/* ct-version: 20260902-32 */
/* ct: Artikelseite nach mockup-artikel.html.
   ⚠️ 20260819-4 ist eine SELEKTOR-KORREKTUR: die Fassung -3 war zu grossen
   Teilen wirkungslos, weil sie gegen geratenes Markup gebaut war. Am echten
   DOM (DDEV, 19.08., axi) nachgemessen gilt:
     .product-info      = die Bootstrap-SPALTE (col-lg-6), NICHT die Kaufbox
     .product-info-inner= die Kaufbox (hier sitzt jetzt Rahmen/Polster/sticky)
     .quantity-wrapper  existiert NICHT -> #quantity-grp (input-group)
     .articlenumber/.product-sn/.product-attributes existieren NICHT
                        -> ul.info-essential > li.product-sku / li.product-category
     .square nutzt ::before{padding-bottom:100%} fuer das Seitenverhaeltnis
   ⚠️ button[name="inWarenkorb"] gibt es ZWEIMAL (Fehlerregister 13): der erste
   ist NOVAs verstecktes .btn-hidden-default direkt im form#buy_form. Alle
   Kauf-Regeln sind deshalb auf #add-to-cart gescopet, nie auf den nackten
   Namensselektor. */
:root{--ct-css-artikel:'20260902-32'}

/* --- Content-Flucht ------------------------------------------------------- */
/* ct: 20260819-9 — die BREITE steht nicht mehr hier (war Fehlerregister 17:
   dieselbe max-width/padding-Regel lag zweimal im Projekt, in
   ct-kategorie.css fuer .is-item-list und hier fuer :has(.product-detail),
   waehrend Startseite und Inhaltsseiten leer ausgingen — bei 1920 lief
   dieser Wrapper sogar linksbuendig 0..1600, weil das margin:auto fehlte).
   Flucht + Neutralisierung der inneren .container liegen jetzt EINMAL in
   ct-base.css auf #content-wrapper; hier bleibt das Vertikalmass. */
/* Vertikalmass aus dem zentralen Raster (ct-base.css) — identisch zur
   Artikelliste, deshalb dasselbe Token und keine eigene Media Query. */
#content-wrapper:has(.product-detail){padding-top:var(--ct-stack-lg)}

/* --- Spaltenverhaeltnis (Mockup: Galerie 1fr / Kaufbox 424 / Gap 56) ------ */
/* ct: NOVA gibt beiden Spalten col-lg-6 (je 625px bei 1440) — das Mockup will
   eine schmale Kaufbox neben einer breiten Buehne. 496 = 56 (Gap, als
   padding-left der Spalte) + 424 (Kaufbox) + 16 (NOVAs Spaltenpolster
   rechts). Die Galerie-Spalte gibt ihr rechtes Polster ab, damit der Gap
   exakt 56 bleibt und nicht 72 wird. */
@media (min-width: 992px){
  /* ct: ⛔ 20260819-11 — `min-width:0` ist hier KEIN Feinschliff, sondern der
     Fix fuer einen Totalausfall des zweispaltigen Layouts (Fehlerregister 15 /
     NOVA-LIVE-LEHREN I.3). Seit der Bildmigration hat der B03 sieben Bilder;
     slick legt dafuer einen `.slick-track` mit INLINE `width:9618px` an.
     Ein Flex-Item hat `min-width:auto` und schrumpft nie unter seine
     min-content-Breite — gemessen 9636px. Die Galerie-Spalte konnte deshalb
     nicht auf ihren Anteil schrumpfen, die Bootstrap-Row (flex-wrap:wrap) hat
     umgebrochen und die Kaufbox stand UNTER der Galerie:
       vorher  Galerie x24 y331 1392x908 | Kaufbox x24 y1239 496x927
       nachher Galerie x24 y331  840x... | Kaufbox x880 y331 496x...
     `overflow:hidden` an `.slick-list` hilft dagegen nicht — es begrenzt den
     Ueberlauf, nicht die intrinsische Mindestbreite. */
  #product-offer > .product-gallery{flex:1 1 0;max-width:none;padding-right:0;min-width:0}
  /* ct: 20260820-26 (Ben: "das VERHÄLTNIS stimmt doch nicht zwischen Bild /
     Buybox") — die feste 496px-Kaufbox stammte aus dem FALSCHEN Mockup
     (424+56+16). Das v1-Mockup misst: Kaufbox-Karte 38,5% der Contentbreite,
     Galerie (inkl. Thumbs) ~57%, Verhältnis ~1,5:1 — die Kaufbox ist fast so
     praesent wie das Bild. Anteilig statt fix, damit das Verhaeltnis auf
     jeder Breite haelt: Basis = Karte 38,5% + 56px Gap (als padding-left). */
  #product-offer > .product-info{
    flex:0 0 calc(38.5% + 56px);
    max-width:calc(38.5% + 56px);
    padding-left:56px;
  }
}

/* --- Kaufbox als kantige Karte ------------------------------------------- */
/* ct: Rahmen/Polster/sticky sitzen auf .product-info-INNER, nicht auf der
   Spalte: auf der Spalte lief der Rahmen mobil bis an die Viewportkante
   (gemessen 0..390) und deckelte ausserdem die Galeriehoehe mit.
   ⚠️ KEIN margin-bottom am sticky-Element — das deckelt den Klebeweg
   (Fehlerregister 5). */
#product-offer .product-info-inner{
  border:1px solid var(--ct-line);
  padding:20px;
  border-radius:var(--ct-radius-lg); /* ct: 20260820-23 — Rolle grosser Container (Kaufbox) */
}
@media (min-width: 992px){
  #product-offer .product-info-inner{padding:28px}
}

/* --- STICKY: die GALERIE klebt, nicht die Kaufbox ------------------------- */
/* ct: Ben-Direktive 19.08.2026 - "Bild und Galerie sollen mit runterscrollen
   wie beim spanl-Projekt". Mechanik 1:1 von spanl NOVAChild571
   (css/spl-artikel.css), auf unsere Struktur adaptiert. Drei Teile, alle
   drei sind noetig:

   1. `align-self:stretch` an der Spalte. Die Bootstrap-Row steht auf
      `align-items:flex-start`; ohne stretch waere die Spalte nur so hoch wie
      ihr Inhalt und `sticky` haette gar keinen Weg zum Kleben.
   2. Der Offset. Unser Kopf ist `position:sticky; top:0` und bleibt beim
      Scrollen mit KONSTANTER Hoehe oben stehen - nachgemessen bei scrollY
      77/400/900/1600: 159px ab 1200px Fensterbreite, 263px zwischen 992 und
      1199 (dort bricht die Navi auf zwei Zeilen um; bei scrollY 1200
      gegengemessen). Ohne Offset schoebe sich die Galerie unter den Kopf.
      Der Zuschlag ist das Rollen-Token --ct-stack-md, kein freier Pixelwert.
   3. `:not(.fullscreen)` ist KEIN Schmuck, sondern der Guard fuer NOVAs
      Bildvergroesserung: die Lightbox ist kein Modal, sondern ein Zustand
      DIESES Elements - der Klick haengt `.fullscreen` an #image_wrapper und
      my-nova.css macht daraus `position:fixed` als Vollbild-Overlay. Unser
      Selektor ist mit (2,2,1) spezifischer als NOVAs
      `#image_wrapper.fullscreen` (1,1,0) und wuerde das `fixed` sonst
      ueberschreiben - bei spanl war genau das Bens Befund "riesige weisse
      Flaeche, Bild abgeschnitten".

   WICHTIG: KEIN margin-bottom am klebenden Element (Fehlerregister 5) - es
   wuerde den Klebeweg deckeln.

   WICHTIG: Die KAUFBOX ist ab -11 bewusst NICHT mehr sticky. Gemessen ist sie
   bei 1440x900 genau 927px hoch; mit `top:22px` (Stand -10) stand sie
   ausserdem unter dem 159px hohen Kopf. Selbst mit korrektem Offset waere
   ihre Unterkante bei 183+927=1110 gelandet - die letzten ~210px (Zahlarten)
   waeren auf einem 900px-Viewport NIE sichtbar gewesen. Kleben darf immer nur
   die KUERZERE Spalte; hier ist das die Galerie. */
@media (min-width: 992px){
  #product-offer{--ct-pdp-sticky:calc(263px + var(--ct-stack-md))}
}
@media (min-width: 1200px){
  #product-offer{--ct-pdp-sticky:calc(159px + var(--ct-stack-md))}
}
@media (min-width: 992px){
  #product-offer > .product-gallery{align-self:stretch}
  #product-offer > .product-gallery > #image_wrapper:not(.fullscreen){
    position:sticky;
    top:var(--ct-pdp-sticky);
    margin-bottom:0;
  }
}

/* --- Kicker + Ueberschrift ------------------------------------------------ */
/* ct: Der Kicker kommt aus productdetails/details.tpl (Kategorie aus dem
   Brotkrumen). Herstellerstufe entfaellt: kHersteller ist bei ALLEN 14
   Artikeln 0 — ein leeres " · " waere erfundene Struktur. */
#product-offer .ct-akicker{
  display:block;
  margin-bottom:12px;
  font-family:var(--ct-font-text);
  font-size:11px;font-weight:600;line-height:1;
  letter-spacing:.14em;text-transform:uppercase;
  color:var(--ct-muted);
}
/* ct: 20260819-9 — die FARBE steht nicht mehr hier. NOVAs rgb(82,82,82) auf
   Ueberschriften ist ein Grundwert und wird seit ct-base.css 20260819-4
   global auf --ct-text gezogen; die lokale Fassung war die zweite Kopie
   derselben Regel (Fehlerregister 17). */
