/* design-system: migriert */
/* ==========================================================================
   Plugin Marketplace (AP6a Grundgerüst + AP6b Feinschliff) — Vollbild-Modal-
   Styling.

   Baut bewusst auf den bestehenden Primitiven aus style.css auf statt ein
   zweites System daneben aufzumachen: .modal-overlay/.modal-dialog (Modal-
   Grundgerüst), .settings-input (Formularfelder), .btn-primary/.btn-danger/
   .icon-btn (Aktionen), .badge/.list-empty/.page-title/.page-subtitle,
   .section-toolbar (Filterzeile), .settings-nav/.tab-btn (Reiter),
   .settings-toggle-row (Checkbox-Zeile). Farben, Abstände, Radien, Schrift
   und Bewegung kommen ausschließlich aus tokens.css.

   AP6c (Schließen-Fix): Sichtbarkeit des Overlays läuft über die
   .is-open-Klasse (siehe .marketplace-modal-overlay unten), nicht über ein
   Inline-Style im Template -- Details dort und in marketplace.js.

   AP7 Apple-Design-Plan (Optik-Stufe 4, 2026-10-12):
   - Auftritt und Abgang gespiegelt. Mit motion.js (window.NCMotion) wächst
     der Dialog per Feder aus dem Auslöser (transform-origin am Sidebar-
     Eintrag) und schrumpft beim Schließen auf demselben Weg zurück; die
     Klasse .nm-motion schaltet dafür die CSS-Keyframes ab. Ohne motion.js
     laufen die Keyframes aus style.css (nm-dialog-in/-out, nm-scrim-in/-out),
     ebenfalls mit Ursprung am Auslöser (marketplace.js setzt
     transform-origin in beiden Fällen). .is-closing hält das Overlay für
     die Dauer des Abgangs sichtbar, aber inert.
   - Reduced Motion, Reduced Transparency und mehr Kontrast laufen allein
     über die Token (--motion-scale, --dur-*, --spring, --material-*,
     --glass-border, --border-width, --focus-ring-width); hier steht dafür
     kein eigener Media-Block.
   - Karten als innere Ebene des Dialogs: --fill-1 statt Glas mit Blur
     (DESIGNRICHTUNG 2.5: höchstens zwei Ebenen, nie zwei durchlässige
     Flächen übereinander). Meta-Zeilen in --text-secondary, weil --text-dim
     auf --fill-1 über --panel-elevated nur 4.34:1 erreicht.
   - Die Filterzeile bleibt beim Scrollen oben stehen und ist das einzige
     Material im Dialog (--material-regular-*): die Karten laufen sichtbar
     darunter durch, statt an einer harten Linie zu enden.
   - Typografie in rem über die Skala, Satzschreibung statt GROSS (H5),
     Radien 8/12/16 über --radius-s/-m/-l, Gedrückt-Zustände mit
     --press-scale. Favoriten-Herz und „Neu“-Badge nehmen den Akzent statt
     --accent-red/--accent-teal (die sind Aufnahme/Peak bzw. Wellenform
     vorbehalten, tokens.css).
   - _marketplace_modal.html ist Golden-Vorlage des C-Clients und bleibt
     unverändert; alles hier wirkt nur über vorhandene Klassen.
   ========================================================================== */

/* Reine Sichtbarkeits-Hilfsklasse für Formular-Label, die nur dem
   Screenreader einen Namen für Suchfeld/Kategorie-Auswahl geben (die
   Platzhalter/Icons allein reichen nicht als zugänglicher Name). */
.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;
}

/* AP6c: Sichtbarkeit läuft über diese Klasse statt über ein Inline-Style im
   Template -- ein von einer restriktiven CSP verworfenes Inline-Style könnte
   das Overlay sonst dauerhaft sichtbar lassen, ohne dass open() je gelaufen
   ist. .modal-overlay (style.css) setzt display:flex ohne Bedingung -- diese
   Regel kommt in der Ladereihenfolge NACH style.css (siehe base.html) und
   gewinnt bei gleicher Spezifität. */
.marketplace-modal-overlay { display: none; }
.marketplace-modal-overlay.is-open,
.marketplace-modal-overlay.is-closing { display: flex; }

/* Abgang ohne motion.js: gespiegelte Keyframes aus style.css. Während des
   Abgangs nimmt das Overlay keine Klicks mehr an (zusätzlich inert, siehe
   marketplace.js). */
.marketplace-modal-overlay.is-closing {
  pointer-events: none;
  animation: nm-scrim-out var(--dur-base) var(--ease) forwards;
}
.marketplace-modal-overlay.is-closing > .marketplace-modal-dialog {
  animation: nm-dialog-out var(--dur-base) var(--ease) forwards;
}
/* Mit motion.js führt die Feder, die Keyframes schweigen. */
.marketplace-modal-overlay.nm-motion,
.marketplace-modal-overlay.nm-motion > .marketplace-modal-dialog { animation: none; }

/* Vollbild-Dialog (Produktentscheidung: kein Slide-in-Panel, keine eigene
   Seite) — größer als das Einstellungen-Modal, damit das Karten-Raster
   Platz hat. Fläche, Rand, Radius (--radius-l) und Schatten kommen aus
   .modal-dialog. dvh, damit die mobile Adressleiste nichts abschneidet. */
