/* TCG Keeper — gemeinsames Stylesheet, Teil 3 von 8: Seitenlayout, Eingabefelder, Seitenleiste, Ansichts-Umschalter, Karten- und Setkacheln (Standard/Groß/Kompakt/Liste/Serien), Druckliste.
   Bis 09.10.2026 eine einzige Datei app.css; aufgeteilt ohne inhaltliche Änderung.
   Alle Teile werden in includes/layout_top.php in dieser Reihenfolge eingebunden —
   die Reihenfolge bestimmt die Kaskade, Regeln nicht zwischen Teilen verschieben. */
/* Karten/Sets/Sammlung use the full screen width (like the offline
   version) so their tile grids can lay out more/bigger columns instead of
   being capped at .page's normal reading-width. */
.page-wide{ max-width:none; }
/* "Rand"-Modus (2. Rückmelderunde): Knopf neben der Hell/Dunkel-Umschaltung
   (siehe #layoutToggleBtn in layout_top.php) setzt data-layout="boxed" auf
   <html> — dann bekommen auch die sonst randlosen .page-wide-Seiten wieder
   eine Höchstbreite mit Rand links/rechts, statt die volle Bildschirmbreite
   auszunutzen. Regel MUSS nach .page-wide stehen, um deren max-width:none
   zuverlässig zu überschreiben (gleiche Spezifität, spätere Regel gewinnt). */
html[data-layout="boxed"] .page-wide{ max-width:var(--page-maxwidth-boxed); margin:0 auto; }
.page h1{ font-size:22px; margin:0 0 4px; }
.page-sub{ color:var(--ink-faint); font-size:13px; margin:0 0 20px; }

.btn{
  display:inline-flex; align-items:center; gap:6px; border:1px solid var(--line);
  background:var(--paper-raised); color:var(--ink); padding:calc(9px * var(--ds, 1)) calc(14px * var(--ds, 1)); border-radius:calc(9px * var(--rs, 1));
  font-size:13.5px; font-weight:500; cursor:pointer; text-decoration:none;
}
.btn:hover{ border-color:var(--accent); color:var(--accent); }
.btn.primary{ background:var(--accent); border-color:var(--accent); color:var(--accent-ink); }
.btn.primary:hover{ opacity:.92; color:var(--accent-ink); }
.btn.danger{ color:var(--danger); border-color:var(--danger); }
.btn.small{ padding:calc(5px * var(--ds, 1)) calc(10px * var(--ds, 1)); font-size:12px; }

.card-box{
  background:var(--paper-raised); border:1px solid var(--line); border-radius:calc(14px * var(--rs, 1));
  padding:calc(24px * var(--ds, 1)); box-shadow:var(--shadow);
}
.form-field{ display:flex; flex-direction:column; gap:6px; margin-bottom:14px; }
.form-field label{ font-size:11px; font-weight:700; text-transform:uppercase; letter-spacing:.05em; color:var(--ink-faint); }
.form-input, .form-textarea, .form-select{
  width:100%; border:1px solid var(--line); background:var(--paper); color:var(--ink);
  padding:calc(9px * var(--ds, 1)) calc(11px * var(--ds, 1)); border-radius:calc(8px * var(--rs, 1)); font-size:14px; font-family:inherit;
}
/* Eingabefelder (Name/Kartentyp/Energie-Typ/Sortierung) sollen dieselbe
   Höhe wie die Knöpfe in derselben Box haben (siehe .btn/.sidebar-actions
   .btn/.filter-rail .field .btn — alle mit min-height:40px). Textarea ist
   davon ausgenommen: die legt ihre Höhe über "rows" fest, min-height würde
   dort nur unnötig Platz verschwenden. */
.form-input, .form-select{ min-height:40px; }
.form-input:focus, .form-textarea:focus, .form-select:focus{ outline:2px solid var(--accent); outline-offset:1px; }

/* Beschreibungs-/Notizenfelder mit Schriftformatierung (2. Rückmelderunde,
   siehe assets/richtext.js/includes/richtext.php). Ohne JavaScript bleibt
   das echte <textarea> einfach sichtbar (ganz normales Textfeld); erst
   richtext.js blendet es aus (hidden-Attribut) und zeigt stattdessen die
   Werkzeugleiste + das editierbare Feld. */
.richtext-field textarea[hidden]{ display:none; }
.richtext-toolbar{ display:none; gap:4px; margin-bottom:6px; }
.richtext-active .richtext-toolbar{ display:flex; }
.richtext-toolbar button{
  width:28px; height:28px; border:1px solid var(--line); border-radius:6px;
  background:var(--paper-raised); color:var(--ink-soft); cursor:pointer;
  font-size:13px; line-height:1; display:flex; align-items:center; justify-content:center;
}
.richtext-toolbar button:hover{ border-color:var(--accent); color:var(--accent); }
.richtext-editable{
  display:none; width:100%; min-height:60px; border:1px solid var(--line);
  background:var(--paper); color:var(--ink); border-radius:8px; padding:9px 11px;
  font-size:14px; font-family:inherit; line-height:1.5;
}
.richtext-active .richtext-editable{ display:block; }
.richtext-editable:focus{ outline:2px solid var(--accent); outline-offset:1px; }
.richtext-editable ul, .richtext-editable ol{ margin:4px 0; padding-left:22px; }
/* contenteditable kennt kein natives placeholder-Attribut — data-placeholder
   (siehe richtext_field()) übernimmt dessen Rolle rein per CSS. */
.richtext-editable:empty::before{ content:attr(data-placeholder); color:var(--ink-faint); pointer-events:none; }
/* Weiterlesen-Punkt (Mario, 27.09.2026, Set-Beschreibung): Knöpfe in der
   Werkzeugleiste (nur bei richtext_field(..., $readMore = true)) und die
   Darstellung des gesetzten Punkts (<hr>) im Editor als gestrichelte Linie
   mit Beschriftung. Qualifiziert mit .richtext-toolbar bzw.
   .richtext-editable, damit die Regeln sicher vor der allgemeinen
   .richtext-toolbar button-Regel (feste 28px Breite) gewinnen. */
.richtext-toolbar .richtext-sep{ width:1px; align-self:stretch; background:var(--line); margin:2px 4px; }
.richtext-toolbar button.richtext-btn-wide{ width:auto; padding:0 10px; font-size:12.5px; gap:4px; white-space:nowrap; }
.richtext-toolbar button.richtext-btn-wide.is-set{ border-color:var(--accent); color:var(--accent); }
.richtext-toolbar button[hidden]{ display:none; }
.richtext-editable hr{
  position:relative; overflow:visible; height:0; margin:14px 0 12px;
  border:0; border-top:2px dashed var(--accent); opacity:.85;
}
.richtext-editable hr::after{
  content:"Weiterlesen"; position:absolute; left:50%; top:-10px; transform:translateX(-50%);
  padding:0 8px; background:var(--paper); color:var(--accent);
  font-size:11px; line-height:18px; font-family:var(--font-mono, inherit); letter-spacing:.03em;
  pointer-events:none;
}
/* overflow-wrap:anywhere behebt einen Layoutfehler auf der
   Seitenanpassung-Seite: Standard-/Beispielwerte wie
   url("images/back/light_pokeback_firstpage.jpg") enthalten keine
   Leerzeichen/Trennstellen, an denen der Browser normalerweise umbricht —
   ohne diese Regel liefen sie deshalb ungebrochen über die Spaltenbreite
   hinaus und überlagerten die Hinweistexte der Nachbarspalte (Mario-
   Feedback, Hintergrundbilder-Anmeldeseite-Bereich). */
