/* ═══════════════════════════════════════════════════════════════
   ExpertMaker Components — Design Tokens & Base Styles
   Extracted from Figma: Whitepace SaaS Landing Page
   ═══════════════════════════════════════════════════════════════ */

/* ─── Design Tokens ───
 *
 * Single Source of Truth für Farben ist em-base.css (--primary-base,
 * --secondary-base, --contrast-base, --shade-*, --text-light/dark inkl.
 * color-mix-Light/Dark-Stufen). Werden zur Runtime per BE-RenderCSSVars
 * pro Tenant überschrieben.
 *
 * Hier nur noch:
 *   - lokale Aliases auf em-base-Tokens (--text-body, --bg-*, --accent-*)
 *     damit der bestehende Component-Code weiter kompiliert
 *   - Layout-/Geometrie-Tokens die kein Farb-Pendant in em-base haben
 *     (--space-*, --radius-*)
 *
 * Brand-Color-Defaults dürfen hier NICHT mehr hartcodiert werden — sonst
 * gewinnt Cascade-Order über die em-base-Definitionen.
 * ─────────────────────────────────────────────────────────────────── */
:root {
  /* Aliases auf canonical em-base-Tokens */
  --text-body:    var(--text-dark);
  /* WCAG-AA: kontrast-berechneter gedimmter Ton statt kontrast-blindem
   * color-mix(…transparent). Default = on-light; sc-*-Klassen (em-base)
   * remappen pro Section-BG auf on-dark/on-primary/etc. */
  --text-muted:   var(--text-muted-on-light, var(--text-dark));
  --bg-white:     var(--color-bg);
  --bg-light:     var(--shade-light-base);
  --bg-dark:      var(--shade-dark-base);
  --accent-base:  var(--contrast-base);
  --accent-dark:  var(--contrast-dark);

  /* Spacing */
  --space-xs:        0.5rem;
  --space-sm:        1rem;
  --space-md:        2rem;
  --space-lg:        3rem;
  --space-xl:        5rem;

  /* Radii */
  --radius-sm:       0.375rem;
  --radius-md:       0.75rem;
  --radius-lg:       1rem;
  --radius-xl:       1.5rem;
}

/* Eyebrow — uses the canonical --eyebrow-* vars from em-base.css.
 * (h1..h6 + h1sub..h4sub are styled in em-base.css via the Type-Scale
 * system; no per-tier declaration belongs here.) */
.mypage .eyebrow {
  font-family:    var(--eyebrow-font-family);
  font-size:      var(--eyebrow-font-size);
  font-weight:    var(--eyebrow-font-weight);
  line-height:    var(--eyebrow-font-lineheight);
  text-transform: var(--eyebrow-text-transform);
  letter-spacing: var(--eyebrow-letter-spacing);
  color:          var(--eyebrow-font-color);
}

/* footer-title — eigenständiger Footer-Spalten-Titel.
 * Kein eyebrow-Stil (kein Primary-Color, kein uppercase-Zwang).
 * Bleibt im RTE linksbündig editierbar. Tenant-Override via --footer-title-*. */
.mypage .footer-title {
  font-family:    var(--copytext-font);
  font-size:      0.75rem;
  font-weight:    700;
  line-height:    1.2;
  text-transform: uppercase;
  letter-spacing: 0.08em;
  /* WCAG-AA: gedimmter Ton via kontrast-berechnetem Token, nicht opacity
   * (opacity 0.55 auf currentColor unterschreitet auf Footer-BG 4.5:1). */
  color:          var(--text-muted);
  margin-bottom:  0.75rem;
  text-align:     left;
}

/* Heading-Companions — h1sub..h4sub on <p> elements as visual leads
 * paired with h1..h4. Each reads its own --h_N_sub-* var slot from
 * em-base.css so a tenant override can recolour/resize a single tier
 * without affecting the others. The tier-sizes are ~50–70% of the
 * paired heading (own typographic axis, NOT the next-smaller-H).
 */
.mypage .h1sub {
  font-family:    var(--h1sub-font-family);
  font-size:      var(--h1sub-font-size);
  font-weight:    var(--h1sub-font-weight);
  line-height:    var(--h1sub-font-lineheight);
  text-transform: var(--h1sub-text-transform);
  letter-spacing: var(--h1sub-letter-spacing);
  color:          var(--h1sub-font-color);
  opacity:        var(--sub-font-opacity, 0.75);
  hyphens:        auto;
}
.mypage .h2sub {
  font-family:    var(--h2sub-font-family);
  font-size:      var(--h2sub-font-size);
  font-weight:    var(--h2sub-font-weight);
  line-height:    var(--h2sub-font-lineheight);
  text-transform: var(--h2sub-text-transform);
  letter-spacing: var(--h2sub-letter-spacing);
  color:          var(--h2sub-font-color);
  opacity:        var(--sub-font-opacity, 0.75);
  hyphens:        auto;
}
.mypage .h3sub {
  font-family:    var(--h3sub-font-family);
  font-size:      var(--h3sub-font-size);
  font-weight:    var(--h3sub-font-weight);
  line-height:    var(--h3sub-font-lineheight);
  text-transform: var(--h3sub-text-transform);
  letter-spacing: var(--h3sub-letter-spacing);
  color:          var(--h3sub-font-color);
  opacity:        var(--sub-font-opacity, 0.75);
  hyphens:        auto;
}
.mypage .h4sub {
  font-family:    var(--h4sub-font-family);
  font-size:      var(--h4sub-font-size);
  font-weight:    var(--h4sub-font-weight);
  line-height:    var(--h4sub-font-lineheight);
  text-transform: var(--h4sub-text-transform);
  letter-spacing: var(--h4sub-letter-spacing);
  color:          var(--h4sub-font-color);
  opacity:        var(--sub-font-opacity, 0.75);
  hyphens:        auto;
}

/* Legacy aliases — keep until call-sites migrate to h_N_sub.
 * `.subline` was used in pre-refactor pricing patterns; new patterns
 * use the explicit hNsub class for the matching heading tier. */
.mypage .subline {
  font-size:      var(--h2sub-font-size);
  line-height:    var(--h2sub-font-lineheight);
  font-weight:    var(--h2sub-font-weight);
  color:          var(--h2sub-font-color);
}

.mypage .lead {
  font-size:      var(--h2sub-font-size);
  line-height:    var(--h2sub-font-lineheight);
  font-weight:    var(--h2sub-font-weight);
  color:          var(--h2sub-font-color);
}

/* ─── Section Color Schemes ─── */
/* ─── Section Color Schemes ───
 * The em-base.css uses CSS variables (--h2-font-color etc.) with !important
 * to set text colors. We override the variables, not the properties,
 * so our overrides win without specificity wars.
 * ─── */

/* ─── Section Color Schemes ───
 * Each scheme sets the background + overrides CSS variables used by the
 * typography rules in em-base.css. Overriding variables (not concrete
 * properties) keeps the specificity chain intact — patterns can set
 * their own class-scoped variables or direct colors and will win
 * against these without needing `!important`.
 *
 * The root `color:` is set without `!important` so a pattern-level
 * rule can change it. The `* { color: inherit }` blanket override was
 * removed — it was force-inheriting colors across every child and
 * blocked legitimate pattern overrides. */

/* Dark sections (dark bg → light text). Token-based, damit per-tenant
   Theming via BE-RenderCSSVars sauber durchgreift. WICHTIG: --eyebrow-
   font-color + --emphasis-font-color werden hier NICHT mehr überschrieben
   — diese Tokens kommen vom html:root-Block der ProjectSettings → Typography
   → Eyebrow. Wenn der User dort einen Wert setzt, soll er auf allen sc-*-
   Sektionen wirken; setzt er nichts, fällt em-base.css auf currentColor
   zurück (= Sektion-Textfarbe, immer lesbar). */
.mypage .sc-dark {
  background-color: var(--shade-dark-base);
  color: var(--text-light);
}

/* Light sections */
.mypage .sc-light {
  /* Sanftes vertikales Gradient statt hartem Flat-Color — gleiche
     Leserichtung wie das Auge (oben hell → Mitte leicht getönt → unten hell).
     --band-bg-* sind in em-base.css definiert und tenant-überschreibbar. */
  background: linear-gradient(
    180deg,
    var(--band-bg-top) 0%,
    var(--band-bg-mid) 45%,
    var(--band-bg-bot) 100%
  );
  color: var(--text-dark);
}