/* ⛔ ct: 20260820-28 — `overflow-wrap` GEHOERT AN DIE BASISREGEL, NICHT IN DIE
   MOBIL-AUSNAHME (Fehlerregister 15 + 17).
   Gemessen bei EXAKT 992px Fensterbreite: die Kaufbox ist dort am schmalsten,
   die die zweispaltige Ansicht kennt (38,5 % von 944 + 56 = 419px Spalte,
   345px Innenraum). Der Artikelname brauchte 366px — `.product-headline`
   scrollWidth 366 gegen clientWidth 289 — und schob die Kette bis zum
   Dokument durch: html scrollWidth 1000 bei clientWidth 992, `scrollX` nach
   `scrollTo(9999,0)` = 8. Also 8px echter horizontaler Scroll, nur auf der
   Artikelseite und nur an diesem Breakpoint.
   Bis -27 stand die Umbruch-Erlaubnis ausschliesslich in der 767er-Media-Query
   — genau die Ausnahme-statt-Grundwert-Falle aus Fehlerregister 17. Sie kostet
   nichts, wo der Titel passt (break-word bricht nur, wenn es sonst
   ueberliefe), und rettet jede Breite, an der er nicht passt.
   ⚠️ `min-width:0` an den beiden Spalten ist die zweite Haelfte: ein
   Flex-/Grid-Kind schrumpft sonst nie unter sein laengstes Wort. Fuer die
   Galerie-Spalte steht es schon oben (slick-Track), die Kaufbox-Spalte hatte
   es nicht. */
#product-offer .product-headline .product-title{
  font-size:32px;line-height:1.05;letter-spacing:-.02em;
  margin-bottom:0;
  overflow-wrap:break-word;
}
#product-offer > .product-info,
#product-offer .product-info-inner,
#product-offer .product-headline{min-width:0}

/* ct: 20260820-27 — SPEC-CHIPS UNTER DEM TITEL (v1: vier graue Pillen).
   Die Chip-Optik ist DIESELBE wie auf der Produktkarte (.ct-spec, definiert in
   ct-startseite.css unter .ct-pgrid) — hier nur die Zeile darum, damit es
   EIN Baustein bleibt (Fehlerregister 13). Weil die Kartenfassung auf
   `.ct-pgrid` gescopet ist, tragen die Chips der Kaufbox ihre Flaeche hier
   selbst; Werte identisch, kein zweiter Ton.
   ⚠️ Zeile rendert nur mit gepflegten Merkmalen (Guard im Template) —
   auf diesem Datenstand existiert sie im DOM gar nicht. */
#product-offer .ct-aspecs{
  display:flex;flex-wrap:wrap;gap:6px;
  margin-top:var(--ct-stack-sm);
}
#product-offer .ct-aspecs .ct-spec{
  padding:4px 9px;background:var(--ct-band-paper);color:var(--ct-text);
  border-radius:var(--ct-radius-sm);
  font-size:11.5px;line-height:1.35;
}

/* --- Meta (Artikelnummer) ------------------------------------------------- */
#product-offer .info-essential{
  margin:14px 0 0;
  font-size:12.5px;line-height:1.5;color:var(--ct-muted);
}
#product-offer .info-essential strong{font-weight:600;color:var(--ct-muted)}
#product-offer .info-essential a{color:var(--ct-muted)}
#product-offer .info-essential a:hover{color:var(--ct-text)}
/* ct: Die Kategorie steht seit -4 als Kicker ueber der H1 — die Zeile in der
   Meta-Liste waere eine Dopplung. Das schema.org-itemprop bleibt im DOM
   (Microdata wird aus dem DOM gelesen, nicht aus dem Rendering). */
#product-offer .info-essential .product-category{display:none}
/* ct: 20260820-27 (Ben, 20.08.2026) — GTIN- UND HAN-ZEILE RAUS AUS DER KOPFZONE.
   Bens Befund am Live-DDEV-Stand: unter der Artikelnummer standen zwei weitere
   rohe Label/Wert-Zeilen ("GTIN: 4251885273706", "HAN: 5273706") — Datenblatt-
   Angaben an einer Stelle, die im v1-Mockup nur Kicker, Titel, Chips und Preis
   traegt. Sichtbar stehen beide jetzt ausschliesslich in der Karte
   "Technische Daten" (Fehlerregister 13: eine sichtbare Quelle).
   ⚠️ `display:none` statt Template-Loeschung ist hier PFLICHT: die `<li>`
   tragen `itemprop="gtin13"`/`gtin8`, und Microdata wird aus dem DOM gelesen.
   Wer das Markup entfernt, nimmt dem Rich Snippet die GTIN — dieselbe
   Ueberlegung wie eine Zeile darueber bei der Kategorie. */
#product-offer .info-essential .product-ean,
#product-offer .info-essential .product-han{display:none}

/* --- Kurzbeschreibung als Kasten unter der Kaufzone (Ben, 20.08.2026) ------ */
/* ct: 20260820-27 — Die alte Regel fuer NOVAs `.shortdesc` ist ersatzlos
   entfallen: der Block ist an NOVAs Platz (ueber dem Preis) leer definiert,
   dort trifft nichts mehr (Fehlerregister 17).
   SOLL ist Bens Live-Shop-Vorbild: ein ruhiger Kasten UNTER der Kaufzone mit
   Innenabstand und einem Sprunglink zu den Produktdetails. Statt der fetten
   Titel-Doppelzeile des Live-Shops traegt der Kasten den CI-Kicker
   "Kurzbeschreibung" — Bens Kennzeichnungs-Wunsch, gleicher Baustein wie die
   Sektionskicker (.ct-kick, ct-startseite.css), keine zweite Fassung.
   Flaeche und Radius aus den Rollen-Tokens (--ct-band-paper wie die
   Sektionsbaender und die Spec-Chips, --ct-radius = Rolle Karte). */
#product-offer .ct-shortbox{
  margin-top:var(--ct-stack-md);
  padding:var(--ct-stack-sm) 18px 18px;
  background:var(--ct-band-paper);
  border-radius:var(--ct-radius);
}
#product-offer .ct-shortbox-kick{margin-bottom:10px}
/* ct: Lesemass auch hier — die Kaufbox ist zwar schmal, aber der Crawl-Text
   bringt eigene Bloecke mit; ohne Typografie liefen NOVAs Bootstrap-Defaults
   durch (1rem-Sammelabstand an jedem <p>, Listen ohne Einzug). */
#product-offer .ct-shortbox-body{
  max-width:62ch;
  font-size:14px;line-height:1.6;color:var(--ct-text);
}
#product-offer .ct-shortbox-body p{margin:0 0 10px}
#product-offer .ct-shortbox-body p:last-child{margin-bottom:0}
#product-offer .ct-shortbox-body ul,
#product-offer .ct-shortbox-body ol{margin:0 0 10px;padding-left:20px}
#product-offer .ct-shortbox-body li{margin-bottom:3px}
#product-offer .ct-shortbox-body strong,
#product-offer .ct-shortbox-body b{font-weight:700}
/* ct: Sprunglink mit echtem Ziel (#tab-description, Guard im Template). */
#product-offer .ct-shortbox-more{
  display:inline-block;margin-top:12px;
  font-size:12px;font-weight:700;letter-spacing:.08em;text-transform:uppercase;
  color:var(--ct-cta);text-decoration:none;
}
#product-offer .ct-shortbox-more:hover{color:var(--ct-cta-d);text-decoration:underline}

/* --- Preiszone: helle Box mit Volt-Kante (v1) ----------------------------- */
/* ct: 20260820-27 — SOLL v1: der Preis sitzt in einer hellen Papier-Box mit
   gruener Kante links, die USt-/Versandzeile steht IN derselben Box unter dem
   Betrag. IST bis -26: nackter Betrag auf Weiss, Hinweiszeile darunter frei
   stehend.
   Die Box ist NOVAs vorhandener `.price_wrapper` — kein zusaetzliches Markup.
   Gemessen enthaelt er `.price.h1`, zwei `<meta>` und `.price-note` (darin
   `.vat_info`); das "ab" davor rendert NOVA selbst als
   `.price_label.pricestarting` — mit genau dem Guard, den v1 verlangt
   (Variationsaufpreis oder Konfigurator vorhanden). Auf diesem Datenstand hat
   KEIN Artikel Variationen, deshalb steht heute kein "ab" da; das ist der
   Guard bei der Arbeit, kein fehlendes Element (Fehlerregister 8 — nichts
   behaupten, was die Daten nicht hergeben).
   ⚠️ Die Kante liegt als border-left INNEN, nicht als Overlay auf der Kante:
   ein absolut gesetzter Balken auf der Boxkante waere beim Rundungs-Clipping
   angeschnitten (Fehlerregister 2 / FEHLERMUSTER 2). */
#product-offer .price_wrapper{
  margin-top:20px;
  padding:16px 20px;
  background:var(--ct-band-paper);
  border-left:4px solid var(--ct-volt);
  border-radius:var(--ct-radius-sm);
  /* ct: der Volt-Balken sitzt links, die Rundung darf ihn nicht abschneiden */
  border-top-left-radius:0;border-bottom-left-radius:0;
}
/* ct: "ab" steht als eigene Zeile-Inline VOR dem Betrag; NOVA rendert es als
   Geschwister des .price-Blocks, der `display:block` ist — ohne Umbau stuende
   es allein auf einer Zeile. Der Flex-Kontext legt beide auf eine Grundlinie. */
#product-offer .price_wrapper{display:flex;flex-wrap:wrap;align-items:baseline;gap:8px}
#product-offer .price_wrapper .price_label.pricestarting,
#product-offer .price_wrapper .price_label.nowonly{
  order:1;
  font-family:var(--ct-font-text);
  font-size:14px;font-weight:600;color:var(--ct-muted);
}
#product-offer .price_wrapper .price{
  order:2;
  margin-bottom:0;
  font-family:var(--ct-font-display);font-weight:900;font-size:46px;line-height:1;
  color:var(--ct-text);
}
/* ct: Die Hinweiszeile bricht als volle Zeile unter den Betrag (order 3 +
   volle Breite), damit sie nicht neben ihm klebt. */
#product-offer .price_wrapper .price-note{order:3;flex:0 0 100%;margin-bottom:0}
#product-offer .price-note,
#product-offer .vat_info{font-size:12px;line-height:1.5;color:var(--ct-muted)}
#product-offer .vat_info a{color:var(--ct-muted);text-decoration:underline}

/* --- Lieferstatus --------------------------------------------------------- */
#product-offer .stock-information{
  margin-top:0;padding-top:18px;
  border-top:1px solid var(--ct-line);
}
#product-offer .delivery-status{font-size:13px;line-height:1.5}
#product-offer .question-on-item .btn-link{
  padding:0;font-size:12px;color:var(--ct-muted);
}
#product-offer .question-on-item .btn-link:hover{color:var(--ct-text)}

