/* TCG Keeper — gemeinsames Stylesheet, Teil 4 von 8: Set-Kacheln und Set-Kopf, Wertvollste Karten, Kartenseite, Lightboxen, Anmeldeseite.
   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. */
/* Set tiles (sets.php grid): logo stacked above the name (bigger than the
   inline logo used elsewhere) instead of side-by-side, so a long name or an
   edit badge never overflows and gets clipped by .card-tile's overflow:hidden
   the way the inline layout could. */
.set-tile{ padding:16px 14px; align-items:center; }
.set-tile-logo{ height:var(--logo-size-settile); display:flex; align-items:center; justify-content:center; margin-bottom:4px; }
.set-tile-logo img{ max-height:var(--logo-size-settile); max-width:100%; object-fit:contain; }
/* Wraps a set logo + its small symbol icon so the symbol always renders
   directly underneath the logo (Mario's explicit request), regardless of
   whether the surrounding tile itself is laid out as a column (Standard/
   Kompakt) or a row (Liste — see .view-mode-list override below). */
.set-tile-logo-wrap{ display:flex; flex-direction:column; align-items:center; }
/* Qualified with the wrap as an ancestor class (two classes) so this
   reliably beats .card-tile img's width:100%;height:100% (one class + one
   element — higher specificity than a lone .set-tile-symbol class, which
   was silently losing to it regardless of source order and rendering the
   symbol logo-sized instead of small, per Mario's screenshot). */
.set-tile-logo-wrap .set-tile-symbol{ display:block; height:var(--symbol-size-settile); width:auto; max-width:var(--symbol-maxwidth-settile); object-fit:contain; margin:0 0 8px; }
.set-tile .tile-body{ position:relative; align-items:center; text-align:center; }
.set-tile .tile-name{ white-space:normal; font-size:14px; }
.set-tile .progress-row{ margin-top:8px; width:100%; }
/* A bit more clearance under the progress bar than the generic has-badge
   padding gives elsewhere — Mario found the badge sitting too close to the
   bar above it. */
.set-tile .tile-body.has-badge{ padding-bottom:34px; }
.set-tile-badge{ position:absolute; bottom:6px; right:8px; }

/* Jede Set-Gruppe in "Meine Sammlung" bekommt seit Mario's Folgerunde
   (16.09.2026: "stärkere visuelle Trennung der Kartensets beim Scrollen")
   zusätzlich die normale .card-box-Optik (eigene Fläche, Rand, Schatten,
   siehe HTML in collection.php) — .set-section selbst liefert nur noch den
   Abstand zur nächsten Box, .card-box das Drumherum. */
.set-section{ margin-bottom:30px; }
.set-section-head{ display:flex; align-items:center; gap:14px; margin-bottom:14px; }
.set-section-head img{ height:var(--logo-size-section); }
/* Same logo+symbol stacking idea as .set-tile-logo-wrap above, for the
   Sammlung grid view's per-set section header. */
.set-section-logo-block{ display:flex; flex-direction:column; align-items:center; gap:3px; flex:none; }
/* Same specificity fix as .set-tile-logo-wrap .set-tile-symbol above — this
   sits inside .set-section-head, whose own ".set-section-head img{height:42px}"
   rule otherwise wins over a lone .set-section-symbol class. */
.set-section-logo-block .set-section-symbol{ height:var(--symbol-size-section); width:auto; max-width:var(--symbol-maxwidth-section); object-fit:contain; }
.set-section-head .name{ font-weight:600; font-size:17px; }
.set-section-head .frac{ font-family:var(--font-mono); font-size:12px; color:var(--ink-faint); margin-left:auto; }
/* Gesamtanzahl (inkl. Mehrfachbesitz) unter der Set-Überschrift in "Meine
   Sammlung" (Mario, 15.09.2026) — rechtsbündig unter .frac, wie eine
   Unterzeile dazu; der negative Top-Margin zieht sie näher an die
   Überschrift heran, statt den vollen .set-section-head-Abstand (14px)
   nochmal draufzuschlagen. */
