/*
 * Platz für eigene Änderungen direkt als CSS
 * Die hier gemachten Änderungen überschreiben ggfs. andere Styles, da diese Datei als letzte geladen wird.
 */
/* lin: Startseite gruenduenger24.de — eigener gd24-Namespace, damit nichts mit NOVA kollidiert.
   Angelegt 05.08.2026 beim Aufbau der Startseite ohne OPC. */

/* lin 26.08.2026 — Palette auf "Mockup 2" umgestellt (Wunsch Jonas).
   Bewusst nur die WERTE getauscht, nicht die Variablennamen: dadurch ziehen alle
   bestehenden Regeln automatisch mit, ohne dass eine einzige Struktur- oder
   Mobil-Korrektur angefasst werden muss.

   Die Leitidee des Mockups: gedaempftes Laubgruen statt Frischgruen, GOLD statt
   Erdbraun als Akzent, Pergament statt Creme, und Spectral (Serif) fuer alles,
   was Aussage traegt — Ueberschriften und Preise.

   Tokenherkunft und Rollen: Projektinformationen/MOCKUP2-DESIGNTOKENS.md */
:root {
    /* Gruen — Marke & Aktion */
    --gd24-green-900: #233F26;  /* tiefstes Gruen: Hero-Verlaufsanfang, Text auf Gold */
    --gd24-green-700: #2F5233;  /* Marken-Dunkelgruen: ALLE Ueberschriften, Preise, Links */
    --gd24-green-500: #4E8247;  /* Primaeraktion: Kaufen-Buttons, aktive Zustaende */
    --gd24-green-400: #3C6837;  /* Hover aller CTAs */
    --gd24-green-300: #C4D2BB;  /* helles Graugruen fuer Text auf dunklem Grund */
    /* lin 28.08.2026: Topbar-Text. Mockup 2 fuehrt #CFDBC7 als Literal (Abschnitt 1,
       "Nicht-Variablen"); hier als benannte Variable, damit die Skala geschlossen bleibt.
       Gemessen auf --gd24-green-900 (#233F26): 8,07:1 — deutlich ueber AA (4,5:1),
       ein Ausweichen auf --gd24-gold-l war nicht noetig. */
    --gd24-topbar-text: #CFDBC7;  /* Topbar-Text auf Tiefgruen */
    /* lin 27.08.2026: Footer-Text auf Tiefgruen, Werte aus Mockup 2 (Sektion 10).
       Gemessen auf #233F26: #B7C6AF 6,3:1 · #9FB197 5,1:1 — beide ueber AA. */
    --gd24-footer-text:  #B7C6AF;  /* Fliesstext, Links im Footer */
    --gd24-footer-muted: #9FB197;  /* Unterzeile (Copyright, Powered by) */

    /* Gold — Akzent. Ersetzt das frühere --gd24-earth (war deklariert, nie benutzt). */
    --gd24-gold:      #B89A5A;  /* Badges, Ribbons, Kicker-Strich, aktive Unterstriche */
    /* ⚠️ Mockup 2 nennt #9C7F42. Gemessen: 3,80:1 auf Weiss, 3,40:1 auf Pergament —
       zu wenig fuer Text. Die Farbe traegt die Weiterlinks der Kategoriekacheln
       ("Zu Phacelia") und das Label ueber den Staffelkacheln, also echten Lesetext.
       Abgedunkelt auf 5,11:1 bzw. 4,57:1. Flaechen-Gold (--gd24-gold) bleibt
       unveraendert, dort steht dunkler Text drauf und der Wert stimmt. */
    --gd24-gold-d:    #856A33;  /* Gold auf hellem Grund — sonst zu wenig Kontrast */
    --gd24-gold-l:    #E4CB92;  /* Gold auf dunklem Grund: Hero-Kicker, Akzentwoerter */
    --gd24-on-gold:   #3A2E12;  /* dunkles Braun statt Schwarz auf Goldflaechen */

    /* Neutral */
    --gd24-cream:     #F6F2E7;  /* "Pergament": Sektionsgrund, USP-Leiste, Karten */
    --gd24-sand:      #E3DAC6;  /* eine Linienfarbe fuer alle Rahmen und Trenner */
    --gd24-ink:       #3A3B33;  /* Fliesstext */
    /* ⚠️ Mockup 2 nennt hier #7C7A6A. Gemessen ergibt das auf Weiss nur 4,33:1 und
       auf Pergament 3,87:1 — beides unter der AA-Schwelle von 4,5:1, und die Farbe
       traegt saemtlichen Fliesstext der Startseite plus Grundpreise und den
       USt-Hinweis. Eine Spur dunkler: 5,29:1 auf Weiss, 4,73:1 auf Pergament.
       Bewusste Abweichung vom Entwurf — Lesbarkeit schlaegt Farbtreue. */
    --gd24-muted:     #6E6C5D;  /* Sekundaertext, Grundpreis, Meta-Angaben */

    /* Schrift */
    --gd24-serif:     'Spectral', Georgia, 'Times New Roman', serif;
    --gd24-sans:      'Open Sans', -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, sans-serif;
}

/* Spectral kennt 500/600/700 — kein 800. Stuende irgendwo 800, wuerde der Browser
   die Fettung selbst berechnen ("faux bold"), was bei einer Serif sichtbar
   verschmiert. Alle frueheren 800er sind deshalb unten auf 700 gezogen. */

/* ---------- HERO ---------- */
/* lin 26.08.2026: Verlauf auf die Mockup-2-Achse gedreht — tief nach warm-mittelgruen.
   ⚠️ 118deg ist nicht kosmetisch, sondern trägt den CTA-Kontrast. Mit dem frueheren
   160deg lief die Aufhellung nach UNTEN, also genau dorthin, wo die beiden Hero-Buttons
   stehen (gemessen: Buttonmitte bei 79 % der Hero-Hoehe). Der gruene Primaerbutton
   stand dadurch auf fast gleich hellem Grund — gemessener Flaechenkontrast 1,64:1,
   noetig sind 3:1. Bei 118deg landet die helle Zone rechts oben beim Produktbild,
   die linke Textspalte bleibt durchgehend dunkel und der Button hebt sich ab. */
