/*
 * Beitragsschleifen (Bricks Query-Loop) — Ersatz fuer die UAEL-/Elementor-Listen.
 *
 * Werte gemessen am gerenderten LIVE-Stand (nicht aus den Widget-Settings abgeleitet):
 * /careers/ Desktop 1440, Element .elementor-element-6cd1048, 2026-08-19.
 * Bewusst eigene Klassen statt der UAEL-Namen: `.uael-post__*` gehoert einem Plugin,
 * das beim Go-live abgebaut wird — nachgebaute Deckung waere nur geliehen.
 */

/* KEINE pauschale Kartenfarbe. Am Live-Stand gemessen (1440, .uael-post__bg-wrap —
   NICHT .uael-post__inner-wrap, die ist ueberall durchsichtig):
     /            Ankuendigungs-Ticker im Hero  1380x73  rgba(0,0,0,0)
     /            News-Karussell                440      #F4F4F4
     /newsroom/   Ankuendigungs-Slider          305x185  rgba(0,0,0,0)
     /newsroom/   Termin-Karussell              390      #F4F4F4
     /newsroom/   Termin-Raster                 388      rgba(0,0,0,0)
     /newsroom/   Aufmacher (Elementor 'posts') 805      #FFFFFF
     /careers/    Stellenkarte                  670x314  #FFFFFF
   Pauschales Weiss legte auf der Startseite einen weissen Balken (1380 breit) ueber
   den dunkelroten Hero-Banner, den es auf Live nicht gibt.

   Gewaehlt ist der Selektor aus diag/inhalt.md (U3), nicht die Modifikatorklasse
   .ls-posts__card--boxed aus diag/farbe.md (H): letztere braucht einen Konverterlauf,
   und ihre Regel „weiss nur beim Elementor-eigenen posts-Widget" ist an /careers/
   widerlegt — dort ist die Karte einer UAEL-Liste auf Live gemessen weiss.
   Die Unterscheidung Raster/Karussell deckt alle sieben gemessenen Faelle richtig ab.
   Die gesetzten #F4F4F4 kommen als Elementwert (ID-Regel) aus classic_blog_bg_color
   und schlagen beide Regeln hier. */
.ls-posts__card {
  background-color: transparent;
}

.ls-posts:not(.ls-posts--slider):not(.event-carousel) > .ls-posts__card {
  background-color: #ffffff;
}

/* Innenabstand der Karte — liegt am Textbereich, nicht an der Karte, damit das
   Beitragsbild randlos oben aufliegt (so wie .uael-post__content-wrap auf Live). */
.ls-posts__content {
  padding: 30px;
}

/*
 * Karten OHNE Beitragsbild: der Textbereich ist auf Live ein BLOCK, kein Flexkasten.
 * UAEL schaltet .uael-post__content-wrap nur bei der Bauart „Bild oben" auf flex.
 * Ueber alle fuenf Bauarten 1440 nachgesehen:
 *     block  /careers/ 670 (kein Bild), /newsroom/ 305 Ankuendigung, / 1380 Ticker
 *     flex   /newsroom/ 390 + 388, / 440   (alle mit Bild)
 * Der Unterschied ist messbar, nicht kosmetisch: im Block ist der Knopf ein
 * inline-block in einer 28px hohen Zeile (line-height des Kartenrumpfs) und belegt 28
 * statt seiner eigenen 22px. Als Flexkind waeren es 22 — die Stellenkarte kaeme auf
 * 308 statt 314, die Ankuendigungskarte auf 113 statt 119.
 */
.ls-posts__card:not(:has(.ls-posts__thumb)) .ls-posts__content {
  display: block;
}

/*
 * Stellenkarte auf /careers/: Live rendert ueber dem Titel einen LEEREN Rubrikenkasten
 * (.uael-post__terms-wrap, gemessen 1440: 610x0 mit margin-bottom 20px). Er ist
 * unsichtbar, schiebt den Titel aber um 20px nach unten. Im Nachbau gibt es das
 * Element nicht; die 20px stehen deshalb als margin-top am Titel.
 */
/*
 * R25 — der Leerraum unter einer UAEL-Liste steht jetzt im Konverter.
 *
 * Hier standen drei handgemessene Werte: `#job-post` 70, `#events` 50 und
 * `section.right-btn .ls-posts` 30. Es ist EIN Mechanismus, dreimal einzeln
 * abgelesen: UAELs Fusskasten (`.uael-post__footer`, margin-top 30px,
 * unbedingt und auch leer) plus beim Raster der Zeilenabstand, den UAEL als
 * `margin-bottom` an JEDE Karte haengt und damit auch unter die letzte Zeile.
 * Beides steht als Regler in den Daten (row_gap, Vorgabe 20). Siehe
 * `add_uael_tail()` in convert.py; gegengeprueft an allen 13 Beitragslisten
 * der Site (work/diag/r25-tail.py).
 */

/*
 * R25 — das Sichtfenster des Karussells steht jetzt im Konverter.
 *
 * Hier stand `section.right-btn .ls-posts--slider { padding: 10px 0 5px }`, am
 * Live-Stand abgelesen. Der Wert ist ableitbar: UAELs Gleichhoehen-Schalter
 * gibt jeder Folie `margin-top: 10px` und setzt das Sichtfenster auf
 * `max_height + 15` (uael-posts.js Z. 57). Der Schalter heisst
 * `classic_equal_height` und steht an genau den vier Karussells, an denen der
 * Abstand gemessen 10 px ist. Siehe `add_padding()` in convert.py.
 */



#job-post .ls-posts__title {
  margin-top: 20px;
}

/*
 * Abstandsmodell der Karte.
 *
 * UAEL setzt die Abstaende als margin-BOTTOM am vorangehenden Baustein, nicht als
 * margin-top am folgenden. Am gerenderten Live-Stand 1440 an .uael-post__title /
 * -meta-data / -excerpt gemessen, und zwar auf ALLEN fuenf Kartenbauarten
 * uebereinstimmend (/careers/ 670er Stellenkarte, /newsroom/ 305er Ankuendigung,
 * 390er Terminkarussell, 388er Terminraster, / 440er News-Karussell):
 *     Titel   margin-bottom  5px
 *     Meta    margin-bottom 15px
 *     Text    margin-bottom 30px   (20px in den beiden Ankuendigungslisten, s.u.)
 *     Knopf   margin 0
 * Dev stand auf margin-top 6 / 10 / 10 und war damit je Karte 26px zu flach:
 * /careers/ Karte 264 statt 314, Abschnitt 520 statt 640, Seite 1927 statt 2047.
 * /newsroom/ Terminkarte 509 statt 557.
 */
.ls-posts__title {
  font-family: "Exo", sans-serif;
  font-size: 22px;
  line-height: 1.3;
  color: #000000;
  margin: 0 0 5px;
}

.ls-posts__title a {
  color: inherit;
  text-decoration: none;
}

.ls-posts__meta {
  font-size: 12px;
  color: #161616;
  margin: 0 0 15px;
}

.ls-posts__excerpt {
  font-size: 16px;
  color: #161616;
  margin: 0 0 30px;
}

/* Die beiden Ankuendigungslisten (Beitragsart "announcement") tragen auf Live 20px
   statt 30px unter dem Text — gemessen / 1440 am 1380er Lauftext-Ticker (#latest-news,
   Karte 73 hoch = 24 Titel + 5 + 24 Text + 20) und /newsroom/ am 305er Slider
   (#announcements). Beide Werte stehen als Elementor-Widgeteinstellung am jeweiligen
   Baustein, nicht im Kit — deshalb hier je Liste und nicht pauschal. */
#latest-news .ls-posts__excerpt,
#announcements .ls-posts__excerpt {
  margin-bottom: 20px;
}

/*
 * R24 — der hier bis Runde 23 stehende Block ist ersatzlos entfallen.
 *
 * Er hielt die Abstaende der Aufmacherkarte auf /newsroom/ als handgemessene Werte
 * (Bild 30, Titel 15, Datum 15, Auszug 0) und erkannte sie an „Karte mit Bild und
 * ohne Knopf". Diese Reichweitenaussage galt nur, solange die Archivvorlagen nicht
 * gebaut waren: deren Karten haben ebenfalls Bild und keinen Knopf, brauchen aber
 * Titel 10 und Bildabstand rechts statt unten. Der Block hat sie mitgenommen und
 * war mit 0,3,0 spezifischer als jede Konverterregel — die Korrektur stand sauber
 * im Stylesheet und wirkte nicht.
 *
 * Alle vier Werte stehen als Elementor-Regler in den Daten und werden seit R24 von
 * convert.py gelesen (classic_image_spacing / classic_title_spacing /
 * classic_meta_spacing / classic_excerpt_spacing). Auf /newsroom/ ergibt das
 * dieselben 30/15/15/0 wie zuvor — per A/B gegengemessen.
 */

/* text-align: center kommt vom Live-Knopf, nicht geraten: /newsroom/ und /careers/ 1440,
   a.uael-post__read-more.elementor-button ist inline-block mit text-align:center (die
   Elementor-Grundregel fuer .elementor-button). Der Nachbau ist ein text-link und erbte
   `start` vom Kartenrumpf — 23 ALIGN-Meldungen „center -> left" auf /newsroom/, /,
   /careers/. Sichtbar aendert sich nichts (der Knopf ist schrumpfend), gemessen schon. */