.marketplace-modal-dialog {
  width: 100%;
  max-width: 1280px;
  height: 88vh;
  height: 88dvh;
  max-height: 88dvh;
}
/* Fokus liegt beim Öffnen auf dem Dialog-Wurzelelement selbst — gleiches
   Muster wie beim Einstellungen-Modal (siehe style.css). */
.marketplace-modal-dialog:focus { outline: none; }

/* Keine Maske am Körper: eine mask-image macht ihn in Chromium zur
   Backdrop-Wurzel, und der Weichzeichner der mitlaufenden Filterzeile
   (unten) bliebe wirkungslos (gemessen: Kartentext darunter gestochen
   scharf). Oben bildet die Filterzeile als Material die Kante, unten
   übernimmt ein mitlaufender Verlauf in der Dialogfarbe den weichen
   Auslauf. Unter mehr Kontrast endet der Inhalt hart (wie
   --scroll-edge-mask: none in tokens.css). */
.marketplace-modal-body {
  padding-top: 0;
  -webkit-mask-image: none;
  mask-image: none;
  /* Per Tab fokussierte Karten nicht unter der mitlaufenden Filterzeile
     verstecken (WCAG 2.4.11): Höhe der Zeile plus ihr Abstand. */
  scroll-padding-top: calc(var(--control-h-m) + 2 * var(--space-2) + var(--space-4));
}
.marketplace-modal-body::after {
  content: "";
  position: sticky;
  /* Chromium hält sticky-Elemente innerhalb des Innenabstands; der Körper
     hat unten --scroll-edge-size Innenabstand (style.css), der Verlauf soll
     aber bündig an der sichtbaren Unterkante liegen. */
  bottom: calc(-1 * var(--scroll-edge-size));
  display: block;
  flex-shrink: 0; /* .modal-body ist ein Flex-Container, sonst schrumpft der Verlauf auf 0 */
  height: var(--scroll-edge-size);
  margin-top: calc(-1 * var(--scroll-edge-size));
  background: linear-gradient(to bottom, transparent, var(--panel-elevated));
  pointer-events: none;
}
@media (prefers-contrast: more) {
  .marketplace-modal-body::after { display: none; }
}

/* Sidebar-Eintrag ist hier ein <button> statt eines <a> (kein eigener
   Seiten-Aufruf, siehe base.html) — .nav-item bringt Layout/Farbe/Hover
   mit, hier nur die button-spezifischen Rücksetzer. */
.nav-item[data-marketplace-trigger] {
  width: 100%;
  background: none;
  border: none;
  text-align: left;
  font: inherit;
}
.nav-item[data-marketplace-trigger]:focus-visible {
  outline: var(--focus-ring-width) solid var(--focus-ring);
  outline-offset: var(--focus-ring-offset);
}

/* --------------------------------------------------------------------
   Reiter Plugins/Bundles — .settings-nav/.tab-btn als Segmentschalter aus
   style.css, hier nur der Abstand.
   -------------------------------------------------------------------- */
.marketplace-tabs {
  margin-top: var(--space-3);
  margin-bottom: var(--space-3);
}

/* --------------------------------------------------------------------
   Filterzeile (Suche, Kategorie, Sortierung, Favoriten) — bleibt beim
   Scrollen stehen. Material mit Lichtkante; unter weniger Transparenz und
   mehr Kontrast wird es über die Token deckend.
   -------------------------------------------------------------------- */
.marketplace-toolbar {
  position: sticky;
  top: 0;
  z-index: 2;
  margin: 0 0 var(--space-4);
  padding: var(--space-2);
  border-radius: var(--radius-m);
  align-items: center;
  justify-content: flex-start;
  background: var(--material-regular-bg);
  -webkit-backdrop-filter: var(--material-regular-filter);
  backdrop-filter: var(--material-regular-filter);
  box-shadow: var(--material-edge), var(--shadow-s);
}
.marketplace-search-label,
.marketplace-category-label,
.marketplace-sort-label {
  display: block;
}
.marketplace-search-input {
  width: 15rem;
  max-width: 100%;
}
.marketplace-category-label select,
.marketplace-sort-label select {
  min-width: 10rem;
}
.marketplace-favorites-toggle {
  margin: 0; /* .settings-toggle-row bringt sonst einen Absatz-Abstand mit */
  white-space: nowrap;
}

/* --------------------------------------------------------------------
   Karten-Raster — bricht ohne eigene Media Query um (auto-fill/minmax).
   -------------------------------------------------------------------- */
.marketplace-grid {
  list-style: none;
  margin: 0;
  padding: 0;
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(min(15rem, 100%), 1fr));
  gap: var(--space-3);
}

.marketplace-card {
  width: 100%;
  /* Füllt das <li> (Flex-Spalte, siehe .marketplace-card-item); darunter
     kann ein Sperrhinweis stehen (AP-ML L9). */
  flex: 1 1 auto;
  display: flex;
  flex-direction: column;
  align-items: stretch;
  gap: var(--space-1);
  text-align: left;
  background: var(--fill-1);
  border: var(--border-width) solid var(--glass-border);
  border-radius: var(--radius-m);
  padding: var(--space-4);
  color: var(--text-primary);
  font-family: var(--font-text);
  cursor: pointer;
  transition: border-color var(--dur-fast) var(--ease),
              background-color var(--dur-fast) var(--ease),
              transform var(--dur-press) var(--ease);
}
.marketplace-card:hover {
  border-color: var(--glass-border-hover);
}
/* Gedrückt: sofort auf pointerdown, Fläche dichter und minimal kleiner. */
.marketplace-card:active {
  background: var(--fill-2);
  transform: scale(var(--press-scale));
}
.marketplace-card:focus-visible {
  outline: var(--focus-ring-width) solid var(--focus-ring);
  outline-offset: var(--focus-ring-offset);
}