.set-section-copies{ text-align:right; font-family:var(--font-mono); font-size:11px; color:var(--ink-faint); margin:-8px 0 12px; }
.progress-track{ height:6px; border-radius:4px; background:var(--paper-sunken); overflow:hidden; margin-bottom:12px; }
.progress-fill{ height:100%; background:var(--accent); }
/* Progress bar + percentage side by side (Sets grid, Sammlung): shrinks the
   bar itself (flex:1) and adds the number Mario asked for next to it. */
.progress-row{ display:flex; align-items:center; gap:8px; }
.progress-row .progress-track{ flex:1; margin-bottom:0; }
.progress-pct{ font-family:var(--font-mono); font-size:10.5px; font-weight:700; color:var(--ink-faint); white-space:nowrap; }

/* set.php's redesigned header (task: "Überschriftsbereich wie Offline-
   Version"), mirroring pokecollector-offline.html's .set-name-row/.meta. */
.set-detail-head{ display:flex; align-items:center; gap:18px; margin-bottom:18px; position:relative; }
/* Logo + its small symbol icon stacked, symbol centered directly underneath
   the logo (Mario's explicit "mittig unter dem Logo") — same idea as
   .set-tile-logo-wrap on the Sets/Sammlung grids. The BLOCK itself (not
   necessarily the logo image) is what stays flush with .set-detail-info's
   left edge on mobile (see test_setheader.js) — that holds regardless of
   which of the two images ends up wider. */
.set-detail-logo-block{ display:flex; flex-direction:column; align-items:center; gap:6px; flex:none; }
.set-detail-head .set-detail-logo{ height:var(--logo-size-setdetail); max-width:var(--logo-maxwidth-setdetail); object-fit:contain; flex:none; }
.set-detail-symbol{ height:var(--symbol-size-setdetail); width:auto; max-width:var(--symbol-maxwidth-setdetail); object-fit:contain; }
.set-detail-info{ min-width:0; }
.set-name-row{ display:flex; align-items:baseline; gap:9px; flex-wrap:wrap; }
.set-name-row h1{ font-size:21px; margin:0; }
.set-detail-info .meta{ font-size:12.5px; color:var(--ink-faint); font-family:var(--font-mono); margin-top:4px; }
/* Mario's set description field (set_edit.php) — same size/color as the
   .meta stat line and .set-detail-note above/below it (12.5px, ink-faint),
   just not monospace like .meta, since it's free-text prose rather than a
   stat line. */
.set-detail-description{ font-size:12.5px; color:var(--ink-faint); margin-top:6px; max-width:640px; white-space:pre-line; }
/* Replaces the old bottom-right "Bearbeitet"/"Eigen" badge on this header —
   Mario asked for a plain text note instead. */
.set-detail-note{ font-size:12.5px; color:var(--ink-faint); margin-top:6px; }
/* Weiterlesen (Mario, 27.09.2026): Set-Beschreibung mit gesetztem
   Weiterlesen-Punkt (siehe richtext_readmore_html()/assets/readmore.js).
   Ohne JavaScript ist alles sichtbar und der Knopf bleibt versteckt. Der
   aufklappbare Teil wird per max-height/opacity sanft ein- und
   ausgeblendet; readmore.js setzt dafür die tatsächliche Höhe. */
.set-detail-description.readmore .readmore-more{
  overflow:hidden; transition:max-height .35s ease, opacity .3s ease;
}
.set-detail-description.readmore.is-collapsed .readmore-more{ max-height:0; opacity:0; }
.set-detail-description .readmore-toggle{
  display:inline-flex; align-items:center; gap:5px; margin-top:4px; padding:0;
  border:0; background:none; cursor:pointer; white-space:nowrap;
  font:inherit; font-size:12.5px; font-weight:600; color:var(--accent);
}
.set-detail-description .readmore-toggle[hidden]{ display:none; }
.set-detail-description .readmore-toggle:hover .readmore-label{ color:var(--accent); } /* keine Unterstreichung mehr (Eintrag 130) */
.set-detail-description .readmore-toggle:focus-visible{ outline:2px solid var(--accent); outline-offset:2px; border-radius:3px; }
.set-detail-description .readmore-arrow{ display:inline-block; font-size:10px; transition:transform .25s ease; }
.set-detail-description.readmore:not(.is-collapsed) .readmore-arrow{ transform:rotate(180deg); }
@media (prefers-reduced-motion: reduce){
  .set-detail-description.readmore .readmore-more,
  .set-detail-description .readmore-arrow{ transition:none; }
}
/* Auf dem Handy: Logo oben links, darunter linksbündig Name/Metadaten statt
   nebeneinander wie am Desktop — bei schmaler Bildschirmbreite wirkt die
   Zeilen-Anordnung sonst gequetscht. Muss NACH der Basisregel oben stehen,
   siehe Hinweis beim Hamburger-Menü weiter oben in dieser Datei. */
