/* Source Sans 3 — selbst gehostet, CI/CD V3.0 §6.1.3 bis §6.1.5.
   Variable Font: eine Datei je Zeichensatz deckt 300 bis 700 ab.
   Nur latin und latin-ext; Kyrillisch und Griechisch braucht diese
   Website nicht und würde die Ladezeit unnötig belasten. */
@font-face {
  font-family: "Source Sans 3";
  font-style: italic;
  font-weight: 400;
  font-display: swap;
  src: url("fonts/source-sans-3-italic-latin.woff2") format("woff2");
  unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+0304, U+0308, U+0329, U+2000-206F, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD;
}
@font-face {
  font-family: "Source Sans 3";
  font-style: italic;
  font-weight: 400;
  font-display: swap;
  src: url("fonts/source-sans-3-italic-latin-ext.woff2") format("woff2");
  unicode-range: U+0100-02BA, U+02BD-02C5, U+02C7-02CC, U+02CE-02D7, U+02DD-02FF, U+0304, U+0308, U+0329, U+1D00-1DBF, U+1E00-1E9F, U+1EF2-1EFF, U+2020, U+20A0-20AB, U+20AD-20C0, U+2113, U+2C60-2C7F, U+A720-A7FF;
}
@font-face {
  font-family: "Source Sans 3";
  font-style: normal;
  font-weight: 300 700;
  font-display: swap;
  src: url("fonts/source-sans-3-normal-latin.woff2") format("woff2");
  unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+0304, U+0308, U+0329, U+2000-206F, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD;
}
@font-face {
  font-family: "Source Sans 3";
  font-style: normal;
  font-weight: 300 700;
  font-display: swap;
  src: url("fonts/source-sans-3-normal-latin-ext.woff2") format("woff2");
  unicode-range: U+0100-02BA, U+02BD-02C5, U+02C7-02CC, U+02CE-02D7, U+02DD-02FF, U+0304, U+0308, U+0329, U+1D00-1DBF, U+1E00-1E9F, U+1EF2-1EFF, U+2020, U+20A0-20AB, U+20AD-20C0, U+2113, U+2C60-2C7F, U+A720-A7FF;
}
/* ===========================================================================
   Oekoboiler — Design-Tokens
   Quelle: Corporate Design Manual V3.0, Juli 2026 (verbindlich)
   Kapitel 5.5 Token-Ramps · 5.6 Semantische UI-Tokens · 7.1–7.3 Spacing,
   Radius, Elevation · 6.1.3 Typografie Web

   Diese Datei definiert ausschliesslich Werte. Die Anwendung auf das Theme
   läuft bewusst über die Shoptimizer-Einstellungen und die Elementor-Globals,
   nicht über CSS-Überschreibungen — sonst entsteht ein Spezifitätskampf gegen
   das eigene Theme.
   =========================================================================== */

:root {
  /* --- Petrol · Marken-Anker ---------------------------------------------- */
  --ob-petrol-50:  #EDF1F2;
  --ob-petrol-100: #D3DCDF;
  --ob-petrol-200: #A9BBC0;
  --ob-petrol-300: #7F9AA1;
  --ob-petrol-400: #557983;
  --ob-petrol-500: #355860;   /* Primärfarbe */
  --ob-petrol-600: #2D4B53;   /* Hover */
  --ob-petrol-700: #243F45;   /* Active */
  --ob-petrol-800: #1B3038;
  --ob-petrol-900: #122026;

  /* --- Neutral ------------------------------------------------------------ */
  --ob-neutral-50:  #FAFBFC;
  --ob-neutral-100: #F0F2F4;
  --ob-neutral-200: #E1E4E7;
  --ob-neutral-300: #C5CACF;
  --ob-neutral-400: #A0A6AC;
  --ob-neutral-500: #76878F;   /* Anthrazit */
  --ob-neutral-600: #5C6B72;
  --ob-neutral-700: #475459;
  --ob-neutral-800: #2F353A;
  --ob-neutral-900: #1A1F21;   /* Tiefschwarz */

  /* --- Kupfer · 25 % Strom, Wärme, Premium -------------------------------- */
  --ob-kupfer-50:  #FBEFE6;
  --ob-kupfer-100: #F5D7BD;
  --ob-kupfer-200: #EDB78D;
  --ob-kupfer-300: #E29765;
  --ob-kupfer-400: #D67D43;
  --ob-kupfer-500: #C8682E;   /* Akzent */
  --ob-kupfer-600: #A85525;
  --ob-kupfer-700: #85431D;
  --ob-kupfer-800: #5F3015;
  --ob-kupfer-900: #3A1E0D;

  /* --- Moos · Sparen, Effizienz, Natur ------------------------------------ */
  --ob-moos-50:  #EEF2EA;
  --ob-moos-100: #D4DFCB;
  --ob-moos-200: #B5C7A6;
  --ob-moos-300: #94AC82;
  --ob-moos-400: #759363;
  --ob-moos-500: #5C7A4F;
  --ob-moos-600: #4A6340;
  --ob-moos-700: #3A4E33;
  --ob-moos-800: #283823;
  --ob-moos-900: #172115;

  /* --- Nebelblau · 75 % Luft. Nur grafisch, nie als Text auf Weiss:
         Kontrast 3.2:1 laut CI §5.8. ------------------------------------- */
  --ob-nebel-50:  #EFF3F6;
  --ob-nebel-100: #D8E2E8;
  --ob-nebel-200: #B9C9D3;
  --ob-nebel-300: #9AB1BD;
  --ob-nebel-400: #7FA0B3;   /* Akzent */
  --ob-nebel-500: #6B8DA1;
  --ob-nebel-600: #577485;
  --ob-nebel-700: #445B68;
  --ob-nebel-800: #30404A;
  --ob-nebel-900: #1D262C;

  /* --- Error -------------------------------------------------------------- */
  --ob-error-50:  #F9E8E8;
  --ob-error-100: #EFC3C3;
  --ob-error-200: #E29797;
  --ob-error-300: #D26B6B;
  --ob-error-400: #C25555;
  --ob-error-500: #B14444;
  --ob-error-600: #923636;
  --ob-error-700: #702929;
  --ob-error-800: #4F1C1C;
  --ob-error-900: #2F1010;

  /* === Semantische Tokens · CI §5.6 ======================================= */
  --ob-surface-page:     var(--ob-neutral-50);
  --ob-surface-card:     #FFFFFF;
  --ob-surface-elevated: #FFFFFF;
  --ob-surface-subtle:   var(--ob-neutral-100);
  --ob-surface-disabled: var(--ob-neutral-200);

  --ob-text-primary:   var(--ob-neutral-900);
  --ob-text-secondary: var(--ob-neutral-700);
  --ob-text-tertiary:  var(--ob-neutral-500);
  --ob-text-disabled:  var(--ob-neutral-300);
  --ob-text-inverse:   #FFFFFF;
  --ob-text-brand:     var(--ob-petrol-500);
  --ob-text-link:      var(--ob-petrol-500);
  --ob-text-link-hover: var(--ob-petrol-600);

  --ob-border-subtle:  var(--ob-neutral-100);
  --ob-border-default: var(--ob-neutral-300);
  --ob-border-strong:  var(--ob-neutral-500);
  --ob-border-focus:   var(--ob-petrol-500);
  --ob-border-error:   var(--ob-error-500);

  --ob-action-primary:        var(--ob-petrol-500);
  --ob-action-primary-hover:  var(--ob-petrol-600);
  --ob-action-primary-active: var(--ob-petrol-700);
  --ob-action-destructive:    var(--ob-error-500);

  --ob-state-success-bg:   rgba(92, 122, 79, .12);
  --ob-state-warning-bg:   rgba(200, 104, 46, .12);
  --ob-state-error-bg:     rgba(177, 68, 68, .12);
  --ob-state-info-bg:      rgba(127, 160, 179, .15);
  --ob-state-success-text: var(--ob-moos-700);
  --ob-state-warning-text: var(--ob-kupfer-700);
  --ob-state-error-text:   var(--ob-error-600);
  --ob-state-info-text:    var(--ob-nebel-700);

  /* === Spacing · CI §7.1 · alles Vielfache von 4 px ====================== */
  --ob-space-xs:  4px;
  --ob-space-sm:  8px;
  --ob-space-md:  16px;
  --ob-space-lg:  24px;
  --ob-space-xl:  32px;
  --ob-space-2xl: 48px;
  --ob-space-3xl: 64px;

  /* === Radius · CI §7.2 · kantig ist der Standard ========================= */
  --ob-radius-none: 0;
  --ob-radius-sm:   4px;
  --ob-radius-md:   8px;
  --ob-radius-lg:   12px;
  --ob-radius-full: 9999px;

  /* === Elevation · CI §7.3 ================================================ */
  --ob-shadow-sm: 0 1px 2px rgba(26, 31, 33, .05);
  --ob-shadow-md: 0 4px 8px rgba(26, 31, 33, .08);
  --ob-shadow-lg: 0 12px 24px rgba(26, 31, 33, .12);

  /* === Typografie · CI §6.1.3 und §6.1.4 ================================== */
  --ob-font-sans: "Source Sans 3", -apple-system, BlinkMacSystemFont,
                  "Segoe UI", Arial, sans-serif;
  --ob-weight-light:    300;
  --ob-weight-regular:  400;
  --ob-weight-semibold: 600;
  --ob-weight-bold:     700;
}
/* ===========================================================================
   Oekoboiler — Anwendungsebene
   Bewusst schlank gehalten. Farben und Schriften kommen aus den
   Shoptimizer-Einstellungen und den Elementor-Globals; hier steht nur, was
   sich dort nicht ausdrücken lässt.
   =========================================================================== */

/* --- Tastaturbedienung ------------------------------------------------------
   Das CI schreibt in §5.6 einen 3-px-Fokusring in Petrol vor. Shoptimizer
   setzt an mehreren Stellen 'outline: none' — das macht die Seite für
   Tastaturnutzer unbedienbar und verstösst gegen WCAG 2.4.7.
   :focus-visible trifft nur echte Tastaturnavigation, Mausklicks bleiben
   unverändert. */
a:focus-visible,
button:focus-visible,
input:focus-visible,
select:focus-visible,
textarea:focus-visible,
[tabindex]:focus-visible,
.button:focus-visible {
  outline: 3px solid var(--ob-border-focus);
  outline-offset: 2px;
  border-radius: var(--ob-radius-sm);
}

::selection {
  background: var(--ob-petrol-100);
  color: var(--ob-text-primary);
}

/* --- Kupferlinie -------------------------------------------------------------
   Aus der Textmappe, Blatt «Was muss erstellt werden»: «kurze kupferfarbene
   Linie unter wichtigen Titeln oder Einleitungen». Als Hilfsklasse, damit sie
   im Baukasten über das Feld «CSS-Klassen» gesetzt werden kann. */
/* Elementor legt den Aussenabstand eines Widgets auf den inneren Container,
   nicht auf den Widget-Rahmen. Die Linie haengt als ::after am Rahmen und
   liegt damit UNTERHALB dieses Abstands. Ohne Gegenregel steht der ganze
   Abstand deshalb ueber der Linie: am 2026-08-26 auf allen Seiten gemessen
   22 px darueber, 0 px darunter — die Linie klebte am Folgeinhalt. Wir nehmen
   den Abstand aus dem Container heraus und setzen ihn beidseitig der Linie.
   Nebeneffekt, der erwuenscht ist: alle Titel mit Kupferlinie haben nun
   denselben Rhythmus, unabhaengig davon, welcher Erzeuger sie gebaut hat. */
.ob-rule > .elementor-widget-container {
  margin-bottom: 0;
}

.ob-rule::after {
  content: "";
  display: block;
  width: 56px;
  height: 2px;
  margin-top: var(--ob-space-md);
  margin-bottom: var(--ob-space-xl);
  background: var(--ob-kupfer-500);
}

.ob-rule--center::after {
  margin-left: auto;
  margin-right: auto;
}

/* --- Bereichstitel -----------------------------------------------------------
   Ebenfalls aus der Textmappe: «Bereichstitel wie Produkte, Lösungen oder
   Fördergelder in Petrol», «grosse Überschriften immer schwarz». */
.ob-eyebrow {
  display: block;
  font-size: .75rem;
  font-weight: var(--ob-weight-semibold);
  letter-spacing: .12em;
  text-transform: uppercase;
  color: var(--ob-text-brand);
  margin-bottom: var(--ob-space-sm);
}

/* --- Sekundärer Button -------------------------------------------------------
   Textmappe: «Verlinkungen ausserhalb von Produktkarten als umrandete Buttons
   mit kupferfarbener Schrift».

   Die Schrift steht auf kupfer.600 (#A85525), nicht auf kupfer.500. Nachgerechnet
   am 2026-08-26: kupfer.500 erreicht auf Weiss nur 3.84:1 und wäre damit für
   Text dieser Grösse unter der AA-Schwelle. kupfer.600 liegt bei 5.26:1.
   Der Rahmen darf kupfer.500 bleiben — für grafische Elemente genügen 3:1.

   Hinweis: Das CI-Manual nennt in §5.8 für Kupfer 4.6:1. Dieser Wert ist zu
   hoch angesetzt; nachgemessen sind es 3.84:1. */