.gd24-hero {
    background: linear-gradient(118deg, var(--gd24-green-900) 0%, var(--gd24-green-700) 55%, #3B6540 100%);
    color: #fff;
    padding: clamp(2.5rem, 6vw, 5.5rem) 1rem;
    position: relative;
    overflow: hidden;
}
/* Der Schein am unteren Rand war hellgruen und lief mit dem Verlauf zusammen.
   Als Gold-Lasur setzt er stattdessen den Akzent, den das Mockup oben rechts
   als Radial fuehrt — hier unten, weil der Hero-Fuss an die USP-Leiste stoesst. */
.gd24-hero::after {
    content: "";
    position: absolute;
    inset: auto 0 0 0;
    height: 120px;
    background: radial-gradient(ellipse at 50% 100%, rgba(184, 154, 90, .22), transparent 70%);
    pointer-events: none;
}
.gd24-hero__inner {
    max-width: 1240px;
    margin: 0 auto;
    display: grid;
    grid-template-columns: 1.15fr .85fr;
    gap: clamp(1.5rem, 4vw, 3.5rem);
    align-items: center;
}
/* Kicker mit vorangestelltem Goldstrich (Mockup-2-Signatur). Der Strich sitzt als
   ::before im Textfluss, damit er bei Umbruch nicht allein stehenbleibt. */
.gd24-hero__kicker {
    display: flex;
    align-items: center;
    gap: .7rem;
    text-transform: uppercase;
    letter-spacing: .14em;
    font-size: .78rem;
    font-weight: 700;
    color: var(--gd24-gold-l);
    margin: 0 0 .9rem;
}
.gd24-hero__kicker::before {
    content: "";
    flex: 0 0 28px;
    height: 2px;
    background: var(--gd24-gold);
}
/* Spectral 700 statt Sans 800. Das negative letter-spacing faellt weg: es war fuer
   eine enge Grotesk gedacht und laesst eine Serif zusammenkleben. */
.gd24-hero__title {
    font-family: var(--gd24-serif);
    font-size: clamp(2.1rem, 5.5vw, 3.9rem);
    line-height: 1.12;
    font-weight: 700;
    margin: 0 0 1.1rem;
    color: #fff;
    letter-spacing: 0;
}
/* Akzentwort in Gold-Kursiv — im Mockup traegt jede Headline eines. */
.gd24-hero__title em { font-style: italic; font-weight: 600; color: var(--gd24-gold-l); }
.gd24-hero__lead {
    font-size: clamp(1rem, 1.6vw, 1.19rem);
    line-height: 1.65;
    max-width: 34em;
    color: rgba(255, 255, 255, .9);
    margin: 0 0 1.9rem;
}
.gd24-hero__lead strong { color: #fff; font-weight: 700; }
.gd24-hero__actions { display: flex; flex-wrap: wrap; gap: .8rem; }
.gd24-hero__media img {
    width: 100%;
    height: auto;
    border-radius: 14px;
    box-shadow: 0 22px 50px rgba(0, 0, 0, .32);
    display: block;
}

/* lin 26.08.2026: Produkt-Hero — der Topseller ist der Bildinhalt, nicht mehr ein
   Stimmungsbild. Preisanker und Vertrauenszeile stehen im Hero, damit die
   Kaufentscheidung nicht erst auf der Artikelseite beginnt. */
.gd24-hero__price {
    display: grid;
    gap: .2rem;
    margin: 0 0 1.8rem;
}
/* Preise laufen im Mockup durchgehend in Spectral — das ist das Merkmal, an dem
   die Schrift im Shop wiedererkennbar wird. */
.gd24-hero__price-value {
    font-family: var(--gd24-serif);
    font-size: clamp(2rem, 4vw, 2.7rem);
    font-weight: 700;
    line-height: 1;
    color: #fff;
    letter-spacing: 0;
}
.gd24-hero__price-unit {
    font-size: .92rem;
    color: rgba(255, 255, 255, .75);
}
/* Staffelpreis-Pille von Gruen auf Gold: sie ist ein Vorteilshinweis, kein
   Statuszustand — Gold ist im Mockup durchgehend die Akzentrolle. */
.gd24-hero__price-bulk {
    display: inline-block;
    justify-self: start;
    margin-top: .5rem;
    padding: .32rem .7rem;
    border-radius: 999px;
    background: rgba(184, 154, 90, .18);
    border: 1px solid rgba(184, 154, 90, .5);
    color: var(--gd24-gold-l);
    font-size: .88rem;
    font-weight: 700;
}
.gd24-hero__trust {
    list-style: none;
    display: flex;
    flex-wrap: wrap;
    gap: .4rem 1.4rem;
    margin: 1.6rem 0 0;
    padding: 0;
}
.gd24-hero__trust li {
    font-size: .88rem;
    color: rgba(255, 255, 255, .82);
    display: flex;
    align-items: center;
    gap: .4rem;
}
.gd24-hero__trust li::before {
    content: "✓";
    color: var(--gd24-gold-l);
    font-weight: 700;
}

/* Produktbild im Hero: Beutel freigestellt auf hellem Feld, damit er nicht
   im dunklen Verlauf verschwindet. contain statt cover — sonst wird der Beutel
   beschnitten (Fehlerklasse "unsichtbare Kartenbilder"). */
.gd24-hero__product {
    position: relative;
    display: block;
    background: #fff;
    border-radius: 18px;
    padding: 1.6rem;
    box-shadow: 0 26px 60px rgba(0, 0, 0, .34);
    transition: transform .18s ease, box-shadow .18s ease;
}
.gd24-hero__product:hover { transform: translateY(-4px); box-shadow: 0 32px 70px rgba(0, 0, 0, .4); }
.gd24-hero__product img {
    width: 100%;
    height: clamp(260px, 32vw, 420px);
    object-fit: contain;
    border-radius: 0;
    box-shadow: none;
}
/* Ribbon in Gold mit dunkelbraunem Text — im Mockup traegt jede Auszeichnung
   ("Bestseller", "Naturrasen") diese Kombination, nie weiss auf Gruen. */
.gd24-hero__badge {
    position: absolute;
    top: -.7rem;
    left: 1.4rem;
    z-index: 2;
    background: var(--gd24-gold);
    color: var(--gd24-on-gold);
    font-size: .78rem;
    font-weight: 700;
    letter-spacing: .08em;
    text-transform: uppercase;
    padding: .38rem .85rem;
    border-radius: 999px;
    box-shadow: 0 6px 16px rgba(35, 42, 29, .32);
}

/* ---------- BUTTONS ---------- */
/* inline-flex statt inline-block: die Buttons stehen in einem Flex-Container und werden
   auf gleiche Hoehe gestreckt. Bei inline-block bleibt der Text dabei oben kleben —
   gemessen 26.08.2026: Box 61,4px, Inhalt des Sekundaerbuttons nur 53,5px, die
   Differenz sass unten. Mit align-items/justify-content sitzt der Text immer mittig,
   unabhaengig davon, wie hoch der Nachbarbutton den Container macht. */
.gd24-btn {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    text-align: center;
    /* lin 27.08.2026, Design-Abgleich Block 2: Mockup-2-Button = R8, 13/26 px, 14,5 px. */
    padding: 13px 26px;
    border-radius: 8px;
    font-weight: 700;
    font-size: .90625rem;
    text-decoration: none;
    transition: transform .15s ease, box-shadow .15s ease, background-color .15s ease;
    border: 2px solid transparent;
}
.gd24-btn:hover, .gd24-btn:focus { text-decoration: none; transform: translateY(-2px); }
/* lin 26.08.2026: Primaeraktion von Hellgruen-auf-Dunkel auf das Mockup-2-Muster
   gedreht — satter gruener Knopf mit weisser Schrift. Kontrast #fff auf #4E8247
   liegt bei 4,66:1 und damit ueber der WCAG-AA-Schwelle von 4,5:1.
   Der Schatten ist gruenstichig statt neutral-schwarz, wie im Mockup durchgehend. */
.gd24-btn--primary {
    background: var(--gd24-green-500);
    color: #fff;
    box-shadow: 0 6px 16px rgba(60, 104, 55, .28);
}
/* ⚠️ Gruener Knopf auf gruenem Hero — der Flaechenkontrast liegt hier bei 2,18:1
   (WCAG 1.4.11 verlangt 3:1 fuer Bedienelemente). Das ist KEIN Versehen, sondern
   der Mockup-Entwurf: dort gemessen 2,27:1, also derselbe Wert. Die Farbe deshalb
   bewusst nicht eigenmaechtig aufgehellt. Was hilft, ohne die Optik zu verlassen:
   ein dunkler Schatten statt eines gruenstichigen — auf gruenem Grund ist ein
   gruener Schatten unsichtbar und traegt die Kante nicht.
   Der weisse Text auf dem Button liegt mit 4,66:1 ueber der Textschwelle. */
.gd24-hero .gd24-btn--primary {
    box-shadow: 0 8px 20px rgba(15, 30, 16, .45);
}
.gd24-btn--primary:hover, .gd24-btn--primary:focus { background: var(--gd24-green-400); color: #fff; }
.gd24-btn--ghost { border-color: currentColor; color: inherit; background: transparent; }
.gd24-guide .gd24-btn--ghost { color: var(--gd24-green-700); }
/* lin: primaerer Hero-CTA darf groesser sein als die Sekundaeraktion daneben. */
.gd24-btn--lg { padding: 1rem 2rem; font-size: 1.06rem; }

/* ---------- USP ---------- */
.gd24-usp { background: var(--gd24-cream); padding: 2.2rem 1rem; border-bottom: 1px solid var(--gd24-sand); }
.gd24-usp__inner {
    max-width: 1240px; margin: 0 auto;
    display: grid; grid-template-columns: repeat(4, 1fr); gap: 1.6rem;
}
.gd24-usp__item { display: flex; flex-direction: column; gap: .25rem; }
/* Die Kuerzel (N₂, H₂O, ↓, ✓) sind im Mockup die goldene Icon-Rolle der USP-Leiste. */
.gd24-usp__num {
    font-family: var(--gd24-serif);
    font-size: 1.35rem; font-weight: 700; color: var(--gd24-gold-d); line-height: 1;
    margin-bottom: .35rem;
}
.gd24-usp__item strong { color: var(--gd24-green-700); font-size: 1.02rem; }
.gd24-usp__item span:last-child { color: var(--gd24-muted); font-size: .9rem; line-height: 1.45; }

/* ---------- SECTION HEAD ---------- */
.gd24-section-head { max-width: 46em; margin: 0 0 2.2rem; }
.gd24-section-head h2 {
    font-family: var(--gd24-serif);
    font-size: clamp(1.6rem, 3.2vw, 2.4rem);
    font-weight: 700; color: var(--gd24-green-700); margin: 0 0 .5rem; letter-spacing: 0;
    line-height: 1.2;
}
.gd24-section-head h2 em { font-style: italic; font-weight: 600; color: var(--gd24-gold-d); }
.gd24-section-head p { color: var(--gd24-muted); font-size: 1.05rem; margin: 0; }

/* ---------- KATEGORIEN ---------- */
/* lin 26.08.2026: Von 6 auf 4 Spalten umgestellt. Es gibt genau 5 aktive Kategorien:
   der Topseller bekommt eine Feature-Kachel ueber die volle Breite, die vier
   uebrigen stehen gleichwertig darunter. Vorher standen hier 5 Kacheln in zwei
   unterschiedlichen Groessen ohne inhaltlichen Grund. */
.gd24-cats { padding: clamp(2.5rem, 5vw, 4.5rem) 1rem; background: #fff; }
.gd24-cats__inner { max-width: 1240px; margin: 0 auto; }
.gd24-cats__grid {
    display: grid;
    grid-template-columns: repeat(4, minmax(0, 1fr));
    gap: 1.3rem;
}
.gd24-cat {
    display: flex; flex-direction: column;
    background: var(--gd24-cream);
    border-radius: 12px; overflow: hidden;
    text-decoration: none; color: inherit;
    border: 1px solid var(--gd24-sand);
    transition: transform .18s ease, box-shadow .18s ease;
    min-width: 0;
}
/* Schattenfarbe gruenstichig statt neutral — im Mockup durchgehend rgba(35,42,29,…),
   dadurch legt sich der Schatten in die Farbwelt statt sie grau zu daempfen. */
.gd24-cat:hover, .gd24-cat:focus {
    transform: translateY(-4px);
    box-shadow: 0 14px 32px rgba(35, 42, 29, .15);
    text-decoration: none; color: inherit;
}
/* lin 26.08.2026: Die Kacheln zeigen jetzt Pflanzenfotos statt freigestellter Beutel.
   Damit ist cover ohne Polster richtig — full-bleed, feste Hoehe, alle Kacheln gleich.
   Die frühere contain-Variante mit hellem Polster entfaellt samt --photo-Modifier. */
.gd24-cat__img {
    background: var(--gd24-cream);
    border-bottom: 1px solid var(--gd24-sand);
    overflow: hidden;
}
.gd24-cat__img img {
    width: 100%;
    height: 200px;
    object-fit: cover;
    display: block;
}
.gd24-cat__body { padding: 1.15rem 1.25rem 1.35rem; display: flex; flex-direction: column; gap: .45rem; flex: 1; }
.gd24-cat__body h3 {
    font-family: var(--gd24-serif);
    font-size: 1.22rem; font-weight: 600; margin: 0; color: var(--gd24-green-700);
    line-height: 1.25;
}
.gd24-cat__body p { margin: 0; color: var(--gd24-muted); font-size: .93rem; line-height: 1.5; flex: 1; }
/* Der "→"-Weiterlink ist im Mockup goldfarben — er markiert den Weg, nicht die Aktion. */
.gd24-cat__more { font-weight: 700; font-size: .89rem; color: var(--gd24-gold-d); }
.gd24-cat__more::after { content: " →"; }

/* Feature-Kachel: volle Breite, Bild und Text nebeneinander, gruener Rahmen. */
.gd24-cat--feature {
    grid-column: 1 / -1;
    flex-direction: row;
    align-items: stretch;
    background: #fff;
    border: 2px solid var(--gd24-gold);
    box-shadow: 0 10px 30px rgba(35, 42, 29, .1);
}
.gd24-cat--feature .gd24-cat__img {
    flex: 0 0 42%;
    max-width: 42%;
    border-bottom: 0;
    border-right: 1px solid var(--gd24-sand);
}
.gd24-cat--feature .gd24-cat__img img { height: 100%; min-height: 280px; }
.gd24-cat--feature .gd24-cat__body {
    justify-content: center;
    padding: 1.8rem 2rem;
    gap: .6rem;
}
.gd24-cat--feature .gd24-cat__body h3 { font-size: clamp(1.3rem, 2.4vw, 1.75rem); }
.gd24-cat--feature .gd24-cat__body p { flex: 0 1 auto; font-size: 1rem; max-width: 46em; }
.gd24-cat__badge {
    align-self: flex-start;
    background: var(--gd24-gold);
    color: var(--gd24-on-gold);
    font-size: .72rem;
    font-weight: 700;
    letter-spacing: .08em;
    text-transform: uppercase;
    padding: .3rem .7rem;
    border-radius: 999px;
}

/* ---------- RATGEBER ---------- */
.gd24-guide { padding: clamp(2.5rem, 5vw, 4.5rem) 1rem; background: var(--gd24-cream); }
.gd24-guide__inner { max-width: 1240px; margin: 0 auto; }
.gd24-guide__grid { display: grid; grid-template-columns: repeat(3, 1fr); gap: 1.3rem; }
.gd24-guide__card {
    background: #fff; border-radius: 12px; padding: 1.6rem 1.5rem;
    border: 1px solid var(--gd24-sand); min-width: 0;
}
.gd24-guide__step {
    display: inline-block; font-family: var(--gd24-serif);
    font-size: .9rem; font-weight: 700; letter-spacing: .1em;
    color: var(--gd24-gold-d); margin-bottom: .6rem;
}
.gd24-guide__card h3 {
    font-family: var(--gd24-serif);
    font-size: 1.12rem; font-weight: 600; margin: 0 0 .5rem; color: var(--gd24-green-700);
    line-height: 1.3;
}
.gd24-guide__card p { margin: 0; color: var(--gd24-muted); font-size: .95rem; line-height: 1.6; }
/* Grid statt Flex-Wrap auf allen Breiten: mit flex-wrap blieben bei 768px rund 31% der
   Zeile rechts leer, weil der dritte Button nicht mehr danebenpasste. auto-fit verteilt
   die Buttons stattdessen gleichmaessig ueber die volle Breite. */
.gd24-guide__actions {
    display: grid;
    grid-template-columns: repeat(auto-fit, minmax(180px, 1fr));
    gap: .8rem;
    margin-top: 2rem;
}
/* lin 26.08.2026: Seit nur noch EIN Button in der Zeile steht, ist auto-fit falsch —
   die einzelne Spalte nimmt sonst die volle Breite und der Knopf wird zum Balken.
   Zentriert und auf Inhaltsbreite. */
.gd24-guide__actions--single {
    display: flex;
    justify-content: center;
}
.gd24-guide__actions--single .gd24-btn { min-width: 220px; }

/* ---------- SEO-TEXT ---------- */
.gd24-seo { padding: clamp(2.5rem, 5vw, 4rem) 1rem; background: #fff; }
.gd24-seo__inner { max-width: 860px; margin: 0 auto; }
.gd24-seo__inner h2 {
    font-family: var(--gd24-serif);
    font-size: clamp(1.3rem, 2.4vw, 1.7rem); font-weight: 600;
    color: var(--gd24-green-700); margin: 2.2rem 0 .7rem; letter-spacing: 0;
    line-height: 1.3;
}
.gd24-seo__inner h2:first-child { margin-top: 0; }
.gd24-seo__inner h3 {
    font-family: var(--gd24-serif);
    font-size: 1.12rem; font-weight: 600; color: var(--gd24-green-700);
    margin: 1.6rem 0 .5rem; line-height: 1.3;
}
.gd24-seo__inner p { color: var(--gd24-ink); line-height: 1.75; margin: 0 0 1.1rem; font-size: 1.02rem; }
.gd24-seo__inner a { color: var(--gd24-green-700); font-weight: 600; text-decoration: underline; }
/* Listen im SEO-Text bekommen das gruene Haekchen des Mockups statt eines Bullets. */
.gd24-seo__inner ul { list-style: none; padding-left: 0; margin: 0 0 1.1rem; }
.gd24-seo__inner ul li {
    position: relative; padding-left: 1.5rem; margin-bottom: .5rem;
    color: var(--gd24-ink); line-height: 1.65;
}
.gd24-seo__inner ul li::before {
    content: "✓"; position: absolute; left: 0; top: 0;
    color: var(--gd24-green-500); font-weight: 700;
}

/* ---------- RESPONSIVE ---------- */
@media (max-width: 991px) {
    .gd24-hero__inner { grid-template-columns: 1fr; }
    .gd24-hero__media { order: -1; }
    .gd24-usp__inner { grid-template-columns: repeat(2, 1fr); gap: 1.3rem; }
    .gd24-cats__grid { grid-template-columns: repeat(2, minmax(0, 1fr)); }
    /* Feature-Kachel kippt auf Tablet in die Spaltenrichtung — nebeneinander
       bliebe fuer den Text zu wenig Platz. */
    .gd24-cat--feature { flex-direction: column; }
    .gd24-cat--feature .gd24-cat__img {
        flex: 0 0 auto; max-width: 100%;
        border-right: 0; border-bottom: 1px solid var(--gd24-sand);
    }
    .gd24-cat--feature .gd24-cat__img img { height: 200px; }
    .gd24-cat--feature .gd24-cat__body { padding: 1.4rem 1.5rem 1.6rem; }
    /* ⚠️ Diese Zeile ist beim Neuschreiben der Datei am 26.08.2026 einmal verlorengegangen.
       Folge: drei Ratgeber-Karten à 105px bei 390px, ein Wort pro Zeile, Text 37px ueber
       die Kartenkante hinaus. Nicht wieder entfernen. */
    .gd24-guide__grid { grid-template-columns: 1fr; }
}
@media (max-width: 575px) {
    .gd24-usp__inner { grid-template-columns: 1fr; }
    .gd24-cats__grid { grid-template-columns: 1fr; }
    .gd24-hero__actions .gd24-btn { flex: 1 1 100%; text-align: center; }
    .gd24-cat__img img { height: 160px; }
    .gd24-hero__trust { gap: .3rem 1rem; }
}

/* ---------- KORREKTUREN nach dem ersten Review (05.08.2026) ---------- */

/* NOVA stylt <header> global mit weissem Hintergrund. Meine Sektionskoepfe
   nutzen dieses Tag und bekamen dadurch einen weissen Kasten auf farbigem Grund. */
.gd24-guide .gd24-section-head,
.gd24-cats .gd24-section-head {
    background: transparent;
    padding: 0;
    border: 0;
}

/* NOVAs #content-wrapper hat 64px padding-top, #content 48px padding-bottom.
   Auf der Startseite entsteht dadurch oben und unten eine tote Flaeche.
   Die Klassen existieren nur hier, der Ausgleich wirkt also nur auf der Startseite. */
/* Ben 27.08. 10:52: "den Abstand UEBER dem Breadcrumb um ein Drittel reduzieren, mobil und
   Desktop" — das ist genau dieses Padding. Deshalb: Padding UND Hero-Ausgleich gemeinsam
   auf 2/3 (64 → 43 px, unter 992 px 32 → 21 px). Wer eins aendert, aendert beides. */
/* NOVA schreibt `#content-wrapper:not(.has-fluid)` (1,1,0) — gleicher Selektor, sonst verliert
   die Regel (27.08. einmal live erlebt: Hero mit 21-px-Luecke zum Header). */
#content-wrapper:not(.has-fluid) { padding-top: 43px; }
.gd24-hero { margin-top: -43px; }
.gd24-seo  { margin-bottom: -48px; }

/* ⚠️ Gemessen 26.08.2026 (Ben: „hier frisst das megamenu den hero .... mobil"):
   Der Ausgleich muss GENAU so gross sein wie das Padding, das er neutralisiert —
   sonst rutscht der Hero unter den Header, der `position: sticky` ist.
       Breite   #content-wrapper padding-top   noetiger Ausgleich
       1440           64px                         -64px  ✅
        768           32px                         -32px
        390           32px                         -32px
   Hier stand -48px, also 16px zu viel: Hero begann bei y=84, der Header endete
   erst bei y=100 — die oberen 16px des Hero lagen darunter.
   Wer diesen Wert aendert, misst vorher `getComputedStyle(#content-wrapper).paddingTop`
   in DER Breite, statt ihn zu schaetzen. */
@media (max-width: 991px) {
    #content-wrapper:not(.has-fluid) { padding-top: 21px; }
    .gd24-hero { margin-top: -21px; }
}
/* Die Gras-Welle (div.grassland) sitzt zwischen </main> und <footer>.
   ⚠️ Korrigiert am 26.08.2026 (Ben: „der footer braucht desktop global ein paar
   pixel abstand zum ueberliegenden content. sonst frisst der das").
   Frueher stand hier `margin-top: -70px`, damit der obere Bildbereich mit dem
   weissen Grund des Startseiten-SEO-Blocks verschmilzt. Der obere Bildrand ist
   aber NICHT transparent, sondern WEISS — auf jeder Seite, deren Inhalt bis nach
   unten reicht, legte er sich damit ueber den Text. Auf /Mein-Konto war der Zeile
   „Noch kein Kunde? Jetzt registrieren" die untere Haelfte abgeschnitten.
   Die Body-Klassen sind auf allen Seiten identisch, die Startseite laesst sich
   also nicht per Selektor ausnehmen. Deshalb: kein negativer Aussenrand mehr,
   stattdessen garantierter Abstand darueber. Auf der Startseite gleicht der
   negative Rand von .gd24-seo das ohnehin aus. */
.grassland { margin-top: 0; position: relative; z-index: 1; pointer-events: none; }
#content-wrapper { padding-bottom: 28px; }
@media (max-width: 767px) { #content-wrapper { padding-bottom: 18px; } }

.gd24-section-head { box-shadow: none !important; background: transparent !important; border: 0 !important; }

/* ==========================================================================
   lin 26.08.2026 — Nachbesserungen Startseite + Artikeldetailseite
   ========================================================================== */

/* Stimmungsfoto in der Sammelkachel: cover statt contain, sonst steht das
   Querformat verloren im 180px-Feld und die Kachelreihe wirkt ungleich.
   ⚠️ Ohne Polsterung war das Bildfeld 29px flacher als bei den Beutel-Kacheln —
   nebeneinander starteten die Ueberschriften dadurch versetzt. Die Hoehe gleicht
   das Polster der Nachbarn aus (2 × .9rem), damit alle Bildfelder gleich hoch sind. */

/* Mobil war der Hero zu bildlastig: das Produktfoto schob den Kaufen-CTA aus
   dem ersten Viewport. Bild kompakter, Typo enger — gemessen bei 390px. */
@media (max-width: 575px) {
    .gd24-hero { padding-top: 1rem; padding-bottom: 2rem; }
    .gd24-hero__product { padding: .7rem; border-radius: 14px; }
    .gd24-hero__product img { height: 175px; }
    .gd24-hero__badge { top: -.55rem; left: 1rem; font-size: .7rem; padding: .3rem .7rem; }
    .gd24-hero__title { font-size: 2.05rem; }
    .gd24-hero__lead { font-size: .98rem; line-height: 1.55; margin-bottom: 1.2rem; }
    .gd24-hero__price { margin-bottom: 1.2rem; }
    .gd24-hero__price-value { font-size: 2.1rem; }
    .gd24-hero__trust { margin-top: 1.1rem; }

    /* Trust-Zeile und Ratgeber-Buttons brachen 1+2 bzw. 2+1 um und liessen ein Drittel
       bis über die Hälfte der Zeile leer — die Sorte gewürfelter Umbruch, die als
       Schlamperei gelesen wird. Untereinander ist ruhiger als ein halb gefuellter Wrap. */
    .gd24-hero__trust { flex-direction: column; gap: .35rem; }
    .gd24-guide__actions { display: grid; grid-template-columns: 1fr; gap: .6rem; }
    .gd24-guide__actions .gd24-btn { width: 100%; }
}

/* ---------- ARTIKELDETAILSEITE: Staffelpreis-Kacheln ---------- */
/* Ersetzt die NOVA-Staffelpreistabelle (in productdetails/price.tpl geleert).
   Muster von drexel-herbarium.com, Farben auf den gd24-Namespace gezogen. */
/* Label ueber den Kacheln als goldenes Kleinkapitaelchen — im Mockup traegt jedes
   Auswahlfeld ("GRÖSSE WÄHLEN") diese Auszeichnung. */
.gd24-bulk-head {
    font-size: .78rem;
    font-weight: 700;
    letter-spacing: .06em;
    text-transform: uppercase;
    color: var(--gd24-gold-d);
    margin: 0 0 .4rem;
    line-height: 1.25;
}
.gd24-bulk-tiles {
    display: flex;
    flex-wrap: nowrap;
    gap: .5rem;
    margin: 0 0 .55rem;
    width: 100%;
}
.gd24-bulk-tiles .gd24-bulk-tile {
    flex: 1 1 0;
    min-width: 0;
    padding: .7rem .35rem;
    /* 1,5px statt 1px: im Mockup tragen interaktive Elemente die staerkere Linie,
       statische Trenner die duenne. Das macht Klickbarkeit ohne Text sichtbar. */
    border: 1.5px solid var(--gd24-sand);
    background: #fff;
    border-radius: 11px;
    cursor: pointer;
    display: flex;
    flex-direction: column;
    align-items: center;
    justify-content: center;
    text-align: center;
    line-height: 1.2;
    font-family: inherit;
    color: var(--gd24-ink);
    overflow: hidden;
    transition: background-color .15s ease, border-color .15s ease, color .15s ease;
    -webkit-tap-highlight-color: transparent;
}
/* Hover nur fuer echte Zeigegeraete — auf Touch bleibt der Zustand sonst kleben. */
@media (hover: hover) and (pointer: fine) {
    .gd24-bulk-tiles .gd24-bulk-tile:hover { border-color: var(--gd24-green-500); background: var(--gd24-cream); }
}
/* Aktive Kachel: gruener Rahmen plus weicher Fokusring wie im Mockup, dazu eine
   sehr helle Fuellung. Die Fuellung bleibt bewusst drin (das Mockup kommt ohne aus) —
   auf Touch ist ein reiner Rahmenwechsel zu leise, um die Auswahl zu zeigen. */
.gd24-bulk-tiles .gd24-bulk-tile.is-active {
    background: #EEF3E9;
    border-color: var(--gd24-green-500);
    box-shadow: 0 0 0 3px rgba(78, 130, 71, .12);
    color: var(--gd24-green-700);
}
.gd24-bulk-tile__qty {
    font-size: .95rem;
    font-weight: 700;
    max-width: 100%;
    white-space: nowrap;
    overflow: hidden;
    text-overflow: ellipsis;
}
.gd24-bulk-tile__unit {
    margin-top: .15rem;
    font-size: .8rem;
    color: var(--gd24-muted);
    white-space: nowrap;
    max-width: 100%;
    overflow: hidden;
    text-overflow: ellipsis;
}
.gd24-bulk-tile.is-active .gd24-bulk-tile__unit { color: var(--gd24-green-700); }
.gd24-bulk-tile__discount {
    margin-top: .25rem;
    font-size: .8rem;
    font-weight: 700;
    color: var(--gd24-green-500);
    white-space: nowrap;
}
/* Platzhalter auf der 1er-Kachel: haelt alle Kacheln gleich hoch, ohne eine
   Ersparnis zu behaupten, die es dort nicht gibt. */
.gd24-bulk-tile__discount.is-empty {
    color: var(--gd24-muted);
    font-weight: 600;
    /* "Einzelpreis" passte bei 390px um 1px nicht in die Kachel (scrollWidth 60 auf
       clientWidth 59) — die Ellipsis machte daraus "Einzelpr…". Ellipsis ist die falsche
       Antwort auf einen 1-Pixel-Engpass: hier schafft eine Spur kleinere Schrift echten
       Platz, statt den Text zu kuerzen. Ellipsis bleibt nur als Notnagel stehen. */
    max-width: 100%;
    overflow: hidden;
    text-overflow: ellipsis;
    font-size: .68rem;
    letter-spacing: -.01em;
}
/* Die "Mehr"-Kachel hat nur zwei Zeilen statt drei; mit align-items:center sass ihr
   Text dadurch 9px tiefer als bei den Nachbarn und die Reihe lag nicht auf einer Linie.
   Ein unsichtbarer dritter Platzhalter stellt dieselbe Zeilenstruktur her. */
.gd24-bulk-tile--more { border-style: dashed; }
.gd24-bulk-tile--more.is-active { border-style: solid; }
.gd24-bulk-tile--more::after {
    content: "\00a0";
    display: block;
    margin-top: .25rem;
    font-size: .72rem;
    font-weight: 600;
    line-height: 1.2;
}

/* Live-Vorschau: zwei Zeilen — Gesamtpreis gross, Rechenweg und Ersparnis klein darunter. */
.gd24-bulk-summary {
    background: var(--gd24-cream);
    border: 1px solid var(--gd24-sand);
    border-radius: 14px;
    padding: .55rem .9rem .6rem;
    margin: 0 0 .7rem;
}
.gd24-bulk-summary__main {
    display: flex;
    justify-content: space-between;
    align-items: baseline;
    gap: 1rem;
}
.gd24-bulk-summary__label { font-size: .92rem; color: var(--gd24-muted); }
.gd24-bulk-summary__value {
    font-family: var(--gd24-serif);
    font-size: 1.35rem;
    font-weight: 700;
    color: var(--gd24-green-700);
    line-height: 1.2;
}
.gd24-bulk-summary__meta {
    font-size: .84rem;
    color: var(--gd24-muted);
    line-height: 1.3;
    margin-top: .1rem;
}
.gd24-bulk-summary__save { color: var(--gd24-green-700); font-weight: 700; }

/* Mengen-Counter ist im Kachelmodus eingeklappt und faehrt nur bei "Mehr" auf.
   Der Kaufen-Button bleibt dabei immer sichtbar.
   ⚠️ visibility + pointer-events sind hier NICHT optional: mit max-height/opacity allein
   bleibt der Stepper im Hit-Testing und in der Tab-Reihenfolge — das eingeklappte
   Zahlenfeld und die beiden +/- Buttons lagen bei 390px unsichtbar exakt auf dem
   Kaufen-Button (gemessen: beide bei x=16, y=276). */
.basket-form-inline.gd24-tiles-mode > [class*="col-"]:first-child {
    overflow: hidden;
    max-height: 0;
    opacity: 0;
    visibility: hidden;
    pointer-events: none;
    margin-bottom: 0;
    transition: max-height .25s ease, opacity .2s ease, margin-bottom .25s ease, visibility 0s linear .25s;
}
.basket-form-inline.gd24-tiles-mode.manual-open > [class*="col-"]:first-child {
    max-height: 160px;
    opacity: 1;
    visibility: visible;
    pointer-events: auto;
    margin-bottom: .5rem;
    transition: max-height .25s ease, opacity .2s ease, margin-bottom .25s ease, visibility 0s;
}

/* Kaufen-Button ist das auffaelligste Element der BuyBox. */
/* lin 27.08.2026, Block 2: Mockup-2-Add-to-Cart = R10, 16 px, gruener Schatten statt
   Bootstrap-Innenschatten. */
.gd24-buy-btn {
    font-size: 1rem; font-weight: 700; padding-top: .85rem; padding-bottom: .85rem;
    border-radius: 10px;
    box-shadow: 0 6px 16px rgba(60, 104, 55, .28);
}
.btn-primary, .btn-outline-primary { border-radius: 8px; }
.btn.gd24-buy-btn { border-radius: 10px; } /* schlaegt die allgemeine .btn-primary-Regel */
/* Der PayPal-Express-Button stand ab 576px auf halber Breite unter dem vollbreiten
   Kaufen-Button — 52% tote Flaeche daneben. Die Breite kommt nicht vom Button selbst,
   sondern von seinem Bootstrap-Container `.ppc-standalone-buttons` (col-sm-6, gemessen
   360px in einer 720px-Zeile). Deshalb den Container weiten, nicht den Button. */
.ppc-standalone-buttons { flex: 0 0 100%; max-width: 100%; }
/* ⚠️ NOVA blendet die Button-Beschriftung unter 576px aus (der Button steht dort im
   Original schmal neben dem Mengenfeld). Bei uns ist er ueber die volle Breite —
   ohne Text stand am Handy nur ein Warenkorb-Icon auf dem Haupt-CTA. Die NOVA-Regel
   ist eine Utility-Klasse, deshalb hier per !important zurueckgeholt. */
@media (max-width: 575.98px) {
    .gd24-buy-btn .btn-basket-check > span { display: inline !important; }
}

/* Reihenfolge in der rechten Spalte: Titel → Kategorie → Preis/Staffel/Kaufen → Nutzenpunkte.
   Gemessen bei 1440x900: die Kurzbeschreibung (105px) stand zwischen Preis und Kaufen-Button
   und schob ihn unter die Falz. Sie steht jetzt direkt darunter — gleiche Seite, gleiche
   Sichtbarkeit, aber die Kaufentscheidung wird nicht mehr von ihr unterbrochen. */
.product-info-inner { display: flex; flex-direction: column; }
.product-info-inner > .product-headline { order: 1; }
.product-info-inner > .info-essential   { order: 2; }
.product-info-inner > .product-offer    { order: 3; }
.product-info-inner > .shortdesc        { order: 4; margin-top: 1rem; }

/* ---------- ARTIKELDETAILSEITE: USP-Kacheln an der BuyBox ---------- */
/* Jede Aussage bekommt einen eigenen Bereich (Vorbild: SuperBee-Shop) statt einer
   gemeinsamen Box. Grid statt Flex, weil Grid die Kaecshen einer Reihe automatisch
   auf gleiche Hoehe zieht — der laengste Text ("Kostenloser Versand aus Deutschland")
   darf dann umbrechen, ohne die Reihe schief zu ziehen. Genau daran ist die
   zweispaltige Flex-Fassung gescheitert. */
.gd24-usp-buybox {
    list-style: none;
    margin: .7rem 0 0;
    padding: 0;
    display: grid;
    grid-template-columns: repeat(2, minmax(0, 1fr));
    grid-auto-rows: 1fr;   /* alle vier Kacheln gleich hoch, auch ueber Reihen hinweg */
    gap: .5rem;
}
.gd24-usp-buybox li {
    display: flex;
    align-items: center;
    /* lin 28.08.2026, Ben-Review Desktop (16/18): Icon + Text sind EIN Kind
       (.gd24-usp-buybox__group) und werden als Gruppe mittig gesetzt — auf beiden
       Breiten. Der `gap` sitzt jetzt in der Gruppe, nicht mehr hier: die Kachel hat
       nur noch ein Kind. */
    justify-content: center;
    background: var(--gd24-cream);
    border: 1px solid var(--gd24-sand);
    border-radius: 8px;
    padding: .6rem .75rem;
    font-size: .85rem;
    line-height: 1.35;
    color: var(--gd24-ink);
    min-width: 0;
    /* Explizit gesetzt, weil die BuyBox-Spalte ihre Ausrichtung vererbt — eine geerbte
       Zentrierung traefe nur den umbrechenden Text (Fehlerregister 27).
       `grid-auto-rows: 1fr` oben haelt alle vier Kacheln gleich hoch. */
    text-align: center;
}
/* lin 28.08.2026, Ben-Review Desktop (Screenshot 18), Ben: "Icon sitzt links am Rand,
   waehrend der Text zentriert ist". Ursache: `<i>` und `<span>` waren zwei Flex-Kinder
   der Kachel. Bricht der Text um, nimmt er die Restbreite, das Icon wird an den linken
   Rand gedrueckt — zwei getrennt zentrierte Elemente statt einer Gruppe.
   Jetzt bilden beide EIN Kind: die Gruppe ist inline-flex, nimmt Inhaltsbreite und wird
   von `justify-content: center` der Kachel als Ganzes zentriert. Der Text bleibt in der
   Gruppe linksbuendig neben dem Icon — falls er doch einmal umbricht (laengere Sprache),
   klebt das Icon weiter am Text statt an der Kachelkante.
   `gap: 8px` ist ein Wert der Mockup-2-Abstands-Skala (2/6/7/8/9/…). */
.gd24-usp-buybox__group {
    display: inline-flex;
    align-items: center;
    gap: 8px;
    text-align: left;
}
/* lin 28.08.2026, Ben (Screenshot 24): "Zertifiziertes Saatgut" brach um, obwohl Platz war.
   Der Text darf schrumpfen, aber nichts darf ihn kuenstlich begrenzen: `flex: 0 1 auto`
   ohne `max-width`, und das `min-width: 0` der Gruppe ist raus — es erlaubte dem
   Flex-Kind, unter seine Inhaltsbreite zu gehen, obwohl die Kachel noch Reserve hatte
   (gemessen 390 px: Kachel innen 154 px, laengster Text 120 px). */
.gd24-usp-buybox__group > span {
    flex: 0 1 auto;
    max-width: none;
}
/* lin 28.08.2026, Ben (Desktop, 11:17): "Zertifiziertes Saatgut" brach auch in der 220-px-Kachel
   um, obwohl Text + Icon + gap (191 px) in die 196 px Innenbreite passen — der Flex-Algorithmus
   rundet die Gruppe auf min-content. Ab 576 px sind die Kacheln breit genug: kein Umbruch mehr.
   Unter 576 px (2 Spalten à 175 px) bleibt der natuerliche Umbruch, dort passt es nicht einzeilig. */
@media (min-width: 576px) {
    .gd24-usp-buybox__group > span { white-space: nowrap; }
}
.gd24-usp-buybox i {
    color: var(--gd24-gold-d);
    font-size: 1rem;
    flex: 0 0 1.15rem;
    text-align: center;
}

/* lin 28.08.2026, Ben (11:23): "kannst du den PayPal-Button so schattieren wie den Warenkorbbutton?"
   Der gelbe Knopf selbst liegt im PayPal-iframe (nicht stylbar), aber PayPals Wrapper
   .paypal-buttons um den iframe ist unser DOM. Er bekommt R10 + Schatten wie .gd24-buy-btn;
   overflow:hidden schneidet die Ecken des iframes auf denselben Radius. Schattenfarbe neutral
   (--schatten-h-Ton) statt Gruen — Gruenschatten unter Gelb wirkt schmutzig.
   Nicht der Container #paypal-button-productDetails-container: das ist die col-12 mit Gutter,
   breiter als der Knopf (480 vs. 448 px gemessen). */
#paypal-button-productDetails-container .paypal-buttons,
#paypal-button-miniCart-container .paypal-buttons {
    border-radius: 10px;
    overflow: hidden;
    box-shadow: 0 6px 16px rgba(35, 42, 29, .18);
}

/* lin 28.08.2026, Ben (11:32, Screenshot 28): Warenkorb "Bestelluebersicht" — Coupon-Hinweis und
   Summenkasten sind NOVAs .card.card-gray (#f5f7fa, Radius 2 px). Auf CI: Pergament, Sandrahmen,
   R12 wie die Karten der PDP. Nur Farbe/Radius/Rahmen, Innenabstaende bleiben NOVA. Gilt fuer alle
   .card-gray im Kaufpfad (Warenkorb, Bestellvorgang-Zusammenfassung). */
.card.card-gray {
    background-color: var(--gd24-cream);
    border: 1px solid var(--gd24-sand);
    border-radius: 12px;
}
/* lin 28.08.2026, Ben (11:33, Screenshot 29): Checkout-Zusammenfassung — die {card}-Komponenten
   (Adresse, Versand/Zahlung, Kommentar, Coupon) haben graue Koepfe (#f5f7fa) und Radius 2 px.
   Anker ist NOVAs body.is-checkout, damit Produkt-/Kontokarten unberuehrt bleiben. Kopf in
   Pergament mit Sandlinie, Karte R12 (overflow hidden schneidet den Kopf auf den Radius). */
body.is-checkout .card {
    border-color: var(--gd24-sand);
    border-radius: 12px;
    overflow: hidden;
}
body.is-checkout .card-header {
    background-color: var(--gd24-cream);
    border-bottom-color: var(--gd24-sand);
}
/* lin 28.08.2026, Ben (11:37, Screenshot 30): "Ändern is noch ziemlich hässlich" — NOVAs
   {button variant="link" size="sm"} (Text unterstrichen + Stift) in den Karten-Koepfen der
   Zusammenfassung (Adresse, Versand/Zahlung, Bestellblock). Als kleiner Outline-Knopf in der CI:
   Sandrahmen, R8, Dunkelgruen, weisser Grund auf dem Pergament-Kopf; Hover gruener Rahmen. */
body.is-checkout .card-header .btn-link {
    display: inline-flex;
    align-items: center;
    gap: 6px;
    padding: 4px 12px;
    border: 1px solid var(--gd24-sand);
    border-radius: 8px;
    background-color: #fff;
    color: var(--gd24-green-700);
    font-weight: 600;
    text-decoration: none;
}
body.is-checkout .card-header .btn-link:hover,
body.is-checkout .card-header .btn-link:focus {
    border-color: var(--gd24-green-500);
    color: var(--gd24-green-500);
    text-decoration: none;
}
body.is-checkout .card-header .btn-link .checkout-confirmation-change { text-decoration: none; }

/* lin 28.08.2026, Ben (11:40): "stell dir vor du bist ein Kunde, der sinnlosen Whitespace hasst" —
   Zusammenfassung verdichtet, Struktur unveraendert. Kurzbeschreibungs-Bullets kommen aus dem Setting
   bestellvorgang_artikelkurzbeschreibung (jetzt N), nicht aus CSS. Werte aus der Abstands-Skala
   (8/12/16/20), Desktop und Mobil. */
body.is-checkout .card-header { padding: 8px 16px; }
body.is-checkout .card-body { padding: 16px 20px; }
body.is-checkout .checkout-confirmation-pre-form-hr { display: none; }   /* Karten haben Rahmen */
body.is-checkout #complete_order hr { margin: 12px 0; }
body.is-checkout .checkout-confirmation-legal-notice { padding: 8px 0; margin: 0; }
body.is-checkout .checkout-confirmation-items .card-header,
body.is-checkout .card-products .card-header { padding: 6px 12px; }
body.is-checkout .card-products .card-body { padding: 8px 16px 12px; }
/* Ben (11:42, Screenshot 33): Doppel-Trennlinie. NOVA rendert <hr> + Checkbox-Include + <hr>; ohne
   Checkbox an dieser Stelle stehen beide Linien direkt untereinander. Die zweite faellt weg. */
body.is-checkout #complete_order hr + hr { display: none; }
body.is-checkout .checkout-items-header { margin-top: 0; padding: 8px 0; }
body.is-checkout .checkout-items-item { padding: 12px 0; }
body.is-checkout .checkout-items-item-image-wrapper img { max-width: 96px; }
body.is-checkout .checkout-items-total-wrapper > .row,
body.is-checkout .checkout-items-total-wrapper .row > .row { padding: 6px 0; }
body.is-checkout .order-submit { margin-top: 12px; }
@media (max-width: 767.98px) {
    body.is-checkout .card-body { padding: 14px 16px; }
    body.is-checkout .card-body h3,
    body.is-checkout .card-body .h3 { margin-bottom: 4px; }
    body.is-checkout .card-body address,
    body.is-checkout .card-body p { margin-bottom: 8px; }
}

/* ---------- ARTIKELDETAILSEITE: Wege kuerzen ---------- */
/* NOVA setzt zwischen Preisblock und Kaufbereich 24px + 32px = 56px tote Flaeche.
   Der Kunde soll vom Preis direkt in die Mengenwahl laufen, nicht durch Leerraum. */
.product-info-inner > .product-offer > .row { margin-bottom: .5rem; }
.product-info-inner > .product-offer > .product-buy { margin-top: .5rem; }
.product-info-inner > .info-essential { margin-bottom: .4rem; }
.product-offer .payment-icons-wrapper { margin-top: .6rem !important; }
/* Versandhinweis direkt hinter der USt-Angabe — schliesst das verwaiste Komma,
   das NOVA dort stehen laesst, und macht die Aussage sichtbar. */
/* lin 27.08.2026: .gd24-shipping-note entfernt — der Child-Versandhinweis in price.tpl ist raus,
   NOVA liefert den Versandtext wieder selbst (Versand-Spezialseite = kLink 71). */

/* Preisblock und Verfuegbarkeitszeile: NOVA setzt hier 24 + 16 + 2×16 px.
   Preis, Verfuegbarkeit und Mengenwahl gehoeren zusammen — nicht durch Luft getrennt.
   lin 28.08.2026: Die dritte Zeile (.product-offer .stock-information, Polster .55rem)
   ist ersatzlos raus — sie hat NIE gegriffen. NOVA schreibt das Polster mit
   `#product-offer .product-info .stock-information.stock-information-p` (1 ID + 3 Klassen)
   und schlaegt jeden kuerzeren Selektor (Fehlerregister 16). Der wirksame Ersatz steht
   unten im Runde-4-Block, mit genau diesem Anker. */
.product-offer .price_wrapper { margin-bottom: .5rem; }
.product-offer .price_wrapper .price { margin-bottom: .35rem; }

@media (max-width: 575px) {
    /* lin 28.08.2026 (P3), Ben: "4 USPs, mobil 2 nebeneinander". Bis 5.9.43 standen sie
       hier einspaltig, weil der laengste Text ("Kostenloser Versand aus Deutschland") in
       einer halbbreiten Kachel drei Zeilen brauchte. Zwei Dinge machen es jetzt moeglich:
       der aeussere Kasten ist weg (36 px mehr Innenbreite) und die Schrift geht auf
       12,5 px — damit bleiben zwei Zeilen. `grid-auto-rows: 1fr` von oben zieht alle vier
       Kacheln auf dieselbe Hoehe, auch ueber die Reihen hinweg (Fehlerregister 27). */
    .gd24-usp-buybox { grid-template-columns: repeat(2, minmax(0, 1fr)); gap: .5rem; }
    .gd24-usp-buybox li { padding: .5rem .6rem; font-size: .78rem; }
    /* lin 28.08.2026: gap wandert mit der Gruppe mit; 6 px ist der naechstkleinere
       Wert der Abstands-Skala. */
    .gd24-usp-buybox__group { gap: 6px; }
    .gd24-usp-buybox i { font-size: .9rem; flex-basis: 1rem; }
    .gd24-bulk-tiles { gap: .35rem; }
    .gd24-bulk-tiles .gd24-bulk-tile { padding: .6rem .2rem; }
    .gd24-bulk-tile__qty { font-size: .88rem; }
    .gd24-bulk-tile__unit { font-size: .74rem; }
    .gd24-bulk-tile__discount { font-size: .74rem; }
}

/* ==========================================================================
   lin 26.08.2026 — GLOBALES CHROME (Mockup 2)
   --------------------------------------------------------------------------
   Bis hierher betraf alles den gd24-Namespace, also Startseite und BuyBox.
   Dieser Block zieht den REST des Shops nach — Kategorie- und Artikelseite,
   Header, Footer, Suchergebnisse. Ohne ihn haette die Startseite eine andere
   Handschrift als jede Seite dahinter.

   ⚠️ Die Regeln hier greifen in NOVA-Klassen. Zwei Dinge dabei beachtet:
   1. `my-nova_crit.css` wird als <style id="criticalCSS"> INLINE im <head>
      ausgegeben, also vor dieser Datei — bei gleicher Spezifitaet gewinnt custom.css.
   2. `!important` steht nur dort, wo NOVA selbst eine Utility-Klasse setzt,
      die sich anders nicht schlagen laesst. Sonst bewusst vermieden.
   ========================================================================== */

/* ---------- Schrift global ---------- */
body {
    font-family: var(--gd24-sans);
    color: var(--gd24-ink);
    /* lin 27.08.2026, Ben (Design-Abgleich, Paket mit Kartenschatten): Mockup 2 laeuft auf
       Weiss mit 15 px / 1.65 statt NOVA-Blaugrau #f5f7fa mit 14 px / 1.5. */
    background-color: #fff;
    font-size: 15px;
    line-height: 1.65;
}

/* lin 28.08.2026, Ben-Review: Der Versandbalken (.versandkostenfrei-header) ist ersatzlos
   entfallen — der Hinweis steht jetzt als erster Eintrag in der Topbar. Die Regeln dazu sind
   hier, in my-nova.css, my-nova_crit.css und im customsass-Feld entfernt; das <div> ist aus
   layout/header.tpl raus. Nicht wieder aufnehmen. */
/* Ueberschriften und Preise laufen in Spectral — das ist der Wiedererkennungszug
   des Mockups. font-weight max. 700, weil Spectral kein 800 mitbringt. */
h1, h2, h3, .h1, .h2, .h3,
.opc-headline, .headline {
    /* Review 27.08. (F3): /Suche rendert die H1 mit Klasse .h1 — NOVAs `.h1{Montserrat}` (0,1,0)
       schlug das blosse `h1`. Die Klassen gehoeren mit in die Regel. */
    font-family: var(--gd24-serif);
    font-weight: 600;
    color: var(--gd24-green-700);
    line-height: 1.25;
}
h1 { font-weight: 700; }
/* lin 27.08.2026: h4–h6 trugen weiter NOVAs Montserrat (Regel in my-nova_crit.css).
   Mockup 2 kennt nur zwei Familien — Zwischenueberschriften unterhalb h3 laufen in der
   Grotesk, halbfett, damit Montserrat nirgends mehr auftaucht. */
h4, h5, h6, .h4, .h5, .h6 {
    font-family: var(--gd24-sans);
    font-weight: 600;
    color: var(--gd24-green-700);
}

/* ⚠️ Produktkarten-Titel bleiben in der GROTESK, obwohl sie <h3> sind — das ist
   eine ausdrueckliche Vorgabe aus Mockup 2 (dort `.pc h3` explizit auf Open Sans
   zurueckgesetzt). Grund: In einer Kachelreihe stehen vier bis sechs Titel eng
   nebeneinander und brechen mehrzeilig um; eine Serif wird dort unruhig. Die
   Serif bleibt Ueberschriften und Preisen vorbehalten. */
.productbox-title, .productbox-title a,
.product-title, .productbox h3, .productbox .title {
    font-family: var(--gd24-sans);
    font-weight: 600;
    line-height: 1.35;
}
h1 em, h2 em, h3 em { font-style: italic; font-weight: 600; color: var(--gd24-gold-d); }

/* Preise: ueberall Spectral, damit sie auf Kategorie- und Artikelseite dieselbe
   Stimme haben wie im Hero. */
.price, .price_wrapper .price, .productbox-price, .product-price {
    font-family: var(--gd24-serif);
    font-weight: 700;
    color: var(--gd24-green-700);
}
.vat_info, .basePrice, .product-base-price, .shipping-note { color: var(--gd24-muted); }

/* ---------- Links und Primaeraktionen ---------- */
/* ⚠️ Links tragen das DUNKLE Gruen, nicht das CTA-Gruen. Zwei Gruende:
   1. Gemessen: #4E8247 auf dem NOVA-Weiss #FCFCFC ergibt 4,44:1 — knapp unter AA.
      #2F5233 liefert 8,84:1.
   2. Mockup 2 fuehrt Navigations- und Textlinks ebenfalls in --green-d; das
      CTA-Gruen ist dort der Aktion vorbehalten (Buttons), nicht dem Lesetext.
   Hover geht ins hellere CTA-Gruen, damit die Zustandsaenderung sichtbar bleibt. */
a { color: var(--gd24-green-700); }
a:hover, a:focus { color: var(--gd24-green-500); }

.btn-primary,
.btn-primary:not(:disabled):not(.disabled) {
    background-color: var(--gd24-green-500);
    border-color: var(--gd24-green-500);
    color: #fff;
}
.btn-primary:hover,
.btn-primary:focus,
.btn-primary:not(:disabled):not(.disabled):active {
    background-color: var(--gd24-green-400);
    border-color: var(--gd24-green-400);
    color: #fff;
}
.btn-outline-primary {
    color: var(--gd24-green-500);
    border-color: var(--gd24-green-500);
}
.btn-outline-primary:hover, .btn-outline-primary:focus {
    background-color: var(--gd24-green-500);
    border-color: var(--gd24-green-500);
    color: #fff;
}

/* ---------- Produktkarten in Listen (Kategorie, Suche, Slider) ---------- */
/* ⚠️ NUR `.productbox` anfassen, NIEMALS `.product-wrapper`.
   Gemessen am 26.08.2026: `.product-wrapper` traegt die Klassen
   `col product-wrapper col-sm-6 col-md-4 col-xl-3 col-6` — das ist die
   BOOTSTRAP-GRID-SPALTE, nicht die Karte. `.productbox` ist ihr Kind und die
   eigentliche Karte. Ein Rahmen auf beiden ergibt zwei ineinanderliegende
   Rahmen ("Rand in Rand in Rand", Ben 26.08.2026).

   ⚠️ Ausserdem KEIN transform/translateY: Ein Lift schiebt die Karte ueber die Kante
   des Sliders (overflow:hidden) — die obere Rahmenlinie verschwindet und der Schatten
   franst in die Nachbarzellen aus ("randfressender Schatten").

   lin 27.08.2026, Ben (Design-Abgleich): Die Karte bekommt jetzt bewusst einen echten
   Rahmen + Grund + Schatten (Mockup 2: weiss, 1 px --linie, R12, 0 2px 12px). Vorher nur
   `border-color`, weil der Body blaugrau war und die Karten randlos sein durften; auf
   weissem Grund brauchen sie eine Kante. Hover: Rahmen gruen + Mockup-Schatten, KEIN Lift. */
.productbox {
    background-color: #fff;
    border: 1px solid var(--gd24-sand);
    border-radius: 12px;
    box-shadow: 0 2px 12px rgba(35, 42, 29, .07);
    transition: border-color .18s ease, box-shadow .18s ease;
}
.productbox:hover {
    border-color: var(--gd24-green-500);
    box-shadow: 0 14px 32px rgba(35, 42, 29, .15);
}
/* Ben 27.08. 10:10: "im non-hover-Zustand sind die Ecken abgeschnitten, bei Hover passt es".
   NOVA legt ab 768 px ein weisses `::before` (inset 0, eckig) ueber `.productbox-inner` — Teil
   seiner Hover-Aufblaeh-Mechanik; auf Hover war es schon ausgeblendet, im Ruhezustand deckte
   der weisse Kasten die runden Ecken der Karte. Die Karte hat jetzt eigenen Grund + Rahmen,
   das Pseudoelement ist ueberfluessig — dauerhaft aus. */
.productbox.productbox-hover .productbox-inner::before { display: none; }
/* Bildflaeche mit Unterlinie zum Textteil (Mockup 2), Titel ohne Unterstreichung,
   Kartenpreis Spectral 20 px statt 16. */
/* Ben 27.08. 10:28 (Listenansicht ?ed=1): "das Artikelbild hat unten irgendeinen Rand, sonst
   keinen" — die Unterlinie gehoert nur in die Kachel, wo Bild UEBER Text steht. Dort heisst der
   Container `.productbox-images.list-gallery`, in der Liste nur `.productbox-images`. */
.productbox .productbox-images.list-gallery { border-bottom: 1px solid var(--gd24-sand); padding-bottom: .75rem; margin-bottom: .75rem; }
/* Ben 27.08. 10:28: "in Listenansicht klebt der Titel ganz oben" — `.productbox-inner` hat nur
   unten Polster (26.08.), in der Liste steht die Textspalte damit an der Kartenkante. */
.product-list.layout-list .productbox .productbox-inner { padding-top: .9rem; }
/* Review 27.08. (F2): Die Listenansicht ist unter 768 px in NOVA ein 2-Spalten-Raster mit 163-px-
   Karten (col-6), ungleichen Hoehen und dreizeiligem CTA. Liste heisst Liste: eine Spalte. */
@media (max-width: 767.98px) {
    .product-list.layout-list > .product-wrapper { flex: 0 0 100%; max-width: 100%; }
}
/* Ben 27.08. 10:29: "die letzte Artikelkarte hat wieder n Layout-Ausreisser". Gemessen: NOVA gibt
   jeder Grid-Spalte `.product-wrapper` 64 px Unterabstand, der LETZTEN aber 0 — Flex-Stretch
   zieht deren Karte um genau diese 64 px in die Hoehe ([393 x5, 457]). Solange die Karte
   randlos war, unsichtbar; mit Rahmen sofort. Register Klasse 5 (Margin-Falle in Flex/Stretch):
   alle Spalten gleich polstern. */
.product-list > .product-wrapper:last-child { margin-bottom: 4rem; }
.productbox .productbox-title a { text-decoration: none; }
.productbox .price, .productbox .productbox-price { font-size: 1.25rem; }
/* ⚠️ Gemessen 26.08.2026 (Ben: „auf der kategorie-ansicht klebt der artikelname
   komplett an der kartenseite"): NOVA baut die Karte als Bootstrap-Grid.
   `.productbox-inner > .row` traegt `margin: 0 -16px`, die Spalten darin
   `padding: 0 16px` — beides hebt sich auf, der Inhalt sitzt bei **0 px** auf der
   Kartenkante (nachgemessen: Titel links 548, Karte links 548).
   Solange die Karte keine sichtbare Kante hatte, fiel das nicht auf; mit dem
   12-px-Radius sofort. Den negativen Aussenrand nehmen — dann wird das
   Spalten-Padding zum echten Innenabstand, fuer Bild UND Text. Entspricht auch
   Mockup 2, wo die Bildflaeche ein Polster von 14–16 px traegt.
   Bewusst auf `.productbox` gescopet, damit keine andere `.row` im Shop mitgeht. */
.productbox .productbox-inner > .row {
    margin-left: 0;
    margin-right: 0;
}
/* Unten fehlte der Gegenpart: die letzte Spalte endet buendig mit der Kartenkante. */
.productbox .productbox-inner { padding-bottom: .9rem; }

/* ---------- Artikeldetailseite: Galerie sticky, Kaufbox ohne Leerraum ---------- */
/* lin 27.08.2026, Ben: (1) Bild samt Galerie soll auf dem Desktop mitscrollen, bis die
   Beschreibung beginnt. `#product-offer` ist die Bootstrap-Row, ihre Hoehe = Kaufbox-Spalte;
   die Tabs folgen direkt darunter (gemessen: 0 px Abstand). `align-self: flex-start` ist
   Pflicht — sonst streckt Flex die Galerie-Spalte auf Zeilenhoehe und sticky hat keinen
   Weg. top = Header 69 px + 16 px Luft. Nur ab lg, mobil liegt die Galerie ueber der Box.
   (2) Leerraum in der Kaufbox, gemessen bei 1280 und 390: Kategorie-Zeile mit 32 px oben
   UND unten um 25 px Text; im `.product-offer` eine unsichtbare Spinner-Row (`d-none`) mit
   24 px Unterabstand; Variationen 24 px, Kaufblock 32 px. Alles auf die 8er-Skala gezogen. */
/* Muster aus alpenwolle (server-work/custom.css, Abschnitt 4b), dort in vier Shops erprobt.
   ⚠️ Der erste Anlauf heute (08:30) hatte die Ausnahme unten NICHT — Ben oeffnete den Zoom und
   sah das Bild zentriert ueber der Kaufbox, Thumbnails ueber der Beschreibung: `position:
   sticky` erzeugt einen Stacking-Context, NOVAs Fullscreen-Zoom (`#image_wrapper.fullscreen`,
   position:fixed, z-index 10000) sitzt IN der Galerie, sein Overlay bleibt darin gefangen und
   Header/Kaufbox stanzen durch. Solange der Zoom offen ist, Sticky aufheben — die Seite
   scrollt dann ohnehin nicht. */
@media (min-width: 992px) {
    .row.product-detail { align-items: flex-start; }
    #product-offer > .product-gallery {
        position: sticky;
        top: 85px;
        align-self: flex-start;
    }
    #product-offer > .product-gallery:has(#image_wrapper.fullscreen) { position: static !important; }
    /* Ben 27.08. 09:46: "das schliesst hier nicht buendig ab" — NOVA gibt #image_wrapper 3rem
       Unterabstand; die Galerie-Box endete an der Beschreibung, die Thumbnails 48 px darueber.
       Desktop 0, mobil bleibt der NOVA-Wert (Galerie steht dort ueber der Kaufbox). */
    #product-offer > .product-gallery #image_wrapper { margin-bottom: 0; }
}
/* Mobil (Galerie ueber der Kaufbox): NOVA stapelt #gallery 2 rem + #image_wrapper 3 rem = 80 px
   Leerraum bis zur H1 — gemessen 27.08. bei 390 px. Ben: "sinnlosen Whitespace deutlich
   reduzieren (Desktop und mobil)". Ein Abstand reicht.
   lin 28.08.2026, Ben-Review Runde 4 (P2): "Abstand Galerie-Punkte → H1 um 80 % kleiner".
   Gemessen bei 390 px: Punktereihe endet bei y 589, H1 beginnt bei 606 = 17 px, davon
   16 px dieser margin-bottom und 1 px die untere Rahmenlinie von #gallery. 20 % von 17
   sind 3,4 px; der naechste Wert der Mockup-2-Abstandsskala ist 2 px (Skala: 2/6/7/8/…),
   macht mit der Rahmenlinie 3 px Restabstand = −82 %. Optisch bleibt mehr Luft als die
   Zahl sagt: der 12-px-Punkt sitzt in einem 28-px-Tap-Ziel, unter ihm liegen also
   weitere 8 px, und die H1-Zeilenbox traegt ihre eigene Oberlaenge. */
@media (max-width: 991.98px) {
    #product-offer > .product-gallery #image_wrapper { margin-bottom: 0; }
    #product-offer > .product-gallery #image_wrapper #gallery { margin-bottom: 2px; }
    /* lin 28.08.2026, Ben-Review Desktop-Runde (Screenshot 17): Ben hat den Leerraum
       ZWISCHEN Bildunterkante und Punktereihe angestrichen — Runde 4 hatte nur die
       Strecke Punkte → H1 gekuerzt. Gemessen bei 390 px: Bild endet bei y 527, die
       Punktereihe beginnt bei 561 = 34 px. Davon sind 32 px NOVAs `margin-top` an
       `.slick-dots`, 2 px der Ueberstand der `.slick-list` unter der Slide.
       Ziel 20 % von 34 = 6,8 px → der Hebel geht auf den Skalenwert 6 (Abstands-Skala
       2/6/7/8/…), zusammen mit dem Ueberstand bleiben 8 px sichtbare Luecke.
       Das 28-px-Tap-Ziel der Punkte bleibt unangetastet (44x28).
       Desktop unveraendert — dort steht die Galerie neben der Kaufbox, Ben hat den
       Befund nur mobil erhoben. */
    #gallery_wrapper .slick-dots { margin-top: 6px; }
}
/* NOVA setzt diese Abstaende mit `#product-offer .product-info …` (my-nova_crit.css) —
   gleicher Praefix, sonst verliert die Regel (27.08. einmal ins Leere deployt). */
#product-offer .product-info ul.info-essential { margin: .5rem 0 1rem; }
#product-offer .product-info .product-offer > .row:first-of-type { margin-bottom: 0; }
#product-offer .product-info .product-offer > .row.variations { margin-bottom: 1rem; }
/* lin 28.08.2026 (P1-Nachtrag Ben): 16 -> 12 px. Der Wert bildet zusammen mit dem
   margin-bottom der Preis-/Verfuegbarkeitszeile den Abstand unter dem Ampel-Badge
   (angrenzende Geschwister, die groessere Margin gewinnt). */
#product-offer .product-info .product-offer .product-buy { margin-top: 12px; }

/* ---------- Block 3 (27.08.2026): Mockup-2-Feinschliff Artikelseite, Suche, Breadcrumb ---------- */
/* Galerie-Buehne: R16 + Linie. KEIN Padding auf #gallery — slick misst die Slide-Breite am
   Container, Padding wuerde die Slides bis zum naechsten Resize falsch rechnen. */
#gallery { border: 1px solid var(--gd24-sand); border-radius: 16px; overflow: hidden; background: #fff; }
#gallery_preview .slick-slide { border-radius: 10px; overflow: hidden; }
#gallery_preview .slick-slide.slick-current { border-color: var(--gd24-green-500) !important; }
/* lin 28.08.2026, Ben-Review Runde 4 (P3): Der aeussere Kasten um die vier USP-Kacheln
   ist raus (Ben, Screenshot 05 — Rahmen im Rahmen). Die Kacheln tragen ihre eigene
   Flaeche und Linie, ein zweiter Rahmen darum war genau die Verschachtelung aus
   Fehlerregister 30. Der Bezugsrahmen der Kacheln ist jetzt die BuyBox-Spalte selbst,
   die Ausrichtung bleibt dieselbe (Fehlerregister 22: Rahmen weg heisst zu Ende bauen).
   Frueher: background #fcfcfb, border 1px, radius 14, padding 16/18. */
/* Verfuegbarkeit als Pill: Grund/Rahmen aus dem Mockup (Abschnitt 1, "Verfuegbarkeits-Pill").
   lin 28.08.2026 (P1): Die Regel hing am ERSTEN <li> der Liste. Seit das Badge ein eigenes
   Element mit Ampelklasse ist (productdetails/stock.tpl), haengt sie an der Klasse — sonst
   traefe sie auch den roten Zustand gruen ein. Alte li-Fassung ersatzlos entfernt, damit es
   nicht zwei Wahrheiten im selben Stylesheet gibt (Fehlerregister 17). */
.gd24-avail {
    display: inline-flex; align-items: center; gap: .4rem;
    border-radius: 999px;
    padding: 4px 12px; font-size: 13px; font-weight: 600;
}
/* Gruen: gemessen 7,67:1 (Text #2F5233 auf #e7f2e4). */
.gd24-avail--green  { background: #e7f2e4; border: 1px solid #cfe6cb; color: var(--gd24-green-700); }
/* Gelb: Gold-Lasur des Mockups (rgba(184,154,90,.16)) mit --gd24-gold-d als Text —
   gemessen 4,65:1, also ueber AA. --gd24-gold (#B89A5A) waere als Text 3,4:1 gewesen. */
.gd24-avail--yellow { background: rgba(184, 154, 90, .16); border: 1px solid var(--gd24-gold); color: var(--gd24-gold-d); }
/* Rot: NOVAs eigenes Danger (#B90000, gemessen an .text-danger) als Text auf einer
   Lasur derselben Farbe — 6,0:1. Kein neuer Rotton im Projekt. */
.gd24-avail--red    { background: rgba(185, 0, 0, .08); border: 1px solid rgba(185, 0, 0, .28); color: #B90000; }
/* Ben (Screenshot 03): die beiden Trennlinien ueber und unter der Zeile raus. Es sind
   NOVAs Rahmen an .stock-information (1 px #ebebeb oben UND unten, gemessen), nicht <hr>.
   Ohne sie schliesst der Preisblock direkt an das Badge an. */
#product-offer .stock-information { border-top: 0; border-bottom: 0; }
/* Tabs: aktiv mit 3-px-Goldkante statt gruenem Balken, 14 px, dunkelgruen. */
.nav-tabs .nav-link { font-size: 14px; color: var(--gd24-muted); }
.nav-tabs .nav-link.active, .nav-tabs .nav-item.show .nav-link {
    color: var(--gd24-green-700); border-color: transparent transparent var(--gd24-gold);
    /* gemessen: NOVA setzt border-bottom 0 mit hoeherer Spezifitaet — Kante explizit. */
    border-bottom: 3px solid var(--gd24-gold) !important;
    /* lin 28.08.2026, Ben (Screenshot 25): KEINE eigene Flaeche am aktiven Reiter — eine
       Pergament-Pille nur um das Wort sah aus wie ein Aufkleber. Das Pergament traegt jetzt
       das Band (.nav-tabs), der aktive Reiter markiert sich allein ueber Farbe und
       Goldstrich. */
    background-color: transparent;
    font-weight: 600;
}
/* Reiterleiste als Pergament-Band ueber der Inhaltskarte — damit der Desktop dieselbe
   Figur zeigt wie das mobile Akkordeon (Pergament-Kopf + Karte darunter). Kein
   Bootstrap-Unterstrich: die Kante entsteht aus dem Rahmen der Karte. */
.nav-tabs {
    background-color: var(--gd24-cream);
    border-radius: 12px 12px 0 0;
    border-bottom: 0;
    /* lin 28.08.2026, Ben (Desktop 11:17): KEIN Padding am <ul>. NOVAs Registerkarten-Ueberlauf-JS
       misst die freie Breite am ul und zog mit 8 px Polster den einzigen Reiter "Beschreibung"
       ins versteckte "weitere Registerkarten"-Dropdown — uebrig blieb ein leerer 8-px-Streifen.
       Live belegt: padding 0 -> Reiter zurueck (41 px). Das Polster sitzt jetzt im .nav-link. */
    padding: 0;
    /* lin 28.08.2026, Ben (11:20): "hier fehlt noch Rand … da sind Luecken" — die Karte darunter hat
       einen 1-px-Sandrahmen, das Band hatte keinen; an den Bandkanten klaffte es. Gleicher Rahmen,
       ohne Unterkante: Band + Karte sind EINE gerahmte Figur (Fehlerregister 11). */
    border: 1px solid var(--gd24-sand);
    border-bottom: 0;
}
.nav-tabs .nav-link { padding: 12px 16px; }
/* Inhaltskarte: weisser Grund, Sandrahmen, unten gerundet, Innenabstand wie die FAQ-Karte.
   Band und Karte haben dieselbe linke/rechte Kante (Fehlerregister 11: eine Bezugskante,
   nicht zwei). */
.tab-content {
    background-color: #fff;
    border: 1px solid var(--gd24-sand);
    border-top: 0;
    border-radius: 0 0 12px 12px;
    padding: 30px;
    /* lin 28.08.2026, Ben (11:20): NOVA setzt hier margin-top 24px — das war die weisse Luecke
       zwischen Band und Karte (gemessen: Band-Unterkante 1147, Karte-Oberkante 1171). */
    margin-top: 0;
}
/* gemessen: die gruene 6-px-Linie ist NOVAs `::after` (absolut, border-bottom #538b4c) —
   derselbe Mechanismus wie der Nav-Unterstrich im Header. Aus, die Goldkante uebernimmt. */
.nav-tabs .nav-link::after { display: none !important; }
/* Breadcrumb als Pergament-Band mit Unterlinie, 12,5 px. */
/* Ben 27.08. 10:45: "Breadcrumb schaut bisschen buggy aus" — Text und Pfeile klebten an der
   Bandkante (NOVA: Zeile ohne Innenabstand, Linien nur oben/unten). Als Kasten mit Polster,
   Rahmen rundum und Radius; die Pfeile rechts bekommen denselben Innenabstand. */
.breadcrumb-wrapper {
    background: var(--gd24-cream);
    border: 1px solid var(--gd24-sand);
    border-radius: 8px;
    padding: .25rem 1rem;
    /* Ben 27.08. 10:49: "Whitespace zwischen Breadcrumb und Bild um zwei Drittel reduzieren,
       mobil und Desktop" — gemessen 57 px, davon 32 px NOVA-margin-bottom, 25 px der
       unsichtbare Konfigurator-Button (unten). Ziel ~19 px = dieser Wert. */
    margin-bottom: 1.25rem;
}
/* Die uebrigen 25 px unter dem Breadcrumb: NOVAs unsichtbarer Konfigurator-Button
   `#buy_form > .js-cfg-validate.btn-hidden` (inline-block, 22 px + Zeilenbox) steht VOR
   #product-offer im Fluss. Bleibt fuer das JS klickbar, nimmt aber keinen Platz mehr. */
#buy_form > .btn-hidden { display: block; height: 0; padding: 0; margin: 0; border: 0; overflow: hidden; }
.breadcrumb-wrapper .breadcrumb, .breadcrumb-wrapper .breadcrumb-item { font-size: 12.5px; }
/* Header-Suche: 44 px, R8, Pergament, 1,5-px-Linie; Button dunkelgruen. */
#search .search-wrapper .form-control {
    height: 44px; border-radius: 8px 0 0 8px; font-size: 14px;
    /* gemessen: NOVA haelt Grund transparent und Rahmen 1 px mit !important-Regeln im
       Header — deshalb hier ebenfalls, sonst bleibt das Feld weiss/duenn. */
    background-color: var(--gd24-cream) !important;
    border: 1.5px solid var(--gd24-sand) !important;
    border-right: 0 !important;
}
#search .search-wrapper .form-control:focus { border-color: var(--gd24-green-500); box-shadow: none; background: #fff; }
#search .search-wrapper .input-group-append .btn {
    height: 44px; border-radius: 0 8px 8px 0; background: var(--gd24-green-700); border-color: var(--gd24-green-700); color: #fff;
}
#search .search-wrapper .input-group-append .btn:hover { background: var(--gd24-green-500); border-color: var(--gd24-green-500); }

/* Review 27.08. (F6): im Warenkorb brach "Zwischensumme:" vor dem Doppelpunkt um (zwei
   Zeilenboxen 126 px + 4 px in einer 159-px-Spalte). Preis-Labels brechen nicht. */
.price_label { white-space: nowrap; }

/* ---------- Trennlinien vereinheitlichen ---------- */
hr, .card, .list-group-item, .table td, .table th, .border, .border-top, .border-bottom {
    border-color: var(--gd24-sand);
}

/* ---------- 🔴 Slider-Hoehe: BLOCKIEREND, nicht kosmetisch ---------- */
/* Gemessen 26.08.2026 im Abnahme-Review: `.slick-list` steht auf einer FESTEN
   `height: 221px` (Inline-Style von slick). Unter 1024 px reicht die nicht mehr:
   - bei 768 px liegen Artikelname UND Preis komplett unter der Kappkante,
     die Karten zeigen nur noch Bilder;
   - bei 390 px wird die Preiszeile waagerecht MITTEN DURCH DIE ZIFFERN geschnitten.
   Auf 1440 px passt es zufaellig (Clip 287 / Inhalt 285) — deshalb beim
   Desktop-Blick unsichtbar.
   Ursache ist der Schriftwechsel: slick misst die Hoehe beim Initialisieren,
   also BEVOR Spectral und Open Sans geladen sind (`font-display: swap`).
   Nach dem Swap wachsen die Zeilen, die gemessene Hoehe bleibt.
   ⚠️ Ein abgeschnittener Preis ist zusaetzlich PAngV-relevant.
   `!important` ist hier nicht Bequemlichkeit: slick schreibt die Hoehe als
   Inline-Style, und den schlaegt man anders nicht. */
.slick-list,
.slick-track,
.product-slider-wrapper .slick-list,
.product-slider-wrapper .slick-track {
    height: auto !important;
}
/* Review 27.08. (B2/B3): reichte nicht — NOVA setzt `.slick-slide{height:100%}`, und bei 768 px
   war der Slide 349 px hoch, sein Inhalt (<a> mit Bild, Titel, Preis) 453 px: Titel und Preis
   lagen unter der Kappkante, bei 390 px der Grundpreis halbiert. Der Slide muss mit seinem
   Inhalt wachsen. */
.product-slider-wrapper .slick-slide { height: auto !important; }

/* ---------- Top-Artikel-Slider (Startseite): Karten-Optik wie im Kategorie-Raster ---------- */
/* Review 27.08. (B4), Ben: "schoen machen". NOVA rendert im Slider keine .productbox, sondern
   `.product-wrapper > a > .item-slider + .item-slider-desc + .item-slider-price` — die
   Kartenregeln griffen dort nicht. Gleiche Sprache wie die Karten: weiss, Sandrahmen, R12,
   Schatten, Bild-Unterlinie, Titel Grotesk 600, Preis Spectral 20 px, Hover ohne Lift. */
.product-slider-wrapper .product-wrapper > a {
    display: block;
    background: #fff;
    border: 1px solid var(--gd24-sand);
    border-radius: 12px;
    box-shadow: 0 2px 12px rgba(35, 42, 29, .07);
    padding: .75rem .75rem .9rem;
    text-decoration: none;
    transition: border-color .18s ease, box-shadow .18s ease;
}
.product-slider-wrapper .product-wrapper > a:hover,
.product-slider-wrapper .product-wrapper > a:focus {
    border-color: var(--gd24-green-500);
    box-shadow: 0 14px 32px rgba(35, 42, 29, .15);
}
.product-slider-wrapper .item-slider.productbox-image { border-bottom: 1px solid var(--gd24-sand); padding-bottom: .75rem; margin-bottom: .75rem; }
.product-slider-wrapper .item-slider-desc { font-family: var(--gd24-sans); font-weight: 600; color: var(--gd24-ink); line-height: 1.35; }
.product-slider-wrapper .item-slider-price .price { font-family: var(--gd24-serif); font-weight: 700; font-size: 1.25rem; color: var(--gd24-green-700); }
.product-slider-wrapper .slick-slide { padding: 0 .5rem; } /* Luft zwischen den Karten, Schatten bleibt in der Spalte */
/* Ben 27.08. 11:58: "ungleiche Groessen" — ein zweizeiliger Titel machte die Karte 26 px hoeher
   (Register Klasse 27). Track als Flex, Slides gestreckt, Karte fuellt die Slide-Hoehe, der
   Titel reserviert zwei Zeilen (text-clamp-2 kappt ohnehin bei zwei). */
.product-slider-wrapper .slick-track { display: flex !important; align-items: stretch; }
.product-slider-wrapper .slick-slide > a { height: 100%; display: flex; flex-direction: column; }
.product-slider-wrapper .item-slider-desc { min-height: 2.7em; }

/* ---------- NOVA-Erbe: Ueberschriften, die der Umbau nicht erwischt hat ---------- */
/* Diese drei tragen weiter Montserrat und NOVA-Grau, weil ihre Selektoren
   spezifischer sind als das globale `h1, h2, h3` weiter oben:
   `h1.h2` (Kategorie-Ueberschrift) ist Element + Klasse und schlaegt ein blosses `h1`. */
h1.h2, h2.h1, h2.h3, h3.h2,
.productlist-filter-headline,
.hr-sect, .hr-sect a,
.subcategories-header, .product-list-headline {
    font-family: var(--gd24-serif) !important;
    color: var(--gd24-green-700);
}
/* lin 27.08.2026, Block 2 — Ueberschriften-Skala aus Mockup 2: Kategorie-H1 32 px (war 24 px
   in NOVA-Gewicht 400), Artikel-H1 29 px / 1.2 (war 24). Hero-H1 bleibt auf Bens Wunsch 60 px. */
h1.h2 { font-size: 2rem; font-weight: 600; }
h1.product-title.h2 { font-size: 1.8125rem; line-height: 1.2; }
#product-offer .product-offer .price_wrapper .price { font-size: 2.125rem; } /* PDP-Hauptpreis 34 px */

/* ---------- Ribbons: NOVA-Fahne → Mockup-2-Gold-Pill ---------- */
/* lin 27.08.2026, Block 2: NOVA zeichnet den Produkt-Badge als graue/gruene Fahne mit
   Dreieck (`::before`) und Schatten, haengend ueber der Kartenkante (left -0.5rem) — auf der
   Karte mit Rahmen und Radius wirkt das fremd. Mockup 2: Gold-Pill 999px, 11 px/700, dunkles
   Braun, 11 px vom Rand. Die Texte (Top, Auf Lager) kommen weiter aus dem Backend; nur Optik.
   Der NOVA-Hover verschiebt die Fahne — hier auf derselben Position gehalten. */
.productbox-ribbon.ribbon,
.productbox.productbox-hover:hover .productbox-ribbon.ribbon {
    top: 11px;
    left: 11px;
    padding: 4px 10px;
    border-radius: 999px;
    background-color: var(--gd24-gold);
    color: var(--gd24-on-gold);
    font-size: 11px;
    font-weight: 700;
    letter-spacing: .04em;
    box-shadow: none;
}
.productbox-ribbon.ribbon::before { display: none; }
.hr-sect a:hover { color: var(--gd24-green-500); }

/* ---------- Inhaltsseiten (FAQ, Tipps, AGB …): Vertikalrhythmus ---------- */
/* lin 27.08.2026, Mobil-Review gemessen: h2/h3 hatten margin-top 0, JEDER Abstand im Text
   war 16 px — Sektionsgrenzen im 6-KB-FAQ nicht ablesbar, h3 (16 px) kaum vom Fliesstext
   (14 px) zu unterscheiden. Werte aus der Bootstrap-Skala (3rem / 1.5rem), h3-Groesse
   nach Mockup 2 "Beschreibungs-H3 18 px". Bewusst auf .link-content gescopet:
   Startseite und Artikelseite haben ihren eigenen Rhythmus. */
.link-content h2 { margin-top: 3rem; }
.link-content h3 { margin-top: 1.5rem; font-size: 1.125rem; }
/* Die h1 steht ausserhalb von .link-content (index-heading-wrapper) — der erste h2-Abstand
   von 48 px unter der Seitenueberschrift ist gemessen und gewollt. */

/* ---------- Hauptnavigation: Mockup 2 statt NOVA-Erbe ---------- */
/* lin 27.08.2026, gemessen bei 1280 px: NOVA fuehrte die Navi in Open Sans 700 / 16 px /
   Grau #525252 — so breit, dass der fuenfte Punkt "Alle Mischungen" hinter dem
   Scroll-Pfeil verschwand. Mockup 2: Nav 600 / 14,5 px / Dunkelgruen.
   Selektor bewusst mit `header` + Kind-Kombinatoren: schlaegt NOVAs
   `.navbar-light .navbar-nav .nav-link` (0,3,0) ohne !important. */
header .navbar-nav > .nav-item > .nav-link {
    font-family: var(--gd24-sans);
    font-weight: 600;
    font-size: .90625rem; /* 14,5 px */
    color: var(--gd24-green-700);
    /* Review 27.08.: Container 543 px bei 1280, Inhalt 627 px → "Alle Mischungen" hinter
       dem Scroll-Pfeil, nicht klickbar. NOVA polstert 24 px je Seite; Mockup 2 sagt 13 px.
       Vertikal bleibt 24 px, damit die Header-Hoehe (69 px, JS-gemessen) nicht kippt. */
    padding-left: 13px;
    padding-right: 13px;
}
header .navbar-nav > .nav-item > .nav-link:hover,
header .navbar-nav > .nav-item > .nav-link:focus,
header .navbar-nav > .nav-item.active > .nav-link { color: var(--gd24-green-500); }

/* ---------- Footer: Mockup 2 (Tiefgruen) — nur Farbe und Schrift ---------- */
/* lin 27.08.2026, Ben: "erstmal nur mit CSS Schriften/Farbgebung optimieren, keine Boxen
   umbauen". Mockup 2, Sektion 10: Footer auf --green-tief #233F26, Text #B7C6AF,
   Unterzeile #9FB197, Spaltenkoepfe Spectral 16 px, Hover gold-l, Trenner
   rgba(255,255,255,.1). NOVA-Boxen und -Grid bleiben unangetastet; der Sandton #D4BF94
   aus dem NOVA-Erbe ist damit weg. Die weissen Zahlungs-/Versand-Logos
   (`*_w.png`) sind fuer dunklen Grund gemacht und bleiben. */
#footer { background-color: var(--gd24-green-900); }
#footer, #footer p, #footer li, #footer td, #footer .footer-text {
    color: var(--gd24-footer-text);
}
/* `.box-content-wrapper a` (Mail-Link in "Wie Sie uns erreichen") blieb gemessen bei
   NOVA-Grau #525252 — unlesbar auf Tiefgruen, deshalb explizit mitgenommen. */
#footer a, #footer .box-content-wrapper a, #footer p a { color: var(--gd24-green-300); }
#footer a:hover, #footer a:focus,
#footer .box-content-wrapper a:hover, #footer p a:hover { color: var(--gd24-gold-l); }
/* Spaltenkoepfe: Spectral 600 / 16 px / Weiss. Deckt Desktop-Titel
   (`.productlist-filter-headline`) und den mobilen Collapse-Kopf (`.box-normal-link`) ab. */
#footer h4, #footer .footer-headline, #footer strong,
#footer .productlist-filter-headline,
#footer .box-normal .box-normal-link {
    font-family: var(--gd24-serif);
    font-weight: 600;
    color: #fff;
}
/* Nur die Titel auf 16 px — `strong` im Fliesstext behaelt die Textgroesse. */
#footer h4, #footer .footer-headline,
#footer .productlist-filter-headline,
#footer .box-normal .box-normal-link { font-size: 1rem; }
/* Widerrufsbutton (27.08.2026 nachgeruestet, layout/footer.tpl): `#footer a` faerbte den
   Button-Text hellgruen auf CTA-Gruen (3,3:1). Button bleibt Button: weiss. */
#footer .withdrawal-link, #footer .withdrawal-link:hover, #footer .withdrawal-link:focus { color: #fff; }
/* NOVA faerbt `.nav-link` spezifischer als `#footer a` — deshalb eigene Regel. */
#footer .nav-panel .nav-link, #footer .nav-link { color: var(--gd24-green-300); font-weight: 400; }
#footer .nav-panel .nav-link:hover, #footer .nav-link:hover,
#footer .nav-panel .nav-link:focus, #footer .nav-link:focus { color: var(--gd24-gold-l); }
/* ---------- Footer einzeilig, volle Breite, zentriert (Ben 27.08.2026, 11:00) ---------- */
/* "ueber die ganze Breite, Inhalt zentrieren falls nochmal ne Linkgruppe nachkommt, einzeilig,
   WRB-Button darunter zentriert". NOVA: .container (960 px) + col-lg-3 = 4 pro Reihe → mit
   fuenf Boxen zweizeilig. Ab lg: Container ohne Maximalbreite, Boxen als flexible Spalten
   ohne Umbruch, mittig — eine sechste Box reiht sich einfach ein. Unter lg bleibt NOVA
   (Collapse-Stapel). */
#footer > .container { max-width: none; width: 100%; }
/* Versand + Zahlungsarten sind seit 27.08. EINE Box (132, "Versand & Zahlung"; 131 deaktiviert).
   Das DHL-Logo steht darin ueber den Zahlungs-Icons. */
/* Ben 27.08. 11:12: "innerhalb der Box aufgeteilt: Versand: / Zahlung:" — zwei Unterzeilen. */
/* Ben 11:03: "die Ueberschrift ist dann unnoetig" — Box-Titel geleert, die zwei Zeilen
   tragen die Spaltenkopf-Optik (Spectral 600 / 16 px / Weiss) wie die Nachbarspalten. */
#footer .footer-sublabel { margin: 0 0 1rem; font-family: var(--gd24-serif); font-size: 1rem; font-weight: 600; color: #fff; }
#footer .footer-shipping + .footer-sublabel { margin-top: 1.25rem; }
/* NOVA rendert den (leeren) Box-Titel trotzdem als Element mit 16 px Unterabstand — das
   schob "Versand:" unter die Nachbar-Koepfe. Nur fuer diese Box ausgeblendet. */
#footer #sidebox132 > .productlist-filter-headline { display: none; }
#footer .footer-shipping { margin: 0 0 .75rem; }
#footer .footer-shipping-logo { max-width: 110px; }
@media (min-width: 992px) {
    /* 5vw Rand nur ab lg — mobil blieb sonst kein Innenabstand (gemessen: Boxen bei x = 4). */
    #footer > .container { padding-left: 5vw; padding-right: 5vw; }
    #footer-boxes { flex-wrap: nowrap; justify-content: center; gap: 2rem; }
    #footer-boxes > .col.col-sm-6.col-md-4.col-lg-3 {
        flex: 0 1 260px; max-width: 260px; min-width: 0;
        padding-left: 0; padding-right: 0;
    }
    #footer .footer-payment-wrapper { max-width: 100%; }
}
/* Review 27.08. (F1): bei 768–991 px brach NOVAs col-md-4 auf 3 + 1 um — die vierte Box stand
   allein mit 512 px Leerflaeche daneben. Auf Tablet 2 x 2. */
@media (min-width: 768px) and (max-width: 991.98px) {
    #footer-boxes > .col.col-sm-6.col-md-4.col-lg-3 { flex: 0 0 50%; max-width: 50%; }
}
#footer .withdrawal-link-wrapper { justify-content: center; }
#footer .withdrawal-link-wrapper > .col { flex: 0 0 auto; width: auto; max-width: none; }
#footer .withdrawal-link-wrapper .withdrawal-link { display: inline-block; width: auto; min-width: 260px; }
#footer .footnote-vat { text-align: center; }

/* Trenner: NOVA zieht weisse 1-px-Linien ueber jede Spalte — auf Tiefgruen zu hart. */
#footer-boxes .col.col-sm-6.col-md-4.col-lg-3 { border-top-color: rgba(255, 255, 255, .1); }
#footer .box-normal-hr { border-top-color: rgba(255, 255, 255, .1); }
/* Unterzeile: statt NOVA-Grau #525252 ein abgesetzter, dunklerer Streifen im selben Gruen. */
#copyright { background-color: rgba(0, 0, 0, .18); color: var(--gd24-footer-muted); }
#copyright a { color: var(--gd24-footer-muted) !important; } /* NOVA setzt .text-white !important */
#copyright a:hover, #copyright a:focus { color: var(--gd24-gold-l) !important; }
/* Review 27.08.: NOVAs Nach-oben-Knopf (weiss + Schatten, Chevron #707070) stand auf dem
   Sand-Footer unauffaellig, auf Tiefgruen als weisser Block. Der Knopf ist `fixed` und
   schwebt auch ueber weissem Inhalt — deshalb deckend im Marken-Dunkelgruen, nicht
   halbtransparent (das waere auf Weiss unsichtbar). */
/* lin 28.08.2026, Ben-Review Runde 4 (P7): Der Knopf ist rund, mobil und Desktop.
   ⚠️ `border-radius: 50%` allein haette eine Ellipse ergeben — NOVA rendert ihn 47 x 44 px
   (gemessen 28.08. bei 390 px: w 47, h 44, padding 2px/1px). Fuer einen Kreis muss die
   Box quadratisch sein; genommen ist die vorhandene HOEHE 44 px, damit das Tap-Ziel
   unveraendert 44 x 44 bleibt (die Breite schrumpft um 3 px). Das Icon wird per Flex
   zentriert, weil das asymmetrische NOVA-Padding es sonst 1 px nach oben zieht. */
.smoothscroll-top {
    background: var(--gd24-green-700);
    color: #fff;
    box-shadow: 0 2px 8px rgba(0, 0, 0, .25);
    width: 44px;
    height: 44px;
    padding: 0;
    border-radius: 50%;
    display: flex;
    align-items: center;
    justify-content: center;
}
/* lin 28.08.2026, Kern-Abnahme: das Icon sass bei 390 px 5 px zu hoch. Die Flex-Zentrierung
   zentriert die ZEILENBOX des `<i>`, nicht die Glyphe — Font Awesome bringt bei `fa-2x`
   eine Zeilenhoehe mit, in der die Glyphe oben sitzt. `line-height: 1` legt Zeilenbox und
   Glyphe uebereinander, `display: block` nimmt den Grundlinien-Versatz des Inline-Kastens. */
.smoothscroll-top i { color: #fff; display: block; line-height: 1; }
.smoothscroll-top:hover, .smoothscroll-top:focus { background: var(--gd24-green-500); }

/* ---------- Consent-Badge: Position ---------- */
/* lin 27.08.2026, Ben: Das Badge bleibt unten LINKS wie bei linsor.de — mobil und Desktop.
   Am 26.08. war es nach rechts verschoben worden, weil es bei 390 px die ersten ~40 px des
   vollbreiten Hero-Kaufbuttons ueberdeckte (Fehlerregister Klasse 7). Rechts kollidierte es
   dafuer mit dem Nach-oben-Pfeil und dem Zeilenende auf Textseiten. Ben nimmt die
   Ueberdeckung am Hero-Button bewusst in Kauf ("darum kann man ja scrollen") —
   NOVA-Standard, keine eigene Regel mehr. Nicht erneut versetzen. */

/* ---------- NOVA-Erbe: mobile Navigation ---------- */
/* Die Off-Canvas-Links liefen weiter in NOVA-Grau (#525252), waehrend die
   Desktop-Navigation laengst gruen ist — derselbe Baustein, zwei Auftritte. */
.offcanvas a, .offcanvas .nav-link,
#sidebar a, .navbar-offcanvas a,
.offcanvas-collapse a, .offcanvas-collapse .nav-link {
    color: var(--gd24-green-700);
}
.offcanvas a:hover, .offcanvas .nav-link:hover,
#sidebar a:hover, .navbar-offcanvas a:hover,
.offcanvas-collapse a:hover { color: var(--gd24-green-500); }

/* ==========================================================================
   TOPBAR (Mockup 2, Bens Fassung) — lin 28.08.2026
   Markup: layout/header.tpl, erste Flaeche der Seite, vor <header>.
   Mockup-Werte: Grund --gd24-green-900 (#233F26), Hoehe 38 px (Sektion 3 "Fixe Hoehen"),
   Schrift 12,5 px (Sektion 2 "Groessenskala"), Text --gd24-topbar-text.
   Bens Abweichungen vom Entwurf: keine Links/Rechts-Teilung, sondern zentriert; Inhalt
   sind fuenf Eintraege OHNE Links (Versandhinweis aus der Sprachvariable + vier USP-Saetze).
   ========================================================================== */
.gd24-topbar {
    background: var(--gd24-green-900);
    color: var(--gd24-topbar-text);
    font-size: 12.5px;
    line-height: 1;
}
.gd24-topbar__list {
    /* 38 px als feste Hoehe in BEIDEN Modi (Reihe wie Rotation) — Ben: "38 px bleibt". */
    height: 38px;
    max-width: 1240px;          /* Mockup-Container */
    margin: 0 auto;
    padding: 0 20px;            /* aus der Gap-Skala (20 = Standardmass) */
    list-style: none;
    display: flex;
    align-items: center;
    justify-content: center;
    gap: 12px;                  /* Gap-Skala: 12 */
}
.gd24-topbar__item {
    white-space: nowrap;        /* Register 3: keine gewuerfelten Umbrueche in der Leiste */
    min-width: 0;
}
/* Trenner als Pseudo-Element, NICHT als Text mit Leerzeichen: so kann die Zeile nie am
   Punkt umbrechen und der Trenner traegt eine eigene Farbe (Gold auf dunklem Grund). */
.gd24-topbar__item + .gd24-topbar__item::before {
    content: "\00B7";
    color: var(--gd24-gold-l);
    margin-right: 12px;
}

/* ---------- Unter 1200 px: rotierend, ein Eintrag sichtbar (Ben) ----------
   Warum genau bei 1200 (xl des Theme-Breakpoint-Satzes 576/768/992/1200):
   ⚠️ lin 28.08.2026 NEU GEMESSEN nach dem fuenften Eintrag. Mit der echten Open Sans in
   12,5 px sind die Eintraege 187 / 187 / 175 / 175 / 206 px breit (die 2.-5. jeweils
   inklusive Trenner-Pseudoelement + 12 px Abstand), dazu 4 Gaps a 12 px und 2x20 px
   Seitenpolster = 1018 px Mindestbreite. Bei 992 px Viewport stehen nur 952 px zur
   Verfuegung — es passt NICHT (mit vier Eintraegen waren es 754 px, deshalb stand hier
   vorher 992). Ab 1200 px passt die Reihe mit 182 px Luft. Also rotiert auch das
   grosse Tablet / kleine Notebook. */
@media (max-width: 1199.98px) {
    .gd24-topbar__list {
        display: block;
        position: relative;
        overflow: hidden;
    }
    .gd24-topbar__item {
        position: absolute;
        top: 0; right: 20px; bottom: 0; left: 20px;
        display: flex;
        align-items: center;
        justify-content: center;
        opacity: 0;
        /* lin 28.08.2026 (Reviewer-Nachfix): zusaetzlich visibility. Ohne sie liegen alle
           vier <li> dauerhaft deckungsgleich uebereinander (position:absolute, inset 0/20px)
           und `elementFromPoint` traf immer das VIERTE — Textmarkierung und Screenreader
           bekamen den unsichtbaren Eintrag. opacity 0 allein nimmt ein Element nicht aus
           dem Hit-Test, visibility:hidden schon. */
        visibility: hidden;
        /* 5 Eintraege a 4 s = 20 s Zyklus, reine CSS-Animation, kein JS. */
        animation: gd24-topbar-rotate 20s linear infinite;
    }
    .gd24-topbar__item:nth-child(1) { animation-delay: 0s; }
    .gd24-topbar__item:nth-child(2) { animation-delay: 4s; }
    .gd24-topbar__item:nth-child(3) { animation-delay: 8s; }
    .gd24-topbar__item:nth-child(4) { animation-delay: 12s; }
    .gd24-topbar__item:nth-child(5) { animation-delay: 16s; }
    /* In der Rotation steht immer nur ein Eintrag — ein Trenner waere sinnlos. */
    .gd24-topbar__item + .gd24-topbar__item::before { content: none; }
}
/* ⚠️ lin 28.08.2026, Reviewer-Nachfix — die erste Fassung (1,5 % ein / 25 % stehen /
   26,5 % aus) war ein Blocker: Der Ausblendvorgang von Eintrag n lief von 4,00 bis 4,24 s,
   der Einblendvorgang von n+1 startet aber bei genau 4,00 s (Delay). 240 ms lang standen
   zwei Texte deckungsgleich uebereinander — 6 % der Laufzeit unlesbar
   (Beleg scratchpad\rev-topbar-390-ueberblendung.png).
   Regel daraus: Das Ausblenden muss VOR dem naechsten Delay fertig sein.
   ⚠️ lin 28.08.2026 (fuenfter Eintrag): Zyklus 16 s → 20 s, ein Schritt ist damit 20 %
   statt 25 %. Die Prozentwerte MUSSTEN mitwandern — mit den alten 23/25 % haette das
   Ausblenden erst bei 4,6-5,0 s geendet, waehrend n+1 schon bei 4,0 s einblendet: exakt
   der Ueberblendungs-Blocker in gross. Jetzt: einblenden 0-2 % (400 ms), stehen bis 18 %,
   ausblenden 18-20 % — Ende exakt auf der 4-s-Marke, an der n+1 bei opacity 0 startet.
   visibility haengt mit drin (siehe Kommentar oben am Item): sichtbar nur im eigenen
   Fenster, danach hidden — damit trifft elementFromPoint den Eintrag, den man auch sieht.
   Zwischen 0 % und 2 % gilt das Element als sichtbar (CSS interpoliert visibility so, dass
   ein sichtbarer Endpunkt das Intervall gewinnt) — das ist genau die Einblendphase, also
   richtig. */
@keyframes gd24-topbar-rotate {
    0%     { opacity: 0; visibility: hidden; }
    2%     { opacity: 1; visibility: visible; }
    18%    { opacity: 1; visibility: visible; }
    20%    { opacity: 0; visibility: hidden; }
    100%   { opacity: 0; visibility: hidden; }
}
/* Bewegungsreduktion: keine Animation, erster Eintrag statisch. Bewusst INNERHALB der
   1199-px-Query — ab 1200 px stehen ohnehin alle fuenf nebeneinander und duerfen nicht
   auf opacity 0 fallen. */
@media (max-width: 1199.98px) and (prefers-reduced-motion: reduce) {
    .gd24-topbar__item { animation: none; opacity: 0; visibility: hidden; }
    .gd24-topbar__item:nth-child(1) { opacity: 1; visibility: visible; }
}

/* ==========================================================================
   F7 — KAUFPFAD-FORMULARE: NUR FARBEN (Ben, 28.08.2026)
   Radius und Hoehen bleiben ausdruecklich NOVA-Standard. Geaendert wird nur, was
   farblich neben der Palette stand: NOVA-Grau #707070 (Rahmen), #525252 (Text) und
   das aus dem Backend-Slot kompilierte Gruen rgb(83,139,76) — nicht ganz unser #4E8247.
   Bewusst GLOBAL und nicht auf den Kaufpfad gescopet (Fehlerregister 17): ein
   Grundwert, der im Warenkorb falsch ist, ist es auf /Kontakt genauso.
   Kein !important-Teppich — custom.css laedt zuletzt, gleiche Spezifitaet gewinnt.
   ========================================================================== */

/* Rahmen ruhend: Ben nannte --gd24-sand (#E3DAC6) als erste Wahl. Gemessen betraegt der
   Kontrast von #E3DAC6 auf Weiss nur 1,39:1 — WCAG 1.4.11 verlangt fuer die Umrandung
   eines Bedienelements 3:1. Ein Eingabefeld waere praktisch randlos. Deshalb die dunklere
   Variante der Palette: --gd24-muted #6E6C5D = 5,29:1 auf Weiss, also derselbe optische
   Halt wie NOVAs #707070 (4,95:1), nur im warmen Ton der Palette statt Neutralgrau.
   `border-color` statt `border`: faerbt nur um, erfindet nirgends einen neuen Rahmen
   (Fehlerregister 30). */
.form-control,
.custom-select {
    border-color: var(--gd24-muted);
    color: var(--gd24-ink);
}
/* Fokus: Rahmen Primaergruen + Ring in derselben Farbe. Ringgeometrie (0,2rem, plus der
   inset-Schatten von NOVA) unveraendert uebernommen — nur die Farbe wechselt, damit die
   Feldhoehe und der Sprung beim Fokussieren exakt gleich bleiben. */
.form-control:focus {
    border-color: var(--gd24-green-500);
    box-shadow: inset 0 1px 1px rgba(0, 0, 0, .075), 0 0 0 .2rem rgba(78, 130, 71, .25);
    /* Gemessen 28.08.: NOVA setzt die Textfarbe im Fokus ein zweites Mal
       (`.form-control:focus{color:#525252}`, 0,2,0) und schlaegt damit die Regel oben (0,1,0) —
       das Feld sprang beim Fokussieren zurueck auf NOVA-Grau. Deshalb hier mitziehen. */
    color: var(--gd24-ink);
}
.custom-select:focus {
    border-color: var(--gd24-green-500);
    box-shadow: 0 0 0 .2rem rgba(78, 130, 71, .25);
}
/* Der Auswahlpfeil des Selects steckt als SVG mit fill #707070 in NOVAs
   background-Kurzform. Nur die Longhand background-image ersetzen — Position, Groesse und
   no-repeat kommen weiter aus NOVAs Regel, die Geometrie bleibt damit unangetastet. */
.custom-select {
    background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 32 32' fill='%232F5233' x='0px' y='0px' xml:space='preserve'%3E%3Cpolygon points='16,18.2 11.8,14.6 12.4,13.8 16,16.8 19.6,13.8 20.2,14.6 '/%3E%3C/svg%3E");
}

/* Angehaengte Kaestchen einer input-group (das "EUR" der Preisspanne, die Einheit am
   Mengenfeld). Gemessen 28.08.: sie bilden mit dem Feld EINEN sichtbaren Rahmen (Ober- und
   Unterkante deckungsgleich, 353,0 / 378,6), zogen ihre Rahmenfarbe aber aus einer zweiten
   Quelle — nach dem Umfaerben stand NOVA-Grau #707070 direkt neben dem warmen Feldrand.
   Genau die halb gestylte Gruppe, die Ben beanstandet. Rahmen mitziehen, Fuellung auf
   Pergament (Mockup 2 nennt --parch fuer die Stepper-/Anhaengsel-Flaechen). Nur Farben —
   Hoehe, Radius und Polster bleiben NOVA. */
.input-group-text {
    border-color: var(--gd24-muted);
    background-color: var(--gd24-cream);
    color: var(--gd24-ink);
}

/* Checkboxen / Radios: NOVA faerbt sie aus dem kompilierten Backend-Slot rgb(83,139,76).
   Auf das exakte Primaergruen ziehen; Form, Groesse und Radius bleiben.
   Bewusst NICHT angefasst: der Druckzustand `:not(:disabled):active` (#b7d6b4, eine
   Aufhellung des alten Slots) — er dauert Millisekunden, und ein Ersatzwert waere ein
   gewuerfelter Ton ausserhalb der Skala. */
.custom-control-input:checked ~ .custom-control-label::before {
    border-color: var(--gd24-green-500);
    background-color: var(--gd24-green-500);
}
.custom-control-input:focus:not(:checked) ~ .custom-control-label::before {
    border-color: var(--gd24-green-500);
}
.custom-control-input:focus ~ .custom-control-label::before {
    box-shadow: inset 0 1px 1px rgba(0, 0, 0, .075), 0 0 0 .2rem rgba(78, 130, 71, .25);
}

/* Mengen-Stepper (PDP und Warenkorb): NOVA nennt den Wrapper .form-counter (#quantity-grp),
   nicht .quantity-wrapper (NOVA-LIVE-LEHREN N.5). Der sichtbare Rahmen sitzt am Wrapper,
   die Plus/Minus-Knoepfe sind rahmenlose .btn in #525252. Nur beides umfaerben — die Hoehen
   (43 px aussen / 41 px innen) bleiben unberuehrt, damit Register 11 nicht aufgeht. */
.form-counter { border-color: var(--gd24-muted); }
.form-counter .btn { color: var(--gd24-green-700); }
.form-counter .btn:hover,
.form-counter .btn:focus { color: var(--gd24-green-500); }
/* lin 28.08.2026, Ben (11:28): "wenn ich im Feld tippen wuerde, kommen am Rand 2 komische Raender".
   Drei NOVA-Regeln aus my-nova.css: `.form-control:focus` macht das Feld WEISS (auf Pergament) und
   haengt den 3,2-px-Ring ans Feld statt an die Gruppe; `.form-counter .btn:hover` faerbt die
   ±-Knoepfe blaugrau (#f5f7fa). Jetzt: Feld bleibt transparent und ringlos, der Fokusring liegt
   auf der ganzen Gruppe (:focus-within, gleiche Geometrie wie F7), Knopf-Hover als Gruen-Lasur. */
.form-counter .form-control:focus {
    background-color: transparent;
    box-shadow: none;
    border-color: transparent;
}
.form-counter:focus-within {
    border-color: var(--gd24-green-500);
    box-shadow: 0 0 0 .2rem rgba(78, 130, 71, .25);
}
.form-counter .btn:hover,
.form-counter .btn:focus { background-color: rgba(78, 130, 71, .08); }

/* Sortier-Select und Ansichts-Umschalter der Kategorie-Toolbar laufen als
   .btn-outline-secondary. Der Rahmen ist bereits Palette-Gold (rgb(184,154,90) =
   --gd24-gold, aus dem Backend-Slot $secondary); daneben standen noch NOVA-Grau #525252
   als Text und #ebebeb als Hover-/Aktiv-Flaeche. Beides auf die Palette.
   Die lange :not()-Kette ist NOVAs eigener Selektor (0,4,0) — ohne sie greift die Regel
   im Aktiv-Zustand nicht (Fehlerregister 16: Spezifitaet, nicht !important). */
/* ⚠️ lin 28.08.2026, Reviewer-Nachtrag: Der Rahmen kam aus dem Backend-Slot als
   --gd24-gold #B89A5A — auf Weiss nur 2,69:1 und damit unter der 3:1-Grenze von
   WCAG 1.4.11 fuer die Umrandung eines Bedienelements. Dieselbe Rechnung wie beim
   Feldrand oben, nur eine Stufe dunkler aus derselben Palette: --gd24-gold-d #856A33.
   Ruhend UND in hover/focus/active gesetzt, sonst wechselt die Gruppe im Betrieb die
   Rahmenfarbe (Fehlerregister 11). Text und Flaeche bleiben wie in Runde 1. */
.btn-outline-secondary { color: var(--gd24-ink); border-color: var(--gd24-gold-d); }
.btn-outline-secondary:focus { border-color: var(--gd24-gold-d); }
@media (hover) {
    .btn-outline-secondary:hover {
        background-color: var(--gd24-cream);
        color: var(--gd24-green-700);
        border-color: var(--gd24-gold-d);
    }
}
.btn-outline-secondary:not(:disabled):not(.disabled):active,
.btn-outline-secondary:not(:disabled):not(.disabled).active,
.show > .btn-outline-secondary.dropdown-toggle {
    background-color: var(--gd24-cream);
    color: var(--gd24-green-700);
    border-color: var(--gd24-gold-d);
}

/* ==========================================================================
   PDP-HEBEL #1/#2/#6/#8 + CONSENT-BADGE — lin 28.08.2026
   Quelle: Projektinformationen\PDP-CONVERSION-AUDIT-2026-08-27.md, von Ben freigegeben.
   Kein !important-Teppich — custom.css laedt zuletzt, gleiche Spezifitaet gewinnt.
   ========================================================================== */

/* ---------- #1 Sticky-Kaufleiste (Markup + JS: productdetails/details.tpl) ---------- */
/* Grundmuster aus dem SuperBee-Shop (NOVAChild571/themes/my-nova/custom.css 306-358),
   dort live erprobt; uebernommen sind seine drei bewussten Punkte:
   - `transform: translateY(110%)` statt `display: none` — die Leiste faehrt weich ein statt
     zu springen und bleibt messbar (aria-hidden + inert setzt das JS);
   - `env(safe-area-inset-bottom)` fuer die Home-Indicator-Zone auf iPhones;
   - Overlay-Hausputz: fixe Fremdelemente weichen, solange die Leiste steht.
   Nur unter 992 px: ab lg haelt die Sticky-Galerie (R.16) den Kaufblock ohnehin im Blick.
   Das JS laeuft auf allen Breiten — der Zustand haengt an der Klasse, nicht an einer
   JS-Breitenabfrage (sonst wird der Resize zur Fehlerquelle).

   lin 28.08.2026, Ben-Review Runde 4 (P6), Ben: "designe das bitte schoen".
   Neu gegenueber 5.9.43: Pergament-Grund statt Weiss (die Leiste liest sich als eigene
   Flaeche, nicht als abgeschnittener Seiteninhalt), links ein Stueckzahl-Stepper in der
   Optik des Formular-Steppers (Weiss, R10, 1,5-px-Linie — Mockup-Abschnitt 4: interaktive
   Elemente 1,5 px), rechts der Kaufknopf ueber die restliche Breite mit dem Betrag IM
   Knopf und dem gruenen Schatten von .gd24-buy-btn. Der Artikelname ist raus.
   Hoehe: 44 px Inhalt + 2 x 8 px Polster = 60 px, plus Safe-Area — Bens Deckel 64 px. */
.gd24-stickybuy { display: none; }

@media (max-width: 991.98px) {
    .gd24-stickybuy {
        display: block;
        position: fixed;
        left: 0;
        right: 0;
        bottom: 0;
        /* NOVAs Header ist .sticky-top = 1020; die Leiste muss darueber liegen, aber unter
           dem Fullscreen-Zoom der Galerie (#image_wrapper.fullscreen, z-index 10000). */
        z-index: 1030;
        background: var(--gd24-cream);
        border-top: 1px solid var(--gd24-sand);
        box-shadow: 0 -6px 20px rgba(35, 63, 38, .14);
        transform: translateY(110%);
        transition: transform .25s ease;
    }
    .gd24-stickybuy.is-visible { transform: translateY(0); }
    .gd24-stickybuy__inner {
        max-width: 960px;
        margin: 0 auto;
        padding: 8px 12px;
        padding-bottom: calc(8px + env(safe-area-inset-bottom));
        display: flex;
        align-items: center;
        gap: 8px;
    }
    /* Stepper: EINE Hoehe fuer die ganze Gruppe, die Teile referenzieren sie
       (Fehlerregister 11) — kein Teil holt seine Hoehe aus dem Inhalt. */
    .gd24-stickybuy__qty {
        /* ⚠️ FESTE Breite, kein `flex: 0 0 auto`. Ben sah live eine Leiste, in der nur
           das "−" stand: die Gruppe war auf die Breite ihres ersten Kindes zusammen-
           gefallen, Zahl und "+" lagen hinter `overflow: hidden`. Headless war sie mit
           108 px korrekt — der Zustand haengt also an einer Browser-/Font-Eigenheit beim
           Content-Sizing verschachtelter Flexboxen. Eine ausgerechnete Breite kann gar
           nicht erst kollabieren: 115 px aussen = 112 px innen = 40 + 32 + 40.
           47 px aussen = 44 px Tap-Hoehe innen (2 x 1,5 px Linie). Die Leiste bleibt mit
           47 + 2 x 8 px Polster bei 63 px und damit unter Bens Deckel von 64 px. */
        flex: 0 0 115px;
        width: 115px;
        display: flex;
        align-items: stretch;
        height: 47px;
        background: var(--gd24-cream);
        border: 1.5px solid var(--gd24-sand);
        border-radius: 10px;
        overflow: hidden;
    }
    .gd24-stickybuy__qty[hidden] { display: none; }
    /* ⚠️ Breite 40 statt 44 px: Ein 44 px breites Trio (44/32/44 = 120 px) laesst bei
       360 px nur 208 px fuer den Knopf, gebraucht werden 205 — es waere knapp, aber die
       Beschriftung duerfte kein Zeichen wachsen. 40/32/40 = 112 px haelt auf beiden
       Breiten Luft. Tap-Ziel 40 x 44 px (Bens Vorgabe: >= 40 px). */
    .gd24-stickybuy__step {
        flex: 1 1 40px;
        border: 0;
        background: transparent;
        color: var(--gd24-green-700);
        font-size: 1.15rem;
        font-weight: 700;
        line-height: 1;
        padding: 0;
        cursor: pointer;
    }
    .gd24-stickybuy__step:hover,
    .gd24-stickybuy__step:focus { background: var(--gd24-cream); color: var(--gd24-green-500); }
    .gd24-stickybuy__count {
        flex: 1 1 32px;
        display: flex;
        align-items: center;
        justify-content: center;
        background: #fff;
        font-size: 15px;
        font-weight: 700;
        color: var(--gd24-ink);
        border-left: 1px solid var(--gd24-sand);
        border-right: 1px solid var(--gd24-sand);
    }
    /* Kaufknopf: Optik von .gd24-buy-btn (R10, Primaergruen, gruener Schatten, 700).
       inline-flex mit space-between — Beschriftung links, Betrag rechts. */
    .gd24-stickybuy__btn {
        flex: 1 1 auto;
        min-width: 0;
        /* dieselbe Hoehe wie der Stepper — eine Quelle fuer die ganze Zeile
           (Fehlerregister 11), nicht zwei Teile mit je eigener Rechnung. */
        min-height: 47px;
        display: flex;
        align-items: center;
        justify-content: space-between;
        gap: 8px;
        padding: 0 14px;
        border: 0;
        border-radius: 10px;
        background: var(--gd24-green-500);
        color: #fff;
        box-shadow: 0 6px 16px rgba(60, 104, 55, .28);
    }
    .gd24-stickybuy__btn:hover,
    .gd24-stickybuy__btn:focus { background: var(--gd24-green-400); color: #fff; }
    /* Nur die Beschriftung darf schrumpfen. Der Betrag NIE — eine abgeschnittene Zahl
       waere eine falsche Preisangabe (Ben: "keine Ellipsen im Preis"). */
    .gd24-stickybuy__label {
        min-width: 0;
        overflow: hidden;
        text-overflow: ellipsis;
        white-space: nowrap;
        font-size: 14px;
        font-weight: 700;
    }
    .gd24-stickybuy__price {
        flex: 0 0 auto;
        white-space: nowrap;
        font-family: var(--gd24-serif);
        font-size: 1.05rem;
        font-weight: 700;
        color: #fff;
    }
    /* Fixe Fremdelemente aus dem Weg, solange die Leiste steht (Fehlerregister 7,
       SuperBee-Muster "Overlay-Hausputz"): der Nach-oben-Pfeil rechts unten und — bei
       768-991 px, wo das Consent-Badge noch sichtbar ist — das Badge links unten.
       Gemessen 28.08. bei 768 px: Badge x16/y968/40x40 gegen Leiste 960-1024, also mitten
       drin. Die Klasse setzt das JS nur waehrend der Sichtbarkeit; beim Zurueckscrollen
       sind beide wieder da. */
    .smoothscroll-top.gd24-overlay-weg,
    #consent-settings-btn.gd24-overlay-weg { display: none; }
    /* Am Seitenende ueberdeckt die Leiste sonst die Fusszeile. `:has` bindet das an die
       Anwesenheit der Leiste, also an die Artikelseite — die Body-Klassen sind auf allen
       Seiten identisch und taugen nicht als Anker. */
    body:has(.gd24-stickybuy) #copyright { padding-bottom: 5rem; }
}
@media (prefers-reduced-motion: reduce) {
    .gd24-stickybuy { transition: none; }
}
/* Sehr schmale Geraete (360 px): Stepper-Zellen und Knopfpolster eine Stufe kleiner,
   damit Beschriftung und Betrag ohne Kuerzung nebeneinander stehen. */
/* 360 px: Stepper und Knopfpolster eine Stufe kleiner. Gerechnet bei 360 px —
   360 - 24 (Polster) - 8 (Abstand) - 105 (Stepper) = 223 px fuer den Knopf; gebraucht
   werden 121 (Beschriftung) + 56 (Betrag) + 8 + 20 = 205. Der Betrag wird nie gekuerzt. */
@media (max-width: 389.98px) {
    .gd24-stickybuy__qty { flex-basis: 105px; width: 105px; }
    .gd24-stickybuy__step { flex-basis: 36px; }
    .gd24-stickybuy__count { flex-basis: 30px; }
    .gd24-stickybuy__btn { padding: 0 10px; }
    .gd24-stickybuy__label { font-size: 13.5px; }
}

/* ---------- #2 Bestaetigungs-Modal nach dem Ajax-Kauf (productdetails/pushed.tpl) ---------- */
/* Der Ajax-Weg zeigt pushed_success.tpl in NOVAs eModal. Gemessen bei 390x844: das
   Produktbild darin ist 441 px hoch, "Zum Warenkorb" landet bei 803-846 px — der Knopf
   wird von der Viewportkante angeschnitten. Nur das Bild deckeln (Reihenfolge Bild →
   Daten → Knoepfe bleibt), damit beide Knoepfe im Bild stehen. Kein Template-Override
   noetig: die Modal-Zellen sind Bootstrap-Spalten, die Hoehe kommt allein vom Bild. */
@media (max-width: 767.98px) {
    #pushed-success .pushed-success-image-wrapper img {
        max-height: 120px;
        width: auto;
        margin: 0 auto;
        display: block;
    }
}

/* ---------- Consent-Badge unter 768 px ausblenden (Ben, 28.08.2026) ---------- */
/* Grund: Das Badge (40x40, fixed unten links) ueberdeckte bei 390 px auf der Artikelseite
   die erste Staffelkachel und auf der Warenkorb-Zwischenseite die Artikelnummer
   (Fehlerregister 7, vom Reviewer gemessen). Ben: unter 768 px raus.
   ⚠️ Das Badge ist NICHT nur Deko, sondern der einzige Weg zurueck in die
   Consent-Einstellungen (Art. 7 Abs. 3 DSGVO: Widerruf so einfach wie die Einwilligung) —
   im Footer stand kein Link dorthin, die Datenschutzseite verweist im Text auf "das auf der
   Webseite bereitgestellte Cookie-Consent-Tool". Deshalb: Der Knopf bleibt im DOM (sein
   Klick-Handler aus consent.js haengt an ihm), er wird nur unsichtbar — und die Fusszeile
   bekommt unter 768 px den sichtbaren Ersatzweg "Cookie-Einstellungen"
   (layout/footer.tpl, Block layout-footer-copyright-copyright), der genau diesen Knopf
   programmatisch ausloest. Das Banner selbst (#consent-banner) ist nicht betroffen. */
@media (max-width: 767.98px) {
    #consent-settings-btn { display: none; }
}
.gd24-consent-link {
    background: none;
    border: 0;
    padding: 0;
    color: inherit;
    text-decoration: underline;
}
.gd24-consent-link:hover, .gd24-consent-link:focus { color: inherit; }

/* ---------- #6 Zahlarten-Logos mobil lesbar ---------- */
/* customsass setzt .payment-icon auf width 40 px (<=768) bzw. 32 px (<=480). Bei nativen
   100x30-Grafiken sind das 10 px Hoehe — als Vertrauenssignal unlesbar (Audit C/F).
   Jetzt die HOEHE fuehrend (20 px; alle acht Dateien sind 100x30, also gleich hoch —
   Fehlerregister 27) und die Breite daraus. 8 Logos a 66,7 px + 10 px Gap brechen bei
   390 px sauber auf 4+4 um, es bleibt keine halbe Reihe stehen (Fehlerregister 3b).
   ⚠️ Befund, kein Fix: bei dpr 3 sind 20 CSS-px = 60 Geraetepixel Hoehe gegen 30 native,
   also Faktor 2,0 (Fehlerregister 25 will <= 1,5). Schaerfer geht nur mit groesseren
   Quelldateien (SVG oder 300x90) — die liegen nicht vor. Lesbar und leicht weich schlaegt
   scharf und unlesbar; die Dateien gehoeren auf die Asset-Liste. */
@media (max-width: 767.98px) {
    .payment-icon { width: auto; height: 20px; }
}

/* ---------- #8 Tap-Ziele: Variationslabel und Galerie-Punkte ---------- */
/* Variationslabel gemessen 25 px hoch (Audit-Priorisierung #8). 44 px Trefferflaeche ueber
   min-height; Radius, Rahmen und Abstaende der Swatches bleiben unangetastet. Der
   Radio-Kreis von Bootstrap sitzt absolut auf top .15625rem — bei hoeherem Label stuende er
   oben statt neben dem Text, deshalb wird er mittig gesetzt. Nur die Position, nicht
   Groesse oder Farbe. */
#product-offer .variations .custom-control-label.variation {
    min-height: 44px;
    align-items: center;
}
/* lin 28.08.2026 (P8): Die Trefferflaeche kommt INNERHALB der Zeile zustande — aus der
   min-height oben, nicht mehr aus Abstaenden darum herum (die stehen unten auf 0). Ein
   zusaetzliches Polster waere doppelt gemoppelt und hat am Desktop 4 px je Zeile gekostet. */
/* Desktop kennt kein Tap-Ziel: dort zaehlt Dichte. 32-px-Zeilen (Ben, P8). */
@media (min-width: 992px) {
    #product-offer .variations .custom-control-label.variation { min-height: 32px; }
}
#product-offer .variations .custom-control-label.variation::before,
#product-offer .variations .custom-control-label.variation::after {
    top: 50%;
    transform: translateY(-50%);
}
/* Galerie-Punkte: NOVA gibt dem Knopf 12x12 px — das IST das Tap-Ziel. Der sichtbare Punkt
   bleibt exakt 12 px (jetzt als ::before gemalt), der Knopf darum wird auf 44x28 px
   vergroessert. Bewusst nicht 44 px hoch: die Punktreihe steht direkt unter dem Hauptbild,
   44 px wuerden den Kaufblock weitere 28 px nach unten schieben — genau die Strecke, die
   Hebel #1 verkuerzen soll. Scope #gallery_wrapper, damit die Punkte der Cross-Selling- und
   Startseiten-Karussells unberuehrt bleiben (Fehlerregister 13).
   Der Aktiv-Zustand muss hier mitkommen: NOVAs Regel faerbt den Knopf-Hintergrund, der
   jetzt transparent ist. Farbe aus der Palette statt NOVA-Grau #525252. */