@media (max-width:900px){
  .set-detail-head{ flex-direction:column; align-items:flex-start; gap:12px; }
}

/* Tablets im Hochkantformat (iPad Mini/iPad/iPad Air/vergleichbare
   Android-Tablets, meist 768–834px breit) fielen bislang unter dieselbe
   @media(max-width:900px)-Regelung wie echte Handys: Seitenleiste wird
   position:static/volle Breite, Kartendetail-Layout klappt in eine
   einzige Spalte um, .set-detail-head stapelt sich — auf einem Tablet
   ist dafür aber reichlich Platz vorhanden, das Kartenbild in der jetzt
   volle Breite einnehmenden Seitenleiste wirkte dadurch "extrem groß"
   (Mario, 22.09.2026, iPad-Mini-Hochkant-Screenshot).
   Korrektur 22.09.2026, zwei Runden (Checkpoint 29 + 30): der erste
   Versuch (Checkpoint 28) grenzte Tablets zusätzlich über die CSS-Media-
   Features (pointer:coarse) + (hover:none) ein — funktionierte in der
   Sandbox (Chromium-Touch-Emulation), aber laut Mario nicht auf seinem
   echten iPad Mini. Grund: iPadOS meldet dort wegen der systemweiten
   Trackpad-/Mausunterstützung fälschlich hover:hover/pointer:fine wie ein
   Desktop-Rechner, auch bei reiner Fingerbedienung ohne angeschlossene
   Maus/Trackpad — eine seit Jahren bekannte WebKit/iPadOS-Eigenheit,
   wodurch die Bedingung dort nie zutraf. Checkpoint 29 erkannte echte
   Touch-Hardware daraufhin korrekt in JavaScript über
   navigator.maxTouchPoints (siehe includes/layout_top.php, Funktion
   pcIsTabletPortrait) — das bleibt von der iPadOS-Eigenheit unberührt, da
   es die tatsächlich vorhandene Touchscreen-Hardware abfragt statt die vom
   Betriebssystem behauptete Zeigegeräte-Fähigkeit —, scheiterte aber
   ebenfalls: eine per Diagnose-Anzeige direkt von Marios Gerät ausgelesene
   Messung ergab window.innerWidth=744 im Hochkantformat, unter der
   damaligen Mindestbreite von 768px. Das aktuelle iPad Mini (6. Generation,
   seit 2021) hat ein anderes Bildschirmformat als ältere iPad-mini-Modelle
   und meldet im Hochkantformat 744 statt der klassischen 768 CSS-Pixel.
   Checkpoint 30 senkt die Schwelle deshalb auf 700px (siehe
   includes/layout_top.php) — mit weiterhin großem Sicherheitsabstand zur
   Breite selbst der größten Handys im Hochkantformat (aktuell max. ca.
   430–480px). Das Skript setzt dafür das Attribut data-tablet-portrait="1"
   auf <html> (nach
   demselben Muster wie data-theme/data-layout/data-nav-view dort), auf
   das die Regeln hier per Attribut-Selektor reagieren. Dadurch automatisch
   unabhängig von der Reihenfolge im Stylesheet stärker als die
   @media(max-width:900px)-Regeln oben (html[attr] .klasse ist immer
   spezifischer als eine reine .klasse-Regel) — die Reihenfolge in dieser
   Datei spielt hier also anders als bei den übrigen "MUSS danach stehen"-
   Hinweisen in dieser Datei keine Rolle mehr. Echte Handys (zu schmal)
   sowie schmale Desktop-/Notebook-Fenster mit Maus (kein Touchscreen,
   maxTouchPoints=0) bleiben unberührt. "order" auf den Kartendetail-
   Kästen (weiter oben) muss hier nicht zurückgesetzt werden: sobald
   .page-sidebar/.page-main wieder echte Boxen statt display:contents
   sind, sind deren Kind-Elemente keine direkten Flex-Kinder von
   .card-detail-layout mehr, "order" wirkt sich dort dadurch ohnehin
   nicht mehr aus. */