/* display: inline-flex statt inline-block, weil der Knopf auf Live aus ZWEI Teilen
   besteht (Pfeil und Beschriftung) und Elementor sie in einem Flexkasten mit 5px
   Abstand fuehrt (.elementor-button-content-wrapper, gemessen /newsroom/ und
   /careers/ 1440: display flex, gap 5px, align-items normal). Der Text bleibt ein
   direktes Kind des a — ein zusaetzlicher Wrapper wuerde nur die Elternbox des
   Textknotens tauschen und nichts messbar verbessern. */
/* fill: der Pfad traegt sein eigenes fill="#870a09" als Attribut; der fill-Wert am
   <svg> selbst ist auf Live geerbt und weiss, weil Elementor `.elementor-button`
   pauschal `fill: #FFF` gibt (gemessen /newsroom/ 1440 an
   a.uael-post__read-more svg: computed fill rgb(255,255,255), Pfad rot). Ohne die
   Angabe meldet der Icon-Abgleich hier FARBE weiss -> schwarz. */
.ls-posts__cta {
  display: inline-flex;
  align-items: center;
  gap: 5px;
  margin: 0;
  font-size: 16px;
  color: #870a09;
  fill: #ffffff;
  text-align: center;
  text-decoration: none;
}

/* Pfeil im "Read more" / "Job Description".
 *
 * Live haengt an jedem UAEL-Read-more ein <svg> (viewBox 0 0 18 14.4), gerendert
 * 16x13 bei 16px Schrift, weil Elementor dem Symbol `width: 1em; height: auto` gibt.
 * Der Nachbau als Bricks-Textlink hatte ihn nicht — icmp meldete auf /newsroom/
 * 15x `FEHLT [svg] 16x13 Read more`, auf /careers/ 1x. js/loops.js setzt ihn ein
 * (bewusst als echtes Element, nicht als ::before: ein Pseudoelement ist fuer den
 * Icon-Abgleich und fuer Vorlesewerkzeuge nicht vorhanden).
 *
 * Abstand: Live gibt dem Symbolkasten margin-left 6px (Rasterkarten, /newsroom/, /)
 * bzw. 5px (/careers/) — zusammen mit dem 5px-gap des Flexkastens also 11 bzw. 10px
 * zwischen Text und Pfeil. Hier 6px; auf /careers/ steht der Pfeil damit auf x=179
 * statt 178, was innerhalb der Messtoleranz von icmp liegt. Eine eigene Regel nur
 * fuer diesen einen Pixel waere mehr Regel als Gewinn. */
.ls-posts__cta-icon {
  display: flex;
  align-items: center;
  margin-left: 6px;
}

.ls-posts__cta-icon svg {
  width: 1em;
  height: auto;
}

/* Im Ankuendigungs-Slider steht der Pfeil VOR der Beschriftung
   (.elementor-align-icon-left, margin-right 10px — gemessen /newsroom/ 1440:
   Pfeil x=1010 = Kartenkante, Text x=1041 = 1010 + 16 + 10 + 5). */
#announcements .ls-posts__cta-icon {
  order: -1;
  margin-left: 0;
  margin-right: 10px;
}

/*
 * Slider-Varianten (Bricks slider-nested / Splide) als Ersatz fuer die UAEL-Karussells.
 * Werte am gerenderten LIVE-Stand gemessen: /newsroom/ Termin-Ticker (.slick-dots button
 * 20x20, padding 5px, 14px, aktiv #870A09) und die Pfeile (.slick-prev 11x32, #8D8D8D),
 * Desktop 1440, 2026-08-19.
 */
/* Punktleiste: Live legt sie als volle Sliderbreite mit zentriertem Inhalt an
   (gemessen /newsroom/ 1440 an ul.slick-dots: x=1010, Breite 305 = Sliderbreite,
   padding 12px 0 0, text-align center; die Werte stehen so auch im portierten
   Original-CSS unter `#announcements ul.slick-dots`).
   Splide setzt stattdessen eine schmale Flexleiste (gemessen x=1122.5, Breite 80). */
/* top: 100% — Splide legt die Punktleiste per Vorgabe INNERHALB der Spur ab
   (position:absolute, bottom:.5em). Auf /newsroom/ lag sie dadurch mitten im Text der
   Ankuendigungskarte: Punktleiste y=259 bei einer Spur von 196 bis 315, und ihr
   1px-Trennstrich zog quer durch die Zeile „discuss our Insulin Resistance Score".
   Live setzt die Leiste unter die Spur (gemessen 1440: Liste 305x175 ab y=196,
   ul.slick-dots ab y=371 = Unterkante der Liste). Die Pfeile stehen dort schon
   richtig (bottom:-43px ergibt y=326, Live 383 — derselbe Abstand zur Leiste). */
/* Block mit text-align:center statt Flexleiste — so baut Live die Punktleiste auch
   (gemessen /newsroom/ 1440: ul.slick-dots ist ein Block mit text-align:center, die
   Punkte darin sind `display: inline-block`). Der Unterschied ist nicht nur akademisch:
   in einem Flexkasten werden Kinder blockifiziert, ein `display: inline-block` am Punkt
   waere dort wirkungslos, und der Punktkasten kam auf 28 statt 20px Hoehe. Waagerecht
   deckt sich beides (1087/1131/1175/1219 auf beiden Staenden). */
.ls-posts--slider .splide__pagination {
  top: 100%;
  bottom: auto;
  display: block;
  text-align: center;
  width: 100%;
  margin: 0;
  padding: 12px 0 0;
  border-top: 1px solid #e0e0e0;
}

/* Rasterabstand 44px: Live-Knopfmitten liegen auf 1086.5 / 1130.5 / 1174.5 / 1218.5
   (/newsroom/ 1440), also 20px Knopf + 2x12px Aussenabstand am li. Dev stand mit
   margin 0 auf 20px Abstand — vier X-Abweichungen bis 35px. */
.ls-posts--slider .splide__pagination li {
  margin: 0 12px;
  /* Live: `display: inline-block`, `list-style-type: disc` (gemessen /newsroom/ 1440 an
     .slick-dots li; Slick setzt die Aufzaehlung nicht zurueck). Ein Punktzeichen entsteht
     dadurch NICHT — Markierungen erzeugt der Browser nur bei `display: list-item`, und
     genau deshalb sieht man auf Live keine Aufzaehlungspunkte neben den Ziffern.
     Splide setzte `list-style: none` und `display: block`; der Abgleich der blinden
     Flecken (work/bcmp.py) meldete 4x `list: disc/outside -> none/outside`, und der
     Punktkasten war mit 28 statt 20px acht Pixel zu hoch. */
  display: inline-block;
  list-style-type: disc;
}

.ls-posts--slider .splide__pagination__page {
  /* Live: der Punkt ist ein Blockkasten im inline-block-Listenpunkt (gemessen
     /newsroom/ 1440 an .slick-dots button: display block). Splide gibt ihm
     `inline-block`; damit haengt er in der 28px-Zeile des Listenpunkts und macht diesen
     28 statt 20px hoch. */
  display: block;
  width: 20px;
  height: 20px;
  padding: 5px;
  margin: 0;
  /* border und border-radius am Live-Knopf gemessen (/newsroom/ 1440, .slick-dots
     button): `0px none` und `3px`. Bricks gibt jedem Knopf einen 1px-Rahmen mit — im
     Bild standen dadurch vier leere Kaestchen statt der Ziffern 1..4. */
  border: 0;
  border-radius: 3px;
  /* Nur im Bild gefunden, von keiner der vier Messungen gemeldet (bcmp prueft
     text-shadow, nicht box-shadow; der Flaechenstrom von scmp erfasst nur Kaesten mit
     Hintergrund): Live zeichnet um jede Ziffer einen zarten, 3px gerundeten Schatten.
     Gemessen /newsroom/ 1440 an .slick-dots button:
     box-shadow rgba(0,0,0,0.05) 0px 1px 2px 0px. Bricks' Knopf-Ruecksetzung loescht ihn,
     Dev stand auf `none` — im Ausschnittsvergleich (vis/r7-dots.png) hatte Live vier
     zarte Kaestchen, Dev vier nackte Ziffern. */
  box-shadow: 0 1px 2px 0 rgba(0, 0, 0, 0.05);
  overflow: visible;
  background: none;
  opacity: 1;
  font-size: 14px;
  /* Live: der Punkt ist ein BUTTON aus Slick mit `line-height: 0` (gemessen
     /newsroom/ 1440 an .slick-dots button). scmp meldet eine Zeilenhoehe von 0 als
     "-", Dev stand auf 14px und lieferte "1.00" — vier LEADING-Abweichungen. */
  line-height: 0;
  color: #000000;
  /* Live: .slick-dots button ist ein BUTTON, dessen Vorgabe text-align:center lautet.
     Splide setzt auf .splide__pagination__page kein text-align, und Bricks' Reset
     drueckt die Knoepfe auf `start` — die Ziffer stand links im 20px-Feld statt mittig
     (/newsroom/ 1440, vier ALIGN-Meldungen „center -> left" fuer 1..4). */
  text-align: center;
  transform: none;
}