.form-hint{ font-size:12px; color:var(--ink-faint); overflow-wrap:anywhere; }
.form-grid-2{ display:grid; grid-template-columns:repeat(auto-fit,minmax(160px,1fr)); gap:0 14px; }

/* Left sidebar + main content used by Kartensuche/Sets/Sammlung: fixed to
   the left on desktop (sticky, so it scrolls with you but never runs
   off past the content below it), stacked back on top on mobile. */
.page-with-sidebar{ display:flex; align-items:flex-start; gap:24px; }
.page-sidebar{ flex:0 0 300px; display:flex; flex-direction:column; gap:20px; position:sticky; top:76px; }
.page-main{ flex:1; min-width:0; }
/* Schwebender "Filter"-Button: nur auf dem Handy aktiv (siehe @media
   unten) — am Desktop bleibt er unsichtbar/wirkungslos, die Filterbox ist
   dort ohnehin immer sichtbar (siehe .page-sidebar oben, dort sticky). */
.filter-fab{ display:none; }
@media (max-width:900px){
  .page-with-sidebar{ display:block; }
  .page-sidebar{ position:static; width:auto; margin-bottom:20px; }

  /* Schwebender "Filter"-Button (nur Handy): erscheint erst, sobald die
     Filter-/Sortierbox beim Scrollen nach unten oben aus dem Bildschirm
     gelaufen ist (siehe assets/filterbox.js) — ein Klick öffnet eine
     Lightbox mit genau dieser Box statt sie im Layout zu fixieren. */
  .filter-fab{
    display:flex; align-items:center; gap:6px;
    position:fixed; left:50%; bottom:18px; z-index:40;
    padding:11px 22px; border-radius:999px; border:none;
    background:var(--accent); color:var(--accent-ink); font-weight:500; font-size:14px;
    box-shadow:var(--shadow); cursor:pointer;
    opacity:0; pointer-events:none; transform:translate(-50%,10px);
    transition:opacity .22s ease, transform .22s ease;
  }
  .filter-fab.show{ opacity:1; pointer-events:auto; transform:translate(-50%,0); }

  /* Kartendetailseite: Bild → Name/Grundwerte/Details → "Zur Sammlung
     hinzufügen" → Preise → Notizen, statt der Desktop-Reihenfolge
     Bild+Sammlung(Sidebar)/Rest(Hauptspalte). display:contents löst die
     beiden Spalten-Wrapper optisch auf, sodass alle Kästen als direkte
     Flex-Kinder von .card-detail-layout selbst per "order" neu sortiert
     werden können. align-items:stretch überschreibt hier bewusst das
     align-items:flex-start der allgemeinen .page-with-sidebar-Basisregel
     (oben, für die Desktop-Zweispaltigkeit gedacht) — sonst richtet sich
     jeder einzelne Kasten in dieser Spalten-Flexbox nur an seiner eigenen
     Inhaltsbreite aus, statt die volle Breite auszufüllen, wodurch die
     Kästen sichtbar unterschiedlich breit wirken. */
  .page-with-sidebar.card-detail-layout{ display:flex; flex-direction:column; align-items:stretch; }
  .page-with-sidebar.card-detail-layout > .page-sidebar,
  .page-with-sidebar.card-detail-layout > .page-main{ display:contents; }
  .card-detail-layout .card-detail-imgbox{ order:1; }
  .card-detail-layout .card-detail-name{ order:2; }
  .card-detail-layout .card-detail-meta{ order:3; }
  .card-detail-layout .card-detail-badges{ order:4; }
  .card-detail-layout .flavor{ order:5; }
  .card-detail-layout .card-detail-databox{ order:6; }
  .card-detail-layout .card-detail-variantbox{ order:7; }
  .card-detail-layout .card-detail-pricebox{ order:8; }
  .card-detail-layout .card-detail-notesbox{ order:9; }
}

.error-box{ background:var(--danger-soft); color:var(--danger); border-radius:10px; padding:12px 14px; font-size:13.5px; margin-bottom:16px; }
.flash{ border-radius:calc(10px * var(--rs, 1)); padding:12px 14px; font-size:13.5px; margin-bottom:16px; }
.flash.info{ background:var(--accent-soft); color:var(--accent); }
.flash.success{ background:var(--good-soft); color:var(--good); }
.flash.error{ background:var(--danger-soft); color:var(--danger); }

.stat-row{ display:grid; grid-template-columns:repeat(auto-fit,minmax(150px,1fr)); gap:14px; margin-bottom:24px; }
.stat-tile{ background:var(--paper-raised); border:1px solid var(--line); border-radius:calc(12px * var(--rs, 1)); padding:calc(14px * var(--ds, 1)) calc(16px * var(--ds, 1)); box-shadow:var(--shadow); }
.stat-tile .num{ font-family:var(--font-mono); font-size:22px; font-weight:600; }
.stat-tile .lbl{ font-size:11.5px; color:var(--ink-faint); text-transform:uppercase; letter-spacing:.05em; margin-top:2px; }
/* Sammlung (mobil): die 5 Statistik-Kacheln sind auf schmalen Bildschirmen
   spürbar kleiner als am Desktop. Muss NACH den Basis-Regeln oben stehen —
   bei gleicher Spezifität gewinnt sonst die frühere @media-Regel nicht
   gegen die spätere unbedingte Basis-Regel (siehe Hinweis beim
   Hamburger-Menü weiter oben in dieser Datei). */
@media (max-width:640px){
  .stat-row{ gap:8px; margin-bottom:16px; }
  .stat-tile{ padding:9px 10px; }
  .stat-tile .num{ font-size:16px; }
  .stat-tile .lbl{ font-size:9.5px; margin-top:0; }
}

.toolbar{ display:flex; gap:10px; flex-wrap:wrap; margin-bottom:18px; align-items:center; }
.toolbar .form-input{ max-width:320px; }

/* Ansichts-Umschalter (Kartensuche/Sets/Sammlung): a small button group,
   wired up by assets/viewmode.js, that toggles a "view-mode-*" class on its
   [data-view-options] container — every .grid/.card-tile below it restyles
   itself via the modifiers further down, no separate markup per mode. The
   chosen mode is remembered (localStorage) across all three pages; a page
   that doesn't support the stored mode (e.g. "sets" outside Sammlung) falls
   back to its own first option instead of breaking. */