html[data-tablet-portrait="1"] .page-with-sidebar{ display:flex; align-items:flex-start; gap:24px; }
html[data-tablet-portrait="1"] .page-sidebar{ position:sticky; top:76px; width:auto; margin-bottom:0; }
html[data-tablet-portrait="1"] .filter-fab{ display:none; }
html[data-tablet-portrait="1"] .page-with-sidebar.card-detail-layout{ display:flex; flex-direction:row; align-items:flex-start; }
html[data-tablet-portrait="1"] .page-with-sidebar.card-detail-layout > .page-sidebar{ display:flex; }
html[data-tablet-portrait="1"] .page-with-sidebar.card-detail-layout > .page-main{ display:block; }
html[data-tablet-portrait="1"] .set-detail-head{ flex-direction:row; align-items:center; gap:18px; }

.badge{ display:inline-flex; align-items:center; gap:4px; font-size:11px; font-weight:600; padding:3px 8px; border-radius:999px; background:var(--paper-sunken); color:var(--ink-soft); width:fit-content; }
.badge.gold{ background:transparent; border:1px solid var(--gold); color:var(--gold); }
.row-wrap{ display:flex; gap:6px; flex-wrap:wrap; }

/* "Wertvollste Karten" (sets.php gesamt, set.php pro Set, collection.php
   beides — siehe render_value_highlights_box() in includes/helpers.php):
   die 3 Karten mit dem höchsten TCGdex/Cardmarket-Einzelpreis, die man
   besitzt (keine mit der Stückzahl multiplizierte Gesamtsumme wie beim
   Sammlungswert oben — hier geht es um die wertvollsten einzelnen Karten). */
.value-box{ background:var(--gold-soft); border:1px solid var(--line); border-radius:14px; padding:16px 18px; margin-bottom:20px; }
.value-box-title{ display:flex; align-items:center; gap:8px; font-weight:600; font-size:13.5px; color:var(--ink); margin-bottom:12px; }
.value-box-icon{ color:var(--gold); }
.value-box-list{ display:flex; gap:12px; flex-wrap:wrap; }
.value-box-item{
  display:flex; align-items:center; gap:10px; flex:1 1 220px; min-width:0;
  background:var(--paper-raised); border:1px solid var(--line); border-radius:10px;
  padding:8px 12px; text-decoration:none; color:inherit; transition:border-color .16s ease;
}
.value-box-item:hover{ border-color:var(--gold); }
.value-box-rank{
  flex:none; width:20px; height:20px; border-radius:50%; background:var(--gold); color:var(--paper-raised);
  font-family:var(--font-mono); font-size:11px; font-weight:600;
  display:flex; align-items:center; justify-content:center;
}
.value-box-thumb{ flex:none; width:30px; height:41px; border-radius:4px; overflow:hidden; background:var(--paper-sunken); }
.value-box-thumb img{ width:100%; height:100%; object-fit:cover; display:block; }
.value-box-info{ min-width:0; flex:1; display:flex; flex-direction:column; }
.value-box-name{ font-size:12.5px; font-weight:600; white-space:nowrap; overflow:hidden; text-overflow:ellipsis; }
.value-box-sub{ font-size:11px; color:var(--ink-faint); font-family:var(--font-mono); }
.value-box-price{ flex:none; font-weight:700; font-size:13px; color:var(--gold); margin-left:auto; }