#gallery_wrapper .slick-dots { height: auto; }
#gallery_wrapper .slick-dots li { margin: 0; }
#gallery_wrapper .slick-dots li button {
    width: 44px;
    height: 28px;
    border: 0;
    background-color: transparent;
    position: relative;
}
#gallery_wrapper .slick-dots li button::before {
    content: "";
    position: absolute;
    top: 50%;
    left: 50%;
    width: .75rem;
    height: .75rem;
    margin: -.375rem 0 0 -.375rem;
    border: .125rem solid #ebebeb;
    border-radius: 50%;
    background-color: #ebebeb;
}
#gallery_wrapper .slick-dots li.slick-active button::before {
    border-color: var(--gd24-green-500);
    background-color: var(--gd24-green-500);
}

/* ==========================================================================
   BEN-REVIEW RUNDE 4 — lin 28.08.2026
   Quelle: HANDOFF.md "Ben-Review 28.08. ~09:00", Screenshots
   Projektinformationen\review-2026-08-28\. Alle Werte aus der Mockup-2-Skala
   (Projektinformationen\MOCKUP2-DESIGNTOKENS.md): Abstaende 2/6/8/12/16/20,
   Radien 8/10/12/14, Farben nur ueber die :root-Tokens.
   ========================================================================== */

/* ---------- P8: Variationsblock verdichten ---------- */
/* Ben: "nicht conversion-tauglich, optimiere das" (Screenshot 10). Gemessen 28.08.
   bei 390 UND 1280 px, Kurzbeschreibung-Unterkante bis Preis-Oberkante: 193 px, davon
   105 px reiner Leerraum. Die vier Luecken aus dem Screenshot einzeln:
     16 px Innenabstand der Kurzbeschreibung + 16 px Aussenabstand der Eckdatenliste,
     24,8 px Label "Menge" + 8 px darunter,
     2 x 8 px zwischen den Optionszeilen,
     16 px unter der Definitionsliste + 16 px unter der Variations-Zeile.
   Die Optionszeilen selbst bleiben mobil 44 px hoch — Bens eigene Vorgabe fuer die
   Trefferflaeche; sie sind damit der Boden, unter den der Block nicht kann. */
