/* ══════════════════════════════════════════════════════════════════════════
   Coach-Grid — Layout-Schicht über dem Design-System „Nocturne".
   nocturne.css liefert Tokens und Komponenten; hier stehen ausschließlich
   Zusammenstellungen daraus. Kein neuer Farb-, Schrift- oder Abstandswert —
   alles kommt aus var(--…). Siehe docs/DESIGN.md §1.
   ══════════════════════════════════════════════════════════════════════ */

/* — Seitengerüst — */
.page       { max-width: 1360px; margin: 0 auto; padding: 40px; }
.page-slim  { max-width: 1100px; margin: 0 auto; padding: 40px; }
.page-flush { max-width: 1360px; margin: 0 auto; padding: 0 40px; }
@media (max-width: 720px) {
  .page, .page-slim, .page-flush { padding: 20px; }
}

.muted   { color: color-mix(in srgb, var(--color-text) 60%, transparent); }
.muted-2 { color: color-mix(in srgb, var(--color-text) 45%, transparent); }
.stack   { display: flex; flex-direction: column; gap: 10px; }

/* — Kopfzeile —
   Wie im Template: klebend, halbtransparent, mit Weichzeichner dahinter. */
.site-header {
  position: sticky; top: 0; z-index: 20;
  background: color-mix(in srgb, var(--color-bg) 88%, transparent);
  backdrop-filter: blur(12px);
}
.site-header .inner {
  max-width: 1360px; margin: 0 auto; padding: 14px 40px;
  display: flex; align-items: center; gap: 22px;
}
.brand {
  display: inline-flex; align-items: center; gap: 10px;
  font-family: var(--font-heading); font-weight: var(--font-heading-weight);
  font-size: 20px; text-decoration: none; color: inherit; margin-right: auto;
}
.brand-mark { flex: none; width: 24px; height: 24px; display: block; }
/* Nur das "Grid" einfärben, nicht die Marke insgesamt */
.brand > span > span { color: var(--color-accent); }
.site-nav { display: flex; align-items: center; gap: 22px; }
.site-nav a { color: inherit; text-decoration: none; font-size: 14px; }
.site-nav a:hover, .site-nav a[aria-current="page"] { color: var(--color-accent); }
.header-actions { display: flex; align-items: center; gap: 12px; }

/* Begrüßung links neben der Navigation. Schmal gehalten: sie ist eine
   Bestätigung, mit welchem Konto man unterwegs ist, kein Menüpunkt.

   Als reines <span> war sie ein anonymes Flex-Element und wurde über die
   Schriftgrundlinie ausgerichtet, nicht über die Mitte — bei 13px neben 14px
   sitzt sie dadurch sichtbar zu hoch. inline-flex plus align-self machen aus
   ihr einen Kasten, den align-items: center sauber mittig setzt. */
.greeting {
  display: inline-flex; align-items: center; align-self: center;
  font-size: 13px; white-space: nowrap;
  color: color-mix(in srgb, var(--color-text) 55%, transparent);
}

/* Auf dem Desktop ist die Hülle nicht vorhanden: display: contents lässt ihre
   Kinder direkt Flex-Elemente der Kopfzeile sein, als gäbe es sie nicht. So
   trägt dasselbe Markup beide Ansichten — kein zweiter Satz Links, der
   auseinanderlaufen kann. */
.nav-panel { display: contents; }
.nav-toggle { display: none; }

/* Auf schmalen Geräten wird die Kopfzeile einzeilig: Marke links, Aufklapp-
   Knopf rechts. Vorher rutschten die Knöpfe in eine zweite Reihe — zwei
   Zeilen für vier Links sind auf 375px schlicht zu viel Platz für zu wenig. */
@media (max-width: 860px) {
  .site-header .inner { padding: 12px 20px; gap: 12px; }

  .nav-toggle {
    display: grid; place-items: center; flex: none;
    width: 40px; height: 40px; margin-left: auto;
    border-radius: var(--radius-sm); border: 1px solid var(--color-divider);
    background: transparent; color: var(--color-text);
    font: inherit; font-size: 20px; cursor: pointer;
  }
  .nav-toggle:hover { border-color: var(--color-accent); color: var(--color-accent); }

  /* Das Aufklappfeld hängt unter der Kopfzeile, nicht in ihr: es soll den
     Seiteninhalt überdecken, statt ihn nach unten zu schieben. */
  .nav-panel {
    display: none;
    position: absolute; top: 100%; left: 0; right: 0;
    flex-direction: column; align-items: stretch; gap: 4px;
    padding: 12px 20px 18px;
    background: var(--color-bg);
    border-top: 1px solid var(--color-divider);
    box-shadow: var(--shadow-md);
  }
  .site-header.is-open .nav-panel { display: flex; }

  .greeting { order: -1; padding: 4px 12px 10px; }

  .site-nav { flex-direction: column; align-items: stretch; gap: 0; }
  .site-nav a { padding: 11px 12px; border-radius: var(--radius-sm); font-size: 15px; }
  .site-nav a:hover { background: color-mix(in srgb, var(--color-text) 6%, transparent); }
  .site-nav a[aria-current="page"] {
    background: color-mix(in srgb, var(--color-accent) 12%, transparent);
  }

  .header-actions {
    flex-direction: column; align-items: stretch; gap: 8px;
    margin-top: 12px; padding-top: 12px;
    border-top: 1px solid var(--color-divider);
  }
  /* justify-content statt center: die Knöpfe füllen die Breite, ihr Inhalt
     bleibt aber links, damit die Symbole untereinander stehen. */
  .header-actions .btn { justify-content: flex-start; }
  .header-actions form { display: block; }
  .header-actions form .btn { width: 100%; }
}

@media (max-width: 400px) {
  .site-header .inner { padding: 10px 16px; }
  .brand { font-size: 18px; }
}

.site-footer {
  display: flex; flex-wrap: wrap; gap: 40px; justify-content: space-between;
  padding: 32px 0; font-size: 13px;
  color: color-mix(in srgb, var(--color-text) 55%, transparent);
}
.site-footer a { color: inherit; text-decoration: none; }
.site-footer a:hover { color: var(--color-accent); }

/* — Hintergrundband der Unterseiten —
   Ein Motiv am Kopf, oben ausgerichtet, das nach unten in die
   Hintergrundfarbe ausläuft.

   z-index: -1 statt eines eigenen Stapels für den Inhalt: so bleibt jedes
   normale Element automatisch darüber, ohne dass main, footer und jede
   künftige Sektion eine Positionsangabe brauchen. Die Kopfzeile liegt mit
   ihrem eigenen z-index ohnehin oben und lässt das Bild durch ihren
   Weichzeichner durchscheinen. */
.page-bg {
  position: absolute; top: 0; left: 0; right: 0;
  height: clamp(340px, 44vw, 620px);
  z-index: -1; overflow: hidden; pointer-events: none;
}
/* object-position oben: die Motive haben ihr Licht im oberen Drittel, und
   genau das soll hinter der Kopfzeile stehen. */
.page-bg img {
  width: 100%; height: 100%; object-fit: cover; object-position: 50% 0%;
  opacity: 0.42;
}

/* Auslauf auf exakt var(--color-bg), damit keine Kante bleibt — dieselbe
   Begründung wie beim Hero der Startseite: eine Maske nach transparent
   trifft die Hintergrundfarbe nur zufällig genau. */