/* --- Menge + CTA: EINE Hoehe fuer die ganze Gruppe ------------------------ */
/* ct: Gemessen vorher 43px (Stepper) gegen 54px (CTA) — genau der Fall aus
   Fehlerregister 11. Die Hoehe wird EINMAL gesetzt und von allen Teilen
   getragen; NOVAs max-height-Deckel muss dabei mit aufgehoben werden
   (NOVA-LIVE-LEHREN I.6), und die input-group-Wrapper brauchen die Hoehe
   selbst, sonst faellt das Prozent der Kinder still auf auto. */
/* ct: 20260820-27 (Ben-Beanstandung Stepper) — DIE HOEHE STEHT JETZT AN GENAU
   ZWEI ELEMENTEN: an der Stepper-GRUPPE und am CTA. Bis -26 trug sie zusaetzlich
   jedes Kind der Gruppe; im 52px-Innenraum der gerahmten Gruppe ergaben die
   54px der Kinder einen 1px-Ueberstand oben UND unten (gemessen, s. ct-base.css
   20260820-17) — vier Hoehenquellen statt einer, also genau Fehlerregister 11.
   Die Kinder stehen ab hier auf `height:auto` (ct-base.css) und werden vom
   Flex-Stretch der Gruppe gefuellt: EINE Quelle, gemeinsame Kanten.
   Der Wert kommt aus dem Rollen-Token, nicht als Pixelwert. */
#add-to-cart #quantity-grp,
#add-to-cart button[name="inWarenkorb"]{
  height:var(--ct-control-h-lg);max-height:none;
}
/* ct: 20260820-24 — die Rundung des Steppers steht NICHT hier, sondern EINMAL
   an der Basis auf `.input-group.form-counter` (ct-base.css): denselben
   Zaehler rendert NOVA auch im Warenkorb (#quantity-grp0), und gemessen war
   er dort nach der ersten Fassung noch kantig, waehrend die PDP-Fassung
   rundete — Fehlerregister 13 (ein Baustein, mehrere Instanzen) und 17
   (Fix nur dort, wo gerade jemand hinsieht). Hier bleibt nur die
   PDP-eigene HOEHE. */
#add-to-cart button[name="inWarenkorb"]{border-radius:var(--ct-radius-sm)}
/* ct: 20260820-27 — die Zeile `…{border-color:var(--ct-line)}` fuer die
   Stepper-Kinder ist ERSATZLOS ENTFALLEN: die Kinder haben seit dem
   Basis-Fix gar keinen Rahmen mehr, nur noch die beiden Naehte, und die
   stehen mit ihrem Ton in ct-base.css. Eine Regel, die nichts mehr trifft,
   waere die Zweitfassung aus Fehlerregister 17. */
#add-to-cart #quantity-grp .form-control{
  font-family:var(--ct-font-display);font-weight:700;font-size:16px;
  color:var(--ct-text);
}
#add-to-cart #quantity-grp .btn{background:#fff;color:var(--ct-muted)}
#add-to-cart #quantity-grp .btn:hover{background:var(--ct-paper);color:var(--ct-text)}

/* ct: Mockup-Verhaeltnis Stepper/CTA — NOVA gibt beiden col-sm-6 (je 50%).
   Der Stepper braucht nur seine Eigenbreite, der CTA nimmt den Rest.
   ⚠️ 156 ist zweimal nachgemessen, nicht geschaetzt — beide Nachbarn haben
   eine harte Untergrenze und sie stehen gegeneinander:
   • Zahlenfeld: 156 - 32 (Spaltenpolster) - 88 (beide Knoepfe) = 36px
     Aussenbreite. NOVAs 15px-Polster je Seite hat davon 30 gefressen und die
     Ziffer auf 2px Inhalt beschnitten — deshalb das schmalere Polster unten;
     damit bleiben 28px Inhalt, genug fuer dreistellige Mengen.
   • CTA: brauchte bei nowrap 206px und hatte nur 186 — das Warenkorb-Symbol
     brach auf eine dritte Zeilenbox um (gemessen: 153x16 | 153x16 | 16x13).
     Mit 156 statt 180 misst der Knopf 212px bei 176px Textbedarf.
   ⚠️ Das ist eine inhaltsabhaengige Rechnung (NOVA-LIVE-LEHREN I.3b): ein
   deutlich laengeres Label — andere Sprache, geaenderter {lang}-String —
   bricht wieder um. Der Umbruch ist der bewusst gewaehlte Ausfallmodus
   (kein nowrap), damit nichts aus dem Knopf laeuft. */
@media (min-width: 576px){
  #add-to-cart .basket-form-inline > .col:first-child{flex:0 0 156px;max-width:156px}
  #add-to-cart .basket-form-inline > .col:last-child{flex:1 1 0;max-width:none}
}
#add-to-cart #quantity-grp .form-control{padding-left:4px;padding-right:4px}

/* --- Kauf-CTA ------------------------------------------------------------- */
/* ct: 20260820-23 (Ben, 20.08.2026) — Kauf-CTA auf CI-Blau (v1-Mockup:
   "In den Warenkorb" in der Kaufbox ist derselbe blaue Primaerknopf wie in
   der Kachel und im Header). Der Knopf traegt zwar .btn-primary, bekommt die
   Farbe hier aber weiterhin explizit: die Regel setzt auch Schrift und
   Groesse, und ein Attributselektor (0,1,1) unter #add-to-cart (1,1,1)
   wuerde die Basisregel sonst nur zur Haelfte begleiten. */
#add-to-cart button[name="inWarenkorb"]{
  background:var(--ct-cta);
  border-color:var(--ct-cta);
  color:#fff;
  font-family:var(--ct-font-text);
  font-weight:800;font-size:13px;
  letter-spacing:.1em;text-transform:uppercase;
}
#add-to-cart button[name="inWarenkorb"]:hover,
#add-to-cart button[name="inWarenkorb"]:focus{
  background:var(--ct-cta-d);border-color:var(--ct-cta-d);color:#fff;
}
/* ⛔ Top-Befund der Abnahme: der Kauf-Button war mobil UNBESCHRIFTET —
   348x54 ohne ein Wort. NOVA haengt an das Label-span d-none d-md-inline,
   und .d-none traegt Bootstraps !important. Hier ist !important deshalb
   Pflicht und kein Nachdruck: die Gegenregel liegt auf der important-Ebene,
   auf der die Spezifitaet entscheidet (Fehlerregister 16) —
   #add-to-cart … .btn-basket-check span = (1,1,1) schlaegt .d-none = (0,1,0). */
#add-to-cart button[name="inWarenkorb"] .btn-basket-check span{
  display:inline!important;
}

/* --- Zahlarten-Chips in der Kaufbox --------------------------------------- */
/* ct: gleiche Quelle wie im Fuss (snippets/ct_paychips.tpl) — die Chips sind
   dort fuer den dunklen Grund gestylt (.ct-paychip mit --ct-dline und weisser
   Schrift). Hier die helle Fassung ueber den Kontext, ohne die Klasse im
   Snippet aendern zu muessen. */
#product-offer .ct-paybox{
  margin-top:22px;padding-top:20px;
  border-top:1px solid var(--ct-line);
}
#product-offer .ct-paybox-head{
  display:block;margin-bottom:12px;
  font-size:11px;font-weight:700;letter-spacing:.12em;text-transform:uppercase;
  color:var(--ct-muted);
}
/* ct: 20260820-30 (Befund 8) — `align-items:stretch` gehoert hier MIT hin.
   Die Hoehenregel der Chips liegt seit ct-footer.css -12 an der ZEILE, nicht
   mehr am Chip (Register 11: eine Quelle je Gruppe). Die PDP rendert dieselben
   Chips in einer ZWEITEN Huelle (`.ct-paybox-chips` statt `.ct-payrow`) —
   Fehlerregister 13. Ohne diese Zeile hinge die PDP-Zeile im Default und die
   zweizeilige Nachnahme-Zahlart haette ihre Nachbarn NICHT mitgezogen. */
#product-offer .ct-paybox-chips{display:flex;flex-wrap:wrap;align-items:stretch;gap:8px}
#product-offer .ct-paybox .ct-paychip{
  border-color:var(--ct-line);
  color:var(--ct-muted);
}
/* ct: 20260820-23 — Radius kommt aus der EINEN Chip-Quelle (.ct-paychip in
   ct-footer.css); hier steht bewusst nur die helle Farbfassung. */

/* --- Merken / Vergleichen: beschriftet unter dem CTA (v1) ----------------- */
/* ct: 20260820-27 — UMZUG, KEIN DUPLIKAT.
   Bis -26 sassen die beiden Aktionen als runde Icon-Knoepfe oben rechts auf
   der Galerie-Buehne (NOVAs Platz) und der Bericht fuehrte die fehlende
   Beschriftung als bewusste Abweichung. v1 zeigt sie beschriftet unter dem
   Kauf-CTA — und das geht ohne Fehlerregister 13, weil hier NOVAs ECHTES
   `.product-actions`-Element steht: der Platz auf der Buehne ist im Child leer
   definiert (productdetails/image.tpl), die Beschriftung kommt aus den
   Snippet-APIs (`buttonAndText`), der Handler bleibt an
   `*[data-toggle="product-actions"] button` innerhalb #result-wrapper
   verdrahtet (NOVA-LIVE-LEHREN N.6).
   Die frueheren `.badge-circle-1`-Regeln (Kreisform mit dokumentiertem
   !important) sind damit ERSATZLOS ENTFALLEN: die beschriftete Fassung traegt
   diese Klasse gar nicht mehr. Eine Regel gegen ein Markup, das es nicht mehr
   gibt, ist die Zweitfassung aus Fehlerregister 17.
   ⚠️ Fehlerregister 3b: beide Knoepfe fuellen die volle Kaufboxbreite und
   stehen untereinander — keine halb belegte Zeile, keine zwei Breiten. */