#product-offer .product-info .info-essential .shortdesc { margin-bottom: 0; }
#product-offer .product-info ul.info-essential { margin: .5rem 0 6px; }
#product-offer .product-info .product-offer > .row.variations { margin-bottom: 6px; }
#product-offer .variations dl { margin-bottom: 0; }
#product-offer .variations .custom-control.custom-radio { margin-bottom: 0; }
/* Das Label "Menge" bekommt die Auszeichnung, die im Shop schon ueber den
   Staffelkacheln steht (.gd24-bulk-head) — zwei Auswahlen untereinander, eine
   Handschrift. Spart nebenbei 9 px Zeilenhoehe. */
#product-offer .variations dt {
    font-size: .78rem;
    font-weight: 700;
    letter-spacing: .06em;
    text-transform: uppercase;
    color: var(--gd24-gold-d);
    line-height: 1.25;
    margin-bottom: 6px;
}
/* Ohne Aussenabstand brauchen zwei gleich hohe Zeilen eine Kante, sonst verschwimmen
   sie zu einem Block. Haarlinie in der Linienfarbe, nur ZWISCHEN den Zeilen. */
#product-offer .variations .custom-control.custom-radio + .custom-control.custom-radio {
    border-top: 1px solid var(--gd24-sand);
}

/* ---------- P5: CI-Flaechen (#F6F2E7) und runde Ecken ---------- */
/* Ben (Screenshots 06/07/08): Tab-Kopf "Beschreibung", FAQ-Karte und Mengen-Stepper
   standen im NOVA-Rohzustand (Blaugrau #F5F7FA, Fast-Weiss #F9F9F9, Radius 2 px). */