.view-switch{ display:flex; gap:6px; flex-wrap:wrap; margin-bottom:16px; }
/* Die Umschalter-Knöpfe nutzten bisher zusätzlich .btn.small (kleinere
   Schrift/Polsterung als die übrigen Knöpfe in der Filter-/Aktionsbox) und
   teilten sich die Zeile nur nach ihrer eigenen Textbreite auf — dadurch
   wirkten sie kleiner und unterschiedlich breit im Vergleich zu "Filtern"
   und den Aktions-Knöpfen darunter. Drei Klassen (mehr als .btn.small mit
   zwei) sorgen dafür, dass diese Regel unabhängig von der Reihenfolge in
   der Datei gewinnt. flex:1 teilt die Zeile gleichmäßig auf alle Knöpfe auf. */
.view-switch-btn.btn.small{ flex:1 1 0; justify-content:center; padding:9px 14px; font-size:13.5px; min-height:40px; }
.view-switch-btn.active{ background:var(--accent); border-color:var(--accent); color:var(--accent-ink); }

/* Sammelt die "+ Eigenes Set anlegen" / "+ Eigene Karte anlegen" und
   "Set von TCGdex laden" / "Karte von TCGdex laden" Knöpfe unterhalb des
   Ansichts-Umschalters in der Filter-/Sortierbox (sets.php/cards.php) —
   vorher eigene .card-box-Kästen, seit Phase 16 hier eingegliedert und
   fixiert; siehe auch .lightbox-scrim/.lightbox-panel weiter unten für das
   "Set/Karte von TCGdex laden"-Formular, das jetzt in einer Lightbox statt
   fest in der Seitenleiste sitzt. */
.sidebar-actions{ display:flex; flex-direction:column; gap:8px; }
/* min-height statt nur width:100%, damit ein Knopf mit ausnahmsweise
   zweizeilig umbrechendem Text (z. B. "Gesammelte Karten ausblenden" bei
   einer breiteren System-Schrift als der Vorgabeschrift) trotzdem dieselbe
   Höhe wie die einzeiligen Knöpfe daneben behält, statt sichtbar höher zu
   wirken. */
.sidebar-actions .btn{ width:100%; justify-content:center; min-height:40px; }

/* Kartenkachelbreite "Mittel" (Mario, 19.09.2026 Folgerunde: "etwas
   vergrößern", dazu editierbar in der Seitenanpassung) — betrifft nur
   Kartenkacheln, NICHT die Set-Kacheln auf sets.php/sets_pocket.php: deren
   ".grid" trägt zusätzlich immer "box-order-group" und wird dadurch weiter
   unten (.grid.box-order-group) auf display:flex umgestellt, das
   grid-template-columns hier greift für sie nie. */
.grid{ display:grid; grid-template-columns:repeat(auto-fill,minmax(var(--cardtile-basis-medium,170px),1fr)); gap:16px; }
.card-tile{
  background:var(--paper-raised); border:1px solid var(--line); border-radius:calc(12px * var(--rs, 1));
  overflow:hidden; display:flex; flex-direction:column; text-decoration:none; color:inherit;
  transition:transform .16s ease, box-shadow .16s ease, border-color .16s ease, opacity .22s ease;
}
/* "Erhaben" (raised) hover effect, per Mario's request — applies to both
   card tiles (cards.php/set.php) and set tiles (sets.php, which carries
   both "card-tile" and "set-tile" classes on the same element). */
.card-tile:hover{ border-color:var(--accent); transform:translateY(calc(-3px * var(--hover-lift, 1))); box-shadow:var(--shadow); }
/* .card-tile.remote-only hatte hier vorher border-color:var(--danger) — seit
   dem 19.09.2026-Umbau übernimmt das Status-Lämpchen (.tile-status-dot
   weiter unten) diese Information differenzierter (grün/orange/rot statt
   nur "rot oder nicht"), ein zusätzlicher roter Kachelrand wäre doppelt
   gemoppelt. Die Klasse .remote-only selbst bleibt im Markup (steuert u. a.
   den Lightbox-Titel), nur diese eine Regel entfällt. */
/* Sanftes Einblenden + Anfügen beim Scrollen (Mario, 14./15.09.2026, siehe
   assets/scrollreveal.js + die Pre-Paint-Zeile in layout_top.php): nur
   aktiv, wenn <html> die Klasse "js-scrollreveal" trägt (progressive
   enhancement — ohne JS/IntersectionObserver oder bei
   "prefers-reduced-motion: reduce" bleibt alles wie bisher sofort
   sichtbar). Jede Kachel (Karten wie Sets, siehe Kommentar oben) startet
   unsichtbar und leicht nach unten versetzt und schiebt sich sanft nach
   oben in ihre Zeile, sobald sie beim Scrollen in den Anzeigebereich
   kommt — wirkt dadurch, als würde sie sich an die zuletzt sichtbare Zeile
   „anfügen", statt nur einzublenden (15.09.2026, auf Wunsch verlangsamt
   und um diese Schiebebewegung ergänzt; vorher: reiner, schnellerer
   Opacity-Fade).
     ".js-scrollreveal .card-tile" (Grundzustand: unsichtbar + versetzt,
   OHNE eigene Transition — die Verzögerung bis zum ersten sichtbaren Wert
   wäre sonst selbst schon eine ungewollte Animation) und
   ".card-tile.reveal-visible" (Zielzustand: sichtbar + an Ort und Stelle)
   sind absichtlich einfache Zwei-Klassen-Regeln OHNE "html."-Element-
   Selektor (die Klasse sitzt ohnehin nur auf <html>, ein zusätzlicher
   Element-Selektor hier würde die Spezifität einseitig erhöhen), damit
   beide exakt dieselbe Spezifität wie ".card-tile.tile-hiding" weiter unten
   haben — bei gleicher Spezifität entscheidet die Reihenfolge im
   Stylesheet: erst gewinnt reveal-visible gegen den Grundzustand, dann
   gewinnt tile-hiding im Zweifel gegen reveal-visible (Filter-Ausblenden
   hat immer Vorrang). Die eigentliche, bewusst langsame Übergangsdauer
   sitzt in der separaten ".reveal-animating"-Klasse (höhere Spezifität als
   die Basisregel oben, überschreibt nur "transition", keine eigenen
   Werte) — scrollreveal.js setzt sie kurz vor dem Wechsel zu
   "reveal-visible" und entfernt sie wieder, sobald die Animation fertig
   ist. Dieser Umweg ist nötig, weil "reveal-visible" sonst dauerhaft eine
   eigene Transition tragen müsste, die dann auch den (bewusst kurzen,
   knackigen) Hover-Effekt der Basisregel oben für immer verlangsamen
   würde, sobald eine Kachel einmal eingeblendet wurde. */
.js-scrollreveal .card-tile{ opacity:0; transform:translateY(26px); }
.card-tile.reveal-animating{ transition:opacity var(--reveal-dur, .65s) cubic-bezier(.16,1,.3,1), transform var(--reveal-dur, .65s) cubic-bezier(.16,1,.3,1); }
.card-tile.reveal-visible{ opacity:1; transform:translateY(0); }
/* Fade-out/in used by set.php's "fehlende Karten ausblenden" toggle
   (assets/set.js): .tile-hiding starts the transition, .tile-hidden is
   added afterwards to pull the tile out of the grid flow entirely. */