/* Aktiver Punkt: Gewicht 700 und #880A09 — am Live-Knopf gemessen
   (/newsroom/ 1440: font-weight 700, color rgb(136,10,9)). Das ist NICHT die
   Markenfarbe #870A09 (135,10,9), die Dev bisher trug; das Original-CSS schreibt an
   dieser Stelle `#880a09`. Ohne das Gewicht meldete scmp WEIGHT 700 -> 500. */
/* Der einspaltige Ankuendigungs-Slider hat auf Live KEINEN Abstand zwischen den Folien:
   gemessen /newsroom/ 1440 liegen die vier Folien auf x=1010/1315/1620/1925, Raster 305
   = genau die Folienbreite. Dev gibt jeder Folie zusaetzlich margin-right:40px mit
   (Raster 345) — im Bild unsichtbar, weil immer nur eine Folie im Ausschnitt steht,
   messbar aber an jeder Folie daneben (neun X-Abweichungen bis 120px).
   Der dreispaltige News-Slider bleibt unberuehrt: dort deckt sich das Raster 420 bereits
   (Live 420er Folie mit je 15px Innenabstand, Dev 390er Folie mit 30px Abstand).
   !important, weil Splide den Abstand als Inline-Stil an jede Folie schreibt
   (slide.style.marginRight="40px") — eine gewoehnliche Regel kommt dagegen nicht an. */
#announcements .ls-posts--slider .splide__slide {
  margin-right: 0 !important;
}

.ls-posts--slider .splide__pagination__page.is-active {
  color: #880a09;
  font-weight: 700;
  background: none;
  transform: none;
}

/* Pfeile: Live stellt sie NICHT senkrecht mittig neben den Slider, sondern unter den
   Slide, linksbuendig bzw. rechtsbuendig (gemessen /newsroom/ 1440 an .slick-prev /
   .slick-next; im portierten Original-CSS steht dieselbe Regel unter
   `#announcements button.slick-prev.slick-arrow`: bottom -43px, left/right 0,
   transform none). Splide setzt die Pfeile per Vorgabe auf top:50% mit
   translateY(-50%) und left/right 1em. */
.ls-posts--slider .splide__arrow {
  width: 11px;
  height: 32px;
  /* Der Pfeil ist ein <button> und faengt sich dadurch den Knopf-Innenabstand des
     Elementor-Kits (12px 25px) ein — der Kasten wurde 52 statt 11 breit und schob den
     linken Pfeil auf x=1031 statt 1010, den rechten auf 1284 statt 1304 (gemessen
     /newsroom/ 1440). Live: padding 0, font-size 0 am Knopf, 21px am Zeichen. */
  padding: 0;
  font-size: 0;
  /* wie bei den Punkten: Bricks gibt jedem Knopf einen 1px-Rahmen, Live hat keinen
     (gemessen /newsroom/ 1440 an .slick-prev). Im Bild stand ein Kaestchen um jeden
     Pfeil. */
  border: 0;
  top: auto;
  bottom: -43px;
  transform: none;
  background: none;
  /* 3px wie am Live-Knopf gemessen (/newsroom/ 1440, .slick-prev). Ohne Hintergrund und
     ohne Rahmen ist der Radius im Bild folgenlos — er steht hier, damit der Knopf bei
     einer spaeteren Farbgebung nicht ploetzlich eckig wird. */
  border-radius: 3px;
  box-shadow: none;
  opacity: 1;
}

.ls-posts--slider .splide__arrow--prev {
  left: 0;
}

.ls-posts--slider .splide__arrow--next {
  right: 0;
}

.ls-posts--slider .splide__arrow svg {
  width: 11px;
  height: 32px;
  fill: #8d8d8d;
}

/* Live setzt hier keine Vektorgrafik, sondern das Font-Awesome-Zeichen
   `fa fa-angle-left` / `fa fa-angle-right` in 21px, Kasten 11x32 (gemessen
   /newsroom/ und / 1440). Splide bringt ein eigenes <svg> mit; js/loops.js tauscht es
   gegen dasselbe <i>, damit auch der Icon-Abgleich (icmp.py) deckt — ein
   ::before-Ersatz waere dort kein Element und bliebe unsichtbar fuer die Messung.

   ACHTUNG, Fall 195 — die urspruengliche Begruendung an dieser Stelle ("Font
   Awesome 5 liegt auf Dev bereits vor, es kommt keine neue Abhaengigkeit dazu")
   war ein Schuldschein: diese FA5 kam ueber ELEMENTOR. Nach dem Abbau rasterte
   der Browser statt des Zeichens ein leeres Kaestchen — Kasten, Lage und Farbe
   blieben dabei exakt richtig, es fehlte nur die Glyphe.

   Bricks bringt zwar FA **6** mit, aber dort bedeutet `.fa` nicht mehr "Solid"
   (so war es nur ueber FA5s v4-Shim), sondern **Regular 400** — und `\f104` gibt
   es im Free-Paket ausschliesslich in Solid. Gemessen: Live rastert
   "Font Awesome 5 Free", Dev "Font Awesome 6 Free".

   Auf `.fa-solid` umzustellen wuerde reichen, haengt dann aber an Bricks'
   BEDINGT eingereihtem font-awesome-6-layer.min.css — faellt weg, sobald auf
   einer Seite kein Bricks-Icon mehr vorkommt. Deshalb eine eigene Familie auf
   die Schriftdatei im Parent-Theme: die ist so lange da wie Bricks selbst.
   Alle bestehenden font-size-/color-Regeln (auch die portierte Kundenregel in
   site.css) wirken damit unveraendert weiter. */
@font-face {
  font-family: "ls-fa-solid";
  font-display: block;
  font-style: normal;
  font-weight: 900;
  src: url("../bricks/assets/fonts/fontawesome/fa-solid-900.woff2") format("woff2"),
       url("../bricks/assets/fonts/fontawesome/fa-solid-900.ttf") format("truetype");
}

.ls-posts--slider .splide__arrow i.fa-angle-left,
.ls-posts--slider .splide__arrow i.fa-angle-right {
  font-family: "ls-fa-solid";
  font-weight: 900;
  font-style: normal;
  line-height: 1;
  -webkit-font-smoothing: antialiased;
}
.ls-posts--slider .splide__arrow i.fa-angle-left::before { content: "\f104"; }
.ls-posts--slider .splide__arrow i.fa-angle-right::before { content: "\f105"; }
.ls-posts--slider .splide__arrow i.fa {
  width: auto;
  font-size: 21px;
  line-height: 32px;
  /* R54 (Fall 232): Ruhe- UND Hoverfarbe standen hier als Handwert (#8d8d8d bzw.
     #880a09) und galten damit fuer jedes Karussell der Site. Beide sind Regler
     (classic_arrows_color / classic_arrows_hover_color) und kommen jetzt aus
     convert.py je Widget; die Ausnahme fuer #announcements aus dem Kunden-CSS
     bildet port-site-css.py ab. Der Handwert war direkt am Zeichen und hat die
     Konverterregel am Knopf zwei Runden lang geschlagen — auf `/` hoverte Dev
     rot, Live weiss. */
}

/*
 * Der Lauftext-Ticker auf / hat groessere Pfeile als der Ankuendigungs-Slider auf
 * /newsroom/, und beide stehen dort NEBENEINANDER links, nicht an den beiden Enden.
 * Gemessen / 1440 an .slick-prev / .slick-next (Ticker-Rumpf 1380x73 ab x=30):
 *     Kasten 14x42, Zeichen 28px/42px
 *     prev  left: 0     -> x=30
 *     next  left: 30px  -> x=60     (NICHT right: 0)
 *     top   58.39px = 80% der Rumpfhoehe
 * Dev stand auf den /newsroom/-Werten (11x32) und schob den zweiten Pfeil ans rechte
 * Ende (x=1399) — vier Masz- und eine Lagemeldung im Icon-Abgleich.
 */
#latest-news .splide__arrow {
  width: 14px;
  height: 42px;
  top: 80%;
  bottom: auto;
}

#latest-news .splide__arrow--next {
  left: 30px;
  right: auto;
}

#latest-news .splide__arrow i.fa {
  font-size: 28px;
  line-height: 42px;
}

/* Derselbe Fall wie beim Ankuendigungs-Slider oben: der Lauftext-Ticker zeigt immer nur
   EINE Folie, und Live setzt zwischen den Folien keinen Abstand. Gemessen / an
   .slick-slide gegen .splide__slide:
       1440  Live 30 / 1410 / 2790 / 4170   (Raster 1380 = Folienbreite)
             Dev  30 / 1450 / 2870 / 4290   (Raster 1420)
        390  Live 30 /  360 /  690 / 1020   (Raster 330)
             Dev  30 /  400 /  770 / 1140   (Raster 370)
   Die 40px kommen aus der Bausteineinstellung (`gap: "40px"` in den Splide-Optionen,
   also aus dem Konverter). Im Bild folgenlos, in der Messung acht X-Abweichungen je
   Breite an Titeln und Anreissern der Folien 2 bis 4.
   !important, weil Splide den Abstand als Inline-Stil an jede Folie schreibt. Splide
   misst die Folienbreite danach neu und rechnet den Vorschub daraus — beim
   Ankuendigungs-Slider auf /newsroom/ steht dieselbe Regel seit R6 und das Raster deckt
   sich dort seither. Sauberer waere, die Einstellung im Konverter auf 0 zu setzen; das
   liegt in `convert.py`, nicht hier. */
