/* ============================================================================
 * panel.css — Vereinsportal (panel.php). Ergänzt head.css.
 * Desktop: feste linke Sidebar + Inhalt rechts. Mobil: gestapelt.
 * Statusfarben kommen aus den --st-*-Tokens in head.css.
 * ========================================================================== */
body { padding:0; }   /* head.css reserviert Platz für App-Bars — hier keine */

/* ---- Auth (Login/Setup/Kein Zugriff) zentriert ---- */
.admin-auth {
  min-height:100dvh; display:flex; align-items:center; justify-content:center; padding:24px;
  &[hidden] { display:none; }   /* sonst überschreibt display:flex das hidden-Attribut */
  & .card { width:100%; max-width:420px; }
  /* Eingabefelder gestapelt statt nebeneinander — nebeneinander sind sie auf
   * 420px zu schmal für eine E-Mail-Adresse. */
  & .card > .row { flex-direction:column; align-items:stretch; gap:12px; }
  & .card > .row + .row { margin-top:18px; }
  & .card > .out { margin-top:10px; }
  & .card > h2 + .out { margin:0 0 16px; }
}

/* ---- Abstände innerhalb der Sektionen ----
 * Der Stapelabstand hängt am Container, nicht an der Karte: eine Regel wie
 * `.admin-section > .card` greift nicht, sobald Karten in einem Raster
 * (.vp-detail-grid) oder in einer Gruppe (.vp-stack) liegen.
 *
 * flex + gap statt `* + *`: der Nachbar-Selektor sieht nur das unmittelbar
 * vorangehende Geschwister — liegt dazwischen ein ausgeblendetes Element
 * (etwa die Nichtmitglied-Karte für Mitglieder), fiel der Abstand aus. `gap` überspringt
 * display:none-Kinder von sich aus. */
.admin-section,
.vp-detail-grid > div,
.vp-stack {
  display:flex; flex-direction:column; gap:14px; align-items:stretch;
}
/* display:flex würde das hidden-Attribut sonst überstimmen. */
.vp-stack[hidden] { display:none; }

.admin-section .card > .row + .row { margin-top:14px; }
.admin-section .card > .out { margin-top:10px; }
.admin-section .card > .row .btn-accent { flex:0 0 auto; }

/* ---- App-Layout ---- */
.admin-app { display:flex; flex-direction:column; min-height:100dvh; }
.admin-app[hidden] { display:none; }
.admin-section[hidden] { display:none; }

/* Die Sidebar ist Markenfläche und bleibt in beiden Themes dunkel. Eigene
 * Tokens statt der globalen: auf --surface würde sie im Light-Theme weiß und
 * das weiße Logo verschwände. */
.admin-side {
  --side-bg:#1b1c26;
  --side-text:#f3f3f6;
  --side-muted:#9a9aa8;
  --side-line:rgba(255,255,255,.10);
  --side-hover:rgba(255,255,255,.07);
  display:flex; flex-direction:column; gap:4px; padding:16px;
  background:var(--side-bg); color:var(--side-text);
}
/* Das Logo ist eine weiße Vektorgrafik im Hochformat (753×980) — die Höhe
 * deckelt, nicht die Breite. */
.admin-brand {
  display:block; padding:6px 8px 14px;
  & img { display:block; height:56px; width:auto; }
}
.admin-nav {
  display:flex; flex-direction:column; gap:2px;
  & button {
    display:flex; align-items:center; gap:10px; width:100%; text-align:left;
    padding:10px 12px; border-radius:10px; border:none; background:none;
    color:var(--side-text); font:inherit; font-size:14.5px; cursor:pointer;
    &:hover { background:var(--side-hover); }
    &.active { background:var(--accent); color:var(--accent-ink); font-weight:600; }
    &[hidden] { display:none; }
  }
  & svg { flex:0 0 auto; width:20px; height:20px; }
}
.admin-foot {
  margin-top:auto; display:flex; align-items:center; gap:10px;
  padding:12px 8px 4px; border-top:1px solid var(--side-line);
  & .admin-foot-user { flex:1; min-width:0; }
  & .admin-foot-email { font-size:13.5px; color:var(--side-text); word-break:break-all; }
  & .admin-foot-role { font-size:12px; color:var(--side-muted); text-transform:uppercase; letter-spacing:.03em; }
}
.admin-logout {
  flex:0 0 auto; display:grid; place-items:center; width:38px; height:38px; border-radius:10px;
  border:1px solid var(--side-line); background:transparent; color:var(--side-text); cursor:pointer;
  &:hover { background:var(--side-hover); }
  &:active { transform:scale(.94); }
  & svg { width:18px; height:18px; }
}
/* min-width:0 ist Pflicht: als Flex-Item schrumpft .admin-content sonst nie
 * unter die Inhaltsbreite — eine breite Tabelle würde die Seite seitlich
 * aufblähen statt in sich zu scrollen. */