.card-tile.tile-hiding{ opacity:0; transform:scale(.85); pointer-events:none; }
.card-tile.tile-hidden{ display:none; }
/* Kartenbild nicht mehr bündig im Karton (Mario, 19.09.2026 Nachbesserung
   zum Kartenansichten-Umbau, per Screenshot-Vorgabe): statt das Bild randlos
   über die volle Kachelbreite zu ziehen, bekommt .thumb-wrap jetzt einen
   eigenen Abstand zum Kachelrand (margin) sowie eine eigene, sanfte
   Ecken-Rundung (border-radius) unabhängig vom äußeren .card-tile-Radius —
   dadurch schimmert die normale Kachel-Hintergrundfarbe als schmaler Rahmen
   um das Bild durch, statt dass nur die vier äußersten Bild-Ecken über das
   overflow:hidden der Kachel mitgerundet werden. Für die Listenansicht
   (ausdrücklich unverändert, siehe deren eigene .thumb-wrap-Regel weiter
   unten) wird beides gezielt wieder auf 0 zurückgesetzt. */
.card-tile .thumb-wrap{ position:relative; aspect-ratio:245/337; background:var(--paper-sunken); display:flex; align-items:center; justify-content:center; overflow:hidden; margin:8px 8px 0; border-radius:calc(8px * var(--rs, 1)); }
.card-tile img{ width:100%; height:100%; object-fit:contain; display:block; }
.card-tile img.img-placeholder{ opacity:.55; }
/* flex:1 fixes the "Online" badge not sitting flush at the very bottom of a
   card when a taller sibling (e.g. one with owned-variant chips) stretches
   the whole row: without it, .tile-body only ever sized itself to its own
   content and the badge (anchored to *its* bottom edge) ended up floating
   above the tile's real, grid-stretched bottom edge instead of sitting on it. */
.card-tile .tile-body{ padding:9px 10px 11px; display:flex; flex-direction:column; gap:2px; position:relative; flex:1; }
.card-tile .tile-body.has-badge{ padding-bottom:27px; }
/* Reserves room for the print-toggle button (below) so it never overlaps
   the variant chips row when a tile is exactly as tall as its content. */
.card-tile .tile-body.has-print{ padding-bottom:34px; }
/* TCG-Pocket-Kennzeichnung in der Kartensuche (Mario, 17.09.2026 Bugreport
   Punkt 6, Farbton korrigiert 19.09.2026 Bugreport Punkt 3, auf die GESAMTE
   Kachel ausgeweitet 19.09.2026 Folgerunde: "nicht nur der untere Bereich")
   — der Vermerk "Pocket" selbst ist seit 19.09.2026 kein eigenes Badge mehr
   (siehe render_card_tile() in helpers.php: einfacher Text in .tile-sub
   hinter der Kartennummer), nur die Hintergrundfarbe bleibt eine eigene
   CSS-Regel. Die Klasse "tile-pocket" sitzt seit der Folgerunde nicht mehr
   auf .tile-body (Infobereich), sondern direkt auf dem äußeren .card-tile
   selbst — dadurch färbt sich die ganze Kachel (inkl. dem schmalen Rahmen um
   das Kartenbild aus Eintrag 83, .thumb-wrap hat weiterhin eine eigene,
   neutrale --paper-sunken-Füllung fürs Bild selbst) statt nur der untere
   Infobereich, ohne dass dafür eine zweite Regel für .thumb-wrap nötig wäre:
   .tile-body hat schon immer keinen eigenen Hintergrund und ließ die Farbe
   des umgebenden .card-tile ohnehin durchscheinen. --pocket-tile-bg ist ein
   von --paper-sunken unabhängiger Farbwert (siehe :root oben), den Mario per
   Screenshot vorgegeben hat. Nur gesetzt, wenn render_card_tile() ein
   set_serie_id mitbekommt (siehe dessen Kommentar in helpers.php — betrifft
   cards.php, set_pocket.php sowie den entsprechend nachgezogenen eigenen
   Kachel-Loop von collection_pocket.php), da nur dort echte Pocket-Karten
   vorkommen können. */
.card-tile.tile-pocket{ background:var(--pocket-tile-bg); }
/* --ink-faint (die normale .tile-sub-Farbe) hat auf --pocket-tile-bg nur noch
   einen Kontrast von ~2:1 (WCAG verlangt 4.5:1 für Fließtext dieser Größe) —
   das gelbgrün/olivfarbene Pocket-Feld ist dafür zu hell (Hell-/zu dunkel im
   Dunkelmodus). --ink-soft ist auf beiden Themes bereits ein vorhandener,
   etwas kräftigerer Grauton (~3.8:1 hell / ~5.2:1 dunkel) und übernimmt hier
   nur innerhalb der Pocket-Kachel die Rolle von --ink-faint, damit "SetName ·
   #123 · Pocket" nicht erneut schwer lesbar wird — derselbe Anlass wie der
   eigentliche Bugreport (verschwindende Schrift), nur diesmal durch die neue
   Hintergrundfarbe statt durch Überlappung verursacht. */
.card-tile.tile-pocket .tile-sub{ color:var(--ink-soft); }
.card-tile .tile-name{ font-size:12.5px; font-weight:600; overflow:hidden; text-overflow:ellipsis; white-space:nowrap; }
.card-tile .tile-sub{ font-size:11px; color:var(--ink-faint); font-family:var(--font-mono); }
.card-tile .tile-price{ font-size:11px; font-weight:700; color:var(--good); font-family:var(--font-mono); margin-top:1px; }
.card-tile .variants{ display:flex; gap:4px; flex-wrap:wrap; margin-top:3px; }
/* Varianten-Kästchen im Lila-Ton der Seite statt eines neutralen Grautons
   (Mario, 19.09.2026 Folgerunde) — --vchip-bg/--vchip-ink siehe :root oben,
   Standard identisch zur aktuellen Akzentfarbe, aber unabhängig editierbar.
   border-color folgt bewusst --vchip-bg selbst statt --line, sonst hätte das
   gefüllte Kästchen einen sichtbar andersfarbigen, unpassenden Rand. */
.card-tile .vchip{ font-family:var(--font-mono); font-size:9.5px; font-weight:600; background:var(--vchip-bg); color:var(--vchip-ink); border:1px solid var(--vchip-bg); padding:1px 5px; border-radius:5px; }
/* .set-tile-badge ("Bearbeitet"/"Eigen") bleibt wie gehabt absolut
   positioniert — betrifft nur Sets (unverändert, siehe Mario's Vorgabe
   "Sets bleibt wie es ist"). .tile-remote-badge ("Online" auf noch nicht
   importierten Kartenkacheln) sitzt seit dem 19.09.2026-Umbau NICHT mehr
   absolut in der Ecke — genau dort sitzt jetzt die neue Aktions-Kapsel
   (.tile-actions weiter unten). Fließt stattdessen ganz normal im Text
   direkt hinter #Nummer, damit beide sich nie überlappen können (vorher
   genau diese Art Überlappung schon einmal Ursache eines Bugs, siehe
   render_card_tile()-Kommentar in helpers.php zum "Pocket"-Vermerk). */
