/* ============================================================================
   ThurData CI 2030 — Base
   ----------------------------------------------------------------------------
   CI 2030 Base V1 — fuer Produktseiten an realen Referenzseiten validiert.
   Referenzen: ThurWeb (Matrix, 5 Produkte) · ThurVDC (Flex, Foto-Hero) ·
   ThurVServer (Flex, Split-Hero) · ThurBuilder (Kacheln, 3 Produkte).
   Stand 28.08.2026.

   Als Foundation zusaetzlich real bestaetigt an Zielgruppen-Seiten (KMU,
   Entwickler) und an einer Hub-/Routing-Seite mit Mini-Hero (Entwickler-Hub).
   Der Mini-/Routing-Hero — ohne Bild, ohne Buehne — braucht KEINE eigene
   Padding-Stufe: --td-hero-pad traegt ihn (gemessen 197 gegen 192 px
   Gesamtluft im Vergleichsstand).

   Aenderung 28.08.2026 (Bugfix, keine neue Generation): Hero-Luft haengt
   nicht mehr am Elementtyp des letzten Inhalts, siehe Abschnitt 4.

   Normative Quelle ist der Skill `ci-2030` (thurdata/skills ->
   plugins/thurdata-skills/skills/ci-2030/SKILL.md).

   Regel: Seiten binden diese Datei ein und definieren KEINE CI-Tokens lokal
   neu. Seitenspezifisches CSS ergaenzt, es ueberschreibt die Foundation nicht.

   Aenderungen am Foundation-/Komponentenkern kuenftig nur aufgrund eines
   realen neuen Falls, eines Fehlers oder eines dokumentierten CI-Entscheids —
   nicht aus theoretischer Optimierung. V1 deckt PRODUKTSEITEN, Zielgruppen-
   Landings und Hub-/Routing-Seiten ab; Tool-Hero und Formulare bleiben
   ungeprueft, bis eine reale Seite sie braucht.

   Entscheidungsspur: thurdata/homepage -> content/entscheidungen/
   ============================================================================ */

/* ---------------------------------------------------------------- 1. Tokens */

:root{
  /* Marke */
  --td-primary:      #1B5F8F;
  --td-secondary:    #7690C9;
  --td-accent:       #F08228;
  --td-accent-hover: #D96F1D;
  --td-dark:         #0F1A24;
  --td-light:        #F5F7FA;
  --td-blue:         #EEF4FA;

  /* Text hell — Kontrastwerte siehe content/ci-konventionen.md 3b */
  --td-text:   #2A2E36;   /* Headlines, zentrale Aussagen        */
  --td-body:   #3F4A5A;   /* Fliesstext, wichtige Erklaertexte   */
  --td-muted:  #526173;   /* Leads, sekundaere Erklaerungen      */
  --td-subtle: #64748B;   /* NUR Metadaten, nie Kaufentscheidung */

  /* Text dunkel */
  --td-dark-text:   rgba(255,255,255,.82);
  --td-dark-muted:  rgba(255,255,255,.68);
  --td-dark-subtle: rgba(255,255,255,.52);

  /* Linien */
  --td-line:        #DCE4EC;
  --td-line-strong: #C9D5E0;
  --td-border:      var(--td-line);

  /* Radius — 6 klein / 10 Karten+Panels / Pill Badges */
  --td-radius-sm:   6px;
  --td-radius-lg:   10px;
  --td-radius-pill: 999px;
  --td-radius:      var(--td-radius-sm);   /* Alias, Altbestand */

  /* Container */
  --td-container:      1180px;
  --td-container-wide: 1400px;
  --td-stage-max:       760px;

  /* Page Gutter — schaltet unten an den Foundation-Breakpoints um */
  --td-page-gutter-desktop: 40px;
  --td-page-gutter-tablet:  28px;
  --td-page-gutter-mobile:  20px;
  --td-page-gutter: var(--td-page-gutter-desktop);

  /* Element-Spacing (Abstaende INNERHALB von Komponenten) */
  --td-space-1:  4px;
  --td-space-2:  8px;
  --td-space-3: 16px;
  --td-space-4: 24px;
  --td-space-5: 32px;
  --td-space-6: 48px;
  --td-space-7: 64px;

  /* Hero-Padding — eigene Skala, schaltet unten an den Foundation-Breakpoints */
  --td-hero-pad: 90px;

  /* Section-Rhythmus — eigene Skala, NICHT an das Element-Raster gebunden */
  --td-sec-compact:  56px;
  --td-sec-default:  84px;
  --td-sec-spacious:104px;
  --td-sec: var(--td-sec-default);

  /* Interaktion */
  --td-focus-ring: 0 0 0 3px rgba(240,130,40,.24);
  --td-shadow-interaction: 0 8px 20px rgba(0,0,0,.08); /* NUR Hover/Overlay */
  --td-transition: .16s ease;
}

/* -------------------------------------------------- 2. Foundation / Reset */

*,*::before,*::after{box-sizing:border-box}

body{
  margin:0;
  font-family:Roboto,"Helvetica Neue",sans-serif;   /* kein Arial, kein system-ui */
  font-size:16px;
  line-height:1.5;
  color:var(--td-text);
  background:#fff;
  -webkit-font-smoothing:antialiased;
}

a{color:var(--td-primary)}
a:hover{color:var(--td-accent)}

img,video{max-width:100%;height:auto}

:focus-visible{outline:none;box-shadow:var(--td-focus-ring)}

/* ------------------------------------------------------------ 3. Typografie */

h1,h2,h3,h4{color:var(--td-text);margin:0 0 .4em}

h1{font-size:42px;line-height:1.08;font-weight:900;letter-spacing:-1px}
h2{font-size:36px;line-height:1.12;font-weight:700;letter-spacing:-.4px}
h3{font-size:21px;line-height:1.18;font-weight:700;letter-spacing:-.01em}

/* Hero-H1 — benannter Sonderfall, nur die H1 im Hero */
.hero h1,h1.td-h1-hero{
  font-size:52px;line-height:1.04;letter-spacing:-.025em;max-width:760px;
}

p{margin:0 0 1em}

.td-lead{
  font-size:17px;line-height:1.6;font-weight:400;
  color:var(--td-muted);max-width:68ch;
}

.td-small,.td-caption{font-size:13px;line-height:1.5;color:var(--td-muted)}

.td-kicker{
  font-size:12px;font-weight:700;letter-spacing:.11em;text-transform:uppercase;
  color:var(--td-primary);margin-bottom:10px;
}

/* Lesbarkeit: erklaerende Texte nie font-weight 300 unter 18px */
.td-text  {color:var(--td-text)}
.td-body  {color:var(--td-body)}
.td-muted {color:var(--td-muted)}
.td-subtle{color:var(--td-subtle)}   /* NUR Metadaten */

/* -------------------------------------------------- 4. Container & Sections */

.td-container{
  width:100%;
  max-width:var(--td-container);
  margin-inline:auto;
  padding-inline:var(--td-page-gutter);
}

/* NUR fuer breite technische Tabellen, Visualisierungen, Datenansichten */
.td-container--wide{max-width:var(--td-container-wide)}

/* Full Bleed: der Hintergrund ist viewportbreit, der Content bleibt im Container */
.td-bleed{width:100%}

.sec{padding:var(--td-sec) 0}
.sec--compact  {--td-sec:var(--td-sec-compact)}
.sec--spacious {--td-sec:var(--td-sec-spacious)}