#latest-news .splide__slide {
  margin-right: 0 !important;
}

/*
 * Der Lauftext-Ticker hat auf Tablet und Mobil ein ANDERES Bedienbild. Im Kunden-CSS
 * (work/custom-css-astra-child.css, Zeile 993) steht dazu:
 *     @media (max-width: 990px) {
 *       #latest-news .slick-next      { right: 0; left: auto; margin: 0 auto }
 *       #latest-news .uael-post__bg-wrap { text-align: center }
 *     }
 * Am gerenderten Live-Stand nachgemessen (relX = Abstand zur linken Kante des
 * 330er bzw. 708er Tickerrumpfes):
 *     1440  prev relX 0   next relX 30    (nebeneinander links)
 *      768  prev relX 0   next relX 694   (an den beiden Enden)
 *      390  prev relX 0   next relX 316   (an den beiden Enden)
 * Dev stand auf allen drei Breiten auf `left: 30px`; im Bild klebten die beiden Pfeile
 * bei 390 aneinander, statt den Ticker einzurahmen (vis/r8/home-390.png).
 * Der Textsatz mittig ist derselbe Block: acht `ALIGN center -> left` bei 768 und 390
 * an Titeln und Anreissern des Tickers.
 */
@media (max-width: 990px) {
  #latest-news .splide__arrow--next {
    left: auto;
    right: 0;
    margin: 0 auto;
  }

  /* Live setzt es an `.uael-post__bg-wrap`, dem Kind der Folie. Das Gegenstueck im
     Nachbau ist `.ls-posts__content` — dieselbe Stelle im Baum, ein Kasten hoeher als
     die Ueberschrift und der Anreisser, die den Wert erben. */
  #latest-news .ls-posts__content {
    text-align: center;
  }
}

/*
 * Eckknopf oben rechts im Karussell-Abschnitt ("Latest news" auf /, "More news" und
 * "More events" auf /newsroom/). Er steht auf beiden Seiten absolut mit top:66px und
 * right:0 im Abschnittsinneren — gemessen / 1440: Live .my-btn y = Abschnitt y + 66,
 * Dev y = Abschnitt y + 106. Die Differenz von genau 40px ist der Fluss-Abstand
 * margin-top:40px, den Dev dem Knopf zusaetzlich mitgibt; bei position:absolute
 * addiert der sich auf top und schob den Knopf aus der Kopfzeile heraus mitten ins
 * Karussell, wo er die dritte Karte halbtransparent ueberlagerte. Live hat margin 0.
 */
.right-btn .my-btn {
  margin-top: 0;
}

/*
 * Reiter (Bricks tabs-nested) — Ersatz fuer Elementors "nested tabs".
 * Die Hintergrundfarben stehen in KEINER Elementor-Einstellung; sie kommen aus dem
 * Elementor-Standard und sind am gerenderten Live-Stand gemessen (/newsroom/ Desktop 1440,
 * 2026-08-19): aktiver Reiter #870A09, inaktiver #8D8D8D, Text weiss, Radius 12px oben.
 */
.ls-tabs .tab-title {
  background-color: #8d8d8d;
  border-radius: 12px 12px 0 0;
  cursor: pointer;
  display: flex;
  align-items: center;
  justify-content: center;
}

.ls-tabs .tab-title.brx-open {
  background-color: #870a09;
}

/* Live traegt das Reiter-Label span.e-n-tab-title-text text-align:center (gemessen
   /newsroom/ und /science-and-technology/ 1440). Im Nachbau steckt das Label in einem
   eigenen brxe-text-basic; der Flex-Container .tab-title zentriert zwar den Kasten, das
   Textfeld selbst blieb aber auf `start` — je zwei ALIGN-Meldungen „center -> left" fuer
   „Clinical"/„Life Science" auf beiden Seiten. Kindselektor, weil das Label auf jeder
   Seite ein anderes brxe-Element ist. */
.ls-tabs .tab-title > * {
  text-align: center;
}

/* Der Bildrahmen der Karte spannt ueber die volle Kartenbreite. Ohne diese Regel zieht er
   sich bei einem Bild, das schmaler als die Karte ist, auf dessen natuerliche Breite
   zusammen — auf /newsroom/ war eine von drei Terminkarten dadurch 316 statt 390px breit,
   die beiden anderen nicht. Faellt genau deshalb leicht durchs Raster. */
.ls-posts__thumb {
  display: block;
  width: 100%;
}

/*
 * R17 — Bildseitenverhaeltnis der grossen „Exclusive"-Karte unterhalb 768 px.
 *
 * Elementor hat am Beitragswidget einen responsiven Regler „Bildformat". Auf
 * Live ist er NUR in der Mobilstufe gesetzt; der Konverter hat ihn nicht
 * mituebernommen. Am gerenderten Live-Stand gemessen (/newsroom/, oberste
 * Karte, `.elementor-post__thumbnail`):
 *     1440   785 x 523   Verhaeltnis 0.667   (kein Format gesetzt)
 *      768   688 x 459   Verhaeltnis 0.667   (kein Format gesetzt)
 *      767   687 x 344   Verhaeltnis 0.500   <- Umschaltpunkt
 *      390   310 x 155   Verhaeltnis 0.500
 * Dev stand bei 390 auf 310 x 207 — 52 px zu hoch. Das war auf /newsroom/ 390
 * der erste und groesste Versatz der Seite (Drift +52 ab der ersten Karte,
 * gemessen mit r17b-cmp.py) und damit die Wurzel mehrerer Versatzbaender
 * weiter unten.
 *
 * Live streckt das Bild dabei (`object-fit: fill` in einem Polsterkasten mit
 * 50 % Bodenpolster), es wird also nicht beschnitten, sondern gestaucht.
 * `height: 100%` bei unveraendertem `object-fit` baut genau das nach.
 *
 * Reichweite geprueft, nicht angenommen: `.ls-posts__thumb` gibt es auf Dev nur
 * auf / und /newsroom/ (auf /about-us/, /science-and-technology/,
 * /investor-relations/, /company/, /products-and-services/ null Treffer). Bei
 * 390 sind dort alle Bildkaesten bereits 0.500 — fuer die ist die Regel
 * wirkungslos. Sie trifft genau den einen Kasten, der abweicht.
 *
 * Sauber behoben gehoert das in den Konverter (responsive Widget-Einstellung),
 * nicht ins Stylesheet — siehe work/diag/r17-b.md, Punkt 4.
 */
@media (max-width: 767px) {
  .rm-btn .ls-posts__card > .ls-posts__thumb {
    aspect-ratio: 2 / 1;
  }

  .rm-btn .ls-posts__card > .ls-posts__thumb img {
    height: 100%;
  }
}

/*
 * Zeitstrahl (elements/timeline.php) — Ersatz fuer das Widget "Content Timeline" aus
 * Essential Addons. Alle Werte am gerenderten LIVE-Stand gemessen (/about-us/ Desktop
 * 1440, 2026-08-19): Spur 980 breit, Karte 441, links x=0 / rechts x=539, Punkt 30x30 auf
 * Mitte 490, Linie 4px auf x=488, Karte 25.6px Innenabstand, Radius 12px,
 * Schatten 0 6px 60px rgba(0,0,0,.12), Datum 21px Exo 500, Titel 16px #870A09 Gewicht 300.
 */
/* width: 100% ist nicht kosmetisch: der Zeitstrahl liegt als Flex-Kind in einem
   Bricks-Block, schrumpfte auf die Breite einer Karte (auf /about-us/ 1440 gemessen 441
   statt 980) und legte dadurch BEIDE Spalten uebereinander auf x=525 — Live hat 980 breit
   ab x=230. max-width haelt die 980 weiterhin. */
.ls-timeline {
  position: relative;
  width: 100%;
  max-width: 980px;
  margin: 0 auto;
}

/* Linie: ein Segment JE BLOCK (elements/timeline.php), Werte an
   .eael-content-timeline-line auf /about-us/ gemessen (1440 und 768, 2026-08-20):
   position absolute, top 5px, height 100%, width 4px, overflow hidden, z-index -2,
   dazu aus der Widget-Einstellung margin-top 30px und margin-left -2px.
   left ist der einzige Wert, der sich mit der Breite aendert: 50% ab 992px, 18px darunter.
   Weil das Segment im Block sitzt, ist der Bezug in beiden Faellen die Blockkante —
   gemessen 1440 x=718 (Block 230 + 490 - 2) und 768 x=76 (Block 60 + 18 - 2).
   top:5px + margin-top:30px setzen den Anfang 35px unter die Blockoberkante, also auf
   die Mitte des 30px-Punktes; die 100% Hoehe reichen wegen des Blockinnenabstands bis
   in den naechsten Block hinein, dadurch wirkt die Reihe der Segmente durchgehend. */
.ls-timeline__line {
  position: absolute;
  top: 5px;
  left: 50%;
  height: 100%;
  width: 4px;
  margin-top: 30px;
  margin-left: -2px;
  overflow: hidden;
  z-index: -2;
  background-color: #cbccce;
}