/* Primary sections (Brand-Farbe → berechneter on-brand-Text) */
.mypage .sc-pri {
  background-color: var(--primary-base);
  color: var(--on-primary-text, #fff);
}

/* Primary light sections */
.mypage .sc-pri-l {
  background-color: var(--primary-light);
  color: var(--text-dark);
}

/* Secondary dark */
.mypage .sc-sec {
  background-color: var(--secondary-base);
  color: var(--on-secondary-text, #fff);
}

/* Accent sections (Kontrast-Farbe → berechneter on-brand-Text) */
.mypage .sc-acc {
  color: var(--on-accent-text, #111827);
}

/* Anchor-Underline auf dunklen Sektionen: der Default --contrast-base
   (Orange) hat auf weißem Text noch okayen Kontrast, aber --contrast-light
   (heller Akzent) liest sich auf Dunkel-BG klarer. Pri-Sektionen (Brand-BG)
   nehmen ebenfalls light, damit der Underline nicht im BG verschwindet. */
/* sc-dark + sc-sec: dunkler Hintergrund → accent-on-dark ≥4.5:1 auf dunklem BG (Task 7) */
.mypage .sc-dark,
.mypage .sc-sec {
  --link-underline-color: var(--contrast-light);
  --link-hover-color:     var(--text-light);
  --eyebrow-font-color:   var(--accent-on-dark, var(--primary-light));
}

/* sc-pri + sc-acc: BRAND-farbiger Hintergrund → on-primary-text = weiß (max. Kontrast, Task 7)
 * primary-light auf primary-Hintergrund wäre fast unsichtbar. */
.mypage .sc-pri,
.mypage .sc-acc {
  --link-underline-color: rgba(255,255,255,0.5);
  --link-hover-color:     var(--text-light);
  --eyebrow-font-color:   var(--on-primary-text, #fff);
}

/* Auf dunklen Hintergründen (sc-dark/sc-pri/sc-sec/sc-acc) erbt stat-value
 * die helle Schriftfarbe des Containers, statt --primary-base zu verwenden
 * (das ist i.d.R. die Hintergrundfarbe → Text unsichtbar).
 * Spezifizität (.mypage + sc-* + .molecule + .stat-value = 4 Klassen)
 * muss > molecule.css (.molecule.stat-item .stat-value = 3 Klassen) sein,
 * weil molecule.css nach em-components.css geladen wird. */
.mypage .sc-dark  .molecule .stat-value,
.mypage .sc-pri   .molecule .stat-value,
.mypage .sc-sec   .molecule .stat-value,
.mypage .sc-acc   .molecule .stat-value {
  color: currentColor;
}

/* ─── Button Base ─── */
.mypage .btn-wrap {
  display: inline-flex;
  align-items: center;
  gap: 0.5rem;
  padding: 0.875rem 2rem;
  /* --cta-color wird von ProjectSettings gesetzt wenn Button ≠ Primary.
     --cta-bg-safe = BE-berechnete dunkle Variante mit ≥4.5:1 Kontrast für weißen Text (Task 7).
     Fallback-Kette: ProjectSettings-CTA → BE-safe → primary-base (legacy). */
  background: var(--cta-color, var(--cta-bg-safe, var(--primary-base)));
  /* `--cta-text` erlaubt eine abweichende Schriftfarbe, wenn der Autor dem
   * EINZELNEN Knopf eine helle Farbe gibt (Inspektor → Knopf-Farbe, 2026-08-11).
   * Ohne die Eigenschaft bleibt es bei Weiss wie bisher. */
  color: var(--cta-text, #fff);
  border-radius: var(--radius-md);
  font-weight: 600;
  font-size: var(--bodytext-font-size);
  text-decoration: none;
  cursor: pointer;
  transition: background 0.2s ease, transform 0.15s ease, box-shadow 0.2s ease;
  /* Atemraum: verhindert optisches Zusammenfließen bei mehreren Buttons */
  margin: 0.25rem 0.375rem;
  border: none;
}

/* Mehrere Buttons in einer Reihe: flex + gap. */
.mypage section[type='layer']:has(> button.btn-wrap),
.mypage section[type='layer']:has(> a.btn-wrap),
.mypage .btn-row {
  display: flex;
  flex-wrap: wrap;
  justify-content: center;
  align-items: center;
  gap: 0.5rem;
}

/* Abstand VOR einer vollbreiten CTA-Zeile — jetzt hier, nicht mehr im Template
 * (2026-08-10; der Kommentar ueber der Regel oben sagte vorher das Gegenteil).
 *
 * Warum die Umkehr: gemessen lagen 21 von 49 CTA-Zeilen bei 20px unter ihrem
 * Inhalt, weitere 6 bei 24px — 20px ist ungefaehr der Absatz-Rhythmus, der
 * Button las sich dadurch als Teil des Textblocks statt als dessen Abschluss.
 * Der Wert ist eine Systemaussage („so weit steht eine Handlung von ihrem
 * Inhalt ab"), keine Eigenschaft eines einzelnen Patterns, und gehoert damit
 * an eine Stelle. 2rem ist derselbe Wert wie `--section-head-gap`: der
 * Uebergang „Ueberschrift -> Inhalt" und „Inhalt -> Handlung" bekommen damit
 * denselben Rhythmus.
 *
 * WARUM NUR `.col-12`: der Selektor `:has(> a.btn-wrap)` trifft jeden Layer
 * mit Button-Kind — auch die CTA-SPALTE im Header (`col-3 htc-cta-row`) und
 * die Aktionszelle in Karten (`download-card-action`, `team-card-cta`). Dort
 * ist ein Abstand nach oben falsch: die Spalte steht neben ihrem Inhalt, nicht
 * darunter. Die Bedingung `.col-12` trennt „vollbreite Zeile unter dem Inhalt"
 * von „Spalte neben dem Inhalt", ohne eine Liste von Ausnahmen zu pflegen.
 *
 * Ueber `--cta-gap` zentral stellbar (Projekt-Ebene oder pattern-lokal, wenn
 * eine Buehne bewusst mehr Luft braucht). */
.mypage section[type='layer'].col-12:has(> button.btn-wrap),
.mypage section[type='layer'].col-12:has(> a.btn-wrap),
.mypage .btn-row.col-12 {
  margin-top: var(--cta-gap, 2rem);
}

.mypage .btn-wrap:hover {
  background: var(--cta-dark, var(--primary-dark));
  transform: translateY(-2px);
  box-shadow: 0 4px 12px rgba(4,56,115,0.3);
}

/* NOTE: inner-element selectors (.btn-wrap p|span|div) were removed —
   they caused double-padding when the editor injects runtime wrappers.
   The button is the wrapper itself. */

/* Dark/primary sections: white button with primary text for max contrast */
/* Auf dunklem Grund ist der Knopf standardmaessig weiss — ABER eine
 * ausdrueckliche Knopf-Farbe des Autors muss gewinnen. Diese Regel liegt bei
 * (0,3,0) und schlaegt die Basis (0,2,0); ohne die Variablen-Kette waere das
 * Farbfeld im Inspektor in jedem dunklen Abschnitt wirkungslos. Ohne
 * gesetzte Eigenschaft ist das Verhalten unveraendert. */
.mypage .sc-dark .btn-wrap,
.mypage .sc-pri .btn-wrap,
.mypage .sc-sec  .btn-wrap,
.mypage .sc-acc  .btn-wrap {
  background: var(--cta-color, #fff);
  color: var(--cta-text, var(--primary-dark, #1a2f5e));
}
.mypage .sc-dark .btn-wrap:hover,
.mypage .sc-pri  .btn-wrap:hover,
.mypage .sc-sec  .btn-wrap:hover,
.mypage .sc-acc  .btn-wrap:hover {
  background: var(--cta-dark, var(--shade-light-base, #f5f5f0));
  transform: translateY(-2px);
  box-shadow: 0 4px 12px rgba(0,0,0,0.2);
}

/* btn-dark: dunkle Button-Variante als globaler Helper. Vorher in mehreren
 * Patterns referenziert (foot_3col_elegant, foot_horizontal_compact, ...)
 * aber nirgends definiert → Button rendete als „schwarzer Blob ohne
 * lesbaren Text". Override beats .btn-wrap default (primary) und die
 * sc-dark/pri/sec/acc Helligkeits-Variante (white BG)). */
.mypage .btn-dark,
.mypage .btn-wrap.btn-dark,
.mypage .sc-dark .btn-wrap.btn-dark,
.mypage .sc-pri .btn-wrap.btn-dark,
.mypage .sc-sec .btn-wrap.btn-dark,
.mypage .sc-acc .btn-wrap.btn-dark {
  background: var(--shade-dark-base) !important;
  color: var(--text-light) !important;
}
/* background ohne Flag (Stufe 4c, Rest, 2026-07-30): schlaegt
 * `.mypage .btn-wrap:hover` (0,3,0) outright per Spezifitaet (0,4,0 fuer
 * "btn-wrap btn-dark", 0,3,0 fuer nur "btn-dark" — beide schlagen den
 * Primary-Hover-Default). Gegen `.sc-dark/pri/sec/acc .btn-wrap:hover`
 * (ebenfalls (0,4,0) im btn-wrap-Fall) steht diese Regel auf Gleichstand,
 * gewinnt aber per Quellreihenfolge — sie ist im selben File WEITER UNTEN
 * deklariert als der sc-*-Block. Keine Patterns.css-Datei definiert diesen
 * Selektor lokal (geprueft: nur foot_3col_elegant hat eine eigene, staerker
 * spezifische Regel mit identischem Wert — kein Konflikt). */
.mypage .btn-dark:hover,
.mypage .btn-wrap.btn-dark:hover {
  background: color-mix(in srgb, var(--shade-dark-base) 88%, var(--text-light) 12%);
}

/* btn-outline: die ZWEITE Handlung — gleiche Vorgeschichte wie btn-dark.
 * `btn-outline` stand im Template von head_brand_tagline_cta, war aber in
 * keiner CSS-Datei beider Repos definiert; am DOM gemessen (2026-08-11)
 * rendeten „Anmelden" und „Loslegen" deshalb als zwei IDENTISCHE gefuellte
 * Knoepfe (beide rgb(114,91,77), border 0px). Zwei gleich laute Handlungen
 * sind keine Hierarchie — der Blick hat keinen Ankerpunkt.
 *
 * Der Rahmen kommt aus `currentColor` (traegt auf hellem wie dunklem Band ohne
 * Nachzug pro Farbpaar) und liegt als INNERER Schatten, nicht als `border`:
 * der Basis-Knopf hat `border: none`, ein echter Rahmen machte die Variante
 * 2px groesser als ihren Nachbarn. Der Hover muss den Ring erneut setzen, weil
 * `.btn-wrap:hover` `box-shadow` ueberschreibt. */
.mypage .btn-wrap.btn-outline {
  /* Eine ausdrueckliche Knopf-Farbe FUELLT auch diese Variante (korrigiert
   * 2026-08-11 nach Rueckmeldung des Users: „setzt nicht die Farbe des Buttons
   * sondern der Schrift").
   *
   * Mein erster Anlauf faerbte hier bewusst nur Ring und Schrift, damit ein
   * Umriss ein Umriss bleibt. Das ist als Systemgedanke verteidigbar, als
   * Bedienung aber falsch: das Feld heisst „Knopf-Farbe", und wer darauf klickt,
   * erwartet eine gefaerbte FLAECHE. Wer den Umriss behalten will, waehlt keine
   * Farbe — der Standard ist unveraendert transparent. */
  background: var(--cta-color, transparent);
  color: var(--cta-text, inherit);
  box-shadow: inset 0 0 0 1px var(--cta-color, currentColor);
}
.mypage .btn-wrap.btn-outline:hover {
  /* Ohne die Variable die alte, leichte Tönung; mit gewaehlter Farbe deren
   * dunklere Fassung — sonst wuerde der Hover die Fuellung wieder wegnehmen. */
  background: var(--cta-dark, color-mix(in srgb, currentColor 10%, transparent));
  box-shadow: inset 0 0 0 1px var(--cta-color, currentColor);
}

/* ─── Logo-Fit Helper ──────────────────────────────────────────────────
 * Structureller Logo-Sizer: ein Layer mit `class="col-N logo-fit"` (oder
 * footer-logo-fit / htc-logo-fit etc.) gibt die Logo-Breite vor.
 *
 * Caveat em-components-Grid: col-N width-Regeln greifen nur wenn der
 * DIREKTE Parent col-12 ist. Bei col-3 inside col-6 brand-block waere
 * die col-Quote daher wirkungslos → Image wuerde auf seine natuerliche
 * Bildgroesse wachsen (typische Brand-Logos: 1600px+).
 *
 * Safety-Cap: --logo-max-w (default 240px). Patterns koennen pro Slot
 * ueberschreiben:
 *    .mypage .brand_banner .brand-logo-fit { --logo-max-w: 360px }
 * Innerhalb der Cap kann col-N noch shrinken (wenn Grid-Parent col-12).
 */
/* Caps entfallen: col-N steuert die Logo-Breite. Voraussetzung: der
 * direkte Parent des logo-fit Layers ist col-12 (logo-row Wrapper im
 * Pattern-Template). Dadurch greift die em-components-Grid-Regel
 * .col-12 > .col-N { width: calc(N/12 * 100%) }. Author kann im Editor
 * den Width-Picker auf logo-fit benutzen und das Logo schrumpfen/wachsen
 * sehen.
 *
 * Optional kann ein Pattern via --logo-max-w noch eine Decke setzen:
 *   .mypage .brand_banner [class*='logo-fit'] { max-width: 320px; }
 * Standard ist keine Decke — col-N + Outer-Brand-Block bestimmen alles. */
.mypage [class*='logo-fit'] img,
.mypage [class*='logo-fit'] picture {
  display: block;
  width: 100%;
  height: auto;
  object-fit: contain;
  object-position: center;  /* kein Beschnitt -> mittig, nicht 30% */
}

/* ─── Unified Header Logo-Container ────────────────────────────────────
 * Expliziter Logo-Sizer für Header: Größe via max-height-Skala (entkoppelt
 * vom col-Grid), vertikal zentriert. Ersetzt die col-N-logo-fit-Mechanik
 * in Header-Patterns. Siehe Spec 2026-07-06-unified-header-contract. */
.mypage .head-logo {
  display: flex;
  align-items: center;      /* vertikal zentriert */
  --head-logo-h: 40px;      /* Default = logo-m */
}
.mypage .head-logo.logo-xs { --head-logo-h: 24px; }
.mypage .head-logo.logo-s  { --head-logo-h: 32px; }
.mypage .head-logo.logo-m  { --head-logo-h: 40px; }
.mypage .head-logo.logo-l  { --head-logo-h: 56px; }
.mypage .head-logo.logo-xl { --head-logo-h: 72px; }
/* Der Wrapper darf nur so breit sein wie das Logo (2026-08-11).
 *
 * DIE URSACHE EINES LANGEN FEHLERS: `render-struct.css` gibt jedem
 * `section[type='layer']` ein `width: -webkit-fill-available`. Der Logo-Wrapper
 * IST so ein Layer, wurde also spaltenbreit — gemessen 1168px in
 * head_centered_logo_nav. Ein Block-`<img>` mit `width: auto` und ohne bekannte
 * Eigenmasse (der Renderer emittiert kein width/height-Attribut) faellt dann auf
 * die Containerbreite zurueck, und `object-fit: contain` macht daraus einen
 * briefkastenfoermigen STREIFEN quer durch den Header.
 * `fit-content` schlaegt die Basis per Spezifitaet (0,3,1 gegen 0,2,1).
 * Dasselbe Problem hatte ich im Footer mit `max-width: 150px` zugeklebt, ohne
 * die Ursache zu sehen. */
.mypage section[type='layer'].head-logo {
  width: fit-content;
  max-width: 100%;
}
.mypage .head-logo img,
.mypage .head-logo picture,
.mypage .head-logo picture img {
  display: block;
  height: var(--head-logo-h);
  width: auto;
  max-width: 100%;
  object-fit: contain;
  /* Linksbuendig statt mittig: das Logo soll optisch an der Inhaltskante
   * sitzen, nicht in einem breiteren Kasten schweben. */
  object-position: left center;
}
/* Brand-Alignment (Left/Center/Right) — einzige erlaubte Header-Variation.
 * Brand-Layer sind flex-COLUMN (Layer-Default). Horizontale Ausrichtung ist
 * daher die CROSS-Achse → align-items (NICHT justify-content, das wäre die
 * vertikale Haupt-Achse und würde die Elemente fälschlich horizontal
 * zentrieren). Vertikale Zentrierung im Header trägt die Row (align-items). */
.mypage .head-align-left,
.mypage .head-align-center,
.mypage .head-align-right,
/* Spezifitaets-Nachzug (2026-08-11, am DOM belegt): render-struct.css gibt
 * JEDEM `section[type='layer']` ein `display: inline-block`, und dieser
 * Selektor liegt bei (0,2,1) — ein Attributselektor zaehlt wie eine Klasse.
 * Die reine Klassenregel darueber liegt bei (0,2,0) und VERLOR. Der
 * Brand-Block blieb damit inline-block, `align-items` war wirkungslos und
 * head_centered_logo_nav zeigte seine Wortmarke LINKS, obwohl
 * `head-align-center` gesetzt war. Sichtbar wurde der Fehler nur bei
 * center/right: links ist ohnehin der Default.
 *
 * `text-align` braucht keinen Nachzug — sobald der Block eine Flex-Spalte
 * ist, schrumpft `align-items: center` das Textkind auf seine Inhaltsbreite
 * und zentriert es als Box. */
.mypage section[type='layer'].head-align-left,
.mypage section[type='layer'].head-align-center,
.mypage section[type='layer'].head-align-right { display: flex; flex-direction: column; justify-content: center; }
.mypage .head-align-left   { align-items: flex-start; text-align: left; }
.mypage .head-align-center { align-items: center;     text-align: center; }
.mypage .head-align-right  { align-items: flex-end;   text-align: right; }
/* Brand-Text: kein p-Default-Margin (descendant, nicht `> p` — das RTE-Markup
 * verschachtelt den <p> tiefer). Sonst wird der Brand-Block höher als der
 * Text und der Text hängt oben statt vertikal zentriert zu sein. */
/* Bis Stufe 2 war hier `!important` noetig: em-base setzte
 * `.mypage p { margin: 0 0 1.25em !important }`, nur ein `!important` mit
 * ≥ Spezifitaet schlug das. Seit dessen Entfernung gewinnt diese Regel
 * (0,2,1) bereits per Spezifitaet gegen `.mypage p` (0,1,1) — das Flag ist
 * ueberfluessig (Stufe 4a, 2026-07-30).
 *
 * Wichtig, geprueft und gewollt: dadurch werden `head_brand_tagline_cta`
 * und `head_floating_glass` wieder wirksam — deren `> p + p { margin-top:
 * 2px }` bzw. `margin-top: 0.4rem` sind mit (0,2,2) bzw. (0,3,2) je nach
 * Pattern-Variante spezifischer als diese Regel hier (0,2,1) und gewinnen
 * jetzt fuer margin-top. Diese Design-Absicht war nie geloescht, nur tot
 * (s. "DERZEIT WIRKUNGSLOS"-Kommentare in den jeweiligen pattern.css) —
 * mit dem Flag-Fall wird sie wieder sichtbar, das ist der Zweck dieses
 * Batches, keine Regression. margin-bottom bleibt 0: die Pattern-eigene
 * `> p { margin: 0 }`-Regel hat dieselbe Spezifitaet (0,2,1) und steht im
 * Quelltext nach dieser hier (patterns laden nach components). */
/* `.htc-brand-text` und `.hfg-brand-text` sind hier entfallen (2026-08-11):
 * seit der Header-Konsolidierung setzt kein Template diese Klassen mehr, die
 * Marke heisst ueberall `head-brand-text`. */
.mypage .head-brand-text p,
.mypage .hcln-brand p { margin: 0; }
/* Header-CTA-Buttons kompakt/dezent — EINE Quelle für beide htc-Varianten
 * (ersetzt divergierende Duplikate in den pattern.css, die sich gegenseitig
 * überschrieben und die Buttons groß gelassen haben). */
.mypage .head_brand_tagline_cta .htc-cta-row .btn-wrap {
  padding: 0.3rem 0.8rem;
  margin: 0;
  font-size: 0.75rem;
  font-weight: 600;
  letter-spacing: 0.01em;
  border-radius: 0.5rem;
  white-space: nowrap;
  transition: background 150ms ease, transform 80ms ease;
}

/* ── Header-über-Hero-Overlay ───────────────────────────────────────
 * Renderer (annotateHeaderOverlay) setzt .head-overlay-active auf die
 * Header-Section, wenn der Hero direkt darunter data-header-overlay
 * trägt; .head-sticky zusätzlich bei data-header-sticky; .hero-under-
 * overlay auf den Hero.
 *
 * Plan E1: .head-overlay-active liefert NUR Struktur. Die Default-Optik
 * (transparent + heller Text + Verlaufs-Scrim) lebt in .head-overlay-scrim,
 * das der Renderer nur ohne explizite Panel-Wahl (sc-* außer sc-light,
 * glass-*, bg-image, head-bg-none) mitsetzt. Explizite Schemata (0,2,0)
 * wirken damit ungehindert; der Scrim-Block hebt sich mit 0,4,1 über den
 * Pattern-Default sc-light (0,2,0). */
.mypage section[type="layer"].head-overlay-active {
  position: absolute;
  top: 0;
  left: 0;
  right: 0;
  z-index: 100;
}

/* Default-Optik: nur bei renderer-gesetztem head-overlay-scrim. */
.mypage section[type="layer"].head-overlay-active.head-overlay-scrim {
  background: transparent;
  color: var(--text-light);
}
/* Kind-Elemente erben die helle Schrift; Brand/Nav-Text explizit hell,
 * ohne hardcodierte Farbe (nutzt die sc-light-Variable). */
.mypage section[type="layer"].head-overlay-active.head-overlay-scrim .head-brand-text {
  color: var(--text-light);
}
/* Nav-Links routen durch --menu-link-color (Menü-Text-Styling gewinnt auch
 * über dem Scrim); Fallback = heller Overlay-Text wie bisher. */
.mypage section[type="layer"].head-overlay-active.head-overlay-scrim .em-nav a,
.mypage section[type="layer"].head-overlay-active.head-overlay-scrim .head-nav-slot a {
  color: var(--menu-link-color, var(--text-light));
}

/* Dezenter Scrim: Verlauf oben, verbessert Kontrast über hellen
 * Bildbereichen, ohne das Hero-Bild flächig abzudunkeln. */
.mypage section[type="layer"].head-overlay-active.head-overlay-scrim::before {
  content: "";
  position: absolute;
  inset: 0 0 auto 0;
  height: 160%;
  pointer-events: none;
  z-index: -1;
  background: linear-gradient(
    to bottom,
    color-mix(in srgb, var(--shade-dark-base) 38%, transparent),
    transparent
  );
}

/* Sticky: beim Scrollen oben gepinnt. Der .scrolled-Zustand (solider BG,
 * dunkle Schrift, JS aus renderer/sticky.go) MUSS nach dem Scrim-Block
 * stehen: gleiche Spezifität (0,4,1) → Source-Order gewinnt. */
.mypage section[type="layer"].head-overlay-active.head-sticky {
  position: fixed;
}
.mypage section[type="layer"].head-overlay-active.head-sticky.scrolled {
  background: var(--shade-light-base);
  color: var(--text-dark);
  box-shadow: 0 2px 12px color-mix(in srgb, var(--shade-dark-base) 12%, transparent);
}
.mypage section[type="layer"].head-overlay-active.head-sticky.scrolled::before {
  display: none;
}
.mypage section[type="layer"].head-overlay-active.head-sticky.scrolled .head-brand-text {
  color: var(--text-dark);
}
.mypage section[type="layer"].head-overlay-active.head-sticky.scrolled .em-nav a,
.mypage section[type="layer"].head-overlay-active.head-sticky.scrolled .head-nav-slot a {
  color: var(--menu-link-color, var(--text-dark));
}

/* Hero unter Overlay: Kopf-Freiraum, damit top-alignter Content nicht
 * unter dem schwebenden Header verschwindet. Vertikal zentrierte Heroes
 * (vh-70 o.ä.) brauchen das kaum, schadet aber nicht. */
.mypage .hero-under-overlay {
  --header-clearance: 5rem;
  padding-top: var(--header-clearance);
}

/* ─── Arrow-Shape Helper ───────────────────────────────────────────────
 * Clip-path-basierte Pfeil-Formen fuer Process-/Step-Patterns. Eine
 * Klasse, vier Direction-Modifier, plus Chevron-Variante mit Notch-
 * links fuer chain-of-cards Optik.
 *
 * Custom-Properties zum Tunen pro Pattern:
 *   --arrow-tip-depth  Tiefe der Spitze als %-Wert (Default 12.5% = 1/8)
 *   --arrow-tip-inset  Inset top/bottom vom Tip-Base in %  (Default 2.5%)
 *   --arrow-pad        Innen-Padding (Default 1.25rem 1.5rem)
 *
 * Erwartete DOM-Struktur: ein einzelnes Element mit Klasse .arrow-shape
 * (+ optional --chevron / --left / --up / --down). Inhalt fluesst innen.
 *
 * Cave-At-Pitfalls:
 *  - clip-path cuts auch ::after-Pseudos und box-shadows weg. Schatten
 *    statt clip-shape entweder via filter:drop-shadow ODER box-shadow
 *    auf einen umliegenden Wrapper.
 *  - Animationen auf clip-path:polygon brauchen gleiche Punktanzahl in
 *    from/to-States — chevron <-> right wechsel triggert Re-Layout.
 */
.mypage .arrow-shape {
  --arrow-tip-depth: 12.5%;
  --arrow-tip-inset: 2.5%;
  --arrow-pad: 1.25rem 1.5rem;
  position: relative;
  padding: var(--arrow-pad);
  padding-right: calc(var(--arrow-tip-depth) + 1rem);
  clip-path: polygon(
    0 0,
    calc(100% - var(--arrow-tip-depth)) 0,
    calc(100% - var(--arrow-tip-depth)) var(--arrow-tip-inset),
    100% 50%,
    calc(100% - var(--arrow-tip-depth)) calc(100% - var(--arrow-tip-inset)),
    calc(100% - var(--arrow-tip-depth)) 100%,
    0 100%
  );
}

/* Chevron: zusaetzlich Notch-links, sodass eine Chain von Karten optisch
 * ineinandergreift (Tipp von Card N landet im Notch von Card N+1). */
.mypage .arrow-shape.arrow-shape--chevron {
  padding-left: calc(var(--arrow-tip-depth) + 1rem);
  padding-right: calc(var(--arrow-tip-depth) + 1rem);
  clip-path: polygon(
    0 0,
    calc(100% - var(--arrow-tip-depth)) 0,
    100% 50%,
    calc(100% - var(--arrow-tip-depth)) 100%,
    0 100%,
    var(--arrow-tip-depth) 50%
  );
}
/* No-left-notch fuer die erste Card in einer Chevron-Chain. */
.mypage .arrow-shape.arrow-shape--chevron.arrow-shape--first {
  padding-left: 1.5rem;
  clip-path: polygon(
    0 0,
    calc(100% - var(--arrow-tip-depth)) 0,
    100% 50%,
    calc(100% - var(--arrow-tip-depth)) 100%,
    0 100%
  );
}
/* No-right-tip fuer die letzte Card in einer Chevron-Chain (Tag-Form). */
.mypage .arrow-shape.arrow-shape--chevron.arrow-shape--last {
  padding-right: 1.5rem;
  clip-path: polygon(
    0 0,
    100% 0,
    100% 100%,
    0 100%,
    var(--arrow-tip-depth) 50%
  );
}

/* Direction-Variants: spiegeln / 90deg-Rotation der polygon-Coords. */
.mypage .arrow-shape.arrow-shape--left {
  padding-left: calc(var(--arrow-tip-depth) + 1rem);
  padding-right: 1.5rem;
  clip-path: polygon(
    var(--arrow-tip-depth) 0,
    100% 0,
    100% 100%,
    var(--arrow-tip-depth) 100%,
    var(--arrow-tip-depth) calc(100% - var(--arrow-tip-inset)),
    0 50%,
    var(--arrow-tip-depth) var(--arrow-tip-inset)
  );
}
.mypage .arrow-shape.arrow-shape--up {
  padding-top: calc(var(--arrow-tip-depth) + 0.75rem);
  padding-right: 1.5rem;
  clip-path: polygon(
    0 var(--arrow-tip-depth),
    var(--arrow-tip-inset) var(--arrow-tip-depth),
    50% 0,
    calc(100% - var(--arrow-tip-inset)) var(--arrow-tip-depth),
    100% var(--arrow-tip-depth),
    100% 100%,
    0 100%
  );
}
.mypage .arrow-shape.arrow-shape--down {
  padding-bottom: calc(var(--arrow-tip-depth) + 0.75rem);
  padding-right: 1.5rem;
  clip-path: polygon(
    0 0,
    100% 0,
    100% calc(100% - var(--arrow-tip-depth)),
    calc(100% - var(--arrow-tip-inset)) calc(100% - var(--arrow-tip-depth)),
    50% 100%,
    var(--arrow-tip-inset) calc(100% - var(--arrow-tip-depth)),
    0 calc(100% - var(--arrow-tip-depth))
  );
}

/* clip-path schneidet ALLES innerhalb des Elements ab — auch TipTap-
 * Toolbars + Editor-Overlays die ueber den Card-Rand hinausragen.
 * Wenn ein Descendant gerade von TipTap bearbeitet wird (tiptap-overlay
 * vom InlineEditor via createPortal in den Click-Target gemounted),
 * clip-path temporaer abschalten damit der Editor sichtbar bleibt.
 *
 * Specificity-Hinweis: muss alle Varianten-Selektoren (0,3,0)
 * schlagen — daher Doppelung der arrow-shape-Klasse im Selector,
 * was die Specificity auf 0,4,0 hebt (.mypage + .arrow-shape ×2
 * + :has(.tiptap-overlay)). Damit gewinnt der Override gegen
 * jede --chevron/--first/--last/--left/--up/--down Variante. */
.mypage .arrow-shape.arrow-shape:has(.tiptap-overlay),
.mypage .arrow-shape.arrow-shape:has([data-tiptap-loading]) {
  clip-path: none;
  overflow: visible;
  z-index: 100;
}

/* ─── IconText (Mini-Inline-Slot) ──────────────────────────────────────
 * <span type="icontext"> ist Inline-Element. Sein Inhalt (Ziffer ODER
 * inline-SVG aus dem TipTap-Icon-Picker) muss in BEIDEN Faellen sauber
 * zentrieren — sowohl in einem flex-zentrierten Eltern (.step-bubble
 * etc.) als auch standalone.
 *
 * Probleme die das loest:
 *  - Inline-SVG sitzt an der text-baseline (= unterhalb der visuellen
 *    Mitte), Ziffer hingegen am text-baseline mittig → asymmetrische
 *    Position abhaengig vom Content.
 *  - Inline-flex auf dem Span selbst sorgt dafuer, dass Text- und
 *    SVG-Content beide ueber die SAME Cross-Axis zentrieren.
 *  - SVG als display:block raus aus dem Inline-Flow → keine Baseline-
 *    Versetzung mehr, Hoehe folgt der SVG-Box statt der Linienhoehe.
 *
 * Anwendbar auf alle icontext-Spans system-weit (proc_*, step-card,
 * trust_avatars-Initialen, beliebige Mini-Bubble-Verwendungen). */
.mypage [type="icontext"] {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  vertical-align: middle;
  line-height: 1;
}
/* SVG-Mode: wenn der icontext-Slot ein Icon enthaelt, fuellt der Span
 * den umgebenden Container (Bubble) komplett, und das SVG nimmt 60%
 * der Container-Groesse. Damit ist die Icon-Groesse FEST mit der
 * Bubble verbunden — egal wie gross die Bubble in pattern.css gesetzt
 * wird, das Icon skaliert proportional mit (Daumenregel: 40% Atemraum
 * zwischen Glyph und Kreisrand).
 *
 * Voraussetzung: der direkte Eltern-Layer (.step-bubble o.ae.) muss
 * eine explizite Groesse haben — Prozentangaben relativieren sich gegen
 * den naechsten gestylten Container. */
.mypage [type="icontext"]:has(> svg) {
  width: 100%;
  height: 100%;
}
.mypage [type="icontext"] > svg {
  display: block;
  width: 60%;
  height: 60%;
}
/* RTE-Wrap-Safety-Net (Render-Mode only): TipTap/ProseMirror wickelt
 * Inline-Text beim Edit in <p>...</p> (Block-Node-Pflicht im Schema).
 * Im Render-Mode soll der <p>-Wrapper das Mini-Layout NICHT stoeren —
 * display:contents macht ihn layout-transparent, der Inhalt rendert
 * direkt als waere er Kind des icontext-Spans.
 *
 * WICHTIG: nur wenn KEIN aktiver Edit (data-tiptap-loading-Attribut
 * fehlt). Waehrend des Edits ist das <p> der Block-Container fuer
 * ProseMirror's Cursor; macht man's contents-only, verliert der
 * Cursor seine Box und Typing/Delete verhalten sich seltsam
 * (beobachtet: "1" loeschen → "3" tippen → nichts uebernommen). */
.mypage [type="icontext"]:not([data-tiptap-loading]) p {
  display: contents;
}

/* ─── Social Pills ───────────────────────────────────────────────────
 * Shared Pill-Style fuer Brand-Anchors (Facebook/Instagram/LinkedIn/…)
 * in Footer-Patterns. Loest pattern-spezifische Duplikate ab
 * (fe-social-btn, fn-social-link, …). Inhalt: <svg> Brand-Icon +
 * <span> Label, optional Label per Modifier --icon-only ausblendbar.
 *
 * Erwartete DOM-Struktur:
 *   <a class="social-pill" href="…">
 *     <svg …>brand-icon</svg>
 *     <span>Facebook</span>
 *   </a>
 *
 * Wrapping-Container kriegt typischerweise display:flex + gap:0.5rem
 * vom Pattern-CSS (z.B. .fe-social-row). Hier wird nur das Pill
 * selbst gestylt, nicht der Container.
 *
 * Variants:
 *   .social-pill--icon-only   Label visuell weg, square padding
 *   .social-pill--dark        Dark-Bg Variante (sc-dark Kontext)
 */
.mypage .social-pill {
  display: inline-flex;
  align-items: center;
  gap: 0.4rem;
  padding: 0.4rem 0.75rem;
  background: color-mix(in srgb, var(--shade-dark-base) 8%, transparent);
  border-radius: 999px;
  font-size: 0.85rem;
  line-height: 1;
  /* text-decoration ohne Flag (Stufe 4c, Rest, 2026-07-30): `.mypage a`
   * (em-base.css) setzt underline mit (0,1,1) — `.mypage .social-pill`
   * ist (0,2,0), schlaegt es outright (b-Stelle 2 > 1 entscheidet vor der
   * c-Stelle). */
  text-decoration: none;
  color: inherit;
  transition: background 120ms ease, transform 120ms ease;
}
.mypage .social-pill:hover {
  background: color-mix(in srgb, var(--shade-dark-base) 18%, transparent);
}
.mypage .social-pill svg {
  flex-shrink: 0;
  /* Icon-Groesse: 1.1em relativ zur pill-font-size. Mit reset wenn das
   * Pattern selbst eine andere svg-Groesse vorgibt — !important wird
   * bewusst vermieden. Pattern-CSS kann ueberschreiben. */
  width: 1.1em;
  height: 1.1em;
}
/* Icon-only: span ist visuell weg (display:none statt visibility:hidden
 * um Padding nicht zu reservieren); padding wird square. Screenreader
 * lesen das span trotzdem nicht — daher braucht der <a> ein aria-label
 * vom Pattern-Autor. */
.mypage .social-pill.social-pill--icon-only {
  padding: 0.5rem;
  aspect-ratio: 1 / 1;
  justify-content: center;
}
.mypage .social-pill.social-pill--icon-only span {
  display: none;
}
/* Dark-Variante fuer dark Footer-Sections (sc-dark/glass-dark): heller
 * Glas-Hintergrund statt dunkler. */
.mypage .social-pill.social-pill--dark,
.mypage .sc-dark .social-pill {
  background: color-mix(in srgb, var(--text-light) 10%, transparent);
  color: var(--text-light);
}
.mypage .social-pill.social-pill--dark:hover,
.mypage .sc-dark .social-pill:hover {
  background: color-mix(in srgb, var(--text-light) 20%, transparent);
}

/* ─── Card Base ─── */
.mypage .molecule {
  transition: transform 0.2s ease;
}

/* ─── Section Header Block ─── */
.mypage .eb-header-block {
  text-align: center;
  margin-bottom: var(--space-lg);
}

.mypage .eb-header-block .eyebrow {
  margin-bottom: var(--space-sm);
}

.mypage .eb-header-block .h3 {
  max-width: 700px;
  margin-left: auto;
  margin-right: auto;
}

/* ─── Flex Grid: equal-height columns ─── */
/* The EmPatterns ua-* system uses inline-block + max-width for columns.
 * For equal-height cards we need flex. The :has() selector targets only
 * rows that actually contain sub-columns (col-1…col-11 — every width
 * that isn't full-bleed col-12), leaving full-width rows untouched.
 *
 * :has() is enumerated explicitly per class because [class*="col-0"]
 * substring-matching misses col-10/11 and would also fire for col-12
 * children (false positive → full-width rows would become flex rows
 * and break their vertical stacking). */

/* 1. Row becomes flex only when it contains fractional columns.
 * Includes both section[type='layer'] (layer key) and div[type='rich']
 * (html key) — patterns may use html nodes directly as flex columns. */
.mypage section[type='layer'].col-12:has(
  > section[type='layer'].col-1,  > div[type='rich'].col-1,
  > section[type='layer'].col-2,  > div[type='rich'].col-2,
  > section[type='layer'].col-3,  > div[type='rich'].col-3,
  > section[type='layer'].col-4,  > div[type='rich'].col-4,
  > section[type='layer'].col-5,  > div[type='rich'].col-5,
  > section[type='layer'].col-6,  > div[type='rich'].col-6,
  > section[type='layer'].col-7,  > div[type='rich'].col-7,
  > section[type='layer'].col-8,  > div[type='rich'].col-8,
  > section[type='layer'].col-9,  > div[type='rich'].col-9,
  > section[type='layer'].col-10, > div[type='rich'].col-10,
  > section[type='layer'].col-11, > div[type='rich'].col-11
) {
  display: flex !important;
  flex-wrap: wrap;
  align-items: stretch;
}

/* 2. Column widths — flex needs explicit width, max-width alone is not enough.
 * Applies to both section[type='layer'] (layer key) and div[type='rich'] (html
 * key) children — patterns sometimes use html nodes as flex-row columns. */
/* 2. Column widths — gap-aware via --grid-gap Custom Property.
 * gap-N Utility-Klassen setzen --grid-gap auf den Container,
 * die col-N Kinder ziehen ihren Anteil automatisch ab. */
.mypage section[type='layer'].col-12 > section[type='layer'].col-1,
.mypage section[type='layer'].col-12 > div[type='rich'].col-1 { width: calc( 8.333% - var(--grid-gap,0px) * 11/12); }
.mypage section[type='layer'].col-12 > section[type='layer'].col-2,
.mypage section[type='layer'].col-12 > div[type='rich'].col-2 { width: calc(16.666% - var(--grid-gap,0px) * 10/12); }
.mypage section[type='layer'].col-12 > section[type='layer'].col-3,
.mypage section[type='layer'].col-12 > div[type='rich'].col-3 { width: calc(25.000% - var(--grid-gap,0px) *  9/12); }
.mypage section[type='layer'].col-12 > section[type='layer'].col-4,
.mypage section[type='layer'].col-12 > div[type='rich'].col-4 { width: calc(33.333% - var(--grid-gap,0px) *  8/12); }
.mypage section[type='layer'].col-12 > section[type='layer'].col-5,
.mypage section[type='layer'].col-12 > div[type='rich'].col-5 { width: calc(41.666% - var(--grid-gap,0px) *  7/12); }
.mypage section[type='layer'].col-12 > section[type='layer'].col-6,
.mypage section[type='layer'].col-12 > div[type='rich'].col-6 { width: calc(50.000% - var(--grid-gap,0px) *  6/12); }
.mypage section[type='layer'].col-12 > section[type='layer'].col-7,
.mypage section[type='layer'].col-12 > div[type='rich'].col-7 { width: calc(58.333% - var(--grid-gap,0px) *  5/12); }
.mypage section[type='layer'].col-12 > section[type='layer'].col-8,
.mypage section[type='layer'].col-12 > div[type='rich'].col-8 { width: calc(66.666% - var(--grid-gap,0px) *  4/12); }
.mypage section[type='layer'].col-12 > section[type='layer'].col-9,
.mypage section[type='layer'].col-12 > div[type='rich'].col-9 { width: calc(75.000% - var(--grid-gap,0px) *  3/12); }
.mypage section[type='layer'].col-12 > section[type='layer'].col-10,
.mypage section[type='layer'].col-12 > div[type='rich'].col-10 { width: calc(83.333% - var(--grid-gap,0px) *  2/12); }
.mypage section[type='layer'].col-12 > section[type='layer'].col-11,
.mypage section[type='layer'].col-12 > div[type='rich'].col-11 { width: 91.666%; }  /* 11/12 */

/* 3. Columns (col-1..col-11) inside a flex-row: flex-column so molecules stretch.
 * Explizit nur col-1..col-11 als Target — col-12 Kinder (z.B. featured-article col-12
 * das selbst ein 9/3-Grid enthält) dürfen NICHT flex-column bekommen. */
.mypage section[type='layer'].col-12:has(> section[type='layer'].col-1,  > div[type='rich'].col-1 ) > section[type='layer'].col-1,
.mypage section[type='layer'].col-12:has(> section[type='layer'].col-2,  > div[type='rich'].col-2 ) > section[type='layer'].col-2,
.mypage section[type='layer'].col-12:has(> section[type='layer'].col-3,  > div[type='rich'].col-3 ) > section[type='layer'].col-3,
.mypage section[type='layer'].col-12:has(> section[type='layer'].col-4,  > div[type='rich'].col-4 ) > section[type='layer'].col-4,
.mypage section[type='layer'].col-12:has(> section[type='layer'].col-5,  > div[type='rich'].col-5 ) > section[type='layer'].col-5,
.mypage section[type='layer'].col-12:has(> section[type='layer'].col-6,  > div[type='rich'].col-6 ) > section[type='layer'].col-6,
.mypage section[type='layer'].col-12:has(> section[type='layer'].col-7,  > div[type='rich'].col-7 ) > section[type='layer'].col-7,
.mypage section[type='layer'].col-12:has(> section[type='layer'].col-8,  > div[type='rich'].col-8 ) > section[type='layer'].col-8,
.mypage section[type='layer'].col-12:has(> section[type='layer'].col-9,  > div[type='rich'].col-9 ) > section[type='layer'].col-9,
.mypage section[type='layer'].col-12:has(> section[type='layer'].col-10, > div[type='rich'].col-10) > section[type='layer'].col-10,
.mypage section[type='layer'].col-12:has(> section[type='layer'].col-11, > div[type='rich'].col-11) > section[type='layer'].col-11 {
  display: flex !important;
  flex-direction: column;
}

/* 4. Molecules fill their column and use flex-column for internal layout */
.mypage section[type='layer'].col-12:has(
  > section[type='layer'].col-1,
  > section[type='layer'].col-2,
  > section[type='layer'].col-3,
  > section[type='layer'].col-4,
  > section[type='layer'].col-5,
  > section[type='layer'].col-6,
  > section[type='layer'].col-7,
  > section[type='layer'].col-8,
  > section[type='layer'].col-9,
  > section[type='layer'].col-10,
  > section[type='layer'].col-11
) > section[type='layer'] > .molecule {
  flex: 1;
  display: flex !important;
  flex-direction: column;
}

/* 4b. AUSNAHME: header-nav bleibt WAAGRECHT, auch in der Spalte einer
 * Mehrspalter-Reihe.
 *
 * Regel 4 dreht jede Molecule in einer col-N-Spalte auf `flex-direction:
 * column`. Fuer Inhalts-Molecules ist das richtig (Bild ueber Text), fuer die
 * Navigation ist es falsch — und der Fehler sah nicht wie ein
 * flex-direction-Fehler aus (gemessen am DOM, 2026-08-11):
 *
 *   head_simple: Molecule 868px breit, rechte Kante genau auf der rechten
 *   Hilfslinie, `justify-content: flex-end` berechnet — und der 278px breite
 *   Menue-Slot stand trotzdem 295px VOR der Kante, also exakt mittig
 *   ((868-278)/2 = 295). `justify-content` per Inline-Flag umzustellen
 *   bewegte ihn um NULL Pixel, `margin-left: auto` dagegen sofort an die
 *   Kante. Ursache: in der Spalte ist die Hauptachse SENKRECHT, dort steuert
 *   `justify-content` also die Hoehe; waagrecht entschied `align-items:
 *   center` aus der Molecule. Dieselbe Achsen-Falle, die Abschnitt „col-N und
 *   justify-content" weiter unten beschreibt.
 *
 * Nur `flex-direction` wird zurueckgedreht — `flex: 1` bleibt erwuenscht,
 * damit die Molecule die Spalte ausfuellt und `flex-end` die rechte
 * Spaltenkante ueberhaupt erreichen kann.
 */
.mypage section[type='layer'].col-12:has(
  > section[type='layer'].col-1,
  > section[type='layer'].col-2,
  > section[type='layer'].col-3,
  > section[type='layer'].col-4,
  > section[type='layer'].col-5,
  > section[type='layer'].col-6,
  > section[type='layer'].col-7,
  > section[type='layer'].col-8,
  > section[type='layer'].col-9,
  > section[type='layer'].col-10,
  > section[type='layer'].col-11
) > section[type='layer'] > .molecule.header-nav,
.mypage section[type='layer'].col-12:has(
  > section[type='layer'].col-1,
  > section[type='layer'].col-2,
  > section[type='layer'].col-3,
  > section[type='layer'].col-4,
  > section[type='layer'].col-5,
  > section[type='layer'].col-6,
  > section[type='layer'].col-7,
  > section[type='layer'].col-8,
  > section[type='layer'].col-9,
  > section[type='layer'].col-10,
  > section[type='layer'].col-11
) > section[type='layer'] > .molecule.social-strip {
  flex-direction: row;
}

/* 5. Inside molecules: children are block, not inline-block
 *
 * Zweck: render-struct.css gibt JEDEM `section[type="layer"]` ein
 * `display: inline-block` — innerhalb einer Molecule ist das falsch, dort
 * sollen die Kinder untereinander stehen. Diese Regel korrigiert das.
 *
 * `!important` ENTFERNT (Stufe 4, Batch 4e, 2026-08-07 — Entscheidung des
 * Users nach vorgelegter Messung). Fuer den eigentlichen Zweck war das Flag
 * nie noetig: gegen render-struct (0,2,1) gewinnt dieser Selektor (0,3,1)
 * allein per Spezifitaet.
 *
 * Das Flag hat stattdessen 35 von 64 erfassten Elementen ueberfahren, deren
 * Molecule bzw. Pattern bewusst ein Flex-Layout deklariert — alle mit (0,4,0),
 * also spezifischer als diese Regel, aber gegen ein !important machtlos.
 * Am DOM durchgerechnet und per injizierter Simulation verifiziert:
 *   13x .molecule.quote-card .quote-author      block -> flex
 *    7x .molecule.step-card .step-bubble        block -> flex
 *    6x .molecule.article-card .article-card-body  block -> flex
 *    4x .proc_arrows .step-card-h .step-bubble  block -> flex
 *    4x .proc_arrows_vertical .step-card-v .step-bubble  block -> flex
 *    1x .scene-trust-strip                      block -> inline-flex
 *                                               (gewinnt per eigenem Flag)
 * Sichtbar war davon nur die Attributions-Zeile der Quote-Card: Avatar und
 * Name standen untereinander statt nebeneinander (Hoehe 103 -> 64px). Die
 * 19 Step-Bubbles und der Trust-Strip aendern ihre Geometrie nicht — deren
 * display-Deklarationen sind faktisch wirkungslos.
 *
 * Wer hier wieder ein Flag setzt, erschlaegt diese Layouts erneut, und zwar
 * still. Wenn eine Molecule ihre Kinder als Block braucht, gehoert das in die
 * jeweilige molecule.css mit ausreichender Spezifitaet — nicht hier.
 * Beleg: tools/geometry-baseline-4e.json, Testseite /basisflag-check. */
.mypage .molecule > section[type='layer'] {
  display: block;
}

/* 6. Equal-height CARD grids via CSS-Grid — SCOPED (2026-07-17).
 * Model-B-gemergte Karten (col-N ist selbst .molecule/.card) equalisieren
 * unter flex align-stretch NICHT (der Merge brach den col-stretch + card:
 * flex-1 Chain; empirisch: price_3tiers 417/480/480). Grid-Zellen sind by
 * design gleich hoch. WICHTIG: nur auf Rows scopen, deren Fraktions-Spalten
 * KARTEN sind — NICHT global auf alle col-N-Rows (ein globaler Grid-Wechsel
 * legte zentrierte Einzelspalten/Headings linksbündig in die Tracks →
 * Flow-Bruch). Zentrierte Single-Cols, asymmetrische Text-Splits und
 * full-bleed bleiben so flex + zentriert.
 * Realistische Karten-Breiten: col-6 (2-Spalter), col-4 (3), col-3 (4),
 * col-2 (6). */
.mypage section[type='layer'].col-12:has(
  > section[type='layer'].col-2.molecule, > section[type='layer'].col-2.card,
  > section[type='layer'].col-3.molecule, > section[type='layer'].col-3.card,
  > section[type='layer'].col-4.molecule, > section[type='layer'].col-4.card,
  > section[type='layer'].col-6.molecule, > section[type='layer'].col-6.card
) {
  display: grid !important;
  grid-template-columns: repeat(12, 1fr);
  align-items: stretch;
}
/* In einer Karten-Grid-Row bestimmt die Grid-Area die Breite ALLER col-Kinder
 * (das flex-Modell-width:calc würde sie sonst schmaler machen → Sliver). */
.mypage section[type='layer'].col-12:has(
  > section[type='layer'].col-2.molecule, > section[type='layer'].col-2.card,
  > section[type='layer'].col-3.molecule, > section[type='layer'].col-3.card,
  > section[type='layer'].col-4.molecule, > section[type='layer'].col-4.card,
  > section[type='layer'].col-6.molecule, > section[type='layer'].col-6.card
) > section[type='layer'][class*='col-'] { width: auto !important; }
/* grid-column span pro col-N — GLOBAL: in flex-Rows inert (flex ignoriert
 * grid-column), in den Grid-Rows oben aktiv. Sichert, dass JEDES col-N-Kind
 * (auch ein col-12-Header, der die Row mit Karten teilt) korrekt spannt statt
 * auf einen Track zu kollabieren. */
.mypage section[type='layer'].col-12 > section[type='layer'].col-1  { grid-column: span 1; }
.mypage section[type='layer'].col-12 > section[type='layer'].col-2  { grid-column: span 2; }
.mypage section[type='layer'].col-12 > section[type='layer'].col-3  { grid-column: span 3; }
.mypage section[type='layer'].col-12 > section[type='layer'].col-4  { grid-column: span 4; }
.mypage section[type='layer'].col-12 > section[type='layer'].col-5  { grid-column: span 5; }
.mypage section[type='layer'].col-12 > section[type='layer'].col-6  { grid-column: span 6; }
.mypage section[type='layer'].col-12 > section[type='layer'].col-7  { grid-column: span 7; }
.mypage section[type='layer'].col-12 > section[type='layer'].col-8  { grid-column: span 8; }
.mypage section[type='layer'].col-12 > section[type='layer'].col-9  { grid-column: span 9; }
.mypage section[type='layer'].col-12 > section[type='layer'].col-10 { grid-column: span 10; }
.mypage section[type='layer'].col-12 > section[type='layer'].col-11 { grid-column: span 11; }
.mypage section[type='layer'].col-12 > section[type='layer'].col-12 { grid-column: span 12; }

/* ─── Default Spalten-Padding fuer col-N innerhalb max-w ──────────────────
 * Konsequente "px-2 ueberall"-Mechanik: jede Spalte in einem max-w-Wrapper
 * bekommt 1rem horizontale Innenabstand. Kombiniert mit dem px-2 auf dem
 * max-w-Wrapper selbst gibt das:
 *
 *   • Spalte → Viewport-Rand: maxW px-2 + col px-2 = 4u (symmetrisch)
 *   • Spalte → Spalte: col-px-2 + col-px-2 = 4u (symmetrisch)
 *
 * col-12 ist ausgeschlossen — der ist ein Full-Width-Passthrough und
 * braucht kein Innenabstand. Author kann das Default pro Spalte via
 * inline-Klasse (px-1 / px-4 etc.) ueberschreiben.
 *
 * Greift auch eine Ebene tiefer (max-w > col-12 > col-N) — verbreitete
 * Footer-Struktur: max-w enthaelt einen col-12-Row-Wrapper, in dem die
 * col-N-Cells sitzen. */
/* `:not([class*='gap-'])` an der Reihe (2026-08-10): traegt sie eine
 * gap-Klasse, gilt Modell B und dieser Gutter darf gar nicht erst greifen.
 * Wichtig ist, dass die Unterscheidung HIER passiert und nicht als
 * Gegenregel am Kind: ein `padding: 0` am col-N traf auch Karten, die SELBST
 * das col-N-Element sind — dort ist das Padding nicht der Layout-Gutter,
 * sondern der Innenabstand der Karte aus `.card` bzw. der Molecule. Gemessen
 * hatten 39 Spalten in 13 Patterns dadurch keinen Innenabstand mehr
 * (quote-card, pricing-card, step-card, stat-item, story-card, team-card).
 * Eine Regel, die nur nicht zutrifft, kann nichts kaputtmachen. */
.mypage .max-w:not([class*='gap-']) > section[type='layer'][class*='col-']:not(.col-12),
.mypage .max-w:not([class*='gap-']) > div[type='rich'][class*='col-']:not(.col-12),
.mypage .max-w > section[type='layer'].col-12:not([class*='gap-']) > section[type='layer'][class*='col-']:not(.col-12),
.mypage .max-w > section[type='layer'].col-12:not([class*='gap-']) > div[type='rich'][class*='col-']:not(.col-12) {
  padding-left: 1rem;
  padding-right: 1rem;
}

/* ─── Modell A und Modell B duerfen sich nicht addieren (2026-08-10) ──────
 * Die Regel darueber ist Modell A: der Spaltenabstand steckt im Padding der
 * Spalten. Der Editor arbeitet aber nach Modell B — Kommentar in
 * EmPages FE/src/components/editor/InlineEditor.jsx:2222: „Abstand zwischen
 * Karten/Spalten = Row-`gap`, NICHT Spalten-Padding". Er setzt dafuer
 * `gap-N` auf die Reihe und strippt `px-/pl-/pr-` von der Spalte.
 *
 * Solange beide Modelle gleichzeitig greifen, addieren sie sich, und das
 * Gap-Control im Inspector luegt ueber seine eigenen Werte: gemessen ergab
 * `gap-4` nicht 32px, sondern 64px. Ueber 49 Spaltenzeilen der
 * All-Pattern-Seite kamen so sieben verschiedene Abstaende zwischen 16 und
 * 96px zustande, ohne dass je einer davon entschieden worden waere.
 *
 * Die Unterscheidung sitzt deshalb IM Gutter-Selektor oben
 * (`:not([class*='gap-'])`) und nicht als Gegenregel am Kind. Der erste
 * Versuch war ein `padding: 0` am col-N — der traf auch Karten, die selbst
 * das col-N-Element sind, und nahm ihnen ihren Innenabstand (39 Spalten in
 * 13 Patterns). Eine Regel, die schlicht nicht zutrifft, hat dieses Problem
 * nicht.
 *
 * Was bleibt: der AUSSENabstand. In Modell B haelt ihn die Reihe — das ist
 * die Aufgabe des Ausrichtungs-Containers, das `gap` haelt nur den
 * Zwischenraum. Ueber die Haelfte der Reihen bringt ihn als `px-2` mit; die
 * uebrigen bekommen ihn hier, damit er nicht davon abhaengt, ob ein Template
 * daran gedacht hat. Ein `px-N` an der Reihe gewinnt weiter (Utility,
 * !important) — inklusive `px-0` fuer bewusst randlose Reihen. */
.mypage section[type='layer'].max-w[class*='gap-'] {
  padding-left: 1rem;
  padding-right: 1rem;
}

/* 6. Push last semantic element to bottom in card-like molecules */
.mypage .molecule > section[type='layer'].quote-author,
.mypage .molecule > section[type='layer'].footer-copyright,
.mypage .molecule > section[type='layer'].profile-links {
  margin-top: auto;
}

/* ─── Grid Row Enhancements ─── */
.mypage .eb-row {
  display: flex;
  flex-wrap: wrap;
  gap: var(--space-md);
  align-items: stretch;
}

.mypage .eb-row > .eb-col {
  flex: 1;
  min-width: 0;
}

/* Responsive: stack on mobile */
@media (max-width: 768px) {
  .mypage .eb-row {
    flex-direction: column;
  }
  .mypage .eb-row > .eb-col {
    /* Ohne `!important` (Stufe 4, Batch 4e, 2026-08-09): am DOM gemessen auf
     * /basisregeln-check, 552px vor wie nach dem Entflaggen — kein
     * Gegenspieler. Randnotiz: das zugehoerige `.eb-row { display: flex }`
     * injiziert nur der Compose-Preview-Endpunkt (renderer/server.go), nicht
     * der Seiten-Render; im Seiten-Kontext sind die Spalten also ohnehin
     * Bloecke und damit von Haus aus 100% breit. */
    width: 100%;
    flex: none;
  }
}

/* ─── MaxW Container ─── */
/* NOTE: Primary .max-w rule lives in em-base.css (display:block + var(--max-w)).
 * Earlier this block redeclared max-width:1280px and silently dropped the
 * display:block, leaving section[type='layer'].max-w as inline-block — and
 * inline-blocks ignore margin:auto centering.
 *
 * Specificity issue: render-struct.css declares
 *   `.mypage section[type='layer'] { display: inline-block; }`
 * which has higher specificity (0,2,1) than a bare `.mypage .max-w` (0,2,0).
 * To reliably win for section[type='layer'].max-w (which is the typical case
 * inside patterns), the override must match the same selector shape. */
.mypage section[type='layer'].max-w,
.mypage section[type='teaser'].max-w,
.mypage section[type='slider'].max-w,
.mypage section[type='squeeze'].max-w,
.mypage .max-w {
  display: block;
}

/* ─── Image defaults ─── */
.mypage img {
  max-width: 100%;
  height: auto;
}

/* ─── Icon base ─── Inline-SVG.
 * Default: Primärfarbe (Markenkonsistenz out-of-the-box).
 * Ausnahmen: Icons in Buttons erben white, Icons in sc-dark erben primary-light.
 * Sizing via modifier classes. */
.mypage .icon {
  display: inline-block;
  width: 1.5rem;
  height: 1.5rem;
  vertical-align: -0.15em;
  /* --icon-color (Projekt-Default oder per-Element-Override) gewinnt; unset =
   * kontext-sichere Akzentfarbe wie bisher (WCAG-AA ≥4.5:1, Task 7). */
  fill:  var(--icon-color, var(--accent-on-light, var(--primary-base)));
  color: var(--icon-color, var(--accent-on-light, var(--primary-base)));
  flex-shrink: 0;
}
/* sc-dark/sc-sec: dunkler Hintergrund → accent-on-dark ≥4.5:1 (Task 7) */
.mypage .sc-dark .icon,
.mypage .sc-sec  .icon {
  fill:  var(--icon-color, var(--accent-on-dark, var(--primary-light)));
  color: var(--icon-color, var(--accent-on-dark, var(--primary-light)));
}
/* sc-pri/sc-acc: brand-farbiger Hintergrund → on-primary-text = weiß (Task 7) */
.mypage .sc-pri .icon,
.mypage .sc-acc .icon {
  fill:  var(--icon-color, var(--on-primary-text, #fff));
  color: var(--icon-color, var(--on-primary-text, #fff));
}
/* In Buttons und Link-Elementen: Textfarbe des Buttons erben */
.mypage .btn-wrap .icon,
.mypage a .icon {
  fill:  currentColor;
  color: currentColor;
}
.mypage .icon.xs  { width: 0.875rem; height: 0.875rem; }
.mypage .icon.sm  { width: 1rem;     height: 1rem; }
.mypage .icon.md  { width: 1.5rem;   height: 1.5rem; }
.mypage .icon.lg  { width: 2rem;     height: 2rem; }
.mypage .icon.xl  { width: 3rem;     height: 3rem; }
.mypage .icon.xxl { width: 4rem;     height: 4rem; }

/* Some SVG sources (logos.json) hardcode fill on children — when the
 * author wants the inherited theme color, opt in via .icon.themed. */
.mypage .icon.themed * { fill: currentColor; }

/* ─── Navigation ─── */
.mypage .em-nav {
  display: flex;
  align-items: center;
  gap: 1.5rem;
  font-family: var(--font-family);
  font-size: var(--font-small, 0.875rem);
  font-weight: 500;
}
.mypage .em-nav a {
  color: inherit;
  text-decoration: none;
  padding: 0.5rem 0;
  border-bottom: 2px solid transparent;
  transition: border-color 0.2s, color 0.2s;
}
.mypage .em-nav a:hover,
.mypage .em-nav a.active {
  border-bottom-color: var(--accent-on-light, var(--primary-base));   /* WCAG-AA ≥4.5:1 (Task 7) */
  color: var(--accent-on-light, var(--primary-base));
}
.mypage .em-nav .nav-item {
  position: relative;
}
.mypage .em-nav .nav-sub {
  display: none;
  position: absolute;
  top: 100%;
  left: 0;
  background: var(--bg-white, #fff);
  box-shadow: 0 4px 12px rgba(0,0,0,0.1);
  border-radius: var(--radius-md);
  padding: 0.5rem 0;
  min-width: 180px;
  z-index: 100;
  flex-direction: column;
}
.mypage .em-nav .nav-item:hover > .nav-sub {
  display: flex;
}
.mypage .em-nav .nav-sub a {
  padding: 0.5rem 1.25rem;
  border-bottom: none;
}
.mypage .em-nav .nav-sub a:hover {
  background: var(--bg-light, #f7f9fc);
}
.mypage .em-nav-header {
  padding: 1rem 2rem;
  justify-content: center;
}
.mypage .em-nav-footer {
  padding: 1.5rem 2rem;
  justify-content: center;
  opacity: 0.7;
  font-size: 0.8125rem;
}
.mypage .em-nav-sidebar {
  flex-direction: column;
  align-items: flex-start;
  padding: 1rem 0;
  gap: 0.25rem;
}
.mypage .em-nav-sidebar a {
  padding: 0.4rem 1rem;
  border-bottom: none;
  border-left: 2px solid transparent;
  width: 100%;
}
.mypage .em-nav-sidebar a:hover,
.mypage .em-nav-sidebar a.active {
  border-left-color: var(--primary-base);
  border-bottom: none;
  background: var(--bg-light, #f7f9fc);
}

@media (max-width: 768px) {
  .mypage .em-nav {
    flex-wrap: wrap;
    gap: 0.75rem;
    justify-content: center;
  }
  .mypage .em-nav-header {
    padding: 0.75rem 1rem;
  }
}

/* ─── Responsive Breakpoints ────────────────────────────────────────
 *
 * Kanonisches 3-Zonen-System (siehe TEMPL_MASTER.md § Responsive):
 *
 *   Mobile             ≤ 640px    (iPhone bis Plus/Max, kleine Android)
 *   Tablet Portrait    641–1023px (iPad Mini/Air/Pro 11" portrait)
 *   Desktop            ≥ 1024px   (iPad Pro 13" portrait, alle Tablet-
 *                                  Landscapes, alle Desktops)
 *
 * Begründung: Tablet-Portrait braucht eine eigene Zone, weil 768–1023px
 * Multi-Column-Layouts erlaubt (kein vertikales Stacking nötig), aber
 * schmale Spalten (col-3 = 200px) zu eng werden für Body-Text. Tablet-
 * Landscape ist ≥1024px und verhält sich wie Desktop.
 * ──────────────────────────────────────────────────────────────────── */

/* ── Tablet Portrait: 641–1023px — kompaktiere schmale Spalten ─────
 * col-1..col-5 widen damit Icon-Companions + Karten lesbar bleiben.
 * col-6..col-11 behalten ihre Desktop-Proportionen — bei einer 50/50
 * Aufteilung haben die Hälften ~400px, was als Tablet-Portrait OK ist. */
@media (min-width: 641px) and (max-width: 1023px) {
  .mypage section[type='layer'].col-12 > section[type='layer'].col-1,
  .mypage section[type='layer'].col-12 > div[type='rich'].col-1 { width: 16.666%; }
  .mypage section[type='layer'].col-12 > section[type='layer'].col-2,
  .mypage section[type='layer'].col-12 > div[type='rich'].col-2 { width: 25.000%; }
  .mypage section[type='layer'].col-12 > section[type='layer'].col-3,
  .mypage section[type='layer'].col-12 > div[type='rich'].col-3 { width: 50.000%; }
  .mypage section[type='layer'].col-12 > section[type='layer'].col-4,
  .mypage section[type='layer'].col-12 > div[type='rich'].col-4 { width: 50.000%; }
  .mypage section[type='layer'].col-12 > section[type='layer'].col-5,
  .mypage section[type='layer'].col-12 > div[type='rich'].col-5 { width: 50.000%; }

  /* Sanft kompaktere Type-Skala in dieser Zone */
  .mypage { --type-scale: 1.15; }
}

/* ── Mobile: ≤ 640px — alle Spalten stacken vertikal ─────────────── */
@media (max-width: 640px) {
  .mypage section[type='layer'].col-12:has(
    > section[type='layer'].col-1,
    > section[type='layer'].col-2,
    > section[type='layer'].col-3,
    > section[type='layer'].col-4,
    > section[type='layer'].col-5,
    > section[type='layer'].col-6,
    > section[type='layer'].col-7,
    > section[type='layer'].col-8,
    > section[type='layer'].col-9,
    > section[type='layer'].col-10,
    > section[type='layer'].col-11
  ) {
    flex-direction: column;
  }
  .mypage section[type='layer'].col-12 > section[type='layer'].col-1,
  .mypage section[type='layer'].col-12 > div[type='rich'].col-1,
  .mypage section[type='layer'].col-12 > section[type='layer'].col-2,
  .mypage section[type='layer'].col-12 > div[type='rich'].col-2,
  .mypage section[type='layer'].col-12 > section[type='layer'].col-3,
  .mypage section[type='layer'].col-12 > div[type='rich'].col-3,
  .mypage section[type='layer'].col-12 > section[type='layer'].col-4,
  .mypage section[type='layer'].col-12 > div[type='rich'].col-4,
  .mypage section[type='layer'].col-12 > section[type='layer'].col-5,
  .mypage section[type='layer'].col-12 > div[type='rich'].col-5,
  .mypage section[type='layer'].col-12 > section[type='layer'].col-6,
  .mypage section[type='layer'].col-12 > div[type='rich'].col-6,
  .mypage section[type='layer'].col-12 > section[type='layer'].col-7,
  .mypage section[type='layer'].col-12 > div[type='rich'].col-7,
  .mypage section[type='layer'].col-12 > section[type='layer'].col-8,
  .mypage section[type='layer'].col-12 > div[type='rich'].col-8,
  .mypage section[type='layer'].col-12 > section[type='layer'].col-9,
  .mypage section[type='layer'].col-12 > div[type='rich'].col-9,
  .mypage section[type='layer'].col-12 > section[type='layer'].col-10,
  .mypage section[type='layer'].col-12 > div[type='rich'].col-10,
  .mypage section[type='layer'].col-12 > section[type='layer'].col-11,
  .mypage section[type='layer'].col-12 > div[type='rich'].col-11 {
    width: 100%;
  }

  /* Section-Padding reduzieren auf Mobile */
  .pt-3 { padding-top:    calc(2 * var(--paddingT)) !important; }
  .pb-3 { padding-bottom: calc(2 * var(--paddingB)) !important; }
  .pl-3 { padding-left:   calc(1.5 * var(--paddingL)) !important; }
  .pr-3 { padding-right:  calc(1.5 * var(--paddingR)) !important; }

  /* Engste Type-Skala — Reading-Flow vor dramatischer Hierarchie. */
  .mypage { --type-scale: 1.1; }

  /* MaxW: Seitenpadding damit Content nicht den Viewport-Rand berührt */
  .mypage .max-w {
    padding-left: 1rem;
    padding-right: 1rem;
  }

  /* Buttons etwas kompakter für Daumen-Reach + 44×44 Apple-HIG-Minimum */
  .mypage .btn-wrap {
    padding: 0.75rem 1.25rem;
    font-size: 0.9375rem;
  }
  .mypage .btn-wrap p,
  .mypage .btn-wrap span,
  .mypage .btn-wrap div {
    padding: 0.75rem 1.25rem;
    font-size: 0.9375rem;
  }
}

/* ─── Smooth section transitions ─── */
.mypage section[type="layer"] {
  position: relative;
}


/* ═══════════════════════════════════════════════════════════════════════
 * Tier-1 Utility-Layer (2026-05-06)
 * ═══════════════════════════════════════════════════════════════════════
 *
 * Block-set für kreative Section-Komposition. Drei Themen-Bündel:
 *
 *   1. dt-* (Desktop-only Position / Z-Index / Negativ-Margin / Bleed) —
 *      lässt Coach + Author Layer-Komp bauen die ÜBER die Grid-Grenzen
 *      hinausragen, ohne Mobile zu zerschießen. Mobile (<1024px)
 *      neutralisiert alle dt-* Klassen: position:static, kein neg
 *      margin, kein bleed.
 *
 *   2. Stoff-Klassen — Cards, Inline-Decos, Deco-Typo, Img-Overlay,
 *      Edge-/Float — Patterns aus realen Hero-Mockups (2026-05-06
 *      Audit: Med+Med, xBlend, Awwwards, HappyRobot, Lewis, AVTL,
 *      Maben, Ditto). Jede ist atomar genug um in Komposition mit
 *      dt-* zu funktionieren.
 *
 *   3. Animation-Library — kuratierte ~20 Animista-Style @keyframes
 *      mit Delay/Duration Modifier, prefers-reduced-motion Guard,
 *      .dt-anim-* Variante für Desktop-only.
 * ─────────────────────────────────────────────────────────────────────── */


/* ─── 1. Desktop-only Positioning (.dt-*) ──────────────────────────────
 * Aktiv ab 1024px. Unter Desktop sind alle dt-* still — Mobile bleibt
 * sauber-linear. NIE auf Mobile Layout-Tricks angewiesen.
 */
@media (min-width: 1024px) {
  .dt-pos-rel { position: relative; }
  .dt-pos-abs { position: absolute; }

  .dt-z-back  { z-index: 0; }
  .dt-z-mid   { z-index: 1; }
  .dt-z-front { z-index: 2; }

  /* Eckanker für absolute Children. Brauchen einen .dt-pos-rel-Parent. */
  .dt-inset-tl     { top: 0;  left: 0; }
  .dt-inset-tr     { top: 0;  right: 0; }
  .dt-inset-bl     { bottom: 0; left: 0; }
  .dt-inset-br     { bottom: 0; right: 0; }
  .dt-inset-t      { top: 0;  left: 50%; transform: translateX(-50%); }
  .dt-inset-b      { bottom: 0; left: 50%; transform: translateX(-50%); }
  .dt-inset-l      { left: 0;  top: 50%; transform: translateY(-50%); }
  .dt-inset-r      { right: 0; top: 50%; transform: translateY(-50%); }
  .dt-inset-center { top: 50%; left: 50%; transform: translate(-50%,-50%); }
  .dt-inset-fill   { top: 0; right: 0; bottom: 0; left: 0; }

  /* Negativ-Margins — Element schiebt sich aus seinem Container */
  .dt-mt-neg-1 { margin-top: -1rem; }
  .dt-mt-neg-2 { margin-top: -2rem; }
  .dt-mt-neg-3 { margin-top: -3rem; }
  .dt-mt-neg-4 { margin-top: -4rem; }
  .dt-mb-neg-1 { margin-bottom: -1rem; }
  .dt-mb-neg-2 { margin-bottom: -2rem; }
  .dt-mb-neg-3 { margin-bottom: -3rem; }
  .dt-ml-neg-1 { margin-left: -1rem; }
  .dt-ml-neg-2 { margin-left: -2rem; }
  .dt-ml-neg-3 { margin-left: -3rem; }
  .dt-mr-neg-1 { margin-right: -1rem; }
  .dt-mr-neg-2 { margin-right: -2rem; }
  .dt-mr-neg-3 { margin-right: -3rem; }

  /* Bleed — Element bricht aus seiner max-w raus auf volle Viewport-Breite */
  .dt-bleed-l  { margin-left:  calc(50% - 50vw); }
  .dt-bleed-r  { margin-right: calc(50% - 50vw); }
  .dt-bleed-x  { margin-left:  calc(50% - 50vw); margin-right: calc(50% - 50vw); }

  /* Tilt / Skew als Deko-Modifier (sparsam!) */
  .dt-rotate-1  { transform: rotate( 1deg); }
  .dt-rotate-2  { transform: rotate( 2deg); }
  .dt-rotate-3  { transform: rotate( 3deg); }
  .dt-rotate-n1 { transform: rotate(-1deg); }
  .dt-rotate-n2 { transform: rotate(-2deg); }
  .dt-rotate-n3 { transform: rotate(-3deg); }
}

@media (max-width: 1023px) {
  /* Mobile-Reset: ALLE dt-* Klassen werden no-op. Layout linearisiert
   * automatisch in den ua-XX → 100% Stack.
   *
   * Bleibt (Stufe 4c, Gruppe A, 2026-07-30): dieser Reset MUSS jede dt-*
   * Positionierung/Rotation schlagen, egal wie spezifisch ein spaeter
   * geladenes Pattern dieselbe Klasse anspricht — sonst bricht das
   * Mobile-Linearisierungs-Versprechen ("nie Layout-Tricks auf Mobile").
   * Gilt fuer position (dt-pos-), transform (dt-inset-/dt-rotate-) und
   * margin (dt-mt/mb/ml/mr-neg-, dt-bleed-) gleichermassen. */
  [class*="dt-pos-"]   { position: static !important; }
  [class*="dt-inset-"] { top: auto !important; right: auto !important;
                          bottom: auto !important; left: auto !important;
                          transform: none !important; }
  [class*="dt-mt-neg-"], [class*="dt-mb-neg-"],
  [class*="dt-ml-neg-"], [class*="dt-mr-neg-"] { margin: 0 !important; }
  .dt-bleed-l, .dt-bleed-r, .dt-bleed-x { margin-left: 0 !important; margin-right: 0 !important; }
  [class*="dt-rotate-"] { transform: none !important; }
}


/* ─── 2. Card-Stoff (.card, .card-*) ───────────────────────────────────
 * Atomare Karten-Erscheinung. Kombinierbar mit:
 *   .glass-* / .glass-frosted (em-base.css) für Glasmorphismus
 *   dt-*                                     für Positionierung
 *   .card-rounded-xl / -2xl                  für runde Ecken
 *   .card-elev-sm / md / lg / xl             für Schattenstufen
 *   .card-border                             für 1px-Akzent-Border
 *
 * Glasmorphismus-Komposition (ersetzt das frühere .card-glass):
 *   class: "card glass-light glass-frosted card-rounded-xl card-border"
 *   class: "card glass-dark  glass-frosted card-rounded-xl"
 */
.card {
  background: var(--color-bg, #fff);
  /* Eigener Foreground, weil .card oft in einem .sc-dark/.sc-pri-Parent
     sitzt der currentColor auf weiß setzt → ohne diese Zeile weißer Text
     auf weißer Karte = unsichtbar. Wer eine dunkle Karte will, kombiniert
     .card mit .sc-dark/.glass-dark/.glass-smoke etc. (die setzen ihre
     eigene Farb-Pair). */
  color: var(--text-dark);
  border-radius: 8px;
  padding: 1.25rem 1.5rem;
  box-shadow: 0 1px 3px rgba(26,47,63,0.06);
  /* Cards sind Flex-Container: Inhalte stapeln vertikal mit konsistenter
     Verteilung, und beim Einbau in einen Grid-Row (col-12 → col-N →
     card) füllt die Karte dank flex:1 die ganze Zellenhöhe — Geschwister-
     Karten in einer Row landen damit automatisch auf gleicher Höhe. */
  display: flex;
  flex-direction: column;
  flex: 1;
}


/* Elevation/Schatten — T-Shirt-Skala (analog Tailwind shadow-{sm,md,lg,xl}).
   Vorgänger card-elev-1/2/3 → card-elev-sm/md/lg, neue xl für Hero-Cards. */
.card-elev-sm { box-shadow: 0 1px 3px rgba(26,47,63,0.06), 0 1px 2px rgba(26,47,63,0.04); }
.card-elev-md { box-shadow: 0 6px 18px rgba(26,47,63,0.10), 0 2px 6px rgba(26,47,63,0.06); }
.card-elev-lg { box-shadow: 0 18px 38px rgba(26,47,63,0.18), 0 6px 12px rgba(26,47,63,0.10); }
.card-elev-xl { box-shadow: 0 28px 60px rgba(26,47,63,0.22), 0 10px 20px rgba(26,47,63,0.12); }

/* 1px-Akzent-Border — meist nur sinnvoll in Kombination mit .glass-*,
   damit die Card vom Hintergrundbild abgehoben wird. */
.card-border       { border: 1px solid rgba(255,255,255,0.40); }
.card-border-dark  { border: 1px solid rgba(255,255,255,0.10); }

/* Selbst-adaptierende, IMMER sichtbare Kontur (Panel-v2 „Rahmen"-Achse).
   Anders als .card-border (weiß, nur auf Glas/Bild sinnvoll) leitet .card-line
   die Farbe aus currentColor ab: auf hellen Karten (color:var(--text-dark))
   ergibt das eine dezente dunkle Linie, auf dunklen/Glas-Karten (heller
   currentColor) eine dezente helle — eine Kontur, die überall funktioniert.
   Zwei Stärken = echte „Rahmen"-Einstellung (Fein/Kräftig). */
.card-line        { border: 1px solid color-mix(in srgb, currentColor 18%, transparent); }
.card-line-strong { border: 2px solid color-mix(in srgb, currentColor 30%, transparent); }


/* ─── 3. Inline-Decoration (.mark, .chip, .bracket) ─────
 * Visuelle Hervorhebung MITTEN im Text. <span class="…">Wort</span>
 * im html-Element. Marker-Highlight, Pill-Chip, Klammer-Annotation.
 */
.mark {
  background: linear-gradient(180deg, transparent 50%, var(--mark-bg, #fef08a) 50%);
  padding: 0 0.15em;
  border-radius: 2px;
  /* Als <mark>-Element (RTE-Highlight) sonst UA-Default color:MarkText (schwarz)
   * → Textfarbe des Kontexts erben, damit Marker auf hell UND dunkel stimmt. */
  color: inherit;
}
.mark-pri  { --mark-bg: rgba(74,158,255,0.30); }
.mark-acc  { --mark-bg: rgba(243,198,74,0.40); }
.mark-warn { --mark-bg: rgba(255,107,107,0.30); }

/* Voll-Stil: deckende Fläche statt Strich, Textfarbe kontrast-aware (--mark-fg,
 * vom RTE gesetzt), pro Zeile eigener Kasten (box-decoration-break). Muss NACH
 * .mark stehen (überschreibt dessen gradient-background + color:inherit). */
.mark--fill {
  background: var(--mark-bg, #fef08a);
  color: var(--mark-fg, #fff);
  padding: 0.08em 0.3em;
  border-radius: 3px;
  -webkit-box-decoration-break: clone;
  box-decoration-break: clone;
}

.chip,
.pill {
  display: inline-flex;
  /* `width: fit-content` schuetzt gegen Blockifizierung als Flex-Item
   * (2026-08-07, Batch 4e). Wird ein Pill direktes Kind eines Flex- oder
   * Grid-Containers, macht die Engine aus `inline-flex` ein `flex` — und
   * `align-items: normal` des Containers dehnt es dann auf die volle
   * Container-Breite. Gemessen an story_3cards und story_featured_3cards:
   * „Featured" 84px Inhalt auf 596px gedehnt, „Tutorial" 74 auf 392.
   * Aufgetreten, als das Basis-Flag an `.molecule > section[type=layer]`
   * fiel und `.article-card-body` dadurch endlich als Flex-Column lief.
   *
   * Warum fit-content und nicht `align-self: flex-start`: fit-content ist
   * richtungsneutral. In einem Column-Container verhindert es die Dehnung,
   * in einem Zeilen-Container ist es ein No-op (das Item ist dort ohnehin
   * inhaltsbreit). `align-self: flex-start` haette in einem Zeilen-Container
   * dagegen die VERTIKALE Ausrichtung gekapert und Pills nach oben gezogen,
   * statt sie zentriert zu lassen. Auf der QA-Seite steht heute kein Pill in
   * einem Zeilen-Container (gemessen: 0), aber die Regel soll auch fuer
   * kuenftige Patterns richtig sein.
   *
   * Verwandt: der Override fuer `div[type='rich'].pill` weiter unten faengt
   * denselben Effekt fuer RTE-Slots ab, dort per display statt Breite. */
  width: fit-content;
  align-items: center;
  gap: 0.3em;
  padding: 0.2em 0.7em;
  border-radius: 999px;
  background: var(--em-surface-hover, #eef0f3);
  color: var(--em-navy, #1a2f3f);
  font-size: 0.92em;
  font-weight: 600;
  vertical-align: baseline;
  white-space: nowrap;
  line-height: 1.4;
}

/* Pill/Chip in Card-Context: Card-Layouts stacken typischerweise
 * Image + Pill + Title vertikal — Pill braucht Bottom-Margin damit
 * der folgende Title nicht dranklebt. inline-block respektiert
 * vertikale Margins zuverlaessig (inline-flex tut das nicht).
 * Single-Source-of-Truth fuer alle .card .pill / .card .chip; vorher
 * mussten Pattern (story_featured_3cards) das per Local-Override
 * machen, story_3cards hat den Override vergessen → inkonsistente
 * Abstaende. */
.mypage .card .pill,
.mypage .card .chip {
  display: inline-block;
  margin: 0 0.35rem 0.5rem 0;
}
/* Farb-Varianten — Theme-aware (folgen --primary/--secondary/--contrast).
 * `chip-*` und `pill-*` sind Aliase: chip ist die etablierte Bezeichnung
 * (Header-Tag, Status-Indicator), pill betont die Form. RTE kann beide
 * über das class-Attribut auf <span> setzen.
 * Light-Suffix (-l) = Soft-Tint-Variante, Dark-Suffix nicht nötig
 * (die Base-Variante ist bereits kontrast-sicher mit text-light). */
.chip-pri,   .pill-pri   { background: var(--primary-base);    color: var(--text-light); }
.chip-pri-l, .pill-pri-l { background: var(--primary-light);   color: var(--text-dark);  }
.chip-sec,   .pill-sec   { background: var(--secondary-base);  color: var(--text-light); }
.chip-sec-l, .pill-sec-l { background: var(--secondary-light); color: var(--text-dark);  }
.chip-acc,   .pill-acc   { background: var(--contrast-base);   color: var(--text-dark);  }
.chip-acc-l, .pill-acc-l { background: var(--contrast-light);  color: var(--text-dark);  }
.chip-dark,  .pill-dark  { background: var(--shade-dark-base); color: var(--text-light); }
.chip-light, .pill-light { background: var(--shade-light-base);color: var(--text-dark);  }

/* Outline-Variante: transparenter BG + farbiger Rahmen + farbiger Text. */
.chip-outline,
.pill-outline {
  background: transparent;
  border: 1px solid currentColor;
}

/* render-struct.css setzt `.mypage div[type='rich'] { display: block }` mit
 * Spezifizität (0,2,1) — schlägt die Basis-`.pill { display: inline-flex }`
 * (0,1,0). Wenn ein html-Slot via Pattern-Klasse zum Pill wird (story_*-
 * eyebrows etc.), würde die Pill auf full-width aufgehen. Override mit
 * (0,3,1) erzwingt inline-flex zurück. */
.mypage div[type='rich'].pill,
.mypage div[type='rich'].chip {
  display: inline-flex;
}

/* Text-Color-Helpers — RTE-Inline-Akzent ohne style-Attribut.
 * Direkt an <span class="txt-pri"> verwendbar. Alias-Paare (pri/primary,
 * acc/accent) erlauben sowohl kurze als auch sprechende Klassennamen. */
.txt-pri,   .txt-primary    { color: var(--accent-on-light, var(--primary-base)); }   /* WCAG-AA ≥4.5:1 auf hellem BG (Task 7) */
.txt-pri-l, .txt-primary-l  { color: var(--primary-light); }
.txt-sec,   .txt-secondary  { color: var(--secondary-base); }
.txt-sec-l, .txt-secondary-l{ color: var(--secondary-light); }
.txt-acc,   .txt-accent     { color: var(--contrast-base); }
.txt-acc-l, .txt-accent-l   { color: var(--contrast-light); }
.txt-light, .txt-on-dark    { color: var(--text-light); }
.txt-dark,  .txt-on-light   { color: var(--text-dark);  }

.bracket {
  position: relative;
  padding: 0 0.4em;
}
.bracket::before { content: "[ "; opacity: 0.5; }
.bracket::after  { content: " ]"; opacity: 0.5; }


/* ─── 4. Decorative Typography (.deco-wordmark, .font-script, ...) ─────
 * Riesige Hintergrund-Wordmarks (Maben-MABEN-Style, Med+Med-Med+Med),
 * Script-Font für editorialische Akzent-Linien (Lewis-Style),
 * Headline-Bleed (Headline überlagert Container-Grenze).
 *
 * .deco-wordmark MUSS auf einem .dt-pos-rel-Parent sitzen +
 * mit .dt-pos-abs platziert werden — sonst verschiebt es Layout.
 */
.deco-wordmark {
  font-family: var(--h1-font-family, inherit);
  font-weight: 900;
  font-size: clamp(8rem, 18vw, 22rem);
  line-height: 0.85;
  letter-spacing: -0.04em;
  color: var(--deco-color, currentColor);
  opacity: 0.08;
  pointer-events: none;
  user-select: none;
  white-space: nowrap;
}
.deco-wordmark-soft  { opacity: 0.05; }
.deco-wordmark-bold  { opacity: 0.14; }

.font-script {
  font-family: 'Caveat', 'Dancing Script', 'Brush Script MT', cursive;
  font-style: normal;
  letter-spacing: 0.01em;
}

.font-smallcaps {
  font-variant: small-caps;
  letter-spacing: 0.08em;
}

/* Headline die über den Card-/Container-Rand hinausragt. Default-Bleed
 * von -1rem links/rechts, anpassbar per dt-ml-neg-N etc. */
.text-bleed {
  margin-left: -0.5rem;
  margin-right: -0.5rem;
}


/* ─── 5. Image-Overlay (.img-rounded, .img-overlay-*) ──────────────────
 * Stoff-Klassen für Bilder die als Photo-Card erscheinen + Overlay-
 * Kinder (Badge, Button, Score). .img-overlay-* sind ABSOLUTE-positioniert
 * — der Img-Container braucht .dt-pos-rel.
 */
/* rounded-* on an image section clips the image to the border-radius */
section[type='image'][class*='rounded'] { overflow: hidden; }


.img-overlay-tl, .img-overlay-tr, .img-overlay-bl, .img-overlay-br {
  position: absolute;
  z-index: 2;
  padding: 0.5rem 0.85rem;
}
.img-overlay-tl { top: 0.75rem;  left: 0.75rem; }
.img-overlay-tr { top: 0.75rem;  right: 0.75rem; }
.img-overlay-bl { bottom: 0.75rem; left: 0.75rem; }
.img-overlay-br { bottom: 0.75rem; right: 0.75rem; }

/* Common overlay-Stoffe — kombinierbar mit img-overlay-*-Position */
.img-overlay-pill {
  background: rgba(255,255,255,0.92);
  border-radius: 999px;
  padding: 0.35em 0.85em;
  font-size: 0.85rem;
  font-weight: 600;
  color: var(--em-navy, #1a2f3f);
  box-shadow: 0 2px 8px rgba(0,0,0,0.12);
}
.img-overlay-badge {
  background: var(--em-navy, #1a2f3f);
  color: #fff;
  border-radius: 8px;
  padding: 0.4em 0.7em;
  font-size: 0.85rem;
  font-weight: 700;
}

/* Play-Button-Overlay für Video-Vorschau-Bilder */
.img-overlay-play::before {
  content: "";
  position: absolute;
  top: 50%; left: 50%;
  transform: translate(-50%,-50%);
  width: 56px; height: 56px;
  border-radius: 50%;
  background: rgba(255,255,255,0.9);
  z-index: 1;
}
.img-overlay-play::after {
  content: "";
  position: absolute;
  top: 50%; left: calc(50% + 2px);
  transform: translate(-50%,-50%);
  width: 0; height: 0;
  border-left: 14px solid var(--em-navy, #1a2f3f);
  border-top: 9px solid transparent;
  border-bottom: 9px solid transparent;
  z-index: 2;
}


/* ─── 6. Edge-/Float-Elemente (.edge-l/r, .float-card-*) ───────────────
 * Vertikaler Sidebar (Maben-Style) + freistehende Floating-Cards
 * (xBlend-Quiz-CTA-Style). Kombinierbar mit dt-* für Positionierung.
 */

/* Volle Höhe-Sidebar links/rechts. Section braucht dt-pos-rel + Höhe.
 * Nur Desktop — auf Mobile fällt die Bar via dt-pos-static raus dem
 * Layout (kann über dt-bleed-x dann full-width oben sitzen, Author-
 * Entscheidung). */
@media (min-width: 1024px) {
  .edge-l, .edge-r {
    position: absolute;
    top: 0; bottom: 0;
    width: var(--edge-w, 60px);
    background: var(--edge-bg, var(--em-navy, #1a2f3f));
    color: var(--edge-color, #fff);
    display: flex;
    flex-direction: column;
    align-items: center;
    padding: 1rem 0;
    z-index: 5;
  }
  .edge-l { left: 0; }
  .edge-r { right: 0; }
}

/* Floating-Card-Stoff — Karte schwebt mit Schatten + leicht verstärktem
 * Padding. Nutzt .card-elev-md als Basis, fügt Hover-Animation hinzu. */
.float-card {
  background: #fff;
  border-radius: 14px;
  padding: 1.25rem 1.5rem;
  box-shadow: 0 12px 32px rgba(26,47,63,0.18), 0 4px 10px rgba(26,47,63,0.08);
  transition: transform 0.2s, box-shadow 0.2s;
}
.float-card:hover {
  transform: translateY(-2px);
  box-shadow: 0 18px 42px rgba(26,47,63,0.22), 0 6px 14px rgba(26,47,63,0.12);
}

/* Avatar-Stack für „X Personen sagten..."-Style Floating-Cards */
.avatar-stack {
  display: inline-flex;
  align-items: center;
}
.avatar-stack img,
.avatar-stack .avatar {
  width: 28px; height: 28px;
  border-radius: 50%;
  border: 2px solid #fff;
  margin-left: -8px;
  background-size: cover;
  background-position: center;
}
.avatar-stack > :first-child { margin-left: 0; }


/* ─── 7. Animation-Library (.anim-*) ───────────────────────────────────
 * Kuratierte ~20 Animationen, Animista-Style. Pure CSS keyframes,
 * kein JS. Application: Class auf Element, Animation läuft on-load
 * (default both fill-mode → Endzustand bleibt sichtbar).
 *
 * Modifier: .anim-delay-N (1=150ms .. 4=600ms), .anim-duration-fast/-slow,
 * .anim-loop (iteration-count: infinite).
 *
 * Accessibility: globaler prefers-reduced-motion Guard schaltet alle
 * .anim-* aus. .dt-anim-* Variante = nur Desktop animiert.
 *
 * em*Prefix auf den keyframes verhindert Kollisionen mit Pattern-CSS.
 */

/* Entrance: fade */
@keyframes emFadeIn {
  from { opacity: 0; }
  to   { opacity: 1; }
}
@keyframes emFadeInBottom {
  from { opacity: 0; transform: translateY(28px); }
  to   { opacity: 1; transform: translateY(0); }
}
@keyframes emFadeInTop {
  from { opacity: 0; transform: translateY(-28px); }
  to   { opacity: 1; transform: translateY(0); }
}
@keyframes emFadeInLeft {
  from { opacity: 0; transform: translateX(-32px); }
  to   { opacity: 1; transform: translateX(0); }
}
@keyframes emFadeInRight {
  from { opacity: 0; transform: translateX(32px); }
  to   { opacity: 1; transform: translateX(0); }
}

/* Entrance: slide */
@keyframes emSlideInBottom {
  from { transform: translateY(60px); opacity: 0; }
  to   { transform: translateY(0);    opacity: 1; }
}
@keyframes emSlideInTop {
  from { transform: translateY(-60px); opacity: 0; }
  to   { transform: translateY(0);     opacity: 1; }
}
@keyframes emSlideInLeft {
  from { transform: translateX(-60px); opacity: 0; }
  to   { transform: translateX(0);     opacity: 1; }
}
@keyframes emSlideInRight {
  from { transform: translateX(60px); opacity: 0; }
  to   { transform: translateX(0);    opacity: 1; }
}

/* Entrance: scale */
@keyframes emZoomIn {
  from { transform: scale(0.85); opacity: 0; }
  to   { transform: scale(1);    opacity: 1; }
}
@keyframes emRotateIn {
  from { transform: rotate(-8deg) scale(0.95); opacity: 0; }
  to   { transform: rotate(0) scale(1);        opacity: 1; }
}

/* Loop / Attention */
@keyframes emPulse {
  0%, 100% { transform: scale(1);    box-shadow: 0 0 0 0 rgba(74,158,255,0.4); }
  50%      { transform: scale(1.03); box-shadow: 0 0 0 12px rgba(74,158,255,0); }
}
@keyframes emFloat {
  0%, 100% { transform: translateY(0); }
  50%      { transform: translateY(-8px); }
}
@keyframes emBounce {
  0%, 20%, 50%, 80%, 100% { transform: translateY(0); }
  40%                     { transform: translateY(-12px); }
  60%                     { transform: translateY(-6px); }
}
@keyframes emShake {
  0%, 100%        { transform: translateX(0); }
  20%, 60%        { transform: translateX(-6px); }
  40%, 80%        { transform: translateX(6px); }
}

/* Text-spezifisch */
@keyframes emTextFocus {
  from { filter: blur(12px); opacity: 0; }
  to   { filter: blur(0);    opacity: 1; }
}
@keyframes emTrackingExpand {
  from { letter-spacing: -0.5em; opacity: 0; }
  to   { letter-spacing: normal; opacity: 1; }
}

/* ── Klassen ────────────────────────────────────────────────────────── */

/* Entrance — Default 600ms ease-out, fill-mode both (Endzustand bleibt) */
.anim-fade-in        { animation: emFadeIn        600ms ease-out both; }
.anim-fade-in-bottom { animation: emFadeInBottom  600ms cubic-bezier(.25,.46,.45,.94) both; }
.anim-fade-in-top    { animation: emFadeInTop     600ms cubic-bezier(.25,.46,.45,.94) both; }
.anim-fade-in-left   { animation: emFadeInLeft    600ms cubic-bezier(.25,.46,.45,.94) both; }
.anim-fade-in-right  { animation: emFadeInRight   600ms cubic-bezier(.25,.46,.45,.94) both; }
.anim-slide-in-bottom{ animation: emSlideInBottom 700ms cubic-bezier(.215,.61,.355,1) both; }
.anim-slide-in-top   { animation: emSlideInTop    700ms cubic-bezier(.215,.61,.355,1) both; }
.anim-slide-in-left  { animation: emSlideInLeft   700ms cubic-bezier(.215,.61,.355,1) both; }
.anim-slide-in-right { animation: emSlideInRight  700ms cubic-bezier(.215,.61,.355,1) both; }
.anim-zoom-in        { animation: emZoomIn        500ms cubic-bezier(.25,.46,.45,.94) both; }
.anim-rotate-in      { animation: emRotateIn      600ms ease-out both; }

/* Loop — sparsam einsetzen, max. 1 pro Section */
.anim-pulse          { animation: emPulse  2.4s ease-in-out infinite; }
.anim-float          { animation: emFloat  3s   ease-in-out infinite; }
.anim-bounce         { animation: emBounce 1.6s ease-in-out infinite; }

/* Text-Effekte */
.anim-text-focus     { animation: emTextFocus      700ms cubic-bezier(.55,.085,.68,.53) both; }
.anim-tracking-expand{ animation: emTrackingExpand 700ms cubic-bezier(.215,.61,.355,1) both; }

/* Modifier — kombinierbar mit den .anim-* Klassen */
.anim-delay-1 { animation-delay: 150ms; }
.anim-delay-2 { animation-delay: 300ms; }
.anim-delay-3 { animation-delay: 450ms; }
.anim-delay-4 { animation-delay: 600ms; }
.anim-delay-5 { animation-delay: 750ms; }
.anim-delay-6 { animation-delay: 900ms; }

.anim-duration-fast  { animation-duration: 350ms; }
.anim-duration-slow  { animation-duration: 1000ms; }

.anim-loop           { animation-iteration-count: infinite; }
.anim-once           { animation-iteration-count: 1; }

/* Accessibility — Reduced-Motion totaler Override.
 * Bleibt (Stufe 4c, Gruppe A, 2026-07-30): muss JEDE .anim-* Animation
 * schlagen, unabhaengig von der Spezifitaet der auslösenden Klasse — ein
 * Reduced-Motion-Guard ohne Durchsetzungskraft ist wirkungslos. */
@media (prefers-reduced-motion: reduce) {
  [class*="anim-"] {
    animation: none !important;
    transition: none !important;
  }
}

/* Desktop-only Variante: alles unter 1024px ohne Animation.
 * Bleibt aus demselben Grund wie oben — Mobile-Guard muss gewinnen. */
@media (max-width: 1023px) {
  [class*="dt-anim-"] {
    animation: none !important;
  }
}
/* Die dt-anim-* Klassen verwenden die gleichen Keyframes wie ihre
 * non-dt Geschwister; sie werden durch den oberen Block oben aktiv
 * eingeblendet. Convention: eigene Klasse anlegen wenn Animation
 * tatsächlich nur auf Desktop sinnvoll ist (z.B. Float-Animation auf
 * einem Floating-Card das auf Mobile sowieso gestackt ist). */
.dt-anim-fade-in        { animation: emFadeIn        600ms ease-out both; }
.dt-anim-fade-in-bottom { animation: emFadeInBottom  600ms cubic-bezier(.25,.46,.45,.94) both; }
.dt-anim-slide-in-left  { animation: emSlideInLeft   700ms cubic-bezier(.215,.61,.355,1) both; }
.dt-anim-slide-in-right { animation: emSlideInRight  700ms cubic-bezier(.215,.61,.355,1) both; }
.dt-anim-float          { animation: emFloat 3s ease-in-out infinite; }
.dt-anim-pulse          { animation: emPulse 2.4s ease-in-out infinite; }


/* ─── 8. Hover-Utilities (.hover-*) ────────────────────────────────────
 * Subtle Mikro-Interaktionen für interaktive Elemente. Default-
 * Transition sorgt dafür dass der Hover butterweich aussieht. Touch-
 * Devices ignorieren das, das ist OK.
 */
.hover-lift,
.hover-zoom,
.hover-glow,
.hover-brighten,
.hover-rotate,
.hover-shrink {
  transition: transform 0.2s ease, box-shadow 0.2s ease, filter 0.2s ease;
}

.hover-lift:hover     { transform: translateY(-3px); box-shadow: 0 12px 28px rgba(26,47,63,0.18); }
.hover-zoom:hover     { transform: scale(1.04); }
.hover-shrink:hover   { transform: scale(0.97); }
.hover-glow:hover     { box-shadow: 0 0 0 4px rgba(74,158,255,0.20), 0 8px 22px rgba(26,47,63,0.16); }
.hover-brighten:hover { filter: brightness(1.08); }
.hover-rotate:hover   { transform: rotate(2deg); }

/* Reduced-motion respektieren.
 * Bleibt (Stufe 4c, Gruppe A, 2026-07-30): analog zum .anim-*-Guard oben —
 * die Hover-Mikro-Interaktion muss auch bei :hover ausbleiben, sonst ist
 * der Reduced-Motion-Schalter nur halb wirksam. */
@media (prefers-reduced-motion: reduce) {
  .hover-lift, .hover-zoom, .hover-glow, .hover-brighten,
  .hover-rotate, .hover-shrink {
    transition: none !important;
  }
  .hover-lift:hover, .hover-zoom:hover, .hover-shrink:hover, .hover-rotate:hover {
    transform: none !important;
  }
}

/* ─── Carousel ──────────────────────────────────────────────────────── */
[type='carousel'] {
  position: relative;
  overflow: hidden;
}
/* nav="inline": prev + dots + next in a bottom row
   .cr-track-wrap clips the slides; carousel itself stays visible for the nav row */
[type='carousel'][data-nav='inline'] { overflow: visible; }
[type='carousel'][data-nav='inline'] .cr-track-wrap { overflow: hidden; }
[type='carousel'][data-nav='inline'] .cr-nav {
  display: flex;
  align-items: center;
  justify-content: center;
  gap: 0.75rem;
  padding: 0.75rem 0 0;
}
[type='carousel'][data-nav='inline'] .cr-prev,
[type='carousel'][data-nav='inline'] .cr-next {
  /* Ohne `!important` (Stufe 4d-1): der Selektor ist mit zwei Attribut-Teilen
     plus Klasse (0,3,0) spezifischer als die Basis-Regel `.cr-prev, .cr-next`
     (0,1,0), die position/top setzt. Kein Pattern setzt position auf
     .cr-prev/.cr-next — geprueft ueber alle pattern.css. */
  position: static;
  /* transform ohne Flag (Stufe 4c, Rest, 2026-07-30): einziger Gegenspieler
   * ist `.cr-prev, .cr-next { transform: translateY(...) }` (0,1,0) —
   * dieser Selektor ist (0,3,0) [type='carousel'] + [data-nav='inline'] +
   * .cr-prev, schlaegt outright. Geprueft: kein Pattern (auch nicht
   * hero_slider, das .cr-prev/.cr-next lokal stylt) setzt transform auf
   * .cr-prev/.cr-next, und data-nav='inline' wird aktuell von keinem
   * Pattern genutzt — kein versteckter Dritter gefunden.
   * (Der Satz „position/top bleiben geflaggt" stand hier bis 2026-08-08 und
   * war ueberholt: 4d-1 hat beide direkt danach entflaggt, siehe oben.) */
  transform: none;
  top: auto;   /* dito, Stufe 4d-1: derselbe Selektor-Vergleich wie bei position */
  box-shadow: 0 1px 4px rgba(0,0,0,0.12);
}
[type='carousel'][data-nav='inline'] .cr-dots { margin: 0; padding: 0; }
[type='carousel'][data-peek='true'] {
  overflow: visible;
  padding: 0 2rem;
}
.cr-track {
  display: flex;
  transition: transform 0.4s cubic-bezier(0.25, 0.46, 0.45, 0.94);
  will-change: transform;
}
.cr-slide {
  flex: 0 0 calc(100% / var(--per-view, 1));
  min-width: 0;
  box-sizing: border-box;
  padding: 0 0.5rem;
}
.cr-prev,
.cr-next {
  position: absolute;
  top: 50%;
  transform: translateY(-50%) translateY(-1.5rem);
  background: rgba(255,255,255,0.9);
  border: none;
  border-radius: 50%;
  width: 2.5rem;
  height: 2.5rem;
  font-size: 1.4rem;
  cursor: pointer;
  z-index: 10;
  box-shadow: 0 2px 8px rgba(0,0,0,0.15);
  display: flex;
  align-items: center;
  justify-content: center;
  line-height: 1;
  transition: background 0.15s;
}
.cr-prev:hover,
.cr-next:hover { background: #fff; }
.cr-prev { left: 0.25rem; }
.cr-next { right: 0.25rem; }
.cr-prev:disabled,
.cr-next:disabled { opacity: 0.3; pointer-events: none; }
.cr-dots {
  display: flex;
  justify-content: center;
  gap: 0.4rem;
  margin-top: 1rem;
  padding-bottom: 0.25rem;
}
.cr-dot {
  width: 0.5rem;
  height: 0.5rem;
  border-radius: 50%;
  border: none;
  background: var(--primary-base);
  opacity: 0.25;
  cursor: pointer;
  padding: 0;
  transition: opacity 0.2s, transform 0.2s;
}
.cr-dot.active {
  opacity: 1;
  transform: scale(1.3);
}
@media (max-width: 640px) {
  .cr-slide { flex: 0 0 100%; }
  .cr-prev  { left: 0; }
  .cr-next  { right: 0; }
}
@media (min-width: 641px) and (max-width: 1023px) {
  .cr-slide {
    flex: 0 0 max(50%, calc(100% / var(--per-view, 1)));
  }
}

/* ─── Marquee / Logo-Ticker ──────────────────────────────────────────── */
.mypage .marquee-viewport {
  overflow: hidden;
  width: 100%;
}
.mypage .marquee-track {
  display: flex;
  width: max-content;
  animation: marquee-scroll 30s linear infinite;
  align-items: center;
  gap: 3rem;
}
.mypage .marquee-track:hover {
  animation-play-state: paused;
}
/* image-Kinder im Track: fixe Breite, kein text-align-Einfluss */
.mypage .marquee-track section[type='layer'],
.mypage .marquee-track div[type='rich'],
.mypage .marquee-track picture {
  flex-shrink: 0;
  text-align: left;
}
.mypage .marquee-track img {
  height: 3rem;
  width: auto;
  max-width: 10rem;
  object-fit: contain;
  object-position: center;  /* kein Beschnitt -> mittig, nicht 30% */
  display: block;
}
@keyframes marquee-scroll {
  from { transform: translateX(0); }
  to   { transform: translateX(-50%); }
}
/* Für farbige Variante: sc-pri-l Hintergrund im Track */
.mypage .glogo_marquee_endless_color .marquee-viewport,
.mypage .glogo_marquee_scroll .marquee-viewport {
  padding: 1rem 0;
}

/* =========================================================================
   Flow-Container (2a) — Track(auto) + Flow-Verhalten für layer-Container
   Ein layer mit .flow-wrap / .flow-scroll / .flow-auto ist ein EIGENER
   Flex-Track (NICHT das :has()-Grid der col-N-Reihen — nicht auf eine
   col-12-Reihe mit col-N-Kindern setzen). Direkte Kinder = geflowte Items
   mit fixer Breite (--flow-item-w). CSS-only: Scroll = natives overflow+snap
   (Swipe gratis), Auto = Marquee (reuse @keyframes marquee-scroll).
   Pfeile/Dots-Nav + nahtloser Auto-Loop (Item-Clone) folgen in 2a-2.
   ========================================================================= */
.mypage section[type='layer'].flow-wrap,
.mypage section[type='layer'].flow-scroll,
.mypage section[type='layer'].flow-auto {
  --flow-item-w: 300px;                 /* auto-Track Item-Breite, überschreibbar */
  --flow-gap: var(--grid-gap, 1rem);
  display: flex;
  gap: var(--flow-gap);
}
/* Items im Flow-Track: feste Breite, kein Schrumpfen (auto-Track) */
.mypage section[type='layer'].flow-wrap  > *,
.mypage section[type='layer'].flow-scroll > *,
.mypage section[type='layer'].flow-auto  > * {
  flex: 0 0 var(--flow-item-w);
  max-width: 100%;
}
/* Item-Breiten-Utilities (Inspector 2a-4 setzt eine davon) */
.mypage section[type='layer'].flow-w-sm { --flow-item-w: 220px; }
.mypage section[type='layer'].flow-w-md { --flow-item-w: 300px; }
.mypage section[type='layer'].flow-w-lg { --flow-item-w: 400px; }

/* Umbruch (Default) — mehrzeilig */
.mypage section[type='layer'].flow-wrap { flex-wrap: wrap; }

/* Scroll — einzeilig, horizontal, snap; Swipe nativ, Scrollbar versteckt */
.mypage section[type='layer'].flow-scroll {
  flex-wrap: nowrap;
  overflow-x: auto;
  overflow-y: hidden;
  scroll-snap-type: x mandatory;
  scroll-behavior: smooth;
  scrollbar-width: none;
  -ms-overflow-style: none;
}
.mypage section[type='layer'].flow-scroll::-webkit-scrollbar { display: none; }
.mypage section[type='layer'].flow-scroll > * { scroll-snap-align: start; }

/* Auto-Lauf — Marquee (reuse @keyframes marquee-scroll); Pause-on-Hover.
   Nahtlos nur mit dupliziertem Item-Satz (Autor/Editor, 2a-2). */
.mypage section[type='layer'].flow-auto {
  flex-wrap: nowrap;
  width: max-content;
  animation: marquee-scroll var(--flow-speed, 30s) linear infinite;
}
.mypage section[type='layer'].flow-auto:hover { animation-play-state: paused; }

/* a11y: kein Auto-Lauf bei reduced-motion (Scroll bleibt — user-initiiert).
   Retrofit der bestehenden .marquee-track (bisher ungeschützt). */
@media (prefers-reduced-motion: reduce) {
  .mypage section[type='layer'].flow-auto { animation: none; width: auto; flex-wrap: wrap; }
  .mypage .marquee-track { animation: none; }
}

/* Mobile: Umbruch-Items einspaltig; Scroll/Auto behalten Swipe/Lauf */
@media (max-width: 640px) {
  .mypage section[type='layer'].flow-wrap > * { flex-basis: 100%; }
}

/* Flow-Nav-Chrome (2a-2) — vom flowEnhanceJS zur Laufzeit gebaut.
   .flow-scroll wird in .flow-scroll-wrap gewrappt; die Nav-Zeile folgt darunter. */
.mypage .flow-scroll-wrap { position: relative; }
.mypage .flow-nav-row {
  display: flex; align-items: center; justify-content: center;
  gap: .75rem; margin-top: .75rem;
}
.mypage .flow-nav-btn {
  width: 2.4rem; height: 2.4rem; border-radius: 50%;
  border: 1px solid var(--border, #ddd); background: var(--surface, #fff);
  color: var(--text, #222); font-size: 1.3rem; line-height: 1; cursor: pointer;
  display: inline-flex; align-items: center; justify-content: center;
  transition: background .2s;
}
.mypage .flow-nav-btn:hover { background: var(--surface-2, #f5f5f5); }
.mypage .flow-dots { display: flex; gap: .4rem; }
.mypage .flow-dot {
  width: .55rem; height: .55rem; border-radius: 50%; border: none; padding: 0;
  background: var(--border, #ccc); opacity: .5; cursor: pointer;
  transition: opacity .2s, transform .2s;
}
.mypage .flow-dot.active { opacity: 1; transform: scale(1.3); background: var(--primary-base, #333); }

/* ─── Logo Row ──────────────────────────────────────────────────────── */
/* Base flex context for .logo-row-inner so gap-* utilities work regardless
   of child element types (picture, img, svg — not col-N layers). */
.mypage .logo-row-inner {
  display: flex;
  flex-wrap: wrap;
  justify-content: center;
  align-items: center;
}
.mypage .logo-row-inner picture[type='picture'],
.mypage .logo-row-inner img {
  flex: 0 0 auto;
  max-height: 3rem;
  width: auto;
  object-fit: contain;
  object-position: center;  /* kein Beschnitt -> mittig, nicht 30% */
  opacity: 0.7;
  transition: opacity 0.2s;
}
.mypage .logo-row-inner picture[type='picture']:hover,
.mypage .logo-row-inner img:hover { opacity: 1; }

/* ─── Contact Strip Icons — SVG-Größe begrenzen ─────────────────────── */
/* gcont_strip_3icons / gcont_strip_3icons_left haben SVG-Icons die ohne
 * explizite Größe auf natürliche Viewbox-Größe skalieren (oft 200px+).
 * 2rem ist die korrekte Icon-Größe für dieses Layout. */
.mypage .contact-icon svg {
  /* Ohne `!important` (Stufe 4, Batch 4e, 2026-08-09): am DOM gemessen, nicht
   * gerechnet — Flag in der CSSOM entfernt, berechneten Wert verglichen,
   * wiederhergestellt. Ergebnis 32px vor wie nach: kein Gegenspieler.
   * Gemessen auf /basisregeln-check, weil .contact-icon auf der
   * All-Pattern-Seite nicht vorkommt (aber sehr wohl auf echten Seiten,
   * u.a. www-setu-io/home — deshalb ist die Regel NICHT tot). */
  width: 2rem;
  height: 2rem;
  display: block;
  flex-shrink: 0;
}
.mypage .contact-item {
  /* Ohne `!important` (Stufe 4d-1): der einzige andere Selektor, der
     flex-direction auf .contact-item setzt, ist
     `.mypage .gcont_strip_3icons_left .contact-item` in einer Media-Query
     (patterns.css) — der ist mit (0,3,0) spezifischer und SOLL dort gewinnen.
     Gegen ihn half auch das Flag nicht (beide trugen eines). Ausserhalb der
     Media-Query gibt es keinen Gegenspieler. */
  flex-direction: row;
  align-items: flex-start;
  gap: 0.75rem;
  text-align: left;
}
.mypage .contact-icon {
  flex-shrink: 0;
  width: 2rem;
  height: 2rem;
  padding-top: 0.1rem;
}

/* ─── art-cat / feat-tag Pills — globale Basisstile ─────────────────── */
/* Werden in Blog/Gallery/CTA Patterns als <p class='art-cat'> verwendet.
 * Scoped Varianten in pattern.css können überschreiben. */
.mypage .art-cat {
  display: inline-flex;
  align-items: center;
  background: color-mix(in srgb, var(--primary-base) 12%, transparent);
  color: var(--primary-dark);
  padding: 0.18rem 0.6rem;
  border-radius: 999px;
  font-size: 0.78rem;
  font-weight: 600;
  margin: 0 0 0.5rem 0;
  text-transform: uppercase;
  letter-spacing: 0.04em;
  width: fit-content;
}
.mypage .feat-tag {
  display: inline-flex;
  align-items: center;
  background: var(--contrast-base);
  color: var(--text-dark);
  padding: 0.22rem 0.7rem;
  border-radius: 999px;
  font-size: 0.78rem;
  font-weight: 700;
  margin: 0 0 0.5rem 0;
  text-transform: uppercase;
  letter-spacing: 0.04em;
  width: fit-content;
}

/* ─── ci-ico — Contact-List Icon Spans ──────────────────────────────── */
/* <span class='ci-ico'><svg class='icon'>...</svg></span> */
.mypage .ci-ico {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  flex-shrink: 0;
  width: 2rem;
  height: 2rem;
}
/* ACHTUNG, Befund aus Batch 4e (2026-08-09): dieser Selektor greift in der
 * Praxis NIE. `.ci-ico` ist selbst das Icon — der Renderer emittiert
 * `<svg class="icon ci-ico">`, es gibt also kein `svg` und kein `.icon`
 * DARIN. Geprueft an 112 gespeicherten Seiten mit .ci-ico und am DOM
 * (`.ci-ico svg` = 0 Treffer auf der All-Pattern-Seite). Die tatsaechliche
 * Groesse kommt aus `.mypage .form_contact .ci-ico { 2.2rem }`.
 * Vermutlich ein Ueberbleibsel aus der Zeit, als das Icon in einem Container
 * lag. Bewusst NICHT geloescht (anders als beim toten .splide__slide in
 * 4d-2): dort war der Selektor gegen geratene Fremd-Klassen geschrieben,
 * hier koennte ein kuenftiges Markup .ci-ico wieder als Container nutzen.
 * Ohne `!important` (Batch 4e): auf /basisregeln-check als Container
 * nachgebaut und gemessen — 20px vor wie nach dem Entflaggen. */
.mypage .ci-ico svg,
.mypage .ci-ico .icon {
  width: 1.25rem;
  height: 1.25rem;
  fill: var(--icon-color, var(--accent-on-light, var(--primary-base)));   /* --icon-color-Override; unset = Akzent (WCAG-AA, Task 7) */
  color: var(--icon-color, var(--accent-on-light, var(--primary-base)));
  display: block;
}
.mypage .contact-list {
  list-style: none;
  padding: 0;
  margin: 1rem 0 0;
  display: flex;
  flex-direction: column;
  gap: 0.85rem;
}
.mypage .contact-list li {
  display: flex;
  align-items: flex-start;
  gap: 0.65rem;
}


/* ─── Background-Video für Layer ──────────────────────────────────
 * Section mit `bg-video`-Attribut → Renderer ergänzt class
 * `layer-with-bg-video` und injiziert picture + video als erste
 * Kinder. Poster lädt eager (LCP-tauglich), Video lädt lazy via
 * IntersectionObserver und fadet on canplay über das Poster.
 * Reduced-motion / reduced-data: nur Poster, kein Video-Stream.
 * Siehe docs/superpowers/specs/2026-05-29-video-embed-player-design.md
 */
.mypage .layer-with-bg-video {
  position: relative;
  isolation: isolate;
}
.mypage .layer-with-bg-video > picture.bg-video-poster,
.mypage .layer-with-bg-video > video.bg-video {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  object-fit: cover;
  z-index: -1;
  pointer-events: none;
}
.mypage .layer-with-bg-video > picture.bg-video-poster img {
  width: 100%;
  height: 100%;
  object-fit: cover;
  display: block;
}
.mypage .layer-with-bg-video > video.bg-video {
  opacity: 0;
  transition: opacity 0.6s ease;
}
.mypage .layer-with-bg-video > video.bg-video.ready {
  opacity: 1;
}

@media (prefers-reduced-motion: reduce),
       (prefers-reduced-data: reduce) {
  .mypage .layer-with-bg-video > video.bg-video {
    display: none;
  }
}

/* ─── Tier-2 Recipe: scene-trust-strip ─────────────────────────────
 * Trust-Strip mit Sternen + Rating-Text als 2-Layer-Struktur
 * (icontext "stars" + html "trust-strip-text"). Frueher war das ein
 * einziger HTML-Slot mit 3 inline-spans — TipTap-inkompatibel weil
 * Klassen beim Reinklicken verloren gingen. Jetzt strukturell, mit
 * Flex-Container fuer horizontale Anordnung. */
.mypage .scene-trust-strip {
  /* `display` BEHAELT sein !important (Stufe 4, Batch 4e, 2026-08-08, am DOM
   * gemessen). Es ist tragend, und zwar erst seit Batch 4e:
   * Gegenspieler ist die Molecule-Engine-Regel
   *   `.mypage .molecule > section[type='layer'] { display: block }`
   * mit (0,3,1). Dieser Selektor hat nur (0,2,0) und verliert per Spezifitaet.
   * Solange die Basis-Regel selbst geflaggt war, verlor dieser Strip ohnehin
   * (Flag gegen Flag, dann entscheidet die Spezifitaet) und lief als Block —
   * die Bewertungszeile stand deshalb zweizeilig. Seit die Basis entflaggt
   * ist, gewinnt dieses Flag und die Zeile laeuft einzeilig (51 -> 25px
   * gemessen). Ohne das Flag faellt genau das wieder zurueck: 1 von 2
   * Strips auf der QA-Seite wechselt zu `block` (der im Molecule; der in
   * hero_form haelt sich ueber `.mypage .hero_form .scene-trust-strip` (0,3,0)
   * auch ohne Flag).
   *
   * Sauberer waere, dem Selektor genug Spezifitaet zu geben statt eines Flags.
   * Bewusst nicht gemacht: der Strip steht mal in einer Molecule, mal nicht,
   * ein Gleichstand-nach-Dateireihenfolge waere hier die schlechtere Loesung
   * (dieselbe Erwaegung wie bei den Chevron-Paddings). */
  display: inline-flex !important;
  flex-wrap: wrap;
  align-items: center;
  justify-content: center;
  gap: 0.5rem;
}
.mypage .scene-trust-strip .stars {
  color: var(--contrast-base);
  letter-spacing: 0.08em;
  /* line-height: 1.5 matched die p-Leading des Rating-Texts daneben — sonst
   * sitzt der icontext-Default (line-height:1) zu tief gegenueber dem Text. */
  line-height: 1.5;
}
.mypage .scene-trust-strip .trust-strip-text > p {
  margin: 0;
}

/* ══════════════════════════════════════════════════════════════════════════
 * FOOTER-ZONEN — gemeinsames Vokabular der fuenf Footer (2026-08-10)
 *
 * Warum hier und nicht in einer Molecule: die fuenf Footer teilen dieses
 * Vokabular, und eine Molecule-Klasse am Footer-ROOT waere riskant — die
 * Basis-Regel `.mypage .molecule > section[type='layer'] { display: block }`
 * wuerde die Ausrichtungs-Reihe darunter treffen. em-components fuehrt
 * ohnehin schon Footer-Klassen (siehe `.footer-copyright` weiter oben), das
 * ist also der etablierte Ort.
 *
 * Das Modell hat vier Zonen, und die Klassen heissen danach:
 *   1 Identitaet  .fl-identity   Logo, Marke, ein Satz, Social
 *   2 Navigation  .fl-nav        Titel + Menue-Slot, ein bis drei Spalten
 *   3 Aktion      .fl-action     GENAU EINE: Newsletter, Kontakt oder CTA
 *   4 Recht       molecule footer-legal (eigene Molecule, immer vorhanden)
 *
 * Alle Farben aus `currentColor` bzw. `--text-muted`, nie aus `--text-dark`:
 * „dunkel" ist eine Einstellung am Abschnitt (sc-dark), kein eigenes Pattern.
 * ══════════════════════════════════════════════════════════════════════════ */

/* ── Zone 1: Identitaet ── */
.mypage .fl-identity {
  text-align: left;
}
/* Logo-Breite. Der Slot ist optional — ein leerer Bild-Slot rendert kein
 * <img>, die Zeile faellt dann einfach weg (kein Loch). */
.mypage .fl-identity .foot-brandbar {
  max-width: 150px;
  margin-bottom: 0.75em;
}
.mypage .fl-identity .footer-logo-fit img {
  width: 100%;
  height: auto;
}
.mypage .fl-brand {
  font-weight: 700;
  margin-bottom: 0.25em;
}
/* Die Marke erscheint EINMAL — dieselbe Regel wie in der Kopfzeile (2026-08-11,
 * Vorgabe des Users: „nur ein Bild ODER Text"). Ist der Logo-Slot gefuellt,
 * traegt das Logo den Namen und der Schriftzug entfaellt; die Positionierungs-
 * zeile (fl-mission) bleibt, sie sagt etwas anderes. Am Netz gesehen stand in
 * der Fusszeile das NORDIX-Logo und darunter noch „Musterfirma GmbH". */
.mypage .fl-identity:has(.foot-brandbar img[src]:not([src=''])) .fl-brand {
  display: none;
}
/* Ein Satz Positionierung: gedaempft und in der Zeilenlaenge begrenzt. 34em
 * ist die Lesemass-Grenze, die auch cta-block nutzt — ein Satz, der ueber die
 * ganze Spalte laeuft, liest sich nicht als Beisatz. */
.mypage .fl-mission {
  color: var(--text-muted);
  max-width: 34em;
}
/* Die Social-Leiste folgt der Identitaets-Spalte, die linksbuendig ist — nicht
 * ihrer eigenen Voreinstellung. Die Molecule steht standardmaessig auf
 * `justify-content: center` (0,3,0) und schlug die kurze Form `.mypage
 * .fl-social` (0,2,0): am DOM standen die drei Kreise 100px eingerueckt neben
 * einem linksbuendigen Logo. Mit der Molecule-Klasse im Selektor (0,4,0)
 * gewinnt die Zone — ohne Flag. */
.mypage .fl-social,
.mypage .molecule.social-strip.fl-social {
  margin-top: 0.75em;
  justify-content: flex-start;
}
/* Flache Variante fuer den einzeiligen Footer: kein Logo, engerer Rhythmus. */
.mypage .fl-identity--flach .foot-brandbar {
  display: none;
}

/* ── Zone 2: Navigation ── */
.mypage .fl-nav-title,
.mypage .fl-action-title {
  /* Mikro-Titel ueber einer Spalte. Zaehlt als Label, nicht als Prosa —
   * font-size und -weight bleiben deshalb Pattern-/Komponenten-Sache. */
  font-size: 0.85rem;
  font-weight: 600;
  text-transform: none;
  margin: 0 0 0.75em 0;
}
.mypage .fl-nav-menu {
  display: flex;
  flex-direction: column;
  gap: 0.5em;
  font-size: 0.9rem;
}
.mypage .fl-nav-menu a,
.mypage .fl-nav-menu .nav-demo {
  color: var(--text-muted);
  text-decoration: none;
}
.mypage .fl-nav-menu a:hover {
  color: inherit;
}
/* Eine Navigationsspalte, deren Menue aufgeloest und LEER ist, verschwindet
 * ganz (2026-08-11): ein Spaltentitel ohne Liste ist ein halbes Element — genau
 * der Fehler, der in foot_horizontal schon einmal behoben wurde.
 *
 * `:empty` trifft ausschliesslich diesen Fall: ein UNkonfiguriertes Menue traegt
 * immer die drei Demo-Eintraege, und im Editor steht im aufgeloest-leeren Slot
 * der Hinweis `.nav-empty` — die Spalte bleibt dort also sichtbar und
 * bearbeitbar. Leer ist der Slot nur in der ausgelieferten Seite.
 *
 * `!important` ist hier NOETIG und am DOM belegt: Gegenspieler ist Regel 3 der
 * Grid-Engine (`col-12:has(> col-N) > col-N { display: flex !important }`), die
 * jede Spalte einer Mehrspalter-Reihe geflaggt auf Flex stellt. Flag gegen Flag
 * entscheidet die Spezifitaet, und dieser Selektor liegt mit (0,8,3) ueber deren
 * (0,5,2) — deshalb steht die volle Kette hier und nicht die kurze Form
 * `.mypage .fl-nav:has(...)`, die mit (0,4,0) auch mit Flag verloren haette
 * (gemessen: Spalte blieb display: flex). */
.mypage section[type='layer'].col-12 > section[type='layer'].fl-nav:has(> div[type='rich'].fl-nav-menu:empty) {
  display: none !important;
}

/* ── Zone 3: Aktion ── */
.mypage .fl-action-body {
  color: var(--text-muted);
  font-size: 0.9rem;
  margin-bottom: 0.75em;
}

/* ── Karte im Fuss ── */
.mypage .fl-map {
  align-self: start;
}

/* ══════════════════════════════════════════════════════════════════════════
 * KARTEN-GRIDS STAPELN AUF SCHMALEN BREITEN (2026-08-10)
 *
 * DER FEHLER, den das schliesst: die Stapelregel weiter unten setzt nur
 * `flex-direction: column`. Im GRID bedeutet das nichts — und Regel 6 oben
 * macht jede Reihe mit Karten-Spalten zu `display: grid !important`. Ergebnis
 * am Telefon gemessen (390px, /quality-test-v135): 15 von 29 mehrspaltigen
 * Reihen blieben EINZEILIG, Spaltenbreiten 68 bis 96px, teils mit
 * horizontalem Ueberlauf bis 121px. Betroffen war alles Kartige:
 * benefit_4icons, proc_4horizontal, proc_3icons, voice_3row/_3stories/_3cards,
 * proof_strip_4/_3labels/_4dark, price_3tiers, team_3persons/_cards_circle/
 * _leadership_bio, content_downloads_3, faq_rows_2col.
 * Die 14 Flex-Reihen stapelten korrekt — der Fehler steckte ausschliesslich im
 * Grid-Pfad, also in dem Zweig, der 2026-07-17 fuer gleich hohe Karten
 * eingefuehrt wurde und dessen Mobil-Fall nie nachgezogen wurde.
 *
 * Zwei Regeln: eine Spur statt zwoelf, und jedes Spaltenkind ueber die ganze
 * Breite. Die zweite MUSS die `grid-column: span N`-Regeln oben schlagen —
 * gleiche Spezifitaet (0,3,2), deshalb steht sie spaeter in DERSELBEN Datei.
 * Das ist normale Kaskade innerhalb einer Datei, keine Abhaengigkeit von der
 * Ladereihenfolge mehrerer Dateien.
 * `span 12` eines col-12-Kindes muss mit zurueckgesetzt werden: in einer
 * einspaltigen Spur wuerde es elf implizite Spalten aufziehen.
 * ══════════════════════════════════════════════════════════════════════════ */
@media (max-width: 640px) {
  .mypage section[type='layer'].col-12:has(
    > section[type='layer'].col-2.molecule, > section[type='layer'].col-2.card, > section[type='layer'].col-3.molecule, > section[type='layer'].col-3.card, > section[type='layer'].col-4.molecule, > section[type='layer'].col-4.card, > section[type='layer'].col-6.molecule, > section[type='layer'].col-6.card
  ) {
    grid-template-columns: 1fr;
  }
  .mypage section[type='layer'].col-12 > section[type='layer'].col-1,
  .mypage section[type='layer'].col-12 > div[type='rich'].col-1,
    .mypage section[type='layer'].col-12 > section[type='layer'].col-2,
  .mypage section[type='layer'].col-12 > div[type='rich'].col-2,
    .mypage section[type='layer'].col-12 > section[type='layer'].col-3,
  .mypage section[type='layer'].col-12 > div[type='rich'].col-3,
    .mypage section[type='layer'].col-12 > section[type='layer'].col-4,
  .mypage section[type='layer'].col-12 > div[type='rich'].col-4,
    .mypage section[type='layer'].col-12 > section[type='layer'].col-5,
  .mypage section[type='layer'].col-12 > div[type='rich'].col-5,
    .mypage section[type='layer'].col-12 > section[type='layer'].col-6,
  .mypage section[type='layer'].col-12 > div[type='rich'].col-6,
    .mypage section[type='layer'].col-12 > section[type='layer'].col-7,
  .mypage section[type='layer'].col-12 > div[type='rich'].col-7,
    .mypage section[type='layer'].col-12 > section[type='layer'].col-8,
  .mypage section[type='layer'].col-12 > div[type='rich'].col-8,
    .mypage section[type='layer'].col-12 > section[type='layer'].col-9,
  .mypage section[type='layer'].col-12 > div[type='rich'].col-9,
    .mypage section[type='layer'].col-12 > section[type='layer'].col-10,
  .mypage section[type='layer'].col-12 > div[type='rich'].col-10,
    .mypage section[type='layer'].col-12 > section[type='layer'].col-11,
  .mypage section[type='layer'].col-12 > div[type='rich'].col-11,
    .mypage section[type='layer'].col-12 > section[type='layer'].col-12,
  .mypage section[type='layer'].col-12 > div[type='rich'].col-12 {
    grid-column: 1 / -1;
  }
}

/* Zwischenstufe Tablet: zwei Spuren statt vier bzw. drei (2026-08-10).
 *
 * Gemessen bei 700px, nachdem die Mobil-Stufe sass: 17 Reihen standen weiter
 * drei- bis vierspaltig, die Vierspalter bei 145px Kartenbreite. Das ist keine
 * Karte mehr, das ist eine Spalte mit Wortumbruch nach zwei Silben.
 * Zwei Spuren sind die uebliche Zwischenstufe: 4 -> 2x2, 3 -> 2+1. Die
 * `grid-column: span N` der Autoren werden dabei auf eine Spur gesetzt, sonst
 * spannt eine col-4 ueber beide und die Reihe kippt wieder auf eine Spalte.
 *
 * Nur der GRID-Pfad. Flex-Reihen bleiben unberuehrt: dort sind drei Spalten bei
 * 700px noch 203 bis 217px breit (Kopfzeile, Chevron-Ketten) — und die
 * Chevron-Ketten MUESSEN in einer Reihe bleiben, ihr Padding formt die Pfeile.
 */
@media (min-width: 641px) and (max-width: 1023px) {
  .mypage section[type='layer'].col-12:has(
    > section[type='layer'].col-2.molecule, > section[type='layer'].col-2.card,
    > section[type='layer'].col-3.molecule, > section[type='layer'].col-3.card,
    > section[type='layer'].col-4.molecule, > section[type='layer'].col-4.card,
    > section[type='layer'].col-6.molecule, > section[type='layer'].col-6.card
  ) {
    grid-template-columns: repeat(2, 1fr);
  }
  .mypage section[type='layer'].col-12:has(
    > section[type='layer'].col-2.molecule, > section[type='layer'].col-2.card,
    > section[type='layer'].col-3.molecule, > section[type='layer'].col-3.card,
    > section[type='layer'].col-4.molecule, > section[type='layer'].col-4.card,
    > section[type='layer'].col-6.molecule, > section[type='layer'].col-6.card
  ) > section[type='layer'][class*='col-']:not(.col-12) {
    grid-column: span 1;
  }
}

/* Leerer Bild-Slot darf keinen Platz belegen (2026-08-10).
 *
 * Ein unbefuellter Bild-Slot rendert `<img src="" alt="…">` — der Browser haelt
 * dafuer eine Box vor. Gemessen im neu instanziierten Master-Header: 268x40px
 * fuer ein Logo, das es nicht gibt, mitten in der Markenspalte.
 * Das betrifft jedes Pattern, dessen Logo optional ist (die konsolidierten
 * Header und der Identitaets-Block der Footer bauen darauf, dass ein leerer
 * Slot NICHTS rendert — diese Annahme war falsch, hier wird sie wahr).
 * `:not([srcset])` als Vorsicht: ein <img> ohne src, das seine Quelle aus einem
 * srcset zieht, ist gueltig und soll bleiben. */
/* Zwei Schreibweisen, weil der Renderer je nach Pfad die eine ODER die andere
 * erzeugt: bei einem leeren Bild-Slot emittiert er `<img alt="Logo" loading=
 * "lazy">` — GANZ OHNE src-Attribut, nicht `src=""`. Mein erster Selektor traf
 * nur die zweite Form und liess den leeren Logo-Kasten stehen (gemessen 54x28
 * mitten in der Markenspalte).
 * `:not([srcset])` bleibt in beiden Faellen: ein <img> ohne src, das seine
 * Quelle aus einem srcset zieht, ist gueltig und soll bleiben. */
.mypage img:not([src]):not([srcset]),
.mypage img[src='']:not([srcset]) {
  display: none;
}
/* Das <picture> drumherum kollabiert mit, sonst bleibt dessen eigene Box. */
.mypage picture:has(> img:not([src]):not([srcset])),
.mypage picture:has(> img[src='']:not([srcset])) {
  display: none;
}
/* Und der Logo-Wrapper selbst — sonst bleibt er als Flex-Kind stehen und
 * erzeugt eine Luecke im gap der Markenspalte. */
.mypage section[type='layer'].head-logo:has(img:not([src]):not([srcset])),
.mypage section[type='layer'].head-logo:has(img[src='']:not([srcset])),
.mypage section[type='layer'].foot-brandbar:has(img:not([src]):not([srcset])),
.mypage section[type='layer'].foot-brandbar:has(img[src='']:not([srcset])) {
  display: none;
}


/* ══════════════════════════════════════════════════════════════════════════
 * HEADER-DOKTRIN (2026-08-11) — Art-Direction-Regeln, am DOM belegt
 *
 * Vorgeschichte: die konsolidierten Header stapelten Logo, Schriftzug UND
 * Tagline uebereinander, die Navigation hing daneben irgendwo (die Reihe stand
 * auf `align-items: stretch`), und das Logo lief als Streifen ueber die ganze
 * Spalte. Drei Fehler, ein Bild.
 *
 * 1 DIE MARKE ERSCHEINT EINMAL. Ist der Logo-Slot gefuellt, zeigt der Header das
 *   LOGO und der Schriftzug entfaellt. Ist er leer, zeigt er den SCHRIFTZUG.
 *   Bild ODER Text, nie beides — und ohne zwei Pattern-Dateien dafuer.
 * 2 Die Tagline gehoert zum Schriftzug, nicht zum Logo: ein grafisches Logo
 *   bringt seine Subline selbst mit. Also faellt sie mit dem Schriftzug weg.
 * 3 Alles andere zentriert sich VERTIKAL an der Marke.
 * ══════════════════════════════════════════════════════════════════════════ */

/* 1+2: gefuellter Logo-Slot verdraengt Schriftzug und Tagline.
 * `img[src]:not([src=''])` ist der Test auf „wirklich gefuellt" — ein leerer
 * Bild-Slot rendert `<img src="">`, das zaehlt nicht. */
.mypage .head-brand:has(.head-logo img[src]:not([src=''])) .head-brand-text,
.mypage .head-brand:has(.head-logo img[src]:not([src=''])) .head-tagline,
.mypage .hcln-brand:has(.head-logo img[src]:not([src=''])) .head-brand-text,
.mypage .hcln-brand:has(.head-logo img[src]:not([src=''])) .head-tagline {
  display: none;
}
/* Umgekehrt: ohne Logo verschwindet der leere Bildkasten (die Regel dafuer
 * steht weiter oben bei `img[src='']`), der Schriftzug traegt die Marke. */

/* 3: vertikale Zentrierung. Die Kopfzeile ist EIN Band mit einer optischen
 * Mitte — Marke, Navigation und Buttons sitzen darauf. EINE Zeile genuegt
 * dafuer: `align-items: center` an der Reihe laesst jede Spalte auf ihre
 * Inhaltshoehe schrumpfen und legt sie auf die Mitte des Bandes.
 *
 * KEIN `justify-content: center` an den Spalten (2026-08-11 wieder entfernt,
 * am DOM belegt): die Absicht war „zentriere senkrecht", weil die Grid-Engine
 * col-N-Spalten auf `flex-direction: column` stellt. Eine Spalte, die ihre
 * Richtung selbst auf `row` zurueckdreht, bekam damit aber eine WAAGRECHTE
 * Zentrierung — die CTA-Spalte von head_brand_tagline_cta stand 53px vor der
 * rechten Hilfslinie, obwohl ihr eigenes pattern.css `justify-content:
 * flex-end` trug (der Doktrin-Selektor liegt bei (0,6,3) und gewann). Dieselbe
 * Achsen-Falle wie bei Regel 4b oben. Eine Eigenschaft, deren Bedeutung von
 * der Flex-Richtung des Ziels abhaengt, darf nicht pauschal ueber eine ganze
 * Sektion gesetzt werden. */
.mypage section[type='layer'][class*='head_'] > section[type='layer'].max-w {
  align-items: center;
}

/* Marke: Logo und Schriftzug teilen dieselbe Zeile, nie gestapelt — und der
 * Zeilenabstand des Schriftzugs bleibt eng, damit die Bandhoehe nicht wandert. */
.mypage .head-brand-text {
  line-height: 1.15;
}
.mypage .head-brand-text p {
  margin: 0;
}
/* Tagline: klar untergeordnet, dicht am Schriftzug. */
.mypage .head-tagline {
  margin-top: 0.15em;
  font-size: 0.8rem;
  line-height: 1.25;
  color: var(--text-muted);
}
.mypage .head-tagline p {
  margin: 0;
}

/* Zentrierte Marken: dort gehoert das Logo in die Mitte des Kastens, nicht an
 * die linke Kante — die Kante ist bei einer zentrierten Kopfzeile keine
 * Bezugslinie. */
.mypage .head-align-center .head-logo img,
.mypage .hcln-brand .head-logo img,
.mypage .head-align-center .head-logo picture img,
.mypage .hcln-brand .head-logo picture img {
  object-position: center;
}
.mypage section[type='layer'].head-align-center.head-logo,
.mypage .hcln-brand section[type='layer'].head-logo {
  margin-left: auto;
  margin-right: auto;
}

/* ── Kopfzeilen stapeln NICHT (2026-08-11) ─────────────────────────────────
 * Die Mobil-Leiter (≤640px) stellt jede Mehrspalter-Reihe auf `column` und
 * ihre Spalten auf `width: 100%`. Fuer Inhalt ist das genau richtig, fuer eine
 * Kopfzeile falsch: bei 390px stand die Wortmarke in Zeile 1 und der Burger
 * darunter rechts (gemessen head_simple: 2 Zeilen, Band ~150px hoch). Eine
 * Kopfzeile ist auf JEDER Breite ein Band — Marke links, Zugang rechts. Genau
 * dafuer gibt es den Burger.
 *
 * `:not(.head_centered_logo_nav)` ist die begruendete Ausnahme: diese Kopfzeile
 * IST zweizeilig gebaut (Marke ueber Navigation) und soll das bleiben; ihre
 * eigene Regel liegt bei (0,4,2) und wuerde von dieser hier sonst ueberstimmt.
 *
 * Spezifitaeten (nachgerechnet, keine Flags): Reihe (0,6,2) gegen die Leiter
 * (0,5,2); Spalten (0,6,3) gegen die Breiten-Regel der Leiter (0,5,2).
 * ─────────────────────────────────────────────────────────────────────────── */
@media (max-width: 640px) {
  .mypage section[type='layer'][class*='head_']:not(.head_centered_logo_nav) > section[type='layer'].max-w {
    flex-direction: row;
    flex-wrap: nowrap;
    justify-content: space-between;
    gap: 0.75rem;
  }
  .mypage section[type='layer'][class*='head_'] > section[type='layer'].max-w > section[type='layer'] {
    width: auto;
  }
  /* Die zweite Handlung entfaellt auf dem Telefon: Marke, Burger UND zwei
   * Knoepfe passen bei 390px nicht in ein Band, ohne dass alles gedraengt
   * wirkt. Es bleibt der Primaer-Knopf — die Hierarchie entscheidet, was
   * ueberlebt, nicht der Zufall der Quellreihenfolge. */
  .mypage section[type='layer'][class*='head_'] .btn-wrap.btn-outline {
    display: none;
  }
}