.tile-remote-badge{ display:inline-block; background:var(--accent); color:var(--accent-ink); font-size:9.5px; padding:2px 7px; margin-top:3px; }

/* Ovale Aktions-Kapsel (Mario, 19.09.2026, "Umbau der Kartenansichten" nach
   KI-Referenz-Screenshots): bündelt Status-Lämpchen (render_tile_status_dot()),
   Zoom-Knopf (render_tile_zoom_button()), "Zu Deck hinzufügen"
   (deck_add_button()) und "Zur Druckliste" (print_list_toggle_button()) in
   EINER gemeinsamen Form statt vorher einzeln, frei in der Ecke
   positionierter Icons (render_tile_actions() in helpers.php). Sitzt absolut
   über der rechten unteren Ecke von .tile-body (dort bereits
   position:relative) — exakt dieselbe Ecke, die zuvor die Einzel-Knöpfe
   belegten. Lebt innerhalb des Kachel-<a>, daher preventDefault()/
   stopPropagation() auf jedem einzelnen Knopf-onclick (unverändert). */
/* Kapsel-Farbton (Mario, 19.09.2026 Nachbesserung, per Screenshot-Vorgabe):
   statt einer festen, hell/dunkel-eigenen Kachel-Farbe (--paper-raised) ein
   halbtransparentes Schwarz — exakt so nachgebaut, wie es in Mario's
   Referenz-Screenshots per Pixelprobe gemessen wurde (rgba(0,0,0,.25) über
   dem jeweiligen Kachel-Hintergrund ergibt in Hell wie in Dunkel exakt die
   dort abgelesenen Werte). Der Vorteil einer echten Transparenz statt zweier
   fest hinterlegter Hell-/Dunkel-Farbwerte: die Kapsel passt sich dadurch
   automatisch jeder Kachel-Hintergrundfarbe an (inkl. der eigenen, gelbgrünen
   TCG-Pocket-Einfärbung, --pocket-tile-bg), ohne eine dritte Variante pflegen
   zu müssen. */
.card-tile .tile-actions{
  position:absolute; bottom:6px; right:6px; z-index:2;
  display:flex; align-items:center; gap:1px;
  background:rgba(0,0,0,.25); border-radius:999px;
  padding:3px 4px;
}
/* Status-"Lämpchen": grün = Lokal gespeichert, orange = Auf Remote-Server
   verfügbar, rot = Nicht verfügbar (tile_status_info() in helpers.php). Rein
   informativ, kein Knopf — daher kein Hover-/Fokus-Zustand. Der Glüheffekt
   (Mario, 19.09.2026 Nachbesserung) ist ein zweistufiger, unscharfer
   box-shadow in der jeweils eigenen Lämpchen-Farbe — dieselbe CSS-Variable
   wie der Hintergrund, kein zusätzlicher Farbwert nötig; die Unschärfe
   (blur) sorgt für den weichen, nach außen ausblassenden Schein statt eines
   harten zweiten Rings. */
.card-tile .tile-status-dot{ width:8px; height:8px; border-radius:999px; flex:none; margin:0 3px 0 3px; }
.card-tile .tile-status-dot.tile-status-local{ background:var(--lamp-local); box-shadow:0 0 3px 1px var(--lamp-local), 0 0 7px 2px var(--lamp-local); }
.card-tile .tile-status-dot.tile-status-remote{ background:var(--lamp-remote); box-shadow:0 0 3px 1px var(--lamp-remote), 0 0 7px 2px var(--lamp-remote); }
.card-tile .tile-status-dot.tile-status-unavailable{ background:var(--lamp-unavailable); box-shadow:0 0 3px 1px var(--lamp-unavailable), 0 0 7px 2px var(--lamp-unavailable); }
/* Die drei Icon-Knöpfe innerhalb der Kapsel — Zoom, Zu-Deck, Druckliste —
   bekommen hier eine gemeinsame, schlichte Grundform (keine eigene Kontur/
   kein eigener Schatten mehr, das übernimmt jetzt die Kapsel als Ganzes).
   .tile-zoom-btn/.deck-add-btn/.print-toggle-btn werden AUSSCHLIESSLICH
   innerhalb dieser Kapsel gerendert (siehe render_tile_actions()), daher
   genügt hier die einfache, ungescopte Klasse statt eines Nachfahren-
   Selektors. */
/* Eigener, etwas dunklerer Kreis je Knopf innerhalb der Kapsel (Mario,
   19.09.2026 Nachbesserung, per Screenshot-Vorgabe) — dieselbe
   rgba(0,0,0,..)-Logik wie die Kapsel selbst, nur eine Stufe dunkler
   (zusätzliche ~35% statt 25%, macht zusammen mit der Kapsel-Fläche
   darunter die per Pixelprobe gemessenen ~50% aus). Die Icons selbst
   (🔍/🃏/🖨️) sind Emojis mit fest eigener Farbe — "color" wirkt hier nur als
   Fallback, falls ein Gerät sie einmal als reinen Text statt als Bild
   rendert, ändert an ihrem sichtbaren Erscheinungsbild sonst nichts. */
.tile-zoom-btn,
.deck-add-btn,
.print-toggle-btn{
  position:static; width:22px; height:22px; padding:0; margin:0;
  border:none; background:rgba(0,0,0,.35); box-shadow:none;
  border-radius:999px; color:var(--ink-soft); font-size:12px; line-height:1;
  display:flex; align-items:center; justify-content:center; cursor:pointer;
}
.tile-zoom-btn:hover,
.deck-add-btn:hover,
.print-toggle-btn:hover{ background:rgba(0,0,0,.5); color:var(--accent); }
.print-toggle-btn.on-list{ background:var(--accent); color:var(--accent-ink); }
.print-toggle-btn:disabled{ opacity:.6; cursor:default; }

/* ---------- Große Ansicht ("Groß") ---------- */
/* Mario, 19.09.2026, "Umbau der Kartenansichten" nach KI-Referenz-
   Screenshots: eine vierte Kachelgröße oberhalb der bisherigen Standard-
   ("Mittel", .grid ohne Modifikator) Ansicht — größere Kacheln, dieselbe
   Aktions-Kapsel nur mit mehr Raum. Muss VOR der allgemeinen .grid-Regel
   (Standard/"Mittel") stehen, damit deren gleich spezifische
   Klassenselektoren nicht versehentlich durch Dateireihenfolge gewinnen —
   beide sind exclusiv über die view-mode-*-Klasse auf demselben Container
   getrennt (assets/viewmode.js setzt immer nur genau eine), daher überschneiden
   sie sich zur Laufzeit nie, die Reihenfolge hier dient nur der Klarheit. */