.page-bg::after {
  content: ""; position: absolute; inset: 0;
  background: linear-gradient(to bottom,
    color-mix(in srgb, var(--color-bg) 26%, transparent)  0%,
    color-mix(in srgb, var(--color-bg) 52%, transparent) 42%,
    color-mix(in srgb, var(--color-bg) 84%, transparent) 76%,
    var(--color-bg) 100%);
}

/* — Hero —
   Vollbreite ohne 100vw: die Sektion selbst ist ein Block auf voller Breite,
   der Inhalt darin bekommt die max-width. Die im Template genutzte Variante
   (left: calc(50% - 50vw); width: 100vw) rechnet die vertikale Scrollleiste
   mit und erzeugt auf dem Desktop eine horizontale — siehe DESIGN.md §6b. */
/* Die Höhe steht an der Sektion, nicht am Bild: so füllt das Bild den Hero
   exakt aus, und der Auslauf-Verlauf endet immer innerhalb der Sektion. Läge
   die Höhe am Bild, würde overflow:hidden den Verlauf auf breiten Bildschirmen
   abschneiden — genau dort, wo er die Hintergrundfarbe erreichen soll.
   65vw entspricht dem Seitenverhältnis 20:13, geklammert für sehr schmale und
   sehr breite Fenster. */
.hero {
  position: relative; overflow: hidden;
  min-height: clamp(620px, 65vw, 1040px);
  display: flex; align-items: flex-end;
}

.hero-media {
  position: absolute; inset: 0;
  z-index: 0; pointer-events: none;
}
.hero-media img {
  width: 100%; height: 100%; object-fit: cover; object-position: 50% 0%;
}

/* Auslauf in den Seitenhintergrund.
   Bewusst ein Verlauf auf --color-bg statt einer Maske nach transparent: eine
   Maske blendet das Bild zwar aus, aber die letzte sichtbare Zeile trifft die
   Hintergrundfarbe nur zufällig genau — je nach Motiv bleibt ein heller oder
   dunkler Saum stehen. Dieser Verlauf endet per Definition auf exakt
   var(--color-bg), also ohne Kante.
   Alle Stufen werden aus derselben Farbe gemischt, damit der Farbton über den
   gesamten Verlauf konstant bleibt (ein Übergang nach "transparent" kann in
   manchen Engines über Grau wandern). */
/* Die Kurve steigt bewusst spät an: die Hero-Karten stehen im unteren Drittel,
   und hinter ihnen muss noch Bild übrig sein, sonst hat der Glaseffekt nichts
   zu brechen und die Flächen wirken flach. Der Verlauf endet trotzdem exakt
   auf var(--color-bg), also weiterhin ohne Kante. */
.hero-fade {
  position: absolute; inset: auto 0 0 0; height: 62%;
  pointer-events: none;
  background: linear-gradient(to bottom,
    color-mix(in srgb, var(--color-bg)   0%, transparent)   0%,
    color-mix(in srgb, var(--color-bg)  16%, transparent)  44%,
    color-mix(in srgb, var(--color-bg)  42%, transparent)  70%,
    color-mix(in srgb, var(--color-bg)  76%, transparent)  88%,
    var(--color-bg) 100%);
}

/* Abdunkelung von links, damit die Überschrift auf jedem Motiv lesbar bleibt */
.hero-scrim {
  position: absolute; inset: 0; z-index: 0; pointer-events: none;
  background: linear-gradient(100deg,
    color-mix(in srgb, var(--color-bg) 72%, transparent) 0%,
    color-mix(in srgb, var(--color-bg) 50%, transparent) 34%,
    color-mix(in srgb, var(--color-bg) 20%, transparent) 66%,
    transparent 100%);
}

.hero-inner {
  position: relative; z-index: 1; width: 100%;
  /* Der Inhalt sitzt unten (align-items: flex-end an .hero), deshalb hebt ihn
     mehr Innenabstand unten an — 88px + 50px. Über padding statt über einen
     negativen Versatz, damit die Sektion ihre Höhe behält und der Auslauf-
     Verlauf unverändert bleibt. */
  max-width: 1360px; margin: 0 auto; padding: 120px 40px 138px;
  display: grid; grid-template-columns: minmax(0,1.05fr) minmax(0,0.95fr);
  gap: 64px; align-items: end;
}
.hero-inner > .hero-cards {
  display: grid; grid-template-columns: 1fr 1fr; gap: 14px;
}

/* Beide Spalten stehen auf derselben Grundlinie (align-items: end). Nur die
   Textspalte steigt darüber hinaus — der Kartenblock bleibt, wo er ist. */
.hero-inner > .hero-copy { margin-bottom: 100px; }

@media (max-width: 1000px) {
  .hero { min-height: 0; display: block; }
  .hero-inner { grid-template-columns: 1fr; gap: 32px; padding: 40px 20px 64px; }
  .hero-inner > .hero-copy { margin-bottom: 0; }

  /* Das Motiv ist im Querformat aufgenommen, der Coach steht links. Auf einem
     schmalen Bildschirm schneidet object-fit: cover von beiden Seiten gleich
     viel weg — und damit genau ihn. Der Ausschnitt wandert deshalb nach links,
     ans Motiv statt in die Bildmitte. */
  .hero-media img { object-position: 22% 0%; }
}

/* — Anstoß zum kostenlosen Konto (Startseite) —
   Zwei Spalten, weil zwei verschiedene Leute auf die Seite kommen: wer einen
   Coach sucht, und wer einer ist. Eine gemeinsame Liste zwingt beide, ihre
   Hälfte erst herauszulesen. */
/* Steht am Seitenende: der Abstand nach oben kommt vom Band darüber, nach
   unten braucht es Luft zur Fußzeile. */
.free-cta { padding: 0 0 64px; }
/* Über die volle Spaltenbreite, damit der Kopf zu den beiden Karten darunter
   passt statt daneben zu stehen. Kein Zeilenmaß: es sind drei Sätze, und die
   Spalte ist auf 1360px begrenzt. */
.free-cta-head { margin-bottom: 28px; }

.free-badge {
  display: inline-flex; align-items: center; gap: 7px;
  padding: 5px 12px; border-radius: 999px;
  font-size: 12px; letter-spacing: 0.02em;
  background: color-mix(in srgb, var(--color-accent) 16%, transparent);
  color: var(--color-accent);
}
.free-badge i { font-size: 14px; }

.free-cta-grid {
  display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); gap: 18px;
}

.free-card {
  padding: 26px 26px 24px;
  border-radius: var(--radius-md);
  background: var(--color-surface);
  box-shadow: var(--shadow-sm);
  /* Der Knopf soll auf gleicher Höhe stehen, auch wenn eine Liste eine Zeile
     länger ist — sonst sieht die kürzere Karte unfertig aus. */
  display: flex; flex-direction: column; align-items: flex-start;
}
.free-card .btn { margin-top: auto; }
.free-card-icon {
  font-size: 26px; color: var(--color-accent);
  margin-bottom: 14px;
}