.ob-button-outline {
  display: inline-block;
  padding: var(--ob-space-sm) var(--ob-space-lg);
  border: 1px solid var(--ob-kupfer-500);
  border-radius: var(--ob-radius-sm);
  background: transparent;
  color: var(--ob-kupfer-600);
  font-size: 1.0625rem;
  font-weight: var(--ob-weight-semibold);
  line-height: 1.4;
  text-decoration: none;
  transition: background-color .15s ease, color .15s ease;
}

.ob-button-outline:hover,
.ob-button-outline:focus-visible {
  background: var(--ob-kupfer-50);
  color: var(--ob-kupfer-700);
}

/* --- Bewegung reduzieren ---------------------------------------------------- */
@media (prefers-reduced-motion: reduce) {
  *,
  *::before,
  *::after {
    animation-duration: .01ms !important;
    animation-iteration-count: 1 !important;
    transition-duration: .01ms !important;
    scroll-behavior: auto !important;
  }
}

/* --- Fusszeile ---------------------------------------------------------------
   Die Fusszeile steht auf Petrol. Die globalen Tokens sind fuer hellen Grund
   gedacht — text.link ist Petrol und damit auf Petrol unsichtbar. Genau das
   ist beim ersten Aufbau passiert: E-Mail, Telefon und die Rechtslinks waren
   da, aber nicht zu sehen. Deshalb hier eigene Werte fuer dunklen Grund. */
.elementor-location-footer a {
  color: var(--ob-petrol-100);
  text-decoration: none;
  transition: color .15s ease;
}

.elementor-location-footer a:hover,
.elementor-location-footer a:focus-visible {
  color: #FFFFFF;
  text-decoration: underline;
  text-underline-offset: 3px;
}

/* Der Fokusring muss auf dunklem Grund ebenfalls sichtbar bleiben — Petrol
   auf Petrol waere unbrauchbar. */
.elementor-location-footer a:focus-visible {
  outline-color: var(--ob-petrol-100);
}

/* ===========================================================================
   Kopfbereich — NUR oberhalb von Shoptimizers Umschaltpunkt (992 px).

   Unterhalb davon ist .primary-navigation nicht die waagerechte Leiste,
   sondern die ausfahrende Klappe des Mobilmenues. Sie parkt bei
   left: -300px und faehrt beim Antippen herein. Eine ungeschuetzte Regel
   left: 0 / right: 0 nagelt sie fest und zerlegt das Menue — genau das ist
   am 2026-08-26 passiert.
   =========================================================================== */
@media (min-width: 993px) {
  /* --- Kopfbereich -------------------------------------------------------------
     Shoptimizers header-4 legt drei Kinder nebeneinander: das Logo, den
     Navigationscontainer und ein Mobil-Overlay. Der Navigationscontainer bekommt
     dabei keine Breite zugewiesen — gemessen am 2026-08-26 waren es 165 px fuer
     eine 999 px breite Menueleiste. Die Liste laeuft nach links ueber und landet
     auf dem Logo. Der Fehler bestand schon vor unserem Eingriff, faellt mit der
     neuen Navigation aber sofort auf.

     Wir geben der Zeile eine tragfaehige Aufteilung: Logo behaelt seine Groesse,
     die Navigation nimmt den Rest und richtet sich rechts aus. */
  .header-4-inner {
    align-items: center;
    gap: var(--ob-space-lg);
  }

  .header-4-inner > .site-header {
    flex: 0 0 auto;
  }

  .header-4-inner > .col-full-nav {
    flex: 1 1 auto;
    min-width: 0;              /* sonst kann der Flex-Bereich nicht schrumpfen */
    display: flex;
    justify-content: flex-end;
  }

  .col-full-nav .main-navigation {
    width: 100%;
  }

  /* Nur die oberste Ebene wird zur Reihe. Die Untermenues muessen Bloecke
     bleiben, sonst klappen sie waagerecht auf.
     Die Kette lautet .main-navigation > .primary-navigation >
     .menu-primary-menu-container > ul.menu — eine Ebene tiefer als vermutet. */
  .col-full-nav .primary-navigation,
  .col-full-nav .menu-primary-menu-container {
    width: 100%;
  }

  .col-full-nav .menu-primary-menu-container > ul.menu {
    display: flex;
    flex-wrap: nowrap;
    justify-content: flex-end;
    align-items: center;
    width: auto;
    position: static;
    margin: 0;
    padding: 0;
  }

  /* Logo auf eine vernuenftige Breite begrenzen. Die Datei ist 1670 x 157 und
     damit sehr breitlaufend; ohne Deckel belegt sie 319 px. */
  .site-branding .custom-logo-link img,
  .header-4 .site-header .custom-logo-link img {
    height: 26px;
    width: auto;
    max-width: 240px;
  }

  /* Etwas kleinere Navigationsschrift. Bei zehn Punkten mit Bezeichnungen wie
     «Kompetenzzentrum» ist 16 px zu gross fuer eine einzeilige Leiste. */
  /* Shoptimizer schaltet erst bei 992 px auf das Kompaktmenue um. Zwischen
     993 px und rund 1400 px ist die Leiste mit acht Punkten zu breit fuer den
     Platz zwischen Logo und Warenkorb — gemessen bei 1265 px Fensterbreite:
     889 px noetig, 722 px vorhanden.

     Statt Punkte zu streichen skaliert die Schrift mit der Fensterbreite. Elias'
     Entwurf arbeitet mit 12.5 px; das ist die untere Grenze, nach oben laufen
     wir auf 15 px. Die Abstaende setzen wir selbst, damit sie nicht zusaetzlich
     mitwachsen. */
  .col-full-nav .menu-primary-menu-container > ul.menu > li > a {
    /* Werte aus Elias' Entwurf, nachgemessen am 2026-08-26 auf
       demo-installation-2026: 12.5 px, Schnitt 500, Farbe Tiefschwarz.
       Nach oben lassen wir etwas Luft, damit die Leiste auf grossen Schirmen
       nicht verloren wirkt — der Entwurf war auf rund 1085 px angelegt. */
    font-size: clamp(12.5px, 0.9vw, 14.5px);
    font-weight: 500;
    color: var(--ob-text-primary);
    padding-left: 0;
    padding-right: 0;
    /* Ohne das brechen die Beschriftungen selbst um — «Wissen &» / «News»
       untereinander. Lieber eine Spur enger als zerrissene Menuepunkte. */
    white-space: nowrap;
  }

  .col-full-nav .menu-primary-menu-container > ul.menu {
    /* Entwurf: 18 px fix. Wir lassen es zwischen 10 und 20 atmen. */
    gap: clamp(10px, 1.4vw, 20px);
  }

  .col-full-nav .menu-primary-menu-container > ul.menu > li {
    margin: 0;
  }

  /* Der Navigationsbereich muss den Restplatz nehmen, nicht seine Inhaltsbreite.
     'flex: 1 1 auto' bemisst die Basis am Inhalt — die Leiste wurde damit 900 px
     breit und schob sich unter Suche und Warenkorb. '1 1 0%' setzt die Basis auf
     null, danach verteilt sich der tatsaechlich freie Platz. */
  .col-full-nav > .main-navigation {
    flex: 1 1 0%;
    min-width: 0;
  }

  /* Der Kern des Problems: .primary-navigation ist absolut positioniert und
     haengt damit an der klebenden Kopfleiste statt am Flex-Layout. Sie wurde
     dadurch so breit wie das ganze Fenster (1425 px gemessen) und lief unter
     Suche und Warenkorb hindurch.

     Wir geben ihr mit position:relative auf der Navigation einen eigenen
     Bezugsrahmen. left:0/right:0 spannt sie danach exakt ueber den Platz, den
     das Flex-Layout der Navigation zugeteilt hat. */
  .col-full-nav > .main-navigation {
    position: relative;
  }

  .col-full-nav .primary-navigation {
    left: 0;
    right: 0;
    width: auto;
  }

  .col-full-nav .menu-primary-menu-container,
  .col-full-nav .menu-primary-menu-container > ul.menu {
    width: 100%;
  }

  /* Aufklappmenues der rechten Punkte nach innen oeffnen. Ohne das ragen die
     Untermenues der letzten Eintraege ueber die Fensterkante hinaus und erzeugen
     waagerechtes Scrollen — gemessen am 2026-08-26: 175 px Ueberstand bei
     «Unternehmen», 57 px bei «Service & Support».

     Die Kette lautet li > div.sub-menu-wrapper > div.container > ul.sub-menu,
     und absolut positioniert wird die ul selbst. Wrapper und Container sind
     statisch — eine Regel auf den Wrapper greift ins Leere. */
  .col-full-nav .menu-primary-menu-container > ul.menu > li:nth-last-child(-n+2)
    > .sub-menu-wrapper > .container > ul.sub-menu {
    left: auto;
    right: 0;
  }

  /* Die Leiste braucht rechts denselben Rand wie das Logo links. */
  .col-full-nav .menu-primary-menu-container > ul.menu {
    padding-right: var(--ob-space-xs);
  }

  /* Zwischen Shoptimizers Umschaltpunkt (992 px) und rund 1250 px wird es eng:
     gemessen bei 1009 px braucht die Leiste 591 px.

     Ein Umbruch auf zwei Zeilen scheidet aus — die Navigation ist absolut
     positioniert, die Kopfleiste waechst also nicht mit und die zweite Zeile
     wird oben und unten abgeschnitten. Getestet und verworfen am 2026-08-26.

     Stattdessen holen wir den Platz dort, wo er entbehrlich ist: kleineres Logo
     und der Betrag neben dem Warenkorb entfaellt. Das Symbol mit dem Zaehler
     bleibt, die Information geht also nicht verloren. */
  @media (max-width: 1400px) {
    .site-branding .custom-logo-link img,
    .header-4 .site-header .custom-logo-link img {
      max-width: 140px;
    }

    .col-full-nav .site-header-cart .woocommerce-Price-amount,
    .col-full-nav .site-header-cart .amount,
    .col-full-nav .cart-contents .woocommerce-Price-amount {
      display: none;
    }
  }

  /* --- Kacheln -----------------------------------------------------------------
     Die Bilder der Uebersichtskacheln haben sehr unterschiedliche Seitenverhaeltnisse
     (1629x934 bis 2477x1558). Ohne feste Hoehe entsteht eine unruhige Treppe.
     190 px entspricht Elias' Entwurf. */
  .ob-kachelbild img {
    width: 100%;
    height: 190px;
    object-fit: cover;
    object-position: center center;
    display: block;
    border-radius: var(--ob-radius-none);
  }

  @media (max-width: 767px) {
    .ob-kachelbild img {
      height: 170px;
    }
  }

  /* Kachelspalten: der kupferne Verweis sitzt immer unten, unabhaengig davon,
     wie lang der Text darueber ist. Ohne das steht der Link bei kurzen Texten
     eine Zeile hoeher als bei den Nachbarn.

     Angesprochen ueber :has(), weil Elementor eigene CSS-Klassen nur auf
     Widgets ausgibt, nicht auf Spalten — nachgeprueft am 2026-08-26. Der Griff
     geht deshalb ueber das Kachelbild, das als Widget die Klasse traegt. */
  .elementor-widget-wrap:has(> .ob-kachelbild) {
    display: flex;
    flex-direction: column;
    flex-wrap: nowrap;
    align-content: flex-start;
    height: 100%;
  }

  .elementor-widget-wrap:has(> .ob-kachelbild) > .elementor-widget-button {
    margin-top: auto;
  }
}

/* --- Lange Woerter -----------------------------------------------------------
   Deutsche Komposita wie «Wärmepumpenboiler» oder «Energieeffizienzverordnung»
   sind laenger als eine schmale Spalte und brechen nicht von selbst um. Ohne
   diese Regel laufen sie rechts aus ihrem Kasten heraus — auf der Startseite
   waren es bei 375 px genau 6 px.

   overflow-wrap greift nur, wenn es wirklich nicht anders geht, und laesst
   normalen Zeilenumbruch unangetastet. */
h1, h2, h3, h4, h5, h6,
.elementor-heading-title {
  overflow-wrap: break-word;
}

/* --- Merkmalsleiste unter dem Hero -------------------------------------------
   Sechs Merkmale mit Phosphor-Icons im Schnitt Light. Duenne Trennlinien
   zwischen den Spalten wie im Entwurf. Angesprochen ueber :has(), weil
   Elementor eigene Klassen nur auf Widgets ausgibt, nicht auf Spalten. */
.elementor-column:has(.ob-badge) + .elementor-column:has(.ob-badge) {
  border-left: 1px solid var(--ob-neutral-200);
}

.ob-badge img {
  /* SVG traegt die Farbe bereits, hier nur die Groesse sichern */
  width: 32px;
  height: 32px;
  display: block;
  margin-inline: auto;
}

@media (max-width: 767px) {
  /* Auf schmalen Schirmen stehen zwei nebeneinander — die senkrechte Linie
     ergibt dann nur noch zwischen den Paaren Sinn. */
  .elementor-column:has(.ob-badge) + .elementor-column:has(.ob-badge) {
    border-left: none;
  }
}