/* ⛔ ct: 20260820-27 (Ben, 20.08.2026, ZWEITE Beanstandung derselben Stelle) —
   `position:static` IST HIER DER EIGENTLICHE FIX, nicht Deko.
   Befund aus Bens Screenshot: die beiden Knoepfe standen nach dem Umzug OBEN
   RECHTS ueber dem Artikeltitel statt unter dem Kaufknopf. Ursache gemessen in
   my-nova.css: `.product-actions{position:absolute; top:…; right:…}` — die
   Klasse bringt NOVAs Buehnen-Positionierung MIT, egal wo im DOM sie steht.
   Wer sie umzieht, ohne `position` zurueckzusetzen, verschiebt nur das
   Elternelement, nicht den Knopf (NOVA-LIVE-LEHREN I.x / Fehlerregister 10:
   umgestylte Framework-Mechanik ohne den Ursprungszustand mitzudenken).
   Bens Ansage dazu: "bau das so wie ichs jetzt im perlenprojekt wollte, als
   Buttons UNTER den Warenkorb — natuerlich desktop und mobil optimiert."
   Muster ist deshalb 1:1 perlenzentrum.de (NOVAChildPZ/css/pz-artikel.css,
   .pz-pdp-actions), in CT-Tokens uebersetzt — Mechanik uebernommen, nicht
   Optik kopiert.

   ⚠️ Raster statt flex-wrap (Fehlerregister 3b): zwei inhaltsbreite Knoepfe in
   einer Flex-Zeile liessen rechts eine Restflaeche stehen. `auto-fit` mit
   minmax gibt beiden dieselbe Breite, stapelt sie, sobald 190px je Knopf nicht
   mehr passen, und laesst den verbleibenden die volle Zeile fuellen, falls eine
   der beiden Funktionen im Shop abgeschaltet wird.
   ⚠️ EINE Hoehe fuer das Paar (Fehlerregister 11): das Mass steht als
   `min-height` am Knopf und die Grid-Reihe streckt beide auf denselben Wert —
   nicht je Knopf aus dem Inhalt (Icon vs. Text) gerechnet. */
#product-offer .ct-actions{
  position:static;
  display:grid;
  grid-template-columns:repeat(auto-fit,minmax(190px,1fr));
  gap:10px;
  margin-top:var(--ct-stack-sm);
  top:auto;right:auto;bottom:auto;left:auto;
}
#product-offer .ct-actions .btn.ct-actionbtn{
  display:inline-flex;align-items:center;justify-content:center;gap:10px;
  width:100%;
  min-height:var(--ct-control-h);
  padding:0 14px;
  border:1px solid var(--ct-line);
  border-radius:var(--ct-radius-sm);
  background:#fff;
  color:var(--ct-text);
  font-family:var(--ct-font-text);
  font-size:10.5px;font-weight:700;
  letter-spacing:.14em;line-height:1.2;text-transform:uppercase;text-align:center;
  text-decoration:none;box-shadow:none;
}
/* ct: NOVAs Wunschzettel-Fassung bringt ihren eigenen Innen-Span mit
   (.wishlist-button-inner), die Vergleichen-Fassung im Child heisst
   .ct-actionbtn-inner — beide gemeinsam angesprochen, damit das Paar EINE
   Optik hat und nicht zwei (Fehlerregister 13). */
#product-offer .ct-actions .ct-actionbtn-inner,
#product-offer .ct-actions .wishlist-button-inner{
  display:inline-flex;align-items:center;justify-content:center;gap:10px;
}
/* ct: Icons sind das einzige Farbsignal des Paares — Volt, wie die
   Kicker-Balken und die Haken der Vorteilsliste. */
#product-offer .ct-actions .ct-actionbtn .fa-list-alt,
#product-offer .ct-actions .ct-actionbtn .wishlist-icon{
  font-size:14px;color:var(--ct-volt-d);
}
/* ⚠️ ct: Die Unterstreichung sitzt NICHT am Knopf, sondern am innersten Span:
   my-nova.css setzt `.wishlist-button .wishlist-button-inner
   .wishlist-button-text{text-decoration:underline}` (0,3,0). Ein
   `text-decoration:none` am Knopf vererbt sich nicht dagegen — sonst stuende
   "AUF WUNSCHZETTEL" unterstrichen neben dem glatten Vergleichen-Knopf, also
   zwei Optiken im Paar (Fehlerregister 11/16; bei perlen am selben Tag
   aufgetreten). Anker deshalb am selben Element. */
#product-offer .ct-actions .wishlist-button-inner .wishlist-button-text{
  text-decoration:none;
}
/* ⚠️ ct: NOVA blendet Beschriftungen in solchen Knoepfen unterhalb md per
   `.hidden-xs/.hidden-sm` aus — im Paar waere das ein Knopf ohne Wort
   (Fehlerregister 9). Unsere beiden Fassungen tragen die Klassen heute nicht;
   die Regel steht als Guard, falls eine NOVA-Aktualisierung sie mitbringt.
   Sie ist billig und verhindert genau den Zustand, den Ben bei perlen
   beanstandet hat. */
#product-offer .ct-actions .hidden-xs,
#product-offer .ct-actions .hidden-sm{display:inline!important}
#product-offer .ct-actions .btn.ct-actionbtn:hover,
#product-offer .ct-actions .btn.ct-actionbtn:focus{
  border-color:var(--ct-cta);color:var(--ct-text);
  background:#fff;text-decoration:none;box-shadow:none;
}
/* ct: Zustand "steht auf der Liste" — NOVA setzt `.on-list` per AJAX. Volt als
   Bestaetigungsfarbe, gleiche Rolle wie beim aktiven Thumb. */
#product-offer .ct-actions .btn.ct-actionbtn.on-list{
  border-color:var(--ct-volt-d);
  color:var(--ct-volt-d);
}

/* --- Galeriezone ---------------------------------------------------------- */
/* ct: Weissbuehne mit Rahmen. Das Seitenverhaeltnis steckt bei NOVA in
   .square::before{padding-bottom:100%} — fuer die 4:3-Buehne des Mockups wird
   genau dieses Pseudoelement ueberschrieben (#gallery … = 1,1,0 schlaegt
   .square = 0,1,0, kein !important noetig).
   ⚠️ Die Bild-Transforms (matrix(1,0,0,1,-65,-65) plus top/left 50%) sind
   NOVAs Zentrierung und werden NICHT angefasst (NOVA-LIVE-LEHREN F.4) —
   der Kamera-Platzhalter bleibt dadurch in jeder Buehnengroesse mittig. */
#product-offer #gallery_wrapper{
  background:#fff;
  border:1px solid var(--ct-line);
  /* ct: 20260820-23 — Rolle grosser Container (Galerie-Buehne). overflow:hidden
     bewusst NICHT gesetzt: slick misst hier den Track, und die Lupe/Zoom-Schicht
     liegt absolut in der Buehne — das Bild ist ohnehin eingerueckt, es steht
     nichts in den Ecken (nachgemessen, siehe Bericht). */
  border-radius:var(--ct-radius-lg);
}
/* ct: NOVA gibt `#gallery` ein `margin-bottom:2rem` (gemessen 32px). Das
   liegt INNERHALB der gerahmten Weissbuehne und liess unter dem Bild 34px
   leeres Weiss im Kasten stehen — gemessen Rahmen 880x576 fuer ein
   540px-Bild. Der Abstand gehoert zwischen Buehne und Thumb-Strip, nicht in
   die Buehne; er kommt ab hier aus dem Rollen-Token --ct-stack-sm
   (16 / mobil 12) statt aus NOVAs Pauschalwert. */
#product-offer #gallery{margin-bottom:0}
#product-offer .product-detail-image-preview-bar{margin-top:var(--ct-stack-sm)}
#product-offer #gallery .square-image::before{padding-bottom:75%}
/* ct: Deckel gegen die Riesen-Leerflaeche. Ohne ihn waere die Buehne bei
   1920 ueber 800px hoch — fuer ein 130px-Platzhalterbild (und auch fuer ein
   echtes Produktfoto) sinnlos viel Weiss. */
/* ct: Buehnenhoehe = Mockup-Mass (.gal .main{height:540px}). Als Deckel auf
   das 4:3-Verhaeltnis, nicht als feste Hoehe: ab ca. 720px Spaltenbreite
   greift der Deckel (1440 -> Spalte 880, 75% waeren 660), darunter schrumpft
   die Buehne mit der Spalte (1200 -> 492, 992 -> 336). Ohne Deckel waere die
   Buehne bei 1920 ueber 700px hoch - fuer ein quadratisches Produktfoto
   (gemessen natural 1440x1440, object-fit:contain) sinnlos viel Weiss.
   WICHTIG: Die Bild-Transforms (matrix(1,0,0,1,-280,-280) =
   translate(-50%,-50%)) sind NOVAs Zentrierung und werden NICHT angefasst
   (NOVA-LIVE-LEHREN F.4). */
#product-offer #gallery .square-image{max-height:540px}
@media (max-width: 991.98px){
  #product-offer #gallery .square-image{max-height:380px}
}

/* ct: 20260820-26 — FULLSCREEN-RESET (Ben: "gleicher fehler wie in spanl ->
   beim klick auf das galeriebild ist das verrupft"; FEHLERMUSTER 4,
   NOVA-LIVE-LEHREN N.5). NOVAs Vollbild ist ein ZUSTAND desselben Elements
   (#image_wrapper.fullscreen -> position:fixed) — unsere Buehnenregeln
   (540px-Deckel, 75%-::before, Rahmen/Radius, gestauchte Margins) galten
   dort weiter: Bild angeschnitten, Thumbs verrutscht, Leerflaechen. Hier
   werden sie im Vollbild auf NOVAs Original zurueckgesetzt (3 IDs schlagen
   unsere 2-ID-Regeln, kein !important). */
#product-offer #image_wrapper.fullscreen #gallery_wrapper{
  border:0;
  border-radius:0;
}
#product-offer #image_wrapper.fullscreen #gallery .square-image{max-height:none}
#product-offer #image_wrapper.fullscreen #gallery .square-image::before{padding-bottom:100%}
#product-offer #image_wrapper.fullscreen #gallery{margin-bottom:2rem}
#product-offer #image_wrapper.fullscreen .product-detail-image-preview-bar{margin-top:0}