/* Boxlose Variante speziell für die globale "Wertvollste Karten"-Übersicht
   ganz oben auf "Meine Sammlung" (Mario, 16.09.2026 vierte Folgerunde:
   "raus aus der BOX ... unter den Statistikboxen ... anordnen" — siehe
   render_value_highlights_section() in helpers.php). Nutzt bewusst dieselben
   .value-box-list/-item/-…-Klassen für die Kartenzeilen (identische Optik),
   nur ohne die umrandete .value-box-Fläche darum und mit etwas größerer,
   seitenüberschriftartiger Titelzeile statt der kompakten Box-Titelzeile. */
.value-section{ margin-bottom:20px; }
.value-section-title{ display:flex; align-items:center; gap:8px; font-weight:700; font-size:15px; color:var(--ink); margin-bottom:12px; }

/* Kartendetailseite (public/card.php): Bild + Aktionen + Sammlungs-Mengen
   sitzen in der linken .page-sidebar (wie bei Kartensuche/Sets/Sammlung/
   Set-Detail — sticky, bleibt beim Scrollen sichtbar), der Rest rechts in
   .page-main, in klar abgegrenzte .card-box-Kästen gruppiert statt als eine
   einzige lange Liste — Mario fand die alte Version "unübersichtlich". */
.img-wrap{ width:100%; border-radius:10px; overflow:hidden; background:var(--paper-sunken); cursor:zoom-in; }
.img-wrap img{ width:100%; display:block; }
.img-wrap-placeholder{ cursor:default; }
.img-wrap-placeholder img{ opacity:.55; }
.card-detail-imgbox{ padding:14px; }
/* Kartenbildgröße auf der Kartendetailseite (Mario, 19.09.2026 Folgerunde,
   editierbar in der Seitenanpassung) — .img-wrap img selbst ist immer
   width:100% seiner Box, die eigentliche Größe kommt von der Breite der
   umgebenden .page-sidebar. Zwei Klassen (statt der einfachen, überall auf
   der Seite genutzten Basisregel .page-sidebar{flex:0 0 300px;} weiter
   oben), damit NUR die Bildspalte der Kartendetailseite betroffen ist, nicht
   die vielen anderen Filter-/Info-Seitenleisten der übrigen Seiten (Sets/
   Kartensuche/Sammlung), die weiterhin fest bei 300px bleiben sollen. Auf
   dem Handy (siehe @media max-width:900px weiter oben) wird .page-sidebar
   dort ohnehin zu display:contents und nimmt an keiner Flex-Berechnung mehr
   teil — diese Regel bleibt dadurch dort automatisch wirkungslos. */
.card-detail-layout .page-sidebar{ flex:0 0 var(--carddetail-image-width,300px); }
.card-detail-actions{ margin-top:12px; }
/* Kartenseite: Aktionen als reine Symbolknöpfe (04.10.2026). */
.card-icon-actions{ display:flex; flex-wrap:wrap; gap:8px; }
.card-icon-actions .icon-btn-form{ display:contents; }
.btn.icon-btn{ width:42px; height:42px; min-height:42px; padding:0; justify-content:center; font-size:19px; line-height:1; border-radius:10px; }
.btn.icon-btn.on-list{ background:var(--accent-soft); border-color:var(--accent); }
.btn.icon-btn:focus-visible{ outline:2px solid var(--accent); outline-offset:2px; }
.card-detail-name{ font-size:23px; margin:0 0 6px; }
.card-detail-meta{ margin-bottom:10px; }
.meta.mono{ font-family:var(--font-mono); font-size:var(--font-size-mono); font-weight:var(--font-weight-mono); font-style:var(--font-style-mono); color:var(--ink-faint); }
.flavor{ font-style:italic; color:var(--ink-soft); font-size:13px; border-left:2px solid var(--line); padding-left:10px; }

/* Details-Kasten: zwei Spalten auf breiten Bildschirmen statt einer langen
   Kv-Liste. */
.kv-grid{ display:grid; grid-template-columns:repeat(auto-fill,minmax(220px,1fr)); column-gap:24px; }
.attack-box{ border:1px solid var(--line); border-radius:10px; padding:10px 12px; margin-bottom:8px; }
.attack-box:last-child{ margin-bottom:0; }
.attack-box-head{ display:flex; justify-content:space-between; align-items:center; gap:10px; }
.attack-box-name{ font-weight:600; font-size:13.5px; }
.attack-box-dmg{ font-family:var(--font-mono); font-weight:600; }
.attack-box-effect{ font-size:12.5px; color:var(--ink-soft); margin-top:4px; }