/* --- Feste Elementbreiten deckeln ---------------------------------------------
   Elementor setzt bei einer eigenen Elementbreite nur 'width', kein
   'max-width'. Auf schmalen Schirmen laeuft das Element dann ueber den Rand —
   gemessen am 2026-08-26 lief der Hero-Kurztext mit 620 px aus einem 375 px
   breiten Fenster heraus.

   Statt an jedem Element eine Mobilvariante zu pflegen, deckeln wir alle
   gemeinsam. Die gesetzte Breite bleibt auf grossen Schirmen wirksam. */
.elementor-element.elementor-widget__width-initial,
.elementor-element.elementor-widget__width-inherit {
  max-width: 100%;
}

/* --- Bildplatzhalter ---------------------------------------------------------
   Steht dort, wo die Textmappe ein Bild vorsieht, das noch fehlt. Zeigt die
   Vorgabe im Klartext, damit beim Durchsehen sofort erkennbar ist, welches
   Motiv gebraucht wird. Vor dem Livegang muss keiner mehr uebrig sein. */
.ob-bildplatz {
  border: 1px dashed var(--ob-neutral-300);
  border-radius: var(--ob-radius-sm);
  background: var(--ob-neutral-50);
  padding: var(--ob-space-lg);
  max-width: 760px;
}

.ob-bildplatz p {
  margin: 0;
}

.ob-bildplatz strong {
  display: block;
  margin-bottom: var(--ob-space-xs);
  color: var(--ob-kupfer-600);
  font-size: .72rem;
  font-weight: var(--ob-weight-semibold);
  letter-spacing: .1em;
  text-transform: uppercase;
}

/* Bildplatzhalter im Kopfbereich: fuellt den Platz, den spaeter das Bild
   einnimmt. Masse aus dem Entwurf demo-installation-2026 (570 x 420). */
.ob-bildplatz--hero {
  min-height: 380px;
  max-width: none;
  display: flex;
  flex-direction: column;
  justify-content: center;
  background: var(--ob-neutral-100);
}

@media (max-width: 767px) {
  .ob-bildplatz--hero {
    min-height: 200px;
  }
}

/* --- Karten -------------------------------------------------------------------
   Gleiche Gestaltung wie der Kachelbereich der Startseite: Titel,
   Kurzbeschrieb, kupferner Verweis. Der Verweis sitzt immer unten, damit die
   Karten einer Reihe auf einer Linie enden. */
.elementor-widget-wrap:has(> .ob-kartentitel) {
  display: flex;
  flex-direction: column;
  flex-wrap: nowrap;
  align-content: flex-start;
  height: 100%;
  padding: var(--ob-space-lg);
  background: var(--ob-surface-card);
  border: 1px solid var(--ob-border-subtle);
  border-radius: var(--ob-radius-sm);
}

.elementor-widget-wrap:has(> .ob-kartentitel) > .elementor-widget-button {
  margin-top: auto;
}

/* Auf grauem Grund braucht die Karte eine sichtbare Kante. */
.elementor-section[style*="240, 242, 244"] .ob-karte > .elementor-widget-wrap,
.elementor-widget-wrap:has(> .ob-kartentitel) {
  box-shadow: var(--ob-shadow-sm);
}

/* --- Stichpunktliste ----------------------------------------------------------
   Für Aufzählungen ohne Titelstruktur. Kupferner Strich als Markierung,
   passend zur Kupferlinie unter den Titeln. */
.ob-liste .elementor-icon-list-item {
  position: relative;
  padding-left: 1.15rem;
}

.ob-liste .elementor-icon-list-item::before {
  content: "";
  position: absolute;
  left: 0;
  top: .72em;
  width: .42rem;
  height: 1.5px;
  background: var(--ob-kupfer-500);
}

.ob-liste .elementor-icon-list-icon {
  display: none;
}

/* --- Innere Sektionen zaehmen --------------------------------------------------
   Das bestehende Child-Theme-Stylesheet enthaelt seit jeher:
       .elementor-section { width: 100vw !important; max-width: 100vw !important; }
   Gedacht war das fuer Sektionen der obersten Ebene. Innere Sektionen tragen
   dieselbe Klasse und werden dadurch ebenfalls auf Fensterbreite gezwungen —
   unsere Kartenreihen liefen am 2026-08-26 dadurch 80 px ueber die Spalte
   hinaus und erzeugten waagerechtes Scrollen.

   Das !important hier ist bewusst gesetzt: es hebt ein bestehendes !important
   auf und laesst sich nicht anders erreichen. Sobald die Regel im alten
   Stylesheet auf Sektionen der obersten Ebene eingegrenzt ist, kann dieser
   Block ersatzlos weg. */
.elementor-section.elementor-inner-section {
  width: 100% !important;
  max-width: 100% !important;
}

/* --- Ablaufschritte -----------------------------------------------------------
   Nummerierte Abfolge mit durchgehender Verbindungslinie zwischen den Marken.
   Grundzustand ist senkrecht (Marke links, Linie nach unten); der Block weiter
   unten schaltet ab 1025 px auf waagerecht um — ausser die Abfolge ist dafür zu
   lang, dann trägt die Marke bereits die Klasse --senkrecht.

   Die Linie sitzt auf der Spalte, nicht auf der Marke: nur die Spalte kennt den
   Abstand bis zur nächsten Marke. Angesprochen über :has(), weil Elementor
   eigene CSS-Klassen ausschliesslich auf Widgets ausgibt. Voraussetzung ist,
   dass die Spalten keinen Innenabstand haben (ob_schritte setzt 'gap' => 'no')
   und die Marke das erste Widget der Spalte ist. */
.ob-schritt-marke {
  position: absolute;
  top: 0;
  /* Die Marke haengt an ihrem eigenen Widget-Kasten, und der beginnt INNERHALB
     des Innenabstands des Wraps. left: 0 setzt sie deshalb auf den Titel statt
     in die Gasse — am 2026-08-26 gemessen, Marke und H3 begannen beide bei
     x = 148. Der Rueckzug um die Gassenbreite stellt sie an den Spaltenrand. */
  left: calc(var(--ob-schritt-gasse) * -1);
  z-index: 1;
  display: flex;
  align-items: center;
  justify-content: center;
  width: 40px;
  height: 40px;
  border-radius: var(--ob-radius-full);
  background: var(--ob-action-primary);
  color: var(--ob-text-inverse);
  font-size: 14px;
  font-weight: 700;
  letter-spacing: 0.5px;
  font-variant-numeric: tabular-nums;
}

.elementor-column:has(.ob-schritt-marke) {
  /* Eine Quelle fuer Gassenbreite und Markenrueckzug — die beiden muessen
     uebereinstimmen, sonst steht die Marke schief zur Linie. */
  --ob-schritt-gasse: 60px;
  position: relative;
}

/* Von der Unterkante der Marke bis zur Spaltenunterkante. Die gestapelten
   Spalten liegen ohne Zwischenraum aneinander, die Linie läuft dadurch ohne
   Bruch bis zur nächsten Marke. */
.elementor-column:has(.ob-schritt-marke)::before {
  content: "";
  position: absolute;
  top: 40px;
  bottom: 0;
  left: 19px;
  width: 2px;
  background: var(--ob-petrol-200);
}

/* Nach dem letzten Schritt kommt nichts mehr. Angesprochen ueber eine eigene
   Klasse auf der Marke, nicht ueber :last-child: im senkrechten Fall steht
   jeder Schritt in einer eigenen Sektion und waere dort jeweils letztes Kind. */
.elementor-column:has(.ob-schritt-marke--letzte)::before {
  display: none;
}

/* Platz für die Marke, die aus dem Textfluss genommen ist.

   Oben darf hier KEIN Innenabstand stehen. Die Marke haengt zwar absolut, ihr
   Bezugskasten ist aber ihr eigenes Widget — und das schiebt ein Innenabstand
   des Wraps mit nach unten. Am 2026-08-26 gemessen: 6 px Abstand ergaben 6 px
   Versatz zwischen Markenunterkante und Linienanfang, die Verbindung riss vor
   jeder Marke sichtbar ab. Ohne Abstand fluchten Spaltenkante, Markenoberkante
   und Linienrechnung. */
.elementor-column:has(.ob-schritt-marke) > .elementor-widget-wrap {
  padding-top: 0;
  padding-left: var(--ob-schritt-gasse);
  padding-bottom: var(--ob-space-lg);
}

@media (min-width: 1025px) {
  /* Waagerecht. Der Umschaltpunkt muss zu Elementors Tablet-Grenze passen —
     bis 1024 px stapelt Elementor die Spalten selbst (_inline_size_tablet). */
  .elementor-column:has(.ob-schritt-marke:not(.ob-schritt-marke--senkrecht)) > .elementor-widget-wrap {
    padding-left: 0;
    padding-bottom: 0;
  }

  /* Waagerecht steht die Marke im Textfluss ueber dem Titel. 'relative' nur,
     damit sie ueber der Verbindungslinie liegt; der Rueckzug muss dann weg. */
  .ob-schritt-marke:not(.ob-schritt-marke--senkrecht) {
    position: relative;
    left: 0;
  }

  .elementor-element:has(> .elementor-widget-container > .ob-schritt-marke:not(.ob-schritt-marke--senkrecht)) {
    margin-bottom: 18px;
  }

  /* Von Markenmitte zu Markenmitte: die Spalte hat keinen Innenabstand, die
     nächste Marke sitzt deshalb genau eine Spaltenbreite weiter rechts. */
  .elementor-column:has(.ob-schritt-marke:not(.ob-schritt-marke--senkrecht))::before {
    top: 19px;
    bottom: auto;
    left: 20px;
    right: -20px;
    width: auto;
    height: 2px;
  }
}

/* --- Aufzählung innerhalb einer Karte ------------------------------------------
   Die Textmappe setzt Punktzeilen mitten in den Kartentext. ob_kartentext()
   macht daraus eine echte Liste; hier bekommt sie denselben Kupferstrich wie
   die freistehende .ob-liste, damit beide Formen zusammengehören. */
.ob-kartenliste {
  margin: 0 0 var(--ob-space-md);
  padding: 0;
  list-style: none;
}

.ob-kartenliste li {
  position: relative;
  padding-left: 1.15rem;
  margin-bottom: var(--ob-space-xs);
}

.ob-kartenliste li::before {
  content: "";
  position: absolute;
  left: 0;
  top: .72em;
  width: .42rem;
  height: 1.5px;
  background: var(--ob-kupfer-500);
}

/* --- Fuge zwischen Karten ------------------------------------------------------
   Elementors Spaltenabstand liegt auf .elementor-element-populated — genau dem
   Element, das bei uns den Kartenrahmen traegt. Der Abstand wurde dadurch zum
   Innenpolster der Karte, und die Kaesten stiessen ohne Fuge aneinander. Am
   2026-08-26 auf /kontakt/ gemessen: 0 px zwischen «Öffnungszeiten» und «Für
   Service & Support», die Rahmen bildeten eine gemeinsame Linie.

   Die Fuge kommt deshalb als flex-gap auf den Spaltencontainer. Die Spalten
   sind schrumpffaehig (flex: 0 1 auto) und geben die Breite von selbst her:
   aus 2 x 585 px werden 2 x 577 px mit 16 px dazwischen. Entscheidend ist,
   dass die Aussenkanten buendig mit dem Fliesstext darueber bleiben — mit
   Aussenabstaenden auf den Karten selbst waere die ganze Reihe schmaler
   geworden und aus der Flucht gefallen.

   Eng auf Kartensektionen begrenzt: die Ablaufschritte rechnen ihre
   Verbindungslinie ueber Spalten OHNE Zwischenraum aus. */
.elementor-inner-section:has(.ob-kartentitel) > .elementor-container {
  gap: var(--ob-space-md);
}

/* Vier Karten in einer Reihe (Kontakt, Technische Hintergründe): auf dem
   Tablet zwei je Reihe. 50 % plus Fuge passt nicht in die Zeile, deshalb
   brach jede Karte einzeln um und stand halb breit untereinander. */
@media (min-width: 768px) and (max-width: 1024px) {
  .elementor-inner-section:has(.ob-kartentitel) > .elementor-container {
    flex-wrap: wrap;
  }
  .elementor-inner-section:has(.ob-kartentitel) > .elementor-container > .elementor-col-25 {
    width: calc(50% - var(--ob-space-md) / 2);
  }
}

/* --- Formulare ----------------------------------------------------------------
   Die beiden Anfrageformulare auf /service-support/ kommen unveraendert aus der
   bisherigen Seite; nur die Gestaltung ist neu. Elementors Grundwerte (Rahmen
   #69727D, kein Radius) passen nicht zur CI-Neutralskala. */
.ob-formular .elementor-field-group > label {
  margin-bottom: var(--ob-space-xs);
}

.ob-formular .elementor-field-textual {
  border: 1px solid var(--ob-border-default);
  border-radius: var(--ob-radius-sm);
  background: var(--ob-surface-card);
  color: var(--ob-text-primary);
  padding: 10px 12px;
  min-height: 44px;                 /* WCAG 2.5.8, Zielgroesse */
  transition: border-color .15s ease, box-shadow .15s ease;
}

.ob-formular textarea.elementor-field-textual {
  min-height: 120px;
}

.ob-formular .elementor-field-textual::placeholder {
  color: var(--ob-text-disabled);
}

/* Der Fokusring aus dem CI, hier zusaetzlich als Rahmenwechsel — sonst sieht
   man bei einem Feld nicht, welches gerade aktiv ist. */