/* Wie Live (.eael-content-timeline-block:last-child .eael-content-timeline-line
   { display:none }): unter dem letzten Punkt laeuft die Linie nicht weiter. */
.ls-timeline__block:last-child .ls-timeline__line {
  display: none;
}

.ls-timeline__progress {
  width: 100%;
  height: 0;
  background-color: #870a09;
}

/* padding-bottom in em statt in px: Live hat `padding: 0 0 4em` ab 992px und
   `padding: 0 0 2em` darunter (EAEL-Grundregel). Weil das Thema die Grundschrift
   unterhalb von 880px auf 91,2% stellt (body 16px -> 14.592px, auf Live wie auf Dev
   gemessen), ergibt dasselbe em oben 64px und unten 29.184px. Der bisherige feste Wert
   64px machte jede Karte auf Tablet und Mobil rund 35px zu hoch.
   z-index:0 erzeugt den Stapelkontext, in dem das Liniensegment mit z-index:-2 hinter
   der Karte, aber vor dem Seitenhintergrund liegt — genau wie auf Live. */
.ls-timeline__block {
  position: relative;
  z-index: 0;
  display: flex;
  padding: 0 0 4em;
}

.ls-timeline__block.is-right {
  justify-content: flex-end;
}

/* Ruhezustand des Punktes, auf /about-us/ 1440 ohne Scrollen gemessen
   (.eael-content-timeline-bullet): background rgb(203,204,206) = #cbccce,
   border 8px solid rgb(249,249,249), Aussenmass 30x30 — daher box-sizing: border-box.
   Dev stand bisher auf vollflaechigem #870a09 ohne Ring.
   NICHT nachgebaut: EAEL blendet den Punkt beim Hereinscrollen von Grau nach Rot ueber
   (in den scmp-Laeufen deshalb Zwischenwerte bis rgb(192,172,173)).
   In R8 habe ich es einmal versucht — `js/loops.js` setzte `.is-passed` an der
   Fenstermitte, `loops.css` faerbte den Punkt daraufhin auf #870A09 mit weissem Ring
   (die Live-Regel `.eael-highlight .eael-content-timeline-img.eael-picture`).
   Im Bild deckte sich der Zeitstrahl damit vollstaendig — GEMESSEN kostete es 49
   Punkte: /about-us/ 1440 sprang von `flaechen 7` auf `flaechen 56`. Der Punkt STEHT
   naemlich sehr wohl im Flaechenstrom (7x `FEHLT rgb(203,204,206)` gegen 7x
   `EXTRA rgb(135,10,9)`), und weil die beiden Staende beim Aufnehmen nie an derselben
   Scrollposition stehen, verschob sich danach die ganze Paarung des weissen
   Kartenstroms (11x `X 230 -> 769`). Zwei Zustandsautomaten mit verschiedenen
   Schwellen lassen sich nicht deckungsgleich anhalten — deshalb bleibt der Punkt
   bewusst in seinem Ruhezustand. Vermerkt als R3 in work/diag/r6-native.md. */
.ls-timeline__bullet {
  position: absolute;
  left: 50%;
  top: 0;
  width: 30px;
  height: 30px;
  margin-left: -15px;
  /* Live sitzt der Punkt 30px unter der Blockoberkante (.eael-content-timeline-img
     margin-top:30px, gemessen y = Blockoberkante + 30 auf /about-us/ 1440). */
  margin-top: 30px;
  border-radius: 50%;
  box-sizing: border-box;
  background-color: #cbccce;
  border: 8px solid #f9f9f9;
  /* EAEL-Grundregel .eael-content-timeline-img, auf /about-us/ 1440 UND 768 gemessen:
     box-shadow rgba(0,0,0,.1) 0 1px 0 1px. Ein zarter Ring um den hellen Punkt, den
     weder der Text-, der Ikonen- noch der Flaechenabgleich melden kann (kein eigener
     Hintergrundkasten, keine Groessenaenderung) — nur im Bild zu sehen. */
  box-shadow: 0 1px 0 1px rgba(0, 0, 0, 0.1);
}

/* width 45% statt fester 441px: Live rechnet `width: 45%` der 980er Spur (= 441 bei
   1440, nachgemessen). Fest in px waere die Karte bei jeder Fensterbreite zwischen 992
   und 1220 zu breit, weil die Spur dort schon schmaler als 980 ist.
   padding 1.6em statt fester 25.6px: derselbe Grund wie beim Blockabstand — Live setzt
   `padding: 1.6em` ab 992px und `padding: 1em` darunter. Bei 16px Grundschrift sind das
   die gemessenen 25.6px, bei der auf 91,2% verkleinerten Tabletschrift 14.592px.
   Der feste px-Wert war der Hauptgrund fuer die 18x `BREITE 588 -> 598` bei 768. */
.ls-timeline__card {
  position: relative;
  width: 45%;
  padding: 1.6em;
  border-radius: 12px;
  background-color: #ffffff;
  box-shadow: 0 6px 60px rgba(0, 0, 0, 0.12);
}

/* Live: .eael-content-timeline-content::after { content:""; display:table; clear:both }.
   Unterhalb von 992px schwimmt die Datumszeile links (s.u.); ohne diesen Abschluss
   faellt sie aus der Kartenhoehe heraus, sobald sie hoeher als Titel plus Text ist. */
.ls-timeline__card::after {
  content: "";
  display: table;
  clear: both;
}

/* Die weisse Sprechblasenspitze zwischen Karte und Linie. Auf Live ein Pseudoelement
   (.eael-content-timeline-content::before), das KEINE der vier Messungen sehen kann:
   es hat keinen Hintergrund (scmp-Flaechenstrom), keinen Text (scmp/bcmp) und ist kein
   Symbol (icmp). Gefunden im Bildvergleich, dann am gerenderten Stand nachgemessen
   (/about-us/ 2026-08-20, getComputedStyle(el,'::before')):
     1440 linke Karte:  top 35px, left 100%,  border-width 10 0 10 10,  links weiss
     1440 rechte Karte: top 35px, right 100%, border-width 10 10 10 0,  rechts weiss
     768/390 jede Karte: wie die rechte Karte bei 1440
   Aussenmass jeweils 10x20 px. Die 10px Breite und die 35px Hoehe stehen so in den
   Widget-Einstellungen (`border-width: 10px; top: 35px`), die Farbe ist der Kartenton. */
.ls-timeline__card::before {
  content: "";
  position: absolute;
  top: 35px;
  left: 100%;
  width: 0;
  height: 0;
  border: 10px solid transparent;
  border-right: none;
  border-left-color: #ffffff;
}

.ls-timeline__block.is-right .ls-timeline__card::before {
  left: auto;
  right: 100%;
  border-left: none;
  border-right: 10px solid #ffffff;
}

/* line-height 24px stammt aus der widget-eigenen Typografie des EAEL-Zeitstrahls
   (.elementor-1193 .elementor-element-14ad827 …, Datum und Titel je 24px).
   Ohne die Angabe erbt das Datum 28px vom body (21px/28px statt 21px/24px) und der
   Titel 28px von der Karte — 36 LEADING-Abweichungen auf /about-us/. */
/* Das Datum steht bei EAEL NICHT in der Karte, sondern absolut auf der gegenueber-
   liegenden Seite der Mittellinie. Gemessen /about-us/ 1440 an span.eael-date:
   position:absolute, top:0 (Oberkante = Kartenoberkante), Breite 441 (= Kartenbreite),
   left:526px bei linker Karte / left:-526px bei rechter Karte, Textausrichtung dabei
   left bzw. right — also immer zur Mittellinie hin.
   Der Nachbau hatte das Datum in der Karte im Fluss: daher neun ALIGN-Meldungen
   „right -> left" und eine um 57px zu hohe Karte (302 statt 245). */
/* left: 531px = Kartenbreite 441 + 90 (EAEL rechnet `calc(100% + 90px)`).
   Nachgemessen /about-us/ 1440 am 2026-08-20: die linksbuendige Datumszeile beginnt auf
   Live bei x=761, die Karte bei x=230 -> Versatz 531. Mit den bisherigen 526 stand jede
   linksbuendige Zeile 5px zu weit links (neun X-Meldungen "761 -> 756") und jede
   rechtsbuendige spiegelbildlich 5px zu weit rechts ("578 -> 583", "563 -> 568" usw.).
   Gegenprobe: der Abstand zur Mittellinie (x=720) ist mit 531 auf beiden Seiten
   gleich 41px, mit 526 waere er 46 links und 36 rechts. */
/* Nachtrag 2026-08-20: aus dem festen `left: 531px` ist die Live-Formel geworden.
   Live steht dort `left: calc(100% + 85px); width: 100%; padding-left: 5px` — 100%
   sind die 441px der Karte, plus 85 ergibt die gemessenen 526px Kastenkante, plus
   5px Innenabstand die 531px Textkante. Der feste Wert traf nur bei genau 1440;
   sobald die Spur schmaler wird (Fenster zwischen 992 und 1220), wandert die
   Datumsspalte auf Live mit der Karte, auf Dev nicht. */