.sec-white{background:#fff}
.sec-light{background:var(--td-light)}
.sec-blue {background:var(--td-blue)}
.sec-dark {background:var(--td-dark);color:var(--td-dark-text)}

.sec-dark h1,.sec-dark h2,.sec-dark h3{color:#fff}
.sec-dark .td-lead{color:var(--td-dark-muted)}
.sec-dark .td-kicker{color:#9fb2c4}
.sec-dark a{color:#fff}

/* Buehnen (Hero mit Bild, Standort-Sektion): nie reines vh, immer gedeckelt */
.td-stage{min-height:min(76vh,var(--td-stage-max))}

/* --- Hero: gemeinsames Skelett, KEIN Universal-Hero -----------------------
   Traegt alle fuenf Hero-Typen des CI, ohne einen davon zu gestalten. Geregelt
   ist nur, was sonst jede Seite neu erfindet: Buehne, Bildebene, Overlay,
   Textbreite, Padding und die Dunkel-/Hellzustaende.
   Die Bildebene gibt es bewusst in ZWEI Formen, beide kommen real vor:
     a) CSS-Hintergrund auf .hero          (ThurWeb — Aufloesungsschwellen im CSS)
     b) .hero-bg mit einem echten <img>    (ThurVDC — srcset, object-position,
        nie loading="lazy", weil der Hero das LCP-Element ist)
   Motiv-Abhaengiges bleibt lokal: welches Bild, welcher Bildausschnitt, wie
   stark der Verlauf deckt. Buehnenhoehe ist opt-in ueber .td-stage. */
.hero{
  position:relative;display:flex;align-items:center;overflow:hidden;
  background-position:center;background-size:cover;background-repeat:no-repeat;
}
.hero>.td-container{position:relative;z-index:2;padding-block:var(--td-hero-pad)}

/* Die aeussere Hero-Luft kommt aus dem Padding, NICHT aus dem Margin des
   letzten Inhaltselements. Ohne diese Regel addiert ein abschliessender
   Absatz sein margin-bottom (1em) auf --td-hero-pad, und der Hero wird unten
   schwerer als oben — je nachdem, welcher Elementtyp zufaellig zuletzt steht.
   Gemessen 28.08.2026 an zwei unabhaengigen Seiten: ThurBuilder (endet mit
   p.tb-trust) 90/104 px, Entwickler-Hub (endet mit p.td-lead) 90/107 px;
   drei Heroes, die mit einem div enden, waren symmetrisch.
   Beide Selektoren noetig: nicht jeder Hero benutzt .hero-copy (ThurVServer
   setzt seine Textspalte direkt in den Container). */
.hero>.td-container>:last-child,
.hero-copy>:last-child{margin-bottom:0}

.hero-bg{position:absolute;inset:0;z-index:0}
.hero-bg img{display:block;width:100%;height:100%;object-fit:cover}

/* NUR die Ebene, KEIN Verlauf. Deckung, Richtung und Intensitaet sind
   Bildkorrektur und haengen am Motiv — an VDC gemessen (27.08.2026): derselbe
   Default-Verlauf, der ThurWeb traegt, liess dort die weisse H1 auf dem hellen
   Monitor stehen. Base definiert die Overlay-Ebene, nicht die Bildkorrektur.
   Jede Seite mit Foto-Hero setzt ihren eigenen background auf .hero-overlay. */
.hero-overlay{position:absolute;inset:0;z-index:1}

/* Textspalte: gedeckelt, damit die Zeilen lesbar kurz bleiben. */
.hero-copy{max-width:var(--td-stage-max)}
/* 42ch ist der Regelfall: im Hero konkurriert der Lead mit einem Bild oder
   einer Medienspalte, und kurze Zeilen halten ihn dort lesbar. Aktiv an
   ThurVDC, ThurWeb und ThurBuilder (je 401 px gemessen 28.08.2026).
   ENTSCHEID ANEB 28.08.2026: der Deckel BLEIBT. Ein Hero OHNE Bild und ohne
   Medienspalte (Mini-/Routing-Hero) weitet lokal auf den globalen Lead-Deckel
   (68ch) — bisher genau ein realer Fall, der Entwickler-Hub. Erst wenn ein
   zweiter unabhaengiger Fall dazukommt, wird daraus eine Base-Regel.
   Kein Umkehrschluss: enger duerfen Heroes lokal jederzeit werden. */
.hero-copy .td-lead{max-width:42ch}

/* Medienflaeche fuer Split-/UI-Heroes — nur Rahmen, keine Typ-Gestaltung. */
.hero-media{position:relative;z-index:2;min-width:0}
.hero-media img{display:block;width:100%;height:auto;border-radius:var(--td-radius-lg)}

/* Dunkel: die Textfarben der Section-Ebene gelten im Hero nicht automatisch,
   weil .hero-dark keine .sec-dark ist. */
.hero-dark{background-color:var(--td-dark);color:var(--td-dark-text)}
.hero-dark h1,.hero-dark h2,.hero-dark h3{color:#fff}
.hero-dark .td-lead{color:var(--td-dark-text)}
.hero-dark .td-kicker{color:#9fb2c4}
.hero-dark .td-small,.hero-dark .td-caption{color:var(--td-dark-muted)}
/* Hell: erbt die Standard-Textfarben, bekommt hier bewusst KEINEN Hintergrund
   aufgezwungen — weiss und --td-light sind beide zulaessig. */

/* --------------------------------------------------------- 5. Basis-Grids */

.td-grid-2,.td-grid-3,.td-grid-cards{display:grid;gap:var(--td-space-4)}
.td-grid-2{grid-template-columns:repeat(2,minmax(0,1fr))}
.td-grid-3{grid-template-columns:repeat(3,minmax(0,1fr))}
.td-grid-cards{grid-template-columns:repeat(auto-fit,minmax(280px,1fr))}
.td-grid--tight{gap:var(--td-space-3)}

/* ------------------------------------------------------------- 6. Buttons */
/* Orange = primaere Handlung · Blau = sekundaer, Navigation, Routing.
   Es gibt KEINEN blau gefuellten Button.                                    */

.btn{
  display:inline-flex;align-items:center;justify-content:center;
  min-height:44px;padding:0 18px;
  border:1.5px solid transparent;border-radius:var(--td-radius-sm);
  font-size:14px;font-weight:700;line-height:1;
  text-decoration:none;cursor:pointer;outline:none;
  transition:background-color var(--td-transition),border-color var(--td-transition),
             color var(--td-transition),box-shadow var(--td-transition);
}

.btn-primary{background:var(--td-accent);border-color:var(--td-accent);color:#fff}
.btn-primary:hover{background:var(--td-accent-hover);border-color:var(--td-accent-hover);color:#fff}
.btn-primary:focus-visible{box-shadow:var(--td-focus-ring)}

.btn-secondary{background:#fff;border-color:var(--td-primary);color:var(--td-primary)}
.btn-secondary:hover,
.btn-secondary:focus-visible{
  border-color:var(--td-accent);color:var(--td-accent);
  background:rgba(240,130,40,.055);
}
.btn-secondary:focus-visible{box-shadow:0 0 0 3px rgba(240,130,40,.15)}

.btn-text{
  min-height:auto;padding:7px 0;border:0;border-radius:0;
  background:transparent;color:var(--td-primary);
}
.btn-text:hover{color:var(--td-accent)}
.btn-text:focus-visible{color:var(--td-accent);box-shadow:0 2px 0 var(--td-accent)}

/* Auf dunklem Grund: kontrastiert, Bedeutung unveraendert */
.sec-dark .btn-secondary,.hero-dark .btn-secondary{
  background:transparent;border-color:rgba(255,255,255,.78);color:#fff;
}
.sec-dark .btn-secondary:hover,.hero-dark .btn-secondary:hover{
  color:var(--td-accent);border-color:var(--td-accent);background:rgba(240,130,40,.07);
}
.sec-dark .btn-text,.hero-dark .btn-text{color:#fff}
.sec-dark .btn-text:hover,.hero-dark .btn-text:hover{color:var(--td-accent)}

/* --- Zustaende gegen das Croster-Theme durchsetzen -----------------------
   Das Theme bringt Bootstrap mit, und dort heissen die Klassen GENAUSO:
   `.btn-secondary` ist dort ROT (#db3f3b), `.btn-primary` BLAU (#1b5f8f).
   Im Ruhezustand gewinnen wir ueber die Ladereihenfolge — bei gleicher
   Spezifitaet zaehlt die spaetere Datei, und unser Base laedt nach dem Theme.

   Bei den ZUSTAENDEN kippt das:
     Bootstrap  .btn-secondary:focus                              = (0,2,0)
     Bootstrap  .btn-secondary:not(:disabled):not(.disabled):active = (0,4,0)
     wir        .btn-secondary                                     = (0,1,0)
   Wir hatten nur `:focus-visible`, und das feuert bei der MAUS gar nicht —
   nur bei Tastatur. Ein Mausklick loest aber `:focus` aus. Ergebnis, am Render
   gesehen (MAEB 08.09.2026): Der angeklickte Bestellknopf wurde ROT und blieb
   es, solange der Fokus stand. Das las sich wie ein Auswahlzustand, den es gar
   nicht gibt — geklickt wird direkt in den Warenkorb. Beim orangen Knopf waere
   dasselbe in Dunkelblau passiert; das hatte nur noch niemand angeklickt.

   Deshalb hier `:focus` UND `:active` mit (0,4,0), also gleich schwer wie
   Bootstraps schwerste Regel und spaeter im Quelltext. Der Tastatur-Ring kommt
   danach mit derselben Spezifitaet zurueck, damit er wieder obenauf liegt.
   Barrierefreiheit bleibt: Wer mit der Tastatur navigiert, sieht den Ring. */
.btn:not(:disabled):not(.disabled):focus{box-shadow:none;outline:none}
.btn-primary:not(:disabled):not(.disabled):focus,
.btn-primary:not(:disabled):not(.disabled):active{
  background:var(--td-accent-hover);border-color:var(--td-accent-hover);color:#fff;
}
.btn-secondary:not(:disabled):not(.disabled):focus,
.btn-secondary:not(:disabled):not(.disabled):active{
  background:rgba(240,130,40,.055);border-color:var(--td-accent);color:var(--td-accent);
}
.btn-primary:not(:disabled):not(.disabled):focus-visible{box-shadow:var(--td-focus-ring)}
.btn-secondary:not(:disabled):not(.disabled):focus-visible{box-shadow:0 0 0 3px rgba(240,130,40,.15)}
.btn-text:not(:disabled):not(.disabled):focus-visible{box-shadow:0 2px 0 var(--td-accent)}

.btn-row{display:flex;gap:12px;flex-wrap:wrap}

/* ══ LEGACY-ALIASE — nur fuer den Altbestand, KEIN neues Markup damit ══
   Kanonisch sind .td-lead und .td-kicker. Die Kurznamen .lead / .kicker /
   .eyebrow stammen aus den Serienseiten vor dem Base-CSS. Zwei gleichwertige
   Namen fuer dieselbe Sache waren ein Grund, warum die Seiten auseinander-
   gedriftet sind (Reifebericht 27.08.2026). Sie bleiben, damit bestehende
   Seiten nicht brechen — der Migrationsweg ist Suchen-und-Ersetzen, kein Umbau.
   Lint-Kandidat: .lead / .kicker / .eyebrow in neuem Markup. */
.lead{font-size:17px;line-height:1.6;color:var(--td-muted);max-width:68ch;margin:14px 0 0}
.kicker,.eyebrow{
  font-size:12px;font-weight:700;letter-spacing:.11em;
  text-transform:uppercase;color:var(--td-primary);
}
.sec-dark .lead{color:var(--td-dark-muted)}
.sec-dark .kicker,.sec-dark .eyebrow{color:#9fb2c4}
.hero-copy .lead{max-width:42ch}
.hero-dark .lead{color:var(--td-dark-text)}
.hero-dark .kicker,.hero-dark .eyebrow{color:#9fb2c4}

/* LEGACY-Buttons — dieselbe Regel: kein neues Markup damit bauen. */
.btn-cta{background:var(--td-accent);border-color:var(--td-accent);color:#fff}
.btn-cta:hover{background:var(--td-accent-hover);border-color:var(--td-accent-hover)}
.btn-outline{background:#fff;border-color:var(--td-primary);color:var(--td-primary)}
.btn-outline:hover{border-color:var(--td-accent);color:var(--td-accent);background:rgba(240,130,40,.055)}
.btn-hero{padding:9px 24px;font-size:14px}

/* ------------------------------------------- 7. Standardflaechen & Content */

.card{
  background:#fff;
  border:1px solid var(--td-border);
  border-radius:var(--td-radius-lg);
  padding:32px 28px;
  /* kein dekorativer Dauerschatten */
}
/* Keine eigene Card-Typografie: H3 und Fliesstext folgen der Typografie-Skala.
   Die frueheren Werte (H3 18px, p 14.5px) stammten aus den Referenzseiten und
   waren nie beschlossen — entfernt 27.08.2026. */

.card-icon{
  width:22px;height:22px;
  display:inline-flex;align-items:center;justify-content:center;
  background:#E7EEF6;color:var(--td-primary);
}
.card-icon svg{
  width:22px;height:22px;
  /* CI: Lucide Outline, monochrom, currentColor, KEIN Filled-Icon-Mix.
     Ohne fill:none rendern Pfade ohne eigenes fill-Attribut schwarz gefuellt
     (an ThurVDC gemessen 27.08.2026). */
  fill:none;stroke:currentColor;stroke-width:2;stroke-linecap:round;stroke-linejoin:round;
}
.sec-dark .card-icon{background:rgba(255,255,255,.08);color:rgba(255,255,255,.8)}

.panel{
  background:#fff;border:1px solid var(--td-line);
  border-radius:var(--td-radius-lg);padding:18px 20px;
}

/* !important ist hier KEINE Schlamperei, sondern der einzige Weg: Das
   Croster-Theme (Bootstrap-Basis) setzt `.badge{background-color:#999!important;
   border-radius:12px!important}`. Gegen ein !important aus einer Datei, die in
   keinem unserer Repos liegt, hilft keine Spezifitaet — nur ein eigenes
   !important. Betraf beide Empfehlungs-Badges (Auswahlmatrix und Tabellenkopf):
   Sie waren auf Devel GRAU statt weiss. Lokal faellt das nie auf, weil dort das
   Theme fehlt (MAEB am Render gesehen, 08.09.2026).
   Nur diese beiden Eigenschaften tragen !important. Schriftgrad, Gewicht und
   Innenabstand setzt das Theme ohne — die gewinnen wir ueber die Ladereihenfolge. */
.badge{
  display:inline-flex;align-items:center;justify-content:center;
  background:#fff!important;color:var(--td-primary);
  border:1px solid rgba(255,255,255,.28);border-radius:var(--td-radius-pill)!important;
  padding:4px 9px;
  font-size:11px;font-weight:700;letter-spacing:.035em;text-transform:uppercase;
  white-space:nowrap;
}

/* FAQ — details/summary, kein JS */
.faq details{border-bottom:1px solid var(--td-line)}
.faq summary{
  cursor:pointer;list-style:none;
  padding:16px 0;font-size:17px;font-weight:700;color:var(--td-text);
  display:flex;justify-content:space-between;align-items:center;gap:16px;
}
.faq summary::-webkit-details-marker{display:none}
.faq summary::after{
  content:"+";font-weight:400;font-size:22px;color:var(--td-primary);
  transition:transform var(--td-transition);
}
.faq details[open] summary::after{content:"\00d7"}
.faq p{color:var(--td-muted);margin:0 0 16px}

/* ------------------------------------------------------- 8. Produktsystem */
/* VERTRAG Swipe (Base-CSS <-> ci-2030-components.js), festgehalten 27.08.2026:
   Der Scroller traegt IMMER beides — seine Klasse UND data-swipe-container:

       <div class="mobile-products" data-swipe-container> … </div>

   Das Attribut ist der kanonische Marker. Das Swipe-LAYOUT haengt daran
   (siehe Abschnitt 9), und das JS bindet den Tap-vs-Swipe-Schutz und den
   Swipe-Hinweis an denselben Selektor. Damit kann kein stiller Fehlzustand
   entstehen: ohne Attribut gibt es KEIN Swipe-Layout — der Fehler ist sofort
   sichtbar, statt dass ein Wisch versehentlich ein Produkt auswaehlt.
   Umgekehrt gilt: Layout ohne Verhalten ist nicht vorgesehen.
   Lint-Kandidat: .product-grid / .mobile-products ohne data-swipe-container. */
/* Regeln: CI -> "Produktauswahl & Paketvergleich".
   Bis 3 Produkte zeigen, ab 4 vergleichen. Eine Designsprache, zwei Formen. */

.product-responsive{container-type:inline-size;container-name:products}
.swipe-wrap{position:relative}

/* --- Produktkachel (2-3 Produkte) --- */
/* align-items:start — sonst zieht das Grid alle Kacheln einer Reihe auf die
   Hoehe der hoechsten. Klappt eine Kachel auf, bekommen die geschlossenen
   leeren Raum unter dem Knopf (am Render gemessen 03.09.2026). */
.product-grid{display:grid;grid-template-columns:repeat(3,minmax(0,1fr));gap:18px;align-items:start}

.product-tile{
  position:relative;display:flex;flex-direction:column;min-width:0;
  background:#fff;border:1px solid var(--td-line-strong);
  border-radius:var(--td-radius-lg);overflow:hidden;
  text-decoration:none;color:inherit;outline:none;
  transition:border-color var(--td-transition),box-shadow var(--td-transition);
}
/* ACHTUNG Theme-Kollision: Die Kachel ist ein <a>, und das Croster-Theme setzt
   fuer a:hover ein text-decoration:underline. Die Grundregel oben deckt nur den
   Ruhezustand — beim Hover unterstreicht das Theme JEDEN Text in der Kachel,
   vom Produktnamen bis zum Merkmalwert (auf Devel gesehen 04.09.2026 an
   ThurBuilder). Vorher fiel es nicht auf, weil die orange Flaechenfaerbung
   dominierte; seit die weg ist, ist es der einzige verbliebene Effekt.
   Deshalb hier explizit und inklusive Kindelementen. */
.product-tile:hover,.product-tile:hover *,
.product-tile:focus-visible,.product-tile:focus-visible *{text-decoration:none}

/* HOVER = UMRANDUNG, NICHT TEXTFLAECHE (Entscheid ANEB/MAEB 03.09.2026).
   Zwei Aenderungen gegenueber V1:
   1. Der Zustand faerbt keine Textflaechen mehr ein, nur noch den Rahmen.
      Die zweite Linie liegt als Innenschatten darin — eine echte
      Border-Verbreiterung wuerde das Layout verschieben.
   2. Gekapselt in @media (hover:hover): Auf Tablets bleibt ein Hover sonst
      nach dem Antippen kleben, bis man woanders hintippt. Auf Touch gibt es
      den Zustand damit gar nicht — dort wird ohnehin direkt getroffen. */
.product-tile:hover{border-color:var(--td-line-strong);box-shadow:none}
@media (hover:hover) and (pointer:fine){
  .product-tile:hover{
    border-color:var(--td-accent);
    box-shadow:inset 0 0 0 1px var(--td-accent);
  }
}
.product-tile:focus-visible{box-shadow:0 0 0 3px rgba(240,130,40,.2),0 8px 22px rgba(15,26,36,.06)}

/* Empfohlen = permanenter Status -> Primary, nie Orange.
   Die Statuslinie liegt als Pseudo-Element UEBER dem Header: ein inset-Schatten
   am .product-tile wird vom dunklen .tile-head verdeckt und bliebe unsichtbar
   (gemessen 27.08.2026 am Referenz-Render). */
.product-tile.recommended{border-color:rgba(27,95,143,.52)}
.product-tile.recommended::before{
  content:"";position:absolute;top:0;left:0;right:0;height:3px;
  background:var(--td-primary);z-index:2;pointer-events:none;
  transition:background var(--td-transition);
}
.product-tile.recommended:hover,.product-tile.recommended:focus-visible{
  border-color:var(--td-accent);
  box-shadow:0 0 0 2px rgba(240,130,40,.16),0 10px 24px rgba(15,26,36,.08);
}
/* Die weisse Pill der Kachel bleibt in JEDEM Zustand Status */
.product-tile .badge{background:#fff;color:var(--td-primary)}

.tile-head{
  padding:21px 22px 18px;background:var(--td-dark);color:#fff;
  border-bottom:1px solid rgba(255,255,255,.08);
}
.tile-head h3{color:#fff;margin:0}
.tile-head-top{display:flex;align-items:flex-start;justify-content:space-between;gap:12px;margin-bottom:7px}
.tile-claim{font-size:14px;color:rgba(255,255,255,.72);margin:6px 0 0;min-height:42px}
/* HINWEIS: Das CI verlangt gleiche Headerhoehe je Produktgruppe. min-height traegt
   nur einzeilige Claims. Den Angleich mehrzeiliger .tile-head macht zentral
   ci-2030-components.js (equalizeTileHeads) — nicht seitenlokales JS. */
/* Der dunkle Header bleibt beim Hover dunkel */
.product-tile:hover .tile-head,.product-tile:focus-visible .tile-head{background:var(--td-dark)}
/* Die Textflaechen bleiben ruhig — siehe Hover-Entscheid oben. ANEB wollte den
   Zustand ausdruecklich am Rahmen sehen, nicht im Text. */
.product-tile:hover .tile-price,.product-tile:hover .setup-fee,.product-tile:hover .tile-fact,
.product-tile:focus-visible .tile-price,.product-tile:focus-visible .setup-fee,
.product-tile:focus-visible .tile-fact{background:transparent}

/* Preis und einmalige Aufschaltung sind getrennte Ebenen */
.tile-price{padding:18px 22px 14px;border-bottom:1px solid var(--td-line)}
.price-main{font-size:29px;line-height:1.05;font-weight:900;color:var(--td-dark);letter-spacing:-.025em}
.price-period{font-size:13px;color:var(--td-muted);margin-top:5px}
.setup-fee{
  padding:10px 22px;border-bottom:1px solid var(--td-line);
  font-size:13px;color:var(--td-body);background:rgba(245,247,250,.65);
}
.setup-fee strong{font-weight:700;color:var(--td-text)}

/* max. 4 entscheidungsrelevante Merkmale */
.tile-facts{display:flex;flex-direction:column}
.tile-fact{
  display:flex;align-items:baseline;justify-content:space-between;gap:18px;
  padding:12px 22px;border-bottom:1px solid var(--td-line);font-size:14px;
}
.tile-fact:last-child{border-bottom:0}
/* ACHTUNG Namenskollision: Das Croster-Theme (assets/css/themes/style.min.css)
   fuehrt eine eigene Klasse .label - ein Bootstrap-Etikett mit font-size:75%,
   eigenem Innenabstand und Radius. Sie trifft jede Produktkachel und macht die
   Merkmalsbezeichnung ein Viertel kleiner als vorgesehen. Im Mockup faellt das
   nicht auf, weil dort kein Theme geladen ist. Die folgenden Angaben setzen die
   Etikett-Eigenschaften bewusst zurueck - nicht entfernen. */
.tile-fact .label{
  color:var(--td-muted);
  font-size:inherit;line-height:inherit;font-weight:400;
  padding:0;max-width:none;border-radius:0;
}
.tile-fact .value{font-weight:700;color:var(--td-dark);text-align:right}

/* --- Produktmatrix (4+ Produkte) --- */
/* Produkte als ZEILEN, Merkmale als Spalten. Max. 6 Spalten, keine Aktionsspalte. */
.product-matrix,.matrix-shell{
  background:#fff;border:1px solid var(--td-line-strong);
  border-radius:var(--td-radius-lg);overflow:hidden;
}
.matrix-head,.matrix-row{
  display:grid;grid-template-columns:1.42fr .82fr .92fr .80fr .92fr 1.38fr;
  align-items:center;column-gap:14px;
}
/* Header NICHT sticky */
.matrix-head{
  background:var(--td-dark);color:#fff;min-height:56px;padding:0 22px;
  font-size:13px;font-weight:700;
}
.matrix-row{
  position:relative;min-height:78px;padding:11px 22px;
  border-top:1px solid var(--td-line);background:#fff;
  text-decoration:none;color:inherit;outline:none;
  transition:background var(--td-transition),box-shadow var(--td-transition);
}
/* Dieselbe Theme-Kollision wie bei der Kachel: a:hover unterstreicht sonst
   jeden Wert in der Zeile. */
.matrix-row:hover,.matrix-row:hover *,
.matrix-row:focus-visible,.matrix-row:focus-visible *{text-decoration:none}
.matrix-row:first-of-type{border-top:0}
.matrix-row::after{
  content:"";position:absolute;inset:-1px;pointer-events:none;
  border:1.5px solid transparent;transition:border-color var(--td-transition);
}
.matrix-row:hover::after,.matrix-row:focus-visible::after{
  border-color:var(--td-accent);
  box-shadow:0 0 0 2px rgba(240,130,40,.16),inset 0 0 18px rgba(240,130,40,.03);
}
.matrix-row:hover,.matrix-row:focus-visible{background:rgba(240,130,40,.028)}

.matrix-row.recommended{background:rgba(27,95,143,.052);box-shadow:inset 3px 0 0 var(--td-primary)}
/* Nur die Zeile als Ganzes reagiert Richtung Orange. Der Badge NICHT:
   Primary = permanenter Status, Orange = aktuelle Interaktion — das gilt fuer
   die Pill in jedem Zustand, in der Kachel wie in der Matrix (ANEB 27.08.2026,
   praezisiert die frueheren "der Badge folgt der Zeile"-Formulierung). */
.matrix-row.recommended:hover,.matrix-row.recommended:focus-visible{
  background:rgba(240,130,40,.07);box-shadow:inset 3px 0 0 var(--td-accent);
}
/* Auf hellem Grund braucht die Pill einen Primary-Rand — der weisse Rand der
   Basisdefinition traegt nur auf dem dunklen Kachelheader. */
.matrix-row .badge{background:#fff;color:var(--td-primary);border-color:rgba(27,95,143,.3)}

.pkg-stack{display:flex;flex-direction:column;align-items:flex-start;gap:5px}
.pkg-name{font-weight:800;color:var(--td-dark)}
.pkg-sub{font-size:12px;color:var(--td-muted);margin-top:2px}
.metric{font-size:14px;color:var(--td-body)}
.metric strong{font-size:15px;color:var(--td-dark)}
.row-price{font-weight:800;color:var(--td-dark);font-size:16px;white-space:nowrap;text-align:right}
/* In der dunklen Kopfzeile traegt die dunkle Schrift nicht (an ThurWeb gemessen
   27.08.2026: die Spaltenueberschrift "Preis" war unsichtbar). */
.matrix-head .row-price{color:#fff;font-weight:700;font-size:13px}
.row-price small{display:block;font-weight:400;color:var(--td-muted);font-size:11px}

/* --- Gemeinsame Leistungen (Ebene 2) --- */
.included{
  margin-top:18px;background:#fff;border:1px solid var(--td-line);
  border-radius:var(--td-radius-lg);padding:18px 20px;
  display:flex;align-items:flex-start;gap:22px;
}
.included h3{font-size:16px;min-width:195px;padding-top:2px}
/* Einspaltig untereinander, Haken im Kaestchen (Entscheid MAEB 07.09.2026).
   Vorher flex-wrap: Die Punkte versackten je nach Textlaenge, die rechte
   Spalte lief unten aus. Untereinander stehen sie in einer klaren Linie —
   die Sektion wird hoeher, aber neben der Pakettabelle ist genug Platz.
   Das Haekchen steht direkt im Text, nicht als CSS-Escape: robuster, und die
   Datei ist ohnehin UTF-8. */
.included-list{display:grid;grid-template-columns:1fr;gap:9px;
               color:var(--td-body);font-size:14px}
.included-list span{display:flex;align-items:flex-start;gap:10px;line-height:1.45}
.included-list span::before{
  content:"✓";flex:0 0 auto;width:19px;height:19px;border-radius:4px;margin-top:1px;
  display:flex;align-items:center;justify-content:center;
  font-size:12px;font-weight:800;
  background:rgba(27,95,143,.10);color:var(--td-primary);
}

.decision-links{display:flex;gap:16px;align-items:center;margin-top:16px;flex-wrap:wrap}

/* --- Swipe-Hinweis: einmaliger Impuls, deshalb Orange zulaessig --- */
.mobile-arrow{display:none}
.mobile-only{display:none}
@keyframes td-nudge{0%,100%{transform:translateX(0);opacity:.88}50%{transform:translateX(5px);opacity:1}}

/* ============================================================================
   9. Responsive — Ebene B: die KOMPONENTENBREITE entscheidet (@container)
   Nicht das Geraet. cqw statt vw. Nie durch Viewport-Breakpoints ersetzen.
   ============================================================================ */

/* 2-3 Produkte: unter 900px Komponentenbreite -> Swipe.
   Angehoben von 820 auf 900 (Entscheid ANEB 27.08.2026 nach dem
   ThurBuilder-Realtest): bei 824-844px passen drei Kacheln zwar hinein, jede
   ist dann aber nur noch ~260px breit und die Claims brechen dreizeilig.
   Drei Kacheln nur, wenn jede Breite fuer ruhige Typografie hat.
   Die Matrixgrenze fuer 4+ Produkte bleibt bewusst bei 860px — eine
   Matrixzeile braucht pro Produkt weniger Platz als eine Kachel. */
@container products (max-width: 899px){
  .product-grid[data-swipe-container]{
    display:flex;overflow-x:auto;scroll-snap-type:x mandatory;
    overscroll-behavior-x:contain;gap:14px;padding:0 0 8px;
    scrollbar-width:none;-webkit-overflow-scrolling:touch;
  }
  .product-grid::-webkit-scrollbar{display:none}
  .product-grid .product-tile{flex:0 0 min(92cqw,600px);scroll-snap-align:start}
  .tile-claim{min-height:auto}

  .product-responsive:not(.matrix-responsive) .mobile-arrow{
    display:flex;position:absolute;right:2px;top:46%;
    width:34px;height:34px;border-radius:var(--td-radius-pill);
    background:var(--td-accent);color:#fff;
    align-items:center;justify-content:center;font-size:22px;font-weight:700;
    z-index:5;box-shadow:0 5px 16px rgba(240,130,40,.24);
    animation:td-nudge 1.35s ease-in-out 2 forwards;
    pointer-events:none;opacity:0;transition:opacity .28s ease;
  }
}

/* 4+ Produkte: Matrix nur, wenn die Komponente ~860px hat — sonst Swipe-Karten.
   Matrix nicht erzwingen: sie erscheint nur, wenn sie komfortabel lesbar ist. */
@container products (max-width: 859px){
  .matrix-responsive .desktop-matrix,
  .matrix-responsive .product-matrix{display:none}
  .matrix-responsive .mobile-only{display:block}
  .matrix-responsive .mobile-products[data-swipe-container]{
    display:flex;overflow-x:auto;scroll-snap-type:x mandatory;
    overscroll-behavior-x:contain;gap:14px;padding:0 0 8px;
    scrollbar-width:none;-webkit-overflow-scrolling:touch;
  }
  .matrix-responsive .mobile-products::-webkit-scrollbar{display:none}
  .matrix-responsive .mobile-products .product-tile{flex:0 0 min(92cqw,600px);scroll-snap-align:start}

  .matrix-responsive .mobile-arrow{
    display:flex;position:absolute;right:2px;top:46%;
    width:34px;height:34px;border-radius:var(--td-radius-pill);
    background:var(--td-accent);color:#fff;
    align-items:center;justify-content:center;font-size:22px;font-weight:700;
    z-index:5;box-shadow:0 5px 16px rgba(240,130,40,.24);
    animation:td-nudge 1.35s ease-in-out 2 forwards;
    pointer-events:none;opacity:0;transition:opacity .28s ease;
  }
}

.mobile-arrow.show{opacity:1}
.mobile-arrow.hide{opacity:0}
.mobile-arrow::after{content:"\203A";transform:translateY(-1px)}

/* Querformat / flache Viewports: Karten decken statt aufblasen */
@media (orientation:landscape) and (max-height:650px){
  .sec{padding:42px 0}
  .product-grid .product-tile,
  .matrix-responsive .mobile-products .product-tile{
    flex-basis:clamp(320px,48cqw,390px);
  }
  .tile-head{padding-top:16px;padding-bottom:14px}
  .tile-price{padding-top:14px;padding-bottom:11px}
  .tile-fact{padding-top:10px;padding-bottom:10px}
  .setup-fee{padding-top:8px;padding-bottom:8px}
}

/* ============================================================================
   10. Responsive — Ebene A: globale Foundation (@media, Viewport)
   Genau drei Breakpoints. Sie zwingen KEINE Komponente.
   ============================================================================ */

/* Intermediate / Tablet: 768-1023px */
@media (max-width:1023px){
  :root{
    --td-hero-pad: 72px;
    --td-page-gutter: var(--td-page-gutter-tablet);
    --td-sec-compact:  48px;
    --td-sec-default:  64px;
    --td-sec-spacious: 84px;
  }
  .td-grid-3{grid-template-columns:repeat(2,minmax(0,1fr))}
}

/* Mobile: <=767px */
@media (max-width:767px){
  :root{
    --td-hero-pad: 64px;
    --td-page-gutter: var(--td-page-gutter-mobile);
    --td-sec-compact:  40px;
    --td-sec-default:  56px;
    --td-sec-spacious: 72px;
  }

  h1{font-size:32px}
  h2{font-size:28px}
  h3{font-size:19px}
  .hero h1,h1.td-h1-hero{font-size:38px}
  .td-lead{font-size:16px}
  .td-kicker{font-size:11px}
  .lead{font-size:16px}                    /* LEGACY, siehe Alias-Block */
  .kicker,.eyebrow{font-size:11px}         /* LEGACY */

  .td-grid-2,.td-grid-3{grid-template-columns:1fr}
  .td-stage{min-height:0}
  /* Auf einer Spalte gibt es nichts mehr zu deckeln */
  .hero-copy{max-width:none}

  .included{display:block;padding:17px}
  .included h3{min-width:0;margin-bottom:12px}
  /* Einspaltig auch hier. Diese Regel stammt aus der Zeit, als die Liste
     ueberall flex-wrap war und auf Mobile zwei Spalten bekam. Seit der
     Umstellung auf einspaltig (07.09.2026) stand sie dagegen und drehte das
     Ergebnis um: Desktop einspaltig, Handy zweispaltig — bei 377px zwei
     137px-Spalten, in denen "Taegliche Sicherungen, bis 180 Tage zurueck"
     dreizeilig brach. Beim Aendern einer Basisregel immer die
     Media-Query-Bloecke mitpruefen. */
  .included-list{grid-template-columns:1fr;gap:9px;font-size:13px}
  .decision-links{gap:10px}

  /* Mobile-Hero-Routing: Full Width, ca. 48px, linksbuendig, KEIN Orange.
     Gilt NUR im Hero — keine globale Full-Width-Buttonregel. */
  .hero .btn-row,.hero-light .btn-row,.hero-dark .btn-row{
    display:grid;grid-template-columns:1fr;gap:10px;margin-top:32px;
  }
  .hero .btn-secondary,.hero-light .btn-secondary,.hero-dark .btn-secondary{
    width:100%;min-height:48px;justify-content:flex-start;padding-inline:16px;
  }
  .hero .btn-secondary,.hero-light .btn-secondary{
    background:rgba(27,95,143,.055);border-color:rgba(27,95,143,.55);color:var(--td-primary);
  }
  .hero .btn-secondary:hover,.hero .btn-secondary:focus-visible,
  .hero-light .btn-secondary:hover,.hero-light .btn-secondary:focus-visible{
    background:rgba(27,95,143,.09);border-color:var(--td-primary);color:var(--td-primary);
    box-shadow:0 0 0 3px rgba(27,95,143,.10);
  }
  .sec-dark .btn-secondary,.hero-dark .btn-secondary{
    background:rgba(255,255,255,.045);border-color:rgba(255,255,255,.42);color:#fff;
  }
  .sec-dark .btn-secondary:hover,.sec-dark .btn-secondary:focus-visible,
  .hero-dark .btn-secondary:hover,.hero-dark .btn-secondary:focus-visible{
    background:rgba(255,255,255,.075);border-color:rgba(255,255,255,.72);color:#fff;
    box-shadow:0 0 0 3px rgba(255,255,255,.08);
  }
  /* Der Textlink steht deutlich hinter den Routing-Flaechen */
  .hero .btn-text,.hero-light .btn-text,.hero-dark .btn-text{
    justify-content:flex-start;margin-top:2px;width:auto;
  }
}

/* Flaches Querformat, NACH den Breakpoint-Bloecken:
   844x420 trifft auch @media(max-width:1023px) — stuende diese Regel weiter
   oben, wuerde der Tablet-Wert sie ueberschreiben und der Hero bliebe hoch. */
@media (orientation:landscape) and (max-height:650px){
  :root{--td-hero-pad:40px}
}

/* ============================================================================
   11. Tabellen & Facts — zwei Muster, beide aus dem Bestand abgeleitet
   ----------------------------------------------------------------------------
   NICHT die Produktmatrix: die ist eine eigene Komponente mit eigenen Regeln
   (Zeilen = Produkte, ganze Zeile klickbar). Hier geht es um Datenblatt und
   Vergleichstabelle — statischer Inhalt, nichts ist auswaehlbar.

   Muster A  .td-facts   Key-Value-Liste, einspaltig, optional gruppiert.
                         Belegt an ThurVDC und ThurVServer.
   Muster B  .td-table   klassische Datentabelle mit Kopf oder Zeilenkopf.
                         Belegt an ThurWeb (Datenblatt + Paketdetails).

   Faustregel: ein Wert je Merkmal -> A. Mehrere Spalten zu vergleichen -> B.
   ============================================================================ */

/* --- A) Facts-Liste ------------------------------------------------------- */
.td-facts{max-width:860px}
.td-fact-group{
  font-size:12px;font-weight:700;letter-spacing:.14em;text-transform:uppercase;
  color:var(--td-subtle);margin:34px 0 4px;      /* Gruppentitel = Metadaten */
}
.td-fact-group:first-child{margin-top:0}
.td-fact{
  display:flex;justify-content:space-between;align-items:baseline;gap:24px;
  padding:12px 0;border-bottom:1px solid var(--td-line);font-size:15px;
}
.td-fact:last-child{border-bottom:0}
.td-fact-label{color:var(--td-muted);font-weight:400}
/* Der Wert ist die Information, nach der jemand sucht — nie zurueckgenommen. */
.td-fact-value{font-weight:700;color:var(--td-dark);text-align:right}
.td-fact-value a{color:var(--td-primary);font-weight:700}
.sec-dark .td-fact{border-bottom-color:rgba(255,255,255,.14)}
.sec-dark .td-fact-label{color:var(--td-dark-muted)}
.sec-dark .td-fact-value{color:#fff}

/* --- B) Datentabelle ------------------------------------------------------ */
/* Breite Tabellen scrollen in ihrem eigenen Container, nie die Seite. */
.td-table-scroll{overflow-x:auto}
/* Der Hinweis darueber wird von ci-2030-components.js eingesetzt — und NUR
   dann, wenn die Tabelle wirklich ueber ihren Kasten hinausragt. Er
   verschwindet, sobald sie einmal bewegt wurde. Die Klasse hier zu haben ist
   Absicht: Das Aussehen gehoert ins CSS, die Messung ins JS.
   Orange wie beim Karussell-Hinweis — es ist derselbe Impuls, und Orange ist
   fuer genau diesen Fall zugelassen. */
.td-scroll-hint{
  display:flex;align-items:center;gap:7px;
  margin:0 0 9px;font-size:13px;color:var(--td-muted);
}
.td-scroll-hint::after{content:"→";color:var(--td-accent);font-weight:700}
.td-table{
  width:100%;border-collapse:collapse;font-size:14.5px;background:#fff;
  border:1px solid var(--td-line-strong);
  /* kein Radius: border-collapse und abgerundete Ecken vertragen sich nicht,
     und eine Tabelle ist keine Karte. */
}
.td-table th,.td-table td{
  padding:11px 16px;border-bottom:1px solid var(--td-line);
  text-align:left;vertical-align:top;
}
.td-table tr:last-child th,.td-table tr:last-child td{border-bottom:0}
/* Zeilenkopf (Merkmal links) */
.td-table tbody th{font-weight:700;color:var(--td-primary);background:rgba(27,95,143,.04)}
/* Spaltenkopf (thead) — dunkel wie die Matrix-Kopfzeile, damit die Seite
   EINE Kopfzeilen-Sprache hat, ohne die Matrixregeln zu erben. */
.td-table thead th{background:var(--td-dark);color:#fff;font-weight:700}
.td-table td{color:var(--td-body)}
/* :not(.btn) ist Pflicht, nicht Kosmetik. `.td-table a` (0,1,1) schlaegt
   `.btn-primary` (0,1,0) — in der Pakettabelle stand deshalb BLAUE Schrift auf
   dem orangen Bestellknopf, waehrend derselbe Knopf in der Auswahlmatrix weiss
   war. Beim Klicken sprang er kurz auf Weiss, weil dort eine andere Regel griff.
   Dritte Kollision dieser Bauart nach der Theme-Unterstreichung und `.label`:
   eine breite Element-Regel faengt eine Komponente ein, die ihre Farbe selbst
   mitbringt. Buttons bleiben ab hier ueberall bei ihrer eigenen Farbe. */
.td-table a:not(.btn){color:var(--td-primary)}
/* Zwei Datenblatt-Tabellen nebeneinander brauchen mehr als die halbe
   Tablet-Breite (an ThurWeb gemessen) — deshalb erst ab Desktop zweispaltig. */
@media (max-width:1023px){
  .td-table-grid{grid-template-columns:1fr}
}

/* --- B2) Pakettabelle: die Datentabelle als Produktvergleich --------------
   BESCHLOSSEN 04.09.2026 (MAEB). Die ausfuehrliche Gegenueberstellung am
   Seitenende: **Merkmale als Zeilen, Pakete als Spalten** — die Umkehrung der
   Auswahlmatrix in S1. Beim Vergleichen liest man ein Merkmal ueber alle
   Pakete, also waagrecht entlang einer Zeile mit Beschriftung am Anfang. Als
   Spalte waere es senkrecht in rund 150px Breite, deren Ueberschrift beim
   Scrollen verschwindet.

   Kein Widerspruch zu «nie Produkte als Spalten»: Diese Regel gilt fuer S1,
   wo die Darstellung auf Mobile stapelbar bleiben muss. Das hier ist die
   separate Detailtabelle auf tieferer Ebene, fuer die der CI den sticky
   Header ausdruecklich erlaubt.

   Ergaenzt .td-table nur um das, was der Produktvergleich zusaetzlich braucht.
   Das Markup bleibt eine echte <table> — semantisch richtig, vorlesbar,
   kopierbar. Grenze: bis 6 Pakete, darueber werden die Spalten zu schmal.
   ---------------------------------------------------------------------- */
.td-pakettabelle{--td-pt-spalten:5}
.td-pakettabelle th,.td-pakettabelle td{text-align:center;vertical-align:middle}
.td-pakettabelle tbody th{text-align:left}
/* Die Produktzeile bleibt beim Scrollen stehen — sonst weiss man nach dem
   fuenften Merkmal nicht mehr, welche Spalte welches Paket ist. */
.td-pakettabelle thead th{position:sticky;top:0;z-index:5}
/* Zebra: bei vielen Merkmalen untereinander verrutscht das Auge sonst. */
.td-pakettabelle tbody tr:nth-child(even) th,
.td-pakettabelle tbody tr:nth-child(even) td{background:#FAFBFC}
.td-pakettabelle tbody tr:nth-child(even) th{background:rgba(27,95,143,.055)}

/* Preiszeile und Bestellzeile rahmen die Merkmale ein: oben der Preis, unten
   die Handlung — dieselbe Reihenfolge wie in der Auswahl. */
.td-pakettabelle .td-pt-preis td{padding-top:14px;padding-bottom:14px;background:#F5F7FA}
.td-pakettabelle .td-pt-preis .td-pt-betrag{font-size:18px;font-weight:900;color:var(--td-dark);
                                            white-space:nowrap;display:block}
.td-pakettabelle .td-pt-preis .td-pt-takt{font-size:11px;color:var(--td-muted);display:block}
.td-pakettabelle .td-pt-cta td{padding:14px 10px}
.td-pakettabelle .td-pt-cta .btn{width:100%;justify-content:center;padding:8px 10px;font-size:13px}

/* Die Empfehlung steht NUR im Spaltenkopf — dieselbe Linie wie Variante A in der
   Auswahlmatrix (MAEB 07.09.2026): die Kennzeichnung traegt der Badge, nicht eine
   Dauereinfaerbung. Zuvor lag ueber der ganzen Spalte ein blauer Ton; zusammen mit
   dem orangen Bestellknopf las sich das wie eine bereits getroffene Vorauswahl,
   und die Zeilen der Spalte hoben sich staerker ab als die Werte, die man
   vergleichen will. Damit faellt der Entscheid vom 04.09. («Spalte durchgehend
   markiert») — er stammte aus der Zeit, als es die Zeilen-Variante noch gab. */
.td-pakettabelle thead .td-pt-empfohlen{background:var(--td-primary)}
.td-pakettabelle thead .td-pt-empfohlen .badge{background:#fff;color:var(--td-primary);
                                               display:inline-block;margin-top:4px}

/* Zeilen-Hover (Variante 1, MAEB 07.09.2026). Die ganze Zeile hebt sich — das
   deckt sich mit der Leserichtung dieser Tabelle: ein Merkmal ueber alle Pakete,
   also waagrecht. Die Spalte waere der Gegenweg und braeuchte ausserdem JS, weil
   CSS keinen Spalten-Selektor kennt; einzelne Zellen helfen beim Vergleichen gar
   nicht. Nur mit echtem Zeiger — auf Touch bliebe der Zustand nach dem Antippen
   kleben, dieselbe Falle wie bei den Kacheln.

   Spezifitaet gegen das Zebra GERECHNET, nicht geschaetzt:
     Zebra   tbody tr:nth-child(even) th = (0,2,3)
     hier    tbody tr:hover th           = (0,2,3)  -> spaeter im Quelltext, gewinnt
   Die Zeile faerbt sich gleichmaessig durch. Seit die Empfehlungsspalte keine
   Dauereinfaerbung mehr hat, gibt es in der Zeile nichts auszunehmen. */
@media (hover:hover) and (pointer:fine){
  .td-pakettabelle tbody tr:hover th,
  .td-pakettabelle tbody tr:hover td{background:rgba(27,95,143,.085)}
}

/* Auf Mobile entfaellt die Tabelle: dort tragen die Swipe-Karten bereits ALLE
   Merkmale im Akkordeon (Entscheid 04.09.2026 «Mobile nie Tabellen»).

   ACHTUNG BEIM BREAKPOINT — hier lag ein Fehler (gefunden 07.09.2026):
   Zuerst stand hier 1023px. Die Auswahl schaltet aber ueber eine
   CONTAINER-Query bei 860px Komponentenbreite um, was rund 920px Viewport
   entspricht. Zwischen 920 und 1023px war damit die MATRIX aktiv — und dort
   ist das Akkordeon ausgeblendet, weil die Details ja in der Tabelle stehen.
   Ergebnis: In diesem Fenster waren die uebrigen Merkmale NIRGENDS erreichbar,
   und der Lead darueber versprach trotzdem "hier stehen sie vollstaendig".

   767px ist der Foundation-Breakpoint fuer Mobile. Dort sind die Karten
   sicher aktiv (Container ~727px < 860px), tragen also alles im Akkordeon.
   Zwischen 767 und 920px stehen Karten UND Tabelle nebeneinander — doppelt,
   aber vollstaendig. Fehlend waere schlimmer als doppelt.

   Der Scroll-Wrapper wird mit ausgeblendet, sonst bleibt ein leerer Kasten
   stehen. Gilt nur fuer die Pakettabelle — andere Datentabellen scrollen
   weiterhin in .td-table-scroll. */
@media(max-width:767px){
  .td-table-scroll:has(.td-pakettabelle){display:none}
  .td-pakettabelle{display:none}
}

/* ----------------------------------------------------------------------------
   11b. Swipe am Rechner - Bildlaufleiste und Greifhand
   Mit dem Finger scrollt das Betriebssystem, die ausgeblendete Leiste stoert
   dort nicht. Mit der Maus fehlt beides: kein Ziehen, keine Leiste - der
   Zustand ist dann unbedienbar, zumal die Karte ein Link ist. Deshalb bekommt
   ein praeziser Zeiger die Leiste zurueck; das Ziehen liefert das Komponenten-JS.
   ---------------------------------------------------------------------------- */
@media (pointer: fine) {
  .product-grid[data-swipe-container],
  .matrix-responsive .mobile-products[data-swipe-container] {
    scrollbar-width: thin;
    scrollbar-color: rgba(15,26,36,.28) transparent;
    cursor: grab;
  }
  .product-grid[data-swipe-container]::-webkit-scrollbar,
  .matrix-responsive .mobile-products[data-swipe-container]::-webkit-scrollbar {
    display: block; height: 8px;
  }
  .product-grid[data-swipe-container]::-webkit-scrollbar-thumb,
  .matrix-responsive .mobile-products[data-swipe-container]::-webkit-scrollbar-thumb {
    background: rgba(15,26,36,.28); border-radius: var(--td-radius-pill);
  }
  .product-grid[data-swipe-container]::-webkit-scrollbar-track,
  .matrix-responsive .mobile-products[data-swipe-container]::-webkit-scrollbar-track {
    background: transparent;
  }
}

/* Waehrend des Ziehens: Greifhand halten, keine Textmarkierung, kein Link-Hover. */
[data-swipe-container].td-zieht { cursor: grabbing; user-select: none; }
[data-swipe-container].td-zieht * { pointer-events: none; }

/* ============================================================================
   12. Lightbox — Aufnahmen gross ansehen
   Standard seit 28.08.2026: jede Aufnahme oeffnet per Klick, mehrere Aufnahmen
   derselben Gruppe lassen sich durchblaettern. Den Dialog baut das
   Komponenten-JS; die Seite markiert nur das Bild mit .td-zoom.
   Vorlaeufer waren die seitenlokalen .lb-* auf der VDC-Entwicklerseite und
   .td-lb auf ThurWeb — zwei Belege, deshalb hier.
   ============================================================================ */
.td-sr{position:absolute;width:1px;height:1px;padding:0;margin:-1px;overflow:hidden;clip:rect(0 0 0 0);white-space:nowrap;border:0}

.td-zoom{cursor:zoom-in}
.td-zoom:focus-visible{outline:2px solid var(--td-accent);outline-offset:4px;border-radius:var(--td-radius-lg)}
button.td-zoom{display:block;width:100%;padding:0;border:0;background:none;text-align:left;font:inherit;color:inherit}
.td-zoom-hint{display:block;margin-top:10px;font-size:13.5px;color:var(--td-muted)}

.td-lb{border:0;padding:0;background:transparent;width:100vw;height:100vh;max-width:100vw;max-height:100vh;overflow:hidden}
.td-lb::backdrop{background:rgba(15,26,36,.88)}
.td-lb .td-lb-fig{
  margin:0;height:100%;display:flex;flex-direction:column;
  align-items:center;justify-content:center;gap:14px;padding:24px;
  overflow:auto;overscroll-behavior:contain;-webkit-overflow-scrolling:touch;
}
.td-lb .td-lb-img{
  display:block;max-width:94vw;max-height:78vh;width:auto;height:auto;
  border-radius:var(--td-radius);box-shadow:0 24px 60px rgba(0,0,0,.5);background:#fff;
}
/* Videos teilen sich die Buehne mit den Bildern. Das hidden-Attribut braucht
   eine eigene Regel, weil display:block es sonst uebersteuert. */
.td-lb .td-lb-video{
  display:block;max-width:94vw;max-height:78vh;width:auto;height:auto;
  border-radius:var(--td-radius);box-shadow:0 24px 60px rgba(0,0,0,.5);background:#000;
}
.td-lb .td-lb-img[hidden],.td-lb .td-lb-video[hidden]{display:none}
.td-lb .td-lb-cap{max-width:760px;text-align:center;font-size:15px;line-height:1.6;color:rgba(255,255,255,.82)}
.td-lb .td-lb-cap b,.td-lb .td-lb-cap strong{color:#fff;font-weight:600}
.td-lb .td-lb-hint,.td-lb .td-lb-count{font-size:13px;color:rgba(255,255,255,.6);letter-spacing:.06em}
.td-lb .td-lb-btn{
  position:fixed;z-index:2;width:44px;height:44px;border-radius:var(--td-radius-pill);
  border:1px solid rgba(255,255,255,.4);background:rgba(15,26,36,.6);color:#fff;
  font-size:24px;line-height:1;cursor:pointer;display:flex;align-items:center;justify-content:center;
  transition:background var(--td-transition),border-color var(--td-transition);
}
.td-lb .td-lb-btn:hover{background:rgba(15,26,36,.9);border-color:#fff}
.td-lb .td-lb-btn:focus-visible{outline:2px solid #fff;outline-offset:2px}
.td-lb .td-lb-close{top:20px;right:20px}
.td-lb .td-lb-prev{left:20px;top:50%;transform:translateY(-50%)}
.td-lb .td-lb-next{right:20px;top:50%;transform:translateY(-50%)}
/* Eine einzelne Aufnahme braucht weder Pfeile noch Zaehler. */
.td-lb.td-lb-einzeln .td-lb-prev,
.td-lb.td-lb-einzeln .td-lb-next,
.td-lb.td-lb-einzeln .td-lb-count{display:none}

/* Originalgroesse: die Figur wird zum Scrollrahmen. Ohne das ist die
   Grossansicht auf dem Handy wirkungslos — 367px statt 335px im Fliesstext. */
.td-lb.kann-zoomen .td-lb-img{cursor:zoom-in}
.td-lb.ist-gezoomt .td-lb-fig{align-items:flex-start;justify-content:flex-start}
.td-lb.ist-gezoomt .td-lb-img{max-width:none;max-height:none;cursor:zoom-out}
.td-lb.ist-gezoomt .td-lb-cap,
.td-lb.ist-gezoomt .td-lb-hint,
.td-lb.ist-gezoomt .td-lb-count{display:none}
.td-lb:not(.kann-zoomen) .td-lb-hint{display:none}

@media (max-width:1023px){
  .td-lb .td-lb-img{max-height:70vh}
  .td-lb .td-lb-close{top:10px;right:10px}
  .td-lb .td-lb-prev{left:8px}
  .td-lb .td-lb-next{right:8px}
}
/* Flache Viewports: die Bildunterschrift weicht dem Bild. */
@media (orientation:landscape) and (max-height:650px){
  .td-lb .td-lb-img{max-height:84vh}
  .td-lb .td-lb-cap{display:none}
}

/* ============================================================================
   12b. PRODUKTLISTE — ein Markup, zwei Darstellungen
   ----------------------------------------------------------------------------
   Beschlossen ANEB + MAEB 04.09.2026, am Geraet geprueft.

   Ersetzt mittelfristig .product-tile / .product-matrix aus Abschnitt 8. Beide
   Systeme stehen bewusst nebeneinander, bis die Seiten migriert sind:
   ThurBuilder, ThurCloud und ThurWeb laufen heute auf dem alten Markup.
   NICHT beide auf derselben Seite mischen.

   Das Modell:

     | Produkte | breit                  | schmal                    |
     |----------|------------------------|---------------------------|
     | bis 3    | Kacheln nebeneinander  | Kacheln gestapelt         |
     | ab 4     | Zeilenmatrix           | Swipe-Bahn                |

   Es gibt genau EIN Markup. Die Umschaltung passiert ausschliesslich per
   Container-Query — kein zweites Markup, keine doppelt gepflegten Zahlen.
   Der Wrapper .pl-wrap traegt container-type und die Modusklasse, gestylt
   wird .pl: eine Container-Query kann den Container SELBST nicht stylen,
   nur seine Nachfahren.

   Aufbau eines Eintrags (DOM-Reihenfolge folgt der Matrix):
     .pl-item > .pl-kopf · .pl-fakten (4 Merkmale) · .pl-preis ·
                .pl-mehr (details, alle uebrigen Merkmale) · .pl-cta
   In der Kachelform zieht `order` den Preis nach oben — ein Markup,
   zwei Leserichtungen.

   Verhalten aus ci-2030-components.js: gemeinsames Aufklappen, Position
   in der Swipe-Bahn, Tap-vs-Swipe.
   ============================================================================ */

/* --pl-spalten ist das Spaltenraster der Zeilenmatrix. Der Standardwert ist das
   an ThurWeb gemessene Raster: Paketname, vier Merkmale, Preis, feste
   Aktionsspalte. Eine Seite mit weniger Merkmalen ueberschreibt die Variable auf
   ihrem eigenen Wrapper — ThurCloud hat nur ein unterscheidendes Merkmal
   (Speicher) und braucht deshalb vier Spalten statt sieben. Ohne die Variable
   muesste jede solche Seite den kompletten Matrix-Regelsatz kopieren. */
.pl-wrap{container-type:inline-size;container-name:pl;
         --pl-spalten:1.5fr .78fr .95fr .68fr .78fr .92fr 132px}
.pl{display:grid;gap:18px;grid-template-columns:repeat(auto-fit,minmax(280px,1fr));
    align-items:start}
.pl-matrixkopf{display:none}

.pl-item{
  display:flex;flex-direction:column;min-width:0;position:relative;
  background:#fff;border:1px solid var(--td-line-strong);border-radius:var(--td-radius-lg);
  overflow:hidden;transition:border-color var(--td-transition),box-shadow var(--td-transition);
}
/* Hover = Umrandung, nur mit echtem Zeiger. Auf Touch bliebe er sonst kleben. */
@media (hover:hover) and (pointer:fine){
  .pl-item:hover{border-color:var(--td-accent);box-shadow:inset 0 0 0 1px var(--td-accent)}
  .pl-item.empfohlen:hover{border-color:var(--td-accent)}
}
.pl-item:focus-within{border-color:var(--td-accent);box-shadow:inset 0 0 0 1px var(--td-accent)}
.pl-item.empfohlen{border-color:rgba(27,95,143,.52)}
.pl-item.empfohlen::before{content:"";position:absolute;top:0;left:0;right:0;height:3px;
  background:var(--td-primary);z-index:2}

/* Leseführung in der Kachel: Kopf, Preis, Merkmale, Akkordeon, Knopf */
.pl-kopf{order:1}
.pl-preis{order:2}
.pl-fakten{order:3}
.pl-mehr{order:4}
.pl-cta{order:5}

.pl-kopf{padding:21px 22px 17px;background:var(--td-dark);color:#fff}
/* Badge NEBEN dem Namen, nie darunter: sonst waechst der Kopf einer Kachel und
   alle folgenden Zeilen fluchten nicht mehr mit den Nachbarkacheln. Deshalb ist
   der Text kurz ("Topseller") und der Umbruch unterbunden. */
.pl-name{font-size:19px;font-weight:700;display:flex;align-items:center;
         justify-content:space-between;gap:10px;flex-wrap:nowrap;min-width:0}
.pl-name .badge{background:#fff;color:var(--td-primary);font-size:11px;flex:0 0 auto;
                white-space:nowrap}
/* Claim-Hoehe reservieren, damit unterschiedlich lange Claims die Zeilen nicht
   verschieben. equalizeTileHeads in ci-2030-components.js macht das genauer. */
.pl-claim{font-size:14px;color:rgba(255,255,255,.72);margin-top:6px;min-height:2.9em}

.pl-preis{padding:17px 22px 14px;border-bottom:1px solid var(--td-line);
          display:flex;flex-direction:column}
.pl-betrag{font-size:28px;font-weight:900;color:var(--td-dark);letter-spacing:-.025em;
           line-height:1.05}
.pl-takt{font-size:13px;color:var(--td-muted);margin-top:4px}
.pl-setup{font-size:12.5px;color:var(--td-body);margin-top:7px}

.pl-fakten{display:flex;flex-direction:column;border-top:1px solid var(--td-line)}
.pl-fakt{display:flex;align-items:baseline;justify-content:space-between;gap:18px;
         padding:11px 22px;border-bottom:1px solid var(--td-line);font-size:14px}
.pl-label{color:var(--td-muted)}
.pl-wert{font-weight:700;color:var(--td-dark);text-align:right}

/* --- Akkordeon: traegt ALLE uebrigen Merkmale ---------------------------
   Bewusst nativ per <details>: funktioniert ohne JavaScript. Das gemeinsame
   Aufklappen kommt aus components.js und ist eine Zutat, keine Bedingung. */
.pl-mehr{border-bottom:1px solid var(--td-line)}
.pl-mehr > summary{list-style:none;cursor:pointer;padding:13px 22px;min-height:44px;
  font-size:14px;font-weight:700;color:var(--td-primary);
  display:flex;align-items:center;justify-content:space-between;gap:12px}
.pl-mehr > summary::-webkit-details-marker{display:none}
/* Plus und Minus erben Farbe, Groesse und Schnitt vom Text daneben.
   U+2212 ist das echte Minuszeichen, nicht der kuerzere Gedankenstrich. */
.pl-mehr > summary::after{content:"+";font-size:inherit;font-weight:inherit;color:inherit;
                          line-height:1;width:1em;text-align:center}
.pl-mehr[open] > summary::after{content:"\2212"}
@media (hover:hover) and (pointer:fine){
  .pl-mehr > summary:hover{color:var(--td-accent)}
}
.pl-mehr > summary:focus-visible{box-shadow:var(--td-focus-ring);border-radius:var(--td-radius-sm)}
.pl-mehr-inhalt .pl-fakt:last-child{border-bottom:0}

/* --- Bestellknopf in jeder Kachel ---------------------------------------
   Abweichung vom fruehen CI-Entscheid "ganze Kachel klickbar, kein Button
   darin" (MAEB 04.09.2026): Beim Wischen auf dem Handy loeste die klickbare
   Flaeche ungewollt den Bestellprozess aus. Nur der Knopf reagiert. */
.pl-cta{padding:16px 22px 20px;margin-top:auto}
.pl-cta .btn{width:100%;justify-content:center}
.pl-cta .hint{display:block;margin-top:9px;font-size:12.5px;color:var(--td-subtle);
              text-align:center}

/* ---------------------------------------------- ab 860px: ZEILENMATRIX --
   Gilt nur fuer .modus-auto (4+ Produkte). Bis 3 Produkte bleibt es in jeder
   Breite bei Kacheln. */
@container pl (min-width:860px){
  .modus-auto .pl{display:block;background:#fff;border:1px solid var(--td-line-strong);
                  border-radius:var(--td-radius-lg);overflow:hidden}

  /* Die Aktionsspalte hat eine FESTE Breite. Mit `auto` richtet sie sich nach
     ihrem Inhalt — und weil jede Zeile ein eigenes Grid ist, bekommt dann jede
     Zeile andere Spaltenbreiten. An ThurWeb gemessen (07.09.2026): Kopf und
     Zeilen liefen um bis zu 56px auseinander, die Knoepfe waren 180-213px
     breit. Deshalb feste Breite und ein kurzer, fuer alle gleicher Knopftext;
     das Produkt steht im aria-label. */
  .modus-auto .pl-matrixkopf,
  .modus-auto .pl-item{
    display:grid;
    grid-template-columns:var(--pl-spalten);
    align-items:center;column-gap:14px;
  }
  .modus-auto .pl-matrixkopf{background:var(--td-dark);color:#fff;min-height:54px;
                             padding:0 22px;font-size:13px;font-weight:700}
  .modus-auto .pl-item{border:0;border-top:1px solid var(--td-line);border-radius:0;
                       padding:12px 22px;min-height:78px;box-shadow:none}
  .modus-auto .pl-item:first-of-type{border-top:0}
  /* In der Matrix gilt wieder die DOM-Reihenfolge */
  .modus-auto .pl-kopf,.modus-auto .pl-preis,.modus-auto .pl-fakten,
  .modus-auto .pl-fakt,.modus-auto .pl-mehr,.modus-auto .pl-cta{order:0}
  @media (hover:hover) and (pointer:fine){
    .modus-auto .pl-item:hover{box-shadow:inset 0 0 0 1.5px var(--td-accent);
                               border-color:var(--td-line)}
  }
  /* Variante A (MAEB 07.09.2026): Hintergrund weg, Balken bleibt. Die
     empfohlene Zeile soll sich wie die uebrigen vier lesen — die Empfehlung
     traegt der Badge, der Balken haelt sie beim Ueberfliegen auffindbar.
     Variante B (auch der Balken weg) war zu leise, C (Balken nur bei Hover)
     verschenkt die Marke genau beim Ueberfliegen, wo sie wirken soll.

     Die Hover-Regel darueber hat dieselbe Spezifitaet (0,3,0) und steht frueher
     im Quelltext — .empfohlen schlaegt sie also und loescht den Rahmen. Solange
     der Hintergrund da war, fiel das nicht auf; ohne ihn waere die empfohlene
     Zeile die einzige, die auf den Zeiger gar nicht reagiert. Deshalb hier
     beide Schatten zusammen: Balken UND Rahmen. */
  .modus-auto .pl-item.empfohlen{box-shadow:inset 3px 0 0 var(--td-primary)}
  @media (hover:hover) and (pointer:fine){
    .modus-auto .pl-item.empfohlen:hover{
      box-shadow:inset 3px 0 0 var(--td-primary),inset 0 0 0 1.5px var(--td-accent);
      border-color:var(--td-line)}
  }
  .modus-auto .pl-item.empfohlen::before{display:none}

  .modus-auto .pl-kopf{background:transparent;color:inherit;padding:0}
  .modus-auto .pl-name{font-size:15.5px;font-weight:800;color:var(--td-dark);
                       display:flex;justify-content:flex-start;gap:8px}
  .modus-auto .pl-name .badge{border:1px solid rgba(27,95,143,.3)}
  .modus-auto .pl-claim{color:var(--td-muted);font-size:12px;margin-top:2px;min-height:0}

  /* Die vier Merkmale werden zu Spalten — Beschriftung traegt der Kopf.
     Werte UND Ueberschriften zentriert, sonst fluchten sie bei
     unterschiedlich langen Werten nicht. */
  .modus-auto .pl-fakten{display:contents}
  .modus-auto .pl-fakt{display:block;padding:0;border:0;font-size:15px;text-align:center}
  .modus-auto .pl-label{display:none}
  .modus-auto .pl-wert{text-align:center;font-weight:700;display:block}
  /* Alle Spalten ausser Paketname und Aktionsspalte zentriert — auch der Preis.
     Vorher stand die Ueberschrift "Preis" zentriert und der Betrag darunter
     rechtsbuendig: Die zentrierende Regel hat wegen der beiden :not() mehr
     Gewicht und schlug die rechtsbuendige (MAEB 07.09.2026 auf Devel gesehen).
     Statt die Spezifitaeten gegeneinander hochzuziehen, ist der Preis jetzt
     wie jede andere Spalte zentriert — Ueberschrift und Wert fluchten. */
  .modus-auto .pl-matrixkopf > div:not(:first-child):not(:last-child){text-align:center}

  .modus-auto .pl-preis{padding:0;border:0;text-align:center;align-items:center}
  .modus-auto .pl-betrag{font-size:17px;font-weight:800;white-space:nowrap}
  .modus-auto .pl-takt{font-size:11px}
  .modus-auto .pl-setup{display:none}

  /* In der Matrix kein Akkordeon — die Details stehen in der Quermatrix */
  .modus-auto .pl-mehr{display:none}

  .modus-auto .pl-cta{padding:0;margin:0}
  .modus-auto .pl-cta .btn{width:100%;justify-content:center;padding:9px 12px;
                           font-size:13.5px;white-space:nowrap}
}

/* -------------------------------------------- unter 860px: SWIPE-BAHN --
   Nur bei 4+ Produkten (.modus-auto). Bis 3 Pakete bleibt es gestapelt:
   dort ist die Seite kurz genug, und man scrollt ohnehin an allen vorbei.
   Am Geraet geprueft 04.09.2026 — Wischen, Akkordeon und Zurueckwischen
   funktionieren zusammen. */
@container pl (max-width:859px){
  /* grid-template-columns MUSS zurueckgesetzt werden: sonst landet die erste
     Karte in der 1fr-Spalte der Kachelform und wird schmaler als alle
     anderen (gemessen 04.09.2026: Kopf 227px statt 113px). */
  .modus-auto .pl{
    grid-template-columns:none;grid-auto-flow:column;grid-auto-columns:82%;gap:14px;
    overflow-x:auto;scroll-snap-type:x mandatory;padding:2px 2px 12px;
    overscroll-behavior-x:contain;scrollbar-color:var(--td-line-strong) transparent;
  }
  .modus-auto .pl > .pl-item{scroll-snap-align:center}
  .modus-auto .pl::-webkit-scrollbar{height:8px}
  .modus-auto .pl::-webkit-scrollbar-thumb{background:var(--td-line-strong);border-radius:999px}
  .modus-auto .pl::-webkit-scrollbar-track{background:transparent}

  /* Feste Zeilenhoehen: NUR so stehen die Merkmale auf allen Karten gleich
     hoch. Sonst verrutscht die Zeile beim Wischen und der Vergleich ist
     dahin — der ganze Zweck der Bahn. Gemessen: 0px Abweichung ueber alle
     Karten und Zeilen. */
  .modus-auto .pl-fakt{min-height:46px}
  .modus-auto .pl-wert{white-space:nowrap;overflow:hidden;text-overflow:ellipsis}
  .modus-auto .pl-mehr > summary{min-height:46px}
  .modus-auto .pl-preis{min-height:96px}
  .modus-auto .pl-kopf{min-height:104px}
  .modus-auto .pl-cta{min-height:76px}
}

/* --- Kennzeichnung der Bahn: ohne sie sieht niemand, dass es weitergeht --- */
.pl-swipekopf{display:none;align-items:baseline;gap:10px;margin-bottom:9px;padding:0 2px}
.pl-swipezahl{font-weight:800;font-size:14.5px;color:var(--td-dark)}
.pl-swipehinweis{font-size:13px;color:var(--td-muted)}
.pl-swipepos{font-size:13px;color:var(--td-muted);margin-left:auto;
             font-variant-numeric:tabular-nums}
.pl-punkte{display:none;gap:6px;justify-content:center;margin-top:2px}
.pl-punkte i{width:20px;height:4px;border-radius:999px;background:var(--td-line-strong);
             transition:background var(--td-transition)}
.pl-punkte i.aktiv{background:var(--td-accent)}
@container pl (max-width:859px){
  .modus-auto .pl-swipekopf{display:flex}
  .modus-auto .pl-punkte{display:flex}
}

/* ============================================================================
   13. OFFEN — noch kein CI-Muster, bewusst nicht gestaltet
   ----------------------------------------------------------------------------
   Formularfelder (Input/Select/Textarea, Label, Error-/Helptext) sind im CI
   als offene Komponente markiert. Hier steht nur der gesetzte Rahmen; das
   Design entscheidet ANEB, bevor hier ausgebaut wird.
   (Tabellen sind seit 27.08.2026 in Abschnitt 11 geregelt.)
   ============================================================================ */

input,select,textarea{
  font-family:inherit;font-size:15px;color:var(--td-text);
  border:1px solid var(--td-line-strong);border-radius:var(--td-radius-sm);
  padding:10px 12px;background:#fff;
}
input:focus-visible,select:focus-visible,textarea:focus-visible{
  outline:none;border-color:var(--td-primary);box-shadow:0 0 0 3px rgba(27,95,143,.12);
}
label{font-size:14px;font-weight:700;color:var(--td-body)}

/* Reduzierte Bewegung respektieren */
@media (prefers-reduced-motion:reduce){
  *,*::before,*::after{animation-duration:.01ms !important;transition-duration:.01ms !important}
}