.ob-formular .elementor-field-textual:focus {
  border-color: var(--ob-border-focus);
  box-shadow: 0 0 0 3px var(--ob-petrol-100);
  outline: none;
}

/* Pflichtfeldstern in Kupfer statt im Fliesstextgrau. */
.ob-formular .elementor-mark-required .elementor-field-label::after {
  color: var(--ob-kupfer-600);
}

/* Auswahlfelder: Elementors Grundgestaltung laesst sie flach wirken. */
.ob-formular .elementor-field-type-radio .elementor-field-subgroup,
.ob-formular .elementor-field-type-checkbox .elementor-field-subgroup {
  gap: var(--ob-space-md);
}

.ob-formular input[type="radio"],
.ob-formular input[type="checkbox"] {
  accent-color: var(--ob-action-primary);
  width: 18px;
  height: 18px;
  margin-right: var(--ob-space-xs);
}

/* Die Zwischenueberschriften im Formular sind html-Felder und erben sonst die
   Fliesstextgroesse. */
.ob-formular .elementor-field-type-html {
  padding-top: var(--ob-space-sm);
}

.ob-formular .elementor-field-type-html strong,
.ob-formular .elementor-field-type-html b {
  font-size: 1.1875rem;
  font-weight: var(--ob-weight-semibold);
  color: var(--ob-text-primary);
}

/* --- Aufnahmen auf der Serviceseite ------------------------------------------- */
.ob-servicebild img {
  border: 1px solid var(--ob-border-subtle);
  border-radius: var(--ob-radius-sm);
  box-shadow: var(--ob-shadow-sm);
}

/* --- Sicherheitsnetz gegen waagerechten Überlauf --------------------------------
   Elementors Breitenangabe («Benutzerdefinierte Breite») schreibt width UND
   max-width in Pixeln:

       width: var(--container-widget-width, 780px);
       max-width: 780px;

   Eine mobile Entsprechung schreibt Elementor nur, wenn man sie im Baukasten
   ausdruecklich setzt. Ohne sie gilt width: 780px auch auf einem 390 px
   breiten Schirm — der Absatz bricht nicht um, sondern schiebt die ganze Seite
   nach rechts. Am 2026-08-27 auf /produkte/ gemeldet: 32 solche Regeln auf
   einer Seite, die Kopfzeile lag bei 390 px, der Fliesstext darunter bei
   780 px.

   Die Gegenregel begrenzt nur die Hoechstbreite und laesst die eingestellte
   Breite in Ruhe. Wer im Baukasten bewusst ein schmales Widget setzt, behaelt
   es; nur breiter als sein Behaelter kann nichts mehr werden.

   Fuenf Klassen, um Elementors eigene Regel zu ueberbieten — die bringt mit
   .elementor-<postid> .elementor-element.elementor-element-<id> drei mit.
   Kein !important noetig. */
@media (max-width: 1024px) {
  .elementor-section .elementor-column .elementor-widget-wrap > .elementor-element {
    max-width: 100%;
  }
}

/* Lange Wörter ohne Trennmöglichkeit — «Wärmepumpenboiler-Fachpartner»,
   E-Mail-Adressen, Dateinamen — sprengen sonst schmale Spalten. */
.elementor-widget-heading .elementor-heading-title,
.elementor-widget-text-editor,
.ob-kartenliste li,
.ob-liste .elementor-icon-list-text {
  overflow-wrap: break-word;
}

/* Auf schmalen Schirmen stehen Formularfelder untereinander.
   Das uebernommene Formular setzt fuer «Hausnummer» 25 % Breite. Auf 375 px
   sind das 80 px — das Eingabefeld passt, die Beschriftung nicht: sie mass am
   2026-08-27 164 px und schob die Seite 61 px nach rechts. Ein 80 px breites
   Feld ist auf dem Handy ohnehin nicht bedienbar. */
@media (max-width: 767px) {
  .ob-formular .elementor-form-fields-wrapper > .elementor-field-group {
    width: 100%;
    flex-basis: 100%;
    max-width: 100%;
  }
}

/* --- Kopfbild der Unterseiten ---------------------------------------------------
   Die vorhandenen Aufnahmen liegen zwischen 1.5:1 und 2:1. Ohne festes
   Seitenverhaeltnis waere jeder Kopfbereich anders hoch und die Reihe der
   Unterseiten verlöre ihre Linie. 4:3 traegt sowohl die Querformate als auch
   die hochformatige Energieetikette, ohne dass etwas Wesentliches wegfaellt. */
.ob-kopfbild img {
  display: block;
  width: 100%;
  aspect-ratio: 4 / 3;
  object-fit: cover;
  object-position: center;
  border-radius: var(--ob-radius-sm);
  box-shadow: var(--ob-shadow-sm);
}

/* Hochformate — Etiketten, Produktfreisteller — nicht beschneiden, sondern
   einpassen. Ein angeschnittenes Energielabel waere unbrauchbar. */
.ob-kopfbild--einpassen img {
  object-fit: contain;
  background: var(--ob-surface-card);
}

@media (max-width: 767px) {
  .ob-kopfbild img {
    aspect-ratio: 3 / 2;
  }
}

/* --- Bild im Fliesstext ---------------------------------------------------------
   Anders als das Kopfbild ohne festen Zuschnitt: diese Aufnahmen stehen mitten
   im Text und behalten ihr Format. Begrenzt wird nur die Breite, damit sie der
   Lesebreite der Absaetze folgen und nicht aus der Spalte laufen. */
.ob-inhaltsbild img {
  display: block;
  width: 100%;
  max-width: 780px;
  height: auto;
  border-radius: var(--ob-radius-sm);
  box-shadow: var(--ob-shadow-sm);
}

/* Hochformate wuerden sonst die halbe Bildschirmhoehe fuellen. */
.ob-inhaltsbild--hoch img {
  max-width: 460px;
}

/* Texte einer Schrittreihe beginnen auf gleicher Hoehe.
   Elementor gibt der Widget-Spalte 'align-content: stretch'. Weil die Spalten
   einer Reihe gleich hoch sind, verteilt der Browser den ueberschuessigen
   Platz auf die Flex-Zeilen — die Marke wuchs dadurch je nach Textlaenge auf
   40, 64 oder 72 px, und Titel und Text rutschten unterschiedlich weit nach
   unten. Am 2026-08-31 von Sonja gemeldet: 64 px Versatz auf der
   Installationsseite. Mit flex-start sammelt sich der Platz unten. */
.elementor-section .elementor-container .elementor-column:has(.ob-schritt-marke)
  > .elementor-widget-wrap.elementor-element-populated {
  align-content: flex-start;
}

/* Zweiter Grund fuer ungleiche Texthoehen: unterschiedlich lange Schritttitel.
   «Passenden Oekoboiler auswählen» braucht zwei Zeilen, «Neubau planen» eine.
   Zwei Zeilen reservieren gleicht das aus, ohne dass bei durchgehend kurzen
   Titeln auffaellig viel Luft entsteht. Nur waagerecht noetig. */
@media (min-width: 1025px) {
  .elementor-column:has(.ob-schritt-marke) h3 {
    min-height: 2.7em;
  }
}

/* Absendeknopf in Knopfbreite, nicht ueber die ganze Spalte.
   Elementor gibt der Absendezeile 100 % und streckt den Knopf mit. */
.ob-formular .elementor-field-type-submit {
  justify-content: flex-start;
}

.ob-formular button[type="submit"] {
  /* Elementor setzt flex-basis: 100% ueber die Klasse button-align-stretch.
     width allein reicht deshalb nicht, die Basis muss mit. */
  flex-basis: auto;
  width: auto;
  min-width: 12rem;
  padding: 14px 28px;
}

/* Der Dateiupload sieht sonst aus wie ein Systemelement von 1998. */
.ob-formular input[type="file"] {
  border: 1px dashed var(--ob-border-default);
  border-radius: var(--ob-radius-sm);
  padding: var(--ob-space-md);
  width: 100%;
  background: var(--ob-surface-card);
  cursor: pointer;
}

.ob-formular input[type="file"]:focus {
  border-color: var(--ob-border-focus);
  border-style: solid;
  outline: none;
  box-shadow: 0 0 0 3px var(--ob-petrol-100);
}

/* Zustimmungshaken: Text neben der Box, nicht darunter. */
.ob-formular .elementor-field-type-acceptance .elementor-field-option {
  display: flex;
  align-items: flex-start;
  gap: var(--ob-space-sm);
}

.ob-formular .elementor-field-type-acceptance label {
  font-weight: 400;
  font-size: .9375rem;
  line-height: 1.5;
}

/* --- Kacheln auf «Wissen & News» -----------------------------------------------
   Von Sonja gemeldet: «die Kacheln sind im Moment etwas gross». Gemessen am
   2026-09-02 bei 1440 px: Kachel 300x601 px, davon allein 211 bis 255 px
   Teasertext. Vier Reihen zu je rund 650 px.

   Die Seite hat Sonja selbst im Baukasten gebaut, sie traegt keine unserer
   Bausteinklassen. Deshalb ist diese Regel bewusst an die Seitenkennung
   gebunden (page-id 3125) und trifft ueber :has() nur Spalten, die Bild,
   Ueberschrift UND Text enthalten — also genau die 16 Kacheln. Einleitung und
   Fusszeile bleiben unberuehrt; nachgezaehlt.

   Sollte die Seite je neu angelegt werden, muss die Kennung hier mitwandern. */
.elementor-page-3125 .elementor-column:has(.elementor-widget-image):has(.elementor-widget-heading):has(.elementor-widget-text-editor) .elementor-widget-text-editor > .elementor-widget-container {
  /* Auf den BLOCK begrenzen, nicht auf den einzelnen Absatz: zwoelf der
     sechzehn Kacheln haben zwei oder drei Absaetze, die sonst je drei Zeilen
     bekaemen — gemessen 60 bis 180 px statt der gewuenschten rund 78. */
  display: -webkit-box;
  -webkit-line-clamp: 3;
  -webkit-box-orient: vertical;
  overflow: hidden;
}

.elementor-page-3125 .elementor-column:has(.elementor-widget-image):has(.elementor-widget-heading):has(.elementor-widget-text-editor) .elementor-widget-text-editor p {
  margin: 0;
}

/* Einheitliches Bildformat — die Aufnahmen liegen zwischen 3:2 und 4:3 vor. */
.elementor-page-3125 .elementor-column:has(.elementor-widget-image):has(.elementor-widget-heading):has(.elementor-widget-text-editor) .elementor-widget-image img {
  aspect-ratio: 3 / 2;
  object-fit: cover;
  width: 100%;
  height: auto;
  border-radius: var(--ob-radius-sm);
}

/* Engere Staffelung innerhalb der Kachel. */
.elementor-page-3125 .elementor-column:has(.elementor-widget-image):has(.elementor-widget-heading):has(.elementor-widget-text-editor) .elementor-widget:not(:last-child) {
  margin-bottom: var(--ob-space-sm);
}

/* Ueberschuessige Hoehe sammelt sich unten, nicht zwischen den Widgets —
   dieselbe Falle wie bei den Ablaufschritten. */
.elementor-page-3125 .elementor-column:has(.elementor-widget-image):has(.elementor-widget-heading):has(.elementor-widget-text-editor) > .elementor-widget-wrap {
  align-content: flex-start;
}

/* Standortbilder auf /kontakt/. Fuellen ihre Spalte, festes Seitenverhaeltnis
   damit die beiden Standorte gleich hoch beginnen — die Aufnahmen liegen in
   3:2 und 16:10 vor. */
.ob-standortbild img {
  display: block;
  width: 100%;
  aspect-ratio: 3 / 2;
  object-fit: cover;
  border-radius: var(--ob-radius-sm);
  box-shadow: var(--ob-shadow-sm);
}

/* Gestapelt braucht es den Spaltenabstand nicht mehr — er schob die
   Standortbloecke sonst 18 px weiter nach innen als den uebrigen Text. */
@media (max-width: 767px) {
  .elementor-inner-section:has(.ob-standortbild) > .elementor-container
    > .elementor-column > .elementor-widget-wrap {
    padding-left: 0;
    padding-right: 0;
  }
}

/* ===========================================================================
   Shop — WooCommerce
   ===========================================================================
   Archiv, Produktseite, Warenkorb und Kasse liegen ausserhalb von Elementor:
   sie kommen aus PHP-Vorlagen (Archiv, Produkt) beziehungsweise aus
   WooCommerce-Blocks (Warenkorb, Kasse). Bis 2026-09-02 trugen sie deshalb
   system-ui, Arial und Roboto und reines Schwarz statt der CI-Werte.

   Der Grund ist aufschlussreich: die Elementor-Seiten sehen nur richtig aus,
   weil JEDES Widget die Schrift selbst mitbringt. Der Body war immer schon
   system-ui. Wir setzen die Schrift deshalb an der Wurzel — das erreicht auch
   Konto, Suche und Fehlerseiten.

   Inhalte, Preise und Einstellungen werden nicht angefasst.
   =========================================================================== */

/* --- Grundschrift für alles ausserhalb von Elementor ------------------------ */
body,
button,
input,
select,
textarea,
optgroup {
  font-family: "Source Sans 3", ui-sans-serif, system-ui, -apple-system,
               "Segoe UI", Roboto, Helvetica, Arial, sans-serif;
}

.woocommerce,
.woocommerce-page {
  color: var(--ob-text-secondary);
}