.free-list {
  margin: 0 0 22px; padding: 0; list-style: none;
  font-size: 14px; line-height: 1.55;
}
.free-list li {
  position: relative; padding-left: 26px; margin-bottom: 10px;
  color: color-mix(in srgb, var(--color-text) 82%, transparent);
}
/* Häkchen als ::before statt als Icon-Element: vier Listen mit je vier
   Einträgen wären sonst sechzehn <i> im Markup, die nichts sagen. */
.free-list li::before {
  content: "✓";
  position: absolute; left: 0; top: 0;
  color: var(--color-accent); font-size: 13px;
}

@media (max-width: 780px) {
  .free-cta { padding-bottom: 48px; }
  .free-cta-grid { grid-template-columns: 1fr; }
  .free-card { padding: 22px; }
}

/* Schmales Band zwischen zwei Listen. Andere Form als die Karten weiter oben:
   derselbe Baustein zum dritten Mal liest sich wie Werbung, ein Streifen
   zwischen zwei Abschnitten wie ein Zwischenruf. */
.join-strip {
  display: flex; align-items: center; gap: 22px; flex-wrap: wrap;
  margin: 56px 0 0; padding: 26px 30px;
  border-radius: var(--radius-lg);
  border: 1px solid color-mix(in srgb, var(--color-accent) 30%, transparent);
  background: color-mix(in srgb, var(--color-accent) 7%, transparent);
}
.join-strip-icon {
  flex: none; font-size: 30px; color: var(--color-accent);
}

@media (max-width: 780px) {
  .join-strip { margin-top: 44px; padding: 22px; gap: 16px; }
  .join-strip-icon { display: none; }
}

/* — Erzeugter Titelbereich für Termine —
   Fremde Flyer werden nicht kopiert (siehe components/event-cover.blade.php).
   Farbwinkel und Neigung stehen als Variablen am Element und kommen aus dem
   Slug des Termins: gleicher Termin, gleiches Bild — zwei nebeneinander aber
   nie dasselbe. */
.event-cover {
  position: relative; overflow: hidden;
  border-radius: var(--radius-md);
  display: grid; place-items: center;
  background: linear-gradient(var(--cover-tilt, 35deg), var(--cover-a), var(--cover-b));
}
/* Ein Raster darüber, damit die Fläche nicht wie ein nicht geladenes Bild
   aussieht. Als Verlauf statt als Grafik: keine zweite Anfrage, und es
   skaliert von der Kachel bis zur vollen Breite. */