.marketplace-card-head {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: var(--space-2);
}
/* Platz für das schwebende Favoriten-Herz oben rechts, damit es die Badges
   nicht verdeckt (nur Karten, die das Herz tragen). */
.marketplace-card-item:has(.marketplace-card-favorite-btn:not([hidden])) .marketplace-card-head {
  padding-right: calc(var(--control-h-s) + var(--space-2));
}

.marketplace-card-name {
  font-size: var(--size-headline);
  line-height: var(--leading-headline);
  letter-spacing: var(--tracking-headline);
  font-weight: var(--weight-semibold);
  min-width: 0;
  overflow-wrap: anywhere;
}

.marketplace-card-badges {
  display: flex;
  align-items: center;
  gap: var(--space-1);
  flex-wrap: wrap;
}
.marketplace-card-badges .badge {
  margin: 0;
  font-size: var(--size-caption);
  line-height: var(--leading-caption);
  letter-spacing: var(--tracking-caption);
  padding: 2px var(--space-2);
}

/* „Neu“: gefülltes Badge in --accent-fill (Weiß darauf 5.55:1).
   „Aktualisiert“: neutral, damit nur Neues den Akzent trägt. */
.marketplace-badge-new {
  color: var(--on-accent-fill);
  background: var(--accent-fill);
}
.marketplace-badge-updated {
  color: var(--text-primary);
  background: var(--fill-2);
}

.marketplace-card-category {
  font-size: var(--size-caption);
  line-height: var(--leading-caption);
  letter-spacing: var(--tracking-caption);
  font-weight: var(--weight-semibold);
  color: var(--text-secondary);
}

.marketplace-card-meta-row {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: var(--space-2);
  margin-top: auto;
  padding-top: var(--space-1);
}

.marketplace-card-installs,
.marketplace-card-rating {
  font-size: var(--size-footnote);
  line-height: var(--leading-footnote);
  letter-spacing: var(--tracking-footnote);
  font-variant-numeric: tabular-nums;
  color: var(--text-secondary);
}

.marketplace-card-desc {
  display: -webkit-box;
  margin: var(--space-1) 0 0;
  font-size: var(--size-callout);
  line-height: var(--leading-callout);
  letter-spacing: var(--tracking-callout);
  color: var(--text-secondary);
  /* Lange Beschreibungen nach drei Zeilen abschneiden, damit die Karten
     einer Rasterzeile gleich hoch bleiben. */
  -webkit-line-clamp: 3;
  -webkit-box-orient: vertical;
  overflow: hidden;
}

/* Favoriten-Umschalter auf der Karte -- eigenständiger <button> NEBEN der
   Karten-Schaltfläche (zwei <button> dürfen nicht ineinander liegen), beide
   im selben <li>. Schwebt über der Karte, deshalb als Material. */
.marketplace-card-item {
  position: relative;
  display: flex;
  flex-direction: column;
  gap: var(--space-1);
}
.marketplace-card-favorite-btn {
  position: absolute;
  top: var(--space-2);
  right: var(--space-2);
  width: 28px;
  height: 28px;
  border-radius: var(--radius-full);
  background: var(--material-thin-bg);
  -webkit-backdrop-filter: var(--material-thin-filter);
  backdrop-filter: var(--material-thin-filter);
}
.marketplace-card-favorite-btn svg { width: 15px; height: 15px; }
.marketplace-card-favorite-btn:active,
.marketplace-favorite-btn:active { transform: scale(var(--press-scale)); }

/* Favorit = aktives Symbol, also --accent (5.38:1 auf --fill-1). */
.marketplace-card-favorite-btn.is-favorite,
.marketplace-favorite-btn.is-favorite { color: var(--accent); }
.marketplace-card-favorite-btn.is-favorite svg,
.marketplace-favorite-btn.is-favorite svg { fill: currentColor; }
.marketplace-card.is-favorite { border-color: var(--glass-border-hover); }

/* .icon-btn (style.css) setzt display:flex, das schlägt [hidden] aus dem
   UA-Stylesheet. Ohne diese Korrektur bliebe ein ausgeblendeter
   Favoriten-Knopf sichtbar (leer und funktionslos). */
.marketplace-favorite-btn[hidden],
.marketplace-card-favorite-btn[hidden] {
  display: none;
}
.marketplace-favorite-btn svg { width: 18px; height: 18px; }

/* --------------------------------------------------------------------
   Bundle-Karten -- gleiche Karte, schlanker (Name, Beschreibung, Anzahl).
   -------------------------------------------------------------------- */
.marketplace-bundle-count {
  display: block;
  margin: auto 0 0;
  padding-top: var(--space-1);
  font-size: var(--size-footnote);
  line-height: var(--leading-footnote);
  font-variant-numeric: tabular-nums;
  color: var(--text-secondary);
}

/* --------------------------------------------------------------------
   Detail-Ansicht
   -------------------------------------------------------------------- */
.marketplace-back-btn {
  display: inline-flex;
  align-items: center;
  gap: var(--space-2);
  margin: var(--space-3) 0 var(--space-5);
}
.marketplace-back-btn svg { width: 16px; height: 16px; }

.marketplace-detail-head {
  display: flex;
  align-items: flex-start;
  justify-content: space-between;
  gap: var(--space-3);
}