/* Mobiler Akkordeon-Kopf der Reiter. */
#tabAccordion .card {
    border: 1px solid var(--gd24-sand);
    border-radius: 12px;
    overflow: hidden;
}
#tabAccordion .card-header {
    background-color: var(--gd24-cream);
    border-bottom-color: var(--gd24-sand);
}

/* FAQ-Karte. Radius 14 wie alle Inhaltsboxen des Mockups (Sidebar-/USP-/Beschreibungsbox). */
.faq-container-wrapper {
    background: var(--gd24-cream);
    border: 1px solid var(--gd24-sand);
    border-radius: 14px;
}

/* ---------- lin 28.08.2026, Ben-Review Desktop (Screenshots 19/20/21/22) ---------- */
/* (1) Whitespace Produktblock -> FAQ-Karte. Gemessen 1280 UND 390 (identisch): letzte
   USP-Kachel endet bei y 1059 (Desktop) / 1428 (mobil), die FAQ-Karte beginnt 72 px
   darunter. Der Abstand kommt aus ZWEI Quellen: 32 px `margin-bottom` an
   `.product-offer` (NOVA) + 40 px `margin-top` an `.faq-container-wrapper` (NOVA).
   Ben: Desktop halbieren, mobil -66 %.
   Die 32 px wandern auf 0 - das ist zugleich (2), siehe unten -, der Rest steht als
   EIN gepflegter Wert am Folgeblock: 24 px mobil (72 -> 24 = -67 %) und 38 px ab
   992 px (72 -> 38 = -47 %, Ziel 36 auf den naechsten Wert der Mockup-2-Abstands-Skala
   2/6/7/8/9/10/11/12/16/20/24/28/30/38/44/50 gerundet). */