/* --- Thumb-Strip: alle Bilder in EINER Zeile ------------------------------ */
/* ct: 20260819-11 - jetzt gegen ECHTE Bilder gebaut (B03 = 7, PK2 = 4).
   Das Mockup zeigt sieben kantige Thumbs nebeneinander; NOVA rendert die
   Leiste stattdessen als slick-Karussell mit `slidesToShow:5` (hart in
   templates/NOVA/js/jtl.evo.js, Zweig 'gallery_preview' - ueber das Template
   NICHT konfigurierbar). Beim B03 waren dadurch 5 von 7 Thumbs sichtbar,
   dazu zwei Pfeile.

   Statt die Slick-Konfiguration per eigenem JS zu ueberschreiben (neue
   Skriptdatei, eigener Versionsmarker, zweite Fehlerquelle) wird die Leiste
   hier per CSS zu einem Raster gemacht. Slicks Klick-Handler bleibt dabei
   unberuehrt - er haengt delegiert an `.slick-list` und liest
   `data-slick-index`, nicht die Position.

   WICHTIG: !important ist hier PFLICHT und dokumentiert: slick schreibt
   Breite und Transform als INLINE-Style an Track und Slides (gemessen:
   `width:5054px; transform:translate3d(-1330px,0,0)` am Track, `width:250px`
   je Slide) und rechnet sie bei jedem resize neu. Das ist genau der im
   Projekt zugelassene Ausnahmefall (Inline-Style), kein Nachdruck gegen eine
   Klassenregel.

   WICHTIG: `.slick-cloned` muss raus - slick legt fuer den Endlosmodus Klone
   an (gemessen 19 Slides bei 7 Bildern). Im Karussell sind sie ausserhalb des
   Sichtfensters, im Raster stuenden sie alle nebeneinander.

   `grid-auto-flow:column` statt `repeat(7,1fr)` (Mockup-Wortlaut) und statt
   `repeat(auto-fit,...)`: das Mockup ist fuer genau sieben Bilder gezeichnet,
   real hat der PK2 vier und acht weitere Artikel je eines. `repeat(7,1fr)`
   haette bei vier Bildern 43% tote Flaeche rechts erzeugt (Fehlerregister 3b);
   `auto-fit` legte gemessen 8 Spuren fuer 7 Bilder an (die leere Spur ist
   nicht kollabiert) und liess damit rechts eine Luecke. `auto-flow:column`
   mit `minmax(0,1fr)` erzeugt IMMER genau so viele gleich breite Spalten wie
   Bilder da sind und fuellt die Zeile exakt.
   Datendrift (NOVA-LIVE-LEHREN M.9): bei sehr vielen Bildern werden die
   Thumbs schmaler statt umzubrechen — `minmax(0,...)` laesst sie beliebig
   schrumpfen, es gibt also keinen Ueberlauf und keinen Anschnitt. Bis 7
   Bildern (heutiger Hoechststand) sind es gemessen 112x84.

   Zwei NOVA-Abstaende muessen dabei weg, sonst stimmt die Rechnung nicht:
   `.slick-list` traegt einen 25px-Aussenrand als Pfeil-Rinne (gemessen: die
   Liste begann bei x65 statt x40 und war nur 831 statt 880 breit), und jeder
   `.slick-slide` traegt 8px Rand je Seite — die Kachel mass dadurch 74px in
   einer 90px-Spur. Beide Raender gehoerten zum Karussell und sind im Raster
   gegenstandslos. */
/* ct: 20260820-30 (Befund 13, Ben 20.08.2026) — SPALTENBREITE GEDECKELT.
   `minmax(0,1fr)` fuellte die Zeile zwar rechnerisch, aber nur mit SPALTEN,
   nicht mit BILDERN: gemessen an einem Artikel mit VIER Bildern (1440) waren
   die Spuren je 184px breit, der Thumb darin blieb bei 82x82 und stand
   mittig — sichtbar belegt waren 328 von 784px, also 41,8 %. Zwischen den
   Thumbs klafften 100px Leere, die wie vergessene Kacheln aussah
   (Fehlerregister 3b: die Zahl "100 % gefuellt" beschrieb das Raster, nicht
   das, was der Kunde sieht — genau die Metrik-Falle aus Register 19).
   Der Deckel ist das Thumb-Token, kein neuer Wert: die Spur ist damit so
   breit wie die Kachel, die darin steht. `justify-content:flex-start` haelt
   die Reihe linksbuendig unter der Buehne — bei sieben Bildern (heutiger
   Hoechststand) fuellt sie die Zeile weiterhin komplett, bei weniger Bildern
   steht die Luecke gesammelt rechts statt als Loch zwischen jedem Thumb.
   ⚠️ `minmax(0,...)` bleibt als Untergrenze: bei sehr vielen Bildern duerfen
   die Spuren weiterhin schrumpfen, sonst laeuft die Leiste ueber. */
#product-offer .product-detail-image-preview-bar .slick-track{
  width:100%!important;
  transform:none!important;
  display:grid;
  grid-auto-flow:column;
  grid-auto-columns:minmax(0,var(--ct-thumb-w));
  justify-content:flex-start;
  gap:var(--ct-stack-sm);
}
#product-offer .product-detail-image-preview-bar .slick-slide{
  width:auto!important;
  margin:0;
}
/* ct: ⚠️ !important ist hier PFLICHT und dokumentiert (Inline-Ausnahme, kein
   Nachdruck gegen eine Klassenregel): slick schreibt beim (Neu-)Initialisieren
   `style="display: block"` DIREKT an die Klon-Slides. Gemessen im
   Fullscreen-Zustand: `inline: "width: 146px; display: block"`, waehrend die
   Regel ohne important als Verliererin danebenstand — Ergebnis waren 19
   sichtbare Kaesten statt 7 (12 davon Klone). */
#product-offer .product-detail-image-preview-bar .slick-cloned{display:none!important}
/* ct: Pfeile brauchen !important, weil slick sie mit INLINE
   `style="display: inline-block"` einblendet (gemessen) — wieder der
   dokumentierte Inline-Ausnahmefall, nicht Nachdruck gegen eine Klasse.
   Ohne das blieben zwei 33px-Knoepfe als Flex-Geschwister der Liste stehen
   und die Leiste war nur 814 statt 880 breit. */
#product-offer .product-detail-image-preview-bar .slick-arrow{display:none!important}
/* ct: slicks Clearfix-Pseudoelemente (`.slick-track:before/:after{content:"";
   display:table}`) sind im Raster ECHTE Grid-Items und haben zwei zusaetzliche
   Spalten erzeugt — gemessen 9 Spuren fuer 7 Bilder. Genau die Messfalle
   „Pseudoelemente zaehlen mit“ aus dem Fehlerregister, hier als Bau-Fehler.
   Im Karussell (Float-Layout) waren sie noetig, im Raster sind sie schaedlich. */
#product-offer .product-detail-image-preview-bar .slick-track::before,
#product-offer .product-detail-image-preview-bar .slick-track::after{
  content:none;
}
#product-offer .product-detail-image-preview-bar .slick-list{
  height:auto;padding:0;margin:0;
}

/* ct: Thumb-Kachel. Hoehe 84px = Mockup (.thumbs span{height:84px}).
   NOVAs Quadrat-Mechanik (`.square::before{padding-bottom:100%}`) muss dafuer
   auf 0, sonst zieht das Pseudoelement die Kachel wieder auf Quadratmass. */
#product-offer .product-detail-image-preview-bar .square-image{
  height:var(--ct-thumb-h);
  /* ct: 20260820-23 — Thumb-Kachel = Rolle Bedienelement. */
  border:1px solid var(--ct-line);border-radius:var(--ct-radius-sm);background:#fff;
}
#product-offer .product-detail-image-preview-bar .square-image::before{
  padding-bottom:0;
}
/* ct: Das Innenpolster sitzt am BILD, nicht an der Kachel - NOVAs `.inner`
   ist `position:absolute` und ignoriert ein Container-Polster in der Breite,
   verschiebt sich aber in der Position (NOVA-LIVE-LEHREN F.6, dort als
   14px-Versatz im Slider aufgetreten). */
#product-offer .product-detail-image-preview-bar .square-image img{
  padding:8px;
}
/* ct: Aktiver Thumb = Mockup `.thumbs span.on`: Ink-Rahmen plus Volt-Kante
   innen unten. NOVAs eigene Aktiv-Farbe (gruen) wird damit ueberschrieben. */
#product-offer .product-detail-image-preview-bar .slick-current .square-image{
  border-color:var(--ct-ink);
  box-shadow:inset 0 -2px 0 var(--ct-volt);
}
/* ct: NOVA markiert den aktiven Thumb ZUSAETZLICH mit einem gruenen Rahmen am
   SLIDE (gemessen an `.slick-current`: `border:1px solid rgb(143,232,56)`),
   also eine Ebene ueber unserer Kachel. Sichtbar waren dadurch zwei Rahmen
   uebereinander — aussen gruen, innen Ink. Das Mockup kennt genau einen.
   Der Slide-Rahmen bleibt als transparente 1px-Spur stehen, damit sich die
   Kachelbreite nicht aendert (gemessen 112px Spur, 110px Kachel). */
#product-offer .product-detail-image-preview-bar .slick-slide,
#product-offer .product-detail-image-preview-bar .slick-slide.slick-current{
  border-color:transparent;
}

/* --- Thumb-Strip im FULLSCREEN (NOVAs Bildvergroesserung) ----------------- */
/* ct: 20260819-19 (Korrekturpaket 1). ⛔ Befund der Abnahme: Im Vollbild war
   die Vorschauleiste zerstoert — gemessen 19 Kaesten a 23x86 mit 19x19-Bildern
   (statt 7 a 112x84 mit 82x82). Zwei Ursachen, beide nur im Fullscreen aktiv:

   1. slick initialisiert die Leiste im Vollbild NEU und schreibt dabei
      `display:block` als INLINE-Style an die 12 Klon-Slides. Unsere
      `.slick-cloned{display:none}` verlor dagegen — deshalb steht sie oben
      jetzt mit dokumentiertem !important (Inline-Ausnahme).
   2. Der Raster-Ansatz `grid-auto-columns:minmax(0,1fr)` verteilt die Spuren
      auf ALLE Slides. Mit 19 Slides in einer 1376px-Leiste bleiben 23px je
      Spur. Nach Fix 1 sind es wieder 7 Spuren — die waeren dann aber 190px
      breit, also deutlich groesser als im Normalzustand.

   Die Leiste ist im Vollbild fast doppelt so breit wie in der Seite; die
   Kachel soll ihre Groesse behalten und mittig stehen, statt sich zu strecken.
   Deshalb hier feste Spurbreite aus dem Rollen-Token und `justify-content:
   center` — kein einseitiger Leerraum (Fehlerregister 3b), keine zweite
   Kachelgroesse im Projekt.

   ⚠️ `#image_wrapper.fullscreen` (1,1,0) plus die Leisten-Klasse ist
   spezifischer als der Normalzustands-Selektor und steht danach — die
   Grundregeln oben bleiben unangetastet gueltig. */