.marketplace-detail-name {
  font-family: var(--font-display);
  font-size: var(--size-title-2);
  line-height: var(--leading-title-2);
  letter-spacing: var(--tracking-title-2);
  font-weight: var(--weight-semibold);
  margin: 0 0 var(--space-1);
}

.marketplace-detail-category {
  font-size: var(--size-footnote);
  line-height: var(--leading-footnote);
  font-weight: var(--weight-semibold);
  color: var(--text-secondary);
  margin: 0 0 var(--space-3);
}

.marketplace-detail-meta {
  display: flex;
  flex-wrap: wrap;
  gap: var(--space-1) var(--space-3);
  font-size: var(--size-footnote);
  line-height: var(--leading-footnote);
  font-variant-numeric: tabular-nums;
  color: var(--text-dim);
  margin: 0 0 var(--space-3);
}

/* --------------------------------------------------------------------
   Sterne-Bewertung -- Aggregat immer sichtbar, die 1-5-Eingabe nur mit
   aktiver Library (renderDetail() in marketplace.js).
   -------------------------------------------------------------------- */
.marketplace-detail-rating {
  margin: 0 0 var(--space-4);
}
.marketplace-detail-rating-average {
  margin: 0 0 var(--space-1);
  font-size: var(--size-callout);
  line-height: var(--leading-callout);
  font-variant-numeric: tabular-nums;
  color: var(--text-secondary);
}
.marketplace-star-input {
  display: inline-flex;
  gap: 2px;
}
.marketplace-star-input button {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  min-width: 28px;
  min-height: 28px;
  background: none;
  border: none;
  border-radius: var(--radius-s);
  padding: 2px;
  cursor: pointer;
  color: var(--text-dim);
  transition: color var(--dur-fast) var(--ease), transform var(--dur-press) var(--ease);
}
.marketplace-star-input button svg { width: 20px; height: 20px; }
.marketplace-star-input button:hover { color: var(--text-secondary); }
.marketplace-star-input button:active { transform: scale(var(--press-scale)); }
.marketplace-star-input button:focus-visible {
  outline: var(--focus-ring-width) solid var(--focus-ring);
  outline-offset: 0;
}
.marketplace-star-input button.is-filled,
.marketplace-star-input button.is-filled svg { color: var(--accent-yellow); fill: var(--accent-yellow); }
.marketplace-detail-rating-hint {
  color: var(--text-dim);
  font-size: var(--size-footnote);
  line-height: var(--leading-footnote);
  margin: var(--space-1) 0 0;
}

.marketplace-detail-description {
  color: var(--text-secondary);
  font-size: var(--size-body);
  line-height: var(--leading-body);
  letter-spacing: var(--tracking-body);
  max-width: 68ch;
  margin: 0 0 var(--space-4);
}

.marketplace-detail-section {
  margin: 0 0 var(--space-5);
}
/* Abschnittskopf über einer Liste: callout 600 in Satzschreibung, wie die
   Gruppenköpfe der macOS-Systemeinstellungen (DESIGNRICHTUNG 2.4). */
.marketplace-detail-subheading {
  font-family: var(--font-text);
  font-size: var(--size-callout);
  line-height: var(--leading-callout);
  font-weight: var(--weight-semibold);
  color: var(--text-secondary);
  margin: 0 0 var(--space-2);
}
.marketplace-detail-inline-empty {
  margin: 0;
  padding: var(--space-2) 0;
  text-align: left;
}
/* Gruppierte Liste: ein Container, eingerückte Haarlinien statt einer Box
   je Zeile (DESIGNRICHTUNG 2.5, Listen). */
.marketplace-preset-list {
  list-style: none;
  margin: 0;
  padding: 0;
  max-width: 40rem;
  background: var(--fill-1);
  border-radius: var(--radius-s);
  overflow: hidden;
}
.marketplace-preset-list:empty { display: none; }
.marketplace-preset-list li {
  position: relative;
  font-size: var(--size-callout);
  line-height: var(--leading-callout);
  color: var(--text-primary);
  padding: var(--space-2) var(--space-3);
}
.marketplace-preset-list li + li::before {
  content: "";
  position: absolute;
  top: 0;
  left: var(--space-3);
  right: 0;
  height: var(--border-width);
  background: var(--separator);
}

/* Demo-Player: natives <audio controls>. */
.marketplace-demo-track {
  margin: 0 0 var(--space-2);
}
.marketplace-demo-track:last-child { margin-bottom: 0; }
.marketplace-demo-track-label {
  display: block;
  font-size: var(--size-footnote);
  line-height: var(--leading-footnote);
  color: var(--text-dim);
  margin: 0 0 var(--space-1);
}
.marketplace-demo-track audio {
  width: 100%;
  max-width: 40rem;
  height: 36px;
}

.marketplace-detail-actions {
  display: flex;
  flex-wrap: wrap;
  gap: var(--space-2);
  margin-bottom: var(--space-2);
}
.marketplace-insert-feedback:not(:empty) {
  font-size: var(--size-footnote);
  line-height: var(--leading-footnote);
  color: var(--text-dim);
  margin-top: var(--space-1);
}