/* Preis-Reiter: reine CSS-Lösung über versteckte Radios + :checked, siehe
   card.php für die Markup-Reihenfolge (Radios → Nav → Panels, alles
   Geschwister), damit der ~-Selektor greift. */
.price-tab-radio{ position:absolute; opacity:0; width:1px; height:1px; pointer-events:none; }
.price-tab-nav{ display:flex; gap:6px; flex-wrap:wrap; margin-bottom:14px; }
.price-tab-btn{ display:inline-flex; align-items:center; padding:7px 13px; border-radius:9px; border:1px solid var(--line); background:var(--paper); color:var(--ink-soft); font-size:13px; font-weight:600; cursor:pointer; }
.price-tab-btn:hover{ border-color:var(--accent); color:var(--accent); }
.price-tab-panel{ display:none; }
#priceTabBinder:checked ~ .price-tab-nav label[for="priceTabBinder"],
#priceTabCardmarket:checked ~ .price-tab-nav label[for="priceTabCardmarket"],
#priceTabTcgplayer:checked ~ .price-tab-nav label[for="priceTabTcgplayer"]{
  background:var(--accent); border-color:var(--accent); color:var(--accent-ink);
}
#priceTabBinder:checked ~ #pricePanelBinder,
#priceTabCardmarket:checked ~ #pricePanelCardmarket,
#priceTabTcgplayer:checked ~ #pricePanelTcgplayer{ display:block; }

.section-title{ font-size:11px; font-weight:700; text-transform:uppercase; letter-spacing:.07em; color:var(--ink-faint); margin:20px 0 8px; }
.kv{ display:flex; justify-content:space-between; font-size:13px; padding:7px 0; border-bottom:1px solid var(--line); }
.kv:last-child{ border-bottom:none; }
.kv .k{ color:var(--ink-soft); }

.price-group-title{ font-size:12px; font-weight:700; color:var(--ink-soft); margin:14px 0 4px; }
.price-note{ font-size:11.5px; color:var(--ink-faint); margin:2px 0 6px; }
.price-table-wrap{ overflow-x:auto; margin:2px 0 8px; border:1px solid var(--line); border-radius:8px; }
.price-table{ width:100%; border-collapse:collapse; font-size:11.5px; font-family:var(--font-mono); white-space:nowrap; }
.price-table th, .price-table td{ padding:5px 8px; text-align:right; }
.price-table th:first-child, .price-table td:first-child{ text-align:left; font-family:var(--font-base); color:var(--ink-soft); white-space:normal; }
.price-table thead th{ color:var(--ink-faint); font-weight:700; text-transform:uppercase; font-size:9.5px; letter-spacing:.04em; border-bottom:1px solid var(--line); }
.price-table tbody tr:not(:last-child) td{ border-bottom:1px solid var(--line); }

.variant-row{ display:flex; align-items:center; justify-content:space-between; gap:10px; padding:9px 0; border-bottom:1px solid var(--line); }
.variant-row:last-child{ border-bottom:none; }
.variant-name{ font-size:13px; font-weight:500; }
.stepper{ display:flex; align-items:center; gap:10px; }
.stepper button{ width:26px; height:26px; border-radius:7px; border:1px solid var(--line); background:var(--paper); color:var(--ink); font-size:15px; cursor:pointer; line-height:1; }
.stepper button:hover{ border-color:var(--accent); }
.stepper .qty{ min-width:20px; text-align:center; font-family:var(--font-mono); font-weight:600; }

/* "Nach oben"-Button (2. Rückmelderunde) — unten rechts, sanft ein-/
   ausgeblendet per Klasse "show" (siehe layout_top.php), damit es nicht
   die volle Seite hindurch sichtbar herumsteht. Eigene, vom "Filter"-FAB
   (unten Mitte, nur mobil) unabhängige Ecke, damit sich beide nie
   überlappen. */