.event-cover::after {
  content: ""; position: absolute; inset: 0;
  background-image:
    linear-gradient(color-mix(in srgb, #fff 5%, transparent) 1px, transparent 1px),
    linear-gradient(90deg, color-mix(in srgb, #fff 5%, transparent) 1px, transparent 1px);
  background-size: 34px 34px;
  mask-image: radial-gradient(120% 100% at 30% 0%, #000 20%, transparent 78%);
}
.event-cover i {
  position: relative; z-index: 1;
  font-size: clamp(38px, 6vw, 76px);
  color: color-mix(in srgb, #fff 82%, transparent);
}

/* — Seitenblätterung —
   Gehört zur eigenen Ansicht in resources/views/vendor/pagination. Die
   Vorgabe von Laravel bringt Tailwind-Klassen mit, die hier ins Leere gehen. */
.pager {
  display: flex; align-items: center; justify-content: center;
  gap: 6px; flex-wrap: wrap; margin-top: 8px;
}
.pager-pages { display: flex; align-items: center; gap: 4px; flex-wrap: wrap; }

.pager-link {
  display: inline-flex; align-items: center; gap: 6px;
  min-width: 36px; height: 36px; padding: 0 11px;
  justify-content: center;
  border-radius: var(--radius-sm);
  font-size: 14px; line-height: 1;
  color: inherit; text-decoration: none;
  background: var(--color-surface);
}
/* Ohne diese Zeile erben die Pfeile die Schriftgröße des Elternelements —
   genau der Fehler, den die Vorgabe hatte, nur eine Stufe kleiner. */
.pager-link i { font-size: 15px; }

.pager-link:hover { background: color-mix(in srgb, var(--color-text) 10%, transparent); }
/* Dieselbe Sprache wie die aktive Zeile im Verwaltungsbereich: getönte Fläche
   und Akzentfarbe. Eine gefüllte Fläche gibt es im Projekt nirgends — auch
   .btn-primary ist eine Kontur. */
.pager-link.is-current {
  background: color-mix(in srgb, var(--color-accent) 14%, transparent);
  color: var(--color-accent);
}
.pager-link.is-disabled { opacity: 0.35; pointer-events: none; }

.pager-gap { padding: 0 4px; color: color-mix(in srgb, var(--color-text) 45%, transparent); }

/* Auf schmalen Schirmen tragen die Pfeile allein — "Previous"/"Next"
   verdoppeln die Breite der Leiste und sagen nichts, was das Zeichen nicht
   schon sagt. */
@media (max-width: 560px) {
  .pager-word { display: none; }
  .pager-link { padding: 0 9px; }
}

/* — Glasflächen —
   Im Template viermal identisch inline gesetzt; hier einmal als Klasse.
   Der deckende Hintergrund ist der Rückfall für Browser ohne backdrop-filter:
   ohne ihn wird der Text auf dem Hero-Bild unlesbar. */
.glass {
  background: var(--color-surface);
  border-radius: var(--radius-lg);
  box-shadow: var(--shadow-sm);
}
@supports (backdrop-filter: blur(10px)) {
  .glass {
    background: color-mix(in srgb, var(--color-surface) 56%, transparent);
    /* saturate() ist der Teil, der die Fläche als Glas lesbar macht: die
       Unschärfe allein wirkt wie Nebel, erst die angehobene Sättigung lässt
       die Farben des Bildes durchscheinen. */
    backdrop-filter: blur(14px) saturate(140%);
    -webkit-backdrop-filter: blur(14px) saturate(140%);
    border: 1px solid color-mix(in srgb, var(--color-text) 10%, transparent);
    /* Lichtkante an der Oberkante — dieselbe Beobachtung wie bei echtem Glas:
       die Kante fängt mehr Licht als die Fläche. */
    box-shadow: var(--shadow-sm),
                inset 0 1px 0 color-mix(in srgb, #fff 9%, transparent);
  }

  /* Über dem Formular liegen Eingabefelder — dort darf weniger durchscheinen,
     sonst kämpfen Beschriftungen gegen das Motiv dahinter. */
  .glass-dense { background: color-mix(in srgb, var(--color-surface) 74%, transparent); }

  /* Die abschließende Karte hebt sich über den Rahmen ab, nicht über die
     Fläche: sie steht am Ende der Reihe und soll leichter wirken. */
  .glass-outline {
    background: color-mix(in srgb, var(--color-bg) 40%, transparent);
    border-color: var(--color-divider);
    box-shadow: inset 0 1px 0 color-mix(in srgb, #fff 6%, transparent);
  }
}

/* — Suche: Filterspalte + Ergebnisraster — */
.search-layout {
  display: grid; grid-template-columns: 264px minmax(0, 1fr);
  gap: 32px; align-items: start;
}
.filter-panel {
  position: sticky; top: 90px;
  display: flex; flex-direction: column; gap: 20px; padding: 20px;
  background: var(--color-surface); border-radius: var(--radius-md);
  box-shadow: var(--shadow-sm);
}
.filter-group-label {
  font-size: 12px; margin-bottom: 9px;
  color: color-mix(in srgb, var(--color-text) 70%, transparent);
}
.checks { display: flex; flex-direction: column; gap: 8px; }
.check  { display: flex; align-items: center; gap: 9px; cursor: pointer; font-size: 14px; }
.check input { accent-color: var(--color-accent); }

.grid-3 { display: grid; grid-template-columns: repeat(3, minmax(0,1fr)); gap: 18px; }
.grid-4 { display: grid; grid-template-columns: repeat(4, minmax(0,1fr)); gap: 14px; }
@media (max-width: 1100px) { .grid-3 { grid-template-columns: repeat(2, minmax(0,1fr)); } }
@media (max-width: 860px)  {
  .search-layout { grid-template-columns: 1fr; }
  .filter-panel  { position: static; }
  .grid-3, .grid-4 { grid-template-columns: 1fr; }
}

/* — Formularraster —
   Zwei bzw. drei Felder nebeneinander, auf schmalen Geräten untereinander.
   Als Klasse und nicht inline, weil ein style-Attribut keine Media-Query
   aufnehmen kann und zwei Eingabefelder auf 375px sonst je 150px breit sind. */
/* Fehlermeldung unter einem Feld. Vorher stand dieselbe Zeile inline in
   jedem Formular — bei einem Formular mit vierzehn Feldern ist das vierzehn
   Mal dieselbe Farbe von Hand. */
.field-error {
  color: var(--color-accent-300);
  font-size: 13px;
  margin: 6px 0 0;
}

.form-grid       { display: grid; grid-template-columns: 1fr 1fr; gap: 16px; }
.form-grid-3     { display: grid; grid-template-columns: repeat(3, minmax(0,1fr)); gap: 16px; }
.form-grid-aside { display: grid; grid-template-columns: minmax(0,1fr) 200px; gap: 14px; align-items: end; }

@media (max-width: 720px) {
  .form-grid, .form-grid-3, .form-grid-aside { grid-template-columns: 1fr; }
  .form-grid-aside { align-items: stretch; }
}

/* — Detailseiten: Inhalt links, Seitenspalte rechts —
   Die Seitenspalte hat eine feste Breite. Ohne den Umbruch unten schrumpft die
   1fr-Spalte auf null und die Seitenspalte schiebt sich über den Inhalt hinaus
   — inline gesetzt ließ sich das nicht abfangen, Style-Attribute kennen keine
   Media-Query. */
.detail-layout {
  display: grid; grid-template-columns: minmax(0,1fr) 380px;
  gap: 40px; align-items: start;
}
.detail-layout-narrow { grid-template-columns: minmax(0,1fr) 340px; }

.detail-aside {
  position: sticky; top: 90px;
  display: flex; flex-direction: column; gap: 16px;
}

@media (max-width: 980px) {
  .detail-layout, .detail-layout-narrow { grid-template-columns: 1fr; gap: 28px; }
  /* Untereinander gestellt hat "klebrig" keinen Sinn mehr — die Spalte würde
     beim Scrollen im Inhalt hängen bleiben. */
  .detail-aside { position: static; }
}

/* — Coach-Karte — */
.coach-card {
  display: flex; flex-direction: column; gap: 12px; padding: 14px;
  text-align: left; font: inherit; color: inherit; text-decoration: none;
  background: var(--color-surface); border: 0; border-radius: var(--radius-md);
  box-shadow: var(--shadow-sm); cursor: pointer;
}
.coach-card { transition: box-shadow .12s ease; }
.coach-card:hover { box-shadow: var(--shadow-md); }
.coach-card .name {
  font-family: var(--font-heading); font-weight: var(--font-heading-weight); font-size: 17px;
}
.coach-card .org {
  font-size: 12px; letter-spacing: .06em; text-transform: uppercase; margin-top: 5px;
  color: color-mix(in srgb, var(--color-text) 55%, transparent);
}
.coach-card .place {
  font-size: 13px; margin-top: 3px;
  color: color-mix(in srgb, var(--color-text) 55%, transparent);
}
.coach-card .tags { display: flex; gap: 6px; margin-top: 10px; flex-wrap: wrap; }

/* Initialen als Bildersatz. Bewusst kein Platzhalterfoto: Initialen auf dem
   dunklen Verlauf wirken im Nocturne-Raster ruhiger als ein generisches Bild
   und zwingen Coaches nicht zu einem Foto, das sie nicht haben. */
.portrait {
  aspect-ratio: 4/3; border-radius: var(--radius-sm);
  display: grid; place-items: center; overflow: hidden;
  background: radial-gradient(120% 90% at 30% 0%, var(--color-neutral-800), var(--color-neutral-900));
  font-family: var(--font-heading); font-size: 34px;
  color: color-mix(in srgb, var(--color-text) 26%, transparent);
}
.portrait img { width: 100%; height: 100%; object-fit: cover; }

.rating { display: flex; align-items: center; gap: 5px; margin-top: 10px; font-size: 13px; }
.rating .star { color: var(--color-accent); }

/* — Kennzahl-Kachel (Dashboard und Athletenprofil) — */
.stat-tile  { padding: 18px; background: var(--color-surface); border-radius: var(--radius-md); box-shadow: var(--shadow-sm); }
.stat-label { font-size: 12px; letter-spacing: .08em; text-transform: uppercase;
              color: color-mix(in srgb, var(--color-text) 55%, transparent); }
.stat-value { font-family: var(--font-heading); font-weight: var(--font-heading-weight);
              font-size: 30px; margin-top: 6px; }
.stat-value.is-empty { color: color-mix(in srgb, var(--color-text) 28%, transparent); }

/* — Messwerte im Athletenprofil —
   Maße aus der Vorlage (html-template, Bildschirm "athlete"): vier Spalten,
   14px Abstand, 16px Innenabstand, Wert in der Überschriftenschrift auf 26px.
   Eigene Klassen und nicht .stat-tile: dort tragen im Dashboard dieselben
   Kacheln 30px große Zahlen, weil es nur vier davon gibt. */
.metric-grid {
  display: grid; grid-template-columns: repeat(4, minmax(0, 1fr)); gap: 14px;
}
.metric-card {
  padding: 16px; background: var(--color-surface);
  border-radius: var(--radius-md); box-shadow: var(--shadow-sm);
}
/* Das Symbol steht in der Beschriftungszeile statt neben dem Wert — so bleibt
   die Kachel so hoch wie in der Vorlage. */
.metric-card .k {
  display: flex; align-items: center; gap: 7px;
  font-size: 12px; letter-spacing: .08em; text-transform: uppercase;
  color: color-mix(in srgb, var(--color-text) 55%, transparent);
}
.metric-card .k i { flex: none; font-size: 14px; color: var(--color-accent); }
.metric-card .v {
  font-family: var(--font-heading); font-weight: var(--font-heading-weight);
  font-size: 26px; margin-top: 6px;
}
@media (max-width: 1100px) { .metric-grid { grid-template-columns: repeat(3, minmax(0,1fr)); } }
@media (max-width: 760px)  { .metric-grid { grid-template-columns: repeat(2, minmax(0,1fr)); } }
@media (max-width: 420px)  { .metric-grid { grid-template-columns: 1fr; } }

/* Formulare im Dashboard bleiben schmal, der Rahmen ringsum nicht: sonst
   springt die Menüleiste beim Wechsel zwischen Übersicht und Profil. */
.dash-narrow { max-width: 900px; }

/* — Nummerierter Schritt —
   Für die Seite nach der Registrierung. Eine Ziffer statt eines Hakens: sie
   sagt, dass es eine Reihenfolge gibt, und nicht, dass schon etwas erledigt
   wäre. */
.step-number {
  flex: none; width: 26px; height: 26px; display: grid; place-items: center;
  border-radius: 50%; font-family: var(--font-heading); font-size: 13px;
  background: var(--color-accent-900); color: var(--color-accent-100);
}

/* — Feld mit Kopieren-Knopf — */
.copy-field { display: flex; gap: 8px; align-items: center; }
.copy-field input { flex: 1 1 auto; min-width: 0; font-size: 13px; }
.copy-field .btn { flex: none; }

@media (max-width: 520px) {
  .copy-field { flex-direction: column; align-items: stretch; }
}

/* — Bild-Upload —
   Datei wählen, Name prüfen, absenden. Das native <input type=file> bleibt
   im Markup, wird aber vom Knopf daneben verdeckt: sein Aussehen lässt sich
   nicht gestalten, sein Verhalten braucht man trotzdem. */
.upload-field {
  display: flex; align-items: center; gap: 10px; flex-wrap: wrap;
  margin-top: 10px;
}
.upload-pick { position: relative; display: inline-flex; cursor: pointer; }
.upload-pick input[type=file] {
  position: absolute; inset: 0; width: 100%; height: 100%;
  opacity: 0; cursor: pointer;
}
.upload-name {
  flex: 1 1 120px; min-width: 0; font-size: 12px;
  overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
}

/* — Verzeichnis der Bundesstaaten —
   Fünfzig Links wollen als Raster gelesen werden, nicht als Fließtext. */
.state-grid {
  display: grid; grid-template-columns: repeat(auto-fill, minmax(180px, 1fr));
  gap: 2px 12px;
}
.state-link {
  display: flex; align-items: baseline; gap: 8px;
  padding: 7px 10px; border-radius: var(--radius-sm);
  font-size: 14px; color: inherit; text-decoration: none;
}
.state-link:hover { background: color-mix(in srgb, var(--color-text) 6%, transparent); color: var(--color-accent); }
.state-link span { font-size: 12px; color: color-mix(in srgb, var(--color-text) 45%, transparent); }
/* Ohne Coaches gedämpft, aber verlinkt: ein leerer Bundesstaat ist die
   ehrliche Antwort und die Einladung, der Erste dort zu sein. */
.state-link.is-empty { color: color-mix(in srgb, var(--color-text) 42%, transparent); }

/* — Bewertungen — */
.review {
  padding: 18px; background: var(--color-surface);
  border-radius: var(--radius-md); box-shadow: var(--shadow-sm);
}
.review-head {
  display: flex; align-items: center; gap: 10px; flex-wrap: wrap;
  font-size: 14px; margin-bottom: 8px;
}
.review-head .muted-2 { font-size: 12px; }
.review p {
  margin: 0; font-size: 14px; line-height: 1.65; max-width: 70ch;
  color: color-mix(in srgb, var(--color-text) 82%, transparent);
}
/* Die Antwort des Coaches eingerückt und abgesetzt: sie gehört zur Bewertung,
   ist aber nicht dasselbe wie die Bewertung. */
.review-reply {
  margin: 12px 0 0 16px; padding-left: 14px;
  border-left: 2px solid var(--color-accent-900);
  font-size: 14px; line-height: 1.65; max-width: 70ch;
  color: color-mix(in srgb, var(--color-text) 78%, transparent);
}
.stars { display: inline-flex; gap: 2px; color: var(--color-accent); font-size: 14px; }

.review-form { margin-top: 20px; }
.review-form > summary {
  display: inline-flex; align-items: center; gap: 8px;
  cursor: pointer; list-style: none; font-size: 14px;
  color: var(--color-accent);
}
.review-form > summary::-webkit-details-marker { display: none; }
.review-form[open] {
  margin-top: 20px; padding: 20px;
  border: 1px solid var(--color-divider); border-radius: var(--radius-md);
}

/* — Ausweisprüfung —
   Der Antrag klappt auf, statt eine eigene Seite zu bekommen: er besteht aus
   einem Feld und drei Sätzen Erklärung, und die gehören neben den Zustand,
   den sie ändern. */
.verify-box { flex: 1 1 100%; }
.verify-box > summary { list-style: none; cursor: pointer; }
.verify-box > summary::-webkit-details-marker { display: none; }
.verify-box[open] > summary { margin-bottom: 18px; }
.verify-box[open] {
  padding: 18px; border-radius: var(--radius-md);
  border: 1px solid var(--color-divider);
}

/* Portrait und Ausweis nebeneinander — der Vergleich ist der ganze Vorgang. */
.verify-pair {
  display: grid; grid-template-columns: 220px minmax(0, 1fr); gap: 20px;
  align-items: start;
}
.verify-pair figure { margin: 0; }
.verify-pair figcaption {
  font-size: 11px; letter-spacing: .08em; text-transform: uppercase;
  color: color-mix(in srgb, var(--color-text) 55%, transparent);
  margin-bottom: 8px;
}
.verify-pair img {
  max-width: 100%; border-radius: var(--radius-md);
  border: 1px solid var(--color-divider);
}
@media (max-width: 760px) {
  .verify-pair { grid-template-columns: 1fr; }
}

/* — Galeriebild als Auslöser für das Overlay — */
.gallery-item { position: relative; display: block; cursor: zoom-in; }
.gallery-zoom {
  position: absolute; right: 8px; bottom: 8px;
  display: grid; place-items: center; width: 30px; height: 30px;
  border-radius: 50%; font-size: 15px;
  background: color-mix(in srgb, var(--color-bg) 72%, transparent);
  color: var(--color-text);
  opacity: 0; transition: opacity .12s ease;
}
.gallery-item:hover .gallery-zoom,
.gallery-item:focus-visible .gallery-zoom { opacity: 1; }

/* — Overlay — */
.lightbox {
  position: fixed; inset: 0; z-index: 100;
  display: flex; align-items: center; justify-content: center; gap: 12px;
  padding: 24px;
  background: color-mix(in srgb, var(--color-bg) 92%, transparent);
  backdrop-filter: blur(6px); -webkit-backdrop-filter: blur(6px);
}
.lightbox[hidden] { display: none; }
.lightbox-stage {
  margin: 0; display: flex; flex-direction: column; align-items: center; gap: 12px;
  max-width: 100%; max-height: 100%;
}
.lightbox-stage img {
  max-width: 100%; max-height: calc(100vh - 120px);
  border-radius: var(--radius-md); box-shadow: var(--shadow-md);
}
.lightbox-count {
  font-size: 13px; color: color-mix(in srgb, var(--color-text) 55%, transparent);
}
.lightbox-nav, .lightbox-close {
  flex: none; display: grid; place-items: center; cursor: pointer;
  border-radius: 50%; border: 1px solid var(--color-divider);
  background: color-mix(in srgb, var(--color-surface) 80%, transparent);
  color: var(--color-text); font: inherit;
}
.lightbox-nav { width: 44px; height: 44px; font-size: 20px; }
.lightbox-close { position: absolute; top: 20px; right: 20px; width: 38px; height: 38px; font-size: 17px; }
.lightbox-nav:hover, .lightbox-close:hover { border-color: var(--color-accent); color: var(--color-accent); }

@media (max-width: 640px) {
  /* Auf dem Telefon an den unteren Rand: dort sind die Daumen. */
  .lightbox { flex-wrap: wrap; padding: 16px; }
  .lightbox-stage { order: 1; flex: 1 0 100%; }
  .lightbox-nav { order: 2; }
  .lightbox-stage img { max-height: calc(100vh - 190px); }
}

/* — Vereinslogo — */
.org-logo {
  flex: none; width: 34px; height: 34px; object-fit: contain;
  border-radius: var(--radius-sm);
  background: color-mix(in srgb, var(--color-text) 6%, transparent);
}
.org-logo.sm { width: 20px; height: 20px; }

/* — Rückmeldung beim Hochladen —
   Die Upload-Formulare senden sich beim Auswählen selbst ab; bis die Antwort
   da ist, passiert sichtbar nichts. */
.upload-progress {
  display: flex; align-items: center; gap: 9px; margin-top: 8px;
  font-size: 13px; color: color-mix(in srgb, var(--color-text) 70%, transparent);
}
.spinner {
  flex: none; width: 15px; height: 15px; border-radius: 50%;
  border: 2px solid color-mix(in srgb, var(--color-text) 18%, transparent);
  border-top-color: var(--color-accent);
  animation: spin .7s linear infinite;
}
@keyframes spin { to { transform: rotate(360deg); } }

@media (prefers-reduced-motion: reduce) {
  /* Ohne Drehung bleibt der Ring als reine Zustandsanzeige stehen. */
  .spinner { animation: none; border-top-color: var(--color-accent); opacity: .7; }
}

/* — Sprungmarken über einem langen Leitfaden —
   Als Reihe von Chips und nicht als Liste: eine nummerierte Gliederung sieht
   nach Pflichtlektüre aus, eine Reihe von Knöpfen nach Auswahl. */
.guide-toc {
  display: flex; flex-wrap: wrap; gap: 8px;
  margin: 0 0 40px;
  padding: 16px 18px;
  border: 1px solid var(--color-divider);
  border-radius: var(--radius-md);
}
.guide-toc a {
  padding: 6px 12px; border-radius: 999px;
  font-size: 13px; text-decoration: none;
  color: color-mix(in srgb, var(--color-text) 78%, transparent);
  background: color-mix(in srgb, var(--color-text) 6%, transparent);
}
.guide-toc a:hover {
  color: var(--color-accent);
  background: color-mix(in srgb, var(--color-accent) 14%, transparent);
}

/* — Aufklappbare Frage —
   Für die FAQ-Blöcke auf den Landingpages. Als <details>: kein JavaScript,
   und der Text steht auch geschlossen im Quelltext, wo Google ihn liest. */
.faq-item {
  padding: 0 18px; border: 1px solid var(--color-divider);
  border-radius: var(--radius-md);
}
.faq-item > summary {
  display: flex; align-items: center; gap: 10px;
  padding: 16px 0; cursor: pointer; list-style: none;
  font-family: var(--font-heading); font-weight: var(--font-heading-weight);
  font-size: 15px;
}
.faq-item > summary::-webkit-details-marker { display: none; }
.faq-item > summary::before {
  content: "+"; flex: none; width: 18px;
  color: var(--color-accent); font-size: 17px; line-height: 1;
}
.faq-item[open] > summary::before { content: "–"; }
.faq-item > p {
  margin: 0 0 18px 28px; font-size: 14px; line-height: 1.65;
  color: color-mix(in srgb, var(--color-text) 78%, transparent);
  max-width: 70ch;
}

/* — Zwei Seiten derselben Sache (Info-Seite) — */
.why-split { display: grid; grid-template-columns: 1fr 1fr; gap: 20px; }
.why-col {
  padding: 26px; background: var(--color-surface);
  border-radius: var(--radius-lg); box-shadow: var(--shadow-sm);
}
.why-head { display: flex; align-items: center; gap: 12px; margin-bottom: 18px; }
.why-head i { font-size: 26px; color: var(--color-accent); }
.why-head h2 { margin: 0; font-size: 21px; }
.why-list { margin: 0 0 22px; padding: 0; list-style: none; }
.why-list li {
  margin-bottom: 14px; padding-left: 24px; position: relative;
  font-size: 14px; line-height: 1.6;
  color: color-mix(in srgb, var(--color-text) 78%, transparent);
}
.why-list li::before {
  content: "✓"; position: absolute; left: 0; top: 0;
  color: var(--color-accent); font-size: 13px;
}
.why-list strong { color: var(--color-text); }

@media (max-width: 860px) {
  .why-split { grid-template-columns: 1fr; }
}

/* — Statuskarte im Dashboard —
   Wie .row-card, aber die drei Blöcke stellen sich unter 780px untereinander.
   Nebeneinander gedrängt brach der Text neben dem Balken auf jedes zweite
   Wort um, und der Knopf lief aus der Seite. */
.status-card {
  display: flex; align-items: center; gap: 20px; padding: 16px;
  background: var(--color-surface); border-radius: var(--radius-md);
  box-shadow: var(--shadow-sm);
}
.status-card-main { display: flex; align-items: center; gap: 16px; flex: 1 1 auto; min-width: 0; }
.status-card-meter { flex: none; width: 170px; }
.status-card form { flex: none; }

@media (max-width: 780px) {
  .status-card { flex-direction: column; align-items: stretch; gap: 16px; }
  .status-card-meter { width: auto; }
}

/* — Navigation im Coach-Dashboard —
   Über die volle Breite und mit Symbolen: als schmales Segment mitten im
   Inhalt las es sich wie eine Filterleiste. Auf schmalen Geräten scrollt sie
   waagerecht, statt umzubrechen — fünf Punkte in zwei Reihen sehen aus wie
   zwei verschiedene Menüs. */
.dash-nav {
  display: flex; gap: 4px; margin-bottom: 28px; padding: 5px;
  background: var(--color-surface); border-radius: var(--radius-md);
  box-shadow: var(--shadow-sm);
  overflow-x: auto; scrollbar-width: none;
}
.dash-nav::-webkit-scrollbar { display: none; }
.dash-nav a {
  display: flex; align-items: center; justify-content: center; gap: 8px;
  flex: 1 1 0; min-width: max-content;
  padding: 11px 14px; border-radius: var(--radius-sm);
  font-size: 14px; color: inherit; text-decoration: none; white-space: nowrap;
  transition: background .12s ease, color .12s ease;
}
.dash-nav a i { font-size: 18px; color: color-mix(in srgb, var(--color-text) 45%, transparent); }
.dash-nav a:hover { background: color-mix(in srgb, var(--color-text) 6%, transparent); }
.dash-nav a[aria-current="page"] {
  background: color-mix(in srgb, var(--color-accent) 14%, transparent);
  color: var(--color-accent);
}
.dash-nav a[aria-current="page"] i { color: var(--color-accent); }
.dash-nav .tag { font-size: 11px; padding: 1px 7px; }

/* Zweite Zeile für den gerade bearbeiteten Athleten. Flacher als die Hauptzeile
   und mit vorangestelltem Namen, damit klar ist, worauf sie sich bezieht. */
.dash-nav-sub {
  margin-top: -20px; margin-bottom: 28px;
  background: color-mix(in srgb, var(--color-surface) 60%, transparent);
  box-shadow: none; border: 1px solid var(--color-divider);
}
.dash-nav-sub a { font-size: 13px; padding: 8px 12px; flex: 0 1 auto; }
.dash-nav-title {
  display: flex; align-items: center; padding: 8px 12px; flex: none;
  font-size: 12px; letter-spacing: .08em; text-transform: uppercase;
  color: color-mix(in srgb, var(--color-text) 45%, transparent);
  white-space: nowrap;
}
@media (max-width: 700px) {
  /* In der Unterzeile bleiben die Beschriftungen stehen — es sind höchstens
     drei, und ohne Text wäre nicht erkennbar, dass sie zum Athleten gehören. */
  .dash-nav-sub a { flex: 0 1 auto; padding: 8px 10px; }
  .dash-nav-sub a > span:not(.tag) {
    position: static; width: auto; height: auto; margin: 0;
    overflow: visible; clip: auto; white-space: nowrap;
  }
  .dash-nav-title { display: none; }
}

@media (max-width: 700px) {
  /* Nur noch die Symbole — fünf Beschriftungen passen nicht in 375px, und
     eine waagerecht scrollende Leiste versteckt die hinteren Punkte.
     Nicht display:none: der Text muss vorgelesen werden können, sonst sind es
     fünf unbeschriftete Knöpfe. */
  .dash-nav a { flex: 1 1 0; min-width: 0; padding: 11px 6px; }
  .dash-nav a > span:not(.tag) {
    position: absolute; width: 1px; height: 1px; padding: 0; margin: -1px;
    overflow: hidden; clip: rect(0,0,0,0); white-space: nowrap; border: 0;
  }
  .dash-nav a i { font-size: 20px; }
}

/* — Verwaltungsbereich —
   Spalte links, Inhalt rechts. Dieselbe Aufteilung wie die Suchseiten, damit
   der Bereich nicht wie ein zweites Produkt wirkt. */
.admin-layout {
  display: grid; grid-template-columns: 210px minmax(0, 1fr);
  gap: 32px; align-items: start;
}
.admin-nav {
  position: sticky; top: 90px;
  display: flex; flex-direction: column; gap: 2px;
  padding: 10px; background: var(--color-surface);
  border-radius: var(--radius-md); box-shadow: var(--shadow-sm);
}
.admin-nav a {
  display: flex; align-items: center; gap: 10px;
  padding: 9px 11px; border-radius: var(--radius-sm);
  font-size: 14px; color: inherit; text-decoration: none;
}
.admin-nav a i { font-size: 17px; color: color-mix(in srgb, var(--color-text) 45%, transparent); }
.admin-nav a:hover { background: color-mix(in srgb, var(--color-text) 6%, transparent); }
.admin-nav a[aria-current="page"] {
  background: color-mix(in srgb, var(--color-accent) 14%, transparent);
  color: var(--color-accent);
}
.admin-nav a[aria-current="page"] i { color: var(--color-accent); }

@media (max-width: 900px) {
  .admin-layout { grid-template-columns: 1fr; gap: 22px; }
  .admin-nav { position: static; flex-direction: row; flex-wrap: wrap; }
  .admin-nav a { font-size: 13px; padding: 7px 10px; }
}

/* — Aktionsspalte in Tabellen —
   Nebeneinander, solange Platz ist; darunter wird gestapelt und die
   Beschriftung faellt weg, sodass nur die Zeichen stehen bleiben. Sechs
   Spalten passen auf 360 Pixel sonst nicht, und eine Tabelle, die seitlich
   aus dem Bild laeuft, verliert genau die Knoepfe rechts aussen. */
.row-actions {
  text-align: right; white-space: nowrap;
  /* inline-flex am Formular, damit der Loeschknopf neben dem Link steht,
     ohne dass jede Zeile ein style-Attribut braucht. */
}
.row-actions > form { display: inline; }

/* Spalten, die auf schmalen Geraeten entfallen. Nicht die Daten selbst,
   sondern die, die auf der Bearbeiten-Seite ohnehin stehen. */
@media (max-width: 720px) {
  .table .col-wide { display: none; }

  .row-actions {
    white-space: normal;
    display: flex; flex-direction: column; align-items: flex-end; gap: 4px;
  }
  .row-actions > form { display: block; }
  .row-actions .btn { padding-inline: 6px; }
  .row-actions .btn-label { display: none; }
  .row-actions .btn i { font-size: 17px; }
}

/* — Ausgabe eines Befehls —
   Die Rückmeldung von backup:run und backup:restore, unverändert. Umbrechen
   statt scrollen (pre-wrap): eine Fehlermeldung, deren Ende rechts aus dem
   Bild läuft, wird nicht gelesen. Die Höhe ist begrenzt, damit ein langer
   Lauf nicht die ganze Seite füllt. */
.console {
  margin: 0 0 20px; padding: 14px 16px;
  max-height: 380px; overflow: auto;
  background: color-mix(in srgb, var(--color-text) 7%, transparent);
  border-radius: var(--radius-sm);
  font-family: ui-monospace, SFMono-Regular, Menlo, Consolas, monospace;
  font-size: 12.5px; line-height: 1.65;
  white-space: pre-wrap; word-break: break-word;
}

/* — Meldeknopf auf den öffentlichen Seiten —
   Klein und ruhig: er soll gefunden werden, wenn jemand ihn sucht, und nicht
   zum Draufklicken einladen. */
.report-box { font-size: 13px; }
.report-box > summary {
  display: flex; align-items: center; gap: 7px;
  padding: 10px 4px; cursor: pointer; list-style: none;
  color: color-mix(in srgb, var(--color-text) 45%, transparent);
}
.report-box > summary::-webkit-details-marker { display: none; }
.report-box > summary:hover { color: var(--color-accent); }
.report-box[open] > summary { color: var(--color-text); }
.report-box[open] {
  padding: 4px 18px 18px;
  border: 1px solid var(--color-divider); border-radius: var(--radius-md);
}

/* — Fließtext für Rechtstexte —
   Eigene Schicht, weil hier als Einziges längere Absätze stehen: Zeilenmaß
   65ch, mehr Zeilenabstand, und Überschriften kleiner als sonst — ein
   Rechtstext hat zwanzig davon, in 32px wäre die Seite eine Gliederung mit
   Textresten dazwischen. */
/* Volle Spaltenbreite. Ein Zeilenmaß von 65ch liest sich zwar angenehmer,
   aber bei einem Rechtstext, den man überfliegt und nach Stichworten
   durchsucht, wiegt die schmale Spalte auf einem 27-Zoll-Schirm schwerer.
   Die Aufzählungen und Definitionslisten bekommen ihre Struktur ohnehin aus
   den Überschriften, nicht aus der Zeilenlänge. */
.prose { max-width: none; font-size: 15px; line-height: 1.7; }
.prose h2 {
  font-size: 21px; margin: 40px 0 12px;
  padding-top: 18px; border-top: 1px solid var(--color-divider);
}
.prose h2:first-of-type { border-top: 0; padding-top: 0; margin-top: 28px; }
.prose h3 { font-size: 16px; margin: 24px 0 8px; }
.prose p, .prose ul, .prose ol { margin: 0 0 14px; }
.prose ul, .prose ol { padding-left: 22px; }
.prose li { margin-bottom: 6px; }
.prose a { color: var(--color-accent); }
.prose strong { font-weight: 600; }
.prose .lead {
  font-size: 16px;
  color: color-mix(in srgb, var(--color-text) 80%, transparent);
}
.prose dl { margin: 0 0 14px; }
.prose dt { font-weight: 600; margin-top: 12px; }
.prose dd { margin: 2px 0 0; color: color-mix(in srgb, var(--color-text) 78%, transparent); }

/* Offene Punkte im Text sichtbar lassen, statt sie zu erfinden. */
.prose .gap {
  padding: 1px 7px; border-radius: var(--radius-sm);
  background: color-mix(in srgb, var(--color-accent) 18%, transparent);
  color: var(--color-accent-100); font-size: 13px;
}

/* — Profillinks in der Seitenspalte —
   Volle Breite statt kleiner Textknöpfe: für einen Trainer ist Hudl oder das
   Saisonvideo der eigentliche Grund, das Profil zu öffnen. Der Rahmen statt
   einer Füllfläche hält die Reihe ruhig, auch wenn sechs davon untereinander
   stehen. */
.link-tile {
  display: flex; align-items: center; gap: 12px;
  padding: 11px 14px; font-size: 14px;
  border-radius: var(--radius-sm); border: 1px solid var(--color-divider);
  color: inherit; text-decoration: none;
  transition: border-color .12s ease, background .12s ease;
}
.link-tile:hover {
  border-color: var(--color-accent);
  background: color-mix(in srgb, var(--color-accent) 8%, transparent);
}
.link-tile > i:first-child { flex: none; font-size: 19px; color: var(--color-accent); }
.link-tile > span { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.link-tile .ext {
  margin-left: auto; font-size: 13px;
  color: color-mix(in srgb, var(--color-text) 35%, transparent);
}

/* — Datums-Chip für Events — */
.date-chip { flex: none; width: 58px; padding: 8px 0; text-align: center;
             border-radius: var(--radius-sm); background: var(--color-accent-900); }
.date-chip .m { font-size: 11px; letter-spacing: .08em; text-transform: uppercase; color: var(--color-accent-300); }
.date-chip .d { font-family: var(--font-heading); font-size: 24px; line-height: 1.1; }

.row-card { display: flex; align-items: center; gap: 16px; padding: 16px;
            background: var(--color-surface); border-radius: var(--radius-md); box-shadow: var(--shadow-sm); }

/* Nur anklickbare Zeilen heben sich beim Überfahren an — dieselbe Reaktion wie
   bei .coach-card. Reine Anzeigekarten (Verfügbarkeit, Adresse) bleiben ruhig:
   ein Hover-Effekt ohne Ziel verspricht eine Interaktion, die es nicht gibt. */
a.row-card { transition: box-shadow .12s ease; }
a.row-card:hover { box-shadow: var(--shadow-md); }

/* — Aktive Filter als entfernbare Chips — */
.chip-row { display: flex; gap: 8px; flex-wrap: wrap; }
.chip-row .tag { text-decoration: none; }

/* — Leerzustand — */
.empty-state {
  padding: 56px 32px; text-align: center;
  border: 1px dashed var(--color-divider); border-radius: var(--radius-lg);
}
.empty-state h3 { margin: 0 0 8px; }

/* Barrierefreiheit: für Screenreader sichtbar, optisch entfernt */
/* Das hidden-Attribut setzt display:none nur im Browser-Standardstylesheet.
   Jede eigene Regel mit display (etwa .check { display:flex }) schlaegt es —
   das Element bleibt sichtbar, obwohl es als versteckt markiert ist. Diese
   Zeile stellt das wieder her, ein Mal fuer das ganze Projekt. */
[hidden] { display: none !important; }

.sr-only {
  position: absolute; width: 1px; height: 1px; padding: 0; margin: -1px;
  overflow: hidden; clip: rect(0,0,0,0); white-space: nowrap; border: 0;
}

/* — Galerie im Dashboard — */
.gallery-grid { display: grid; grid-template-columns: repeat(4, minmax(0,1fr)); gap: 10px; }
@media (max-width: 700px) { .gallery-grid { grid-template-columns: repeat(2, minmax(0,1fr)); } }

.save-btn {
  width: 26px; height: 26px; display: grid; place-items: center; cursor: pointer;
  border-radius: var(--radius-sm); border: 1px solid var(--color-divider);
  background: color-mix(in srgb, var(--color-bg) 78%, transparent); color: var(--color-text);
  font: inherit; font-size: 13px;
}
.save-btn:hover { border-color: var(--color-accent); color: var(--color-accent); }

/* — Karte auf Event- und Coach-Seiten —
   Der Rahmen steht schon vor dem Laden, damit beim Klick nichts springt
   (Cumulative Layout Shift). */
.map-shell {
  margin-top: 10px; padding: 24px;
  display: flex; flex-direction: column; align-items: center; justify-content: center;
  min-height: 260px; border-radius: var(--radius-md);
  background: var(--color-surface); box-shadow: var(--shadow-sm);
}
.map-shell iframe {
  width: 100%; height: 320px; border: 0;
  border-radius: var(--radius-md); display: block;
}

/* — Profillinks im Athleten-Formular — */
/* Adresse oben, Plattformwahl darunter: bei zwanzig Symbolen wird eine
   Icon-Spalte neben dem Eingabefeld zu breit. */
.link-row {
  display: flex; flex-direction: column; gap: 10px;
  padding: 14px; border-radius: var(--radius-sm);
  border: 1px solid var(--color-divider);
}
.link-row-url {
  display: grid; grid-template-columns: minmax(0,1fr) 26px;
  gap: 10px; align-items: center;
}

/* Plattformwahl als Icon-Reihe statt Auswahlliste: ein Instagram-Glyph ist
   schneller erfasst als ein Wort, und native <select> können keine Icons. */
.icon-picker { display: flex; flex-wrap: wrap; gap: 4px; }
/* position: relative, damit das absolut gesetzte Radio im Label bleibt und der
   Browser beim Fokussieren nicht an eine falsche Stelle springt. */
.icon-picker label { position: relative; display: inline-flex; cursor: pointer; }
.icon-picker input {
  position: absolute; inset: 0; opacity: 0; width: 100%; height: 100%;
  margin: 0; cursor: pointer;
}
.icon-picker span:first-of-type {
  display: grid; place-items: center; width: 32px; height: 32px;
  border-radius: var(--radius-sm); border: 1px solid var(--color-divider);
  font-size: 16px; color: color-mix(in srgb, var(--color-text) 55%, transparent);
}
.icon-picker label:hover span:first-of-type { border-color: var(--color-accent); }
.icon-picker input:checked + span {
  border-color: var(--color-accent); color: var(--color-accent);
  background: color-mix(in srgb, var(--color-accent) 14%, transparent);
}
/* Tastaturbedienung: das Radio ist unsichtbar, der Fokus muss trotzdem sichtbar sein */
.icon-picker input:focus-visible + span { outline: 2px solid var(--color-accent); outline-offset: 2px; }
