/*
 * USF mobile-first redesign layer.
 * Loaded after app.css on migrated pages while the legacy stylesheet remains
 * the functional compatibility base during the staged rollout.
 */

html[data-theme="light"] {
  /* Ohne dies erbt die Seite das "color-scheme: dark" aus app.css: native Bedienelemente
     - Ankreuzfelder, Radios, Auswahllisten, Bildlaufleisten - bleiben dann auch im hellen
     Design dunkel, was ein unausgewaehltes Kaestchen wie einen gefuellten Kasten aussehen
     laesst. Zahlenfelder behalten ihre eigene Regel und damit ihre hellen Spinner. */
  color-scheme: light;
  --bg: #f2f4f5;
  --bg-soft: #e8ecef;
  --card: #ffffff;
  --text: #17212b;
  --fg: #17212b;
  --muted: #65717d;
  --accent: #d4142a;
  --accent-2: #ed3449;
  --warning: #b86d0c;
  --warning-2: #d88618;
  --border: #d8dee3;
  --input: #f8f9fa;
  --surface-raised: #ffffff;
  --surface-subtle: #e8ecef;
  --surface-pressed: #dde3e7;
  --text-on-dark: #f7f8f9;
  --muted-on-dark: #b8c2cb;
  --danger: #c51f32;
  --success: #157a4a;
  --caution: #9c620d;
  --info: #4046bd;
  --focus-ring: rgba(212, 20, 42, .2);
  --shadow: 0 22px 70px rgba(23, 33, 43, .12);
  --shadow-soft: 0 8px 28px rgba(23, 33, 43, .07);
  --hero: #14202b;
  --drawer: #f8f9fa;
}

/* Platzbelegung – gemeinsame Belegungsphasen. Eine Phase ist bewusst nur die
   Arbeitsansicht auf bestehende Terminpläne und erhält deshalb eine leichte,
   offene Kartenoptik statt eines dritten Plan-Statusdesigns. */
.resource-schedule-page .resource-phase-hub {
  display: grid;
  gap: 18px;
  padding: clamp(18px, 2vw, 28px) 2px 4px;
}

.resource-schedule-page .resource-phase-hub-head,
.resource-schedule-page .resource-phase-context,
.resource-schedule-page .resource-phase-plan-picker-head,
.resource-schedule-page .resource-phase-modal-actions {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 18px;
}

.resource-schedule-page .resource-phase-hub-head h3 {
  margin: 3px 0 4px;
  font-family: "Barlow Condensed", sans-serif;
  font-size: clamp(25px, 2.4vw, 34px);
  line-height: 1;
}

.resource-schedule-page .resource-phase-hub-head p,
.resource-schedule-page .resource-phase-empty p,
.resource-schedule-page .resource-phase-truth-note p {
  margin: 0;
  color: var(--muted);
  font-size: 13px;
  line-height: 1.55;
}

.resource-schedule-page .resource-phase-cards {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(min(100%, 300px), 1fr));
  gap: 12px;
}

.resource-schedule-page .resource-phase-card {
  position: relative;
  display: flex;
  flex-direction: column;
  min-height: 210px;
  padding: 20px 20px 17px 24px;
  overflow: hidden;
  border: 1px solid var(--border);
  border-radius: 15px;
  background: var(--surface-raised);
  color: var(--text);
  text-decoration: none;
  box-shadow: var(--shadow-soft);
  transition: transform .16s ease, border-color .16s ease, box-shadow .16s ease;
}

.resource-schedule-page .resource-phase-card::before {
  content: "";
  position: absolute;
  inset: 0 auto 0 0;
  width: 4px;
  background: var(--accent);
}

.resource-schedule-page .resource-phase-card:hover {
  transform: translateY(-2px);
  border-color: color-mix(in srgb, var(--accent) 42%, var(--border));
  box-shadow: var(--shadow);
}

.resource-schedule-page .resource-phase-card > strong {
  margin-top: 7px;
  font-family: "Barlow Condensed", sans-serif;
  font-size: 27px;
  line-height: 1.05;
}

.resource-schedule-page .resource-phase-period {
  margin-top: 5px;
  color: var(--muted);
  font-size: 13px;
}

.resource-schedule-page .resource-phase-meta {
  display: flex;
  flex-wrap: wrap;
  gap: 6px;
  margin-top: 20px;
}

.resource-schedule-page .resource-phase-meta > span {
  padding: 4px 8px;
  border-radius: 999px;
  background: var(--surface-subtle);
  color: var(--muted);
  font-size: 11px;
  font-weight: 650;
}

.resource-schedule-page .resource-phase-open {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 10px;
  margin-top: auto;
  padding-top: 18px;
  color: var(--accent);
  font-size: 12px;
  font-weight: 750;
}

.resource-schedule-page .resource-phase-open span {
  font-size: 21px;
  line-height: 1;
}

.resource-schedule-page .resource-phase-empty {
  display: flex;
  align-items: center;
  gap: 14px;
  min-height: 130px;
  padding: 20px;
  border: 1px dashed var(--border-strong);
  border-radius: 14px;
  background: var(--surface-subtle);
}

.resource-schedule-page .resource-phase-empty-icon {
  display: grid;
  place-items: center;
  width: 42px;
  height: 42px;
  flex: 0 0 auto;
  border-radius: 50%;
  background: color-mix(in srgb, var(--accent) 12%, var(--surface-raised));
  color: var(--accent);
  font-size: 20px;
}

/* Der Arbeitskontext ist eine Angabe, keine Warnung und keine Aktion: Er traegt
   dieselbe ruhige Flaeche wie die Modusleiste darueber und bildet mit ihr den Kopf.
   Rot bleibt der Navigation, den Primaeraktionen und dem Konflikt vorbehalten. */
.resource-schedule-page .resource-phase-context {
  margin: 0 0 12px;
  padding: 8px 12px;
  border: 1px solid var(--border);
  border-radius: 13px;
  background: var(--surface-subtle);
}

/* Eine Zeile statt vier: Label, Name, Zeitraum und Kennzahlen stehen nebeneinander
   und brechen erst um, wenn die Breite es erzwingt. */
.resource-schedule-page .resource-phase-context-copy {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  flex: 1;
  gap: 3px 10px;
}

.resource-schedule-page .resource-phase-context-actions {
  display: flex;
  align-items: center;
  gap: 8px;
  flex-shrink: 0;
}

.resource-schedule-page .resource-phase-context-copy > strong {
  font-size: 16px;
}

/* Dieselben Pillen wie auf der Uebersichtskarte, dort mit Abstand zum Kartenfuss.
   In der einzeiligen Kontextzeile stehen sie direkt neben dem Zeitraum. */
.resource-schedule-page .resource-phase-context .resource-phase-meta {
  margin-top: 0;
}

.resource-schedule-page .resource-phase-context-copy > span:not(.eyebrow),
.resource-schedule-page .resource-phase-context-copy > small {
  color: var(--muted);
  font-size: 12px;
}

.resource-schedule-page .wchip-plan {
  display: block;
  max-width: 100%;
  overflow: hidden;
  color: var(--muted);
  font-size: 9px;
  line-height: 1.2;
  text-overflow: ellipsis;
  white-space: nowrap;
}

.resource-schedule-page .resource-phase-modal {
  width: min(900px, calc(100vw - 28px));
  max-height: min(860px, calc(100dvh - 28px));
}

/* Erklaert direkt an der Auswahl, wofuer sie da ist und dass sie leer bleiben darf. */
/* Kopfzeile der Einteilungs-Uebersicht: Archivzugang neben der Primaeraktion. Die Gruppe
   darf nicht schrumpfen – sonst bricht sie unter dem langen Beschreibungstext daneben
   in zwei Zeilen um und der Archivzugang steht allein ueber der Hauptaktion. */
.resource-schedule-page .resource-phase-hub-actions {
  display: flex;
  align-items: center;
  gap: 8px;
  flex-shrink: 0;
}

.resource-schedule-page .resource-phase-hub-actions .btn {
  white-space: nowrap;
}

/* Archivkarte nennt zusaetzlich die beteiligten Teams – im Archiv sucht man nach
   "welche Mannschaften waren da drin", nicht nach der Anzahl. */
.resource-schedule-page .resource-phase-teamnames {
  color: var(--muted);
  font-size: .74rem;
  line-height: 1.45;
}

.resource-schedule-page .resource-phase-picker-lead {
  margin: 10px 0 12px;
  color: var(--muted);
  font-size: .76rem;
  line-height: 1.55;
}

.resource-schedule-page .resource-phase-picker-lead strong {
  color: var(--text);
  font-weight: 600;
}

.resource-schedule-page .resource-phase-truth-note {
  display: flex;
  align-items: flex-start;
  gap: 10px;
  margin: 14px 0;
  padding: 11px 13px;
  border: 1px solid var(--border);
  border-radius: 11px;
  background: var(--surface-subtle);
}

.resource-schedule-page .resource-phase-truth-note > span {
  display: grid;
  place-items: center;
  width: 24px;
  height: 24px;
  flex: 0 0 auto;
  border-radius: 50%;
  background: var(--surface-raised);
  color: var(--accent);
  font-weight: 800;
  font-style: italic;
}

.resource-schedule-page .resource-phase-plan-picker {
  margin-top: 12px;
  padding: 14px;
  border: 1px solid var(--border);
  border-radius: 13px;
  background: var(--surface-subtle);
}

.resource-schedule-page .resource-phase-plan-picker-head {
  margin-bottom: 10px;
}

.resource-schedule-page .resource-phase-plan-picker-head > div {
  display: grid;
  gap: 2px;
}

.resource-schedule-page .resource-phase-candidates {
  display: grid;
  grid-template-columns: repeat(2, minmax(0, 1fr));
  gap: 9px;
  max-height: 360px;
  overflow-y: auto;
}

.resource-schedule-page .resource-phase-team-group {
  display: grid;
  align-content: start;
  gap: 6px;
  padding: 10px;
  border: 1px solid var(--border);
  border-radius: 10px;
  background: var(--surface-raised);
}

.resource-schedule-page .resource-phase-team-name {
  padding: 0 2px 3px;
  color: var(--text);
  font-size: 12px;
  font-weight: 750;
}

.resource-schedule-page .resource-phase-choice {
  display: flex;
  align-items: flex-start;
  gap: 9px;
  padding: 9px;
  border: 1px solid var(--border);
  border-radius: 9px;
  cursor: pointer;
}

.resource-schedule-page .resource-phase-choice:has(input:checked) {
  border-color: color-mix(in srgb, var(--accent) 62%, var(--border));
  background: color-mix(in srgb, var(--accent) 8%, var(--surface-raised));
}

.resource-schedule-page .resource-phase-choice input {
  margin-top: 2px;
  accent-color: var(--accent);
}

.resource-schedule-page .resource-phase-choice-copy {
  display: grid;
  min-width: 0;
  gap: 2px;
}

.resource-schedule-page .resource-phase-choice-title {
  color: var(--text);
  font-size: 12px;
  font-weight: 700;
}

.resource-schedule-page .resource-phase-choice-subtitle {
  color: var(--muted);
  font-size: 10px;
  line-height: 1.4;
}

.resource-schedule-page .resource-phase-action-spacer {
  flex: 1;
}

@media (max-width: 720px) {
  .resource-schedule-page .resource-phase-hub-head,
  .resource-schedule-page .resource-phase-context {
    align-items: stretch;
    flex-direction: column;
  }

  /* Die Aktionen des Kontextbands sind kurz ("Einteilung wechseln", "Zeitraum &
     Pläne ändern"). Gestreckt belegten sie je eine volle Zeile und schoben das
     Raster nach unten; nebeneinander teilen sie sich eine. Umbrechen dürfen sie
     weiterhin, wenn der Platz nicht reicht. */
  .resource-schedule-page .resource-phase-context-actions {
    width: 100%;
    flex-wrap: wrap;
  }

  /* Beide Aktionen teilen sich eine Zeile, statt je eine zu belegen. `flex-basis: 0`
     verteilt die Breite gleichmäßig; passt ein Text nicht einzeilig, bricht er im
     Knopf um – das bleibt immer noch niedriger als zwei volle Zeilen. Die
     Trefferfläche hält die Mindesthöhe. */
  .resource-schedule-page .resource-phase-context-actions .btn {
    flex: 1 1 0;
    min-width: 0;
    padding: 8px 10px;
    font-size: 13px;
    text-align: center;
  }

  .resource-schedule-page .resource-phase-hub-head .btn {
    width: 100%;
  }

  .resource-schedule-page .resource-phase-form-grid,
  .resource-schedule-page .resource-phase-candidates {
    grid-template-columns: 1fr;
  }

  /* Mobil steht die Aktionsgruppe unter dem Text und teilt sich die Zeile. */
  .resource-schedule-page .resource-phase-hub-actions {
    width: 100%;
  }

  .resource-schedule-page .resource-phase-hub-actions .btn {
    flex: 1;
  }

  .resource-schedule-page .resource-phase-modal-actions {
    align-items: stretch;
    flex-direction: column;
  }

  .resource-schedule-page .resource-phase-action-spacer {
    display: none;
  }
}

/* Terminplaner – mehrere benannte Plaene auf einer gemeinsamen Regelbasis. */
.season-planner-page .planner-card-copy {
  margin: 5px 0 0;
  max-width: 760px;
}

.season-planner-page .planner-info-strip,
.season-planner-page .planner-resource-note {
  display: flex;
  align-items: flex-start;
  gap: 12px;
  padding: 14px 16px;
  border: 1px solid var(--border);
  border-radius: 14px;
  background: var(--surface-subtle);
  color: var(--muted);
  font-size: .86rem;
  line-height: 1.55;
}

.season-planner-page .planner-info-strip strong {
  color: var(--text);
}

.season-planner-page .planner-info-mark {
  display: inline-grid;
  place-items: center;
  flex: 0 0 25px;
  width: 25px;
  height: 25px;
  border-radius: 50%;
  background: color-mix(in srgb, var(--accent) 14%, var(--surface-raised));
  color: var(--accent);
  font-family: Sora, sans-serif;
  font-size: .78rem;
  font-weight: 800;
}

.season-planner-page .planner-plan-list {
  display: grid;
  gap: 12px;
  margin-top: 18px;
}

.season-planner-page .planner-plan-card {
  position: relative;
  display: grid;
  grid-template-columns: minmax(0, 1fr) auto;
  gap: 20px;
  min-height: 116px;
  padding: 20px 22px 20px 31px;
  overflow: hidden;
  border: 1px solid var(--border);
  border-radius: 16px;
  background: var(--surface-raised);
  color: var(--text);
  text-decoration: none;
  transition: background-color .16s ease, transform .16s ease;
}

.season-planner-page .planner-plan-card:hover,
.season-planner-page .planner-plan-card:focus-visible {
  background: color-mix(in srgb, var(--accent) 6%, var(--surface-raised));
  transform: translateY(-1px);
}

.season-planner-page .planner-plan-stripes {
  position: absolute;
  inset: 0 auto 0 0;
  width: 3px;
  background: var(--accent);
}

.season-planner-page .planner-plan-main,
.season-planner-page .planner-plan-origin {
  display: flex;
  flex-direction: column;
}

.season-planner-page .planner-plan-title-row {
  display: flex;
  align-items: center;
  flex-wrap: wrap;
  gap: 10px;
}

.season-planner-page .planner-plan-title-row > strong {
  font-family: "Barlow Condensed", sans-serif;
  font-size: clamp(1.35rem, 2vw, 1.75rem);
  line-height: 1;
}

.season-planner-page .planner-plan-period {
  margin-top: 8px;
  color: var(--muted);
  font-variant-numeric: tabular-nums;
}

.season-planner-page .planner-plan-metrics {
  display: flex;
  flex-wrap: wrap;
  gap: 8px 20px;
  margin-top: 13px;
  color: var(--muted);
  font-size: .8rem;
}

.season-planner-page .planner-plan-metrics strong {
  color: inherit;
  font-variant-numeric: tabular-nums;
}

.season-planner-page .planner-plan-origin {
  align-items: flex-end;
  justify-content: space-between;
  color: var(--muted);
  font-size: .76rem;
  text-align: right;
}

.season-planner-page .planner-plan-origin .editable-row-open {
  color: var(--text);
  font-size: 1.8rem;
}

.season-planner-page .planner-empty-state {
  display: grid;
  justify-items: center;
  gap: 8px;
  padding: 42px 20px 26px;
  text-align: center;
}

.season-planner-page .planner-empty-state.compact {
  padding: 28px 16px 14px;
}

.season-planner-page .planner-empty-state p {
  max-width: 620px;
  margin: 0 0 8px;
  color: var(--muted);
  line-height: 1.55;
}

.season-planner-page .planner-form-modal {
  width: min(780px, calc(100vw - 28px));
  max-height: calc(100dvh - 28px);
  padding: 26px;
  overflow-y: auto;
}

.season-planner-page .planner-form-modal--match,
.season-planner-page .planner-form-modal--help {
  width: min(920px, calc(100vw - 28px));
}

.season-planner-page .planner-form-modal--draft {
  width: min(840px, calc(100vw - 28px));
}

.season-planner-page .planner-form-modal .app-modal-header {
  align-items: flex-start;
  margin-bottom: 20px;
  padding-bottom: 18px;
  border-bottom: 1px solid var(--border);
}

.season-planner-page .planner-modal-title {
  min-width: 0;
}

.season-planner-page .planner-modal-title .eyebrow {
  display: block;
  margin-bottom: 5px;
}

.season-planner-page .planner-modal-title > strong {
  display: block;
  font-family: "Barlow Condensed", sans-serif;
  font-size: clamp(1.55rem, 3vw, 2rem);
  line-height: 1.05;
}

.season-planner-page .planner-modal-title > p {
  max-width: 720px;
  margin: 7px 0 0;
  color: var(--muted);
  font-size: .84rem;
  line-height: 1.55;
}

.season-planner-page .planner-modal-form {
  display: grid;
  gap: 14px;
}

.season-planner-page .planner-form-section {
  display: grid;
  gap: 15px;
  padding: 18px;
  border: 1px solid var(--border);
  border-radius: 15px;
  background: var(--surface-subtle);
}

.season-planner-page .planner-form-section-heading {
  display: flex;
  align-items: flex-start;
  gap: 11px;
  padding-bottom: 13px;
  border-bottom: 1px solid var(--border);
}

.season-planner-page .planner-form-section-heading > span {
  display: grid;
  place-items: center;
  flex: 0 0 29px;
  width: 29px;
  height: 29px;
  border-radius: 50%;
  background: var(--accent);
  color: var(--text-on-dark);
  font-size: .75rem;
  font-weight: 800;
}

.season-planner-page .planner-form-section-heading strong {
  display: block;
  font-size: .9rem;
}

.season-planner-page .planner-form-section-heading p {
  margin: 3px 0 0;
  color: var(--muted);
  font-size: .76rem;
  line-height: 1.5;
}

.season-planner-page .planner-form-modal .field {
  margin: 0;
  overflow: visible;
}

.season-planner-page .planner-form-modal :is(input, select, textarea) {
  min-height: 44px;
}

.season-planner-page .field-help {
  display: block;
  margin-top: 7px;
  color: var(--muted);
  font-size: .72rem;
  line-height: 1.5;
}

/* Gilt appweit: Ein Feld als optional zu kennzeichnen ist kein Terminplaner-Thema. */
.redesign-page .planner-label-optional {
  color: var(--muted);
  font-size: .62rem;
  font-weight: 500;
  letter-spacing: .04em;
  text-transform: none;
}

.season-planner-page .planner-protection-note,
.season-planner-page .planner-auto-sync-note {
  display: flex;
  align-items: flex-start;
  gap: 10px;
  padding: 12px 14px;
  border: 1px solid color-mix(in srgb, var(--success) 32%, var(--border));
  border-radius: 12px;
  background: color-mix(in srgb, var(--success) 8%, var(--surface-raised));
  color: var(--muted);
  font-size: .76rem;
  line-height: 1.5;
}

.season-planner-page .planner-protection-note > span:first-child,
.season-planner-page .planner-auto-sync-note > span:first-child {
  color: var(--success);
  font-weight: 800;
}

/* Derselbe Hinweis, aber als alleiniger Karteninhalt statt als Randnotiz. */
.season-planner-page .planner-auto-sync-note--card {
  align-items: center;
  gap: 12px;
  padding: 15px 17px;
  font-size: .78rem;
}

/* Zustandskasten mit Aktion: Der Text nimmt den Platz, der Knopf sitzt rechts aussen –
   dieselbe Aufteilung wie im Freigabe-Kasten, damit beide Zustaende gleich aussehen. */
.season-planner-page .planner-auto-sync-note--with-action {
  flex-wrap: wrap;
  gap: 12px 16px;
}

.season-planner-page .planner-auto-sync-note--with-action > div {
  flex: 1 1 340px;
  min-width: 0;
}

.season-planner-page .planner-auto-sync-note--with-action > form {
  flex: 0 0 auto;
  margin-left: auto;
}

.season-planner-page .planner-auto-sync-note--card > span:first-child {
  font-size: 1.1rem;
}

.season-planner-page .planner-auto-sync-note--card strong {
  display: block;
  margin-bottom: 2px;
  color: var(--text);
  font-size: .85rem;
}

.season-planner-page textarea {
  min-height: 92px;
  resize: vertical;
}

.season-planner-page .planner-plan-hero {
  position: relative;
  display: grid;
  grid-template-columns: minmax(0, 1fr) auto;
  align-items: center;
  gap: 22px;
  overflow: hidden;
  padding-left: 34px;
}

.season-planner-page .planner-plan-heading {
  display: flex;
  align-items: center;
  flex-wrap: wrap;
  gap: 12px;
}

.season-planner-page .planner-plan-heading h2 {
  margin: 0;
  font-family: "Barlow Condensed", sans-serif;
  font-size: clamp(2rem, 4vw, 3.25rem);
  line-height: .95;
}

/* `align-items: center` ist Pflicht: Der runde Infoknopf hat eine feste Hoehe,
   der Textbutton daneben nicht. Ohne diese Zeile streckt sich nur der Textbutton
   und der Kreis haengt an der Oberkante statt auf gleicher Hoehe. */
.season-planner-page .planner-plan-hero-actions,
.season-planner-page .planner-match-rule-actions {
  display: flex;
  align-items: center;
  flex-wrap: wrap;
  justify-content: flex-end;
  gap: 8px;
}

.season-planner-page .planner-band-scroll {
  overflow-x: auto;
  overscroll-behavior-inline: contain;
  padding: 2px 2px 9px;
  scroll-snap-type: x proximity;
}

.season-planner-page .planner-band {
  display: flex;
  gap: 8px;
  min-width: max-content;
}

.season-planner-page .planner-band-week {
  display: grid;
  gap: 7px;
  width: 124px;
  min-height: 94px;
  padding: 11px 12px;
  appearance: none;
  border: 1px solid var(--border);
  border-radius: 12px;
  background: var(--surface-subtle);
  /* Der Zustandsbalken laeuft ueber eine Variable, damit ihn die Auswahl weiter
     unten nicht ueberschreibt. Vorher setzte `.is-selected` den box-shadow neu –
     wer die Konfliktwoche anklickte, verlor genau deren Markierung. */
  --band-mark: color-mix(in srgb, var(--muted) 42%, transparent);
  box-shadow: inset 0 -3px 0 var(--band-mark);
  color: var(--text);
  font: inherit;
  text-align: left;
  cursor: pointer;
  scroll-snap-align: start;
  transition: border-color .16s ease, background-color .16s ease, transform .16s ease;
}

.season-planner-page .planner-band-week:hover,
.season-planner-page .planner-band-week:focus-visible {
  border-color: color-mix(in srgb, var(--accent) 46%, var(--border));
  background: color-mix(in srgb, var(--accent) 6%, var(--surface-subtle));
  outline: none;
  transform: translateY(-1px);
}

/* Ein Spiel ist eine Information, ein Konflikt eine Aufgabe. Beide waren rot –
   `--accent` und `--danger` liegen im hellen Theme 15 Punkte auseinander und sind
   auf einer schmalen Kachel nicht zu trennen. Bei einem woechentlichen Spieltag
   leuchtet dann das ganze Band, und die eine Problemwoche verschwindet darin.
   Rot bleibt deshalb dem Konflikt vorbehalten, das Spiel wird neutral markiert. */
.season-planner-page .planner-band-week.has-match {
  --band-mark: color-mix(in srgb, var(--text) 45%, transparent);
  background: color-mix(in srgb, var(--text) 5%, var(--surface-subtle));
}

.season-planner-page .planner-band-week.has-exception {
  --band-mark: var(--caution);
  background: color-mix(in srgb, var(--caution) 10%, var(--surface-subtle));
}

.season-planner-page .planner-band-week.has-conflict {
  --band-mark: var(--danger);
  border-color: color-mix(in srgb, var(--danger) 55%, var(--border));
  background: color-mix(in srgb, var(--danger) 14%, var(--surface-subtle));
}

/* Die Auswahl arbeitet ueber Rahmen und Ring, nicht ueber eine rote Flaeche:
   Sonst ist die gewaehlte Woche von einer Konfliktwoche nicht zu unterscheiden.
   Der Zustandsbalken bleibt sichtbar. */
.season-planner-page .planner-band-week.is-selected {
  border-color: var(--accent);
  background: color-mix(in srgb, var(--accent) 5%, var(--surface-raised));
  box-shadow: inset 0 -3px 0 var(--band-mark), 0 0 0 2px var(--accent), 0 0 0 5px var(--focus-ring);
}

.season-planner-page .planner-band-week-top {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 8px;
}

.season-planner-page .planner-band-kw {
  font-size: .7rem;
  font-weight: 800;
}

.season-planner-page .planner-band-date,
.season-planner-page .planner-band-count {
  color: var(--muted);
  font-size: .68rem;
  font-variant-numeric: tabular-nums;
}

.season-planner-page .planner-band-count {
  display: grid;
  place-items: center;
  min-width: 24px;
  height: 24px;
  padding: 0 6px;
  border-radius: 999px;
  background: var(--surface-raised);
  color: var(--text);
  font-weight: 800;
}

.season-planner-page .planner-band-meta {
  overflow: hidden;
  color: var(--muted);
  font-size: .65rem;
  line-height: 1.35;
  text-overflow: ellipsis;
  white-space: nowrap;
}

.season-planner-page .planner-band-meta .is-match { color: var(--text); font-weight: 600; }
.season-planner-page .planner-band-meta .is-exception { color: var(--caution); font-weight: 600; }
.season-planner-page .planner-band-meta .is-conflict { color: var(--danger); font-weight: 700; }

/* Farbe allein traegt die Unterscheidung nicht. Der Konflikt bekommt zusaetzlich
   ein Zeichen, damit er auch bei Rotsehschwaeche und im Ueberflug auffaellt. */
.season-planner-page .planner-band-meta .is-conflict::before {
  content: "!";
  display: inline-grid;
  place-items: center;
  width: 13px;
  height: 13px;
  margin-right: 4px;
  border-radius: 50%;
  background: var(--danger);
  color: var(--surface-raised);
  font-size: .62rem;
  font-weight: 800;
  vertical-align: -2px;
}

.season-planner-page .planner-band-hint {
  margin: -3px 0 12px;
  font-size: .75rem;
}

.season-planner-page .planner-band-header-tools {
  display: flex;
  align-items: center;
  gap: 14px;
}

.season-planner-page .planner-band-controls {
  display: flex;
  gap: 5px;
}

.season-planner-page .planner-band-controls[hidden] {
  display: none;
}

.season-planner-page .planner-band-controls button {
  display: grid;
  place-items: center;
  width: 36px;
  height: 36px;
  padding: 0;
  border: 1px solid var(--border);
  border-radius: 10px;
  background: var(--surface-subtle);
  color: var(--text);
  font-size: 1.35rem;
  line-height: 1;
  cursor: pointer;
}

.season-planner-page .planner-band-controls button:disabled {
  opacity: .42;
  cursor: default;
}

.season-planner-page .planner-band-legend {
  display: flex;
  flex-wrap: wrap;
  gap: 12px;
  color: var(--muted);
  font-size: .72rem;
}

.season-planner-page .planner-band-legend span::before {
  content: "";
  display: inline-block;
  width: 8px;
  height: 8px;
  margin-right: 5px;
  border-radius: 50%;
  /* Deckungsgleich mit dem Zustandsbalken der Kachel – sonst wirkt der
     Standardzustand in der Legende kraeftiger als die Spielmarkierung. */
  background: color-mix(in srgb, var(--muted) 42%, transparent);
}

.season-planner-page .planner-band-legend .is-match::before { background: color-mix(in srgb, var(--text) 45%, transparent); }
.season-planner-page .planner-band-legend .is-exception::before { background: var(--caution); }
.season-planner-page .planner-band-legend .is-conflict::before { background: var(--danger); }

.season-planner-page .planner-tabs {
  margin-bottom: 16px;
}

/* ── Schrittfolge statt Tabs ────────────────────────────────────────────────
   Die drei Bereiche haben eine Reihenfolge. Solange der Plan aufgebaut wird,
   traegt jeder Schritt Nummer und Untertitel; sobald Regeln stehen, schrumpft
   die Leiste auf Orientierung; nach der Freigabe ist sie wieder schlicht. */
.season-planner-page .planner-steps .tab-btn {
  display: flex;
  align-items: center;
  gap: 9px;
  text-align: left;
}

.season-planner-page .planner-step-no {
  display: inline-grid;
  place-items: center;
  width: 22px;
  height: 22px;
  flex-shrink: 0;
  border-radius: 50%;
  background: color-mix(in srgb, var(--text) 12%, transparent);
  color: var(--muted);
  font-size: .72rem;
  font-weight: 800;
}

.season-planner-page .planner-steps .tab-btn.active .planner-step-no {
  background: var(--accent);
  color: var(--text-on-dark);
}

/* Erledigt heisst: Der Schritt traegt Inhalt. Das Haekchen ersetzt die Nummer,
   damit man den Fortschritt im Vorbeigehen sieht. */
.season-planner-page .planner-steps .tab-btn.is-done:not(.active) .planner-step-no {
  background: color-mix(in srgb, var(--success) 18%, transparent);
  color: var(--success);
  font-size: 0;
}

.season-planner-page .planner-steps .tab-btn.is-done:not(.active) .planner-step-no::before {
  content: "✓";
  font-size: .78rem;
}

.season-planner-page .planner-step-label {
  display: grid;
  gap: 1px;
  min-width: 0;
}

.season-planner-page .planner-step-label small {
  color: var(--muted);
  font-size: .68rem;
  font-weight: 500;
  line-height: 1.3;
}

/* Nur beim Aufbau traegt die Leiste ihre Untertitel. Danach genuegt der Name. */
.season-planner-page .planner-steps:not(.is-setup) .planner-step-label small,
.season-planner-page .planner-steps.guide-off .planner-step-label small {
  display: none;
}

.season-planner-page .planner-steps.guide-off .planner-step-no {
  display: none;
}

.season-planner-page .planner-steps-toggle {
  display: flex;
  justify-content: flex-end;
  margin: -10px 0 14px;
}

.season-planner-page .planner-steps-toggle .btn {
  font-size: .72rem;
  padding: 4px 10px;
  min-height: 0;
}

/* Erklaerung ueber dem Schritt – nur waehrend des Aufbaus. */
.season-planner-page .planner-step-intro {
  margin-bottom: 14px;
  padding: 15px 17px;
  border: 1px solid color-mix(in srgb, var(--accent) 30%, var(--border));
  border-radius: 14px;
  background: color-mix(in srgb, var(--accent) 6%, var(--surface-raised));
}

/* Nur das direkte Kind ist die Ueberschrift. Ohne den Kindselektor werden auch die
   Labels im Fliesstext ("Was du tust:") zu Display-Zeilen und der Block waechst auf
   das Doppelte. */
.season-planner-page .planner-step-intro > strong {
  display: block;
  margin: 3px 0 7px;
  font-family: "Barlow Condensed", sans-serif;
  font-size: 1.4rem;
}

.season-planner-page .planner-step-intro p {
  margin: 0;
  color: var(--muted);
  font-size: .8rem;
  line-height: 1.65;
}

/* Die Labels fuehren durch den Absatz, ohne ihn zu zerreissen. */
.season-planner-page .planner-step-intro p strong {
  color: var(--text);
  font-weight: 700;
}

.season-planner-page .planner-step-next {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 12px;
  flex-wrap: wrap;
  margin-top: 16px;
  padding-top: 14px;
  border-top: 1px solid var(--border);
  color: var(--muted);
  font-size: .78rem;
}

/* Abschluss des Aufbaus: steht dort, wo man die Termine prueft. */
.season-planner-page .planner-release-block {
  display: flex;
  align-items: flex-start;
  justify-content: space-between;
  gap: 20px;
  flex-wrap: wrap;
  margin: 22px 0 16px;
  padding: 18px 0 0;
  border-top: 1px solid var(--border);
}

.season-planner-page .planner-release-copy {
  flex: 1 1 340px;
  min-width: 0;
}

.season-planner-page .planner-release-copy strong {
  display: block;
  margin: 3px 0 5px;
  font-size: .95rem;
}

.season-planner-page .planner-release-copy p {
  margin: 0 0 10px;
  color: var(--muted);
  font-size: .78rem;
  line-height: 1.55;
}

.season-planner-page .planner-release-check {
  display: inline-flex;
  align-items: center;
  gap: 9px;
  padding: 8px 12px;
  border: 1px solid var(--border);
  border-radius: 10px;
  background: var(--surface-raised);
  font-size: .8rem;
  font-weight: 600;
  cursor: pointer;
}

.season-planner-page .planner-release-check input {
  width: 16px;
  height: 16px;
  min-height: 0;
  flex-shrink: 0;
  cursor: pointer;
}

.season-planner-page .planner-release-hint {
  margin: 8px 0 0;
  color: var(--success);
  font-size: .72rem;
}

.season-planner-page .planner-release-action {
  display: grid;
  justify-items: end;
  gap: 6px;
}

.season-planner-page .planner-release-blocked {
  max-width: 260px;
  color: var(--muted);
  font-size: .72rem;
  line-height: 1.45;
  text-align: right;
}

/* Uebersichtskopf: Archivzugang neben der Primaeraktion. */
.season-planner-page .planner-overview-actions {
  display: flex;
  align-items: center;
  gap: 8px;
  flex-wrap: wrap;
}

/* Archiv-Detail: Der Plan ist eingefroren – der Hinweis sagt das, bevor jemand
   nach Bedienelementen sucht, die es hier bewusst nicht gibt. */
.season-planner-page .planner-readonly-note {
  display: flex;
  align-items: flex-start;
  gap: 11px;
  margin-bottom: 14px;
  padding: 13px 15px;
  border: 1px solid var(--border);
  border-radius: 13px;
  background: var(--surface-subtle);
  color: var(--muted);
  font-size: .78rem;
  line-height: 1.55;
}

.season-planner-page .planner-readonly-note strong {
  display: block;
  color: var(--text);
}

.season-planner-page .planner-archive-facts,
.resource-schedule-page .planner-archive-facts {
  display: grid;
  grid-template-columns: repeat(4, minmax(0, 1fr));
  gap: 10px;
}

.season-planner-page .planner-archive-facts > div,
.resource-schedule-page .planner-archive-facts > div {
  display: grid;
  gap: 3px;
  padding: 13px 15px;
  border: 1px solid var(--border);
  border-radius: 13px;
  background: var(--surface-subtle);
}

.season-planner-page .planner-archive-facts strong,
.resource-schedule-page .planner-archive-facts strong {
  font-family: "Barlow Condensed", sans-serif;
  font-size: 1.6rem;
  line-height: 1;
}

.season-planner-page .planner-archive-facts span,
.resource-schedule-page .planner-archive-facts span {
  color: var(--muted);
  font-size: .72rem;
}

/* Herkunft in der Planvorschau: Gattung oben, konkrete Regel darunter. Ohne die
   zweite Zeile steht bei mehreren Matchtag-Regeln ueberall derselbe Text. */
.season-planner-page .planner-origin {
  display: grid;
  gap: 2px;
  justify-items: start;
}

.season-planner-page .planner-origin-kind {
  font-weight: 600;
}

.season-planner-page .planner-origin.planner-origin-inline {
  display: flex;
  align-items: center;
  gap: 12px;
  white-space: nowrap;
}

.season-planner-page .planner-origin-inline form {
  margin: 0;
}

.season-planner-page .planner-origin-inline .table-text-action {
  min-height: 0;
  padding: 0;
}

/* Die gemeinsame Tabellenregel ruecht Tags nach rechts ein. In der gestapelten
   Herkunft steht der Tag am Zeilenanfang und braucht diesen Einzug nicht. */
.season-planner-page .planner-origin .tag {
  margin-left: 0;
  margin-top: 2px;
}

.redesign-page .table-text-action {
  display: inline-flex;
  align-items: center;
  min-height: 32px;
  padding: 4px 0;
  border: 0;
  border-radius: 0;
  background: transparent;
  box-shadow: none;
  color: var(--muted);
  font: inherit;
  font-size: 12px;
  font-weight: 500;
  text-decoration: underline;
  text-underline-offset: 3px;
  cursor: pointer;
}

.redesign-page .table-text-action:hover {
  color: var(--text);
  background: transparent;
}

.redesign-page .table-text-action:focus-visible {
  outline: 2px solid var(--muted);
  outline-offset: 3px;
}

.season-planner-page .planner-origin-detail {
  color: var(--muted);
  font-size: 12px;
  line-height: 1.35;
}

/* Der Speichern-Button stand direkt unter der Tabelle und am unteren Kartenrand.
   Die Trennlinie gibt der Abschlusszeile eine eigene Zone. */
.season-planner-page .settings-save-row {
  margin-top: 18px;
  padding-top: 14px;
  border-top: 1px solid var(--border);
}

.season-planner-page .planner-rules-table {
  min-width: 1120px;
}

.season-planner-page .planner-rules-table :is(input, select, button) {
  width: 100%;
}

.season-planner-page .planner-rules-table :is(th, td):is(:nth-child(1), :nth-child(2)) { width: 128px; }
.season-planner-page .planner-rules-table :is(th, td):is(:nth-child(3), :nth-child(4), :nth-child(7), :nth-child(8)) { width: 92px; }
.season-planner-page .planner-rules-table :is(th, td):nth-child(5) { width: 190px; }
.season-planner-page .planner-rules-table :is(th, td):last-child { width: 54px; }

/* Einstieg in den Anlagenplan-Dialog. Seitenunabhaengig, weil ihn Terminplaner und
   Platzbelegung teilen – der Plan selbst (.resource-area-picker-*) ist es laengst. */
.planner-resource-trigger {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 8px;
  width: 100%;
  min-height: 44px;
  padding: 8px 10px;
  overflow: hidden;
  border: 1px solid var(--border);
  border-radius: 10px;
  background: var(--surface-subtle);
  color: var(--text);
  font: inherit;
  text-align: left;
  cursor: pointer;
}

.planner-resource-trigger:hover {
  border-color: color-mix(in srgb, var(--accent) 40%, var(--border));
}

.planner-resource-trigger span:first-child {
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}

.season-planner-page .planner-resource-readonly {
  display: block;
  color: var(--muted);
  line-height: 1.4;
}

.season-planner-page .planner-rule-remove .btn {
  min-width: 44px;
}

.season-planner-page .planner-match-rule-list {
  display: grid;
  gap: 10px;
}

.season-planner-page .planner-match-rule {
  display: grid;
  grid-template-columns: 72px minmax(0, 1fr) auto;
  align-items: center;
  gap: 16px;
  padding: 14px 16px;
  border: 1px solid var(--border);
  border-radius: 14px;
  background: var(--surface-subtle);
}

.season-planner-page .planner-match-offset {
  color: var(--accent);
  font-family: "Barlow Condensed", sans-serif;
  font-size: 1.7rem;
  font-weight: 800;
  text-align: center;
}

.season-planner-page .planner-match-rule-copy {
  display: flex;
  flex-wrap: wrap;
  align-items: baseline;
  gap: 5px 14px;
}

.season-planner-page .planner-match-rule-copy strong {
  flex-basis: 100%;
}

.season-planner-page .planner-match-rule-copy span {
  color: var(--muted);
  font-size: .78rem;
}

/* Die Kennzahlen stehen in zwei Gruppen: was der Button aendert, und was er
   unberuehrt laesst. Ohne diese Trennung liest man die Zahlen als Beschreibung
   der Terminliste weiter unten – sie sind aber eine reine Rechnung. */
.season-planner-page .planner-impact-group {
  margin-top: 16px;
}

.season-planner-page .planner-impact-group .eyebrow {
  display: block;
  margin-bottom: 7px;
}

/* `auto-fit` statt einer festen Spaltenzahl, damit eine weitere Kennzahl nicht
   jede Breakpoint-Stufe nachziehen muss. */
.season-planner-page .planner-impact-grid {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(148px, 1fr));
  gap: 10px;
}

/* Zusammensetzung des Bestands: schlichte Textzeile unter der Kartenbeschreibung.
   Als Chip gesetzt wirkt sie wie ein verirrtes Label ueber dem Aktionsblock. */
.season-planner-page .planner-stock-line {
  margin: -4px 0 14px;
  font-size: .78rem;
}

.season-planner-page .planner-stock-line strong {
  color: var(--text);
}

/* Eine Aufgabe ueber der gemeinsamen Terminliste, keine zweite Tabelle oder Warnkarte. */
.season-planner-page .planner-review-note {
  display: flex;
  align-items: center;
  justify-content: space-between;
  flex-wrap: wrap;
  gap: 8px 16px;
  margin: 0 0 16px;
  padding: 12px 16px;
  border-radius: 10px;
  background: var(--surface-subtle);
  font-size: .8rem;
  line-height: 1.5;
}

/* Ohne offene Aenderungen traegt der Bereich keine Karte – zwei Hinweiszeilen brauchen
   keinen eigenen Rahmen, und die Seite hat ohnehin genug Ebenen. */
.season-planner-page .planner-impact-card:not(.card) {
  display: grid;
  gap: 10px;
  margin-bottom: 16px;
}

/* Welche Termine eine Aenderung trifft. Das Zeichen traegt die Richtung, die Farbe
   nur die Betonung – ein Minus bleibt auch ohne Farbwahrnehmung ein Minus. */
.season-planner-page .planner-change-list {
  display: grid;
  gap: 4px;
}

.season-planner-page .planner-change-row {
  display: flex;
  align-items: baseline;
  flex-wrap: wrap;
  gap: 8px;
  padding: 7px 11px;
  border: 1px solid var(--border);
  border-radius: 10px;
  background: var(--surface-subtle);
  font-size: .78rem;
}

.season-planner-page .planner-change-mark {
  display: inline-grid;
  place-items: center;
  width: 17px;
  height: 17px;
  flex-shrink: 0;
  border-radius: 50%;
  background: color-mix(in srgb, var(--text) 12%, transparent);
  color: var(--text);
  font-size: .7rem;
  font-weight: 800;
}

.season-planner-page .planner-change-row.is-created .planner-change-mark {
  background: color-mix(in srgb, var(--success) 18%, transparent);
  color: var(--success);
}

.season-planner-page .planner-change-row.is-removed .planner-change-mark {
  background: color-mix(in srgb, var(--danger) 18%, transparent);
  color: var(--danger);
}

.season-planner-page .planner-change-row strong {
  font-variant-numeric: tabular-nums;
}

.season-planner-page .planner-impact-grid > div {
  display: grid;
  gap: 3px;
  padding: 14px;
  border: 1px solid var(--border);
  border-radius: 13px;
  background: var(--surface-subtle);
}

.season-planner-page .planner-impact-grid strong {
  font-family: "Barlow Condensed", sans-serif;
  font-size: 1.75rem;
  line-height: 1;
}

.season-planner-page .planner-impact-grid span {
  color: var(--muted);
  font-size: .7rem;
}

.season-planner-page .planner-stock-notice {
  margin-top: 12px;
  padding: 14px 16px;
  border: 1px solid var(--border);
  border-radius: 13px;
  background: var(--surface-subtle);
  color: var(--muted);
}

.season-planner-page .planner-stock-notice p {
  margin: 5px 0 0;
  font-size: .8rem;
}

.season-planner-page .planner-adopt-modal {
  display: flex;
  flex-direction: column;
  max-height: 90dvh;
  overflow: hidden;
}

.season-planner-page #adoptSessionsForm {
  display: flex;
  flex-direction: column;
  min-height: 0;
  overflow: auto;
}

.season-planner-page .planner-adopt-list {
  min-height: 0;
  overflow: auto;
}

.season-planner-page .planner-adopt-modal .app-modal-actions {
  flex-shrink: 0;
}

.season-planner-page .planner-adopt-list thead th {
  position: sticky;
  top: 0;
  z-index: 1;
}

.season-planner-page .planner-conflict-list {
  margin-top: 12px;
  padding: 14px 16px;
  border: 1px solid color-mix(in srgb, var(--danger) 45%, var(--border));
  border-radius: 13px;
  background: color-mix(in srgb, var(--danger) 9%, var(--surface-raised));
  color: var(--danger);
}

.season-planner-page .planner-conflict-list p {
  margin: 5px 0 0;
  font-size: .8rem;
}

.season-planner-page .planner-draft-conflict {
  display: grid;
  grid-template-columns: 34px minmax(0, 1fr) auto;
  align-items: start;
  gap: 11px;
  padding: 14px;
  border: 1px solid color-mix(in srgb, var(--danger) 42%, var(--border));
  border-radius: 13px;
  background: color-mix(in srgb, var(--danger) 8%, var(--surface-raised));
}

.season-planner-page .planner-draft-conflict[hidden] {
  display: none;
}

.season-planner-page .planner-draft-conflict-mark {
  display: grid;
  place-items: center;
  width: 34px;
  height: 34px;
  border-radius: 50%;
  background: color-mix(in srgb, var(--danger) 14%, var(--surface-raised));
  color: var(--danger);
  font-weight: 800;
}

.season-planner-page .planner-draft-conflict-copy {
  display: grid;
  gap: 5px;
}

.season-planner-page .planner-draft-conflict-copy strong {
  color: var(--danger);
  font-size: .84rem;
}

.season-planner-page .planner-draft-conflict-copy p {
  margin: 0;
  color: var(--muted);
  font-size: .74rem;
  line-height: 1.55;
  white-space: pre-line;
}

.season-planner-page .planner-preview-basis {
  display: inline-flex;
  flex-wrap: wrap;
  gap: 4px;
  margin-top: 9px;
  padding: 7px 10px;
  border-radius: 9px;
  background: var(--surface-subtle);
  color: var(--muted);
  font-size: .72rem;
}

.season-planner-page .planner-preview-basis strong {
  color: var(--text);
}

/* Veroeffentlichungsblock: Zuerst die Lage ueber die volle Breite, darunter eine
   abgesetzte Aktionszeile. Die frueher nebeneinander stehende Anordnung liess
   die Buttons auf Hoehe des Vergangenheits-Schalters schweben – der Schalter sah
   dadurch aus wie ein dritter Button. */
.season-planner-page .planner-publish-row {
  display: grid;
  gap: 12px;
  margin-bottom: 14px;
  padding: 14px 16px;
  border: 1px solid var(--border);
  border-radius: 14px;
  background: var(--surface-subtle);
}

.season-planner-page .planner-publish-summary {
  display: grid;
  gap: 4px;
}

.season-planner-page .planner-publish-bar {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 14px;
  flex-wrap: wrap;
  padding-top: 12px;
  border-top: 1px solid var(--border);
}

/* Ohne vergangene Entwuerfe entfaellt der Schalter; die Aktionen bleiben rechts. */
.season-planner-page .planner-publish-bar > .inline-actions {
  margin-left: auto;
}

.season-planner-page .planner-publish-past {
  display: flex;
  align-items: center;
  gap: 8px;
  padding: 8px 11px;
  border: 1px solid var(--border);
  border-radius: 9px;
  background: var(--surface-raised);
  color: var(--text);
  font-size: 12px;
  font-weight: 600;
  cursor: pointer;
  min-width: 0;
}

.season-planner-page .planner-publish-past input[type="checkbox"] {
  width: 15px;
  height: 15px;
  flex-shrink: 0;
  cursor: pointer;
}

.season-planner-page .planner-conflict-intro {
  color: color-mix(in srgb, var(--danger) 78%, var(--text));
  font-weight: 600;
}

.season-planner-page .planner-exception-section {
  display: grid;
  gap: 12px;
  margin-bottom: 16px;
  padding: 16px;
  border: 1px solid color-mix(in srgb, var(--caution) 38%, var(--border));
  border-radius: 14px;
  background: color-mix(in srgb, var(--caution) 7%, var(--surface-raised));
}

.season-planner-page .planner-exception-section[hidden],
.season-planner-page .planner-exception-row[hidden],
.season-planner-page .planner-exception-panel[hidden] {
  display: none;
}

.season-planner-page .planner-exception-heading {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 12px;
}

.season-planner-page .planner-exception-heading > div {
  display: grid;
  gap: 3px;
}

.season-planner-page .planner-exception-heading strong {
  font-family: "Barlow Condensed", sans-serif;
  font-size: 1.45rem;
  line-height: 1;
}

.season-planner-page .planner-exception-count {
  display: grid;
  place-items: center;
  min-width: 30px;
  height: 30px;
  padding: 0 9px;
  border: 1px solid color-mix(in srgb, var(--caution) 42%, var(--border));
  border-radius: 999px;
  background: color-mix(in srgb, var(--caution) 12%, var(--surface-raised));
  color: var(--caution);
  font-size: .74rem;
  font-weight: 800;
}

.season-planner-page .planner-exception-section > p {
  max-width: 820px;
  margin: -3px 0 0;
  color: var(--muted);
  font-size: .76rem;
  line-height: 1.55;
}

.season-planner-page .planner-exception-list {
  display: grid;
  gap: 8px;
}

.season-planner-page .planner-exception-row {
  display: grid;
  grid-template-columns: 90px minmax(0, 1fr) auto;
  align-items: center;
  gap: 14px;
  padding: 12px 13px;
  border: 1px solid var(--border);
  border-radius: 12px;
  background: var(--surface-raised);
}

.season-planner-page .planner-exception-date,
.season-planner-page .planner-exception-copy {
  display: grid;
  gap: 3px;
}

.season-planner-page .planner-exception-date strong {
  color: var(--caution);
  font-family: "Barlow Condensed", sans-serif;
  font-size: 1.35rem;
  line-height: 1;
}

.season-planner-page .planner-exception-date span,
.season-planner-page .planner-exception-copy span {
  color: var(--muted);
  font-size: .7rem;
  line-height: 1.4;
}

.season-planner-page .planner-exception-copy .planner-exception-reason {
  margin-top: 2px;
  color: var(--text);
}

.season-planner-page .planner-exception-row form {
  margin: 0;
}

/* Datum mit Wochentag: Der Tag steht klein daneben, damit die Spalte nicht waechst. */
.season-planner-page .planner-session-date {
  display: flex;
  align-items: baseline;
  gap: 6px;
  white-space: nowrap;
}

.season-planner-page .planner-session-date > span {
  color: var(--muted);
  font-size: .74rem;
}

.season-planner-page .planner-session-table :is(th, td):is(:nth-child(1), :nth-child(3)) {
  font-variant-numeric: tabular-nums;
  white-space: nowrap;
}

.season-planner-page .planner-session-table :is(th, td):nth-child(1) { width: 142px; }
.season-planner-page .planner-session-table :is(th, td):nth-child(3) { width: 118px; }

.season-planner-page .planner-session-table :is(th, td):is(:nth-child(2), :nth-child(6), :nth-child(7)) {
  width: 135px;
}

/* Herkunft traegt zwei Zeilen (Gattung und konkrete Regel) und braucht deshalb
   mehr Platz als die uebrigen schmalen Spalten. */
.season-planner-page .planner-session-table :is(th, td):nth-child(5) {
  width: 190px;
}

.season-planner-page .planner-session-table .tag {
  margin-left: 5px;
}

.planner-resource-options {
  display: grid;
  gap: 8px;
  max-height: min(50vh, 430px);
  overflow-y: auto;
}

.planner-resource-group-label {
  grid-column: 1 / -1;
  margin: 6px 2px 0;
  color: var(--muted);
  font-size: .64rem;
  font-weight: 800;
  letter-spacing: .11em;
  text-transform: uppercase;
}

.season-planner-page .planner-resource-group-label:first-child {
  margin-top: 0;
}

.season-planner-page .planner-exception-panel {
  display: grid;
  grid-template-columns: 48px minmax(0, 1fr);
  gap: 14px;
  margin-top: 14px;
  padding: 16px;
  border: 1px solid color-mix(in srgb, var(--caution) 40%, var(--border));
  border-radius: 14px;
  background: color-mix(in srgb, var(--caution) 8%, var(--surface-raised));
}

.season-planner-page .planner-exception-panel-mark {
  display: grid;
  place-items: center;
  width: 48px;
  height: 48px;
  border-radius: 50%;
  background: color-mix(in srgb, var(--caution) 16%, var(--surface-raised));
  color: var(--caution);
  font-family: "Barlow Condensed", sans-serif;
  font-size: 1.2rem;
  font-weight: 800;
}

.season-planner-page .planner-exception-panel > div:last-child {
  display: grid;
  gap: 7px;
}

.season-planner-page .planner-exception-panel strong {
  font-size: .9rem;
}

.season-planner-page .planner-exception-panel p {
  margin: 0;
  color: var(--muted);
  font-size: .75rem;
  line-height: 1.55;
}

.season-planner-page .planner-exception-panel .field {
  margin-top: 5px;
}

.season-planner-page .planner-resource-options--inline {
  grid-template-columns: repeat(2, minmax(0, 1fr));
  max-height: 260px;
  margin-top: 9px;
  padding: 2px;
}

.season-planner-page .planner-resource-options--inline .cal-team-picker-option {
  min-height: 54px;
  margin: 0;
  border: 1px solid var(--border);
  border-radius: 11px;
  background: var(--surface-raised);
}

.season-planner-page .planner-resource-options--inline .cal-team-picker-option.selected {
  border-color: color-mix(in srgb, var(--accent) 48%, var(--border));
  background: color-mix(in srgb, var(--accent) 8%, var(--surface-raised));
}

.season-planner-page .planner-offset-presets {
  display: flex;
  flex-wrap: wrap;
  gap: 7px;
}

.season-planner-page .planner-offset-presets button {
  min-width: 58px;
  min-height: 38px;
  padding: 6px 12px;
  border: 1px solid var(--border);
  border-radius: 999px;
  background: var(--surface-raised);
  color: var(--text);
  font: inherit;
  font-size: .76rem;
  font-weight: 700;
  cursor: pointer;
}

.season-planner-page .planner-offset-presets button:hover,
.season-planner-page .planner-offset-presets button:focus-visible,
.season-planner-page .planner-offset-presets button.is-selected {
  border-color: var(--accent);
  background: color-mix(in srgb, var(--accent) 10%, var(--surface-raised));
  color: var(--accent);
  outline: none;
}

.season-planner-page .planner-auto-sync-note {
  align-items: center;
  border-color: var(--border);
  background: var(--surface-subtle);
}

.season-planner-page .planner-auto-sync-note.is-active {
  border-color: color-mix(in srgb, var(--success) 32%, var(--border));
  background: color-mix(in srgb, var(--success) 8%, var(--surface-raised));
}

.season-planner-page .planner-preview-action,
.season-planner-page .planner-preview-action form {
  margin: 0;
}

/* Der Button traegt nur die Anzahl. Was er tatsaechlich schreibt, steht als
   kurze Zeile darunter – sonst muss man die Kennzahlen weiter unten deuten. */
.season-planner-page .planner-preview-action form {
  display: grid;
  justify-items: end;
  gap: 6px;
}

.season-planner-page .planner-preview-action-hint {
  max-width: 320px;
  color: var(--muted);
  font-size: 12px;
  line-height: 1.45;
  text-align: right;
}

.season-planner-page .planner-week-filter {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 16px;
  margin-bottom: 14px;
  padding: 13px 15px;
  border: 1px solid color-mix(in srgb, var(--accent) 34%, var(--border));
  border-radius: 13px;
  background: color-mix(in srgb, var(--accent) 7%, var(--surface-raised));
}

.season-planner-page .planner-week-filter[hidden] {
  display: none;
}

.season-planner-page .planner-week-filter > div {
  display: grid;
  gap: 3px;
}

.season-planner-page .planner-week-filter strong {
  font-family: "Barlow Condensed", sans-serif;
  font-size: 1.35rem;
}

/* Flex statt fester Spaltenzahl: Die Kette hat vier Stationen und drei Pfeile –
   eine `grid-template-columns`-Liste muesste bei jeder weiteren Station
   nachgezogen werden. */
/* ==========================================================================
   Bausteine fuer Erklaerdialoge: Ablaufband mit Pfeilen, nummerierte
   Schrittkarten, Spaltenkarten mit Akzentbalken, Button-Verzeichnis und
   Warnkasten. Stammen aus dem Terminplaner und lagen dort seitengebunden;
   seit Budget und Sponsoring dieselben Dialoge brauchen, gelten die Regeln
   app-weit. Die .planner-*- und .schedule-*-Namen bleiben als Alias erhalten,
   damit die Terminplaner-Templates unveraendert weiterlaufen.
   ========================================================================== */
.explainer-flow,
.season-planner-page .planner-help-flow {
  display: flex;
  align-items: stretch;
  gap: 10px;
  margin-bottom: 16px;
}

.explainer-flow > div,
.season-planner-page .planner-help-flow > div {
  display: grid;
  flex: 1 1 0;
  min-width: 0;
  gap: 4px;
  min-height: 88px;
  align-content: center;
  padding: 15px 12px;
  border: 1px solid var(--border);
  border-radius: 13px;
  background: var(--surface-subtle);
  text-align: center;
}

.explainer-flow > div strong,
.season-planner-page .planner-help-flow > div strong {
  color: var(--accent);
  font-family: "Barlow Condensed", sans-serif;
  font-size: 1.35rem;
}

.explainer-flow > div span,
.season-planner-page .planner-help-flow > div span,
.explainer-flow > span,
.season-planner-page .planner-help-flow > span {
  color: var(--muted);
  font-size: .72rem;
  line-height: 1.45;
}

.explainer-flow > span,
.season-planner-page .planner-help-flow > span {
  align-self: center;
  color: var(--accent);
  font-size: 1.1rem;
  font-weight: 800;
}

.explainer-steps,
.season-planner-page .schedule-help-grid {
  display: grid;
  grid-template-columns: repeat(2, minmax(0, 1fr));
  gap: 10px;
}

.explainer-steps section,
.season-planner-page .schedule-help-grid section {
  display: flex;
  gap: 12px;
  padding: 16px;
  border: 1px solid var(--border);
  border-radius: 13px;
  background: var(--surface-subtle);
}

.explainer-steps p,
.season-planner-page .schedule-help-grid p,
.explainer-columns p,
.season-planner-page .planner-help-columns p {
  margin: 5px 0 0;
  color: var(--muted);
  font-size: .75rem;
  line-height: 1.55;
}

/* Bei ungerader Kachelzahl fuellt die letzte die Reihe, sonst bleibt daneben
   eine leere Haelfte stehen. */
.explainer-steps section:last-child:nth-child(odd),
.season-planner-page .planner-help-steps section:last-child:nth-child(odd) {
  grid-column: 1 / -1;
}

/* Verzeichnis der Buttons: Der Name allein erklaert nicht, was ein Klick
   auslöst – erst recht nicht bei „Übernehmen" gegenüber „Veröffentlichen". */
.explainer-actions,
.season-planner-page .planner-help-actions {
  margin-top: 16px;
  padding: 16px 17px;
  border: 1px solid var(--border);
  border-radius: 13px;
  background: var(--surface-subtle);
}

.explainer-actions dl,
.season-planner-page .planner-help-actions dl {
  display: grid;
  gap: 10px;
  margin: 10px 0 0;
}

.explainer-actions dt,
.season-planner-page .planner-help-actions dt {
  color: var(--text);
  font-size: .8rem;
  font-weight: 700;
}

.explainer-actions dd,
.season-planner-page .planner-help-actions dd {
  margin: 3px 0 0;
  color: var(--muted);
  font-size: .75rem;
  line-height: 1.55;
}

.explainer-number,
.season-planner-page .schedule-help-number {
  display: grid;
  place-items: center;
  flex: 0 0 30px;
  width: 30px;
  height: 30px;
  border-radius: 50%;
  background: var(--accent);
  color: var(--text-on-dark);
  font-size: .75rem;
  font-weight: 800;
}

.explainer-columns,
.season-planner-page .planner-help-columns {
  display: grid;
  grid-template-columns: repeat(2, minmax(0, 1fr));
  gap: 10px;
  margin-top: 16px;
}

.explainer-columns section,
.season-planner-page .planner-help-columns section {
  padding: 16px;
  border-left: 3px solid var(--accent);
  border-radius: 0 12px 12px 0;
  background: var(--surface-subtle);
}

.explainer-columns strong,
.season-planner-page .planner-help-columns strong {
  display: block;
  margin-top: 5px;
}

.explainer-callout,
.season-planner-page .schedule-help-callout {
  margin-top: 16px;
  padding: 15px 17px;
  border: 1px solid color-mix(in srgb, var(--caution) 36%, var(--border));
  border-radius: 12px;
  background: color-mix(in srgb, var(--caution) 8%, var(--surface-raised));
  color: var(--muted);
  font-size: .75rem;
  line-height: 1.55;
}

.explainer-callout > strong,
.season-planner-page .schedule-help-callout > strong {
  display: block;
  margin-bottom: 5px;
  color: var(--text);
}

.explainer-callout > span,
.season-planner-page .schedule-help-callout > span {
  display: block;
  margin-top: 8px;
}

.explainer-callout ul,
.season-planner-page .schedule-help-callout ul {
  margin: 4px 0 8px;
  padding-left: 20px;
}

.season-planner-page .planner-modal-secondary-action {
  display: flex;
  justify-content: flex-end;
  gap: 8px;
  flex-wrap: wrap;
  margin-top: 12px;
  padding-top: 12px;
  border-top: 1px solid var(--border);
}

/* Ob die Regeln noch eingreifen, entscheidet ueber jede weitere Handlung im Plan –
   das gehoert in den Kopf, nicht in einen Dialog. */
.season-planner-page .planner-rules-state {
  margin: 8px 0 0;
  color: var(--muted);
  font-size: .78rem;
  line-height: 1.5;
}

.season-planner-page .planner-rules-state strong {
  color: var(--text);
}

.season-planner-page .planner-rules-state.is-released strong {
  color: color-mix(in srgb, var(--caution) 72%, var(--text));
}

@media (max-width: 980px) {
  .season-planner-page .planner-impact-grid {
    grid-template-columns: repeat(3, minmax(0, 1fr));
  }
}

@media (max-width: 720px) {
  .season-planner-page .planner-overview-card .card-title-row,
  .season-planner-page .planner-plan-hero,
  .season-planner-page .planner-publish-row {
    align-items: stretch;
    grid-template-columns: 1fr;
    flex-direction: column;
  }

  .season-planner-page .planner-overview-card .card-title-row .btn,
  .season-planner-page .planner-plan-hero-actions .btn,
  .season-planner-page .planner-publish-row .inline-actions {
    width: 100%;
  }

  .season-planner-page .planner-plan-card {
    grid-template-columns: 1fr;
    gap: 10px;
    padding: 18px 18px 18px 28px;
  }

  .season-planner-page .planner-plan-origin {
    flex-direction: row;
    align-items: center;
    text-align: left;
  }

  .season-planner-page .planner-plan-hero-actions {
    justify-content: stretch;
  }

  .season-planner-page .planner-band-header-tools {
    width: 100%;
    justify-content: space-between;
  }

  .season-planner-page .planner-band-week {
    width: 116px;
  }

  .season-planner-page .planner-match-rule {
    grid-template-columns: 58px minmax(0, 1fr);
  }

  .season-planner-page .planner-match-rule-actions {
    grid-column: 1 / -1;
    justify-content: stretch;
  }

  .season-planner-page .planner-match-rule-actions :is(button, form) {
    flex: 1;
  }

  .season-planner-page .planner-match-rule-actions button {
    width: 100%;
  }

  .season-planner-page .planner-impact-grid,
  .season-planner-page .planner-archive-facts,
  .resource-schedule-page .planner-archive-facts {
    grid-template-columns: repeat(2, minmax(0, 1fr));
  }

  .season-planner-page .planner-overview-actions,
  .season-planner-page .planner-overview-actions > :is(a, button),
  .season-planner-page .planner-plan-hero-actions form,
  .season-planner-page .planner-plan-hero-actions form > button {
    width: 100%;
  }

  .season-planner-page .planner-publish-bar {
    align-items: stretch;
    flex-direction: column;
  }

  .season-planner-page .planner-publish-bar > .inline-actions {
    margin-left: 0;
  }

  .season-planner-page .planner-publish-row .inline-actions {
    display: grid;
    grid-template-columns: 1fr;
  }

  .season-planner-page .planner-publish-row form,
  .season-planner-page .planner-publish-row button {
    width: 100%;
  }

  .season-planner-page .planner-preview-action form {
    justify-items: stretch;
  }

  .season-planner-page .planner-preview-action-hint {
    max-width: none;
    text-align: left;
  }

  .season-planner-page .planner-release-block,
  .season-planner-page .planner-step-next {
    align-items: stretch;
    flex-direction: column;
  }

  .season-planner-page .planner-release-action {
    justify-items: stretch;
  }

  .season-planner-page .planner-release-action .btn {
    width: 100%;
  }

  .season-planner-page .planner-release-blocked {
    max-width: none;
    text-align: left;
  }

  .season-planner-page .planner-steps .planner-step-label small {
    display: none;
  }

  .season-planner-page .planner-form-modal {
    width: calc(100vw - 16px);
    max-height: calc(100dvh - 16px);
    padding: 20px 16px;
  }

  .season-planner-page .planner-form-section {
    padding: 15px;
  }

  .season-planner-page .planner-form-modal .grid-2,
  .season-planner-page .planner-resource-options--inline,
  .explainer-steps,
  .season-planner-page .schedule-help-grid,
  .explainer-columns,
  .season-planner-page .planner-help-columns {
    grid-template-columns: 1fr;
  }

  .explainer-flow,
  .season-planner-page .planner-help-flow {
    align-items: stretch;
    flex-direction: column;
  }

  .explainer-flow > span,
  .season-planner-page .planner-help-flow > span {
    transform: rotate(90deg);
    text-align: center;
  }

  .season-planner-page .planner-week-filter {
    align-items: stretch;
    flex-direction: column;
  }

  .season-planner-page .planner-week-filter .btn {
    width: 100%;
  }

  .season-planner-page .planner-exception-row {
    grid-template-columns: 72px minmax(0, 1fr);
  }

  .season-planner-page .planner-exception-row form {
    grid-column: 1 / -1;
  }

  .season-planner-page .planner-exception-row button {
    width: 100%;
  }

  .season-planner-page .planner-exception-panel {
    grid-template-columns: 1fr;
  }

  .season-planner-page .planner-draft-conflict {
    grid-template-columns: 34px minmax(0, 1fr);
  }

  .season-planner-page .planner-draft-conflict .btn {
    grid-column: 1 / -1;
    width: 100%;
  }
}

@media (prefers-reduced-motion: reduce) {
  .season-planner-page :is(.planner-plan-card, .planner-band-week) { transition: none; }
}

html[data-theme="dark"] {
  --bg: #0b1118;
  --bg-soft: #101922;
  --card: #15202a;
  --text: #f2f5f7;
  --fg: #f2f5f7;
  --muted: #97a4b0;
  --accent: #ed3449;
  --accent-2: #ff5364;
  --warning: #d78a28;
  --warning-2: #eda13f;
  --border: #2a3743;
  --input: #0e171f;
  --surface-raised: #15202a;
  --surface-subtle: #101922;
  --surface-pressed: #202d38;
  --text-on-dark: #f7f8f9;
  --muted-on-dark: #aab6c1;
  --danger: #ff6474;
  --success: #64d49a;
  --caution: #efb757;
  --info: #8b94ff;
  --focus-ring: rgba(237, 52, 73, .24);
  --shadow: 0 26px 80px rgba(0, 0, 0, .42);
  --shadow-soft: 0 10px 34px rgba(0, 0, 0, .24);
  --hero: #111b25;
  --drawer: #101922;
}

html[data-theme] {
  background: var(--bg);
  /* Compatibility aliases for older domain-local styles during the rollout. */
  --border-color: var(--border);
  --muted-color: var(--muted);
  --card-bg: var(--card);
  --input-bg: var(--input);
  --text-color: var(--text);
  --hover-bg: color-mix(in srgb, var(--accent) 6%, var(--surface-raised));
}

.redesign-page,
.login-page {
  min-height: 100vh;
  min-height: 100svh;
  background: var(--bg);
  background-image: none;
  color: var(--text);
  font-family: "Sora", "Avenir Next", sans-serif;
  font-size: 14px;
  letter-spacing: -.01em;
  transition: background-color .25s ease, color .25s ease;
}

.redesign-page::before,
.redesign-page::after,
.login-page::before,
.login-page::after {
  display: none;
}

.redesign-page * {
  scrollbar-color: var(--border) transparent;
}

.redesign-page a,
.login-page a {
  color: var(--accent);
}

.redesign-page .container {
  width: 100%;
  max-width: none;
  margin: 0 auto;
  padding: max(18px, env(safe-area-inset-top)) max(clamp(20px, 2.4vw, 52px), env(safe-area-inset-right)) max(52px, calc(env(safe-area-inset-bottom) + 28px)) max(clamp(20px, 2.4vw, 52px), env(safe-area-inset-left));
}

.redesign-page :focus-visible,
.login-page :focus-visible {
  outline: 3px solid var(--focus-ring);
  outline-offset: 2px;
}

.redesign-page .card,
.redesign-page .db-card {
  background: var(--card);
  border: 1px solid var(--border);
  border-radius: 18px;
  box-shadow: var(--shadow-soft);
}

/* Ankreuz- und Radiofelder sind ausgenommen: Feldhoehe, Innenabstand, Rahmen und
   Radius machen aus einem Kaestchen sonst eine grosse abgerundete Box. Genau das ist
   ueber Jahre in jeder betroffenen Liste einzeln mit !important zurueckgesetzt worden
   (Rechnungen, Belege, Tickets, Kalender, Wettbewerbsliste ...) - der Ausschluss steht
   deshalb hier an der Quelle. Die naechste Regel schliesst dieselben Typen bereits aus. */
.redesign-page input:not([type="checkbox"]):not([type="radio"]):not([type="range"]),
.redesign-page select,
.redesign-page textarea,
.login-page input:not([type="checkbox"]):not([type="radio"]):not([type="range"]),
.login-page select,
.login-page textarea {
  min-height: 40px;
  padding: 7px 11px;
  border: 1px solid var(--border);
  border-radius: 11px;
  background: var(--input);
  color: var(--text);
  font-family: "Sora", "Avenir Next", sans-serif;
  font-size: 14px;
  box-shadow: none;
}

.redesign-page input:not([type="checkbox"]):not([type="radio"]):not([type="file"]):not([type="range"]):not([type="color"]),
.redesign-page select,
.login-page input:not([type="checkbox"]):not([type="radio"]):not([type="file"]):not([type="range"]):not([type="color"]),
.login-page select {
  height: 40px;
}

/* Ein Auswahlfeld, das als offene Trefferliste dient, braucht seine
   tatsaechliche Hoehe statt der einzeiligen Feldhoehe. */
.redesign-page select.is-open-list {
  height: auto;
  margin-top: 6px;
  padding: 4px;
}

.redesign-page select.is-open-list option {
  padding: 7px 9px;
  border-radius: 7px;
}

.redesign-page input:focus,
.redesign-page select:focus,
.redesign-page textarea:focus,
.login-page input:focus,
.login-page select:focus,
.login-page textarea:focus {
  border-color: var(--accent);
  box-shadow: 0 0 0 4px var(--focus-ring);
}

/* Langer Text in fester Zweizeilenhoehe: der Text bricht um, was darueber hinausgeht,
   scrollt innerhalb des Feldes. Alle Tabellenzeilen bleiben dadurch gleich hoch.
   .purpose-cell ist die Anzeige (Verwendungszweck, Notiz in Buchungslisten),
   .text-scroll-field das bearbeitbare Gegenstueck (Notizen in Planung und Altdaten).
   Beide teilen dieselbe Textzeilenhoehe, damit Lesen und Bearbeiten gleich aussehen. */
.redesign-page .purpose-cell {
  max-height: 2.8em;
  overflow-y: auto;
  white-space: normal;
  text-align: left;
  border: 1px solid transparent;
  border-radius: 5px;
  padding: 4px 6px;
  margin: -4px -6px;
}

.redesign-page .purpose-cell:hover {
  background: var(--input);
  border-color: var(--border);
}

.redesign-page textarea.text-scroll-field {
  display: block;
  width: 100%;
  /* Zwei Zeilen zu je 1.4 plus Innenabstand und Rahmen - fest, damit ein langer Text die
     Zeile nicht aufzieht. */
  height: calc(2.8em + 14px + 2px);
  line-height: 1.4;
  overflow-y: auto;
  resize: none;
}

/* Geldbeträge: Vorzeichenwechsel als ruhiger Suffix im Eingabefeld. */
.redesign-page .amount-input-wrap {
  position: relative;
}

.redesign-page .amount-input-wrap .amount-input {
  padding-right: 46px;
}

.redesign-page .amount-input-wrap .amount-sign-toggle {
  position: absolute;
  top: 50%;
  right: 4px;
  display: grid;
  width: 32px;
  min-width: 32px;
  height: 32px;
  min-height: 32px;
  padding: 0;
  transform: translateY(-50%);
  place-items: center;
  border: 1px solid var(--border);
  border-radius: 8px;
  background: var(--surface-pressed);
  box-shadow: none;
  color: var(--muted);
  font-family: "Sora", sans-serif;
  font-size: 15px;
  font-weight: 800;
  line-height: 1;
}

.redesign-page .amount-input-wrap .amount-sign-toggle:hover,
.redesign-page .amount-input-wrap .amount-sign-toggle:focus-visible {
  transform: translateY(-50%);
  border-color: color-mix(in srgb, var(--accent) 58%, var(--border));
  background: color-mix(in srgb, var(--accent) 10%, var(--surface-pressed));
  color: var(--accent);
  box-shadow: 0 0 0 3px color-mix(in srgb, var(--accent) 14%, transparent);
}

.redesign-page .amount-input-wrap .amount-sign-toggle:active {
  transform: translateY(-50%) scale(.96);
}

.redesign-page .amount-input-wrap .amount-sign-toggle:disabled {
  border-color: var(--border);
  background: var(--surface-subtle);
  color: var(--muted);
  opacity: .48;
  cursor: not-allowed;
}

.redesign-page .field label,
.login-page .field label {
  margin-bottom: 8px;
  color: var(--muted);
  font-size: 10px;
  font-weight: 700;
  letter-spacing: .13em;
}

/* Nur die Feldbeschriftung selbst wird zum Block – verschachtelte Labels (etwa um ein
   Ankreuzfeld) bleiben in der Zeile, sonst reisst es jede Optionsliste auseinander. */
.redesign-page .field > label,
.login-page .field > label {
  display: block;
}

/* Erklaerung unter dem Feld – so schreibt es das Designsystem vor, und dort trennt sie
   nicht Beschriftung und Eingabe voneinander. Ohne eigene Regel klebte sie am Rand des
   Eingabefelds und wirkte wie abgeschnittener Text. */
.redesign-page .field > small,
.login-page .field > small {
  display: block;
  margin-top: 6px;
  color: var(--muted);
  font-size: 11px;
  line-height: 1.45;
}

/* Steht die Erklaerung ausnahmsweise ueber dem Feld (etwa als Pflichthinweis), braucht
   sie den Abstand nach unten statt nach oben. */
.redesign-page .field > small + :is(input, select, textarea),
.login-page .field > small + :is(input, select, textarea) {
  margin-top: 6px;
}

.redesign-page button,
.redesign-page .btn,
.login-page button,
.login-page .btn {
  min-height: 44px;
  padding: 10px 16px;
  border-radius: 10px;
  font-family: "Sora", "Avenir Next", sans-serif;
  font-size: 13px;
  font-weight: 650;
  box-shadow: none;
}

.redesign-page button:hover,
.redesign-page .btn:hover,
.login-page button:hover,
.login-page .btn:hover {
  box-shadow: none;
  transform: translateY(-1px);
}

.redesign-page .btn:not(.secondary):not(.danger):not(.warning):not(.ghost),
.login-page .btn:not(.secondary):not(.danger):not(.warning):not(.ghost) {
  color: #fff;
  border-color: var(--accent);
  background: var(--accent);
}

.redesign-page .btn:not(.secondary):not(.danger):not(.warning):not(.ghost):hover,
.login-page .btn:not(.secondary):not(.danger):not(.warning):not(.ghost):hover {
  color: #fff;
  border-color: var(--accent-2);
  background: var(--accent-2);
}

.redesign-page .btn:disabled:not(.secondary):not(.danger):not(.warning):not(.ghost),
.redesign-page .btn[aria-disabled="true"]:not(.secondary):not(.danger):not(.warning):not(.ghost),
.login-page .btn:disabled:not(.secondary):not(.danger):not(.warning):not(.ghost),
.login-page .btn[aria-disabled="true"]:not(.secondary):not(.danger):not(.warning):not(.ghost) {
  opacity: 1;
  color: var(--muted);
  border-color: var(--border);
  background: var(--surface-pressed);
}

.redesign-page button.secondary,
.redesign-page .btn.secondary,
.login-page button.secondary,
.login-page .btn.secondary {
  background: var(--surface-subtle);
  border-color: var(--border);
  color: var(--text);
}

.redesign-page .btn.danger,
.redesign-page button.danger {
  background: color-mix(in srgb, var(--danger) 11%, var(--surface-raised));
  border-color: color-mix(in srgb, var(--danger) 58%, var(--border));
  color: var(--danger);
}

.redesign-page .btn.warning,
.redesign-page button.warning {
  background: color-mix(in srgb, var(--caution) 12%, var(--surface-raised));
  border-color: color-mix(in srgb, var(--caution) 56%, var(--border));
  color: var(--caution);
}

.redesign-page .btn.ghost,
.redesign-page button.ghost {
  background: transparent;
  border-color: var(--border);
  color: var(--muted);
}

.redesign-page input.readonly,
.redesign-page input[readonly] {
  background: var(--surface-subtle);
  color: var(--text);
}

.redesign-page .msg,
.login-page .msg {
  border-radius: 12px;
  padding: 12px 14px;
  box-shadow: none;
}

/* Statusfarben appweit aus einer Familie. Die alten Werte waren helle
   Pastelltöne für das dunkle Theme und im hellen Theme kaum lesbar. Fläche,
   Rahmen und Text kommen jetzt durchgehend aus denselben Tokens. */
.redesign-page .msg.success {
  border-color: var(--success);
  background: color-mix(in srgb, var(--success) 12%, var(--card));
  color: var(--success);
}

.redesign-page .msg.error {
  border-color: var(--danger);
  background: color-mix(in srgb, var(--danger) 12%, var(--card));
  color: var(--danger);
}

.redesign-page .msg.warning {
  border-color: var(--caution);
  background: color-mix(in srgb, var(--caution) 13%, var(--card));
  color: var(--caution);
}

.redesign-page :is(.badge.green, .badge-green, .badge-success) {
  border-color: color-mix(in srgb, var(--success) 38%, var(--border));
  background: color-mix(in srgb, var(--success) 12%, var(--surface-raised));
  color: var(--success);
}

.redesign-page :is(.badge.muted, .badge-gray, .badge-neutral) {
  border-color: var(--border);
  background: var(--surface-subtle);
  color: var(--muted);
}

.redesign-page :is(.badge-warning, .badge-pending) {
  border-color: color-mix(in srgb, var(--caution) 40%, var(--border));
  background: color-mix(in srgb, var(--caution) 13%, var(--surface-raised));
  color: var(--caution);
}

.redesign-page .badge-danger {
  border-color: color-mix(in srgb, var(--danger) 38%, var(--border));
  background: color-mix(in srgb, var(--danger) 12%, var(--surface-raised));
  color: var(--danger);
}

.redesign-page :is(.badge-mandatory, .tag) {
  border-color: color-mix(in srgb, var(--accent) 38%, var(--border));
  background: color-mix(in srgb, var(--accent) 11%, var(--surface-raised));
  color: var(--accent);
}

.redesign-page .tag.danger {
  border-color: color-mix(in srgb, var(--danger) 40%, var(--border));
  background: color-mix(in srgb, var(--danger) 12%, var(--surface-raised));
  color: var(--danger);
}

.redesign-page :is(.text-success, .status-active) {
  color: var(--success);
}

.redesign-page :is(.text-warning, .status-expired) {
  color: var(--caution);
}

.redesign-page :is(.text-danger, .field-error, .status-invalidated) {
  color: var(--danger);
}

.redesign-page .required {
  color: var(--accent);
}

/* Shared theme selector */
.redesign-page .theme-segmented-control,
.login-page .theme-segmented-control {
  display: grid;
  grid-template-columns: repeat(3, minmax(0, 1fr));
  gap: 3px;
  padding: 3px;
  border: 1px solid var(--border);
  border-radius: 12px;
  background: var(--surface-subtle);
}

.redesign-page .theme-option,
.login-page .theme-option {
  display: inline-flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  gap: 4px;
  min-width: 0;
  min-height: 48px;
  padding: 5px 7px;
  border: 0;
  border-radius: 8px;
  background: transparent;
  color: var(--muted);
  font-size: 10px;
  font-weight: 600;
}

.redesign-page .theme-option svg,
.login-page .theme-option svg {
  width: 17px;
  height: 17px;
  fill: none;
  stroke: currentColor;
  stroke-linecap: round;
  stroke-linejoin: round;
  stroke-width: 1.5;
}

.redesign-page .theme-option.is-selected,
.login-page .theme-option.is-selected {
  background: var(--surface-raised);
  color: var(--accent);
  box-shadow: 0 2px 8px rgba(0, 0, 0, .08);
}

.redesign-page .ui-scale-segmented-control {
  background: var(--surface-subtle);
}

.redesign-page .ui-scale-option {
  font-family: "Sora", sans-serif;
}

.redesign-page .ui-scale-option.is-selected {
  background: var(--surface-raised);
  color: var(--accent);
  box-shadow: 0 2px 8px rgba(0, 0, 0, .08);
}

/* Tabellenlayout in derselben Sprache wie Darstellung und Ansichtsgröße –
   zwei Segmente statt drei, sonst identisch aufgebaut. */
.redesign-page .table-layout-segmented-control {
  display: grid;
  grid-template-columns: repeat(2, minmax(0, 1fr));
  gap: 4px;
  padding: 4px;
  border: 1px solid var(--border);
  border-radius: 12px;
  background: var(--surface-subtle);
}

.redesign-page .table-layout-option {
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  gap: 2px;
  min-width: 0;
  min-height: 48px;
  padding: 5px 6px;
  border: 0;
  border-radius: 8px;
  background: transparent;
  box-shadow: none;
  color: var(--muted);
  font-family: "Sora", sans-serif;
  text-align: center;
}

.redesign-page .table-layout-option strong {
  color: inherit;
  font-size: 12px;
}

.redesign-page .table-layout-option span {
  font-size: 9px;
  font-weight: 600;
  line-height: 1.3;
}

.redesign-page .table-layout-option.is-selected {
  background: var(--surface-raised);
  color: var(--accent);
  box-shadow: 0 2px 8px rgba(0, 0, 0, .08);
}

/* App header */
.redesign-page .v2-app-header {
  display: grid;
  grid-template-columns: 1fr auto 1fr;
  align-items: center;
  min-height: 76px;
  margin: 0 0 22px;
  padding: 0 2px 16px;
  border-bottom: 1px solid var(--border);
}

.redesign-page .v2-app-header .nav-drawer-trigger {
  grid-column: 1;
  justify-self: start;
  width: 44px;
  height: 44px;
  min-height: 44px;
  border-radius: 12px;
  background: var(--surface-raised);
  border-color: var(--border);
}

/* Bewusst ohne Header-Kontext: Der Ticket-Scanner setzt den Menüzugang ohne
   v2-app-header direkt auf die Seite. Hing die Größe am Header, blieb das
   Symbol dort auf seiner Rohgröße und war praktisch unsichtbar.
   Mindestmaße und Strichfarbe stehen zusätzlich fest, damit das Symbol auch
   dann erscheint, wenn eine Seite eigene Regeln für Schalter mitbringt. */
.redesign-page .nav-drawer-trigger {
  color: var(--text);
}

.redesign-page .nav-drawer-trigger-icon {
  flex: 0 0 auto;
  width: 19px;
  min-width: 19px;
  height: 19px;
  min-height: 19px;
  stroke: currentColor;
}

.redesign-page .v2-app-header .brand {
  grid-column: 2;
  justify-self: center;
  gap: 13px;
  min-width: 0;
}

/* Ohne min-width:0 schrumpft der Textblock nicht unter die Breite der
   laengsten unumbrochenen Zeile. Der Untertitel sprengte dadurch die
   Markenbreite und lief mobil aus dem Bild, statt zu kuerzen. */
.redesign-page .v2-app-header .brand > div {
  width: auto;
  min-width: 0;
  overflow: hidden;
}

.redesign-page .v2-app-header .logo {
  width: 47px;
  height: 57px;
  object-fit: contain;
  filter: drop-shadow(0 5px 10px rgba(0, 0, 0, .12));
}

.redesign-page .v2-app-header .brand-title {
  font-size: 19px;
  font-weight: 700;
  letter-spacing: -.025em;
}

.redesign-page .v2-app-header .page-title {
  margin-top: 3px;
  color: var(--text);
  font-size: 13px;
  font-weight: 600;
}

.redesign-page .v2-app-header .subtitle {
  margin-top: 3px;
  color: var(--muted);
  font-size: 10px;
  letter-spacing: .12em;
}

.redesign-page .v2-app-header > .actions {
  grid-column: 3;
  justify-self: end;
  width: auto;
}

/* Drawer — mechanics remain in app.css, this is the new skin. */
.redesign-page .nav-drawer {
  width: min(380px, 92vw);
  background: var(--drawer);
  border-right-color: var(--border);
  box-shadow: 28px 0 90px rgba(0, 0, 0, .28);
}

.redesign-page .nav-drawer-backdrop {
  background: rgba(5, 10, 15, .58);
  backdrop-filter: blur(4px);
}

/* Mitlaufender Tabellenkopf – gilt für jede Redesign-Seite, nicht nur für
   einzelne Bereiche. Zwei Flächen sind dafür nötig, beide waren transparent
   gestellt und haben den Kopf deshalb überall „durchsichtig" gemacht:
   - Die Maske füllt den Streifen oberhalb des Kopfes, auf dem Handy also die
     Zone der Statusleiste. Ohne sie laufen Tabellenzeilen sichtbar dahinter.
   - Der Kopfcontainer füllt die ganze Kartenbreite. Ist die Tabelle breiter als
     der Bildschirm, blieb sonst rechts neben der letzten Spalte ein Streifen,
     durch den die Zeilen liefen. */
.redesign-page .sticky-table-head-mask {
  z-index: 800;
  background: var(--bg);
}

.redesign-page .sticky-table-head {
  top: env(safe-area-inset-top);
  border: 0;
  border-radius: 0;
  background: var(--surface-subtle);
  box-shadow: 0 1px 0 var(--border);
}

/* Beide Ausschnitte tragen dieselbe Fläche wie die Kopfzellen. Transparent
   gestellt blieben zwischen der fixierten ersten Spalte und dem scrollenden
   Rest sowie an den Rändern Lücken, durch die die Tabellenzeilen liefen. */
.content-page .sticky-table-head-scroll,
.content-page .sticky-table-head-first {
  border-radius: 0;
  background: var(--surface-subtle);
}

.content-page .sticky-table-head-first,
.content-page .sticky-table-head th,
.content-page .sticky-table-head th:first-child {
  color: var(--muted);
  border-radius: 0 !important;
  background: var(--surface-subtle);
  box-shadow: 0 1px 0 var(--border);
}

/* Der Ausschnitt der ersten Spalte braucht beide Linien: rechts die
   Spaltentrennung, unten den Abschluss zur Tabelle. Mit nur einem Schatten
   fehlte unter der ersten Spalte die Unterkante, während sie rechts daneben
   durchlief. */
.content-page .sticky-table-head-first {
  box-shadow: 1px 0 0 var(--border), 0 1px 0 var(--border);
}

.redesign-page .nav-drawer-head {
  padding: max(18px, env(safe-area-inset-top)) 18px 15px;
  background: var(--drawer);
}

.redesign-page .nav-drawer-head-row {
  gap: 14px;
  margin-bottom: 15px;
}

.redesign-page .nav-drawer-brand {
  gap: 10px;
  color: var(--text);
}

.redesign-page .nav-drawer-brand:hover {
  color: var(--text);
}

.redesign-page .nav-drawer-brand-logo {
  width: 34px;
  height: 42px;
}

.redesign-page .nav-drawer-title {
  font-family: "Sora", sans-serif;
  font-size: 15px;
  font-weight: 700;
  letter-spacing: -.03em;
}

.redesign-page .nav-drawer-team {
  margin-top: 3px;
  font-size: 9px;
  letter-spacing: .12em;
}

.redesign-page .nav-drawer-head-actions .btn.account-menu-trigger,
.redesign-page .nav-drawer-close {
  width: 38px;
  height: 38px;
  min-width: 38px;
  min-height: 38px;
  border-radius: 10px;
  background: var(--surface-raised);
  color: var(--muted);
}

.redesign-page .nav-drawer-head .account-menu-panel {
  top: calc(100% + 1px);
  left: 12px;
  right: 12px;
  max-height: calc(100svh - max(88px, env(safe-area-inset-top)));
  overflow-y: auto;
  padding: 14px;
  border-radius: 16px;
  background: var(--surface-raised);
  box-shadow: var(--shadow);
}

.redesign-page .nav-drawer-search input {
  min-height: 44px;
  padding-left: 40px;
  border-radius: 12px;
  background-color: var(--input);
  background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='18' height='18' viewBox='0 0 20 20' fill='none' stroke='%23808b96' stroke-width='1.6'%3E%3Ccircle cx='8.5' cy='8.5' r='5.5'/%3E%3Cpath d='m13 13 4 4'/%3E%3C/svg%3E");
  background-repeat: no-repeat;
  background-position: 13px center;
}

.redesign-page .drawer-settings-section {
  padding-top: 13px;
  border-top-color: var(--border);
}

.redesign-page .drawer-settings-kicker,
.redesign-page .account-menu-section-kicker {
  color: var(--muted);
  font-size: 9px;
  font-weight: 700;
  letter-spacing: .14em;
}

.redesign-page .account-menu-section-title {
  font-family: "Barlow Condensed", sans-serif;
  font-size: 26px;
  font-weight: 700;
  letter-spacing: .01em;
}

/* Kontofunktionen sind Ziele, keine Aktionen: gleiche ruhige Fläche wie die
   Segmentleisten darüber, mit Chevron als Hinweis auf die Navigation. Sie
   sollen neben den Umschaltern nicht wie unfertige Knöpfe wirken. */
.redesign-page .drawer-account-links .btn,
.redesign-page .drawer-account-links button,
.redesign-page .view-toggle-btn {
  display: flex;
  align-items: center;
  justify-content: flex-start;
  width: 100%;
  min-height: 46px;
  padding: 11px 13px;
  border: 1px solid var(--border);
  border-radius: 12px;
  background: var(--surface-subtle);
  box-shadow: none;
  color: var(--text);
  font-size: 14px;
  font-weight: 600;
}

.redesign-page .drawer-account-links a.btn::after {
  margin-left: auto;
  color: var(--muted);
  content: "›";
  font-size: 19px;
  line-height: 1;
}

@media (hover: hover) {
  .redesign-page .drawer-account-links .btn:hover,
  .redesign-page .drawer-account-links button:hover {
    border-color: color-mix(in srgb, var(--accent) 42%, var(--border));
    background: color-mix(in srgb, var(--accent) 7%, var(--surface-raised));
    transform: none;
  }

  .redesign-page .drawer-account-links a.btn:hover::after {
    color: var(--accent);
  }
}

/* Abmelden verlässt den Bereich – räumlich abgesetzt und als solche benannt. */
.redesign-page .drawer-account-links form {
  margin-top: 4px;
  padding-top: 10px;
  border-top: 1px solid var(--border);
}

.redesign-page .drawer-account-links form button {
  justify-content: center;
  border-color: color-mix(in srgb, var(--danger) 30%, var(--border));
  background: color-mix(in srgb, var(--danger) 8%, var(--surface-raised));
  color: var(--danger);
}

@media (hover: hover) {
  .redesign-page .drawer-account-links form button:hover {
    border-color: color-mix(in srgb, var(--danger) 48%, var(--border));
    background: color-mix(in srgb, var(--danger) 14%, var(--surface-raised));
    color: var(--danger);
  }
}

.redesign-page .nav-drawer-body {
  padding: 13px 12px max(28px, env(safe-area-inset-bottom));
}

.redesign-page .nav-drawer-groups {
  gap: 22px;
}

.redesign-page .nav-drawer-groups .nav-group {
  overflow: visible;
  border: 0;
  border-radius: 0;
  background: transparent;
  box-shadow: none;
}

.redesign-page .nav-drawer-groups .nav-group-header {
  padding: 0 10px 8px;
  border: 0;
  color: var(--muted);
  font-size: 9px;
  font-weight: 700;
  letter-spacing: .15em;
}

.redesign-page .nav-drawer-groups .nav-group-personal {
  margin: 0 2px;
  padding: 13px 8px 9px;
  border: 1px solid color-mix(in srgb, var(--accent) 26%, var(--border));
  border-radius: 15px;
  background: color-mix(in srgb, var(--accent) 5%, var(--surface-raised));
}

.redesign-page .nav-drawer-groups .nav-group-personal .nav-group-header {
  color: var(--accent);
}

.redesign-page .nav-drawer-groups .nav-item {
  min-height: 44px;
  padding: 11px 10px;
  border: 0;
  border-radius: 9px;
  color: var(--text);
}

.redesign-page .nav-drawer-groups .nav-group-personal .nav-item,
.redesign-page .nav-drawer-groups .nav-item.is-current {
  color: var(--accent);
}

.redesign-page .nav-drawer-groups .nav-group-personal + .nav-group {
  margin-top: 4px;
  padding-top: 25px;
  border-top: 1px solid var(--border);
}

.redesign-page .nav-drawer-groups .nav-item + .nav-item {
  margin-top: 2px;
}

.redesign-page .nav-drawer-groups .nav-item:hover {
  background: var(--surface-subtle);
}

.redesign-page .nav-drawer-groups .nav-item.is-current {
  padding-left: 12px;
  border-left: 3px solid var(--accent);
  border-radius: 3px 9px 9px 3px;
  background: var(--surface-subtle);
}

.redesign-page .nav-item-title {
  font-size: 13px;
  font-weight: 500;
}

/* Shared content pages — one shell for player and account workflows. */
.content-page {
  overflow-x: hidden;
  overflow-x: clip;
  overscroll-behavior-x: none;
}

.content-page .container {
  position: relative;
  z-index: 1;
}

.content-page .card {
  margin-bottom: 14px;
  padding: clamp(18px, 2vw, 28px);
}

.content-page .card-title {
  margin: 0 0 5px;
  color: var(--text);
  font-family: "Barlow Condensed", sans-serif;
  font-size: clamp(25px, 2.2vw, 32px);
  font-weight: 700;
  letter-spacing: -.01em;
  line-height: 1;
}

.content-page .muted {
  color: var(--muted);
}

/* Shared administration shell. Domain-specific layouts can build on these
   surfaces without falling back to the former dark-only palette. */
.admin-content-page .card > :is(h2, h3):first-child,
.admin-content-page .card-title,
.admin-content-page .section-title {
  color: var(--text);
  font-family: "Barlow Condensed", sans-serif;
  font-weight: 700;
  letter-spacing: -.01em;
}

.admin-content-page .card > :is(h2, h3):first-child {
  margin-top: 0;
  font-size: clamp(25px, 2.2vw, 32px);
  line-height: 1;
}

.admin-content-page .nav-groups-grid {
  grid-template-columns: repeat(auto-fit, minmax(min(100%, 280px), 1fr));
  gap: 14px;
}

.admin-content-page .nav-groups-grid > .nav-group {
  position: relative;
  border-color: var(--border);
  border-radius: 18px;
  background: var(--surface-raised);
  box-shadow: var(--shadow-soft);
  overflow: hidden;
}

.admin-content-page .nav-groups-grid > .nav-group::before {
  position: absolute;
  z-index: 2;
  top: 0;
  left: 18px;
  width: 52px;
  height: 3px;
  border-radius: 0 0 999px 999px;
  background: var(--accent);
  content: "";
}

.admin-content-page .nav-groups-grid > .nav-group > .nav-group-header {
  padding: 12px 15px 10px;
  background: var(--surface-subtle);
  color: var(--muted);
  font-size: 10px;
  font-weight: 700;
  letter-spacing: .13em;
}

.admin-content-page .nav-groups-grid > .nav-group > .nav-item {
  min-height: 48px;
  border-top-color: var(--border);
  color: var(--text);
}

@media (hover: hover) {
  .admin-content-page .nav-groups-grid > .nav-group > .nav-item:hover {
    background: color-mix(in srgb, var(--accent) 6%, var(--surface-raised));
    color: var(--text);
  }
}

.admin-content-page :is(.app-modal, .users-modal, .fine-types-modal, .res-picker-modal) {
  background: var(--surface-raised);
  border-color: var(--border);
  color: var(--text);
}

.admin-content-page :is(.settings-row-split, .permission-row, .user-account-action-group, .batch-section) {
  border-color: var(--border);
}

/* Berechtigungszeilen: Die Grundfläche war fest dunkel, während die aktiven
   Zustände nur eine schwach deckende Farbe darüberlegten. Im hellen Theme wurde
   daraus ein schwarzer Block für alles, was nicht gewährt ist. Alle vier
   Zustände kommen jetzt aus derselben Token-Familie. */
.admin-content-page .permission-row {
  background: var(--surface-subtle);
}

.admin-content-page .permission-row.is-mandatory {
  border-color: color-mix(in srgb, var(--accent) 36%, var(--border));
  background: color-mix(in srgb, var(--accent) 9%, var(--surface-raised));
}

.admin-content-page .permission-row.is-active:not(.is-mandatory) {
  border-color: color-mix(in srgb, var(--success) 36%, var(--border));
  background: color-mix(in srgb, var(--success) 10%, var(--surface-raised));
}

.admin-content-page .permission-row.has-revoke:not(.is-mandatory) {
  border-color: color-mix(in srgb, var(--caution) 40%, var(--border));
  background: color-mix(in srgb, var(--caution) 11%, var(--surface-raised));
}

.admin-content-page :is(.user-account-action-group, .batch-section) {
  border-radius: 15px;
  background: var(--surface-subtle);
}

/* Der Konto-Bereich hat bereits abgesetzte Untergruppen. Die aeussere
   Feldflaeche traegt deshalb nur den Rahmen; die alte halbtransparente
   Dunkelflaeche wuerde im hellen Theme als grauer Kasten erscheinen. */
.admin-content-page :is(.user-edit-security-grid, .user-edit-account-grid) > .field {
  border-color: var(--border);
  border-radius: 16px;
  background: transparent;
}

/* Zugangsstatus: lesbarer Kontrast in beiden Themes statt heller Pastelltoene. */
.admin-content-page .user-account-status.is-active {
  color: var(--success);
}

.admin-content-page .user-account-status.is-inactive {
  color: var(--caution);
}

.admin-content-page .user-account-status-badge.is-active {
  border-color: color-mix(in srgb, var(--success) 38%, var(--border));
  background: color-mix(in srgb, var(--success) 11%, var(--surface-raised));
}

.admin-content-page .user-account-status-badge.is-inactive {
  border-color: color-mix(in srgb, var(--caution) 40%, var(--border));
  background: color-mix(in srgb, var(--caution) 12%, var(--surface-raised));
}

/* Tab- und Segmentleisten sind eine zusammenhaengende Flaeche. Die
   AE-Auswahlchips sind dagegen unabhaengige Mehrfachauswahlen und bekommen
   deshalb keine gemeinsame Hintergrundflaeche hinter sich gelegt. */
.admin-content-page :is(.tab-bar, .view-toggle) {
  border-color: var(--border);
  border-radius: 13px;
  background: var(--surface-subtle);
}

.admin-content-page .ae-type-toggle-group {
  border: 0;
  border-radius: 0;
  background: transparent;
}

.admin-content-page :is(.tab-btn, .view-toggle a, .ae-type-toggle) {
  color: var(--muted);
}

.admin-content-page :is(.tab-btn.active, .view-toggle a.active, .ae-type-toggle.active) {
  border-color: var(--border);
  background: var(--surface-raised);
  color: var(--accent);
  box-shadow: var(--shadow-soft);
}

/* Neue Strafe: eine Kartenfläche, Trennung durch Linien und Abstände. */
.fine-entry-page .tab-bar {
  display: inline-flex;
  width: fit-content;
  max-width: 100%;
  padding: 4px;
  gap: 4px;
  background: var(--surface-subtle);
}

.fine-entry-page .tab-btn {
  border-color: transparent;
  background: transparent;
}

.fine-entry-page .tab-btn.active {
  border-color: var(--border);
  background: var(--surface-raised);
}

/* Tab-Leisten auf dem Handy: Auf Inhaltsbreite geschrumpft brechen die Schalter
   untereinander und bilden einen schmalen Block am linken Rand. Sie teilen sich
   deshalb die volle Breite zu gleichen Teilen und bleiben in einer Reihe – zwei
   Schalter je die Haelfte, drei je ein Drittel, vier je ein Viertel. Lange
   Beschriftungen brechen im Schalter um, statt die Leiste zu sprengen.
   Gilt zentral fuer alle Tab-Leisten: Strafeneingabe, Tickets, Zeugwart. */
@media (max-width: 720px) {
  .redesign-page :is(.tab-bar, .eq-section-tabs) {
    display: flex;
    flex-direction: row;
    flex-wrap: nowrap;
    width: 100%;
  }

  /* justify-content zusaetzlich zu text-align: Die Schalter des Zeugwarts sind
     .btn-Elemente und damit Flex-Container – dort richtet text-align allein den
     Beschriftungstext nicht mittig aus. */
  .redesign-page :is(.tab-bar .tab-btn, .eq-section-tabs .btn) {
    flex: 1 1 0;
    min-width: 0;
    justify-content: center;
    height: auto;
    min-height: 40px;
    padding: 9px 5px;
    font-size: 12px;
    line-height: 1.25;
    text-align: center;
    overflow-wrap: anywhere;
  }
}

.fine-entry-page .tab-pane > .card {
  background: var(--surface-raised);
}

.fine-entry-page .batch-section {
  margin-top: 22px;
  padding-top: 18px;
  border: 0;
  border-top: 1px solid var(--border);
  border-radius: 0;
  background: transparent;
}

.fine-entry-page .batch-row {
  padding: 14px;
  background: transparent;
}

.fine-entry-page .batch-title {
  color: var(--text);
  font-family: "Barlow Condensed", sans-serif;
  font-size: 21px;
  font-weight: 700;
}

.fine-entry-page .add-row {
  background: transparent;
}

.fine-entry-page .fine-entry-date-toolbar {
  display: grid;
  grid-template-columns: minmax(0, 1fr) minmax(220px, 300px);
  align-items: end;
  gap: 24px;
  padding: 14px 0 4px;
}

.fine-entry-page .fine-entry-date-copy {
  display: grid;
  gap: 4px;
}

.fine-entry-page .fine-entry-date-copy strong {
  color: var(--text);
  font-family: "Barlow Condensed", sans-serif;
  font-size: 24px;
  line-height: 1;
}

.fine-entry-page .fine-entry-date-copy > span:last-child {
  color: var(--muted);
  font-size: 12px;
}

.fine-entry-page .fine-entry-date-field {
  margin: 0;
}

/* Strafenkatalog: lesen in der Liste, bearbeiten im fokussierten Detaildialog. */
.fine-type-catalog-page .admin-fine-types-table :is(th, td):last-child {
  width: 48px;
  min-width: 48px;
  padding-right: 14px;
  text-align: center;
}

.fine-type-catalog-page .fine-type-catalog-row.is-clickable {
  cursor: pointer;
}

.fine-type-catalog-page .fine-type-catalog-name {
  font-weight: 650;
}

.fine-type-catalog-page .fine-type-catalog-amount {
  font-variant-numeric: tabular-nums;
  white-space: nowrap;
}

.fine-type-catalog-page .fine-type-mode-badge {
  display: inline-flex;
  align-items: center;
  min-height: 26px;
  padding: 4px 9px;
  border: 1px solid var(--border);
  border-radius: 999px;
  background: var(--surface-subtle);
  color: var(--muted);
  font-size: 11px;
  font-weight: 650;
}

.fine-type-catalog-page .fine-type-mode-badge.is-aggregated {
  border-color: color-mix(in srgb, var(--accent) 34%, var(--border));
  background: color-mix(in srgb, var(--accent) 7%, var(--surface-subtle));
  color: var(--accent);
}

@media (hover: hover) {
  .fine-type-catalog-page .admin-fine-types-table .fine-type-catalog-row.is-clickable:hover > td,
  .fine-type-catalog-page .admin-fine-types-table .fine-type-catalog-row.is-clickable:hover > td:first-child {
    background: color-mix(in srgb, var(--accent) 7%, var(--surface-raised));
  }

  .fine-type-catalog-page .fine-type-catalog-row.is-clickable:hover .editable-row-open {
    color: var(--accent);
  }
}

.fine-type-catalog-page .fine-type-catalog-row.is-clickable:focus-visible {
  outline: 2px solid var(--accent);
  outline-offset: -3px;
}

.fine-type-catalog-page .fine-type-detail-modal {
  width: min(780px, 100%);
}

/* Bezeichnungen sind lang, Beträge kurz: Das Namensfeld bekommt den Raum,
   das Betragsfeld nur seine tatsächlich nötige Breite. */
.fine-type-catalog-page .fine-type-detail-grid {
  grid-template-columns: minmax(0, 1fr) 160px;
}

.fine-type-catalog-page .fine-type-detail-mode-field {
  grid-column: 1 / -1;
}

.fine-type-catalog-page .field-help {
  margin-top: 7px;
  color: var(--muted);
  font-size: 11px;
  line-height: 1.45;
}

.fine-type-catalog-page .fine-type-detail-actions .danger {
  margin-right: auto;
}

.admin-content-page :is(.ticketing-table-wrap, .week-grid, .day-layout) {
  border-color: var(--border);
  border-radius: 16px;
  background: var(--surface-raised);
  box-shadow: var(--shadow-soft);
}

.admin-content-page :is(.cfg-dropdown, .recipient-dropdown, .ticket-dropdown, .search-results) {
  border-color: var(--border);
  background: var(--surface-raised);
  color: var(--text);
  box-shadow: var(--shadow-soft);
}

@media (hover: hover) {
  .admin-content-page :is(.cfg-dropdown, .recipient-dropdown, .ticket-dropdown, .search-results) li:hover,
  .admin-content-page .search-result-item:hover {
    background: color-mix(in srgb, var(--accent) 6%, var(--surface-raised));
  }
}

.admin-content-page :is(.bulk-actions-bar, .cfg-detail-box, .release-panel) {
  border-color: var(--border);
  background: var(--surface-subtle);
}

.admin-content-page .auswertung-count strong {
  color: var(--text);
}

.admin-content-page :is(.status-badge-published, .release-offer-badge.consumed) {
  border-color: color-mix(in srgb, var(--success) 44%, var(--border));
  background: color-mix(in srgb, var(--success) 11%, var(--surface-raised));
  color: var(--success);
}

.admin-content-page :is(.status-badge-pending, .release-offer-badge:not(.consumed):not(.draft)) {
  border-color: color-mix(in srgb, var(--caution) 44%, var(--border));
  background: color-mix(in srgb, var(--caution) 11%, var(--surface-raised));
  color: var(--caution);
}

.admin-content-page :is(.app-modal-backdrop, .users-modal-backdrop, .fine-types-modal-backdrop, .res-picker-bg) {
  background: rgba(5, 10, 15, .66);
  backdrop-filter: blur(7px);
  -webkit-backdrop-filter: blur(7px);
}

/* Content-Karten erhalten im Seitengerüst einen unteren Abstand. Modals liegen
   teilweise ebenfalls als .card vor; dort würde dieser Abstand die vertikale
   Zentrierung aufheben. Diese Regel gilt bewusst für alle Redesign-Seiten und
   damit auch für Ticketing-, Physio-, Budget- und fragmentbasierte Dialoge. */
.redesign-page .app-modal {
  margin: auto !important;
}

/* Breiter Dialog fuer Listen, die je Zeile mehr als ein Feld tragen - im Bewertungsdialog
   Regler und Notiz nebeneinander. Bei der Standardbreite von 860px schrumpft die Notiz auf
   eine Briefmarke, und der Regler wird ungenau: er ist nur so fein, wie er lang ist. */
.redesign-page .app-modal.app-modal-wide {
  width: min(1040px, 100%);
}

.admin-content-page :is(.table, .data-table, .resource-table, .ticket-table, .rec-table, .cd-table, .batch-table, .absence-tbl, .week-table, .summary-table) {
  color: var(--text);
  background: transparent;
}

.admin-content-page :is(.table, .data-table, .resource-table, .ticket-table, .rec-table, .cd-table, .batch-table, .absence-tbl, .week-table, .summary-table) thead th {
  background: var(--surface-subtle);
  color: var(--muted);
  border-color: var(--border);
}

.admin-content-page :is(.table, .data-table, .resource-table, .ticket-table, .rec-table, .cd-table, .batch-table, .absence-tbl, .week-table, .summary-table) tbody td {
  background: var(--surface-raised);
  color: var(--text);
  border-color: var(--border);
}

@media (hover: hover) {
  .admin-content-page :is(.table, .data-table, .resource-table, .ticket-table, .rec-table, .cd-table, .batch-table, .absence-tbl, .week-table, .summary-table) tbody tr:hover td {
    background: color-mix(in srgb, var(--accent) 6%, var(--surface-raised));
  }
}

/* Dauerhaft markierte Tabellenzeilen (aktive Saison, aktuelle Woche) sind
   bereits hervorgehoben. Hover darf weder die Fläche verstärken noch die
   erste Spalte als zweiten roten Block einfärben. */
.admin-content-page .table tbody tr.current-week {
  background: transparent;
  box-shadow: none;
}

.admin-content-page .table tbody tr.current-week > td,
.admin-content-page .table tbody tr.current-week > td:first-child,
.admin-content-page .table tbody tr.current-week:hover > td,
.admin-content-page .table tbody tr.current-week:hover > td:first-child {
  background: color-mix(in srgb, var(--accent) 7%, var(--surface-raised)) !important;
}

.admin-content-page .table tbody tr.current-week > td:first-child {
  border-left: 0;
  box-shadow: inset 3px 0 0 var(--accent);
}

/* Tabellen mit bereits markierten Zeilen behalten beim Hover exakt eine
   zusammenhängende Fläche statt einer dunkleren ersten Spalte. */
.duties-page .duties-table tbody tr.current-week {
  background: transparent;
  box-shadow: none;
}

.duties-page .duties-table tbody tr.current-week > td,
.duties-page .duties-table tbody tr.current-week > td:first-child,
.duties-page .duties-table tbody tr.current-week:hover > td,
.duties-page .duties-table tbody tr.current-week:hover > td:first-child {
  background: color-mix(in srgb, var(--accent) 7%, var(--surface-raised)) !important;
}

.duties-page .duties-table tbody tr.current-week > td:first-child {
  border-left: 0;
  box-shadow: inset 3px 0 0 var(--accent);
}

@media (hover: hover) {
  .competition-admin-page .competition-admin-table tbody tr:hover > td,
  .competition-admin-page .competition-admin-table tbody tr:hover > td:first-child {
    background: color-mix(in srgb, var(--accent) 7%, var(--surface-raised)) !important;
  }
}

/* Erreichte Schwellenwerte tragen ihre Farbe auch an der Zeilenkante. Als
   Inset-Schatten statt Rahmen, weil die gemeinsame Tabellenregel jede
   Rahmenfarbe auf --border vereinheitlicht. */
.competition-admin-page .competition-admin-table tbody tr:is(.competition-row-positive, .competition-row-negative) > td:first-child {
  border-left: 0;
}

.competition-admin-page .competition-admin-table tbody tr.competition-row-positive > td:first-child {
  box-shadow: inset 3px 0 0 var(--success);
}

.competition-admin-page .competition-admin-table tbody tr.competition-row-negative > td:first-child {
  box-shadow: inset 3px 0 0 var(--danger);
}

/* Der Ausgleich erscheint nur bei erreichtem Schwellenwert. Sein Platz bleibt
   trotzdem immer reserviert, damit die übrigen Aktionen nicht verrutschen. */
.competition-admin-page .comp-resolve-threshold.is-inactive {
  visibility: hidden;
}

.competition-admin-page .competition-row-positive .comp-resolve-threshold {
  border-color: color-mix(in srgb, var(--success) 52%, var(--border));
  background: color-mix(in srgb, var(--success) 14%, var(--surface-raised));
  color: var(--success);
}

.competition-admin-page .competition-row-negative .comp-resolve-threshold {
  border-color: color-mix(in srgb, var(--danger) 52%, var(--border));
  background: color-mix(in srgb, var(--danger) 14%, var(--surface-raised));
  color: var(--danger);
}

/* Kalender-Einstellungen: Terminarten und Freigabezeilen liegen auf einer
   Karte. `--bg-soft` ist im dunklen Theme dunkler als die Karte, wodurch die
   Felder als Löcher wirkten. Eine symmetrische Mischung hebt sie in beiden
   Themes gleichmäßig von der Kartenfläche ab. */
.admin-content-page :is(.calendar-settings-color-field, .calendar-settings-share-row) {
  border-color: var(--border);
  background: color-mix(in srgb, var(--text) 6%, var(--surface-raised));
}

/* Der "Heute"-Streifen behält Abstand zu den farbigen Slotflächen, damit die
   beiden Markierungen nicht ineinanderlaufen. Das negative Margin wächst
   mit dem Padding mit, sodass der Streifen an seiner Position bleibt. */
.redesign-page .physio-today-row {
  padding-left: 17px;
  margin-left: -20px;
}

/* Einmaliger Hinweis auf das neue Design. Eingangsbewegung wie bei der
   Erinnerung zu fehlenden Kontaktdaten, damit sich beide Dialoge gleich
   anfühlen. */
.redesign-page .redesign-intro-backdrop {
  opacity: 0;
  transition: opacity .25s ease;
}

.redesign-page .redesign-intro-backdrop.is-visible {
  opacity: 1;
}

.redesign-page .redesign-intro-card {
  width: min(560px, 100%);
  transform: translateY(14px) scale(.97);
  transition: transform .25s cubic-bezier(.2, .8, .2, 1);
}

.redesign-page .redesign-intro-backdrop.is-visible .redesign-intro-card {
  transform: translateY(0) scale(1);
}

.redesign-page .redesign-intro-head h3 {
  margin: 3px 0 8px;
}

.redesign-page .redesign-intro-head p {
  margin: 0;
  font-size: 14px;
  line-height: 1.55;
}

.redesign-page .redesign-intro-list {
  display: grid;
  gap: 11px;
  margin: 18px 0;
  padding: 0;
  list-style: none;
}

.redesign-page .redesign-intro-list li {
  display: flex;
  align-items: flex-start;
  gap: 13px;
  padding: 13px 14px;
  border: 1px solid var(--border);
  border-radius: 14px;
  background: var(--surface-subtle);
}

.redesign-page .redesign-intro-icon {
  display: grid;
  width: 36px;
  height: 36px;
  flex: 0 0 auto;
  place-items: center;
  border: 1px solid color-mix(in srgb, var(--accent) 34%, var(--border));
  border-radius: 11px;
  background: color-mix(in srgb, var(--accent) 10%, var(--surface-raised));
  color: var(--accent);
}

.redesign-page .redesign-intro-icon svg {
  width: 19px;
  height: 19px;
}

.redesign-page .redesign-intro-text {
  display: grid;
  gap: 3px;
  min-width: 0;
  color: var(--muted);
  font-size: 13px;
  line-height: 1.45;
}

.redesign-page .redesign-intro-text strong {
  color: var(--text);
  font-size: 14px;
}

/* Der Weg zu den neuen Einstellungen steht abgesetzt: Er ist die eigentliche
   Handlungsanweisung des Dialogs, nicht nur eine Fussnote. Das Zahnrad davor
   ist dasselbe Zeichen wie im Menükopf. */
.redesign-page .redesign-intro-hint {
  display: flex;
  align-items: flex-start;
  gap: 10px;
  margin: 0 0 18px;
  padding: 11px 13px;
  border: 1px solid var(--border);
  border-radius: 12px;
  background: var(--surface-subtle);
  color: var(--muted);
  font-size: 12px;
  line-height: 1.45;
}

.redesign-page .redesign-intro-gear {
  flex: none;
  width: 17px;
  height: 17px;
  margin-top: 1px;
  color: var(--accent);
}

@media (max-width: 720px) {
  .redesign-page .redesign-intro-actions {
    display: grid;
    grid-template-columns: minmax(0, 1fr);
    gap: 8px;
  }

  /* Die empfohlene Aktion steht mobil oben. */
  .redesign-page .redesign-intro-actions .btn.primary {
    order: -1;
  }
}

/* Schnellzugriff: die wichtigsten Ziele des jeweiligen Nutzers direkt unter dem
   Begrüßungsblock. Ruhige Flächen, damit sie den Tagesinhalt darunter nicht
   überstrahlen – sie sind Abkürzung, nicht Schwerpunkt. */
.player-home-page .quick-actions {
  margin-bottom: 16px;
}

.player-home-page .quick-actions-head {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 12px;
  margin-bottom: 9px;
}

.player-home-page .quick-actions-head .eyebrow {
  margin: 0;
}

.player-home-page .quick-actions-edit {
  min-height: 32px;
  padding: 5px 11px;
  font-size: 12px;
}

/* Der Drawer trägt dieselben Symbole wie die Schnellzugriffe: Wer eine Funktion
   auf der Startseite kennt, erkennt sie in der Navigation an derselben Form.
   Zurückhaltend eingefärbt, damit die Beschriftung führend bleibt – nur der
   aktuelle Eintrag hebt sein Symbol hervor. */
.redesign-page .nav-item > .quick-action-icon {
  width: 19px;
  height: 19px;
  flex: 0 0 auto;
  color: var(--muted);
}

.redesign-page .nav-item.is-current > .quick-action-icon {
  color: var(--accent);
}

@media (hover: hover) {
  .redesign-page .nav-item:hover > .quick-action-icon {
    color: var(--accent);
  }
}

/* Kompakte Kacheln: Symbol über kurzer Beschriftung. So passen mobil vier in
   eine Reihe, ohne dass der Bereich den Tagesinhalt darunter verdrängt. */
.player-home-page .quick-actions-grid {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(104px, 1fr));
  gap: 9px;
}

.player-home-page .quick-action {
  position: relative;
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  gap: 8px;
  overflow: hidden;
  min-height: 92px;
  padding: 14px 10px 12px;
  border: 1px solid var(--border);
  border-radius: 16px;
  background: var(--surface-raised);
  color: var(--text);
  text-align: center;
  text-decoration: none;
  box-shadow: var(--shadow-soft);
}

/* Vereinsstreifen als schmale Signatur an der Oberkante. */
.player-home-page .quick-action::before {
  position: absolute;
  top: 0;
  left: 50%;
  width: 34px;
  height: 3px;
  transform: translateX(-50%);
  border-radius: 0 0 999px 999px;
  background: color-mix(in srgb, var(--accent) 55%, transparent);
  content: "";
  transition: width .18s ease, background .18s ease;
}

.player-home-page .quick-action-icon {
  width: 25px;
  height: 25px;
  flex: 0 0 auto;
  color: var(--accent);
}

.player-home-page .quick-action-label {
  display: -webkit-box;
  overflow: hidden;
  -webkit-box-orient: vertical;
  -webkit-line-clamp: 2;
  color: var(--text);
  font-size: 12px;
  font-weight: 650;
  line-height: 1.25;
}

@media (hover: hover) {
  .player-home-page .quick-action:hover {
    border-color: color-mix(in srgb, var(--accent) 42%, var(--border));
    background: color-mix(in srgb, var(--accent) 7%, var(--surface-raised));
  }

  .player-home-page .quick-action:hover::before {
    width: 100%;
    background: var(--accent);
  }
}

.player-home-page .quick-action:active {
  transform: scale(.98);
}

/* Zähler für Zustände, die eine Handlung verlangen. Erscheint nur, wenn
   tatsächlich etwas offen ist – eine Kachel ohne Aufgabe bleibt ruhig. */
.player-home-page .quick-action-badge {
  position: absolute;
  top: 8px;
  right: 8px;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  min-width: 20px;
  height: 20px;
  padding: 0 6px;
  border-radius: 999px;
  background: var(--accent);
  color: #fff;
  font-size: 11px;
  font-weight: 750;
  font-variant-numeric: tabular-nums;
  line-height: 1;
}

.player-home-page .quick-action:focus-visible {
  outline: none;
  border-color: var(--accent);
  box-shadow: 0 0 0 4px var(--focus-ring);
}

.player-home-page .quick-actions-empty {
  margin: 0;
  font-size: 13px;
}

/* Anpassen-Dialog: Auswahl als ruhige Liste, erreichtes Limit sichtbar.
   Breiter als ein Standarddialog, weil zwanzig Bezeichnungen sonst umbrechen. */
.redesign-page .quick-action-modal {
  width: min(720px, 100%);
}

.redesign-page .quick-action-hint {
  margin: 0 0 14px;
  font-size: 13px;
}

.redesign-page .quick-action-hint.is-limit {
  color: var(--caution);
}

.redesign-page .quick-action-group + .quick-action-group {
  margin-top: 15px;
}

.redesign-page .quick-action-group-title {
  margin-bottom: 7px;
  color: var(--muted);
}

.redesign-page .quick-action-choices {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(240px, 1fr));
  gap: 7px;
  margin-bottom: 4px;
}

.redesign-page .quick-action-group:last-of-type .quick-action-choices {
  margin-bottom: 18px;
}

.redesign-page .quick-action-choice {
  display: flex;
  align-items: center;
  gap: 11px;
  padding: 10px 12px;
  border: 1px solid var(--border);
  border-radius: 11px;
  background: var(--surface-subtle);
  cursor: pointer;
}

.redesign-page .quick-action-choice .quick-action-icon {
  width: 19px;
  height: 19px;
  flex: 0 0 auto;
  color: var(--muted);
}

.redesign-page .quick-action-choice:has(input:checked) .quick-action-icon {
  color: var(--accent);
}

/* Die generische Formularregel setzt jedes input auf volle Breite und
   Feldhöhe. Fuer ein Kontrollkaestchen muss beides zurueckgenommen werden,
   sonst schiebt es die Beschriftung aus der Zeile. */
.redesign-page .quick-action-choice input[type="checkbox"] {
  width: 19px;
  min-width: 19px;
  height: 19px;
  min-height: 19px;
  flex: 0 0 auto;
  margin: 0;
  padding: 0;
  accent-color: var(--accent);
}

.redesign-page .quick-action-choice > span {
  min-width: 0;
  line-height: 1.3;
}

.redesign-page .quick-action-choice:has(input:checked) {
  border-color: color-mix(in srgb, var(--accent) 42%, var(--border));
  background: color-mix(in srgb, var(--accent) 9%, var(--surface-raised));
}

.redesign-page .quick-action-choice.is-disabled {
  opacity: .5;
  cursor: not-allowed;
}

/* Physio-Slots: Frei, reserviert und gebucht müssen auf einen Blick
   unterscheidbar bleiben. Die alten 5-Prozent-Flächen verschwanden im hellen
   Theme fast vollständig; Farbstreifen, Fläche und Symbole tragen jetzt
   ausreichend Kontrast. */
.redesign-page .slot-row {
  border-left-width: 3px;
}

.redesign-page .slot-row.free {
  border-left-color: var(--success);
  background: color-mix(in srgb, var(--success) 10%, var(--surface-raised));
}

.redesign-page .slot-row.booked {
  border-left-color: var(--danger);
  background: color-mix(in srgb, var(--danger) 10%, var(--surface-raised));
}

.redesign-page .slot-row.reserved {
  border-left-color: var(--caution);
  background: color-mix(in srgb, var(--caution) 13%, var(--surface-raised));
}

.redesign-page .slot-row.disabled {
  border-left-color: var(--border);
  background: var(--surface-subtle);
  opacity: .55;
}

.redesign-page .slot-row-btn {
  width: 28px;
  height: 28px;
  min-height: 28px;
  border-radius: 7px;
  font-size: 17px;
}

.redesign-page .slot-row-btn.cancel {
  color: var(--danger);
}

.redesign-page .slot-row-btn.add {
  color: var(--success);
}

@media (hover: hover) {
  .redesign-page .slot-row-btn:hover {
    background: color-mix(in srgb, currentcolor 14%, transparent);
  }
}

.redesign-page .slot-reason-badge.MASSAGE {
  border: 1px solid color-mix(in srgb, var(--success) 34%, var(--border));
  background: color-mix(in srgb, var(--success) 12%, var(--surface-raised));
  color: var(--success);
}

.redesign-page .slot-reason-badge.INJURY {
  border: 1px solid color-mix(in srgb, var(--danger) 34%, var(--border));
  background: color-mix(in srgb, var(--danger) 12%, var(--surface-raised));
  color: var(--danger);
}

/* Ab Tabletbreite braucht die Ansichtsgroesse keine Breitenkompensation mehr:
   Aktuelle Browser loesen Prozentbreiten bereits im gezoomten Koordinatensystem
   auf, sodass die zusaetzliche Kompensation den Body zu breit macht. Zentrierte
   Inhalte rutschen dadurch nach rechts und der rechte Rand wird abgeschnitten.
   Die mobile vw-Variante in app.css bleibt unberuehrt. */
@media (min-width: 721px) {
  html[data-ui-scale="compact"] body,
  html[data-ui-scale="large"] body {
    width: auto;
  }
}

/* Die Ansichtsgroesse wird ueber `body { zoom }` umgesetzt. Fixed-Overlays erben
   diese Skalierung: Die explizite 100vh-Hoehe des Dialoghintergrunds schrumpft
   bei 90 Prozent auf 90 Prozent des Bildschirms, sodass unten ein ungedeckter
   Streifen sichtbar bleibt. Die Hoehe wird deshalb gegengerechnet - analog zur
   Breitenkompensation am body. */
/* iOS zoomt beim Fokussieren in ein Feld hinein, dessen Schrift *auf dem
   Bildschirm* kleiner als 16px ist – und bleibt danach hineingezoomt, wodurch
   die Seite seitlich verschoben und rechts angeschnitten erscheint. app.css
   setzt dafür 16px, doch bei 90 Prozent Ansichtsgröße kommen davon nur 14,4px
   an. Die Schrift wird deshalb gegengerechnet, sodass wieder 16px sichtbar
   sind. Bei 110 Prozent ist die Grenze ohnehin überschritten. */
@media (max-width: 640px) {
  html[data-ui-scale="compact"] :is(input, select, textarea) {
    font-size: 17.78px;
  }
}

html[data-ui-scale="compact"] .redesign-page .app-modal-backdrop {
  height: 111.111111vh;
  height: 111.111111dvh;
}

html[data-ui-scale="large"] .redesign-page .app-modal-backdrop {
  height: 90.909091vh;
  height: 90.909091dvh;
}

/* Aufklappmenues (Konto, Zeilenaktionen) sind schwebende Flaechen und
   verwenden dieselben Oberflaechenvariablen wie Karten und Dialoge. Die alte
   fest verdrahtete Dunkelflaeche erschien im hellen Theme als schwarzer Kasten. */
.redesign-page :is(.account-menu-panel, .action-menu-panel, .row-action-panel) {
  border-color: var(--border);
  background: var(--surface-raised);
  color: var(--text);
}

/* Ein geoeffnetes Zeilenmenue haengt per JS direkt am <body> und traegt diese
   Markierung. Erst dadurch liegt es zuverlaessig ueber nachfolgenden Karten und
   Sticky-Leisten - es bleibt aber unterhalb von Navigationsdrawer und Dialogen. */
.redesign-page .row-action-panel-lifted {
  z-index: 290;
  box-shadow: var(--shadow);
}

.redesign-page .row-action-menu.is-open {
  z-index: 280;
}

/* Eyebrow/Kicker nach Designsystem Abschnitt 3: Sora, Versalien, deutliches
   Letter-Spacing. Ordnet einen Titel seinem Bereich zu, ohne ihm Gewicht zu nehmen. */
.redesign-page :is(.eyebrow, .modal-kicker) {
  color: var(--accent);
  font-family: "Sora", sans-serif;
  font-size: 9px;
  font-weight: 750;
  letter-spacing: .14em;
  line-height: 1.4;
  text-transform: uppercase;
}

.redesign-page :is(.eyebrow, .modal-kicker) + h2,
.redesign-page :is(.eyebrow, .modal-kicker) + h3 {
  margin-top: 3px;
}

/* Im Dialogkopf steht die Versalienzeile ueber dem Titel, nicht neben ihm. Beide sind
   <span>, also inline - ohne diese Regel landen sie auf einer Zeile, und der Titel
   beginnt hinter der Bereichsangabe. */
.redesign-page .app-modal-header .eyebrow {
  display: block;
}

/* Einheitlicher Schliessen-Knopf für alle Dialoge: quadratisches Touch-Ziel,
   ruhige Fläche, keine Konkurrenz zur Primäraktion im Dialogfuss. */
.redesign-page .app-modal-close {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 40px;
  min-width: 40px;
  height: 40px;
  min-height: 40px;
  flex: 0 0 auto;
  padding: 0;
  border: 1px solid var(--border);
  border-radius: 11px;
  background: var(--surface-subtle);
  box-shadow: none;
  color: var(--muted);
  font-size: 17px;
  line-height: 1;
  cursor: pointer;
}

@media (hover: hover) {
  .redesign-page .app-modal-close:hover {
    border-color: color-mix(in srgb, var(--accent) 42%, var(--border));
    background: color-mix(in srgb, var(--accent) 9%, var(--surface-subtle));
    color: var(--accent);
    transform: none;
  }
}

.redesign-page .app-modal-close:focus-visible {
  outline: none;
  border-color: var(--accent);
  box-shadow: 0 0 0 4px var(--focus-ring);
}

/* Titelzeile mit Aktion rechts: bricht bei schmalen Karten sauber um. */
.redesign-page .card-title-row {
  gap: 10px;
  flex-wrap: wrap;
}

/* Mehrere Knoepfe rechts in einer Titelzeile - etwa der Infoknopf neben der
   Hauptaktion. Ohne die Gruppe stapelt die Titelzeile am Handy jeden Knopf
   einzeln und der runde Infoknopf rutscht linksbuendig unter die Ueberschrift.
   Lag zuerst seitenlokal in budget/invoice-list.html; seit das Ticketing
   dieselbe Zeile braucht, gilt die Regel app-weit. */
.redesign-page .actions-inline {
  display: flex;
  align-items: center;
  justify-content: flex-end;
  gap: 8px;
  flex-wrap: wrap;
}


/* Verwaltungslisten als Master-Detail: Die Zeile ist der Auslöser, bearbeitet
   wird im mittigen Dialog. Ersetzt die früheren Inline-Editoren in Vereins- und
   Ticketing-Einstellungen und gilt fuer jede weitere Verwaltungsliste. */
.redesign-page .editable-list-table tbody td {
  vertical-align: middle;
}

.redesign-page .editable-table-row {
  cursor: pointer;
}

.redesign-page .editable-table-row:focus-visible {
  outline: 2px solid var(--accent);
  outline-offset: -3px;
}

.redesign-page .strafe-edit-row {
  cursor: pointer;
}

@media (hover: hover) {
  /* Nicht an .editable-list-table gebunden: eine anklickbare Zeile muss ueberall
     zurueckmelden, dass sie anklickbar ist - auch in einer schlichten .table. */
  .redesign-page tbody tr.editable-table-row:hover > td,
  .redesign-page tbody tr.editable-table-row:hover > td:first-child {
    background: color-mix(in srgb, var(--accent) 7%, var(--surface-raised)) !important;
  }

  .redesign-page :is(.editable-table-row, .strafe-edit-row):hover .editable-row-open {
    color: var(--accent);
  }
}

/* Inaktive Eintraege treten ueber die Textfarbe zurueck. Opazitaet wuerde den
   Text im hellen Theme unlesbar machen. */
.redesign-page .editable-list-table tbody tr.inactive-row > td:first-child {
  color: var(--muted);
}

/* Der Chevron macht die Zeile als Einstieg erkennbar. Bewusst unabhaengig vom
   Tabellentyp, damit auch Listen mit eigenem Zeilenverhalten ihn tragen koennen. */
.redesign-page :is(th, td).editable-row-open {
  width: 44px;
  min-width: 44px;
  padding-left: 0;
  color: var(--muted);
  font-size: 25px;
  line-height: 1;
  text-align: center;
}

/* Sortier- und Statusspalten brauchen nur ihre tatsaechliche Breite. */
.redesign-page .editable-list-table :is(th, td).col-sort {
  width: 116px;
  min-width: 116px;
  font-variant-numeric: tabular-nums;
}

.redesign-page .editable-list-table :is(th, td).col-check {
  width: 124px;
  min-width: 124px;
}

/* Fachstatus als ruhige Pille; Farbe kommt ausschliesslich aus den Tokens. */
.redesign-page .status-pill {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  min-height: 24px;
  padding: 3px 10px;
  border: 1px solid var(--border);
  border-radius: 999px;
  background: var(--surface-subtle);
  color: var(--muted);
  font-size: 12px;
  font-weight: 650;
  letter-spacing: .01em;
  white-space: nowrap;
}

.redesign-page .status-pill::before {
  width: 6px;
  height: 6px;
  border-radius: 50%;
  background: currentcolor;
  content: "";
  flex-shrink: 0;
}

.redesign-page .status-pill.active {
  border-color: color-mix(in srgb, var(--success) 38%, var(--border));
  background: color-mix(in srgb, var(--success) 11%, var(--surface-raised));
  color: var(--success);
}

.redesign-page .status-pill.paused {
  border-color: color-mix(in srgb, var(--caution) 40%, var(--border));
  background: color-mix(in srgb, var(--caution) 12%, var(--surface-raised));
  color: var(--caution);
}

.redesign-page .status-pill.inactive {
  border-color: var(--border);
  background: var(--surface-subtle);
  color: var(--muted);
}

/* Rote Stufe der bestehenden Pillenfamilie: Sperrvermerk und die oberste
   Belastungsampel. Bewusst als weitere Variante von .status-pill statt als
   zweite Pillenfamilie. */
.redesign-page .status-pill.critical {
  border-color: color-mix(in srgb, var(--danger) 40%, var(--border));
  background: color-mix(in srgb, var(--danger) 12%, var(--surface-raised));
  color: var(--danger);
}

/* Detaildialog: Loeschen sitzt links, Abbrechen und Speichern rechts. */
.redesign-page .app-modal-actions--split {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 12px;
  flex-wrap: wrap;
}

.redesign-page .app-modal-actions-group {
  display: flex;
  align-items: center;
  gap: 10px;
  margin-left: auto;
}

/* Die linke Gruppe der geteilten Fussleiste nimmt das `margin-left: auto` der
   Basisregel zurueck. Ohne das teilen sich beide Gruppen den freien Raum und die
   destruktive Aktion steht eingerueckt statt in der Ecke. */
.redesign-page .app-modal-actions-group--start {
  justify-content: flex-start;
  margin-left: 0;
  margin-right: auto;
}

/* Ein Schalter mit Beschriftung und Erklaerung innerhalb eines Dialogfelds. */
.redesign-page .inline-toggle-field {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 16px;
  margin-bottom: 16px;
  padding: 12px 14px;
  border: 1px solid var(--border);
  border-radius: 12px;
  background: var(--surface-subtle);
}

.redesign-page .inline-toggle-field > :first-child {
  min-width: 0;
}

.redesign-page .inline-toggle-field label {
  margin-bottom: 2px;
}

.redesign-page .inline-toggle-field .muted {
  font-size: 12px;
  line-height: 1.4;
}

/* Abschlusszeile eines mehrteiligen Einstellungsformulars: Sie sagt, was der
   Button umfasst. Ohne diesen Satz wirkt er wie die Aktion der letzten Karte
   darueber – genau die Verwechslung, die es zu vermeiden gilt. */
.redesign-page .settings-save-row {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 14px;
  flex-wrap: wrap;
}

.redesign-page .settings-save-row .muted {
  margin: 0;
  font-size: 12px;
}

/* Rueckmeldung fuer Felder, die beim Umschalten sofort speichern. Sie steht in
   der Titelzeile ihrer Karte, erscheint kurz und verschwindet wieder; nur ein
   Fehler bleibt stehen. */
.redesign-page .autosave-hint {
  color: var(--success);
  font-size: 12px;
  font-weight: 600;
}

.redesign-page .autosave-hint.is-error {
  color: var(--danger);
}

/* Verwaltungstabellen mit Aktionsspalte: Die Buttons bekommen nur ihre
   tatsaechliche Breite, der gesamte Rest gehoert den Inhalten. `width: 1%`
   zwingt die Spalte in einer Auto-Layout-Tabelle auf ihre Mindestbreite. */
.admin-content-page .utensils-manage-table :is(th, td):last-child,
.budget-content-page .period-table :is(th, td):last-child {
  width: 1%;
  white-space: nowrap;
}

/* Teamliste: Die beiden Navigationsziele stehen nebeneinander und brauchen
   nur ihre Buttonbreite; Name und Typ bekommen den Rest. */
.admin-content-page .teams-table :is(th, td):nth-child(5) {
  width: 1%;
  white-space: nowrap;
}

/* Trefferzahl neben dem Zuruecksetzen-Knopf: Sie sagt, wie viel der Filter
   gerade ausblendet – ohne sie wirkt eine kurze Liste wie ein leerer Datenstand. */
.redesign-page .absence-filter-count {
  margin-left: auto;
  font-size: 12px;
}

/* ── Abwesenheiten: Zeitraum-Übersicht ─────────────────────────────────────
   Eine Zeile je Spieler, ein Balken je Zeitraum. Die Tagesspalten entstehen als
   Raster (`--days` setzt das Skript je Monat), die Balken belegen daraus
   `grid-column: erster / letzter + 1` – dadurch braucht es keine Pixelrechnung
   und Monate mit 28 bis 31 Tagen passen von selbst. */
.redesign-page .absence-timeline-scroll {
  overflow-x: auto;
  margin-top: 12px;
}

.redesign-page .absence-timeline {
  min-width: 720px;
}

/* Kein Spaltenabstand: Die stehenbleibende Namensspalte muss unmittelbar an das
   Tagesraster grenzen, sonst scrollen die Balken durch die Lücke daneben. Der
   Abstand steckt im Innenabstand des Namens. */
/* Die Namensbreite kommt aus dem längsten Namen (per Skript gemessen und als
   Variable gesetzt) – jede Zeile ist ein eigenes Raster, `max-content` würde sie
   also unterschiedlich breit machen und die Balken gegeneinander verschieben.
   Der Rest gehört den Tagen. */
/* align-items: stretch statt center – die stehenbleibende Namensfläche muss die
   ganze Zeilenhöhe decken. Bei überlappenden Meldungen wächst die Zeile um eine
   zweite Spur; eine nur texthohe Fläche ließ den Balken daneben sichtbar
   durchlaufen. Zentriert wird der Name in seiner Zelle. */
.redesign-page .absence-timeline-row {
  display: grid;
  grid-template-columns: var(--timeline-name-col, 148px) minmax(0, 1fr);
  align-items: stretch;
  column-gap: 0;
  padding: 4px 0;
  border-bottom: 1px solid var(--border);
}

.redesign-page .absence-timeline-row:last-child {
  border-bottom: 0;
}

.redesign-page .absence-timeline-head {
  border-bottom: 1px solid var(--border);
  padding-bottom: 6px;
}

/* Die Namensspalte bleibt beim seitlichen Scrollen stehen – sonst weiß man bei
   den späteren Tagen des Monats nicht mehr, zu wem ein Balken gehört. Sie
   braucht dafür eine deckende Fläche und eine Ebene über den Balken, sonst
   laufen diese sichtbar darunter durch. */
.redesign-page .absence-timeline-name {
  position: sticky;
  left: 0;
  z-index: 2;
  display: flex;
  align-items: center;
  min-width: 0;
  overflow: hidden;
  padding-right: 8px;
  background: var(--surface-raised);
  box-shadow: 1px 0 0 var(--border);
  color: var(--text);
  font-size: 12px;
  font-weight: 600;
  white-space: nowrap;
}

/* Traegt den Namen und damit die messbare Textbreite. Ohne dieses Element
   liefert nur die Zelle einen Wert – und die ist stets so breit wie ihre
   Rasterspalte. */
.redesign-page .absence-timeline-name-text {
  display: inline-block;
  max-width: 100%;
  overflow: hidden;
  text-overflow: ellipsis;
  vertical-align: middle;
  white-space: nowrap;
}

.redesign-page .absence-timeline-days {
  display: grid;
  grid-template-columns: repeat(var(--days, 31), minmax(0, 1fr));
  grid-auto-rows: 16px;
  row-gap: 3px;
  align-items: stretch;
}

.redesign-page .absence-timeline-day {
  color: var(--muted);
  font-size: 9px;
  font-weight: 600;
  text-align: center;
}

.redesign-page .absence-timeline-day.is-weekend {
  color: color-mix(in srgb, var(--muted) 60%, transparent);
}

/* Termintage: Unter der Tagesnummer sitzt ein Marker – nur die Spaltentönung in
   den Zeilen genügt nicht, weil Balken sie verdecken und ihr der Bezug zur
   Kopfzeile fehlt. Der Marker steht immer und macht die Spalte zuordenbar. */
.redesign-page .absence-timeline-day {
  position: relative;
  padding-bottom: 6px;
}

.redesign-page .absence-timeline-day:is(.has-session, .has-match)::after {
  position: absolute;
  right: 15%;
  bottom: 0;
  left: 15%;
  height: 3px;
  border-radius: 2px;
  content: "";
}

.redesign-page .absence-timeline-day.has-session {
  color: var(--text);
}

.redesign-page .absence-timeline-day.has-session::after {
  background: color-mix(in srgb, var(--muted) 55%, transparent);
}

.redesign-page .absence-timeline-day.has-match {
  color: var(--accent);
  font-weight: 800;
}

.redesign-page .absence-timeline-day.has-match::after {
  background: var(--accent);
}

/* Heute: Die Tagesnummer steckt in einer eigenen Fläche, damit sie sich nicht
   nur über die Textfarbe behaupten muss – Spieltage stehen ohnehin schon in
   Akzentfarbe und Termintage in Textfarbe, beides würde die bloße Einfärbung
   überschreiben. Die Nummer sitzt deshalb in einem eigenen Element; sonst
   liefe die Fläche über die ganze Rasterspalte.
   Bewusst neutral invertiert statt in Akzentfarbe: Rot heißt hier Spieltag,
   eine rote Heute-Markierung wäre ein zweites Signal in derselben Farbe. So
   bleiben die drei Aussagen getrennt – rot Spieltag, grau Termin, hell heute.
   Die Fläche bleibt flach, damit der Marker darunter frei bleibt: Ob heute
   trainiert wird, liest man genau hier ab. */
.redesign-page .absence-timeline-day-num {
  display: inline-block;
  min-width: 14px;
  padding: 0 4px;
  border-radius: 999px;
  line-height: 12px;
}

.redesign-page .absence-timeline-day.is-today .absence-timeline-day-num {
  background: var(--text);
  color: var(--surface-raised);
  font-weight: 800;
}

/* Heute zieht sich als eigene Spalte durch alle Zeilen – erst dadurch lässt
   sich ohne Abzählen ablesen, welche Balken heute laufen. Getragen wird sie
   von den beiden Kanten, nicht von der Füllung: Die Flächen sind hier bereits
   vergeben (rot Spieltag, grau Termin), eine kräftig getönte Spalte wäre in
   jeder Farbe mit einer von beiden verwechselbar. Die Füllung bleibt deshalb
   fast durchsichtig und neutral, sodass ein Spieltag oder Termin auch heute
   noch unter ihr durchscheint.
   Eingefügt wird sie nach den Balken und liegt damit über ihnen, die negativen
   Außenabstände überbrücken den Zeilen-Innenabstand, sonst bricht die Spalte
   an jeder Zeilengrenze ab. */
.redesign-page .absence-timeline-today {
  margin-block: -4px;
  border-inline: 1px solid color-mix(in srgb, var(--text) 60%, transparent);
  background: color-mix(in srgb, var(--text) 6%, transparent);
  pointer-events: none;
}

.redesign-page .absence-timeline-mark {
  border-radius: 3px;
}

.redesign-page .absence-timeline-mark.is-session {
  background: color-mix(in srgb, var(--muted) 12%, transparent);
}

.redesign-page .absence-timeline-mark.is-match {
  background: color-mix(in srgb, var(--accent) 12%, transparent);
}

.redesign-page .absence-timeline-legend {
  display: flex;
  flex-wrap: wrap;
  gap: 14px;
  margin-top: 12px;
  color: var(--muted);
  font-size: 11px;
}

.redesign-page .absence-timeline-legend span {
  display: inline-flex;
  align-items: center;
  gap: 6px;
}

.redesign-page .absence-timeline-legend-key {
  width: 14px;
  height: 10px;
  border-radius: 3px;
}

.redesign-page .absence-timeline-legend-key.is-match {
  background: color-mix(in srgb, var(--accent) 22%, var(--surface-subtle));
}

.redesign-page .absence-timeline-legend-key.is-session {
  background: color-mix(in srgb, var(--muted) 22%, var(--surface-subtle));
}

.redesign-page .absence-timeline-legend-key.is-bar {
  background: color-mix(in srgb, var(--info) 22%, var(--surface-subtle));
  box-shadow: inset 0 0 0 1px color-mix(in srgb, var(--info) 45%, transparent);
}

.redesign-page .absence-timeline-legend-key.is-bar.is-pending {
  background: color-mix(in srgb, var(--caution) 16%, var(--surface-subtle));
  box-shadow: inset 0 0 0 1px color-mix(in srgb, var(--caution) 55%, transparent);
}

/* Bestaetigte Zeitraeume stehen als ruhige Flaeche, offene bleiben als Umriss
   erkennbar – dieselbe Unterscheidung wie in der Statusspalte der Liste. */
.redesign-page .absence-timeline-bar {
  overflow: hidden;
  min-width: 3px;
  padding: 0 5px;
  border-radius: 5px;
  background: color-mix(in srgb, var(--info) 22%, var(--surface-subtle));
  box-shadow: inset 0 0 0 1px color-mix(in srgb, var(--info) 45%, transparent);
  color: var(--text);
  font-size: 9px;
  font-weight: 600;
  line-height: 16px;
  text-overflow: ellipsis;
  white-space: nowrap;
}

.redesign-page .absence-timeline-bar.is-pending {
  background: color-mix(in srgb, var(--caution) 16%, var(--surface-subtle));
  box-shadow: inset 0 0 0 1px color-mix(in srgb, var(--caution) 55%, transparent);
}

.redesign-page .absence-timeline-empty {
  margin: 6px 0 0;
  font-size: 13px;
}

.redesign-page .absence-timeline-nav {
  gap: 8px;
}

.redesign-page .absence-timeline-month {
  min-width: 128px;
  color: var(--text);
  font-size: 13px;
  font-weight: 600;
  text-align: center;
}

/* Monatswechsel auf dem Handy: eine eigene Zeile unter dem Kartentitel, nicht
   der Restplatz daneben. Die generischen Mobilregeln stellen .inline auf eine
   Spalte und ziehen Schalter auf volle Breite; blieb die Zeile dagegen im
   Titelbereich, schrumpften Pfeil und Datum bis zum Umbruch mitten im Wort.
   Deshalb: volle Breite erzwingen, Pfeile fest, Datum mittig und ungebrochen. */
@media (max-width: 720px) {
  .redesign-page .absence-timeline-nav {
    flex: 1 0 100%;
    flex-direction: row;
    flex-wrap: nowrap;
    align-items: center;
    justify-content: space-between;
    gap: 8px;
    width: 100%;
  }

  .redesign-page .absence-timeline-nav .btn {
    flex: 0 0 36px;
    width: 36px;
    min-width: 36px;
    min-height: 36px;
    padding: 0;
    font-size: 16px;
    line-height: 1;
  }

  .redesign-page .absence-timeline-month {
    flex: 1 1 auto;
    min-width: 0;
    font-size: 13px;
    white-space: nowrap;
  }
}

/* Abwesenheiten: Bestaetigen und Loeschen stehen nebeneinander, Grund und
   Anmerkung bekommen den freien Raum. Ueber die Klasse statt :last-child, weil
   die Spalte ohne Verwaltungsrecht ganz fehlt. */
.admin-content-page .absence-tbl :is(th, td).absence-actions {
  width: 1%;
  white-space: nowrap;
}

/* Auf Inhaltsbreite gesetzte Aktionsspalten duerfen ihre Buttons nicht
   untereinander umbrechen - sonst wird die Zeile unnoetig hoch. */
.redesign-page :is(.teams-table, .season-table, .period-table, .absence-tbl) td .inline-actions {
  flex-wrap: nowrap;
}

/* Aktionen sitzen am rechten Rand ihrer Spalte. Faellt in einer Zeile eine
   bedingte Aktion weg – etwa „Bestaetigen" bei bereits bestaetigten Eintraegen –,
   rutscht die verbleibende sonst nach links aus der Spaltenflucht.
   Nur ab Tabellenbreite: In der gestapelten Ansicht bleiben die Aktionen
   zentriert (app.css, ab 640px abwaerts). */
@media (min-width: 641px) {
  .redesign-page :is(.teams-table, .season-table, .period-table, .absence-tbl) td .inline-actions {
    justify-content: flex-end;
  }
}

.admin-content-page .teams-table :is(th, td):is(:nth-child(1), :nth-child(4)) {
  width: 130px;
}

/* Datums- und Statusspalten sind in ihrer Breite vorhersehbar. */
.admin-content-page .season-table :is(th, td):is(:nth-child(2), :nth-child(3)),
.budget-content-page .period-table :is(th, td):is(:nth-child(2), :nth-child(3)) {
  width: 118px;
  font-variant-numeric: tabular-nums;
  white-space: nowrap;
}

.admin-content-page .season-table :is(th, td):nth-child(4),
.budget-content-page .period-table :is(th, td):nth-child(4) {
  width: 108px;
}

/* Saisonliste: Status und Zustandswechsel stehen als zwei gleich breite
   Spalten untereinander bündig, unabhängig von der Wortlänge. */
.admin-content-page .season-table :is(th, td):nth-child(5) {
  width: 156px;
}

.admin-content-page .season-table td:nth-child(4) .status-pill,
.admin-content-page .season-table td:nth-child(5) :is(.btn, button) {
  width: 100%;
  justify-content: center;
}

/* Terminplaner-Entwuerfe: Datum, Tag, Typ, Zeiten und Konflikt sind schmal,
   "Plaetze" bekommt den frei werdenden Raum. */
.admin-content-page .season-drafts-table :is(th, td):nth-child(1) {
  width: 112px;
  font-variant-numeric: tabular-nums;
  white-space: nowrap;
}

.admin-content-page .season-drafts-table :is(th, td):nth-child(2) {
  width: 118px;
}

.admin-content-page .season-drafts-table :is(th, td):nth-child(3) {
  width: 124px;
}

.admin-content-page .season-drafts-table :is(th, td):is(:nth-child(4), :nth-child(5)) {
  width: 76px;
  font-variant-numeric: tabular-nums;
  white-space: nowrap;
}

.admin-content-page .season-drafts-table :is(th, td):nth-child(7) {
  width: 104px;
}

/* Die Umschalter selbst bilden die Gruppe; kein zusätzlicher Rahmen außen. */
.resource-schedule-page .view-toggle {
  padding: 0;
  border: 0;
  border-radius: 0;
  background: transparent;
}

/* Ticketlisten bemessen ihre Spalten am Inhalt statt an einer festen Aufteilung.
   Die Aktionen bleiben dadurch vollständig als echte Buttons sichtbar, statt zu
   "…" beschnitten zu werden. Wird die Tabelle dabei breiter als das Fenster,
   scrollt sie seitlich in ihrem eigenen Container. */
.admin-content-page :is(.ticket-list-table, .ticket-batch-jobs-table, .cfg-table, .ticket-batch-archive-table) {
  table-layout: auto;
}

.admin-content-page :is(.ticket-list-table, .ticket-batch-jobs-table, .cfg-table, .ticket-batch-archive-table) :is(th, td) {
  overflow: visible;
  text-overflow: clip;
}

.admin-content-page :is(.ticket-list-table, .ticket-batch-jobs-table, .cfg-table, .ticket-batch-archive-table) :is(th, td).ticketing-actions {
  width: 1%;
  white-space: nowrap;
}

/* Bewusst gekürzte Inhaltsspalten behalten ihre Ellipsis. */
.admin-content-page .ticket-list-table .ticket-company-cell {
  overflow: hidden;
  text-overflow: ellipsis;
}

/* Budget and invoice workflows share the same calm data-heavy language. */
.budget-content-page :is(.kpi-card, .invoice-detail-section, .detail-booking-list) {
  background: var(--surface-raised);
  border-color: var(--border);
  border-radius: 16px;
  box-shadow: none;
}

.budget-content-page :is(.app-modal, .invoice-match-modal) {
  border-color: var(--border);
  background: var(--surface-raised);
  color: var(--text);
}

.budget-content-page .app-modal-backdrop {
  background: rgba(5, 10, 15, .66);
  backdrop-filter: blur(7px);
  -webkit-backdrop-filter: blur(7px);
}

/* Der Empfänger-Picker ist eine Suchansicht, kein kleines Formular. Mehr Höhe
   und eine im Dialogfluss liegende Trefferliste machen auch lange Listen
   sichtbar, ohne dass das Dropdown am Kartenrand abgeschnitten wird. */
.sponsoring-content-page .ticket-recipient-link-dialog {
  display: flex;
  flex-direction: column;
  width: min(980px, 100%);
  height: min(680px, calc(100dvh - 48px));
}

.sponsoring-content-page .ticket-recipient-link-dialog > form {
  display: flex;
  flex: 1;
  flex-direction: column;
  min-height: 0;
}

.sponsoring-content-page .ticket-recipient-link-dialog .category-picker-results {
  position: static;
  max-height: 420px;
  margin-top: 6px;
  box-shadow: none;
}

.sponsoring-content-page .ticket-recipient-link-dialog .app-modal-actions {
  margin-top: auto;
}

.budget-content-page :is(
  .search-results,
  .cat-picker-crumb,
  .summary-tile,
  .allocation-editor-summary,
  .allocation-editor-section,
  .allocation-editor-balance-item,
  .invoice-assignment-main,
  .invoice-match-context,
  .invoice-match-balance-item,
  .invoice-match-detail-fact,
  .invoice-match-item,
  .invoice-match-note
) {
  border-color: var(--border);
  background: var(--surface-subtle);
  color: var(--text);
}

.budget-content-page :is(.invoice-match-list-panel, .invoice-match-detail) {
  border-color: var(--border);
  background: var(--surface-raised);
}

.budget-content-page :is(.document-tabs, .open-ledger-tabs) {
  border-color: var(--border);
  background: var(--surface-subtle);
}

.budget-content-page :is(.document-tab, .open-ledger-tab) {
  color: var(--muted);
}

.budget-content-page :is(.document-tab.is-active, .open-ledger-tab.is-active) {
  border-color: var(--border);
  background: var(--surface-raised);
  color: var(--accent);
  box-shadow: var(--shadow-soft);
}

.budget-content-page :is(.document-tab-count, .open-ledger-tab-count) {
  background: var(--surface-pressed);
  color: var(--muted);
}

.budget-content-page :is(.document-tab.is-active, .open-ledger-tab.is-active) :is(.document-tab-count, .open-ledger-tab-count) {
  background: color-mix(in srgb, var(--accent) 10%, var(--surface-raised));
  color: var(--accent);
}

.budget-content-page :is(.row-child.row-parent td:first-child, .row-parent td:first-child) {
  color: var(--text);
}

/* Die Kategoriespalte ist eine ganze Spalte aus Links. In Vereinsrot konkurriert sie mit
   der Negativ-Signalfarbe der Beträge, deshalb bleibt sie im Lauftext und zeigt ihre
   Klickbarkeit erst im Hover. Die Ohne-Kategorie-Zeile behält ihren Warnakzent. */
.budget-content-page .budget-table .cat-link:not(.uncategorized-label) {
  color: var(--text);
}

@media (hover: hover) {
  .budget-content-page .budget-table .cat-link:not(.uncategorized-label):hover {
    color: var(--accent);
    text-decoration: underline;
    text-underline-offset: 3px;
  }
}

.budget-content-page :is(.row-total, .cat-row, .allocation-editor-row) {
  background: var(--surface-subtle);
}

.budget-content-page .uncategorized-label {
  color: var(--caution);
}

.budget-content-page .invoice-match-current-row + .invoice-match-current-row {
  border-top-color: var(--border);
}

.budget-content-page .invoice-match-current-open {
  border-color: transparent;
  background: transparent;
  color: var(--text);
}

.budget-content-page .period-sep {
  border-left-color: color-mix(in srgb, var(--muted) 38%, var(--border)) !important;
}

@media (hover: hover) {
  .budget-content-page :is(.cat-row, .search-result-item, .cat-picker-drill, .invoice-match-item):hover {
    background: color-mix(in srgb, var(--accent) 6%, var(--surface-raised));
  }

  .budget-content-page :is(.invoice-assignment-main, .invoice-match-current-open):hover {
    border-color: var(--border);
    background: color-mix(in srgb, var(--accent) 6%, var(--surface-raised));
  }

  .budget-content-page .cat-indent-btn:hover {
    background: var(--surface-pressed);
    color: var(--text);
  }
}

.budget-content-page .kpi-card {
  box-shadow: var(--shadow-soft);
}

/* Geldbeträge stehen in Budget und Sponsoring durchgängig in der Textschrift - sie werden
   Ziffer für Ziffer gelesen und miteinander verglichen, wofür die schmale Display-Schrift
   schlechter trägt. Hervorgehoben wird über Farbe und Gewicht: freistehende Werte (KPI- und
   Summenkacheln, Modal-Beträge) kräftig, Zellen in einer Zahlenkolonne einen Schritt
   leichter, damit die ungefärbten Nachbarn nicht zurückfallen. */
.budget-content-page :is(.kpi-value, .amount-pos, .amount-neg, .amount-neutral),
.sponsoring-content-page :is(.kpi-value, .amount-pos, .amount-neg, .amount-neutral) {
  font-family: "Sora", sans-serif;
  font-weight: 700;
}

.budget-content-page td:is(.amount-pos, .amount-neg, .amount-neutral),
.sponsoring-content-page td:is(.amount-pos, .amount-neg, .amount-neutral) {
  font-weight: 600;
}

.budget-content-page :is(.amount-pos, .kpi-positive, .row-amount.amount-pos, .invoice-match-context-amount, .invoice-match-item-amount:not(.is-refund)),
.sponsoring-content-page :is(.amount-pos, .kpi-positive) {
  color: var(--success);
}

.budget-content-page :is(.amount-neg, .kpi-negative, .row-amount.amount-neg, .invoice-match-context-amount.is-refund, .invoice-match-item-amount.is-refund),
.sponsoring-content-page :is(.amount-neg, .kpi-negative) {
  color: var(--danger);
}

.budget-content-page .amount-neutral,
.sponsoring-content-page .amount-neutral {
  color: var(--muted);
}

.budget-content-page :is(.form-label, .kpi-label) {
  color: var(--muted);
  font-family: "Sora", sans-serif;
  font-size: 10px;
  font-weight: 700;
  letter-spacing: .12em;
  text-transform: uppercase;
}

.budget-content-page :is(.data-table, .budget-table, .review-table) {
  color: var(--text);
  background: transparent;
}

.budget-content-page :is(.data-table, .budget-table, .review-table) thead th {
  background: var(--surface-subtle);
  color: var(--muted);
  border-color: var(--border);
}

/* Die gemeinsame Zellenregel würde jede Vorzeichenfarbe überschreiben - Betragszellen
   behalten deshalb ihre Signalfarbe aus den .amount-*-Klassen (gleiches Prinzip wie bei
   der Zeilenkante, die deshalb als inset-Schatten gesetzt wird). */
.budget-content-page :is(.data-table, .budget-table, .review-table) tbody
  td:not(.amount-pos, .amount-neg, .amount-neutral, .text-success, .text-danger) {
  color: var(--text);
}

.budget-content-page :is(.data-table, .budget-table, .review-table) tbody td {
  background: var(--surface-raised);
  border-color: var(--border);
}

@media (hover: hover) {
  .budget-content-page :is(.data-table, .budget-table, .review-table) tbody tr:hover td,
  .budget-content-page :is(.data-table, .budget-table, .review-table) tbody tr:hover td:first-child {
    background: color-mix(in srgb, var(--accent) 6%, var(--surface-raised));
  }
}

.budget-content-page :is(.badge-neutral, .badge-warning, .badge-success, .badge-danger) {
  border-color: color-mix(in srgb, currentColor 28%, transparent);
}

.budget-content-page .badge-neutral {
  background: var(--surface-subtle);
  color: var(--muted);
}

.budget-content-page .badge-warning {
  background: color-mix(in srgb, var(--caution) 12%, var(--surface-raised));
  color: var(--caution);
}

.budget-content-page .badge-success {
  background: color-mix(in srgb, var(--success) 12%, var(--surface-raised));
  color: var(--success);
}

.budget-content-page .badge-danger {
  background: color-mix(in srgb, var(--danger) 10%, var(--surface-raised));
  color: var(--danger);
}

/* Equipment, physio and sponsoring keep their domain accents while sharing
   the same structural surfaces and interaction states. */
.equipment-content-page :is(.tab-bar, .eq-section-tabs) {
  gap: 8px;
  padding: 4px;
  border: 1px solid var(--border);
  border-radius: 13px;
  background: var(--surface-subtle);
}

.equipment-content-page :is(.tab-btn, .eq-section-tabs .btn.secondary) {
  border-color: transparent;
  background: transparent;
  color: var(--muted);
}

.equipment-content-page :is(.tab-btn.active, .eq-section-tabs .btn.secondary.is-current) {
  background: var(--surface-raised);
  border-color: var(--border);
  color: var(--accent);
  box-shadow: var(--shadow-soft);
}

.equipment-content-page .table.is-filtered tr.filter-even td {
  background: var(--surface-subtle);
}

.equipment-content-page :is(#eq-return-modal, #eq-edit-modal) {
  background: rgba(5, 10, 15, .66);
  backdrop-filter: blur(7px);
  -webkit-backdrop-filter: blur(7px);
}

.physio-admin-page :is(#physio-slot-panel, .app-modal) {
  background: var(--surface-raised);
  border-color: var(--border);
  color: var(--text);
}

.physio-admin-page :is(#physio-slot-overlay, .app-modal-backdrop) {
  background: rgba(5, 10, 15, .66);
  backdrop-filter: blur(7px);
  -webkit-backdrop-filter: blur(7px);
}

.physio-admin-page .physio-avail-row {
  padding: 15px 0;
}

.sponsoring-content-page :is(.detail-tile, .form-section) {
  background: var(--surface-raised);
  border-color: var(--border);
  border-radius: 16px;
  box-shadow: var(--shadow-soft);
}

.sponsoring-content-page :is(.form-label, .stat-label) {
  color: var(--muted);
  font-size: 10px;
  font-weight: 700;
  letter-spacing: .12em;
  text-transform: uppercase;
}

.sponsoring-content-page .data-table thead th {
  background: var(--surface-subtle);
  color: var(--muted);
}

/* Wie im Budget-Modul: Vorzeichenzellen behalten ihre Signalfarbe, die gemeinsame
   Zellenregel wäre sonst spezifischer und würde sie überschreiben. */
.sponsoring-content-page .data-table tbody
  td:not(.amount-pos, .amount-neg, .amount-neutral, .text-success, .text-danger) {
  color: var(--text);
}

.sponsoring-content-page .data-table tbody td {
  background: var(--surface-raised);
}

@media (hover: hover) {
  .sponsoring-content-page .data-table tbody tr:hover td,
  .sponsoring-content-page .data-table tbody tr:hover td:first-child {
    background: color-mix(in srgb, var(--accent) 6%, var(--surface-raised));
  }
}

.sponsoring-content-page .badge-neutral {
  background: var(--surface-subtle);
  color: var(--muted);
}

.sponsoring-content-page .badge-warning {
  background: color-mix(in srgb, var(--caution) 12%, var(--surface-raised));
  color: var(--caution);
}

.sponsoring-content-page .badge-success {
  background: color-mix(in srgb, var(--success) 12%, var(--surface-raised));
  color: var(--success);
}

.sponsoring-content-page .badge-danger {
  background: color-mix(in srgb, var(--danger) 10%, var(--surface-raised));
  color: var(--danger);
}

.service-home-page .container > .card {
  position: relative;
  overflow: hidden;
  padding: clamp(24px, 3vw, 42px);
}

.service-home-page .container > .card::before {
  position: absolute;
  top: 0;
  left: clamp(24px, 3vw, 42px);
  width: 58px;
  height: 3px;
  border-radius: 0 0 999px 999px;
  background: var(--accent);
  content: "";
  pointer-events: none;
}

.service-home-page .container > .card > * {
  position: relative;
  z-index: 1;
}

.service-home-page .container > .card h3 {
  margin: 0 0 8px;
  font-family: "Barlow Condensed", sans-serif;
  font-size: clamp(34px, 4vw, 58px);
  line-height: .95;
}

.service-home-page .container > .card .actions {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(220px, 1fr));
  gap: 10px;
  max-width: 980px;
  margin-top: 24px;
}

.service-home-page .container > .card .actions .btn {
  justify-content: space-between;
  min-height: 56px;
  padding: 13px 16px;
  text-align: left;
}

/* One modal language for every migrated feature, including fragment-based
   budget dialogs. The modal itself remains the only scroll container for iOS. */
.content-page .app-modal-backdrop {
  padding: max(12px, env(safe-area-inset-top)) max(12px, env(safe-area-inset-right)) max(12px, env(safe-area-inset-bottom)) max(12px, env(safe-area-inset-left));
  background: rgba(5, 10, 15, .66);
  backdrop-filter: blur(7px);
  -webkit-backdrop-filter: blur(7px);
}

.content-page .card.app-modal {
  border-color: var(--border);
  border-radius: 20px;
  background: var(--surface-raised);
  color: var(--text);
  box-shadow: var(--shadow);
}

.content-page .app-modal-header {
  padding-bottom: 13px;
  border-bottom: 1px solid var(--border);
}

.content-page .app-modal-header .card-title,
.content-page .app-modal-title {
  font-family: "Barlow Condensed", sans-serif;
  font-size: clamp(27px, 3vw, 38px);
  line-height: 1;
}

.content-page :is(.app-modal-actions, .app-modal-footer, .form-actions) {
  border-color: var(--border);
}

/* Public/legal pages use the same editorial shell without requiring the
   authenticated navigation drawer. */
.public-content-page .section-title,
.public-content-page .card > h3:first-child {
  margin-top: 0;
  color: var(--text);
  font-family: "Barlow Condensed", sans-serif;
  font-size: clamp(27px, 2.4vw, 36px);
  line-height: 1;
}

.public-content-page .nav {
  display: inline-flex;
  gap: 4px;
  margin-bottom: 14px;
  padding: 4px;
  border: 1px solid var(--border);
  border-radius: 13px;
  background: var(--surface-subtle);
}

.public-content-page .nav a {
  min-width: 84px;
  padding: 9px 15px;
  border-radius: 9px;
  color: var(--muted);
  font-weight: 650;
  text-align: center;
}

.public-content-page .nav a.active {
  background: var(--surface-raised);
  color: var(--accent);
  box-shadow: var(--shadow-soft);
}

.public-content-page .privacy-draft-notice {
  margin-bottom: 16px;
  border-color: color-mix(in srgb, var(--caution) 44%, var(--border));
  background: color-mix(in srgb, var(--caution) 8%, var(--surface-raised));
}

/* Resource scheduling stays information-dense, but neutral bookings must
   remain readable in both themes. */
.admin-content-page .week-table .col-res,
.admin-content-page .time-ruler,
.admin-content-page .time-ruler-header,
.admin-content-page .day-col-header {
  background: var(--surface-subtle);
}

.admin-content-page :is(.wchip, .tslot).team-other,
.admin-content-page :is(.wchip, .tslot).team-neutral {
  background: color-mix(in srgb, var(--muted) 10%, var(--surface-raised));
  border-color: color-mix(in srgb, var(--muted) 54%, var(--border));
}

.content-page .table-wrap,
.content-page .table-scroll {
  max-width: 100%;
  overflow-x: auto;
  border: 1px solid var(--border);
  border-radius: 16px;
  background: var(--surface-raised);
  box-shadow: var(--shadow-soft);
  scrollbar-gutter: stable;
}

.content-page .card > .table-wrap,
.content-page .card > .table-scroll {
  margin-top: 16px;
  box-shadow: none;
}

.content-page .table,
.content-page .absence-table {
  margin: 0;
  background: transparent;
}

.content-page .table th,
.content-page .absence-table th {
  color: var(--muted);
  background: var(--surface-subtle);
  font-size: 9px;
  font-weight: 700;
  letter-spacing: .12em;
  text-transform: uppercase;
}

.content-page :is(.table-wrap, .table-scroll) > table thead th,
.content-page :is(.table-wrap, .table-scroll) > table thead th:first-child,
.content-page :is(.table-wrap, .table-scroll) > table[data-sortable] thead th:hover {
  background: var(--surface-subtle);
  color: var(--muted);
}

/* Sortierbare Kopfzellen sagen es schon im Ruhezustand.
   Bisher verriet nur die aktive Spalte ihren Pfeil - eine Tabelle ohne Vorsortierung sah damit
   aus wie jede andere, und niemand kam auf die Idee zu klicken. Der Hintergrund bleibt dafuer
   unangetastet: er traegt den mitlaufenden Kopf, eine Hover-Flaeche wuerde ihn zerreissen. Die
   Rueckmeldung sitzt deshalb an Zeichen und Schriftfarbe. */
table[data-sortable] thead th:not([data-sort-attr="nosort"])::after {
  content: "⇅";
  position: absolute;
  right: 4px;
  font-size: .78em;
  font-weight: 600;
  opacity: .34;
}

table[data-sortable] thead th:is(.sort-asc, .sort-desc)::after {
  content: attr(data-sort-label);
  opacity: .85;
}

table[data-sortable] thead th:not([data-sort-attr="nosort"]):hover {
  color: var(--text);
}

table[data-sortable] thead th:not([data-sort-attr="nosort"]):hover::after {
  opacity: .9;
}

.content-page .table td,
.content-page .absence-table td {
  color: var(--text);
  border-bottom-color: var(--border);
  transition: background-color .18s ease;
}

.content-page .table tbody tr,
.content-page .absence-table tbody tr {
  background-color: transparent;
  transition: none;
}

@media (hover: hover) {
  .content-page :is(.table-wrap, .table-scroll) > table tbody tr:hover td,
  .content-page :is(.table-wrap, .table-scroll) > table tbody tr:hover td:first-child {
    background: color-mix(in srgb, var(--accent) 6%, var(--surface-raised));
  }
}

.content-page .table tbody tr.squad-own-row {
  background: transparent;
}

.content-page .table tbody tr.squad-own-row td {
  background: color-mix(in srgb, var(--accent) 8%, var(--surface-raised));
}

.content-page .table tbody tr.squad-own-row td:first-child {
  background: color-mix(in srgb, var(--accent) 8%, var(--surface-raised));
  box-shadow: inset 3px 0 0 var(--accent);
}

@media (hover: hover) {
  .content-page .table tbody tr.squad-own-row:hover td,
  .content-page .table tbody tr.squad-own-row:hover td:first-child {
    background: color-mix(in srgb, var(--accent) 8%, var(--surface-raised));
  }
}

.content-page .stats-grid-user {
  display: grid;
  grid-template-columns: repeat(6, minmax(0, 1fr));
  gap: 12px;
  margin-bottom: 14px;
  overflow: visible;
}

.content-page .stats-grid-user .stat-card {
  min-width: 0;
  margin: 0;
  padding: 18px;
}

.content-page .stats-grid-user .stat-label,
.content-page .db-kicker {
  color: var(--muted);
  font-size: 9px;
  font-weight: 700;
  letter-spacing: .12em;
  text-transform: uppercase;
}

.content-page .stats-grid-user .stat-value,
.content-page .competition-score {
  margin-top: 8px;
  color: var(--text);
  font-family: "Barlow Condensed", sans-serif;
  font-size: 34px;
  font-weight: 700;
  line-height: 1;
}

.content-page .stats-grid-user .stat-value.text-success {
  color: var(--success);
}

.content-page .stats-grid-user .stat-value.text-warning {
  color: var(--caution);
}

.content-page .stats-grid-user .stat-value.text-danger,
.content-page .competition-score-negative {
  color: var(--danger);
}

.content-page .competition-score-positive {
  color: var(--success);
}

/* Zelle "Erreichte Schwellen": beide Zaehler nebeneinander, sonst ein ruhiges ±0. */
.content-page .competition-balance {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 5px;
  font-size: 12px;
}

.content-page .competition-rank-hint {
  margin: -6px 0 14px;
  font-size: 12px;
}

.content-page .table tbody tr.duty-current-week td {
  background: color-mix(in srgb, var(--accent) 7%, var(--surface-raised));
}

.content-page .table tbody tr.duty-current-week td:first-child {
  border-left: 0;
  box-shadow: inset 3px 0 0 var(--accent);
}

@media (hover: hover) {
  .content-page .table tbody tr.duty-current-week:hover td,
  .content-page .table tbody tr.duty-current-week:hover td:first-child {
    background: color-mix(in srgb, var(--accent) 10%, var(--surface-raised));
  }
}

.redesign-page .tag {
  color: var(--accent);
  border-color: color-mix(in srgb, var(--accent) 48%, var(--border));
  background: color-mix(in srgb, var(--accent) 8%, var(--surface-raised));
}

.attendance-overview-page .attendance-month-toolbar {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 24px;
  min-height: 82px;
  padding: 14px 18px;
}

.attendance-overview-page .attendance-month-copy {
  display: grid;
  gap: 3px;
}

.attendance-overview-page .attendance-month-copy strong {
  color: var(--text);
  font-size: 14px;
  font-weight: 600;
}

.attendance-overview-page .attendance-month-form {
  flex: 0 1 310px;
  margin: 0;
}

.attendance-overview-page .attendance-month-form input {
  width: 100%;
  margin: 0;
}

/* Calendar — dense working surface with the same visual language as the dashboard. */
.calendar-page .container > .card {
  padding: clamp(16px, 1.8vw, 24px);
}

.calendar-page .cal-nav {
  gap: 10px 12px;
  margin-bottom: 18px;
}

.calendar-page .cal-nav h3 {
  color: var(--text);
  font-family: "Barlow Condensed", sans-serif;
  font-size: clamp(27px, 2.4vw, 36px);
  font-weight: 700;
  letter-spacing: -.015em;
  line-height: 1;
}

.calendar-page .cal-view-switch {
  gap: 2px;
  padding: 3px;
  border-color: var(--border);
  border-radius: 12px;
  background: var(--surface-subtle);
}

.calendar-page .cal-view-btn {
  min-height: 38px;
  border-radius: 9px;
  color: var(--muted);
}

.calendar-page .cal-view-btn.active,
.calendar-page .cal-view-btn.active:hover {
  color: var(--accent);
  border: 0;
  background: var(--surface-raised);
  box-shadow: 0 4px 14px color-mix(in srgb, var(--text) 8%, transparent);
}

.calendar-page .cal-filter-bar {
  gap: 8px;
  padding: 10px 12px;
  border-color: var(--border);
  border-radius: 14px;
  background: var(--surface-subtle);
}

.calendar-page .cal-filter-label {
  color: var(--muted);
  font-size: 9px;
  font-weight: 700;
  letter-spacing: .1em;
  text-transform: uppercase;
}

/* Die Beschriftungsspalte war auf 88px festgelegt – zu schmal für
   „Abwesenheiten:“. Das Label lief über seine Spalte hinaus und stieß an den
   ersten Schalter, während die kürzeren Beschriftungen viel Luft hatten. Feste
   Breite plus eigener Spaltenabstand hält alle Reihen in einer Flucht. */
.calendar-page .cal-filter-group {
  grid-template-columns: 112px minmax(0, 1fr);
  column-gap: 14px;
}

.calendar-page .cal-chip {
  min-height: 32px;
  border-radius: 9px;
  background: var(--surface-raised);
}

.calendar-page .cal-chip.active,
.calendar-page .cal-chip.active:hover,
.calendar-page .cal-chip.active:focus-visible,
.calendar-page .cal-chip.active:active {
  color: var(--accent);
  border-color: color-mix(in srgb, var(--accent) 55%, var(--border));
  background: color-mix(in srgb, var(--accent) 7%, var(--surface-raised));
}

.calendar-page .cal-grid.month-view,
.calendar-page .cal-grid.week-mobile-view {
  gap: 3px;
}

/* Spaltenfluss, damit der Abwesenheitsstreifen mit margin-top: auto an den
   unteren Rand der Zelle sinkt – sonst haengt er direkt unter den Terminen und
   sitzt in jeder Zelle auf einer anderen Hoehe. */
.calendar-page .cal-day {
  display: flex;
  flex-direction: column;
  border: 1px solid transparent;
  border-radius: 9px;
  background: var(--surface-subtle);
}

.calendar-page .cal-day:hover {
  border-color: color-mix(in srgb, var(--accent) 32%, var(--border));
  background: color-mix(in srgb, var(--accent) 5%, var(--surface-subtle));
}

.calendar-page .cal-day.today {
  outline: 0;
  border-color: var(--accent);
  box-shadow: inset 0 0 0 1px var(--accent);
}

.calendar-page :is(.cal-week-column, .cal-day-panel) {
  border-color: var(--border);
  background: var(--surface-subtle);
}

/* Abwesenheiten-Ebene: bewusst neutral gehalten. Die Termintypen tragen im
   Kalender ihre eigenen, frei konfigurierten Farben – eine weitere bunte
   Markierung würde mit ihnen konkurrieren. Nur die Zahl steht in Textfarbe,
   damit sie ablesbar bleibt. */
.calendar-page .cal-absence-strip {
  margin-top: auto;
  padding: 2px 6px;
  border-radius: 6px;
  border: 1px solid var(--border);
  background: var(--surface-raised);
  color: var(--muted);
  font-size: 10px;
  font-weight: 600;
  letter-spacing: .02em;
  line-height: 1.4;
}

.calendar-page .cal-absence-strip {
  overflow: hidden;
}

.calendar-page .cal-absence-head {
  display: flex;
  align-items: center;
  gap: 5px;
  min-width: 0;
}

.calendar-page .cal-absence-count {
  color: var(--text);
  font-size: 11px;
  font-weight: 700;
}

/* Wochenansicht: Dort tragen die Spalten wenige Termine, also stehen die Namen
   direkt im Streifen statt nur im Tooltip. */
.calendar-page .cal-absence-strip.has-names {
  padding: 5px 7px;
}

.calendar-page .cal-absence-names {
  margin-top: 2px;
  color: var(--text);
  font-size: 10px;
  font-weight: 500;
  letter-spacing: 0;
  line-height: 1.45;
}

/* Eigene Abwesenheit: immer sichtbar und bewusst anders als die Teamebene –
   dort steht eine Zahl, hier eine Aussage über einen selbst. Bestätigt in
   Erfolgsfarbe, offen in Achtungsfarbe, weil genau das die Information ist. */
.calendar-page .cal-own-absence {
  margin-top: auto;
  overflow: hidden;
  padding: 2px 6px;
  border-radius: 6px;
  border: 1px solid color-mix(in srgb, var(--success) 45%, transparent);
  background: color-mix(in srgb, var(--success) 12%, var(--surface-raised));
  color: color-mix(in srgb, var(--success) 80%, var(--text));
  font-size: 10px;
  font-weight: 700;
  letter-spacing: .02em;
  line-height: 1.4;
}

.calendar-page .cal-own-absence.is-pending {
  border-color: color-mix(in srgb, var(--caution) 50%, transparent);
  background: color-mix(in srgb, var(--caution) 14%, var(--surface-raised));
  color: color-mix(in srgb, var(--caution) 85%, var(--text));
}

.calendar-page .cal-own-absence-text {
  display: block;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}

/* Legendenpunkte der eigenen Abmeldung – dieselben Farben wie die Markierung im
   Raster, damit die Zuordnung ohne Nachdenken gelingt. */
.calendar-page .cal-legend-dot.cal-legend-own {
  background: color-mix(in srgb, var(--success) 70%, var(--surface-raised));
  box-shadow: inset 0 0 0 1px color-mix(in srgb, var(--success) 60%, transparent);
}

.calendar-page .cal-legend-dot.cal-legend-own-pending {
  background: color-mix(in srgb, var(--caution) 70%, var(--surface-raised));
  box-shadow: inset 0 0 0 1px color-mix(in srgb, var(--caution) 60%, transparent);
}

/* Stehen beide Hinweise in einer Zelle, uebernimmt der eigene den Abstand nach
   oben und die Teamzahl folgt direkt darunter. */
.calendar-page .cal-own-absence + .cal-absence-strip {
  margin-top: 3px;
}

.calendar-page .cal-day-panel .cal-own-absence {
  margin-top: 14px;
  padding: 7px 10px;
  font-size: 12px;
}

/* Tagesansicht: Hier ist Platz für die Namen, die im Raster nur als Zahl
   erscheinen. Der Grund bleibt auch hier außen vor. */
.calendar-page .cal-day-absences {
  margin-top: 14px;
  padding-top: 12px;
  border-top: 1px solid var(--border);
}

.calendar-page .cal-day-absences-title {
  margin-bottom: 4px;
  color: var(--muted);
  font-size: 11px;
  font-weight: 700;
  letter-spacing: .07em;
  text-transform: uppercase;
}

.calendar-page .cal-day-absences-names {
  color: var(--text);
  font-size: 13px;
  line-height: 1.5;
}

.calendar-page :is(.cal-week-column.today, .cal-day-panel.today) {
  border-color: var(--accent);
  box-shadow: inset 3px 0 0 var(--accent);
}

.calendar-page .cal-day-panel-title,
.calendar-page .cal-week-header-date {
  color: var(--text);
  font-family: "Barlow Condensed", sans-serif;
  font-weight: 700;
}

.calendar-page .cal-modal-bg {
  padding: max(14px, env(safe-area-inset-top)) max(14px, env(safe-area-inset-right)) max(14px, env(safe-area-inset-bottom)) max(14px, env(safe-area-inset-left));
  background: rgba(5, 9, 13, .7);
  backdrop-filter: blur(9px);
}

.calendar-page .cal-modal {
  color: var(--text);
  border-color: var(--border);
  border-radius: 18px;
  background: var(--surface-raised);
  box-shadow: var(--shadow);
}

.calendar-page .cal-modal h3 {
  color: var(--text);
  font-family: "Barlow Condensed", sans-serif;
  font-size: 28px;
  font-weight: 700;
}

.calendar-page .cal-team-picker-trigger,
.calendar-page .cal-modal :is(input, select, textarea) {
  color: var(--text);
  border-color: var(--border);
  background: var(--input);
}

.calendar-page .utensil-qty-controls {
  gap: 8px;
}

.calendar-page .utensil-qty-btn {
  width: 44px;
  min-width: 44px;
  height: 44px;
  min-height: 44px;
  padding: 0;
  color: var(--text);
  border-color: var(--border);
  border-radius: 10px;
  background: var(--surface-subtle);
}

.calendar-page input.utensil-qty-input {
  width: 56px;
  min-width: 56px;
  height: 44px;
  min-height: 44px;
  padding: 0 6px;
  appearance: textfield;
  -moz-appearance: textfield;
  color: var(--text);
  -webkit-text-fill-color: var(--text);
  border-radius: 10px;
  background: var(--input);
  font-weight: 700;
  opacity: 1;
  text-align: center;
}

.calendar-page input.utensil-qty-input::-webkit-inner-spin-button,
.calendar-page input.utensil-qty-input::-webkit-outer-spin-button {
  margin: 0;
  appearance: none;
  -webkit-appearance: none;
}

/* Equipment — assigned numbers are the personal anchor of the page. */
.equipment-my-page .equipment-number-card {
  padding: 0;
  overflow: hidden;
}

.equipment-my-page .number-widget {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(180px, 1fr));
  gap: 1px;
  margin: 0;
  background: var(--border);
}

.equipment-my-page .number-widget .number-box {
  align-items: flex-start;
  justify-content: center;
  min-height: 132px;
  padding: 22px 24px;
  background: var(--surface-raised);
}

.equipment-my-page .number-box .label {
  color: var(--muted);
  font-size: 9px;
  font-weight: 700;
  letter-spacing: .12em;
  text-transform: uppercase;
}

.equipment-my-page .number-widget-centered .number-box .value {
  margin-top: 6px;
  color: var(--accent);
  font-family: "Barlow Condensed", sans-serif;
  font-size: 52px;
  font-weight: 700;
  line-height: .9;
}

.equipment-my-page .equipment-list-header {
  align-items: center;
  gap: 14px;
  margin-bottom: 0;
}

.equipment-my-page .equipment-list-header .card-title {
  margin: 0;
}

.equipment-my-page .eq-badge {
  border-radius: 8px;
  background: var(--surface-subtle);
}

.equipment-my-page .eq-badge.partial {
  color: var(--caution);
  border-color: color-mix(in srgb, var(--caution) 45%, var(--border));
  background: color-mix(in srgb, var(--caution) 9%, var(--surface-raised));
}

/* Physio — purple remains a domain accent, while surfaces stay in the system. */
.physio-portal-page {
  --physio-accent: #ad59c7;
}

.physio-portal-page .physio-cal-nav {
  gap: 12px;
  margin-bottom: 14px;
  padding: 14px;
  border: 1px solid var(--border);
  border-radius: 16px;
  background: var(--surface-raised);
  box-shadow: var(--shadow-soft);
}

.physio-portal-page .physio-nav-center h3 {
  color: var(--text);
  font-family: "Barlow Condensed", sans-serif;
  font-size: 26px;
  font-weight: 700;
  letter-spacing: -.01em;
}

.physio-portal-page .physio-availability-card {
  border-left: 3px solid var(--physio-accent);
}

.physio-portal-page .physio-avail-header {
  display: flex;
  align-items: baseline;
  gap: 10px;
  flex-wrap: wrap;
}

.physio-portal-page .physio-avail-header h4 {
  margin: 0;
  color: var(--text);
  font-family: "Barlow Condensed", sans-serif;
  font-size: 25px;
}

.physio-portal-page .physio-avail-time {
  color: var(--muted);
  font-size: 13px;
}

.physio-portal-page .physio-slot-btn {
  min-height: 46px;
  border-radius: 10px;
  color: var(--text);
  background: var(--surface-subtle);
}

.physio-portal-page .physio-slot-btn.free {
  color: var(--success);
  border-color: color-mix(in srgb, var(--success) 52%, var(--border));
  background: color-mix(in srgb, var(--success) 8%, var(--surface-raised));
}

.physio-portal-page .physio-slot-btn.mine {
  color: var(--physio-accent);
  border-color: color-mix(in srgb, var(--physio-accent) 58%, var(--border));
  background: color-mix(in srgb, var(--physio-accent) 10%, var(--surface-raised));
}

.physio-portal-page .physio-slot-btn.booked-other {
  color: var(--muted);
  border-color: var(--border);
  background: var(--surface-subtle);
}

.physio-portal-page .physio-legend {
  margin: 2px 0 0;
  padding: 10px 4px;
}

.physio-portal-page .physio-legend-dot.mine {
  border-color: var(--physio-accent);
  background: color-mix(in srgb, var(--physio-accent) 18%, transparent);
}

.physio-portal-page #physio-book-overlay {
  background: rgba(5, 9, 13, .7);
  backdrop-filter: blur(9px);
}

.physio-portal-page #physio-book-dialog {
  width: min(420px, calc(100vw - 28px));
  padding: 22px;
  color: var(--text);
  border-color: var(--border);
  border-radius: 18px;
  background: var(--surface-raised);
  box-shadow: var(--shadow);
}

.physio-portal-page #physio-book-dialog h4 {
  color: var(--text);
  font-family: "Barlow Condensed", sans-serif;
  font-size: 28px;
  font-weight: 700;
}

.physio-portal-page .physio-dialog-label {
  margin-bottom: 10px;
  color: var(--muted);
  font-size: 9px;
  font-weight: 700;
  letter-spacing: .1em;
  text-transform: uppercase;
}

.physio-portal-page .physio-dialog-note-label {
  margin-bottom: 6px;
}

.physio-portal-page .book-reason-btn,
.physio-portal-page #physio-book-note {
  color: var(--text);
  border-color: var(--border);
  border-radius: 10px;
  background: var(--input);
}

.physio-portal-page .my-booking-note {
  border-left-color: var(--physio-accent);
}

.content-page .card-title-row {
  gap: 16px;
}

.account-content-page .container > .card {
  max-width: 920px;
  margin-right: auto;
  margin-left: auto;
}

.account-content-page .container > .msg {
  max-width: 920px;
  margin-right: auto;
  margin-left: auto;
}

@media (max-width: 1180px) {
  .content-page .stats-grid-user {
    grid-template-columns: repeat(3, minmax(0, 1fr));
  }
}

/* Login */
.login-page {
  overflow: hidden;
}

.login-shell {
  display: grid;
  grid-template-columns: minmax(0, 1.08fr) minmax(420px, .92fr);
  min-height: 100vh;
  min-height: 100svh;
}

.login-club-panel {
  position: relative;
  display: flex;
  flex-direction: column;
  justify-content: space-between;
  overflow: hidden;
  padding: max(34px, env(safe-area-inset-top)) 46px max(40px, env(safe-area-inset-bottom));
  background: #111b25;
  color: #f7f8f9;
}

.login-club-topline {
  position: relative;
  z-index: 2;
  display: flex;
  align-items: flex-start;
  justify-content: space-between;
  gap: 24px;
}

.login-club-brand {
  display: inline-flex;
  align-items: center;
  gap: 13px;
  color: #f7f8f9;
}

.login-club-brand:hover {
  color: #f7f8f9;
}

.login-club-brand img {
  width: 49px;
  height: 61px;
  object-fit: contain;
  filter: drop-shadow(0 8px 16px rgba(0, 0, 0, .28));
}

.login-club-brand span {
  display: flex;
  flex-direction: column;
  gap: 3px;
}

.login-club-brand strong {
  font-size: 17px;
  letter-spacing: -.03em;
}

.login-club-brand small {
  color: #aeb9c4;
  font-size: 9px;
  font-weight: 700;
  letter-spacing: .18em;
  text-transform: uppercase;
}

.login-page .login-theme-control {
  width: 190px;
  border-color: #33414e;
  background: #0b141c;
}

.login-page .login-theme-control .theme-option {
  min-height: 44px;
  color: #94a2ae;
}

.login-page .login-theme-control .theme-option.is-selected {
  background: #202c37;
  color: #ff5364;
}

.login-club-copy {
  position: relative;
  z-index: 2;
  max-width: 640px;
  margin: auto 0;
  padding: 68px 0 54px;
}

.login-eyebrow,
.login-form-kicker {
  color: #ff5364;
  font-size: 10px;
  font-weight: 700;
  letter-spacing: .18em;
  text-transform: uppercase;
}

.login-club-copy h1 {
  margin: 16px 0 20px;
  font-family: "Barlow Condensed", "Arial Narrow", sans-serif;
  font-size: clamp(64px, 7.2vw, 116px);
  font-weight: 700;
  letter-spacing: -.045em;
  line-height: .78;
  text-transform: uppercase;
}

.login-club-copy p {
  max-width: 480px;
  margin: 0;
  color: #abb7c1;
  font-size: 14px;
  line-height: 1.65;
}

.login-club-watermark {
  position: absolute;
  right: 3vw;
  bottom: 68px;
  color: transparent;
  font-family: "Barlow Condensed", sans-serif;
  font-size: clamp(220px, 31vw, 540px);
  font-weight: 800;
  letter-spacing: -.08em;
  line-height: .7;
  opacity: .1;
  -webkit-text-stroke: 2px #dbe2e8;
  pointer-events: none;
  user-select: none;
}

.club-stripe,
.player-hero-stripe {
  position: absolute;
  display: grid;
  grid-template-columns: 9px 5px 9px;
  gap: 4px;
  pointer-events: none;
}

.club-stripe {
  top: 0;
  right: 26px;
  bottom: 0;
}

.club-stripe i,
.player-hero-stripe i {
  display: block;
  background: #d4142a;
}

.club-stripe i:nth-child(2),
.player-hero-stripe i:nth-child(2) {
  background: #f4f5f2;
}

.login-form-panel {
  display: flex;
  flex-direction: column;
  min-width: 0;
  padding: max(32px, env(safe-area-inset-top)) max(44px, 7vw) max(22px, env(safe-area-inset-bottom));
  background: var(--bg);
}

.login-form-inner {
  width: min(100%, 440px);
  margin: auto;
}

.login-form-heading {
  margin-bottom: 34px;
}

.login-form-heading h2 {
  margin: 12px 0 8px;
  color: var(--text);
  font-family: "Barlow Condensed", "Arial Narrow", sans-serif;
  font-size: 54px;
  font-weight: 700;
  letter-spacing: -.035em;
  line-height: .95;
}

.login-form-heading p {
  margin: 0;
  color: var(--muted);
  font-size: 13px;
}

.login-form {
  display: flex;
  flex-direction: column;
  gap: 20px;
}

.login-page .login-form input:not([type="checkbox"]) {
  min-height: 54px;
  border-radius: 12px;
  font-size: 16px;
}

.login-page .password-toggle {
  width: 44px;
  min-width: 44px;
  min-height: 44px;
  color: var(--muted);
}

/* Die Augen-Symbole tragen nur eine viewBox, keine Maße – ohne Größenangabe
   fällt ein SVG auf 300x150 zurück und wird im Knopf so beschnitten, dass
   nichts Erkennbares übrig bleibt. Gilt für alle Passwortfelder. */
.redesign-page .password-toggle,
.login-page .password-toggle {
  width: 38px;
  min-width: 38px;
  height: 38px;
  min-height: 38px;
  border-radius: 9px;
  color: var(--muted);
}

.redesign-page .password-toggle :is(.icon-eye, .icon-eye-off),
.login-page .password-toggle :is(.icon-eye, .icon-eye-off) {
  width: 19px;
  height: 19px;
  flex: 0 0 auto;
}

@media (hover: hover) {
  .redesign-page .password-toggle:hover,
  .login-page .password-toggle:hover {
    background: color-mix(in srgb, var(--accent) 9%, transparent);
    color: var(--accent);
  }
}

.redesign-page .password-toggle:focus-visible,
.login-page .password-toggle:focus-visible {
  outline: none;
  box-shadow: 0 0 0 3px var(--focus-ring);
}

.login-remember {
  display: flex;
  align-items: center;
  gap: 11px;
  width: fit-content;
  color: var(--muted);
  font-size: 12px;
  cursor: pointer;
}

.login-page .login-remember input {
  flex: 0 0 auto;
  width: 20px;
  height: 20px;
  min-height: 20px;
  padding: 0;
  accent-color: var(--accent);
}

.login-page .login-submit {
  display: flex;
  align-items: center;
  justify-content: space-between;
  min-height: 56px;
  margin-top: 2px;
  padding: 12px 18px;
  border-radius: 12px;
  background: var(--accent);
  color: #fff;
  font-size: 14px;
}

.login-page .login-submit span {
  font-size: 22px;
  font-weight: 400;
}

.login-footer {
  margin-top: auto;
  padding-top: 28px;
  color: var(--muted);
  font-size: 10px;
  text-align: center;
}

/* Player home */
.player-hero {
  position: relative;
  display: flex;
  align-items: center;
  min-height: 264px;
  overflow: hidden;
  margin-bottom: 16px;
  padding: 38px 42px;
  border-radius: 24px;
  background: var(--hero);
  color: var(--text-on-dark);
  box-shadow: 0 26px 70px rgba(4, 10, 16, .25);
}

.player-hero-copy {
  position: relative;
  z-index: 2;
  max-width: 650px;
}

.player-hero-meta {
  display: flex;
  align-items: center;
  gap: 10px;
  color: var(--muted-on-dark);
  font-size: 9px;
  font-weight: 700;
  letter-spacing: .15em;
  text-transform: uppercase;
}

.player-hero-meta > span[aria-hidden] {
  width: 3px;
  height: 3px;
  border-radius: 50%;
  background: #ff5364;
}

.player-hero h2 {
  margin: 18px 0 15px;
  font-family: "Barlow Condensed", "Arial Narrow", sans-serif;
  font-size: clamp(54px, 5.1vw, 80px);
  font-weight: 700;
  letter-spacing: -.045em;
  line-height: .82;
  text-transform: uppercase;
}

.player-hero h2 span,
.player-hero h2 strong {
  display: block;
}

.player-hero h2 span {
  color: #aeb9c3;
  font-size: .52em;
  font-weight: 600;
  letter-spacing: .01em;
}

/* Kein overflow: hidden hier: Bei einer Zeilenhoehe von .82 ragen Umlautpunkte
   und Akzente über die Zeilenbox hinaus und wurden oben abgeschnitten. Das
   frühere text-overflow: ellipsis konnte ohnehin nie greifen – dafür fehlte
   white-space: nowrap. Lange Namen brechen stattdessen um. */
.player-hero h2 strong {
  max-width: 850px;
  overflow-wrap: anywhere;
}

.player-hero p {
  max-width: 470px;
  margin: 0;
  color: var(--muted-on-dark);
  font-size: 13px;
}

.player-identity-number {
  position: absolute;
  right: 54px;
  top: 50%;
  color: transparent;
  font-family: "Barlow Condensed", "Arial Narrow", sans-serif;
  font-size: clamp(220px, 23vw, 390px);
  font-weight: 800;
  letter-spacing: -.08em;
  line-height: .7;
  opacity: .17;
  transform: translateY(-48%);
  -webkit-text-stroke: 2px #e8edf1;
  pointer-events: none;
  user-select: none;
}

.player-identity-number.is-wordmark {
  right: 34px;
  font-size: clamp(160px, 19vw, 300px);
}

.player-hero-stripe {
  right: 34px;
  bottom: 0;
  left: auto;
  width: 31px;
  height: 72px;
}

.player-dashboard-grid {
  display: grid;
  grid-template-columns: repeat(12, minmax(0, 1fr));
  grid-template-areas:
    "today today today today today today today today today finance finance finance"
    "tomorrow tomorrow tomorrow tomorrow tomorrow tomorrow tomorrow tomorrow tomorrow tomorrow tomorrow tomorrow"
    "tiles tiles tiles tiles tiles tiles tiles tiles tiles tiles tiles tiles";
  gap: 14px;
  align-items: stretch;
}

.player-dashboard-grid .home-today { grid-area: today; }
.player-dashboard-grid .home-tomorrow { grid-area: tomorrow; }
.player-dashboard-grid .home-finances { grid-area: finance; }

/* Anwesenheit, Physio, Utensilien und Wettbewerb teilen eine Reihe. Als eigener
   Container verteilen sie die Breite unter sich: vier Karten ergeben Viertel,
   zwei ergeben Haelften. Feste Rasterplaetze hinterliessen eine Luecke, sobald
   eine Karte fehlte – etwa bei Nutzern ohne Trainingskader. */
.player-dashboard-grid .db-tiles {
  grid-area: tiles;
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(200px, 1fr));
  gap: 14px;
  align-items: stretch;
}

/* Fallen alle vier Karten weg – etwa bei Funktionaersrollen ohne Kaderbezug –,
   verschwindet der Container samt Abstand. Nicht :empty, denn Zeilenumbrueche
   und Kommentare im Template zaehlen als Inhalt. */
.player-dashboard-grid .db-tiles:not(:has(> *)) {
  display: none;
}

.player-dashboard-grid .db-card {
  min-width: 0;
  padding: 20px 22px;
}

.player-dashboard-grid .db-card-session-group {
  padding: 0;
}

.player-dashboard-grid .sess-item-colored {
  padding: 22px 24px 22px 30px;
}

.player-dashboard-grid .db-card-slim .sess-item-colored {
  padding: 17px 22px 17px 28px;
}

.player-dashboard-grid .sess-item-colored::before {
  width: 4px;
}

.player-dashboard-grid .sess-header {
  margin-bottom: 11px;
}

.player-dashboard-grid .sess-kicker,
.player-dashboard-grid .db-kicker {
  color: var(--muted);
  font-size: 9px;
  font-weight: 700;
  letter-spacing: .15em;
}

.player-dashboard-grid .sess-badge {
  padding: 3px 8px;
  border-radius: 5px;
  font-size: 9px;
}

.player-dashboard-grid .sess-date-big,
.home-empty-title {
  color: var(--text);
  font-family: "Barlow Condensed", "Arial Narrow", sans-serif;
  font-size: 34px;
  font-weight: 700;
  letter-spacing: -.025em;
  line-height: 1;
}

.home-empty-title {
  margin: 18px 0 8px;
}

.player-dashboard-grid .sess-date-small {
  color: var(--text);
  font-family: "Barlow Condensed", sans-serif;
  font-size: 23px;
  letter-spacing: -.02em;
}

.player-dashboard-grid .sess-meta {
  gap: 10px 22px;
  margin-top: 16px;
}

.player-dashboard-grid .session-fact {
  display: flex;
  flex-direction: column;
  align-items: flex-start;
  gap: 2px;
}

.player-dashboard-grid .session-fact small {
  color: var(--muted);
  font-size: 8px;
  font-weight: 700;
  letter-spacing: .12em;
  text-transform: uppercase;
}

.player-dashboard-grid .session-fact > span {
  color: var(--text);
  font-size: 12px;
  font-weight: 600;
}

.squad-status-row {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 7px;
  margin-top: 14px;
}

.squad-status {
  display: inline-flex;
  align-items: center;
  min-height: 29px;
  padding: 5px 10px;
  border: 1px solid;
  border-radius: 8px;
  font-size: 10px;
  font-weight: 700;
}

.squad-status.is-nominated {
  border-color: color-mix(in srgb, var(--success) 34%, transparent);
  background: color-mix(in srgb, var(--success) 11%, transparent);
  color: var(--success);
}

.squad-status.is-not-nominated {
  border-color: color-mix(in srgb, var(--caution) 34%, transparent);
  background: color-mix(in srgb, var(--caution) 11%, transparent);
  color: var(--caution);
}

.squad-status.is-ticket {
  border-color: color-mix(in srgb, #378bd6 34%, transparent);
  background: color-mix(in srgb, #378bd6 11%, transparent);
  color: #378bd6;
}

.squad-status-row .sess-cal-link {
  margin: 0 0 0 auto;
}

.player-dashboard-grid .home-finances {
  position: relative;
  overflow: hidden;
}

.player-dashboard-grid .dashboard-card-link {
  color: var(--text);
  text-decoration: none;
}

.player-dashboard-grid :is(.dashboard-card-link, .dashboard-card-toggle, [data-card-href]) {
  cursor: pointer;
  transition: border-color .16s ease, background-color .16s ease, transform .16s ease;
}

.player-dashboard-grid :is(.dashboard-card-link, .dashboard-card-toggle, .home-attendance):hover {
  background: color-mix(in srgb, var(--accent) 3%, var(--card));
  color: var(--text);
}

.player-dashboard-grid [data-card-href]:hover {
  background: color-mix(in srgb, var(--accent) 3%, var(--card));
}

.player-dashboard-grid :is(.dashboard-card-link, .dashboard-card-toggle, [data-card-href]):focus-visible {
  outline: 2px solid var(--accent);
  outline-offset: -3px;
}

.player-dashboard-grid .home-attendance {
  display: flex;
  flex-direction: column;
  min-height: 132px;
  color: var(--text);
  text-decoration: none;
}

.player-dashboard-grid .home-attendance:hover {
  color: var(--text);
}

/* Persoenlicher Belastungseinstieg: bewusst als ruhige Dashboard-Kachel und
   nicht als Warnwert. Die Analyse beginnt erst auf der Zielseite; hier genuegt
   die bekannte Verlaufslinie als Orientierung. */
.player-dashboard-grid .home-personal-load {
  position: relative;
  display: flex;
  min-height: 132px;
  overflow: hidden;
  flex-direction: column;
}

.player-dashboard-grid .home-personal-load strong {
  margin-top: 3px;
  color: var(--text);
  font-family: "Barlow Condensed", sans-serif;
  font-size: 23px;
  font-weight: 700;
  line-height: 1;
}

.player-dashboard-grid .home-personal-load-period {
  margin-top: auto;
  color: var(--muted);
  font-size: 9px;
  font-weight: 700;
  letter-spacing: .08em;
  text-transform: uppercase;
}

.player-dashboard-grid .home-personal-load-bars {
  height: 20px;
  min-width: 38px;
  margin-top: 0;
  flex: 1 1 auto;
}

.player-dashboard-grid .home-personal-load-footer {
  display: flex;
  align-items: flex-end;
  gap: 8px;
  min-width: 0;
  margin-top: 8px;
}

/* Auf der halbbreiten Mobile-Karte bleibt die Ampel ein kurzer Zusatz zum
   Verlauf. Die ausfuehrliche, rein beschreibende Einordnung steht auf der Zielseite. */
.player-dashboard-grid .home-personal-load-status {
  min-height: 20px;
  max-width: 105px;
  padding: 2px 7px;
  overflow: hidden;
  flex: 0 1 auto;
  font-size: 8px;
  text-overflow: ellipsis;
}

.player-dashboard-grid .home-personal-load-icon {
  position: absolute;
  top: 17px;
  right: 18px;
  display: inline-flex;
  color: color-mix(in srgb, var(--accent) 62%, var(--muted));
}

.player-dashboard-grid .home-personal-load-icon .quick-action-icon {
  width: 24px;
  height: 24px;
}

/* Rein lesende Saisonkarte: Sportwerte statt einer generischen Beschreibung.
   Die Symbole fuer Tor und Karte stammen aus demselben System wie der Spielbericht. */
.player-dashboard-grid .home-personal-season {
  display: flex;
  min-height: 132px;
  flex-direction: column;
}

.player-dashboard-grid .home-personal-season > strong {
  margin-top: 5px;
  overflow: hidden;
  color: var(--text);
  font-family: "Barlow Condensed", sans-serif;
  font-size: 21px;
  font-weight: 700;
  line-height: 1;
  text-overflow: ellipsis;
  white-space: nowrap;
}

.player-dashboard-grid .home-season-scoreline {
  display: grid;
  grid-template-columns: repeat(4, minmax(0, 1fr));
  gap: 7px;
  margin-top: auto;
  padding-top: 12px;
}

.player-dashboard-grid .home-season-score {
  display: grid;
  grid-template-columns: auto auto;
  align-items: center;
  justify-content: start;
  gap: 2px 4px;
  min-width: 0;
}

.player-dashboard-grid .home-season-score .match-event-icon {
  width: 14px;
  height: 14px;
  color: var(--accent);
}

.player-dashboard-grid .home-season-score b {
  color: var(--text);
  font-family: "Barlow Condensed", sans-serif;
  font-size: 19px;
  font-variant-numeric: tabular-nums;
  line-height: 1;
}

.player-dashboard-grid .home-season-score small {
  grid-column: 1 / -1;
  overflow: hidden;
  color: var(--muted);
  font-size: 7px;
  font-weight: 700;
  letter-spacing: .04em;
  text-overflow: ellipsis;
  text-transform: uppercase;
  white-space: nowrap;
}

/* Kennzahl mit Fortschrittsbalken: eine grosse Zahl, eine kurze Einordnung
   daneben und darunter der Balken. Anwesenheitsquote und Wettbewerbspunkte
   verwenden denselben Baustein; die Karte liefert `--rate-value` (Fuellstand)
   und ueber eine `.rate-level-*`-Klasse die Farbe. */
.rate-row {
  display: flex;
  align-items: flex-end;
  gap: 11px;
  margin: auto 0 12px;
}

/* Bewertung der Quote wie unter „Meine Anwesenheit": ab 100 % gut, unter 80 %
   kritisch, dazwischen Achtung. Wert und Balken teilen die Farbe über eine
   Variable, damit die Schwelle nur an einer Stelle steht. */
.rate-level-success { --rate-color: var(--success); }
.rate-level-warning { --rate-color: var(--caution); }
.rate-level-danger { --rate-color: var(--danger); }

.rate-row strong {
  color: var(--rate-color, var(--text));
  font-family: "Barlow Condensed", sans-serif;
  font-size: 42px;
  font-weight: 700;
  letter-spacing: -.025em;
  line-height: .8;
}

.rate-row > span {
  color: var(--muted);
  font-size: 9px;
  font-weight: 700;
  letter-spacing: .08em;
  line-height: 1.3;
  text-transform: uppercase;
}

.rate-row small {
  font-size: 8px;
  font-weight: 500;
}

.rate-track {
  height: 4px;
  overflow: hidden;
  border-radius: 999px;
  background: var(--surface-pressed);
}

.rate-track span {
  display: block;
  width: var(--rate-value);
  height: 100%;
  border-radius: inherit;
  background: var(--rate-color, var(--accent));
}

.player-dashboard-grid .home-finances::after {
  content: "€";
  position: absolute;
  right: -7px;
  bottom: -35px;
  color: var(--text);
  font-family: "Barlow Condensed", sans-serif;
  font-size: 170px;
  font-weight: 800;
  line-height: 1;
  opacity: .025;
  pointer-events: none;
}

.player-dashboard-grid .fines-sum {
  color: var(--text);
  font-family: "Barlow Condensed", sans-serif;
  font-size: 48px;
  font-weight: 700;
  letter-spacing: -.02em;
}

.player-dashboard-grid .fines-sum.red {
  color: var(--danger);
}

.player-dashboard-grid .home-competition {
  display: flex;
  min-height: 132px;
  flex-direction: column;
}

.player-dashboard-grid .competition-score {
  color: var(--text);
  font-family: "Barlow Condensed", sans-serif;
  font-size: 40px;
  font-weight: 700;
  letter-spacing: -.025em;
  line-height: .8;
}

/* Weg bis zur naechsten Schwelle. Steht direkt unter dem Balken und traegt
   dessen Aussage in Worten. */
.player-dashboard-grid .competition-target {
  margin-top: 7px;
  overflow: hidden;
  color: var(--muted);
  font-size: 9px;
  font-weight: 700;
  letter-spacing: .08em;
  text-overflow: ellipsis;
  text-transform: uppercase;
  white-space: nowrap;
}

/* Bereits erreichte Schwellen: ruhige Zeile, keine Pille. Die gruene Pille steht
   in der Rangliste fuer "jetzt einloesbar" - hier geht es um Vergangenes. */
.player-dashboard-grid .competition-reached {
  margin-top: 7px;
  color: var(--muted);
  font-size: 9px;
  font-weight: 700;
  letter-spacing: .08em;
  line-height: 1.5;
  text-transform: uppercase;
}

/* Wettbewerbsfarben aus Tokens. Die Basiswerte in app.css stammen aus der reinen
   Dunkelansicht; Punktestand und Schwellen-Pillen stehen inzwischen auch auf der
   Startseite und muessen in beiden Themes lesbar sein. Die Regeln stehen bewusst
   nach der Kachelregel, damit die Statusfarbe den Standardton uebersteuert. */
.redesign-page .competition-score-positive {
  color: var(--success);
}

.redesign-page .competition-score-negative {
  color: var(--danger);
}

.redesign-page .competition-badge {
  border-radius: 999px;
  font-size: 10px;
  font-weight: 700;
  letter-spacing: .04em;
}

/* Zaehler der erreichten Schwellen: nur die Zahl traegt die Richtungsfarbe, der
   Rest bleibt Fliesstext. So ist die Angabe nicht mit einem Status zu verwechseln. */
.redesign-page .competition-count {
  color: var(--muted);
  white-space: nowrap;
}

.redesign-page .competition-count b {
  font-weight: 700;
}

.redesign-page .competition-count-up b {
  color: var(--success);
}

.redesign-page .competition-count-down b {
  color: var(--danger);
}

.redesign-page .competition-count-sep {
  color: var(--border);
}

.redesign-page .competition-badge-positive {
  color: var(--success);
  border-color: color-mix(in srgb, var(--success) 38%, var(--border));
  background: color-mix(in srgb, var(--success) 12%, var(--surface-raised));
}

.redesign-page .competition-badge-negative {
  color: var(--danger);
  border-color: color-mix(in srgb, var(--danger) 38%, var(--border));
  background: color-mix(in srgb, var(--danger) 12%, var(--surface-raised));
}

.player-dashboard-grid .bank-compact {
  grid-template-columns: 1fr;
  gap: 9px;
}

.player-dashboard-grid .bank-lbl {
  font-size: 8px;
  letter-spacing: .12em;
}

.player-dashboard-grid .bank-val {
  color: var(--text);
  font-size: 11px;
}

.player-dashboard-grid .fines-toggle {
  height: auto;
  min-height: 34px;
  padding: 7px 10px;
  border-radius: 8px;
  background: var(--surface-subtle);
  color: var(--muted);
  font-size: 9px;
}

.player-dashboard-grid .fines-table td,
.player-dashboard-grid .fines-table th {
  border-color: var(--border);
}

.player-home-page {
  position: relative;
  isolation: isolate;
}

.player-home-page > .container {
  position: relative;
  z-index: 1;
}

.player-home-watermark {
  position: absolute;
  right: 0;
  bottom: 8px;
  z-index: 0;
  width: clamp(280px, 20vw, 390px);
  opacity: .022;
  filter: grayscale(1);
  pointer-events: none;
  user-select: none;
}

html[data-theme="light"] .player-home-watermark {
  opacity: .052;
  filter: grayscale(1) brightness(.52) contrast(1.15);
}

.player-home-watermark img {
  display: block;
  width: 100%;
  height: auto;
}

/* Attendance */
.attendance-page .attendance-date-nav {
  margin-bottom: 14px;
  padding: 10px;
  border-radius: 15px;
}

.attendance-page .attendance-nav-bar {
  gap: 7px;
}

.attendance-page .attendance-nav-arrow {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 42px;
  min-width: 42px;
  padding: 0;
  border-radius: 10px;
  background: var(--surface-subtle);
  color: var(--text);
  font-size: 11px;
}

.attendance-page .attendance-kader-slot {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  justify-content: flex-end;
  gap: 8px;
  min-height: 36px;
}

.attendance-page a.attendance-kader-btn {
  color: #fff;
}

.attendance-page .attendance-utensil-btn {
  background: var(--accent);
  border-color: var(--accent);
  color: #fff;
}

.attendance-page .utensil-qty-controls {
  gap: 8px;
}

.attendance-page .utensil-qty-btn {
  width: 44px;
  min-width: 44px;
  height: 44px;
  min-height: 44px;
  padding: 0;
  background: var(--surface-subtle);
  border-color: var(--border);
  color: var(--text);
}

.attendance-page .utensil-qty-input {
  width: 56px;
  height: 44px;
  min-height: 44px;
  padding: 0 6px;
  appearance: textfield;
  -moz-appearance: textfield;
  background: var(--input);
  color: var(--text);
  -webkit-text-fill-color: var(--text);
  font-weight: 700;
  opacity: 1;
  text-align: center;
}

html[data-theme="light"] .attendance-page .utensil-qty-input {
  color-scheme: light;
}

html[data-theme="dark"] .attendance-page .utensil-qty-input {
  color-scheme: dark;
}

.attendance-page .utensil-qty-input::-webkit-inner-spin-button,
.attendance-page .utensil-qty-input::-webkit-outer-spin-button {
  margin: 0;
  appearance: none;
  -webkit-appearance: none;
}

.attendance-page .attendance-nav-chip {
  min-height: 48px;
  padding: 8px 6px;
  border-radius: 10px;
  background: var(--surface-subtle);
  border-color: transparent;
  color: var(--muted);
}

.attendance-page .attendance-nav-chip.active {
  background: var(--accent);
  color: #fff;
  box-shadow: 0 7px 20px rgba(212, 20, 42, .2);
}

.attendance-page .attendance-nav-chip-wd {
  font-size: 11px;
}

.attendance-page .attendance-nav-chip-ty {
  font-size: 9px;
}

.attendance-page .attendance-editor,
.attendance-page .attendance-empty-state,
.attendance-page .attendance-readonly {
  padding: 24px;
}

.attendance-page .attendance-editor-heading {
  display: flex;
  align-items: flex-start;
  justify-content: space-between;
  gap: 20px;
  margin-bottom: 22px;
  padding-bottom: 18px;
  border-bottom: 1px solid var(--border);
}

.attendance-editor-kicker {
  color: var(--accent);
  font-size: 9px;
  font-weight: 700;
  letter-spacing: .15em;
  text-transform: uppercase;
}

.attendance-page .attendance-editor-heading h2 {
  margin: 5px 0 2px;
  color: var(--text);
  font-family: "Barlow Condensed", "Arial Narrow", sans-serif;
  font-size: 38px;
  font-weight: 700;
  letter-spacing: -.025em;
  line-height: 1;
  text-transform: capitalize;
}

.attendance-page .attendance-editor-heading p {
  margin: 0;
  color: var(--muted);
  font-size: 11px;
}

.attendance-page .attendance-note-row {
  margin-bottom: 14px;
}

.attendance-page .attendance-note-actions .btn {
  min-height: 46px;
  padding: 9px 12px;
  border-radius: 10px;
  font-size: 11px;
}

/* Auswahlkaestchen in Listen.

   Die Optik stammt aus der Kadernominierung (.squad-checkbox), war dort aber
   seitenlokal definiert und deshalb nirgends sonst verfuegbar - neue Listen
   bekamen das nackte Browser-Kaestchen. Jetzt zentral; der alte Klassenname
   bleibt als Selektor bestehen, weil das JavaScript der Nominierung ihn nutzt. */
.redesign-page .app-checkbox,
.redesign-page .squad-checkbox {
  appearance: none;
  -webkit-appearance: none;
  width: 20px;
  height: 20px;
  min-height: 20px;
  padding: 0;
  border-radius: 5px;
  border: 2px solid var(--accent);
  background: transparent;
  cursor: pointer;
  vertical-align: middle;
  transition: background .15s, border-color .15s;
  flex-shrink: 0;
}

.redesign-page .app-checkbox:checked,
.redesign-page .squad-checkbox:checked {
  background: var(--accent);
  border-color: var(--accent);
  background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 12 12'%3E%3Cpath fill='%23fff' d='M2 6l3 3 5-5'/%3E%3C/svg%3E");
  background-repeat: no-repeat;
  background-position: center;
  background-size: 12px;
}

.redesign-page .app-checkbox:hover:not(:disabled),
.redesign-page .squad-checkbox:hover:not(:disabled) {
  border-color: var(--accent-2);
}

.redesign-page .app-checkbox:focus-visible,
.redesign-page .squad-checkbox:focus-visible {
  outline: 2px solid var(--accent);
  outline-offset: 2px;
}

.redesign-page .app-checkbox:disabled,
.redesign-page .squad-checkbox:disabled {
  border-color: var(--border);
  cursor: default;
  opacity: .6;
}

.redesign-page .app-checkbox:disabled:checked,
.redesign-page .squad-checkbox:disabled:checked {
  background-color: var(--muted);
  border-color: var(--muted);
}

/* Auswahlkaestchen in Listen, Tabellen und Optionsgruppen.

   Die Optik ist die der Rechnungsliste: das native Kaestchen in Vereinsfarbe. Sie lag
   bisher als seitenlokaler !important-Block in jeder betroffenen Seite (Rechnungen,
   Belege, Tickets, CSV-Import, Kalender, Wettbewerbsliste, Sponsoring, Ressourcenplan)
   und driftete dort zwischen 15, 16 und 18 Pixeln auseinander - jetzt einmal hier.

   Der Klassenname ist bewusst nicht .row-checkbox: den fragt das JavaScript der
   Rechnungsliste als Zeilen-Haken ab. Optik und Verhalten bleiben getrennte Klassen. */
.app-select-cb,
.redesign-page .app-select-cb,
.cal-team-picker-option input[type="checkbox"],
.cal-team-picker-option input[type="radio"] {
  width: 16px;
  height: 16px;
  min-height: 0;
  padding: 0;
  border: none;
  background: none;
  border-radius: 3px;
  margin: 0;
  accent-color: var(--accent);
  cursor: pointer;
  flex: 0 0 auto;
}

/* Spielverlauf als Ereignisliste.

   Eine chronologische Liste statt dreier Tabellen nach Ereignisart: der Trainer denkt
   in Minuten. Die Zeile traegt ihr Symbol vorne und bleibt dadurch auf einen Blick
   einsortierbar, ohne dass eine Ueberschrift die Art erklaeren muss. */
.redesign-page .event-add-actions {
  display: flex;
  gap: 8px;
  flex-wrap: wrap;
}

.redesign-page .event-add-actions .btn {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  min-height: 44px;
}

.redesign-page .event-list {
  display: flex;
  flex-direction: column;
  gap: 8px;
  margin-top: 12px;
}

.redesign-page .event-empty {
  margin: 4px 0;
}

.redesign-page .event-row {
  display: flex;
  align-items: center;
  gap: 8px;
  padding: 8px 10px;
  border: 1px solid var(--border);
  border-radius: 12px;
  background: var(--surface-subtle);
}

.redesign-page .event-row .match-event-icon {
  flex: 0 0 auto;
  color: var(--accent);
}

.redesign-page .event-row .event-minute {
  flex: 0 0 72px;
  text-align: right;
  font-variant-numeric: tabular-nums;
}

.redesign-page .event-row .event-minute-unit {
  flex: 0 0 auto;
  margin-left: -4px;
  color: var(--muted);
}

/* Begrenzt, damit eine Kartenzeile mit nur einem Spielerfeld nicht anders aussieht
   als eine Wechselzeile mit zweien. */
.redesign-page .event-row .event-player {
  flex: 1 1 160px;
  max-width: 300px;
  min-width: 0;
}

.redesign-page .event-row .event-position {
  flex: 0 1 150px;
  min-width: 0;
}

.redesign-page .event-row .event-arrow {
  flex: 0 0 auto;
  color: var(--muted);
}

.redesign-page .event-row .event-remove {
  flex: 0 0 auto;
  width: 36px;
  height: 36px;
  padding: 0;
  border: 1px solid var(--border);
  border-radius: 10px;
  background: var(--surface-raised);
  color: var(--muted);
  cursor: pointer;
}

.redesign-page .event-row .event-remove:hover {
  border-color: color-mix(in srgb, var(--danger) 40%, var(--border));
  color: var(--danger);
}

/* Mobil bricht die Zeile um: Symbol und Minute bleiben oben zusammen, die
   Auswahlfelder nehmen darunter die volle Breite. */
@media (max-width: 640px) {
  /* Spielrahmen: Dauer und Intensitaet bilden die Belastung, die beiden
     Torfelder das Ergebnis. Diese fachlichen Paare stehen mobil je in einer
     Zeile statt vier volle Zeilen zu verbrauchen. */
  .load-match-page .match-summary-fields {
    display: grid;
    grid-template-columns: repeat(2, minmax(0, 1fr));
    align-items: end;
    gap: 10px;
  }

  .load-match-page .match-summary-fields > .field {
    width: auto;
    min-width: 0;
  }

  /* Vier gleichwertige Ereignisarten als stabiles 2-mal-2-Raster. */
  .load-match-page .event-add-actions {
    display: grid;
    grid-template-columns: repeat(2, minmax(0, 1fr));
    flex: 1 1 100%;
    width: 100%;
  }

  .load-match-page .event-add-actions .btn {
    width: 100%;
    justify-content: center;
  }

  /* Teamkennzeichen stehen unter dem Namen. Nebeneinander addierten sich Name
     und Vereinsname sonst zur Mindestbreite der ersten Scrollspalte. */
  .load-match-page #appearance-table :is(th, td).load-col-name {
    width: 144px;
    min-width: 144px;
    max-width: 144px;
    white-space: normal;
  }

  .load-match-page #appearance-table td.load-col-name :is(.guest-badge, .status-pill) {
    display: block;
    width: fit-content;
    max-width: 100%;
    margin: 4px 0 0;
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
  }

  .redesign-page .event-row {
    flex-wrap: wrap;
    row-gap: 6px;
  }

  /* order: 1 schiebt alle Auswahlfelder hinter die Kopfzeile aus Symbol, Minute und
     Loeschknopf - sonst landet das ✕ allein in einer eigenen Zeile am Ende.
     max-width zurueckgesetzt, sonst waeren die Felder unterschiedlich breit. */
  .redesign-page .event-row .event-player,
  .redesign-page .event-row .event-position {
    flex: 1 1 100%;
    max-width: none;
    order: 1;
  }

  .redesign-page .event-row .event-arrow {
    display: none;
  }

  .redesign-page .event-row .event-remove {
    margin-left: auto;
  }
}

/* Erklaerdialog: Fliesstext mit Zwischenueberschriften in einem Modal.
   Die uebrigen Dialoge der App sind Formulare - dort gibt es keine Typografie
   fuer laengere Texte. Allgemein gehalten, damit andere Module denselben
   Baustein verwenden koennen. */
.redesign-page .explainer-body p {
  margin: 0 0 12px;
  line-height: 1.55;
  max-width: 68ch;
}

.redesign-page .explainer-body h3 {
  margin: 22px 0 8px;
  font-family: 'Barlow Condensed', sans-serif;
  font-size: 20px;
  font-weight: 700;
  letter-spacing: .01em;
}

.redesign-page .explainer-body h3:first-child {
  margin-top: 0;
}

.redesign-page .explainer-body ul {
  margin: 0 0 12px;
  padding-left: 20px;
  line-height: 1.55;
  max-width: 68ch;
}

.redesign-page .explainer-body li {
  margin-bottom: 8px;
}

.redesign-page .explainer-body .explainer-table {
  margin: 4px 0 14px;
}

/* Bezugsangabe und Erklaerung gehoeren in den Kartenkopf. Der Infoknopf bleibt
   dort auch mobil ein kleines Werkzeug statt zur vollbreiten Hauptaktion zu werden. */
.redesign-page .load-info-title-row {
  display: grid;
  grid-template-columns: minmax(0, 1fr) auto;
  align-items: start;
  gap: 12px;
}

.redesign-page .load-info-title-row > .btn.icon-only {
  justify-self: end;
  width: 32px;
}

/* Drei Werte mit klarer Rangfolge duerfen die Kartenbreite ausnutzen. Die
   allgemeinen Mobile-Tabellen verwenden max-content, was diese kurze Tabelle
   sonst links zusammenschiebt. */
.redesign-page .load-focus-table {
  width: 100%;
}

.redesign-page .load-type-source {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  white-space: nowrap;
}

.redesign-page :is(.load-player-value-badge, .load-team-value-badge) {
  padding: 3px 6px;
  font-size: 8px;
  letter-spacing: .04em;
}

.redesign-page .load-team-value-badge {
  min-width: 0;
  font-size: 9px;
  text-transform: uppercase;
}

/* Spaltenaufteilung im Belastungsmodul.

   Bewusst ohne Tabellenpraefix: dieselben vier Spaltenarten kommen in allen
   Tabellen des Moduls vor, und eine Regel je Tabelle waere dieselbe Regel
   viermal. Ohne feste Breiten nimmt sich die Namensspalte die halbe Tabelle,
   und die Zahlen stehen weit auseinander, obwohl man sie vergleichen will.

   Nur ab Tablet: mobil wird die Zeile ohnehin zur Karte, und eine Breite von
   1% wuerde dort die Beschriftung zerquetschen. */
@media (min-width: 641px) {
  /* Zahlen: Inhaltsbreite, rechtsbuendig, gleiche Ziffernbreiten - so stehen
     Hunderter unter Hundertern und man liest die Spalte im Blick. */
  .redesign-page .load-col-num {
    width: 1%;
    white-space: nowrap;
    text-align: right;
    font-variant-numeric: tabular-nums;
  }

  /* Kurze Texte wie Datum, Typ oder Kartenkuerzel. */
  .redesign-page .load-col-tight {
    width: 1%;
    white-space: nowrap;
  }

  .redesign-page .load-col-status {
    width: 1%;
    white-space: nowrap;
    text-align: right;
  }

  .redesign-page .load-col-chart,
  .redesign-page .load-col-week {
    width: 1%;
    white-space: nowrap;
  }

  /* Formularfelder in Tabellen dehnen sich sonst auf die volle Spaltenbreite. */
  .redesign-page .load-col-input {
    width: 1%;
    white-space: nowrap;
  }

  .redesign-page .load-col-input select,
  .redesign-page .load-col-input input {
    min-width: 84px;
  }

  /* Die Bewertungsspalte bekommt als einzige eine feste Breite statt Inhaltsbreite:
     ein Regler ist nur so genau, wie er lang ist. Was hier an Platz gebunden wird,
     fehlt der Notizspalte - das ist die bewusste Abwaegung. */
  .redesign-page .load-col-rating {
    width: 260px;
  }
}

/* Schieberegler - ein gemeinsamer Baustein fuer alle Regler der App.

   Die Browser zeichnen Regler sehr unterschiedlich; Safari am Mac etwa setzt eine
   breite Pille auf die Spur, die an den Enden nicht bis zum Rand reicht - bei 1 blieb
   links Farbe stehen, bei 10 rechts Grau. Deshalb zeichnen wir Spur und Knopf selbst.

   Die Fuellung endet exakt unter der Knopfmitte: Der Knopf wandert nur ueber die Spur
   abzueglich seiner eigenen Breite, also gilt dasselbe fuer die Fuellung. Den Anteil
   (0 bis 1) setzt app.js als --range-progress; ohne Skript steht die Fuellung leer.
   Die Farbe kommt aus --range-accent, damit Bausteine wie die Notenskala sie je
   Zustand setzen koennen, ohne die Pseudo-Elemente erneut anzufassen. */
.redesign-page input[type="range"] {
  --range-thumb: 22px;
  --range-track: 6px;
  --range-accent: var(--accent);
  --range-fill-end: calc(var(--range-thumb) / 2
      + (100% - var(--range-thumb)) * var(--range-progress, 0));
  -webkit-appearance: none;
  appearance: none;
  width: 100%;
  min-height: var(--range-thumb);
  margin: 0;
  padding: 0;
  border: 0;
  border-radius: 0;
  background: transparent;
  box-shadow: none;
  cursor: pointer;
}

.redesign-page input[type="range"]:focus {
  outline: none;
  box-shadow: none;
}

.redesign-page input[type="range"]::-webkit-slider-runnable-track {
  height: var(--range-track);
  border-radius: 999px;
  background: linear-gradient(to right,
      var(--range-accent) 0 var(--range-fill-end),
      var(--border) var(--range-fill-end) 100%);
}

.redesign-page input[type="range"]::-moz-range-track {
  height: var(--range-track);
  border-radius: 999px;
  background: linear-gradient(to right,
      var(--range-accent) 0 var(--range-fill-end),
      var(--border) var(--range-fill-end) 100%);
}

.redesign-page input[type="range"]::-webkit-slider-thumb {
  -webkit-appearance: none;
  appearance: none;
  width: var(--range-thumb);
  height: var(--range-thumb);
  margin-top: calc((var(--range-track) - var(--range-thumb)) / 2);
  border: 2px solid var(--range-accent);
  border-radius: 50%;
  background: var(--surface-raised);
  box-shadow: 0 1px 3px rgba(0, 0, 0, .18);
}

.redesign-page input[type="range"]::-moz-range-thumb {
  box-sizing: border-box;
  width: var(--range-thumb);
  height: var(--range-thumb);
  border: 2px solid var(--range-accent);
  border-radius: 50%;
  background: var(--surface-raised);
  box-shadow: 0 1px 3px rgba(0, 0, 0, .18);
}

.redesign-page input[type="range"]:focus-visible::-webkit-slider-thumb {
  box-shadow: 0 0 0 4px var(--focus-ring);
}

.redesign-page input[type="range"]:focus-visible::-moz-range-thumb {
  box-shadow: 0 0 0 4px var(--focus-ring);
}

.redesign-page input[type="range"]:disabled {
  cursor: default;
}

/* Bewertungsregler des Spielberichts.

   Ein Auswahlfeld waere schmaler, aber die Zehnerskala lebt davon, die Lage zu
   sehen statt eine Zahl zu lesen. Die Anzeige rechts ist zugleich der Schalter,
   der eine Bewertung wieder zuruecknimmt - ein eigener Knopf haette die Spalte
   ein weiteres Mal verbreitert. */
.redesign-page .rating-field {
  display: flex;
  align-items: center;
  gap: 8px;
}

.redesign-page .rating-slider {
  flex: 1 1 auto;
  /* Ein Regler ist nur so genau, wie er lang ist. Der Browser gibt von sich aus
     rund 129px - in der gestapelten Ansicht steht deutlich mehr zur Verfuegung,
     und ohne Untergrenze bliebe er trotzdem kurz. */
  min-width: 170px;
  --range-accent: var(--muted);
}

/* Der Regler traegt die Farbe der Bewertung, nicht die Markenfarbe: eine rote
   Spur unter einer gruenen Sieben sendet zwei widerspruechliche Signale. */
.redesign-page .rating-field.is-good .rating-slider {
  --range-accent: var(--success);
}

.redesign-page .rating-field.is-fair .rating-slider {
  --range-accent: var(--caution);
}

.redesign-page .rating-field.is-weak .rating-slider {
  --range-accent: var(--danger);
}

/* Unbewertet tritt der Regler zurueck. Ohne das saehe eine unberuehrte Zeile
   genauso aus wie eine bewusst mit 6,0 bewertete. */
.redesign-page .rating-field.is-unset .rating-slider {
  opacity: .4;
  filter: grayscale(1);
}

.redesign-page .rating-value {
  min-width: 48px;
  padding: 3px 8px;
  border: 1px solid var(--border);
  border-radius: 999px;
  background: var(--surface-subtle);
  color: var(--muted);
  font-size: 12px;
  font-weight: 700;
  font-variant-numeric: tabular-nums;
  text-align: center;
  cursor: pointer;
}

.redesign-page .rating-value:disabled {
  cursor: default;
}

.redesign-page .rating-field.is-good .rating-value {
  border-color: color-mix(in srgb, var(--success) 38%, var(--border));
  background: color-mix(in srgb, var(--success) 11%, var(--surface-raised));
  color: var(--success);
}

.redesign-page .rating-field.is-fair .rating-value {
  border-color: color-mix(in srgb, var(--caution) 40%, var(--border));
  background: color-mix(in srgb, var(--caution) 12%, var(--surface-raised));
  color: var(--caution);
}

.redesign-page .rating-field.is-weak .rating-value {
  border-color: color-mix(in srgb, var(--danger) 38%, var(--border));
  background: color-mix(in srgb, var(--danger) 11%, var(--surface-raised));
  color: var(--danger);
}

/* Spieler-Rueckfragen: Terminarten und Fragen sind kompakte Mehrfachauswahlen;
   erst im Spielerbereich werden die ausgewaehlten Fragen zu grossen Skalen. */
.redesign-page :is(.feedback-question-toggle, .feedback-session-type-toggle) input:checked + span {
  border-color: color-mix(in srgb, var(--accent) 42%, var(--border));
  background: color-mix(in srgb, var(--accent) 12%, var(--surface-raised));
  color: var(--accent);
}

.redesign-page .feedback-trigger-form {
  display: grid;
  gap: 16px;
}

.redesign-page .feedback-scope-note {
  display: grid;
  gap: 3px;
  margin-top: 16px;
  padding: 11px 13px;
  border-left: 3px solid var(--accent);
  border-radius: 0 10px 10px 0;
  background: var(--surface-subtle);
  color: var(--muted);
  font-size: 12px;
  line-height: 1.45;
}

.redesign-page .feedback-scope-note strong {
  color: var(--text);
}

.redesign-page .feedback-stage-list {
  display: grid;
  gap: 14px;
  margin-top: 16px;
}

.redesign-page .feedback-stage {
  padding: 18px;
  border: 1px solid var(--border);
  border-radius: 14px;
  background: var(--surface-subtle);
}

.redesign-page .feedback-stage-head {
  display: flex;
  align-items: flex-start;
  justify-content: space-between;
  gap: 18px;
}

.redesign-page .feedback-stage-title {
  color: var(--text);
  font-family: "Barlow Condensed", sans-serif;
  font-size: 23px;
  font-weight: 700;
  line-height: 1.05;
}

.redesign-page .feedback-stage-head p {
  max-width: 64ch;
  margin: 5px 0 0;
  color: var(--muted);
  font-size: 12px;
  line-height: 1.45;
}

.redesign-page .feedback-stage-switch {
  display: inline-flex;
  align-items: center;
  gap: 9px;
  flex: 0 0 auto;
  min-height: 32px;
  margin: 0;
  color: var(--text);
  font-size: 12px;
  font-weight: 650;
  cursor: pointer;
}

.redesign-page .feedback-stage-fields {
  display: flex;
  align-items: flex-end;
  gap: 12px 24px;
  flex-wrap: wrap;
  margin-top: 16px;
}

.redesign-page .feedback-compact-field {
  flex: 0 0 auto;
  margin: 0;
}

.redesign-page .feedback-value-control {
  display: flex;
  align-items: center;
  gap: 8px;
}

.redesign-page .feedback-value-control input {
  width: 88px;
  min-width: 88px;
}

.redesign-page .feedback-value-control .feedback-intensity-input {
  width: 68px;
  min-width: 68px;
}

.redesign-page .feedback-value-control span {
  color: var(--muted);
  font-size: 12px;
  white-space: nowrap;
}

.redesign-page .feedback-choice-field {
  margin: 14px 0 0;
}

.redesign-page .feedback-choice-field > label .muted {
  font-size: 10px;
  font-weight: 500;
  letter-spacing: 0;
  text-transform: none;
}

.redesign-page .feedback-history-title-row {
  align-items: flex-end;
}

.redesign-page .feedback-settings-save-row {
  margin-top: 18px;
  padding-top: 16px;
  border-top: 1px solid var(--border);
}

.redesign-page .feedback-manual-modal {
  width: min(680px, 100%);
}

.redesign-page .feedback-question-readonly {
  margin-top: 14px;
}

.redesign-page .feedback-request-list {
  display: grid;
  gap: 8px;
  margin-top: 14px;
}

.redesign-page .feedback-request-link {
  display: flex;
  align-items: center;
  justify-content: space-between;
  min-height: 64px;
  padding: 12px 14px;
  border: 1px solid var(--border);
  border-radius: 12px;
  background: var(--surface-subtle);
  color: var(--text);
  text-decoration: none;
}

.redesign-page .feedback-request-link:hover,
.redesign-page .feedback-request-link:focus-visible {
  border-color: color-mix(in srgb, var(--accent) 42%, var(--border));
  background: color-mix(in srgb, var(--accent) 6%, var(--surface-raised));
}

.redesign-page .feedback-request-link > span:first-child {
  display: grid;
  gap: 4px;
}

.redesign-page .feedback-request-link small {
  color: var(--muted);
}

.redesign-page .feedback-scale-card {
  margin-bottom: 14px;
  padding: 20px;
  border: 1px solid var(--border);
  border-radius: 18px;
  background: var(--surface-raised);
  box-shadow: var(--shadow-soft);
}

.redesign-page .feedback-scale-head {
  display: flex;
  align-items: flex-start;
  justify-content: space-between;
  gap: 16px;
  margin-bottom: 18px;
}

.redesign-page .feedback-scale-head label {
  color: var(--text);
  font-family: "Barlow Condensed", sans-serif;
  font-size: 23px;
  font-weight: 700;
  line-height: 1.1;
}

.redesign-page .feedback-scale-head output {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  min-width: 48px;
  min-height: 44px;
  border: 1px solid color-mix(in srgb, var(--accent) 40%, var(--border));
  border-radius: 999px;
  background: color-mix(in srgb, var(--accent) 11%, var(--surface-raised));
  color: var(--accent);
  font-size: 18px;
  font-weight: 700;
  font-variant-numeric: tabular-nums;
}

.redesign-page .feedback-range {
  width: 100%;
  min-height: 44px;
}

.redesign-page .feedback-scale-labels {
  display: flex;
  justify-content: space-between;
  gap: 12px;
  color: var(--muted);
  font-size: 11px;
}

.redesign-page .feedback-scale-labels span:last-child {
  text-align: right;
}

.redesign-page .feedback-submit-row {
  display: flex;
  align-items: center;
  justify-content: flex-end;
  gap: 14px;
  margin-top: 16px;
}

/* Offene Rueckfragen sind eine Aufgabe statt einer Dashboard-Kennzahl. Die
   schmale Zeile bleibt im Lesefluss, waehrend nur Seitenkante und bekanntes
   Belastungssymbol die noetige Aufmerksamkeit herstellen. */
.player-home-page .home-load-feedback {
  position: relative;
  display: grid;
  grid-template-columns: auto minmax(0, 1fr) auto;
  align-items: center;
  gap: 10px;
  min-height: 52px;
  margin-bottom: 10px;
  padding: 7px 10px 7px 14px;
  overflow: hidden;
  border-color: var(--border);
  border-radius: 14px;
  background: color-mix(in srgb, var(--accent) 6%, var(--surface-raised));
  color: var(--text);
  text-decoration: none;
  box-shadow: inset 3px 0 0 var(--accent), var(--shadow-soft);
  transition: border-color .16s ease, background-color .16s ease, transform .16s ease;
}

.player-home-page .home-load-feedback-icon {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 22px;
  height: 22px;
  margin-left: 2px;
  color: var(--accent);
}

.player-home-page .home-load-feedback-icon .quick-action-icon {
  width: 22px;
  height: 22px;
}

.player-home-page .home-load-feedback-copy {
  display: flex;
  min-width: 0;
  flex-direction: column;
}

.player-home-page .home-load-feedback-copy strong {
  color: var(--text);
  font-size: 14px;
  font-weight: 650;
  line-height: 1.25;
}

.player-home-page .home-load-feedback-open {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 32px;
  height: 32px;
  color: var(--muted);
  font-size: 23px;
  font-weight: 500;
  line-height: 1;
}

@media (hover: hover) {
  .player-home-page .home-load-feedback:hover {
    border-color: color-mix(in srgb, var(--accent) 34%, var(--border));
    background: color-mix(in srgb, var(--accent) 9%, var(--surface-raised));
    color: var(--text);
  }

  .player-home-page .home-load-feedback:hover .home-load-feedback-open {
    color: var(--accent);
  }
}

.player-home-page .home-load-feedback:active {
  transform: scale(.995);
}

.player-home-page .home-load-feedback:focus-visible {
  outline: none;
  border-color: var(--accent);
  box-shadow: inset 3px 0 0 var(--accent), 0 0 0 4px var(--focus-ring);
}

/* Antworttabelle: Bewertungen und Status haben feste Vergleichsspalten;
   Spielername und Notiz bekommen den restlichen Platz. */
.redesign-page .feedback-response-heading {
  margin-bottom: 12px;
}

.redesign-page .feedback-response-summary {
  display: flex;
  align-items: baseline;
  gap: 5px;
  color: var(--muted);
  font-size: 12px;
  white-space: nowrap;
}

.redesign-page .feedback-response-summary strong {
  color: var(--text);
  font-family: "Barlow Condensed", sans-serif;
  font-size: 21px;
  font-variant-numeric: tabular-nums;
  line-height: 1;
}

.redesign-page .feedback-responses-table .feedback-response-score {
  width: 110px;
  text-align: center;
  font-variant-numeric: tabular-nums;
  white-space: nowrap;
}

.redesign-page .feedback-responses-table .feedback-response-note {
  min-width: 160px;
  overflow-wrap: anywhere;
}

.redesign-page .feedback-responses-table .feedback-response-status {
  width: 126px;
  text-align: center;
  white-space: nowrap;
}

.redesign-page .feedback-responses-table .feedback-response-status .status-pill {
  width: 102px;
  justify-content: center;
}

@media (max-width: 640px) {
  .player-home-page .home-load-feedback {
    min-height: 50px;
    padding-block: 6px;
  }

  .player-home-page .home-load-feedback-open {
    width: 28px;
    height: 28px;
    border: 0;
    background: transparent;
  }

  .redesign-page .feedback-response-heading {
    align-items: flex-start;
    flex-direction: row;
  }

  .redesign-page .feedback-responses-table .feedback-response-status .status-pill {
    width: 102px;
  }

  /* Diese drei Ansichten sind eine zusammenhaengende Segmentleiste. Die globale
     Mobile-Regel stapelt allgemeine Tab-Leisten fuer laengere Beschriftungen;
     hier passen alle drei bewusst in eine Zeile. */
  .redesign-page .load-tabs {
    display: grid;
    grid-template-columns: repeat(3, minmax(0, 1fr));
    gap: 4px;
    padding: 4px;
  }

  .redesign-page .load-tabs .tab-btn {
    min-width: 0;
    padding: 9px 5px;
    overflow: hidden;
    font-size: 12px;
    text-align: center;
    text-overflow: ellipsis;
    white-space: nowrap;
  }

  .redesign-page .load-info-title-row {
    align-items: start;
    flex-direction: initial;
  }

  .redesign-page .load-info-title-row > .btn.icon-only {
    width: 30px;
    min-width: 30px;
    height: 30px;
    min-height: 30px;
    padding: 0;
  }

  /* Die Namensspalte bleibt beim horizontalen Scrollen stehen. Kennzeichen
     duerfen sie deshalb nicht auf fast die ganze Handybreite aufziehen. */
  .redesign-page .load-season-table {
    min-width: 760px;
  }

  .redesign-page .load-season-table :is(th, td):first-child {
    width: 148px;
    min-width: 148px;
    max-width: 148px;
    white-space: normal;
  }

  .redesign-page .load-season-player {
    overflow-wrap: anywhere;
    vertical-align: top;
  }

  .redesign-page .load-season-player .status-pill {
    max-width: 100%;
    margin: 4px 3px 0 0;
    padding: 3px 6px;
    font-size: 9px;
    white-space: normal;
  }

  .redesign-page .load-focus-table {
    width: 100%;
    min-width: 100%;
    table-layout: fixed;
  }

  .redesign-page .load-focus-table :is(th, td):first-child {
    width: 58%;
    white-space: normal;
  }

  /* Datum, Typ, Schwerpunkt und die drei Kennzahlen brauchen eine echte
     Scrollflaeche; reine Inhaltsbreite presst vor allem den Schwerpunkt. */
  .redesign-page .load-player-sessions-table {
    min-width: 680px;
  }

  .redesign-page .feedback-stage {
    padding: 15px;
  }

  .redesign-page .feedback-stage-head {
    gap: 12px;
  }

  .redesign-page .feedback-stage-switch {
    flex-direction: column;
    align-items: flex-end;
    gap: 4px;
  }

  .redesign-page .feedback-stage-fields {
    gap: 12px 18px;
  }

  .redesign-page .feedback-submit-row {
    align-items: stretch;
    flex-direction: column;
  }

  .redesign-page .feedback-submit-row .btn {
    width: 100%;
  }
}

/* Der Klammerzusatz „(1 Spiel)" braucht Abstand zur Zahl - der Zeilenumbruch
   im Markup ergibt nur ein schmales Leerzeichen. */
.redesign-page .load-col-num .muted {
  margin-left: 5px;
}

/* Rechenweg im Wochendialog.

   Die sieben Tageswerte stehen als Reihe, damit man die Verteilung sieht, aus der
   die Monotonie entsteht - eine Aufzaehlung im Fliesstext waere nicht zu lesen. */
.redesign-page .week-calc {
  margin: 12px 0 16px;
  padding: 14px;
  border: 1px solid var(--border);
  border-radius: 12px;
  background: var(--surface-subtle);
}

.redesign-page .week-calc-days {
  display: flex;
  gap: 6px;
  margin-bottom: 14px;
}

.redesign-page .week-calc-day {
  display: flex;
  flex: 1 1 0;
  flex-direction: column;
  align-items: center;
  gap: 3px;
  min-width: 0;
  padding: 6px 2px;
  border-radius: 8px;
  background: var(--surface-raised);
}

.redesign-page .week-calc-day-name {
  color: var(--muted);
  font-size: 11px;
  font-weight: 700;
  letter-spacing: .04em;
  text-transform: uppercase;
}

.redesign-page .week-calc-day-au {
  font-size: 13px;
  font-weight: 700;
  font-variant-numeric: tabular-nums;
}

/* Rechenschritte als Beschreibungsliste: links der Begriff, rechts der Wert.
   Ohne feste Spalte springen die Werte je nach Wortlaenge des Begriffs. */
.redesign-page .week-calc-steps {
  display: grid;
  gap: 8px;
  margin: 0;
}

.redesign-page .week-calc-steps > div {
  display: grid;
  grid-template-columns: 170px 1fr;
  gap: 10px;
  align-items: baseline;
}

.redesign-page .week-calc-steps dt {
  color: var(--muted);
  font-size: 13px;
  font-weight: 650;
}

.redesign-page .week-calc-steps dd {
  margin: 0;
  font-size: 14px;
}

@media (max-width: 640px) {
  /* Mobil untereinander: 170px Begriffsspalte plus Wert passen nicht in eine
     Handybreite, der Wert wuerde umbrechen und die Flucht verlieren. */
  .redesign-page .week-calc-steps > div {
    grid-template-columns: 1fr;
    gap: 2px;
  }

  /* Sieben Felder nebeneinander werden auf dem Handy zu schmal fuer die Zahl. */
  .redesign-page .week-calc-days {
    flex-wrap: wrap;
  }

  .redesign-page .week-calc-day {
    flex: 1 1 60px;
  }
}

/* Schwerpunktauswahl mit optionaler Minutenangabe.

   Die Auswahlkachel des Team-Pickers stapelt von sich aus; hier gehoert das
   Minutenfeld auf dieselbe Zeile wie der Name. Eigene Klasse statt :has(), damit
   die Regel nicht davon abhaengt, was im Kaestchen steht. */
.redesign-page .focus-option {
  flex-direction: row;
  align-items: center;
  gap: 8px;
}

.redesign-page .focus-option .cal-team-picker-option-main {
  flex: 1 1 auto;
  min-width: 0;
}

.redesign-page .focus-minutes {
  flex: 0 0 auto;
  padding-right: 10px;
}

.redesign-page .focus-minutes input {
  /* Breit genug fuer den Platzhalter „min" neben den Steppern. */
  width: 84px;
  min-width: 0;
  text-align: right;
}

/* Solange der Schwerpunkt nicht gewaehlt ist, tritt sein Minutenfeld zurueck: es
   bleibt bedienbar, drangt sich aber nicht auf. Die Klasse pflegt das Skript der
   Erfassungsseite beim Umschalten mit. */
.redesign-page .focus-option:not(.selected) .focus-minutes {
  opacity: .45;
}

/* Die Minutenbilanz bleibt beim Scrollen durch den langen Schwerpunktkatalog sichtbar.
   Der Trainer sieht dadurch vor jedem weiteren Eintrag, wie viel Trainingszeit noch frei ist. */
.redesign-page .focus-picker-footer {
  position: sticky;
  bottom: -20px;
  z-index: 3;
  justify-content: space-between;
  margin: 16px -20px -20px;
  padding: 14px 20px max(20px, env(safe-area-inset-bottom));
  background: var(--surface-raised);
}

.redesign-page .focus-time-status {
  display: grid;
  grid-template-columns: auto auto;
  align-items: baseline;
  justify-content: start;
  gap: 2px 8px;
  min-width: 0;
}

.redesign-page .focus-time-status-label {
  color: var(--muted);
  font-size: 9px;
  font-weight: 750;
  letter-spacing: .11em;
  text-transform: uppercase;
}

.redesign-page .focus-time-status strong {
  color: var(--accent);
  font-family: "Barlow Condensed", sans-serif;
  font-size: 25px;
  line-height: 1;
}

.redesign-page .focus-time-status-detail {
  grid-column: 1 / -1;
  overflow: hidden;
  color: var(--muted);
  font-size: 10px;
  text-overflow: ellipsis;
  white-space: nowrap;
}

.redesign-page .focus-time-status.is-complete strong {
  color: var(--success);
}

.redesign-page .focus-time-status.is-over :is(.focus-time-status-label, strong) {
  color: var(--danger);
}

@media (max-width: 640px) {
  .content-page .focus-picker-footer {
    grid-template-columns: minmax(0, 1fr) auto;
  }

  .content-page .focus-picker-footer > button {
    width: auto;
    min-width: 72px;
  }
}

/* Runder Knopf fuer ein einzelnes Zeichen - das „i" neben einem Kartentitel.

   Eigene Klasse statt .btn mit Sonderbreite: ein Knopf mit einem Buchstaben braucht
   gleiche Hoehe und Breite, sonst wird er zum Oval. Das Touch-Ziel bleibt bei 32px,
   weil er neben einer Ueberschrift steht und nicht in einer Werkzeugleiste. */
.redesign-page .btn.icon-only {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 32px;
  min-width: 32px;
  height: 32px;
  min-height: 32px;
  padding: 0;
  border-radius: 50%;
  font-family: "Sora", sans-serif;
  font-size: 14px;
  font-weight: 750;
  font-style: italic;
  line-height: 1;
}

/* Aufklappbare Erklaerung innerhalb eines Dialogs.

   Fuer Herleitungen, die die meisten nicht brauchen und einige schon: eingeklappt
   stoert sie nicht, aufgeklappt spart sie den Weg in eine andere Ansicht. */
.redesign-page .explainer-details {
  margin: 12px 0 16px;
  padding: 10px 14px;
  border: 1px solid var(--border);
  border-radius: 12px;
  background: var(--surface-subtle);
}

.redesign-page .explainer-details > summary {
  cursor: pointer;
  color: var(--accent);
  font-size: 14px;
  font-weight: 700;
  /* Ohne Listenstil bleibt nur das Dreieck des Browsers - das genuegt als Hinweis
     und braucht keine eigene Ikonografie. */
  list-style-position: inside;
}

.redesign-page .explainer-details[open] > summary {
  margin-bottom: 10px;
}

.redesign-page .explainer-details > summary:focus-visible {
  outline: 2px solid var(--accent);
  outline-offset: 2px;
}

/* Der Schlusssatz nach der Rechnung braucht Abstand, sonst liest er sich wie eine
   weitere Zeile der Liste darueber. */
.redesign-page .explainer-details .week-calc-steps + p {
  margin-top: 12px;
}

/* Aktueller Stand im Spielerprofil des Trainerbereichs. Rohzahlen und Ampel
   bleiben zusammen, weil die Literaturkennzahl allein kein Urteil tragen darf. */
.redesign-page .load-current-status {
  display: grid;
  grid-template-columns: minmax(280px, 1.35fr) minmax(360px, 1fr);
  gap: 20px;
  margin: 14px 0 16px;
  padding: 15px 17px;
  border: 1px solid var(--border);
  border-left: 3px solid var(--accent);
  border-radius: 13px;
  background: var(--surface-subtle);
}

.redesign-page .load-current-status-head {
  display: flex;
  min-width: 0;
  align-items: center;
  justify-content: space-between;
  gap: 16px;
}

.redesign-page .load-current-status-head strong {
  color: var(--text);
  font-family: "Barlow Condensed", sans-serif;
  font-size: 22px;
  line-height: 1;
}

.redesign-page .load-current-status-head p {
  margin: 5px 0 0;
  color: var(--muted);
  font-size: 11px;
  line-height: 1.4;
}

.redesign-page .load-current-status-pill {
  flex: 0 0 auto;
}

.redesign-page .load-current-status-values {
  display: grid;
  grid-template-columns: repeat(3, minmax(0, 1fr));
  align-items: stretch;
  gap: 8px;
  margin: 0;
}

.redesign-page .load-current-status-values > div {
  min-width: 0;
  padding: 9px 10px;
  border-radius: 9px;
  background: var(--surface-raised);
}

.redesign-page .load-current-status-values dt {
  color: var(--muted);
  font-size: 8px;
  font-weight: 700;
  letter-spacing: .08em;
  text-transform: uppercase;
}

.redesign-page .load-current-status-values dd {
  margin: 4px 0 0;
  color: var(--text);
  font-size: 13px;
  font-weight: 700;
  font-variant-numeric: tabular-nums;
  white-space: nowrap;
}

/* Bezugsgroessen unter der Wochentabelle. */
.redesign-page .week-reference {
  margin-top: 10px;
}

@media (max-width: 760px) {
  .redesign-page .load-current-status {
    grid-template-columns: 1fr;
    gap: 12px;
    padding: 13px;
  }

  .redesign-page .load-current-status-head {
    align-items: flex-start;
    flex-direction: column;
    gap: 10px;
  }
}

@media (max-width: 430px) {
  .redesign-page .load-current-status-values {
    gap: 5px;
  }

  .redesign-page .load-current-status-values > div {
    padding: 8px 6px;
  }

  .redesign-page .load-current-status-values dt {
    font-size: 7px;
    letter-spacing: .04em;
  }

  .redesign-page .load-current-status-values dd {
    font-size: 11px;
  }
}

/* Legende des Wochenbilds. Verwendet dieselben Felder wie die Tabelle - eine
   nachgebaute Legende driftet frueher oder spaeter vom Original weg. */
.redesign-page .week-legend {
  display: flex;
  flex-wrap: wrap;
  gap: 6px 18px;
  margin: 0 0 14px;
  font-size: 13px;
  color: var(--muted);
}

.redesign-page .week-legend-item {
  display: inline-flex;
  align-items: center;
  gap: 6px;
}

/* In der Legende genuegt ein niedrigeres Feld - dort geht es um die Farbe,
   nicht um die Hoehe. */
.redesign-page .week-legend .week-day {
  height: 18px;
}

/* Wochenbild: Montag bis Sonntag als sieben Felder.

   Anders als .load-bar geht es hier nicht um den Verlauf ueber Wochen, sondern um
   die Struktur einer Woche - deshalb feste Felder gleicher Breite mit Grundlinie,
   auch fuer freie Tage. Ein leerer Tag muss sichtbar bleiben, sonst sieht eine
   Woche mit drei Einheiten aus wie eine mit sieben. */
.redesign-page .week-strip {
  display: flex;
  align-items: flex-end;
  /* Mittig in der Spalte: die Tabelle verteilt ihren Ueberschuss gleichmaessig, und
     ein linksbuendiger Streifen liesse rechts davon eine Luecke stehen, die aussieht
     wie ein Fehler. Die Spaltenueberschrift steht ebenfalls mittig. */
  justify-content: center;
  gap: 3px;
  height: 26px;
}

.redesign-page .week-day {
  position: relative;
  display: flex;
  align-items: flex-end;
  width: 12px;
  height: 100%;
  border-radius: 3px;
  background: var(--surface-subtle);
  border: 1px solid var(--border);
  overflow: hidden;
}

.redesign-page .week-day-bar {
  width: 100%;
  min-height: 2px;
  border-radius: 2px 2px 0 0;
  background: currentColor;
}

/* Farbe je Tagesart - der Balken erbt sie ueber currentColor.

   Die drei Farben sind eine Belastungsleiter, keine Bewertung: gruen fuer die Einheit,
   orange fuer das Spiel, rot fuer beides am selben Tag. Vorher trug das Training das
   Vereinsrot und das Spiel Gruen - damit stand die Signalfarbe auf dem leichteren Termin
   und die Aussage war verkehrt herum.

   Rot steht hier auch neben der Luecke, die mit derselben Farbe schraffiert. Verwechseln
   laesst sich beides nicht: die Luecke hat gestrichelten Rahmen und keinen Balken. */
.redesign-page .week-day-training {
  color: var(--success);
}

.redesign-page .week-day-spiel {
  color: var(--caution);
}

.redesign-page .week-day-beides {
  color: var(--danger);
}

/* Freier Tag: nur die Grundlinie, kein Balken. */
.redesign-page .week-day-frei .week-day-bar {
  min-height: 0;
  height: 0 !important;
}

/* Luecke: schraffiert, damit sie sich klar von einem Ruhetag unterscheidet. */
.redesign-page .week-day-luecke {
  border-style: dashed;
  border-color: color-mix(in srgb, var(--danger) 50%, var(--border));
  background: repeating-linear-gradient(
      45deg,
      transparent 0 3px,
      color-mix(in srgb, var(--danger) 22%, transparent) 3px 6px);
}

.redesign-page .week-day-luecke .week-day-bar {
  height: 0 !important;
}

/* Trainingsform in der Kadernominierung.

   Wert und Abweichung stehen in einer Zelle: die Zahl allein sagt wenig, erst der Abstand zum
   eigenen Saisonschnitt macht sie zur Aussage. Die Abweichung ist kleiner gesetzt, weil sie den
   Wert einordnet und ihn nicht ersetzt.

   Gefaerbt wird erst ab einem halben Notenpunkt und ab zwei beurteilten Einheiten - die Grenzen
   sitzen im DTO, nicht hier. Ohne sie waere nach zwei Wochen die halbe Liste bunt. */
.redesign-page .training-form-cell {
  white-space: nowrap;
}

.redesign-page .training-form-value {
  font-variant-numeric: tabular-nums;
  font-weight: 600;
}

/* Der Saisonschnitt ordnet den Wert ein, ohne mit ihm zu konkurrieren: kleiner und
   zurueckgenommen, das Zeichen davor macht ihn ohne Beschriftung lesbar. */
.redesign-page .training-form-season {
  margin-left: 6px;
  font-size: 12px;
  color: var(--muted);
  font-variant-numeric: tabular-nums;
}

/* Der Wert traegt die Farbe nur, wenn die Abweichung belegbar ist - dieselbe Schwelle wie
   beim Delta, entschieden im DTO. Gemischt mit der Textfarbe, weil hier kein Alarm ausgeht,
   sondern eine Einordnung: die volle Signalfarbe stuende in einer Namensliste zu laut. */
.redesign-page .training-form-value.is-above {
  color: color-mix(in srgb, var(--success) 70%, var(--text));
}

.redesign-page .training-form-value.is-below {
  color: color-mix(in srgb, var(--danger) 70%, var(--text));
}

/* Kartensymbole.

   Feste Farben statt Tokens: Gelb und Rot sind hier keine Statusfarben, sondern
   der Gegenstand selbst - eine gelbe Karte bleibt gelb, egal welches Theme. Der
   Rahmen sorgt dafuer, dass die Kaertchen auch auf heller Flaeche stehen. */
.redesign-page .card-count {
  display: inline-flex;
  align-items: center;
  gap: 4px;
  margin-left: 10px;
  font-variant-numeric: tabular-nums;
}

.redesign-page .card-count:first-child {
  margin-left: 0;
}

/* Rechtsbuendig, weil nicht jeder Spieler alle drei Kartenarten hat - sonst
   beginnt jede Zeile an anderer Stelle. */
.redesign-page .load-col-cards {
  text-align: right;
}

.redesign-page .card-chip {
  display: inline-block;
  width: 11px;
  height: 15px;
  border-radius: 2px;
  border: 1px solid rgba(0, 0, 0, .35);
  vertical-align: -2px;
}

.redesign-page .card-chip-yellow {
  background: #f2c230;
}

.redesign-page .card-chip-red {
  background: #d8332f;
}

/* Gelb-Rot als zweifarbiges Kaertchen - so zeigt es auch der Schiedsrichter. */
.redesign-page .card-chip-yellow-red {
  background: linear-gradient(160deg, #f2c230 0 50%, #d8332f 50% 100%);
}

/* Termine, die keinen Beitrag zur Belastungsrechnung liefern: fehlende Intensitaet oder ein
   Spiel ohne Bericht. Der Zaehler im Kartenkopf sagt, wie viele es sind - welche es sind, muss
   die Zeile zeigen. Balken statt Flaeche: die Zeile bleibt lesbar, und mehrere offene Termine
   untereinander faerben nicht die halbe Tabelle ein.

   Am ersten Feld, weil das die klebende Spalte ist - dort bleibt die Markierung auch sichtbar,
   wenn die Tabelle waagrecht gescrollt wird. */
.redesign-page .editable-list-table tbody tr.load-row-open > td:first-child {
  box-shadow: inset 3px 0 0 var(--danger);
}

/* Statuspillen in einer Spalte gleich breit, damit sie eine saubere Kante bilden.
   Der Text bleibt zentriert - sonst wandert er je nach Laenge im Kaestchen.
   Drei Breiten, weil die Spalten unterschiedlich lange Beschriftungen tragen:
   „Datenbasis zu kurz" braucht mehr als „vollstaendig". */
.redesign-page .load-pill {
  min-width: 148px;
  justify-content: center;
}

.redesign-page .session-pill {
  min-width: 118px;
  justify-content: center;
}

.redesign-page .week-pill {
  min-width: 106px;
  justify-content: center;
}

/* Der Live-Status im Spielbericht wechselt zwischen „Bank" und „Start – 60'“ -
   ohne feste Breite springt die Spalte bei jeder Eingabe. */
.redesign-page .appearance-status {
  min-width: 112px;
  justify-content: center;
}

/* Name und Kennzeichnung dahinter brauchen Luft. Der blosse Zeilenumbruch im
   Markup ergibt nur ein schmales Leerzeichen, und die Pille klebt am Namen. */
.redesign-page .load-col-name .status-pill,
.redesign-page .load-col-name .guest-badge {
  margin-left: 10px;
}

/* Fremdteam-Kennzeichen waren aus der alten reinen Dunkelansicht fest in Braun
   und Gelb codiert. Als Statusflaeche folgt das Kennzeichen jetzt dem Theme. */
.redesign-page .guest-badge {
  border-color: color-mix(in srgb, var(--caution) 42%, var(--border));
  background: color-mix(in srgb, var(--caution) 12%, var(--surface-raised));
  color: var(--caution);
}

/* Verlaufsbalken der Belastungssteuerung.

   Aus CSS gebaut statt mit einer Chart-Bibliothek: eine Suche in app.css und
   app-redesign.css ergab keine bestehende Balken- oder Meter-Klasse, und eine
   Zwoelf-Wochen-Reihe rechtfertigt keine neue Laufzeitabhaengigkeit.
   Die Hoehe kommt per --bar-height aus dem Template, die Farben aus Tokens. */
.redesign-page .load-bar {
  display: flex;
  align-items: flex-end;
  gap: 2px;
  height: 34px;
}

/* Feste Balkenbreite statt flex: eine Reihe aus drei Wochen soll nicht dieselbe
   Flaeche fuellen wie eine aus zwoelf - sonst taeuscht sie eine Datenmenge vor,
   die es nicht gibt. */
.redesign-page .load-bar-col {
  flex: 0 0 auto;
  width: 6px;
  height: var(--bar-height, 0%);
  min-height: 2px;
  border-radius: 2px 2px 0 0;
  /* Gegen transparent gemischt statt gegen --surface-subtle: dort ist der Ton im
     dunklen Theme fast so dunkel wie die Karte und der Balken verschwindet. */
  background: color-mix(in srgb, var(--accent) 45%, transparent);
}

/* Die aktuelle Woche fuehrt die Reihe an - sie ist der Wert, um den es geht. */
.redesign-page .load-bar-col:last-child {
  background: var(--accent);
}

/* Eine Woche ohne Belastung bleibt als Grundlinie sichtbar, damit die Reihe
   nicht auseinanderfaellt. */
.redesign-page .load-bar-col.is-empty {
  background: var(--border);
}

/* Persoenlicher Belastungsverlauf.

   Der Spieler sieht keine interne AU-Skala, sondern sechs relativ zueinander
   gezeichnete Wochen. Die Einheiten darunter liefern den nachvollziehbaren
   Rechenweg aus Dauer und Intensitaet. */
.personal-load-page .personal-load-overview {
  overflow: hidden;
}

.personal-load-page .personal-load-heading h2,
.personal-load-page .personal-load-session-heading h2 {
  margin: 0;
  color: var(--text);
  font-family: "Barlow Condensed", sans-serif;
  font-size: clamp(28px, 3vw, 38px);
  font-weight: 700;
  letter-spacing: -.025em;
  line-height: 1;
}

.personal-load-page .personal-load-heading p {
  margin: 9px 0 0;
  color: var(--muted);
  font-size: 13px;
}

/* Aktueller Stand vor dem historischen Verlauf. Die Pille verwendet dieselbe
   Statusfamilie wie die Traineransicht; der Text ist fuer Spieler bewusst ohne
   Fachabkuerzung und ohne Trainingsaufforderung formuliert. */
.personal-load-page .personal-load-current-status {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 20px;
  margin-top: 18px;
  padding: 15px 17px;
  border: 1px solid var(--border);
  border-left: 3px solid var(--accent);
  border-radius: 13px;
  background: var(--surface-subtle);
}

.personal-load-page .personal-load-current-copy {
  min-width: 0;
}

.personal-load-page .personal-load-current-copy > span {
  color: var(--text);
  font-family: "Barlow Condensed", sans-serif;
  font-size: 20px;
  font-weight: 700;
  line-height: 1;
}

.personal-load-page .personal-load-current-copy p {
  max-width: 760px;
  margin: 6px 0 0;
  color: var(--muted);
  font-size: 11px;
  line-height: 1.45;
}

.personal-load-page .personal-load-current-pill {
  flex: 0 0 auto;
}

.personal-load-page .personal-load-facts-heading {
  display: flex;
  align-items: baseline;
  justify-content: space-between;
  gap: 14px;
  margin-top: 22px;
}

.personal-load-page .personal-load-facts-heading strong {
  color: var(--text);
  font-family: "Barlow Condensed", sans-serif;
  font-size: 20px;
  font-weight: 700;
}

.personal-load-page .personal-load-facts-heading span {
  color: var(--muted);
  font-size: 10px;
  font-weight: 700;
  letter-spacing: .06em;
  text-transform: uppercase;
}

.personal-load-page .personal-load-facts {
  display: grid;
  grid-template-columns: repeat(3, minmax(0, 1fr));
  gap: 10px;
  margin-top: 8px;
}

/* Spieler-Saisonbilanz: dieselben objektiven Mannschaftsdaten wie in der
   Traineransicht, aber ohne subjektive Leistungsnoten oder Schreibaktionen. */
.player-season-page .player-season-heading {
  align-items: flex-end;
}

.player-season-page .player-season-heading h2 {
  margin: 0;
  color: var(--text);
  font-family: "Barlow Condensed", sans-serif;
  font-size: clamp(30px, 3vw, 40px);
  font-weight: 700;
  letter-spacing: -.025em;
  line-height: 1;
}

.player-season-page .player-season-heading p {
  margin: 9px 0 0;
  color: var(--muted);
  font-size: 12px;
}

.player-season-page .player-season-table tbody tr.player-season-own-row td,
.player-season-page .player-season-table tbody tr.player-season-own-row td:first-child {
  background: color-mix(in srgb, var(--accent) 8%, var(--surface-raised));
}

.player-season-page .player-season-table tbody tr.player-season-own-row td:first-child {
  box-shadow: inset 3px 0 0 var(--accent);
}

@media (hover: hover) {
  .player-season-page .player-season-table tbody tr:hover td,
  .player-season-page .player-season-table tbody tr:hover td:first-child {
    background: color-mix(in srgb, var(--accent) 5%, var(--surface-raised));
  }

  .player-season-page .player-season-table tbody tr.player-season-own-row:hover td,
  .player-season-page .player-season-table tbody tr.player-season-own-row:hover td:first-child {
    background: color-mix(in srgb, var(--accent) 11%, var(--surface-raised));
  }
}

.personal-load-page .personal-load-fact {
  display: flex;
  min-width: 0;
  min-height: 82px;
  padding: 14px 16px;
  border: 1px solid var(--border);
  border-radius: 13px;
  background: var(--surface-subtle);
  flex-direction: column;
  justify-content: center;
}

.personal-load-page .personal-load-fact strong {
  color: var(--text);
  font-family: "Barlow Condensed", sans-serif;
  font-size: 34px;
  font-weight: 700;
  font-variant-numeric: tabular-nums;
  line-height: .9;
}

.personal-load-page .personal-load-fact span {
  margin-top: 7px;
  color: var(--muted);
  font-size: 10px;
  font-weight: 700;
  letter-spacing: .08em;
  text-transform: uppercase;
}

.personal-load-page .personal-load-rhythm {
  margin-top: 12px;
  padding: 18px 20px 14px;
  border: 1px solid var(--border);
  border-radius: 15px;
  background: var(--surface-subtle);
}

.personal-load-page .personal-load-rhythm-head {
  display: flex;
  align-items: baseline;
  justify-content: space-between;
  gap: 16px;
  margin-bottom: 14px;
}

.personal-load-page .personal-load-rhythm-head strong {
  color: var(--text);
  font-size: 13px;
}

.personal-load-page .personal-load-rhythm-head span {
  color: var(--muted);
  font-size: 11px;
  text-align: right;
}

.personal-load-page .personal-load-week-bars {
  display: grid;
  grid-template-columns: repeat(6, minmax(0, 1fr));
  gap: 8px;
  min-width: 0;
}

.personal-load-page .personal-load-week {
  display: flex;
  min-width: 0;
  flex-direction: column;
  text-align: center;
}

.personal-load-page .personal-load-week-track {
  display: flex;
  height: 112px;
  margin-bottom: 9px;
  padding: 0 18%;
  align-items: flex-end;
  border-bottom: 1px solid var(--border);
}

.personal-load-page .personal-load-week-track span {
  display: block;
  width: 100%;
  height: var(--personal-load-height, 0%);
  min-height: 3px;
  border-radius: 5px 5px 2px 2px;
  background: color-mix(in srgb, var(--accent) 42%, var(--surface-pressed));
}

.personal-load-page .personal-load-week.is-current .personal-load-week-track span {
  background: var(--accent);
}

.personal-load-page .personal-load-week.is-empty .personal-load-week-track span {
  background: var(--border);
}

.personal-load-page .personal-load-week strong {
  color: var(--text);
  font-size: 10px;
  font-weight: 700;
}

.personal-load-page .personal-load-week.is-current strong {
  color: var(--accent);
}

.personal-load-page .personal-load-week small {
  margin-top: 3px;
  overflow: hidden;
  color: var(--muted);
  font-size: 9px;
  text-overflow: ellipsis;
  white-space: nowrap;
}

.personal-load-page .personal-load-explainer {
  margin: 14px 0 0;
  color: var(--muted);
  font-size: 11px;
  line-height: 1.5;
}

.personal-load-page .personal-load-empty {
  margin-top: 14px;
  padding: 16px;
  border: 1px solid var(--border);
  border-radius: 13px;
  background: var(--surface-subtle);
}

.personal-load-page .personal-load-empty strong {
  color: var(--text);
  font-size: 13px;
}

.personal-load-page .personal-load-empty p {
  margin: 6px 0 0;
  color: var(--muted);
  font-size: 12px;
  line-height: 1.45;
}

.personal-load-page .personal-load-session-heading {
  align-items: flex-end;
}

.personal-load-page .personal-load-period {
  color: var(--muted);
  font-size: 10px;
  font-weight: 700;
  letter-spacing: .08em;
  text-transform: uppercase;
}

.personal-load-page .personal-load-session-list {
  display: grid;
  gap: 8px;
  margin-top: 16px;
}

.personal-load-page .personal-load-session {
  display: grid;
  grid-template-columns: 82px minmax(150px, 1fr) minmax(270px, .9fr);
  align-items: center;
  gap: 16px;
  min-width: 0;
  padding: 12px 14px;
  border: 1px solid var(--border);
  border-radius: 13px;
  background: var(--surface-subtle);
}

.personal-load-page .personal-load-session-date {
  display: flex;
  flex-direction: column;
}

.personal-load-page .personal-load-session-date strong {
  color: var(--text);
  font-family: "Barlow Condensed", sans-serif;
  font-size: 23px;
  font-weight: 700;
  font-variant-numeric: tabular-nums;
  line-height: 1;
}

.personal-load-page .personal-load-session-date span {
  margin-top: 4px;
  color: var(--muted);
  font-size: 9px;
  font-weight: 700;
  letter-spacing: .1em;
  text-transform: uppercase;
}

.personal-load-page .personal-load-session-main {
  display: flex;
  min-width: 0;
  align-items: flex-start;
  flex-direction: column;
  gap: 6px;
}

.personal-load-page .personal-load-session-title-row {
  display: flex;
  min-width: 0;
  align-items: center;
  gap: 9px;
  flex-wrap: wrap;
}

.personal-load-page .personal-load-session-title-row > strong {
  color: var(--text);
  font-size: 13px;
}

.personal-load-page .personal-load-focuses {
  display: flex;
  min-width: 0;
  align-items: baseline;
  gap: 4px 9px;
  flex-wrap: wrap;
  color: var(--muted);
  font-size: 9px;
  line-height: 1.35;
}

.personal-load-page .personal-load-focus-label {
  font-size: 8px;
  font-weight: 700;
  letter-spacing: .08em;
  text-transform: uppercase;
}

.personal-load-page .personal-load-focus {
  white-space: nowrap;
}

.personal-load-page .personal-load-focus small {
  color: inherit;
  font-size: inherit;
  font-variant-numeric: tabular-nums;
}

.personal-load-page .personal-load-source {
  display: inline-flex;
  min-height: 24px;
  padding: 4px 8px;
  align-items: center;
  border: 1px solid var(--border);
  border-radius: 999px;
  background: var(--surface-raised);
  color: var(--muted);
  font-size: 9px;
  font-weight: 700;
  white-space: nowrap;
}

.personal-load-page .personal-load-source.is-player {
  border-color: color-mix(in srgb, var(--success) 36%, var(--border));
  background: color-mix(in srgb, var(--success) 10%, var(--surface-raised));
  color: var(--success);
}

.personal-load-page .personal-load-source.is-external {
  border-color: color-mix(in srgb, var(--caution) 38%, var(--border));
  background: color-mix(in srgb, var(--caution) 10%, var(--surface-raised));
  color: var(--caution);
}

.personal-load-page .personal-load-session-values {
  display: grid;
  grid-template-columns: repeat(2, minmax(0, 1fr));
  gap: 10px;
  margin: 0;
}

.personal-load-page .personal-load-session-values div {
  min-width: 0;
}

.personal-load-page .personal-load-session-values dt {
  color: var(--muted);
  font-size: 8px;
  font-weight: 700;
  letter-spacing: .1em;
  text-transform: uppercase;
}

.personal-load-page .personal-load-session-values dd {
  margin: 3px 0 0;
  color: var(--text);
  font-size: 12px;
  font-weight: 700;
  font-variant-numeric: tabular-nums;
}

@media (max-width: 720px) {
  .personal-load-page .personal-load-current-status {
    align-items: flex-start;
    flex-direction: column;
    gap: 11px;
    margin-top: 15px;
    padding: 13px 14px;
  }

  .personal-load-page .personal-load-current-pill {
    align-self: flex-start;
  }

  .personal-load-page .personal-load-facts-heading {
    align-items: flex-start;
    flex-direction: column;
    gap: 2px;
    margin-top: 17px;
  }

  .personal-load-page .personal-load-facts {
    gap: 7px;
    margin-top: 8px;
  }

  .personal-load-page .personal-load-fact {
    min-height: 72px;
    padding: 11px 10px;
    border-radius: 11px;
  }

  .personal-load-page .personal-load-fact strong {
    font-size: 29px;
  }

  .personal-load-page .personal-load-fact span {
    font-size: 8px;
    letter-spacing: .05em;
  }

  .personal-load-page .personal-load-rhythm {
    padding: 15px 12px 12px;
  }

  .personal-load-page .personal-load-rhythm-head {
    align-items: flex-start;
    flex-direction: column;
    gap: 4px;
  }

  .personal-load-page .personal-load-rhythm-head span {
    text-align: left;
  }

  .personal-load-page .personal-load-week-bars {
    gap: 4px;
  }

  .personal-load-page .personal-load-week-track {
    height: 86px;
    padding-inline: 12%;
  }

  .personal-load-page .personal-load-week small {
    font-size: 8px;
  }

  .personal-load-page .personal-load-session {
    grid-template-columns: 62px minmax(0, 1fr);
    grid-template-areas:
      "date main"
      "date values";
    gap: 9px 12px;
    padding: 12px;
  }

  .personal-load-page .personal-load-session-date { grid-area: date; }
  .personal-load-page .personal-load-session-main { grid-area: main; }
  .personal-load-page .personal-load-session-values { grid-area: values; }

  .personal-load-page .personal-load-session-values {
    gap: 8px;
  }
}

.redesign-page .load-deviation {
  font-variant-numeric: tabular-nums;
  white-space: nowrap;
}

.redesign-page .load-deviation.is-up {
  color: var(--caution);
}

.redesign-page .load-deviation.is-down {
  color: var(--muted);
}

/* Aktionsspalte nach Abschnitt 7 des Designsystems: genau ihre Inhaltsbreite,
   Inhalt rechtsbuendig, kein Umbruch der Buttons. */
.redesign-page .squad-suspension-cell {
  width: 1%;
  white-space: nowrap;
  text-align: right;
}

.redesign-page .squad-suspension-cell .status-pill {
  margin-right: 6px;
}

/* Belastungszeile: erbt Layout und Mobile-Stapelung von .attendance-note-row.
   Abweichend ist nur die Breitenverteilung - Zahlenfelder brauchen wenig Platz,
   die Notiz bekommt den Rest. */
/* Breitenverteilung nur ab Tablet: .attendance-note-row stapelt mobil zur Spalte,
   und dort wird aus flex-basis die HOEHE - eine Basis von 150px risse jedes Feld
   auf 150px Hoehe auseinander. */
@media (min-width: 641px) {
  .attendance-page .attendance-load-row > .field {
    flex: 0 1 130px;
  }

  .attendance-page .attendance-load-row > .attendance-load-focus {
    flex: 0 1 170px;
  }

  .attendance-page .attendance-load-row > .attendance-load-note {
    flex: 1 1 240px;
  }
}

.attendance-page .attendance-load-row .btn {
  min-height: 44px;
  width: 100%;
  justify-content: center;
}

/* Die Belastungsfelder sind Termindaten wie die Notiz darueber - aber ein eigener
   Gedanke. Die Versalienzeile trennt sie, ohne eine zweite Karte aufzumachen. */
.attendance-page .attendance-load-block {
  margin: 4px 0 14px;
  padding-top: 12px;
  border-top: 1px solid var(--border);
}

.attendance-page .attendance-load-block > .eyebrow {
  display: block;
  margin-bottom: 8px;
}

/* Erklaerung unter der Zeile statt im Platzhalter: der Hinweis passt in kein
   Zahlenfeld und wurde dort abgeschnitten. */
.attendance-page .attendance-load-hint {
  margin: -4px 0 12px;
  font-size: 13px;
  color: var(--muted);
}

/* Die Minutenabweichung ist ein zwei- bis dreistelliger Ausnahmewert und braucht
   nur ihre Inhaltsbreite - der Platz gehoert dem Kommentar. Nur auf Desktop:
   mobil wird die Zeile ohnehin zur Karte. */
@media (min-width: 641px) {
  .attendance-page .attendance-user-table th.load-minutes-col,
  .attendance-page .attendance-user-table td.load-minutes-col {
    width: 1%;
    white-space: nowrap;
  }

  .attendance-page .attendance-user-table td.load-minutes-col input {
    width: 92px;
  }
}

.attendance-page .attendance-day-stats {
  border-color: var(--border);
  background: var(--surface-subtle);
}

.attendance-page .table-wrap {
  border: 1px solid var(--border);
  border-radius: 14px;
  background: var(--card);
  box-shadow: none;
}

.attendance-page .table {
  color: var(--text);
}

.attendance-page .table th {
  height: 45px;
  padding: 10px 12px;
  border-color: var(--border);
  background: var(--surface-subtle);
  color: var(--muted);
  font-size: 9px;
  font-weight: 700;
  letter-spacing: .1em;
  text-transform: uppercase;
}

.attendance-page .table td {
  padding: 10px 12px;
  border-color: var(--border);
  background: var(--card);
}

.attendance-page :is(.table-wrap > table, .table-scroll > table) tbody tr:hover td,
.attendance-page :is(.table-wrap > table, .table-scroll > table) tbody tr:hover td:first-child {
  background: var(--surface-pressed);
}

.attendance-page :is(.table-wrap > table, .table-scroll > table) thead th,
.attendance-page :is(.table-wrap > table, .table-scroll > table) thead th:first-child,
.attendance-page :is(.table-wrap > table, .table-scroll > table)[data-sortable] thead th:hover {
  background: var(--surface-subtle);
  color: var(--muted);
}

/* Der mitlaufende Tabellenkopf hat hier keine Sonderregeln mehr. Die früheren
   setzten Maske, Container und Ausschnitte auf transparent und hoben damit genau
   den Deckel auf, den alle Seiten gemeinsam nutzen: Tabellenzeilen liefen
   sichtbar hinter dem Kopf und durch die Zone der Statusleiste. Die Seite folgt
   jetzt `.content-page`. */

/* Bottom prompts and the personal-data reminder follow the selected theme. */
.redesign-page [data-push-prompt] {
  bottom: max(16px, calc(env(safe-area-inset-bottom) + 10px)) !important;
  border-color: var(--border) !important;
  border-radius: 14px !important;
  background: var(--surface-raised) !important;
  color: var(--text) !important;
  box-shadow: var(--shadow) !important;
}

.redesign-page [data-push-prompt] #push-allow-btn {
  background: var(--accent) !important;
  color: #fff !important;
}

.redesign-page [data-push-prompt] #push-deny-btn {
  border-color: var(--border) !important;
  background: var(--surface-subtle) !important;
  color: var(--text) !important;
}

.redesign-page .personal-data-reminder-backdrop {
  background: color-mix(in srgb, var(--bg) 60%, transparent);
  backdrop-filter: blur(7px);
  -webkit-backdrop-filter: blur(7px);
}

html[data-theme="light"] .redesign-page .personal-data-reminder-backdrop {
  background: rgba(23, 33, 43, .28);
}

.redesign-page .personal-data-reminder-card {
  border-color: var(--border);
  border-radius: 20px;
  background: var(--surface-raised);
  color: var(--text);
  box-shadow: var(--shadow);
}

.redesign-page .personal-data-reminder-card h3 {
  color: var(--text);
  font-family: "Barlow Condensed", "Arial Narrow", sans-serif;
  font-size: 27px;
  letter-spacing: -.02em;
}

.redesign-page .personal-data-reminder-card p {
  color: var(--muted);
}

.redesign-page .personal-data-reminder-actions {
  gap: 8px;
}

.redesign-page .personal-data-reminder-actions #personal-data-reminder-cta {
  border-color: var(--accent);
  background: var(--accent);
  color: #fff;
}

.redesign-page .personal-data-reminder-actions .btn-later {
  min-height: 44px;
  border: 1px solid var(--border);
  background: var(--surface-subtle);
  color: var(--text);
}

.redesign-page .personal-data-reminder-actions .btn-later:hover {
  border-color: color-mix(in srgb, var(--accent) 35%, var(--border));
  background: color-mix(in srgb, var(--accent) 3%, var(--surface-subtle));
  color: var(--text);
}

.attendance-page .attendance-status-select,
.attendance-page .ae-override-select,
.attendance-page .attendance-user-table input[type="text"] {
  min-height: 42px;
  font-size: 12px;
}

.attendance-page select.status-anwesend {
  border-color: color-mix(in srgb, var(--success) 34%, transparent);
  background: color-mix(in srgb, var(--success) 11%, var(--input));
  color: var(--success);
}

.attendance-page select.status-entschuldigt {
  border-color: color-mix(in srgb, var(--caution) 34%, transparent);
  background: color-mix(in srgb, var(--caution) 11%, var(--input));
  color: var(--caution);
}

.attendance-page select.status-fehlend {
  border-color: color-mix(in srgb, var(--danger) 34%, transparent);
  background: color-mix(in srgb, var(--danger) 11%, var(--input));
  color: var(--danger);
}

/* Individuelles Training ist der vierte Anwesenheitsstatus. Er hatte im
   Redesign keine Regel und blieb dadurch in beiden Themes farblos. */
.attendance-page select.status-individuell {
  border-color: color-mix(in srgb, var(--info) 34%, transparent);
  background: color-mix(in srgb, var(--info) 11%, var(--input));
  color: var(--info);
}

/* Tageszaehler und schreibgeschuetzte Statusangaben stammen aus der dunklen
   Anfangszeit und trugen feste Hex-Werte, die im hellen Theme auf weisser
   Fläche kaum lesbar sind. Farben kommen aus denselben Tokens wie die Selects. */
.redesign-page :is(.stat-anwesend, .status-text-anwesend) {
  color: var(--success);
}

.redesign-page :is(.stat-individuell, .status-text-individuell) {
  color: var(--info);
}

.redesign-page :is(.stat-entschuldigt, .status-text-entschuldigt) {
  color: var(--caution);
}

.redesign-page :is(.stat-fehlend, .status-text-fehlend) {
  color: var(--danger);
}

.redesign-page .status-text-individuell {
  font-weight: 600;
}

.attendance-page .attendance-form-actions {
  align-items: center;
  margin-top: 18px;
}

.attendance-page .attendance-form-actions button:first-child {
  min-width: 160px;
}

.attendance-page .attendance-form-actions button.danger {
  margin-left: auto;
  color: var(--danger);
}

@media (min-width: 721px) {
  .player-hero {
    min-height: 198px;
    padding: 27px 36px;
    border-radius: 20px;
  }

  .player-hero h2 {
    margin: 13px 0 10px;
    font-size: clamp(49px, 4.4vw, 70px);
  }

  .player-hero p {
    font-size: 12px;
  }

  .player-identity-number {
    right: 42px;
    font-size: clamp(180px, 18vw, 290px);
  }

  .player-identity-number.is-wordmark {
    right: 28px;
    font-size: clamp(145px, 16vw, 240px);
  }

  .player-hero-stripe {
    right: 30px;
    height: 58px;
  }

  .player-dashboard-grid .home-today,
  .player-dashboard-grid .home-tomorrow {
    position: relative;
  }

  .player-dashboard-grid .home-today::after,
  .player-dashboard-grid .home-tomorrow::after {
    position: absolute;
    top: -1px;
    left: 22px;
    width: 58px;
    height: 3px;
    border-radius: 0 0 3px 3px;
    background: var(--accent);
    content: "";
    pointer-events: none;
  }

  .player-dashboard-grid .home-tomorrow::after {
    width: 34px;
    height: 2px;
    opacity: .55;
  }

  .player-dashboard-grid .home-today .sess-kicker,
  .player-dashboard-grid .home-tomorrow .sess-kicker {
    color: var(--accent);
  }
}

@media (min-width: 981px) {
  /* Aufgeklappte Strafen brauchen Hoehe: die Karte spannt dann rechts ueber
     beide Terminzeilen. Die Kachelreihe bleibt darunter voll breit – der
     Bereichsname muss hier mitgenannt werden, sonst faellt .db-tiles aus dem
     Raster und wird automatisch platziert. */
  .player-dashboard-grid:has(.home-finances[aria-expanded="true"]),
  .player-dashboard-grid:has(.home-finances .bank-compact) {
    grid-template-areas:
      "today today today today today today today finance finance finance finance finance"
      "tomorrow tomorrow tomorrow tomorrow tomorrow tomorrow tomorrow finance finance finance finance finance"
      "tiles tiles tiles tiles tiles tiles tiles tiles tiles tiles tiles tiles";
  }

  /* Die aufgeklappte Strafenliste bestimmt die Hoehe ihrer Zeilen. Die
     Terminkarten daneben wuerden mitgestreckt und zeigten dann grosse leere
     Flaechen – sie behalten ihre eigene Hoehe. */
  .player-dashboard-grid:has(.home-finances[aria-expanded="true"]) :is(.home-today, .home-tomorrow) {
    align-self: start;
  }
}

@media (max-width: 980px) {
  .player-dashboard-grid {
    grid-template-columns: repeat(2, minmax(0, 1fr));
    grid-template-areas:
      "today today"
      "tomorrow tomorrow"
      "finance finance"
      "tiles tiles";
  }

  .player-identity-number {
    right: 34px;
  }
}

@media (max-width: 860px) {
  .redesign-page .container {
    width: 100%;
    padding: max(12px, env(safe-area-inset-top)) max(12px, env(safe-area-inset-right)) max(46px, calc(env(safe-area-inset-bottom) + 24px)) max(12px, env(safe-area-inset-left));
  }

  .redesign-page .v2-app-header {
    grid-template-columns: 48px minmax(0, 1fr) auto;
    grid-template-areas: none;
    min-height: 60px;
    margin-bottom: 14px;
    padding-bottom: 12px;
  }

  .redesign-page .v2-app-header .nav-drawer-trigger {
    grid-area: auto;
    grid-column: 1;
    width: 42px;
    height: 42px;
  }

  .redesign-page .v2-app-header .brand {
    grid-area: auto;
    grid-column: 2;
    justify-self: center;
  }

  .redesign-page .v2-app-header > .actions {
    grid-area: auto;
    grid-column: 3;
    justify-self: end;
  }

  .redesign-page .v2-app-header .actions .btn {
    min-height: 42px;
  }

  /* Die Vereinsmarke nutzt mobil die Hoehe neben dem Menuezugang aus. Die Werte
     stehen bewusst in der gemeinsamen Header-Regel, damit Seiten mit und ohne
     zusaetzliche Aktion identisch aussehen. */
  .redesign-page .v2-app-header .brand-title {
    font-size: 16px;
  }

  .redesign-page .v2-app-header .page-title {
    font-size: 13px;
  }

  .redesign-page .v2-app-header .subtitle {
    display: none;
  }

  /* Rueckmeldungen und die persoenlichen Belastungsseiten brauchen die dritte
     Zeile zur Einordnung von Team beziehungsweise Ansicht. Sie passt neben die
     bewusst hohe Vereinsmarke. */
  .redesign-page:is(.load-feedback-page, .personal-load-page, .player-season-page) .v2-app-header .subtitle {
    display: block;
    overflow: hidden;
    font-size: 9px;
    font-weight: 700;
    line-height: 1.3;
    text-overflow: ellipsis;
    white-space: nowrap;
  }

  /* Auf Höhe der drei Markenzeilen. */
  .redesign-page .v2-app-header .logo {
    width: 46px;
    height: 56px;
  }
}

@media (max-width: 720px) {
  html {
    max-width: 100%;
    overflow-x: hidden;
    overscroll-behavior-x: none;
  }

  .login-page {
    overflow: auto;
  }

  .player-home-page {
    overflow-x: hidden;
    overflow-x: clip;
    overscroll-behavior-x: none;
    touch-action: pan-y;
  }

  .content-page .card {
    margin-bottom: 10px;
    padding: 15px 14px;
    border-radius: 15px;
    box-shadow: none;
  }

  .content-page .app-header.has-account-menu.v2-app-header {
    position: relative;
    grid-template-columns: minmax(0, 1fr);
    grid-template-areas:
      "brand"
      "actions";
    align-items: start;
    min-height: 0;
    margin-bottom: 10px;
    padding: 2px 0 9px;
  }

  .content-page .app-header.has-account-menu.v2-app-header .btn.nav-drawer-trigger {
    position: absolute;
    z-index: 2;
    top: 2px;
    right: 0;
    left: auto;
    width: 40px;
    height: 40px;
    min-height: 40px;
  }

  .redesign-page .v2-app-header .nav-drawer-trigger-icon {
    width: 25px !important;
    height: 25px !important;
  }

  .content-page .app-header.has-account-menu.v2-app-header .brand {
    grid-area: brand;
    grid-column: auto;
    align-self: start;
    justify-self: center;
    gap: 10px;
    max-width: calc(100% - 96px);
  }

  .content-page .app-header.has-account-menu.v2-app-header .subtitle {
    display: block;
    margin-top: 3px;
    overflow: hidden;
    color: var(--muted);
    font-size: 9px;
    font-weight: 700;
    letter-spacing: .11em;
    line-height: 1.3;
    text-overflow: ellipsis;
    white-space: nowrap;
  }

  .content-page .app-header.has-account-menu.v2-app-header > .actions {
    grid-area: actions;
    grid-column: auto;
    justify-self: stretch;
    justify-content: flex-end;
    width: 100%;
    margin-top: 7px;
  }

  .content-page .app-header.has-account-menu.v2-app-header > .actions .btn {
    width: auto;
    max-width: 100%;
    min-height: 32px;
    padding: 5px 9px;
    border-radius: 8px;
    font-size: 10px;
    white-space: normal;
  }

  .public-content-page .v2-app-header {
    grid-template-columns: minmax(0, 1fr);
    min-height: 0;
    margin-bottom: 10px;
    padding: 2px 0 9px;
  }

  .public-content-page .v2-app-header .brand {
    grid-column: 1;
    justify-self: center;
    gap: 10px;
    max-width: calc(100% - 24px);
  }

  .public-content-page .v2-app-header .subtitle {
    display: block;
    margin-top: 2px;
    overflow: hidden;
    font-size: 8px;
    font-weight: 700;
    letter-spacing: .11em;
    line-height: 1.3;
    text-overflow: ellipsis;
    white-space: nowrap;
  }

  .public-content-page .v2-app-header > .actions {
    grid-column: 1;
    justify-self: center;
    margin-top: 7px;
  }

  .public-content-page .nav {
    display: grid;
    grid-template-columns: repeat(2, minmax(0, 1fr));
    width: 100%;
  }

  .admin-content-page .nav-groups-grid {
    grid-template-columns: minmax(0, 1fr);
    gap: 10px;
  }

  .admin-content-page .nav-group {
    border-radius: 15px;
    box-shadow: none;
  }

  .admin-content-page .nav-group-header {
    padding: 11px 13px 8px;
  }

  .admin-content-page .nav-group .nav-item {
    min-height: 46px;
    padding: 10px 13px;
  }

  .fine-entry-page .fine-entry-date-toolbar {
    grid-template-columns: minmax(0, 1fr);
    gap: 12px;
    padding-top: 4px;
  }

  .fine-entry-page .fine-entry-date-field {
    width: 100%;
  }

  .fine-type-catalog-page .fine-type-detail-grid {
    grid-template-columns: minmax(0, 1fr);
  }

  .fine-type-catalog-page .fine-type-detail-mode-field {
    grid-column: auto;
  }

  .fine-type-catalog-page .fine-type-detail-actions {
    display: grid;
    grid-template-columns: repeat(2, minmax(0, 1fr));
  }

  .fine-type-catalog-page .fine-type-detail-actions .danger {
    grid-column: 1 / -1;
    order: 3;
    margin-right: 0;
  }

  .admin-content-page :is(.ticketing-table-wrap, .week-grid, .day-layout) {
    max-width: 100%;
    border-radius: 14px;
    box-shadow: none;
  }

  body.mobile-layout-stack .admin-content-page :is(.ticket-list-table, .ticket-batch-jobs-table, .cfg-table) {
    min-width: 0;
  }

  body.mobile-layout-stack .admin-content-page :is(.ticket-list-table, .ticket-batch-jobs-table, .cfg-table) :is(th, td).ticketing-actions {
    width: 100%;
    min-width: 0;
    overflow: visible;
  }

  .budget-content-page :is(.kpi-grid, .summary-grid, .detail-grid) {
    grid-template-columns: repeat(2, minmax(0, 1fr));
    gap: 9px;
  }

  .budget-content-page .kpi-card {
    min-width: 0;
    padding: 14px;
    border-radius: 14px;
    box-shadow: none;
  }

  .budget-content-page :is(.document-tabs, .open-ledger-tabs) {
    max-width: 100%;
    padding: 4px;
    overflow-x: auto;
    border-radius: 12px;
  }

  .budget-content-page :is(.document-tab, .open-ledger-tab) {
    flex: 0 0 auto;
    min-height: 38px;
    padding: 7px 10px;
    white-space: nowrap;
  }

  .content-page .card.app-modal {
    width: 100%;
    max-height: calc(100dvh - max(24px, env(safe-area-inset-top) + env(safe-area-inset-bottom)));
    padding: 17px 14px;
    border-radius: 17px;
  }

  .sponsoring-content-page .ticket-recipient-link-dialog {
    height: auto;
    min-height: min(560px, calc(100dvh - 24px));
  }

  .sponsoring-content-page .ticket-recipient-link-dialog .category-picker-results {
    max-height: 45dvh;
  }

  .content-page .app-modal-header {
    align-items: flex-start;
    gap: 8px;
  }

  .content-page .app-modal-header > .btn,
  .content-page .app-modal-header > button {
    min-height: 34px;
    padding: 6px 9px;
    font-size: 10px;
  }

  .content-page :is(.app-modal-actions, .app-modal-footer, .form-actions) {
    display: grid;
    grid-template-columns: repeat(2, minmax(0, 1fr));
    gap: 8px;
  }

  .content-page :is(.app-modal-actions, .app-modal-footer, .form-actions) > :is(.btn, button) {
    width: 100%;
    min-width: 0;
    justify-content: center;
  }

  .service-home-page .container > .card {
    padding: 22px 16px;
  }

  .service-home-page .container > .card .actions {
    grid-template-columns: minmax(0, 1fr);
    margin-top: 18px;
  }

  .service-home-page .container > .card .actions .btn {
    min-height: 50px;
  }

  .content-page .card-title {
    font-size: 27px;
  }

  .attendance-overview-page .attendance-month-toolbar {
    display: grid;
    grid-template-columns: minmax(0, 1fr);
    gap: 10px;
    min-height: 0;
    padding: 14px;
  }

  .attendance-overview-page .attendance-month-copy {
    gap: 2px;
  }

  .attendance-overview-page .attendance-month-form {
    width: 100%;
  }

  .calendar-page .container > .card {
    padding: 12px 8px;
  }

  .calendar-page .cal-nav h3 {
    font-size: 24px;
  }

  .calendar-page .cal-nav-secondary {
    gap: 7px;
  }

  .calendar-page .cal-view-switch {
    width: auto;
    max-width: 100%;
    flex: 0 1 auto;
    flex-wrap: nowrap;
    border-radius: 12px;
  }

  .calendar-page .cal-view-btn {
    flex: 0 0 auto;
    min-width: 68px;
    min-height: 40px;
    padding: 8px 10px;
  }

  .calendar-page .cal-filter-bar {
    padding: 9px 8px;
  }

  .calendar-page .cal-filter-group {
    grid-template-columns: minmax(0, 1fr);
    gap: 5px;
  }

  .calendar-page .cal-filter-chips {
    width: 100%;
  }

  /* Der Status-Umschalter der Ticket-Auswertung braucht die ganze Breite: In
     einer halben Rasterspalte reichen die beiden Beschriftungen nicht aus, und
     weil sie nicht umbrechen dürfen, lief „Nicht gescannt“ aus dem Feld. */
  .admin-content-page .user-filter-grid .field:has(.auswertung-toggle) {
    grid-column: 1 / -1;
  }

  .admin-content-page .auswertung-toggle button {
    flex: 1 1 0;
    min-width: 0;
    padding: 8px 10px;
  }

  /* Tagesfelder sind auf dem Handy nur wenige Zeichen breit – „abwesend“ passt
     dort nicht und wurde zu „abwese…“ abgeschnitten. Es bleibt bei der Zahl:
     Dass sie Abwesenheiten zählt, sagt der eingeblendete Filter darüber, der
     Tooltip nennt die Namen. Für Screenreader bleibt die Beschriftung im
     Dokument, nur unsichtbar (aria-label am Streifen ergänzt die Zahl). */
  .calendar-page .cal-day .cal-absence-strip {
    padding: 2px 4px;
  }

  .calendar-page .cal-day .cal-absence-head {
    justify-content: center;
  }

  .calendar-page .cal-day .cal-absence-label {
    position: absolute;
    width: 1px;
    height: 1px;
    margin: -1px;
    overflow: hidden;
    clip: rect(0, 0, 0, 0);
  }

  .calendar-page .cal-legend {
    justify-content: flex-start;
    width: 100%;
    max-width: none;
    padding: 2px 2px 4px;
    overflow-x: auto;
  }

  .calendar-page .cal-modal {
    width: 100%;
    max-width: 620px;
    max-height: calc(100dvh - 28px);
    padding: 18px 16px;
  }

  .calendar-page .cal-team-picker-modal {
    width: 100%;
    max-height: calc(100dvh - 28px);
    height: auto;
    border-radius: 18px;
  }

  .equipment-my-page .number-widget {
    grid-template-columns: repeat(auto-fit, minmax(130px, 1fr));
  }

  .equipment-my-page .number-widget .number-box {
    min-height: 106px;
    padding: 18px;
  }

  .equipment-my-page .number-widget-centered .number-box .value {
    font-size: 43px;
  }

  .equipment-my-page .equipment-list-header {
    align-items: stretch;
    flex-direction: column;
  }

  .equipment-my-page .eq-filter-toggle-wrap,
  .equipment-my-page .eq-filter-toggle-wrap .btn {
    width: 100%;
    max-width: none;
  }

  .physio-portal-page .physio-cal-nav {
    gap: 9px;
    padding: 11px;
  }

  .physio-portal-page .physio-nav-center h3 {
    font-size: 22px;
  }

  .physio-portal-page .physio-availability-card {
    padding-left: 16px;
  }

  /* Der „Heute“-Streifen zog seine Zeile über ein negatives Margin an den
     Kartenrand. Mobil ist das Kartenpolster kleiner als dieses Margin, und weil
     Karten dort ihren Überhang abschneiden, fehlte vom Text links ein Stück.
     Der Streifen bleibt hier innerhalb der Karte. */
  .redesign-page .physio-today-row {
    margin-left: 0;
    padding-left: 11px;
  }

  .physio-portal-page .physio-slot-grid {
    gap: 7px;
  }

  .physio-portal-page #physio-book-dialog {
    max-height: calc(100dvh - 28px);
    overflow-y: auto;
    padding: 18px;
  }

  .content-page .stats-grid-user {
    grid-template-columns: repeat(2, minmax(0, 1fr));
    gap: 9px;
    margin-bottom: 10px;
  }

  .content-page .stats-grid-user .stat-card {
    min-width: 0;
    padding: 14px;
  }

  .content-page .stats-grid-user .stat-value,
  .content-page .competition-score {
    font-size: 30px;
  }

  .content-page .table-wrap,
  .content-page .table-scroll {
    max-width: 100%;
    border-radius: 14px;
    box-shadow: none;
  }

  .content-page.mobile-layout-stack .table-wrap,
  .content-page.mobile-layout-stack .table-scroll {
    overflow: visible;
    border: 0;
    background: transparent;
  }

  .content-page.mobile-layout-stack :is(.table, .absence-table) tr {
    background: var(--surface-raised);
    border-color: var(--border);
    border-radius: 13px;
    box-shadow: none;
  }

  .content-page.mobile-layout-stack :is(.table, .absence-table) td {
    position: static;
    left: auto;
    color: var(--text);
    border-bottom-color: var(--border);
    background: transparent;
  }

  .content-page.mobile-layout-stack :is(.table, .absence-table) td::before {
    color: var(--muted);
    font-size: 8px;
    font-weight: 700;
    letter-spacing: .11em;
  }

  .content-page .card-title-row {
    align-items: stretch;
    flex-direction: column;
  }

  .content-page .card-title-row .btn {
    width: 100%;
    justify-content: center;
  }

  /* `align-items: stretch` oben gilt den Knöpfen. Ein Zahlenfeld ist keiner – es
     zog sich sonst als schmaler Balken über die ganze Kartenbreite. */
  .content-page .card-title-row > .badge {
    align-self: flex-start;
    width: auto;
  }

  /* Titelzeilen ohne Knöpfe bleiben einzeilig: Der Zähler gehört neben die
     Überschrift, nicht darunter. */
  .content-page .card-title-row--inline {
    flex-direction: row;
    align-items: center;
  }

  .account-content-page .container > .card .actions {
    display: grid;
    grid-template-columns: 1fr;
  }

  .account-content-page .container > .card .actions .btn,
  .account-content-page .container > .card .actions button {
    width: 100%;
    justify-content: center;
  }

  .redesign-page :is(input, select, textarea),
  .login-page :is(input, select, textarea) {
    font-size: 16px;
  }

  .player-home-page .app-header.has-account-menu.v2-app-header {
    grid-template-columns: 44px minmax(0, 1fr) 44px;
    grid-template-areas: ". brand trigger";
    align-items: start;
    min-height: 0;
    margin-bottom: 12px;
    padding: 2px 0 10px;
  }

  .player-home-page .app-header.has-account-menu.v2-app-header .btn.nav-drawer-trigger {
    grid-area: trigger;
    align-self: start;
    justify-self: end;
    width: 40px;
    height: 40px;
    min-height: 40px;
  }

  .player-home-page .app-header.has-account-menu.v2-app-header .brand {
    grid-area: brand;
    align-self: start;
    justify-self: center;
    gap: 10px;
  }

  /* Groessen kommen aus der gemeinsamen Header-Regel; hier wird nur die dritte
     Markenzeile wieder eingeblendet, die mobil sonst entfaellt. */
  .player-home-page .app-header.has-account-menu.v2-app-header .subtitle {
    display: block;
    margin-top: 3px;
    font-size: 9px;
    font-weight: 700;
    letter-spacing: .13em;
  }

  .login-shell {
    display: block;
  }

  .login-club-panel {
    min-height: 310px;
    padding: max(18px, env(safe-area-inset-top)) 20px 24px;
  }

  .login-club-topline {
    display: grid;
    grid-template-columns: minmax(0, 1fr) auto;
    align-items: center;
    gap: 12px;
  }

  .login-club-brand {
    min-width: 0;
  }

  .login-club-brand span {
    min-width: 0;
  }

  .login-club-brand img {
    width: 38px;
    height: 47px;
  }

  .login-club-brand strong {
    font-size: 14px;
  }

  .login-page .login-theme-control {
    width: 112px;
  }

  .login-page .login-theme-control .theme-option {
    min-height: 38px;
    padding: 4px;
  }

  .login-page .login-theme-control .theme-option span {
    display: none;
  }

  .login-club-copy {
    margin: 0;
    padding: 50px 0 8px;
  }

  .login-club-copy h1 {
    margin: 10px 0 11px;
    font-size: clamp(49px, 15vw, 70px);
    line-height: .83;
  }

  .login-club-copy p {
    max-width: 330px;
    font-size: 11px;
    line-height: 1.5;
  }

  .login-club-watermark {
    right: -10px;
    bottom: -32px;
    font-size: 220px;
  }

  .club-stripe {
    top: auto;
    right: 18px;
    bottom: 0;
    height: 48px;
  }

  .login-form-panel {
    min-height: calc(100svh - 310px);
    padding: 35px 20px max(18px, env(safe-area-inset-bottom));
  }

  .login-form-inner {
    width: 100%;
  }

  .login-form-heading {
    margin-bottom: 26px;
  }

  .login-form-heading h2 {
    font-size: 43px;
  }

  .login-footer {
    padding-top: 34px;
  }

  /* Mobil tritt der Begrüßungsblock etwas zurück: Er bleibt die Signatur der
     Startseite, überlässt dem Tagesinhalt darunter aber mehr vom ersten Bild. */
  .player-hero {
    min-height: 196px;
    margin-bottom: 12px;
    padding: 24px 21px;
    border-radius: 19px;
  }

  .player-hero h2 {
    margin: 13px 0 10px;
    font-size: clamp(45px, 13.5vw, 62px);
  }

  .player-hero h2 strong {
    max-width: 78vw;
  }

  .player-hero p {
    max-width: 70%;
    font-size: 11px;
    line-height: 1.5;
  }

  .player-identity-number {
    right: 15px;
    font-size: clamp(148px, 50vw, 218px);
    opacity: .14;
  }

  .player-identity-number.is-wordmark {
    right: 5px;
    font-size: 120px;
  }

  .player-hero-stripe {
    right: 20px;
    height: 42px;
  }

  .player-home-watermark {
    right: 0;
    bottom: max(10px, env(safe-area-inset-bottom));
    width: 220px;
    opacity: .018;
  }

  html[data-theme="light"] .player-home-watermark {
    opacity: .024;
  }

  .player-dashboard-grid {
    display: grid;
    grid-template-columns: repeat(2, minmax(0, 1fr));
    grid-auto-flow: row dense;
    gap: 10px;
  }

  .player-dashboard-grid > :is(
    .home-today,
    .home-tomorrow,
    .db-tiles,
    .home-attendance,
    .home-finances,
    .home-duty,
    .home-competition,
    .home-personal-load,
    .home-personal-season,
    .home-physio
  ) {
    grid-area: auto;
  }

  /* Die Kachelreihe bleibt auch mobil ein eigenes Raster: volle Breite, darin
     zwei Spalten. Innerhalb der Reihe zaehlt die Reihenfolge im Template. */
  .player-dashboard-grid .db-tiles {
    grid-column: 1 / -1;
    grid-template-columns: repeat(2, minmax(0, 1fr));
    grid-auto-flow: row dense;
    gap: 10px;
    order: 5;
  }

  /* Anwesenheit und Wettbewerb sind kompakte Kennzahlen und bilden das erste
     Paar. Fehlt eine davon, nimmt die verbleibende Karte die ganze Zeile ein. */
  .player-dashboard-grid .db-tiles > :is(.home-attendance, .home-competition) {
    order: 1;
  }

  .player-dashboard-grid .db-tiles:not(:has(.home-competition)) > .home-attendance,
  .player-dashboard-grid .db-tiles:not(:has(.home-attendance)) > .home-competition {
    grid-column: 1 / -1;
  }

  /* Die Zuständigkeit darf beliebig viele Namen und Utensilien enthalten. Als
     volle Zeile wächst sie fuer sich, ohne die Anwesenheitskarte mitzuziehen. */
  .player-dashboard-grid .db-tiles > .home-duty {
    grid-column: 1 / -1;
    order: 2;
    min-height: 0;
  }

  .player-dashboard-grid .home-duty .utensil-tag-list {
    display: grid;
    grid-template-columns: repeat(2, minmax(0, 1fr));
    gap: 6px;
  }

  .player-dashboard-grid .home-duty .utensil-tag {
    display: block;
    min-width: 0;
    padding: 5px 8px;
    overflow-wrap: anywhere;
  }

  /* Belastungsverlauf und Saisonbilanz gehoeren als zweites Kennzahlenpaar
     zusammen. Ist noch keine Saison aktiv, wird der Verlauf vollbreit. */
  .player-dashboard-grid .db-tiles > :is(.home-personal-load, .home-personal-season) {
    order: 3;
  }

  .player-dashboard-grid .db-tiles:not(:has(.home-personal-season)) > .home-personal-load,
  .player-dashboard-grid .db-tiles:not(:has(.home-personal-load)) > .home-personal-season {
    grid-column: 1 / -1;
  }

  .player-dashboard-grid .db-tiles > .home-physio {
    order: 4;
  }

  .player-dashboard-grid .home-today { order: 1; }
  .player-dashboard-grid .home-tomorrow { order: 2; }
  .player-dashboard-grid .home-finances { order: 4; }

  /* Bank und Strafen stehen mobil immer allein in ihrer Reihe – seit die
     Kacheln einen eigenen Container haben, gibt es keinen Nachbarn mehr, der
     die zweite Haelfte fuellen koennte. */
  .player-dashboard-grid :is(.home-today, .home-tomorrow, .home-physio, .home-finances) {
    grid-column: 1 / -1;
  }

  .player-dashboard-grid .home-finances {
    max-width: 100%;
    overflow: hidden;
  }

  .player-dashboard-grid .home-finances .fines-list.open {
    width: 100%;
    max-width: 100%;
    overflow-x: hidden;
    overflow-y: auto;
    scrollbar-gutter: auto;
  }

  .player-dashboard-grid .home-finances .fines-table {
    width: 100%;
    min-width: 0;
    max-width: 100%;
    table-layout: fixed;
  }

  .player-dashboard-grid .home-finances .fines-table :is(th, td):first-child {
    width: 48%;
    overflow-wrap: anywhere;
    word-break: normal;
    white-space: normal;
  }

  .player-dashboard-grid .home-finances .fines-table :is(th, td):nth-child(2) {
    width: 22%;
    white-space: nowrap;
  }

  .player-dashboard-grid .home-finances .fines-table :is(th, td):nth-child(3) {
    width: 30%;
    white-space: nowrap;
  }

  .player-dashboard-grid .db-card {
    padding: 16px;
    border-radius: 15px;
    box-shadow: none;
  }

  /* Mindesthoehe nur fuer die halbbreiten Kacheln, damit Paare gleich hoch
     wirken. Bank und Strafen nehmen die volle Breite ein und richten sich nach
     ihrem Inhalt – sonst bliebe unter dem Betrag eine leere Flaeche. */
  .player-dashboard-grid :is(.home-attendance, .home-duty, .home-competition, .home-personal-load, .home-personal-season) {
    min-height: 126px;
  }

  .player-dashboard-grid .db-card-session-group {
    padding: 0;
  }

  .player-dashboard-grid .sess-item-colored {
    padding: 18px 18px 18px 24px;
  }

  .player-dashboard-grid .sess-date-big {
    font-size: 29px;
  }

  .player-dashboard-grid .fines-sum {
    margin-top: auto;
    font-size: clamp(38px, 11vw, 48px);
  }

  .player-dashboard-grid .competition-score {
    font-size: 38px;
  }

  .player-dashboard-grid .sess-meta {
    display: grid;
    grid-template-columns: repeat(2, minmax(0, 1fr));
    gap: 11px;
  }

  .player-dashboard-grid .home-finances .bank-compact {
    grid-template-columns: repeat(2, minmax(0, 1fr));
  }

  /* Die Terminleiste bleibt bewusst nicht am oberen Rand kleben: Beim Erfassen
     braucht man die Spaltenüberschriften im Blick, nicht die Terminauswahl.
     Sticky war hier das falsche Element – es verdrängte den mitlaufenden
     Tabellenkopf. */
  .attendance-page .attendance-date-nav {
    margin-bottom: 10px;
    padding: 7px;
    box-shadow: var(--shadow-soft);
  }

  /* Die Monatsuebersicht bleibt mobil erreichbar, verliert aber ihre
     Beschriftung: Als quadratisches Kalendersymbol passt sie neben die
     Pfeile, ohne die Terminkacheln zu verdraengen. */
  .attendance-page .attendance-nav-all .attendance-nav-all-label {
    display: none;
  }

  .attendance-page .attendance-nav-all .action-menu-trigger {
    width: 36px;
    min-width: 36px;
    padding: 0;
    gap: 0;
    justify-content: center;
  }

  .attendance-page .attendance-editor,
  .attendance-page .attendance-empty-state,
  .attendance-page .attendance-readonly {
    padding: 17px 14px;
    border-radius: 15px;
    box-shadow: none;
  }

  .attendance-page .attendance-editor-heading {
    /* Umbrechen statt schrumpfen: die Karte kappt auf Mobile per overflow:hidden,
       eine nicht umbrechende Aktionszeile waere sonst halb abgeschnitten. */
    flex-wrap: wrap;
    margin-bottom: 17px;
    padding-bottom: 15px;
  }

  .attendance-page .attendance-kader-slot {
    justify-content: flex-start;
  }

  .attendance-page .attendance-editor-heading h2 {
    font-size: 31px;
  }

  .attendance-page .attendance-note-actions {
    display: grid;
    grid-template-columns: repeat(2, minmax(0, 1fr));
  }

  .attendance-page .attendance-note-actions .btn {
    width: 100%;
    min-height: 47px;
    padding: 8px;
  }

  .attendance-page.mobile-layout-stack .table-wrap {
    overflow: visible;
    border: 0;
    border-radius: 0;
    background: transparent;
  }

  .attendance-page.mobile-layout-stack .attendance-user-table,
  .attendance-page.mobile-layout-stack .attendance-user-table tbody {
    display: block;
    width: 100%;
  }

  .attendance-page.mobile-layout-stack .attendance-user-table thead {
    display: none;
  }

  .attendance-page.mobile-layout-stack .attendance-user-table tbody {
    display: flex;
    flex-direction: column;
    gap: 9px;
  }

  .attendance-page.mobile-layout-stack .attendance-user-table tr {
    display: grid;
    grid-template-columns: repeat(2, minmax(0, 1fr));
    gap: 11px 10px;
    width: 100%;
    padding: 14px;
    border: 1px solid var(--border);
    border-radius: 13px;
    background: var(--surface-raised);
    box-shadow: none;
  }

  .attendance-page.mobile-layout-stack .attendance-user-table td {
    display: flex;
    flex-direction: column;
    align-items: stretch;
    justify-content: flex-start;
    gap: 5px;
    width: auto;
    min-width: 0;
    padding: 0;
    border: 0;
    background: transparent;
    text-align: left;
  }

  .attendance-page.mobile-layout-stack .attendance-user-table td::before {
    display: block;
    width: auto;
    margin: 0;
    color: var(--muted);
    content: attr(data-label);
    font-size: 8px;
    font-weight: 700;
    letter-spacing: .11em;
    text-transform: uppercase;
  }

  .attendance-page.mobile-layout-stack .attendance-user-table td:first-child {
    grid-column: 1 / -1;
    padding-bottom: 10px;
    border-bottom: 1px solid var(--border);
    color: var(--text);
    font-family: "Barlow Condensed", sans-serif;
    font-size: 22px;
    font-weight: 700;
  }

  .attendance-page.mobile-layout-stack .attendance-user-table td:first-child::before {
    display: none;
  }

  .attendance-page.mobile-layout-stack .attendance-user-table td[data-label="Kommentar"] {
    grid-column: 1 / -1;
  }

  .attendance-page.mobile-layout-stack .attendance-user-table input,
  .attendance-page.mobile-layout-stack .attendance-user-table select {
    width: 100%;
    min-height: 48px;
    font-size: 13px;
  }

  /* Kleiner Auslauf unter der Tabelle: Am Ende der Liste sitzt die Speicherleiste
     an ihrer eigenen Position, ein Auslauf in Leistenhöhe würde dort eine große
     Lücke aufreißen. Er hält nur die letzte Zeile frei, während die Leiste noch
     mitwandert. */
  .attendance-page .attendance-editor .table-wrap {
    padding-bottom: 18px;
  }

  .attendance-page .attendance-form-actions {
    position: sticky;
    z-index: 35;
    right: 0;
    bottom: calc(env(safe-area-inset-bottom) + 8px);
    left: 0;
    display: grid;
    grid-template-columns: 1fr auto;
    gap: 7px;
    margin: 14px -7px 0;
    padding: 8px;
    border: 1px solid var(--border);
    border-radius: 14px;
    background: color-mix(in srgb, var(--surface-raised) 92%, transparent);
    box-shadow: var(--shadow);
    backdrop-filter: blur(16px);
  }

  .attendance-page .attendance-form-actions button {
    min-width: 0;
    min-height: 48px;
    margin: 0;
  }

  .attendance-page .attendance-form-actions button:first-child {
    min-width: 0;
  }

  .attendance-page .attendance-form-actions button.secondary,
  .attendance-page .attendance-form-actions button.danger {
    grid-column: auto;
    width: 48px;
    overflow: hidden;
    padding: 0;
    color: transparent;
    font-size: 0;
  }

  .attendance-page .attendance-form-actions button.secondary::after {
    content: "↺";
    color: var(--muted);
    font-size: 20px;
  }

  .attendance-page .attendance-form-actions button.danger {
    display: none;
  }
}

@media (max-width: 390px) {
  /* Auf sehr schmalen Geraeten eine Stufe kleiner - einheitlich fuer alle
     Seiten, damit der Kopf ueberall gleich reagiert. */
  .redesign-page .v2-app-header .brand-title {
    display: block;
    font-size: 15px;
  }

  .redesign-page .v2-app-header .page-title {
    font-size: 12px;
  }

  .redesign-page .v2-app-header .logo {
    width: 42px;
    height: 51px;
  }

  .redesign-page .v2-app-header .brand {
    gap: 8px;
  }

  .player-hero h2 strong {
    max-width: 78vw;
  }

  .player-dashboard-grid .sess-meta {
    grid-template-columns: 1fr;
  }

  .attendance-page .attendance-nav-arrow {
    width: 36px;
    min-width: 36px;
  }
}

@media (prefers-reduced-motion: reduce) {
  .redesign-page *,
  .login-page * {
    scroll-behavior: auto !important;
    transition-duration: .001ms !important;
    animation-duration: .001ms !important;
    animation-iteration-count: 1 !important;
  }
}

/* ========================================================================== */
/* Platzbelegung – Planungsarbeitsplatz                                       */
/* ========================================================================== */

.resource-schedule-page .container {
  max-width: none;
}

.resource-schedule-page .container > .card {
  padding: clamp(18px, 2.4vw, 32px);
  overflow: visible;
}

.resource-schedule-page .schedule-workbench-head {
  display: flex;
  align-items: flex-start;
  justify-content: space-between;
  gap: 24px;
  padding: 4px 2px 16px;
}

.resource-schedule-page .schedule-workbench-copy {
  max-width: 720px;
}

.resource-schedule-page .schedule-workbench-copy h2 {
  margin: 3px 0 4px;
  font-family: "Barlow Condensed", sans-serif;
  font-size: clamp(28px, 3vw, 40px);
  line-height: 1;
  letter-spacing: -.015em;
}

.resource-schedule-page .schedule-workbench-copy p,
/* Auswahlzeilen im Veroeffentlichen-Dialog tragen Inhaltsdaten (Team- und Planname).
   Sie liegen in einem `.field`, dessen Regel Feldbeschriftungen in Versalien setzt –
   das gilt fuer Beschriftungen, nicht fuer Namen. */
.resource-schedule-page .field label.cpm-plan-option {
  text-transform: none;
  letter-spacing: normal;
  font-size: .85rem;
}

.resource-schedule-page .cpm-plan-option strong {
  color: var(--text);
  font-weight: 600;
}

.resource-schedule-page .cpm-plan-option small {
  color: var(--muted);
}

.resource-schedule-page .schedule-modal-lead {
  margin: 0;
  color: var(--muted);
  font-size: 14px;
  line-height: 1.55;
}

.resource-schedule-page .schedule-workbench-actions {
  display: flex;
  align-items: center;
  justify-content: flex-end;
  gap: 8px;
  flex-wrap: wrap;
}

/* Runder Infoknopf neben einem Karten- oder Seitenkopf. Entspricht bewusst
   derselben kompakten Werkzeugform wie in der Belastungssteuerung. */
.redesign-page .btn.icon-only {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 32px;
  min-width: 32px;
  height: 32px;
  min-height: 32px;
  padding: 0;
  border-radius: 50%;
  font-family: "Sora", sans-serif;
  font-size: 14px;
  font-weight: 750;
  font-style: italic;
  line-height: 1;
}

/* Die Zähler-Knöpfe der Kopfzeile ("Änderungsanträge", "Ohne Platz", "Alter Platz
   zugewiesen") tragen dieselbe Form: Text plus rundes Zahlenfeld. Unterschiedlich ist
   nur die Dringlichkeit – wer eine Handlung verlangt, ist gefüllt, der Rest ruhig.
   Vorher stand die Zahlenform zweimal fast gleich da, und ein neuer Knopf traf mit
   `secondary` plus der gefüllten Klasse einen Zwitter aus beidem. */
.resource-schedule-page .schedule-count-button .badge {
  min-width: 22px;
  min-height: 22px;
  display: inline-grid;
  place-items: center;
  padding: 1px 6px;
  margin-left: 4px;
  border-radius: 999px;
  background: var(--accent);
  color: var(--text-on-dark);
}

/* Platzlose konkrete Termine verlangen eine Handlung. Diese Aktion darf nicht wie
   eine gleichwertige Nebenfunktion aussehen: das volle Vereinsrot macht sie zum
   klaren Einstieg, während Änderungsanträge bewusst ruhig bleiben. */
.resource-schedule-page .schedule-unassigned-button {
  border-color: var(--danger);
  background: var(--danger);
  color: var(--text-on-dark);
  font-weight: 750;
  box-shadow: 0 7px 16px color-mix(in srgb, var(--danger) 26%, transparent);
}

.resource-schedule-page .schedule-unassigned-button:hover {
  border-color: var(--accent-2);
  background: var(--accent-2);
  color: var(--text-on-dark);
}

/* Auf der gefüllten Aktion dreht sich das Zahlenfeld um: helle Fläche, rote Ziffer. */
.resource-schedule-page .schedule-unassigned-button .badge {
  background: var(--surface-raised);
  color: var(--danger);
}

/* Platzverwaltung: Der Anlagenplan zeigt echte Flächen als ein bewusst
   vereinfachtes Raster. Das Raster ist nur die visuelle Orientierung; Termine
   bleiben weiter an den bestehenden Ressourcen gebunden. */
.resource-management-page .resource-layout-card {
  margin-top: 18px;
}

.resource-management-page .resource-layout-title {
  margin: 3px 0 0;
  font-family: "Barlow Condensed", sans-serif;
  font-size: clamp(26px, 2.4vw, 34px);
  line-height: 1;
}

.resource-management-page .resource-layout-grid-label {
  flex: 0 0 auto;
  padding: 6px 9px;
  border: 1px solid var(--border);
  border-radius: 999px;
  background: var(--surface-subtle);
  color: var(--muted);
  font-size: 11px;
  font-weight: 700;
}

.resource-management-page .resource-layout-lead {
  max-width: 720px;
  margin: 12px 0 16px;
  color: var(--muted);
  font-size: 13px;
  line-height: 1.55;
}

.resource-management-page .resource-layout-editor {
  display: grid;
  grid-template-columns: repeat(12, minmax(0, 1fr));
  grid-template-rows: repeat(14, minmax(34px, 1fr));
  height: clamp(500px, 48vw, 700px);
  overflow: hidden;
  border: 1px solid var(--border);
  border-radius: 16px;
  background-color: var(--surface-subtle);
  background-image: linear-gradient(to right, color-mix(in srgb, var(--border) 72%, transparent) 1px, transparent 1px), linear-gradient(to bottom, color-mix(in srgb, var(--border) 72%, transparent) 1px, transparent 1px);
  background-size: calc(100% / 12) calc(100% / 14);
  touch-action: none;
}

.resource-management-page .resource-layout-tile {
  grid-column: var(--layout-x) / span var(--layout-width);
  grid-row: var(--layout-y) / span var(--layout-height);
  display: grid;
  align-content: center;
  justify-items: center;
  gap: 3px;
  min-width: 0;
  min-height: 0;
  padding: 9px;
  border: 2px solid color-mix(in srgb, var(--success) 76%, var(--border));
  border-radius: 8px;
  background: color-mix(in srgb, var(--success) 9%, var(--surface-raised));
  color: var(--text);
  cursor: grab;
  user-select: none;
  transition: border-color .14s ease, background-color .14s ease, box-shadow .14s ease, transform .14s ease;
}

.resource-management-page .resource-layout-tile:active {
  cursor: grabbing;
}

.resource-management-page .resource-layout-tile:hover,
.resource-management-page .resource-layout-tile.is-selected {
  z-index: 1;
  border-color: var(--accent);
  background: color-mix(in srgb, var(--accent) 11%, var(--surface-raised));
  box-shadow: 0 0 0 3px color-mix(in srgb, var(--accent) 14%, transparent);
}

.resource-management-page .resource-layout-tile strong {
  max-width: 100%;
  overflow: hidden;
  font-family: "Barlow Condensed", sans-serif;
  font-size: clamp(20px, 2.2vw, 32px);
  font-weight: 750;
  line-height: .95;
  text-overflow: ellipsis;
  white-space: nowrap;
}

.resource-management-page .resource-layout-tile > span:not(.resource-layout-resize-handle),
.resource-management-page .resource-layout-tile small {
  max-width: 100%;
  overflow: hidden;
  color: var(--muted);
  font-size: 10px;
  line-height: 1.2;
  text-align: center;
  text-overflow: ellipsis;
  white-space: nowrap;
}

.resource-management-page .resource-layout-tile[data-split="HALVES"]::after,
.resource-management-page .resource-layout-tile[data-split="QUARTERS"]::after {
  content: "";
  position: absolute;
  inset: 50% 8px auto;
  border-top: 1px dashed color-mix(in srgb, var(--accent) 64%, transparent);
  pointer-events: none;
}

.resource-management-page .resource-layout-tile[data-split="QUARTERS"]::before {
  content: "";
  position: absolute;
  inset: 8px auto 8px 50%;
  border-left: 1px dashed color-mix(in srgb, var(--accent) 64%, transparent);
  pointer-events: none;
}

.resource-management-page .resource-layout-tile {
  position: relative;
}

.resource-management-page .resource-layout-resize-handle {
  display: none;
  position: absolute;
  z-index: 2;
  width: 14px;
  height: 14px;
  border: 2px solid var(--surface-raised);
  border-radius: 4px;
  background: var(--accent);
  box-shadow: 0 1px 3px color-mix(in srgb, var(--text) 24%, transparent);
  touch-action: none;
}

.resource-management-page .resource-layout-tile.is-selected .resource-layout-resize-handle {
  display: block;
}

.resource-management-page .handle-nw { top: 5px; left: 5px; cursor: nwse-resize; }
.resource-management-page .handle-n { top: 5px; left: calc(50% - 7px); cursor: ns-resize; }
.resource-management-page .handle-ne { top: 5px; right: 5px; cursor: nesw-resize; }
.resource-management-page .handle-e { top: calc(50% - 7px); right: 5px; cursor: ew-resize; }
.resource-management-page .handle-se { right: 5px; bottom: 5px; cursor: nwse-resize; }
.resource-management-page .handle-s { bottom: 5px; left: calc(50% - 7px); cursor: ns-resize; }
.resource-management-page .handle-sw { bottom: 5px; left: 5px; cursor: nesw-resize; }
.resource-management-page .handle-w { top: calc(50% - 7px); left: 5px; cursor: ew-resize; }

.resource-management-page .resource-layout-controls {
  display: grid;
  grid-template-columns: minmax(180px, 1fr) minmax(190px, .85fr);
  gap: 14px;
  align-items: center;
  margin-top: 14px;
  padding: 13px;
  border: 1px solid var(--border);
  border-radius: 13px;
  background: var(--surface-subtle);
}

.resource-management-page .resource-layout-selected {
  display: grid;
  gap: 3px;
}

.resource-management-page .resource-layout-selected > strong {
  color: var(--text);
  font-size: 15px;
}

.resource-management-page .resource-layout-selected > small {
  color: var(--muted);
  font-size: 11px;
}

.resource-management-page .resource-layout-split-field {
  display: grid;
  gap: 6px;
  color: var(--muted);
  font-size: 11px;
  font-weight: 700;
}

.resource-management-page .resource-layout-split-field select {
  min-width: 0;
  height: 38px;
}

.resource-management-page .resource-layout-warning {
  margin: 10px 0 0;
  color: var(--danger);
  font-size: 12px;
  font-weight: 650;
}

.resource-management-page .resource-layout-save-row {
  margin-top: 14px;
}

.resource-management-page .resource-layout-save-row > span {
  max-width: 640px;
}

.content-page .club-settings-resource-actions {
  display: flex;
  align-items: center;
  gap: 8px;
}

.resource-schedule-page .schedule-mode-tabs {
  display: grid;
  grid-template-columns: repeat(2, minmax(0, 1fr));
  gap: 8px;
  padding: 6px;
  margin-bottom: 14px;
  border: 1px solid var(--border);
  border-radius: 14px;
  background: var(--surface-subtle);
}

.resource-schedule-page .schedule-mode-tabs a {
  display: flex;
  flex-direction: column;
  gap: 1px;
  min-height: 48px;
  justify-content: center;
  padding: 7px 16px;
  border: 1px solid transparent;
  border-radius: 10px;
  color: var(--muted);
  text-decoration: none;
}

.resource-schedule-page .schedule-mode-tabs a span {
  color: inherit;
  font-weight: 700;
}

.resource-schedule-page .schedule-mode-tabs a small {
  font-size: 11px;
}

.resource-schedule-page .schedule-mode-tabs a.active {
  border-color: var(--border);
  background: var(--surface-raised);
  color: var(--text);
  box-shadow: var(--shadow-soft);
}

.resource-schedule-page .schedule-controlbar {
  display: flex;
  align-items: center;
  gap: 10px;
  min-height: 56px;
  margin: 0 0 14px;
  padding: 8px 10px;
  border: 1px solid var(--border);
  border-radius: 12px;
  background: var(--surface-raised);
}

.resource-schedule-page .schedule-controlbar .sched-range {
  margin-left: 4px;
  font-size: 14px;
  white-space: nowrap;
}

/* `.sched-nav` und `.sched-toolbar` standen im Markup, aber nie im Stylesheet – die
   Blaetterpfeile brachen dadurch umeinander um. Die Gruppe bleibt in einer Reihe und
   behaelt ihre Breite. */
.resource-schedule-page .schedule-controlbar .sched-nav {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  flex-shrink: 0;
}

/* `input[type=date]` traegt global `width: 100%` (app.css). Als Flex-Kind der Leiste
   frisst das Feld damit den gesamten Rest; es gehoert kompakt an den rechten Rand. */
.resource-schedule-page .schedule-controlbar .sched-date-input {
  width: auto;
  min-width: 150px;
  margin-left: auto;
  flex-shrink: 0;
}

.resource-schedule-page .schedule-pattern-reference {
  justify-content: space-between;
}

.resource-schedule-page .schedule-pattern-reference > div {
  display: grid;
  gap: 2px;
}

.resource-schedule-page .schedule-pattern-reference .sched-range {
  margin-left: 0;
}

.resource-schedule-page .schedule-pattern-reference small {
  line-height: 1.4;
}

.resource-schedule-page .schedule-view-switch,
.resource-schedule-page .schedule-day-select {
  display: inline-flex;
  align-items: center;
  gap: 3px;
  padding: 3px;
  border-radius: 9px;
  background: var(--surface-subtle);
}

.resource-schedule-page .schedule-view-switch {
  margin-left: auto;
}

.resource-schedule-page .schedule-view-switch a,
.resource-schedule-page .schedule-day-select a {
  min-height: 36px;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  padding: 6px 13px;
  border-radius: 7px;
  color: var(--muted);
  text-decoration: none;
  font-size: 13px;
  font-weight: 650;
}

.resource-schedule-page .schedule-view-switch a.active,
.resource-schedule-page .schedule-day-select a.active {
  background: var(--surface-raised);
  color: var(--accent);
  box-shadow: 0 1px 5px color-mix(in srgb, var(--text) 10%, transparent);
}

.resource-schedule-page .schedule-date-form {
  display: contents;
}

.resource-schedule-page .sched-date-input {
  min-height: 40px;
  border-color: var(--border);
  border-radius: 8px;
  background: var(--surface-raised);
  color: var(--text);
}

.resource-schedule-page .res-filter {
  gap: 7px;
  margin-bottom: 9px;
}

.resource-schedule-page .res-chip {
  min-height: 34px;
  padding: 5px 12px;
  border-color: var(--border);
  border-radius: 999px;
  background: var(--surface-raised);
  color: var(--muted);
}

.resource-schedule-page .res-chip.sel {
  border-color: color-mix(in srgb, var(--accent) 55%, var(--border));
  background: color-mix(in srgb, var(--accent) 9%, var(--surface-raised));
  color: var(--accent);
}

.resource-schedule-page .legend {
  min-height: 34px;
  padding: 6px 10px;
  margin: 12px 0;
  border-radius: 8px;
  background: var(--surface-subtle);
  color: var(--muted);
}

/* Legende links, Ansichtsumschalter rechts - beides direkt ueber der Tabelle,
   damit dafuer keine eigene Steuerzeile noetig ist. */
.resource-schedule-page .schedule-table-bar {
  display: flex;
  align-items: center;
  gap: 10px;
  margin: 0 0 10px;
}

.resource-schedule-page .schedule-table-bar .legend {
  flex: 1 1 auto;
  margin: 0;
}

.resource-schedule-page .schedule-table-bar .schedule-view-switch {
  flex: 0 0 auto;
  margin-left: auto;
}

.resource-schedule-page .leg-dot.team-own {
  background: var(--success);
}

.resource-schedule-page .leg-dot.team-other,
.resource-schedule-page .leg-dot.team-neutral {
  background: var(--muted);
}

.resource-schedule-page .leg-dot.draft {
  background: color-mix(in srgb, var(--caution) 28%, var(--surface-raised));
  border-color: var(--caution);
}

.resource-schedule-page .leg-dot.conf {
  background: var(--danger);
  box-shadow: 0 0 0 2px color-mix(in srgb, var(--danger) 25%, transparent);
}

/* Einzelne Hinweiszeile ueber der Tabelle. Sie tritt nur bei Handlungsbedarf auf und
   ist deshalb keine Kachelreihe mehr: eine Zeile, volle Breite, direkt anschliessend. */
.resource-schedule-page .schedule-status-note {
  min-height: 52px;
  display: flex;
  align-items: center;
  gap: 10px;
  margin: 2px 0 12px;
  padding: 9px 12px;
  border: 1px solid var(--border);
  border-radius: 10px;
  background: var(--surface-raised);
}

.resource-schedule-page .schedule-status-note > span:last-child {
  display: flex;
  flex-direction: column;
  min-width: 0;
}

/* Eine aktuell verdrängte Grundregel bleibt zuweisbar; der Hinweis erklärt nur,
   warum sie im laufenden Zeitraum noch keine konkreten Termine erzeugt. */
.resource-schedule-page .unassigned-idle {
  display: block;
  color: var(--muted);
  font-size: .74rem;
  line-height: 1.4;
}

/* Die Arbeitslisten („Ohne Platz", „Platz nicht mehr verfügbar") stehen in einem
   scrollenden Rahmen. Ohne feste Zeilen liefen lange Teamnamen in die Nachbarspalte –
   die Zellen bleiben deshalb einzeilig, gescrollt wird der Rahmen. */
/* Die Listen borgen sich die Rastertabelle. Deren `table-layout: fixed` teilt die
   Breite gleichmäßig auf – für „Kampfmannschaft“ reichte die Spalte nicht, und der
   Name lief in die Nachbarspalte. Als Liste richten sich die Spalten nach ihrem
   Inhalt; gescrollt wird der Rahmen darum. */
.resource-schedule-page :is(#unassigned-entries, #unavailable-entries) table {
  table-layout: auto;
}

.resource-schedule-page :is(#unassigned-entries, #unavailable-entries) :is(th, td) {
  white-space: nowrap;
}

.resource-schedule-page :is(#unassigned-entries, #unavailable-entries) td small {
  display: block;
}

/* Eine Regel ohne aktiven Platz findet derzeit nirgends statt – das ist der
   dringende Fall in der Liste und trägt deshalb die Warnfarbe. */
.resource-schedule-page .assignment-gap {
  color: var(--caution);
  font-weight: 700;
}

.resource-schedule-page .unassigned-count {
  text-align: center;
  font-variant-numeric: tabular-nums;
}

/* Regeln ohne Platz sind das einzige Feld dieser Leiste, das eine Handlung verlangt –
   ein gelbes Zaehlerzeichen in einer neutralen Kachel geht neben drei Haekchen unter.
   Die Kachel traegt die Warnfarbe deshalb selbst. */
.resource-schedule-page .schedule-status-link {
  border-color: color-mix(in srgb, var(--caution) 42%, var(--border)) !important;
  background: color-mix(in srgb, var(--caution) 10%, var(--surface-raised)) !important;
  color: inherit;
  text-decoration: none;
}

.resource-schedule-page .schedule-status-link strong {
  color: color-mix(in srgb, var(--caution) 70%, var(--text));
}

.resource-schedule-page .schedule-status-link:hover {
  border-color: color-mix(in srgb, var(--caution) 60%, var(--border)) !important;
  background: color-mix(in srgb, var(--caution) 16%, var(--surface-raised)) !important;
}

.resource-schedule-page .schedule-status-note strong {
  font-size: 13px;
}

.resource-schedule-page .schedule-status-note small {
  color: var(--muted);
  font-size: 11px;
  line-height: 1.35;
}

.resource-schedule-page .schedule-status-icon {
  width: 28px;
  height: 28px;
  flex: 0 0 28px;
  display: grid;
  place-items: center;
  border-radius: 50%;
  background: var(--surface-subtle);
  color: var(--muted);
  font-size: 12px;
  font-weight: 800;
}

.resource-schedule-page .schedule-status-icon.is-warning {
  background: color-mix(in srgb, var(--caution) 15%, var(--surface-raised));
  color: var(--caution);
}

.resource-schedule-page .week-grid {
  max-height: min(68vh, 760px);
  overflow: auto;
  border: 1px solid var(--border);
  border-radius: 12px;
  background: var(--surface-raised);
  box-shadow: 0 10px 26px color-mix(in srgb, var(--text) 5%, transparent);
}

.resource-schedule-page .week-table {
  border-spacing: 0;
}

.resource-schedule-page .week-table th,
.resource-schedule-page .week-table td {
  border-color: var(--border);
  padding: 8px;
}

.resource-schedule-page .week-table th,
.resource-schedule-page .week-table .col-res {
  background: var(--surface-subtle);
}

.resource-schedule-page .week-table tbody td:not(.col-res) {
  min-height: 54px;
  transition: background .14s ease, box-shadow .14s ease;
}

/* Leere Zellen bleiben ruhig: der Anlegen-Hinweis erscheint erst auf der Zelle,
   ueber der die Maus steht. Klickbar ist die Flaeche trotzdem durchgehend. */
.resource-schedule-page .schedule-cell-add {
  width: 100%;
  min-height: 42px;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  border: 1px dashed transparent;
  border-radius: 7px;
  background: transparent;
  color: var(--muted);
  cursor: pointer;
  opacity: 0;
  font: inherit;
  transition: opacity .12s ease, border-color .12s ease, background .12s ease, color .12s ease;
}

.resource-schedule-page .schedule-cell-add:hover,
.resource-schedule-page .schedule-cell-add:focus-visible,
.resource-schedule-page td:hover .schedule-cell-add {
  opacity: 1;
  border-color: color-mix(in srgb, var(--accent) 35%, var(--border));
  background: color-mix(in srgb, var(--accent) 6%, var(--surface-raised));
  color: var(--accent);
}

/* Ohne Hover (Touch) gaebe es sonst keinen sichtbaren Einstieg. */
@media (hover: none) {
  .resource-schedule-page .schedule-cell-add {
    opacity: 1;
  }
}

.resource-schedule-page .wchip,
.resource-schedule-page .tslot {
  border-radius: 7px;
  overflow: hidden;
  transition: transform .14s ease, box-shadow .14s ease, opacity .14s ease;
}

/* Team- und Platznamen sind lange Einzelwörter ("Kampfmannschaft",
   "Niederneukirchen"). In einer schmalen Rasterspalte gibt es darin keine Stelle
   zum Umbrechen, und das Wort lief aus der Karte in die Nachbarspalte. Getrennt
   wird nach Silben – dasselbe Mittel wie in der Ressourcenspalte der Tabelle
   (`hyphens` braucht das `lang` am Dokument); `overflow-wrap` bleibt der
   Notausgang, wenn selbst eine Silbe nicht passt. Das `overflow: hidden` oben ist
   nur das Sicherheitsnetz dahinter.

   Die einzeiligen Nebenangaben (`.wchip-team`, `.wchip-plan`) kürzen weiterhin mit
   Auslassungspunkten: Dort hält eine feste Zeilenzahl das Raster ruhig, und der
   volle Name steht im Dialog. */
.resource-schedule-page :is(.wchip, .tslot) strong {
  -webkit-hyphens: auto;
  hyphens: auto;
  overflow-wrap: break-word;
}

.resource-schedule-page .wchip[draggable="true"],
.resource-schedule-page .tslot[draggable="true"] {
  cursor: grab;
}

/* Der Ziehgriff hing per `float:right` hinter dem letzten Textblock und landete damit
   unter der Uhrzeit – gelesen als abgeschnittener Inhalt. Er sitzt jetzt fest in der
   Ecke und tritt erst hervor, wenn die Maus auf dem Block steht: Dass man ziehen kann,
   muss nicht dauerhaft danebenstehen, der Zeiger sagt es beim Hinfahren. */
.resource-schedule-page .wchip[draggable="true"] {
  position: relative;
}

.resource-schedule-page .wchip[draggable="true"]::after {
  content: "⋮⋮";
  position: absolute;
  right: 3px;
  bottom: 2px;
  color: var(--muted);
  font-size: 10px;
  letter-spacing: -3px;
  opacity: 0;
  transition: opacity .12s ease;
  pointer-events: none;
}

.resource-schedule-page .wchip[draggable="true"]:hover::after {
  opacity: .55;
}

.resource-schedule-page .wchip[draggable="true"]:active,
.resource-schedule-page .tslot[draggable="true"]:active {
  cursor: grabbing;
}

.resource-schedule-page .wchip.team-own,
.resource-schedule-page .tslot.team-own {
  border-color: var(--success);
  border-left-color: var(--success);
  background: color-mix(in srgb, var(--success) 13%, var(--surface-raised));
}

.resource-schedule-page .wchip.team-other,
.resource-schedule-page .wchip.team-neutral,
.resource-schedule-page .tslot.team-other,
.resource-schedule-page .tslot.team-neutral {
  border-color: color-mix(in srgb, var(--muted) 48%, var(--border));
  border-left-color: var(--muted);
  background: color-mix(in srgb, var(--muted) 9%, var(--surface-raised));
}

/* Doppelbelegungen sind die Information, wegen der man auf die Seite schaut:
   der Konflikt schlaegt die Teamfarbe, nicht nur das Badge. */
.resource-schedule-page .wchip.conflict,
.resource-schedule-page .tslot.conflict {
  border-color: var(--danger);
  border-left-color: var(--danger);
  background: color-mix(in srgb, var(--danger) 13%, var(--surface-raised));
  box-shadow: inset 0 0 0 1px var(--danger),
              0 0 0 2px color-mix(in srgb, var(--danger) 20%, transparent);
}

.resource-schedule-page .wchip.conflict strong,
.resource-schedule-page .tslot.conflict .tslot-type {
  color: var(--danger);
}

/* Die betroffene Zelle bekommt einen leisen Anstrich, damit die Ueberschneidung
   schon beim Ueberfliegen des Rasters auffaellt. */
.resource-schedule-page .week-table tbody td:has(.wchip.conflict) {
  background: color-mix(in srgb, var(--danger) 6%, transparent);
}

.resource-schedule-page .wchip-badge.draft,
.resource-schedule-page .tslot-badge.draft {
  background: var(--caution);
  color: var(--surface-raised);
}

.resource-schedule-page .wchip-badge.conflict,
.resource-schedule-page .tslot-badge.conflict,
.resource-schedule-page .badge-pending {
  background: var(--danger);
  color: var(--surface-raised);
}

/* Ein offener Antrag verlangt eine Entscheidung und ist damit das einzige Zeichen am
   Termin, das eine Handlung traegt. Eine blasse Toenung reicht dafuer nicht – es traegt
   die Warnfarbe voll und einen Ring, der es aus dem Block heraushebt. */
.resource-schedule-page .status-pending {
  background: var(--caution);
  color: var(--surface-raised);
  box-shadow: 0 0 0 2px color-mix(in srgb, var(--caution) 28%, transparent);
  font-weight: 800;
  cursor: pointer;
}

.resource-schedule-page .status-approved {
  background: color-mix(in srgb, var(--success) 17%, var(--surface-raised));
  color: var(--success);
  cursor: pointer;
}

.resource-schedule-page .status-rejected {
  background: color-mix(in srgb, var(--danger) 16%, var(--surface-raised));
  color: var(--danger);
}

/* In der Legende steht das Zeichen fuer sich, nicht angehaengt an einen Termin – der
   Einzug von `.badge-pending` wuerde es dort vom eigenen Text abruecken. */
.resource-schedule-page .legend .leg-badge {
  margin-left: 0;
  margin-right: 2px;
  flex-shrink: 0;
}

/* Im Dialogkopf ist Platz fuer das Wort: Dort steht der Antragsstand beschriftet
   neben "Entwurf" und "Überschneidung", nicht als blosses Zeichen. */
.resource-schedule-page .sdm-request-badge {
  border: 0;
  font: inherit;
  font-size: .62rem;
  font-weight: 700;
  cursor: pointer;
}

.resource-schedule-page .sdm-request-badge:hover {
  filter: brightness(1.06);
}

.resource-schedule-page .schedule-request-status {
  padding: 11px 14px;
  margin-bottom: 14px;
  border-radius: 9px;
  font-weight: 700;
}

.resource-schedule-page .is-dragging {
  opacity: .42;
  transform: scale(.97);
}

.resource-schedule-page .schedule-drop-target {
  background: color-mix(in srgb, var(--accent) 10%, var(--surface-raised)) !important;
  box-shadow: inset 0 0 0 2px var(--accent);
}

.resource-schedule-page .day-layout {
  max-height: 72vh;
  overflow: auto;
  border: 1px solid var(--border);
  border-radius: 12px;
  background: var(--surface-raised);
}

.resource-schedule-page .day-col-header,
.resource-schedule-page .time-ruler-header,
.resource-schedule-page .time-ruler {
  background: var(--surface-subtle);
}

.resource-schedule-page .day-col-header {
  min-height: 42px;
  display: grid;
  place-items: center;
}

.resource-schedule-page .schedule-col-hint {
  display: block;
  color: var(--muted);
  font-size: 8px;
  font-weight: 500;
  line-height: 1.15;
}

.resource-schedule-page .app-modal.schedule-modal {
  width: min(880px, calc(100vw - 32px));
  max-width: 880px;
  max-height: min(88vh, 920px);
  padding: clamp(22px, 3vw, 34px);
  overflow: auto;
  border-radius: 18px;
}

.resource-schedule-page .schedule-modal--inbox,
.resource-schedule-page .schedule-modal--help {
  max-width: 980px;
}

/* Die offenen Einzeltermine sind eine Aufgabenliste, keine zweite Seite vor dem
   Raster. Das Modal hält den Kalender unmittelbar sichtbar; die Tabelle selbst
   scrollt innerhalb der bewährten Dialogfläche. */
.resource-schedule-page .schedule-modal--unassigned {
  max-width: 1180px;
}

.resource-schedule-page .schedule-session-assign-context {
  display: grid;
  gap: 3px;
  padding: 14px 16px;
  margin: 0 0 16px;
  border: 1px solid color-mix(in srgb, var(--danger) 34%, var(--border));
  border-radius: 12px;
  background: color-mix(in srgb, var(--danger) 7%, var(--surface-subtle));
}

.resource-schedule-page .schedule-session-assign-context strong {
  font-size: 17px;
}

.resource-schedule-page .schedule-session-assign-context small {
  color: var(--muted);
}

.resource-schedule-page .schedule-session-resources {
  display: grid;
  grid-template-columns: repeat(2, minmax(0, 1fr));
  gap: 6px;
  max-height: 250px;
  overflow-y: auto;
  padding: 8px;
  border: 1px solid var(--border);
  border-radius: 10px;
  background: var(--surface-subtle);
}

.resource-schedule-page .schedule-session-resources label {
  display: flex;
  align-items: center;
  gap: 8px;
  min-height: 42px;
  padding: 8px 10px;
  border: 1px solid var(--border);
  border-radius: 8px;
  background: var(--surface-raised);
  font-size: 13px;
  font-weight: 650;
  cursor: pointer;
}

.resource-schedule-page .schedule-session-cabins {
  display: grid;
  gap: 7px;
  margin-top: 12px;
}

.resource-schedule-page .schedule-session-cabins > .muted {
  font-size: .76rem;
  font-weight: 700;
  letter-spacing: .05em;
  text-transform: uppercase;
}

.resource-schedule-page .schedule-session-more {
  display: grid;
  gap: 10px;
  padding: 12px 0 0;
  border-top: 1px solid var(--border);
}

.resource-schedule-page .schedule-session-more summary {
  color: var(--muted);
  font-size: 13px;
  font-weight: 700;
  cursor: pointer;
}

.resource-schedule-page .schedule-modal .app-modal-header {
  margin-bottom: 18px;
}

.resource-schedule-page .schedule-modal .app-modal-header > div:first-child {
  display: flex;
  flex-direction: column;
  gap: 2px;
}

.resource-schedule-page .schedule-modal .app-modal-header strong {
  font-family: "Barlow Condensed", sans-serif;
  font-size: clamp(25px, 3vw, 34px);
  line-height: 1;
}

.resource-schedule-page .schedule-modal .app-modal-close {
  width: 44px;
  height: 44px;
  flex: 0 0 44px;
}

.resource-schedule-page .schedule-modal-lead {
  margin: -4px 0 18px;
}

.resource-schedule-page .schedule-scope-banner {
  display: flex;
  align-items: center;
  gap: 14px;
  padding: 15px 17px;
  margin-bottom: 20px;
  border: 1px solid color-mix(in srgb, var(--accent) 30%, var(--border));
  border-radius: 12px;
  background: color-mix(in srgb, var(--accent) 7%, var(--surface-raised));
}

.resource-schedule-page .schedule-scope-banner.is-neutral {
  border-color: var(--border);
  background: var(--surface-subtle);
}

.resource-schedule-page .schedule-scope-icon {
  width: 44px;
  height: 44px;
  flex: 0 0 44px;
  display: grid;
  place-items: center;
  border-radius: 50%;
  background: var(--surface-raised);
  color: var(--accent);
  font-weight: 800;
}

.resource-schedule-page .schedule-scope-banner > div {
  display: flex;
  flex-direction: column;
  gap: 2px;
}

.resource-schedule-page .schedule-scope-banner strong {
  font-size: 18px;
}

.resource-schedule-page .schedule-scope-banner small,
.resource-schedule-page .schedule-form-grid .field > small {
  color: var(--muted);
  font-size: 11px;
  line-height: 1.4;
}

/* Der Name ist Freitext und braucht die volle Zeile; Von und Bis gehoeren als Paar
   nebeneinander. Muss nach der generischen Rasterregel stehen, sonst wirkt es nicht. */
.resource-schedule-page .resource-phase-name-field {
  grid-column: 1 / -1;
}

.resource-schedule-page .schedule-form-grid {
  display: grid;
  grid-template-columns: repeat(2, minmax(0, 1fr));
  gap: 18px;
  margin-bottom: 16px;
}

.resource-schedule-page .schedule-form-grid .field {
  display: flex;
  flex-direction: column;
  gap: 6px;
  margin: 0;
}

/* Die Eingabefelder der Termindialoge stehen nebeneinander und müssen deshalb
   gleich hoch sein. Die `:not()`-Kette der Grundregel für Eingabefelder wiegt
   schwerer als ein zweiteiliger Klassenpfad – ohne sie hier blieben die Zeitfelder
   auf ihren 40px, während Auswahlfelder und Platz-Schalter auf 48px standen. */
.resource-schedule-page .schedule-form-grid select,
.resource-schedule-page .schedule-form-grid input:not([type="checkbox"]):not([type="radio"]),
.resource-schedule-page .schedule-modal .field input:not([type="checkbox"]):not([type="radio"]),
.resource-schedule-page .schedule-modal .field select,
.resource-schedule-page .schedule-picker-trigger,
.resource-schedule-page .planner-resource-trigger {
  width: 100%;
  min-height: 48px;
}

.resource-schedule-page .schedule-picker-trigger {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 8px;
  padding: 9px 13px;
  border: 1px solid var(--border);
  border-radius: 9px;
  background: var(--surface-subtle);
  color: var(--text);
  cursor: pointer;
  text-align: left;
  font: inherit;
}

.resource-schedule-page .schedule-time-range {
  display: grid;
  grid-template-columns: 1fr auto 1fr;
  align-items: center;
  gap: 9px;
}

/* Termin-Dialoge folgen derselben Lesereihenfolge: erst Kontext und Zeit,
   dann die Ressource, deren aktuelle Belegung dadurch aussagekräftig wird. */
.resource-schedule-page .schedule-form-grid--create #csm-team-field,
.resource-schedule-page .schedule-form-grid--assignment #assign-team-field { order: 1; }

.resource-schedule-page .schedule-form-grid--create #csm-type-field,
.resource-schedule-page .schedule-form-grid--assignment #assign-type-field { order: 2; }

.resource-schedule-page .schedule-form-grid--create #csm-time-field,
.resource-schedule-page .schedule-form-grid--assignment #assign-time-field { order: 3; }

.resource-schedule-page .schedule-form-grid--create #csm-resource-field,
.resource-schedule-page .schedule-form-grid--assignment #assign-resource-field { order: 4; }

/* Nur die Wochenregel braucht zusätzlich ihren Gültigkeitsbereich. */
.resource-schedule-page .schedule-form-grid--assignment #assign-plan-field {
  order: 5;
  grid-column: 1 / -1;
}

.resource-schedule-page .schedule-request-list {
  display: flex;
  flex-direction: column;
  gap: 10px;
  max-height: 60vh;
  overflow: auto;
  padding: 2px;
}

.resource-schedule-page .change-request-item {
  padding: 15px 17px;
  border: 1px solid var(--border);
  border-radius: 11px;
  background: var(--surface-raised);
  cursor: pointer;
}

.resource-schedule-page .change-request-item:hover {
  border-color: color-mix(in srgb, var(--accent) 45%, var(--border));
  background: color-mix(in srgb, var(--accent) 4%, var(--surface-raised));
}

.resource-schedule-page .schedule-request-item-head {
  display: flex;
  justify-content: space-between;
  gap: 12px;
  align-items: center;
  margin-bottom: 9px;
}

.resource-schedule-page .schedule-request-item-head > div {
  display: flex;
  align-items: center;
  gap: 8px;
}

.resource-schedule-page .schedule-scope-pill {
  display: inline-flex;
  padding: 3px 7px;
  border-radius: 999px;
  background: var(--surface-subtle);
  color: var(--muted);
  font-size: 10px;
  font-weight: 700;
  text-transform: uppercase;
  letter-spacing: .035em;
}

/* Wochenmuster und Einzeltermin sind unterschiedlich schwer: Der eine Antrag aendert
   einen Tag, der andere die Regel dahinter und damit jede Wiederholung. In einer
   grauen Liste sehen beide gleich aus – das Muster bekommt deshalb die Warnfarbe und
   eine Kante an der Karte, der Einzeltermin bleibt ruhig. */
.resource-schedule-page .schedule-scope-pill.is-pattern {
  background: color-mix(in srgb, var(--caution) 20%, var(--surface-raised));
  color: color-mix(in srgb, var(--caution) 72%, var(--text));
}

.resource-schedule-page .change-request-item.is-pattern {
  border-left: 3px solid var(--caution);
}

.resource-schedule-page .change-request-item.is-single {
  border-left: 3px solid color-mix(in srgb, var(--muted) 40%, var(--border));
}

.resource-schedule-page .schedule-request-change {
  color: var(--muted);
  font-size: 13px;
}

.resource-schedule-page .schedule-change-arrow {
  display: inline-block;
  margin: 0 7px;
  color: var(--accent);
  font-weight: 800;
}

.resource-schedule-page .schedule-request-reason {
  margin-top: 8px;
  overflow: hidden;
  color: var(--text);
  font-size: 12px;
  white-space: nowrap;
  text-overflow: ellipsis;
}

.resource-schedule-page .schedule-empty-state {
  min-height: 170px;
  display: grid;
  place-content: center;
  gap: 4px;
  text-align: center;
  color: var(--muted);
}

.resource-schedule-page .schedule-empty-state strong {
  color: var(--success);
  font-size: 18px;
}

.resource-schedule-page .schedule-request-summary {
  display: grid;
  grid-template-columns: repeat(2, minmax(0, 1fr));
  gap: 10px;
  margin-bottom: 14px;
}

.resource-schedule-page .schedule-request-summary > div,
.resource-schedule-page .schedule-session-facts > div {
  display: flex;
  flex-direction: column;
  gap: 3px;
  padding: 11px 13px;
  border: 1px solid var(--border);
  border-radius: 9px;
  background: var(--surface-subtle);
}

.resource-schedule-page .schedule-before-after {
  display: grid;
  grid-template-columns: minmax(0, 1fr) auto minmax(0, 1fr);
  align-items: stretch;
  gap: 10px;
  margin: 12px 0;
}

.resource-schedule-page .schedule-before-after section {
  display: flex;
  flex-direction: column;
  gap: 5px;
  padding: 15px;
  border: 1px solid var(--border);
  border-radius: 10px;
  background: var(--surface-subtle);
}

.resource-schedule-page .schedule-before-after section.is-requested {
  border-color: color-mix(in srgb, var(--accent) 35%, var(--border));
  background: color-mix(in srgb, var(--accent) 7%, var(--surface-raised));
}

.resource-schedule-page .schedule-before-after-arrow {
  display: grid;
  place-items: center;
  color: var(--accent);
  font-size: 22px;
  font-weight: 800;
}

.resource-schedule-page .schedule-impact-note {
  padding: 10px 12px;
  border-left: 3px solid var(--caution);
  background: color-mix(in srgb, var(--caution) 8%, var(--surface-raised));
  color: var(--muted);
  font-size: 12px;
  line-height: 1.5;
}

/* Ablaufkette im Hilfedialog – dieselbe Form wie im Terminplaner, damit beide
   Strecken als ein System lesbar sind. */
.resource-schedule-page .schedule-help-flow {
  display: flex;
  align-items: stretch;
  gap: 10px;
  margin-bottom: 16px;
}

.resource-schedule-page .schedule-help-flow > div {
  display: grid;
  flex: 1 1 0;
  min-width: 0;
  gap: 4px;
  align-content: center;
  padding: 14px 12px;
  border: 1px solid var(--border);
  border-radius: 13px;
  background: var(--surface-subtle);
  text-align: center;
}

.resource-schedule-page .schedule-help-flow > div strong {
  color: var(--accent);
  font-family: "Barlow Condensed", sans-serif;
  font-size: 1.3rem;
}

.resource-schedule-page .schedule-help-flow > div span {
  color: var(--muted);
  font-size: .72rem;
  line-height: 1.45;
}

.resource-schedule-page .schedule-help-flow > span {
  align-self: center;
  color: var(--accent);
  font-size: 1.1rem;
  font-weight: 800;
}

.resource-schedule-page .schedule-help-grid {
  display: grid;
  grid-template-columns: repeat(2, minmax(0, 1fr));
  gap: 10px;
}

.resource-schedule-page .schedule-help-grid section {
  display: flex;
  gap: 12px;
  padding: 16px;
  border: 1px solid var(--border);
  border-radius: 11px;
  background: var(--surface-subtle);
}

.resource-schedule-page .schedule-help-grid p {
  margin: 4px 0 0;
  color: var(--muted);
  font-size: 12px;
  line-height: 1.5;
}

.resource-schedule-page .schedule-help-number {
  width: 30px;
  height: 30px;
  flex: 0 0 30px;
  display: grid;
  place-items: center;
  border-radius: 50%;
  background: var(--accent);
  color: var(--text-on-dark);
  font-weight: 800;
}

.resource-schedule-page .schedule-help-callout,
.resource-schedule-page .schedule-publish-notice {
  margin-top: 12px;
  padding: 13px 15px;
  border: 1px solid color-mix(in srgb, var(--caution) 36%, var(--border));
  border-radius: 10px;
  background: color-mix(in srgb, var(--caution) 9%, var(--surface-raised));
  color: var(--muted);
  font-size: 12px;
  line-height: 1.5;
}

/* Mehrteilige Hinweise brauchen Absaetze; die Basisregel oben faerbt und rahmt nur. */
.resource-schedule-page .schedule-help-callout > strong {
  display: block;
  margin-bottom: 4px;
  color: var(--text);
}

.resource-schedule-page .schedule-help-callout > span {
  display: block;
  margin-top: 7px;
}

/* Die Kernaussage des Dialogs hebt sich vom gelben Randhinweis ab. */
.resource-schedule-page .schedule-help-callout--key {
  border-color: color-mix(in srgb, var(--accent) 38%, var(--border));
  background: color-mix(in srgb, var(--accent) 7%, var(--surface-raised));
}

.resource-schedule-page .schedule-publish-notice {
  display: flex;
  gap: 11px;
  margin: 0 0 18px;
}

.resource-schedule-page .schedule-publish-notice > span {
  width: 28px;
  height: 28px;
  flex: 0 0 28px;
  display: grid;
  place-items: center;
  border-radius: 50%;
  background: var(--caution);
  color: var(--surface-raised);
  font-weight: 800;
}

.resource-schedule-page .schedule-publish-notice p {
  margin: 0;
}

.resource-schedule-page .schedule-session-facts {
  display: grid !important;
  grid-template-columns: repeat(2, minmax(0, 1fr));
  gap: 9px !important;
}

.resource-schedule-page .schedule-modal-header-actions {
  display: flex;
  align-items: center;
  gap: 6px;
}

@media (max-width: 720px) {
  .resource-schedule-page .container > .card {
    padding: 14px;
  }

  .resource-schedule-page .schedule-workbench-head {
    flex-direction: column;
    gap: 14px;
  }

  .resource-schedule-page .schedule-workbench-actions {
    width: 100%;
    justify-content: flex-start;
  }

  /* Gestreckt bekam jeder Knopf eine eigene Zeile, auch wenn zwei nebeneinander
     gepasst hätten – der Seitenkopf wurde dadurch auf dem Handy sehr hoch. Sie
     behalten deshalb ihre Textbreite und teilen sich die Zeile; die Trefferfläche
     bleibt über `min-height` erhalten. */
  .resource-schedule-page .schedule-workbench-actions .btn:not(.icon-only) {
    flex: 0 1 auto;
  }

  .resource-schedule-page .schedule-mode-tabs a {
    min-height: 50px;
    padding: 7px 10px;
  }

  /* Der Hilfeknopf gehört auf dem Handy in die Ecke der Karte, statt eine eigene
     Zeile unter den Zählern zu belegen. Er sitzt dort neben der Bereichszeile. */
  .resource-schedule-page .schedule-workbench-head {
    position: relative;
  }

  .resource-schedule-page .schedule-workbench-actions .btn.icon-only {
    position: absolute;
    top: 0;
    right: 0;
  }

  /* Platz für den Knopf in der Ecke, damit die Überschrift nicht darunter läuft. */
  .resource-schedule-page .schedule-workbench-copy {
    padding-right: 44px;
  }

  /* Die beiden Arbeitslisten sind Aufgaben, keine Nebenschalter: Sie nehmen die
     ganze Zeile und sind damit auf dem Handy sofort als Handlung erkennbar. Der
     Posteingang „Änderungsanträge" bleibt daneben kompakt. */
  .resource-schedule-page #openUnassignedSessionsModal,
  .resource-schedule-page #openRetiredResourceSessionsModal {
    flex: 1 1 100%;
    justify-content: center;
  }

  /* Der Umschalter Wochenplan/Kalender zentriert seine Beschriftung – linksbündig
     wirkte die aktive Hälfte verrutscht. */
  .resource-schedule-page .schedule-mode-tabs a {
    align-items: center;
    text-align: center;
  }

  /* Woche/Tag über die ganze Zeile, wie der Umschalter darüber: So ist erkennbar,
     dass beide dasselbe tun – die Ansicht wechseln. */
  .resource-schedule-page .schedule-view-switch {
    width: 100%;
    margin-left: 0;
  }

  .resource-schedule-page .schedule-view-switch a {
    flex: 1 1 0;
  }

  /* Die Datumsnavigation steht mittig: Pfeile, Zeitraum und Datumsfeld gehören
     zusammen und wirken linksbündig wie abgerissen. */
  .resource-schedule-page .schedule-controlbar {
    justify-content: center;
    text-align: center;
  }

  .resource-schedule-page .schedule-controlbar .sched-range {
    justify-content: center;
    text-align: center;
  }

  /* Die Platz- und Kabinenfilter brauchten vier Zeilen und schoben das Raster vom
     Bildschirm. Sie laufen jetzt seitlich, wie die Filterleiste im Kalender – die
     Auswahl bleibt vollständig, nur eben in einer Zeile. */
  .resource-schedule-page .res-filter {
    flex-wrap: nowrap;
    overflow-x: auto;
    padding-bottom: 4px;
    -webkit-overflow-scrolling: touch;
    scrollbar-width: none;
  }

  .resource-schedule-page .res-filter::-webkit-scrollbar { display: none; }

  .resource-schedule-page .res-filter > * {
    flex: 0 0 auto;
  }

  /* Der Einstiegssatz erklärt die Ansicht. Auf dem Handy steigt niemand ein, um das
     Programm kennenzulernen – dort wird nachgesehen, wo das Training ist. Die
     Erklärung bleibt im Untertitel des Umschalters und im Hilfedialog. Der Satz für
     Zuschauer bleibt stehen: Er nennt die einzige Handlung, die sie hier haben. */
  .resource-schedule-page .schedule-intro-hint {
    display: none;
  }

  /* Die Legende erklärt nur; auf dem Handy darf sie das Raster nicht vom Bildschirm
     schieben. Enger gesetzt braucht sie zwei statt drei Zeilen. */
  .resource-schedule-page .legend {
    gap: 6px 10px;
    padding: 6px 8px;
    margin: 8px 0;
    font-size: 11px;
  }

  .resource-schedule-page .schedule-mode-tabs a small {
    display: none;
  }

  .resource-schedule-page .schedule-controlbar {
    align-items: stretch;
    flex-wrap: wrap;
  }

  .resource-schedule-page .schedule-controlbar .sched-range {
    flex-basis: calc(100% - 150px);
    display: flex;
    align-items: center;
    white-space: normal;
  }

  /* Das Datumsfeld gehört neben den Zeitraum, nicht darunter: Der Text daneben lässt
     mit `calc(100% - 150px)` genau dafür Platz. Mit voller Breite brach es um und
     belegte eine eigene Zeile, obwohl 150px reichen. */
  .resource-schedule-page .schedule-controlbar .sched-date-input {
    width: auto;
    min-width: 140px;
    margin-left: 0;
    flex: 0 1 auto;
  }

  .resource-schedule-page .schedule-day-select {
    width: 100%;
    overflow-x: auto;
  }

  .resource-schedule-page .schedule-day-select a {
    flex: 1 0 42px;
  }

  .resource-schedule-page .schedule-form-grid,
  .resource-schedule-page .schedule-help-flow {
    align-items: stretch;
    flex-direction: column;
  }

  .resource-schedule-page .schedule-help-flow > span {
    transform: rotate(90deg);
  }

  .resource-schedule-page .schedule-help-grid,
  .resource-schedule-page .schedule-request-summary,
  .resource-schedule-page .schedule-session-facts {
    grid-template-columns: 1fr;
  }

  .resource-schedule-page .schedule-session-resources {
    grid-template-columns: 1fr;
  }

  .resource-schedule-page .schedule-table-bar {
    flex-wrap: wrap;
  }

  .resource-schedule-page .schedule-table-bar .legend {
    flex-basis: 100%;
    order: 2;
  }

  .resource-schedule-page .schedule-table-bar .schedule-view-switch {
    order: 1;
  }

  .resource-schedule-page .schedule-before-after {
    grid-template-columns: 1fr;
  }

  .resource-schedule-page .schedule-before-after-arrow {
    transform: rotate(90deg);
  }

  .resource-schedule-page .app-modal.schedule-modal {
    width: calc(100vw - 16px);
    max-height: calc(100dvh - 16px);
    padding: 20px 16px;
    border-radius: 14px;
  }
}

/* ==========================================================================
   Monospace-Auszeichnung fuer Kennungen (Rechnungsnummern u.ae.)
   Lag bisher als identische Kopie in budget/invoice-list.html und
   budget/invoice-open.html; mit der Rechnungsspalte in budget/buchungen.html
   waere eine dritte Kopie entstanden, daher zentral.
   ========================================================================== */
.mono { font-family: 'Space Grotesk', monospace; }

/* Anlagenplan im Platz-Zuweisungsdialog. Die echte Geometrie bleibt die gleiche
   wie im Editor; ausgewählt wird hier aber bewusst direkt auf der Spielfläche. */
.resource-area-picker-section { margin-bottom: 18px; }
.resource-area-picker-heading { display: grid; gap: 3px; margin-bottom: 10px; }
.resource-area-picker-heading small { color: var(--muted); font-size: .78rem; }
.resource-area-picker-map {
  display: grid;
  grid-template-columns: repeat(12, minmax(0, 1fr));
  grid-template-rows: repeat(14, 34px);
  gap: 3px;
  min-height: 290px;
  padding: 5px;
  overflow: auto;
  border: 1px solid var(--border);
  border-radius: 14px;
  background-color: color-mix(in srgb, var(--text) 5%, var(--surface-subtle));
  background-image: linear-gradient(to right, color-mix(in srgb, var(--border) 75%, transparent) 1px, transparent 1px),
                    linear-gradient(to bottom, color-mix(in srgb, var(--border) 75%, transparent) 1px, transparent 1px);
  background-size: calc(100% / 12) calc(100% / 14);
}
.resource-area-picker-tile {
  position: relative;
  min-width: 0;
  min-height: 0;
  overflow: hidden;
  border: 2px solid color-mix(in srgb, var(--success) 72%, var(--border));
  border-radius: 10px;
  background: color-mix(in srgb, var(--success) 8%, var(--surface-raised));
}
.resource-area-picker-label {
  position: absolute;
  z-index: 2;
  inset: 50% auto auto 50%;
  display: grid;
  gap: 0;
  max-width: calc(100% - 16px);
  transform: translate(-50%, -50%);
  pointer-events: none;
  text-align: center;
}
.resource-area-picker-label strong { color: var(--text); font-family: 'Barlow Condensed', sans-serif; font-size: clamp(1rem, 2.1vw, 1.8rem); line-height: .9; }
.resource-area-picker-label small { overflow: hidden; color: var(--muted); font-size: .68rem; line-height: 1.2; text-overflow: ellipsis; white-space: nowrap; }
.resource-area-picker-occupancy {
  position: absolute;
  z-index: 3;
  right: 5px;
  bottom: 4px;
  max-width: calc(100% - 10px);
  overflow: hidden;
  padding: 2px 5px;
  border-radius: 5px;
  background: color-mix(in srgb, var(--caution) 18%, var(--surface-raised));
  color: var(--caution);
  font-size: .62rem;
  font-weight: 700;
  line-height: 1.1;
  text-overflow: ellipsis;
  white-space: nowrap;
  pointer-events: none;
}
.resource-area-picker-zones,
.resource-area-picker-zone--whole { position: absolute; inset: 0; display: grid; padding: 0; border: 0; background: transparent; }
.resource-area-picker-zones--halves { grid-template-rows: 1fr 1fr; }
.resource-area-picker-zones--quarters { grid-template-columns: 1fr 1fr; grid-template-rows: 1fr 1fr; }
.resource-area-picker-zone { min-width: 0; min-height: 0; margin: 0; border: 1px dashed color-mix(in srgb, var(--danger) 62%, transparent); border-radius: 0; background: transparent; cursor: pointer; transition: background .15s ease, box-shadow .15s ease; }
.resource-area-picker-zone:hover,
.resource-area-picker-zone:focus-visible { outline: none; background: color-mix(in srgb, var(--danger) 14%, transparent); }
.resource-area-picker-zone.is-selected { background: color-mix(in srgb, var(--danger) 25%, var(--surface-raised)); box-shadow: inset 0 0 0 2px var(--danger); }
.resource-area-picker-zone.is-occupied {
  background: color-mix(in srgb, var(--caution) 36%, var(--surface-raised));
  box-shadow: inset 0 0 0 2px color-mix(in srgb, var(--caution) 78%, var(--border));
}
.resource-area-picker-zone.is-occupied.is-selected {
  background: color-mix(in srgb, var(--danger) 30%, var(--surface-raised));
  box-shadow: inset 0 0 0 3px var(--danger);
}
.resource-area-picker-zone--whole { border-radius: 8px; }
.resource-area-picker-tile.has-selection { border-color: var(--danger); }
/* Nur-Ansicht: wer die Platzbelegung nicht verwaltet, sieht die Belegung, waehlt aber nicht aus. */
.resource-area-picker-map.is-readonly .resource-area-picker-zone { border-style: solid; border-color: color-mix(in srgb, var(--border) 80%, transparent); cursor: default; }
.resource-area-picker-map.is-readonly .resource-area-picker-zone:hover { background: transparent; }
.resource-area-picker-map.is-readonly .resource-area-picker-zone:disabled { opacity: 1; }

/* Jeder Dialog, in dem der Anlagenplan zur Platzwahl steht, hat dieselbe Groesse –
   im Kalender, in der Platzbelegung und im Terminplaner. Vorher trug jede Seite ihre
   eigene Breite (680 bis 1080px), und derselbe Plan war je nach Einstieg unterschiedlich
   gross oder musste in sich gescrollt werden.

   Die Regel steht bewusst hier statt bei den Seiten: Der Plan ist ein gemeinsamer
   Baustein, seine Dialoggroesse gehoert deshalb zu ihm und nicht zur jeweiligen Seite. */
:is(.season-planner-page, .calendar-page, .resource-schedule-page)
  :is(.app-modal, .cal-modal).resource-picker-dialog {
  width: min(1080px, calc(100vw - 32px));
  max-width: 1080px;
  max-height: min(92dvh, 1100px);
}

/* Der Plan zeigt immer alle Plaetze auf einmal. Er scrollte sonst in sich selbst,
   waehrend im Dialog daneben noch Raum frei war; gescrollt wird der Dialog.

   Dasselbe gilt fuer den Rahmen um ihn herum: Die Optionsliste der Dialoge war auf
   430px begrenzt, weil sie frueher eine lange Checkbox-Liste trug. Mit dem Anlagenplan
   darin schnitt diese Grenze die unteren Plaetze ab, obwohl der Dialog noch Platz hatte. */
.resource-picker-dialog .resource-area-picker-map,
.resource-picker-dialog .planner-resource-options,
.resource-picker-dialog .cal-team-picker-list {
  max-height: none;
  overflow: visible;
}

/* Teilbelegungen bleiben im Kalender auf einen Blick als solche erkennbar.

   Sie stehen dabei rechts in der Zeitzeile: dort ist der Platz ohnehin frei, waehrend
   eine eigene Zeile jeden Termin im Raster um eine Zeile hoeher machte. Der Umbruch ist
   nur der Notausgang - "¼ oben links" passt in einer schmalen Spalte nicht neben die
   Uhrzeit und rutscht dann darunter, statt aus dem Chip zu laufen. */
.wchip-meta,
.tslot-meta {
    display: flex;
    flex-wrap: wrap;
    align-items: baseline;
    gap: 2px 8px;
}

.wchip-area,
.tslot-area {
    color: var(--caution);
    font-size: .68rem;
    font-weight: 700;
    line-height: 1.2;
    margin-left: auto;
    white-space: nowrap;
}
@media (max-width: 700px) {
  .resource-area-picker-map { grid-template-rows: repeat(14, 25px); min-height: 210px; }
  .resource-area-picker-label small { display: none; }
}

/* ==========================================================================
   CC-Auswahl im Rechnungs-Versanddialog
   Der Dialog (budget/invoice-action-modals.html) wird auf fuenf Seiten eingebunden -
   die Regel muss deshalb zentral stehen, nicht in einem Template.
   ========================================================================== */
.compose-cc-list {
  display: flex;
  flex-wrap: wrap;
  gap: 6px 16px;
}

.compose-cc-list:empty {
  display: none;
}

.compose-cc-list label {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  font-size: .84rem;
}

.compose-cc-list label small {
  color: var(--muted);
}

/* Legende mit echten Badges statt Textkuerzeln: die Farbe ist der Wiedererkennungswert.
   Das Badge steht in der dt-Spalte links, die Erklaerung daneben. */
.explainer-legend > div {
  display: grid;
  grid-template-columns: 76px minmax(0, 1fr);
  gap: 4px 12px;
  align-items: baseline;
}

.explainer-legend dt {
  justify-self: start;
}

.explainer-legend dd {
  margin: 0;
}

/* Gemeinsame Team-Einstellungen und Funktionsverwaltung. */
    .settings-row-split { display:grid; grid-template-columns:1fr 1fr; gap:12px 48px; align-items:start; padding:18px 0; border-top:1px solid var(--border); }
    .settings-row-split:first-child { border-top:none; padding-top:0; }
    .split-label strong { display:block; font-size:.9rem; font-weight:600; margin-bottom:5px; color:var(--text); }
    .split-label p { margin:0; font-size:.84rem; color:var(--muted); line-height:1.5; }
    .split-controls { display:flex; flex-direction:column; gap:10px; }
    .split-controls .field { margin-bottom:0; width:100%; }
    .split-controls .grid-2 { display:grid; grid-template-columns:1fr 1fr; gap:10px; width:100%; }
    @media (max-width:640px) {
      .settings-row-split { grid-template-columns:1fr; gap:10px; }
      .split-controls .grid-2 { grid-template-columns:1fr; }
    }

/* Binäre Einstellungen: Text bekommt den Platz, der Schalter nur Inhaltsbreite. */
.redesign-page .settings-row-split--toggle {
  grid-template-columns: minmax(0, 1fr) auto;
  align-items: center;
  gap: 12px 24px;
  padding-block: 14px;
}

.redesign-page .settings-toggle {
  display: inline-flex;
  align-items: center;
  justify-content: flex-end;
  gap: 10px;
  min-height: 44px;
  min-width: 112px;
  width: auto;
  margin: 0;
  cursor: pointer;
  color: var(--muted);
  font-size: .875rem;
}

.redesign-page .settings-toggle:has(input:disabled) {
  cursor: not-allowed;
}

.redesign-page .settings-toggle .switch-slider {
  background: var(--surface-subtle);
  border-color: var(--muted);
}

.redesign-page .settings-toggle .switch-slider::before {
  background: var(--muted);
}

.redesign-page .settings-toggle input:checked + .switch-slider {
  background: color-mix(in srgb, var(--success) 18%, var(--surface-raised));
  border-color: var(--success);
}

.redesign-page .settings-toggle input:checked + .switch-slider::before {
  background: var(--success);
}

.redesign-page .settings-toggle input:focus-visible + .switch-slider {
  outline: 2px solid var(--accent);
  outline-offset: 3px;
  box-shadow: none;
}

/* Einrückung und Verbindungslinie zeigen die fachliche Abhängigkeit, auch ohne Farbe. */
.redesign-page .settings-row-split--dependent {
  position: relative;
  margin-left: 16px;
  padding-left: 20px;
}

.redesign-page .settings-row-split--dependent::before {
  content: "";
  position: absolute;
  top: 0;
  left: 0;
  width: 10px;
  height: 28px;
  border-left: 2px solid var(--border);
  border-bottom: 2px solid var(--border);
}

.redesign-page .split-label .settings-dependency {
  margin-top: 6px;
  font-size: .875rem;
}

.redesign-page .settings-row-split--dependent.is-blocked .settings-dependency,
.redesign-page .settings-row-split--dependent.is-blocked .settings-toggle {
  color: var(--caution);
}

@media (max-width: 540px) {
  .redesign-page .settings-row-split--toggle {
    grid-template-columns: minmax(0, 1fr);
    gap: 4px;
  }
  .redesign-page .settings-toggle {
    justify-self: start;
    justify-content: flex-start;
    flex-direction: row-reverse;
    min-width: 0;
  }
}

@media (prefers-reduced-motion: reduce) {
  .redesign-page .settings-toggle .switch-slider,
  .redesign-page .settings-toggle .switch-slider::before {
    transition: none;
  }
}

/* ── Spielfeld zur Aufstellung ─────────────────────────────────────────────────

   Ein gemeinsamer Baustein wie der Anlagenplan: Markup in `fragments/match-pitch.html`,
   Verhalten in `match-pitch.js`, Aussehen hier.

   Die Plaetze liegen nach normierten Koordinaten auf der Flaeche (`--slot-x` quer, `--slot-y`
   in der Tiefe, jeweils 0 bis 1). Dadurch zeichnet dieselbe Regel jede Mannschaftsgroesse -
   eine Reihe mit drei Spielern verteilt sich auf dieselbe Breite wie eine mit vier, und eine
   Neuner- oder Siebenerformation braucht spaeter keine eigene Regel. Aus demselben Grund
   laesst sich das Feld auf breiten Schirmen quer legen: dort werden nur die beiden Achsen
   getauscht.

   Alle Groessen haengen an `--chip`, dem Durchmesser der Nummernscheibe. Wer das Feld
   groesser oder kleiner will, aendert diese eine Zahl.

   Die Farben kommen ausnahmslos aus den Tokens. Ein gruener Rasen mit festem Hexwert saehe im
   hellen Thema gleich aus wie im dunklen und passte in keinem von beiden. */
.match-pitch-board {
  --chip: 46px;
  display: grid;
  gap: 12px;
}

.match-pitch-head {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  justify-content: space-between;
  gap: 10px;
}

.match-pitch-formation {
  display: flex;
  align-items: center;
  gap: 8px;
  margin: 0;
}

.match-pitch-formation > span {
  color: var(--muted);
  font-size: 9px;
  font-weight: 700;
  letter-spacing: .12em;
  text-transform: uppercase;
}

.match-pitch-formation select {
  width: auto;
  min-width: 110px;
}

/* Der Rasen. Die Linien sind Farbverlaeufe statt Bildern: sie skalieren mit und tragen in
   beiden Themen, weil sie aus der Rahmenfarbe gemischt sind.

   Die Hoehe wird ueber die Breite gedeckelt: ein Feld im Verhaeltnis 5:7 wuerde sonst bei
   voller Spaltenbreite hoeher als der Bildschirm und die Seite unbrauchbar lang. */
.match-pitch {
  position: relative;
  aspect-ratio: 5 / 7;
  width: 100%;
  max-width: min(560px, calc(78vh * 5 / 7));
  margin: 0 auto;
  border: 1px solid var(--border);
  border-radius: 16px;
  background-color: color-mix(in srgb, var(--success) 16%, var(--surface-subtle));
  background-image:
    /* Mittellinie */
    linear-gradient(to bottom, transparent calc(50% - 1px),
      color-mix(in srgb, var(--border) 90%, transparent) calc(50% - 1px),
      color-mix(in srgb, var(--border) 90%, transparent) calc(50% + 1px), transparent calc(50% + 1px)),
    /* Mittelkreis */
    radial-gradient(circle at 50% 50%, transparent calc(14% - 1px),
      color-mix(in srgb, var(--border) 90%, transparent) calc(14% - 1px),
      color-mix(in srgb, var(--border) 90%, transparent) 14%, transparent 14%);
}

/* Die beiden Straefraeume. Als eigene Elemente waeren sie Markup ohne Aussage.

   pointer-events: none ist hier kein Feinschliff: als letztes Kind der Flaeche liegt ::after
   ueber den Plaetzen und schluckte den Klick auf den Stuermer - die Marke liess sich dort
   nicht absetzen. */
.match-pitch::before,
.match-pitch::after {
  content: "";
  position: absolute;
  pointer-events: none;
  left: 50%;
  width: 56%;
  height: 15%;
  transform: translateX(-50%);
  border: 1px solid color-mix(in srgb, var(--border) 90%, transparent);
}

.match-pitch::before { top: 0; border-top: 0; border-radius: 0 0 8px 8px; }
.match-pitch::after  { bottom: 0; border-bottom: 0; border-radius: 8px 8px 0 0; }

/* Der Platz ist der Anker: genau so gross wie die Nummernscheibe und auf seiner Koordinate
   zentriert. Die Marke haengt sich darauf, nicht hinein - sie ist mit ihrem Namen breiter und
   hoeher, und als Rasterkind wuerde sie beim Ueberlaufen an den Rand gedraengt statt zentriert.
   Genau daher kamen die Ringe, die neben ihren Scheiben sassen. */
.match-pitch-slot {
  position: absolute;
  left: calc(var(--slot-x) * 100%);
  top: calc(var(--slot-y) * 100%);
  width: var(--chip);
  height: var(--chip);
  transform: translate(-50%, -50%);
  display: grid;
  place-items: center;
  border-radius: 50%;
  border: 1px dashed color-mix(in srgb, var(--muted) 45%, transparent);
  background: color-mix(in srgb, var(--surface-raised) 40%, transparent);
  transition: border-color .15s ease, background .15s ease, box-shadow .15s ease;
}

/* Freie Plaetze treten hervor, sobald ein Spieler gewaehlt ist - sonst muss man raten,
   wohin man ihn setzen kann. */
.match-pitch-slot.is-open {
  border-style: solid;
  border-color: var(--accent);
  background: color-mix(in srgb, var(--accent) 14%, var(--surface-raised));
  box-shadow: 0 0 0 4px color-mix(in srgb, var(--accent) 18%, transparent);
}

.match-pitch-slot-role {
  color: var(--muted);
  font-size: calc(var(--chip) * .24);
  font-weight: 700;
  letter-spacing: .06em;
  pointer-events: none;
}

/* Die Platzbeschriftung steht immer im Markup und weicht der Marke. So bleibt das Verschieben
   im Skript eine reine Bewegung - es muss nichts auf- oder abbauen. */
.match-pitch-slot:has(.match-pitch-chip) .match-pitch-slot-role,
.match-pitch-bench:has(.match-pitch-chip) .match-pitch-bench-empty {
  display: none;
}

/* Ein Spieler. Sichtbar sind die runde Nummernscheibe und der Name darunter; der Name darf
   breiter sein als der Platz. Elf Kreise mit je drei lesbaren Buchstaben waeren eine
   Aufstellung, die niemand erkennt.

   Die Scheibe liegt genau auf dem Platz: die Marke beginnt eine halbe Scheibe ueber dessen
   Mitte, der Name flieszt darunter aus dem Ring heraus.

   Die Regeln stehen auf .redesign-page, weil die Seite jedem button Polsterung, Mindesthoehe
   und eckige Ecken gibt. Ohne das gewinnt die allgemeine Regel und die Scheibe ist ein
   abgerundetes Rechteck. */
.redesign-page .match-pitch-slot .match-pitch-chip {
  position: absolute;
  left: 50%;
  top: 50%;
  transform: translate(-50%, calc(var(--chip) / -2));
}

.redesign-page .match-pitch-chip {
  display: grid;
  justify-items: center;
  gap: 3px;
  width: calc(var(--chip) * 1.9);
  min-height: 0;
  padding: 0;
  border: 0;
  border-radius: 8px;
  background: transparent;
  color: var(--text);
  box-shadow: none;
  cursor: pointer;
  /* manipulation, nicht none: bis zum Halten soll der Wisch ueber einer Marke die Seite
     scrollen. Auf der Bank ist fast jede Flaeche eine Marke - mit none koennte man dort
     ueberhaupt nicht mehr scrollen. Waehrend des Ziehens haelt das Skript die Seite an. */
  touch-action: manipulation;
  /* Das lange Halten darf nicht die Lupe und die Textauswahl des Systems aufrufen. */
  -webkit-touch-callout: none;
  user-select: none;
  transition: transform .12s ease, opacity .15s ease;
}

.redesign-page .match-pitch-chip:hover,
.redesign-page .match-pitch-chip:focus-visible {
  outline: none;
  background: transparent;
  transform: translate(-50%, calc(var(--chip) / -2)) scale(1.04);
}

.match-pitch-chip-number {
  position: relative;
  display: grid;
  place-items: center;
  overflow: visible;
  width: var(--chip);
  height: var(--chip);
  border: 2px solid color-mix(in srgb, var(--accent) 70%, var(--border));
  border-radius: 50%;
  background: var(--surface-raised);
  font-family: "Barlow Condensed", "Avenir Next", sans-serif;
  font-size: calc(var(--chip) * .42);
  font-weight: 800;
  line-height: 1;
  transition: border-color .15s ease, background .15s ease, box-shadow .15s ease;
}

.match-pitch-chip-name {
  display: -webkit-box;
  -webkit-box-orient: vertical;
  -webkit-line-clamp: 2;
  max-width: 100%;
  overflow: hidden;
  /* Unter zehn Pixeln liest sich ein Name auf dem Handy nicht mehr. */
  font-size: max(10px, calc(var(--chip) * .21));
  font-weight: 600;
  line-height: 1.15;
  text-align: center;
  overflow-wrap: anywhere;
}

.redesign-page .match-pitch-chip:hover .match-pitch-chip-number,
.redesign-page .match-pitch-chip:focus-visible .match-pitch-chip-number {
  border-color: var(--accent);
  box-shadow: 0 0 0 3px color-mix(in srgb, var(--accent) 22%, transparent);
}

.redesign-page .match-pitch-chip.is-selected .match-pitch-chip-number {
  border-color: var(--accent);
  background: color-mix(in srgb, var(--accent) 18%, var(--surface-raised));
  box-shadow: 0 0 0 4px color-mix(in srgb, var(--accent) 28%, transparent);
}

.redesign-page .match-pitch-slot .match-pitch-chip.is-selected {
  transform: translate(-50%, calc(var(--chip) / -2)) scale(1.06);
}

.redesign-page .match-pitch-chip.is-dragging { opacity: .35; cursor: grabbing; }

/* Die Kopie, die am Zeiger haengt.

   Sie liegt am body: im Feld waere sie von dessen abgerundetem Rand beschnitten und lieze sich
   nicht ueber die Bank ziehen. Deshalb fixed und nicht absolut - so folgt sie dem Zeiger
   unabhaengig davon, wie weit die Seite gescrollt ist. */
.redesign-page .match-pitch-ghost {
  position: fixed;
  z-index: 60;
  transform: translate(-50%, -50%) scale(1.08);
  opacity: .96;
  pointer-events: none;
  cursor: grabbing;
  filter: drop-shadow(0 8px 16px color-mix(in srgb, var(--text) 32%, transparent));
}

.redesign-page .match-pitch-ghost:hover { transform: translate(-50%, -50%) scale(1.08); }

/* Tore und Karte haengen an der Scheibe, nicht an der Marke: die ist mitsamt Namen unterschiedlich
   hoch, und eine Marke am Rand eines wachsenden Kastens wandert mit dem Namen mit. */
.match-pitch-chip-goals,
.match-pitch-chip-card {
  position: absolute;
  pointer-events: none;
}

/* Die Masze sind Anteile der Scheibe, nicht von --chip: auf der Bank ist sie kleiner, und
   feste Abstaende haetten die Marken dort neben die Pille geschoben. */
.match-pitch-chip-goals {
  top: -6%;
  right: -8%;
  display: grid;
  place-items: center;
  min-width: 38%;
  height: 38%;
  padding: 0 3px;
  border: 1px solid var(--surface-raised);
  border-radius: 999px;
  background: var(--success);
  color: #fff;
  font-size: calc(var(--chip) * .24);
  font-weight: 800;
  line-height: 1;
}

.match-pitch-chip-card {
  top: -6%;
  left: -6%;
  width: 17%;
  height: 26%;
  border: 1px solid var(--surface-raised);
  border-radius: 2px;
  background: var(--caution);
}

.match-pitch-chip-card.is-gelb { background: var(--caution); }
.match-pitch-chip-card.is-rot { background: var(--danger); }
/* Gelb-Rot traegt beide Farben, so wie sie zustande kam. */
.match-pitch-chip-card.is-gelb-rot {
  background: linear-gradient(135deg, var(--caution) 0 50%, var(--danger) 50% 100%);
}

/* Ausgewechselt oder vom Platz gestellt: er stand da, steht aber nicht mehr. */
.redesign-page .match-pitch-chip.is-off { opacity: .55; }

.redesign-page .match-pitch-chip.is-off .match-pitch-chip-number {
  border-color: color-mix(in srgb, var(--muted) 55%, var(--border));
  background: var(--surface-subtle);
  color: var(--muted);
}

/* Worauf die gezogene Marke zeigt. Der Platz leuchtet, und wer dort steht, rueckt sichtbar
   zur Seite - sonst sieht man erst nach dem Loslassen, wen man verschoben hat. */
.match-pitch-slot.is-swap {
  border-style: solid;
  border-color: color-mix(in srgb, var(--caution) 70%, transparent);
}

.match-pitch-slot.is-target {
  border-style: solid;
  border-color: var(--accent);
  background: color-mix(in srgb, var(--accent) 20%, var(--surface-raised));
  box-shadow: 0 0 0 6px color-mix(in srgb, var(--accent) 22%, transparent);
}

.match-pitch-bench.is-target {
  border-style: solid;
  border-color: var(--accent);
  background: color-mix(in srgb, var(--accent) 16%, var(--surface-subtle));
}

/* Der Spieler, der dem Platz weichen wuerde.

   Gekennzeichnet wird die Scheibe, nicht die Marke: die ist mitsamt Namen hoeher, und jede
   Verformung drehte oder schob sie um einen Punkt weit unter dem Kreis. Eine Drehung sah
   ausserdem nach Fehler aus - ein Rueckwaertsschritt sagt dasselbe ruhiger. */
.redesign-page .match-pitch-chip.is-swap .match-pitch-chip-number {
  border-style: dashed;
  border-color: var(--caution);
  background: color-mix(in srgb, var(--caution) 18%, var(--surface-raised));
  transform: scale(.86);
}

/* Das Aktionsmenue sitzt an der Marke, zu der es gehoert. Am Ende des Feldes klappt es zur
   Mitte hin auf - sonst stuende es ausserhalb der Flaeche. */
.match-pitch-menu {
  position: absolute;
  left: calc(var(--slot-x) * 100%);
  top: calc(var(--slot-y) * 100%);
  z-index: 4;
  width: 196px;
  padding: 6px;
  transform: translate(-50%, calc(var(--chip) * .8));
  border: 1px solid var(--border);
  border-radius: 12px;
  background: var(--surface-raised);
  box-shadow: var(--shadow);
}

/* Nah am gegnerischen Tor - also oben - klappt es nach unten auf. */
.match-pitch-menu.is-above {
  transform: translate(-50%, calc(var(--chip) * .8));
}

.match-pitch-menu:not(.is-above) {
  transform: translate(-50%, calc(-100% - var(--chip) * .8));
}

.match-pitch-menu-actions {
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: 4px;
}

/* Bei ungerader Anzahl fuellt der letzte Knopf seine Zeile aus - eine halb leere Zeile sieht
   aus, als fehle etwas. */
.redesign-page .match-pitch-menu-actions .btn:nth-child(odd):last-child {
  grid-column: 1 / -1;
}

.redesign-page .match-pitch-menu .btn {
  display: flex;
  align-items: center;
  justify-content: center;
  gap: 5px;
  min-height: 40px;
  padding: 6px 4px;
  font-size: 12px;
}

.match-pitch-menu .match-event-icon { width: 15px; height: 15px; }

/* Die Eingabe am Spieler: Minute, dazu Kartenart oder neue Position. */
.match-pitch-pad { display: grid; gap: 6px; }

.match-pitch-pad-title {
  color: var(--muted);
  font-size: 10px;
  font-weight: 700;
  letter-spacing: .06em;
  text-transform: uppercase;
}

.match-pitch-pad-choice { display: grid; grid-template-columns: 1fr 1fr 1fr; gap: 4px; }

.redesign-page .match-pitch-pad-choice .btn {
  min-height: 34px;
  padding: 4px 2px;
  font-size: 11px;
}

.redesign-page .match-pitch-pad-choice .btn.is-selected {
  border-color: var(--accent);
  background: color-mix(in srgb, var(--accent) 16%, var(--surface-raised));
}

.match-pitch-pad-row { display: grid; grid-template-columns: 1fr auto; gap: 6px; }

.redesign-page .match-pitch-pad-row input {
  min-height: 40px;
  padding: 6px 8px;
  text-align: center;
}

.redesign-page .match-pitch-pad-row .btn { min-height: 40px; padding: 6px 12px; }

.match-pitch-bench-title {
  color: var(--muted);
  font-size: 9px;
  font-weight: 700;
  letter-spacing: .12em;
  text-transform: uppercase;
}

.match-pitch-bench {
  display: flex;
  flex-wrap: wrap;
  gap: 6px;
  min-height: 64px;
  margin-top: 6px;
  padding: 8px;
  border: 1px dashed var(--border);
  border-radius: 14px;
  background: var(--surface-subtle);
  transition: border-color .15s ease, background .15s ease;
}

/* Auf der Bank ist Platz fuer den ganzen Namen - eine Zeile liest sich schneller als ein
   Kreis mit drei Buchstaben. */
.redesign-page .match-pitch-bench .match-pitch-chip {
  position: static;
  grid-auto-flow: column;
  justify-content: start;
  align-items: center;
  gap: 8px;
  width: auto;
  max-width: 100%;
  min-height: 44px;
  /* Links etwas mehr Luft: dort sitzt die Kartenmarke an der Scheibe. */
  padding: 4px 14px 4px 5px;
  transform: none;
  border: 1px solid var(--border);
  border-radius: 999px;
  background: var(--surface-raised);
}

.redesign-page .match-pitch-bench .match-pitch-chip:hover,
.redesign-page .match-pitch-bench .match-pitch-chip.is-selected {
  transform: none;
}

.match-pitch-bench .match-pitch-chip-number {
  width: calc(var(--chip) * .8);
  height: calc(var(--chip) * .8);
  font-size: calc(var(--chip) * .34);
}

.match-pitch-bench .match-pitch-chip-name {
  display: block;
  max-width: 150px;
  overflow: hidden;
  font-size: 12px;
  text-align: left;
  text-overflow: ellipsis;
  white-space: nowrap;
}

/* Wartet auf den Einwechselspieler oder nimmt einen vom Feld entgegen. */
.match-pitch-bench.is-open,
.match-pitch-bench.is-awaiting {
  border-style: solid;
  border-color: var(--accent);
  background: color-mix(in srgb, var(--accent) 10%, var(--surface-subtle));
}

/* Der Wechsel wartet auf genau eine Antwort: wer kommt? Deshalb leuchtet hier nur die Bank,
   und zwar deutlicher als bei der blossen Auswahl - das Feld ist in diesem Moment nicht
   gemeint, und ohne den Unterschied sah beides gleich aus. */
.match-pitch-bench.is-awaiting {
  background: color-mix(in srgb, var(--accent) 16%, var(--surface-subtle));
  box-shadow: 0 0 0 4px color-mix(in srgb, var(--accent) 18%, transparent);
}

.redesign-page .match-pitch-bench.is-awaiting .match-pitch-chip {
  border-color: color-mix(in srgb, var(--accent) 55%, var(--border));
}

/* Die Ueberschrift sagt, auf wen die Bank wartet - der Text wird beim Warten gesetzt. */
.match-pitch-bench-wrap:has(.match-pitch-bench.is-awaiting) .match-pitch-bench-title {
  color: var(--accent);
}

/* Der gedrueckte Knopf bleibt sichtbar gedrueckt, solange seine Frage offen ist. */
.redesign-page .match-pitch-menu .btn.is-active {
  border-color: var(--accent);
  background: color-mix(in srgb, var(--accent) 20%, var(--surface-raised));
  color: var(--accent);
}

.match-pitch-bench-empty {
  align-self: center;
  color: var(--muted);
  font-size: 12px;
}

/* Nur-Ansicht: der abgeschlossene Bericht zeigt die Aufstellung, laesst sie aber in Ruhe. */
.redesign-page .match-pitch-board.is-readonly .match-pitch-chip {
  cursor: default;
  opacity: 1;
}

.redesign-page .match-pitch-board.is-readonly .match-pitch-chip.is-off { opacity: .55; }

.redesign-page .match-pitch-board.is-readonly .match-pitch-slot .match-pitch-chip:hover {
  transform: translate(-50%, calc(var(--chip) / -2));
}

.redesign-page .match-pitch-board.is-readonly .match-pitch-bench .match-pitch-chip:hover {
  transform: none;
}

/* Ab Tablet steht die Bank neben dem Feld: der Weg vom Spieler zu seinem Platz wird kuerzer,
   und die Seite wird nicht unnoetig lang. */
@media (min-width: 900px) {
  .match-pitch-board {
    --chip: 54px;
    grid-template-columns: minmax(0, 1fr) 270px;
    grid-template-areas:
      "head head"
      "pitch bench";
    align-items: start;
  }
  .match-pitch-head { grid-area: head; }
  .match-pitch { grid-area: pitch; }
  .match-pitch-bench-wrap { grid-area: bench; }
  .match-pitch-bench {
    flex-direction: column;
    align-content: flex-start;
    min-height: 220px;
  }
}

/* Aufstellung und Spielverlauf nebeneinander.

   Das Feld steht hochkant - eigenes Tor unten, Angriff nach oben, so hat es jeder im Kopf, der
   Fussball schaut. Hochkant deckelt es sich aber an der Fensterhoehe und liesse auf einem
   Schreibtischbildschirm die halbe Karte leer. Genau dort steht jetzt der Spielverlauf: beides
   gleichzeitig sichtbar, und ein Ereignis am Feld landet in einer Liste, die man nicht erst
   suchen muss. */
@media (min-width: 1200px) {
  .load-match-page .match-layout {
    display: grid;
    grid-template-columns: minmax(0, 1fr) minmax(380px, 520px);
    align-items: start;
    gap: 16px;
  }
  /* Die Karten im Raster tragen keinen eigenen Abstand mehr - den gibt das Raster. Seinen
     eigenen Abstand nach unten braucht es aber weiterhin, sonst klebt die Bewertungstabelle
     daran. */
  .load-match-page .match-layout { margin-bottom: 14px; }
  .load-match-page .match-layout > .card { margin: 0; }
  .load-match-page .match-layout > .card + .card { position: sticky; top: 12px; }
  .match-pitch-board { --chip: 60px; }
}

/* Neben dem Spielverlauf ist die Spalte schmaler. Die Bank rueckt dann unter das Feld, damit
   das Feld die Breite behaelt - sonst schrumpfte es auf einem Laptop auf ein Drittel. */
@media (min-width: 1200px) and (max-width: 1599px) {
  .load-match-page .match-layout .match-pitch-board {
    grid-template-columns: minmax(0, 1fr);
    grid-template-areas: "head" "pitch" "bench";
  }
  .load-match-page .match-layout .match-pitch-bench {
    flex-direction: row;
    flex-wrap: wrap;
    min-height: 64px;
  }
}

/* Am Handy wird das Feld schmaler; die Marken schrumpfen mit, bleiben aber greifbar. */
@media (max-width: 480px) {
  .match-pitch-board { --chip: 42px; }
  .match-pitch-bench .match-pitch-chip-name { max-width: 120px; }
}

/* ── Entwurfshinweis ─────────────────────────────────────────────────────────
   Steht über dem Arbeitsbereich auf Seiten, die erst am Ende in einem Zug speichern, und
   meldet Eingaben, die ein früherer Besuch hinterlassen hat (Fragment fragments/draft-restore,
   eingeblendet von draft-store.js).

   Neutral getönt wie die übrigen Streifen, die eine Aktion tragen: Der Entwurf ist ein Angebot,
   kein Problem. Rot bleibt in diesen Ansichten der Validierungswarnung am Eingabefeld
   vorbehalten – zwei rote Flächen übereinander nehmen ihr die Bedeutung. */
.redesign-page .draft-restore-note {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 12px;
  flex-wrap: wrap;
  margin: 2px 0 12px;
  padding: 9px 12px;
  border: 1px solid var(--border);
  border-radius: 10px;
  background: var(--surface-raised);
}

.redesign-page .draft-restore-note .draft-restore-text {
  display: flex;
  flex-direction: column;
  min-width: 0;
}

.redesign-page .draft-restore-note strong {
  font-size: 13px;
}

.redesign-page .draft-restore-note small {
  color: var(--muted);
  font-size: 11px;
  line-height: 1.35;
}

/* Am Handy stehen die beiden Knöpfe unter dem Text und füllen die Breite – nebeneinander
   gequetscht trifft man sie nicht. */
@media (max-width: 640px) {
  .redesign-page .draft-restore-note .actions-inline {
    width: 100%;
    justify-content: stretch;
  }

  .redesign-page .draft-restore-note .actions-inline .btn {
    flex: 1;
  }
}
