
/* --- Videoliste ------------------------------------------------------------
   Auf /videos/ holte ein Framer-Baustein die Videos erst im Browser. Ohne sein
   Skript blieben sechs graue Kaesten stehen. Die Liste steht jetzt fest in der
   Seite; das Vorschaubild liegt lokal, zu YouTube geht erst eine Verbindung,
   wenn jemand ein Video startet. */
.cp-videos{display:grid;grid-template-columns:repeat(3,1fr);gap:32px 20px;width:100%}
@media (max-width:1000px){.cp-videos{grid-template-columns:repeat(2,1fr)}}
@media (max-width:700px){.cp-videos{grid-template-columns:1fr}}
.cp-video{display:flex;flex-direction:column;min-width:0}
.cp-video-bild{position:relative;display:block;border-radius:12px;overflow:hidden;background:#1a1a1a;aspect-ratio:16/9}
.cp-video-bild img{width:100%;height:100%;object-fit:cover;display:block;transition:transform .35s ease}
.cp-video-bild:hover img{transform:scale(1.03)}
.cp-video-play{position:absolute;inset:0;margin:auto;width:56px;height:56px;border-radius:50%;background:rgba(0,0,0,.6);display:flex;align-items:center;justify-content:center;transition:background .2s ease}
.cp-video-bild:hover .cp-video-play{background:rgba(0,0,0,.85)}
.cp-video-play svg{width:19px;height:19px;fill:#fff;margin-left:3px}
.cp-video-dauer{position:absolute;right:8px;bottom:8px;padding:2px 6px;border-radius:4px;background:rgba(0,0,0,.8);color:#fff;font-size:12px;line-height:1.4;font-variant-numeric:tabular-nums}
.cp-video-titel{margin:14px 0 4px;font-size:16px;line-height:1.35;font-weight:600}
.cp-video-titel a{color:inherit;text-decoration:none}
.cp-video-titel a:hover{text-decoration:underline}
.cp-video-datum{margin:0;font-size:14px;color:rgba(0,0,0,.5)}
.cp-video-rahmen{width:100%;aspect-ratio:16/9;display:block;border:0;border-radius:12px}
.cp-video-hinweis{margin:28px 0 0;font-size:14px;line-height:1.5;color:rgba(0,0,0,.5)}
/* --- Spaet rendern ---------------------------------------------------------
   Abschnitte ausserhalb des Bildschirms werden erst berechnet, wenn sie in
   die Naehe kommen.

   Die Platzhalterhoehe stand bis 08.09.2026 pauschal auf 900px. Die echten
   Hoehen liegen zwischen 429 und 1578px (Desktop), auf dem Handy noch weiter
   auseinander - beim ersten Durchscrollen tauschte der Browser jede Schaetzung
   gegen den echten Wert und der Inhalt darunter sprang, im schlimmsten Fall um
   678px. Jetzt traegt jeder Abschnitt seine gemessene Hoehe als Variable
   (scripts/abschnittshoehen.mjs, laeuft im Bau nach der Uebernahme). Die
   Rueckfallwerte greifen nur, wenn der Messlauf uebersprungen wurde. */
[data-cp-spaet]{content-visibility:auto;contain-intrinsic-size:auto var(--cp-h,900px)}
@media (max-width:809px){
  [data-cp-spaet]{contain-intrinsic-size:auto var(--cp-hm,1500px)}
}

/* --- Zeiger ueber Karten ---------------------------------------------------
   Framer setzt auf Textbausteine cursor:auto. Liegt so ein Baustein in einem
   Link (Blogkarten bestehen fast nur daraus), zeigt der Zeiger den normalen
   Pfeil - die Karte fuehlt sich tot an, obwohl der Klick funktioniert. */
a[href],a[href] *{cursor:pointer}
a[href] input,a[href] textarea,a[href] select{cursor:auto}

/* --- Kopfzeile beim Scrollen -----------------------------------------------
   Framer haelt zwei Kopfzeilen bereit: eine durchsichtige fuer den Anfang und
   eine, die beim Scrollen oben bleibt ("Header on scroll"). Die zweite bekommt
   im Original einen weissen Grund - ohne Framers Skript blieb sie durchsichtig,
   dann stand weisse Schrift auf hellem Inhalt. */
/* Die Kopfzeile traegt ihren Hintergrund INLINE (background-color:var(--token…,
   rgba(255,255,255,0))). Ohne !important verliert jede Regel dagegen - dann
   steht dunkle Schrift auf durchsichtigem Grund: ueber hellen Abschnitten
   sichtbar, ueber dunklen weg. Genau das war "manchmal ist die Navi da,
   manchmal nicht". Gilt fuer beide Bauformen: "Header on scroll" (Seiten mit
   dunklem Hero) und die "…/On Scroll"-Varianten (alle anderen Seiten). */
nav[name="Header on scroll"],
nav[data-framer-name$="/On Scroll"]{transition:background-color .25s ease,box-shadow .25s ease}
html[data-cp-gescrollt] nav[name="Header on scroll"],
html[data-cp-gescrollt] nav[data-framer-name$="/On Scroll"]{
  background-color:#fff!important;box-shadow:0 4px 20px rgba(6,31,48,.10)}
html[data-cp-gescrollt] nav[name="Header on scroll"] p,
html[data-cp-gescrollt] nav[name="Header on scroll"] span,
html[data-cp-gescrollt] nav[name="Header on scroll"] select,
html[data-cp-gescrollt] nav[name="Header on scroll"] label{
  color:#061F30!important;--framer-text-color:#061F30!important}
html[data-cp-gescrollt] nav[name="Header on scroll"] .framer-locale-picker svg{fill:#061F30!important}
/* Der gruene Kontakt-Knopf tragt schon dunkle Schrift - nicht anfassen. */
html[data-cp-gescrollt] nav[name="Header on scroll"] [data-framer-name="Action"] a p{color:#061F30!important}

/* --- Menue fuer das Handy --------------------------------------------------
   In der Handy-Kopfzeile stehen im HTML nur Logo-Links; die Punkte baut Framer
   erst im Browser. Der Burger war eine Zeichnung. Dieses Menue ist unser
   eigenes und liegt am Ende des Rumpfes. */
[data-cp-burger]{cursor:pointer}
.cp-mobilmenue{
  position:fixed;inset:0;z-index:2147483200;background:rgba(6,31,48,.45);
  opacity:0;transition:opacity .2s ease;
  font-family:'DM Sans',system-ui,sans-serif;
}
.cp-mobilmenue[data-offen]{opacity:1}
.cp-mm-blatt{
  position:absolute;top:0;right:0;bottom:0;width:min(92vw,420px);
  background:#fff;box-shadow:-8px 0 40px rgba(6,31,48,.25);
  display:flex;flex-direction:column;
  transform:translateX(100%);transition:transform .22s ease;
  overflow-y:auto;-webkit-overflow-scrolling:touch;
}
.cp-mobilmenue[data-offen] .cp-mm-blatt{transform:none}
.cp-mm-kopf{
  display:flex;align-items:center;justify-content:space-between;
  padding:18px 20px;border-bottom:1px solid #ececf0;position:sticky;top:0;background:#fff;
}
.cp-mm-titel{font-size:15px;color:#9a9aa2}
.cp-mm-zu{
  border:0;background:transparent;font-size:20px;line-height:1;color:#061F30;
  padding:6px 10px;cursor:pointer;border-radius:8px;
}
.cp-mm-zu:hover{background:rgba(6,31,48,.06)}
.cp-mm-nav{padding:8px 8px 28px}
.cp-mm-nav a{text-decoration:none;color:#061F30;display:block}
.cp-mm-punkt{border-bottom:1px solid #f1f1f4}
.cp-mm-punkt>summary{
  list-style:none;cursor:pointer;padding:15px 12px;font-size:18px;font-weight:500;
  display:flex;align-items:center;justify-content:space-between;color:#061F30;
}
.cp-mm-punkt>summary::-webkit-details-marker{display:none}
.cp-mm-punkt>summary::after{
  content:'';width:9px;height:9px;margin-right:4px;flex:none;
  border-right:1.6px solid #9a9aa2;border-bottom:1.6px solid #9a9aa2;
  transform:rotate(45deg);transition:transform .18s ease;
}
.cp-mm-punkt[open]>summary::after{transform:rotate(-135deg)}
/* Aufgeklappter Punkt bleibt unter der Kopfzeile stehen. Ohne das scrollte
   seine Beschriftung unter die klebende Kopfzeile und nur die Ecke des Pfeils
   lugte neben dem Schliessen-Kreuz hervor - Nadines Screenshot vom 08.09.2026.
   68px = Hoehe der Kopfzeile (18px Polster oben und unten plus Zeile). */
.cp-mm-kopf{z-index:2}
.cp-mm-punkt[open]>summary{position:sticky;top:68px;background:#fff;z-index:1}
.cp-mm-inhalt{padding:2px 12px 14px}
.cp-mm-gruppe{margin:12px 0 4px;font-size:13px;color:#9a9aa2}
.cp-mm-inhalt a{padding:9px 0 9px 14px;border-left:1px solid #e4e4e7;font-size:16px}
.cp-mm-inhalt a:hover{border-left-color:#c8f8a9}
.cp-mm-link{padding:15px 12px;font-size:18px;font-weight:500;border-bottom:1px solid #f1f1f4}
.cp-mm-alle{padding:9px 0 9px 14px;border-left:1px solid #e4e4e7;font-weight:500}
.cp-mm-alle:hover{border-left-color:#c8f8a9}
.cp-mm-cta{
  margin:18px 12px 0;padding:14px 18px;border-radius:8px;background:#061F30;
  color:#fff!important;text-align:center;font-weight:500;
}
.cp-mm-sprache{margin:14px 12px 0;font-size:15px}
.cp-mm-sprache a{color:#6b6b73;display:inline}
@media (min-width:810px){.cp-mobilmenue{display:none}}

/* --- Fenster fuer den Shop-Check ------------------------------------------
   "Shop-Check anfragen" ist ein Framer-Baustein, der im Browser ein Formular
   oeffnet. Ohne Framer passierte beim Klick nichts. */
.cp-fenster{
  position:fixed;inset:0;z-index:2147483300;background:rgba(6,31,48,.5);
  display:none;align-items:center;justify-content:center;padding:20px;
  font-family:'DM Sans',system-ui,sans-serif;
}
.cp-fenster[data-offen]{display:flex}
.cp-fenster-blatt{
  background:#fff;border-radius:16px;padding:28px 26px 26px;
  width:min(100%,460px);max-height:90vh;overflow-y:auto;position:relative;
  box-shadow:0 30px 80px rgba(6,31,48,.35);
}
.cp-fenster-blatt h2{margin:0 0 18px;font-family:'Forum',Georgia,serif;font-size:26px;color:#061F30}
.cp-fenster-zu{
  position:absolute;top:14px;right:14px;border:0;background:transparent;
  font-size:18px;color:#6b6b73;cursor:pointer;padding:4px 8px;border-radius:6px;
}
.cp-fenster-zu:hover{background:rgba(6,31,48,.06)}
.cp-fenster-blatt label{display:block;margin-bottom:14px;font-size:14px;color:#6b6b73}
.cp-fenster-blatt input,.cp-fenster-blatt textarea{
  display:block;width:100%;box-sizing:border-box;margin-top:5px;padding:11px 13px;
  border:1px solid rgba(6,31,48,.2);border-radius:8px;font:inherit;font-size:16px;color:#061F30;
}
.cp-fenster-blatt input:focus,.cp-fenster-blatt textarea:focus{outline:2px solid #061F30;outline-offset:1px}
.cp-fenster-blatt button[type=submit]{
  width:100%;margin-top:6px;padding:14px;border:0;border-radius:8px;
  background:#061F30;color:#fff;font:inherit;font-size:16px;font-weight:500;cursor:pointer;
}
.cp-fenster-blatt button[type=submit]:hover{filter:brightness(1.15)}

/* --- Blogübersicht ---------------------------------------------------------
   Alle Karten stehen in der Seite; ueber die erste Portion hinaus sind sie
   ausgeblendet, bis "Mehr laden" oder ein Filter etwas anderes sagt. */
[data-cp-verborgen]{display:none!important}
[data-cp-filter]{transition:opacity .15s ease}
[data-cp-filter]:hover{opacity:.65}
[data-cp-filter][data-cp-aktiv]{text-decoration:underline;text-underline-offset:4px}

/* --- Akkordeons (FAQ) ------------------------------------------------------
   Zugeklappt: Antwort weg, Zeile behaelt Framers feste Hoehe. Aufgeklappt:
   Antwort da, Zeile bekommt ueber die getauschte Variantenklasse
   height:min-content - dieselben Regeln, die auch das Original nutzt. */
[data-cp-klapp]{cursor:pointer}
[data-cp-klapp]:not([data-cp-offen]) [data-cp-antwort]{display:none!important}
[data-cp-klapp][data-cp-offen]{height:min-content!important}
[data-cp-klapp][data-cp-offen] [data-cp-antwort]{opacity:1!important}
[data-cp-klapp]:focus-visible{outline:2px solid #061F30;outline-offset:4px}
/* Pfeil rechts neben der Frage: zeigt nach unten, aufgeklappt nach oben. */
[data-cp-klapp-symbol]{display:inline-flex;align-items:center;justify-content:center;color:#061F30;flex:none}
.cp-klapp-symbol-eigen{margin-left:12px;width:32px;height:32px;border-radius:50%;background:#f4f4f5}
.cp-klapp-pfeil{display:block;transition:transform .2s ease}
[data-cp-klapp][data-cp-offen] .cp-klapp-pfeil{transform:rotate(180deg)}
/* Framers 45-Grad-Drehung des Symbolbehaelters (fuer das Plus) aufheben. */
[data-cp-klapp-symbol-huelle]{transform:none!important;rotate:none!important}
[data-cp-klapp-symbol] > div{display:flex!important;align-items:center;justify-content:center;width:100%;height:100%}

/* --- Rueckmeldung der Formulare -------------------------------------------
   Ohne Skript fuehrt das Absenden auf eine Dankesseite; mit Skript bleibt der
   Besucher hier und liest die Meldung an dieser Stelle. */
[data-meldung]{margin:10px 0 0;font-family:'DM Sans',system-ui,sans-serif;font-size:15px;min-height:1.4em}
[data-meldung]:empty{margin:0;min-height:0}

/* --- Absende-Knopf auf /kontakt, /en/contact, /ueber-uns, /en/about-us ---
   Die Knopfzeile (width:1fr = ungueltig, place-self:start) bekam ihre Breite nur vom
   reCAPTCHA-iframe (304px). Ohne iframe schrumpft sie auf den Inhalt. Unter 810px
   stellt Framer das Formular auf Spalten um, dort ist sie ohnehin 100% breit. */
@media (min-width:810px){
  [data-cp-knopfzeile]{grid-column:1/-1;width:100%!important;max-width:304px}
}

/* --- Silbentrennung --------------------------------------------------------
   Das Original trennt nicht (kein hyphens im Framer-Stylesheet, Browser-Standard
   manual) und setzt hyphens:auto nur inline auf einzelnen Textbausteinen - die
   uebernehmen wir ohnehin. Framers word-break:break-word gilt auf allen Breiten,
   bricht aber erst auf dem Handy mitten im Wort ("Fehlentscheidunge n:"). Nur dort
   trennen wir an der richtigen Stelle. 809px ist Framers Handy-Breakpoint. */
h1,h2,h3,h4{overflow-wrap:break-word}
@media (max-width:809px){
  /* word-break:break-word setzt Framer auf allen Textbausteinen. Das bricht
     nicht erst im Notfall, sondern schon, wenn das Wort auf der naechsten Zeile
     Platz haette - daher "Fehlentscheidunge|n" ohne Trennstrich. Erst
     word-break:normal laesst hyphens:auto zum Zug kommen. Das !important ist
     noetig, weil Framers Regel spezifischer greift als unsere. */
  h1,h2,h3,h4,:is(h1,h2,h3,h4) .framer-text{
    word-break:normal!important;overflow-wrap:break-word;hyphens:auto;-webkit-hyphens:auto;
    /* Nadine am 08.09.2026: "da koennte das neue wort einfach in der neuen zeile
       stehen". Ohne Grenze trennt der Browser auch dort, wo das Wort auf der
       naechsten Zeile bequem Platz haette ("Mi-gration", "Marke-ting"). Mit der
       Grenze wird nur getrennt, was wirklich nicht in eine Zeile passt:
       "Fehlentscheidungen:" ist bei 44px 367px breit, die Zeile hat 343px.
       14 = Mindestlaenge des Wortes, 7 = Zeichen vor, 5 = Zeichen nach dem
       Trennstrich. Safari ab 17 und Chrome ab 109 koennen das; wo nicht, greift
       einfach die normale Trennung wie bisher. */
    -webkit-hyphenate-limit-before:7;-webkit-hyphenate-limit-after:5;
    hyphenate-limit-chars:14 7 5}
}

/* --- Kopfzeile beim Scrollen: leerer Kasten auf dem Handy -------------------
   Nadines Screenshot vom 08.09.2026 zeigte beim Scrollen einen grossen weissen
   Block unter dem Logo. Ursache: die Handy-Fassung der Scroll-Kopfzeile
   enthaelt neben "Logo + Menu" (33px) noch einen voellig leeren div - 0 Kinder,
   0 Zeichen, 0 HTML - der 41px hoch ist und die Kopfzeile von 73 auf 164px
   aufblaeht. Framers Skript wuerde ihn fuellen, wir haben es entfernt.
   :empty trifft nur wirklich leere Kaesten, kann also nichts verschlucken, was
   Inhalt hat. Ueber data-framer-name="Inner" (in allen 299 Seiten) statt ueber
   den Namen der Kopfzeile: name="Header on scroll" gibt es nur auf 2 Seiten,
   die uebrigen heissen "…/On Scroll". */
@media (max-width:809px){
  nav [data-framer-name="Inner"]>div:empty{display:none!important}
}

/* --- Kennzahlen im Hero auf dem Handy --------------------------------------
   Nadine am 08.09.2026: "die punkte nebeneinander oder 2/1 und auch die badges
   koennen breiter sein". Framer stapelt die drei Kennzahlen auf dem Handy
   untereinander und nagelt jede auf 79,7px Breite fest - dadurch stand
   "Jahre E-/Commerce-/Erfahrung" auf drei Zeilen in einer duennen Spalte.
   Jetzt zwei nebeneinander, die dritte darunter, alle gleich breit (je 162px
   bei 375px Anzeige). calc(50% - 10px) statt flex-basis, damit die dritte
   Kachel nicht ueber die volle Breite aufreisst.
   .framer-mcvvnv ist der Kennzahlen-Streifen der beiden Startseiten (DE/EN);
   holt jemand die Vorlage neu von Framer, kann sich der Klassen-Hash aendern. */
@media (max-width:809px){
  .framer-mcvvnv{flex-flow:row wrap!important;gap:18px 20px!important}
  .framer-mcvvnv>*{width:auto!important;flex:0 1 calc(50% - 10px)!important;min-width:0}
}

/* --- Knopfbeschriftungen auf dem Handy -------------------------------------
   Framer nagelt Knoepfe auf die Breite fest, die der Text im Desktop-Entwurf
   brauchte. Auf dem Handy ist die Schrift teils groesser: "Paradox Check
   anfragen" brauchte 138px, der Knopf war 122px breit und schnitt ab
   (/whitepaper/hersteller-paradox). min-width statt width, damit vollbreite
   Knoepfe (width:100%) nicht auf Textbreite zusammenschrumpfen - min-width
   hebt nur den Boden an. data-framer-name="Button/Primary" ist Framers
   Komponentenname und damit stabil: 74 Vorkommen auf 36 Seiten. */
@media (max-width:809px){
  [data-framer-name^="Button/"]{min-width:max-content}
}

/* --- Zeile "Durchgaengige Verantwortung" (Startseiten DE/EN) ---------------
   Die Zeile ist 299px breit und traegt overflow:hidden, Text plus Symbol
   brauchen 306px - abgeschnitten wurde das Symbol am rechten Rand. Der Kasten
   sitzt in einem 339px breiten Eltern-Element, es ist also Platz da; nur die
   Klemme muss weg. Geprueft: Hoehe bleibt 34px, Layout aendert sich nicht.
   Die Alternative (Symbol in die naechste Zeile) haette die Zeile auf 66px
   aufgeblaeht - deshalb dieser Weg. */
@media (max-width:809px){
  .framer-q8vl4n{overflow:visible!important}
}

/* --- Rechtslinks in der Fusszeile (englische Seiten) -----------------------
   Der Kasten mit Impressum/Datenschutz steht auf width:min-content mit
   overflow:hidden. Im Deutschen passt das (184px reichen), im Englischen sind
   "Imprint" und "Data protection" laenger: 161px noetig, 143px vorhanden - die
   zweite Beschriftung war angeschnitten. width:auto laesst den Kasten seine
   echte Breite nehmen; auf den deutschen Seiten aendert sich dadurch nichts
   (dort bleibt es bei 184px, geprueft). Er sitzt nach dem Umbruch der
   Fusszeile ohnehin auf einer eigenen Zeile mit 343px Platz. */
@media (max-width:809px){
  .framer-s7wprw{width:auto!important;overflow:visible!important}
}

/* --- Abschnitts-Badges auf dem Handy ---------------------------------------
   Framer nagelt die grauen Abschnitts-Badges auf die im Entwurf gemessene
   Breite. Auf dem Handy quetschte das den Text: "Fuer wen wir arbeiten" stand
   in einem 82px-Kasten auf drei Zeilen, "Womit duerfen wir helfen?" in 74px
   sogar auf vier. Allein auf der Startseite acht solcher Badges.

   Nadine am 08.09.2026, nach einem Zwischenstand mit voller Breite: "eher so,
   dass es immer mittig ist und dann nur leichtes padding links und rechts, so
   dass das gesamtbild stimmig ist". Also die Pille eng um den Text statt ueber
   die ganze Breite - Framers eigenes Polster (6px 10px) bleibt.

   BEWUSST NICHT zentriert erzwungen: auf der Startseite ist nur der erste
   Abschnitt zentriert, die anderen sieben sind linksbuendig (text-align:start,
   Ueberschrift bei 16px). Mit max-content folgt das Badge automatisch seinem
   Abschnitt - im zentrierten sitzt es mittig (102px Rand links wie rechts),
   in den linksbuendigen buendig bei 16px auf der Kante der Ueberschrift. Ein
   erzwungenes margin-inline:auto haette sieben Badges mittig ueber
   linksbuendige Ueberschriften gesetzt.

   max-width:100% ist die Bremse fuer schmale Geraete: "Ein Auszug unserer
   Kernkompetenzen" braucht 297px, auf einem 320px-Display darf es umbrechen
   statt hinauszulaufen. Der Container muss mitgehen, sonst bleibt er auf
   Framers fester Breite stehen. Betrifft 1.156 Badges auf 297 Seiten; das
   Hero-Badge heisst "Primary" und bleibt unberuehrt. */
@media (max-width:809px){
  div:has(> :is([data-framer-name="Secondary"],[data-framer-name="Green"],[data-framer-name="Badge"])){
    width:max-content!important;max-width:100%!important}
  :is([data-framer-name="Secondary"],[data-framer-name="Green"],[data-framer-name="Badge"]){
    width:max-content!important;max-width:100%!important}
}

/* --- Handy: keine Brueche mitten im Wort, keine Trennung im Fliesstext -----
   Nadines Screenshots vom 08.09.2026: "kundenindividuelle|n Preisen",
   "Freigabeprozesse|n", "Entwicklu|ng", "Bestellprozes|s" - Framer setzt auf
   ALLEN Textbausteinen word-break:break-word, das bricht mitten im Wort statt
   das Wort umzubrechen. Dazu setzt Framer auf einzelnen Abschnitten INLINE
   hyphens:auto, was sich in den Fliesstext vererbt ("verglei-chen",
   "son-dern", "ha-ben").
   Jetzt: Fliesstext ohne Trennung und ohne Wortbruch, nur Ueberschriften
   trennen weiter (mit der 14-Zeichen-Grenze von weiter oben, damit
   "Fehlentscheidungen:" umbrechen kann - das Wort ist 367px breit und passt
   in keine 343px-Zeile).
   Der Griff geht ueber data-framer-component-type="RichTextContainer" -
   Framer markiert damit JEDEN Textkasten, das ist stabiler als Klassen-Hashes.
   Die Ueberschriften-Zeile braucht !important, weil ein Attribut-Selektor
   (0,1,0) sonst den Element-Selektor h1 (0,0,1) schlaegt. */
@media (max-width:809px){
  [data-framer-component-type="RichTextContainer"],
  [data-framer-component-type="RichTextContainer"] *,
  .framer-text{word-break:normal!important}
  [data-framer-component-type="RichTextContainer"],
  [data-framer-component-type="RichTextContainer"] *{hyphens:manual;-webkit-hyphens:manual}
  h1,h2,h3,h4,:is(h1,h2,h3,h4) *{hyphens:auto!important;-webkit-hyphens:auto!important}
}

/* --- Zweispaltige Karten auf dem Telefon einspaltig ------------------------
   Framer stellt seine Karten-Raster im Handy-Breakpoint auf zwei Spalten.
   Auf 375px sind das Spalten von 132-172px, der Textkasten darin nur 122px -
   dort passt kein deutsches Substantiv mehr hinein. Betroffen allein auf der
   Startseite sieben Raster (Karten, Fallstudien-Vergleich, Kontaktformular).
   520px als Grenze, NICHT 809px: auf einem 700px-Tablet sind zwei Spalten mit
   je ~340px voellig in Ordnung, nur auf Telefonen nicht.
   grid-template-columns auf Nicht-Raster zu setzen ist wirkungslos, deshalb
   darf der Selektor breit sein - Flex-Layouts (Logo-Streifen, Navigation)
   bleiben unberuehrt. Gemessen: Kartentext von 122px auf 303px. */
@media (max-width:520px){
  [class*="framer-"]{grid-template-columns:1fr!important}
  /* Die zweite Zeile ist noetig: im Kontaktformular sitzen die Felder fest auf
     Spalte 1 und 2 und erzeugen sich ihre Spuren dadurch selbst. Ein
     grid-template-columns:1fr allein blieb dort wirkungslos - auch inline mit
     !important gesetzt kamen weiterhin "192px 192px" heraus. Erst das
     Aufloesen der Platzierung macht daraus eine Spalte (283px).
     Auf Nicht-Rastern ist grid-column wirkungslos, der Selektor darf also
     breit sein. */
  [class*="framer-"]>*{grid-column:auto!important}
}

/* --- Die zwei schmalen Knoepfe auf der Startseite --------------------------
   "Alle Marketing-Leistungen" stand in einem 134px-Knopf auf drei Zeilen
   (108px hoch), daneben blieb der Platz leer. Nicht der Knopf ist schuld,
   sondern sein Behaelter .framer-1swyepl - der war auf 152px festgenagelt.
   Der Knopf hat width:100% und folgt dem Behaelter von selbst.

   NICHT den Knopf selbst auf max-content setzen (Fehler vom 08.09.2026, war
   kurz live): Framer gibt der Beschriftung width:1px zusammen mit flex:1 0 0,
   sie waechst also normalerweise auf die Knopfbreite. Bei max-content zaehlt
   aber genau dieses 1px als Inhalt - Ergebnis: 1px Text + 17px Pfeil = 50px
   breiter Knopf, in dem "Zur Shopware Migration" mit EINEM Buchstaben pro
   Zeile stand. Die Klasse framer-lux5qc tragen ausserdem ALLE Knoepfe dieser
   Bauart, nicht nur die zwei schmalen.
   ACHTUNG: Klassen-Hash. Wird die Vorlage neu von Framer geholt, kann er sich
   aendern - dann hier nachziehen. */
@media (max-width:809px){
  /* Behaelter UND Knopf: der Behaelter stand auf width:min-content (152px),
     der Knopf darin hat seine eigene feste Breite (134px) - beide muessen. */
  .framer-1swyepl{width:100%!important}
  .framer-1swyepl>a{width:100%!important}
}

/* --- Blogliste auf dem Handy ----------------------------------------------
   Nadines Screenshot vom 08.09.2026: die Kategorie "Technologien &
   Plattformen" stand in einem 66px-Kasten auf drei Zeilen, die Lesezeit
   "4 Min." in 28px auf zwei. Beides sind wieder Framers feste Breiten.
   Container UND Badge muessen mit - das Badge traegt eine eigene feste Breite,
   ein max-content nur am Container liess "KI & Trends" weiter umbrechen.
   Ergebnis: alle Kategorien einzeilig (26px hoch, 90-217px breit).
   "Lesezeit + Autor" ist ein Framer-Komponentenname und steckt in 256 Seiten;
   framer-1iqst47-container ist ein Klassen-Hash der beiden Blog-Uebersichten
   (14 Vorkommen) - bei einem Neu-Holen der Vorlage hier nachziehen. */
@media (max-width:809px){
  [data-framer-name="Lesezeit + Autor"]>*{min-width:max-content!important}
  .framer-1iqst47-container,.framer-1iqst47-container>*{width:max-content!important;max-width:100%!important}
}

/* --- Startseite: Listen schlanker (Nadine, 08.09.2026) ---------------------
   Nach der Umstellung auf eine Spalte standen die Bloecke sehr hoch:
   im dunklen Abschnitt Zahl und Ueberschrift untereinander, in den weissen
   Karten der Zahlenkreis mittig ueber dem Text. Nadine: "hier zahl und
   ueberschrift in eine zeile" und "vllt koennen wir das schlanker gestalten".

   Dazu die Trennlinie: jeder Eintrag der dunklen Liste hat ein ::after ueber
   die volle Flaeche mit border-right - im zweispaltigen Entwurf die Linie
   ZWISCHEN den Spalten. Einspaltig zog sie einen senkrechten Strich am rechten
   Rand (Nadines rotes X). Nur der Rahmen faellt weg, das ::after bleibt.

   Messwerte: dunkler Eintrag 61 -> 31px; weisse Karte 167 -> 116px,
   der ganze Kartenblock 728 -> 653px. Die Zeilenhoehen des Rasters standen
   fest ("95px 167px 167px 167px") und mussten mit auf auto. */
@media (max-width:520px){
  /* WICHTIG - ueber die STRUKTUR zielen, nicht ueber Klassennamen: Framer gibt
     jeder Karte und jedem Listeneintrag eine eigene Klasse. Ein Griff auf
     .framer-1xfy2ry bzw. .framer-xwfuxd erwischte nur den ERSTEN Eintrag,
     die uebrigen blieben untereinander stehen (Nadines Screenshot 4:25). */

  /* Dunkle Liste: erstes Kind jedes Eintrags ist der Block aus Zahl und
     Ueberschrift - in eine Zeile. Zweites Kind ist der Fliesstext. */
  .framer-nyjxkg>*>*:first-child{flex-direction:row!important;align-items:baseline!important;gap:12px!important}
  /* Der Titel hat eine feste Breite von 303px und wuerde die Zeile sprengen -
     im Titelblock darf alles schrumpfen, nur der Zahlenkasten nicht. */
  .framer-nyjxkg>*>*:first-child *{min-width:0!important;flex-shrink:1!important}
  .framer-nyjxkg>*>*:first-child>*:first-child{flex:0 0 auto!important}
  .framer-nyjxkg>*::after{border-right:0!important;border-left:0!important}

  /* Weisse Karten: Karte > Huelle > Block aus Zahlenkreis und Text. */
  .framer-mbmagp{grid-template-rows:auto!important;grid-auto-rows:auto!important}
  .framer-mbmagp>*{height:auto!important;padding:16px!important}
  .framer-mbmagp>*>*>*{flex-direction:row!important;align-items:flex-start!important;gap:14px!important}
  .framer-mbmagp>*>*>*>*{min-width:0!important}
  .framer-mbmagp>*>*>*>*:first-child{flex:0 0 auto!important}
  /* Der Text neben dem Zahlenkreis muss schrumpfen duerfen, sonst braucht die
     Zeile 369px bei 311px Platz. */
  .framer-mbmagp>*>*>*>*:last-child{flex:1 1 auto!important}
}

/* --- Handy: Texte, die Framer nicht umbrechen laesst -----------------------
   Framer legt um jeden Textbaustein einen Wrapper mit white-space:pre und
   flex:none. Auf dem Desktop passt der Text hinein, unter 810px ragt er aus
   seinem Kasten. Gemessen am 08.09.2026 bei 375px Breite:
     - Hero-Badge "Shopware und E-Commerce seit 1999 …": 440px breit in einem
       343px-Kasten, links und rechts abgeschnitten (298 Seiten)
     - Copyright-Zeile: 423px breit, schob Impressum/Datenschutz auf x=381 und
       damit komplett aus dem Bild (299 Seiten)
     - Impressum: "Headquarter Nie", "Standort Deutsc", "hallo@commerce-pa"
   pre-wrap behaelt Framers gewollte Zeilenumbrueche und erlaubt zusaetzlich den
   Umbruch am Rand. Nur 32 Klassen im Projekt tragen dieses Muster, und alle
   umschliessen direkt einen .framer-text - deshalb der :has()-Griff statt 32
   fest verdrahteter Klassen-Hashes.
   ACHTUNG: Im Framer-Original steht das genauso kaputt (Regeln zeichengleich
   verglichen). Das hier ist eine bewusste Abweichung vom 1:1-Nachbau, von
   Nadine am 08.09.2026 freigegeben. */
@media (max-width:809px){
  [class*="framer-"]:has(> .framer-text){white-space:pre-wrap;max-width:100%}
  .framer-text{overflow-wrap:break-word}
  /* Reihen, die nicht mehr in eine Zeile passen, duerfen umbrechen:
     .framer-86nxku = Fusszeile (Copyright + Rechtslinks, alle 299 Seiten),
     .framer-naw3ph = Adressspalten im Impressum,
     .framer-q8vl4n = Zeile "Durchgaengige Verantwortung".
     !important, weil Framer seine Regeln mit einer zweiten Klasse scoped
     (.framer-uD5fO .framer-86nxku) und uns sonst bei der Spezifitaet schlaegt. */
  .framer-86nxku,.framer-naw3ph,.framer-q8vl4n{flex-wrap:wrap!important;row-gap:12px}
}

/* --- Hero auf dem Handy ----------------------------------------------------
   Der Hero ist 100vh hoch UND traegt overflow:hidden. Sein Inhalt (Hinweis,
   Ueberschrift, Absatz, Knopf, drei Kennzahlen) ist auf 375px aber rund
   1160px hoch. Weil der Inhalt senkrecht zentriert wird, ragte er oben UND
   unten je ~180px heraus und wurde abgeschnitten: der Hinweis "Shopware und
   E-Commerce seit 1999 …" stand bei y=-6, also hinter dem Logo, die
   Kennzahlen unten waren angeschnitten. (Gemessen am 08.09.2026.)

   Warum height:auto allein nicht reicht: die beiden Kaesten im Hero haben
   flex:1 0 0px. Eine Flex-Basis von 0 laesst die Auto-Hoehe des Hero auf 0
   zusammenfallen, dann gewinnt min-height und der Inhalt quillt wieder heraus.
   Deshalb bekommen sie flex-basis:auto - erst damit reicht der Hero die
   Inhaltshoehe nach oben durch. Ergebnis: Hero waechst von 812 auf 1159px,
   nichts wird mehr geklemmt, der Hinweis sitzt bei y=176.
   NICHT breiter fassen: mit einem Griff ueber zwei Ebenen ohne Klassenfilter
   traf die Regel auch die
   Hintergrundebene, der Hero wurde 6332px hoch. */
@media (max-width:809px){
  #main header[data-framer-name="Hero"]{height:auto!important;min-height:100svh}
  #main header[data-framer-name="Hero"]>[class*="framer-"]{flex-basis:auto!important;height:auto!important}
  #main header[data-framer-name="Hero"]>[class*="framer-"]>[class*="framer-"]{flex-basis:auto!important;height:auto!important}
  /* Luft oben, damit der Hinweis die durchsichtige Kopfzeile (73px) freilaesst. */
  #main header[data-framer-name="Hero"] [data-framer-name="Title"]{padding-top:120px}
}

/* --- Zeilen aus Symbol und Text --------------------------------------------
   Framer baut Aufzaehlungen als Flex-Zeile: SVG-Symbol (25px) + Textkasten,
   beide mit flex:none. Auf dem Handy braucht die Zeile 254px, hat aber nur
   243px - die letzten Zeichen wurden abgeschnitten ("Welche Daten muessen mit
   (Produkte,"). Auf /shopware-migration allein 10 solcher Stellen.
   min-width:0 allein hilft nicht, weil flex:none das Schrumpfen verbietet;
   noetig ist flex-shrink. Bewusst NICHT global auf jedes letzte Kind: die
   Slideshow lebt von einer absichtlich ueberbreiten Spur, die dann in sich
   zusammenfiele. Der Griff ueber :has(> svg) trifft genau das Symbol-Text-
   Muster (25 Elemente auf /shopware-migration). Schrumpfen aendert nur etwas,
   wenn die Zeile ohnehin ueberlaeuft - sonst ist die Regel wirkungslos. */
@media (max-width:809px){
  [class*="framer-"]:has(> svg)>[class*="framer-"]:last-child{flex-shrink:1!important;min-width:0}
}

/* --- Ein Raster fuer Kopfzeile, Inhalt und Fusszeile -----------------------
   Ab 1920px verbreitert Framer NUR den Seiteninhalt: 1200 -> 1400, ab 2560 ->
   1550. Navigation und Fusszeile sind eigene Bausteine mit eigenen
   Haltepunkten und bleiben bei 1200 stehen - der Inhalt ragt dadurch links und
   rechts rund 100px ueber das Logo hinaus ("laeuft aus dem Rahmen"). Die
   Fusszeile traegt ihr Seitenpolster ausserdem INNERHALB ihrer 1200er Grenze;
   ihre Spalten sitzen deshalb auf jeder Breite 30px weiter innen als der Rest.
   Beide bekommen hier dieselben Stufen wie der Inhalt, die Fusszeile zusaetzlich
   das Polster obendrauf (1200 + 2x30 = 1260). Damit stehen Logo oben, Inhalt
   und Logo unten auf einer Linie - auf jeder Breite.
   margin-inline haelt die Kaesten auch dann mittig, wenn place-content im
   Browser nicht greift; die Handy-Fassungen der Navigation heben ihre Grenze
   mit hoeherer Gewichtung selbst wieder auf und bleiben unberuehrt. */
.framer-nI3Xr .framer-1jq2l5y,
.framer-nI3Xr .framer-1b9undg,
.framer-Os7il .framer-1uuwtbo{margin-left:auto;margin-right:auto}
.framer-Os7il .framer-1uuwtbo{max-width:1260px}
@media (min-width:1920px){
  .framer-nI3Xr .framer-1jq2l5y,
  .framer-nI3Xr .framer-1b9undg{max-width:1400px}
  .framer-Os7il .framer-1uuwtbo{max-width:1460px}
}
@media (min-width:2560px){
  .framer-nI3Xr .framer-1jq2l5y,
  .framer-nI3Xr .framer-1b9undg{max-width:1550px}
  .framer-Os7il .framer-1uuwtbo{max-width:1610px}
}
/* Unter 1260px traegt keine Breitengrenze mehr, dort macht allein das Polster
   den Einzug - und da hat Framer drei verschiedene Werte: Navigation 30px,
   Fusszeile 30px, ihre Tablet-Fassung aber 24px, das Handy 20px. Die
   Tablet-Fassung greift schon ab 1200px und zieht die Fusszeile dort 6px nach
   links. Beide Fassungen bekommen deshalb denselben Wert wie die Navigation.
   Die Variantenklasse muss mitgenannt werden, sonst gewinnt Framers Regel. */
.framer-Os7il .framer-1uuwtbo,
.framer-Os7il.framer-v-ialcm4 .framer-1uuwtbo{padding-left:30px;padding-right:30px}
@media (max-width:809px){
  .framer-Os7il .framer-1uuwtbo,
  .framer-Os7il.framer-v-ialcm4 .framer-1uuwtbo{padding-left:20px;padding-right:20px}
}

/* ===========================================================================
   Designpruefung Gruppe B - Lesbarkeit (10.09.2026)

   Diese drei Regeln weichen bewusst vom Framer-Original ab. Sie beheben
   Befunde, die im Entwurf angelegt sind und sich nicht durch genaueres
   Nachbauen loesen lassen.
   =========================================================================== */

/* B1 - Zeilenlaenge.
   Drei Absaetze liefen ueber die volle Inhaltsbreite von 1200px bei 20px
   Schrift, also rund 120 Zeichen je Zeile; beim Zeilenwechsel findet das Auge
   den Anfang der naechsten Zeile dann nicht mehr zuverlaessig. 35em ergeben
   bei 20px genau 700px und damit etwa 70 Zeichen.

   Die Grenze steht auf dem ABSATZ, nicht auf dem RichTextContainer: dessen
   Schriftgroesse ist immer 12px, eine em- oder ch-Angabe dort rechnet also mit
   der falschen Basis (66ch ergaben 454px statt 900). Ausserdem sitzen die
   Container haeufig in zentrierenden Flex-Eltern - ein schmalerer Container
   rutscht dort zur Mitte und reisst linksbuendigen Text mit. Der Absatz als
   Blockelement bleibt dagegen an seiner Kante stehen.

   Zentrierte Absaetze muessen mittig bleiben. Framer schreibt ihre Ausrichtung
   als Inline-Stil --framer-text-alignment:center, deshalb sind sie ohne
   Klassen-Hashes greifbar. (Nadines Regel von den Abschnitts-Badges gilt
   genauso: mittig bleibt mittig, links bleibt links.) */
[data-framer-component-type="RichTextContainer"] > p{max-width:35em}
[data-framer-component-type="RichTextContainer"] > p[style*="alignment:center"]{margin-inline:auto}

/* B2 - "Vier Gruende, warum Warten teuer wird" stand in vier Spalten a 300px.
   Bei 20px Schrift sind das rund 26 Zeichen je Zeile, und der Browser trennte
   fast jede zweite ("Wettbewer-ber", "des-to", "Fahr-plan"). Zwei mal zwei
   verdoppelt die Spaltenbreite auf 580px. Erst ab 810px, damit die einspaltige
   Handy-Fassung unberuehrt bleibt. */
@media (min-width:810px){
  .framer-nyjxkg{grid-template-columns:1fr 1fr!important;gap:46px 40px!important}
}

/* B3 - Die Leistungskarten hingen an einer im Entwurf gemessenen Reihenhoehe
   von 500px, waehrend ihr Text nur rund 300px braucht; zwischen Textende und
   Knopf klaffte bis zu 195px Leere. Die feste Hoehe steht auf der REIHE
   (.framer-1wddk83), nicht auf den Karten - die tragen height:min-content und
   wurden nur mitgezogen. Mit auto folgt die Reihe ihrem Inhalt, mit stretch
   bleiben die vier Karten untereinander gleich hoch.
   Die Karten selbst heissen alle "Card/Service", haben aber vier verschiedene
   Klassen-Hashes - deshalb ueber den Namen statt ueber die Hashes. */
.framer-1wddk83{height:auto!important;align-items:stretch!important}
[data-framer-name="Card/Service"]{height:auto!important}