.woocommerce h1, .woocommerce-page h1,
.woocommerce h2, .woocommerce-page h2,
.woocommerce h3, .woocommerce-page h3 {
  color: var(--ob-text-primary);
  font-weight: var(--ob-weight-semibold);
}

/* Betraege immer mit gleichbreiten Ziffern — sonst tanzen die Spalten. */
.woocommerce .price,
.woocommerce-Price-amount,
.wc-block-components-formatted-money-amount,
.wc-block-components-totals-item__value {
  font-variant-numeric: tabular-nums;
}

/* --- Produktkacheln im Archiv ----------------------------------------------
   Dieselbe Anmutung wie die Karten auf den Inhaltsseiten: heller Grund,
   feine Kante, ruhiger Schatten. */
/* Produktkachel — gleiche Bauweise wie die Inhaltskarten auf den
   Loesungsseiten: heller Grund, 1 px Rand in border.subtle, radius.sm,
   shadow.sm, und das Bild um die Polsterung eingerueckt statt randbuendig.
   Nachgemessen: Kachel 17 px Einzug, Inhaltskarte 16 px — dieselbe Optik.

   Ein Versuch ohne Rand ist am 2026-09-09 verworfen worden: die Kacheln
   sollen im ganzen Shop so aussehen wie die Karten im uebrigen Seiteninhalt. */
.woocommerce ul.products li.product {
  background: var(--ob-surface-card);
  border: 1px solid var(--ob-border-subtle);
  border-radius: var(--ob-radius-sm);
  box-shadow: var(--ob-shadow-sm);
  transition: box-shadow 0.15s ease;
  padding: var(--ob-space-md);
  transition: box-shadow .15s ease, border-color .15s ease;
}

.woocommerce ul.products li.product:hover {
  border-color: var(--ob-border-default);
  box-shadow: var(--ob-shadow-md);
}

.woocommerce ul.products li.product .woocommerce-loop-product__title {
  color: var(--ob-text-primary);
  font-size: 1.0625rem;
  font-weight: var(--ob-weight-semibold);
  line-height: 1.35;
}

.woocommerce ul.products li.product .price {
  color: var(--ob-text-primary);
  font-size: 1.0625rem;
  font-weight: var(--ob-weight-semibold);
}

.woocommerce ul.products li.product .price del {
  color: var(--ob-neutral-600);
  font-weight: var(--ob-weight-regular);
}

.woocommerce ul.products li.product .price ins {
  color: var(--ob-kupfer-600);
  text-decoration: none;
}

/* --- Produktseite ---------------------------------------------------------- */
.woocommerce div.product .product_title {
  color: var(--ob-text-primary);
  font-weight: var(--ob-weight-semibold);
  line-height: 1.2;
}

.woocommerce div.product .summary .price {
  color: var(--ob-text-primary);
  font-weight: var(--ob-weight-semibold);
}

.woocommerce div.product .woocommerce-tabs ul.tabs li a {
  color: var(--ob-text-secondary);
  font-weight: var(--ob-weight-semibold);
}

.woocommerce div.product .woocommerce-tabs ul.tabs li.active a {
  color: var(--ob-text-primary);
}

/* --- Knöpfe ----------------------------------------------------------------
   Der Knopf auf der Produktseite trug einen halbrunden Radius nur rechts
   (0 25px 25px 0). Alle Kaufknöpfe folgen jetzt der CI-Vorgabe. */
.woocommerce a.button,
.woocommerce button.button,
.woocommerce input.button,
.woocommerce #respond input#submit,
.woocommerce div.product form.cart button.single_add_to_cart_button,
.wc-block-components-button {
  border-radius: var(--ob-radius-sm);
  font-family: inherit;
  font-weight: var(--ob-weight-semibold);
}

.woocommerce a.button.alt,
.woocommerce button.button.alt,
.woocommerce div.product form.cart button.single_add_to_cart_button,
.wc-block-components-button:not(.is-link) {
  background: var(--ob-action-primary);
  color: var(--ob-text-inverse);
}

.woocommerce a.button.alt:hover,
.woocommerce button.button.alt:hover,
.woocommerce div.product form.cart button.single_add_to_cart_button:hover,
.wc-block-components-button:not(.is-link):hover {
  background: var(--ob-action-primary-hover);
  color: var(--ob-text-inverse);
}

/* --- Eingabefelder ---------------------------------------------------------
   Gleiche Anmutung wie die Formularfelder auf den Inhaltsseiten. */
.woocommerce form .form-row input.input-text,
.woocommerce form .form-row textarea,
.woocommerce form .form-row select,
.woocommerce .quantity input.qty,
.wc-block-components-text-input input,
.wc-block-components-textarea,
.wc-block-components-select__select {
  border: 1px solid var(--ob-border-default);
  border-radius: var(--ob-radius-sm);
  background: var(--ob-surface-card);
  color: var(--ob-text-primary);
  font-family: inherit;
}

.woocommerce form .form-row input.input-text:focus,
.woocommerce form .form-row textarea:focus,
.woocommerce form .form-row select:focus,
.woocommerce .quantity input.qty:focus,
.wc-block-components-text-input input:focus {
  border-color: var(--ob-border-focus);
  box-shadow: 0 0 0 3px var(--ob-petrol-100);
  outline: none;
}

/* --- Warenkorb und Kasse (WooCommerce-Blocks) -------------------------------
   Die Blocks bringen eine eigene Grössenskala mit: 1.2rem für Fliesstext und
   Beträge, was neben unseren 16 px unruhig wirkt. Wir ziehen sie auf die
   CI-Skala zurück. Die Blocks setzen ihre Werte über eigene Klassen, deshalb
   sind die Selektoren hier etwas länger als sonst. */
.wc-block-components-product-name,
.wc-block-components-product-price,
.wc-block-components-totals-item__label,
.wc-block-components-totals-item__value,
.wc-block-components-quantity-selector input,
.wc-block-cart-items__header {
  font-size: 1rem;
}

.wc-block-components-product-name {
  color: var(--ob-text-primary);
  font-weight: var(--ob-weight-semibold);
}

a.wc-block-components-product-name:hover {
  color: var(--ob-text-link-hover);
}

.wc-block-components-product-metadata,
.wc-block-components-product-metadata__description {
  color: var(--ob-neutral-600);
}

/* Spaltenkopf der Warenkorbtabelle wie unsere Tabellenköpfe. */
.wc-block-cart-items__header {
  color: var(--ob-text-primary);
  font-weight: var(--ob-weight-semibold);
  letter-spacing: .06em;
  text-transform: uppercase;
  font-size: .75rem;
  border-bottom: 1px solid var(--ob-border-default);
}

/* Summenblock als Karte, wie die Kacheln auf den Inhaltsseiten. */
.wc-block-cart__sidebar .wc-block-components-totals-wrapper,
.wc-block-checkout__sidebar .wc-block-components-totals-wrapper {
  border-color: var(--ob-border-subtle);
}

.wc-block-components-totals-item__label {
  color: var(--ob-text-secondary);
}

.wc-block-components-totals-item__value {
  color: var(--ob-text-primary);
  font-weight: var(--ob-weight-semibold);
}

.wc-block-components-totals-footer-item .wc-block-components-totals-item__value {
  font-size: 1.25rem;
}

/* Schritt-Überschriften der Kasse. */
.wc-block-components-checkout-step__title {
  color: var(--ob-text-primary);
  font-size: 1.25rem;
  font-weight: var(--ob-weight-semibold);
}

.wc-block-components-checkout-step__description {
  color: var(--ob-neutral-600);
}

.wc-block-components-text-input label,
.wc-block-components-checkbox__label {
  color: var(--ob-text-secondary);
}

/* Versand- und Zahlungsoptionen: ausgewählte Zeile in Petrol markieren,
   statt sie nur blass zu hinterlegen. */
.wc-block-components-radio-control__option {
  border-radius: var(--ob-radius-sm);
}

.wc-block-components-radio-control-accordion-option--checked-option,
.wc-block-components-radio-control__option--checked-option {
  border-color: var(--ob-border-focus);
}

.wc-block-components-radio-control__input:checked {
  accent-color: var(--ob-action-primary);
}

/* Der grosse Bestellknopf. Blocks setzen 6 px Radius und 1.2rem. */
.wc-block-components-checkout-place-order-button,
.wc-block-cart__submit-button {
  border-radius: var(--ob-radius-sm);
  font-size: 1rem;
  font-weight: var(--ob-weight-semibold);
}

/* Hinweise und Fehlermeldungen in den CI-Farben. */
.wc-block-components-notice-banner.is-error {
  border-color: var(--ob-border-error);
}