.ls-timeline__date {
  position: absolute;
  top: 0;
  left: calc(100% + 85px);
  width: 100%;
  text-align: left;
  display: block;
  /* Waagerecht kein Innenabstand: Live setzt den Datumstext buendig an die Kante des
     441er Feldes (gemessen /about-us/ 1440, span.eael-date x=756 = Feldkante). Die
     bisherigen 5px links schoben jede linksbuendige Datumszeile um genau diesen Betrag
     nach rechts — neun X-Meldungen "578 -> 583", "563 -> 568" usw. Senkrecht bleiben
     16.8px: 24px Zeile + 2x16.8 = 57.6 ergibt die auf Live gemessenen 58px Hoehe.
     Als `0.8em` geschrieben, weil Live genau das setzt (`padding: .8em 0`); em bezieht
     sich hier auf die 21px der Datumszeile selbst, ergibt also weiterhin 16.8px, folgt
     aber automatisch, falls die Schriftgroesse je eine Stufe bekommt. */
  padding: 0.8em 0 0.8em 5px;
  font-family: "Exo", sans-serif;
  font-size: 21px;
  line-height: 24px;
  font-weight: 500;
  color: #161616;
  /* Die Datumszeile ist auf Live halbtransparent: gemessen /about-us/ 1440 an
     span.eael-date opacity 0.7 bei color rgb(22,22,22) — auf hellgrauem Grund also ein
     deutlich helleres Grau als der Kartentext. Dev stand auf voller Deckung.
     Sichtbarer Unterschied an allen 18 Datumszeilen, den weder der Text-, der Icon-
     noch der Flaechenabgleich meldet: die Deckkraft aendert weder die berechnete Farbe
     noch Lage oder Masze. Nur der Abgleich der blinden Flecken (work/bcmp.py) sieht sie
     — dort 18x "opacity: 0.7 -> 1".
     Bewusst als opacity und nicht als aufgehellte Farbe: EAEL setzt genau das, und ueber
     einem farbigen Grund (Zeitstrahl auf hellgrau) waere ein fest gerechneter Grauwert
     nur an dieser einen Stelle richtig. */
  opacity: 0.7;
}

/* Spiegelbild: Live setzt `right: calc(100% + 85px); left:auto; padding-right:5px`.
   Rechnerisch dasselbe wie das bisherige `left: -531px` bei genau 1440 (rechte
   Textkante 679 auf beiden Staenden nachgemessen), aber ebenfalls mitlaufend. */
.ls-timeline__block.is-right .ls-timeline__date {
  left: auto;
  right: calc(100% + 85px);
  padding: 0.8em 5px 0.8em 0;
  text-align: right;
}

/* Zwei Klassen, nicht eine. Elementors Kit-Stylesheet (post-9.css) ist auf Dev
   weiterhin geladen und setzt `.elementor-kit-9 p { margin-block-end: 20px }` —
   Spezifitaet (0,1,1) und dazu die LOGISCHE Eigenschaft, die `margin-bottom`
   ueberschreibt. Ein einklassiges `.ls-timeline__title { margin: 0 }` (0,1,0)
   verliert dagegen; Farbe, Groesse und Gewicht kamen durch, nur der Rand nicht.
   Folge bei 768: der Titel schob die <h3> um 20px nach unten, damit rutschte
   deren zweite Zeile unter das linke Float-Datum (h=57.6) und begann bei x=135
   statt bei x=236 — drei Meldungen `X 236 -> 135` plus drei `BREITE`.
   Live loest es genauso, mit zwei Klassen:
   `.eael-content-timeline-content .eael-timeline-title { margin: 0 }` (0,2,0).
   Nachgewiesen mit diag/r10n/p16.py (Blattweise abschalten) und p17.py. */
.ls-timeline__card .ls-timeline__title {
  margin: 0;
  font-size: 16px;
  line-height: 24px;
  font-weight: 300;
  color: #870a09;
}

.ls-timeline__text > div > *:first-child {
  margin-top: 0;
}

/* Live: `.eael-content-timeline-content p { margin: 1em 0 }` liefert margin-top 16px,
   `.elementor-kit-9 p { margin-block-end: 20px }` gewinnt beim margin-bottom.
   Gemessen an /about-us/ 1440 (diag/r10n/p18.py), letzter Absatz einer Karte:
       LIVE  mt=16px mb=20px      DEV (vorher)  mt=0px mb=0px
   Das `mb: 0` hier war ein zweiter Fehler, der den ersten (2.1) genau aufhob:
   Karte und Live waren beide 230,38 hoch, obwohl BEIDE Abstaende falsch sassen.
   Nach der Behebung von 2.1 fiel die Karte auf 210,38 — daher jetzt beide Werte
   nach Live gesetzt. `margin-top` faellt ohnehin mit dem `margin-bottom: 20px` der
   <h3> zusammen (Randverschmelzung, max(20,16)=20) und ist nur fuer den Fall da,
   dass ein Absatz direkt auf einen Absatz folgt; der erste Knoten wird von der
   Regel darueber auf 0 gesetzt, wie auf Live. */
.ls-timeline__card .ls-timeline__text p {
  margin: 16px 0 20px;
}

/* Der Umbruchpunkt ist 991/992px, nicht 1024. Das ist der Wert aus EAELs eigener
   Stilvorlage (`@media only screen and (min-width: 992px)` fuer die zweispaltige
   Fassung, alles darunter ist die Grundfassung) — nachgelesen an der gerenderten
   Regelliste von Live, work/diag/r8/live-tlrules.txt. Mit 1024 lag der Nachbau
   zwischen 992 und 1024 eine Fassung daneben. */
@media (max-width: 991px) {
  /* Punkt an die Blockkante (Live: `left:0` aus der Grundregel, dazu `margin-left:0`
     aus der Widget-Regel fuer max-width 880). Gemessen /about-us/ 768 x=60 = Blockkante,
     390 x=30. Das Liniensegment steht 18px weiter innen, gemessen 76 bzw. 46. */
  .ls-timeline__line {
    left: 18px;
  }

  .ls-timeline__bullet {
    left: 0;
    margin-left: 0;
  }

  /* Einspaltig steht die Karte LINKS an der Linie, nicht rechts am Rand. */
  .ls-timeline__block,
  .ls-timeline__block.is-right {
    justify-content: flex-start;
    padding-bottom: 2em;
  }

  /* Live: `.eael-content-timeline-content { margin-left: 60px; padding: 1em }`, die
     Breite ergibt sich also aus dem Rest. Gemessen 768: Block 648 -> Karte 588 ab
     x=120; 390: Block 330 -> Karte 270 ab x=90. Der bisherige Nachbau rechnete
     `width: calc(100% - 50px)` bei rechtsbuendigem Block und landete deshalb 10px zu
     breit und 10px zu weit links (598 ab 110 bzw. 280 ab 80) — das waren die 18x
     `BREITE 588->598` und 18x `X 120->110` im Flaechenstrom. */
  .ls-timeline__card {
    width: auto;
    flex: 1 1 auto;
    margin-left: 60px;
    padding: 1em;
  }

  /* Einspaltig zeigt die Spitze immer nach links, zur Linie hin. */
  .ls-timeline__card::before,
  .ls-timeline__block.is-right .ls-timeline__card::before {
    left: auto;
    right: 100%;
    border-left: none;
    border-right: 10px solid #ffffff;
  }

  /* Einspaltig gibt es keine Gegenseite: das Datum geht zurueck in die Karte.
     ABER nicht als eigene Zeile, sondern als LINKS SCHWIMMENDER Kasten — Live setzt
     `float: left` (EAEL-Grundregel `.eael-content-timeline-content .eael-date`),
     gemessen /about-us/ 768: span.eael-date 162x58 auf x=135, Titel und Text
     beginnen in derselben Zeile bei x=297 und fliessen um die 58px hohe Datumsspalte
     herum. Der bisherige Nachbau setzte das Datum als Block darueber; dadurch war
     jede Karte 58px zu hoch (145->225, 169->249) und jede Titelzeile begann 161px zu
     weit links (`X 297 -> 136`). Nicht die Karte war anders gebaut, sondern der
     Umflusssatz fehlte. */
  .ls-timeline__date,
  .ls-timeline__block.is-right .ls-timeline__date {
    position: static;
    float: left;
    left: auto;
    right: auto;
    width: auto;
    text-align: left;
    padding: 0.8em 0;
  }
}

/* Gegenstueck zu Elementors .elementor-screen-only: der Name des Symbols steht fuer
   Vorlesewerkzeuge im Markup, ist aber nicht zu sehen. Bricks kennt nur ein sichtbares
   Label, deshalb hier ausgeblendet statt weggelassen.
   text-align: center steht auf Live an span.elementor-screen-only (gemessen /about-us/
   1440); der Bricks-Nachbau erbte `right` vom umgebenden a und meldete dreimal
   „Linkedin" und dreimal „Envelope" als „center -> right". */
/* Ersatz fuer Bricks' eigene Regeln `.brxe-social-icons li` und `.brxe-social-icons li a`
   (assets/css/elements/social-icons.min.css). js/loops.js haengt das <li> auf ein <span>
   um — wie auf Live, wo die Leiste keine Liste ist, sondern
   `div.elementor-social-icons-wrapper > span.elementor-grid-item` (Begruendung dort).
   Damit greifen Bricks' Regeln nicht mehr, weil sie am Tagnamen haengen. Hier stehen sie
   wortgleich weiter, an der Klasse statt am Tag — am Bild aendert sich dadurch nichts. */
