/* ============================================================================
   KUMMERKASTEN PREMIUM MOTION — zentrale Animations-Bibliothek (Marketing)
   ============================================================================
   Wird von allen public/*.html eingebunden. Vanilla CSS, keine externen Quellen
   (CSP). Alle Effekte GPU-beschleunigt (transform/opacity) und respektieren
   prefers-reduced-motion. Progressive Enhancement: ohne JS bleibt alles lesbar —
   die Aktivierungsklassen (pv-ready, visible) setzt erst premium.js.
   ============================================================================ */

/* ── Scroll-Progress-Bar (wird von premium.js eingefügt) ─────────────────── */
.pv-progress {
  position: fixed;
  top: 0;
  left: 0;
  height: 2px;
  width: 100%;
  z-index: 200;
  background: linear-gradient(90deg, var(--accent, #0071e3), #6366f1);
  transform-origin: 0 50%;
  transform: scaleX(0);
  pointer-events: none;
}

/* ── Nav-Elevation: Schatten + stärkeres Glas erst beim Scrollen ─────────── */
.nav-wrap {
  transition: box-shadow .35s ease, background .35s ease;
}
.nav-wrap.pv-scrolled {
  box-shadow: 0 1px 0 rgba(0, 0, 0, .06), 0 8px 24px rgba(0, 0, 0, .06);
  background: rgba(250, 250, 250, .92);
}

/* ── Hero: Wort-für-Wort-Reveal (Rise + Stagger via --pv-i) ──────────────── */
/* Erst wenn JS die Wörter zerlegt hat (.pv-ready), wird animiert — sonst
   bleibt die H1 unangetastet sichtbar (kein FOUC, kein unsichtbarer Text).
   WICHTIG: Elemente mit background-clip:text (Gradient-Überschriften/-Spans)
   werden von premium.js grundsätzlich NICHT zerlegt und NICHT animiert —
   inline-block-Wrapper, filter oder animation-Overrides würden den Text-Clip
   brechen (unsichtbarer Text) bzw. seiteneigene Shimmer-Animationen killen.
   Gradient-Texte stehen sofort; nur normale Wörter staggern. */
.pv-words.pv-ready .pv-word {
  display: inline-block;
  opacity: 0;
  transform: translateY(0.35em);
  animation: pvWordIn .7s cubic-bezier(.16, 1, .3, 1) forwards;
  animation-delay: calc(var(--pv-i) * 70ms);
}
/* Blur nur solange die Animation läuft — NIE mehr, sobald der Endzustand
   (.pv-done) erreicht ist. Ohne das :not(.pv-done) würde diese Regel nach
   dem Abschalten der Animation wieder greifen und den Text dauerhaft
   unscharf stellen (Spezifität schlägt die pv-done-Regel). */
.pv-words.pv-ready:not(.pv-done) .pv-word {
  filter: blur(8px);
}
@keyframes pvWordIn {
  to { opacity: 1; filter: blur(0); transform: translateY(0); }
}
/* Failsafe: Nach Animationsende (oder wenn Animationen unterdrückt werden,
   z. B. Energiesparmodus) erzwingt JS den sichtbaren Endzustand. Es darf
   strukturell unmöglich sein, dass Überschriften-Text unsichtbar bleibt. */
.pv-words.pv-done .pv-word {
  animation: none;
  opacity: 1;
  filter: none;
  transform: none;
}

/* ── Section-Reveals: bestehende .reveal-Klasse wird verfeinert ──────────── */
/* Sanftes Scale zusätzlich zum Rise; nutzt die vorhandene .visible-Mechanik. */
.reveal {
  opacity: 0;
  transform: translateY(24px) scale(.985);
  transition:
    opacity .7s cubic-bezier(.16, 1, .3, 1),
    transform .7s cubic-bezier(.16, 1, .3, 1);
  will-change: opacity, transform;
}
.reveal.visible {
  opacity: 1;
  transform: translateY(0) scale(1);
}
/* Was schon im ersten Bildschirm steht, wird NICHT eingeblendet.
   Gemessen am Handy (Slow 4G): Überschrift und Unterzeile blieben bis zu
   0,8 s nach dem ersten Aufbau unsichtbar, weil das Einblenden erst nach
   dem vollständigen HTML-Download startete — genau dieser Moment ist der
   Wert, den Google als LCP misst. Unterhalb des ersten Bildschirms läuft
   die Animation unveraendert weiter. */
.hero .reveal,
.hero.reveal,
main > section:first-of-type .reveal,
main > section:first-of-type.reveal {
  opacity: 1;
  transform: none;
  transition: none;
}

/* ── Karten: Gradient-Border-Glow beim Hover (21st.dev-Pattern) ──────────── */
.pv-glow {
  position: relative;
  overflow: hidden;
}
.pv-glow::before {
  content: "";
  position: absolute;
  inset: 0;
  border-radius: inherit;
  padding: 1px;
  background: linear-gradient(135deg,
    rgba(0, 113, 227, .55), rgba(99, 102, 241, .45), rgba(168, 85, 247, .35));
  -webkit-mask: linear-gradient(#fff 0 0) content-box, linear-gradient(#fff 0 0);
  mask: linear-gradient(#fff 0 0) content-box, linear-gradient(#fff 0 0);
  -webkit-mask-composite: xor;
  mask-composite: exclude;
  opacity: 0;
  transition: opacity .35s ease;
  pointer-events: none;
}
.pv-glow:hover::before { opacity: 1; }
/* Sanfter Licht-Spot, folgt der Maus (Position via --pv-x/--pv-y aus JS) */
.pv-glow::after {
  content: "";
  position: absolute;
  inset: 0;
  border-radius: inherit;
  background: radial-gradient(360px circle at var(--pv-x, 50%) var(--pv-y, 50%),
    rgba(0, 113, 227, .07), transparent 65%);
  opacity: 0;
  transition: opacity .35s ease;
  pointer-events: none;
}
.pv-glow:hover::after { opacity: 1; }

/* ── Magnetic CTA: JS setzt transform, CSS liefert die Feder zurück ──────── */
.pv-magnetic {
  transition: transform .25s cubic-bezier(.34, 1.3, .64, 1), box-shadow .25s ease;
  will-change: transform;
}

/* ── Count-up-Zahlen: dezenter Pop wenn der Zähler startet ───────────────── */
[data-countup] {
  font-variant-numeric: tabular-nums;
}
[data-countup].pv-counting {
  animation: pvNumPop .5s cubic-bezier(.16, 1, .3, 1);
}
@keyframes pvNumPop {
  0% { opacity: .35; transform: translateY(6px); }
  100% { opacity: 1; transform: translateY(0); }
}

/* ── Marquee (Logo-/Trust-Leisten): nahtlose Endlos-Schleife ─────────────── */
.pv-marquee {
  overflow: hidden;
  -webkit-mask-image: linear-gradient(90deg, transparent, #000 8%, #000 92%, transparent);
  mask-image: linear-gradient(90deg, transparent, #000 8%, #000 92%, transparent);
}
.pv-marquee-track {
  display: inline-flex;
  gap: 48px;
  padding-right: 48px;
  white-space: nowrap;
}
/* Schleife erst, wenn JS den Inhalt dupliziert hat — ohne Duplikat entstünde
   pro Durchlauf eine sichtbare Lücke (und ohne JS liefe die Animation leer). */
.pv-marquee-ready .pv-marquee-track {
  animation: pvMarquee 28s linear infinite;
}
.pv-marquee:hover .pv-marquee-track { animation-play-state: paused; }
@keyframes pvMarquee {
  to { transform: translateX(-50%); }
}

/* ── Dezente Hero-Ambient-Fläche (optional per .pv-ambient auf Hero) ─────── */
.pv-ambient {
  position: relative;
}
.pv-ambient::before {
  content: "";
  position: absolute;
  top: -20%;
  left: 50%;
  width: min(900px, 90vw);
  height: 480px;
  transform: translateX(-50%);
  background:
    radial-gradient(closest-side, rgba(0, 113, 227, .08), transparent 70%),
    radial-gradient(closest-side, rgba(99, 102, 241, .06), transparent 70%);
  filter: blur(40px);
  animation: pvAmbient 14s ease-in-out infinite alternate;
  pointer-events: none;
  z-index: -1;
}
@keyframes pvAmbient {
  from { transform: translateX(-54%) translateY(0); }
  to   { transform: translateX(-46%) translateY(24px); }
}

/* ============================================================================
   PREMIUM-POLISH-LAYER (Website-Design-Bauweise, 2026-08-24)
   Additiv: lädt NACH dem Inline-CSS jeder Seite — gleiche Spezifität, spätere
   Quelle gewinnt. Kein DOM-Umbau nötig; Seiten ohne diese Klassen bleiben
   unverändert. Eine Easing-Kurve für alles: cubic-bezier(.16,1,.3,1).
   ============================================================================ */

/* ── Zweilagige Schatten (enger Kontakt- + weiter Ambient-Schatten) ──────── */
/* Überschreibt die einlagigen Tokens der Seiten zentral für alle Karten,
   Bilder und Boxen. Einlagige Schatten wirken flach und billig. */
:root {
  --shadow-sm: 0 1px 2px rgba(29, 29, 31, .04), 0 2px 8px rgba(29, 29, 31, .05);
  --shadow-md: 0 2px 6px rgba(29, 29, 31, .05), 0 10px 32px rgba(29, 29, 31, .09);
  --shadow-lg: 0 4px 12px rgba(29, 29, 31, .06), 0 20px 56px rgba(29, 29, 31, .13);
}

/* ── Tastatur-Fokus sichtbar und markenfarben (nie outline:none) ─────────── */
:focus-visible {
  outline: 2px solid var(--accent, #0071e3);
  outline-offset: 3px;
}
.btn:focus-visible, .nav-cta:focus-visible { outline-offset: 2px; }

/* ── Text-Auswahl in Markenfarbe ─────────────────────────────────────────── */
::selection { background: rgba(0, 113, 227, .18); }

/* ── Animierte Unterstreichung auf Nav- und Footer-Links (nur echte Maus) ── */
@media (hover: hover) and (pointer: fine) {
  .nav-center a, .footer-links a { position: relative; }
  .nav-center a::after, .footer-links a::after {
    content: "";
    position: absolute;
    left: 0;
    right: 0;
    bottom: -4px;
    height: 1.5px;
    background: currentColor;
    transform: scaleX(0);
    transform-origin: left;
    transition: transform .32s cubic-bezier(.16, 1, .3, 1);
  }
  .nav-center a:hover::after, .footer-links a:hover::after { transform: scaleX(1); }
}

/* ── Button-Detail: Active drückt zurück auf die Grundlinie ──────────────── */
.btn:active, .nav-cta:active { transform: translateY(0); }

/* ── Bild-Reveal: Aufwischen statt Einblenden ────────────────────────────── */
/* Nur aktiv, wenn JS läuft (html.pv-js setzt premium.js in Zeile 1) — ohne
   JS bleibt jedes Bild sofort sichtbar. Endzustand reserviert Platz: kein CLS. */
html.pv-js .pv-img-reveal { clip-path: inset(0 100% 0 0); }
html.pv-js .pv-img-reveal.pv-in {
  clip-path: inset(0 0 0 0);
  transition: clip-path 1.2s cubic-bezier(.7, 0, .3, 1);
}

/* ── Scroll-Cue im Hero: zeigt, dass es weitergeht ───────────────────────── */
.pv-scroll-cue {
  display: inline-block;
  margin-top: 40px;
  width: 22px;
  height: 34px;
  border: 1.5px solid var(--text-tertiary, #6e6e73);
  border-radius: 12px;
  position: relative;
  opacity: .7;
}
.pv-scroll-cue::before {
  content: "";
  position: absolute;
  top: 6px;
  left: 50%;
  width: 3px;
  height: 7px;
  border-radius: 2px;
  background: var(--text-tertiary, #6e6e73);
  transform: translateX(-50%);
  animation: pvCue 2.5s ease-in-out infinite alternate;
}
@keyframes pvCue {
  from { opacity: .4; transform: translate(-50%, 0); }
  to   { opacity: .9; transform: translate(-50%, 6px); }
}

/* ── Dunkle Höhepunkt-Sektion (Bento) ────────────────────────────────────── */
.pv-dark {
  background: #16161a;
  color: #f5f5f7;
}
.pv-dark .headline-lg, .pv-dark .headline-sm, .pv-dark h3 { color: #f5f5f7; }
.pv-dark .subline { color: rgba(245, 245, 247, .64); }
.pv-dark .label { color: #6e9fff; }
/* Der blaue Button-Schatten und der CTA-Glow der Seiten wirken auf dunklem
   Grund als bunter Halo um den hellen Button — dort bleibt er flächig. */
.pv-dark .btn-primary::after { display: none; }
.pv-dark .btn-primary { box-shadow: 0 2px 8px rgba(0, 0, 0, .4); }
.pv-bento {
  display: grid;
  grid-template-columns: repeat(4, 1fr);
  gap: 16px;
  text-align: left;
}
.pv-bento-card {
  background: rgba(255, 255, 255, .05);
  border: 1px solid rgba(255, 255, 255, .09);
  border-radius: var(--radius, 20px);
  padding: 28px;
  transition: background .32s ease, border-color .32s ease, transform .35s cubic-bezier(.16, 1, .3, 1);
}
.pv-bento-card:hover {
  background: rgba(255, 255, 255, .08);
  border-color: rgba(255, 255, 255, .16);
  transform: translateY(-4px);
}
.pv-bento-card .emoji { font-size: 34px; margin-bottom: 12px; display: block; }
.pv-bento-card h3 { font-size: 18px; font-weight: 700; letter-spacing: -.02em; margin-bottom: 8px; }
.pv-bento-card p { font-size: 15px; line-height: 1.55; color: rgba(245, 245, 247, .64); }
.pv-bento-card a { color: #6e9fff; font-weight: 600; }
.pv-bento-card.b-lg { grid-column: span 2; grid-row: span 2; padding: 36px; display: flex; flex-direction: column; justify-content: flex-end; }
/* Faktenliste der dominanten Kachel — sie trägt die Sektion, deshalb hat sie
   als einzige mehr als einen Absatz. */
.pv-bento-card.b-lg ul { list-style: none; display: grid; gap: 10px; margin-top: 20px; }
.pv-bento-card.b-lg li {
  display: flex;
  align-items: flex-start;
  gap: 10px;
  font-size: 15px;
  line-height: 1.5;
  color: rgba(245, 245, 247, .78);
}
.pv-bento-card.b-lg li::before { content: "✓"; color: #4ade80; font-weight: 700; flex-shrink: 0; }
.pv-bento-card.b-lg .emoji { font-size: 46px; }
.pv-bento-card.b-lg h3 { font-size: 24px; }
.pv-bento-card.b-lg p { font-size: 16px; }
.pv-bento-card.b-wide { grid-column: span 2; }
@media (max-width: 900px) {
  .pv-bento { grid-template-columns: 1fr 1fr; }
  .pv-bento-card.b-lg { grid-column: span 2; grid-row: auto; }
}
@media (max-width: 600px) {
  .pv-bento { grid-template-columns: 1fr; }
  .pv-bento-card.b-lg, .pv-bento-card.b-wide { grid-column: auto; }
}

/* ── „Beliebt“-Badge auf der hervorgehobenen Preis-Karte ─────────────────── */
/* Sitzt INNERHALB der Karte, nicht überstehend: Karten mit `.pv-glow` tragen
   `overflow:hidden` — ein Badge auf negativem `top` würde dort abgeschnitten. */
.pv-badge {
  position: absolute;
  top: 16px;
  left: 50%;
  transform: translateX(-50%);
  background: var(--accent, #0071e3);
  color: #fff;
  font-size: 12px;
  font-weight: 700;
  letter-spacing: .06em;
  text-transform: uppercase;
  padding: 5px 14px;
  border-radius: 999px;
  white-space: nowrap;
}

/* ── Smooth-Scroll respektiert reduced motion ────────────────────────────── */
@media (prefers-reduced-motion: reduce) {
  html { scroll-behavior: auto; }
}

/* ── Aufzaehlungen: ein Textfluss statt drei Flex-Spalten ────────────────── */
/* Die Seiten setzen `.check-list li { display:flex }`. Dadurch wird JEDES Kind
   ein eigenes Flex-Item: Bei "<strong>Titel</strong> – Erklaerung" stehen
   Fettteil und Erklaerung als zwei schmale Spalten nebeneinander und brechen
   frueh um ("Anony- mer Rueckka- nal"). Mit absolut gesetztem Haken laeuft der
   ganze Eintrag als normaler Text und bricht dort, wo er soll. */
.check-list li {
  display: block;
  position: relative;
  padding-left: 26px;
  hyphens: auto;
  overflow-wrap: break-word;
}
.check-list li::before {
  position: absolute;
  left: 0;
  top: 0;
  margin-top: 0;
}
/* Fette Teil-Ueberschrift im Stichpunkt bleibt im Fluss, bekommt aber Luft
   zum nachfolgenden Erklaertext. */
.check-list li > strong { font-weight: 600; }

/* ── Menue mit Untermenue (Funktionen, Loesungen) ────────────────────────── */
/* Der Trigger bleibt ein echter Link auf die Uebersichtsseite — das Untermenue
   ist eine Abkuerzung, kein Ersatz. Oeffnet per Hover UND per Tastatur-Fokus
   (:focus-within), damit es ohne Maus bedienbar bleibt. Auf Touch und schmalen
   Fenstern bleibt es zu; dort fuehrt der Link direkt zur Uebersicht und das
   mobile Menue traegt die Unterpunkte als eigene Zeilen. */
.nav-drop { position: relative; display: inline-flex; align-items: center; }
.nav-drop-trigger { display: inline-flex; align-items: center; gap: 5px; }
.nav-drop-caret {
  width: 10px; height: 10px; flex-shrink: 0;
  transition: transform .28s cubic-bezier(.16, 1, .3, 1);
}
.nav-drop-panel {
  position: absolute;
  top: calc(100% + 14px);
  left: 50%;
  transform: translateX(-50%) translateY(-6px);
  min-width: 560px;
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: 2px 10px;
  padding: 14px;
  border-radius: 18px;
  /* Deckend, nicht transparent: Das Panel liegt ueber der Hero-Ueberschrift —
     jede Restdurchsicht macht beide Texte schwer lesbar. */
  background: #fff;
  border: 1px solid var(--border, rgba(0, 0, 0, .08));
  box-shadow: var(--shadow-lg);
  opacity: 0;
  visibility: hidden;
  pointer-events: none;
  transition: opacity .24s cubic-bezier(.16, 1, .3, 1), transform .24s cubic-bezier(.16, 1, .3, 1), visibility .24s;
  z-index: 120;
}
/* Unsichtbare Bruecke: sonst schliesst das Panel, wenn die Maus die Luecke
   zwischen Trigger und Panel quert. */
.nav-drop-panel::before {
  content: "";
  position: absolute;
  left: 0; right: 0; top: -16px; height: 16px;
}
.nav-drop-item {
  display: block;
  padding: 11px 13px;
  border-radius: 12px;
  transition: background .2s ease;
}
.nav-drop-item:hover, .nav-drop-item:focus-visible { background: var(--bg-alt, #f5f5f7); }
.nav-drop-item .t {
  display: block;
  font-size: 14.5px;
  font-weight: 600;
  color: var(--text, #1d1d1f);
  line-height: 1.35;
}
.nav-drop-item .d {
  display: block;
  margin-top: 3px;
  font-size: 12.5px;
  line-height: 1.45;
  color: var(--text-tertiary, #6e6e73);
}
/* Fusszeile des Panels: Weg zur vollstaendigen Uebersicht */
.nav-drop-all {
  grid-column: 1 / -1;
  margin-top: 6px;
  padding: 11px 13px;
  border-top: 1px solid var(--border, rgba(0, 0, 0, .08));
  font-size: 13.5px;
  font-weight: 600;
  color: var(--accent, #0071e3);
}
.nav-drop-all:hover { text-decoration: underline; }

@media (hover: hover) and (pointer: fine) {
  .nav-drop:hover .nav-drop-panel,
  .nav-drop:focus-within .nav-drop-panel {
    opacity: 1;
    visibility: visible;
    pointer-events: auto;
    transform: translateX(-50%) translateY(0);
  }
  .nav-drop:hover .nav-drop-caret,
  .nav-drop:focus-within .nav-drop-caret { transform: rotate(180deg); }
}
/* Tastatur ohne Maus: Fokus im Trigger oeffnet ebenfalls */
.nav-drop:focus-within .nav-drop-panel {
  opacity: 1;
  visibility: visible;
  pointer-events: auto;
  transform: translateX(-50%) translateY(0);
}
/* Mit Escape geschlossen: Der Trigger behaelt den Fokus (damit die Tastatur
   nicht ins Nichts springt), deshalb wuerde :focus-within das Panel sofort
   wieder oeffnen. Diese Klasse haelt es zu, bis der Fokus den Bereich
   verlaesst oder die Maus neu darueber faehrt. */
.nav-drop.is-dismissed .nav-drop-panel {
  opacity: 0 !important;
  visibility: hidden !important;
  pointer-events: none !important;
}
.nav-drop.is-dismissed .nav-drop-caret { transform: none !important; }

/* Die animierte Unterstreichung der Nav-Links darf den Trigger nicht doppelt
   markieren, waehrend das Panel offen ist. */
.nav-drop-panel a::after { content: none !important; }

@media (max-width: 900px) {
  .nav-drop-panel { display: none; }
  .nav-drop-caret { display: none; }
}

/* Unterpunkte im mobilen Menue: eingerueckt unter ihrem Hauptpunkt */
.mobile-menu .mobile-sub {
  display: block;
  padding: 11px 0 11px 18px;
  font-size: 15px;
  color: var(--text-secondary, #6e6e73);
  border-bottom: 1px solid var(--border, rgba(0, 0, 0, .08));
}

/* ── Icons statt Deko-Emojis (Corporate-Umbau 24.08.2026) ────────────────── */
/* Marketing zeigt Icons im Lucide-Stil: 24er-Raster, Strichstaerke 1.5,
   currentColor. Emojis rendern auf jedem System anders, tragen fremde Farben
   und lassen eine B2B-Seite nach Bastelei aussehen. Entscheidung und
   Begruendung: docs/DECISIONS.md, Eintrag 2026-08-24 (Corporate-Bildsprache). */
.kk-icon {
  display: block;
  flex-shrink: 0;
  color: var(--accent, #0071e3);
}
/* Icon-Kachel: gibt dem Strich-Icon Flaeche, damit es eine Ueberschrift traegt */
.kk-icon-tile {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 46px;
  height: 46px;
  border-radius: 13px;
  background: rgba(0, 113, 227, .08);
  margin-bottom: 14px;
}
.icon-card .kk-icon-tile { margin: 0 auto 14px; }
.pv-dark .kk-icon-tile { background: rgba(255, 255, 255, .09); }
.pv-dark .kk-icon { color: #6e9fff; }

/* Status-Symbole in Vergleichstabellen: Farbe traegt die Bedeutung,
   das Icon macht sie auch ohne Farbwahrnehmung erkennbar. */
.kk-state { display: inline-flex; align-items: center; gap: 6px; }
.kk-state .kk-icon { width: 17px; height: 17px; }
.compare-table .yes .kk-icon { color: var(--green, #22c55e); }
.compare-table .no .kk-icon { color: var(--red, #ef4444); }
.compare-table .mid .kk-icon { color: var(--amber, #f59e0b); }

/* Der TEXT daneben braucht dunklere Töne: die hellen Ampelfarben erreichen
   auf Weiß nur 2,1-3,6:1, WCAG AA verlangt 4,5:1. Das Icon bleibt hell —
   dort trägt die Form die Bedeutung, nicht die Lesbarkeit. */
.compare-table .yes { color: #15803d; }
.compare-table .no { color: #b91c1c; }
.compare-table .mid { color: #b45309; }

/* Abschnitts-Label („PREISE & PLÄNE"): #0071e3 als 13-px-Großbuchstaben
   erreicht auf dem grauen Abschnitt nur 4,31:1. Dieselbe dunklere
   Text-Variante wie in brand.css (--accent-text). */
.label { color: #0064c9; }

/* `.box-titel` hatte auf den Marketing-Seiten gar keine Regel und fiel auf die
   Browser-Vorgabe (18,72 px). Werte Zeichen für Zeichen wie in brand.css —
   dort ist 18 px/700 eine Entscheidung (Überschriften-Ebene, nicht Optik). */
.box-titel { font-size: 18px; font-weight: 700; letter-spacing: -.01em; }

/* Untergrenze der Schriftgröße in Vergleichstabellen. Am Handy fielen
   dieselben Tabellen auf 10-12 px; die Seiten scrollen die Tabelle ohnehin
   waagerecht oder brechen die Zellen um. */
@media (max-width: 768px) {
  .compare-table,
  .compare-table th,
  .compare-table td,
  .card .compare-table,
  .card .compare-table th,
  .card .compare-table td { font-size: 13px; }
}

/* Wortmarke: gezeichnetes Zeichen statt Emoji */
.nav-brand .kk-mark, .footer-inner .kk-mark {
  width: 22px;
  height: 22px;
  flex-shrink: 0;
  color: var(--accent, #0071e3);
}
.nav-brand { gap: 9px; }

/* ── Satzbild: keine haengenden Einzelwoerter ────────────────────────────── */
/* `balance` verteilt Ueberschriften gleichmaessig auf ihre Zeilen, statt ein
   einzelnes Wort allein in die letzte zu schicken. `pretty` tut dasselbe fuer
   Fliesstext und Listen. Beides ohne Markup-Aenderung, auf allen Seiten. */
h1, h2, h3, h4,
.headline-xl, .headline-lg, .headline-md, .headline-sm {
  text-wrap: balance;
}
p, li, .subline, .body-text, figcaption {
  text-wrap: pretty;
}

/* ── Karten in einer Reihe enden auf einer Linie ─────────────────────────── */
/* Das Raster streckt alle Karten auf dieselbe Hoehe, der Inhalt endete aber je
   Karte woanders — auf der Preisseite standen die fuenf CTA-Buttons bis zu
   563 px versetzt. Mit Flex-Spalte und `margin-top:auto` am Fussteil sitzt der
   Abschluss jeder Karte unten, egal wie lang die Liste darueber ist. */
.price-card {
  display: flex;
  flex-direction: column;
}
.price-card > .btn,
.price-card > a.btn {
  margin-top: auto;
}
/* Funktions- und Feature-Karten: der Verweislink haengt am Kartenfuss */
.fx-card {
  display: flex;
  flex-direction: column;
}
.fx-card > .fx-more {
  margin-top: auto;
  padding-top: 14px;
}

/* ── Tabellen brechen nicht aus ihrer Karte aus ──────────────────────────── */
/* Statt negativer Aussenabstaende (die die Kartenkante durchstossen) scrollt
   die Tabelle in ihrem eigenen Kasten. */
.card .compare-table,
.card table {
  display: block;
  max-width: 100%;
  overflow-x: auto;
  -webkit-overflow-scrolling: touch;
}
@media (max-width: 768px) {
  .card .compare-table {
    margin-left: 0;
    margin-right: 0;
    width: 100%;
  }
}

/* ── Lange Komposita brechen um, statt ueberzustehen ─────────────────────── */
.related-card h4,
.blog-card h3,
.card h3,
.card h4 {
  overflow-wrap: break-word;
  hyphens: auto;
}

/* ── Druck: nichts darf versteckt bleiben ────────────────────────────────── */
@media print {
  .reveal { opacity: 1 !important; transform: none !important; }
  html.pv-js .pv-img-reveal { clip-path: inset(0 0 0 0) !important; }
  .pv-progress, .pv-scroll-cue { display: none !important; }
}

/* ── Reduced Motion: alles Bewegte abschalten, Inhalte sofort zeigen ─────── */
@media (prefers-reduced-motion: reduce) {
  .pv-words.pv-ready .pv-word { animation: none; opacity: 1; filter: none; transform: none; }
  .reveal { opacity: 1; transform: none; transition: none; }
  .pv-marquee-track { animation: none; }
  .pv-ambient::before { animation: none; }
  .pv-magnetic { transition: none; }
  [data-countup].pv-counting { animation: none; }
  .pv-progress { display: none; }
  html.pv-js .pv-img-reveal { clip-path: inset(0 0 0 0) !important; transition: none; }
  .pv-scroll-cue::before { animation: none; }
}

/* ══════════════════════════════════════════════════════════════════════════
   Erster Sichtbereich: nie wegblenden (Befund 05.09.2026)
   ══════════════════════════════════════════════════════════════════════════
   `.reveal` setzt opacity:0, bis das Skript das Element sichtbar meldet. Auf
   20 Marketing-Seiten war das LCP-Element genau so ein Absatz: erster Anstrich
   nach 0,5 s, groesster Inhalt erst nach 1,4 s — am Handy mit gedrosselter CPU
   gemessen. Und faellt das Skript aus, bleibt der Text dauerhaft unsichtbar.
   Deshalb: Was im Kopfbereich steht, wird sofort gezeichnet. Animiert einlaufen
   darf nur, was ohnehin erst nach dem Scrollen zu sehen ist.
   ══════════════════════════════════════════════════════════════════════════ */
.hero .reveal,
.hero.reveal,
.section:first-of-type > .container > .reveal,
.section:first-of-type .subline.reveal,
.section:first-of-type h1.reveal {
  opacity: 1;
  transform: none;
  transition: none;
}
