/* ═══════════════════════════════════════════════════════════════════════════════
 * em-base.css — Plattform Design-Defaults (ExpertMaker Pages)
 * Plattform-Defaults — werden durch project.css des jeweiligen Projekts überschrieben.
 * ═══════════════════════════════════════════════════════════════════════════════ */

/* ── Schriften von fonts.expmk.de ─────────────────────────────────────────── */
@import "https://fonts.expmk.de/css2?family=Roboto:ital,wght@0,300;0,400;0,500;0,700;1,300;1,400;1,700&display=swap";
@import "https://fonts.expmk.de/css2?family=Roboto+Slab:wght@300;400;700&display=swap";

/* ── Design-Tokens (globaler Default — wird durch BE <style>-Block pro Tenant überschrieben) ── */
:root {
  --font-size: 1rem;

  /* Spacing — single base, all utilities calc(N * --spacing) */
  --spacing: 0.5rem;

  /* ── Brand-Farben (Fallback; kommen vom BE RenderCSSVars) ── */
  --primary-base:    #2563EB;
  --primary-dark:    color-mix(in hsl, #2563EB 72%, black 28%);
  --primary-light:   color-mix(in hsl, #2563EB 25%, white 75%);

  --secondary-base:  #1E293B;
  --secondary-dark:  color-mix(in hsl, #1E293B 72%, black 28%);
  --secondary-light: color-mix(in hsl, #1E293B 25%, white 75%);

  --contrast-base:   #F59E0B;
  --contrast-dark:   color-mix(in hsl, #F59E0B 72%, black 28%);
  --contrast-light:  color-mix(in hsl, #F59E0B 25%, white 75%);

  /* ── Shade: neutrales Grau-System (unabhängig von Brand-Farben) ── */
  --shade:            0, 0%, 50%;
  --shade-base:       hsl(var(--shade));
  --shade-dark:       color-mix(in hsl, hsl(var(--shade)) 70%, black 30%);
  --shade-dark-base:  color-mix(in hsl, hsl(var(--shade)) 70%, black 30%);
  /* Page-Default ist Reinweiß: "Kein" (kein sc-* gesetzt) zeigt damit
   * sauberes Weiß, nicht warm-off-white. Die alte Annahme war
   * "wollweiß als sanfter Anker", in der Praxis wirkte das wie Grau
   * und kollidierte mit dem "Kein"-Zustand im Editor.
   *
   * --color-bg ist der Project-Settings-Hintergrund (ProjectSettings →
   * "Hintergrund"-Farbpicker). Default: weiß. Wenn das BE/RenderCSSVars
   * einen Wert setzt, gewinnt der per Cascade. */
  --color-bg:         #ffffff;
  /* --shade-light{,-base} bleibt warm-off-white und ist NUR noch das
   * Background-Token für die explizite '.sc-light'-Wahl ('Hell' im
   * Picker), damit 'Hell' visuell vom puren Weiß abhebbar bleibt. */
  --shade-light:      hsl(45, 30%, 97%);
  --shade-light-base: hsl(45, 30%, 97%);
  --shade-lightgray:  #e4e9f0;

  /* Auto-alternating-band background tokens. Intentionally lighter than
   * --shade-lightgray (which is a hard border/divider tone) so the zebra
   * effect reads as breathing room, not as a slab. The band renders as
   * a soft vertical gradient — top/bottom almost white, middle dips ~4%. */
  --band-bg-top:    #fbfcfd;
  --band-bg-mid:    #eef1f5;
  --band-bg-bot:    #fbfcfd;

  /* ── Textfarben ── */
  --text-dark:  #111827;
  --text-light: #ffffff;

  /* ── Kontext-Tokens (abgeleitet, READ-ONLY für Pattern-Autoren) ──────
   * Definieren welche Akzentfarbe auf welchem Hintergrundkontext
   * lesbar ist. Basis für Eyebrow, Icons, Stat-Values, Links.
   *
   *   --on-surface   helle / neutrale Fläche  → primary-base (Markierung)
   *   --on-primary   primary-farbige Fläche   → text-light (weiß, max. Kontrast)
   *   --on-dark      dunkle Fläche            → primary-light (Akzent sichtbar)
   *
   * Werden von sc-* Klassen in em-components.css auf --eyebrow-font-color
   * und --icon-color gemappt. Tenant-Override: direkt --eyebrow-font-color
   * in ProjectSettings setzen. */
  --on-surface:  var(--primary-base);
  --on-primary:  var(--text-light);
  --on-dark:     var(--primary-light);

  /* Neutrale Sub-Text-Stufe: 60% Mix zwischen dark und light, taugt
     als Sub-/Caption-Farbe wo currentColor zu kräftig wäre. Vorher
     wurde --shade-mid an mehreren Stellen referenziert ohne je
     definiert zu sein → Browser-Default schwarz, brach Sub-Layout
     auf dunklen Sektionen. */
  --shade-mid:  color-mix(in srgb, var(--text-dark) 60%, var(--text-light) 40%);

  /* Muted Subtext: WCAG-AA berechnete gedimmte Textfarbe statt opacity (kontrast-blind).
     Fallback #595959 für den Fall dass das BE die Var nicht setzt (dev/test).
     sc-dark/pri/sec/acc überschreiben unten auf die dunkle Variante.
     Pattern-Autoren benutzen var(--text-muted) ohne Fallback — der Token ist hier garantiert definiert. */
  --text-muted: var(--text-muted-on-light, var(--text-dark));

  /* sc-* exponierte Token-Aliases für pattern.css. Erlaubt Pattern-
     Authoren `var(--sc-light)` / `var(--sc-dark)` direkt zu verwenden
     (R4-Pattern-Konvention) ohne hartcodierte Hex-Fallbacks. */
  --sc-light:   var(--text-light);
  --sc-dark:    var(--text-dark);

  /* Anchor-Default: Text erbt Container-Farbe, Underline kommt aus dem
     Accent-Token. Editorial-Look — der Link sticht durch die Underline,
     nicht durch die Schriftfarbe. sc-* können diese Vars überschreiben. */
  --link-underline-color: var(--contrast-base);
  --link-hover-color:     var(--contrast-dark);

  /* ── Layout ── */
  /* --max-w wird vom BE via ProjectSettings.Layout.MaxW überschrieben.
     Default 1200px lässt auf 1366×768-Screens (~83px Rand) noch Luft;
     1280px war früher der Wert, wurde auf 1200px normiert. */
  --max-w: 1200px;

  /* ── Schriften (Fallback; kommen vom BE RenderCSSVars) ── */
  --headline-font: 'Roboto Slab', serif;
  --copytext-font: 'Roboto', sans-serif;

  /* ── Eyebrow — steht VOR der Überschrift (Kicker/Label) ── */
  /* Gesetzt via ProjectSettings → Typography → Eyebrow ✦             */
  /* Ein einheitlicher Stil für alle Ebenen, override im Custom CSS.   */
  /* Eyebrow / heading colors default to currentColor so they ride
   * Default: Primärfarbe auf hellen Sektionen, helle Primärvariante auf dunklen.
   * sc-dark/sc-pri/sc-sec überschreiben auf --primary-light (siehe em-components.css).
   * Per-project override: --eyebrow-font-color in ProjectSettings → Typography. */
  --eyebrow-font-color:        var(--accent-on-light, var(--primary-base));   /* WCAG-AA ≥4.5:1 auf hellem Hintergrund (Task 7) */
  --eyebrow-font-family:       var(--copytext-font);
  --eyebrow-font-size:         0.75rem;
  --eyebrow-font-weight:       700;
  --eyebrow-font-lineheight:   1.2;
  --eyebrow-text-transform:    uppercase;
  --eyebrow-letter-spacing:    0.12em;

  /* ── Sub-Headings — eigene typografische Achse ──────────────────────
   * Sub-Klassen (h1sub..h4sub) sind KEINE nächst-kleinere H-Stufe,
   * sondern eine separate Skala: ~50–70% des paired H, body-font,
   * leichteres Weight (300 für display-Stufen, 400 für content-nahe).
   * Visuell als Lead/Untertitel klar unterscheidbar von der Heading
   * (sonst frisst der Sub die Hierarchie der Heading auf — der Bug
   * der vorigen styles.css, die Sub = next-H-Size setzte).
   *
   * Per-Tenant overrides via ProjectSettings → Typography → Sub/Kicker
   * setzen die `--<class>-font-color/family/...` Vars um.
   * ───────────────────────────────────────────────────────────────── */
  /* Sub-headings: dim relative to the section text-color (currentColor)
   * via opacity rather than a fixed grey. With shade-mid the sub on
   * sc-dark would still resolve to a dark-grey = invisible on dark bg.
   * 0.75 opacity keeps the "lead" softer than the heading without
   * needing a hardcoded color that fights sc-* states. */
  /* Sub-Headings nicht mehr per opacity dimmen — Farbe kommt aus dem
   * kontrast-sicheren Muted-Token. opacity bleibt 1. */
  --sub-font-color:        var(--text-muted);
  --sub-font-opacity:      1;
  --sub-font-family:       var(--copytext-font);

  /* Sub-sizes follow the same scale: paired-heading × --type-sub-ratio.
   * h1sub..h2sub use light weight for the hero/section-lead "airy"
   * feel; h3sub..h4sub stay at regular weight since they sit close
   * to body-size and would look anaemic at 300. */

  --h1sub-font-color:       var(--sub-font-color);
  --h1sub-font-family:      var(--sub-font-family);
  --h1sub-font-size:        calc(var(--h1-font-size) * var(--type-sub-ratio));
  --h1sub-font-weight:      300;
  --h1sub-font-lineheight:  1.4;
  --h1sub-text-transform:   none;
  --h1sub-letter-spacing:   0;

  --h2sub-font-color:       var(--sub-font-color);
  --h2sub-font-family:      var(--sub-font-family);
  --h2sub-font-size:        calc(var(--h2-font-size) * var(--type-sub-ratio));
  --h2sub-font-weight:      300;
  --h2sub-font-lineheight:  1.45;
  --h2sub-text-transform:   none;
  --h2sub-letter-spacing:   0;

  --h3sub-font-color:       var(--sub-font-color);
  --h3sub-font-family:      var(--sub-font-family);
  --h3sub-font-size:        calc(var(--h3-font-size) * var(--type-sub-ratio));
  --h3sub-font-weight:      400;
  --h3sub-font-lineheight:  1.5;
  --h3sub-text-transform:   none;
  --h3sub-letter-spacing:   0;

  --h4sub-font-color:       var(--sub-font-color);
  --h4sub-font-family:      var(--sub-font-family);
  --h4sub-font-size:        calc(var(--h4-font-size) * var(--type-sub-ratio));
  --h4sub-font-weight:      400;
  --h4sub-font-lineheight:  1.5;
  --h4sub-text-transform:   none;
  --h4sub-letter-spacing:   0;

  /* Legacy alias */
  --emphasis-font-color:    var(--eyebrow-font-color);
  --emphasis-font-family:   var(--eyebrow-font-family);
  --emphasis-font-size:     var(--eyebrow-font-size);
  --emphasis-font-weight:   var(--eyebrow-font-weight);

  /* ── Type Scale ─────────────────────────────────────────────────────
   * Two knobs drive every heading + sub-heading size:
   *   --type-base   — body-tier reference (h6 = base, body = base)
   *   --type-scale  — multiplier between adjacent tiers
   *
   * Default = 1.2 (Minor Third), tighter scale chosen because long
   * German compound words ("Datenschutzbeauftragter") in display
   * sizes get unwieldy with broader scales (Major Third 1.25 +
   * Perfect Fourth 1.333 still selectable per project).
   *
   * Available scales (from typescale.com nomenclature):
   *   1.067 Minor Second     — very tight
   *   1.125 Major Second     — subtle
   *   1.2   Minor Third      — DEFAULT (DE-friendly)
   *   1.25  Major Third      — editorial
   *   1.333 Perfect Fourth   — UI-strong
   *   1.414 Augmented Fourth
   *   1.5   Perfect Fifth
   *   1.618 Golden Ratio     — dramatic
   *
   * --type-sub-ratio is the sub-heading multiplier vs paired heading
   * (h_N_sub = h_N * sub-ratio). 0.55 places sub between the next
   * two h-tiers — visually distinct from BOTH so the hierarchy reads
   * cleanly even when sub appears alone.
   * ───────────────────────────────────────────────────────────────── */
  --type-base:        1rem;
  --type-scale:       1.2;
  --type-sub-ratio:   0.55;
  --type-s1: var(--type-scale);
  --type-s2: calc(var(--type-s1) * var(--type-scale));
  --type-s3: calc(var(--type-s2) * var(--type-scale));
  --type-s4: calc(var(--type-s3) * var(--type-scale));
  --type-s5: calc(var(--type-s4) * var(--type-scale));
  /* Display-Stufen über h1 hinaus — für txt-5xl / txt-6xl (Hero-Headlines). */
  --type-s6: calc(var(--type-s5) * var(--type-scale));
  --type-s7: calc(var(--type-s6) * var(--type-scale));

  --h1-font-color:        var(--headline-font-color, currentColor);
  --h1-font-family:       var(--headline-font);
  --h1-font-size:         calc(var(--type-base) * var(--type-s5));
  --h1-font-weight:       700;
  --h1-font-lineheight:   1.15;
  --h1-font-textransform: none;

  --h2-font-color:        var(--headline-font-color, currentColor);
  --h2-font-family:       var(--headline-font);
  --h2-font-size:         calc(var(--type-base) * var(--type-s4));
  --h2-font-weight:       700;
  --h2-font-lineheight:   1.2;
  --h2-font-textransform: none;

  --h3-font-color:        var(--headline-font-color, currentColor);
  --h3-font-family:       var(--headline-font);
  --h3-font-size:         calc(var(--type-base) * var(--type-s3));
  --h3-font-weight:       600;
  --h3-font-lineheight:   1.3;
  --h3-font-textransform: none;

  --h4-font-color:        var(--headline-font-color, currentColor);
  --h4-font-family:       var(--copytext-font);
  --h4-font-size:         calc(var(--type-base) * var(--type-s2));
  /* 600, nicht 500 (2026-07-30, User-Entscheid): h4 war der einzige Ausreisser
     einer Skala, die bei h3, h5 und h6 durchgehend 600 traegt. Die Folge war,
     dass Karten-Ueberschriften (proc_*, benefit_*, story_*) sich per
     `font-weight: 700` in pattern.css selbst korrigierten — 87 Kopien gegen
     einen Wert. Mit 600 an dieser Stelle entfallen die Kopien in Stufe 3
     ersatzlos, und eine h4-Karten-Ueberschrift liest sich wieder als
     Ueberschrift und nicht wie Fliesstext daneben. */
  --h4-font-weight:       600;
  --h4-font-lineheight:   1.4;
  --h4-font-textransform: none;

  --h5-font-color:        var(--headline-font-color, currentColor);
  --h5-font-family:       var(--copytext-font);
  --h5-font-size:         calc(var(--type-base) * var(--type-s1));
  --h5-font-weight:       600;
  --h5-font-lineheight:   1.4;
  --h5-font-textransform: none;

  --h6-font-color:        var(--headline-font-color, currentColor);
  --h6-font-family:       var(--copytext-font);
  --h6-font-size:         var(--type-base);
  --h6-font-weight:       600;
  --h6-font-lineheight:   1.4;
  --h6-font-textransform: none;

  --bodytext-font-color:      currentColor;
  --bodytext-font-family:     var(--copytext-font);
  --bodytext-font-size:       1rem;
  --bodytext-font-weight:     400;
  --bodytext-font-lineheight: 1.65;
}

/* ── Body / Base ──────────────────────────────────────────────────────────── */
/* Both body.mypage (live site) and div.mypage (editor canvas) must get base styles */
body.mypage,
div.mypage {
  -webkit-text-size-adjust: none;
  /* Body-Typography über --bodytext-* Tokens, so wirkt ProjectSettings →
     Typography → Body (font-family/size/weight/lineheight) global. Color
     bleibt explizit --text-dark auf Body-Ebene, da --bodytext-font-color
     auf currentColor defaultet (für Paragraph-Inheritance in sc-*-Sektionen)
     — auf Body wäre das zirkulär. User-Body.Color trifft p-Elemente direkt. */
  font-family: var(--bodytext-font-family, var(--copytext-font));
  font-size: var(--bodytext-font-size, var(--font-size));
  font-weight: var(--bodytext-font-weight, 400);
  line-height: var(--bodytext-font-lineheight, 1.65);
  color: var(--text-dark);
  background-color: var(--color-bg);
}

/* ── Typography ───────────────────────────────────────────────────────────── */
/* Hyphens-Konvention für alle Überschriften:
   - hyphens: auto + -webkit-hyphens: auto (Safari)
   - overflow-wrap: break-word als Fallback wenn die Hyphen-Engine kein
     break-point findet (engl. "verylongwordwithoutspaces", oder bei
     CJK/zh/jp). hyphens allein lässt sehr lange Wörter über die Container-
     Kante laufen → Layout-Bruch auf Mobile.
   - Pflicht: html lang="de" (in renderHostPage gesetzt).
   - hyphenate-limit-chars: short-Hyphens vermeiden ("Ihr stärks-tes" wäre
     hässlich, "Nutzen-versprechen" gewünscht). 6 2 3 = mindestens 6 Zeichen
     in der ersten Silbe, 2 vor, 3 nach Bruch. */
.mypage h1, .mypage .h1,
.mypage h2, .mypage .h2,
.mypage h3, .mypage .h3 {
  hyphens: auto;
  -webkit-hyphens: auto;
  overflow-wrap: break-word;
  hyphenate-limit-chars: 6 2 3;
}
.mypage h1, .mypage .h1 {
  font-family: var(--h1-font-family);
  font-size: var(--h1-font-size);
  font-weight: var(--h1-font-weight);
  line-height: var(--h1-font-lineheight);
  color: var(--h1-font-color);
  margin: 0 0 0.5em;  /* Leiterstufe statt 0.55em (2026-08-10) */
}
.mypage h2, .mypage .h2 {
  font-family: var(--h2-font-family);
  font-size: var(--h2-font-size);
  font-weight: var(--h2-font-weight);
  line-height: var(--h2-font-lineheight);
  color: var(--h2-font-color);
  margin: 0 0 0.5em;
}
.mypage h3, .mypage .h3 {
  font-family: var(--h3-font-family);
  font-size: var(--h3-font-size);
  font-weight: var(--h3-font-weight);
  line-height: var(--h3-font-lineheight);
  color: var(--h3-font-color);
  margin: 0 0 0.5em;
}
.mypage h4, .mypage .h4 {
  font-family: var(--h4-font-family);
  font-size: var(--h4-font-size);
  font-weight: var(--h4-font-weight);
  line-height: var(--h4-font-lineheight);
  color: var(--h4-font-color);
  margin: 0 0 0.5em;
}
.mypage h5, .mypage .h5 {
  font-family: var(--h5-font-family);
  font-size: var(--h5-font-size);
  font-weight: var(--h5-font-weight);
  line-height: var(--h5-font-lineheight);
  color: var(--h5-font-color);
  margin: 0 0 0.45em;
}
.mypage h6, .mypage .h6 {
  font-family: var(--h6-font-family);
  font-size: var(--h6-font-size);
  font-weight: var(--h6-font-weight);
  line-height: var(--h6-font-lineheight);
  color: var(--h6-font-color);
  margin: 0 0 0.45em;
}
.mypage p  {
  /* Color über --bodytext-font-color (em-base :root default: currentColor)
     — ProjectSettings → Typography → Body → Color setzt die Var via
     html:root und greift damit überall, auch in sc-*-Sektionen. */
  color: var(--bodytext-font-color);
  /* Ohne `!important` (2026-07-30, Spec D1): das Flag hat jede Pattern-Regel an
     einem Absatz unwirksam gemacht — 48 `p { margin: 0 }`-Resets in pattern.css
     waren toter Code, der eine Absicht behauptete, die nie ausgeführt wurde
     (am DOM belegt: banner_top und benefit_checklist_avatars setzen margin 0,
     berechnet waren 20px). Die Projekt-Einstellung greift weiterhin überall, wo
     kein Pattern bewusst überschreibt — und ein Pattern, das überschreibt, tut
     es jetzt sichtbar statt vergeblich. */
  line-height: var(--bodytext-font-lineheight, 1.65);
  margin: 0 0 1.25em;
}
/* Letztes Kind lässt unten keine Luft — das ist eine Systemregel, kein
 * Pattern-Detail (Spec D2). Sie ersetzt den Großteil der 63 per-Pattern-Resets
 * („Absatz als letztes Element einer Karte/Zelle"). Bleibt nach dieser Regel
 * irgendwo ein Reset nötig, muss sein Kommentar sagen, warum die Stelle nicht
 * `:last-child` ist. */
.mypage p:last-child,
.mypage h1:last-child, .mypage h2:last-child, .mypage h3:last-child,
.mypage h4:last-child, .mypage h5:last-child, .mypage h6:last-child {
  margin-bottom: 0;
}
/* Eyebrow/Emphasis/Subline brauchen ihre eigenen Margins, ueberschreiben das
 * generische .mypage p { margin: 0 0 1.25em }. Bis Stufe 2 war dafuer
 * `!important` noetig, weil `.mypage p` selbst ein Flag trug. Seit dessen
 * Entfernung reicht Specificity 0,2,1 gegen 0,1,1 allein, das Flag ist
 * ueberfluessig (Stufe 4a, 2026-07-30). Gilt fuer alle drei Bloecke hier
 * (Eyebrow/Emphasis, Caption/Caption-sub, Subline). */
.mypage p.eyebrow,
.mypage p.emphasis {
  /* margin-bottom bewusst NICHT hier (2026-08-10). Diese Regel ist mit (0,2,1)
   * spezifischer als `.mypage .eyebrow` (0,2,0) und hat den Abstand dadurch
   * fuer alle <p>-Eyebrows entschieden — 84 Stueck blieben bei 0.6em, waehrend
   * die 111 div-basierten schon auf 1em standen. Genau der Split, den die
   * Vereinheitlichung heute frueh beseitigen sollte.
   * Jetzt gibt es EINE Quelle fuer den Eyebrow-Abstand: `.mypage .eyebrow`.
   * `.emphasis` faellt auf den gemeinsamen Block weiter oben zurueck (0.5rem);
   * die Rolle kommt auf der QA-Seite aktuell nullmal vor. */
  margin-top: 1em;
}
/* caption / caption-sub — generische Attributions-/Bildunterschrift-Absatzstile,
 * RTE-wählbar (Modell eyebrow/subline). `caption` = betonte Attributions-Zeile
 * (Name), `caption-sub` = gedämpfte Unterzeile (Rolle). Pro Pattern überschreibbar
 * via `.mypage .<pattern> .caption { … }`. Konsolidiert die frühere separate
 * `.caption`-Regel (war Duplikat). (Projekt B 2b/2c, 2026-07-24) */
.mypage .caption {
  display: block;
  font-size: 0.95em;
  font-weight: 600;
}
.mypage .caption-sub {
  display: block;
  font-size: 0.85em;
  font-weight: 400;
  /* WCAG-AA: kontrast-berechneter Muted-Ton statt opacity-Dimming. */
  color: var(--text-muted);
}
/* Zeilenabstand + Margins ueberschreiben `.mypage p` (0,1,1). Bis Stufe 2
 * war dafuer `!important` und der `p`-Prefix noetig, exakt wie bei
 * eyebrow/emphasis darueber: `.mypage p` setzte line-height UND margin
 * selbst mit `!important`, dagegen kam `.mypage .caption` (0,2,0) NICHT an —
 * Spezifität schlägt kein `!important`. Symptom vorher (gemessen an
 * team_5avatars, 2026-07-30): Name in 15,2px bekam 25,08px Zeilenhöhe (1,65
 * Fließtext-Maß) und 19px Abstand nach unten, obwohl hier 1,25 und 0 steht —
 * Name und Rolle standen dadurch wie zwei unabhängige Absätze statt als ein
 * Attributions-Block. Das `font-size: 0.95em` griff, weil es unbestritten ist;
 * genau diese Mischung machte den Fehler unauffällig.
 *
 * Seit Stufe 2 traegt `.mypage p` kein Flag mehr: `.mypage p.caption`
 * (0,2,1) gewinnt jetzt allein per Spezifitaet gegen `.mypage p` (0,1,1),
 * das Flag ist ueberfluessig (Stufe 4a, 2026-07-30).
 *
 * Werte: eng gesetzt, aber nicht gedrängt. Der Abstand Name→Rolle (0.15em)
 * ist bewusst kleiner als jeder Absatzabstand, damit die beiden Zeilen als
 * Einheit lesen; nach der Rolle folgt der normale Block-Abstand. */
.mypage p.caption {
  line-height: 1.25;
  /* 0.25em statt 0.15em (Abstands-Runde, 2026-08-10): dieselbe Enge, aber auf
   * der Leiterstufe (2.3px -> 3.8px). Hier ist `em` der RICHTIGE Massstab,
   * anders als beim Eyebrow: getrennt werden zwei fast gleich grosse Zeilen
   * (Name und Rolle), und die sollen als eine Einheit lesen. Der Abstand
   * bleibt deshalb bewusst der kleinste der Leiter. */
  margin: 0 0 0.25em;
}
/* Symmetrie zu p.caption-sub (Abstands-Runde, 2026-08-10). caption-sub hatte
 * diesen Reset seit jeher, caption nicht — und der generische
 * `.mypage p:last-child`-Reset greift hier NICHT, weil er mit (0,2,1) genauso
 * spezifisch ist wie `.mypage p.caption` und frueher in der Datei steht.
 * Folge: 117 von 138 Captions trugen als letztes Kind einen Rest von 2.28px,
 * der die Karten-Unterkanten uneinheitlich machte. */
.mypage p.caption:last-child {
  margin-bottom: 0;
}
.mypage p.caption-sub {
  line-height: 1.3;
  /* Vorher hart 0 (58f9d96) — richtig, wenn caption-sub das letzte Element
     ist (voice_single, team_5avatars), aber zu eng, wenn danach noch
     Fliesstext folgt (team_leadership_bio: Rolle direkt gefolgt von
     Bio-Text — Feinkorrektur-Fund aus Stufe 2, tools/typography-baseline-
     after.json feinkorrekturKandidatenStufe3[1]). team_leadership_bio
     konnte das damals nicht selbst loesen: sein eigener margin-bottom:
     0.85rem in pattern.css verlor gegen dieses `!important`, egal welche
     Spezifitaet er trug (die Regel ist seither aus dem Pattern entfernt).
     Deshalb hier (EINZIGE Ausnahme von "em-base in Stufe 3 nicht anfassen",
     Plan 1b): caption-sub bekommt einen eigenen kleinen Default-Abstand,
     das :last-child-Reset aus Stufe 2 (Spec D2, oben in dieser Datei) nimmt
     ihn wieder weg, wenn caption-sub tatsaechlich das letzte Kind ist —
     dafuer die eigene, spezifischere :last-child-Regel direkt danach
     (noetig, weil `.mypage p:last-child` und `.mypage p.caption-sub` gleich
     spezifisch sind, 0,2,1 — ohne die zusaetzliche Spezifitaet wuerde die
     Quellreihenfolge entscheiden und caption-sub gewaenne immer, auch wenn
     es letztes Kind ist).

     Stufe 4a (2026-07-30): `!important` hier und bei :last-child entfernt.
     `.mypage p.caption-sub` (0,2,1) schlaegt `.mypage p` (0,1,1) und
     `.mypage p.caption-sub:last-child` (0,3,1) schlaegt `.mypage p:last-child`
     (0,2,1) jeweils allein per Spezifitaet — die :last-child-Tiebreak-Logik
     oben ist davon unberuehrt, sie gilt unabhaengig vom Flag. */
  margin-bottom: 0.75em;  /* Leiterstufe statt 0.85em (2026-08-10) */
}
.mypage p.caption-sub:last-child {
  margin-bottom: 0;
}
.mypage p.subline,
.mypage p.h1sub,
.mypage p.h2sub,
.mypage p.h3sub,
.mypage p.h4sub {
  margin-top: 0.5em;
  margin-bottom: 1.25em;
}
/* Kein Gegenspieler gefunden (Repo-weite Suche ueber alle pattern.css/
 * molecule.css, Stufe 4a, 2026-07-30): kein Pattern/Molecule setzt
 * font-weight auf strong/b bzw. margin-left auf ol/ul mit gleicher oder
 * niedrigerer Spezifitaet als `.mypage b/strong` bzw. `.mypage ol/ul`
 * (0,1,1). Die einzigen gefundenen Ueberschreibungen (z.B. `.bca-social
 * strong`, `.gcont_strip_3icons_left .contact-text strong`) sind mit
 * (0,3,1) ohnehin spezifischer und haetten auch ohne dieses Flag gewonnen.
 * War also reine Vorsicht, entfernt. */
.mypage b, .mypage strong { font-weight: 700; }
/* Ohne `!important` (Stufe 4c): (0,1,1) schlaegt den globalen Reset (0,1,0). */
.mypage i, .mypage em    { font-style: italic; }
.mypage ol, .mypage ul   { margin-left: 1.75rem; }
/* ── Listen-Rhythmus ───────────────────────────────────────────────────────
 * Punkte einer Liste gehoeren zusammen. Ihr Abstand muss deshalb deutlich
 * kleiner sein als der Absatzabstand (1.25em) — sonst liest die Liste als
 * Folge einzelner Zeilen statt als ein Block. 0.5em ist die Leiterstufe
 * dafuer: klar enger als ein Absatz, weit genug fuer Ein- und Mehrzeiler.
 *
 * Bewusst `li + li` statt Padding an jedem `li` (2026-08-10). Symmetrisches
 * Padding legt auch UEBER den ersten und UNTER den letzten Punkt Luft, die zu
 * keinem Rhythmus gehoert — die Aussenkanten der Liste verschwimmen, und der
 * Abstand zum umgebenden Text wird unkontrollierbar. Mit `li + li` entsteht
 * der Abstand nur ZWISCHEN den Punkten; die Liste hat saubere Kanten und
 * traegt ihren Abstand nach aussen ueber die ul/ol-Margins.
 *
 * Vorher setzte jedes Pattern das selbst und in drei verschiedenen Werten:
 * pricing-card 0.4rem (12.8px zwischen den Punkten), benefit_image_left
 * 0.5rem (16px), text_with_header gar nichts. */
.mypage li + li { margin-top: 0.5em; }
.mypage small            { font-size: 0.8125rem; color: var(--text-muted); }

/* ── Font-Size Utilities (txt-*) ─────────────────────────────────────────────
 * Reine Größenklassen — kein weight, keine Familie, keine Farbe.
 * Referenzieren die gleichen Typ-Skala-Tokens wie h1–h6, damit
 * ProjectSettings → TypeBase/TypeScale auch txt-* Elemente mitskaliert.
 * Werden im TipTap-RTE über das "Größe"-Dropdown gesetzt und entfernt.
 * Default (keine Klasse) = "Auto" = erbt Kontext-Größe (body/section).
 * ─────────────────────────────────────────────────────────────────────────── */
.mypage .txt-xs   { font-size: 0.75rem !important; }
.mypage .txt-sm   { font-size: 0.875rem !important; }
.mypage .txt-base { font-size: var(--type-base) !important; }
.mypage .txt-lg   { font-size: var(--h5-font-size) !important; }
.mypage .txt-xl   { font-size: var(--h4-font-size) !important; }
.mypage .txt-2xl  { font-size: var(--h3-font-size) !important; }
.mypage .txt-3xl  { font-size: var(--h2-font-size) !important; }
.mypage .txt-4xl  { font-size: var(--h1-font-size) !important; }
.mypage .txt-5xl  { font-size: calc(var(--type-base) * var(--type-s6)) !important; }
.mypage .txt-6xl  { font-size: calc(var(--type-base) * var(--type-s7)) !important; }

/* ── Brand-Text — Wortmarken-Typografie (Logo-Begleittext, Markenname) ────
 * Eigene Schrift-Achse (--brand-font). Im Editor via TipTap-Mark "BRAND"
 * gesetzt, manuell via class="brand-text". Inline-Element (span/strong-
 * kompatibel) damit es in normalen Text-Flow eingebettet werden kann. */
.mypage .brand-text {
  font-family: var(--brand-font, var(--headline-font));
  letter-spacing: 0.04em;
}

/* ── Eyebrow / Emphasis ───────────────────────────────────────────────────── */
.mypage .emphasis,
.mypage .eyebrow {
  color:           var(--emphasis-font-color);
  font-family:     var(--emphasis-font-family);
  font-size:       var(--emphasis-font-size);
  font-weight: var(--emphasis-font-weight);
  line-height:     var(--emphasis-font-lineheight);
  text-transform:  var(--emphasis-font-textransform);
  letter-spacing:  var(--emphasis-letter-spacing);
  display: block;
  /* Atemraum: immer ca. eine Zeile Abstand oben/unten — auch wenn der
   * Eyebrow das erste Element im Container ist. Frueher gab es hier einen
   * :first-child{margin-top:0}-Reset (Annahme: section-py-N liefert das
   * Polster schon), aber bei fullbleed-Hero / vh-N-Sections ohne py klebt
   * der Eyebrow sonst direkt unter der Section-Oberkante / vertikalen
   * Zentrierung — visuell zu kurz. 1em ist universell vertraeglich.
   * Wer's enger braucht, overridet pro Section. */
  margin-top: 1em;
  margin-bottom: 0.5rem;
}

/* ── Kopfblock einer Section ───────────────────────────────────────────────
 * `.section-head` ist die kanonische Klasse fuer den Block aus Eyebrow,
 * Ueberschrift und optionaler Subline, der ueber dem Inhalt einer Section
 * steht. Sie definiert den Abstand zum Inhalt an EINER Stelle.
 *
 * Warum es sie braucht (gemessen 2026-08-10 ueber 44 Patterns): vorher war
 * dieser Abstand nirgends definiert. Jedes Pattern meldete
 * padding-bottom 0, margin-bottom 0, gap normal — die Luecke entstand
 * ausschliesslich als Nebenprodukt dessen, was zufaellig das letzte
 * Textelement im Kopf war:
 *     endet auf p.subline  -> 23px   (30 Patterns)
 *     endet auf h2         ->  0px   (11 Patterns, Inhalt klebte an der
 *                                     Ueberschrift — der :last-child-Reset
 *                                     nimmt der Ueberschrift ihren Margin)
 *     Sonderstruktur       -> 55px   (3 Patterns)
 * Drei Patterns loesten dieselbe Aufgabe auf drei Arten, keine davon als
 * Regel formuliert.
 *
 * Der zweite Teil der Regel ist genauso wichtig wie der erste: der Margin
 * des letzten Textelements MUSS auf 0, sonst addiert er sich zum
 * Block-Abstand statt ersetzt zu werden (der Kopf-Layer ist inline-block,
 * bildet also einen eigenen BFC — die Margins kollabieren nicht).
 * `.mypage p:last-child` allein reicht dafuer nicht: es ist mit (0,2,1)
 * genauso spezifisch wie `.mypage p.subline` und steht frueher in der Datei,
 * die Subline behaelt ihre 1.25em. Mit dem `.section-head`-Praefix sind es
 * (0,3,1) und der Reset gewinnt.
 *
 * Der Wert liegt auf der Layout-Skala (rem), nicht auf der Typografie-Skala
 * (em): es ist ein Abstand zwischen zwei Bloecken, kein Zeilenabstand.
 * 2rem entspricht gap-4 — dasselbe Mass, das drei Patterns vorher schon
 * von Hand gesetzt hatten. */
/* Der Abstand haengt daran, dass der Kopf ueberhaupt etwas enthaelt. Der
 * Anwender darf im Editor jedes einzelne Element entfernen — Eyebrow,
 * Ueberschrift, Subline — oder den ganzen Block. `:has()` sorgt dafuer, dass
 * ein leergeraeumter Kopf keine 2rem Nichts hinterlaesst. */
.mypage .section-head:has(h1, h2, h3, h4, p, .eyebrow) {
  margin-bottom: var(--section-head-gap, 2rem);
}
/* Steht der Kopf allein in der Section (Inhalt entfernt), braucht er keine
 * Luft nach unten — das Section-Padding uebernimmt. */
.mypage .section-head:last-child {
  margin-bottom: 0;
}
/* Das jeweils letzte Textelement gibt seinen eigenen Abstand ab, egal welches
 * es gerade ist. Deshalb sind hier ALLE moeglichen Schlusselemente gelistet:
 * loescht der Anwender die Subline, endet der Kopf auf der Ueberschrift;
 * loescht er die Ueberschrift, endet er auf dem Eyebrow. Der Eyebrow ist
 * dabei meist kein <p>, sondern ein div[type="rich"] — deshalb die
 * eigene Zeile fuer `.eyebrow`. */
.mypage .section-head p:last-child,
.mypage .section-head h1:last-child,
.mypage .section-head h2:last-child,
.mypage .section-head h3:last-child,
.mypage .section-head h4:last-child,
.mypage .section-head .eyebrow:last-child {
  margin-bottom: 0;
}

/* ── Layout ────────────────────────────────────────────────────────────────── */
.mypage .max-w,
.mypage .section .max-w,
.mypage .footerSection .max-w { display: block; max-width: var(--max-w); margin-left: auto; margin-right: auto; }

/* ── Text-Alignment ────────────────────────────────────────────────────────
 * Konvention: text-align DEFAULT = left. Sections / Patterns die ihre
 * Inhalte zentrieren wollen, setzen explizit `.text-center` auf den
 * Wrapper. Headings, Eyebrows, Sublines erben — kein zentral verdrahteter
 * Center-Default für h1/h2/h3.
 *
 * Utility-Klassen:
 *   .text-left / .text-center / .text-right  — direkte Ausrichtung
 *
 * Migration-Hinweis (2026-06-05): Vorher wurden h1/h2/h3 + .eyebrow +
 * .emphasis hier standardmäßig zentriert. Diese Defaults sind entfernt —
 * Pattern-Templates müssen die zentrierte Variante explizit über
 * `.text-center` auf einem Wrapper-Element ausdrücken. */
.mypage section[type="layer"]:not(.text-center):not(.text-right):not(.text-left) {
  text-align: inherit;
}
.mypage .text-left   { text-align: left; }
.mypage .text-center { text-align: center; }
.mypage .text-right  { text-align: right; }

/* ── Eyebrow — steht VOR der Überschrift ──────────────────────────────────── */
/* Ein geteilter Stil für alle Ebenen. Override: .mypage .eyebrow { ... }      */
.mypage .eyebrow {
  color:          var(--eyebrow-font-color);
  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);
  display: block;
  /* 1em (Abstands-Runde, 2026-08-10). Der Weg dahin in zwei Schritten, weil der
   * zweite den ersten korrigiert:
   *
   * (a) Derselbe Baustein bekam je nach Markup zwei verschiedene Abstaende.
   *     Am DOM gezaehlt: 111 Eyebrows sind `div[type="rich"]` (RTE-Slots) und
   *     landeten ueber diese Regel bei 6.4px; 100 sind `<p>` und bekamen ueber
   *     `.mypage p.eyebrow` (0,2,1) 0.6em = 7.2px. Gleiche Rolle, gleiche
   *     Optik, unterschiedlicher Abstand — nur weil der eine Slot ein Absatz
   *     ist und der andere nicht.
   * (b) rem koppelt den Abstand an die Wurzel, em an die eigene Schriftgroesse.
   *     Der Eyebrow ist ein typografischer Baustein; sein Abstand soll
   *     mitwachsen, wenn ein Tenant --eyebrow-font-size aendert. Der Rest des
   *     Vertikalrhythmus (h1-h6, p, subline, caption) rechnet ebenfalls in em;
   *     die Utilities (py-N, gap-N) bleiben bewusst bei rem/--spacing.
   *
   * (c) Der Wert war zunaechst 0.6em — der damals dominierende. Am gerenderten
   *     Bild war er zu eng, und der Grund ist systematisch: dieser Abstand
   *     trennt ein 12px-Element von einer 33-56px-Ueberschrift, gemessen wird
   *     er aber in em der KLEINEREN Schrift. 0.6em sind 7.2px — weniger als
   *     die Versalhoehe der Ueberschrift daneben. Der Eyebrow klebt dann an
   *     ihr, statt als eigene Registerzeile zu lesen.
   *
   *     Faustregel, die daraus folgt und ueber diesen Fall hinausgeht:
   *     `em` ist der richtige Massstab, wenn die beiden getrennten Elemente
   *     AEHNLICH GROSS sind (Name/Rolle in p.caption etwa). Bei stark
   *     unterschiedlichen Groessen fuehrt die em-Groesse des kleineren in die
   *     Irre — der Abstand faellt zu klein aus.
   *
   *     1em = 12px ist die Zeilenhoehe des Eyebrows selbst: genug, dass das
   *     Auge ihn als Vorspann erkennt, wenig genug, dass er zur Ueberschrift
   *     gehoert. Das Verhaeltnis zum Abstand Kopfblock->Inhalt
   *     (--section-head-gap, 32px) liegt damit bei rund 1:2.7 — der Kopf liest
   *     als eine Gruppe und ist klar vom Inhalt abgesetzt. Bei 0.6em waeren es
   *     1:4.4 gewesen, und die Gruppe faellt innerlich auseinander. */
  margin-bottom: 1em;
}

/* ── Per-Level Subtitle Elemente — stehen NACH der Überschrift ─────────────── */
/* Jede Ebene erbt --sub-* von der zentralen Einstellung.                       */
/* Pro-Override im Custom CSS: .mypage .h2sub { color: var(--h2sub-font-color) } */

.mypage .h1sub {
  color:          var(--h1sub-font-color);
  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);
  display: block;
  margin-top: 0.5rem;
}
.mypage .h2sub {
  color:          var(--h2sub-font-color);
  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);
  display: block;
  margin-top: 0.4rem;
}
.mypage .h3sub {
  color:          var(--h3sub-font-color);
  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);
  display: block;
  margin-top: 0.3rem;
}
.mypage .h4sub {
  color:          var(--h4sub-font-color);
  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);
  display: block;
  margin-top: 0.2rem;
}

.mypage .clearfix    { clear: both; }
.mypage .float-start { float: left; }
.mypage .float-end   { float: right; }

/* ── Border-Radius — Tailwind-aligned rounded-* scale ────────────────────── */
.mypage .rounded-none { border-radius: 0; }
.mypage .rounded-sm   { border-radius: 0.375rem; }  /* 6px  */
.mypage .rounded      { border-radius: 0.5rem; }    /* 8px  — default alias */
.mypage .rounded-md   { border-radius: 0.75rem; }   /* 12px */
.mypage .rounded-lg   { border-radius: 1rem; }      /* 16px */
.mypage .rounded-xl   { border-radius: 1.5rem; }    /* 24px */
.mypage .rounded-2xl  { border-radius: 2rem; }      /* 32px */
.mypage .rounded-3xl  { border-radius: 3rem; }      /* 48px */
.mypage .rounded-full { border-radius: 9999px; }

/* ── Blockquote ───────────────────────────────────────────────────────────── */
/* Ohne `!important` (Stufe 4c, 2026-07-30): der Selektor `.mypage blockquote`
 * ist (0,1,1) und schlaegt damit den globalen Reset `.mypage, .mypage *`
 * (0,1,0) aus render-struct.css schon per Spezifitaet. Die Flags waren reine
 * Vorsicht — nachgerechnet, nicht vermutet. */
.mypage blockquote {
  border-left: 4px solid var(--primary-base);
  margin: 0;
  padding: 0.75rem 0 0.75rem 1.25rem;
}
.mypage blockquote p {
  margin: 0;
  font-size: 1.0625rem;
  font-style: italic;
  line-height: 1.55;
}

/* ── Buttons ──────────────────────────────────────────────────────────────── */
.mypage a.btn,
.mypage .btn {
  display:          inline-flex;
  align-items:      center;
  justify-content:  center;
  gap:              0.5rem;
  padding:          0.7rem 1.75rem;
  border-radius:    0.375rem;
  font-family:      var(--copytext-font);
  font-size:        0.9375rem;
  font-weight:      500;
  text-decoration:  none;
  cursor:           pointer;
  border:           none;
  transition:       background-color 0.18s ease, color 0.18s ease, transform 0.12s ease;
}
.mypage a.btn:hover,
.mypage .btn:hover {
  transform: translateY(-1px);
}

/* CTA button (sc-cta) — cta-bg-safe ≥4.5:1 für weißen Text (Task 7) */
.mypage .btn.sc-cta {
  background-color: var(--cta-bg-safe, var(--primary-base));
  color:            var(--text-light);
}
.mypage .btn.sc-cta:hover {
  background-color: var(--primary-dark);
  color:            var(--text-light);
}

/* ── Default Anchor ───────────────────────────────────────────────────────
 * Generic <a> picks up its container's text color (so a link in a dark
 * section is light, a link in a light section is dark). Underline kept
 * for affordance, lifted on hover. .btn / .anchor / .announce-link
 * patterns override below as needed.
 */
.mypage a {
  /* --link-color: wenn gesetzt, überschreibt "inherit" für Link-Textfarbe.
     Fallback bleibt inherit = Sectionsfarbe (Standard-Verhalten). */
  color:                     var(--link-color, inherit);
  text-decoration:           underline;
  text-decoration-color:     var(--link-underline-color);
  text-underline-offset:     2px;
  text-decoration-thickness: 1px;
  transition:                text-decoration-color 0.12s ease, text-decoration-thickness 0.12s ease;
}
.mypage a:hover {
  text-decoration-color:     var(--link-hover-color);
  text-decoration-thickness: 2px;
}
/* Inline-substituierte Brand-/Utility-Icons (vom Renderer eingefügt für
   `<span class="icon icon-NAME"></span>` Patterns).
   Default-Größe = aktuelles Font, vertikal an Baseline. Patterns können
   per spezifischerem Selector größenanpassen (z.B. .team-socials svg.icon
   → width:1rem; height:1rem;).
 */
.mypage svg.icon {
  width: 1em;
  height: 1em;
  vertical-align: -0.125em;
  fill: currentColor;
}

/* Link-Type Icons (gesetzt vom TipTap-Link-Editor via data-link-type).
 * Dekorativ: currentColor, dezent transparent, Hover-Bewegung in Pfeil-
 * richtung + text-decoration:none (Pfeil wird nicht unterstrichen). */
.mypage a[data-link-type]::after {
  display: inline-block;
  margin-left: 0.3em;
  font-size: 0.9em;
  line-height: 1;
  text-decoration: none;
  vertical-align: baseline;
  color: currentColor;
  opacity: 0.7;
  transition: transform 160ms ease, opacity 160ms ease;
}
.mypage a[data-link-type]:hover::after { opacity: 1; }
.mypage a[data-link-type="external"]::after  { content: "↗"; }
.mypage a[data-link-type="external"]:hover::after { transform: translate(2px, -2px); }
.mypage a[data-link-type="download"]::after  { content: "↓"; }
.mypage a[data-link-type="download"]:hover::after { transform: translateY(2px); }
.mypage a[data-link-type="email"]::after     { content: "✉"; }
.mypage a[data-link-type="phone"]::after     { content: "☎"; }
.mypage a[data-link-type="anchor"]::after    { content: "↓"; }
.mypage a[data-link-type="anchor"]:hover::after { transform: translateY(2px); }
.mypage a[data-link-type="internal"]::after  { content: "→"; }
.mypage a[data-link-type="internal"]:hover::after { transform: translateX(3px); }

/* Anchor/link button */
.mypage a.anchor {
  color:           var(--accent-on-light, var(--primary-base));   /* WCAG-AA ≥4.5:1 auf hellem BG (Task 7) */
  text-decoration: none;
  font-weight:     500;
}
.mypage a.anchor:hover {
  text-decoration: underline;
  text-underline-offset: 3px;
}

/* ── Auto-Alternating Section Backgrounds ─────────────────────────────────
 * Sections ohne explizite Farbwahl (kein sc-*) wechseln automatisch
 * zwischen weiß (ungerade) und hellgrau (gerade).
 *
 * HINWEIS: Die Seiten-Sections sind Grandchildren von .mypage (EditorPage.tsx
 * packt alle sections in einen äußeren section.col-12.center-Wrapper).
 * → KEIN > Combinator, stattdessen Depth-2: .mypage > section > section
 *
 * WICHTIG: nth-of-type statt nth-child — Editor-Overlays (section-menu-bar,
 * insert-strip) sind <div>-Elemente und werden vom Zähler ignoriert.
 * ─────────────────────────────────────────────────────────────────────────── */

/* (Removed) Auto-band coloring (odd=white / even=gradient on inner
 * sections without sc-*). Was a workaround for the OLD model where
 * outer-section grouped multiple inner bands and the pattern had no
 * intrinsic backdrop. Under the post-2026-05 "section-IS-the-band"
 * architecture every Abschnitt's root carries its own optional sc-*
 * (or stays transparent), and inner bands of refactored content
 * sections (header + content) MUST stay transparent so the user's
 * single sc-choice on root determines the look. The auto-rule
 * stamped a hard-white header strip and a grey gradient content
 * strip onto every non-themed section — surprising side-effect.
 *
 * If a tenant ever wants alternating zebra-striping, they can opt
 * in via a class like .zebra on the root + their own selector. */


/* ── Spacing-Prinzip: pd-B für innere Elemente ─────────────────────────────
 * Innere Elemente verwenden pd-B (nur unten) statt pd-Y (oben+unten).
 * Der Container-Layer (pd-3Y / pd-2Y) trägt den oberen Randabstand.
 * Die Datenmigration hat alle pd-Y → pd-B in den JSON-Daten umgestellt.
 * Eine globale :first-child { padding-top: 0 } Regel ist daher NICHT nötig
 * und würde den pd-3Y-Top des Content-Wrappers fälschlicherweise nullen.
 * ─────────────────────────────────────────────────────────────────────── */

/* ── Color Schemes (sc-*) ────────────────────────────────────────────────── */

/* sc-dark */
.mypage .sc-dark {
  background-color: var(--shade-dark-base) !important;
  color: var(--text-light);
  --text-muted: var(--text-muted-on-dark, rgba(255,255,255,0.82));
  /* Headline-Farben an die (helle) Section-Farbe koppeln. Ohne diesen Reset
     schlägt ein per ProjectSettings gesetzter html:root-Wert (--headline-font-
     color, z.B. dunkles Markenbraun) durch → h1-6 dark-on-dark (WCAG-Bruch).
     Wichtig: --h_N_-font-color = var(--headline-font-color, …) wird bereits auf
     .mypage aufgelöst und vererbt sich als fertiger Wert; ein bloßer Reset von
     --headline-font-color hier greift daher NICHT — die --h_N_-font-color
     müssen direkt neu gesetzt werden, damit sie auf currentColor (= text-light)
     re-evaluieren. (2026-07-24) */
  --headline-font-color: currentColor;
  --h1-font-color: currentColor;
  --h2-font-color: currentColor;
  --h3-font-color: currentColor;
  --h4-font-color: currentColor;
  --h5-font-color: currentColor;
  --h6-font-color: currentColor;
}
/* Direkte color-Overrides auf sc-dark h1-3 + p ENTFERNT — alle Typography-
   Farben fließen jetzt über das Token-System:
     • Headings via --h_N_-font-color (em-base :root default: currentColor,
       auf dunklen Sektionen zusätzlich via --headline-font-color: currentColor
       oben zurückgesetzt, damit ProjectSettings-Headline-Farbe nicht durchschlägt)
     • Body   via --bodytext-font-color (em-base :root default: currentColor)
   currentColor erbt sich von .sc-dark { color: var(--text-light) } → h1
   und p werden automatisch hell, ohne dass wir die Werte zweimal setzen.
   Konsequenz: User-Settings aus ProjectSettings (Eyebrow.Color, Body.Color)
   landen via BE-injected html:root und greifen auch in dunklen Sektionen. */

/* sc-light */
.mypage .sc-light {
  background-color: var(--shade-light-base) !important;
  color: var(--text-dark);
}

/* sc-pri */
.mypage .sc-pri {
  background-color: var(--primary-base) !important;
  color: var(--text-light);
  --text-muted: var(--text-muted-on-primary, rgba(255,255,255,0.82));
  /* Headline-Farben auf currentColor (= text-light) — s. sc-dark. */
  --headline-font-color: currentColor;
  --h1-font-color: currentColor;
  --h2-font-color: currentColor;
  --h3-font-color: currentColor;
  --h4-font-color: currentColor;
  --h5-font-color: currentColor;
  --h6-font-color: currentColor;
}

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

/* sc-sec */
.mypage .sc-sec {
  background-color: var(--secondary-base) !important;
  color: var(--text-light);
  --text-muted: var(--text-muted-on-secondary, rgba(255,255,255,0.82));
  /* Headline-Farben auf currentColor (= text-light) — s. sc-dark. */
  --headline-font-color: currentColor;
  --h1-font-color: currentColor;
  --h2-font-color: currentColor;
  --h3-font-color: currentColor;
  --h4-font-color: currentColor;
  --h5-font-color: currentColor;
  --h6-font-color: currentColor;
}

/* sc-sec-l */
.mypage .sc-sec-l {
  background-color: var(--secondary-light) !important;
  color: var(--text-dark);
}

/* sc-acc */
.mypage .sc-acc {
  background-color: var(--contrast-base) !important;
  color: var(--text-light);
  --text-muted: var(--text-muted-on-accent, rgba(0,0,0,0.7));
}

/* Sub-/Subline-Farbkette (--sub-font-color → --hNsub-font-color → .subline/.hNsub)
 * wird im :root einmalig zu on-light substituiert und vererbt konkret — die
 * sc-*-Override von --text-muted erreicht sie NICHT (CSS-var-Substitution
 * passiert am Deklarations-Element). Darum die konsumierte Ebene (hNsub) pro
 * farbigem/dunklem Kontext direkt an das kontext-remappte --text-muted binden.
 * ProjectSettings-Sub-Farbe gilt weiter auf sc-light; auf farbigen Sektionen
 * gewinnt der WCAG-sichere Kontext-Ton. */
.mypage .sc-dark, .mypage .sc-pri, .mypage .sc-sec, .mypage .sc-acc {
  --sub-font-color:   var(--text-muted);
  --h1sub-font-color: var(--text-muted);
  --h2sub-font-color: var(--text-muted);
  --h3sub-font-color: var(--text-muted);
  --h4sub-font-color: var(--text-muted);
}

/* sc-acc-l */
.mypage .sc-acc-l {
  background-color: var(--contrast-light) !important;
  color: var(--text-dark);
}

/* ── Glass Modifiers ─────────────────────────────────────────────────────
 * Semi-transparent box ON TOP of any background. Use on cards / panels
 * inside hero sections to keep the underlying image partially visible
 * while remaining readable. Composable with `.card`, padding utilities,
 * `.glass-frosted` (backdrop-blur) and any `.text-*` color helper.
 *
 * Sibling family `.overlay-*` (in fullbleed.css) does the same job at
 * the SECTION level via a ::before pseudo. Same opacity ladder so design
 * intent matches across both families.
 *
 * Opacity ladder:
 *   solid base:    dark 70 % / light 85 %
 *   gradient top:  dark 85→55 % / light 92→72 %
 *   primary tint:  75 % of brand color
 * ───────────────────────────────────────────────────────────────────── */
/* Glass-Tinten — Reihenfolge weiß → rauch → dunkel, jeweils mit korrektem
   Foreground. Opacity reduziert (0.55–0.65) damit der Hintergrund deutlich
   durchscheint; mit .glass-frosted wird daraus echtes Rauchglas. */
.mypage .glass-light       { background: rgba(255,255,255,0.65); color: var(--text-dark); }
.mypage .glass-smoke       { background: rgba(40,46,56,0.45);    color: var(--text-light); }
.mypage .glass-dark        { background: rgba(0,0,0,0.55);       color: var(--text-light); }
.mypage .glass-light-fade  { background: linear-gradient(180deg, rgba(255,255,255,0.72) 0%, rgba(255,255,255,0.42) 100%); color: var(--text-dark); }
.mypage .glass-dark-fade   { background: linear-gradient(180deg, rgba(0,0,0,0.70) 0%, rgba(0,0,0,0.35) 100%);            color: var(--text-light); }
.mypage .glass-pri         { background: color-mix(in srgb, var(--primary-base)  60%, transparent); color: var(--text-light); }
.mypage .glass-pri-l       { background: color-mix(in srgb, var(--primary-light) 70%, transparent); color: var(--text-dark);  }
.mypage .glass-sec         { background: color-mix(in srgb, var(--secondary-base) 60%, transparent); color: var(--text-light); }
.mypage .glass-sec-l       { background: color-mix(in srgb, var(--secondary-light) 70%, transparent); color: var(--text-dark);  }
.mypage .glass-acc         { background: color-mix(in srgb, var(--contrast-base) 60%, transparent); color: var(--text-dark);  }
.mypage .glass-acc-l       { background: color-mix(in srgb, var(--contrast-light) 70%, transparent); color: var(--text-dark);  }

/* Orthogonal modifier — adds frosted-glass blur to any glass-* or overlay-*
   surface. Wrap with @supports so older browsers fall back gracefully. */
@supports (backdrop-filter: blur(1px)) or (-webkit-backdrop-filter: blur(1px)) {
  .mypage .glass-frosted {
    -webkit-backdrop-filter: blur(10px);
            backdrop-filter: blur(10px);
  }
}

/* ── Menu-Slots & Nav-Items ──────────────────────────────────────────────
 * Slots mit slot="menu" rendern entweder:
 *   - <a>-Tags (live, vom BE-Resolve oder Slot-Override)
 *   - <span class="nav-demo">…</span> (Demo-Fallback, wenn weder Items
 *     noch Master.Nav vorhanden — Editor-Sichtbarkeit)
 * Beide bekommen das gleiche Inline-Flex-Layout damit ein Slot-Container
 * im Editor mit Demo-Spans visuell identisch zum Live-Render mit Items
 * aussieht (Lesbarkeit + Konsistenz).
 *
 * `.menu-list` ist die Default-Klasse für das Slot-Container-Element.
 * Pattern-Autoren können sie überschreiben (footer-menu, head-nav-slot
 * etc.) — die hier definierten Item-Styles greifen aber überall wo
 * der Slot menu* heißt, via Attribute-Selector. */
/* Selector-Hinweis: bewusst OHNE .mypage-Prefix damit die Regel auch im
 * Editor-Preview (/api/render-editable ohne mypage-Wrapper) greift.
 * Attribute-Selector [slot=menu*] ist spezifisch genug — kein Konflikt
 * mit dem Web-Components-slot-Use, weil em* keine Shadow-DOM-Slots nutzt. */
/* Menu-Slots:
 *   slot="menu-h" — horizontal (Top-Nav im Header)
 *   slot="menu-v" — vertical (Footer-Kolumnen, Sidebar)
 *   menu-h_2, menu-v_2, ... — sekundäre Slots in derselben Pattern
 *
 * Legacy `slot="menu"` und `menu_N` ohne Direction-Suffix werden NICHT mehr
 * unterstützt — alle Patterns sind migriert (Commit "footer menu-slots
 * vertikal stapeln"). */
[slot="menu-h"],
[slot^="menu-h_"],
[slot="menu-v"],
[slot^="menu-v_"] {
  /* `!important` ist hier LASTTRAGEND — Stufe 4d-1, am DOM belegt. Ich hatte es
     entfernt mit der Begruendung "kein Gegenspieler gefunden"; das Gate hat den
     Fehler gefangen: ohne Flag fielen 23 von 31 Menu-Slots auf `display: block`,
     naemlich genau die Footer-Slots (`slot="menu-v"`). Die sollen flex-column
     sein — der Block weiter unten (`[slot="menu-v"] { flex-direction: column }`)
     setzt selbst KEIN display und verlaesst sich auf dieses `flex`. Ohne das
     Flag stapeln die Footer-Kolumnen zwar zufaellig aehnlich, verlieren aber
     `gap` und `align-items`.
     GEGENSPIELER IDENTIFIZIERT (2026-08-10) — der offene Punkt ist geschlossen.
     Es ist `.mypage div[type='rich'] { display: block }` aus
     `css/render-struct.css`, Spezifitaet (0,2,1). Das deckt sich genau mit dem
     damaligen Injektions-Test („(0,2,0) verliert, (0,3,0) gewinnt"). Gefunden
     ueber eine CSSOM-Introspektion, die nicht nach der Regel suchte, sondern
     alle Regeln durchging, die auf einen konkreten Menue-Slot MATCHEN
     (`el.matches(r.selectorText)`) — die frueheren Versuche haben nach dem
     Selektor gesucht statt nach dem Element.
     Das Flag BLEIBT: es ohne Flag zu loesen braeuchte entweder ein `.mypage`
     davor (dann greift die Regel nicht mehr im Editor-Preview ohne
     mypage-Wrapper — genau das war der Grund fuer den fehlenden Prefix) oder
     einen Gleichstand bei (0,2,1), der nur ueber die Dateireihenfolge
     entschieden wuerde. Ein sichtbares Flag ist robuster als eine versteckte
     Abhaengigkeit von der Ladereihenfolge.
     FOLGE FUER PATTERN-AUTOREN: wer einen Menue-Slot verstecken will (z.B. das
     Mobil-Menue der header-nav-Molecule), braucht dafuer ebenfalls ein Flag —
     Flag gegen Flag entscheidet die Spezifitaet, und (0,3,0) schlaegt die
     (0,1,0) hier. */
  display: flex !important;
  align-items: flex-start;
  gap: 0.5rem 1.25rem;
  /* Straffe Zeilenhöhe: falls die Nav (unerwünscht) mehrzeilig umbricht,
   * sollen die Zeilen kompakt bleiben statt mit Fließtext-line-height (~1.5)
   * auseinanderzufallen. */
  line-height: 1.2;
  color: var(--menu-link-color, inherit);
  /* unset Schrift → Marken-Headline-Font (brandiger Nav-Default); Gewicht/
   * Transform erben Nav-Default (nicht Heading-700). Menü-Styling gewinnt. */
  font-family: var(--menu-font, var(--headline-font, inherit));
  font-weight: var(--menu-font-weight, inherit);
  text-transform: var(--menu-text-transform, none);
}
[slot="menu-h"],
[slot^="menu-h_"] {
  flex-direction: row;
  flex-wrap: wrap;
  align-items: center;
}
[slot="menu-v"],
[slot^="menu-v_"] {
  flex-direction: column;
  align-items: flex-start;
  gap: 0.5rem;
}
[slot^="menu-"].text-center { justify-content: center; align-items: center; }
[slot^="menu-"].text-right  { justify-content: flex-end; align-items: flex-end; }
[slot^="menu-"].text-left   { justify-content: flex-start; align-items: flex-start; }

[slot^="menu-"] > a {
  color: inherit;
  text-decoration: none;
  font-size: var(--menu-font-size, 0.9375rem);
  padding: 0.25rem 0;
  position: relative;
  transition: color 120ms ease;
}
[slot^="menu-"] > a:hover {
  color: var(--primary-base, currentColor);
}

/* Demo-Spans: Platzhalter-Marker für leere Nav-Slots. Confident-but-clearly-
 * placeholder Styling — uppercase + tracking statt italic+dashed-underline,
 * damit die Header-Komposition nicht zaghaft wirkt. Dot-separator ersetzt
 * gap-Whitespace für sichtbare Strukturierung. */
.nav-demo {
  color: var(--menu-link-color, var(--text-muted));
  font-size: var(--menu-font-size, 0.75rem);
  padding: 0.25rem 0;
  text-transform: var(--menu-text-transform, uppercase);
  letter-spacing: 0.05em;
  cursor: default;
  user-select: none;
  white-space: nowrap;
}
.nav-demo + .nav-demo::before {
  content: "·";
  display: inline-block;
  margin: 0 0.5rem;
  opacity: 0.5;
}

/* `.nav-empty` — der Editor-Hinweis fuer ein AUFGELOESTES, aber leeres Menue
 * (2026-08-11). Unterschied zu `.nav-demo`: die Demo steht fuer „hier ist ein
 * Menue, es ist noch nicht konfiguriert", der Hinweis fuer „konfiguriert, aber
 * es passt gerade keine Seite dazu". Auf der Live-Seite erscheint keins von
 * beidem — der Renderer emittiert den Hinweis nur im Editier-Modus. */
.nav-empty {
  color: var(--text-muted);
  font-size: 0.75rem;
  font-style: italic;
  padding: 0.25rem 0;
  cursor: default;
  user-select: none;
}

/* In vertikalen Menü-Kontexten (Footer-Nav-Spalten, menu-v Slots,
 * .menu-list-vertical) sind die nav-demos auf eigenen Zeilen.
 * Dot-Separator vor Item 2+3 würde sie nach rechts schieben statt
 * linksbündig zu stapeln. Plus: uppercase+letter-spacing wirkt
 * vertikal heavy — auf normale Caption zurück. */
[slot^="menu-v"] .nav-demo,
.menu-list-vertical .nav-demo,
.fe-menu-slot .nav-demo {
  text-transform: none;
  letter-spacing: normal;
  font-size: 0.85rem;
}
[slot^="menu-v"] .nav-demo + .nav-demo::before,
.menu-list-vertical .nav-demo + .nav-demo::before,
.fe-menu-slot .nav-demo + .nav-demo::before {
  content: none;
  margin: 0;
}

/* Vertikale Variante: Patterns/Molecules die ihre Menu-Liste vertikal
 * stapeln wollen, setzen .menu-list-vertical (oder analoge Helper-Klasse).
 * Plus: pattern.css darf via [data-direction=column] flex-direction
 * setzen ohne mit unserem !important display:flex zu kollidieren. */
[slot="menu"].menu-list-vertical,
[slot^="menu_"].menu-list-vertical {
  flex-direction: column;
  align-items: flex-start;
  gap: 0.5rem;
}

/* ── Grid Aliases ─────────────────────────────────────────────────────────── */
.mypage .full    { width: 100%; }
.mypage .half    { width: 50%; }
.mypage .third   { width: 33.333%; }
.mypage .quarter { width: 25%; }

/* ── Spacing utilities — alle auf --spacing: 0.5rem Basis ───────────────── */
/* N=1→0.5rem  N=2→1rem  N=4→2rem  N=6→3rem  N=8→4rem  N=10→5rem  N=12→6rem */
.mypage .pt-0  { padding-top:    0 !important; }
.mypage .pt-1  { padding-top:    calc(1  * var(--spacing)) !important; }
.mypage .pt-2  { padding-top:    calc(2  * var(--spacing)) !important; }
.mypage .pt-3  { padding-top:    calc(3  * var(--spacing)) !important; }
.mypage .pt-4  { padding-top:    calc(4  * var(--spacing)) !important; }
.mypage .pt-5  { padding-top:    calc(5  * var(--spacing)) !important; }
.mypage .pt-6  { padding-top:    calc(6  * var(--spacing)) !important; }
.mypage .pt-8  { padding-top:    calc(8  * var(--spacing)) !important; }
.mypage .pt-10 { padding-top:    calc(10 * var(--spacing)) !important; }
.mypage .pt-12 { padding-top:    calc(12 * var(--spacing)) !important; }

.mypage .pb-0  { padding-bottom: 0 !important; }
.mypage .pb-1  { padding-bottom: calc(1  * var(--spacing)) !important; }
.mypage .pb-2  { padding-bottom: calc(2  * var(--spacing)) !important; }
.mypage .pb-3  { padding-bottom: calc(3  * var(--spacing)) !important; }
.mypage .pb-4  { padding-bottom: calc(4  * var(--spacing)) !important; }
.mypage .pb-5  { padding-bottom: calc(5  * var(--spacing)) !important; }
.mypage .pb-6  { padding-bottom: calc(6  * var(--spacing)) !important; }
.mypage .pb-8  { padding-bottom: calc(8  * var(--spacing)) !important; }
.mypage .pb-10 { padding-bottom: calc(10 * var(--spacing)) !important; }
.mypage .pb-12 { padding-bottom: calc(12 * var(--spacing)) !important; }

.mypage .pl-0  { padding-left:   0 !important; }
.mypage .pl-1  { padding-left:   calc(1  * var(--spacing)) !important; }
.mypage .pl-2  { padding-left:   calc(2  * var(--spacing)) !important; }
.mypage .pl-3  { padding-left:   calc(3  * var(--spacing)) !important; }
.mypage .pl-4  { padding-left:   calc(4  * var(--spacing)) !important; }
.mypage .pl-5  { padding-left:   calc(5  * var(--spacing)) !important; }
.mypage .pl-6  { padding-left:   calc(6  * var(--spacing)) !important; }
.mypage .pl-8  { padding-left:   calc(8  * var(--spacing)) !important; }
.mypage .pl-10 { padding-left:   calc(10 * var(--spacing)) !important; }
.mypage .pl-12 { padding-left:   calc(12 * var(--spacing)) !important; }

.mypage .pr-0  { padding-right:  0 !important; }
.mypage .pr-1  { padding-right:  calc(1  * var(--spacing)) !important; }
.mypage .pr-2  { padding-right:  calc(2  * var(--spacing)) !important; }
.mypage .pr-3  { padding-right:  calc(3  * var(--spacing)) !important; }
.mypage .pr-4  { padding-right:  calc(4  * var(--spacing)) !important; }
.mypage .pr-5  { padding-right:  calc(5  * var(--spacing)) !important; }
.mypage .pr-6  { padding-right:  calc(6  * var(--spacing)) !important; }
.mypage .pr-8  { padding-right:  calc(8  * var(--spacing)) !important; }
.mypage .pr-10 { padding-right:  calc(10 * var(--spacing)) !important; }
.mypage .pr-12 { padding-right:  calc(12 * var(--spacing)) !important; }

.mypage .px-0  { padding-left: 0 !important; padding-right: 0 !important; }
.mypage .px-1  { padding-left: calc(1 * var(--spacing)) !important; padding-right: calc(1 * var(--spacing)) !important; }
.mypage .px-2  { padding-left: calc(2 * var(--spacing)) !important; padding-right: calc(2 * var(--spacing)) !important; }
.mypage .px-3  { padding-left: calc(3 * var(--spacing)) !important; padding-right: calc(3 * var(--spacing)) !important; }
.mypage .px-4  { padding-left: calc(4 * var(--spacing)) !important; padding-right: calc(4 * var(--spacing)) !important; }
.mypage .px-5  { padding-left: calc(5 * var(--spacing)) !important; padding-right: calc(5 * var(--spacing)) !important; }
.mypage .px-6  { padding-left: calc(6 * var(--spacing)) !important; padding-right: calc(6 * var(--spacing)) !important; }
.mypage .px-8  { padding-left: calc(8 * var(--spacing)) !important; padding-right: calc(8 * var(--spacing)) !important; }
.mypage .px-10 { padding-left: calc(10 * var(--spacing)) !important; padding-right: calc(10 * var(--spacing)) !important; }
.mypage .px-12 { padding-left: calc(12 * var(--spacing)) !important; padding-right: calc(12 * var(--spacing)) !important; }

.mypage .py-0  { padding-top: 0 !important; padding-bottom: 0 !important; }
.mypage .py-1  { padding-top: calc(1  * var(--spacing)) !important; padding-bottom: calc(1  * var(--spacing)) !important; }
.mypage .py-2  { padding-top: calc(2  * var(--spacing)) !important; padding-bottom: calc(2  * var(--spacing)) !important; }
.mypage .py-3  { padding-top: calc(3  * var(--spacing)) !important; padding-bottom: calc(3  * var(--spacing)) !important; }
.mypage .py-4  { padding-top: calc(4  * var(--spacing)) !important; padding-bottom: calc(4  * var(--spacing)) !important; }
.mypage .py-5  { padding-top: calc(5  * var(--spacing)) !important; padding-bottom: calc(5  * var(--spacing)) !important; }
.mypage .py-6  { padding-top: calc(6  * var(--spacing)) !important; padding-bottom: calc(6  * var(--spacing)) !important; }
.mypage .py-8  { padding-top: calc(8  * var(--spacing)) !important; padding-bottom: calc(8  * var(--spacing)) !important; }
.mypage .py-10 { padding-top: calc(10 * var(--spacing)) !important; padding-bottom: calc(10 * var(--spacing)) !important; }
.mypage .py-12 { padding-top: calc(12 * var(--spacing)) !important; padding-bottom: calc(12 * var(--spacing)) !important; }

/* Skala-Lücken 7/9/11 gefüllt (2026-07-16): das Innenabstand-Box-Feld im Editor
   erlaubt jeden 0–12-Wert; ohne diese Klassen liefen 7/9/11 ins Leere (kein Effekt).
   Durchgehende 0–12-Padding-Skala für pt/pr/pb/pl/px/py. */
.mypage .pt-7  { padding-top:    calc(7  * var(--spacing)) !important; }
.mypage .pt-9  { padding-top:    calc(9  * var(--spacing)) !important; }
.mypage .pt-11 { padding-top:    calc(11 * var(--spacing)) !important; }
.mypage .pb-7  { padding-bottom: calc(7  * var(--spacing)) !important; }
.mypage .pb-9  { padding-bottom: calc(9  * var(--spacing)) !important; }
.mypage .pb-11 { padding-bottom: calc(11 * var(--spacing)) !important; }
.mypage .pl-7  { padding-left:   calc(7  * var(--spacing)) !important; }
.mypage .pl-9  { padding-left:   calc(9  * var(--spacing)) !important; }
.mypage .pl-11 { padding-left:   calc(11 * var(--spacing)) !important; }
.mypage .pr-7  { padding-right:  calc(7  * var(--spacing)) !important; }
.mypage .pr-9  { padding-right:  calc(9  * var(--spacing)) !important; }
.mypage .pr-11 { padding-right:  calc(11 * var(--spacing)) !important; }
.mypage .px-7  { padding-left: calc(7  * var(--spacing)) !important; padding-right: calc(7  * var(--spacing)) !important; }
.mypage .px-9  { padding-left: calc(9  * var(--spacing)) !important; padding-right: calc(9  * var(--spacing)) !important; }
.mypage .px-11 { padding-left: calc(11 * var(--spacing)) !important; padding-right: calc(11 * var(--spacing)) !important; }
.mypage .py-7  { padding-top: calc(7  * var(--spacing)) !important; padding-bottom: calc(7  * var(--spacing)) !important; }
.mypage .py-9  { padding-top: calc(9  * var(--spacing)) !important; padding-bottom: calc(9  * var(--spacing)) !important; }
.mypage .py-11 { padding-top: calc(11 * var(--spacing)) !important; padding-bottom: calc(11 * var(--spacing)) !important; }

/* Margin utilities */
.mypage .mt-1  { margin-top:    calc(1  * var(--spacing)) !important; }
.mypage .mt-2  { margin-top:    calc(2  * var(--spacing)) !important; }
.mypage .mt-4  { margin-top:    calc(4  * var(--spacing)) !important; }
.mypage .mt-6  { margin-top:    calc(6  * var(--spacing)) !important; }
.mypage .mt-8  { margin-top:    calc(8  * var(--spacing)) !important; }
.mypage .mb-1  { margin-bottom: calc(1  * var(--spacing)) !important; }
.mypage .mb-2  { margin-bottom: calc(2  * var(--spacing)) !important; }
.mypage .mb-4  { margin-bottom: calc(4  * var(--spacing)) !important; }
.mypage .mb-6  { margin-bottom: calc(6  * var(--spacing)) !important; }
.mypage .mb-8  { margin-bottom: calc(8  * var(--spacing)) !important; }
.mypage .my-2  { margin-top: calc(2 * var(--spacing)) !important; margin-bottom: calc(2 * var(--spacing)) !important; }
.mypage .my-4  { margin-top: calc(4 * var(--spacing)) !important; margin-bottom: calc(4 * var(--spacing)) !important; }
.mypage .my-6  { margin-top: calc(6 * var(--spacing)) !important; margin-bottom: calc(6 * var(--spacing)) !important; }

/* ── Alignment atoms (Tailwind-compatible) ─────────────────────────────────── */
.mypage .mx-auto       { margin-left: auto; margin-right: auto; }
.mypage .text-center   { text-align: center; }
.mypage .justify-center { justify-content: center; }

/* ── 9-Punkt-Ausrichtungsmatrix ─────────────────────────────────────────────
 * Jede align-XY-Klasse setzt H + V + Text-Align in einem Token.
 * Angewendet auf flex-column-Layer (sections, col-N):
 *   justify-content  → Vertikal  (start=oben, center=Mitte, end=unten)
 *   align-items      → Horizontal (start=links, center=Mitte, end=rechts)
 *   text-align       → Textausrichtung der Kind-Elemente
 * Gesetzt über den "Ausrichtung"-Picker im Section-Menu-Bar.
 * ─────────────────────────────────────────────────────────────────────────── */
.mypage .align-tl { justify-content: flex-start !important; align-items: flex-start !important; text-align: left   !important; }
.mypage .align-tc { justify-content: flex-start !important; align-items: center      !important; text-align: center !important; }
.mypage .align-tr { justify-content: flex-start !important; align-items: flex-end   !important; text-align: right  !important; }
.mypage .align-ml { justify-content: center     !important; align-items: flex-start !important; text-align: left   !important; }
.mypage .align-mc { justify-content: center     !important; align-items: center     !important; text-align: center !important; }
.mypage .align-mr { justify-content: center     !important; align-items: flex-end   !important; text-align: right  !important; }
.mypage .align-bl { justify-content: flex-end   !important; align-items: flex-start !important; text-align: left   !important; }
.mypage .align-bc { justify-content: flex-end   !important; align-items: center     !important; text-align: center !important; }
.mypage .align-br { justify-content: flex-end   !important; align-items: flex-end   !important; text-align: right  !important; }
/* Explizite UI-Ausrichtung ist AUTORITATIV: sie muss Pattern-/Molecule-Defaults
 * (z.B. .molecule.benefit-item{text-align:center} @0-3-0) UND die eigenen
 * .text-center/.text-left/.text-right-Utilities der direkten Kinder überstimmen.
 * !important + Kind-Kaskade, weil der Picker nur auf explizit ausgerichteten
 * Containern greift (kein Default-Blast-Radius). */
.mypage .align-tl > *, .mypage .align-ml > *, .mypage .align-bl > * { text-align: left   !important; }
.mypage .align-tc > *, .mypage .align-mc > *, .mypage .align-bc > * { text-align: center !important; }
.mypage .align-tr > *, .mypage .align-mr > *, .mypage .align-br > * { text-align: right  !important; }

/* Die Matrix muss WAAGRECHTE Molecules erreichen (2026-08-11, Befund des Users:
 * „hier habe ich 2 verschachtelte Spalten und kann es nicht ausrichten").
 *
 * Warum sie das sonst nicht kann: die Matrix arbeitet mit `align-items` an der
 * Spalte, was ein Kind normalerweise auf Inhaltsbreite schrumpfen und an die
 * gewaehlte Kante ruecken laesst. Eine Molecule ist aber ein
 * `section[type='layer']`, und render-struct.css gibt jedem davon
 * `width: -webkit-fill-available` — sie bleibt also VOLLBREIT, egal was die
 * Spalte sagt. Damit war die Ausrichtung fuer die Kopfzeilen-Navigation
 * wirkungslos: verschoben haette sie nur `justify-content` an der Molecule
 * selbst. Genau das setzen diese Regeln jetzt.
 *
 * Nur die WAAGRECHTE Zelle wird uebersetzt (links/Mitte/rechts). Die senkrechte
 * traegt im Kopfband ohnehin `align-items: center` an der Reihe. */
.mypage .align-tl > .molecule.header-nav,
.mypage .align-ml > .molecule.header-nav,
.mypage .align-bl > .molecule.header-nav { justify-content: flex-start; }
.mypage .align-tc > .molecule.header-nav,
.mypage .align-mc > .molecule.header-nav,
.mypage .align-bc > .molecule.header-nav { justify-content: center; }
.mypage .align-tr > .molecule.header-nav,
.mypage .align-mr > .molecule.header-nav,
.mypage .align-br > .molecule.header-nav { justify-content: flex-end; }

/* ── Aspect ratio atoms ──────────────────────────────────────────────────────
 * aspect-ratio sets the BOX shape; without object-fit on the image inside,
 * the browser stretches the bitmap to fill the box → visible distortion
 * whenever the asset's native ratio ≠ the requested ratio. The cover-rule
 * below crops to fill without warping. Applies to:
 *   - the element itself (when an <img>/<video> carries the class)
 *   - direct or nested <img>/<picture> children (typical pattern shape)
 * ──────────────────────────────────────────────────────────────────────── */
.mypage .aspect-21-9 { aspect-ratio: 21 / 9; overflow: hidden; }
.mypage .aspect-1-1  { aspect-ratio: 1 / 1;  overflow: hidden; }
.mypage .aspect-4-3  { aspect-ratio: 4 / 3;  overflow: hidden; }
.mypage .aspect-16-9 { aspect-ratio: 16 / 9; overflow: hidden; }

.mypage img.aspect-21-9,
.mypage img.aspect-1-1,
.mypage img.aspect-4-3,
.mypage img.aspect-16-9,
.mypage .aspect-21-9 img,
.mypage .aspect-1-1 img,
.mypage .aspect-4-3 img,
.mypage .aspect-16-9 img,
.mypage .aspect-21-9 picture,
.mypage .aspect-1-1 picture,
.mypage .aspect-4-3 picture,
.mypage .aspect-16-9 picture {
  width: 100%;
  height: 100%;
  object-fit: cover;
  display: block;
}

/* ── Bild-Schwerpunkt beim Beschneiden ────────────────────────────────────
 * Wird ein Bild per `object-fit: cover` in ein anderes Seitenverhaeltnis
 * gezwungen, entscheidet `object-position`, WO beschnitten wird. Der
 * Browser-Default `50% 50%` schneidet oben und unten gleich viel ab — bei
 * Portraits kostet das regelmaessig die Stirn, bei Motiven mit Horizont den
 * Himmel.
 *
 * `50% 30%` verschiebt den Ausschnitt nach oben: es bleibt mehr vom oberen
 * Bilddrittel stehen, wo die Bildaussage meistens sitzt (Gesicht, Kopfzeile,
 * Produkt). Bewusst NICHT `top` — das schneidet bei Portraits die Stirn an
 * und laesst bei Landschaften nur noch Himmel uebrig. 30 % trifft in der
 * Praxis Augenhoehe.
 *
 * Das ist der DEFAULT. Sobald es ein Focal-Point-Control gibt, setzt der pro
 * Bild ein eigenes object-position und diese Regel ist der Rueckfall fuer
 * alles, wo nichts gesetzt wurde — also fuer importierte und Stock-Bilder.
 *
 * Ausgenommen sind Bilder mit `object-fit: contain` (Logos): dort wird nichts
 * beschnitten, und eine Verschiebung wuerde das Logo nur aus der Mitte
 * ruecken. Die entsprechenden Regeln setzen `object-position: center`
 * ausdruecklich zurueck. */
.mypage img,
.mypage picture,
.mypage video {
  object-position: 50% 30%;
}

/* ── Molecule Frame (.mol) ────────────────────────────────────────────────────
 * Problem: Grid-Spalten (col-4, col-6, …) haben kein eigenes Padding.
 * Moleküle in farbigen Containern sitzen deshalb bündig am Rand.
 *
 * Lösung: .mol gibt einer Spalte / einem Layer einen Innenrahmen.
 *   → Padding nach innen, sodass Inhalt Luft hat.
 *
 * Varianten:
 *   .mol        – Standard-Innenpadding (1× paddingX / paddingY)
 *   .mol-sm     – Kompaktes Padding (0.5× Einheit, z. B. für dichte Karten)
 *   .mol-lg     – Großzügiges Padding (1.5× Einheit, z. B. für Hero-Karten)
 *   .mol-card   – Wie .mol + eigener weißer Hintergrund + Border-Radius
 *                 (→ klassische Card auf farbigem Hintergrund)
 *   .mol-card-dark – Card-Rahmen in Dunkelmodus
 *
 * Verwendung im Editor: layer-Klasse "col-4 mol" oder "col-4 mol mol-card"
 * ─────────────────────────────────────────────────────────────────────────── */

.mypage .mol {
  padding: calc(1 * var(--paddingT)) calc(1 * var(--paddingL));
  box-sizing: border-box;
  height: 100%;
}

.mypage .mol-sm {
  padding: calc(0.5 * var(--paddingT)) calc(0.5 * var(--paddingL));
  box-sizing: border-box;
  height: 100%;
}

.mypage .mol-lg {
  padding: calc(1.5 * var(--paddingT)) calc(1.5 * var(--paddingL));
  box-sizing: border-box;
  height: 100%;
}

/* mol-card: mol + eigene Oberfläche (helle Karte). Eigene color-Property
   setzt currentColor zurück damit ein .sc-dark/.sc-pri-Parent (white text)
   nicht in die helle Karte bleedet → weißer Text auf weißer Karte. */
.mypage .mol-card {
  padding:          calc(1.25 * var(--paddingT)) calc(1.25 * var(--paddingL));
  background-color: color-mix(in srgb, var(--color-bg) 95%, transparent);
  color:            var(--text-dark);
  border-radius:    var(--border-radius, 0.75rem);
  box-shadow:       0 2px 12px rgba(0,0,0,0.06);
  box-sizing:       border-box;
  height:           100%;
}

/* mol-card-dark: Card auf hellem Hintergrund in dunkler Variante */
.mypage .mol-card-dark {
  padding:          calc(1.25 * var(--paddingT)) calc(1.25 * var(--paddingL));
  background-color: var(--shade-dark-base);
  color:            var(--text-light);
  border-radius:    var(--border-radius, 0.75rem);
  box-shadow:       0 2px 12px rgba(0,0,0,0.18);
  box-sizing:       border-box;
  height:           100%;
}

/* Eyebrow + h1sub gehen über die kanonischen Tokens (--eyebrow-font-color,
   --sub-font-color), gesetzt in :root und über ProjectSettings überschreibbar.
   Die alten .sc-pri .mol-card-Bandagen (Heading/p/eyebrow hardcoded auf
   dark Farben) sind weg — Karte hat jetzt eigenes color: --text-dark als
   Stamm, alles vererbt sauber. h1sub holt sich --shade-mid wie überall. */

/* ── Caption ─────────────────────────────────────────────────────────────── */
/* `.caption`/`.caption-sub` sind oben definiert (RTE-wählbare Absatzstile,
 * Projekt B). Die frühere separate, gedämpfte `.caption`-Regel wurde dorthin
 * konsolidiert (war Duplikat mit gleicher Spezifität). */

/* ── Gap Utilities ─────────────────────────────────────────────────────
 * Für Flex- und Grid-Container — nur Abstände ZWISCHEN Elementen,
 * keine Außenabstände. Erste/letzte Kinder bündig zum Container-Rand.
 * Separate Achsen: gap-x-N (horizontal), gap-y-N (vertikal). */
.mypage .gap-0  { gap: 0;                                    --grid-gap: 0px; }
.mypage .gap-1  { gap: calc(1 * var(--spacing));             --grid-gap: calc(1 * var(--spacing)); }
.mypage .gap-2  { gap: calc(2 * var(--spacing));             --grid-gap: calc(2 * var(--spacing)); }
.mypage .gap-3  { gap: calc(3 * var(--spacing));             --grid-gap: calc(3 * var(--spacing)); }
.mypage .gap-4  { gap: calc(4 * var(--spacing));             --grid-gap: calc(4 * var(--spacing)); }
.mypage .gap-5  { gap: calc(5 * var(--spacing));             --grid-gap: calc(5 * var(--spacing)); }
.mypage .gap-6  { gap: calc(6 * var(--spacing));             --grid-gap: calc(6 * var(--spacing)); }
.mypage .gap-8  { gap: calc(8 * var(--spacing));             --grid-gap: calc(8 * var(--spacing)); }

.mypage .gap-x-1 { column-gap: calc(1 * var(--spacing)); }
.mypage .gap-x-2 { column-gap: calc(2 * var(--spacing)); }
.mypage .gap-x-3 { column-gap: calc(3 * var(--spacing)); }
.mypage .gap-x-4 { column-gap: calc(4 * var(--spacing)); }
.mypage .gap-x-6 { column-gap: calc(6 * var(--spacing)); }

.mypage .gap-y-1 { row-gap: calc(1 * var(--spacing)); }
.mypage .gap-y-2 { row-gap: calc(2 * var(--spacing)); }
.mypage .gap-y-3 { row-gap: calc(3 * var(--spacing)); }
.mypage .gap-y-4 { row-gap: calc(4 * var(--spacing)); }
.mypage .gap-y-6 { row-gap: calc(6 * var(--spacing)); }

/* ── Header-Modes ──────────────────────────────────────────────────────────
 * Zwei orthogonale Klassen, stackbar mit sc-* / glass-* / py-N:
 *   .head-overlay  — Header schwebt über der nächsten Section (Hero startet
 *                    bei y=0). Position absolute + z-index high.
 *   .head-sticky   — Header bleibt beim Scrollen oben kleben.
 * Kombinationen:
 *   `head-overlay glass-light glass-frosted` → Glass-Header über Hero
 *   `head-sticky sc-light`                   → Solid sticky
 *   `head-overlay head-sticky`               → Overlay, mitscrollend
 *   `head-overlay` ohne sc-*                  → vollständig transparent
 * Hero-Patterns sollten bei head-overlay-Verwendung ggf. pt-N setzen,
 * damit Hero-Content nicht unter dem Header verschwindet. */
.mypage .head-overlay {
  position: absolute;
  top: 0;
  left: 0;
  right: 0;
  z-index: 100;
}

.mypage .head-sticky {
  position: sticky;
  top: 0;
  z-index: 100;
}

/* ─── BITV 2.0 / WCAG 2.4.7 — Globaler Focus-Indikator ───────────────
 * Tastatur-Nutzer müssen sehen, wo der Fokus steht. :focus-visible
 * greift nur bei Keyboard-Fokus (nicht bei Maus-Klick), daher kein
 * störender Ring bei Maus-Bedienung. 2px solid contrast-base + 2px
 * offset garantiert Sichtbarkeit auf hellem wie dunklem Background.
 * Patterns können den Ring pro Element überschreiben, aber nie
 * komplett entfernen (outline:none ohne Ersatz = BITV-Verstoß). */
.mypage a:focus-visible,
.mypage button:focus-visible,
.mypage [role="button"]:focus-visible,
.mypage input:focus-visible,
.mypage select:focus-visible,
.mypage textarea:focus-visible,
.mypage [tabindex]:focus-visible,
.mypage summary:focus-visible {
  outline: 2px solid var(--contrast-base, #2563eb);
  outline-offset: 2px;
  border-radius: 2px;
}