.back-to-top-btn{
  position:fixed; right:20px; bottom:20px; z-index:40;
  width:44px; height:44px; border-radius:999px;
  display:flex; align-items:center; justify-content:center;
  background:var(--accent); color:var(--accent-ink); border:none;
  font-size:20px; line-height:1; cursor:pointer; box-shadow:var(--shadow);
  opacity:0; visibility:hidden; transform:translateY(10px);
  transition:opacity .2s ease, transform .2s ease, visibility 0s linear .2s;
}
.back-to-top-btn.show{
  opacity:1; visibility:visible; transform:translateY(0);
  transition:opacity .2s ease, transform .2s ease, visibility 0s;
}
.back-to-top-btn:hover{ filter:brightness(1.08); }
@media (max-width:640px){
  /* Über dem mobilen "Filter"-FAB (unten Mitte) statt daneben, damit beide
     auf einem schmalen Bildschirm nicht kollidieren. */
  .back-to-top-btn{ right:14px; bottom:14px; width:40px; height:40px; font-size:18px; }
}
.lightbox-scrim{ position:fixed; inset:0; background:rgba(10,10,16,.82); display:flex; align-items:center; justify-content:center; opacity:0; pointer-events:none; transition:opacity .15s; z-index:100; }
.lightbox-scrim.open{ opacity:1; pointer-events:auto; }
.lightbox-scrim img{ max-width:min(92vw,560px); max-height:88vh; border-radius:10px; box-shadow:0 20px 60px rgba(0,0,0,.5); }
.lightbox-close{ position:fixed; top:18px; right:22px; background:none; border:none; color:#fff; font-size:28px; cursor:pointer; z-index:101; }
/* Text variant of the lightbox (set.php's "Änderungslog anzeigen"). */
.lightbox-panel{ max-width:min(92vw,640px); max-height:82vh; overflow:auto; background:var(--paper-raised); color:var(--ink); border-radius:calc(12px * var(--rs, 1)); padding:22px 24px; box-shadow:0 20px 60px rgba(0,0,0,.5); }
.lightbox-panel h3{ margin:0 0 14px; font-size:16px; }
.lightbox-panel pre{ white-space:pre-wrap; word-break:break-word; font-family:var(--font-mono); font-size:12.5px; line-height:1.7; margin:0; }
/* set.php: der "Änderungslog anzeigen"-Knopf sitzt jetzt mit in der
   Filter-/Sortierbox (siehe .sidebar-actions) und wird auf dem Handy mit
   dieser Box zusammen in die Filter-Lightbox verschoben — ein Klick darauf
   öffnet also das Änderungslog VERSCHACHTELT über der bereits offenen
   Filter-Lightbox. Beide teilen sich sonst dieselbe .lightbox-scrim-Klasse
   und denselben z-index, wodurch die (im HTML spätere) Filter-Lightbox das
   Änderungslog optisch verdecken würde. ID-Selektor gewinnt unabhängig von
   der Reihenfolge gegen die Klassen-Basisregel.
   Dasselbe Problem betrifft auch "Set von TCGdex laden" (sets.php) und
   "Karte von TCGdex laden" (cards.php): auch deren Buttons liegen in der
   verschiebbaren Sidebar-Box und wurden bislang durch die offene
   Filter-Lightbox verdeckt, wenn man sie auf dem Handy anklickt. */
#changelogScrim,
#tcgdexSetScrim,
#tcgdexCardScrim{ z-index:110; }
/* Filter-Lightbox (Kartensuche/Sets/Sammlung/Set-Detail, nur Handy — siehe
   .filter-fab und assets/filterbox.js): die echte Filter-/Sortierbox wird
   per JS unverändert in #filterLightboxSlot hinein- und wieder
   herausgeschoben (kein zweites, separat gepflegtes Formular), daher hier
   nur ihre eigene Kästchen-Optik (Hintergrund/Rand/Schatten/Innenabstand)
   entfernt, damit sie nicht wie eine Box-in-der-Box wirkt. */
.lightbox-panel .card-box{ background:none; border:none; box-shadow:none; padding:0; }
.filter-apply-btn{ width:100%; justify-content:center; margin-top:16px; }

.empty-box{ border:1px dashed var(--line); border-radius:12px; padding:28px; text-align:center; color:var(--ink-faint); font-size:14px; }

.auth-wrap{ max-width:380px; margin:60px auto; padding:0 20px; }
.auth-wrap .auth-logo{ display:block; width:var(--logo-size-auth); height:var(--logo-size-auth); margin:0 auto 10px; object-fit:contain; }
.auth-wrap h1{ font-size:22px; text-align:center; margin-bottom:2px; }
.auth-wrap .auth-credit{ text-align:center; font-size:11px; font-weight:500; color:var(--ink-faint); letter-spacing:.02em; margin-bottom:14px; }
.auth-wrap .sub{ text-align:center; color:var(--ink-faint); font-size:13px; margin-bottom:22px; }
.auth-wrap .switch{ text-align:center; margin-top:16px; font-size:13px; color:var(--ink-faint); }
.auth-wrap .auth-theme-row{ text-align:center; margin-top:16px; }

/* Login-Hintergrundbild (Mario's request): body.auth-page wird nur von
   login.php gesetzt (siehe dort), damit register.php — identisches
   .auth-wrap-Markup — unberührt bleibt. Vier Bilder aus public/images/back:
   je ein Hell-/Dunkel-Motiv, je einmal normal und einmal "wide" für sehr
   breite Bildschirme. .card-box hat bereits eine deckende eigene Fläche
   (--paper-raised) + Schatten, bleibt also unverändert gut lesbar. Pfade
   relativ zu assets/, nicht über IMAGES_URL, weil dies eine reine CSS-Regel
   ist (kein PHP) — funktioniert unabhängig von BASE_PATH. */
body.auth-page{
  min-height:100vh;
  background-image:var(--bg-auth-light);
  background-size:cover; background-position:center; background-repeat:no-repeat;
}
/* Gleiches Selektor-Muster wie bei den Farbvariablen oben: OS-Dunkelmodus
   ohne manuelle Übersteuerung, dann die explizite "dunkel"-Auswahl übers
   Umschalt-Icon — unabhängig vom OS. */
@media (prefers-color-scheme: dark){
  :root:not([data-theme="light"]) body.auth-page{ background-image:var(--bg-auth-dark); }
}
:root[data-theme="dark"] body.auth-page{ background-image:var(--bg-auth-dark); }
/* Widescreen/Ultrawide (≥ 19:9 Seitenverhältnis): eigene "wide"-Bildvariante
   statt die normale einfach hochzuskalieren. */
@media (min-aspect-ratio:19/9){
  body.auth-page{ background-image:var(--bg-auth-light-wide); }
  :root[data-theme="dark"] body.auth-page{ background-image:var(--bg-auth-dark-wide); }
}
@media (prefers-color-scheme: dark) and (min-aspect-ratio:19/9){
  :root:not([data-theme="light"]) body.auth-page{ background-image:var(--bg-auth-dark-wide); }
}

.icon-btn{ background:none; border:1px solid var(--line); border-radius:8px; width:34px; height:34px; display:inline-flex; align-items:center; justify-content:center; cursor:pointer; color:var(--ink-soft); }
.icon-btn:hover{ border-color:var(--accent); color:var(--accent); }

.log-box{ max-height:340px; overflow-y:auto; border:1px solid var(--line); border-radius:8px; padding:10px 12px; background:var(--paper-sunken); font-family:var(--font-mono); font-size:11.5px; line-height:1.6; color:var(--ink-soft); }
.log-box div{ white-space:pre-wrap; word-break:break-word; }

.mono{ font-family:var(--font-mono); font-size:var(--font-size-mono); font-weight:var(--font-weight-mono); font-style:var(--font-style-mono); }

.data-table{ width:100%; border-collapse:collapse; font-size:13px; }
.data-table th, .data-table td{ padding:8px 10px; text-align:left; border-bottom:1px solid var(--line); vertical-align:middle; }
.data-table thead th{ color:var(--ink-faint); font-weight:700; text-transform:uppercase; font-size:10.5px; letter-spacing:.04em; }
.data-table tbody tr:last-child td{ border-bottom:none; }
.data-table td form{ display:inline; }

.filter-rail{ display:flex; gap:10px; flex-wrap:wrap; align-items:flex-end; margin-bottom:16px; }