.wc-block-components-notice-banner.is-success {
  border-color: var(--ob-moos-500, #5C7A4F);
}

/* --- Tastaturbedienung im Shop ---------------------------------------------
   Der Fokusring aus §5.6 gilt auch hier. WooCommerce und die Blocks setzen an
   mehreren Stellen eigene Umrisse. */
.woocommerce a:focus-visible,
.woocommerce button:focus-visible,
.woocommerce input:focus-visible,
.woocommerce select:focus-visible,
.wc-block-components-button:focus-visible,
.wc-block-components-product-name:focus-visible {
  outline: 3px solid var(--ob-border-focus);
  outline-offset: 2px;
  border-radius: var(--ob-radius-sm);
}

/* Mengenfeld auf der Produktseite. Kam mit 13 px und schwarzem Rahmen —
   das ist der unformatierte Browserstandard. 44 px Mindesthoehe wie bei den
   uebrigen Eingabefeldern (WCAG 2.5.8). */
.woocommerce div.product form.cart .quantity input.qty,
.woocommerce div.product .elementor-widget-woocommerce-product-add-to-cart .quantity input.qty {
  font-size: 1rem;
  font-weight: var(--ob-weight-semibold);
  color: var(--ob-text-primary);
  border: 1px solid var(--ob-border-default);
  border-radius: var(--ob-radius-sm);
  min-height: 44px;
  text-align: center;
}

/* Absendeknopf in Formularen: Groesse und Gewicht mitgeben, sonst erbt er
   je nach Vorlage 15 px in Normalschrift. */
.ob-formular button[type="submit"] {
  font-size: 1rem;
  font-weight: var(--ob-weight-semibold);
}

/* --- Letzte Fremdfarben im Shop --------------------------------------------
   Nach dem Umstellen blieben vier Stellen mit Grautoenen ausserhalb der
   CI-Neutralskala (#111, #222, #333). Gemessen am 2026-09-02. */

/* «CHF» stand eine Spur dunkler als der Betrag daneben. */
.woocommerce-Price-currencySymbol,
.wc-block-formatted-money-amount {
  color: inherit;
}

/* Das Entfernen-Kreuz im Warenkorb. Kupfer statt Grau — es ist die einzige
   ruecknehmende Handlung und darf als solche erkennbar sein. */
.woocommerce a.remove,
.wc-block-cart-item__remove-link {
  color: var(--ob-kupfer-600);
}

.woocommerce a.remove:hover,
.wc-block-cart-item__remove-link:hover {
  color: var(--ob-kupfer-700);
  background: transparent;
}

/* KEINE pauschale Regel fuer «sekundaere» Knoepfe: der Kaufknopf im Archiv
   traegt Petrol als Grund, aber nicht die Klasse .alt. Eine Regel ueber
   :not(.alt) faerbte seine Schrift dunkel — 2.15:1 auf Petrol, unlesbar.
   Kaufknoepfe im Archiv bekommen deshalb ausdruecklich weisse Schrift. */
.woocommerce ul.products li.product a.button,
.woocommerce ul.products li.product a.add_to_cart_button {
  color: var(--ob-text-inverse);
}

/* Warenkorb-Schublade und Mobilmenue im Kopfbereich gehoeren zum Einkauf. */
.cart-drawer,
.cart-drawer-heading,
.widget_shopping_cart_content,
.handheld-navigation {
  color: var(--ob-text-secondary);
}

.cart-drawer-heading,
.widget_shopping_cart_content .total {
  color: var(--ob-text-primary);
}

/* --- Archivrahmen ----------------------------------------------------------
   Ergebniszaehler, Seitennummerierung, Kategorie- und Brotkrumenverweise
   standen noch in Fremdgrau (#111, #444, #2C2D33). */
/* neutral-600 statt text-tertiary: der Token erreicht auf Weiss nur 3.73:1
   und ist damit fuer Fliesstext unter der AA-Schwelle. neutral-600 liegt bei
   5.52:1. Nachgerechnet am 2026-09-02, Rechner an #767676 = 4.54:1 geeicht. */
.woocommerce .woocommerce-result-count,
.woocommerce .woocommerce-breadcrumb {
  color: var(--ob-neutral-600);
}

.woocommerce .woocommerce-breadcrumb a,
.woocommerce .product-categories a,
.woocommerce .widget_product_categories a,
.woocommerce ul.products li.product a:not(.button) {
  color: var(--ob-text-link);
}

.woocommerce .woocommerce-breadcrumb a:hover,
.woocommerce .product-categories a:hover,
.woocommerce .widget_product_categories a:hover {
  color: var(--ob-text-link-hover);
}

.woocommerce nav.woocommerce-pagination ul li a,
.woocommerce nav.woocommerce-pagination ul li span {
  color: var(--ob-text-secondary);
  border-radius: var(--ob-radius-sm);
}

.woocommerce nav.woocommerce-pagination ul li a:hover {
  color: var(--ob-text-link-hover);
  background: var(--ob-surface-subtle);
}

/* Die aktive Seitenzahl. Die Schriftfarbe braucht dieselbe Spezifitaet wie
   der Grund, sonst gewinnt die Linkfarbe des Themes — Petrol auf Petrol. */
.woocommerce nav.woocommerce-pagination ul li span.current,
.woocommerce nav.woocommerce-pagination ul li a.current,
.woocommerce nav.woocommerce-pagination ul li .page-numbers.current {
  background: var(--ob-action-primary);
  color: var(--ob-text-inverse);
}

/* --- Produktbühne ----------------------------------------------------------
   Die Produktfotos sind Studioaufnahmen im Hochformat 567 x 850. Gemessen am
   2026-09-02 über ein Helligkeitsprofil: das Gerät selbst belegt darin nur
   rund 208 x 575 Bildpunkte. 31 % links und 32 % rechts sind leerer Grund,
   oben 20 %, unten 12 %. In einer 550 px breiten Spalte wurde daraus ein
   825 px hohes Bild — die Seite wurde dadurch unnötig lang.

   Ein randloses Bild in einer querformatigen Bühne ist mit diesen Aufnahmen
   rechnerisch nicht möglich: um 550 x 480 ohne Verzerrung zu füllen, müsste
   das Bild auf 550 x 824 wachsen. Das Gerät wäre dann 557 px hoch, 77 px
   davon lägen ausserhalb — der Boilerfuss würde abgeschnitten.

   Deshalb bekommt die Bühne das Seitenverhältnis der Aufnahme selbst.
   Damit fallen «einpassen» und «ausfüllen» zusammen: das Bild füllt die
   Fläche randlos und wird an keiner Stelle beschnitten. Den Wert setzt
   ci-setup.php je Produkt, weil Boiler (567 x 850) und Zubehör (567 x 600)
   in verschiedenen Formaten aufgenommen sind. Die Bühne ist in der Breite
   begrenzt; der gewonnene Platz geht an die Produktangaben. */
.woocommerce div.product .woocommerce-product-gallery {
  max-width: min(100%, 380px);
  margin-right: auto;
}

/* FlexSlider schreibt die Höhe des Ansichtsfensters per Skript als Inline-Stil
   (gemessen 824.5 px). Ein Inline-Stil schlägt jeden Selektor — das
   !important ist hier unvermeidbar. */
.woocommerce div.product .flex-viewport {
  height: auto !important;
}

/* Das Seitenverhältnis der Bühne setzt ci-setup.php je Produkt aus dem
   Hauptbild. Der Wert hier greift nur, falls das ausbleibt. */
.woocommerce div.product .woocommerce-product-gallery__image {
  aspect-ratio: 567 / 850;
  background: var(--ob-surface-page);
  border-radius: var(--ob-radius-sm);
  overflow: hidden;
}

.woocommerce div.product .woocommerce-product-gallery__image > a {
  display: block;
  height: 100%;
}

.woocommerce div.product .woocommerce-product-gallery__wrapper img {
  width: 100%;
  height: 100%;
  object-fit: cover;
  object-position: center;
}

/* Bilder, die vom Format der Bühne abweichen, werden eingepasst statt
   gefüllt — sonst würden sie sichtbar beschnitten. Das betrifft vor allem
   die Energieetiketten (1241 x 2363), die als Dokument vollständig lesbar
   bleiben müssen. Die Klasse vergibt ci-setup.php. */
.woocommerce div.product .woocommerce-product-gallery__image.ob-einpassen img {
  object-fit: contain;
}

/* Miniaturen darunter in gleicher Anmutung.
   Shoptimizer setzt sie als 60-px-Kaestchen zentriert in die Leiste — bei
   380 px Buehnenbreite blieben links und rechts je rund 60 px leer
   (gemessen 11.09.). Jetzt teilen sie sich die volle Breite, buendig mit dem
   Hauptbild: ein Raster mit gleich breiten Spalten, so viele wie Bilder da
   sind. Format wie die Buehne (--ob-buehne kommt je Produkt aus
   ci-setup.php), damit die Geraete in der Miniatur so aussehen wie oben.
   Schmalere Motive wie die Energieetikette werden eingepasst, nicht
   beschnitten. */
.woocommerce div.product .woocommerce-product-gallery .flex-control-thumbs {
  display: grid;
  grid-auto-flow: column;
  grid-auto-columns: 1fr;
  gap: var(--ob-space-sm);
  margin: var(--ob-space-sm) 0 0;
  padding: 0;
  text-align: initial;
}

.woocommerce div.product .woocommerce-product-gallery .flex-control-thumbs li {
  display: block;
  width: auto;
  margin: 0;
}

.woocommerce div.product .flex-control-thumbs li img {
  display: block;
  width: 100%;
  height: auto;
  border-radius: var(--ob-radius-sm);
  border: 1px solid var(--ob-border-subtle);
  background: var(--ob-surface-page);
  aspect-ratio: var(--ob-buehne, 567 / 850);
  object-fit: contain;
  opacity: .75;
  transition: opacity .15s ease, border-color .15s ease;
}

.woocommerce div.product .flex-control-thumbs li img:hover,
.woocommerce div.product .flex-control-thumbs li img.flex-active {
  opacity: 1;
  border-color: var(--ob-border-focus);
}

/* --- Sprungziele ------------------------------------------------------------
   Sprungknöpfe gibt es auf /wissen/ (Wissensteil) und auf /kontakt/ (Kontakt,
   Formular, Standorte). Die Kopfleiste legt sich beim Hochscrollen über den
   Inhalt und würde das Ziel verdecken; der Abstand hält es frei.

   Angesprochen wird über die Kennung, nicht über eine Klasse: Elementor gibt
   `_css_classes` an Abschnitten und Spalten nicht aus — nur an Widgets.
   Am 2026-09-08 nachgemessen. */
.ob-sprungziel,
#wissen, #kontakt, #formular, #standorte, #anfrage {
  scroll-margin-top: 104px;
}

@media (max-width: 992px) {
  .ob-sprungziel,
  #wissen, #kontakt, #formular, #standorte, #anfrage { scroll-margin-top: 80px; }
}

/* --- Beitragsübersicht mit Kategoriefilter ---------------------------------
   Gehört zum Shortcode [ob_beitraege] in ci-setup.php. Das Raster liegt im
   CSS-Grid: beim Filtern verschwinden Karten über das hidden-Attribut, die
   übrigen rücken von selbst nach. Dafür braucht es keine Bibliothek. */

.ob-filter {
  display: flex;
  flex-wrap: wrap;
  gap: var(--ob-space-xs);
  margin-bottom: var(--ob-space-lg);
}

.ob-filter-knopf {
  font: inherit;
  font-size: 15px;
  font-weight: 600;
  line-height: 1;
  padding: 10px 18px;
  border: 1px solid var(--ob-border-default);
  border-radius: 999px;
  background: transparent;
  color: var(--ob-text-secondary);
  cursor: pointer;
  transition: background .15s ease, border-color .15s ease, color .15s ease;
}

.ob-filter-knopf:hover {
  border-color: var(--ob-action-primary);
  color: var(--ob-action-primary);
}

.ob-filter-knopf.ist-aktiv {
  background: var(--ob-action-primary);
  border-color: var(--ob-action-primary);
  color: var(--ob-text-inverse);
}

.ob-filter-knopf:focus-visible {
  outline: 2px solid var(--ob-border-focus);
  outline-offset: 2px;
}

.ob-beitragsraster {
  display: grid;
  grid-template-columns: repeat(3, 1fr);
  gap: var(--ob-space-md);
}

@media (max-width: 1024px) {
  .ob-beitragsraster { grid-template-columns: repeat(2, 1fr); }
}

@media (max-width: 640px) {
  .ob-beitragsraster { grid-template-columns: 1fr; }
}

.ob-beitrag {
  display: flex;
  flex-direction: column;
  background: var(--ob-surface-card);
  border: 1px solid var(--ob-border-subtle);
  border-radius: var(--ob-radius-sm);
  overflow: hidden;
}

/* Der Filter blendet über das hidden-Attribut aus. Das display:none des
   Browsers stammt aus dem Standard-Stylesheet und wird von der Regel darüber
   geschlagen — ohne diese Zeile bleibt jede Karte sichtbar, obwohl das
   Attribut gesetzt ist. */
.ob-beitrag[hidden] {
  display: none;
}

/* Einheitliches Bildformat — die Aufnahmen liegen zwischen 3:2 und 2:3 vor,
   die Energieetikette sogar hochkant. Ohne feste Vorgabe wären die Karten
   unterschiedlich hoch. */
.ob-beitrag-bild {
  display: block;
  aspect-ratio: 3 / 2;
  background: var(--ob-surface-page);
  overflow: hidden;
}

.ob-beitrag-bild img,
.ob-beitrag-leer {
  display: block;
  width: 100%;
  height: 100%;
  object-fit: cover;
}

.ob-beitrag-text {
  display: flex;
  flex-direction: column;
  gap: 6px;
  padding: var(--ob-space-md);
}

.ob-beitrag-kategorie {
  font-size: 12px;
  font-weight: 700;
  letter-spacing: .08em;
  text-transform: uppercase;
  color: var(--ob-kupfer-600);
}

.ob-beitrag-titel {
  margin: 0;
  font-size: 19px;
  font-weight: 600;
  line-height: 1.35;
}

.ob-beitrag-titel a {
  color: var(--ob-text-primary);
  text-decoration: none;
}

.ob-beitrag-titel a:hover {
  color: var(--ob-action-primary);
}

.ob-beitrag-datum {
  font-size: 13px;
  color: var(--ob-text-secondary);
}

.ob-beitrag-anriss {
  margin: 0;
  font-size: 15px;
  line-height: 1.6;
  color: var(--ob-text-secondary);
}

/* Der Weiterlesen-Verweis sitzt unten, damit die Karten gleich enden. */
.ob-beitrag-mehr {
  margin-top: auto;
  padding-top: 6px;
  font-size: 15px;
  font-weight: 600;
  color: var(--ob-kupfer-600);
  text-decoration: none;
}

.ob-beitrag-mehr:hover {
  color: var(--ob-kupfer-700);
}

.ob-filter-leer {
  margin-top: var(--ob-space-md);
  color: var(--ob-text-secondary);
}

/* --- Knopf im Fliesstext ----------------------------------------------------
   Für Beiträge, die zügig auf eine Seite weiterführen sollen. Im klassischen
   Editor gibt es kein Knopf-Widget, deshalb ein Verweis mit dieser Klasse. */
.ob-textknopf {
  display: inline-block;
  padding: 13px 26px;
  border-radius: var(--ob-radius-sm);
  background: var(--ob-action-primary);
  color: var(--ob-text-inverse);
  font-size: 16px;
  font-weight: 600;
  line-height: 1.2;
  text-decoration: none;
}

.ob-textknopf:hover,
.ob-textknopf:focus {
  background: var(--ob-action-primary-hover, #2D4B53);
  color: var(--ob-text-inverse);
}

.ob-textknopf:focus-visible {
  outline: 2px solid var(--ob-border-focus);
  outline-offset: 3px;
}

/* --- Hinweismeldungen von WooCommerce --------------------------------------
   Die Erfolgsmeldung nach dem Hinzufuegen zum Warenkorb kam in einem Gruen
   (#3BB54A), das im CI nicht vorkommt und neben dem Petrol-Knopf direkt
   darunter wie ein Fremdkoerper wirkte. Sie traegt jetzt dieselbe Farbe wie
   der Kaufknopf.

   Fehlermeldungen bleiben bewusst rot: eine Warnung in Markenfarbe wird
   ueberlesen. Das ist kein Gestaltungsmangel, sondern Absicht. */
.woocommerce-message {
  background: var(--ob-action-primary);
}

.woocommerce-message::before {
  color: var(--ob-text-inverse);
}

/* Die Knoepfe in der Meldung sind Textknoepfe auf dunklem Grund. Ohne eigene
   Regel erben sie text.link — Petrol auf Petrol, also nichts. Dieselbe Falle
   wie seinerzeit in der Fusszeile. */
.woocommerce-message a.button,
.woocommerce-message a.button:hover,
.woocommerce-message a.wc-forward {
  color: var(--ob-text-inverse);
}

.woocommerce-message a.button:hover {
  text-decoration: underline;
}

/* --- Produktkacheln im Archiv: Platz fuer den Kaufknopf ---------------------
   Shoptimizer legt den Knopf im Archiv absolut an den unteren Kachelrand und
   blendet ihn erst beim Ueberfahren ein. Die Kachel hat dafuer aber keinen
   Platz vorgesehen: der Knopf begann 12 px oberhalb der Preisunterkante und
   deckte den Betrag zur Haelfte zu — gemessen bei 1200 und 1900 px.

   Die Kachel bekommt deshalb unten so viel Polsterung, dass der Knopf unter
   den Preis rutscht: 16 px Grundpolsterung + 40 px Knopfhoehe minus dessen
   Ueberstand, macht 44 px und 16 px Luft zwischen Preis und Knopf.

   Nur ab 769 px. Darunter steht der Knopf ohnehin im Textfluss und immer
   sichtbar (position: relative) — dort waere die Polsterung nur ein Loch. */
@media (min-width: 769px) {
  .woocommerce ul.products li.product {
    padding-bottom: 44px;
  }
}

/* --- Seitenleiste des Shops ------------------------------------------------
   Vorgefunden: Suchfeld ohne Gestaltung, eine Kategorienliste mit dem Titel
   «Produkt» und fuenf leere Attributfilter, die nichts ausgaben. Die Leiste
   wirkte dadurch wie ein vergessener Rest.

   Sie traegt jetzt dieselbe Sprache wie der uebrige Seiteninhalt: Titel in
   Semibold mit Kupferlinie, Eintraege mit ruhigem Zeilenmass, die Anzahl
   rechts und zurueckgenommen. Kein Rahmen um die Leiste — das CI arbeitet
   mit Weissraum, nicht mit Kaesten. */

#secondary .widget {
  margin-bottom: var(--ob-space-xl);
}

