/* ============================================================================
 * patterns.css — Auto-Generated
 *
 * Automatisch generiert aus allen pattern.css Dateien in data/global/patterns/.
 * NICHT manuell bearbeiten — Änderungen gehen beim nächsten Build verloren.
 *
 * Build: 2026-08-11T19:47:05Z
 * =========================================================================== */

/* ── banner_top ──────────────────────────────────────────── */
/* banner_top — schmale Announcement-Zeile.
 * Struktur: icontext (Icon) + html-Text in flex-row. */
.mypage .banner_top .announce-bar {
  display: inline-flex;  /* 4f: entflaggt, am DOM gemessen — kein Gegenspieler */
  flex-wrap: wrap;
  align-items: center;
  justify-content: center;
  gap: 0.5rem;
}
.mypage .banner_top .announce-text > p {
  /* margin: 0 entfaellt: einziges/letztes Kind des Announce-Text-Wrappers,
   * :last-child-Reset der Basis (Spec D2) greift bereits identisch. */
  display: inline;
}
/* Override em-components Bubble-Mode (`[type="icontext"]:has(> svg) { width:100% }`):
 * Bubble-Mode ist fuer Avatare/Step-Bubbles die einen runden Container fuellen
 * sollen. Hier ist die Icon ein normales Inline-Icon neben Text — Auto-Size. */
.mypage .banner_top .announce-icon[type="icontext"] {
  width: auto;  /* 4f: entflaggt, am DOM gemessen — kein Gegenspieler */
  height: auto;  /* 4f: entflaggt, am DOM gemessen — kein Gegenspieler */
  /* line-height: 1 auf dem Icon-Wrapper, keine Prosa (D3 Kategorie F) —
   * die Basis-Typografie ist fuer Icon-Container nicht zustaendig. */
  line-height: 1;
}
.mypage .banner_top .announce-icon > svg {
  width: 1.1em;  /* 4f: entflaggt, am DOM gemessen — kein Gegenspieler */
  height: 1.1em;  /* 4f: entflaggt, am DOM gemessen — kein Gegenspieler */
}

/* ── benefit_4icons ──────────────────────────────────────────── */
/* benefit_4icons — four-column benefit grid (icons + headline + text).
 *
 * Color-pair self-consistency: foreground tracks the sc-* background
 * class, mirrors gbfit_3cards01.
 */