/* (2) Sticky-Galerie soll buendig mit der letzten USP-Kachel stoppen (Ben, Screenshot 20).
   Der Klebeweg eines `position: sticky`-Elements endet an der Unterkante seines
   Containing Blocks - das ist `.row.product-detail`, deren Hoehe die laengere
   Info-Spalte vorgibt. Solange `.product-offer` 32 px Unterabstand hat, endet die Zeile
   32 px UNTER der letzten USP-Kachel, und genau so weit rutschte die Galerie mit den
   Thumbnails darunter. Mit `margin-bottom: 0` faellt Zeilenende und Kachelunterkante
   zusammen - kein zweiter Hebel noetig, die Zoom-Ausnahme aus R.16 bleibt unberuehrt.
   Praefix wie bei den Nachbarregeln, sonst gewinnt my-nova_crit.css (Fehlerregister 16). */
#product-offer .product-info .product-offer { margin-bottom: 0; }

/* Der Abstand steht jetzt EINMAL am Folgeblock, fuer beide Faelle gleich:
   16 px mobil (Ben, Screenshot 23: "schon ein paar Pixel Abstand" - 24 px waren zu wenig
   Reserve, 0 px entstanden auf Artikeln OHNE FAQ, weil dort statt der FAQ-Karte direkt
   die Reiter folgen) und 38 px ab 992 px (72 -> 38 = -47 %).
   ⚠ Der Reiterblock hat ZWEI Fassungen (Fehlerregister 13): `.tab-navigation` liefert
   der Shop an Desktop-Browser, `#tabAccordion` an erkannte Mobilgeraete. Eine Regel nur
   auf `.tab-navigation` griff in Bens Ansicht deshalb nicht - beide stehen im Selektor. */