.brxe-social-icons .repeater-item,
.brxe-social-icons .repeater-item > a {
  display: flex;
  flex: 1;
  gap: 5px;
  align-items: center;
  justify-content: center;
}

/* Farbe: Elementor faerbt Sozialsymbole per Vorgabe #69727D; auf /about-us/ steht an
   a.elementor-social-icon gemessen rgb(105,114,125), das SVG darin nimmt currentColor.
   Dev stand auf der Markenfarbe rgb(135,10,9) — die Symbole waren rot statt graublau,
   und der versteckte Name erbte die Farbe mit (sechs COLOR-Meldungen). */
.brxe-social-icons .repeater-item > a {
  color: #69727d;
}

/* Abstand zwischen den Symbolen: Live setzt 5px (gemessen /about-us/ 1440 an den
   Leitungskarten, Linkedin x=397 und Envelope x=426 bei 24px Symbolbreite -> 5px
   Luecke; die Gruppe endet auf beiden Staenden buendig bei x=450). Bricks legt die
   Liste als Flexleiste ohne Abstand an, das erste Symbol stand dadurch auf 402 —
   drei X-Meldungen im Icon-Abgleich. */
.brxe-social-icons {
  column-gap: 5px;
  /* word-spacing gehoert hier zum Nachbau, es ist KEIN Gegenmittel gegen eine Messzahl.
     Elementor legt die Symbolleiste als Reihe von inline-block-Kaesten an und fuehrt den
     Abstand zwischen ihnen als `word-spacing` am Rahmen der Leiste — dieselben 5px, die
     oben als column-gap stehen. Gemessen /about-us/ 1440: der Wert ist an
     div.elementor-social-icons-wrapper.elementor-grid deklariert und erbt bis auf den
     span.elementor-screen-only hinunter (Kette screen-only / a / grid-item / wrapper
     durchgehend 5px, erst .elementor-widget-container darueber 0px). Dev stand auf 0px —
     6x "word-sp: 5px -> 0px" im Abgleich der blinden Flecken (work/bcmp.py).
     Sichtbar aendert sich dadurch nichts: der einzige Text darunter ist der fuer
     Vorlesewerkzeuge ausgeblendete Symbolname. Die 5px als Wert zwischen den Symbolen
     macht weiterhin column-gap, nicht diese Zeile. */
  word-spacing: 5px;
}

/* fill: currentColor ist Elementors eigene Regel fuer seine Symbol-Vektoren
   (.e-font-icon-svg). Bricks laesst fill leer, der Vektor faellt damit auf Schwarz
   zurueck, obwohl die Farbeinstellung des Bausteins als `color` bereits richtig
   ankommt (#brxe-ea2c6f .icon { color: #FFFFFF }). Gemessen /about-us/ 1440:
   Live fill rgb(255,255,255), Dev rgb(0,0,0) — sechs FARBE-Meldungen, und im Bild
   schwarze Symbole auf der dunklen Ueberblendung der Leitungskarte. */
.brxe-social-icons .repeater-item > a > svg {
  fill: currentColor;
}

.brxe-social-icons .repeater-item > a > span {
  text-align: center;
  position: absolute;
  width: 1px;
  height: 1px;
  margin: -1px;
  padding: 0;
  overflow: hidden;
  clip: rect(0, 0, 0, 0);
  /* Zeilenhoehe 1: Live rechnet am screen-only-Feld 21px/21px bzw. 30px/30px
     (/about-us/ 1440), Dev stand auf 28px/24px — sechs LEADING-Meldungen
     "1.00 -> 1.15". */
  line-height: 1;
  /* word-break: break-word steht auf Live an .elementor-screen-only (dort ueber
     `word-wrap`/`word-break` aus dem Elementor-Grundstil). In einem 1px breiten Kasten
     bricht der Name dadurch zeichenweise um und der Textknoten misst nur die breiteste
     Glyphe: "Linkedin" 14px, "Envelope" 15px (gemessen /about-us/ 1440). Ohne die
     Angabe bleibt das Wort als Ganzes stehen und misst 94 bzw. 100px — sechs
     BREITE-Meldungen an einem Text, den niemand sieht. */
  word-break: break-word;
  border: 0;
}

/* ===================================================================
   R9 — Publikationsraster (.publication-item) unter 768px
   ===================================================================
   Belegt am gerenderten Dokument, /science-and-technology/ 390 (Regelabzug
   mit `work/diag/r9n/p3.py`, Kastenabzug mit `p4.py`):

   Live setzt die Spaltenbreiten der Karte NUR ab Tablet:
     inline @(min-width: 768px) .elementor-element-948db65 { --width: 80px }
     inline @(min-width: 768px) .elementor-element-6c3d40e { --width: 90%  }
   und faellt darunter auf Elementors Grundregel zurueck:
     frontend.css @(max-width: 767px) .e-con.e-flex { --width: 100% }
   dazu je Spalte im Mobilblock `--align-items: center`.

   Der Konverter schreibt die Desktopbreite dagegen OHNE Medienabfrage:
     inline .brxe-cd0ef3 .brxe-a393b5.brxe-block { width: 80px }
     inline .brxe-cd0ef3 .brxe-eeb142.brxe-block { width: 90% }
   Gemessen /science-and-technology/ 390:
     Symbolspalte  live w=330 -> dev w=80    (doc-icon `X 170 -> 30`, Jahr `X 180 -> 55`, je 12x)
     Textspalte    live w=330 -> dev w=297   (90% von 330; daher die Kette
                   `BREITE 3xx -> 2xx` an Titel, Autoren, Zusammenfassung, je 12 Karten)
   Zusammen sind das rund 126 der 170 Meldungen auf /science-and-technology/
   und rund 131 der 147 auf /newsroom/ — dasselbe Raster steht auf beiden Seiten.

   Bewusst nur auf `.publication-item` begrenzt: die fehlende Medienabfrage ist ein
   allgemeiner Konverterfehler (Elementor-Containerbreiten gelten erst ab 768px),
   die Behebung an der Wurzel gehoert in `convert.py`. Eine globale CSS-Regel waere
   hier falsch, weil auf /science-and-technology/ drei und auf /about-us/ zwei
   Bausteine sehr wohl eine eigene Mobilbreite mitbringen, die sie ueberschreiben
   wuerde. */
/* NACHTRAG R11 — HALB ERLEDIGT, nachgemessen statt abgewogen.
   Der Konverter-Agent (R10) hielt diesen Block fuer ueberfluessig, der Native-Agent
   fuer noch gebraucht. Beide hatten zur Haelfte recht.

   Verfahren (`work/diag/r11k/nagel.py publikation <breite>`): die Regeln werden zur
   LAUFZEIT aus dem geladenen Stylesheet geloescht und dieselben Kaesten davor und
   danach gemessen. Je Breite dreimal wiederholt, jedes Mal identisch.

     BREITENREGEL  `…ls-con { width: 100% }`
       390: 0 von 30 Kaesten aendern sich   768: 0 von 30
       Die Wurzel steckt seit R9 im Konverter (`_width:mobile: 100%`), Bricks gibt
       daraus `@media(max-width:767px){ #brxe-… { width:100% } }` (1,0,0) aus.
       -> ENTFERNT.

     BILDREGEL  `> img.brxe-image { margin-inline: auto }`
       390: 10 von 10 Bildern aendern sich
            mit Regel  x=170 (= Live)      ohne Regel  x=30
       -> BLEIBT. */
@media (max-width: 767px) {
  /* Das Bild traegt aus der Umwandlung `margin-right: auto; margin-left: 0`
     (Elementor-Ausrichtung "links"). In der Spalte mit `align-items: center`
     schlaegt der Randversatz die Ausmittung und haelt das Symbol bei x=30,
     gemessen: dev `margin: 0 30.0156px 0 0`. Live hat am Bild keinen Rand und
     mittelt ueber `--align-items: center` auf x=170. */
  main .publication-item [class*="brxe-"].ls-con > img.brxe-image {
    margin-left: auto;
    margin-right: auto;
  }
}