#secondary .widget:last-child {
  margin-bottom: 0;
}

#secondary .widget-title,
#secondary .widgettitle,
#secondary .wp-block-heading {
  position: relative;
  margin: 0 0 var(--ob-space-md);
  padding-bottom: 10px;
  font-size: 1rem;
  font-weight: var(--ob-weight-semibold);
  line-height: 1.35;
  color: var(--ob-text-primary);
  text-transform: none;
  letter-spacing: 0;
}

/* Kupferlinie wie unter den Abschnittstiteln, nur kuerzer */
#secondary .widget-title::after,
#secondary .widgettitle::after {
  content: "";
  position: absolute;
  left: 0;
  bottom: 0;
  width: 28px;
  height: 2px;
  background: var(--ob-kupfer-500);
}

/* --- Listen --- */

#secondary .widget ul {
  margin: 0;
  padding: 0;
  list-style: none;
}

#secondary .widget ul li {
  margin: 0;
  padding: 0;
  border: 0;
  font-size: 0.9375rem;
  line-height: 1.5;
}

#secondary .widget ul li > a {
  display: flex;
  align-items: baseline;
  justify-content: space-between;
  gap: var(--ob-space-sm);
  padding: 7px 0;
  color: var(--ob-text-primary);
  text-decoration: none;
  transition: color 0.15s ease;
}

#secondary .widget ul li > a:hover,
#secondary .widget ul li > a:focus-visible {
  color: var(--ob-text-link);
}

/* Die Anzahl steht als Geschwister neben dem Link, nicht darin — deshalb
   traegt der Eintrag selbst das Flex-Layout und nicht der Link allein.

   flex-wrap ist Pflicht: die Unterliste ist ein weiteres Geschwister und
   legte sich sonst neben den Link. «Boiler» und «150 L» standen dadurch auf
   derselben Zeile. */
#secondary .widget ul li {
  display: flex;
  flex-wrap: wrap;
  align-items: baseline;
  justify-content: space-between;
  gap: 0 var(--ob-space-sm);
}

#secondary .widget ul li > a {
  flex: 1 1 auto;
  display: block;
}

#secondary .widget ul li .count {
  flex: 0 0 auto;
  font-size: 0.8125rem;
  font-variant-numeric: tabular-nums;
  color: var(--ob-text-tertiary);
}

/* Aktive Kategorie hervorheben */
#secondary .widget ul li.current-cat > a,
#secondary .widget ul li.chosen > a {
  color: var(--ob-text-link);
  font-weight: var(--ob-weight-semibold);
}

/* --- Unterkategorien -------------------------------------------------------
   Die Litergroessen haengen unter «Boiler». Ein duenner Strich links macht
   die Zugehoerigkeit sichtbar, ohne dass es nach Baumansicht aussieht. */

#secondary .widget ul li > ul.children {
  flex: 1 0 100%;
  margin: 2px 0 6px;
  padding-left: 14px;
  border-left: 1px solid var(--ob-border-subtle);
}

#secondary .widget ul li > ul.children li > a {
  padding: 5px 0;
  font-size: 0.875rem;
  color: var(--ob-text-secondary);
}

#secondary .widget ul li > ul.children li > a:hover {
  color: var(--ob-text-link);
}

/* Trennlinien nur zwischen den obersten Eintraegen */
#secondary .widget_product_categories > ul > li + li,
#secondary .widget_layered_nav > ul > li + li {
  border-top: 1px solid var(--ob-border-subtle);
}

/* --- Suchfeld --------------------------------------------------------------
   Gleiche Anmutung wie die uebrigen Eingabefelder, 44 px Mindesthoehe
   (WCAG 2.5.8). Die Beschriftung «Suchen» ueber dem Feld und der
   Absendeknopf daneben sind bei einem Feld mit Lupe redundant — beides
   bleibt fuer Screenreader erhalten, verschwindet aber optisch. */

#secondary .wp-block-search__label {
  position: absolute;
  width: 1px;
  height: 1px;
  padding: 0;
  margin: -1px;
  overflow: hidden;
  clip: rect(0 0 0 0);
  white-space: nowrap;
  border: 0;
}

#secondary .wp-block-search__inside-wrapper {
  position: relative;
}

#secondary .wp-block-search__input {
  width: 100%;
  min-height: 44px;
  padding: 10px 44px 10px 14px;
  border: 1px solid var(--ob-border-default);
  border-radius: var(--ob-radius-sm);
  background: var(--ob-surface-card);
  font-family: inherit;
  font-size: 0.9375rem;
  color: var(--ob-text-primary);
}

#secondary .wp-block-search__input:focus {
  border-color: var(--ob-border-focus);
  box-shadow: 0 0 0 3px var(--ob-petrol-100);
  outline: none;
}

#secondary .wp-block-search__button {
  position: absolute;
  top: 0;
  right: 0;
  height: 100%;
  width: 44px;
  padding: 0;
  border: 0;
  border-radius: 0 var(--ob-radius-sm) var(--ob-radius-sm) 0;
  background: transparent;
  color: transparent;
  font-size: 0;
  cursor: pointer;
}

/* Lupe als Hintergrundbild, damit der Knopf ohne Beschriftung lesbar bleibt */
#secondary .wp-block-search__button::before {
  content: "";
  position: absolute;
  inset: 0;
  background: no-repeat center / 17px 17px
    url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='%23475459' stroke-width='2' stroke-linecap='round'%3E%3Ccircle cx='11' cy='11' r='7'/%3E%3Cpath d='M20 20l-4.2-4.2'/%3E%3C/svg%3E");
}

#secondary .wp-block-search__button:hover::before {
  opacity: 0.7;
}

/* --- Attributfilter: Punkt und Text lagen uebereinander --------------------
   Shoptimizer setzt vor jeden Filtereintrag einen 8-px-Punkt als ::before mit
   «position: absolute; left: 0» und macht dafuer mit «padding-left: 20px» am
   Eintrag Platz. Mein Grundreset weiter oben setzt die Polsterung aller
   Eintraege auf 0 — damit fiel der Punkt auf den Text.

   Die Einrueckung kommt zurueck. Der Punkt wird ausserdem an der ersten
   Textzeile ausgerichtet statt ueber margin-top geschoben: 7 px Polsterung
   des Links plus halbe Zeilenhoehe minus halber Punkt ergibt 14 px. */

#secondary .widget_layered_nav ul li {
  padding-left: 20px;
}

#secondary .widget_layered_nav ul li::before {
  top: 14px;
  margin-top: 0;
}

/* Ist der Wert gewaehlt, wird der Punkt gefuellt statt nur umrandet. */
#secondary .widget_layered_nav ul li.chosen::before {
  background: var(--ob-action-primary);
  box-shadow: 0 0 0 1px var(--ob-action-primary);
}

/* Kachel hebt sich beim Ueberfahren — 150 ms nach §7.5 duration.fast.
   Der Rand bleibt, nur der Schatten waechst; so bleibt die Kachel im
   Ruhezustand identisch zu den Inhaltskarten und zeigt beim Ueberfahren
   trotzdem, dass sie anklickbar ist. */
.woocommerce ul.products li.product:hover,
.woocommerce ul.products li.product:focus-within {
  box-shadow: var(--ob-shadow-md);
}

/* --- Fuge zwischen den Produktkacheln ---------------------------------------
   Auf dem Desktop stiessen die Kacheln ohne Zwischenraum aneinander — zwei
   1-px-Raender nebeneinander ergaben eine doppelte Linie. Die Inhaltskarten
   auf den Loesungsseiten stehen mit 16 px auseinander; der Shop zieht nach.

   WICHTIG: Die Liste ist NICHT durchgaengig dasselbe Layout.
     ab  993 px  ->  display: flex, Kachelbreite 33.3053 % vom Theme
     bis 992 px  ->  display: grid, repeat(2, 1fr), gap 30/20 vom Theme

   Unterhalb 993 px gab es die Fuge also laengst — dort ist nur die Groesse
   auf 16 px zu vereinheitlichen, und die Breite darf NICHT angefasst werden:
   im Grid bestimmt die Spaltenvorlage die Zelle, eine Breite am Element
   schrumpft die Kachel nur innerhalb ihrer Zelle. Genau das ist mir beim
   ersten Anlauf passiert — 111 px breite Kacheln mit 256 px Luft dazwischen.

   Im Flex-Fall dagegen muss die Fuge von der Breite abgezogen werden, sonst
   passt die dritte Spalte nicht mehr in die Reihe und bricht um. */

.woocommerce ul.products {
  gap: var(--ob-space-md);
}

@media (min-width: 993px) {
  .woocommerce ul.products.columns-2 li.product {
    width: calc((100% - var(--ob-space-md)) / 2);
  }
  .woocommerce ul.products.columns-3 li.product {
    width: calc((100% - 2 * var(--ob-space-md)) / 3);
  }
  .woocommerce ul.products.columns-4 li.product {
    width: calc((100% - 3 * var(--ob-space-md)) / 4);
  }
}

/* --- Ungleich hohe Produktkacheln — der alte 23-px-Befund -------------------
   Kacheln einer Reihe waren unterschiedlich hoch, sobald ein Produkttitel auf
   zwei Zeilen umbrach (etwa «RS-Oekoboiler ZG 04 / 150 Liter» bei 1100 px).
   Gemessen 418 gegen 440 px, also 22 px Versatz — die Raender einer Reihe
   endeten auf verschiedener Hoehe.

   Frueher als «align-items: stretch greift nicht» notiert. Der Grund war ein
   anderer: die Kachel traegt selbst «align-self: flex-start» und schlaegt
   damit jede Vorgabe des Containers. Nicht der Container war das Problem,
   sondern das Element.

   Betrifft nur die Flex-Anordnung ab 993 px; im Grid darunter dehnen sich
   Zellen ohnehin. Die Regel schadet dort nicht.

   Der lange Selektor ist noetig: die Theme-Regel lautet
   «body:not(.static-cta-buttons) ul.products li.product» und ist damit um ein
   Element spezifischer als eine Regel, die mit .woocommerce beginnt. Ein
   erster Anlauf ohne den body-Teil wurde kommentarlos ueberstimmt. */
body:not(.static-cta-buttons) .woocommerce ul.products li.product,
body:not(.static-cta-buttons) ul.products li.product {
  align-self: stretch;
}

/* --- Modellvergleich --------------------------------------------------------
   Tabelle mit Dark-Green-Kopf nach §11.5 «Professionelle Tabellen». Neun
   Spalten passen auf breiten Schirmen; darunter rollt die Tabelle waagerecht
   in ihrem eigenen Bereich, statt die Seite zu sprengen. Die Modellspalte
   bleibt beim Rollen stehen — ohne sie weiss nach zwei Spalten niemand mehr,
   welche Zeile er liest. */

.ob-vergleich {
  margin: 0 0 var(--ob-space-lg);
}

.ob-vergleich-rollbereich {
  overflow-x: auto;
  -webkit-overflow-scrolling: touch;
  border: 1px solid var(--ob-border-subtle);
  border-radius: var(--ob-radius-sm);
  background: var(--ob-surface-card);
}

/* Sichtbarer Fokus, wenn der Bereich mit der Tastatur angesteuert wird */
.ob-vergleich-rollbereich:focus-visible {
  outline: 3px solid var(--ob-border-focus);
  outline-offset: 2px;
}

.ob-vergleich-tabelle {
  width: 100%;
  border-collapse: collapse;
  font-size: 0.875rem;
  line-height: 1.45;
  /* Ziffern gleich breit — sonst tanzen Artikelnummern und COP-Werte */
  font-variant-numeric: tabular-nums;
}

.ob-vergleich-tabelle th,
.ob-vergleich-tabelle td {
  padding: 10px 14px;
  text-align: left;
  white-space: nowrap;
  border-bottom: 1px solid var(--ob-border-subtle);
}

/* Kein «position: sticky» am Kopf: der Rollbereich hat keine feste Hoehe und
   rollt deshalb nur waagerecht — ein klebender Kopf haette hier keine Wirkung
   und waere tote Regel. Die Modellspalte klebt dagegen wirklich, sie braucht
   die waagerechte Achse. */
.ob-vergleich-tabelle thead th {
  background: var(--ob-action-primary);
  color: var(--ob-text-inverse);
  font-weight: var(--ob-weight-semibold);
  white-space: nowrap;
}

.ob-vergleich-tabelle tbody tr:nth-child(even) {
  background: var(--ob-surface-subtle);
}