/* ==========================================================================
   AP-ML L9 (2026-10-13): Abo-/User-Bereiche, Stufen-Badges, Bundles als
   <details>, Einreichen und Melden. Alles wird per JS eingefügt
   (marketplace.js), die Golden-Vorlage bleibt unverändert. Farben nur über
   Token. Kontrast der Badges (--fill-2 auf einer --fill-1-Karte über
   --panel-elevated): --warning 5.7:1, --success 4.7:1, --text-secondary
   5.0:1. --danger erreicht dort nur 3.4:1 und färbt deshalb nur Rand oder
   Symbol, nie Badge-Text.
   ========================================================================== */

/* -- Bereichsschalter: Segmentschalter wie .settings-nav, aber aus zwei
      Radioknöpfen (Pfeiltasten wechseln, Screenreader sagt „1 von 2“). -- */
.marketplace-section-switch {
  display: inline-flex;
  flex-wrap: wrap;
  gap: 2px;
  margin: var(--space-3) 0 0;
  padding: 2px;
  border: 0;
  border-radius: var(--radius-s);
  background: var(--fill-1);
  max-width: 100%;
  min-width: 0;
}
.marketplace-section-option {
  position: relative;
  display: inline-flex;
}
/* Radio sichtbar versteckt, aber fokussierbar und klickbar über das Label. */
.marketplace-section-option input {
  position: absolute;
  inset: 0;
  margin: 0;
  opacity: 0;
  cursor: pointer;
}
.marketplace-section-option-text {
  display: inline-flex;
  align-items: center;
  min-height: var(--control-h-s);
  padding: 0 var(--space-3);
  border-radius: calc(var(--radius-s) - 2px);
  font-size: var(--size-callout);
  line-height: var(--leading-callout);
  font-weight: var(--weight-medium);
  color: var(--text-secondary);
  transition: background var(--dur-fast) var(--ease), color var(--dur-fast) var(--ease);
}
.marketplace-section-option:hover .marketplace-section-option-text { color: var(--text-primary); }
.marketplace-section-option input:checked + .marketplace-section-option-text {
  background: var(--surface-3);
  color: var(--text-primary);
  box-shadow: var(--shadow-s);
}
.marketplace-section-option input:focus-visible + .marketplace-section-option-text {
  outline: var(--focus-ring-width) solid var(--focus-ring);
  outline-offset: var(--focus-ring-offset);
}

/* -- Nutzer-Bereich: Einreichen und „Meine Einreichungen“ ---------------- */
.marketplace-user-panel {
  margin: var(--space-3) 0 0;
  padding: var(--space-4);
  border-radius: var(--radius-m);
  background: var(--fill-1);
}
.marketplace-user-panel[hidden] { display: none; }
.marketplace-user-panel-head {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  justify-content: space-between;
  gap: var(--space-3);
}
.marketplace-user-panel-text { min-width: 0; flex: 1 1 18rem; }
.marketplace-user-panel-title {
  margin: 0 0 var(--space-1);
  font-family: var(--font-text);
  font-size: var(--size-headline);
  line-height: var(--leading-headline);
  font-weight: var(--weight-semibold);
}
.marketplace-user-panel-desc {
  margin: 0;
  font-size: var(--size-footnote);
  line-height: var(--leading-footnote);
  color: var(--text-secondary);
}
.marketplace-mine {
  margin-top: var(--space-3);
}
.marketplace-mine-summary {
  display: inline-flex;
  align-items: center;
  min-height: var(--control-h-s);
  border-radius: var(--radius-s);
  font-size: var(--size-callout);
  font-weight: var(--weight-semibold);
  color: var(--text-primary);
  cursor: pointer;
}
.marketplace-mine-summary:focus-visible {
  outline: var(--focus-ring-width) solid var(--focus-ring);
  outline-offset: var(--focus-ring-offset);
}
.marketplace-mine-status {
  margin: var(--space-2) 0 0;
  padding: var(--space-2) 0;
  text-align: left;
}
.marketplace-mine-list {
  list-style: none;
  margin: var(--space-2) 0 0;
  padding: 0;
}
.marketplace-mine-item {
  display: flex;
  flex-wrap: wrap;
  align-items: flex-start;
  justify-content: space-between;
  gap: var(--space-2) var(--space-3);
  padding: var(--space-3) 0;
  border-top: var(--border-width) solid var(--separator);
}
.marketplace-mine-main { min-width: 0; flex: 1 1 16rem; }
.marketplace-mine-name-row {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: var(--space-2);
}
.marketplace-mine-name {
  font-weight: var(--weight-semibold);
  overflow-wrap: anywhere;
}
.marketplace-mine-meta,
.marketplace-mine-note {
  margin: var(--space-1) 0 0;
  font-size: var(--size-footnote);
  line-height: var(--leading-footnote);
  color: var(--text-secondary);
  overflow-wrap: anywhere;
}
.marketplace-status { margin: 0; }
.marketplace-status-pending { color: var(--text-primary); background: var(--fill-2); }
.marketplace-status-approved { color: var(--success); background: var(--fill-2); }
.marketplace-status-rejected { color: var(--text-primary); background: var(--fill-2); box-shadow: inset 0 0 0 var(--border-width) var(--danger); }
.marketplace-status-withdrawn,
.marketplace-status-unknown { color: var(--text-secondary); background: var(--fill-2); }

/* -- Stufen- und Sperr-Badges ------------------------------------------- */
.marketplace-badge-free {
  color: var(--success);
  background: var(--fill-2);
}
.marketplace-badge-tier {
  color: var(--accent);
  background: var(--accent-soft);
}
.marketplace-badge-lock {
  display: inline-flex;
  align-items: center;
  gap: var(--space-1);
  color: var(--warning);
  background: var(--fill-2);
}
.marketplace-badge-icon { display: inline-flex; }
.marketplace-badge-icon svg { width: 0.9em; height: 0.9em; }
.marketplace-detail-meta .badge { margin: 0; }