/* ------------------------------------------------------------------
 * R16 — Borlabs-Inhaltssperre „Google Maps": Einzelstil fehlt auf Dev
 *
 * Die Karten-Sperre steht auf /metabopro-regensburg/ und /metabopro-event-de/
 * und ist bei 1440, 768 und 390 der Grund fuer je zwei Baender: die beiden
 * Knoepfe sind auf Dev in einem anderen Blau.
 *
 * Gemessen am Knopf `.brlbs-cmpnt-cb-google-maps .brlbs-cmpnt-cb-btn`,
 * /metabopro-event-de/, 1440 (Kasten, Polster, Schrift, Textfarbe auf beiden
 * Seiten identisch — 383x45 @y=2905, pad 12px 20px, 14px/21px, #FFFFFF):
 *     Hintergrund   Live rgb(66,133,244) = #4285f4   Dev rgb(0,99,227) = #0063e3
 *     Eckenradius   Live 3px                          Dev 4px
 *
 * Gewinnender Selektor auf Live (Borlabs-Stilblatt
 * litespeed/css/7e6ca994….css, ueber CDP CSS.getMatchedStylesForNode geholt):
 *   body div.brlbs-cmpnt-container.brlbs-cmpnt-content-blocker.brlbs-cmpnt-with-individual-styles[data-borlabs-cookie-content-blocker-id]
 *     .brlbs-cmpnt-cb-google-maps .brlbs-cmpnt-cb-btn { background:#4285f4; border-radius:3px }
 * Gewinnend auf Dev: die Borlabs-Grundregel
 *   body .brlbs-cmpnt-container.brlbs-cmpnt-content-blocker a.brlbs-cmpnt-cb-btn
 *     { background-color: var(--content-blocker-button-color) }  -> #0063e3
 *
 * Die Ursache liegt NICHT im Konverter, sondern in den Borlabs-Daten: der
 * „individual style" des Sperr-Typs google-maps wurde beim Uebernehmen der
 * Plugin-Einstellungen nicht mitgenommen. Das Markup traegt auf Dev sehr wohl
 * `brlbs-cmpnt-with-individual-styles` und das data-Attribut, nur die Regel
 * dazu fehlt im erzeugten Stilblatt. Richtig behoben waere es in den
 * Borlabs-Einstellungen auf Dev; hier steht die Regel als Deckung, damit das
 * Bild stimmt. Selektor 1:1 von Live uebernommen, damit die Spezifitaet
 * (0,6,2) die Grundregel (0,3,2) schlaegt — kein !important noetig.
 * Beleg: work/diag/r16-responsiv.md, Ursache 2.
 * ------------------------------------------------------------------ */

body div.brlbs-cmpnt-container.brlbs-cmpnt-content-blocker.brlbs-cmpnt-with-individual-styles[data-borlabs-cookie-content-blocker-id]
  .brlbs-cmpnt-cb-google-maps .brlbs-cmpnt-cb-btn {
  background: #4285f4;
  border-radius: 3px;
}

/* ── Vorschaubild im Termin-/Beitragskarussell ─────────────────────────────
 * Entsprechung zur Kundenregel `.event-carousel .uael-post__thumbnail
 * { position: relative; padding-bottom: 50% }`. Die laesst sich nicht
 * umbenennen (s. Begruendung in work/port-site-css.py): sie haengt an Live's
 * Verschachtelung DIV > A > IMG, die der Konverter zu einem A zusammenfasst.
 *
 * Am Live-Stand gemessen (work/diag/r20-cards.py, 1440, Einzelbeitrag News):
 * Bildkasten 377 x 188,5 px bei allen vier Karten, Bild darin beschnitten
 * (`overflow: hidden`, Bildhoehen 266/210/210/252). 188,5 / 377 = exakt 0,5.
 * Ohne diese Regel behaelt jedes Bild seine natuerliche Hoehe (gemessen
 * 189/197/140/265 px) und die Kartentitel stehen auf verschiedenen Hoehen.
 */
.event-carousel .ls-posts__thumb {
  display: block;
  aspect-ratio: 2 / 1;
  overflow: hidden;
}
/* Das BILD darin behaelt seine natuerliche Hoehe und wird oben angeschlagen —
 * es wird NICHT auf den Kasten skaliert.
 *
 * Am Live-Stand je Bild gemessen (work/diag/r23-thumbbox.py, zwei Artikel,
 * beruhigtes Karussell): Kasten immer 377 x 188,5 mit `overflow: hidden`, das
 * Bild darin `object-fit: fill` in Naturhoehe und oben buendig — 251,3 / 251,5
 * / 166 / 197,3 px. Sichtbar ist also der OBERE Ausschnitt, und bei einem
 * Bild flacher als 2:1 (Picture1, 166 px) bleibt unten sogar Platz frei.
 *
 * `height: 100%; object-fit: cover` war deshalb falsch: cover skaliert auf
 * Deckung und schneidet MITTIG — bei 1536x1024 fehlten oben 31,5 px, die auf
 * Live zu sehen sind. In Zahlen sah es richtig aus (Kasten 188,3 wie Live),
 * der Bildausschnitt war ein anderer. */
.event-carousel .ls-posts__thumb img {
  width: 100%;
  height: auto;
  object-fit: fill;
  align-self: flex-start;
}

/* ── Karussell auf dem News-Einzelbeitrag ──────────────────────────────────
 * Hier stand `align-items: stretch`, mit der Begruendung "Live gibt dort jeder
 * Folie dieselbe Hoehe — gemessen 4 x 462,5 px".
 *
 * Die Messung war falsch: sie lief ueber `.slick-slide` OHNE die Klone
 * auszuschliessen. Slick haengt vor die echten Folien Kopien, die Reihenfolge
 * im DOM beginnt also nicht beim ersten Beitrag. Ohne Klone gemessen sind
 * Live's acht Karten 462,5 / 462,5 / 462,5 / 462,5 / 486,5 / 458,5 / 514,5 /
 * 514,5 — Slick gleicht gar nichts an, die vier gleichen Werte sind schlicht
 * vier gleich lange Anrisse. Die Regel zog Dev damit auf die HOECHSTE Karte
 * (514) und machte den Baustein 36,5 px zu hoch.
 * Beleg: work/diag/r25-single2.py.
 */

/* R45 — Endmeldung am Ende der nachladenden Beitragsliste (Elementor Pro
   `.e-load-more-message`). Alle Werte am Live-Stand gemessen
   (diag/r45-inf2.py): 18px / Zeilenhoehe 24 / zentriert / #161616, darueber
   30px Abstand. Die 30 sind Elementors `--load-more-spacing`-Vorgabe.
   Sie stehen in KEINER Einstellung — die Optik kam aus Elementor Pros
   Stylesheet und faellt mit dem Plugin weg. */
.ls-posts__end {
  margin-top: 30px;
  text-align: center;
  font-size: 18px;
  line-height: 24px;
  color: #161616;
}

/* ---------------------------------------------------------------------------
   R60 — Auszug in Beitragslisten: Elementor Pros Vorgabe am Absatz.

   Elementor Pro bringt mit:
       .elementor-posts .elementor-post__excerpt p { margin: 0 }
   (elementor-pro/assets/css/widget-posts.min.css, per CDP am Live-Knoten als
   gewinnende Regel bestaetigt). Die Regel faellt mit dem Plugin weg. Unsere
   Grundregel `p { margin-bottom: 20px }` aus elements.css — noetig fuer rohes
   HTML in Rechtstexten — greift dann in den Auszug hinein.

   Gemessen auf der Suchseite (/?s=metabolomics) bei 1440: je Karte konstant
   +20 px, ueber 10 Karten +200 px, ueber 24 Karten +426 px. Der Absatz selbst
   ist beidseitig identisch (Text, 15 px, Zeilenhoehe 24, eigene Hoehe 48 px);
   weil die Karte ein Flex-Kind ist, kollabiert der Aussenabstand nicht nach
   aussen und zaehlt voll zur Kartenhoehe.

   Reichweite vorher erhoben (diag/r60-exz-bestand.log, 8 Listenrouten bei
   1440): NUR die Suchseite rendert den Auszug als `<p>` und traegt die 20 px.
   Die uebrigen Listen geben ihn als DIV aus, dort trifft die p-Grundregel
   ohnehin nicht. Die Regel ist trotzdem auf die Auszugsklassen beider Familien
   geschrieben — sie ist die woertliche Entsprechung von Elementors Vorgabe,
   nicht ein an einer Stelle abgelesener Wert.
   Dritte Wiederholung derselben Familie: `.elementor-author-box__bio`
   (R29) und die TEC-Sammelregel (R22).
   --------------------------------------------------------------------------- */
p.ls-archive__excerpt, .ls-archive__excerpt p,
p.ls-posts__excerpt,   .ls-posts__excerpt p { margin: 0; }

/* ---------------------------------------------------------------------------
   R60 — "Read More" der Archiv-/Suchkarte: die Zeilenbox der Vorlage.

   Elementors `a.elementor-post__read-more` ist `display: inline` und liegt in
   einem Blockkasten. Seine Zeilenbox ist deshalb so hoch wie der STRUT des
   Elternteils (28 px), nicht wie der Link selbst (Schriftgroesse 16, Zeilenhoehe
   22 -> 21 px Inhalt). Bricks' text-link ist dagegen selbst das Flex-Kind der
   Karte und verbraucht genau seine 22 px.

   Gemessen (Suchseite 1440, alle 24 Karten): je Karte exakt 6 px zu wenig,
   Summe 144 px. Typografie ist beidseitig identisch (16 px / 22 px / 400, per
   CDP an beiden Knoten bestaetigt) — es ist ausschliesslich die Zeilenbox.
   Live 147 = Titel 56 + 10 + Auszug 48 + 5 + ZEILE 28.
   Dev  141 = Titel 56 + 10 + Auszug 48 + 5 + Link 22.

   Der Wert ist kein Handwert: `--ls-strut` ist die ohnehin portierte
   Zeilenhoehe des `body` (28 px), dieselbe Variable wie beim Knopf-Strut aus
   R35 (Fall 154). Gleiche Ursache, gleiche Loesung.
   --------------------------------------------------------------------------- */
.ls-archive__cta { min-height: var(--ls-strut); align-items: center; }