.ob-vergleich-tabelle tbody tr:hover {
  background: var(--ob-petrol-50);
}

.ob-vergleich-tabelle tbody tr:last-child th,
.ob-vergleich-tabelle tbody tr:last-child td {
  border-bottom: 0;
}

/* Modellspalte bleibt beim waagerechten Rollen stehen */
.ob-vergleich-modell {
  position: sticky;
  left: 0;
  z-index: 1;
  background: var(--ob-surface-card);
  font-weight: var(--ob-weight-semibold);
  box-shadow: 1px 0 0 var(--ob-border-subtle);
}

.ob-vergleich-tabelle tbody tr:nth-child(even) .ob-vergleich-modell {
  background: var(--ob-surface-subtle);
}

.ob-vergleich-tabelle tbody tr:hover .ob-vergleich-modell {
  background: var(--ob-petrol-50);
}

.ob-vergleich-tabelle thead .ob-vergleich-modell {
  z-index: 3;
  background: var(--ob-action-primary);
  box-shadow: none;
}

.ob-vergleich-modell a {
  color: var(--ob-text-primary);
  text-decoration: none;
}

.ob-vergleich-modell a:hover {
  color: var(--ob-text-link);
  text-decoration: underline;
}

.ob-vergleich-jn {
  color: var(--ob-text-secondary);
}

.ob-vergleich-klasse {
  display: inline-block;
  padding: 1px 7px;
  border-radius: var(--ob-radius-sm);
  background: var(--ob-moos-100);
  color: var(--ob-moos-700);
  font-weight: var(--ob-weight-semibold);
  font-size: 0.8125rem;
}

.ob-vergleich-fuss {
  margin: 10px 0 0;
  font-size: 0.8125rem;
  color: var(--ob-text-tertiary);
}

/* --- Serienausstattung zweispaltig ------------------------------------------
   Sechs kurze Merkmale untereinander ergaben eine unnoetig lange Spalte.
   Zweispaltig ab 600 px, mit Haken statt Strich — es sind Ausstattungs-
   merkmale, keine Aufzaehlung. */

.ob-serie .elementor-icon-list-items {
  display: grid;
  grid-template-columns: 1fr;
  gap: 2px var(--ob-space-lg);
}

@media (min-width: 600px) {
  .ob-serie .elementor-icon-list-items {
    grid-template-columns: 1fr 1fr;
  }
}

/* Die Liste traegt zusaetzlich ob-liste. Deren Strich sitzt absolut am
   Listeneintrag bei top: .72em mit 1.15rem Platz links — der Haken erbte
   diese Position, lag unter der Textmitte und stiess fast an den Text.

   Zweiter Befund (11.09.): Auch am Eintrag verankert und auf «1lh» gemittet
   lag der Haken nicht ueberall gleich. Der Eintrag ist ein Flex-Container,
   der seinen Text vertikal zentriert; wird er hoeher — etwa weil der Nachbar
   in derselben Rasterzeile umbricht —, rutscht der Text nach unten, der Haken
   bleibt oben. Gemessen bei 700 px: «Magnesium Backup Anode» neben dem
   zweizeiligen «Service Flansch …» 11.8 px zu hoch.

   Deshalb haengt der Haken jetzt am TEXT selbst: er folgt dessen erster
   Zeile, egal wie hoch der Eintrag ist. 10 px Abstand zum Text. */
.ob-serie .elementor-icon-list-item {
  padding-left: calc(15px + 10px);
}

.ob-serie .elementor-icon-list-item::before {
  content: none;                   /* Strich aus ob-liste abschalten */
}

.ob-serie .elementor-icon-list-text {
  position: relative;
}

.ob-serie .elementor-icon-list-text::before {
  content: "";
  position: absolute;
  left: calc(-15px - 10px);
  top: .3em;                       /* Rueckfall ohne lh-Einheit */
  top: calc((1lh - 15px) / 2);
  width: 15px;
  height: 15px;
  background: no-repeat center / 15px 15px
    url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='%23355860' stroke-width='2.5' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='M20 6L9 17l-5-5'/%3E%3C/svg%3E");
}

/* --- Freigestelltes Kopfbild ------------------------------------------------
   Der Tennisball auf /unternehmen/sponsoring/ liegt bereits mit Alphakanal
   vor. Die Regel «--einpassen» legte ihm aber eine weisse Karte unter, dazu
   Rundung und Schatten — der freigestellte Ball sass dadurch in einem weissen
   Kasten mit Rand.

   «--frei» nimmt Karte, Rundung und Schatten weg. Das 4:3-Format bleibt: so
   ist der Kopfbereich genauso hoch wie auf allen anderen Unterseiten, der Ball
   steht nur direkt auf dem Grund des Abschnitts statt auf einer Flaeche.

   Nur fuer Motive mit echtem Alphakanal. Ein JPEG bekaeme hier lediglich
   seinen weissen Rand weg — der Kasten bliebe. */
.ob-kopfbild--frei img {
  object-fit: contain;
  background: none;
  border-radius: 0;
  box-shadow: none;
}

/* --- Bildreihen und Bildunterschriften (Korrekturliste 11.09.) -------------
   Bilder, die nebeneinander stehen, bekommen ein gemeinsames Format — sonst
   enden zwei Aufnahmen mit verschiedenem Seitenverhaeltnis auf verschiedener
   Hoehe und die Reihe wirkt zufaellig.
     ob-bildpaar   4:3  — Personen, Raeume, Typenschilder
     ob-bildreihe  3:2  — Arbeitsschritte (Vorlagen sind 3:2)
   Die Unterschrift sitzt 8 px unter dem Bild statt in einem eigenen Block. */

.ob-bildpaar img,
.ob-bildreihe img {
  display: block;
  width: 100%;
  object-fit: cover;
  border-radius: var(--ob-radius-sm);
  box-shadow: var(--ob-shadow-sm);
}

.ob-bildpaar img  { aspect-ratio: 4 / 3; }
.ob-bildreihe img { aspect-ratio: 3 / 2; }

/* --- Technische Hintergründe --------------------------------------------------
   Bildmaterial aus dem Produktekatalog 2026.
     ob-aufstellbild  Raumillustrationen der Aufstellorte. Die Katalogausschnitte
                      sind unterschiedlich hoch; 2:1 am Boden ausgerichtet, damit
                      die vier Karten auf einer Linie stehen.
     ob-fachbild      Schemas, Luftführung, Wartungsschritte. Nie beschneiden —
                      Beschriftungen und Nummern müssen vollständig bleiben.
                      Weisser Grund, weil mehrere PNG transparent sind. */
.ob-aufstellbild img {
  display: block;
  width: 100%;
  aspect-ratio: 2 / 1;
  object-fit: cover;
  object-position: center bottom;
  border-radius: var(--ob-radius-sm);
}

.ob-fachbild img {
  display: block;
  width: 100%;
  height: auto;
  background: #FFFFFF;
  border: 1px solid var(--ob-border-subtle);
  border-radius: var(--ob-radius-sm);
}

.elementor-widget-image figure.wp-caption {
  margin: 0;
}

.elementor-widget-image .widget-image-caption {
  margin: 8px 0 0;
  font-size: 0.875rem;
  line-height: 1.45;
  color: var(--ob-text-secondary);
  text-align: left;
}

/* --- Piktogramm als Inline-SVG ----------------------------------------------
   Farbe ueber currentColor, damit das Symbol der Primaerfarbe folgt. */
.ob-piktogramm {
  color: var(--ob-action-primary);
  line-height: 0;
  margin: 0 0 16px;
}

.ob-piktogramm svg {
  display: block;
  width: 64px;
  height: 64px;
}

/* --- Knoepfe nebeneinander ---------------------------------------------------
   Zwei gefuellte Knoepfe hintereinander tragen «_element_width: auto».
   Im Kompatibilitaetsmodus aelterer Seiten (elementor-bc-flex-widget) ist der
   Widget-Container ein Block — dort nimmt ein Block-Element auch mit
   width: auto die ganze Zeile, die Knoepfe standen untereinander.

   Erster Versuch (verworfen): den Container zum Flex-Container machen. Dann
   rutschte der erste Knopf in die 420 px NEBEN den Text, weil Ueberschrift und
   Absatz nur 780 px Lesebreite haben, und nur der zweite brach um — gemessen
   auf /loesungen/photovoltaik/: Knopf 1 bei x = 888 neben dem Text.

   Richtig ist inline-block: im Blockfluss bekommt jedes Element mit
   Lesebreite seine eigene Zeile, die Knoepfe laufen darunter nebeneinander und
   brechen auf schmalen Schirmen von selbst um. In Containern, die ohnehin Flex
   sind (Kopfbereich /kontakt/, Flexbox-Container auf /boiler-check/), ist
   inline-block wirkungslos — dort bleibt Elementors eigenes Verhalten. */
.elementor-widget-wrap > .elementor-widget__width-auto {
  display: inline-block;
  vertical-align: top;
}

/* --- Bildreihen buendig am Raster ------------------------------------------
   Elementor polstert jede Spalte einer inneren Sektion mit 15 px
   (gap: extended). Die erste Spalte beginnt dadurch 15 px rechts vom Raster —
   gemessen auf /unternehmen/ueber-uns/: Bilder bei 123 px, Ueberschriften bei
   108 px. Wie bei den Kartenreihen kommt die Fuge deshalb als flex-gap auf den
   Spaltencontainer, und die Spaltenpolsterung faellt weg: die Aussenkanten
   liegen buendig auf dem Raster.
   Bewusst NICHT ueber ob-inhaltsbild: diese Klasse steht auch in den Karten auf
   /loesungen/einfamilienhaus/, deren Polsterung das Karteninnere ist. Reihen
   ohne festes Format (Sponsoring) tragen deshalb die Markierung ob-bildfrei.
   Steht Text neben dem Bild, braucht es mehr Luft: 48 statt 24 px. */
.elementor-inner-section:has(.ob-bildpaar, .ob-bildreihe, .ob-bildfrei) > .elementor-container {
  gap: var(--ob-space-lg);
}

.elementor-inner-section:has(.ob-bildpaar, .ob-bildreihe, .ob-bildfrei):has(.elementor-widget-text-editor) > .elementor-container {
  gap: var(--ob-space-2xl);
}

.elementor-inner-section:has(.ob-bildpaar, .ob-bildreihe, .ob-bildfrei) > .elementor-container > .elementor-column > .elementor-element-populated {
  padding: 0;
}

/* --- Brotkrumen auf der Produktseite -----------------------------------------
   Auf allen Seiten und im Shop beginnt der Inhalt bei 108 px (1400 px Fenster),
   die Brotkrumen der Produktseite aber bei 113 px. Shoptimizer rechnet ihre
   seitliche Polsterung in em — und die Brotkrumen haben eine kleinere Schrift
   (13.5 statt 16 px): 2.617924em ergeben dort 35 px statt 42 px wie am
   Seitencontainer, dazu kommen im mittleren Bereich noch 5 px.
   Mit rem gerechnet stimmt es. Unterhalb 993 px folgen die Brotkrumen dem
   Einzug der Elementor-Seiten: 28 px Abschnittspolsterung + 15 px Gasse
   (Tablet) bzw. 18 + 15 px (mobil), abzueglich 15 px Containerpolsterung. */
@media (min-width: 993px) {
  .single-product .woocommerce-breadcrumb {
    box-sizing: border-box;
    padding-left: 2.617924rem;
    padding-right: 2.617924rem;
  }

  /* Die Maximalbreite braucht mehr Gewicht: Shoptimizers Inline-Regel
     (kirki-inline-styles) setzt max-width: calc(5.2325em + 1170px) — wieder
     in em, also 1240 statt 1254 px — ueber einen Selektor mit drei Klassen
     und wird zudem NACH ci.css geladen. :not(#ob-kein) hebt die Spezifitaet
     auf ID-Stufe, ohne !important. Gemessen vorher: Text bei 114 statt 108 px. */
  .single-product .woocommerce-breadcrumb:not(#ob-kein) {
    max-width: calc(1170px + 2 * 2.617924rem);
  }
}

@media (min-width: 768px) and (max-width: 992px) {
  .single-product .woocommerce-breadcrumb {
    padding-left: 28px;
    padding-right: 28px;
  }
}

@media (max-width: 767px) {
  .single-product .woocommerce-breadcrumb {
    padding-left: 18px;
    padding-right: 18px;
  }
}

/* --- Detailangaben auf Anfrage ------------------------------------------------
   Statt Datenblatt zum Herunterladen (Sonja via Ronny, 16.09.2026): ein
   Hinweis mit Sprungverweis auf das Anfrageformular weiter unten auf der
   Produktseite. Bewusst kein zweiter Knopf — er staende direkt neben «In den
   Warenkorb» und wuerde mit ihm konkurrieren. */
.ob-detailanfrage {
  margin: var(--ob-space-md) 0 0;
  color: var(--ob-text-secondary);
  font-size: .9375rem;
  line-height: 1.6;
}

.ob-detailanfrage a {
  color: var(--ob-text-link);
  font-weight: 600;
  text-decoration: none;
  white-space: nowrap;
}

.ob-detailanfrage a:hover,
.ob-detailanfrage a:focus-visible {
  color: var(--ob-text-link-hover);
  text-decoration: underline;
}