.view-mode-large .grid{ grid-template-columns:repeat(auto-fill,minmax(var(--cardtile-basis-large,240px),1fr)); gap:20px; }
.view-mode-large .card-tile .tile-name{ font-size:14.5px; }
.view-mode-large .card-tile .tile-sub{ font-size:12.5px; }
.view-mode-large .card-tile .tile-price{ font-size:12.5px; }
.view-mode-large .card-tile .tile-body{ padding:12px 14px 14px; }
.view-mode-large .card-tile .tile-body.has-print{ padding-bottom:40px; }
.view-mode-large .card-tile .tile-actions{ padding:4px 6px; gap:2px; }
.view-mode-large .card-tile .tile-status-dot{ width:10px; height:10px; }
.view-mode-large .tile-zoom-btn,
.view-mode-large .deck-add-btn,
.view-mode-large .print-toggle-btn{ width:26px; height:26px; font-size:14px; }

/* ---------- Kompakte Ansicht ---------- */
/* Same markup as the standard grid, just smaller — a pure CSS restyle
   driven by the "view-mode-compact" class assets/viewmode.js puts on the
   [data-view-options] container. */
.view-mode-compact .grid{ grid-template-columns:repeat(auto-fill,minmax(var(--cardtile-basis-compact,110px),1fr)); gap:10px; }
/* Setkacheln zeigen in Kompakt deutlich mehr Text (Name, Datum, Statistik,
   Fortschrittsbalken) als eine reine Kartenkachel — bei derselben schmalen
   96px-Spaltenbreite wie Karten brechen Wörter unschön um (Mario-Feedback
   11.09.2026). Eigene, breitere Spaltenbreite nur für Setkacheln-Grids;
   höhere Spezifität (Attribut-Selektor) statt Regel-Reihenfolge, damit das
   unabhängig davon gilt, ob dieses Grid zusätzlich eine Boxen-Gruppe ist. */
.view-mode-compact .grid[data-box-order-group="set_tiles"]{ grid-template-columns:repeat(auto-fill,minmax(var(--settile-grid-min-compact,150px),1fr)); }
.view-mode-compact .card-tile .tile-body{ padding:6px 7px 7px; gap:1px; }
.view-mode-compact .card-tile .tile-body.has-badge{ padding-bottom:22px; }
.view-mode-compact .card-tile .tile-body.has-print{ padding-bottom:28px; }
.view-mode-compact .card-tile .tile-name{ font-size:10.5px; }
.view-mode-compact .card-tile .tile-sub{ font-size:9px; }
.view-mode-compact .card-tile .tile-price{ font-size:9px; }
.view-mode-compact .card-tile .vchip{ font-size:8px; padding:1px 4px; }
.view-mode-compact .card-tile .tile-actions{ padding:2px 3px; gap:0; bottom:4px; right:4px; }
.view-mode-compact .card-tile .tile-status-dot{ width:6px; height:6px; margin:0 2px; }
.view-mode-compact .tile-zoom-btn,
.view-mode-compact .deck-add-btn,
.view-mode-compact .print-toggle-btn{ width:18px; height:18px; font-size:9px; }
.view-mode-compact .tile-remote-badge{ font-size:8.5px; padding:1.5px 5px; }
/* .set-tile-badge ("Bearbeitet"/"Eigen") had no compact-specific shrink of
   its own, unlike .tile-remote-badge above — it kept its full standard size
   while .set-tile .tile-body.has-badge fell back to the generic 22px
   compact padding-bottom (meant for the smaller .tile-remote-badge), so the
   full-size badge sat on top of the progress bar in Kompaktansicht
   (Mario-Feedback 11.09.2026). Shrink the badge and give it its own,
   larger compact padding-bottom so it clears the bar and sits tucked
   further into the corner. Same specificity as the generic has-badge rule
   above (4 classes each) — this wins on source order, must stay after it. */
.view-mode-compact .set-tile-badge{ font-size:8px; padding:1.5px 5px; bottom:4px; right:5px; }
.view-mode-compact .set-tile .tile-body.has-badge{ padding-bottom:26px; }
.view-mode-compact .set-tile-logo{ height:var(--logo-size-settile-compact); margin-bottom:2px; }
.view-mode-compact .set-tile-logo img{ max-height:var(--logo-size-settile-compact); }
/* Three classes (not two) so this reliably beats the base
   .set-tile-logo-wrap .set-tile-symbol rule further down the file at equal
   specificity would otherwise go to whichever is LATER in source order —
   see that rule's comment for why it needs two classes of its own. */
.view-mode-compact .set-tile-logo-wrap .set-tile-symbol{ height:var(--symbol-size-settile-compact); margin:0 0 4px; }

/* ---------- Listenansicht ---------- */
/* Turns the same tile markup into horizontal rows: small fixed-width
   thumbnail on the left, everything else flowing right in one line instead
   of stacked. Card tiles and set tiles get their own row rules since their
   base layouts differ (image+text-below vs. logo-stacked-and-centered). */
.view-mode-list .grid{ display:flex; flex-direction:column; gap:8px; }
/* Kein align-items:center mehr hier (19.09.2026 Bugfix, siehe Kommentar bei
   .thumb-wrap/.tile-body unten): der Standard-Wert "stretch" lässt
   .tile-body die volle Zeilenhöhe einnehmen, statt kürzer als das
   .thumb-wrap-Bild zu bleiben — sonst schimmerte oben/unten die normale
   .card-tile-Hintergrundfarbe durch eine kürzere .tile-pocket-Fläche durch
   ("weißer Streifen", Mario-Bugreport 19.09.2026 Punkt 2). */
.view-mode-list .card-tile{ flex-direction:row; }
.view-mode-list .card-tile:hover{ transform:none; }
/* align-self:center hält das schmale 44px-Vorschaubild bei seiner eigenen,
   durchs aspect-ratio vorgegebenen Höhe fest, obwohl die Zeile selbst jetzt
   (kein align-items:center mehr am .card-tile) auf "stretch" steht. */
.view-mode-list .card-tile .thumb-wrap{ width:44px; flex:none; align-self:center; margin:0; border-radius:0; }
.view-mode-list .card-tile .tile-body{ flex-direction:row; align-items:center; gap:12px; padding:8px 12px; flex-wrap:wrap; }
.view-mode-list .card-tile .tile-body.has-badge,
.view-mode-list .card-tile .tile-body.has-print{ padding-bottom:8px; }
.view-mode-list .card-tile .tile-name{ white-space:normal; flex:1 1 180px; }
.view-mode-list .card-tile .tile-sub{ flex:none; }
.view-mode-list .card-tile .tile-price{ flex:none; margin-top:0; }
.view-mode-list .card-tile .variants{ margin-top:0; flex:none; }
/* 19.09.2026 Bugfix ("Symbole haben unterschiedliche Abstände zueinander,
   Schrift verschwindet teilweise unter den Symbolen"): .deck-add-btn wurde
   hier bisher gar nicht auf position:static umgestellt — es blieb also
   weiterhin absolut auf der Kachel positioniert (bottom:6px;right:38px; aus
   der Grundregel), während .print-toggle-btn schon in die normale Flex-Zeile
   floss. Dadurch überlappte der Deck-Knopf frei schwebend Text/Preis/den
   anderen Knopf, statt sauber daneben zu sitzen. Jetzt fließen beide Knöpfe
   in der Zeile; "order" hält dieselbe links-rechts-Reihenfolge wie in
   Standard-/Kompaktansicht (dort: Deck-Knopf links vom Druckliste-Knopf, da
   bottom:6px;right:38px vs. right:6px), margin-left:auto auf dem jetzt
   ERSTEN der beiden schiebt beide gemeinsam an den rechten Rand, ein fester
   6px-Abstand zwischen ihnen ersetzt das bisher zufällige (Overlap-)
   "Abstand". */