/* Gesperrte Karte bleibt sichtbar und bedienbar, tritt aber zurück. */
.marketplace-card-item.is-locked .marketplace-card { border-style: dashed; }
.marketplace-card-access-hint {
  font-size: var(--size-caption);
  line-height: var(--leading-caption);
  color: var(--text-secondary);
}
.marketplace-card-lock-note {
  margin: 0;
  padding: 0 var(--space-1);
  font-size: var(--size-footnote);
  line-height: var(--leading-footnote);
  color: var(--text-secondary);
  overflow-wrap: anywhere;
}
.marketplace-access-note {
  margin: 0 0 var(--space-3);
  padding: var(--space-2) var(--space-3);
  border-radius: var(--radius-s);
  background: var(--fill-1);
  font-size: var(--size-callout);
  line-height: var(--leading-callout);
  color: var(--text-secondary);
  max-width: 68ch;
}
.marketplace-access-note.is-locked { box-shadow: inset 3px 0 0 var(--warning); }
.marketplace-access-note.is-unknown { box-shadow: inset 3px 0 0 var(--border-strong); }
.marketplace-detail-access[hidden] { display: none; }
.marketplace-upgrade-link {
  color: var(--accent);
  font-weight: var(--weight-semibold);
  text-decoration: underline;
  text-underline-offset: 2px;
  border-radius: var(--radius-s);
}
.marketplace-upgrade-link:focus-visible,
.marketplace-upgrade-btn:focus-visible {
  outline: var(--focus-ring-width) solid var(--focus-ring);
  outline-offset: var(--focus-ring-offset);
}
.marketplace-upgrade-btn { text-decoration: none; }

/* -- Bundles als aufklappbare Liste ------------------------------------- */
.marketplace-grid.marketplace-bundle-list { grid-template-columns: minmax(0, 1fr); }
.marketplace-bundle {
  background: var(--fill-1);
  border: var(--border-width) solid var(--glass-border);
  border-radius: var(--radius-m);
  transition: border-color var(--dur-fast) var(--ease);
}
.marketplace-bundle:hover,
.marketplace-bundle[open] { border-color: var(--glass-border-hover); }
.marketplace-bundle-item.is-locked .marketplace-bundle { border-style: dashed; }
.marketplace-bundle-summary {
  display: grid;
  grid-template-columns: auto minmax(0, 1fr) auto;
  align-items: center;
  gap: var(--space-3);
  padding: var(--space-3) var(--space-4);
  border-radius: var(--radius-m);
  list-style: none;
  cursor: pointer;
}
.marketplace-bundle-summary::-webkit-details-marker { display: none; }
.marketplace-bundle-summary:focus-visible {
  outline: var(--focus-ring-width) solid var(--focus-ring);
  outline-offset: var(--focus-ring-offset);
}
.marketplace-bundle-cover {
  display: block;
  width: 4rem;
  height: 4rem;
  border-radius: var(--radius-s);
  overflow: hidden;
  background: var(--fill-2);
}
.marketplace-bundle-cover img {
  display: block;
  width: 100%;
  height: 100%;
  object-fit: cover;
}
.marketplace-bundle-text {
  display: flex;
  flex-direction: column;
  gap: var(--space-1);
  min-width: 0;
}
.marketplace-bundle-text .marketplace-bundle-count { margin: 0; padding: 0; }
/* Pfeil aus zwei Rändern: zeigt nach unten, aufgeklappt nach oben. */
.marketplace-bundle-chevron {
  width: 0.55rem;
  height: 0.55rem;
  margin: 0 var(--space-1);
  border-right: 2px solid var(--text-secondary);
  border-bottom: 2px solid var(--text-secondary);
  transform: translateY(-25%) rotate(45deg);
  transition: transform var(--dur-fast) var(--ease);
}
.marketplace-bundle[open] .marketplace-bundle-chevron { transform: translateY(25%) rotate(225deg); }
.marketplace-bundle-body {
  padding: 0 var(--space-4) var(--space-4);
}
.marketplace-bundle-status {
  margin: 0;
  padding: var(--space-2) 0;
  text-align: left;
}
.marketplace-bundle-plugins {
  list-style: none;
  margin: 0;
  padding: 0;
}
.marketplace-bundle-plugin + .marketplace-bundle-plugin {
  border-top: var(--border-width) solid var(--separator);
}
.marketplace-bundle-plugin-btn {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: var(--space-1) var(--space-3);
  width: 100%;
  min-height: var(--control-h-m);
  padding: var(--space-2) var(--space-2);
  border: 0;
  border-radius: var(--radius-s);
  background: none;
  color: var(--text-primary);
  font: inherit;
  text-align: left;
  cursor: pointer;
  transition: background var(--dur-fast) var(--ease);
}
.marketplace-bundle-plugin-btn:hover { background: var(--fill-1); }
.marketplace-bundle-plugin-btn:active { background: var(--fill-2); }
.marketplace-bundle-plugin-btn:focus-visible {
  outline: var(--focus-ring-width) solid var(--focus-ring);
  outline-offset: 0;
}
.marketplace-bundle-plugin-name {
  flex: 1 1 10rem;
  min-width: 0;
  font-weight: var(--weight-medium);
  overflow-wrap: anywhere;
}
.marketplace-bundle-plugin-version {
  font-size: var(--size-footnote);
  line-height: var(--leading-footnote);
  font-variant-numeric: tabular-nums;
  color: var(--text-secondary);
}
.marketplace-bundle-actions {
  display: flex;
  justify-content: flex-end;
  margin-top: var(--space-3);
}

