/* components.css — Layer: components (seitenübergreifende UI-Bausteine).
 * Buttons, Artikelkarten, Terminliste, Badges — überall wiederverwendbar.
 * Nav liegt separat in nav.css, seitenspezifische Blöcke in blocks.css. */
@layer components {

/* =====================================================
 * 4. COMPONENTS
 * ===================================================== */

/* ——— Buttons ——— */
.btn, a.btn, button.btn, input.btn {
  display: inline-block;
  padding: var(--sp-3) var(--sp-6);
  font-size: var(--fs-sm);
  font-weight: 500;
  font-family: var(--font-sans);
  line-height: 1.2;
  text-decoration: none;
  border-radius: var(--radius-md);
  border: 1px solid transparent;
  cursor: pointer;
  transition: background 180ms, border-color 180ms, color 180ms;
}

.btn-primary, a.btn-primary, button.btn-primary {
  background: var(--frgs-red);
  color: var(--white);
  border-color: var(--frgs-red);
}
.btn-primary:hover, a.btn-primary:hover, button.btn-primary:hover {
  background: var(--frgs-red-dark);
  border-color: var(--frgs-red-dark);
  color: var(--white);
}

.btn-outline, a.btn-outline, button.btn-outline {
  background: transparent;
  color: var(--color-accent-ink);
  border-color: var(--color-accent);
}
.btn-outline:hover { background: var(--frgs-red-soft); }

.btn-ghost {
  background: transparent;
  color: var(--ink-700);
  border-color: var(--color-border);
}
.btn-ghost:hover {
  border-color: var(--ink-500);
  color: var(--ink-900);
}

.btn-dark-bg {
  background: transparent;
  color: var(--white);
  border-color: rgba(255,255,255,0.6);
}
.btn-dark-bg:hover {
  background: rgba(255,255,255,0.1);
  border-color: var(--white);
}

/* ——— Article cards — Markup: snippets/article-card.php ——— */
.article-card {
  background: var(--color-surface);
  border: 1px solid var(--color-border);
  border-radius: var(--radius-md);
  overflow: hidden;
  display: flex;
  flex-direction: column;
  /* Bezugsrahmen für den Stretched Link unten */
  position: relative;
  transition: border-color 180ms ease, box-shadow 180ms ease;
}
@media (prefers-reduced-motion: reduce) {
  .article-card { transition: none; }
}
/* Ganze Karte als Klickziel. Das Pseudo-Element hängt am vorhandenen
 * Titel-Anker, erzeugt also KEINEN zweiten Tab-Stop und keinen zweiten
 * Linktext — vorher war das Medienfeld ein toter Bereich, obwohl dort
 * erfahrungsgemäß geklickt wird.
 * Kompromiss dieses Musters: Text in der Karte lässt sich schlechter
 * markieren, weil die Klickfläche darüber liegt.
 *
 * :not(.boot-card) ist wichtig: der Bootspark löst dasselbe Problem schon
 * selbst, mit einem eigenen Anker ums Medienfeld
 * (bootspark.php:84, .boot-card-media-link, tabindex="-1" aria-hidden). Ohne
 * den Ausschluss lägen dort zwei Klickflächen übereinander, und die
 * Boot-Karte bekäme ungefragt Hover- und Rahmenzustände dazu. */
.article-card:not(.boot-card) .article-card-title a::after {
  content: '';
  position: absolute;
  inset: 0;
}
/* Sichtbare Rückmeldung, damit die Klickbarkeit überhaupt auffällt.
 * focus-within, damit Tastaturnutzer dasselbe Signal bekommen. */
.article-card:not(.boot-card):hover,
.article-card:not(.boot-card):focus-within {
  border-color: var(--ink-300);
  box-shadow: var(--shadow-card);
}
.article-card-media {
  aspect-ratio: 16/10;
  background: var(--ink-100);
  position: relative;
  overflow: hidden;
}
.article-card-media img {
  width: 100%; height: 100%;
  object-fit: cover;
  display: block;
}
.article-card-body { padding: var(--sp-4) var(--sp-6) var(--sp-6); }
/* „Weiterlesen" auf eine Linie bringen: Titel und Auszug sind unterschiedlich
 * lang, der Link stand deshalb je Karte auf anderer Höhe. Der Body füllt die
 * Karte (die Grid-Zeile streckt alle Karten gleich hoch), margin-top:auto
 * schiebt den Link an den unteren Rand.
 *
 * :not(.boot-card), weil die Boot-Karte keinen „Weiterlesen"-Link hat, aber
 * mehrere <p> im Body stapelt: als Flex-Container würden deren vertikale
 * Ränder nicht mehr kollabieren und die Abstände dort sichtbar anders ausfallen. */
.article-card:not(.boot-card) .article-card-body {
  display: flex;
  flex-direction: column;
  flex: 1;
}
.article-card-date {
  font-size: var(--fs-xs);
  color: var(--color-text-muted);
  text-transform: uppercase;
  letter-spacing: 0.04em;
  margin-bottom: var(--sp-2);
}
.article-card-title {
  font-family: var(--font-display);
  font-size: var(--fs-lg);
  font-weight: 500;
  line-height: 1.25;
  margin: 0 0 var(--sp-3);
}
.article-card-title a { color: inherit; text-decoration: none; }
.article-card-title a:hover { color: var(--frgs-red-dark); }
.article-card-excerpt {
  color: var(--color-text-muted);
  font-size: var(--fs-sm);
  margin: 0;
}
.article-card-more {
  display: inline-block;
  /* margin-top:auto schiebt den Link an den unteren Rand des Bodys, damit
   * „Weiterlesen" über alle Karten einer Zeile auf einer Linie liegt — Titel
   * und Auszug sind unterschiedlich lang. Der Mindestabstand zum Auszug kommt
   * als padding, nicht als margin: bei langem Auszug bleibt für margin:auto
   * kein Platz, es fiele auf 0 zurück und der Link klebte am Text.
   * Wirkt nur, wo der Body Flex-Container ist (also nicht in der Boot-Karte). */
  margin-top: auto;
  padding-top: var(--sp-3);
  /* über der Klickfläche des Stretched Links, damit der eigene Hover-/
   * Fokuszustand erhalten bleibt */
  position: relative;
  font-size: var(--fs-xs);
  font-weight: 600;
  text-transform: uppercase;
  letter-spacing: 0.04em;
  color: var(--frgs-red-dark);
  text-decoration: none;
}
.article-card-more::after { content: " →"; }
.article-card-more:hover { text-decoration: underline; }

/* Nur für Screenreader sichtbar (z.B. Artikel-Titel im Weiterlesen-Link) */
.visually-hidden {
  position: absolute;
  width: 1px;
  height: 1px;
  padding: 0;
  margin: -1px;
  overflow: hidden;
  clip-path: inset(50%);
  white-space: nowrap;
  border: 0;
}

/* ——— Termine (Nächste Termine) — Markup: snippets/termin-list.php ——— */
.termin-box {
  background: var(--color-surface);
  border: 1px solid var(--color-border);
  border-radius: var(--radius-md);
  padding: var(--sp-6);
}
.termin-box h3 {
  font-size: var(--fs-md);
  font-family: var(--font-sans);
  font-weight: 600;
  margin-bottom: var(--sp-4);
}
.termin-list { list-style: none; margin: 0; padding: 0; }
.termin-item {
  display: flex;
  gap: var(--sp-3);
  padding: var(--sp-3) 0;
  border-bottom: 1px solid var(--color-border);
  align-items: flex-start;
}
.termin-item:last-child { border-bottom: 0; padding-bottom: 0; }
.termin-item:first-child { padding-top: 0; }
.termin-date {
  flex-shrink: 0;
  width: 48px;
  text-align: center;
  background: var(--ink-100);
  border-radius: var(--radius-sm);
  padding: var(--sp-1) 0;
}
.termin-date-month {
  font-size: var(--fs-xs);
  color: var(--color-text-muted);
  text-transform: uppercase;
  letter-spacing: 0.05em;
}
.termin-date-day {
  font-family: var(--font-display);
  font-size: var(--fs-lg);
  font-weight: 500;
  line-height: 1;
}
.termin-body {
  flex: 1;
  min-width: 0;
  display: flex;
  flex-direction: column;
  gap: 2px;
  align-items: flex-start;
}
.termin-body .badge { margin: var(--sp-1) 0 0; }
.termin-title {
  font-weight: 500;
  font-size: var(--fs-sm);
  color: inherit;
  text-decoration: none;
  display: block;
}
.termin-meta { font-size: var(--fs-xs); color: var(--color-text-muted); }
.termin-box > p { margin: var(--sp-4) 0 0; font-size: var(--fs-sm); }

/* ——— Badges — vergeben in termin-list.php (badge-<kategorie>) und bootspark.php (badge-<verfuegbarkeit>) ——— */
.badge {
  display: inline-block;
  padding: 2px var(--sp-2);
  border-radius: var(--radius-sm);
  font-size: var(--fs-xs);
  font-weight: 500;
  letter-spacing: 0.02em;
  margin-right: var(--sp-2);
}
.badge-regatta { background: var(--frgs-red-soft); color: var(--frgs-red-dark); }
.badge-wanderfahrt { background: #E8F0E5; color: #2F5524; }
.badge-vereinsleben { background: #EDE7F5; color: #3D2D6B; }
.badge-fest { background: var(--warn-bg); color: var(--warn-ink); }
.badge-sonstiges { background: var(--ink-100); color: var(--ink-700); }

/* Bootspark-Gate (Mitgliederbereich) */
.bootspark-gate {
  max-width: 26rem;
  padding: var(--sp-8) 0;
}
.bootspark-gate form {
  display: flex;
  flex-direction: column;
  gap: var(--sp-2);
  align-items: flex-start;
  margin-top: var(--sp-4);
}
.bootspark-gate label {
  font-size: var(--fs-xs);
  font-weight: 500;
  text-transform: uppercase;
  letter-spacing: 0.06em;
  color: var(--color-text-muted);
}
.bootspark-gate input[type="password"] {
  width: 100%;
  padding: var(--sp-2) var(--sp-3);
  border: 1px solid var(--color-border);
  border-radius: var(--radius-sm);
  background: var(--color-surface);
  font: inherit;
  font-size: var(--fs-sm);
}
.bootspark-gate input[type="password"]:focus-visible,
.bootspark-gate button:focus-visible {
  outline: 2px solid var(--color-accent);
  outline-offset: 2px;
}
.bootspark-gate button {
  margin-top: var(--sp-2);
  padding: var(--sp-2) var(--sp-6);
  border: none;
  border-radius: var(--radius-sm);
  background: var(--color-accent);
  color: #fff;
  font: inherit;
  font-size: var(--fs-sm);
  font-weight: 500;
  cursor: pointer;
}
.bootspark-gate button:hover { background: var(--color-accent-ink); }
.bootspark-gate-error {
  padding: var(--sp-2) var(--sp-3);
  border-radius: var(--radius-sm);
  background: var(--frgs-red-soft);
  color: var(--frgs-red-dark);
  font-size: var(--fs-sm);
}

/* ---- Galerie (wiederverwendbar: Artikel + Wanderfahrten; Lightbox: gallery.js) ---- */
.frgs-gallery {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(160px, 1fr));
  gap: var(--sp-2);
  margin-block: var(--sp-8);
}
.frgs-gallery-item {
  position: relative;
  display: block;
  border-radius: var(--radius-md);
  overflow: hidden;
  aspect-ratio: 3 / 2;
  background: var(--ink-100);
}
.frgs-gallery-item img {
  width: 100%;
  height: 100%;
  object-fit: cover;
  display: block;
  transition: transform 180ms ease;
}
.frgs-gallery-item:hover img,
.frgs-gallery-item:focus-visible img {
  transform: scale(1.03);
}
.frgs-gallery-item:focus-visible {
  outline: 2px solid var(--color-accent);
  outline-offset: 2px;
}
/* Anker um ein Inline-Bild (blocks/image.php). Ohne display:block spannt die
 * Box eines <a> über die ganze Textbreite — gemessen 1096×420 statt der
 * Bildgröße — und der Fokusring, den der Browser nach dem Schließen der
 * Lightbox auf den zurückfokussierten Anker zeichnet, umrahmt dann die halbe
 * Spalte statt das Bild. fit-content lässt die Box aufs Bild schrumpfen. */
.frgs-bild-link {
  display: block;
  width: fit-content;
  max-width: 100%;
  border-radius: var(--radius-md);
}
.frgs-bild-link:focus-visible {
  outline: 2px solid var(--color-accent);
  outline-offset: 3px;
}
/* Vergrößern-Hinweis. Dauerhaft sichtbar statt nur bei Hover: auf Touch-Geräten
 * gibt es keinen Hover, und ohne Hinweis bleibt die Klickbarkeit unentdeckt. */
.frgs-bild-link--zoom { position: relative; }
.frgs-bild-zoom {
  position: absolute;
  right: var(--sp-2);
  bottom: var(--sp-2);
  display: grid;
  place-items: center;
  width: 2rem;
  height: 2rem;
  border-radius: var(--radius-sm);
  background: color-mix(in srgb, var(--ink-900) 55%, transparent);
  color: var(--white);
  transition: background 180ms ease;
}
.frgs-bild-zoom .icon {
  width: 1rem;
  height: 1rem;
  stroke: currentColor;
}
.frgs-bild-link--zoom:hover .frgs-bild-zoom,
.frgs-bild-link--zoom:focus-visible .frgs-bild-zoom {
  background: var(--ink-900);
}
@media (prefers-reduced-motion: reduce) {
  .frgs-bild-zoom { transition: none; }
}

.frgs-gallery-more-label {
  position: absolute;
  inset: 0;
  display: grid;
  place-items: center;
  background: color-mix(in srgb, var(--ink-900) 55%, transparent);
  color: var(--white);
  font-weight: 600;
  font-size: var(--fs-md);
}
@media (prefers-reduced-motion: reduce) {
  .frgs-gallery-item img { transition: none; }
}

/* ---- Lightbox (gallery.js) ---- */
.frgs-lightbox {
  border: none;
  padding: 0;
  width: 100vw;
  height: 100dvh;
  max-width: none;
  max-height: none;
  background: color-mix(in srgb, var(--ink-900) 96%, transparent);
  color: var(--white);
}
.frgs-lightbox::backdrop { background: transparent; }
.frgs-lightbox-strip {
  display: flex;
  overflow-x: auto;
  scroll-snap-type: x mandatory;
  width: 100%;
  height: 100%;
  scrollbar-width: none;
}
.frgs-lightbox-strip::-webkit-scrollbar { display: none; }
.frgs-lightbox-slide {
  flex: 0 0 100%;
  scroll-snap-align: center;
  display: grid;
  place-items: center;
  padding: var(--sp-8) var(--sp-4) var(--sp-16);
}
.frgs-lightbox-slide img {
  max-width: 100%;
  /* max-height: 100% griff nicht: die Prozentangabe löst gegen eine
   * inhaltsbasierte Grid-Zeile auf und wird dann als `none` behandelt —
   * Hochformate liefen aus dem Dialog heraus (gemessen 1248×1664 bei 800 px
   * Viewport, also 864 px Überhang; Bedienelemente und Bildunterschrift lagen
   * außerhalb). Deshalb explizit gegen die Viewport-Höhe minus Slide-Padding
   * (2rem oben + 4rem unten). dvh zusätzlich, damit auf dem Handy die
   * ein-/ausfahrende Browserleiste nicht mitzählt; vh bleibt als Rückfall. */
  max-height: calc(100vh - 6rem);
  max-height: calc(100dvh - 6rem);
  object-fit: contain;
  border-radius: var(--radius-sm);
}
.frgs-lightbox-close,
.frgs-lightbox-prev,
.frgs-lightbox-next {
  position: fixed;
  z-index: 2;
  min-width: 44px;
  min-height: 44px;
  border: none;
  border-radius: var(--radius-md);
  background: color-mix(in srgb, var(--white) 12%, transparent);
  color: var(--white);
  font-size: var(--fs-xl);
  line-height: 1;
  cursor: pointer;
}
.frgs-lightbox-close:hover, .frgs-lightbox-prev:hover, .frgs-lightbox-next:hover {
  background: color-mix(in srgb, var(--white) 24%, transparent);
}
.frgs-lightbox-close:focus-visible, .frgs-lightbox-prev:focus-visible, .frgs-lightbox-next:focus-visible {
  outline: 2px solid var(--white);
  outline-offset: 2px;
}
.frgs-lightbox-close { top: var(--sp-4); right: var(--sp-4); }
.frgs-lightbox-prev  { left: var(--sp-4);  top: 50%; transform: translateY(-50%); }
.frgs-lightbox-next  { right: var(--sp-4); top: 50%; transform: translateY(-50%); }
.frgs-lightbox-bar {
  position: fixed;
  bottom: var(--sp-4);
  left: 50%;
  transform: translateX(-50%);
  display: flex;
  gap: var(--sp-4);
  font-size: var(--fs-sm);
  color: var(--ink-300);
  margin: 0;
  max-width: 90vw;
}
.frgs-lightbox-counter { color: var(--white); font-variant-numeric: tabular-nums; }

/* ---- Aufklappbare Legende (Bedienmuster: Statistik + Bootspark) ----
 * Basis-Look; seitenspezifischer Inhalt (Listenform, Grid, Beispieltext,
 * @media print) bleibt in pages/*.css. */
.frgs-legende {
  margin-block-end: var(--sp-6);
  padding: var(--sp-4) var(--sp-6);
  background: var(--color-surface);
  border: 1px solid var(--color-border);
  border-radius: var(--radius-sm);
  font-size: var(--fs-sm);
  color: var(--color-text-muted);
}
.frgs-legende summary {
  cursor: pointer;
  font-weight: 600;
  color: var(--color-text);
}

/* Ruderampel-Widget der Startseite. Steht hier statt in pages/ruderampel.css,
 * weil es auf der Startseite erscheint — pages/*-Dateien laden nur auf ihrem
 * eigenen Template. Bewusst immer eine Zeile, auch bei Gelb und Rot: die
 * Begründung steht auf der Ampelseite. */
.ampel-zeile {
  display: flex;
  align-items: center;
  gap: var(--sp-3);
  margin-top: var(--sp-4);
  padding: var(--sp-3) var(--sp-4);
  border: 1px solid var(--color-border);
  border-radius: var(--radius-md);
  background: var(--color-surface);
  color: var(--color-text);
  text-decoration: none;
  font-size: var(--fs-sm);
}
.ampel-zeile:hover { border-color: var(--ink-300); }

.ampel-punkt { width: 11px; height: 11px; border-radius: 50%; flex: 0 0 auto; background: var(--ampel-unbekannt); }
.ampel-zeile--frei .ampel-punkt           { background: var(--ampel-frei); }
.ampel-zeile--eingeschraenkt .ampel-punkt { background: var(--ampel-limit); }
.ampel-zeile--gesperrt .ampel-punkt       { background: var(--ampel-sperre); }

/* Statt umzubrechen wird bei Platzmangel gekürzt — sonst bricht der Text im
 * schmalen Mobile-Viewport in eine zweite Zeile um, und genau das soll
 * „immer eine Zeile" ausschließen. Der Status ist der Grund, warum es das
 * Widget gibt, und darf darum nie gekürzt werden (flex-shrink: 0, keine
 * min-width nötig, da er ohnehin nicht schrumpft). Die Zeit ist nur Kontext
 * und schrumpft bzw. kürzt darum zuerst; overflow/ellipsis bleiben als
 * Absicherung, falls doch einmal kein Platz mehr bleibt. */
.ampel-zeile strong {
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
  flex-shrink: 0;
}
.ampel-zeile-zeit {
  color: var(--color-text-muted);
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
  min-width: 0;
  flex-shrink: 1;
}
.ampel-zeile-mehr {
  margin-left: auto;
  display: inline-flex;
  align-items: center;
  gap: var(--sp-1);
  color: var(--color-accent-ink);
  white-space: nowrap;
  flex-shrink: 0;
}

/* Unter 768px (gleicher Bruch wie nav.css) reicht die Breite nicht für Status,
 * Zeit und „Details" zugleich. Die Zeit bleibt hier absichtlich sichtbar —
 * sie sagt aus, wie alt der Messwert ist, und genau das braucht, wer am
 * Bootshaus mit dem Handy nachsieht. Stattdessen entfällt das Label
 * „Details": die ganze Zeile ist ohnehin ein Link, das Wort ist redundant. */
@media (max-width: 767px) {
  .ampel-zeile-mehr-label { display: none; }
}

} /* Ende @layer components */