/* ct: ⚠️ Dritte Ursache, erst nach dem Fix von 1 und 2 messbar: NOVA deckelt
   den Vollbild-Vorschau-Container auf `#gallery_preview_wrapper{max-width:760px;
   margin:0 292px}` — das ist der Platz fuer slicks feste 5 Thumbs
   (NOVA-LIVE-LEHREN N.1). Mit 7 Kacheln a 112 + 6 Luecken a 16 braucht die
   Leiste 880px; in 728px Innenraum lief das Raster beidseitig ueber und wurde
   von `.slick-list{overflow:hidden}` links UND rechts angeschnitten (gemessen:
   Liste 356..1084, Kacheln 280..1160). Der Deckel gehoert im Vollbild weg —
   dort ist die ganze Bildschirmbreite da. */
#image_wrapper.fullscreen #gallery_preview_wrapper{
  max-width:none;margin-left:0;margin-right:0;
}
#image_wrapper.fullscreen .product-detail-image-preview-bar .slick-track{
  /* minmax statt fester Spur: bis zur Bildschirmbreite behaelt die Kachel ihr
     Mass, danach schrumpft sie — Datendrift-Sicherung fuer Artikel mit vielen
     Bildern (NOVA-LIVE-LEHREN M.9), damit nie wieder etwas angeschnitten wird. */
  grid-auto-columns:minmax(0,var(--ct-thumb-w));
  justify-content:center;
}
/* Im Vollbild traegt NOVA den dunklen Grund — die Kachel braucht dort ihre
   eigene weisse Flaeche, sonst steht das Produktfoto auf Schwarz. */
#image_wrapper.fullscreen .product-detail-image-preview-bar .square-image{
  height:var(--ct-thumb-h);
  background:#fff;
}

/* --- Mobiler Galerie-Zweig: Punkte statt Thumb-Strip ---------------------- */
/* ct: NOVA hat fuer die Galerie einen EIGENEN Mobil-Zweig (NOVA-LIVE-LEHREN
   M.5): unterhalb 992px blendet es `#gallery_preview_wrapper` aus (gemessen:
   die Vorschauleiste misst dort 382x0) und schaltet stattdessen slicks Punkte
   ein. Der Thumb-Strip oben erreicht mobil also NICHTS — wer das nicht
   pruefen wuerde, lieferte hier den unbetreuten Framework-Standard aus
   (Fehlerregister 9).

   Gemessener Ausgangszustand: 7 runde Punkte, 12x12, Grund rgb(82,82,82) —
   also NOVAs Grauwert, den ct-base.css sonst ueberall abgeloest hat, und die
   einzige runde Form der Seite. Aktiv und inaktiv unterschieden sich nur ueber
   die Deckkraft.

   Sieben 39px-Thumbs statt der Punkte waeren bei 348px Buehnenbreite keine
   Verbesserung; der Punkt-Zweig bleibt, bekommt aber unsere Formensprache:
   kantig, Linienfarbe inaktiv, Ink aktiv. */
@media (max-width: 991.98px){
  #product-offer #gallery .slick-dots li,
  #product-offer #gallery .slick-dots li button{
    /* ct: 20260820-23 — 3px statt kantig: die Rolle ist ein 10px-Bedienpunkt,
       --ct-radius-sm (8px) waere darauf faktisch ein Kreis und damit wieder
       NOVAs Ausgangsform. Bewusst gesetzter Sonderwert, im Bericht benannt. */
    width:10px;height:10px;border-radius:3px;padding:0;
  }
  #product-offer #gallery .slick-dots li button{
    background:var(--ct-line);opacity:1;border:0;
  }
  #product-offer #gallery .slick-dots li.slick-active button{
    background:var(--ct-ink);
  }
}

/* --- Karte "Technische Daten" (v1: FAHRZEUGDATEN / TECHNISCHE DATEN) ------ */
/* ct: 20260820-27 — NEUE SEKTION zwischen Kaufzone und Beschreibungsband.
   SOLL v1 (mockup-artikel-v1.pdf, im PDF-Viewer angesehen): weisse Karte mit
   Kicker, Ueberschrift, zweispaltiger Werteliste (duenne Linie je Zeile) und
   einer Hinweiszeile mit ⓘ darunter.
   Auf unserem WEISSEN Seitengrund braucht die Karte eine Kante, um Karte zu
   sein — v1 setzt sie auf hellgrauen Seitengrund ab. Der globale
   Seitenhintergrund ist eine offene Ben-Frage (so notiert in ct-base.css) und
   wird hier NICHT im Vorbeigehen entschieden; stattdessen dieselbe
   Linie+Radius-Kante wie Kaufbox und Galerie-Buehne, damit die PDP EINE
   Kartensprache hat (Fehlerregister 13).
   Markup und Abstaende: productdetails/details.tpl. */
#content-wrapper:has(.product-detail) .ct-techcard{
  margin-top:var(--ct-band-y);
  padding:var(--ct-stack-lg);
  border:1px solid var(--ct-line);
  border-radius:var(--ct-radius-lg);
  background:#fff;
}
/* ct: Kopf IN der Karte — derselbe Baustein wie die Sektionskoepfe der Site
   (.ct-sechead.ct-sechead-stack aus ct-startseite.css), nur eine Stufe kleiner:
   42px waeren in einer Karte eine zweite Seitenueberschrift. Der Modifier
   aendert AUSSCHLIESSLICH die Groesse — Kicker, Balken, Abstand bleiben. */
#content-wrapper:has(.product-detail) .ct-sechead-card{margin-bottom:var(--ct-stack-lg)}
#content-wrapper:has(.product-detail) .ct-sechead-card .ct-h2{font-size:28px}
/* ct: ZWEISPALTIG — die Aufteilung macht das Template (zwei ausbalancierte
   Haelften), damit unten rechts kein Loch entsteht (Fehlerregister 3b).
   Hier nur die beiden Spuren und ihr Abstand; unter lg wird eine Spalte, weil
   zwei Label/Wert-Paare nebeneinander bei 390px keine 90px Wert mehr uebrig
   lassen (Fehlerregister 9: der Mobilzustand ist entschieden, nicht geerbt). */
#content-wrapper:has(.product-detail) .ct-techgrid{
  display:grid;grid-template-columns:1fr 1fr;
  gap:0 var(--ct-stack-lg);
}
@media (max-width: 991.98px){
  #content-wrapper:has(.product-detail) .ct-techgrid{grid-template-columns:1fr}
}
#content-wrapper:has(.product-detail) .ct-techcol{margin:0}
/* ct: Jede Zeile ist ein Label/Wert-Paar auf EINER Grundlinie mit duenner
   Trennlinie darunter — dl/dt/dd statt Tabelle, weil es eine Definitionsliste
   ist und keine Matrix. Das Paar wird per Grid gesetzt: `dt` feste Spur,
   `dd` der Rest. `min-width:0` am Wert ist Pflicht, sonst spannt eine lange
   ungetrennte Zeichenkette (GTIN, Artikelnummer) die Spalte auf
   (Fehlerregister 15). */
#content-wrapper:has(.product-detail) .ct-techcol dt,
#content-wrapper:has(.product-detail) .ct-techcol dd{
  padding:12px 0;
  border-bottom:1px solid var(--ct-line);
  font-size:14px;line-height:1.45;
  margin:0;
}
#content-wrapper:has(.product-detail) .ct-techcol{
  display:grid;grid-template-columns:minmax(120px,38%) 1fr;
}
#content-wrapper:has(.product-detail) .ct-techcol dt{
  color:var(--ct-muted);font-weight:400;
}
#content-wrapper:has(.product-detail) .ct-techcol dd{
  min-width:0;color:var(--ct-text);font-weight:600;
  overflow-wrap:break-word;
}
#content-wrapper:has(.product-detail) .ct-techcol dd a{color:var(--ct-text);text-decoration:underline}
#content-wrapper:has(.product-detail) .ct-technote{
  display:flex;gap:10px;align-items:flex-start;
  margin:var(--ct-stack-md) 0 0;
  font-size:12.5px;line-height:1.5;color:var(--ct-muted);
}
#content-wrapper:has(.product-detail) .ct-technote-icon{
  flex:0 0 16px;
  width:16px;height:16px;margin-top:1px;
  border:1px solid var(--ct-line);border-radius:50%;
  font-family:var(--ct-font-display);font-size:10px;font-weight:800;
  line-height:14px;text-align:center;color:var(--ct-muted);
}

/* --- Beschreibungsband: Tabs + Texte -------------------------------------- */
/* ct: 20260820-27 — Das Band ist jetzt eine KARTE wie die Technischen Daten
   (v1 zeigt Reiterleiste und Text in einem eigenen weissen Kasten).
   ⚠️ Bis -26 standen hier Regeln fuer `.product-tabs .card` — die haben NIE
   gegriffen: `.product-tabs` ist die `<ul>` der Reiterleiste, das mobile
   Akkordeon haengt an `.accordion#tabAccordion`. Eine Regel, die am falschen
   Anker haengt, sieht aus wie Betreuung und ist keine (Fehlerregister 9/23 —
   die Zweitansicht, die nie jemand anklickt). Der Akkordeon-Zweig ist unten
   mit dem RICHTIGEN Anker versorgt. */