/* -- Unterdialoge (Einreichen, Melden): natives <dialog> im Top Layer --- */
.marketplace-subdialog {
  width: min(36rem, calc(100vw - 2 * var(--space-4)));
  max-width: none;
  max-height: calc(100dvh - 2 * var(--space-4));
  margin: auto;
  padding: 0;
  overflow: hidden;
  border: var(--border-width) solid var(--separator);
  border-radius: var(--radius-l);
  background: var(--panel-elevated);
  color: var(--text-primary);
  font-family: var(--font-text);
  box-shadow: var(--material-edge), var(--shadow-l);
}
.marketplace-subdialog[open] { animation: nm-dialog-in var(--dur-spring) var(--spring) backwards; }
.marketplace-subdialog::backdrop { background: var(--scrim); }
/* Der Innenteil scrollt, nicht das <dialog>: ein Klick auf dessen
   Bildlaufleiste zählte sonst als Klick daneben und schlösse den Dialog. */
.marketplace-subdialog-inner {
  box-sizing: border-box;
  max-height: calc(100dvh - 2 * var(--space-4));
  overflow-y: auto;
  padding: var(--space-6);
}
.marketplace-subdialog-head {
  display: flex;
  align-items: flex-start;
  justify-content: space-between;
  gap: var(--space-3);
  margin-bottom: var(--space-3);
}
.marketplace-subdialog-title {
  margin: 0;
  font-family: var(--font-text);
  font-size: var(--size-title-3);
  line-height: var(--leading-title-3);
  font-weight: var(--weight-semibold);
}
.marketplace-subdialog-close { flex-shrink: 0; }
.marketplace-subdialog-close svg { width: 18px; height: 18px; }
.marketplace-subdialog-intro {
  margin: 0 0 var(--space-4);
  font-size: var(--size-callout);
  line-height: var(--leading-callout);
  color: var(--text-secondary);
  overflow-wrap: anywhere;
}
.marketplace-field { margin: 0 0 var(--space-4); }
.marketplace-field-label {
  display: block;
  margin: 0 0 var(--space-1);
  font-size: var(--size-footnote);
  line-height: var(--leading-footnote);
  font-weight: var(--weight-semibold);
  color: var(--text-secondary);
}
.marketplace-field .settings-input { width: 100%; box-sizing: border-box; }
.marketplace-report-comment { resize: vertical; min-height: 6rem; font: inherit; }
.marketplace-field-hint {
  margin: var(--space-1) 0 0;
  font-size: var(--size-footnote);
  line-height: var(--leading-footnote);
  color: var(--text-secondary);
}
.marketplace-file-input {
  display: block;
  width: 100%;
  font: inherit;
  font-size: var(--size-callout);
  color: var(--text-secondary);
  border-radius: var(--radius-s);
}
.marketplace-file-input::file-selector-button {
  margin-right: var(--space-3);
  min-height: var(--control-h-m);
  padding: 0 var(--space-4);
  border: 0;
  border-radius: var(--radius-s);
  background: var(--fill-2);
  color: var(--text-primary);
  font: inherit;
  cursor: pointer;
}
.marketplace-file-input::file-selector-button:hover { background: var(--fill-3); }
.marketplace-file-input:focus-visible {
  outline: var(--focus-ring-width) solid var(--focus-ring);
  outline-offset: var(--focus-ring-offset);
}
.marketplace-terms-title {
  margin: 0 0 var(--space-2);
  font-family: var(--font-text);
  font-size: var(--size-callout);
  line-height: var(--leading-callout);
  font-weight: var(--weight-semibold);
  color: var(--text-secondary);
}
.marketplace-terms {
  max-height: 12rem;
  overflow-y: auto;
  margin: 0 0 var(--space-3);
  padding: var(--space-3) var(--space-4);
  border-radius: var(--radius-s);
  background: var(--fill-1);
  font-size: var(--size-footnote);
  line-height: var(--leading-footnote);
  color: var(--text-secondary);
}
.marketplace-terms:focus-visible {
  outline: var(--focus-ring-width) solid var(--focus-ring);
  outline-offset: var(--focus-ring-offset);
}
.marketplace-terms-list { margin: 0; padding-left: var(--space-5); }
.marketplace-terms-list li + li { margin-top: var(--space-2); }
.marketplace-agree-row { margin: 0 0 var(--space-4); align-items: flex-start; }
/* Lizenz in der Detailansicht (2026-10-18, marketplace.js: renderDetailLicense):
   Kasten wie die Upload-Bedingungen, Zeilenumbrüche des Lizenztexts bleiben. */
.marketplace-detail-license { margin: 0 0 var(--space-3); max-width: 68ch; }
.marketplace-detail-license[hidden] { display: none; }
.marketplace-license-text { white-space: pre-wrap; }
/* Angekündigte Stufenerhöhung (§ 327r BGB, 2026-10-18, marketplace.js:
   renderDetailTierChange): nur für Konten, die noch die alte Stufe behalten. */