.faq-container-wrapper,
body:not(:has(.faq-container-wrapper)) .tab-navigation,
body:not(:has(.faq-container-wrapper)) #tabAccordion { margin-top: 16px; }
@media (min-width: 992px) {
    .faq-container-wrapper,
    body:not(:has(.faq-container-wrapper)) .tab-navigation,
    body:not(:has(.faq-container-wrapper)) #tabAccordion { margin-top: 38px; }
}

/* (3) Reiter auf die Breite der FAQ-Karte (Ben, Screenshot 22: "Platzverschwendung").
   Die FAQ-Karte IST der `.container` - Hintergrund und Rahmen liegen auf dessen
   Randbox, ihre Kante steht damit bei 160/1120 (1280 px). Reiterkopf und Reiterinhalt
   liegen dagegen INNERHALB des Container-Polsters von 16 px und standen deshalb bei
   176/1104. Das Polster faellt fuer genau diese beiden Container weg; die Textabstaende
   kommen aus den Elementen selbst (Akkordeon-Karte bzw. `.nav-link`). */
/* ⚠ KEIN Anker am Grosselternteil: NOVA baut den Reiterbereich nach dem Laden per JS
   um (`.tab-content` wandert in die `nav`, `.result-wrapper`/`.content` kommen erst
   danach dazu). Ein Selektor mit `.result-wrapper >` griff im ersten Anlauf deshalb
   nicht. Anker ist der Container selbst. */