#content-wrapper:has(.product-detail) .tab-navigation{
  display:block;
  margin-top:var(--ct-band-y);
  padding:var(--ct-stack-lg);
  border:1px solid var(--ct-line);
  border-radius:var(--ct-radius-lg);
  background:#fff;
}
#content .nav-tabs{border-bottom:1px solid var(--ct-line);margin-bottom:var(--ct-stack-lg)}
#content .nav-tabs .nav-link{
  /* ct: 20260820-23 — Reiter sitzen auf der Trennlinie: nur die OBEREN Ecken
     runden, sonst schwebt der aktive Reiter ueber seiner eigenen Kante. */
  border-radius:var(--ct-radius-sm) var(--ct-radius-sm) 0 0;
  border-color:transparent;
  font-size:12px;font-weight:700;letter-spacing:.12em;
  text-transform:uppercase;color:var(--ct-muted);
}
/* ct: 20260820-27 — aktive Kante in CI-BLAU statt Volt. v1 unterstreicht den
   aktiven Reiter blau; Volt bleibt der Akzent fuer Kicker und Haken. */
#content .nav-tabs .nav-link.active{
  color:var(--ct-text);border-color:transparent;
  box-shadow:inset 0 -2px 0 var(--ct-cta);
  background:transparent;
}
#content .tab-content{font-size:15px;line-height:1.62}

/* ct: 20260820-27 (Ben-Wunsch) — LANGBESCHREIBUNG MIT KICKER.
   Die Kurzbeschreibung steht als Kasten in der Kaufbox (.ct-shortbox), hier
   folgt der Langtext — beide gekennzeichnet, jede genau einmal auf der Seite
   (Fehlerregister 13).
   Der Kicker ist derselbe Baustein wie die Sektionskicker (.ct-kick mit
   Volt-Balken, ct-startseite.css) — keine dritte Kicker-Fassung; hier nur der
   Abstand um ihn herum.
   ⚠️ LESEMASS AUFGEHOBEN — ct: 20260902-32 (Ralf, 31.08.2026, Kundenbefund).
   Bis 20260820-31 stand hier `max-width:78ch` (gemessen 738px in einem
   1294px-Container bei 1440), linksbuendig ohne Zentrierung. Die Kundendaten
   auf cargotrikenord.de bringen zentrierte Ueberschriften mit (text-align:center
   im Wawi-HTML) — in der links verankerten Spalte wirkte die Beschreibung wie
   eine halb leere Seite. Ralfs Wortlaut: „Die Beschreibung nutzt nicht den
   verfuegbaren Bereich." Der Block nutzt jetzt die volle Contentbreite; die
   Zeilenlaenge steuert der Kunde ueber seine Texte (FEHLERMUSTER 11). */
#content-wrapper:has(.product-detail) .ct-desc-kick{margin-top:var(--ct-stack-lg)}
#content-wrapper:has(.product-detail) .ct-desc > .ct-desc-kick:first-child{margin-top:0}
#content-wrapper:has(.product-detail) .ct-desc-body{
  margin-top:var(--ct-stack-sm);
  font-size:15px;line-height:1.62;color:var(--ct-text);
}
/* ct: Typografie der Crawl-Texte. Der Inhalt kommt aus dem Live-Shop und
   bringt p/ul/ol/h3/b/strong mit; ohne diese Regeln laufen NOVAs
   Bootstrap-Defaults durch (h3 in Versalien-Display, Listen ohne Einzug,
   Absaetze mit 1rem-Sammelabstand). Werte aus dem vorhandenen Raster. */
#content-wrapper:has(.product-detail) .ct-desc-body p{margin:0 0 var(--ct-stack-sm)}
#content-wrapper:has(.product-detail) .ct-desc-body p:last-child{margin-bottom:0}
#content-wrapper:has(.product-detail) .ct-desc-body ul,
#content-wrapper:has(.product-detail) .ct-desc-body ol{margin:0 0 var(--ct-stack-sm);padding-left:22px}
#content-wrapper:has(.product-detail) .ct-desc-body li{margin-bottom:4px}
#content-wrapper:has(.product-detail) .ct-desc-body h1,
#content-wrapper:has(.product-detail) .ct-desc-body h2,
#content-wrapper:has(.product-detail) .ct-desc-body h3,
#content-wrapper:has(.product-detail) .ct-desc-body h4{
  margin:var(--ct-stack-md) 0 var(--ct-stack-sm);
  font-size:19px;line-height:1.2;letter-spacing:-.01em;
}
#content-wrapper:has(.product-detail) .ct-desc-body img{max-width:100%;height:auto}
#content-wrapper:has(.product-detail) .ct-desc-body a{color:var(--ct-cta);text-decoration:underline}
/* ⚠️ ct: 20260820-27 — LEERZEILEN-KETTEN AUS DEM CRAWL EINFANGEN.
   Gemessen im ausgelieferten HTML des Beispielartikels:
     …45km/h Mokick Version<br><p> <br><br><br><b> EccoStar B03 …
   Drei `<br>` hintereinander plus der Absatzabstand ergaben rund 80px weisses
   Loch mitten im Text — genau der "gewuerfelte Whitespace" aus
   Fehlerregister 3, nur kommt er hier aus den Wawi-Daten und nicht aus dem
   CSS. Die Daten gehoeren dem Kunden; die Darstellung gehoert uns:
   `br + br` blendet jede FOLGE-Leerzeile aus, die erste bleibt stehen.
   ⚠️ Kein `<br>`-Verbot: einzelne Umbrueche sind im Quelltext gewollt
   (Adressbloecke, Aufzaehlungen ohne Liste). */
#content-wrapper:has(.product-detail) .ct-desc-body br + br{display:none}
/* ct: 20260820-27 — TABELLEN AUS DEM CRAWL. Die Langbeschreibung bringt ein
   echtes `<table>` mit den Fahrzeugdaten mit (gemessen: 18 Zeilen). Ohne Regel
   liefe es als nackte Bootstrap-Tabelle ohne Linien und ohne Spaltenmass
   durch — zwei Datenblatt-Optiken auf einer Seite (Fehlerregister 13). Werte
   deshalb identisch zur Technische-Daten-Karte oben.
   `overflow-wrap` ist Pflicht: die Werte enthalten ungetrennte Ketten wie
   "L=2450 mm, B=930 mm, H=1215 mm", die die Spalte sonst aufspannen
   (Fehlerregister 15). */
#content-wrapper:has(.product-detail) .ct-desc-body table{
  width:100%;max-width:100%;
  margin:0 0 var(--ct-stack-md);
  border-collapse:collapse;
}
#content-wrapper:has(.product-detail) .ct-desc-body td,
#content-wrapper:has(.product-detail) .ct-desc-body th{
  padding:10px 0;
  border-bottom:1px solid var(--ct-line);
  font-size:14px;line-height:1.45;
  vertical-align:top;
  /* ct: `break-word`, NICHT `anywhere`: `anywhere` bricht auch dann mitten im
     Wort, wenn es nicht noetig waere — gemessen im iPhone-Screenshot stand dort
     "Höchstgeschwin / digkeit" (Fehlerregister 3, Wortriss). */
  overflow-wrap:break-word;
}
#content-wrapper:has(.product-detail) .ct-desc-body td:first-child,
#content-wrapper:has(.product-detail) .ct-desc-body th:first-child{
  width:42%;padding-right:16px;color:var(--ct-muted);
}
#content-wrapper:has(.product-detail) .ct-desc-body td p{margin:0}
/* ct: 20260820-27 — Unter 576px hat eine zweispaltige Wertetabelle keinen
   Platz mehr: bei 402px Geraetebreite bleiben fuer die Label-Spur 133px, und
   "Höchstgeschwindigkeit" braucht 150 — der Umbruch traf mitten ins Wort
   (gemessen mit echter iPhone-Kennung ueber playwright-cli, WebKit).
   Deshalb stapeln Label und Wert, genau wie die Technische-Daten-Karte dort
   auf eine Spalte geht (Fehlerregister 13: gleicher Baustein, gleiche
   Mobilentscheidung). Die Zeilenlinie wandert dabei an die `tr`. */
@media (max-width: 575.98px){
  #content-wrapper:has(.product-detail) .ct-desc-body table,
  #content-wrapper:has(.product-detail) .ct-desc-body tbody,
  #content-wrapper:has(.product-detail) .ct-desc-body tr,
  #content-wrapper:has(.product-detail) .ct-desc-body td,
  #content-wrapper:has(.product-detail) .ct-desc-body th{
    display:block;width:auto;
  }
  #content-wrapper:has(.product-detail) .ct-desc-body tr{
    padding:10px 0;border-bottom:1px solid var(--ct-line);
  }
  #content-wrapper:has(.product-detail) .ct-desc-body td,
  #content-wrapper:has(.product-detail) .ct-desc-body th{
    padding:0;border-bottom:0;
  }
  #content-wrapper:has(.product-detail) .ct-desc-body td:first-child,
  #content-wrapper:has(.product-detail) .ct-desc-body th:first-child{
    padding-right:0;margin-bottom:2px;
  }
}

/* ct: 20260820-27 — MOBILER AKKORDEON-ZWEIG, jetzt am richtigen Anker.
   NOVA schaltet ihn ueber `$isMobile` (Server-seitige UA-Erkennung), er ist
   also NICHT ueber die Fensterbreite erreichbar — geprueft wird er mit
   playwright-cli und Mobil-User-Agent (Fehlerregister 23: eine Zweitansicht,
   die nie geklickt wurde, ist ungeprueft, nicht fertig). */
#content-wrapper:has(.product-detail) .accordion > .card{
  margin-bottom:var(--ct-stack-sm);
  border:1px solid var(--ct-line);
  border-radius:var(--ct-radius);
  overflow:hidden;
}
#content-wrapper:has(.product-detail) .accordion > .card .card-header{
  background:var(--ct-band-paper);
  border-bottom:1px solid var(--ct-line);
  font-size:12px;font-weight:700;
  letter-spacing:.1em;text-transform:uppercase;color:var(--ct-text);
}