.marketplace-tier-change {
  margin: 0 0 var(--space-3);
  max-width: 68ch;
  padding: var(--space-2) var(--space-3);
  font-size: var(--size-footnote);
  line-height: var(--leading-footnote);
  color: var(--text-primary);
  background: var(--fill-2);
  border-radius: var(--radius-s);
}
.marketplace-tier-change[hidden] { display: none; }
.marketplace-upload-progress {
  display: grid;
  grid-template-columns: auto minmax(0, 1fr) auto;
  align-items: center;
  gap: var(--space-3);
  margin: 0 0 var(--space-3);
  font-size: var(--size-footnote);
  color: var(--text-secondary);
}
.marketplace-upload-progress[hidden] { display: none; }
.marketplace-upload-progress progress {
  width: 100%;
  height: var(--space-2);
  accent-color: var(--accent-fill);
}
.marketplace-upload-progress-text { font-variant-numeric: tabular-nums; }
.marketplace-upload-status:empty { display: none; }
.marketplace-form-error {
  margin: 0 0 var(--space-2);
  font-size: var(--size-callout);
  line-height: var(--leading-callout);
  color: var(--danger);
}
.marketplace-form-error[hidden] { display: none; }
.marketplace-form-errorbox {
  margin: 0 0 var(--space-4);
  padding: var(--space-3);
  border-radius: var(--radius-s);
  background: var(--fill-1);
}
.marketplace-form-errorbox[hidden] { display: none; }
.marketplace-form-errorbox > :last-child { margin-bottom: 0; }
.marketplace-findings {
  list-style: none;
  margin: var(--space-2) 0 0;
  padding: 0;
  font-size: var(--size-footnote);
  line-height: var(--leading-footnote);
  color: var(--text-secondary);
}
.marketplace-finding {
  display: flex;
  flex-wrap: wrap;
  gap: 0 var(--space-2);
  padding: var(--space-1) 0;
  overflow-wrap: anywhere;
}
.marketplace-finding-severity { font-weight: var(--weight-semibold); }
.marketplace-finding.is-error .marketplace-finding-severity { color: var(--danger); }
.marketplace-finding.is-warning .marketplace-finding-severity { color: var(--warning); }
.marketplace-finding-code { font-family: var(--font-mono); color: var(--text-secondary); }
.marketplace-subdialog-actions { margin-top: var(--space-2); }

/* L9 auf schmalen Fenstern: Schalter über die volle Breite, Bundle-Cover
   kleiner, Dialoge mit weniger Rand. */
@media (max-width: 640px) {
  .marketplace-section-switch { display: flex; width: 100%; }
  .marketplace-section-option { flex: 1 1 0; }
  .marketplace-section-option-text { flex: 1 1 auto; justify-content: center; text-align: center; }
  .marketplace-user-panel { padding: var(--space-3); }
  .marketplace-submit-btn { width: 100%; justify-content: center; }
  .marketplace-bundle-summary { padding: var(--space-3); gap: var(--space-2); }
  .marketplace-bundle-cover { width: 3rem; height: 3rem; }
  .marketplace-bundle-body { padding: 0 var(--space-3) var(--space-3); }
  .marketplace-subdialog-inner { padding: var(--space-4); }
  .marketplace-subdialog-actions > * { flex: 1 1 auto; }
}

@media (pointer: coarse) {
  .marketplace-section-option-text,
  .marketplace-mine-summary { min-height: var(--hit-min); }
  .marketplace-bundle-plugin-btn { min-height: var(--hit-min); }
}

/* Schmale Fenster: Dialog fast randlos, Filter untereinander. */
@media (max-width: 640px) {
  .marketplace-modal-dialog {
    height: 94vh;
    height: 94dvh;
    max-height: 94dvh;
    padding: var(--space-4) var(--space-3);
  }
  .marketplace-search-input {
    width: 100%;
  }
  /* Vier Zeilen Filter würden mitlaufend ein Viertel des Bildschirms
     belegen; hier scrollen sie mit. */
  .marketplace-modal-body { scroll-padding-top: 0; }
  .marketplace-toolbar {
    position: static;
    flex-direction: column;
    align-items: stretch;
  }
  .marketplace-category-label select,
  .marketplace-sort-label select {
    width: 100%;
  }
  .marketplace-detail-head {
    flex-direction: column;
  }
}

/* Touch: Trefferflächen auf das Mindestmaß. */
@media (pointer: coarse) {
  .marketplace-card-favorite-btn { width: var(--hit-min); height: var(--hit-min); top: var(--space-1); right: var(--space-1); }
  .marketplace-card-item:has(.marketplace-card-favorite-btn:not([hidden])) .marketplace-card-head {
    padding-right: var(--hit-min);
  }
  .marketplace-star-input button { min-width: var(--hit-min); min-height: var(--hit-min); }
}

/* Handy hochkant: Sicherheitsabstände, 16px-Eingaben, kein Seitwärtsscrollen */
@media (max-width: 640px) {
  .marketplace-modal-dialog { width: 100%; max-width: 100%; border-radius: 20px 20px 0 0; padding-bottom: max(var(--space-3), env(safe-area-inset-bottom)); overflow-x: hidden; }
  .marketplace-modal-dialog input, .marketplace-modal-dialog select, .marketplace-modal-dialog textarea { font-size: 16px; min-height: 44px; }
  .marketplace-modal-body { overflow-x: hidden; overflow-wrap: anywhere; }
  .marketplace-subdialog-inner { padding-bottom: max(var(--space-4), env(safe-area-inset-bottom)); }
}