.mypage .benefit_4icons.sc-dark,
.mypage .benefit_4icons.sc-pri,
.mypage .benefit_4icons.sc-sec,
.mypage .benefit_4icons.sc-acc {
  color: var(--sc-light, #f5f5f0);
}
.mypage .benefit_4icons.sc-light,
.mypage .benefit_4icons.sc-pri-l,
.mypage .benefit_4icons.sc-sec-l,
.mypage .benefit_4icons.sc-acc-l {
  color: var(--sc-dark, #1a1a1a);
}

/* ── benefit_alternating ──────────────────────────────────────────── */
/* benefit_alternating — 3 Reihen Image+Text, jede zweite gespiegelt */
.mypage .benefit_alternating .alt-text {
 display: flex;
 flex-direction: column;
 justify-content: center;
}
.mypage .benefit_alternating .alt-text h3,
.mypage .benefit_alternating .alt-text .eyebrow,
.mypage .benefit_alternating .alt-text p {
 text-align: left;
}
@media (min-width: 1024px) {
 .mypage .benefit_alternating .alt-row:nth-child(even) {
 flex-direction: row-reverse;
 }
}

/* ── benefit_checklist_avatars ──────────────────────────────────────────── */
/* benefit_checklist_avatars — 2 Spalten: links Eyebrow+H2+Avatar-Stack+Social-
 * Proof-Zahl, rechts eine Checkliste (Check-Icon + H4 + Kurztext, Trennlinien).
 * Avatar-Stack jetzt canonical (molecule avatar-stack > avatar-row > .trust-avatar,
 * molecule.css, Backport 2026-07-28) — kein pattern-lokales Avatar-Circle-CSS
 * mehr. Typografie/Farben aus em-base; kein Marker-Slot für Text. */

.mypage .benefit_checklist_avatars .bca-left {
  align-self: center;
}

/* Avatar-Reihe hier linksbuendig, nicht zentriert (2026-08-07). Das Molecule
 * setzt `justify-content: center` — das war wirkungslos, solange die Reihe als
 * Block-Container lief (Basis-Flag em-components.css:909). Seit die Molecule
 * ihr `display: flex` durchsetzt, wuerde die Zentrierung greifen und die
 * Avatare gemessen von 0px auf 517px schieben, also quer weg von der
 * Social-Proof-Zahl, mit der sie in `.bca-social` eine Zeile bilden. Hier
 * bewusst zurueckgeholt: der Stack sitzt links an der Zahl, wie bisher.
 * Kein Flag noetig — (0,5,0) gegen die Molecule (0,4,0). */
.mypage .benefit_checklist_avatars .molecule.avatar-stack .avatar-row {
  justify-content: flex-start;
}

/* Social-Proof: Avatar-Stack-Molecule + Zahl nebeneinander in einer Zeile. */
.mypage .benefit_checklist_avatars .bca-social {
  display: flex;  /* 4f: entflaggt, am DOM gemessen — kein Gegenspieler */
  align-items: center;
  gap: 1rem;
  margin-top: 1.5rem;
  flex-wrap: wrap;
}
/* Card-Dichte: Social-Proof-Zeile bewusst enger als Basis-Fliesstext (D3
 * Kategorie E) — font-size bleibt Pattern-Deklaration. */
.mypage .benefit_checklist_avatars .bca-social p {
  /* margin entfaellt: p ist das einzige/letzte Element neben dem Avatar-
   * Stack in .bca-social, :last-child-Reset der Basis (D2) deckt es. */
  font-size: 0.95rem;
  color: var(--text-muted);
}
/* Zahlen-Highlight ("15.000+"), keine Prosa (D3 Kategorie E/F) — font-size/
 * font-weight/line-height bleiben Pattern-Deklaration. */
.mypage .benefit_checklist_avatars .bca-social strong {
  display: block;
  font-size: 1.35rem;
  font-weight: 800;
  line-height: 1.1;
  color: var(--primary-base);
}

/* Rechte Checkliste. */
.mypage .benefit_checklist_avatars .bca-list {
  display: flex;
  flex-direction: column;
}
.mypage .benefit_checklist_avatars .bca-item {
  display: flex;  /* 4f: entflaggt, am DOM gemessen — kein Gegenspieler */
  align-items: flex-start;
  gap: 1rem;
  padding: 1.1rem 0;
}
.mypage .benefit_checklist_avatars .bca-item:not(:last-child) {
  border-bottom: 1px solid color-mix(in srgb, var(--text-dark) 12%, transparent);
}
.mypage .benefit_checklist_avatars .bca-check {
  flex-shrink: 0;
  width: 1.6rem;
  height: 1.6rem;
  color: var(--primary-base);
  fill: var(--primary-base);
  margin-top: 0.15rem;
}
.mypage .benefit_checklist_avatars .bca-item-content {
  flex: 1 1 auto;
  min-width: 0;
}
/* margin bleibt ABWEICHEND vom D2-Muster: h4 ist NICHT :last-child (die
 * Kurzbeschreibung als <p> folgt), der :last-child-Reset der Basis greift
 * hier nicht. Der Basis-H4-Default (0.5em) waere fast doppelt so gross wie
 * die aktuellen 0.25rem und wuerde den Checklisten-Eintrag optisch lockern
 * — ohne Browser-Verifikation bleibt die explizite Regel bestehen (analog
 * foot_brand_3nav_store/.fbns-store p, Commit e1632dd, Batch 2). */
.mypage .benefit_checklist_avatars .bca-item-content h4 {
  margin: 0 0 0.25em 0;  /* Leiter: rem -> em, 4px bleibt 4px */
}
/* Card-Dichte: line-height bewusst enger als Basis-Fliesstext (1.65) (D3
 * Kategorie F) — bleibt Pattern-Deklaration. */
.mypage .benefit_checklist_avatars .bca-item-content p {
  /* margin entfaellt: p ist letztes Kind von .bca-item-content ({{content}}
   * = h4+p, p folgt als letztes Element), :last-child-Reset (D2) deckt es. */
  color: var(--text-muted);
  line-height: 1.5;
}

@media (max-width: 1023px) {
  .mypage .benefit_checklist_avatars .bca-right {
    margin-top: 2rem;
  }
}

/* ── benefit_image_left ──────────────────────────────────────────── */
/* benefit_image_left — Image-left + Checkmark-Bullets rechts */
.mypage .benefit_image_left .bullets-block {
 text-align: left;
}
.mypage .benefit_image_left .bullet-check {
 list-style: none;
 margin: 0;
 padding: 0;
}
/* Listentext (li, keine Prosa/kein p) — Card-Dichte (D3 Kategorie F):
 * line-height bewusst enger als Basis-Fliesstext, bleibt Pattern-
 * Deklaration. */
.mypage .benefit_image_left .bullet-check li {
 position: relative;
 padding: 0 0 0 1.85rem;  /* vertikales Padding raus (2026-08-10), Abstand kommt aus der Basis-Regel li + li */
 line-height: 1.55;
}
/* Bullet-Icon (Checkmark-Zeichen im ::before), keine Prosa (D3 Kategorie
 * E/F) — font-size/font-weight/line-height bleiben Pattern-Deklaration. */
.mypage .benefit_image_left .bullet-check li::before {
 content: "✓";
 position: absolute;
 left: 0;
 top: 0.55rem;
 width: 1.35rem;
 height: 1.35rem;
 border-radius: 999px;
 background: var(--primary-base);
 color: var(--text-light);
 font-size: 0.85rem;
 line-height: 1.35rem;
 text-align: center;
 font-weight: 700;
}
.mypage .benefit_image_left h2,
.mypage .benefit_image_left .eyebrow,
.mypage .benefit_image_left .subline {
 text-align: left;
}

/* ── benefit_steps_dark ──────────────────────────────────────────── */
/* benefit_steps_dark — vertikale Step-Liste mit Verbindungslinie.
 * Struktur via _repeat in layer-divs (NICHT ol/li), damit TipTap beim
 * Bearbeiten der Text-Slots die Struktur nicht zerschießt. Jede step-row
 * ist ein Flex-Row mit Bubble links + Content rechts. Connector-Linie
 * via ::before zwischen den Bubbles. */
.mypage .benefit_steps_dark .step-list {
  display: flex;
  flex-direction: column;
  gap: 0.4rem;
}
.mypage .benefit_steps_dark .step-row {
  display: flex;  /* 4f: entflaggt, am DOM gemessen — kein Gegenspieler */
  align-items: flex-start;
  gap: 1rem;
  position: relative;
  padding-bottom: 1.25rem;
}
.mypage .benefit_steps_dark .step-row:not(:last-child)::before {
  content: "";
  position: absolute;
  left: 1.05rem;
  top: 2.4rem;
  bottom: -0.3rem;
  width: 2px;
  background: color-mix(in srgb, var(--text-light) 18%, transparent);
}
.mypage .benefit_steps_dark .step-row .step-num {
  flex-shrink: 0;
  width: 2.1rem;
  height: 2.1rem;
  border-radius: 50%;
  background: var(--primary-base);
  color: var(--text-light);
  display: inline-flex;
  align-items: center;
  justify-content: center;
  /* Zaehler-Zahl in der Bubble, keine Prosa (D3 Kategorie E/F) —
   * font-weight/font-size bleiben Pattern-Deklaration. */
  font-weight: 700;
  font-size: 0.95rem;
  position: relative;
  z-index: 1;
  /* num-Slot rendert als <div type="rich"><p>1</p></div> — Wrapper-Div +
   * inneren <p> auf full-size, damit "1" dead-center in der Bubble sitzt. */
}
.mypage .benefit_steps_dark .step-row .step-num > div[type="rich"],
.mypage .benefit_steps_dark .step-row .step-num p {
  margin: 0;
  padding: 0;
  line-height: 1;
}

.mypage .benefit_steps_dark .step-content {
  flex: 1 1 auto;
  min-width: 0;
}
/* Überschrift + Fließtext leben jetzt in EINEM RTE (h4 + p) unter .step-content;
 * die Marker-Klassen step-headline/step-body sind entfallen (Projekt B 2c,
 * 2026-07-24). Styling daher kontextuell auf das innere h4/p. */
/* h4 semantisch, h5 optisch — der klassische D3-Kategorie-A-Fall, ABER
 * class="h5" ist hier NICHT sicher: der Text kommt aus meta.json samples
 * (items[].content, RTE-Slot vom Typ richHtml), nicht aus einem Template-
 * Knoten (Spec D3, Blockquote "Praezisierung nach Batch 1"). Verifiziert an
 * FE/src/components/editor/extensions/CustomHeading.js (EmPages): parseHTML
 * fuer ein <h4>-Tag ruft extractSize() auf, das NUR txt-*-Groessenklassen
 * erkennt (txt-xs…txt-6xl) — eine zusaetzliche "h5"-Klasse auf einem <h4>
 * wird beim naechsten Laden in TipTap stillschweigend verworfen, noch bevor
 * ein Redakteur ueberhaupt klickt. Genau der Batch-1-Fehler (Ueberschrift
 * springt auf die falsche Groesse), nur umgekehrt. font-size bleibt daher
 * als literale Stufen-Abbildung bestehen. margin bleibt ebenfalls
 * ABWEICHEND vom D2-Muster: h4 ist NICHT :last-child (p folgt), der
 * Basis-H4-Default (0.5em) waere fast doppelt so gross wie die aktuellen
 * 0.25rem (analog foot_brand_3nav_store/.fbns-store p, Commit e1632dd,
 * Batch 2) — ohne Browser-Verifikation bleibt die explizite Regel
 * bestehen. */
.mypage .benefit_steps_dark .step-content h4 {
  margin: 0 0 0.25em 0;  /* Leiter: rem -> em, 4 -> 4.8px */
  font-size: var(--h5-font-size); /* vormals txt-lg auf der <h4> */
}
/* Card-Dichte: font-size/line-height bewusst enger als Basis-Fliesstext
 * (D3 Kategorie E/F) — bleiben Pattern-Deklaration. */
.mypage .benefit_steps_dark .step-content p {
  /* margin entfaellt: p ist letztes Kind von .step-content ({{content}} =
   * h4+p, p folgt als letztes Element), :last-child-Reset (D2) deckt es. */
  opacity: 0.85;
  font-size: 0.92rem;
  line-height: 1.45;
}

/* ── content_downloads_list ──────────────────────────────────────────── */
/* content_downloads_list — Downloads als schmale Listenzeilen (col-8) mit
 * Begleitkarte rechts (col-4).
 *
 * Die Begleitkarte ist 2026-08-10 dazugekommen. Vorher stand die Liste als
 * einzelnes col-8 in einem col-12-Raster: sie sass links, das rechte Drittel
 * blieb leer, und die Section sah aus wie ein angeschnittenes Layout statt
 * wie eine Entscheidung. Inhaltlich ist die Karte der passende Nachbar einer
 * Dokumentenliste — wer nicht findet, was er sucht, soll fragen koennen.
 *
 * Zum Spaltenabstand: der Engine-Gutter (je 1rem padding INNEN an den
 * col-N-Kindern von .max-w) reicht hier nicht, weil die Begleitkarte eine
 * gemalte Flaeche ist — ihr Hintergrund beginnt exakt an der Boxkante, also
 * direkt neben der letzten Trennlinie der Liste. Gemessen: 0px zwischen den
 * beiden Boxen. Deshalb `gap-4` am Row-Layer UND `px-0` an beiden Spalten —
 * gap-4 allein, also zusaetzlich zum Gutter, ergaebe 64px und liesse die
 * Liste unnoetig schrumpfen.
 *
 * Warum die Karte in einem col-4-WRAPPER steckt und nicht selbst das col-4
 * ist: `px-0` traegt !important und haette sonst auch das Innenpadding der
 * Karte auf 0 gesetzt — gemessen `20px 0px`, Text buendig an der Kartenkante.
 * Der Wrapper nimmt den Gutter weg, die Karte behaelt ihr `.card`-Padding. */

.mypage .content_downloads_list .downloads-aside {
  height: 100%;
  display: flex;
  flex-direction: column;
  align-items: flex-start;
  text-align: left;
}

/* Der Button sitzt am unteren Rand der Karte, damit er auf einer Hoehe mit
 * dem Ende der Liste steht, statt direkt unter dem Text zu kleben. */
/* Ein Selektorglied mehr als noetig aussieht, und das mit Absicht: die
 * Button-Reihe wird von em-components per
 * `.mypage section[type='layer']:has(> a.btn-wrap)` zentriert, und `:has()`
 * uebernimmt die Spezifitaet seines Arguments — die Regel liegt damit bei
 * (0,3,2), nicht bei (0,2,2). Ein dreigliedriger Selektor (0,3,0) verliert
 * dagegen; gemessen blieb `justify-content: center` stehen, obwohl die eigene
 * Regel im CSSOM stand. Mit `.downloads-aside` davor sind es (0,4,0) — kein
 * !important noetig. */
.mypage .content_downloads_list .downloads-aside .downloads-aside-action {
  margin-top: auto;
  padding-top: 1rem;
  align-self: stretch;
  justify-content: flex-start;
}

/* Der Hinweistext der Karte ist Nebentext, nicht Fliesstext der Section. */
.mypage .content_downloads_list .downloads-aside-body p:not(.caption) {
  color: var(--text-muted);
}

@media (max-width: 1023px) {
  /* Unter Tablet stapelt das Raster; dann braucht die Karte Luft nach oben
   * und der Button darf wieder direkt unter dem Text stehen. */
  .mypage .content_downloads_list .downloads-aside {
    margin-top: 2rem;
  }
  .mypage .content_downloads_list .downloads-aside-action {
    margin-top: 0;
  }
}

/* ── cta_dual ──────────────────────────────────────────── */
/* cta_dual — Inline-Reihe für die zwei CTAs.
 * Ein kleiner Layout-Helper auf den Pattern-Namen gescoped.
 * Auf Mobile stacken die beiden Buttons untereinander mit etwas
 * Abstand, auf Desktop liegen sie nebeneinander.
 */
.mypage .cta_dual .btn-row {
 display: inline-flex;
 flex-wrap: wrap;
 justify-content: center;
 gap: 0.75rem;
}
@media (max-width: 640px) {
 .mypage .cta_dual .btn-row {
 flex-direction: column;
 align-items: stretch;
 }
 .mypage .cta_dual .btn-row .btn-wrap {
 width: 100%;
 justify-content: center;
 }
}

/* ── faq_2col_collapsible ──────────────────────────────────────────── */
/* Der Regelsatz `.faq-row::before/::after { content: none }` ist am
 * 2026-08-10 entfallen — gleiche Begruendung wie in faq_collapsible: dieses
 * Pattern hat keine `.faq-row`, und das "+" der Molecule sitzt auf
 * `.faq-question::after`. Defensiv gegen ein Pseudoelement, das es nie gab. */
.mypage .faq_2col_collapsible .faq-collapsible {
 border-bottom: 1px solid color-mix(in srgb, var(--text-dark) 10%, transparent);
 text-align: left;
}
.mypage .faq_2col_collapsible .faq-collapsible details {
 width: 100%;
}
.mypage .faq_2col_collapsible .faq-collapsible summary {
 list-style: none;
 cursor: pointer;
 display: flex;
 align-items: center;
 justify-content: space-between;
 gap: 1rem;
 padding: 0.25rem 0;
 text-align: left;
}
.mypage .faq_2col_collapsible .faq-collapsible summary::-webkit-details-marker {
 display: none;
}
.mypage .faq_2col_collapsible .faq-collapsible summary::marker {
 display: none;
 content: "";
}
/* Akkordeon-Titel (span, keine Prosa/kein p), D3 Kategorie E — font-weight
 * bleibt Pattern-Deklaration. */
.mypage .faq_2col_collapsible .faq-collapsible .faq-question {
 flex: 1;
 font-weight: 600;
}
/* Plus/Minus-Icon, keine Prosa (D3 Kategorie E/F) — font-size/line-height
 * bleiben Pattern-Deklaration. */
.mypage .faq_2col_collapsible .faq-collapsible .faq-icon {
 flex: 0 0 auto;
 width: 1.75rem;
 height: 1.75rem;
 display: inline-flex;
 align-items: center;
 justify-content: center;
 font-size: 1.5rem;
 line-height: 1;
 transition: transform 0.3s ease;
 user-select: none;
}
.mypage .faq_2col_collapsible .faq-collapsible details[open] .faq-icon {
 transform: rotate(45deg);
}
.mypage .faq_2col_collapsible .faq-collapsible .faq-answer {
 overflow: hidden;
 max-height: 0;
 opacity: 0;
 transition: max-height 0.4s ease, opacity 0.3s ease, padding 0.3s ease;
 padding-top: 0;
 text-align: left;
}
.mypage .faq_2col_collapsible .faq-collapsible details[open] .faq-answer {
 max-height: 40rem;
 opacity: 1;
 padding-top: 0.75rem;
}
/* ── faq_2col_static ──────────────────────────────────────────── */
/* faq_2col_static — 2-Spalten-FAQ statisch, alle Q&A direkt sichtbar.
 *
 * Layout: CSS-Columns 2 auf dem Grid-Wrapper. Items[] werden automatisch
 * auf 2 Spalten verteilt; break-inside:avoid haelt Q+A zusammen pro Item.
 *
 * Item-Struktur via items[]: pro faq-q ein Layer mit faq-q-headline (html)
 * + faq-q-answer (html) — keine h4/p im Rich-HTML-Blob. */

.mypage .faq_2col_static .faq-static-grid {
 column-count: 2;
 column-gap: 2.5rem;
 text-align: left;
}
@media (max-width: 640px) {
 .mypage .faq_2col_static .faq-static-grid {
  column-count: 1;
 }
}
.mypage .faq_2col_static .faq-q {
 text-align: left;
 padding: 0.65rem 0;
 border-bottom: 1px solid color-mix(in srgb, var(--text-dark) 8%, transparent);
 break-inside: avoid;
 -webkit-column-break-inside: avoid;
 page-break-inside: avoid;
}
/* Frage-Titel (div, keine Prosa/kein h-Tag), D3 Kategorie E/F — font-weight/
 * font-size/line-height bleiben Pattern-Deklaration. margin bleibt
 * unangetastet (Kategorie G — .faq-q-headline ist kein h/p-Selektor, ausser
 * Scope dieses Batches). */
.mypage .faq_2col_static .faq-q-headline {
 font-weight: 700;
 font-size: 1.05rem;
 line-height: 1.35;
 margin: 0 0 0.3rem;
 color: var(--text-dark);
}
/* Antwort-Text, Card-Dichte (D3 Kategorie E/F) — font-size/line-height
 * bleiben Pattern-Deklaration. margin bleibt unangetastet: der erste
 * Selektor-Zweig (.faq-q-answer, das Wrapper-div aus dem Template) ist
 * Kategorie G; beim div ist margin:0 der UA-Default. Der zweite Zweig
 * (.faq-q-answer p) trifft den einzigen/letzten Absatz im Wrapper, dort
 * liefert der :last-child-Reset der Basis dasselbe. `margin: 0` war damit
 * fuer BEIDE Zweige wirkungslos und ist entfallen — ein Split war dafuer
 * nicht noetig, nur das Streichen der einen Deklaration (Toter-Code-Gate
 * §4.2, Review Batch 4). font-size/line-height/opacity bleiben: Nicht-Prosa
 * im Sinne der Karten-Dichte, dafuer ist die Basis-Typografie nicht
 * zustaendig. */
.mypage .faq_2col_static .faq-q-answer,
.mypage .faq_2col_static .faq-q-answer p {
 text-align: left;
 font-size: 0.95rem;
 opacity: 0.85;
 line-height: 1.55;
}

/* ── faq_collapsible ──────────────────────────────────────────── */
/* faq_collapsible — zentrierte, einspaltige FAQ. Jeder Eintrag ein natives
 * <details>/<summary> (Akkordeon ohne JS). Struktur via _repeat=items (kein
 * manuell dupliziertes <details>-Blob im RTE). Mechanik analog
 * faq_2col_collapsible, eine Spalte. */

/* Der Regelsatz `.faq-row::before/::after { content: none }` ist am
 * 2026-08-10 entfallen: dieses Pattern enthaelt gar keine `.faq-row` (es baut
 * auf nativem <details>/<summary>), und die faq-row-Molecule setzt "+" nur auf
 * `.faq-question::after`. Die Regel war eine defensive Vorsichtsmassnahme
 * gegen ein Pseudoelement, das es nie gab. */
.mypage .faq_collapsible .faq-collapsible {
  text-align: left;
}
/* Pro Item eine Trennlinie (die _repeat-Einheit ist .faq-item). */
.mypage .faq_collapsible .faq-item {
  border-bottom: 1px solid color-mix(in srgb, var(--text-dark) 10%, transparent);
}
.mypage .faq_collapsible .faq-collapsible details {
  width: 100%;
}
.mypage .faq_collapsible .faq-collapsible summary {
  list-style: none;
  cursor: pointer;
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 1rem;
  padding: 0.9rem 0;
  text-align: left;
}
.mypage .faq_collapsible .faq-collapsible summary::-webkit-details-marker {
  display: none;
}
.mypage .faq_collapsible .faq-collapsible summary::marker {
  display: none;
  content: "";
}
/* Akkordeon-Titel (span, keine Prosa/kein p), D3 Kategorie E — wie
 * faq_2col_collapsible — font-weight bleibt Pattern-Deklaration. */
.mypage .faq_collapsible .faq-collapsible .faq-question {
  flex: 1;
  font-weight: 600;
}
/* Plus/Minus-Icon, keine Prosa (D3 Kategorie E/F) — font-size/line-height
 * bleiben Pattern-Deklaration. */
.mypage .faq_collapsible .faq-collapsible .faq-icon {
  flex: 0 0 auto;
  width: 1.75rem;
  height: 1.75rem;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  font-size: 1.5rem;
  line-height: 1;
  transition: transform 0.3s ease;
  user-select: none;
}
.mypage .faq_collapsible .faq-collapsible details[open] .faq-icon {
  transform: rotate(45deg);
}
.mypage .faq_collapsible .faq-collapsible .faq-answer {
  overflow: hidden;
  max-height: 0;
  opacity: 0;
  transition: max-height 0.4s ease, opacity 0.3s ease, padding 0.3s ease;
  padding-top: 0;
  text-align: left;
}
.mypage .faq_collapsible .faq-collapsible details[open] .faq-answer {
  max-height: 40rem;
  opacity: 1;
  padding-bottom: 0.9rem;
}
/* .faq-collapsible .faq-answer p { margin: 0 } entfaellt komplett: Antwort-p
 * ist letztes (und einziges) Kind des Akkordeon-Panels (<div class=
 * "faq-answer"><p>…</p></div>), :last-child-Reset (D2) deckt es bereits. */

/* ── faq_sidebar ──────────────────────────────────────────── */
/* faq_sidebar — Sidebar links + FAQ-Akkordeon rechts */
.mypage .faq_sidebar .faq-aside {
 text-align: left;
}
.mypage .faq_sidebar .faq-aside h2,
.mypage .faq_sidebar .faq-aside .eyebrow,
.mypage .faq_sidebar .faq-aside p {
 text-align: left;
}
/* Reset am Anfang der Spalte (margin-top), kein D2-:last-child-Fall —
 * :first-child ist generisch (kein reiner H-Tag-Selektor), bleibt
 * unangetastet (Kategorie G/B1 gemischt). */
.mypage .faq_sidebar .faq-aside > :first-child,
.mypage .faq_sidebar .faq-aside h2,
.mypage .faq_sidebar .faq-aside .eyebrow {
 margin-top: 0;
}
.mypage .faq_sidebar .faq-row {
 border-bottom: 1px solid color-mix(in srgb, var(--text-dark) 8%, transparent);
 padding: 0.85rem 0;
}
.mypage .faq_sidebar .faq-row:first-child {
 margin-top: -20px;
}
.mypage .faq_sidebar .faq-list {
 margin-top: 0;
}
/* Akkordeon-Titel (summary, keine Prosa/kein p), D3 Kategorie E/F —
 * font-weight/font-size bleiben Pattern-Deklaration. */
.mypage .faq_sidebar .faq-row summary {
 list-style: none;
 cursor: pointer;
 font-weight: 600;
 font-size: 1.05rem;
 display: flex;
 justify-content: space-between;
 align-items: center;
 text-align: left;
}
.mypage .faq_sidebar .faq-row summary::-webkit-details-marker {
 display: none;
}
/* Plus/Minus-Zeichen (::after-Pseudoelement), keine Prosa (D3 Kategorie
 * E/F) — font-size/font-weight bleiben Pattern-Deklaration. */
.mypage .faq_sidebar .faq-row summary::after {
 content: "+";
 font-size: 1.4rem;
 font-weight: 400;
 margin-left: 1rem;
 color: var(--primary-base);
 flex: 0 0 auto;
}
.mypage .faq_sidebar .faq-row[open] summary::after {
 content: "−";
}
.mypage .faq_sidebar .faq-body {
 padding: 0.55rem 0 0.25rem 0;
}
/* Card-Dichte: line-height bewusst enger als Basis-Fliesstext (D3
 * Kategorie F) — bleibt Pattern-Deklaration. */
.mypage .faq_sidebar .faq-body p {
 /* margin entfaellt: Antwort-p ist letztes (und einziges) Kind von
  * .faq-body (<div class="faq-body"><p>…</p></div>), :last-child-Reset
  * (D2) deckt es. */
 text-align: left;
 line-height: 1.55;
 opacity: 0.85;
}
/* ── foot_3col ──────────────────────────────────────────── */
/* foot_3col — color self-consistency aus gfoot_simple01 übernommen. */
.mypage .foot_3col.sc-dark,
.mypage .foot_3col.sc-pri,
.mypage .foot_3col.sc-sec,
.mypage .foot_3col.sc-acc {
 color: var(--sc-light, #f5f5f0);
}
.mypage .foot_3col.sc-light,
.mypage .foot_3col.sc-pri-l,
.mypage .foot_3col.sc-sec-l,
.mypage .foot_3col.sc-acc-l {
 color: var(--sc-dark, #1a1a1a);
}

/* Logo-Box im Footer: begrenzt Breite, damit das Logo deutlich kleiner sitzt. */
.mypage .foot_3col .footer-logo-box {
 max-width: 140px;
 margin-bottom: 1rem;
}
.mypage .foot_3col .footer-logo-box img {
 width: 100%;
 height: auto;
 display: block;
}



/* Eyebrows linksbündig in den Spalten (col-4 text-left). Flag entfernt
 * (Stufe 4b, 2026-07-30): eigene Deklaration auf .eyebrow schlägt eine
 * vererbte Ausrichtung vom Wrapper immer, unabhängig von Spezifität —
 * Vererbung ist die niedrigste Prioritätsstufe der Cascade. Spezifität
 * der Regel selbst (.mypage .foot_3col .text-left .eyebrow, 4 Klassen)
 * ist 0,4,0. Setzt ein Autor zusätzlich eine .align-*-Utility direkt auf
 * das Eyebrow-Element, gewinnt die Utility jetzt korrekt über ihr eigenes
 * !important (vorher blockiert durch dieses Flag + höhere Spezifität). */
.mypage .foot_3col .text-left .eyebrow {
 text-align: left;
}
.mypage .foot_3col .text-right .eyebrow {
 text-align: right;
}
/* Trennlinie zwischen Spalten-Block und Bottom-Bar. */
.mypage .foot_3col .footer-divider {
 border-top: 1px solid currentColor;
 opacity: 0.95;
}
.mypage .foot_3col .footer-divider > * {
 opacity: 1;
}
/* ── foot_minimal ──────────────────────────────────────────── */



/* ── form_contact ──────────────────────────────────────────── */
/* form_contact — Contact-Info links + Form rechts */
.mypage .form_contact .contact-info {
 text-align: left;
}
.mypage .form_contact .contact-info h2,
.mypage .form_contact .contact-info .eyebrow,
.mypage .form_contact .contact-info .subline {
 text-align: left;
}
.mypage .form_contact .contact-list {
 display: flex;
 flex-direction: column;
 margin: 1.5rem 0 0 0;
 padding: 0;
 /* eigener Slot neben .contact-info → erbt sonst text-center der Row.
  * Linke Hälfte durchgängig linksbündig. */
 text-align: left;
}
/* Eine Kontaktzeile = _repeat-Item (Icon-Node + Text), add/delete/dup-bar. */
.mypage .form_contact .contact-item {
 display: flex;  /* 4f: entflaggt, am DOM gemessen — kein Gegenspieler */
 gap: 0.85rem;
 padding: 0.6rem 0;
 align-items: flex-start;
}
/* ci-ico ist jetzt ein echtes Icon-Element (svg), kein Inline-SVG-Blob im RTE.
 * Der Kreis-Hintergrund + Padding lassen das Glyph mittig in der Bubble sitzen. */
.mypage .form_contact .ci-ico {
 flex: 0 0 2.2rem;
 width: 2.2rem;
 height: 2.2rem;
 padding: 0.5rem;
 box-sizing: border-box;
 border-radius: 999px;
 background: color-mix(in srgb, var(--primary-base) 14%, transparent);
 color: var(--primary-base);
 fill: var(--primary-base);
}
.mypage .form_contact .ci-text {
 flex: 1 1 auto;
 min-width: 0;
}
.mypage .form_contact .ci-text p {
 /* margin: 0 entfaellt: einziges/letztes Element des Kontakt-Item-Texts,
  * :last-child-Reset der Basis (Spec D2) greift bereits identisch. */
}
/* Meta-Zusatzzeile in der Kontaktliste (z.B. "Antwort meist innerhalb..."),
 * keine Prosa (D3 Kategorie E) — font-size bleibt Pattern-Deklaration. */
.mypage .form_contact .contact-list .muted {
 color: var(--text-muted);
 font-size: 0.9rem;
}
.mypage .form_contact .contact-form {
 display: flex;
 flex-direction: column;
 gap: 0.5rem;
}
/* Formular-Label, keine Prosa (D3 Kategorie E/F) — die Basis-Typografie ist
 * fuer Formularfelder nicht zustaendig, font-size/font-weight bleiben
 * Pattern-Deklaration. margin ist Kategorie G (kein h/p-Selektor), unangetastet. */
.mypage .form_contact .form-label {
 font-size: 0.85rem;
 font-weight: 600;
 margin: 0.5rem 0 0.25rem 0;
 text-align: left;
}
/* Formular-Eingabefeld, keine Prosa (D3 Kategorie E) — font-size bleibt
 * Pattern-Deklaration. */
.mypage .form_contact .form-input {
 padding: 0.7rem 0.85rem;
 border-radius: 10px;
 border: 1px solid color-mix(in srgb, var(--text-dark) 14%, transparent);
 font-size: 0.95rem;
 font-family: inherit;
 background: var(--color-bg);
 width: 100%;
 box-sizing: border-box;
}
.mypage .form_contact .form-input:focus {
 outline: 2px solid var(--primary-base);
 outline-offset: 1px;
}
.mypage .form_contact textarea.form-input {
 resize: vertical;
 min-height: 110px;
}
/* Formular-Hinweistext unter dem Form, keine Prosa (D3 Kategorie E) —
 * font-size bleibt Pattern-Deklaration. margin ist Kategorie G (kein
 * p-Element-Selektor, "text"-Slot ohne TipTap-Absatz), unangetastet. */
.mypage .form_contact .form-hint {
 margin: 0.55rem 0 0 0;
 font-size: 0.85rem;
 color: var(--text-muted);
 text-align: left;
}
.mypage .form_contact button.btn-wrap {
 margin-top: 0.85rem;
 width: 100%;
}

/* ── form_newsletter ──────────────────────────────────────────── */
/* form_newsletter — Inline Email + Submit für Newsletter.
 * Strikt auf das Pattern gescoped.
 */
.mypage .form_newsletter .subscribe-inline {
 display: inline-flex;
 gap: 0.5rem;
 align-items: stretch;
 margin: 1rem 0 0.5rem;
 width: 100%;
 max-width: 28rem;
 flex-wrap: wrap;
 justify-content: center;
}
/* Formular-Eingabefeld, keine Prosa (D3 Kategorie E) — font-size bleibt
 * Pattern-Deklaration. */
.mypage .form_newsletter .subscribe-inline .form-input {
 flex: 1 1 14rem;
 min-width: 0;
 padding: 0.7rem 0.95rem;
 font-size: 1rem;
 font-family: inherit;
 color: inherit;
 background: var(--color-bg);
 border: 1px solid var(--shade-lightgray);
 border-radius: 10px;
 transition: border-color .15s ease, box-shadow .15s ease;
}
.mypage .form_newsletter .subscribe-inline .form-input:focus {
 outline: none;
 border-color: var(--primary-base, #2563EB);
 box-shadow: 0 0 0 3px color-mix(in srgb, var(--primary-base, #2563EB) 18%, transparent);
}
.mypage .form_newsletter .subscribe-inline .btn-wrap {
 flex: 0 0 auto;
 white-space: nowrap;
}
/* Formular-Hinweistext, keine Prosa (D3 Kategorie E) — font-size bleibt
 * Pattern-Deklaration. margin ist Kategorie G (kein p-Element-Selektor),
 * unangetastet. */
.mypage .form_newsletter .form-hint {
 font-size: 0.8rem;
 color: var(--text-muted, rgba(33,37,41,0.55));
 margin: 0.5rem 0 0;
}
.mypage .form_newsletter .visually-hidden {
 position: absolute;
 width: 1px; height: 1px;
 padding: 0; margin: -1px;
 overflow: hidden; clip: rect(0,0,0,0);
 white-space: nowrap; border: 0;
}
@media (max-width: 480px) {
 .mypage .form_newsletter .subscribe-inline {
 flex-direction: column;
 align-items: stretch;
 }
 .mypage .form_newsletter .subscribe-inline .btn-wrap {
 width: 100%;
 justify-content: center;
 }
}

/* ── gal_carousel ──────────────────────────────────────────── */
/* gal_carousel — horizontale Editorial-Galerie mit Right-Bleed */
.mypage .gal_carousel { overflow: hidden; }

.mypage .gal_carousel .carousel-wrap {
 position: relative;
}

.mypage .gal_carousel .gal-track {
 display: flex;
 gap: 14px;
 overflow-x: auto;
 overflow-y: hidden;
 scroll-snap-type: x mandatory;
 scroll-behavior: smooth;
 scrollbar-width: none;
 -ms-overflow-style: none;
 padding: 0 0 18px max(1rem, calc((100vw - 1280px) / 2 + 1rem));
 -webkit-mask-image: linear-gradient(to right, #000 0, #000 calc(100% - 80px), transparent 100%);
 mask-image: linear-gradient(to right, #000 0, #000 calc(100% - 80px), transparent 100%);
 /* Auto-Peek: zeigt einmal kurz, dass hier weiter gescrollt werden kann */
 animation: ggal-carousel-peek 2.6s ease-in-out 0.8s 2 both;
}
.mypage .gal_carousel .gal-track::-webkit-scrollbar { display: none; }

/* Sobald der User interagiert, Animation pausieren — der Hinweis hat seinen Job getan */
.mypage .gal_carousel .gal-track:hover,
.mypage .gal_carousel .gal-track:focus-within,
.mypage .gal_carousel .gal-track:active {
 animation-play-state: paused;
 animation: none;
}

@keyframes ggal-carousel-peek {
 0% { transform: translateX(0); }
 35% { transform: translateX(-48px); }
 65% { transform: translateX(-48px); }
 100% { transform: translateX(0); }
}

.mypage .gal_carousel .gal-slide {
 flex: 0 0 auto;
 width: 340px;
 height: 420px;
 border-radius: 8px;
 overflow: hidden;
 background: var(--shade-lightgray);
 scroll-snap-align: start;
 min-width: 0;
 min-height: 0;
}
.mypage .gal_carousel .gal-slide.gal-slide-wide { width: 560px; }
.mypage .gal_carousel .gal-slide.gal-slide-tall { width: 280px; }

.mypage .gal_carousel .gal-slide img,
.mypage .gal_carousel .gal-slide picture,
.mypage .gal_carousel .gal-slide picture img {
 width: 100%;
 height: 100%;
 object-fit: cover;
 display: block;
}

/* Pfeil-Hint rechts oben — jetzt zurückhaltender, der Track macht die Hauptarbeit.
 * width:max-content overridet render-struct.css default `section[type="layer"]
 * { width: -webkit-fill-available }`. Nach Wegfall des html-div-Wrappers
 * (icontext-Direktkind) zieht der absolute Container sich sonst auf
 * volle Breite und der 44px-Arrow sitzt links statt rechts. */
.mypage .gal_carousel .carousel-hint {
 position: absolute;
 top: -60px;
 right: max(1rem, calc((100vw - 1280px) / 2 + 1rem));
 width: max-content;
 pointer-events: none;
}
/* Pfeil-Icon, keine Prosa (D3 Kategorie E) — die Basis-Typografie ist fuer
 * Icon-Container nicht zustaendig, font-size bleibt Pattern-Deklaration. */
.mypage .gal_carousel .carousel-arrow {
 display: inline-flex;
 align-items: center;
 justify-content: center;
 width: 44px;
 height: 44px;
 border-radius: 50%;
 border: 1px solid currentColor;
 font-size: 1.2rem;
 opacity: 0.5;
}

@media (prefers-reduced-motion: reduce) {
 .mypage .gal_carousel .gal-track { animation: none; }
}

@media (max-width: 1023px) {
 .mypage .gal_carousel .gal-track {
 padding-left: 1rem;
 padding-right: 0;
 }
 .mypage .gal_carousel .carousel-hint {
 right: 1rem;
 top: -52px;
 }
 .mypage .gal_carousel .gal-slide { width: 260px; height: 320px; }
 .mypage .gal_carousel .gal-slide.gal-slide-wide { width: 380px; }
 .mypage .gal_carousel .gal-slide.gal-slide-tall { width: 220px; }
}
/* ── gal_grid ──────────────────────────────────────────── */
.mypage .gal_grid .gal-grid {
 display: grid;
 grid-gap: 10px;
 grid-template-columns: repeat(auto-fit, minmax(220px, 1fr));
 grid-auto-rows: 180px;
 grid-auto-flow: dense;
}

.mypage .gal_grid .gal-cell {
 overflow: hidden;
 border-radius: 6px;
 background: var(--shade-lightgray);
 width: 100%;
 height: 100%;
 min-height: 0;
 min-width: 0;
}

.mypage .gal_grid .gal-cell img,
.mypage .gal_grid .gal-cell picture,
.mypage .gal_grid .gal-cell picture img {
 width: 100%;
 height: 100%;
 object-fit: cover;
 display: block;
}

.mypage .gal_grid .gal-cell.wide { grid-column: span 2; }
.mypage .gal_grid .gal-cell.tall { grid-row: span 2; }
.mypage .gal_grid .gal-cell.big { grid-column: span 2; grid-row: span 2; }

@media (max-width: 600px) {
 .mypage .gal_grid .gal-grid {
 grid-template-columns: repeat(2, 1fr);
 grid-auto-rows: 140px;
 }
 .mypage .gal_grid .gal-cell.big,
 .mypage .gal_grid .gal-cell.wide { grid-column: span 2; }
}
/* ── gal_masonry ──────────────────────────────────────────── */
/* gal_masonry — CSS-Grid Masonry, dense packing, bündige Gradient-Captions */
.mypage .gal_masonry .masonry {
 display: grid;
 grid-template-columns: repeat(4, 1fr);
 grid-auto-rows: 220px;
 grid-auto-flow: dense;
 gap: 1rem;
}
.mypage .gal_masonry .m-tile {
 position: relative;
 margin: 0;
 border-radius: 14px;
 overflow: hidden;
 background: var(--shade-dark-base);
 /* Grid-Item min-width DEFAULT ist `auto` (content-based) — bei großen
  * picture-Children (intrinsic ~1024px) sprengt das die Grid-Spalten,
  * masonry collapsed auf 1 Spalte. min-width:0 + min-height:0 brechen
  * die Content-basis und respektieren grid-template-columns/auto-rows. */
 min-width: 0;
 min-height: 0;
 /* render-struct.css setzt section[type='layer'] auf
  * width: -webkit-fill-available → grid-item überschreibt aber wir
  * machen es explizit für Browser-Konsistenz. */
 width: auto;
}
.mypage .gal_masonry .m-tile.m-tall { grid-row: span 2; }
.mypage .gal_masonry .m-tile.m-wide { grid-column: span 2; }
/* Picture-wrapper + IMG werden BEIDE auf 100%×100% gezwungen, sonst
 * rendert das <picture>-Element bei Image-Load auf seine intrinsische
 * (Bild-)Größe → sprengt die masonry-Grid-Zelle, alle Bilder landen
 * oberhalb der Tile-Reihe statt drinnen. Selector deckt auch <picture
 * type='picture'> ab. */
.mypage .gal_masonry .m-tile img,
.mypage .gal_masonry .m-tile picture,
.mypage .gal_masonry .m-tile picture[type='picture'] {
 display: block;
 position: absolute;
 inset: 0;
 width: 100%;
 height: 100%;
 max-width: 100%;
 max-height: 100%;
 object-fit: cover;
 transition: transform 0.5s ease;
}
.mypage .gal_masonry .m-tile:hover img,
.mypage .gal_masonry .m-tile:hover picture {
 transform: scale(1.05);
}
.mypage .gal_masonry .m-tile .m-caption {
 position: absolute;
 left: 0;
 right: 0;
 bottom: 0;
 padding: 2.5rem 1.25rem 1rem 1.25rem;
 background: linear-gradient(to top,
 color-mix(in srgb, var(--shade-dark-base) 78%, transparent) 0%,
 color-mix(in srgb, var(--shade-dark-base) 55%, transparent) 50%,
 transparent 100%);
 display: flex;
 flex-direction: column;
 gap: 0.25rem;
 text-align: left;
 /* Caption-Container ist Pointer-transparent damit Hover- und Image-
  * Pick-Klicks AUF DEM BILD landen (nicht im Gradient-Background).
  * Die TEXT-Kinder bekommen pointer-events:auto zurueck damit der
  * Editor sie editieren kann — sonst sind die m-cap-cat/-title/-place
  * Slots im RTE unereichbar. */
 pointer-events: none;
}
.mypage .gal_masonry .m-caption > * {
 pointer-events: auto;
}
/* Caption-Text: Kategorie als eyebrow, Titel als caption — beide RTE-wählbar in
 * EINEM richHtml-Slot (Projekt B 2026-07-24, vormals Slot-Marker m-cap-cat/-title).
 * Farben/Größe kontextuell hell für das dunkle Gradient-Overlay; Werte 1:1 aus den
 * alten Marker-Regeln übernommen. */
/* Kategorie-Zeile ueber der Bild-Caption, nutzt die Basis-Rolle .eyebrow
 * mit eigener (kleinerer) Groesse fuers kompakte Gradient-Overlay (D3
 * Kategorie E/F) — keine Umbenennung/zweite Klasse (Rule 3: eyebrow ist
 * ein TipTap-Node, renderHTML haertet die Klasse).
 * Flag entfernt (Stufe 4b, 2026-07-30): em-base setzt seit Stufe 4a kein
 * !important mehr auf `.mypage p.eyebrow, .mypage p.emphasis` (margin-top/
 * -bottom, Spezifität 0,2,1). Der lokale Selektor
 * `.mypage .gal_masonry .m-caption .eyebrow` ist mit 4 Klassen (0,4,0)
 * spezifischer und gewinnt für margin-top/-bottom bereits allein per
 * Spezifität (b-Komponente 4 > 2) — das Flag war ueberfluessig. */
.mypage .gal_masonry .m-caption .eyebrow {
 font-size: 0.72rem;
 font-weight: 700;
 text-transform: uppercase;
 letter-spacing: 0.08em;
 color: color-mix(in srgb, var(--text-light) 85%, transparent);
 margin: 0 0 0.25em 0;  /* Leiter: rem -> em, 2.4 -> 2.9px */
}
/* Bildtitel, nutzt die Basis-Rolle .caption mit eigener (groesserer)
 * Groesse — Bildunterschrift ist bewusst groesser als der Basis-Default
 * 0.95em (D3 Kategorie E/F). Keine Umbenennung/zweite Klasse (Rule 3). */
.mypage .gal_masonry .m-caption .caption {
 font-size: 1.05rem;
 font-weight: 600;
 color: var(--text-light);
 line-height: 1.3;
 text-shadow: 0 1px 2px color-mix(in srgb, var(--shade-dark-base) 30%, transparent);
 /* margin: 0 entfaellt: Inhalt ist tatsaechlich <p class="caption"> (verifiziert
  * gegen pattern.template.json/meta.json samples, "<p class='eyebrow'>...</p>
  * <p class='caption'>...</p>" — kein div/span), damit Kategorie C statt G.
  * p.caption ist letztes Kind von .m-caption (die zwei p's aus dem
  * richHtml-Slot sind dessen einzige Kinder, s. `.m-caption > *`-Regel oben).
  * Redundant ohnehin: `.mypage p.caption { margin: 0 0 0.15em !important }`
  * (em-base.css) gewann gegen dieses lokale `margin: 0` — die lokale Regel
  * hatte nie eine Wirkung.
  *
  * Zur Begruendung, korrigiert nach dem Abschluss-Review (2026-07-30): NICHT
  * wegen gleicher Spezifitaet. Der lokale Selektor
  * `.mypage .gal_masonry .m-caption .caption` ist mit vier Klassen und null
  * Elementen (0,4,0) sogar SPEZIFISCHER als `.mypage p.caption` (0,2,1).
  * Entschieden hat allein das `!important` — das gewinnt unabhaengig vom
  * Spezifitaetsgrad gegen eine Deklaration ohne Flag. Die urspruengliche
  * Rechnung im Kommentar war falsch; das Fazit (Regel war tot, entfaellt)
  * bleibt richtig. */
}
@media (max-width: 1023px) {
 .mypage .gal_masonry .masonry {
 grid-template-columns: repeat(2, 1fr);
 grid-auto-rows: 200px;
 }
}
@media (max-width: 600px) {
 .mypage .gal_masonry .masonry {
 grid-template-columns: 1fr;
 }
 .mypage .gal_masonry .m-tile.m-tall,
 .mypage .gal_masonry .m-tile.m-wide {
 grid-row: span 1;
 grid-column: span 1;
 }
}
/* ── head_brand_tagline_cta ──────────────────────────────────────────── */
/* head_brand_tagline_cta — Brand-Icon+Tagline links, Nav mittig, 2 CTAs rechts.
 * Default solid auf sc-light. Mobile: Burger collapse + CTAs unten. */
/* htc-row: 3 Spalten in einer Zeile, KEIN wrap. !important schlaegt die
 * em-components-Regel `.col-12:has(>.col-N)` die sonst flex-wrap:wrap
 * setzt und unsere Spalten in die naechste Zeile umlegt. */
.mypage .head_brand_tagline_cta .htc-row {
  display: flex;  /* 4f: entflaggt, am DOM gemessen — kein Gegenspieler */
  align-items: center;
  /* `!important` ZURUECKGEHOLT (4f-Nachlauf, 2026-08-09): ohne Flag kippt die
   * Zeile auf `wrap` und der Header waechst von 88 auf 171px. Die
   * Einzelmessung hatte "entbehrlich" gemeldet — falsch, weil diese Regel in
   * head_brand_tagline_cta_logo UND _text WORTGLEICH steht: beim Entflaggen
   * einer Kopie hielt die andere den Wert. Erst der Seiten-Regressionslauf,
   * der beide zugleich zuruecksetzte, hat es gezeigt. */
  flex-wrap: nowrap !important;
  /* gap lebt jetzt als `gap-2` an der Reihe im Template (20er-Migration,
   * 2026-08-10). Vorher stand er hier UND Modell A legte 16px Spalten-
   * Padding drauf: der Inhalt sass 32px von der Reihenkante, waehrend
   * jeder andere Header bei 16px liegt — die Kopfzeilen hielten also
   * keinen gemeinsamen Rand. Eine Quelle, und es ist die, die das
   * Control im Inspector bedient. */
}
/* min-width:0 auf allen Flex-Children damit der intrinsic min-content
 * (großes Logo / langer Brand-Text) die anderen Spalten nicht in die
 * nächste Zeile drückt. */
.mypage .head_brand_tagline_cta .htc-row > * {
  min-width: 0;
}

/* Entfallen (2026-08-11): die Regeln fuer `.htc-brand-block`,
 * `.htc-logo-fit` und `.htc-brand-text` standen noch aus der Fassung vor der
 * Header-Konsolidierung. Das Template benutzt seit dem Umbau das gemeinsame
 * Vokabular (`head-brand`, `head-align-left`, `head-logo`, `head-brand-text`,
 * `head-tagline`), also traf keiner dieser Selektoren mehr etwas. Ihre
 * Absicht — Wortmarke fett und klein, Tagline eine Stufe leiser, Logo ohne
 * Beschnitt — liegt jetzt zentral in em-components (Header-Doktrin). */

/* Spezifitaet angehoben mit `section[type='layer']` (2026-08-10), NICHT mit
 * einem Flag. Gegenspieler ist die Button-Zeilen-Regel in em-components:
 *   `.mypage section[type='layer']:has(> a.btn-wrap) { justify-content: center }`
 * `:has()` erbt die Spezifitaet seines Arguments, die Regel liegt also bei
 * (0,3,2) und schlug die (0,3,0) hier — die CTA-Zeile stand zentriert statt an
 * der Kante. Sichtbar wurde das erst, seit `btn-wrap` am Anchor sitzt (Umzug
 * vom 2026-08-10): vorher trug der Reihen-Layer die Klasse selbst, das `:has`
 * traf nicht. Mit `section[type='layer']` liegt dieser Selektor bei (0,4,1) und
 * gewinnt per Spezifitaet. */
.mypage .head_brand_tagline_cta section[type='layer'].htc-cta-row {
  display: flex;  /* 4f: entflaggt, am DOM gemessen — kein Gegenspieler */
  /* `!important` ZURUECKGEHOLT (4f-Nachlauf, 2026-08-09): ohne Flag `column`
   * statt `row`, die CTA-Zeile stapelt. Gleiche Duplikat-Falle wie bei
   * .htc-row flex-wrap (Regel steht in beiden Varianten-Dateien). */
  flex-direction: row !important;
  flex-wrap: nowrap;
  gap: 0.5rem;
  justify-content: flex-end;
  align-items: center;
}
/* Button-Größe: zentral in em-components (.head_brand_tagline_cta .htc-cta-row
   .btn-wrap) — kein pattern-lokales Duplikat mehr. */

/* Der Mobil-Block ist entfallen (2026-08-10): Navigation verstecken und
 * wieder einblenden liegt jetzt in der `header-nav`-Molecule, das Auf-Zu in
 * `renderer/headnav.go`. Vorher stand hier ein Media-Query mit
 * `.head-mobile-open` — eine Klasse, die NIEMAND gesetzt hat (kein Burger, kein
 * JS in beiden Repos). Die Navigation war unter 767px also weg und nicht
 * zurueckholbar. */

/* ── head_centered_logo_nav ──────────────────────────────────────────── */
/* head_centered_logo_nav — Brand zentriert oben, Nav-Row horizontal darunter.
 * Klassisch-konservativ. Default sc-light solid. */
/* Die Kopfzeile ist ZWEIZEILIG: Marke oben, Navigation darunter — und beide
 * Zeilen sind `col-12`. Genau daran scheiterte der Abstand (gemessen
 * 2026-08-11): die Grid-Engine macht eine `col-12`-Reihe nur dann zum Flex,
 * wenn sie eine `col-1..col-11`-Spalte enthaelt. Hier tat sie es nicht, die
 * Reihe blieb `display: block`, und damit war sowohl das `gap-3` der Reihe als
 * auch die senkrechte Zentrierung der Header-Doktrin wirkungslos: Marke und
 * Navigation standen mit 0px Abstand aufeinander. Die Reihe muss ihr Layout
 * hier also selbst tragen. Spezifitaet (0,4,2) schlaegt das
 * `display: inline-block` aus render-struct.css (0,2,1) ohne Flag.
 *
 * (Vorher stand hier eine `.hcln-stack`-Regel — eine Klasse, die kein
 * Template setzte. Dieselbe Art toter Mechanik wie `.head-mobile-open`.) */
.mypage .head_centered_logo_nav > section[type='layer'].max-w {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 1rem;
}

/* Wordmark-Presentation: nur Pattern-spezifische Groesse + Letter-Spacing.
 * font-family bewusst NICHT gesetzt — kommt entweder von der .brand-text-
 * Klasse (3. Schrift, --brand-font) oder erbt vom Project-Body. Nicht-Prosa
 * (D3 Kategorie E/F, Wortmarke) — bleibt Pattern-Deklaration. */
.mypage .head_centered_logo_nav .hcln-brand {
  font-size: 1.6rem;
  font-weight: 400;
  letter-spacing: 0.02em;
}
/* TipTap normalisiert Brand-Inhalt zu <p>. Regel (margin:0) entfaellt:
 * einziges Kind des Brand-Blocks, :last-child (Spec D2) setzt Margin
 * schon auf 0. */

.mypage .head_centered_logo_nav .em-nav,
.mypage .head_centered_logo_nav .head-nav-slot {
  display: inline-flex;
  gap: 0.4rem 2rem;
  justify-content: center;
  align-items: center;
  flex-wrap: wrap;
}
/* Nav-Link, keine Prosa (D3 Kategorie E) — font-size bleibt Pattern-Deklaration. */
.mypage .head_centered_logo_nav .em-nav a {
  text-decoration: none;
  color: inherit;
  font-size: 0.95rem;
  letter-spacing: 0.04em;
  text-transform: uppercase;
  opacity: 0.75;
  transition: opacity 0.15s ease;
}
.mypage .head_centered_logo_nav .em-nav a:hover,
.mypage .head_centered_logo_nav .em-nav a.active {
  opacity: 1;
}

/* Mobile: Nav-Link-Groesse verkleinert sich weiter, keine Prosa (D3 E). */
@media (max-width: 767px) {
  .mypage .head_centered_logo_nav .em-nav,
  .mypage .head_centered_logo_nav .head-nav-slot {
    gap: 1rem;
    font-size: 0.85rem;
  }
}

/* ── head_floating_glass ──────────────────────────────────────────── */
/* head_floating_glass — Header in Glass-Optik (glass-light + glass-frosted).
 * NICHT mehr selbst-schwebend: das Overlay/Schweben liefert generisch das
 * Header-über-Hero-Feature (Hero setzt data-header-overlay → Renderer setzt
 * .head-overlay-active/.head-overlay-scrim, em-components positioniert
 * absolute+z-index). Dieses Pattern trägt nur noch die Glass-*Optik* + das
 * Brand/Nav-Layout; als In-Flow-Header ohne Overlay verhält es sich wie ein
 * normaler Header (kein Kollaps/Overlap mehr in gestapelten Kontexten). */
.mypage .head_floating_glass .hfg-row {
  display: flex;  /* 4f: entflaggt, am DOM gemessen — kein Gegenspieler */
  align-items: center;
}

/* Der Markenblock traegt sein Layout NICHT selbst (2026-08-11).
 *
 * Vorher stand hier `display: inline-flex; align-items: center` — geschrieben
 * fuer eine waagrechte Marke aus Logo NEBEN Schriftzug. Seit der Doktrin
 * „die Marke erscheint einmal" ist immer nur EIN Kind sichtbar, und die
 * Regel richtete stattdessen Schaden an: mit (0,3,0) schlug sie
 * `head-align-left` (0,2,0), der Block wurde zur zentrierten Achse, und die
 * Wortmarke stand 108px INNERHALB der linken Hilfslinie statt auf ihr
 * (gemessen: Block L0/368px breit, Wortmarke L108/152px breit).
 * Die waagrechte Ausrichtung gehoert allein zu `head-align-*`. */
/* Die drei `.hfg-brand-text`-Regeln sind entfallen (2026-08-11): die Klasse
 * steht in keinem Template mehr — die konsolidierte Kopfzeile nutzt das
 * gemeinsame Vokabular `head-brand-text` / `head-tagline`, dessen Typografie
 * weiter unten (reduzierte Fassung) bzw. zentral in em-components liegt. */

.mypage .head_floating_glass .em-nav,
.mypage .head_floating_glass .head-nav-slot {
  display: inline-flex;
  gap: 0.4rem 1.5rem;
  justify-content: flex-end;
  align-items: center;
}
/* Nav-Link, keine Prosa (D3 Kategorie E) — font-size bleibt Pattern-Deklaration. */
.mypage .head_floating_glass .em-nav a {
  text-decoration: none;
  color: inherit;
  font-size: 0.9rem;
  opacity: 0.75;
  transition: opacity 0.15s ease;
}
.mypage .head_floating_glass .em-nav a:hover {
  opacity: 1;
}

/* Der Mobil-Block ist entfallen (2026-08-10): Navigation verstecken und
 * wieder einblenden liegt jetzt in der `header-nav`-Molecule, das Auf-Zu in
 * `renderer/headnav.go`. Vorher stand hier ein Media-Query mit
 * `.head-mobile-open` — eine Klasse, die NIEMAND gesetzt hat (kein Burger, kein
 * JS in beiden Repos). Die Navigation war unter 767px also weg und nicht
 * zurueckholbar. */

/* ─── Typografisch reduziert (2026-08-11) ───────────────────────────────
 * Diese Kopfzeile SCHWEBT UEBER DEM HERO. Sie hat damit eine andere Aufgabe als
 * eine Kopfzeile mit eigenem Grund: sie muss auffindbar sein, ohne mit der
 * Hero-Headline zu konkurrieren. Zwei Dinge lauter zu machen heisst, beides
 * leiser zu machen.
 *
 * Also: kleinere Marke, engeres Band, ruhigere Navigation — und KEINE Tagline.
 * Eine Positionierungszeile ueber einem Hero, der genau das schon sagt, ist
 * Doppelung. Der Slot bleibt (wer ihn braucht, hat ihn), er wird hier nur nicht
 * gezeigt.
 * ─────────────────────────────────────────────────────────────────────── */
.mypage .head_floating_glass .head-logo {
  --head-logo-h: 28px;          /* statt 40 — zwei Stufen kleiner als im Band */
}
.mypage .head_floating_glass .head-brand-text {
  font-size: 0.95rem;
  letter-spacing: 0.01em;
}
.mypage .head_floating_glass .head-tagline {
  display: none;
}
.mypage .head_floating_glass .head-nav-slot,
.mypage .head_floating_glass .em-nav {
  font-size: 0.85rem;
}

/* Eigenes Innenmass fuer die schwebende Karte (2026-08-11).
 *
 * Die Bandhoehe kam vorher ALLEIN vom 40px-Logo — es gab kein py-N an der Wurzel
 * und keine Polsterung hier. Sobald die Marke ein Schriftzug ist (25px) statt
 * eines Logos, schrumpfte die Karte auf 25px: ein Streifen, in dem der Text die
 * Kanten beruehrt. Eine schwebende Karte braucht ihr Mass selbst, unabhaengig
 * davon, was gerade drinsteht.
 *
 * `min-height` statt nur Polsterung, damit Logo- und Schriftzug-Fassung
 * DIESELBE Bandhoehe haben — sonst huepft die Karte, wenn ein Kunde vom
 * Schriftzug aufs Logo wechselt. 28px Logo + 2x14px = 56px. */
.mypage .head_floating_glass.hfg-card {
  padding-top: 0.875rem;
  padding-bottom: 0.875rem;
  min-height: 3.5rem;
  box-sizing: border-box;
}

/* ── head_simple ──────────────────────────────────────────── */
/* head_simple — Brand left + Nav right.
 * Default Overlay-Modus (Klasse `head-overlay` auf der Section) — Hero darunter
 * startet bei y=0. Nav-Items inline horizontal mit Lücke. Mobile: Burger. */
.mypage .head_simple .head_simple-row {
  display: flex;  /* 4f: entflaggt, am DOM gemessen — kein Gegenspieler */
  align-items: center;
}

/* Wordmark-Presentation: nur Pattern-spezifische Groesse + Letter-Spacing.
 * font-family bewusst NICHT gesetzt — kommt entweder von der .brand-text-
 * Klasse (3. Schrift, --brand-font) oder erbt vom Project-Body. Nicht-Prosa
 * (D3 Kategorie E/F, Wortmarke) — bleibt Pattern-Deklaration. */
.mypage .head_simple .head-brand {
  font-weight: 400;
  letter-spacing: 0.12em;
  font-size: 1.1rem;
}
/* TipTap normalisiert Brand-Inhalt zu <p>. Regel (margin:0) entfaellt:
 * einziges Kind des Brand-Text-Wrappers, :last-child (Spec D2) setzt
 * Margin schon auf 0. */

.mypage .head_simple .em-nav,
.mypage .head_simple .head-nav-slot {
  display: inline-flex;
  gap: 0.4rem 1.5rem;
  justify-content: flex-end;
  align-items: center;
}

/* Nav-Link, keine Prosa (D3 Kategorie E) — font-size bleibt Pattern-Deklaration. */
.mypage .head_simple .em-nav a {
  color: inherit;
  text-decoration: none;
  font-size: 0.95rem;
  letter-spacing: 0.02em;
  transition: opacity 0.15s ease;
}
.mypage .head_simple .em-nav a:hover {
  opacity: 0.65;
}

/* Mobile: Burger-Toggle via checkbox-hack. Klassen werden vom Renderer-
 * Output generiert (em-nav). Below md collapse to vertical drawer. */

/* Der Mobil-Block ist entfallen (2026-08-10): Navigation verstecken und
 * wieder einblenden liegt jetzt in der `header-nav`-Molecule, das Auf-Zu in
 * `renderer/headnav.go`. Vorher stand hier ein Media-Query mit
 * `.head-mobile-open` — eine Klasse, die NIEMAND gesetzt hat (kein Burger, kein
 * JS in beiden Repos). Die Navigation war unter 767px also weg und nicht
 * zurueckholbar. */

/* ── hero_centered ──────────────────────────────────────────── */

/* ── hero_compact ──────────────────────────────────────────── */

/* ── hero_dark_coach ──────────────────────────────────────────── */
/* hero_dark_coach — dunkler Hero: Portrait rechts, links Eyebrow + Claim
 * (Akzent-Wort in <em>) + Subline + Pill-CTA. Gestaffelte Entrance-Animation
 * (Eyebrow → Claim → Subline → CTA) rein per CSS, reduced-motion-aware.
 * Typografie/Farben aus em-base (sc-dark); Pattern nur für Layout, Akzent-Wort,
 * Pill-Radius und die Staffelung. */

.mypage .hero_dark_coach .col-12.max-w {
  align-items: center;
}
.mypage .hero_dark_coach .hdc-copy {
  align-self: center;
}

/* Akzent-Wort im Claim: em (em-base erzwingt kursiv !important) in Akzentfarbe —
 * kursiv + Akzent ist die bewusste Hervorhebung. */
.mypage .hero_dark_coach .hdc-text h1 em {
  color: var(--accent-base, var(--primary-light));
}

/* Portrait rechts, gerundet, feste Höhe. */
.mypage .hero_dark_coach .hdc-portrait,
.mypage .hero_dark_coach .hdc-portrait img {
  width: 100%;
  object-fit: cover;
  border-radius: var(--radius-lg, 1.25rem);
}

/* CTA links ausrichten (die :has()-Regel in em-components zentriert sonst) +
 * als Pill. */
/* Spezifitaet angehoben mit `section[type='layer']` (2026-08-10), NICHT mit
 * einem Flag. Gegenspieler ist die Button-Zeilen-Regel in em-components:
 *   `.mypage section[type='layer']:has(> a.btn-wrap) { justify-content: center }`
 * `:has()` erbt die Spezifitaet seines Arguments, die Regel liegt also bei
 * (0,3,2) und schlug die (0,3,0) hier — die CTA-Zeile stand zentriert statt an
 * der Kante. Sichtbar wurde das erst, seit `btn-wrap` am Anchor sitzt (Umzug
 * vom 2026-08-10): vorher trug der Reihen-Layer die Klasse selbst, das `:has`
 * traf nicht. Mit `section[type='layer']` liegt dieser Selektor bei (0,4,1) und
 * gewinnt per Spezifitaet. */
.mypage .hero_dark_coach section[type='layer'].hdc-cta-wrap {
  justify-content: flex-start;
}
.mypage .hero_dark_coach .btn-wrap {
  border-radius: 999px;
}

/* ── Gestaffelte Entrance: Eyebrow → Claim → Subline → CTA ──────────────
 * Nutzt die globale Animista-Keyframe emFadeInBottom (em-components.css).
 * Die RTE-Kinder (p.eyebrow / h1 / p.subline) werden per nth-child gestaffelt,
 * damit intro EIN RTE bleibt (Projekt B — keine getrennten Slots). */
.mypage .hero_dark_coach .hdc-text > *,
.mypage .hero_dark_coach .hdc-cta-wrap {
  animation: emFadeInBottom 600ms cubic-bezier(.25, .46, .45, .94) both;
}
.mypage .hero_dark_coach .hdc-text > :nth-child(1) { animation-delay: 60ms; }
.mypage .hero_dark_coach .hdc-text > :nth-child(2) { animation-delay: 200ms; }
.mypage .hero_dark_coach .hdc-text > :nth-child(3) { animation-delay: 340ms; }
.mypage .hero_dark_coach .hdc-cta-wrap { animation-delay: 480ms; }

@media (prefers-reduced-motion: reduce) {
  .mypage .hero_dark_coach .hdc-text > *,
  .mypage .hero_dark_coach .hdc-cta-wrap {
    animation: none;
  }
}

@media (max-width: 1023px) {
  .mypage .hero_dark_coach .hdc-portrait-col {
    margin-top: 2rem;
    order: -1;
  }
  .mypage .hero_dark_coach .hdc-portrait,
  .mypage .hero_dark_coach .hdc-portrait img {
    max-width: 18rem;
    margin: 0 auto;
  }
}

/* ── hero_eyebrow_pill ──────────────────────────────────────────── */
/* hero_eyebrow_pill — mark-pri Compact-Highlight
 * Override damit das Highlight nur die Wort-Boxen umfasst, nicht die
 * volle inline-block-Breite des Spans (Original-Bug bei zentrierten
 * Multi-Line-Headlines). */
.mypage .hero_eyebrow_pill h1 .mark,
.mypage .hero_eyebrow_pill h1 .mark-pri {
 -webkit-box-decoration-break: clone;
 box-decoration-break: clone;
 display: inline;
 padding: 0.05em 0.2em;
 background-image: linear-gradient(
 to right,
 color-mix(in srgb, var(--primary-base) 18%, transparent),
 color-mix(in srgb, var(--primary-base) 18%, transparent)
 );
 background-size: 100% 65%;
 background-position: 0 88%;
 background-repeat: no-repeat;
}


/* ── hero_form ──────────────────────────────────────────── */
/* hero_form — Inline-Form-Stack für die Email-Capture-Card.
 * Lokal auf das Pattern gescoped, kein globaler Stoff.
 */
.mypage .hero_form .signup-form-stack {
 display: flex;
 flex-direction: column;
 gap: 0.65rem;
 margin-top: 1rem;
}
.mypage .hero_form .signup-form-stack .form-label {
 font-size: 0.85rem;
 font-weight: 500;
 color: var(--text-muted, rgba(33,37,41,0.7));
 margin: 0;
}
.mypage .hero_form .signup-form-stack .form-input {
 width: 100%;
 padding: 0.7rem 0.9rem;
 font-size: 1rem;
 border: 1px solid var(--shade-lightgray);
 border-radius: 10px;
 background: var(--color-bg);
 font-family: inherit;
 color: inherit;
 transition: border-color .15s ease, box-shadow .15s ease;
}
.mypage .hero_form .signup-form-stack .form-input:focus {
 outline: none;
 border-color: var(--primary-base, #2563EB);
 box-shadow: 0 0 0 3px color-mix(in srgb, var(--primary-base, #2563EB) 18%, transparent);
}
.mypage .hero_form .signup-form-stack .btn-wrap {
 margin-top: 0.5rem;
 width: 100%;
 justify-content: center;
}
.mypage .hero_form .signup-form-stack .form-hint {
 font-size: 0.8rem;
 color: var(--text-muted, rgba(33,37,41,0.55));
 margin: 0.25rem 0 0;
}

/* Mini circular avatar thumbnails in trust strip.
 * border-radius/object-fit ohne Flag (Stufe 4c, Rest, 2026-07-30): dieses
 * Pattern nutzt die avatar-stack-Molecule NICHT (kein `.molecule.avatar-
 * stack`-Wrapper im Markup, geprueft) — die Molecule-Regeln fuer
 * `.trust-avatar` greifen also gar nicht. Kein anderer Gegenspieler fuer
 * border-radius/object-fit auf `.trust-avatar` im ganzen Repo gefunden
 * (nur `.mypage img { max-width; height:auto }` global, ohne diese
 * Properties). Flag war reine Vorsicht. */
.mypage .hero_form .trust-avatar,
.mypage .hero_form img.trust-avatar {
  width: 3rem;  /* 4f: entflaggt, am DOM gemessen — kein Gegenspieler */
  height: 3rem;  /* 4f: entflaggt, am DOM gemessen — kein Gegenspieler */
  max-width: 3rem;  /* 4f: entflaggt, am DOM gemessen — kein Gegenspieler */
  border-radius: 50%;
  object-fit: cover;
  display: inline-block;
  /* Overlap 0.25 der Breite = 12px bei 3rem, wie die avatar-stack-Molecule
   seit 2026-08-10 (dieses Pattern hat keinen molecule-Wrapper und traegt
   eine eigene Kopie der Regeln — Wert deshalb hier nachgezogen). */
  margin: 0 -0.75rem 0 0;
  border: 2px solid var(--color-bg, #fff);
  box-shadow: 0 2px 6px color-mix(in srgb, var(--shade-dark-base) 12%, transparent);
  vertical-align: middle;
}

/* Trust-Strip-Inline-Row: Sterne + Rating-Text. Sterne als Unicode-
 * Glyphs sitzen tief unter dem Baseline; flex + align-items:center
 * zentriert sie optisch auf der Text-Mitte. */
.mypage .hero_form .scene-trust-strip {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: 0.5rem;
}
.mypage .hero_form .stars {
  display: inline-flex;
  align-items: center;
  line-height: 1;
  color: #f5a623;
  font-size: 1.05em;
  letter-spacing: 0.05em;
  /* Unicode-Stern-Glyph-Ink sitzt ~5.8px unter der Text-Ink-Mitte
   * (gemessen via Range.getBoundingClientRect Ink-Vergleich gegen
   * trust-strip-text). -0.46em ≈ -7.8px hebt die Stars-Ink auf die
   * Text-Baseline-Mitte. */
  position: relative;
  top: -0.46em;
}
.mypage .hero_form .trust-strip-text,
.mypage .hero_form .trust-strip-text p {
  margin: 0;
  line-height: 1.4;
}

/* ── hero_image_right ──────────────────────────────────────────── */
/* hero_image_right — 6/6 Split: linke Text-Spalte, rechte Bild-Spalte.
 *
 * Hoehe wird ueber die image-col (rechte Spalte) gesteuert — entweder via
 * aspect-*-Klasse (Format bestimmt Hoehe) oder vh-*-Klasse (feste Hoehe).
 * Picker im Editor sitzt am Bildcontainer. align-items:stretch zieht die
 * Text-Spalte auf die gleiche Hoehe.
 *
 * Wenn KEINE Klasse gesetzt ist (Auto), greift hier ein min-height-Fallback.
 */
.mypage .hero_image_right > section[type='layer'].col-12 {
  align-items: stretch;
}
.mypage .hero_image_right > section[type='layer'].col-12 > section[type='layer'].col-6:first-child {
  display: flex;
  flex-direction: column;
  justify-content: center;
  gap: 1rem;
  padding: 2rem 1.5rem;
  min-width: 0;
}
.mypage .hero_image_right > section[type='layer'].col-12 > section[type='layer'].col-6:last-child {
  position: relative;
  overflow: hidden;
}
/* Fallback: nur wenn der Author keine Format-/Hoehen-Klasse gesetzt hat. */
.mypage .hero_image_right > section[type='layer'].col-12 > section[type='layer'].col-6:last-child:not([class*="aspect-"]):not([class*="vh-"]) {
  min-height: 45vw;
}
/* Wenn aspect-* gesetzt ist: image-col NICHT stretchen. Sonst stretchen
 * flexbox + align-items:stretch die Hoehe auf max(text-col, image-col)
 * und das aspect-ratio wird ignoriert. align-self:center laesst die
 * aspect-derived Hoehe wirken und zentriert das Bild vertikal in der
 * Row, falls text-col groesser ist. Bei vh-* ist Stretch erwuenscht. */
.mypage .hero_image_right > section[type='layer'].col-12 > section[type='layer'].col-6:last-child[class*="aspect-"] {
  align-self: center;
}
.mypage .hero_image_right > section[type='layer'].col-12 > section[type='layer'].col-6:last-child img,
.mypage .hero_image_right > section[type='layer'].col-12 > section[type='layer'].col-6:last-child picture {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  object-fit: cover;
}

@media (max-width: 767px) {
  .mypage .hero_image_right > section[type='layer'].col-12 > section[type='layer'].col-6:last-child {
    order: -1;
  }
  /* Mobile-Fallback: aspect-Klassen werden in fullbleed.css unter 640px
   * auf aspect-ratio:auto gesetzt, deshalb hier zusaetzlich ein
   * intrinsisches Hoehen-Minimum, damit die image-col sichtbar bleibt. */
  .mypage .hero_image_right > section[type='layer'].col-12 > section[type='layer'].col-6:last-child:not([class*="vh-"]) {
    min-height: 56vw;
  }
}

/* CTA-Abstand pattern-lokal auf 1rem (2026-08-10).
 * Die Eltern-Reihe dieses Heroes traegt ein `gap-2` fuer ihre gestapelten
 * Bloecke, und ein row-gap addiert sich zum `margin-top` der CTA-Zeile:
 * 16px gap + 32px Standard + 4px Eigenabstand des Buttons = 52px, waehrend
 * die anderen 21 CTA-Zeilen bei 36px liegen. Mit 1rem kommt der Abstand auf
 * dieselben 36px — die Reihe traegt 16, der gap 16.
 * Bewusst ueber `--cta-gap` und nicht ueber ein eigenes margin: der Wert
 * bleibt damit an der Variable, die em-components fuehrt, und ein Umstellen
 * des Systemwerts wirkt hier weiter mit. */
.mypage .hero_image_right section[type='layer'].col-12:has(> button.btn-wrap),
.mypage .hero_image_right section[type='layer'].col-12:has(> a.btn-wrap) {
  --cta-gap: 1rem;
}

/* ── hero_image_right_full ──────────────────────────────────────────── */
/* hero_image_right_full — Full-bleed 6/6: linke Text-Spalte, rechte Bild
 * volle Section-Hoehe. Image edge-to-edge, kein Padding, object-fit cover.
 */
.mypage .hero_image_right_full > section[type='layer'].col-12 {
  min-height: 80vh;
  align-items: stretch;
}
.mypage .hero_image_right_full > section[type='layer'].col-12 > section[type='layer'].col-6:first-child {
  display: flex;
  flex-direction: column;
  justify-content: center;
  gap: 1rem;
  padding: 3rem 2rem 3rem 3rem;
  min-width: 0;
}
.mypage .hero_image_right_full > section[type='layer'].col-12 > section[type='layer'].col-6:last-child {
  position: relative;
  overflow: hidden;
  min-height: 80vh;
}
.mypage .hero_image_right_full > section[type='layer'].col-12 > section[type='layer'].col-6:last-child img,
.mypage .hero_image_right_full > section[type='layer'].col-12 > section[type='layer'].col-6:last-child picture {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  object-fit: cover;
}

@media (max-width: 767px) {
  .mypage .hero_image_right_full > section[type='layer'].col-12 {
    min-height: auto;
  }
  .mypage .hero_image_right_full > section[type='layer'].col-12 > section[type='layer'].col-6:last-child {
    min-height: 60vw;
    order: -1;
  }
}

/* CTA-Abstand pattern-lokal auf 1rem (2026-08-10).
 * Die Eltern-Reihe dieses Heroes traegt ein `gap-2` fuer ihre gestapelten
 * Bloecke, und ein row-gap addiert sich zum `margin-top` der CTA-Zeile:
 * 16px gap + 32px Standard + 4px Eigenabstand des Buttons = 52px, waehrend
 * die anderen 21 CTA-Zeilen bei 36px liegen. Mit 1rem kommt der Abstand auf
 * dieselben 36px — die Reihe traegt 16, der gap 16.
 * Bewusst ueber `--cta-gap` und nicht ueber ein eigenes margin: der Wert
 * bleibt damit an der Variable, die em-components fuehrt, und ein Umstellen
 * des Systemwerts wirkt hier weiter mit. */
.mypage .hero_image_right_full section[type='layer'].col-12:has(> button.btn-wrap),
.mypage .hero_image_right_full section[type='layer'].col-12:has(> a.btn-wrap) {
  --cta-gap: 1rem;
}

/* ── hero_minimal ──────────────────────────────────────────── */
/* hero_minimal — Type-First Hero: Oversized Typography, maximum Whitespace.
 *
 * Hoehe kommt jetzt aus `vh-60` im Template (2026-08-10), nicht mehr aus einem
 * Hardcode hier. Vorher standen 70vh / 60vh / 50vh ueber drei Breakpoints in
 * dieser Datei — das war eine zweite Kopie des Hoehen-Modells, das
 * `css/fullbleed.css` schon als `vh-N`-Leiter fuehrt und das der
 * „Hero-Hoehe"-Picker im Editor bedient. Solange der Wert hier stand, konnte
 * der Picker ihn nicht aendern.
 * Die Breakpoint-Staffelung entfaellt bewusst: `vh` ist von sich aus relativ
 * zum Viewport, 60vh sind auf dem Telefon 60% eines kleinen Fensters. Die
 * Staffelung hat also ein Problem geloest, das die Einheit nicht hat. */
.mypage .hero_minimal {
  display: flex;
  flex-wrap: nowrap;          /* override globale col-12 flex-wrap: wrap */
  align-items: center;
  justify-content: center;
}

/* Headline tighter spacing — Hero-Display-Ausnahme (D3 explizit benannt).
 * line-height 1.05 ist bewusst enger als der H1-Default (1.15) — bei
 * Display-Groesse (txt-6xl) sonst zu viel Weissraum zwischen Zeilen.
 * margin-bottom 1.5rem ist der bewusst groessere Abstand zur Subline bei
 * dieser Display-Groesse (H1-Default 0.55em waere hier zu knapp). Beide
 * bleiben unveraendert. */
.mypage .hero_minimal h1.txt-6xl {
  letter-spacing: -0.02em;
  line-height: 1.05;
  margin-bottom: 0.5em;  /* Leiter: rem -> em, 24 -> 28.7px */
}

/* Subline knapp + leiser. Groesse via --h1sub-font-size — gepaart mit
 * der Hero-H1, faellt mit der Project-Type-Scale automatisch passend.
 * font-size sieht wie ein Duplikat der Basis-Utility .h1sub aus (beide
 * lesen dieselbe Variable), bleibt aber bewusst auf .subline statt einer
 * Klassen-Umstellung: Subline.js (EmPages-RTE) rendert dieses Format IMMER
 * mit class="subline" (hart codiert in renderHTML, mergeAttributes(...,
 * {class:'subline'})) — eine Umbenennung auf "h1sub" wuerde beim naechsten
 * Speichern in TipTap wieder auf "subline" zurueckspringen. Ausserdem
 * haengen die Zentrierung/max-width-Regeln weiter unten in dieser Datei
 * an .subline, nicht an .h1sub — eine reine Klassen-Umbenennung im
 * pattern.json/-template wuerde die Zentrierung sofort brechen, noch vor
 * jeder RTE-Bearbeitung. Da --h1sub-font-size und die Basis-Utility
 * dieselbe Variable referenzieren, ist das kein Wert-Duplikat, das
 * auseinanderdriften kann — nur redundant geschrieben. */
.mypage .hero_minimal .subline {
  font-size: var(--h1sub-font-size);
  color: var(--text-muted);
  max-width: 38ch;
  /* em-base .mypage p.subline ueberschreibt nur margin-top/-bottom
   * !important, laesst margin-left/-right bei der generischen .mypage p
   * {margin:0 0 1.25em !important} Regel (0) — !important noetig um die
   * 0-Werte zu schlagen und die max-width-Zentrierung durchzusetzen. */
  margin-left: auto;  /* 4f: entflaggt, am DOM gemessen — kein Gegenspieler */
  margin-right: auto;  /* 4f: entflaggt, am DOM gemessen — kein Gegenspieler */
}

/* Mobile-Override fuer txt-6xl-H1 entfernt — Type-Scale-Anpassung gehoert
 * ins em-base (via --type-base / --type-scale), nicht ins Pattern. */
/* ── hero_pitchdeck ──────────────────────────────────────────── */
/* hero_pitchdeck — Pitchdeck-Hero: H1 links + Meta-Spalte rechts, darunter Bild-Card.
 * Typografie + Alignment kommen über Utility-Klassen im Template (text-left,
 * text-right). Hier nur pattern-spezifisches Visual: gerundete Card-Form +
 * Hero-Bild via background-image. Keine H1-Hardcodes — H1 nutzt em-base
 * --h1-font-size, identisch in Edit- und Preview-DOM. */
.mypage .hero_pitchdeck .hero-card-top {
 background: var(--color-bg);
 color: var(--text-dark);
 border-radius: 2rem 2rem 0 0;
}
.mypage .hero_pitchdeck .hero-card-image {
 aspect-ratio: 16 / 9;
 background-image: url('/patterns/assets/img/stock/agentur-team.webp');
 background-size: cover;
 background-position: center;
 border-radius: 0 0 2rem 2rem;
}
/* Autorenname: caption-sub (RTE-wählbarer Absatzstil, Basis in em-base.css),
 * ersetzt die frühere Marker-Klasse .hero-card-author (Projekt B, 2026-07-24). */
/* hero-card-meta: Layout-Container fuer chip (icontext) + author (html-p).
 * Beide untereinander rechtsbuendig. */
.mypage .hero_pitchdeck .hero-card-meta {
 display: flex;  /* 4f: entflaggt, am DOM gemessen — kein Gegenspieler */
 flex-direction: column;
 align-items: flex-end;
 gap: 0.5rem;
}

/* ── hero_slider ──────────────────────────────────────────── */
/* hero_slider — Fullbleed Hero Carousel
 * Hintergrundbild per Layer-style-Attribut (nativer Pages-Editor-Button).
 * Scrim via ::before, Content via z-index.
 */

.mypage .hero_slider [type='carousel'] {
  overflow: hidden;
}

/* Slides ohne horizontale Innenabstaende — Hero-Slider ist full-bleed,
 * der em-components Default cr-slide padding: 0 0.5rem (fuer Slide-Gaps
 * bei multi-slide-Karussellen) wuerde hier einen sichtbaren Randabstand
 * erzeugen. */
.mypage .hero_slider .cr-slide {
  position: relative;
  padding: 0;
}

/* ── Slide: BG via style-Attribut, Scrim via ::before ─────── */
.mypage .hero_slider .hero-slide {
  position: relative;
  display: flex;
  align-items: center;
  justify-content: center;
  width: 100%;
}

.mypage .hero_slider .hero-slide::before {
  content: '';
  position: absolute;
  inset: 0;
  background: color-mix(in srgb, var(--shade-dark-base) 52%, transparent);
  z-index: 1;
  pointer-events: none;
}

/* ── Content ──────────────────────────────────────────────── */
/* padding-top/-bottom ohne Flag (Stufe 4c, Rest, 2026-07-30): `.hero-slide-
 * content` traegt selbst die Klasse `max-w`, ist aber KIND von `.cr-slide`,
 * nicht Kind eines `.max-w` — die Gutter-Regel der Grid-Engine greift also
 * nicht (falscher Elternbezug). `.mypage .max-w` selbst setzt kein Padding
 * (nur display/max-width/margin, geprueft in em-base.css + em-components.css).
 * Kein Gegenspieler fuer padding-top/-bottom gefunden, Flag war reine
 * Vorsicht. */
.mypage .hero_slider .hero-slide-content {
  position: relative;
  z-index: 2;
  padding-top: 0;
  padding-bottom: 0;
}

.mypage .hero_slider .hero-slide-cta {
  display: flex;
  justify-content: center;
  gap: 1rem;
}

/* ── Typografie ───────────────────────────────────────────── */

/* color ohne Flag (Stufe 4c, Gruppe E, 2026-07-30): zwei Gegenspieler
 * geprueft — `.mypage .eyebrow` (em-base.css/em-components.css, WCAG-Default
 * fuer HELLEN Hintergrund via --eyebrow-font-color) ist (0,2,0); `.text-light
 * .eyebrow` (fullbleed.css, faerbt Eyebrow/h1..h6/p auf Bild-Hintergruenden
 * um) ist ebenfalls (0,2,0) und laedt nach den Basis-Dateien, gewinnt also
 * bereits gegen den Eyebrow-Default. Dieser Pattern-Selektor `.mypage
 * .hero_slider .hero-slide .eyebrow` ist (0,4,0) — schlaegt BEIDE outright,
 * kein Gleichstand. Farbwert bleibt UNVERAENDERT: `color-mix(in srgb,
 * var(--text-light) 75%, transparent)` gilt vorher wie nachher, nur der
 * Mechanismus wechselt von !important auf Spezifitaet. */
.mypage .hero_slider .hero-slide .eyebrow {
  color: color-mix(in srgb, var(--text-light) 75%, transparent);
  margin-bottom: 0.75rem;
}

/* font-size sieht wie ein Duplikat der Basis-Utility .h1sub aus (beide
 * lesen dieselbe Variable --h1sub-font-size), bleibt aber bewusst auf
 * .subline statt einer Klassen-Umstellung — wie bei hero_minimal:
 * Subline.js (EmPages-RTE) rendert dieses Format IMMER mit class="subline"
 * (hart codiert), eine Umbenennung auf "h1sub" waere beim naechsten
 * Speichern in TipTap verloren. Der Subline-Sample-Text liegt hier zudem
 * pro Slide in meta.json (samples[].subline), nicht in pattern.json —
 * class="h1sub" wuerde ausserdem die Zentrierung/max-width-Regeln direkt
 * unten brechen, die an .subline haengen, nicht an .h1sub. Da beide
 * Selektoren dieselbe CSS-Variable referenzieren, ist es kein Wert-
 * Duplikat, das auseinanderdriften kann — nur redundant geschrieben. */
.mypage .hero_slider .hero-slide .subline {
  color: color-mix(in srgb, var(--text-light) 85%, transparent);
  font-size: var(--h1sub-font-size);
  max-width: 50ch;
  /* em-base setzt .mypage p.subline { margin-top/-bottom !important } aber
   * laesst margin-left/-right bei der generischen .mypage p { margin:0 0 1.25em
   * !important } Regel (0). Das reicht fuer normalerweise full-width Sublines,
   * aber hier braucht .subline wegen max-width:50ch echte Zentrierung —
   * !important noetig um die 0-Werte zu schlagen (analog .hcln-brand p Fix). */
  margin-left: auto;  /* 4f: entflaggt, am DOM gemessen — kein Gegenspieler */
  margin-right: auto;  /* 4f: entflaggt, am DOM gemessen — kein Gegenspieler */
  text-align: center;
}

/* ── Navigation ───────────────────────────────────────────── */
.mypage .hero_slider .cr-prev,
.mypage .hero_slider .cr-next {
  z-index: 10;
  background: color-mix(in srgb, var(--text-light) 18%, transparent);
  color: var(--text-light);
}

.mypage .hero_slider .cr-prev:hover,
.mypage .hero_slider .cr-next:hover {
  background: color-mix(in srgb, var(--text-light) 35%, transparent);
}

.mypage .hero_slider .cr-dots {
  position: absolute;
  bottom: 1.5rem;
  left: 50%;
  transform: translateX(-50%);
  z-index: 10;
  margin: 0;
}

.mypage .hero_slider .cr-dot        { background: color-mix(in srgb, var(--text-light) 50%, transparent); }
.mypage .hero_slider .cr-dot.active { background: var(--text-light); opacity: 1; }

@media (max-width: 640px) {
  
}

/* ── hero_split ──────────────────────────────────────────── */
/* hero_split — Flacher Split-Hero: linke Text-Hälfte + rechte Bild-Hälfte.
 *
 * Layout: Zwei col-6-Spalten ohne max-w → volle Breite Edge-to-Edge.
 *
 * Hoehe wird ueber die hero-img-col (rechte Spalte) gesteuert — entweder
 * via aspect-*-Klasse (Format bestimmt Hoehe) oder vh-*-Klasse (feste
 * Hoehe). Picker im Editor sitzt am Bildcontainer.
 * align-items:stretch (em-base) zieht die linke Text-Spalte mit.
 *
 * Color-pair: sc-* auf .hero-txt-col gesetzt, Schrift folgt dem Pair.
 */

/* ─── Linke Text-Spalte ─── */
.mypage .hero_split .hero-txt-col {
  display: flex;
  flex-direction: column;
  /* justify-content:center fuer vertikale Mittelachse — sonst klebt der
   * Text-Block am oberen Rand und die rechte Bild-Hälfte wirkt überproportioniert. */
  justify-content: center;
  gap: 1rem;
  padding: 2rem 1.5rem;
  /* min-width:0 erzwingt dass die Spalte ihre col-6-Breite respektiert auch
   * bei langen H1-Wörtern — ohne diesen Reset hat flex default min-width:auto,
   * dann sprengt der H1-Text die Spalte und ragt in die hero-img-col rein. */
  min-width: 0;
}

/* ─── Rechte Bild-Spalte ─── */
.mypage .hero_split .hero-img-col {
  position: relative;
  overflow: hidden;
}
/* Fallback-Hoehe nur wenn keine Format-/vh-Klasse gesetzt. */
.mypage .hero_split .hero-img-col:not([class*="aspect-"]):not([class*="vh-"]) {
  min-height: 45vw;
}
/* Bei aspect-* nicht stretchen — sonst gewinnt flexbox-stretch ueber
 * aspect-ratio und das Format wird ignoriert. */
.mypage .hero_split .hero-img-col[class*="aspect-"] {
  align-self: center;
}

/* Das gerenderte section[data-key="image"] und das darin liegende img/picture
   füllen die Spalte vollständig — object-fit:cover für sauberen Beschnitt. */
.mypage .hero_split .hero-img-col section[type="layer"][data-key="image"],
.mypage .hero_split .hero-img-col picture,
.mypage .hero_split .hero-img-col img {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  object-fit: cover;
  display: block;
}

/* ─── Mobile: ≤640px — Bild oben, Text darunter ───
 * em-components.css stackt col-6-Geschwister automatisch zu col-12 in
 * natürlicher Quellreihenfolge. Wir wollen aber Bild ZUERST (Hook),
 * dann Text — deshalb order:-1 auf der Image-Col. */
@media (max-width: 640px) {
  .mypage .hero_split .hero-img-col {
    order: -1;
  }
  /* Mobile-Fallback: fullbleed.css resettet aspect-*-Klassen unter 640px,
   * vh-* bleibt. Wenn weder gesetzt noch Mobile-vh aktiv: intrinsisches
   * Minimum, damit die image-col sichtbar bleibt. */
  .mypage .hero_split .hero-img-col:not([class*="vh-"]) {
    min-height: 55vw;
  }
  .mypage .hero_split .hero-txt-col {
    padding: 1.5rem 0;
  }
}


/* ── hero_split_textleft_full ──────────────────────────────────────────── */

/* ── offer_image_left ──────────────────────────────────────────── */
/* offer-image-inline: Bild als Content (Logo/Illustration), nicht als
 * stretched BG. object-fit:contain verhindert Beschneidung; max-height
 * begrenzt vertikales Wachstum bei quadratischen/hochformatigen Bildern. */

/* ── offer_image_left_full ──────────────────────────────────────────── */

/* ── offer_image_right ──────────────────────────────────────────── */

/* ── offer_image_right_full ──────────────────────────────────────────── */

/* ── offer_services_slider ──────────────────────────────────────────── */
/* Center inner wrappers with max-w; beat section-layer inline-block default.
 * display/margin-left/margin-right ohne Flag (Stufe 4d-2, 2026-08-07): der
 * globale Fix in em-components.css (`.mypage section[type='layer'].max-w,
 * ... { display:block }`) ist bereits (0,3,1) [mypage + [type='layer'] +
 * .max-w Klassen, section Typ] und schlaegt den render-struct-Inline-Block-
 * Default (0,2,1) [mypage + [type='layer'] Klassen, section Typ]. Dieser
 * Pattern-Selektor traegt mit `.offer_services_slider` eine Klasse MEHR als
 * der globale Fix: (0,4,1) — schlaegt damit BEIDE outright, unabhaengig vom
 * Flag. margin-left/margin-right: einziger Gegenspieler ist `.mypage .max-w`
 * (em-base.css) mit (0,2,0) — ebenfalls klar geschlagen. */
.mypage .offer_services_slider > section[type='layer'].max-w {
  display: block;
  width: 100%;
  max-width: var(--max-w, 1200px);
  margin-left: auto;
  margin-right: auto;
}

/* offer_services_slider — Service-Cards Carousel (per-view: 3)
 *
 * Renderer hängt user-`class` an <img>, NICHT an <picture>. Wir müssen also
 * BEIDE styling-Ziele bedienen:
 *   - <picture> (Container) via :has(img.card-image) — sicheres Sizing
 *   - <img class="card-image"> — fillt picture-Container mit cover
 * :has() ist heute überall supported und vermeidet das alte Anti-Pattern,
 * picture per <picture class="card-image"> stylen zu wollen (renderer setzt
 * dort keine Klasse).
 */
/* aspect-ratio ohne Flag (Stufe 4c, Rest, 2026-07-30): kein anderes CSS im
 * Repo setzt aspect-ratio auf `picture[type='picture']` (die em-base.css
 * `.aspect-16-9`-Utility greift auf einem anderen Element — dem `<img
 * class="card-image aspect-16-9">` selbst, nicht auf `<picture>` — und
 * kollidiert daher nicht). display/width/height/max-height ohne Flag (Stufe
 * 4d-2, 2026-08-07): dieser Selektor liegt mit `:has(> img.card-image)`
 * (das `:has()`-Argument `img.card-image` traegt (0,1,1) bei) bei (0,4,2) —
 * schlaegt den einzigen Gegenspieler `.mypage picture { display:
 * inline-block }` (render-struct.css, (0,1,1)) klar. Kein anderes CSS im
 * Repo setzt width/height/max-height auf `picture`. */
.mypage .offer_services_slider picture[type='picture']:has(> img.card-image) {
  display: block;
  width: 100%;
  aspect-ratio: 16 / 9;
  height: auto;
  max-height: none;
  overflow: hidden;
  border-radius: 0.5rem 0.5rem 0 0;
}
/* object-fit ohne Flag (Stufe 4c, Rest, 2026-07-30): einziger Gegenspieler
 * ist `.mypage img.aspect-16-9 { object-fit: cover }` (em-base.css, greift
 * weil das Bild zusaetzlich die Utility-Klasse "aspect-16-9" traegt) —
 * (0,2,1) gegen diesen Pattern-Selektor `.mypage .offer_services_slider
 * img.card-image` (0,3,1). Pattern gewinnt outright per Spezifitaet, Werte
 * sind ohnehin identisch (`cover`). width/height/max-width/max-height ohne
 * Flag (Stufe 4d-2, 2026-08-07): gleiche Rechnung — (0,3,1) schlaegt sowohl
 * `.mypage img.aspect-16-9` (0,2,1, width/height:100%) als auch die
 * generischen Resets `.mypage img { width:100% }` (render-struct.css) und
 * `.mypage img { max-width:100%; height:auto }` (em-components.css), beide
 * (0,1,1). */
.mypage .offer_services_slider img.card-image {
  display: block;
  width: 100%;
  height: 100%;
  max-width: none;
  max-height: none;
  object-fit: cover;
}
/* TOTER SELEKTOR entfernt (Stufe 4d-2, 2026-08-07): `.splide__slide` /
 * `[data-carousel-slide]` kommen im gerenderten Markup dieses Patterns nicht
 * vor. Der `carousel`-Key (json2html-Renderer, siehe docs/superpowers/specs/
 * 2026-05-27-carousel-key-type-design.md) erzeugt
 * `<div class="cr-track"><div class="cr-slide">...</div></div>` — eine
 * eigene Vanilla-JS-Loesung (`emCarousel`), kein Splide.js. Die Regel wurde
 * am 2026-06-16 defensiv ("falls Splide variable Breiten setzt") fuer zwei
 * geratene Klassennamen zugleich eingebaut, keiner trifft — git-blame zeigt,
 * dass der Vorgaenger-Slug gserv_3cards_slider von Anfang an mit dem
 * `carousel`-Key/`cr-slide`-System gebaut wurde, nie mit Splide. Selbst mit
 * korrektem Selektor waere die Regel redundant: em-components.css setzt
 * bereits global `.cr-slide { flex: 0 0 calc(100% / var(--per-view, 1)); }`,
 * und die emCarousel-Initialisierung setzt `--per-view` aus
 * `data-per-view="3"` — exakt der Wert, den die tote Regel hart auf
 * `calc(100% / 3)` dupliziert haette. Kein Ersatz noetig. */
/* Card hat keine eigene Padding mehr (px-2 py-4 raus aus Template); damit das
 * Bild fullbleed an den Card-Ecken sitzt. overflow:hidden auf der Card sorgt
 * dafür, dass das Bild bei rounded corners sauber clippt. Body + Button
 * bekommen ihr Padding lokal, sodass nur das Bild edge-to-edge sitzt.
 *
 * Explizit flex-direction column + align-items stretch + justify-content
 * flex-start, sonst greift die globale `section[type='layer']:has(> a.btn-
 * wrap)` Regel aus em-components.css und macht die Card zu flex-row mit
 * justify-content center → Card-Inhalte rendern dann horizontal zentriert
 * statt top-stacked.
 *
 * display/flex-direction/align-items/justify-content ohne Flag (Stufe 4d-2,
 * 2026-08-07): dieser Selektor `.mypage .offer_services_slider
 * .molecule.card.feature-card` hat 5 Klassen = (0,5,0). Der im Kommentar
 * genannte Gegenspieler `.mypage section[type='layer']:has(> a.btn-wrap)`
 * wird durch das `:has()`-Argument `a.btn-wrap` (0,1,1) auf (0,3,2)
 * ausgerechnet — 5 Klassen schlagen 3 Klassen, unabhaengig vom Typ-Anteil.
 * Ein zweiter, schwaecherer Gegenspieler `.mypage .molecule.feature-card`
 * (feature-card/molecule.css, display:flex + flex-direction:column) liegt
 * bei (0,3,0) — ebenfalls klar geschlagen. */
.mypage .offer_services_slider .molecule.card.feature-card {
  display: flex;
  flex-direction: column;
  align-items: stretch;
  justify-content: flex-start;
  overflow: hidden;
}
.mypage .offer_services_slider .card-body {
  padding: 1rem 1rem 0.5rem;
}
/* Button: margin-top: auto pinnt ihn an die Card-Unterkante, sodass alle
 * Cards (unabhängig von Body-Länge) ihre Buttons auf gleicher Höhe haben. */
.mypage .offer_services_slider .molecule.card.feature-card > a.btn-wrap {
  margin: 0.25rem 1rem 1rem;
  margin-top: auto;
  align-self: flex-start;
}

/* ── price_2tiers ──────────────────────────────────────────── */
/* price_2tiers — two-tier pricing (Self-Service / Full-Service).
 *
 * Color-pair self-consistency on root; the featured tier carries
 * sc-acc-l locally for the inverse-on-bg readability.
 */
.mypage .price_2tiers.sc-dark,
.mypage .price_2tiers.sc-pri,
.mypage .price_2tiers.sc-sec,
.mypage .price_2tiers.sc-acc {
  color: var(--sc-light, #f5f5f0);
}
.mypage .price_2tiers.sc-light,
.mypage .price_2tiers.sc-pri-l,
.mypage .price_2tiers.sc-sec-l,
.mypage .price_2tiers.sc-acc-l {
  color: var(--sc-dark, #1a1a1a);
}

/* ── price_3tiers ──────────────────────────────────────────── */
/* price_3tiers — three pricing tiers (Starter / Professional / Enterprise).
 *
 * Color-pair self-consistency: the section-root foreground tracks
 * sc-* on the root; the featured tier carries its own sc-acc-l
 * locally, which the cards' molecule CSS already inverts — so the
 * featured card stays readable independent of section-bg.
 */
.mypage .price_3tiers.sc-dark,
.mypage .price_3tiers.sc-pri,
.mypage .price_3tiers.sc-sec,
.mypage .price_3tiers.sc-acc {
  color: var(--sc-light, #f5f5f0);
}
.mypage .price_3tiers.sc-light,
.mypage .price_3tiers.sc-pri-l,
.mypage .price_3tiers.sc-sec-l,
.mypage .price_3tiers.sc-acc-l {
  color: var(--sc-dark, #1a1a1a);
}

/* ── price_compare ──────────────────────────────────────────── */
/* price_compare — Pricing-Compare-Tabelle */
.mypage .price_compare .compare-wrap {
 overflow-x: auto;
}
/* Tabellen-Text, Card-Dichte — keine Prosa (D3 Kategorie E). Die ganze
 * Tabelle ist Nicht-Prosa (th/td-Struktur), Basis-Typografie nicht
 * zustaendig; font-size bleibt Pattern-Deklaration. */
.mypage .price_compare .pricing-compare {
 width: 100%;
 border-collapse: collapse;
 border-radius: 14px;
 overflow: hidden;
 background: var(--color-bg);
 box-shadow: 0 1px 3px color-mix(in srgb, var(--shade-dark-base) 6%, transparent);
 font-size: 0.95rem;
}
.mypage .price_compare .pricing-compare th,
.mypage .price_compare .pricing-compare td {
 padding: 0.85rem 1rem;
 text-align: center;
 border-bottom: 1px solid color-mix(in srgb, var(--text-dark) 6%, transparent);
}
/* Tabellenkopf, keine Prosa (D3 Kategorie E) — font-weight bleibt Pattern-
 * Deklaration. */
.mypage .price_compare .pricing-compare thead th {
 background: color-mix(in srgb, var(--text-dark) 4%, transparent);
 font-weight: 700;
 vertical-align: top;
 padding: 1.1rem 1rem;
}
/* Preis-Highlight (Nicht-Prosa, D3 Kategorie E/F) — font-size/font-weight
 * bleiben Pattern-Deklaration. margin-top ist Kategorie G (kein h/p-
 * Selektor), unangetastet. */
.mypage .price_compare .pricing-compare .plan-price {
 display: block;
 font-size: 1.05rem;
 font-weight: 600;
 /* Preis sitzt auf leicht getönten Plan-Spalten (thead 4% + feat-col-active
  * 6% primary tint). accent-on-light ist auf 4,5:1 gegen WEISS geklemmt und
  * fällt auf den Tints unter 4,5. Lokal abdunkeln (accent + text-dark gemischt)
  * → bleibt erkennbar Brand-Blau, hält aber ≥4,5:1 auch auf den Tints. */
 color: color-mix(in srgb, var(--accent-on-light, var(--primary-base)) 75%, var(--text-dark));
 margin-top: 0.25rem;
}
/* Tabellen-Struktur, keine Prosa (D3 Kategorie E) — font-weight bleibt
 * Pattern-Deklaration fuer .feat-col / tbody-Erstspalte / feat-col-active. */
.mypage .price_compare .pricing-compare .feat-col {
 text-align: left;
 font-weight: 600;
}
.mypage .price_compare .pricing-compare tbody td:first-child {
 text-align: left;
 font-weight: 500;
}
.mypage .price_compare .pricing-compare .feat-col-active {
 background: color-mix(in srgb, var(--primary-base) 6%, transparent);
 font-weight: 600;
}
/* Tabellen-Gruppentitel, keine Prosa (D3 Kategorie E) — font-weight/
 * font-size bleiben Pattern-Deklaration. */
.mypage .price_compare .pricing-compare .feat-group td {
 background: color-mix(in srgb, var(--text-dark) 4.5%, transparent);
 font-weight: 700;
 text-transform: uppercase;
 letter-spacing: 0.04em;
 font-size: 0.78rem;
 text-align: left;
 padding: 0.7rem 1rem;
 color: color-mix(in srgb, var(--text-dark) 60%, transparent);
}

/* ── price_single ──────────────────────────────────────────── */
/* price_single — Override pricing-card check-glyph with
 * mask-image SVG (Unicode '✓' renders as Hollow-Square in headless
 * Chrome without symbol fonts). Also styles the Empfohlen-Badge as
 * prominent pill at top of the card. */

.mypage .price_single .molecule.pricing-card .pricing-features li::before {
 content: "";
 display: inline-block;
 width: 1.05em;
 height: 1.05em;
 background-color: var(--success-base, #10b981);
 vertical-align: -0.18em;
 margin-right: 0.35em;
 -webkit-mask-image: url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24'><path fill='black' d='M9 16.17 4.83 12l-1.42 1.41L9 19 21 7l-1.41-1.41z'/></svg>");
 mask-image: url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24'><path fill='black' d='M9 16.17 4.83 12l-1.42 1.41L9 19 21 7l-1.41-1.41z'/></svg>");
 -webkit-mask-position: center;
 mask-position: center;
 -webkit-mask-repeat: no-repeat;
 mask-repeat: no-repeat;
 -webkit-mask-size: contain;
 mask-size: contain;
}

/* Empfohlen-Badge als prominente Pill ÜBER dem Card-Header. */
.mypage .price_single .molecule.pricing-card .pricing-badge {
 text-align: center;
 margin-bottom: 1rem;
}

/* ── proc_3icons ──────────────────────────────────────────── */
/* proc_3icons — 3-phase process row, mid-step gets sc-acc-l accent. */
.mypage .proc_3icons.sc-dark,
.mypage .proc_3icons.sc-pri,
.mypage .proc_3icons.sc-sec,
.mypage .proc_3icons.sc-acc {
  color: var(--sc-light, #f5f5f0);
}
.mypage .proc_3icons.sc-light,
.mypage .proc_3icons.sc-pri-l,
.mypage .proc_3icons.sc-sec-l,
.mypage .proc_3icons.sc-acc-l {
  color: var(--sc-dark, #1a1a1a);
}
/* Überschrift + Beschreibung leben jetzt in EINEM RTE (.step-content: h3 + p);
 * vormals getrennte Slots step-headline/step-desc (Projekt B 2026-07-24).
 * Default h3-Margin zuruecksetzen damit Card-Layout beim Edit stabil bleibt
 * (der p-Teil verlaesst sich jetzt auf den :last-child-Reset der Basis,
 * s. Kommentar unten). */
/* h3 ist NICHT :last-child (p folgt) — Basis-Default (margin-bottom 0.5em)
 * wuerde sonst Card-Layout im Edit-Modus verschieben (s. Kommentar oben:
 * "Default h3-Margin zuruecksetzen damit Card-Layout beim Edit stabil
 * bleibt"). Der p-Teil der alten Regel war redundant mit dem :last-child-
 * Reset aus der Basis (Spec D2) und entfaellt. */
.mypage .proc_3icons .step-content h3 {
  margin: 0;
}

/* ── proc_4horizontal ──────────────────────────────────────────── */
/* proc_4horizontal — 4-step process row (with connector molecule). */
.mypage .proc_4horizontal.sc-dark,
.mypage .proc_4horizontal.sc-pri,
.mypage .proc_4horizontal.sc-sec,
.mypage .proc_4horizontal.sc-acc {
  color: var(--sc-light, #f5f5f0);
}
.mypage .proc_4horizontal.sc-light,
.mypage .proc_4horizontal.sc-pri-l,
.mypage .proc_4horizontal.sc-sec-l,
.mypage .proc_4horizontal.sc-acc-l {
  color: var(--sc-dark, #1a1a1a);
}

/* Step-Bubble-Centering jetzt am Molecule (data/global/molecules/step-card/molecule.css). */

/* Schritt-Überschrift + Beschreibung in EINEM RTE (.step-content: h4 + p);
 * vormals getrennte Slots step-headline/step-desc (Projekt B 2026-07-24). */
.mypage .proc_4horizontal .step-content h4 {
  /* Stufen-Abbildung statt Wert-Kopie: in dieser Karte rendert ein h4 auf der
   * h6-Stufe. Der Wert kommt aus der Basis (`--h6-font-size`), es ist also
   * keine Kopie — und die Groesse bleibt an die Modulskala gekoppelt.
   *
   * Warum NICHT `class="h6"` am Element (wie D3 vorschlaegt): das h4 steht hier
   * nicht im Template, sondern in den `meta.json`-Samples bzw. im
   * RTE-Inhalt — es ist AUTORENTEXT. Eine Klasse dort wird von TipTap beim
   * Reinklicken gestrippt (Projekt-Konvention), und die All-Pattern-Seite wird
   * aus Template + Samples gebaut, wo die Klasse gar nicht ankam: gemessen am
   * 2026-07-30 sprang die Ueberschrift dadurch von 16px auf den H4-Default
   * 23.04px. Ein Tag-Wechsel auf `<h6>` waere die Alternative, verbiegt aber
   * die Dokument-Gliederung. font-weight/line-height entfallen weiter
   * ersatzlos (D3) — die Basis traegt sie. */
  font-size: var(--h6-font-size);
}
.mypage .proc_4horizontal .step-content p {
  /* margin: 0 war redundant mit dem :last-child-Reset der Basis (p ist
     letztes Kind von .step-content, Spec D2) — entfernt.
     font-size/line-height bleiben: Card-Dichte (0.9rem/1.45 statt
     16px/1.65 Basisprosa), keine Basis-Klasse deckt diese Bandbreite ab
     (Spec D3 „Gemischt", hier als Card-/Spalten-Dichte entschieden). */
  font-size: 0.9rem;
  opacity: 0.85;
  line-height: 1.45;
}

/* ── proc_arrows ──────────────────────────────────────────── */
/* proc_arrows — 4 horizontale Steps mit Pfeil-Connectors.
 * Step-Card reused (molecule step-card, Backport 2026-07-28): Wrapper trägt
 * jetzt zusätzlich class="molecule step-card" (siehe pattern.template.json),
 * damit globale step-card-Fixes (Bubble-Zentrierung des Nummer-Slots via
 * molecules.css) automatisch mitkommen. Die kompakte 2.5rem-Bubble ist ein
 * bewusster pattern-scoped Size-Override (kleiner als der 3.5rem-Default am
 * Molecule) und bleibt hier bestehen — kein Duplikat, sondern eine Variante,
 * die per Kaskade (pattern.css lädt nach molecules.css) gewinnt. */
.mypage .proc_arrows .arrow-step {
 position: relative;
}
.mypage .proc_arrows .step-card-h {
 text-align: center;
 padding: 1rem 0.5rem;
 border-radius: 8px;
 min-height: 6rem;
}
.mypage .proc_arrows .step-card-h .step-bubble {
 display: flex;
 align-items: center;
 justify-content: center;
 width: 2.5rem;
 height: 2.5rem;
 border-radius: 999px;
 background: var(--primary-base);
 color: var(--text-light);
 /* Zaehler-Kreis, keine Prosa (D3 Kategorie E/F) — die Basis-Typografie ist
  * dafuer nicht zustaendig, font-weight/font-size bleiben Pattern-Deklaration. */
 font-weight: 700;
 font-size: 1.05rem;
 margin: 0 auto 0.85rem;
 flex-shrink: 0;
}
.mypage .proc_arrows .step-card-h .step-num {
 /* Zaehler-Ziffer, keine Prosa (D3) — line-height bleibt. */
 margin: 0;
 padding: 0;
 line-height: 1;
}
.mypage .proc_arrows .step-card-h .step-content h4 {
  /* Stufen-Abbildung statt Wert-Kopie: in dieser Karte rendert ein h4 auf der
   * h6-Stufe. Der Wert kommt aus der Basis (`--h6-font-size`), es ist also
   * keine Kopie — und die Groesse bleibt an die Modulskala gekoppelt.
   *
   * Warum NICHT `class="h6"` am Element (wie D3 vorschlaegt): das h4 steht hier
   * nicht im Template, sondern in den `meta.json`-Samples bzw. im
   * RTE-Inhalt — es ist AUTORENTEXT. Eine Klasse dort wird von TipTap beim
   * Reinklicken gestrippt (Projekt-Konvention), und die All-Pattern-Seite wird
   * aus Template + Samples gebaut, wo die Klasse gar nicht ankam: gemessen am
   * 2026-07-30 sprang die Ueberschrift dadurch von 16px auf den H4-Default
   * 23.04px. Ein Tag-Wechsel auf `<h6>` waere die Alternative, verbiegt aber
   * die Dokument-Gliederung. font-weight/line-height entfallen weiter
   * ersatzlos (D3) — die Basis traegt sie. */
  font-size: var(--h6-font-size);
}
.mypage .proc_arrows .step-card-h .step-content p {
 /* margin: 0 war redundant mit dem :last-child-Reset der Basis (p ist
  * letztes Kind von .step-content, Spec D2) — entfernt. font-size/
  * line-height bleiben: Card-Dichte (0.9rem/1.45), keine Basis-Klasse
  * deckt diese Bandbreite ab (Spec D3 „Gemischt"). */
 font-size: 0.9rem;
 opacity: 0.85;
 line-height: 1.45;
}

/* Verbindungs-Pfeil zwischen Schritten: scharfes Primary-Dreieck zentriert
 * im Gap. Vorher war es ein 20px Chevron mit 10%-Opazität — kaum sichtbar.
 * Jetzt sharp CSS-Border-Triangle in --primary-base. Nur auf ≥1024px
 * (mobile = vertikaler Stack, dort keine Pfeile dazwischen). */
@media (min-width: 1024px) {
 .mypage .proc_arrows .arrow-step:not(:last-child)::after {
  content: "";
  position: absolute;
  top: 50%;
  /* Dreieck zentriert auf der Spaltengrenze. Vorher right:-1.25rem
   * verschob es ~13px nach rechts in den Nachbar-Step rein. */
  right: 0;
  transform: translate(50%, -50%);
  width: 0;
  height: 0;
  border-style: solid;
  border-width: 0.55rem 0 0.55rem 0.85rem;
  border-color: transparent transparent transparent var(--primary-base);
  z-index: 2;
  pointer-events: none;
 }
}

/* ── proc_arrows_vertical ──────────────────────────────────────────── */
/* proc_arrows_vertical — N vertikal gestapelte Steps mit Pfeil-Connectors
 * nach unten. Visueller Spiegel von proc_arrows (horizontal) — gleicher
 * Card-Look (step-card-v statt -h), aber Layout in Spalte + Pfeil-Down.
 *
 * Container .pav-list nutzt flex-column statt grid-row damit die Steps
 * untereinander stehen (Override der em-components.col-N-Grid-Regel).
 *
 * Step-Card reused (molecule step-card, Backport 2026-07-28): Wrapper trägt
 * jetzt zusätzlich class="molecule step-card" (siehe pattern.template.json),
 * damit globale step-card-Fixes (Bubble-Zentrierung des Nummer-Slots via
 * molecules.css) automatisch mitkommen. Die kompakte 2.5rem-Bubble bleibt
 * ein bewusster pattern-scoped Size-Override (kleiner als der 3.5rem-Default
 * am Molecule) — kein Duplikat, gewinnt per Kaskade (pattern.css lädt nach
 * molecules.css).
 */
.mypage .proc_arrows_vertical .pav-list {
  display: flex !important;
  flex-direction: column;
  align-items: center;
  gap: 2rem;
}
.mypage .proc_arrows_vertical .pav-step {
  position: relative;
  /* Keine col-N-Klasse auf pav-step → em-components Grid-Regeln greifen
   * nicht. Der Stack ist flex-column (s. .pav-list), Karten zentrieren
   * sich ueber align-items:center der pav-list. Width-Cap via max-width
   * statt !important-Kette. */
  width: 100%;
  max-width: 32rem;
  padding-top: 1rem;
}
.mypage .proc_arrows_vertical .step-card-v {
  text-align: center;
  padding: 1.25rem 1rem;
  border-radius: 8px;
  min-height: 6rem;
}
.mypage .proc_arrows_vertical .step-card-v .step-bubble {
  display: flex;
  align-items: center;
  justify-content: center;
  width: 2.5rem;
  height: 2.5rem;
  border-radius: 999px;
  background: var(--primary-base);
  color: var(--text-light);
  /* Zaehler-Kreis, keine Prosa (D3 Kategorie E/F) — die Basis-Typografie ist
   * dafuer nicht zustaendig, font-weight/font-size bleiben Pattern-Deklaration. */
  font-weight: 700;
  font-size: 1.05rem;
  margin: 0 auto 0.85rem;
  flex-shrink: 0;
}
.mypage .proc_arrows_vertical .step-card-v .step-num {
  /* Zaehler-Ziffer, keine Prosa (D3) — line-height bleibt. */
  margin: 0;
  padding: 0;
  line-height: 1;
}
.mypage .proc_arrows_vertical .step-card-v .step-content h4 {
  /* Stufen-Abbildung statt Wert-Kopie: in dieser Karte rendert ein h4 auf der
   * h6-Stufe. Der Wert kommt aus der Basis (`--h6-font-size`), es ist also
   * keine Kopie — und die Groesse bleibt an die Modulskala gekoppelt.
   *
   * Anders als bei proc_4horizontal/proc_arrows (dort war der Hartwert exakt
   * 1rem = --h6-font-size, keine sichtbare Aenderung durch die Abbildung):
   * hier war der Hartwert 1.05rem (16.8px), naechstliegende Stufe zu
   * --h6-font-size (1rem/16px) mit Δ 0.05rem. Die Stufen-Abbildung rundet
   * also minimal ab (16.8px → 16px) — bewusst in Kauf genommen, weil es
   * keine Zwischenstufe zwischen h6 und h5 gibt (Nicht-Ziel: keine neue
   * Skala) und die Differenz optisch nicht auffaellt.
   *
   * Warum NICHT `class="h6"` am Element (wie D3 vorschlaegt): das h4 steht hier
   * nicht im Template, sondern in den `meta.json`-Samples bzw. im
   * RTE-Inhalt — es ist AUTORENTEXT. Eine Klasse dort wird von TipTap beim
   * Reinklicken gestrippt (Projekt-Konvention), und die All-Pattern-Seite wird
   * aus Template + Samples gebaut, wo die Klasse gar nicht ankam: gemessen am
   * 2026-07-30 sprang die Ueberschrift dadurch auf den H4-Default 23.04px.
   * Ein Tag-Wechsel auf `<h6>` waere die Alternative, verbiegt aber
   * die Dokument-Gliederung. font-weight/line-height entfallen weiter
   * ersatzlos (D3) — die Basis traegt sie. */
  font-size: var(--h6-font-size);
}
.mypage .proc_arrows_vertical .step-card-v .step-content p {
  /* margin: 0 war redundant mit dem :last-child-Reset der Basis (p ist
   * letztes Kind von .step-content, Spec D2) — entfernt. font-size/
   * line-height bleiben: Card-Dichte (0.95rem/1.5), keine Basis-Klasse
   * deckt diese Bandbreite ab (Spec D3 „Gemischt"). */
  font-size: 0.95rem;
  opacity: 0.85;
  line-height: 1.5;
}

/* Pfeil-Down zwischen Steps: scharfes Primary-Dreieck zwischen je zwei
 * Karten. Im Gegensatz zu proc_arrows (horizontal) IMMER sichtbar —
 * vertikaler Flow funktioniert auf jeder Viewport-Breite. */
.mypage .proc_arrows_vertical .pav-step:not(:last-child)::after {
  content: "";
  position: absolute;
  left: 50%;
  bottom: -1.4rem;
  transform: translateX(-50%);
  width: 0;
  height: 0;
  border-style: solid;
  border-width: 0.85rem 0.55rem 0 0.55rem;
  border-color: var(--primary-base) transparent transparent transparent;
  z-index: 2;
  pointer-events: none;
}

/* ── proc_chevron_horizontal ──────────────────────────────────────────── */
/* proc_chevron_horizontal — 3 Chevron-Karten zentriert, kompakt.
 * Arrow-Shape Padding via --arrow-pad: left/right kleiner damit der
 * Text-Block die volle Card-Breite nutzt (vorher schob das Default-
 * arrow-pad den Content auf ~50% Spaltenbreite).
 *
 * Step-Bubble + Step-Num: separate Elemente analog proc_4horizontal,
 * sodass die Nummer als Kreis ueber dem Headline-Text steht (statt
 * inline in einem Mustache-Render).
 */
.mypage .proc_chevron_horizontal .pch-chain {
  display: flex;  /* 4f: entflaggt, am DOM gemessen — kein Gegenspieler */
  flex-direction: row;
  flex-wrap: nowrap !important;
  align-items: stretch;
  justify-content: center;
  /* gap lebt jetzt als `gap-0` an der Reihe im Template (20er-Migration,
   * 2026-08-10) — eine Quelle, und die Reihe faellt damit aus der
   * Gutter-Regel von Modell A heraus. Das ist die Voraussetzung dafuer, dass
   * die zwei !important am Step-Padding unten wegfallen konnten. */
  overflow: hidden;
  width: 100%;
  max-width: 48rem;
  margin-left: auto;
  margin-right: auto;
}
/* overflow:hidden clipped TipTap-Toolbars beim Inline-Edit weg. Wenn ein
 * Step im Edit-Modus ist, Chain temporaer overflow:visible. */
.mypage .proc_chevron_horizontal .pch-chain:has(.tiptap-overlay),
.mypage .proc_chevron_horizontal .pch-chain:has([data-tiptap-loading]) {
  overflow: visible;
}
.mypage .proc_chevron_horizontal .pch-step {
  --arrow-tip-depth: 10%;
  --arrow-tip-inset: 0%;
  /* Padding: tip-area minimal, sonst extra horizontal Atemraum fuer Text. */
  --arrow-pad: 0.8rem 0.5rem;
  flex: 1 1 0;
  min-width: 0;
  /* Farbe/Kontrast kommt jetzt aus dem Modell (sc-pri-l am Step im Template)
   * → das „Hintergrund"-Control zeigt die Farbe, Textfarbe kontrastiert
   * automatisch (text-dark auf hellem Primary-Tint). Vorher hardcoded
   * color-mix + text-dark → nicht im Modell + Kontrast-Bruch bei dunklem
   * Tenant-Primary. */
  text-align: center;
  /* Horizontales Padding MUSS tiefer sein als die Kerbe, sonst schneidet das
   * clip-path die ersten Zeichen weg (gemessen 2026-07-30 auf test: Text
   * begann bei 16px, Kerbe reicht 25px tief → „Analyse" wurde zu „nalyse").
   *
   * Warum nicht mehr `calc(var(--arrow-tip-depth) + …)`: das Prozent löst in
   * einer PADDING-Berechnung hier zu 0 auf (Flex-Item ohne definite Inline-Size
   * des Containing Blocks), im clip-path dagegen normal gegen die eigene Box —
   * dieselbe Variable ergab also 0px Padding gegen 25px Kerbe. Gemessen an
   * beiden Chevron-Patterns: identische 16px trotz unterschiedlicher
   * Chain-Breite, was das Prozent-Kollabieren belegt.
   *
   * Deshalb feste rem-Werte, bemessen am Maximum der Kerbe: Chain ist auf
   * 48rem begrenzt, /3 Steps = 16rem, davon 10% = 1.6rem Kerbe → 2.25rem gibt
   * Deckung plus Atemraum. */
  /* Flag ENTFERNT (20er-Migration, 2026-08-10) — und zwar ersatzlos, ohne dass
   * der Gleichstand-Trick von unten noetig war.
   *
   * Die Vorgeschichte, damit niemand das Flag zurueckbaut: der Gegenspieler war
   * nie `.mypage .arrow-shape.arrow-shape--chevron` (gleichrangig, verliert
   * ueber die Quellreihenfolge), sondern die GUTTER-Regel der Grid-Engine in
   * em-components.css. Die trug (0,4,1) gegen die (0,3,0) hier und hat das
   * Padding auf 16px zurueckgezogen — die Kerbe reicht 25px (bzw. 33px) tief,
   * der Text stand also IN der Kerbe („Analyse" wurde zu „nalyse").
   *
   * Diese Gutter-Regel greift jetzt nur noch in Reihen OHNE gap-Klasse:
   *   `.mypage .max-w:not([class*='gap-']) > … [class*='col-']`
   * Und die Kette traegt seit der Migration `gap-0` im Template. Damit hat die
   * Regel hier keinen Treffer mehr — es gibt keinen Gegenspieler, gegen den
   * ein Flag helfen muesste. Eine Regel, die nicht zutrifft, braucht keine
   * Prioritaet.
   *
   * Setzt jemand die gap-Klasse an der Kette zurueck, kommt die Gutter-Regel
   * zurueck und mit ihr der Fehler. Die Klasse ist also tragend, nicht Kosmetik. */
  padding-left: 2.25rem;
  padding-right: 2.25rem;
}

/* Step-Bubble: Kreis mit Nummer, zentriert oben. Zaehler, keine Prosa (D3
 * Kategorie E/F) — die Basis-Typografie ist dafuer nicht zustaendig,
 * font-weight/font-size/line-height bleiben Pattern-Deklaration. */
.mypage .proc_chevron_horizontal .pch-step .step-bubble {
  display: flex;
  align-items: center;
  justify-content: center;
  width: 1.75rem;
  height: 1.75rem;
  border-radius: 50%;
  background: var(--primary-base);
  color: var(--text-light);
  font-weight: 700;
  font-size: 0.85rem;
  line-height: 1;
  margin: 0 auto 0.45rem;
  flex-shrink: 0;
}
.mypage .proc_chevron_horizontal .pch-step .step-num {
  /* Zaehler-Ziffer, keine Prosa (D3) — margin/line-height bleiben. */
  margin: 0;
  padding: 0;
  line-height: 1;
}
.mypage .proc_chevron_horizontal .pch-step .step-num p {
  /* p im Zaehler-Container, keine Prosa (D3) — margin/line-height bleiben. */
  margin: 0;
  line-height: 1;
}

.mypage .proc_chevron_horizontal .pch-step .step-content h4 {
  /* Sub-h6-Kartendichte (Spec D3, Befund dieses Plans): die Chevron-Karte
   * ist zu schmal fuer die kleinste Basis-Stufe (--h6-font-size = 1rem).
   * Es gibt keine Stufe darunter (Nicht-Ziel: keine neue Skala) — bleibt
   * als Pattern-Deklaration, analog zur Hero-Display-Ausnahme aus D3.
   * font-weight/line-height sind trotzdem entfallen (D3, ausnahmslos). */
  font-size: 0.9rem;
}
.mypage .proc_chevron_horizontal .pch-step .step-content p {
  /* margin: 0 war redundant mit dem :last-child-Reset der Basis (p ist
   * letztes Kind von .step-content, Spec D2) — entfernt. font-size/
   * line-height bleiben: Card-Dichte (0.72rem/1.35). */
  font-size: 0.72rem;
  opacity: 0.85;
  line-height: 1.35;
}

@media (max-width: 640px) {
  /* flex-wrap bleibt geflaggt (Stufe 4c, Rest, 2026-07-30, geprueft): die
   * Basis-Deklaration `.pch-chain { flex-wrap: nowrap !important }` (oben,
   * Zeile ~13, art LAYOUT — anderer Batch) traegt SELBST ein Flag bei
   * identischer Selektor-Spezifitaet (0,3,0 = 0,3,0). Ein !important-Wert
   * schlaegt IMMER einen nicht-!important-Wert, unabhaengig von Spezifitaet
   * oder Ladereihenfolge — wuerde ich hier das Flag entfernen, faellt die
   * Chain auf Mobile nie in den Wrap-Modus, weil die Basis-Regel gewinnt.
   * Muss bleiben, solange die Basis ihr eigenes Flag traegt (LAYOUT-Batch). */
  .mypage .proc_chevron_horizontal .pch-chain {
    flex-wrap: wrap !important;
    max-width: 22rem;
  }
  .mypage .proc_chevron_horizontal .pch-step {
    flex: 0 0 100%;
  }
}

/* ── proc_chevron_horizontal_big ──────────────────────────────────────────── */
/* proc_chevron_horizontal — 3 Chevron-Karten zentriert, kompakt.
 * Arrow-Shape Padding via --arrow-pad: left/right kleiner damit der
 * Text-Block die volle Card-Breite nutzt (vorher schob das Default-
 * arrow-pad den Content auf ~50% Spaltenbreite).
 *
 * Step-Bubble + Step-Num: separate Elemente analog proc_4horizontal,
 * sodass die Nummer als Kreis ueber dem Headline-Text steht (statt
 * inline in einem Mustache-Render).
 */
.mypage .proc_chevron_horizontal_big .pch-chain {
  display: flex;  /* 4f: entflaggt, am DOM gemessen — kein Gegenspieler */
  flex-direction: row;
  flex-wrap: nowrap !important;
  align-items: stretch;
  justify-content: center;
  /* gap lebt jetzt als `gap-0` an der Reihe im Template (20er-Migration,
   * 2026-08-10) — eine Quelle, und die Reihe faellt damit aus der
   * Gutter-Regel von Modell A heraus. Das ist die Voraussetzung dafuer, dass
   * die zwei !important am Step-Padding unten wegfallen konnten. */
  overflow: hidden;
  width: 100%;
  max-width: 64rem;
  margin-left: auto;
  margin-right: auto;
}
/* overflow:hidden clipped TipTap-Toolbars beim Inline-Edit weg. Wenn ein
 * Step im Edit-Modus ist, Chain temporaer overflow:visible. */
.mypage .proc_chevron_horizontal_big .pch-chain:has(.tiptap-overlay),
.mypage .proc_chevron_horizontal_big .pch-chain:has([data-tiptap-loading]) {
  overflow: visible;
}
.mypage .proc_chevron_horizontal_big .pch-step {
  --arrow-tip-depth: 10%;
  --arrow-tip-inset: 0%;
  /* Padding: tip-area minimal, sonst extra horizontal Atemraum fuer Text. */
  --arrow-pad: 0.8rem 0.5rem;
  flex: 1 1 0;
  min-width: 0;
  /* Farbe/Kontrast kommt jetzt aus dem Modell (sc-pri-l am Step im Template)
   * → das „Hintergrund"-Control zeigt die Farbe, Textfarbe kontrastiert
   * automatisch (text-dark auf hellem Primary-Tint). Vorher hardcoded
   * color-mix + text-dark → nicht im Modell + Kontrast-Bruch bei dunklem
   * Tenant-Primary. */
  text-align: center;
  /* Wie proc_chevron_horizontal, nur groesser bemessen: Chain ist auf 64rem
   * begrenzt, /3 Steps = 21.3rem, davon 10% = 2.13rem Kerbe → 3rem Padding.
   * Gemessen 2026-07-30: Text begann bei 16px, Kerbe 33px tief → die ersten
   * Zeichen wurden weggeschnitten. Begruendung fuer feste rem-Werte statt
   * `calc(var(--arrow-tip-depth) + …)` siehe proc_chevron_horizontal. */
  /* Flag ENTFERNT (20er-Migration, 2026-08-10) — und zwar ersatzlos, ohne dass
   * der Gleichstand-Trick von unten noetig war.
   *
   * Die Vorgeschichte, damit niemand das Flag zurueckbaut: der Gegenspieler war
   * nie `.mypage .arrow-shape.arrow-shape--chevron` (gleichrangig, verliert
   * ueber die Quellreihenfolge), sondern die GUTTER-Regel der Grid-Engine in
   * em-components.css. Die trug (0,4,1) gegen die (0,3,0) hier und hat das
   * Padding auf 16px zurueckgezogen — die Kerbe reicht 25px (bzw. 33px) tief,
   * der Text stand also IN der Kerbe („Analyse" wurde zu „nalyse").
   *
   * Diese Gutter-Regel greift jetzt nur noch in Reihen OHNE gap-Klasse:
   *   `.mypage .max-w:not([class*='gap-']) > … [class*='col-']`
   * Und die Kette traegt seit der Migration `gap-0` im Template. Damit hat die
   * Regel hier keinen Treffer mehr — es gibt keinen Gegenspieler, gegen den
   * ein Flag helfen muesste. Eine Regel, die nicht zutrifft, braucht keine
   * Prioritaet.
   *
   * Setzt jemand die gap-Klasse an der Kette zurueck, kommt die Gutter-Regel
   * zurueck und mit ihr der Fehler. Die Klasse ist also tragend, nicht Kosmetik. */
  padding-left: 3rem;
  padding-right: 3rem;
}

/* Step-Bubble: Kreis mit Nummer, zentriert oben. Zaehler, keine Prosa (D3
 * Kategorie E/F) — die Basis-Typografie ist dafuer nicht zustaendig,
 * font-weight/font-size/line-height bleiben Pattern-Deklaration. */
.mypage .proc_chevron_horizontal_big .pch-step .step-bubble {
  display: flex;
  align-items: center;
  justify-content: center;
  width: 1.75rem;
  height: 1.75rem;
  border-radius: 50%;
  background: var(--primary-base);
  color: var(--text-light);
  font-weight: 700;
  font-size: 1.1rem;
  line-height: 1;
  margin: 0 auto 0.45rem;
  flex-shrink: 0;
}
.mypage .proc_chevron_horizontal_big .pch-step .step-num {
  /* Zaehler-Ziffer, keine Prosa (D3) — margin/line-height bleiben. */
  margin: 0;
  padding: 0;
  line-height: 1;
}
.mypage .proc_chevron_horizontal_big .pch-step .step-num p {
  /* p im Zaehler-Container, keine Prosa (D3) — margin/line-height bleiben. */
  margin: 0;
  line-height: 1;
}

.mypage .proc_chevron_horizontal_big .pch-step .step-content h4 {
  /* 1.5rem ≈ H4-Default (1.44rem, Δ 4 %) — keine Klasse noetig, entfaellt
   * ersatzlos (Spec D3 Kategorie A). font-weight/line-height entfallen
   * ebenso ohne Ersatz (D3, ausnahmslos). margin entfaellt, :last-child ist
   * nicht einschlaegig (h4 ist nicht letztes Kind), aber der Basis-H4-
   * Default-Abstand (0.5em) passt hier — kein Ersatz noetig. */
}
.mypage .proc_chevron_horizontal_big .pch-step .step-content p {
  /* margin: 0 war redundant mit dem :last-child-Reset der Basis (p ist
   * letztes Kind von .step-content, Spec D2) — entfernt. font-size/
   * line-height bleiben: Card-Dichte (1.05rem/1.35). */
  font-size: 1.05rem;
  opacity: 0.85;
  line-height: 1.35;
}

@media (max-width: 640px) {
  /* flex-wrap bleibt geflaggt (Stufe 4c, Rest, 2026-07-30, geprueft): analog
   * proc_chevron_horizontal — die Basis-Deklaration `.pch-chain { flex-wrap:
   * nowrap !important }` (art LAYOUT, anderer Batch) traegt selbst ein Flag
   * bei identischer Spezifitaet (0,3,0). !important schlaegt immer
   * nicht-!important, egal wie spezifisch. Muss bleiben, solange die Basis
   * ihr eigenes Flag traegt. */
  .mypage .proc_chevron_horizontal_big .pch-chain {
    flex-wrap: wrap !important;
    max-width: 22rem;
  }
  .mypage .proc_chevron_horizontal_big .pch-step {
    flex: 0 0 100%;
  }
}

/* ── proc_chevron_vertical ──────────────────────────────────────────── */
/* proc_chevron_vertical — 3 Pfeil-Down-Karten zentriert.
 * Text-Block in BEIDEN Achsen mittig in der Karte: flex-column + center.
 * Karte ist kompakt (max-width 18rem), kein Auffaecher.
 */
.mypage .proc_chevron_vertical .pcv-chain {
  display: flex;  /* 4f: entflaggt, am DOM gemessen — kein Gegenspieler */
  flex-direction: column;
  align-items: center;
  justify-content: center;
  gap: 0.4rem;
}
.mypage .proc_chevron_vertical .pcv-step {
  --arrow-tip-depth: 12%;
  --arrow-tip-inset: 0%;
  --arrow-pad: 0.85rem 0.8rem;
  /* Farbe/Kontrast kommt jetzt aus dem Modell (sc-pri-l am Step im Template)
   * → das „Hintergrund"-Control zeigt die Farbe, Textfarbe kontrastiert
   * automatisch (text-dark auf hellem Primary-Tint). Vorher hardcoded
   * color-mix + text-dark → nicht im Modell + Kontrast-Bruch bei dunklem
   * Tenant-Primary. */
  text-align: center;
  width: 100%;  /* 4f: entflaggt, am DOM gemessen — kein Gegenspieler */
  max-width: 18rem;  /* 4f: entflaggt, am DOM gemessen — kein Gegenspieler */
  margin-left: auto;
  margin-right: auto;
  /* Text-Block zentriert in beiden Achsen: flex-column-center.
   * Padding-bottom hebt den Content über die Pfeil-Tip-Spitze (unteres ~12%
   * der Höhe, arrow-shape--down). Der frühere calc(… var(--arrow-tip-depth)
   * * 0.75rem) war ungültig (% × length) → wurde von der Engine verworfen →
   * padding-bottom 0 → Text stieß an die Spitze. Fester Wert (2026-07-24). */
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  padding-bottom: 1.4rem;
}

/* Step-Bubble: Kreis mit Nummer, kompakt zentriert. Zaehler, keine Prosa (D3
 * Kategorie E/F) — die Basis-Typografie ist dafuer nicht zustaendig,
 * font-weight/font-size/line-height bleiben Pattern-Deklaration. */
.mypage .proc_chevron_vertical .pcv-step .step-bubble {
  display: flex;
  align-items: center;
  justify-content: center;
  width: 1.6rem;
  height: 1.6rem;
  border-radius: 50%;
  background: var(--primary-base);
  color: var(--text-light);
  font-weight: 700;
  font-size: 0.78rem;
  line-height: 1;
  margin: 0 auto 0.3rem;
  flex-shrink: 0;
}
.mypage .proc_chevron_vertical .pcv-step .step-num {
  /* Zaehler-Ziffer, keine Prosa (D3) — margin/line-height bleiben. */
  margin: 0;
  padding: 0;
  line-height: 1;
}
.mypage .proc_chevron_vertical .pcv-step .step-num p {
  /* p im Zaehler-Container, keine Prosa (D3) — margin/line-height bleiben. */
  margin: 0;
  line-height: 1;
}

.mypage .proc_chevron_vertical .pcv-step .step-content h4 {
  /* Sub-h6-Kartendichte (Spec D3, Befund dieses Plans): die Chevron-Karte
   * ist zu schmal fuer die kleinste Basis-Stufe (--h6-font-size = 1rem).
   * Es gibt keine Stufe darunter (Nicht-Ziel: keine neue Skala) — bleibt
   * als Pattern-Deklaration, analog zur Hero-Display-Ausnahme aus D3.
   * font-weight/line-height sind trotzdem entfallen (D3, ausnahmslos). */
  font-size: 0.95rem;
}
.mypage .proc_chevron_vertical .pcv-step .step-content p {
  /* margin: 0 war redundant mit dem :last-child-Reset der Basis (p ist
   * letztes Kind von .step-content, Spec D2) — entfernt. font-size/
   * line-height bleiben: Card-Dichte (0.78rem/1.35). */
  font-size: 0.78rem;
  opacity: 0.85;
  line-height: 1.35;
}

/* ── proc_chevron_vertical_big ──────────────────────────────────────────── */
/* proc_chevron_vertical — 3 Pfeil-Down-Karten zentriert.
 * Text-Block in BEIDEN Achsen mittig in der Karte: flex-column + center.
 * Karte ist kompakt (max-width 18rem), kein Auffaecher.
 */
.mypage .proc_chevron_vertical_big .pcv-chain {
  display: flex;  /* 4f: entflaggt, am DOM gemessen — kein Gegenspieler */
  flex-direction: column;
  align-items: center;
  justify-content: center;
  gap: 0.4rem;
}
.mypage .proc_chevron_vertical_big .pcv-step {
  --arrow-tip-depth: 12%;
  --arrow-tip-inset: 0%;
  --arrow-pad: 0.85rem 0.8rem;
  /* Farbe/Kontrast kommt jetzt aus dem Modell (sc-pri-l am Step im Template)
   * → das „Hintergrund"-Control zeigt die Farbe, Textfarbe kontrastiert
   * automatisch (text-dark auf hellem Primary-Tint). Vorher hardcoded
   * color-mix + text-dark → nicht im Modell + Kontrast-Bruch bei dunklem
   * Tenant-Primary. */
  text-align: center;
  width: 100%;  /* 4f: entflaggt, am DOM gemessen — kein Gegenspieler */
  max-width: 18rem;  /* 4f: entflaggt, am DOM gemessen — kein Gegenspieler */
  margin-left: auto;
  margin-right: auto;
  /* Text-Block zentriert in beiden Achsen: flex-column-center.
   * Padding-bottom hebt den Content über die Pfeil-Tip-Spitze (unteres ~12%
   * der Höhe, arrow-shape--down). Der frühere calc(… var(--arrow-tip-depth)
   * * 0.75rem) war ungültig (% × length) → wurde von der Engine verworfen →
   * padding-bottom 0 → Text stieß an die Spitze. Größer als bei der Basis-
   * Variante, da hier größere Schrift/höhere Karten (2026-07-24). */
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  padding-bottom: 2rem;
}

/* Step-Bubble: Kreis mit Nummer, kompakt zentriert. Zaehler, keine Prosa (D3
 * Kategorie E/F) — die Basis-Typografie ist dafuer nicht zustaendig,
 * font-weight/font-size/line-height bleiben Pattern-Deklaration. */
.mypage .proc_chevron_vertical_big .pcv-step .step-bubble {
  display: flex;
  align-items: center;
  justify-content: center;
  width: 1.6rem;
  height: 1.6rem;
  border-radius: 50%;
  background: var(--primary-base);
  color: var(--text-light);
  font-weight: 700;
  font-size: 0.78rem;
  line-height: 1;
  margin: 0 auto 0.3rem;
  flex-shrink: 0;
}
.mypage .proc_chevron_vertical_big .pcv-step .step-num {
  /* Zaehler-Ziffer, keine Prosa (D3) — margin/line-height bleiben. */
  margin: 0;
  padding: 0;
  line-height: 1;
}
.mypage .proc_chevron_vertical_big .pcv-step .step-num p {
  /* p im Zaehler-Container, keine Prosa (D3) — margin/line-height bleiben. */
  margin: 0;
  line-height: 1;
}

.mypage .proc_chevron_vertical_big .pcv-step .step-content h4 {
  /* 1.5rem ≈ H4-Default (1.44rem, Δ 4 %) — keine Klasse noetig, entfaellt
   * ersatzlos (Spec D3 Kategorie A). font-weight/line-height entfallen
   * ebenso ohne Ersatz (D3, ausnahmslos). margin entfaellt, :last-child ist
   * nicht einschlaegig (h4 ist nicht letztes Kind), aber der Basis-H4-
   * Default-Abstand (0.5em) passt hier — kein Ersatz noetig. */
}
.mypage .proc_chevron_vertical_big .pcv-step .step-content p {
  /* margin: 0 war redundant mit dem :last-child-Reset der Basis (p ist
   * letztes Kind von .step-content, Spec D2) — entfernt. font-size/
   * line-height bleiben: Card-Dichte (1.05rem/1.35). */
  font-size: 1.05rem;
  opacity: 0.85;
  line-height: 1.35;
}

/* ── proc_timeline ──────────────────────────────────────────── */
/* proc_timeline — Vertikale Timeline mit Date-Pill + Content
 *
 * Struktur (items[]-Pattern, kein rich-html-Blob mehr):
 *   .timeline (layer, col-8)
 *     .tl-item (layer, _repeat=items)
 *       .tl-icon (icontext-span) — Date-Pill links
 *       .tl-content (layer)
 *         html (RTE) — <h4> Station-Titel + <p> 1-2 Saetze in EINEM Feld
 *
 * Connector-Linie wird per Item-::before gezeichnet (Linie ZWISCHEN
 * Items, nicht durchgehend). Vorteil: last-child kriegt automatisch
 * keine Linie unter sich. */

.mypage .proc_timeline .timeline {
 position: relative;
 padding: 0;
 text-align: left;
}
.mypage .proc_timeline .tl-item {
 position: relative;
 display: flex;  /* 4f: entflaggt, am DOM gemessen — kein Gegenspieler */
 gap: 1.25rem;
 padding: 0.5rem 0 1.5rem 0;
 align-items: flex-start;
}
/* Connector-Linie: pro Item ein Stueck NACH UNTEN, vom Bubble-Center
 * bis zum unteren Item-Rand. Letztes Item bekommt keinen Connector. */
.mypage .proc_timeline .tl-item:not(:last-child)::before {
 content: "";
 position: absolute;
 left: 2.5rem;
 top: calc(0.5rem + 2.6rem);
 bottom: 0;
 width: 2px;
 background: color-mix(in srgb, var(--text-dark) 10%, transparent);
}
/* Date-Pill — icontext-Span direkt als Pill gestylt. flex: 0 0 5rem
 * fixiert die Breite, Hoehe per height:2.6rem. inline-flex + center
 * fuer die Glyph-Position bekommt der icontext-Span ohnehin von der
 * em-components [type="icontext"]-Regel. */
.mypage .proc_timeline .tl-icon {
 flex: 0 0 5rem;
 width: 5rem;
 height: 2.6rem;
 border-radius: 999px;
 background: var(--cta-bg-safe, var(--primary-base));   /* WCAG-AA: weißer Text ≥4.5:1 (Task 7) */
 color: var(--text-light);
 /* Date-Pill-Label, keine Prosa (D3 Kategorie E/F) — die Basis-Typografie
  * ist dafuer nicht zustaendig, font-weight/font-size bleiben. */
 font-weight: 700;
 font-size: 0.95rem;
 z-index: 1;
}
.mypage .proc_timeline .tl-content {
 flex: 1;
 padding-top: 0.15rem;
 text-align: left;
}
/* Titel + Beschreibung leben jetzt in EINEM RTE (h4 + p) unter .tl-content;
 * die Marker-Klassen tl-headline/tl-desc sind entfallen (Projekt B,
 * 2026-07-24). Styling daher kontextuell auf das innere h4/p. */
.mypage .proc_timeline .tl-content h4 {
 /* font-weight/line-height entfallen ohne Ersatz (D3, ausnahmslos): h4
  * rendert jetzt im H4-Default-Gewicht (600 statt 700, Basis seit Commit
  * 7c7c4bd) mit dem H4-Default-line-height. margin entfaellt, :last-child
  * ist nicht einschlaegig (h4 ist nicht letztes Kind), aber der Basis-H4-
  * Default-Abstand (0.5em) passt hier — kein Ersatz noetig. */
}
.mypage .proc_timeline .tl-content p {
 /* margin: 0 war redundant mit dem :last-child-Reset der Basis (p ist
  * letztes Kind von .tl-content, Spec D2) — entfernt. line-height bleibt:
  * Card-Dichte (1.5). */
 text-align: left;
 line-height: 1.5;
 color: color-mix(in srgb, var(--text-dark) 80%, transparent);
}

/* ── proof_4dark ──────────────────────────────────────────── */
/* proof_4dark — 4 große Stat-Items auf sc-dark, jetzt als stat-item-Molecule
 * (Backport 2026-07-28, s. docs/superpowers/specs/2026-07-28-molecule-
 * backport-batch-design.md). Value-/Label-Basistypografie + Default-Farbe
 * kommen aus molecules.css (`.molecule.stat-item .stat-value/.stat-label`).
 *
 * MIGRATIONS-HINWEIS: vorher waren die 4 Zahlen-Farben per Marketer-RTE
 * (Inline `style="color: ...`) unabhängig editierbar — das ist mit dem
 * items[]-Slot-Modell (nur `value`/`label` als Text, kein per-Item-RTE)
 * nicht mehr möglich. Die 4 ursprünglichen Farben sind hier fix per
 * Position nachgebildet (nth-of-type auf .molecule.stat-item — der
 * Stats-Row-Container hat NUR stat-item-Kinder, daher zählt nth-of-type
 * korrekt 1..4 ohne Offset durch den Header). Ein Redesign auf mehr/weniger
 * als 4 Items behält nur für Position 1-4 eine Akzentfarbe; darüber hinaus
 * greift der molecule-Default (--primary-base). */
/* Zahlen-Highlight (div.stat-value, kein p — molecule stat-item), keine
 * Prosa (D3 Kategorie E/F) — font-weight/line-height bleiben Pattern-
 * Deklaration. margin ist Kategorie G (kein h/p-Selektor), unangetastet. */
.mypage .proof_4dark .stat-value {
  font-weight: 800;
  line-height: 1.05;
  margin: 0 0 0.35rem 0;
}

.mypage .proof_4dark .molecule.stat-item:nth-of-type(1) .stat-value {
  color: var(--primary-base);
}
.mypage .proof_4dark .molecule.stat-item:nth-of-type(2) .stat-value {
  color: var(--contrast-base);
}
.mypage .proof_4dark .molecule.stat-item:nth-of-type(3) .stat-value {
  color: var(--text-light);
}
.mypage .proof_4dark .molecule.stat-item:nth-of-type(4) .stat-value {
  color: var(--primary-light);
}

/* Schmale vertikale Divider zwischen den Stats (Desktop) */
@media (min-width: 1024px) {
  .mypage .proof_4dark .molecule.stat-item + .molecule.stat-item {
    position: relative;
  }
  .mypage .proof_4dark .molecule.stat-item + .molecule.stat-item::before {
    content: "";
    position: absolute;
    left: 0;
    top: 1.5rem;
    bottom: 1.5rem;
    width: 1px;
    background: color-mix(in srgb, var(--text-light) 12%, transparent);
  }
}

/* ── proof_strip_3labels ──────────────────────────────────────────── */
/* proof_strip_3labels — 3-stat strip with section header (default neutral bg). */
.mypage .proof_strip_3labels.sc-dark,
.mypage .proof_strip_3labels.sc-pri,
.mypage .proof_strip_3labels.sc-sec,
.mypage .proof_strip_3labels.sc-acc {
  color: var(--sc-light, #f5f5f0);
}
.mypage .proof_strip_3labels.sc-light,
.mypage .proof_strip_3labels.sc-pri-l,
.mypage .proof_strip_3labels.sc-sec-l,
.mypage .proof_strip_3labels.sc-acc-l {
  color: var(--sc-dark, #1a1a1a);
}

/* ── proof_strip_4 ──────────────────────────────────────────── */
/* proof_strip_4 — 4-stat strip (typically on a primary-color band).
 *
 * Self-consistent text color based on the chosen sc-* class.
 * em-base.css already sets color via .sc-XX on the root, but molecule.css
 * for .stat-item hardcodes `color: var(--primary-base)` on .stat-value
 * with .mypage.molecule.stat-item.stat-value = 4 specificity. We need to
 * beat that to make stat-value inherit from the section's bg-aware color.
 */
.mypage .proof_strip_4.sc-dark,
.mypage .proof_strip_4.sc-pri,
.mypage .proof_strip_4.sc-sec,
.mypage .proof_strip_4.sc-acc {
  color: var(--text-light);
}
.mypage .proof_strip_4.sc-light,
.mypage .proof_strip_4.sc-pri-l,
.mypage .proof_strip_4.sc-sec-l,
.mypage .proof_strip_4.sc-acc-l {
  color: var(--text-dark);
}

/* Force stat-value to inherit the section's base text color, and bind
 * stat-label + subline to the context-safe muted token so they contrast
 * with the chosen sc-* background. Beat molecule.css and em-components.css
 * specificity by chaining the pattern root.
 */
.mypage .proof_strip_4 .molecule.stat-item .stat-value {
  color: inherit;
}
.mypage .proof_strip_4 .molecule.stat-item .stat-label,
.mypage .proof_strip_4 .subline {
  color: var(--text-muted);
}

/* ── story_3cards ──────────────────────────────────────────── */
/* story_3cards — 3-Spalten Article-Cards.
 * Klassen an die tatsächliche Template-Struktur angeglichen (article-card-img /
 * article-card-body / article-text) — die vormaligen .art-*-Regeln waren tot
 * (Template nutzt article-*). */
.mypage .story_3cards .article-card {
 overflow: hidden;
 display: flex;
 flex-direction: column;
 height: 100%;
}
.mypage .story_3cards .article-card-img,
.mypage .story_3cards .article-card-img img,
.mypage .story_3cards .article-card-img picture {
 display: block;
 width: 100%;
 height: 200px;
 object-fit: cover;
}
.mypage .story_3cards .article-card-body {
 padding: 1.25rem 1.25rem 1.5rem;
 text-align: left;
}
/* Titel + Meta leben jetzt in EINEM RTE (.article-text: h3 + p.caption-sub);
 * die früheren Slot-Marker article-title/excerpt/meta/date → RTE-Absatzstile
 * (Projekt B 2026-07-24). */
.mypage .story_3cards .article-text h3 {
 margin: 0 0 0.5em 0;  /* Leiter: rem -> em, 8 -> 9.2px */
 font-size: 1.15rem;
 line-height: 1.3;
}
/* `:not(.caption-sub)` ist noetig, nicht kosmetisch (Befund Stufe 4a, am DOM
 * gemessen): `.mypage .story_3cards .article-text p` hat Spezifitaet (0,3,1) —
 * genau so viel wie `.mypage p.caption-sub:last-child` in der Basis, weil
 * `:last-child` als Klasse zaehlt. Bei Gleichstand entscheidet die Reihenfolge,
 * und patterns.css laedt nach em-base.css. Seit in Stufe 4a das !important der
 * Basis-Regel gefallen ist, gewann daher diese Pattern-Regel und gab der
 * Attributions-Zeile 12px Abstand nach unten, obwohl sie letztes Kind der Karte
 * ist. Mit dem :not() trifft die Regel nur noch die Prosa-Absaetze, fuer die sie
 * gedacht ist. */
.mypage .story_3cards .article-text p:not(.caption-sub) {
 margin: 0 0 0.75em 0;  /* Leiter: rem -> em, Kartentext */
 font-size: 0.95rem;
 opacity: 0.85;
}
.mypage .story_3cards .article-text .caption-sub {
 /* margin entfaellt: caption-sub ist :last-child (h3 dann caption-sub im
    selben content-RTE, Beleg pattern.json), die neue em-base-:last-child-
    Regel fuer caption-sub liefert 0 bereits selbst (Batch-5-em-base-
    Ausnahme). */
 font-size: 0.85rem;
 opacity: 0.65;
}

/* ── story_featured_3cards ──────────────────────────────────────────── */
/* Local pill-spacing override entfernt — Card-Context-Pill-Spacing
 * kommt jetzt aus em-components.css (.mypage .card .pill / .chip) als
 * single source-of-truth. Story_3cards hatte vorher kein Override →
 * inkonsistent. Jetzt einheitlich ueber alle Card-Patterns. */

.mypage .story_featured_3cards .article-link {
  margin-top: 0.5rem;
}
.mypage .story_featured_3cards .article-link a {
  display: inline-flex;
  align-items: center;
  gap: 0.35rem;
  font-size: 0.875rem;
  font-weight: 600;
  color: var(--accent-on-light, var(--primary-base));
  text-decoration: none;
  transition: gap 0.2s ease, color 0.2s ease;
}
.mypage .story_featured_3cards .article-link a:hover {
  gap: 0.6rem;
  color: var(--accent-on-light, var(--primary-base));
}
.mypage .story_featured_3cards .article-link--lg a {
  font-size: 1rem;
}
/* Titel + Excerpt + Meta leben jetzt in EINEM RTE (.article-text: h3 + p +
 * p.caption-sub); der article-meta-Marker → RTE-Absatzstil caption-sub
 * (Projekt B 2026-07-24). article-link (CTA) bleibt eigener Slot. */
.mypage .story_featured_3cards .article-text h3,
.mypage .story_featured_3cards .article-text p,
.mypage .story_featured_3cards .article-link > p {
  margin: 0;
}
.mypage .story_featured_3cards .article-text h3 {
  font-size: 1.25rem;
  line-height: 1.3;
  margin-bottom: 0.5em;  /* Leiter: rem -> em, 8 -> 10px / 8px */
}
/* `:not(.caption-sub)` aus demselben Grund wie in story_3cards (Befund Stufe 4a,
 * am DOM gemessen): dieser Selektor hat (0,3,1), genau so viel wie
 * `.mypage p.caption-sub:last-child` in der Basis — `:last-child` zaehlt als
 * Klasse. Bei Gleichstand gewinnt die spaeter geladene Datei, also patterns.css.
 * Seit 4a das !important der Basis-Regel entfernt hat, bekam die
 * Attributions-Zeile dadurch 8px Abstand nach unten, obwohl sie letztes Kind
 * ist. Die Einschraenkung trifft nur die Prosa-Absaetze. */
.mypage .story_featured_3cards .article-text p:not(.caption-sub) {
  margin-bottom: 0.5em;  /* Leiter: rem -> em, 8 -> 10px / 8px */
  color: var(--text-muted);
}
.mypage .story_featured_3cards .article-text .caption-sub {
  font-size: 0.875rem;
  color: var(--text-muted);
  /* margin-bottom entfaellt: caption-sub ist hier :last-child (Byline nach
     h3 bzw. h3+p, Beleg pattern.json), die neue em-base-:last-child-Regel
     fuer caption-sub liefert 0 bereits selbst (Batch-5-em-base-Ausnahme). */
}
/* ── team_3persons ──────────────────────────────────────────── */
/* team_3persons — three-person team grid (image + name + role). */
.mypage .team_3persons.sc-dark,
.mypage .team_3persons.sc-pri,
.mypage .team_3persons.sc-sec,
.mypage .team_3persons.sc-acc {
  color: var(--sc-light, #f5f5f0);
}
.mypage .team_3persons.sc-light,
.mypage .team_3persons.sc-pri-l,
.mypage .team_3persons.sc-sec-l,
.mypage .team_3persons.sc-acc-l {
  color: var(--sc-dark, #1a1a1a);
}

/* Card-Layout: equal-height Karten mit Foto oben + Name/Rolle darunter. */
.mypage .team_3persons .team-card {
  text-align: center;
  height: 100%;
  display: flex;
  flex-direction: column;
}

/* Team-Foto: 1:1 Ratio, runde Form, gleichgrosse Bilder über alle Karten. */
.mypage .team_3persons .team-card .team-photo {
  display: block;
  width: 160px;
  height: 160px;
  margin: 0 auto 1rem;
  border-radius: 999px;
  overflow: hidden;
  aspect-ratio: 1 / 1;
}
.mypage .team_3persons .team-card .team-photo img {
  display: block;
  width: 100%;
  height: 100%;
  object-fit: cover;
}

@media (max-width: 640px) {
  .mypage .team_3persons .team-card .team-photo {
    width: 130px;
    height: 130px;
  }
}

/* ── team_5avatars ──────────────────────────────────────────── */
/* team_5avatars — 5 kompakte Avatar-Cards in einer Reihe */
.mypage .team_5avatars .compact-list {
 display: flex;
 flex-wrap: wrap;
 justify-content: center;
 gap: 1.5rem;
}
.mypage .team_5avatars .compact-item {
 flex: 0 0 calc(20% - 1rem);
 max-width: 180px;
 text-align: center;
}
.mypage .team_5avatars .compact-item picture[type='picture'] {
 display: block;
 width: 100px;
 height: 100px;
 border-radius: 999px;
 overflow: hidden;
 margin: 0 auto 0.75rem;
}
.mypage .team_5avatars .compact-item img {
 display: block;
 width: 100%;
 height: 100%;
 object-fit: cover;
}
/* Name/Rolle → RTE-Absatzstile caption/caption-sub (Projekt B 2026-07-24);
 * Basis-Optik aus em-base, Name hier etwas kräftiger als der caption-Default. */
.mypage .team_5avatars .caption {
 font-weight: 700;
}
@media (max-width: 767px) {
 .mypage .team_5avatars .compact-item {
 flex: 0 0 calc(33% - 1rem);
 }
}
/* ── team_leadership_bio ──────────────────────────────────────────── */
/* team_leadership_bio — Team-Cards mit Bio + Social */
.mypage .team_leadership_bio .team-card {
 text-align: center;
 height: 100%;
 display: flex;
 flex-direction: column;
}
.mypage .team_leadership_bio .team-card .team-photo,
.mypage .team_leadership_bio .team-card .team-photo img {
 display: block;
 width: 110px;
 height: 110px;
 object-fit: cover;
 border-radius: 999px;
 margin: 0 auto 1rem;
}
/* Rolle → Standard-Absatzstil caption-sub (Projekt B 2026-07-24, „auf den
 * Standard"). Regel entfaellt: css/em-base.css .mypage p.caption-sub
 * liefert diesen Abstand jetzt selbst als Default (Batch-5-em-base-
 * Ausnahme, Stufe 3) — team_leadership_bios eigener Wert war ohnehin
 * wirkungslos gegen das dortige margin: 0 !important. */
/* Bio-Absatz: plain <p> im content-RTE (die Marker-Klasse team-bio wurde von
 * TipptTap beim Edit gestrippt → kontextueller Selektor, Projekt B 2026-07-24).
 * caption-sub (Rolle) ist ausgenommen, die trägt ihren eigenen Stil. */
.mypage .team_leadership_bio .team-card p:not(.caption-sub) {
 margin: 0 0 1em 0;  /* Leiter: rem -> em, 16 -> 15.2px */
 font-size: 0.95rem;
 opacity: 0.85;
 line-height: 1.55;
 text-align: center;
}
/* Socials = kopierte social-strip-Struktur (Projekt „Socials-Molecule", 2026-07-24).
 * Styling kommt aus molecules.css `.molecule.social-strip`; hier nur die Card-
 * Bottom-Ausrichtung im Flex-Column-Card erhalten. */
.mypage .team_leadership_bio .molecule.social-strip {
 margin-top: auto;
}

/* ── text_prose ──────────────────────────────────────────── */

/* ── text_prose_2col ──────────────────────────────────────────── */
/* text_prose_2col — Body in 2 CSS-Spalten unter separatem Section-Header.
 * Header (eyebrow+h2+subline) lebt im col-8-Block darüber; hier flowt
 * nur der body-Slot durch 2 Spalten. Container col-8 (max-w-zentriert).
 * columns rule auf den rich-div (innerhalb der section-layer-Klasse),
 * weil der section-wrapper nur 1 block-child hat → flow braucht den
 * inner-Container. */
.mypage .text_prose_2col .prose-cols-2 > div[type='rich'] {
  columns: 2;
  column-gap: 1.5rem;
}
.mypage .text_prose_2col .prose-cols-2 > div[type='rich'] p,
.mypage .text_prose_2col .prose-cols-2 > div[type='rich'] li {
  break-inside: avoid-column;
  hyphens: auto;
}
@media (max-width: 640px) {
  .mypage .text_prose_2col .prose-cols-2 > div[type='rich'] { columns: 1; }
}

/* ── text_prose_3col ──────────────────────────────────────────── */
/* text_prose_3col — Body in 3 CSS-Spalten unter separatem Section-Header.
 * Container col-12 (volle max-w). */
.mypage .text_prose_3col .prose-cols-3 > div[type='rich'] {
  columns: 3;
  column-gap: 1.5rem;
}
.mypage .text_prose_3col .prose-cols-3 > div[type='rich'] p,
.mypage .text_prose_3col .prose-cols-3 > div[type='rich'] li {
  break-inside: avoid-column;
  hyphens: auto;
}
@media (max-width: 640px) {
  .mypage .text_prose_3col .prose-cols-3 > div[type='rich'] { columns: 1; }
}
@media (min-width: 641px) and (max-width: 1023px) {
  .mypage .text_prose_3col .prose-cols-3 > div[type='rich'] { columns: 2; }
}

/* ── trust_avatars_color ──────────────────────────────────────────── */
/* Portrait-Variante: größere, farbig umrandete Kreis-Avatare — Overlap-Optik
 * der avatar-stack-Molecule (molecule.css) wie bei trust_avatars_stars, nur
 * mit 5rem/6rem statt 3rem und farbigem statt weissem Ring. Bis 2026-08-07
 * hob dieses Pattern den Overlap auf und ersetzte ihn durch positiven Abstand;
 * das ist zurueckgenommen (Details am margin- und gap-Kommentar unten).
 * Struktur jetzt canonical (molecule avatar-stack > avatar-row > .trust-avatar,
 * Backport 2026-07-28) — hier nur das pattern-spezifische Größen-/Farb-Override,
 * kein Basis-Layout/Circle-CSS mehr (das liefert molecule.css global). */
/* gap ENTFERNT (2026-08-07, Entscheidung des Users): dieses Pattern nutzt jetzt
 * den Overlap der Molecule wie trust_avatars_stars, statt den Overlap
 * aufzuheben und durch positiven Abstand zu ersetzen. Damit entfaellt sowohl
 * `gap: 1.25rem` hier als auch `gap: 2rem` im Desktop-Block unten — der
 * Abstand kommt jetzt ausschliesslich aus dem negativen Margin am Bild
 * (molecule.css), also aus genau derselben Deklaration, die stars nutzt.
 *
 * Vorgeschichte, damit der naechste Leser nicht den alten Weg wiederbelebt:
 * das `gap` war ueber Monate wirkungslos, weil die Reihe als Block-Container
 * lief (Basis-Flag em-components.css:909 schlug das `display: flex` der
 * Molecule) und `gap` nur in Flex-/Grid-Containern gilt. Gemessen 0px statt
 * 32px, die Avatare standen auf Kante. Belegt in tools/avatar-gap-lab.html.
 *
 * flex-wrap bleibt (ohne Flag, kein Gegenspieler — geprueft in Stufe 4d-2:
 * kein CSS im Repo setzt flex-wrap auf `.avatar-row` oder eine Elternklasse).
 * Anders als bei stars ist es hier noetig: sechs 5rem/6rem-Avatare brauchen
 * mit Overlap ~544px und passen auf schmalen Viewports nicht in eine Zeile,
 * die fuenf 3rem-Avatare von stars mit ~214px schon. */
.mypage .trust_avatars_color .molecule.avatar-stack .avatar-row {
  flex-wrap: wrap;
}

/* width, height, min-/max-Werte und flex ohne Flag (Stufe 4d-2, 2026-08-07): Molecule-
 * Selektor `.mypage .molecule.avatar-stack img.trust-avatar` / `.trust-avatar`
 * ist (0,4,1) / (0,4,0), dieser Pattern-Selektor hat mit `.trust_avatars_color`
 * eine Klasse mehr: (0,5,1) / (0,5,0) — gewinnt outright per Spezifitaet.
 * min-height/max-height haben in molecule.css ohnehin GAR KEINEN Gegenspieler
 * (dort nur width/min-width/max-width gesetzt, siehe molecule.css Zeile
 * 19-32); die Notiz "em-components.css setzt 3rem" unten bezieht sich auf
 * width/max-width, nicht auf max-height. `flex: 0 0 auto` hat ebenfalls
 * keinen Gegenspieler — kein CSS im Repo setzt `flex` auf dieses Element,
 * der Browser-Default (0 1 auto) wird von nichts erzwungen. */
/* Groesse jetzt ueber die Variable der Molecule (2026-08-10). Vorher standen
 * hier sechs Deklarationen (width/height/min/max), plus ein max-height-Override
 * gegen die 3rem-Kappung aus em-components — beides ist in die Molecule
 * gewandert. Uebrig bleibt der eine Wert, der dieses Pattern ausmacht.
 *
 * Damit ist auch die Overlap-Frage aus dem alten Kommentar geloest: der
 * Overlap ist in der Molecule ein ANTEIL der Breite (--avatar-overlap: 0.25),
 * skaliert also mit. Die 5rem-Avatare ueberlappen jetzt mit 20px genauso
 * stark wie die 3rem-Avatare mit 12px — vorher waren es bei beiden 6.4px,
 * relativ also 6,7% gegen 13,3%. */
.mypage .trust_avatars_color .molecule.avatar-stack {
  --avatar-size: 5rem;
}

.mypage .trust_avatars_color .molecule.avatar-stack img.trust-avatar,
.mypage .trust_avatars_color .molecule.avatar-stack .trust-avatar {
  flex: 0 0 auto;
  /* object-fit/border-radius ohne Flag (Stufe 4c, Gruppe D, 2026-07-30):
   * gleiche Rechnung wie beim margin-Fall oben — Molecule setzt hier
   * (0,4,1) fuer den img-Zweig bzw. (0,4,0) fuer den .trust-avatar-Zweig,
   * dieser Pattern-Selektor mit der zusaetzlichen `.trust_avatars_color`
   * Klasse liegt bei (0,5,1)/(0,5,0) und gewinnt allein per Spezifitaet.
   * aspect-ratio/opacity/filter hatten in molecule.css nie einen
   * Gegenspieler (dort gar nicht gesetzt) — das Flag war dort reine
   * Vorsicht ohne jeden Konflikt. */
  object-fit: cover;
  border-radius: 50%;
  aspect-ratio: 1 / 1;
  opacity: 1;
  filter: none;
  box-shadow: 0 4px 14px color-mix(in srgb, var(--shade-dark-base) 25%, transparent);
  border: 3px solid var(--primary-base, #4a7c9e);
  transition: transform 0.25s ease, box-shadow 0.25s ease, border-color 0.25s ease;
}

.mypage .trust_avatars_color .molecule.avatar-stack img.trust-avatar:hover {
  transform: translateY(-3px);
  box-shadow: 0 8px 22px color-mix(in srgb, var(--shade-dark-base) 35%, transparent);
  border-color: var(--primary-dark, #2c5470);
}

@media (min-width: 1024px) {
  /* Der Desktop-`gap: 2rem` ist mit der Umstellung auf Overlap entfallen
   * (2026-08-07) — der Regelsatz enthielt nur diese eine Deklaration und ist
   * damit ganz weg. Der Uebergang 5rem→6rem unten bleibt. */
  /* width, height und die min-/max-Werte ohne Flag (Stufe 4d-2, 2026-08-07): identische
   * Rechnung wie im Basis-Block oben — (0,5,1)/(0,5,0) schlagen die Molecule
   * (0,4,1)/(0,4,0) unabhaengig von der Media-Query. Basis-Block und dieser
   * Block haben dieselbe Spezifitaet; bei aktiver Media-Query entscheidet
   * dann die Quellreihenfolge (dieser Block steht spaeter im File) —
   * genau das macht den Uebergang 5rem→6rem ab 1024px moeglich, UND ZWAR
   * NUR weil der Basis-Block ebenfalls kein Flag mehr traegt (s.o.). Mit
   * !important auf beiden Seiten waere das Ergebnis von der Quellreihen-
   * folge der !important-Deklarationen abhaengig gewesen (hier zufaellig
   * noch richtig, aber eine versteckte Abhaengigkeit statt einer klaren
   * Spezifitaets-Kaskade). */
  .mypage .trust_avatars_color .molecule.avatar-stack img.trust-avatar,
  .mypage .trust_avatars_color .molecule.avatar-stack .trust-avatar {
    width: 6rem;
    height: 6rem;
    min-width: 6rem;
    min-height: 6rem;
    max-width: 6rem;
    max-height: 6rem;
  }
}

/* ── trust_avatars_stars ──────────────────────────────────────────── */
/* trust_avatars_stars — Trust-Strip Section.
 * Avatar-Reihe + Sterne/Rating-Zeile jetzt über die canonical avatar-stack-
 * Molecule (molecule.css, /api/css/molecules.css) — kein pattern-lokales
 * .avatar-row/.trust-avatar/.stars/.trust-strip-text CSS mehr (Backport 2026-07-28). */
/* Zitat-Absatz (p.trust-quote), Card-Dichte — keine generische Basis-
 * Prosa (D3 Kategorie E/F), font-size/line-height bewusst groesser/lockerer
 * als Fliesstext fuers Zitat-Layout, bleiben Pattern-Deklaration. */
.mypage .trust_avatars_stars .trust-quote {
 font-family: var(--quote-font, var(--copytext-font));
 font-size: 1.15rem;
 line-height: 1.55;
 color: var(--text-dark, #1A3453);
}

/* ── trust_logos_endless ──────────────────────────────────────────── */
/* Viewport: maskiert den Track, Soft-Fade an den Rändern */
.mypage .trust_logos_endless .marquee-viewport {
  overflow: hidden;
  width: 100%;
  -webkit-mask-image: linear-gradient(90deg, transparent 0, #000 8%, #000 92%, transparent 100%);
          mask-image: linear-gradient(90deg, transparent 0, #000 8%, #000 92%, transparent 100%);
}

/* Track: flexbox-row, doppelte Logo-Sequenz, animiert um -50% */
.mypage .trust_logos_endless .marquee-track {
  display: flex;  /* 4f: entflaggt, am DOM gemessen — kein Gegenspieler */
  flex-direction: row;  /* 4f: entflaggt, am DOM gemessen — kein Gegenspieler */
  flex-wrap: nowrap;  /* 4f: entflaggt, am DOM gemessen — kein Gegenspieler */
  align-items: center;
  gap: 3.5rem;
  width: max-content;
  animation: glogo-marquee-scroll 40s linear infinite;
}

.mypage .trust_logos_endless .marquee-track img {
  height: 2.5rem;
  width: auto;
  flex: 0 0 auto;
  object-fit: contain;
  object-position: center;  /* kein Beschnitt -> mittig, nicht 30% */
  opacity: 0.55;
  filter: grayscale(100%);
  transition: opacity 0.3s ease, filter 0.3s ease;
}

.mypage .trust_logos_endless .marquee-track img:hover {
  opacity: 1;
  filter: grayscale(0%);
}

/* Pause bei Hover über den Track */
.mypage .trust_logos_endless .marquee-viewport:hover .marquee-track {
  animation-play-state: paused;
}

/* Track enthält 4 identische Kopien des Logo-Sets (32 Items). Animation
 * translatiert -25% = exakt 1 Set-Breite → bei Loop-Restart sitzt die
 * naechste Kopie nahtlos an gleicher Position. 4 Kopien stellen sicher
 * dass der Track auch bei Wide-Viewports immer ueber den Rand hinaus
 * reicht (vorher 2 Kopien × 700px = 1400px in 1495px Viewport → sichtbare
 * Luecke am rechten Rand bei translateX(-50%) → 'lädt zu spät nach'). */
@keyframes glogo-marquee-scroll {
  from { transform: translateX(0); }
  to   { transform: translateX(-25%); }
}

/* Desktop: größere Logos, langsamer */
@media (min-width: 1024px) {
  .mypage .trust_logos_endless .marquee-track {
    gap: 4.5rem;
    animation-duration: 50s;
  }
  .mypage .trust_logos_endless .marquee-track img {
    height: 3rem;
  }
}

/* Reduced Motion: Animation aus, Logos statisch sichtbar */
@media (prefers-reduced-motion: reduce) {
  .mypage .trust_logos_endless .marquee-track {
    animation: none;
    flex-wrap: wrap;  /* 4f: entflaggt, unter prefers-reduced-motion gemessen — die Basis-Regel darueber traegt seit 4f selbst kein Flag mehr, damit gewinnt diese hier per Quellreihenfolge */
    justify-content: center;
    width: 100%;
  }
}
/* ── voice_3cards ──────────────────────────────────────────── */
/* voice_3cards — 3-Spalten-Quote-Cards mit Avatar-Author-Block */
/* Der Block `.quote-card-3 …` (4 Regelsaetze: quote-body, quote-author-row,
 * .avatar, .muted) ist am 2026-08-10 entfallen. Das Template nutzt die
 * quote-card-Molecule mit `.quote-card`/`.quote-text`/`.quote-author`/
 * `.quote-avatar` — die Klassen hier matchten nichts, nachweisbar bis zur
 * T0-Migration (3997a35) zurueck; notes.md beschrieb sogar ein
 * Flex-Row-Avatar-Layout, das es im Template nie gab. Die Optik kommt aus dem
 * Molecule, das Entfernen ist folgenlos. */


/* ── voice_3stories ──────────────────────────────────────────── */
/* voice_3stories — 3-col narrative card grid with headline + body */

.mypage .voice_3stories .molecule.story-card {
  display: flex;
  flex-direction: column;
  gap: 0.5rem;
  /* `padding: 0` entfernt (2026-08-10). Die Null ist die Karten-Doktrin fuer
   * Karten MIT randlosem Bild — dort traegt der Body den Abstand zurueck.
   * Diese Karte hat kein Bild und keinen eigenen Body: der Inhalt ist EIN RTE.
   * Die Null nahm ihr also den Innenabstand komplett, `py-2` im Template gab
   * nur die vertikale Haelfte zurueck — gemessen 16px/0px, der Text stand auf
   * der Kartenkante. Jetzt gilt der Abstand aus `.card` (20px 24px), wie bei
   * den 15 anderen Kartenkoerpern des Systems. */
}

/* Titel + Story-Text leben jetzt in EINEM RTE (h4 + p) in der story-card;
 * Marker-Klassen story-headline/story-body entfallen (Projekt B, 2026-07-24).
 * H4-Größe kommt aus em-base; Pattern setzt nur Abstand + Quote-Font auf den Body. */
.mypage .voice_3stories .story-card h4 {
  margin-bottom: 0.25em;  /* Leiter: rem -> em, 4 -> 5.8px */
}

.mypage .voice_3stories .story-card p {
  font-family: var(--quote-font, var(--copytext-font));
  color: inherit;
  /* margin entfaellt: p ist :last-child der Karte — einziger Inhalt nach
     h4 im selben content-RTE, kein weiterer Slot folgt in .story-card
     (Spec D2). Falls danach visuell zu wenig Abstand zur naechsten Karte
     bleibt, gehoert der Abstand an den Karten-Container (Kategorie G,
     gap), nicht zurueck auf den Text (Spec D3 B2/D). */
}

/* ── voice_single ──────────────────────────────────────────── */
/* voice_single — TipTap-Round-Trip-Safe: alle Quote-Slots in <p> gewickelt.
 * Default-p-Margins zuruecksetzen, damit das Layout sich beim Edit nicht
 * verschiebt. */
.mypage .voice_single .quote-text > p,
.mypage .voice_single .quote-mark > p {
  /* margin entfaellt: beide sind jeweils einziges/letztes Kind ihres
     Containers (Spec D2) — quote-text > p ist der alleinige Absatz im
     Zitat-Slot, base setzt margin-top ohnehin 0 und :last-child nimmt
     margin-bottom auf 0. `.quote-mark > p` ist zusaetzlich toter Code im
     aktuellen Template (quote-mark ist heute ein Icon-Node, kein
     p-wickelnder div), bleibt aber harmlos fuer etwaige Alt-Snapshots. */
}
/* Name/Rolle: 2026-07-24 von Slot-Klassen quote-name/quote-role auf RTE-wählbare
 * caption/caption-sub migriert (Basis-Stil in em-base.css). */

/* ── voice_slider ──────────────────────────────────────────── */
/* voice_slider — Testimonials Carousel
 * Inner wrappers use `.max-w mx-auto` for centering on the page; force
 * block + max-width to beat the section-layer inline-block default. */
.mypage .voice_slider > section[type='layer'].max-w {
  display: block;  /* 4f: entflaggt, am DOM gemessen — kein Gegenspieler */
  width: 100%;
  max-width: var(--max-w, 1200px);
  margin-left: auto;  /* 4f: entflaggt, am DOM gemessen — kein Gegenspieler */
  margin-right: auto;  /* 4f: entflaggt, am DOM gemessen — kein Gegenspieler */
}

/* ── voice_slider_portrait ──────────────────────────────────────────── */
/* voice_slider_portrait — Testimonial-Slider: großes rundes Portrait links,
 * kursives Zitat rechts, Name (caption) + Rolle (caption-sub). Farbige
 * Full-Bleed-Section (sc-pri). Pfeile/Dots liefert der carousel-Node.
 * Kein eigenes JS, keine Slot-Marker für Typografie — Name/Rolle sind
 * caption/caption-sub-Absatzstile in einem RTE (Projekt B). */

/* Slide-Row: Portrait + Quote nebeneinander, vertikal zentriert. */
.mypage .voice_slider_portrait .vsp-slide {
  display: flex;  /* 4f: entflaggt, am DOM gemessen — kein Gegenspieler */
  align-items: center;
  gap: 2.5rem;
}
/* Das Portrait steht rechts in seiner Spalte, also direkt am Zitat
 * (2026-08-10). Vorher stand hier `justify-content: center` — wirkungslos,
 * weil das Flex-Item nicht das Bild ist, sondern das <picture>: das laeuft
 * als Block ueber die volle Spaltenbreite (gemessen 480px), waehrend das
 * runde Bild darin mit 240px inline am linken Rand klebte. Zentriert wurde
 * also eine unsichtbare vollbreite Box. Erst wenn das <picture> selbst auf
 * Bildbreite gesetzt ist, greift die Ausrichtung.
 * Zur Erinnerung fuer den naechsten Fall: Bild-Slots rendern als
 * <picture type="picture"> OHNE die im Template vergebene Klasse — die
 * landet am <img>. Deshalb hier der Elementselektor. */
/* Ausgerichtet wird ueber `align-items`, NICHT `justify-content` — die
 * Grid-Engine (em-components) macht aus jedem col-N-Kind eines col-12-Layers
 * einen `flex-direction: column`-Container. In einer Spalte ist die
 * Hauptachse vertikal, `justify-content` schiebt also nach oben/unten und
 * bewirkt horizontal genau nichts. Gemessen: mit `flex-end` blieb das Bild
 * bei linksInSpalte 0 / rechtsInSpalte 240. Die horizontale Achse ist hier
 * die Querachse. */
.mypage .voice_slider_portrait .vsp-portrait-col {
  display: flex;
  align-items: flex-end;
  justify-content: center;
}
.mypage .voice_slider_portrait .vsp-portrait-col > picture[type='picture'] {
  display: block;
  width: 15rem;
  max-width: 100%;
}
/* Rundes Portrait, feste Maximalgröße damit es nicht die halbe Section füllt. */
.mypage .voice_slider_portrait .vsp-portrait,
.mypage .voice_slider_portrait .vsp-portrait img {
  width: 100%;
  max-width: 15rem;
  aspect-ratio: 1 / 1;
  object-fit: cover;
  border-radius: 999px;
}

/* Quote-Mark: dezente Deko, auf farbigem Grund hell statt primary. */
.mypage .voice_slider_portrait .split-quote svg.quote-mark {
  width: 3.5rem;
  height: 3.5rem;
  fill: currentColor;
  opacity: 0.4;
  margin: 0 0 0.25em 0;  /* Leiter: rem -> em, 4px bleibt */
}
/* Kursives, groß gesetztes Zitat. Größe kommt aus em-base (<h3>); Pattern
 * setzt nur Kursivstellung, Zeilenhöhe und Abstand. */
/* margin-bottom BEHALTEN (Abweichung vom Plan-1b-Brief, der hier ENT vorsah):
 * {{quote}} rendert als alleiniges <h3 class="quote-body"> in seinem eigenen
 * anonymen Slot-Div — h3 ist damit :last-child DIESES Divs, obwohl direkt
 * danach noch ein separater {{author}}-Slot-Div (Name/Rolle als
 * caption/caption-sub, margin-top 0 !important) folgt. Ohne diese Regel
 * würde em-base h3:last-child (0,2,1) den Abstand auf 0 ziehen, weil die
 * Spezifität ausreicht sobald das Pattern nicht mehr gegensteuert — echter,
 * nicht nur potenzieller Regressionsfall (Rule 4: Element ist zwar
 * DOM-technisch :last-child, aber nicht das visuell letzte Element der
 * Zitat-Attributions-Einheit). Analog zu team_leadership_bio (Social-Strip
 * folgt) — dort behält der Brief den Abstand aus demselben Grund. */
.mypage .voice_slider_portrait .quote-body {
  font-family: var(--quote-font, var(--copytext-font));
  font-style: italic;
  font-weight: 500;
  line-height: 1.35;
  text-align: left;
  margin: 0 0 0.75em 0;  /* Leiter: rem -> em, 20 -> 21px */
}
/* caption/caption-sub (Name/Rolle) erben Optik aus em-base; auf sc-pri sind
 * beide hell (caption-sub = --text-muted-on-primary). Nur linksbündig +
 * kompakter Abstand. */
.mypage .voice_slider_portrait .vsp-quote-col .caption,
.mypage .voice_slider_portrait .vsp-quote-col .caption-sub {
  text-align: left;
}

/* Mobil: Portrait über dem Zitat, beide zentriert. */
@media (max-width: 1023px) {
  .mypage .voice_slider_portrait .vsp-slide {
    flex-direction: column;
    gap: 1.25rem;
    text-align: center;
  }
  .mypage .voice_slider_portrait .vsp-portrait,
  .mypage .voice_slider_portrait .vsp-portrait img {
    max-width: 10rem;
  }
  /* Gestapelt steht das Portrait wieder mittig, nicht rechts. */
  .mypage .voice_slider_portrait .vsp-portrait-col {
    align-items: center;
  }
  .mypage .voice_slider_portrait .vsp-portrait-col > picture[type='picture'] {
    width: 10rem;
  }
  .mypage .voice_slider_portrait .quote-body,
  .mypage .voice_slider_portrait .vsp-quote-col .caption,
  .mypage .voice_slider_portrait .vsp-quote-col .caption-sub {
    text-align: center;
  }
  .mypage .voice_slider_portrait .split-quote {
    display: flex;
    justify-content: center;
  }
}

/* ── voice_with_portrait ──────────────────────────────────────────── */
/* voice_with_portrait — Editorialer Quote mit großem Portrait-Bild
 * links und groß-gesetztem Quote-Text rechts.
 */
.mypage .voice_with_portrait .split-quote {
 position: relative;
 padding-left: 1.25rem;
}
/* Quote-Mark: neue Instanzen nutzen einen Icon-Node (<svg class="icon quote-mark">,
 * dezente Deko), Projekt B 2026-07-24 — analog quote-card/voice_single. */
.mypage .voice_with_portrait .split-quote svg.quote-mark {
 width: 4.5rem;
 height: 4.5rem;
 fill: var(--icon-color, var(--primary-base));
 margin: 0 0 0.5em 0;  /* Leiter: rem -> em, 8px bleibt */
 opacity: 0.55;
}
/* Alt-Instanzen (getipptes „ als <p class="quote-mark">) behalten die
 * typografische Variante. */
.mypage .voice_with_portrait .split-quote p.quote-mark {
 font-family: var(--headline-font);
 font-size: 4.5rem;
 line-height: 0.85;
 color: var(--primary-base);
 /* margin entfaellt, s. Begruendung voice_3cards (Spec D3 B2/D). */
 opacity: 0.55;
}

/* Praefix `.split-quote` entfernt (2026-08-10) — das war der Grund, warum
 * dieses Zitat fett in der Ueberschriftenschrift stand statt kursiv in der
 * Zitatschrift wie jedes andere voice_*-Pattern.
 *
 * Batch 5 (2026-07-30) hatte den Selektor bereits als tot erkannt und
 * ausdruecklich nicht angefasst („braucht visuelle Verifikation"): h3.quote-body
 * und p.quote-author liegen in einem eigenen `.text-center`-Div NEBEN
 * `.split-quote` — dieses wrappt nur den Icon-Block. Bis zur T0-Migration
 * (3997a35) zurueckverfolgt, kein Refactor hatte es je anders. Ohne Treffer
 * blieb die h3 beim em-base-Ueberschriftenstil stehen, und genau das war
 * sichtbar.
 *
 * `.split-quote p.quote-mark` oben bleibt wie es ist: dort matcht das Praefix
 * korrekt (bei Alt-Snapshots war der quote-mark-Absatz direkter Inhalt des
 * .split-quote-Divs).
 *
 * Werte analog voice_slider_portrait, dem naechsten Verwandten (grosses
 * Einzelzitat): Zitatschrift, kursiv, Gewicht 500, Zeile 1.35. */
.mypage .voice_with_portrait .quote-body {
 font-family: var(--quote-font, var(--copytext-font));
 font-style: italic;
 font-weight: 500;
 line-height: 1.35;
 text-align: left;
}
.mypage .voice_with_portrait .quote-author {
 font-size: 0.95rem;
 color: var(--text-muted);
 margin: 0;
}
@media (max-width: 1023px) {
 .mypage .voice_with_portrait .split-quote {
 padding-left: 0;
 padding-top: 1rem;
 }
}