/* --- Empfehlungsband ("Weitere Fahrzeuge") -------------------------------- */
/* ct: 20260820-27 — STATISCHES RASTER STATT SLIDER (v1: "PASSENDE
   ALTERNATIVEN", vier Karten nebeneinander, kein Bedienschritt).
   Umgesetzt am TEMPLATE (productdetails/ct_recgrid.tpl), nicht per CSS gegen
   slick — dieselbe Entscheidung wie auf der Startseite. Damit sind ALLE
   frueheren Gegenregeln dieses Bandes ERSATZLOS ENTFALLEN statt tot stehen zu
   bleiben (Fehlerregister 17):
     • `.hr-sect`-Rueckfallebene — es wird kein Slider mit `title` mehr gebaut
     • `padding-right:96px` am Kopf (Platz fuer Pfeile) samt Mobil-Ausnahme
     • der komplette `.slick-arrow`-Block (Position, Hover, disabled, prev/next)
   Das Raster selbst braucht hier KEINE eigene Regel: `.ct-pgrid` und die
   Karten-Anbauten stehen in ct-startseite.css und greifen ueber die Klasse —
   EIN Baustein, eine Quelle (Fehlerregister 13). Hier bleibt nur das BAND:
   Abstand, Trennlinie.
   Vertikalmass weiter aus dem Rollen-Raster von ct-base.css:
     margin-top  = --ct-band-y   (Bandtrennung; 44 / mobil 28)
     padding-top = --ct-head-gap (Trennlinie -> Inhalt, 40 / mobil 28) */
#content-wrapper:has(.product-detail) .recommendations{
  margin-top:var(--ct-band-y);
  padding-top:var(--ct-head-gap);
  border-top:1px solid var(--ct-line);
}
/* ct: Mehrere Baender untereinander (XSell-Gruppen + Kaufverhalten +
   Aehnliche) brauchen zwischen sich denselben Rhythmus wie zum Vorgaenger —
   sonst kleben zwei Raster aneinander. Gilt ab dem ZWEITEN Kopf im Band. */
#content-wrapper:has(.product-detail) .recommendations .ct-pgrid + .ct-sechead{
  margin-top:var(--ct-band-y);
}

/* ct: 20260819-17 — TOTE FLAECHE im Empfehlungsband (Fehlerregister 3b).
   NOVA gibt der Slider-Variante `.carousel-arrows-inside` eine Pfeilrinne als
   `.slick-track{margin:0 99px}`. Gemessen standen die sechs Kacheln dadurch
   bei x123..1317 in einem Band, dessen Ueberschrift bei x40..1400 laeuft —
   198px (14,5% der Bandbreite) blanker Rand fuer Pfeile, die es hier gar
   nicht gibt: slick baut sie nur, wenn mehr Slides als `slidesToShow`
   vorhanden sind (hier 6 von 7), und gemessen existiert kein einziges
   `.slick-arrow`-Element. Auf der Startseite steht derselbe Kacheltyp ohne
   diese Klasse buendig bei x24 — zwei Fluchten fuer denselben Baustein.

   Der `:has()`-Guard nimmt die Rinne NUR weg, wenn wirklich keine Pfeile im
   Slider stehen. Kommen spaeter mehr Empfehlungen dazu (NOVA-LIVE-LEHREN M.9),
   baut slick die Pfeile, der Guard greift nicht mehr und die Rinne ist
   wieder da — statt dass die Pfeile auf den Randkacheln liegen.

   Bewusst NICHT auf die Artikelseite gescopet (Fehlerregister 17): die Rinne
   ohne Pfeile ist ueberall falsch, wo diese Slider-Variante vorkommt. Aktuell
   ist das gemessen genau eine Instanz im ganzen Shop. */
#content .carousel-arrows-inside:not(:has(> .slick-arrow)) .slick-track{
  margin-left:0;
  margin-right:0;
}

/* --- Mobil ---------------------------------------------------------------- */
/* ct: Mobil sprengte der Artikelname die 390px-Breite (gemessen: scrollWidth
   406, Taeter .product-headline — "Strassenzulassung" ist bei 32px Archivo
   ein unumbrechbares 18-Zeichen-Wort). Kleinere Stufe plus Umbruch-Erlaubnis;
   der Wortriss faengt nur den Extremfall ab (Fehlerregister 15). */
@media (max-width: 767.98px){
  /* ct: 20260820-28 — hier steht nur noch die SCHRIFTSTUFE; die
     Umbruch-Erlaubnis ist an die Basisregel gewandert (siehe dort). */
  #product-offer .product-headline .product-title{
    font-size:24px;
  }
  #product-offer .price_wrapper .price{font-size:38px}
  /* ct: Der Stepper lief mobil auf volle Kartenbreite (gemessen 308px) — eine
     Mengenangabe mit 200px Luft zwischen − und +. Gleiche Eigenbreite wie ab
     576px, damit das Bauteil ueber alle Breiten dasselbe Mass hat. */
  #add-to-cart #quantity-grp{max-width:180px}
}

/* --- Langbeschreibung: Klappe statt Textwand ------------------------------
   ct: 20260820-30 (Befund 12, Ben 20.08.2026). Markup und Begruendung der
   Mechanik stehen in productdetails/ct_desc.tpl. Hier nur die Optik:
   400px Klappe (Ben-Vorgabe; entspricht rund 15 Zeilen und damit einer
   Textmenge, die man im Vorbeigehen erfassen kann), darunter ein Verlauf,
   damit sichtbar ist, dass der Text weitergeht, und der Umschalter.
   ⚠️ Die Klappe haengt am WRAPPER-Zustand, nicht am Knopf: `:checked ~` gibt
   dem Text `max-height:none` UND blendet den Verlauf ab. Beide Zustaende sind
   real geklickt und gemessen (Fehlerregister 14). */
.ct-desc-clamp{position:relative}
/* Die Checkbox bleibt im Layout (0x0, opacity 0) statt display:none — sonst
   waere der Umschalter nicht mehr per Tastatur erreichbar. */
.ct-desc-switch{position:absolute;width:0;height:0;opacity:0;pointer-events:none}
.ct-desc-clamp .ct-desc-body{
  max-height:400px;
  overflow:hidden;
  position:relative;
}
.ct-desc-clamp .ct-desc-body::after{
  content:"";
  position:absolute;left:0;right:0;bottom:0;height:120px;
  background:linear-gradient(to bottom,rgba(255,255,255,0),#fff 88%);
  pointer-events:none;
}
.ct-desc-switch:checked ~ .ct-desc-body{max-height:none}
.ct-desc-switch:checked ~ .ct-desc-body::after{display:none}
/* Umschalter in der Optik der uebrigen Textlinks des Projekts (Fusszeile
   .ct-fcontact): Volt-Unterstrich, Displayschrift, versal. */
.ct-desc-more{
  display:inline-flex;align-items:center;gap:8px;
  margin-top:var(--ct-stack-md);margin-bottom:0;
  min-height:var(--ct-control-h);
  padding:0 2px;
  cursor:pointer;
  font-size:11.5px;font-weight:700;letter-spacing:.12em;text-transform:uppercase;
  color:var(--ct-text);
  border-bottom:2px solid var(--ct-volt);
}
.ct-desc-more:hover{color:var(--ct-cta)}
.ct-desc-more::after{
  content:"";width:7px;height:7px;flex:none;
  border-right:2px solid var(--ct-volt);border-bottom:2px solid var(--ct-volt);
  transform:rotate(45deg) translate(-2px,-2px);
}
.ct-desc-switch:checked ~ .ct-desc-more::after{transform:rotate(225deg) translate(-2px,-2px)}
/* Beschriftung folgt dem Zustand — nur EIN Text ist je sichtbar. */
.ct-desc-more .ct-desc-more-hide{display:none}
.ct-desc-switch:checked ~ .ct-desc-more .ct-desc-more-show{display:none}
.ct-desc-switch:checked ~ .ct-desc-more .ct-desc-more-hide{display:inline}
/* Tastaturfokus sichtbar machen — die Checkbox selbst ist unsichtbar. */
.ct-desc-switch:focus-visible ~ .ct-desc-more{outline:2px solid var(--ct-cta);outline-offset:3px}

/* ==========================================================================
   Zahlarten-Plugins in der Buy-Box — VORHALTUNG (Ben-Review 20.08.)
   --------------------------------------------------------------------------
   PayPal Commerce und AmazonPay injizieren ihre Buttons per phpQuery in
   woertliche NOVA-Selektoren (spanl-Recherche 20.08.):
     PayPal:  #add-to-cart (append) · Banner an #add-to-cart.product-buy ·
              #cart-checkout-btn · .cart-dropdown-buttons:first ·
              meta[itemprop=price] in #buy_form
     Amazon:  #add-to-cart (append, .lpa-button-context-payDetail) ·
              .cart-summary .card > .card-body · .cart-dropdown-buttons
   Unser Child laesst basket.tpl/basket/index.tpl im NOVA-Stock — die Anker
   existieren alle. Hier steht nur die OPTIK, damit die Buttons beim
   Aktivieren sauber einbetten statt roh anzuflanschen (spanl-Muster,
   spl-artikel.css 1546ff., auf ct-Tokens uebertragen):
   1) Amazon-payDetail: Trennlinie + Beschriftung ueber dem Button.
      ⚠️ Der kontextlose .lpa-button-context-login (0x0) bleibt bewusst
      ungestylt — sonst steht eine Trennlinie ohne Button. */
body[data-page="1"] #add-to-cart .lpa-button-context-payDetail{
  margin-top:18px;
  padding-top:16px;
  border-top:1px solid var(--ct-line);
}
body[data-page="1"] #add-to-cart .lpa-button-context-payDetail::before{
  content:"oder direkt bezahlen mit";
  display:block;
  font-size:12.5px;color:var(--ct-muted);
  margin-bottom:10px;
}
/* 2) Die Plugin-eigene Bootstrap-Row bringt Negativmargins mit und stand
      bei spanl @390 16px ueber dem Inhaltsrand — vorsorglich nullen. */
@media (max-width: 767.98px){
  body[data-page="1"] .lpa-button-content.row{
    margin-left:0;
    margin-right:0;
  }
}
/* 3) PayPal braucht KEINE Regel: der Wrapper nutzt Bootstrap-cols im
      unangetasteten #add-to-cart-Grid (halbbreite Buttons dort waren bei
      spanl ein Konfig-Thema — fehlende zweite Funding-Source, kein CSS). */