.view-mode-list .deck-add-btn{ position:static; margin-left:auto; box-shadow:none; order:1; }
.view-mode-list .print-toggle-btn{ position:static; margin-left:6px; box-shadow:none; order:2; }
.view-mode-list .tile-remote-badge{ margin-left:auto; margin-top:0; }
/* Die Listenansicht bleibt laut Mario (19.09.2026, "Umbau der
   Kartenansichten") ausdrücklich UNVERÄNDERT — Status-Lämpchen, Zoom-Knopf
   und die neue ovale Kapsel (.tile-actions, siehe weiter oben) sind Teil des
   Umbaus der Groß/Mittel/Klein-Kacheln, nicht der Liste. display:contents
   löst den Kapsel-<div> hier wieder aus dem Layoutbaum heraus, sodass seine
   Kind-Elemente wieder direkt zu Flex-Kindern von .tile-body werden — exakt
   wie vor dem Umbau, als es .tile-actions noch gar nicht gab. Status-Lämpchen
   und Zoom-Knopf werden zusätzlich ausgeblendet (Liste zeigt weiterhin nur
   Zu-Deck/Druckliste). Drei Klassen (.view-mode-list .card-tile .X) statt nur
   zwei, damit diese Wiederherstellung unabhängig von der Dateireihenfolge
   IMMER gegen die neue, einklassige .tile-zoom-btn/.deck-add-btn/
   .print-toggle-btn-Grundregel weiter oben gewinnt (siehe deren eigener
   Kommentar zur CSS-Spezifitäts-Falle in diesem Projekt). */
.view-mode-list .card-tile .tile-actions{ position:static; display:contents; }
.view-mode-list .card-tile .tile-status-dot,
.view-mode-list .card-tile .tile-zoom-btn{ display:none; }
.view-mode-list .card-tile .deck-add-btn,
.view-mode-list .card-tile .print-toggle-btn{
  width:26px; height:26px; font-size:13px;
  border:1px solid var(--line); background:var(--paper-raised);
}
.view-mode-list .card-tile .deck-add-btn:hover,
.view-mode-list .card-tile .print-toggle-btn:hover{ border-color:var(--accent); color:var(--accent); background:var(--paper-raised); }
.view-mode-list .card-tile .print-toggle-btn.on-list{ background:var(--accent); border-color:var(--accent); color:var(--accent-ink); }
.view-mode-list .set-tile{ flex-direction:row; align-items:center; padding:10px 14px; }
/* Row layout here, not stacked — a symbol drawn under a 40px-tall logo has
   no useful vertical room in a one-line list row, so it sits beside the
   logo instead within their shared wrap. */
.view-mode-list .set-tile-logo-wrap{ flex-direction:row; align-items:center; margin-right:14px; }
.view-mode-list .set-tile-logo{ height:var(--logo-size-settile-list); margin-bottom:0; margin-right:8px; }
.view-mode-list .set-tile-logo img{ max-height:var(--logo-size-settile-list); }
/* Three classes for the same reason as the Kompakt override above. */
.view-mode-list .set-tile-logo-wrap .set-tile-symbol{ height:var(--symbol-size-settile-list); margin:0; }
.view-mode-list .set-tile .tile-body{ align-items:flex-start; text-align:left; flex-direction:row; flex-wrap:wrap; gap:4px 16px; padding:0; }
.view-mode-list .set-tile .tile-name{ font-size:13px; }
.view-mode-list .set-tile .progress-row{ width:160px; margin-top:0; }
.view-mode-list .set-tile-badge{ position:static; }

/* ---------- "Serien"-Übersicht (Mario, 13.09.2026 zweite Rückmelderunde) ---------- */
/* sets.php rendert bei aktivierter Serien-Gruppierung zusätzlich zur
   normalen Setkachel-Übersicht einen zweiten Block (.serie-groups-wrap),
   der dieselben Setkacheln nach Serie gruppiert mit Überschrift (Logo +
   Name) zeigt — sichtbar/unsichtbar über dieselbe [data-view-options]-
   Mechanik wie Standard/Kompakt/Liste (assets/viewmode.js), nur mit drei
   weiteren Werten ("series-grid"/"series-compact"/"series-list"). Statt
   jede Kompakt-/Listen-Regel oben zu duplizieren, hängen genau die
   Selektoren, die für Setkacheln zählen, hier per Komma an dieselbe Regel
   an. */
.view-mode-series-grid .flat-sets-grid,
.view-mode-series-compact .flat-sets-grid,
.view-mode-series-list .flat-sets-grid,
.view-mode-grid .serie-groups-wrap,
.view-mode-compact .serie-groups-wrap,
.view-mode-list .serie-groups-wrap{ display:none; }

.serie-group{ margin-bottom:28px; }
.serie-group-header{ display:flex; align-items:center; gap:10px; margin-bottom:12px; padding-bottom:8px; border-bottom:1px solid var(--line); }
.serie-group-header .serie-group-logo{ height:32px; max-width:140px; object-fit:contain; }
.serie-group-header .serie-group-name{ font-size:16px; font-weight:700; }
.serie-group-header .serie-group-count{ font-size:12px; color:var(--ink-faint); margin-left:auto; }

/* Kachelgröße "Serien / Standard" (Mario, 13.09.2026 dritte Rückmelderunde):
   die ursprüngliche Annahme oben ("Basis-.set-tile-Größe gilt automatisch")
   war falsch — die Basisgröße ist ein reines CSS-Grid mit 150px-Mindest-
   breite, während die flache Standard-Ansicht ein Flexbox-Layout mit fester
   --settile-basis-standard-Breite je Kachel ist (siehe .grid.box-order-group
   weiter unten). Damit beide Ansichten niemals wieder auseinanderlaufen
   können, liest diese Regel exakt dieselbe Variable UND wendet sie exakt so
   an wie dort — inklusive einer eventuell je Set gewählten Größenstufe
   (Klein/Groß/Volle Breite, sets_render_tile_plain() rendert dafür jetzt
   dieselben box_order_item_attrs() wie die flache Ansicht). Bewusst über den
   [data-box-order-group]-Attribut-Selektor statt der .box-order-group-Klasse
   angesprochen: die Drag&Drop-Funktion (assets/boxorder.js) bindet
   ausschließlich an Container mit der Klasse .box-order-group, die dieses
   Grid absichtlich nicht trägt — die Kacheln bekommen also exakt dieselbe
   Breite, bleiben aber unziehbar (Reihenfolge kommt aus der Serien-
   Gruppierung, siehe Kommentar oben bei .serie-groups-wrap). */