.container:has(> .tab-navigation),
.container:has(> .tab-content),
.container:has(> #tabAccordion) {
    padding-left: 0;
    padding-right: 0;
}

/* Mengen-Stepper: eine Flaeche, ein Radius, buendige Kanten (Fehlerregister 11 —
   die Hoehe kommt weiter aus der Gruppe, nicht aus den Einzelteilen). */
#quantity-grp {
    border-radius: 8px;
    background-color: var(--gd24-cream);
}
#quantity-grp > .input-group-prepend > .btn { border-radius: 8px 0 0 8px; }
#quantity-grp > .input-group-append > .btn:last-child { border-radius: 0 8px 8px 0; }
#quantity-grp .form-control,
#quantity-grp .input-group-text { background-color: transparent; }

/* Bleibt von der Toolbar nichts uebrig, steht dort trotzdem NOVAs Rasterzeile mit
   margin-top 48 px (mobil) bzw. 32 px (Desktop) — 48 px Luft ueber der ersten Karte,
   und mobil MEHR als am Desktop. `:empty` greift nicht (Whitespace-Textknoten), deshalb
   ueber die Element-Kinder. Danach: 24 px H1 → erste Karte auf beiden Breiten. */
.productlist-page-nav:not(:has(> *)) { display: none; }

/* P8, Nachtrag nach der ersten Messung: Zwischen der letzten Optionszeile und dem Preis
   standen noch einmal 16 px — sie kommen NICHT von der <dl> (die steht auf 0), sondern
   von NOVAs <dd class="form-group"> darin (Bootstrap .form-group { margin-bottom: 1rem }).
   Gemessen 28.08.: dd endet bei y 883, die Spalte bei 899. */
#product-offer .variations dd.form-group { margin-bottom: 0; }

/* ---------- K2: "Frage zum Artikel" unter der FAQ-Sektion ---------- */
/* Outline-Knopf der Skala (R8, 11/26 Polster laut Mockup-Abschnitt 3), zentriert wie die
   Ueberschrift der FAQ-Karte darueber. inline-flex, nicht inline-block — sonst klebt das
   Label bei gestreckter Zeile oben (Fehlerregister 28). */
.gd24-question-wrap { text-align: center; margin: 1.25rem auto 1.5rem; }
.gd24-question-btn {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    gap: .5rem;
    min-height: 44px;
    padding: 11px 26px;
    border: 1.5px solid var(--gd24-green-500);
    border-radius: 8px;
    background: transparent;
    color: var(--gd24-green-700);
    font-size: 14.5px;
    font-weight: 700;
}
.gd24-question-btn:hover,
.gd24-question-btn:focus {
    background: var(--gd24-green-500);
    border-color: var(--gd24-green-500);
    color: #fff;
}

/* ---------- P1-Nachtrag: Trennlinien um die Verfuegbarkeitszeile ---------- */
/* Die Regel weiter oben (#product-offer .stock-information) hat NICHT gegriffen —
   NOVA schreibt die Rahmen mit `#product-offer .product-info .stock-information`
   (1 ID + 2 Klassen) und schlaegt damit jeden kuerzeren Selektor, auch mit !important
   (Fehlerregister 16). Gemessen 28.08. an 5.9.43: borderTop/Bottom weiterhin 1px.
   Gleicher Anker, gleiche Spezifitaet, jetzt spaeter im Stylesheet = gewinnt. */
#product-offer .product-info .stock-information.stock-information-p,
#product-offer .product-info .stock-information {
    border-top: 0;
    border-bottom: 0;
    /* Ben, 28.08. nachgereicht: Der Leerraum UEBER dem Badge (unter "inkl. 7% USt., …")
       und DARUNTER (bis "MENGE WAEHLEN & SPAREN") soll auf ein Drittel.
       Gemessen 5.9.45: oben 40 px (390) / 24 px (1280), unten 40 px auf beiden Breiten.
       Zusammensetzung oben = margin-top 16 (nur mobil) + 8 px Restzeile aus .price-note
       + padding-top 16. Unten = padding-bottom 16 + 24 px margin der Preiszeile.
       Beide Polster und die Mobil-Margin fallen weg; uebrig bleiben oben die 8 px
       Restzeile, unten 12 px aus dem Zeilenabstand. Ein Wert fuer beide Breiten statt
       zwei verschiedener — sonst waere es genau die Beliebigkeit, die Ben beanstandet. */
    padding-top: 0;
    padding-bottom: 0;
    margin-top: 0;
}
#product-offer .product-info .product-offer > .row:has(.stock-information) { margin-bottom: 12px; }
/* Die Rasterspalte, in der NOVAs "Frage zum Artikel" sass, bleibt als leere Huelle mit
   `margin-left: auto` zurueck (der {col} liegt ausserhalb des ueberschriebenen Blocks).
   `:empty` greift wegen der Whitespace-Textknoten nicht. */
#product-offer .product-info .question-on-item:not(:has(> *)) { display: none; }

/* ---------- P3: Reihenfolge im Kaufblock ---------- */
/* Ben: Warenkorb-Knopf → PayPal-Express → Zahlungsicons → USP-Kacheln.
   PayPal haengt das Plugin per Output-Filter ans ENDE von #add-to-cart
   (NOVA-LIVE-LEHREN O.5) — seine Position ist also nicht per Template steuerbar, wohl
   aber per `order`. Deshalb wird #add-to-cart zur Spalten-Flexbox und ALLE Kinder
   bekommen eine Ordnung: unbenannte Kinder (PayPal-Zeilen, Skripte, Hinweis-Alerts)
   liegen auf 3 und damit zwischen Formular und Icons. Ein Kind ohne `order` haette
   sonst 0 und stuende ganz vorn.
   lin 28.08.2026, Ben-Review Desktop (Screenshot 16): Die Ordnung galt bis 5.9.51 nur
   unter 768 px — am Desktop stand PayPal ganz unten, unter den Zahlungsicons. Jetzt
   ohne Media-Query auf JEDER Breite: der Befund war ueberall derselbe, also gehoert die
   Korrektur an die Basis und nicht in eine Breiten-Ausnahme (Fehlerregister 17).
   Ein Plugin-Setting (Selektor des PayPal-Mounts) ist dafuer nicht noetig und bleibt
   unangetastet. */
#add-to-cart { display: flex; flex-direction: column; }
#add-to-cart > * { order: 3; }
#add-to-cart > .gd24-bulk-head,
#add-to-cart > .gd24-bulk-tiles,
#add-to-cart > .gd24-bulk-summary { order: 1; }
#add-to-cart > .basket-form-inline { order: 2; }
#add-to-cart > .gd24-pay-icons { order: 4; }
#add-to-cart > .gd24-usp-buybox { order: 5; }

@media (max-width: 767.98px) {
    /* Die Spalten sind aus der {row} heraus zu direkten Kindern geworden — die
       Rasterabstaende der Zeile gelten dort nicht mehr, also hier explizit. */
    #add-to-cart > .gd24-pay-icons { margin-top: .6rem; }
    #add-to-cart > .gd24-usp-buybox { margin-top: .7rem; }
    /* Ben: "Zahlungsicons kleiner, direkt unter PayPal". Hoehe fuehrend wie bisher
       (alle acht Dateien sind 100x30, Fehlerregister 27), 20 → 16 px.
       ⚠ Befund, kein Fix: acht Logos in EINER Reihe sind bei 390 px nicht moeglich —
       bei 16 px Hoehe ist jedes 53 px breit, acht davon brauchen 427 px bei 358 px
       Platz. Eine echte Einzeiligkeit ginge nur mit weniger Logos — Bens Entscheidung.
       ⚠ Der Umbruch im Fluss ergab 5 + 3 (gemessen 28.08. bei 390 px) — eine angebrochene
       zweite Reihe, genau das Muster aus Fehlerregister 3b. Deshalb ein festes 4er-Raster:
       zwei volle Reihen, kein Rest, auf jeder Breite gleich. */
    .payment-icon { width: auto; height: 16px; }
}

/* Zahlungsicons: festes 4er-Raster auf JEDER Breite. Im Fluss brachen sie mobil auf
   5 + 3 und am Desktop auf 6 + 2 um — beides eine angebrochene zweite Reihe
   (Fehlerregister 3b). Vier Spalten ergeben zwei volle Reihen, unabhaengig von der
   Breite. Acht Logos in EINER Reihe sind bei 390 px nicht moeglich: bei 16 px Hoehe
   ist jedes 53 px breit, acht brauchen 427 px bei 358 px Platz — Einzeiligkeit ginge
   nur mit weniger Logos, das ist Bens Entscheidung. */
.payment-icons-wrapper {
    display: grid;
    grid-template-columns: repeat(4, 1fr);
    justify-items: center;
    align-items: center;
    gap: 10px;
}

/* ---------- P9: Attribut-Tabelle unter der Beschreibung ---------- */
/* Ben (Screenshots 13/15): (a) bei 390 px brach "Versandgewich-t:" mitten im Wort,
   (b) NOVA-Rohoptik (Bootstrap-Grau #f8f9fa, eckig) statt CI.
   (a) Ursache war die feste Rasterbreite der Label-Spalte (gemessen 126 px bei einem
   Wortbedarf von ~130 px). `word-break`/`hyphens` waeren Symptomkosmetik — die Spalte
   bekommt Inhaltsbreite (`width: 1%` + `nowrap` ist die uebliche Tabellen-Redewendung
   dafuer), der Wert steht direkt daneben statt in der Bildschirmmitte. Gemessen passt
   das Label bis hinunter zu 320 px; das von Ben genannte Stapeln unter 360 px ist damit
   nicht noetig.
   (b) `border-collapse: separate` ist Pflicht, sonst greift der Radius nicht — bei
   `collapse` (Bootstrap-Standard) ignorieren Browser border-radius auf der Tabelle. */
.product-attributes table {
    border-collapse: separate;
    border-spacing: 0;
    border: 1px solid var(--gd24-sand);
    border-radius: 12px;
    overflow: hidden;
}
.product-attributes table td,
.product-attributes table th { border-color: var(--gd24-sand); }
.product-attributes table td:first-child {
    width: 1%;
    white-space: nowrap;
    color: var(--gd24-green-700);
    font-weight: 600;
    /* Bootstraps .h6 auf einem <td> bringt margin-bottom .5rem mit — auf Tabellenzellen
       wirkungslos gemeint, in der Praxis Zeilenhoehe. */
    margin-bottom: 0;
}
.product-attributes table td { color: var(--gd24-ink); }
.product-attributes .table-striped tbody tr:nth-of-type(odd) { background-color: var(--gd24-cream); }
/* Die Gegenzeile blieb im NOVA-Blaugrau (#f8f9fa) stehen und ergab ein Pergament/Blau-
   Zebra. Weiss ist der Gegenpart zu Pergament im ganzen Shop (Karten, Preisbox). */
.product-attributes .table-striped tbody tr:nth-of-type(even) { background-color: #fff; }