.admin-content { flex:1; min-width:0; padding:20px 18px 44px; max-width:1000px; width:100%; }
/* Overlays hängen an <body>, nicht in .admin-content — beide Scopes brauchen
 * die Größenbremse, sonst zieht ein Inline-SVG den Button auf. */
.admin-content button svg,
.vp-modal button svg { width:16px; height:16px; display:block; flex:0 0 auto; }
.admin-h1 { font-size:22px; font-weight:800; letter-spacing:-.02em; }

/* Listen- und Detailansichten brauchen die volle Breite — die 1000px-Deckelung
 * oben gilt für die schmalen Verwaltungsseiten (Benutzer, Mein Konto). */
.admin-section-wide { width:100%; min-width:0; & > * { max-width:100%; } }

/* ---- Untermenü (z.B. Ausfahrten unter „Fahrten") ---- */
.admin-nav-sub {
  display:flex; flex-direction:column; gap:2px; margin:2px 0 6px 12px;
  padding-left:10px; border-left:1px solid var(--side-line);
  & button {
    display:flex; align-items:center; gap:8px; width:100%; text-align:left;
    padding:7px 10px; border-radius:8px; border:none; background:none;
    color:var(--side-muted); font:inherit; font-size:13.5px; cursor:pointer;
    &:hover { background:var(--side-hover); color:var(--side-text); }
    &.active { background:var(--side-hover); color:#fff; font-weight:600; }
  }
}
.admin-nav-subtext { flex:1; min-width:0; overflow:hidden; text-overflow:ellipsis; white-space:nowrap; }
.admin-nav-count {
  flex:0 0 auto; font-size:11.5px; font-weight:700; color:var(--side-muted);
  background:var(--side-hover); border-radius:999px; padding:1px 7px;
}

@media (min-width:900px) {
  .admin-app { flex-direction:row; }
  .admin-side {
    position:fixed; top:0; left:0; bottom:0; width:250px;
    overflow:auto;
  }
  .admin-content { margin-left:250px; padding:30px 36px 60px; }
  .admin-content:has(.admin-section-wide:not([hidden])) { max-width:none; }
}

/* ---- Kurzmeldungen (panel.php lädt toast.js nicht) ---- */
.admin-toasts {
  position:fixed; right:16px; bottom:16px; z-index:200;
  display:flex; flex-direction:column; gap:8px; align-items:flex-end;
  pointer-events:none;
}
.admin-toast {
  pointer-events:auto; max-width:min(420px, calc(100vw - 32px));
  background:var(--surface); color:var(--text);
  border:1px solid var(--line); border-left:4px solid var(--accent);
  border-radius:12px; padding:10px 14px; font-size:14px; line-height:1.35;
  box-shadow:0 10px 30px -12px rgba(0,0,0,.4);
  opacity:0; transform:translateY(10px); transition:opacity .2s, transform .2s;
  &.show { opacity:1; transform:translateY(0); }
  &.error { border-left-color:var(--st-abgelehnt); }
}

/* ---- Stats-Kacheln (Übersicht) ---- */
/* Grid statt flex-wrap: sonst streckt sich die letzte Zeile über die volle
 * Breite, sobald die Kachelzahl nicht aufgeht. */
.admin-stats {
  display:grid; grid-template-columns:repeat(auto-fill, minmax(150px, 1fr));
  gap:12px;
}
.admin-tile {
  background:var(--surface); border:1px solid var(--line);
  border-radius:var(--radius); padding:16px 18px;
  /* Als <button> gerendert (klickbare Kachel) sonst zentriert und mit
     Systemschrift — hier bleibt sie optisch eine Kachel. */
  text-align:left; font:inherit; color:inherit; width:100%;
  & .admin-tile-n { font-size:30px; font-weight:800; letter-spacing:-.02em; }
  /* hyphens:auto lässt das Soft-Hyphen im Label greifen; Text bleibt in den
   * Text-Tokens — die Farbe trägt der Rahmen, nicht die Schrift. */
  & .admin-tile-l { font-size:13px; color:var(--muted); margin-top:2px; overflow-wrap:break-word; hyphens:auto; }
}
/* Statuskacheln: Rahmen in der Statusfarbe, dazu ein zarter Anflug der Farbe
 * in der Fläche, damit der 1px-Rand nicht die ganze Arbeit macht. */
.admin-tile-toned {
  border-color:var(--tile-tone);
  background:color-mix(in srgb, var(--tile-tone) 5%, var(--surface));
}
/* Klickbare Kachel: führt in die zugehörige Liste, dort gleich gefiltert. */
.admin-tile-link {
  cursor:pointer;
  &:hover { border-color:var(--accent); }
  &:active { transform:scale(.99); }
  &:focus-visible { outline:2px solid var(--accent); outline-offset:2px; }
}
.admin-overview-extra:empty { display:none; }

/* ---- Benutzer-Liste ---- */
.admin-users { display:flex; flex-direction:column; gap:8px; margin-top:10px; }
.admin-user {
  display:flex; align-items:center; gap:10px;
  background:var(--surface-2); border:1px solid var(--line); border-radius:12px; padding:10px 13px;
  & .admin-uinfo { flex:1; min-width:0; display:flex; align-items:center; gap:10px; }
  & .admin-uemail { font-size:14.5px; word-break:break-all; }
}
.admin-role {
  font-size:11px; font-weight:700; text-transform:uppercase; letter-spacing:.03em;
  padding:2px 8px; border-radius:999px; border:1px solid var(--line); color:var(--muted);
  &.admin-role-mitglied { background:color-mix(in srgb, var(--st-aktiv) 16%, var(--surface)); color:#07785b; border-color:transparent; }
  &.admin-role-admin { background:var(--accent); color:var(--accent-ink); border-color:transparent; }
  &.admin-role-superadmin { background:var(--text); color:var(--bg); border-color:transparent; }
}
/* padding-right lässt Platz für den Chevron aus head.css — sonst liegt er auf
 * dem Text. */
.admin-roasel { width:auto; flex:0 0 auto; padding:5px 26px 5px 9px; font-size:12.5px; }
.del-btn {
  border:1px solid var(--line); background:var(--surface); color:var(--text);
  border-radius:10px; padding:8px 12px; font:inherit; font-size:13px; cursor:pointer;
  &:disabled { opacity:.5; cursor:default; }
  &:not(:disabled):active { transform:scale(.97); }
}

/* ---- Frontend-Fehler-Log ---- */
.admin-logs { display:flex; flex-direction:column; gap:6px; margin-top:10px; }
.admin-log {
  display:flex; align-items:baseline; gap:10px; font-size:12.5px;
  padding:8px 10px; background:var(--surface-2); border:1px solid var(--line); border-radius:10px;
  & .admin-log-date { color:var(--muted); font-variant-numeric:tabular-nums; white-space:nowrap; }
  & .admin-log-ip { color:var(--muted); white-space:nowrap; }
  & .admin-log-msg { flex:1; min-width:0; word-break:break-word; }
  & .admin-log-type {
    font-size:10.5px; font-weight:700; text-transform:uppercase; padding:1px 6px; border-radius:999px;
    border:1px solid var(--line); color:var(--muted); white-space:nowrap;
    &.admin-log-error { background:#c0392b; color:#fff; border-color:transparent; }
    &.admin-log-warn { background:#d68910; color:#fff; border-color:transparent; }
  }
}

/* ============================================================================
 * Bausteine für die Fachmodule (panel-*.js) — Präfix vp- (Vereinsportal).
 * ========================================================================== */

/* ---- Statuspunkt + Pill ---- */
.vp-dot { flex:0 0 auto; width:9px; height:9px; border-radius:50%; background:var(--muted); }
.vp-dot-pending    { background:var(--st-pending); }
.vp-dot-aktiv      { background:var(--st-aktiv); }
.vp-dot-inaktiv    { background:var(--st-inaktiv); }
.vp-dot-abgelehnt  { background:var(--st-abgelehnt); }
.vp-dot-gebucht    { background:var(--st-gebucht); }
.vp-dot-warteliste { background:var(--st-warteliste); }
.vp-dot-storniert  { background:var(--st-abgelehnt); }

.vp-pill {
  display:inline-flex; align-items:center; gap:6px; white-space:nowrap;
  padding:3px 10px; border-radius:999px; font-size:12.5px; font-weight:600;
  background:var(--surface-2); color:var(--text);
}
/* Textfarbe bei Gelb/Grün bewusst abgedunkelt — die Signalfarbe selbst hat auf
 * hellem Grund zu wenig Kontrast für Fließtext. */
.vp-pill-pending    { background:color-mix(in srgb, var(--st-pending) 16%, var(--surface)); color:#a35c04; }
.vp-pill-aktiv      { background:color-mix(in srgb, var(--st-aktiv) 14%, var(--surface)); color:#07785b; }
.vp-pill-nichtmitglied { background:var(--surface-2); color:var(--text); }
.vp-pill-inaktiv    { background:var(--surface-2); color:var(--muted); }
.vp-pill-abgelehnt  { background:color-mix(in srgb, var(--st-abgelehnt) 12%, var(--surface)); color:var(--st-abgelehnt); }
.vp-pill-gebucht    { background:color-mix(in srgb, var(--st-gebucht) 14%, var(--surface)); color:var(--st-gebucht); }
.vp-pill-warteliste { background:color-mix(in srgb, var(--st-warteliste) 14%, var(--surface)); color:var(--st-warteliste); }
.vp-pill-storniert  { background:var(--surface-2); color:var(--muted); text-decoration:line-through; }
.vp-pill-offen      { background:color-mix(in srgb, var(--st-pending) 16%, var(--surface)); color:#a35c04; }
.vp-pill-abgebucht,
.vp-pill-bezahlt    { background:color-mix(in srgb, var(--st-aktiv) 14%, var(--surface)); color:#07785b; }
.vp-pill-erlassen   { background:var(--surface-2); color:var(--muted); }

/* ---- Kopfzeile + Toolbar ---- */
.vp-head {
  display:flex; align-items:center; gap:14px; flex-wrap:wrap;
  & .admin-h1 { margin:0; flex:1; min-width:0; }
  &[hidden] { display:none; }
}
.vp-head-actions { display:flex; align-items:center; gap:8px; }
.vp-head-actions .btn-accent { padding:10px 16px; border-radius:12px; }

.vp-toolbar {
  display:flex; align-items:center; gap:10px; flex-wrap:wrap; justify-content:space-between;
  background:var(--surface); border:1px solid var(--line); border-radius:14px;
  padding:10px 12px;
  &[hidden] { display:none; }
}
.vp-toolbar-left { display:flex; align-items:center; gap:10px; flex:1; min-width:0; flex-wrap:wrap; }
.vp-toolbar-right { display:flex; align-items:center; gap:8px; }
.vp-filter { width:auto; flex:0 0 auto; padding:8px 32px 8px 12px; font-size:13.5px; }
.vp-search { flex:1; min-width:160px; padding:8px 12px; font-size:13.5px; }
.vp-chip {
  flex:0 0 auto; font-size:12.5px; font-weight:600; color:var(--muted);
  background:var(--surface-2); border-radius:999px; padding:5px 12px; white-space:nowrap;
}

/* ---- Tabelle ---- */
.vp-listwrap {
  background:var(--surface); border:1px solid var(--line); border-radius:14px; overflow-x:auto;
  &[hidden] { display:none; }
}
/* Zwischenüberschrift innerhalb einer Karte (z.B. „Grundpreis" / „Ab 01.11.") */
.vp-subhead { font-size:14px; font-weight:700; }
.vp-table {
  width:100%; border-collapse:collapse; font-size:14px;
  & th {
    text-align:left; font-size:12.5px; font-weight:600; color:var(--muted);
    padding:12px 14px; border-bottom:1px solid var(--line); white-space:nowrap;
  }
  & td { padding:11px 14px; border-bottom:1px solid var(--line); white-space:nowrap; }
  & tbody tr:last-child td { border-bottom:none; }
  & .vp-td-name { font-weight:600; }
  & .vp-td-num { text-align:right; font-variant-numeric:tabular-nums; }
  & input[type=checkbox] { width:16px; height:16px; accent-color:var(--accent); cursor:pointer; }
}
/* Nur klickbare Tabellen bekommen den Zeiger — Preis-Matrizen sind reine
 * Eingaberaster und dürfen nicht so aussehen, als führten sie irgendwohin. */
.vp-table-click tbody tr { cursor:pointer; }
.vp-table-click tbody tr:hover { background:var(--surface-2); }
.vp-empty { color:var(--muted); font-size:14px; padding:22px 14px; text-align:center; }

/* ---- Detailansicht (ersetzt den Maincontent, kein Popup) ---- */
.vp-detail[hidden] { display:none; }
.vp-detail-head {
  display:flex; align-items:center; gap:12px; flex-wrap:wrap; margin-bottom:18px;
  & .vp-detail-name { font-size:22px; font-weight:800; letter-spacing:-.02em; margin-right:4px; }
}
.vp-chips { display:flex; align-items:center; gap:8px; margin-left:auto; flex-wrap:wrap; }
.vp-contact {
  display:inline-flex; align-items:center; gap:7px; font-size:13.5px;
  background:var(--surface); border:1px solid var(--line); border-radius:11px; padding:7px 12px;
  color:var(--text); text-decoration:none;
  & svg { width:15px; height:15px; color:var(--muted); flex:0 0 auto; }
}
a.vp-contact {
  &:hover { border-color:var(--accent); color:var(--accent); }
  &:hover svg { color:var(--accent); }
}
/* Zwei Spalten ab Tablet: links Stammdaten, rechts Verlauf/Zusatz. */
.vp-detail-grid { display:grid; grid-template-columns:1fr; gap:14px; align-items:start; }
@media (min-width:1000px) { .vp-detail-grid { grid-template-columns:1.15fr .85fr; } }

/* Feldraster für Stammdaten — Label links, Wert/Eingabe rechts. */
.vp-fields { display:flex; flex-direction:column; }
.vp-frow {
  display:grid; grid-template-columns:170px 1fr; gap:12px; align-items:center;
  padding:8px 0; border-bottom:1px solid var(--line);
  &:last-child { border-bottom:none; }
  & > label { font-size:13px; color:var(--muted); }
  & > .vp-fval { font-size:14px; word-break:break-word; }
}
@media (max-width:560px) { .vp-frow { grid-template-columns:1fr; gap:4px; } }

/* ---- Auslastungsbalken (Busplätze) ---- */
.vp-bar {
  height:8px; border-radius:999px; background:var(--surface-2); overflow:hidden;
  & > span { display:block; height:100%; background:var(--accent); border-radius:999px; }
  &.full > span { background:var(--st-abgelehnt); }
}
.vp-bar-label { font-size:12.5px; color:var(--muted); margin-top:5px; font-variant-numeric:tabular-nums; }

/* ---- Modal (das <app-modal> aus components.js lädt panel.php nicht, und mit
 *      380px wäre es für Formulare ohnehin zu schmal) ---- */
.vp-overlay {
  position:fixed; inset:0; z-index:150; display:grid; place-items:center; padding:20px;
  background:rgba(0,0,0,.45);
  &[hidden] { display:none; }
}
.vp-modal {
  width:100%; max-width:560px; max-height:calc(100dvh - 40px); overflow:auto;
  background:var(--surface); border:1px solid var(--line); border-radius:var(--radius);
  padding:20px 22px; box-shadow:0 24px 60px -20px rgba(0,0,0,.55);
  & > h2 { font-size:17px; font-weight:700; margin-bottom:14px; }
}
.vp-modal-wide { max-width:820px; }
.vp-modal-actions { display:flex; gap:10px; justify-content:flex-end; margin-top:20px; flex-wrap:wrap; }
.btn-danger {
  border:1px solid var(--st-abgelehnt); background:var(--st-abgelehnt); color:#fff;
  border-radius:12px; padding:10px 16px; font:inherit; font-size:14px; cursor:pointer;
  &:active { transform:scale(.97); }
}

/* ---- Wiederholbare Zeilen (Haltestellen, Betreuer) ---- */
.vp-repeat { display:flex; flex-direction:column; gap:8px; }
.vp-repeat-row {
  display:flex; gap:8px; align-items:center; flex-wrap:wrap;
  & input, & select { flex:1; min-width:120px; }
  & .del-btn { flex:0 0 auto; }
}

/* ---- Personenauswahl beim Buchen ----
 * Grid statt flex-wrap: die Spalten müssen untereinander fluchten, sonst
 * springen Preis und Leistungsschalter je nach Namenslänge. */
.vp-person {
  display:grid; align-items:center; gap:10px;
  grid-template-columns:minmax(160px,1.4fr) auto minmax(150px,auto) 90px auto;
  padding:9px 0; border-bottom:1px solid var(--line);
  &:last-of-type { border-bottom:none; }
  & > label { display:flex; align-items:center; gap:8px; margin:0; cursor:pointer; }
  & input[type=checkbox] { width:17px; height:17px; accent-color:var(--accent); flex:0 0 auto; }
  & .vp-price { text-align:right; font-variant-numeric:tabular-nums; font-weight:600; }
  & .vp-price-free { color:var(--st-aktiv); }
}
@media (max-width:720px) {
  .vp-person { grid-template-columns:1fr auto; row-gap:4px; }
}

/* Deaktivierte Aktionen müssen auch deaktiviert aussehen — ein voll gefärbter
 * Button, der nicht reagiert, liest sich als Fehler. */
.btn-accent:disabled, .btn-ghost:disabled, .btn-danger:disabled {
  opacity:.45; cursor:default; filter:saturate(.6);
}