.view-mode-series-grid .grid[data-box-order-group="set_tiles"]{ display:flex; flex-wrap:wrap; }
.view-mode-series-grid .grid[data-box-order-group="set_tiles"] > .box-order-item{ --box-basis:var(--settile-basis-standard,220px); flex:0 1 var(--box-basis); }

/* Fehlte bisher komplett (Mario, 13.09.2026 dritte Rückmelderunde): die
   allgemeine Kompakt-Regel oben (.view-mode-compact .grid{...gap:10px})
   greift nur unter der Klasse "view-mode-compact" — die gruppierte Ansicht
   trägt aber "view-mode-series-compact" und blieb dadurch stillschweigend
   beim normalen 16px-Standardabstand (.grid{gap:16px}), obwohl die
   Spaltenbreite selbst schon korrekt auf Kompakt-Maß stand. Dadurch wirkten
   Serien/Kompakt-Kacheln trotz gleicher Breite spürbar weiter auseinander
   als in der flachen Kompakt-Ansicht. */
.view-mode-series-compact .grid{ gap:10px; }
.view-mode-series-compact .grid[data-box-order-group="set_tiles"]{ grid-template-columns:repeat(auto-fill,minmax(var(--settile-grid-min-compact,150px),1fr)); }
.view-mode-series-compact .set-tile-badge{ font-size:8px; padding:1.5px 5px; bottom:4px; right:5px; }
.view-mode-series-compact .set-tile .tile-body.has-badge{ padding-bottom:26px; }
.view-mode-series-compact .set-tile-logo{ height:var(--logo-size-settile-compact); margin-bottom:2px; }
.view-mode-series-compact .set-tile-logo img{ max-height:var(--logo-size-settile-compact); }
.view-mode-series-compact .set-tile-logo-wrap .set-tile-symbol{ height:var(--symbol-size-settile-compact); margin:0 0 4px; }

.view-mode-series-list .grid{ display:flex; flex-direction:column; gap:8px; }
/* Gleicher Grund wie bei der flachen Listenansicht weiter oben: in der
   Spaltenrichtung wäre --box-basis sonst plötzlich die Höhe statt die
   Breite jeder Zeile (eine ggf. gewählte Größenstufe würde die Zeile
   unnötig hoch statt normal hoch machen). */
.view-mode-series-list .grid[data-box-order-group="set_tiles"] > .box-order-item{ flex:0 0 auto !important; }
.view-mode-series-list .card-tile{ flex-direction:row; align-items:center; }
.view-mode-series-list .card-tile:hover{ transform:none; }
.view-mode-series-list .set-tile{ flex-direction:row; align-items:center; padding:10px 14px; }
.view-mode-series-list .set-tile-logo-wrap{ flex-direction:row; align-items:center; margin-right:14px; }
.view-mode-series-list .set-tile-logo{ height:var(--logo-size-settile-list); margin-bottom:0; margin-right:8px; }
.view-mode-series-list .set-tile-logo img{ max-height:var(--logo-size-settile-list); }
.view-mode-series-list .set-tile-logo-wrap .set-tile-symbol{ height:var(--symbol-size-settile-list); margin:0; }
.view-mode-series-list .set-tile .tile-body{ align-items:flex-start; text-align:left; flex-direction:row; flex-wrap:wrap; gap:4px 16px; padding:0; }
.view-mode-series-list .set-tile .tile-name{ font-size:13px; }
.view-mode-series-list .set-tile .progress-row{ width:160px; margin-top:0; }
.view-mode-series-list .set-tile-badge{ position:static; }
.view-mode-series-list .serie-group-header{ margin-bottom:8px; }

/* ---------- Sammlung: Ansicht "Sets" ---------- */
/* Two alternate contents for the same page-main area: .view-panel-cards is
   the existing per-set list of owned cards, .view-panel-sets is a plain
   set-tile overview (like sets.php) linking into set.php. Both are always
   rendered server-side; only one shows at a time, and the default (no JS,
   or before it runs) is the pre-existing cards view, unchanged. */
.view-panel-sets{ display:none; }
.view-mode-sets .view-panel-cards{ display:none; }
.view-mode-sets .view-panel-sets{ display:block; }
/* Same "active" look for the text-label version of the toggle on the card
   detail page (public/card.php) — a plain .btn rather than the round
   overlay button used on grid tiles. */
.btn.on-list{ background:var(--accent); border-color:var(--accent); color:var(--accent-ink); }

/* print_list.php: one .print-set-group per originating set (logo + name
   heading, per Mario's request), each with its own .print-sheet grid inside. */
.print-set-group{ margin-bottom:28px; }
.print-set-group:last-child{ margin-bottom:0; }
.print-set-group-head{ display:flex; align-items:center; gap:10px; margin-bottom:12px; padding-bottom:8px; border-bottom:1px solid var(--line); }
.print-set-group-logo-block{ display:flex; flex-direction:column; align-items:flex-start; gap:2px; flex:none; }
.print-set-group-logo{ height:var(--logo-size-print); max-width:var(--logo-maxwidth-print); object-fit:contain; flex:none; }
.print-set-group-symbol{ height:var(--symbol-size-print); width:auto; max-width:var(--symbol-maxwidth-print); object-fit:contain; }
.print-set-group-name{ font-weight:700; font-size:15px; }

/* print_list.php's grid + its own remove button, top-right of each card
   the same way the toggle button sits on the browsing grids. */
.print-sheet{ display:grid; grid-template-columns:repeat(auto-fill,minmax(150px,1fr)); gap:16px; }
.print-card{ position:relative; background:var(--paper-raised); border:1px solid var(--line); border-radius:12px; padding:10px; text-align:center; }
.print-card-img img{ width:100%; border-radius:8px; display:block; }
.print-card-name{ font-size:12.5px; font-weight:600; margin-top:6px; }
.print-card-sub{ font-size:11px; color:var(--ink-faint); font-family:var(--font-mono); }
.print-card-remove{ position:absolute; top:6px; right:6px; z-index:2; }
.print-card-remove .btn{ padding:2px 8px; }

/* Printing the Druckliste: hide everything that isn't the card grid itself
   (nav, page intro text, the remove/leeren buttons, flash messages) so the
   printed sheet is just cards — name, set, number, image. */
@media print{
  .no-print, .topbar, .flash{ display:none !important; }
  body, .page{ background:#fff !important; }
  .print-sheet{ grid-template-columns:repeat(var(--print-cols, 4),1fr); gap:10px; } /* Spalten einstellbar (25.10.2026) */
  /* No border around the printed cards — Mario's explicit request; the
     on-screen editing view (.print-card, above) keeps its box/border so the
     list is still easy to manage before printing. */
  .print-card{ border:none; box-shadow:none; break-inside:avoid; }
  .print-set-group{ break-inside:avoid; }
}

