@import url("tokens.css");

/* ==========================================================================
   Zajadacz Designsystem, system.css
   Stand 08.09.2026, Korrekturrunde 1 nach dem Zweitblick (Opus, Forge).
   Eine Datei fuer alle Komponenten aus KOMPONENTEN.md.
   Regel: keine Farbe und keine Groesse ausserhalb von tokens.css erfinden.
   Wo hier eine nackte Zahl steht, ist sie ein Abstand ohne Figma-Vorlage und
   im BAU-PROTOKOLL.md begruendet.
   ========================================================================== */

/* --- 1. Schrift ---------------------------------------------------------- */

@font-face {
  font-family: "Mark Pro";
  src: url("fonts/Mark-Regular.ttf") format("truetype");
  font-weight: 400; font-style: normal; font-display: swap;
}
@font-face {
  font-family: "Mark Pro";
  src: url("fonts/Mark-Medium.ttf") format("truetype");
  font-weight: 500; font-style: normal; font-display: swap;
}
@font-face {
  font-family: "Mark Pro";
  src: url("fonts/Mark-Bold.ttf") format("truetype");
  font-weight: 700; font-style: normal; font-display: swap;
}

/* --- 2. Reset ------------------------------------------------------------ */
/* Kein overflow-x: hidden auf body. Es hat zwei echte Ueberlaeufe verdeckt
   (Shop-Zeile bei 1024, Kamm-Strich unter 455). Beide sind jetzt behoben,
   und ein neuer Ueberlauf soll wieder sichtbar werden. */

*, *::before, *::after { box-sizing: border-box; }
html { -webkit-text-size-adjust: 100%; }
body {
  margin: 0;
  font-family: var(--zj-font);
  font-weight: var(--zj-weight-regular);
  font-size: var(--zj-body-size);
  line-height: var(--zj-body-line);
  letter-spacing: var(--zj-tracking);
  color: var(--zj-text);
  background: var(--zj-white);
  text-wrap: pretty;
}
img, svg, video { display: block; max-width: 100%; }
a { color: inherit; }
button { font: inherit; letter-spacing: inherit; color: inherit; background: none; border: 0; }
table { border-collapse: collapse; }
h1, h2, h3, p, ul, ol, figure, blockquote { margin: 0; }
ul, ol { padding: 0; list-style: none; }
/* Fokus: auf Weiss navy (Kontrast 13,8 zu 1), auf dunkler Flaeche gelb.
   Gelb auf Weiss waere 1,5 zu 1 und damit unbrauchbar. */
:focus-visible { outline: 3px solid var(--zj-fokus-farbe, var(--zj-navy)); outline-offset: 2px; }

/* --- 2b. Dunkle Flaechen -------------------------------------------------- */
/* Eine Liste an einer Stelle. Wer eine neue dunkle Flaeche baut, traegt sie
   hier ein, dann stimmen Sekundaerknopf, Umriss-Knopf, Fokus und der gelbe
   Punkt automatisch. Bewusst NICHT in der Liste: .zj-hero--bento (weisser
   Grund, Figma zeigt den Punkt dort navy) und .zj-hero--foto (heller
   Platzhalter). */
.zj-sektion--navy, .zj-sektion--blau,
.zj-hero--bild-rechts, .zj-hero--band,
.zj-trust, .zj-ctaband, .zj-standort, .zj-fusszeile,
.zj-kasten--navy, .zj-karte--blau, .zj-kachel--shop, .zj-auf-dunkel {
  --zj-link-farbe: var(--zj-yellow);
  --zj-umriss-farbe: var(--zj-yellow);
  --zj-fokus-farbe: var(--zj-yellow);
  /* "--zj-punkt-farbe" stand hier bis zur Fix-Runde 15.09.2026 und machte den
     Punkt NUR auf dunklem Grund gelb. Der Kanon gilt seit 14.09. auf jedem
     Grund, deshalb steht der Grundwert jetzt global (Abschnitt 3) und diese
     Zeile waere nur noch eine Wiederholung. */
  /* 09.09.2026, Abschnitt 33: Hover. Der Text ist hier im Ruhezustand schon
     gelb, ein gelber Hover waere kein Wechsel. Auf dunkel geht der Text
     deshalb auf Weiss, der Marker bleibt gelb. */
  --zj-hover-text: var(--zj-white);
  --zj-hover-flieszlink: var(--zj-yellow);
}

/* --- 3. Ueberschriften und Text (Komponente 3 und 4) --------------------- */

.zj-h1, .zj-h2, .zj-h3 {
  font-weight: var(--zj-weight-bold);
  letter-spacing: var(--zj-tracking);
  text-wrap: balance;
  color: inherit;
}
.zj-h1 { font-size: var(--zj-h1-size); line-height: var(--zj-h1-line); max-width: var(--zj-hero-h1-w); }
.zj-h2 { font-size: var(--zj-h2-size); line-height: var(--zj-h2-line); max-width: var(--zj-h2-w); }
.zj-h3 { font-size: var(--zj-h3-size); line-height: var(--zj-h3-line); }

/* Der Punkt am Satzende ist gelb, auf JEDEM Grund (Kanon-Aenderung 14.09.2026,
   Vivi #31/#34/#46). Bis zur Fix-Runde 15.09. wurde "--zj-punkt-farbe" nur im
   Dunkel-Scope gesetzt, auf Weiss fiel der Punkt deshalb auf currentColor und
   mass Navy. Der Grundwert steht jetzt hier; wer den Punkt in der Textfarbe
   will, setzt die Variable lokal um (siehe .zj-karte--einfarbig). */
:root { --zj-punkt-farbe: var(--zj-accent); }
.zj-punkt { color: var(--zj-punkt-farbe, currentColor); }
/* Ein blaues Wort in der H1 (Startseite: "Elektrogrosshandel") */
.zj-blau { color: var(--zj-blue); font-style: normal; }
/* Eine gelbe Zeile in der H2 (LiKoTECH: "wirklich zahlen.") */
.zj-gelb { color: var(--zj-yellow); font-style: normal; }

/* Schraegstrich vor einer Ueberschrift oder einem Label. Inline-Block vor
   dem Text, nicht Flex-Kind, sonst reisst der Punkt am Satzende ab. */
/* An der Karte haengt der Strich seit 09.09. am Modifier der KARTE, nicht mehr
   an einer Zusatzklasse des Titels (Konsistenzpruefung Befund 3): dieselbe
   Klasse .zj-karte trug ihn mal ja, mal nein, und man sah es der Karte nicht
   an. Jetzt sagt .zj-karte--strich es an der Karte. Ohne den Modifier traegt
   eine Karte kein Markenzeichen, das ist die Voreinstellung. */
.zj-h1--slash, .zj-h2--slash, .zj-h3--slash, .zj-slash,
.zj-karte--strich .zj-karte__titel { display: block; max-width: none; }
.zj-h1--slash::before, .zj-h2--slash::before, .zj-h3--slash::before, .zj-slash::before,
.zj-karte--strich .zj-karte__titel::before {
  content: "";
  display: inline-block;
  /* Optisch mittig zur VERSALHOEHE, nicht auf der Grundlinie sitzend
     [Vivi 10.09.2026 #30, #40, #41, #42: "Slash nicht optisch mittig zum
     Text."] Auf der Grundlinie steht der 22 px hohe Strich unten buendig und
     ragt oben ueber die Versalien hinaus. 1cap ist die echte Versalhoehe der
     geladenen Schrift, deshalb rechnet die Zeile fuer jede Schriftgroesse
     selbst: H3 24 px ergibt rund -2,4 px, das Label 24 px dasselbe.
     Die erste Zeile ist der Rueckfall fuer Browser ohne cap-Einheit. */
  vertical-align: baseline;
  vertical-align: calc((1cap - var(--zj-card-slash-h)) / 2);
  width: var(--zj-card-slash-w);
  height: var(--zj-card-slash-h);
  margin-right: var(--zj-card-slash-gap);
  background: var(--zj-accent);
  clip-path: polygon(71.43% 0, 100% 0, 28.57% 100%, 0 100%);
}

/* max-width: Figma begrenzt jede Textspalte auf 875 px (H2 auf 894). In schmalen
   Containern (Karte 329, Person 255) greift die Grenze nicht, dort bleibt alles wie es war. */
/* Regular, nicht Medium [Vivi 10.09.2026 #53 "falscher Schriftschnitt"]. Die
   Schrifttabelle im DESIGN-KANON fuehrt den Lead unter "Fliesstext 18/25
   Regular"; Medium ist dort nur fuer Listen und Eyebrows vorgesehen. Der Bau
   setzte bis v1 Medium 500 und widersprach damit dem eigenen Kanon. */
.zj-lead  { font-size: var(--zj-body-size); line-height: var(--zj-body-line); font-weight: var(--zj-weight-regular); max-width: var(--zj-text-w); }
.zj-body  { font-size: var(--zj-body-size); line-height: var(--zj-body-line); max-width: var(--zj-text-w); }
.zj-body + .zj-body { margin-top: var(--zj-body-line); }
.zj-body strong, .zj-lead strong { font-weight: var(--zj-weight-bold); }
.zj-note  { display: none; }           /* Wireframe-Annotation, im Design aus */
.zj-note.is-sichtbar { display: block; font-size: var(--zj-small-size); opacity: .7; }
.zj-claim { font-size: var(--zj-h2-size); line-height: var(--zj-h2-line); font-weight: var(--zj-weight-bold); }
.zj-claim__wort { font-size: 1.8em; line-height: 1; color: var(--zj-yellow); }
.zj-manifest > p + p { margin-top: var(--zj-body-line); }
.zj-manifest--summe > p { font-weight: var(--zj-weight-bold); }

/* --- 4. Eyebrow (Komponente 2) ------------------------------------------ */

.zj-eyebrow {
  display: block;
  font-size: var(--zj-eyebrow-size);
  line-height: var(--zj-eyebrow-line);
  font-weight: var(--zj-weight-regular);
  color: var(--zj-blue);
}
.zj-eyebrow--hell   { color: var(--zj-blue); }
.zj-eyebrow--dunkel { color: var(--zj-accent); }
.zj-eyebrow--caps   { text-transform: uppercase; font-size: var(--zj-small-size);
                      letter-spacing: .08em; font-weight: var(--zj-weight-bold); }
.zj-eyebrow--kpz {
  display: inline-flex; align-items: center; gap: var(--zj-abstand-12);
  color: var(--zj-yellow);
  font-weight: var(--zj-weight-bold);
  font-size: var(--zj-eyebrow-kpz-size);
  text-transform: uppercase;
  letter-spacing: .02em;
}
.zj-eyebrow--kpz .zj-icon { width: var(--zj-kpz-icon); height: var(--zj-kpz-icon); }

/* --- 5. Icons (Komponente 7) -------------------------------------------- */

.zj-sprite { display: none; }   /* das Symbol-Sprite selbst wird nie gezeigt */
.zj-icon { display: inline-block; fill: currentColor; color: inherit; flex: none; }
.zj-icon--pfeil { width: var(--zj-arrow-w); height: var(--zj-arrow-h); }
.zj-icon--schraegstrich { width: var(--zj-card-slash-w); height: var(--zj-card-slash-h); }
.zj-icon--haken { width: var(--zj-haken); height: var(--zj-haken); }
.zj-icon--chevron { width: 12px; height: 8px; }
.zj-icon--extern { width: 12px; height: 12px; }

/* --- 6. Buttons (Komponente 1) ------------------------------------------ */

.zj-button {
  display: inline-flex; align-items: center;
  font-size: var(--zj-small-size); line-height: var(--zj-small-line);
  font-weight: var(--zj-weight-bold);
  letter-spacing: var(--zj-tracking);
  text-decoration: none; cursor: pointer;
}
/* Externer Link. Das Zeichen kommt aus dem Attribut, damit im HTML nur
   data-extern steht und kein zusaetzliches Markup noetig ist. */
.zj-button[data-extern]::after,
a[data-extern]::after { content: "\2197"; margin-left: var(--zj-abstand-8); font-size: .9em; }

/* 6a. Primaer: gelber Koerper mit schraeger rechter Kante plus abgetrennter
   Strich. Geometrie 1:1 aus Figma Group 51 (192,5 x 43): Koerper oben 0..168,5,
   unten 0..148; Strich oben 180,5..192,5, unten 160..172. */
.zj-button--primaer {
  position: relative; isolation: isolate;
  height: var(--zj-btn-h);
  padding-left: var(--zj-btn-pad-x);
  padding-right: calc(var(--zj-btn-pad-x) + var(--zj-btn-slant));
  color: var(--zj-navy);
  margin-right: calc(var(--zj-btn-slash-gap) + var(--zj-btn-slash-w));
}
.zj-button--primaer::before {
  content: ""; position: absolute; inset: 0; z-index: -1;
  background: var(--zj-yellow);
  clip-path: polygon(0 0, 100% 0, calc(100% - var(--zj-btn-slant)) 100%, 0 100%);
}
.zj-button--primaer::after {
  content: ""; position: absolute; top: 0; bottom: 0; z-index: -1;
  left: calc(100% - var(--zj-btn-slant) + var(--zj-btn-slash-w));
  width: calc(var(--zj-btn-slant) + var(--zj-btn-slash-w));
  background: var(--zj-yellow);
  clip-path: polygon(var(--zj-btn-slant) 0, 100% 0,
                     var(--zj-btn-slash-w) 100%, 0 100%);
}

/* 6b. Sekundaer: Textlink mit Pfeil. Farbe kommt aus der Flaeche. */
.zj-button--sekundaer { gap: var(--zj-abstand-16); color: var(--zj-link-farbe, var(--zj-navy)); }
.zj-button--sekundaer .zj-icon--pfeil { transition: transform .15s ease; }
.zj-button--sekundaer:hover .zj-icon--pfeil { transform: translateX(4px); }
.zj-button--sekundaer.zj-button--gross { font-size: var(--zj-body-size); }
/* Der Sammel-Link traegt im Textmaster einen Pfeil als Schriftzeichen. Er
   bleibt Zeichen, damit der Text-Freeze haelt; das Pfeil-Icon entfaellt dort. */
.zj-button--pfeilzeichen { gap: 0; }

/* 6c. Umriss */
.zj-button--umriss {
  justify-content: center;
  min-width: var(--zj-btn-umriss-w); height: var(--zj-btn-umriss-h);
  border: var(--zj-btn-outline) solid var(--zj-umriss-farbe, var(--zj-navy));
  color: var(--zj-umriss-farbe, var(--zj-navy));
  background: transparent;
}

/* Buttonzeile */
.zj-buttons { display: flex; flex-wrap: wrap; align-items: center; gap: var(--zj-abstand-20) var(--zj-abstand-32); }

/* --- 7. Listen (Komponente 5) ------------------------------------------- */

.zj-liste { display: grid; gap: var(--zj-abstand-12); }
.zj-liste--haken > li { display: grid; grid-template-columns: 27px 1fr; align-items: start;
                        font-weight: var(--zj-weight-medium); }
.zj-liste--haken > li > .zj-icon { margin-top: .35em; color: var(--zj-link-farbe, var(--zj-navy)); }
.zj-liste--punkt > li { position: relative; padding-left: var(--zj-liste-einzug); }
.zj-liste--punkt > li::before {
  content: ""; position: absolute; left: 0; top: .55em;
  width: 5px; height: 5px; border-radius: 50%; background: currentColor;
}
.zj-liste--auftakt > li > strong { font-weight: var(--zj-weight-bold); }
.zj-liste--linie { gap: var(--zj-abstand-20); }
.zj-liste--linie > li { border-left: 3px solid var(--zj-yellow); padding-left: var(--zj-abstand-16); }
.zj-liste--linie .zj-liste__titel { display: block; font-weight: var(--zj-weight-bold); }
.zj-liste--icon > li { display: flex; align-items: center; gap: var(--zj-abstand-16); }
.zj-liste__chip {
  display: inline-flex; align-items: center; justify-content: center;
  width: var(--zj-bedien-h); height: var(--zj-bedien-h); flex: none;
  border: 1px dashed var(--zj-linie); border-radius: var(--zj-card-radius);
  font-size: var(--zj-small-size);
}

/* --- 8. Pills (Komponente 6) -------------------------------------------- */

.zj-pills { display: flex; flex-wrap: wrap; gap: var(--zj-abstand-12); align-items: center; }
.zj-pills--filter { gap: var(--zj-abstand-12) var(--zj-abstand-16); }
.zj-pills--filter .zj-pills__label {
  font-size: var(--zj-small-size); font-weight: var(--zj-weight-bold);
  text-transform: uppercase; letter-spacing: .08em; margin-right: var(--zj-abstand-8);
}
.zj-pill {
  display: inline-flex; align-items: center; gap: var(--zj-abstand-8);
  padding: var(--zj-abstand-8) var(--zj-abstand-16); border-radius: 999px;
  font-size: var(--zj-small-size); line-height: 1.2;
  font-weight: var(--zj-weight-medium);
  background: var(--zj-grey); color: var(--zj-navy);
  border: 1px solid transparent; text-decoration: none;
}
.zj-pill--erfolg  { background: var(--zj-blue); color: var(--zj-white); }
.zj-pill--warnung { background: var(--zj-yellow); color: var(--zj-navy);
                    font-weight: var(--zj-weight-bold); text-transform: uppercase; }
.zj-pill.is-aktiv { background: var(--zj-navy); color: var(--zj-white); }
.zj-pill.is-versteckt { display: none; }

/* --- 9. Seite und Inhalt (Komponente 8) --------------------------------- */

.zj-seite { display: flow-root; }
.zj-inhalt { width: 100%; padding-inline: var(--zj-rand); }
/* Schmale Textspalte: 894 px Inhalt, unabhaengig vom Seitenrand.
   v2: LINKSbuendig statt mittig [Vivi 10.09.2026 #60 "Text sitzt zu mittig,
   links ausrichten"]. Die Spalte beginnt jetzt an derselben Kante wie jede
   andere Sektion der Seite (x 230 bei 1728), statt als Insel in der Mitte
   zu stehen. Rechts bleibt der Rest offen. */
.zj-inhalt--schmal { max-width: calc(var(--zj-schmal-w) + 2 * var(--zj-rand));
                     margin-inline: 0 auto; }

/* --- 10. Sektion (Komponente 9) ----------------------------------------- */

.zj-sektion { padding-block: var(--zj-section-pad-top) var(--zj-section-pad-bottom); }
.zj-sektion--weiss { background: var(--zj-white); color: var(--zj-text); }
.zj-sektion--grau  { background: var(--zj-grey);  color: var(--zj-text); }
.zj-sektion--gelb  { background: var(--zj-yellow);color: var(--zj-navy); }
.zj-sektion--navy  { background: var(--zj-navy);  color: var(--zj-text-invert); }
.zj-sektion--blau  { background: var(--zj-blue);  color: var(--zj-text-invert); }
.zj-sektion--navy .zj-eyebrow, .zj-sektion--blau .zj-eyebrow { color: var(--zj-yellow); }
.zj-sektion--eng { padding-block: var(--zj-abstand-48); }

.zj-sektion__kopf > .zj-eyebrow + .zj-h2 { margin-top: var(--zj-eyebrow-to-h2); }
.zj-sektion__kopf > .zj-h2 + .zj-lead,
.zj-sektion__kopf > .zj-h2 + .zj-body { margin-top: var(--zj-h2-to-lead); }
.zj-sektion__kopf--zentriert { text-align: center; }
.zj-sektion__kopf--zentriert .zj-h1,
.zj-sektion__kopf--zentriert .zj-h2,
.zj-sektion__kopf--zentriert .zj-lead,
.zj-sektion__kopf--zentriert .zj-body { margin-inline: auto; }
.zj-sektion__kopf + * { margin-top: var(--zj-lead-to-grid); }
.zj-sektion__fuss { margin-top: var(--zj-abstand-40); }

/* --- 11. Raster (Komponente 10) ----------------------------------------- */

.zj-raster { display: grid; gap: var(--zj-gap); }
.zj-raster--2 { grid-template-columns: repeat(2, minmax(0, 1fr)); }
/* Dreispalter: bei 1268 Inhalt und 20 Abstand sind das die 409 aus --zj-col-3 */
.zj-raster--3 { grid-template-columns: repeat(3, minmax(0, 1fr)); }
.zj-raster--4 { grid-template-columns: repeat(4, minmax(0, 1fr)); }
/* Bento: Reihe 1 zwei Karten, Reihe 2 drei Karten */
.zj-raster--bento-5 { grid-template-columns: repeat(6, minmax(0, 1fr)); }
.zj-raster--bento-5 > :nth-child(-n+2) { grid-column: span 3; }
.zj-raster--bento-5 > :nth-child(n+3)  { grid-column: span 2; }
/* Bild und Text nebeneinander, Bild links (Standard) */
.zj-raster--bild-text { grid-template-columns: 2fr 3fr; align-items: center; }
.zj-raster--bild-text.zj-raster--bild-rechts > :first-child { order: 2; }
/* Detail: Hauptspalte plus klebende Seitenspalte */
.zj-raster--detail { grid-template-columns: 2fr 1fr; align-items: start; gap: var(--zj-abstand-40); }
.zj-raster--detail > aside { position: sticky; top: calc(var(--zj-header-h) + var(--zj-abstand-20)); }
/* Startseiten-Zweispalter aus dem Kanon */
.zj-raster--374-873 { grid-template-columns: 374fr 873fr; }
.zj-raster--749-499 { grid-template-columns: 749fr 499fr; }

/* --- 12. Bildplatzhalter ------------------------------------------------ */

.zj-bild {
  display: flex; align-items: center; justify-content: center;
  padding: var(--zj-abstand-16); text-align: center;
  background: var(--zj-platzhalter);
  color: var(--zj-navy);
  font-size: var(--zj-small-size); line-height: 1.35;
  border-radius: var(--zj-card-radius);
  min-height: var(--zj-karte-bild-h);
}
.zj-bild--4-3  { aspect-ratio: 4 / 3; }
.zj-bild--16-9 { aspect-ratio: 16 / 9; }
.zj-bild--1-1  { aspect-ratio: 1 / 1; }
.zj-bild--voll { height: 100%; border-radius: 0; min-height: 260px; }
/* Bild ueber die volle Inhaltsbreite, Text darueber. Figma stellt die Halle so. */
.zj-bild--breit { height: var(--zj-bild-breit-h); min-height: var(--zj-bild-breit-h); }
.zj-bild--band { min-height: 260px; border-radius: 0; }
.zj-bild--weiss { background: var(--zj-white); }
.zj-bild__text { max-width: 46ch; }

/* --- 13. Kopfzeile (Komponente 11) -------------------------------------- */

.zj-kopfzeile {
  position: relative; z-index: 40;
  background: var(--zj-white); color: var(--zj-navy);
}
.zj-kopfzeile__leiste {
  display: flex; align-items: center; gap: var(--zj-abstand-24);
  height: var(--zj-header-h);
}
.zj-kopfzeile__logo { flex: none; }
.zj-kopfzeile__logo img { width: var(--zj-logo-w); height: var(--zj-logo-h); }
.zj-kopfzeile__nav { display: flex; align-items: center; gap: var(--zj-abstand-8); margin-left: auto; }
.zj-kopfzeile__link {
  display: inline-flex; align-items: center; gap: var(--zj-abstand-8);
  height: var(--zj-nav-active-h); padding-inline: var(--zj-abstand-24);
  font-size: var(--zj-nav-size); line-height: var(--zj-nav-line);
  font-weight: var(--zj-weight-bold); text-decoration: none;
  /* Gehrung auf null, passend zum gelben Knopf. [Vivi 10.09.2026 #4/#27/#54:
     "Ecken zu rund, Gehrung auf null."] War 4px. */
  border-radius: 0; white-space: nowrap;
  /* Die Pillengeometrie steht schon im Ruhezustand, nur der Grund ist
     durchsichtig. Damit springt beim Ueberfahren kein Mass (Regel 1). */
  background: transparent;
}
.zj-kopfzeile__link.is-aktiv {
  min-width: var(--zj-nav-active-w); justify-content: center;
  background: var(--zj-navy); color: var(--zj-white);
}
.zj-kopfzeile__cta { flex: none; margin-left: var(--zj-abstand-24); }
.zj-kopfzeile__burger { display: none; margin-left: auto; padding: var(--zj-abstand-12); cursor: pointer; }
.zj-kopfzeile__burger span {
  display: block; width: 24px; height: 2px; background: var(--zj-navy);
}
.zj-kopfzeile__burger span + span { margin-top: var(--zj-abstand-4); }

/* Megamenue. Bezug ist die KOPFZEILE, nicht der Menuepunkt: nur so laeuft die
   Klappe vollbreit und die Karten bekommen ihre 409 px. */
.zj-kopfzeile__punkt { display: contents; }
.zj-mega {
  position: absolute; left: 0; right: 0; top: 100%;
  background: var(--zj-white); color: var(--zj-navy);
  border-top: 1px solid var(--zj-linie);
  box-shadow: 0 18px 40px rgba(20, 40, 100, .12);
  padding-block: var(--zj-abstand-40);
  max-height: var(--zj-mega-max-h); overflow: auto;
}
.zj-mega[hidden] { display: none; }
/* Ohne JavaScript oeffnet die Klappe per Hover und per Tastatur-Fokus.
   Das Skript verbessert nur (Klick, Escape, Klick nach aussen). */
.zj-kopfzeile__punkt:hover > .zj-mega[hidden],
.zj-kopfzeile__punkt:focus-within > .zj-mega[hidden] { display: block; }
.zj-mega__raster { display: grid; gap: var(--zj-gap); margin-top: var(--zj-abstand-24); }
.zj-mega__raster--3 { grid-template-columns: repeat(3, minmax(0, 1fr)); }
.zj-mega__raster--2 { grid-template-columns: repeat(2, minmax(0, 1fr)); }
.zj-mega__fuss { margin-top: var(--zj-abstand-32); display: flex; flex-wrap: wrap; align-items: center; gap: var(--zj-abstand-12) var(--zj-abstand-24); }
.zj-kopfzeile__trigger .zj-icon--chevron { transition: transform .15s ease; }
.zj-kopfzeile__trigger[aria-expanded="true"] .zj-icon--chevron { transform: rotate(180deg); }

/* Flache Kopfzeile (Karriere) */
.zj-kopfzeile--flach .zj-kopfzeile__link { padding-inline: var(--zj-abstand-16); font-size: var(--zj-small-size); }
.zj-kopfzeile__marke {
  font-size: var(--zj-small-size); font-weight: var(--zj-weight-bold);
  text-transform: uppercase; letter-spacing: .08em; color: var(--zj-blue);
  margin-left: var(--zj-abstand-12);
}

/* --- 14. Hero (Komponente 12) ------------------------------------------- */

.zj-hero { position: relative; }
.zj-hero__text { display: grid; align-content: center; gap: 0; }
.zj-hero__text > .zj-eyebrow + .zj-h1 { margin-top: var(--zj-abstand-32); }
.zj-hero__text > .zj-h1 + * { margin-top: var(--zj-abstand-40); }
.zj-hero__text > * + .zj-buttons { margin-top: var(--zj-abstand-48); }

/* 14a. Bild rechts, navy, 800 hoch. Bild 748 breit ab x 979 bei 1728. */
.zj-hero--bild-rechts {
  background: var(--zj-navy); color: var(--zj-text-invert);
  display: grid; grid-template-columns: minmax(0, 1fr) minmax(0, var(--zj-hero-img-w));
  min-height: var(--zj-hero-h);
  /* Query-Container, damit die Textspalte den Rand aus der SEITENbreite
     rechnen kann und nicht aus ihrer eigenen. Ohne das fiel der Rand auf den
     Mindestwert zurueck und der Hero-Text stand bei x 24 statt 230 (Simeon
     09.09.2026: "der Hero header geht ueber die ganze Breite"). */
  container-type: inline-size;
}
.zj-hero--bild-rechts .zj-hero__text {
  padding: var(--zj-abstand-80) var(--zj-gap) var(--zj-abstand-80) var(--zj-rand-cq);
}
.zj-hero--bild-rechts .zj-hero__bild { min-height: 100%; }
.zj-hero--bild-rechts .zj-bild { height: 100%; border-radius: 0; }

/* 14b. Bento, Startseite: Text links, Kachelfeld rechts, beide 624 breit */
.zj-hero--bento .zj-hero__grid {
  display: grid; grid-template-columns: minmax(0, 1fr) minmax(0, 1fr);
  gap: var(--zj-gap); padding-block: var(--zj-abstand-40) 0;
}
.zj-hero__kacheln { display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); gap: var(--zj-gap); }
.zj-hero__spalte { display: grid; gap: var(--zj-gap); align-content: start; }
.zj-hero__spalte--versatz { padding-top: var(--zj-abstand-40); }
.zj-hero__kachel { position: relative; overflow: hidden; }
.zj-hero__kachel .zj-bild { border-radius: 0; min-height: 210px; height: 100%; }
.zj-hero__kachel-label {
  position: absolute; left: 0; right: 0; bottom: 0;
  min-height: var(--zj-bento-label-h);
  display: flex; align-items: center; padding-inline: var(--zj-abstand-12);
  background: var(--zj-navy); color: var(--zj-white);
  font-size: var(--zj-body-size); font-weight: var(--zj-weight-bold);
}
.zj-kachel--shop {
  background: var(--zj-blue); color: var(--zj-text-invert);
  padding: var(--zj-abstand-24); display: grid; align-content: center; gap: var(--zj-abstand-12); min-height: 250px;
}
/* clamp statt fester 54 px: zwischen 900 und 1200 lief die Zeile sonst
   ueber die Kachel und ueber den Seitenrand hinaus. */
.zj-kachel__zeile {
  font-size: clamp(26px, 3.2vw, var(--zj-h1-size));
  line-height: 1.05; font-weight: var(--zj-weight-bold);
  overflow-wrap: anywhere;
}

/* 14c. Textband, 14d. Fotobox, 14e. Bildband */
.zj-hero--band { background: var(--zj-navy); color: var(--zj-text-invert); padding-block: var(--zj-abstand-96); }
.zj-hero--foto { position: relative; }
.zj-hero--foto .zj-hero__box {
  min-height: 420px; display: grid; align-content: center; justify-items: center;
  gap: var(--zj-abstand-24); text-align: center; padding: var(--zj-abstand-48) var(--zj-abstand-24);
  background: var(--zj-platzhalter); color: var(--zj-navy);
}
.zj-hero__scroll {
  font-size: var(--zj-small-size); text-transform: uppercase; letter-spacing: .12em;
  font-weight: var(--zj-weight-bold);
}
.zj-hero--bildband .zj-hero__text { padding-block: var(--zj-abstand-48) 0; }

/* --- 15. Karte (Komponente 13) ------------------------------------------ */
/* Abstand kommt ausschliesslich ueber Margin, nicht zusaetzlich ueber Gap.
   Vorher addierten sich 14 px Gap und 25 px Margin zu 39 px zwischen zwei
   Absaetzen, waehrend dieselben zwei Absaetze in einer Textsektion 25 px
   auseinander standen. */
.zj-karte {
  display: flex; flex-direction: column;
  background: var(--zj-grey); color: var(--zj-navy);
  border-radius: var(--zj-card-radius);
  overflow: hidden;
  text-decoration: none;
}
.zj-karte__inhalt {
  padding: var(--zj-card-pad-top) var(--zj-card-pad) var(--zj-card-pad);
  display: flex; flex-direction: column; flex: 1;
}
.zj-karte__inhalt > * + * { margin-top: var(--zj-abstand-16); }
.zj-karte__bild { border-radius: 0; min-height: var(--zj-karte-bild-h); }
.zj-karte--gelb  { background: var(--zj-yellow); }
.zj-karte--weiss { background: var(--zj-white); }
.zj-karte--blau  { background: var(--zj-blue); color: var(--zj-text-invert); }
.zj-karte--blau .zj-eyebrow { color: var(--zj-yellow); }
.zj-karte__eyebrow + .zj-karte__titel { margin-top: var(--zj-abstand-24); }
.zj-karte__nummer {
  font-size: var(--zj-h3-size); line-height: 1; font-weight: var(--zj-weight-bold);
  color: var(--zj-blue);
}
.zj-karte__chip {
  width: var(--zj-bedien-h); height: var(--zj-bedien-h); display: inline-flex; align-items: center; justify-content: center;
  border-radius: var(--zj-card-radius); background: var(--zj-white);
  font-size: var(--zj-small-size); font-weight: var(--zj-weight-bold);
}
.zj-karte__kennzahl { font-size: var(--zj-small-size); opacity: .8; }
.zj-karte .zj-buttons, .zj-karte .zj-button--sekundaer { margin-top: auto; padding-top: var(--zj-abstand-16); }

/* --- 13a. Zitat (Komponente 13a) ---------------------------------------- */
/* Zwei Formen: als Karte (Branchen-Trust) und als Randlinie im BildText. */
/* v2, 14.09.2026 [Vivi #56 "nicht das ausgesuchte Zitat-Modul", Anhang
   Pastel 979019]: kein Kasten, kein Grund, kein Radius. Links ein
   freistehender gelber Schraegstrich 23 x 124 (dieselbe Form wie im Kamm,
   als Slash), 56 px Luft, rechts das Zitat kursiv in Navy; darunter mit
   32 px Abstand ein kleines Portraet 48 x 48 und zwei Zeilen Quelle. */
.zj-zitat {
  background: none; border-radius: 0; padding: 0;
  color: inherit;
  margin-block: var(--zj-abstand-48);
  display: grid; grid-template-columns: var(--zj-kamm-slash-w) 1fr;
  column-gap: var(--zj-sektion-pad);
  align-items: start;
}
/* Fix-Runde 15.09.2026 [Opus-B1]: "grid-row: 1 / -1" war wirkungslos. Das
   Raster hat keine explizite Zeile, damit ist Linie -1 dieselbe wie Linie 1;
   die Regel fiel auf EINE implizite Zeile zurueck, und die feste Hoehe 124
   blies Zeile 1 auf. Folge: 106 px statt 32 px zwischen Zitat und Quelle.
   Jetzt "span 2" (zaehlt Zeilen, braucht keine Linie -1) plus stretch, die
   Hoehe kommt aus dem Raster, 124 bleibt nur noch Mindestmass. */
.zj-zitat::before {
  content: ""; display: block;
  grid-row: 1 / span 2; align-self: stretch;
  width: var(--zj-kamm-slash-w); height: auto; min-height: var(--zj-kamm-slash-h);
  background: var(--zj-yellow);
  transform: skewX(calc(-1 * var(--zj-kamm-angle)));
  transform-origin: bottom left;
}
.zj-zitat > * { grid-column: 2; }
.zj-zitat__text { font-style: italic; max-width: var(--zj-text-w); }
.zj-zitat__quelle {
  margin-top: var(--zj-abstand-32);
  display: grid; grid-template-columns: var(--zj-zitat-foto) 1fr;
  column-gap: var(--zj-abstand-16); align-items: center;
}
.zj-zitat__foto {
  width: var(--zj-zitat-foto); height: var(--zj-zitat-foto);
  border-radius: 4px; object-fit: cover; background: var(--zj-platzhalter);
  display: block;
}
.zj-zitat__name, .zj-zitat__betrieb {
  display: block;
  font-size: var(--zj-small-size); line-height: var(--zj-small-line);
}
.zj-zitat__name    { font-weight: var(--zj-weight-bold); }
.zj-zitat__betrieb { font-weight: var(--zj-weight-regular); margin-top: var(--zj-abstand-4); }
/* Auf Navy erbt das Modul die Flaechenfarbe: Zitat und Name weiss, die
   Betrieb-Zeile gelb wie eine Eyebrow auf dunkel. Der Strich bleibt gelb.
   Die Bestandszeile ".zj-trust .zj-zitat { background: weiss }" ist entfallen. */
.zj-sektion--navy .zj-zitat__betrieb,
.zj-sektion--blau .zj-zitat__betrieb,
.zj-trust .zj-zitat__betrieb { color: var(--zj-yellow); }
.zj-zitat--linie { background: none; border-radius: 0; padding: 0 0 0 var(--zj-abstand-16);
                   border-left: 3px solid var(--zj-yellow);
                   display: block; column-gap: 0; margin-block: 0; }
.zj-zitat--linie::before { display: none; }

/* --- 13b. Kachel (Komponente 13b) --------------------------------------- */
/* Foto mit Label und Button darauf. Verlauf unter dem Text, damit der Titel
   auch auf einem hellen Foto lesbar bleibt. */
.zj-kachel {
  position: relative; min-height: 220px; overflow: hidden;
  border-radius: var(--zj-card-radius); display: flex;
}
.zj-kachel .zj-bild { position: absolute; inset: 0; height: 100%; border-radius: inherit; }
.zj-kachel__inhalt {
  position: relative; z-index: 1; width: 100%;
  display: flex; flex-direction: column; justify-content: flex-end; align-items: flex-start;
  gap: var(--zj-abstand-16); padding: var(--zj-card-pad);
  background: linear-gradient(transparent, rgba(20, 40, 100, .75));
}
.zj-kachel__titel { color: var(--zj-white); }

/* --- 13c. Cluster (Komponente 13c) -------------------------------------- */
.zj-cluster { background: var(--zj-grey); color: var(--zj-navy);
              border-radius: var(--zj-card-radius);
              padding: var(--zj-card-pad-top) var(--zj-card-pad) var(--zj-card-pad); }
.zj-cluster > * + * { margin-top: var(--zj-abstand-16); }
.zj-cluster__marken { font-size: var(--zj-small-size); }
.zj-cluster__range { font-style: italic; font-size: var(--zj-small-size); }

/* --- 13d. Megakarte (Komponente 13d) ------------------------------------ */
/* v2: seitliches Polster plus negatives Aussenmass. Der Text steht exakt da,
   wo er vorher stand (Ruhelage bewegt sich nicht), die graue Hover-Flaeche
   hat aber Luft um den Text herum statt ihn zu beschneiden. */
.zj-megakarte { display: block; text-decoration: none;
                padding: var(--zj-abstand-12);
                margin-inline: calc(-1 * var(--zj-abstand-12));
                border-radius: var(--zj-card-radius); }
.zj-megakarte__titel { display: block; }
.zj-megakarte__lead { display: block; margin-top: var(--zj-abstand-4); }
.zj-megakarte.is-aktuell .zj-megakarte__titel,
.zj-megakarte.is-aktiv .zj-megakarte__titel { color: var(--zj-blue); }

/* --- 16. Trust (Komponente 14) ------------------------------------------ */

.zj-trust { background: var(--zj-navy); color: var(--zj-text-invert); }
.zj-trust__raster { display: grid; grid-template-columns: repeat(3, minmax(0, 1fr)); gap: var(--zj-gap); }
.zj-trust__raster--2 { grid-template-columns: repeat(2, minmax(0, 1fr)); }
.zj-trust__raster--4 { grid-template-columns: repeat(4, minmax(0, 1fr)); }
.zj-trust .zj-karte { background: var(--zj-white); min-height: var(--zj-trust-karte-h); }

/* --- 17. LogoStrip (Komponente 15) -------------------------------------- */

.zj-logostrip { background: var(--zj-grey); min-height: var(--zj-logo-strip-h);
                display: flex; align-items: center; padding-block: var(--zj-abstand-24); }
.zj-logostrip__band { display: flex; align-items: center; gap: var(--zj-abstand-64); flex-wrap: wrap;
                      justify-content: center; width: 100%; }
.zj-logostrip__item { display: grid; justify-items: center; gap: var(--zj-abstand-8); }
.zj-logostrip__item img { height: 26px; width: auto; }
.zj-logostrip__caption { font-size: var(--zj-logo-caption-size); line-height: 1.2; }
.zj-logostrip__platz {
  width: var(--zj-logostrip-platz-w); height: 26px; display: flex; align-items: center; justify-content: center;
  background: var(--zj-platzhalter); color: var(--zj-navy);
  font-size: 11px; font-weight: var(--zj-weight-bold); letter-spacing: .04em;
}
.zj-logostrip--namen .zj-logostrip__band { gap: var(--zj-abstand-12) var(--zj-abstand-20); font-weight: var(--zj-weight-medium); }
.zj-logostrip--namen .zj-logostrip__trenner { opacity: .5; }

/* Marken-Variante (14.09.2026, Vivi #55): dreizehn echte Logos statt Namen.
   Eigene Luecke, weil 64 px bei dreizehn Stuecken die Leiste dreireihig macht;
   64 bleibt der Wert fuer die vierstellige Partner-Variante darueber. */
.zj-logostrip--marken .zj-logostrip__band { gap: var(--zj-abstand-24) var(--zj-abstand-32); }
.zj-logostrip--marken .zj-logostrip__item img { height: var(--zj-marken-h); }
/* Eine optische Korrektur, keine mathematische: WAGO traegt Luft in seiner
   viewBox und sitzt auf gleicher Kastenhoehe zu klein.
   Die Rittal-Zeile ist am 15.09.2026 entfallen [Opus-S1]: das Zeichen steht
   jetzt als Wortmarke. Der Token --zj-marken-h-hoch bleibt fuer den Rueckweg
   in tokens.css stehen und wird aktuell von keiner Regel gelesen. */
.zj-logostrip--marken .zj-logostrip__item img[alt="WAGO"]   { height: var(--zj-marken-h-luft); }
/* Lapp und Rittal haben kein beschaffbares freies Logo und stehen als Wortmarke. */
.zj-logostrip__wortmarke { font-size: var(--zj-marken-wortmarke-size); line-height: var(--zj-marken-h);
  font-weight: var(--zj-weight-bold); letter-spacing: .02em; color: var(--zj-navy); }
.zj-logostrip--kennzahlen .zj-logostrip__band {
  display: grid; grid-template-columns: repeat(3, minmax(0, 1fr)); text-align: center; gap: var(--zj-gap);
}
.zj-logostrip__zahl { display: block; font-size: var(--zj-h2-size); line-height: 1.1;
                      font-weight: var(--zj-weight-bold); }
.zj-logostrip__label { font-size: var(--zj-small-size); }

/* --- 18. Personen (Komponente 16) --------------------------------------- */

.zj-personen__gruppe + .zj-personen__gruppe { margin-top: var(--zj-personen-gruppe); }
.zj-personen__label {
  font-size: var(--zj-h3-size); line-height: var(--zj-h3-line);
  font-weight: var(--zj-weight-bold); text-transform: uppercase;
  margin-bottom: var(--zj-abstand-24);
}
.zj-personen__raster { display: grid; grid-template-columns: repeat(3, minmax(0, 1fr)); gap: var(--zj-gap); }
.zj-person {
  display: grid; grid-template-columns: var(--zj-person-photo-w) 1fr;
  min-height: var(--zj-person-h);
  background: var(--zj-grey); color: var(--zj-navy);
  border-radius: var(--zj-card-radius); overflow: hidden;
}
.zj-person__foto { background: var(--zj-platzhalter); display: flex; align-items: center;
                   justify-content: center; font-size: 12px; text-align: center; }
.zj-person__meta { padding: var(--zj-person-pad-top) var(--zj-person-gap); }
.zj-person__name { display: block; font-weight: var(--zj-weight-bold); }
.zj-person__fn { display: block; }
.zj-person--leitung { max-width: 634px; }
.zj-person--watch { border: 2px dashed var(--zj-linie); background: transparent; }
.zj-person--watch .zj-person__foto { background: repeating-linear-gradient(
    45deg, var(--zj-linie-invers) 0 6px, transparent 6px 12px); }
.zj-personen__kontakt { margin-top: var(--zj-abstand-48); }

/* --- 19. Querverweis (Komponente 17) ------------------------------------ */

.zj-querverweis__raster { display: grid; grid-template-columns: repeat(3, minmax(0, 1fr)); gap: var(--zj-gap); }
.zj-querverweis .zj-karte__bild { min-height: var(--zj-cross-bild-h); }
.zj-querverweis__z { color: var(--zj-yellow); }

/* --- 20. CTA-Band (Komponente 18) --------------------------------------- */
/* Kein Eyebrow (Simeon 08.09.). Der H2 sitzt an der Stelle, an der in Figma
   die Eyebrow-Zeile stand, also 78 px unter der Bandkante. */
.zj-ctaband {
  background: var(--zj-blue); color: var(--zj-text-invert);
  min-height: var(--zj-cta-band-h);
  display: grid; align-content: center;
  padding-block: var(--zj-section-pad-top) var(--zj-section-pad-bottom);
}
.zj-ctaband .zj-h2 + .zj-body { margin-top: var(--zj-h2-to-lead); }
.zj-ctaband .zj-buttons { margin-top: var(--zj-abstand-48); }
.zj-ctaband--kurz { min-height: 0; padding-block: var(--zj-abstand-64); }

/* --- 21. BildText (Komponente 19) --------------------------------------- */

.zj-bildtext__raster { display: grid; grid-template-columns: 2fr 3fr; gap: var(--zj-abstand-64); align-items: center; }
.zj-bildtext--bild-rechts .zj-bildtext__bild { order: 2; }
.zj-bildtext__text > * + * { margin-top: var(--zj-abstand-24); }
.zj-bildtext__qr { display: grid; gap: var(--zj-abstand-8); justify-items: start; }
.zj-bildtext__qr .zj-bild { width: var(--zj-qr-w); min-height: var(--zj-qr-w); }
.zj-badges { display: flex; gap: var(--zj-gap); flex-wrap: wrap; }
.zj-badges .zj-bild { width: 190px; min-height: 90px; }

/* --- 22. Tabelle (Komponente 20) ---------------------------------------- */

.zj-tabelle { width: 100%; background: var(--zj-white); color: var(--zj-navy);
              border: 1px solid var(--zj-linie); border-radius: var(--zj-card-radius);
              overflow: hidden; font-size: var(--zj-body-size); }
.zj-tabelle th, .zj-tabelle td { padding: var(--zj-abstand-12) var(--zj-abstand-16); height: var(--zj-bedien-h); text-align: left;
                                 border-bottom: 1px solid var(--zj-linie); }
.zj-tabelle thead th { background: var(--zj-grey); font-weight: var(--zj-weight-bold); }
.zj-tabelle tbody tr:last-child td { border-bottom: 0; }
.zj-tabelle__zahl { text-align: right; }
.zj-tabelle__rolle { overflow-x: auto; }
.zj-tabelle--tco { max-width: var(--zj-schmal-w); }
/* Stellentabelle: vier Spalten, verlinkte Zeilen */
.zj-tabelle--stellen td a { font-weight: var(--zj-weight-bold); text-decoration: underline;
                            text-underline-offset: 3px; }
.zj-tabelle--stellen tbody tr:hover { background: var(--zj-grey); }

/* --- 23. Kasten (Komponente 21) ----------------------------------------- */

.zj-kasten { background: var(--zj-grey); color: var(--zj-navy);
             border-radius: var(--zj-card-radius); padding: var(--zj-abstand-40); }
.zj-kasten > * + * { margin-top: var(--zj-abstand-20); }
.zj-kasten--hellblau { background: var(--zj-hellblau); }
.zj-kasten--gelb { background: var(--zj-yellow); }
.zj-kasten--navy { background: var(--zj-navy); color: var(--zj-text-invert); }
.zj-kasten--navy .zj-eyebrow { color: var(--zj-yellow); }
.zj-kasten--kante { border-left: 8px solid var(--zj-yellow); }

/* --- 24. Standort (Komponente 22) --------------------------------------- */

.zj-standort { background: var(--zj-blue); color: var(--zj-text-invert); min-height: 754px;
               display: grid; align-content: center;
               padding-block: var(--zj-section-pad-top) var(--zj-section-pad-bottom); }
/* Die Karte ist 773 px breit, kein Verhaeltnis. Die Textspalte nimmt den Rest. */
/* Die Karte bleibt im Raster (Simeon 09.09.: „Standort muss ins Raster passen"). Figma
   laesst sie 149 px ueber die Inhaltsbreite ragen; wir nehmen die Rasterdisziplin.
   Die Textspalte haelt die Mindestbreite der Knopfzeile, die Karte nimmt den Rest. */
.zj-standort__raster { display: grid;
  grid-template-columns: minmax(var(--zj-standort-text-min), 1fr) minmax(0, var(--zj-karte-nord-w));
                       gap: var(--zj-abstand-40); align-items: center; }
.zj-standort__text { text-align: center; display: grid; gap: var(--zj-abstand-24); justify-items: center; }
.zj-standort__text .zj-h2 { max-width: 16ch; }
.zj-standort .zj-buttons { justify-content: center; }
.zj-standort__karte { min-height: 480px; }
.zj-standort__detail { margin-top: 0; }

/* --- 25. Kontakt (Komponente 23) ---------------------------------------- */

.zj-kontakt__raster { display: grid; grid-template-columns: repeat(3, minmax(0, 1fr)); gap: var(--zj-gap);
                      align-items: start; }
.zj-kontakt__spalte > * + * { margin-top: var(--zj-abstand-12); }
.zj-kontakt .zj-buttons { margin-top: var(--zj-abstand-40); }

/* --- 26. Kamm (Komponente 24) ------------------------------------------- */
/* Die Zaehne sind Streifen eines wiederholenden Verlaufs: ein Streifen in
   einem 58 px hohen Kasten IST das Parallelogramm. Die Quermasse rechnet CSS
   selbst aus den Kanon-Tokens (cos), damit kein zweiter Zahlensatz entsteht.
   Neigung aus --zj-kamm-angle (26 Grad, oben links, am Render gemessen). */
.zj-kamm {
  position: relative; z-index: 1;
  height: var(--zj-kamm-h);
  background:
    repeating-linear-gradient(calc(90deg - var(--zj-kamm-angle)),
      var(--zj-navy) 0 calc(var(--zj-kamm-tooth-w) * cos(var(--zj-kamm-angle))),
      var(--zj-blue) calc(var(--zj-kamm-tooth-w) * cos(var(--zj-kamm-angle)))
                    calc(var(--zj-kamm-pitch) * cos(var(--zj-kamm-angle))));
}
.zj-kamm::after {
  content: "";
  position: absolute; top: 0;
  /* min() haelt den Strich auch unter 455 px Breite im Bild. */
  left: min(var(--zj-kamm-strich-x),
            100% - var(--zj-kamm-slash-w) - var(--zj-kamm-strich-dx) - var(--zj-rand-min));
  width: calc(var(--zj-kamm-slash-w) + var(--zj-kamm-strich-dx));
  height: var(--zj-kamm-slash-h);
  background: var(--zj-yellow);
  clip-path: polygon(var(--zj-kamm-strich-dx) 0, 100% 0,
                     var(--zj-kamm-slash-w) 100%, 0 100%);
}
/* Der Strich steht in einer Luecke: Figma laesst dort zwei Zahnplaetze frei.
   Das blaue Feld radiert den Kamm aus, der gelbe Strich liegt darueber. */
.zj-kamm::before {
  content: "";
  position: absolute; top: 0; height: 100%;
  width: var(--zj-kamm-luecke);
  background: var(--zj-blue);
  left: min(calc(var(--zj-kamm-strich-x) + var(--zj-kamm-luecke-dx)),
            100% - var(--zj-kamm-luecke) - var(--zj-rand-min));
}
.zj-kamm[data-schraegstrich="aus"]::before { content: none; }
.zj-kamm[data-schraegstrich="aus"]::after { content: none; }

/* --- 27. Fusszeile (Komponente 25) -------------------------------------- */

.zj-fusszeile { background: var(--zj-navy); color: var(--zj-text-invert);
                min-height: var(--zj-footer-h);
                padding-block: var(--zj-abstand-96) var(--zj-abstand-48); }
.zj-fusszeile__raster { display: grid; grid-template-columns: 497px 1fr; gap: var(--zj-abstand-64) var(--zj-gap); }
.zj-fusszeile__logo img { width: var(--zj-fuss-logo-w); height: var(--zj-fuss-logo-h); }
.zj-fusszeile__marke > * + * { margin-top: var(--zj-abstand-40); }
.zj-fusszeile__block > * + * { margin-top: var(--zj-abstand-20); }
.zj-fusszeile__nav { display: grid; grid-template-columns: repeat(3, minmax(0, 1fr)); gap: var(--zj-abstand-40) var(--zj-gap); }
.zj-fusszeile__nav h3 { font-size: var(--zj-small-size); text-transform: uppercase;
                        letter-spacing: .08em; margin-bottom: var(--zj-abstand-12); }
.zj-fusszeile__nav li + li { margin-top: var(--zj-abstand-8); }
.zj-fusszeile__nav a, .zj-fusszeile__rechts a { text-decoration: underline; text-underline-offset: 3px; }
.zj-fusszeile__unten { margin-top: var(--zj-abstand-64); padding-top: var(--zj-abstand-24);
                       border-top: 1px solid var(--zj-linie-invers);
                       display: flex; flex-wrap: wrap; gap: var(--zj-abstand-12) var(--zj-abstand-24); justify-content: space-between;
                       font-size: var(--zj-small-size); }
.zj-fusszeile__rechts { display: flex; flex-wrap: wrap; gap: var(--zj-abstand-12) var(--zj-abstand-24); }

/* --- 28. Stellendetail (Komponente 26) ---------------------------------- */

.zj-stellendetail__anzeige > * + * { margin-top: var(--zj-abstand-24); }
.zj-stellendetail__karte { background: var(--zj-grey); border-radius: var(--zj-card-radius);
                           padding: var(--zj-abstand-32); display: grid; gap: var(--zj-abstand-20); }

/* --- 29. Musterseite ----------------------------------------------------- */


/* --- 30. Responsiv ------------------------------------------------------- */
/* Alle Umbruchpunkte sind Educated Guess, Begruendung je Punkt im BAU-PROTOKOLL. */

@media (max-width: 1400px) {
  /* Unter 1400 ist die feste Bildspalte von 748 px zu breit: die Textspalte
     wuerde auf unter 300 px schrumpfen. Ab hier teilen sich beide die Flaeche. */
  /* 36 statt 45 Prozent: haelt das neue Verhaeltnis 620 zu 1728 auch
     unterhalb der Artboard-Breite konstant [v2, Vivi #28/#50]. */
  .zj-hero--bild-rechts { grid-template-columns: minmax(0, 1fr) minmax(0, 36%); }
}

@media (max-width: 1200px) {
  .zj-hero--bild-rechts { min-height: 640px; }
  .zj-bildtext__raster { gap: var(--zj-abstand-32); }
  .zj-fusszeile__raster { grid-template-columns: 1fr; }
  /* Standort: unter 1200 passt die 773er Karte nicht mehr neben den Text. */
  .zj-standort { min-height: 0; }
  .zj-standort__raster { grid-template-columns: 1fr; }
  /* Die flache Karriere-Kopfzeile traegt fuenf Links plus Marke. Ab hier
     darf die Leiste umbrechen, statt aus dem Fenster zu laufen. */
  .zj-kopfzeile__leiste { flex-wrap: wrap; height: auto; min-height: var(--zj-header-h);
                          padding-block: var(--zj-abstand-8); gap: var(--zj-abstand-8) var(--zj-abstand-16); }
  .zj-kopfzeile__nav { gap: var(--zj-abstand-4); }
  .zj-kopfzeile__link { padding-inline: var(--zj-abstand-12); }
  .zj-kopfzeile__cta { margin-left: var(--zj-abstand-12); }
}

@media (max-width: 900px) {
  :root { --zj-h1-size: 40px; --zj-h1-line: 46px; --zj-h2-size: 32px; --zj-h2-line: 40px; }
  .zj-kopfzeile__nav {
    display: none; position: absolute; left: 0; right: 0; top: 100%;
    flex-direction: column; align-items: stretch; gap: var(--zj-abstand-4);
    background: var(--zj-white); padding: var(--zj-abstand-16) var(--zj-rand) var(--zj-abstand-24);
    box-shadow: 0 18px 40px rgba(20, 40, 100, .12);
  }
  .zj-kopfzeile.is-offen .zj-kopfzeile__nav { display: flex; }
  .zj-kopfzeile__burger { display: block; }
  .zj-kopfzeile__cta { display: none; }
  .zj-kopfzeile.is-offen .zj-kopfzeile__cta { display: block; margin: var(--zj-abstand-16) 0 0; }
  .zj-mega { position: static; box-shadow: none; padding-block: var(--zj-abstand-16); max-height: none; }
  .zj-mega__raster--3, .zj-mega__raster--2 { grid-template-columns: 1fr; }

  .zj-raster--3, .zj-raster--4,
  .zj-trust__raster, .zj-trust__raster--2, .zj-trust__raster--4,
  .zj-personen__raster, .zj-querverweis__raster, .zj-kontakt__raster,
  .zj-fusszeile__nav, .zj-logostrip--kennzahlen .zj-logostrip__band { grid-template-columns: 1fr; }
  .zj-raster--bento-5 { grid-template-columns: 1fr; }
  .zj-raster--bento-5 > * { grid-column: auto; }

  .zj-hero--bild-rechts { grid-template-columns: 1fr; min-height: 0; }
  .zj-hero--bild-rechts .zj-hero__text { padding: var(--zj-abstand-48) var(--zj-rand-cq); }
  .zj-hero--bild-rechts .zj-hero__bild { order: 2; }
  .zj-hero--bild-rechts .zj-bild { min-height: 320px; }
  .zj-hero--bento .zj-hero__grid { grid-template-columns: 1fr; }
  .zj-hero__spalte--versatz { padding-top: 0; }

  .zj-raster--detail { grid-template-columns: 1fr; }
  .zj-raster--detail > aside { position: static; }
  .zj-ctaband { min-height: 0; }
}

@media (max-width: 700px) {
  .zj-raster--2, .zj-raster--374-873, .zj-raster--749-499,
  .zj-bildtext__raster, .zj-raster--bild-text,
  .zj-hero__kacheln { grid-template-columns: 1fr; }
  .zj-bildtext--bild-rechts .zj-bildtext__bild,
  .zj-raster--bild-text.zj-raster--bild-rechts > :first-child { order: 0; }
  .zj-sektion { padding-block: var(--zj-sektion-pad); }
  .zj-karte__inhalt, .zj-zitat, .zj-cluster, .zj-kachel__inhalt { padding: var(--zj-abstand-24); }
  .zj-kasten { padding: var(--zj-abstand-24); }
  .zj-person { grid-template-columns: 90px 1fr; }
  /* Auf schmalen Breiten stehen Knoepfe untereinander. Nebeneinander laufen
     sie sonst aus der Spalte, weil der Primaerknopf seinen Schraegstrich
     als Aussenabstand mittraegt. */
  .zj-buttons { flex-direction: column; align-items: flex-start; }
  .zj-standort .zj-buttons { align-items: center; }
  .zj-button { max-width: 100%; }
}

@media (max-width: 480px) {
  :root { --zj-h1-size: 32px; --zj-h1-line: 38px; --zj-h2-size: 26px; --zj-h2-line: 32px;
          --zj-h3-size: 20px; --zj-h3-line: 26px; }
  .zj-button--umriss { min-width: 0; width: 100%; }
}

@media (prefers-reduced-motion: reduce) {
  * { transition: none !important; animation: none !important; }
}

/* --- 27. Echte Bilder aus Figma (09.09.2026) ----------------------------
   Text-Freeze: das Briefing bleibt als Text im DOM (.zj-vh), damit der
   Extraktor es weiter liest; sichtbar liegt das Foto darueber. Deshalb
   NICHT display:none und nicht hidden. */

.zj-vh {
  position: absolute;
  width: 1px; height: 1px;
  margin: -1px; padding: 0; border: 0;
  overflow: hidden;
  clip-path: inset(50%);
  white-space: nowrap;
}

/* Eine Flaeche, die ein echtes Foto traegt. Masse und Radius kommen
   weiter von .zj-bild / .zj-karte__bild / .zj-person__foto. */
.zj-hat-foto { position: relative; overflow: hidden; padding: 0; }
.zj-hat-foto > img {
  position: absolute; inset: 0;
  width: 100%; height: 100%;
  object-fit: cover; object-position: center;
  border-radius: inherit;
}

/* --- 31. Startseite: Bento-Hero, Logo-Band, Branchen-Raster --------------
   Gebaut 09.09.2026 aus dem Figma-Frame 472:444. Bewusst EIN Block am
   Dateiende statt verteilt in den Abschnitten: an derselben Datei arbeitete
   zeitgleich ein zweiter Bauer, und ein zusammenhaengender Block laesst sich
   ohne Konflikt einfuegen. Weil der Block hinter Abschnitt 30 steht, traegt
   er seine eigenen Umbruchpunkte am Ende (31e).
   -------------------------------------------------------------------------- */

/* 31a. Bento-Hero. Abschnitt 14b hatte den Versatz als 40 px Innenabstand
   und die Kacheln ohne feste Hoehe. Gemessen sind es 153 px NEGATIVER
   Aussenabstand der linken Spalte und Kacheln von 302 x 322; die rechte
   Spalte laeuft unten aus dem Hero heraus und wird beschnitten. */
.zj-hero--bento { overflow: hidden; }
.zj-hero--bento .zj-hero__grid {
  /* feste Hoehe, nicht min-height: die rechte Kachelspalte ist 934 hoch und
     wird in Figma vom Logo-Band beschnitten. Mit min-height waere der Hero
     52 px zu hoch. */
  height: var(--zj-hero-bento-h);
  grid-template-columns:
    minmax(0, 1fr)
    minmax(0, calc(2 * var(--zj-bento-spalte) + var(--zj-gap)));
  align-items: center;
  padding-block: 0;
}
.zj-hero--bento .zj-hero__kacheln { align-self: start; }
.zj-hero--bento .zj-hero__spalte--hoch { margin-top: calc(-1 * var(--zj-bento-versatz)); }
.zj-hero--bento .zj-hero__kachel { height: var(--zj-bento-tile-h); }
.zj-hero--bento .zj-hero__kachel .zj-bild { height: 100%; min-height: 0; }
.zj-hero--bento .zj-kachel--shop { height: var(--zj-bento-shop-h); min-height: 0; }

/* 31b. Logo-Band (Komponente: zj-logoband). Grau 151 hoch, echte
   Herstellerlogos in einer 26 px hohen Box unten buendig, darunter eine
   optionale Unterzeile 14. Figma zeigt vier Logos in zwei Durchlaeufen;
   die Komponente traegt beliebig viele. Die Bildmasse stehen als
   width/height am <img>, nicht im CSS: jedes Logo hat in Figma seine eigene
   optische Hoehe (Siemens 21, Liebherr 23, Schneider 24, ABB 26) und wuerde
   von einer gemeinsamen CSS-Hoehe verzerrt oder falsch skaliert. */
.zj-logoband {
  background: var(--zj-grey); color: var(--zj-navy);
  min-height: var(--zj-logoband-h);
  display: flex; align-items: center;
  overflow: hidden;
}
.zj-logoband__band {
  display: flex; align-items: flex-start; justify-content: center;
  flex-wrap: wrap; gap: var(--zj-abstand-20) var(--zj-logoband-gap);
  width: 100%;
}
.zj-logoband__item { display: block; }
.zj-logoband__logo { height: var(--zj-logoband-logo-h); display: flex; align-items: flex-end; }
.zj-logoband__logo img { display: block; max-width: 100%; height: auto; }
/* "Premium Partner" ist in Figma farblich abgesetzt [Vivi 10.09.2026 #11,
   am Figma-Render 14.09. bestaetigt: blau, live schwarz]. Blau und nicht
   Gelb, weil der Kanon dem Blau die Rolle "Eyebrow auf hell" gibt und diese
   Zeile genau das ist; Gelb auf Grau traegt bei 14 px nicht (1,7 zu 1),
   Blau auf #EDEDED liegt bei rund 6,4 zu 1. */
.zj-logoband__caption {
  display: block; margin-top: var(--zj-abstand-8);
  font-size: var(--zj-logo-caption-size); line-height: 1.2;
  color: var(--zj-blue);
}
/* Umlaufendes Band: zwei identische Gruppen, die zweite ist die Kopie.
   Bei prefers-reduced-motion steht es still (globale Regel in Abschnitt 30). */
.zj-logoband--laufend .zj-logoband__band {
  flex-wrap: nowrap; justify-content: flex-start; width: max-content;
  animation: zj-logoband-lauf var(--zj-logoband-lauf) linear infinite;
}
.zj-logoband--laufend .zj-logoband__gruppe {
  display: flex; align-items: flex-start; gap: var(--zj-logoband-gap);
  padding-right: var(--zj-logoband-gap);
}
@keyframes zj-logoband-lauf { from { transform: translateX(0); } to { transform: translateX(-50%); } }

/* 31c. Branchen-Raster. Drei Reihen mit ungleichen Spalten; die fr-Werte
   sind die Figma-Breiten, damit das Verhaeltnis bei jeder Fensterbreite
   stimmt und bei 1728 genau 374/873, 749/499 und 374/355/499 herauskommt. */
.zj-branchen { display: grid; gap: var(--zj-gap); }
.zj-branchen__reihe { display: grid; gap: var(--zj-gap); }
.zj-branchen__reihe--374-873     { grid-template-columns: 374fr 873fr; }
.zj-branchen__reihe--749-499     { grid-template-columns: 749fr 499fr; }
.zj-branchen__reihe--374-355-499 { grid-template-columns: 374fr 355fr 499fr; }
.zj-branchen .zj-karte, .zj-branchen > * > .zj-bild { min-height: var(--zj-branchen-karte-h); }

/* Karte mit Bild an der Seite: das Bild laeuft bis an drei Kartenkanten.
   In Figma sind es freigestellte Motive auf der Kartenflaeche; als
   Platzhalter steht hier die graue Flaeche in derselben Breite. */
.zj-karte--bild-seite { flex-direction: row; }
.zj-karte--bild-seite > .zj-karte__seitenbild {
  flex: 0 0 var(--zj-branchen-bild-w); align-self: stretch;
  border-radius: 0; min-height: 0;
}
.zj-karte--bild-seite > .zj-karte__inhalt { min-width: 0; justify-content: center; }
.zj-karte--bild-seite.zj-karte--bild-rechts { flex-direction: row-reverse; }

/* Karte, die alles in einer Farbe setzt. Der Kanon macht Links und Eyebrow
   auf dunklem Grund gelb; die blaue Fragen-Karte der Startseite ist in
   Figma durchgehend weiss, Haken und Pfeil eingeschlossen. */
.zj-karte--einfarbig { --zj-link-farbe: currentColor; --zj-punkt-farbe: currentColor; }
.zj-karte--einfarbig .zj-eyebrow { color: currentColor; }

/* Karte, die nur ein Bild traegt (Tablet-Kachel, LKW-Kachel). */
.zj-karte--nurbild { padding: 0; }
.zj-karte--nurbild > .zj-bild { flex: 1; border-radius: 0; min-height: 0; }

/* 31d. Aufklapp-Pfeil unter einer Karte (dritte Projektkarte in Figma). */
.zj-karte__mehr {
  margin-top: auto; padding-top: var(--zj-abstand-20);
  display: flex; justify-content: center;
  color: var(--zj-navy);
}
.zj-karte__mehr .zj-icon { width: 18px; height: 12px; }

/* 31e. Umbruchpunkte fuer die Startseiten-Bausteine. Stehen hier, weil
   dieser Block hinter Abschnitt 30 liegt und sonst dessen Regeln schluege. */
@media (max-width: 1200px) {
  /* Zwei feste 302er Spalten plus Text passen ab hier nicht mehr nebeneinander. */
  .zj-hero--bento .zj-hero__grid { grid-template-columns: minmax(0, 1fr) minmax(0, 50%); height: auto; min-height: var(--zj-hero-bento-h); }
  .zj-hero--bento .zj-hero__kachel { height: auto; min-height: 240px; }
  .zj-hero--bento .zj-hero__spalte--hoch { margin-top: 0; }
  .zj-branchen .zj-karte, .zj-branchen > * > .zj-bild { min-height: 300px; }
}

@media (max-width: 900px) {
  .zj-hero--bento { overflow: visible; }
  .zj-hero--bento .zj-hero__grid { grid-template-columns: 1fr; min-height: 0; padding-block: var(--zj-abstand-48); }
  .zj-hero--bento .zj-kachel--shop { height: auto; min-height: 240px; }
  .zj-branchen__reihe--374-873,
  .zj-branchen__reihe--749-499,
  .zj-branchen__reihe--374-355-499 { grid-template-columns: 1fr; }
  .zj-branchen .zj-karte, .zj-branchen > * > .zj-bild { min-height: 0; }
  .zj-karte--bild-seite, .zj-karte--bild-seite.zj-karte--bild-rechts { flex-direction: column; }
  .zj-karte--bild-seite > .zj-karte__seitenbild { flex: 0 0 auto; min-height: 200px; }
  .zj-karte--nurbild > .zj-bild { min-height: 220px; }
  .zj-logoband__band { justify-content: flex-start; }
}

/* 31f. Shop-Kachel: "Shop" ist in Figma gelb UND der Link, der Pfeil steht
   in derselben Zeile dahinter (60 x 35, Kanon). */
.zj-kachel__link {
  color: var(--zj-yellow); text-decoration: none;
  display: inline-flex; align-items: center; gap: var(--zj-abstand-16);
}
.zj-kachel__link .zj-icon--pfeil { width: 60px; height: 35px; }

/* 31g. Standort auf der Startseite. Figma laesst die Karte nach rechts ueber
   die Inhaltsbreite hinauslaufen: rechte Kante bei x 1641 statt 1498. Erst
   dadurch wird die Textspalte 605 statt 455 breit und die beiden Knoepfe
   stehen nebeneinander. Der Ueberhang endet, sobald der Seitenrand ihn nicht
   mehr hergibt: unter 1560 px Fensterbreite ist der Rand kleiner als 145 und
   der Ueberhang wuerde die Seite waagerecht ueberlaufen lassen. Als Media Query
   statt als min()-Rechnung, weil --zj-rand mit 100 Prozent des ELTERNelements
   rechnet und in der Kartenspalte deshalb den falschen Wert ergibt. */
@media (min-width: 1560px) {
  /* Nicht als negativer Aussenabstand: .zj-inhalt hat width:100%, dort wirkt er
     nicht, und als Ueberbreite erzeugt er waagerechten Ueberlauf. Stattdessen
     faellt der rechte Seitenrand um 145 kleiner aus. */
}

/* --- 32. Startseiten-Bilder aus Figma (09.09.2026) -----------------------
   Der Regelfall laeuft ueber .zj-hat-foto (Abschnitt 27): Foto formatfuellend,
   beschnitten. Drei Motive der Startseite sind aber FREIGESTELLT (Ortsschild,
   Industrieroboter, Lkw) und die Deutschlandkarte ist eine Zeichnung: sie
   liegen frei auf der Kartenflaeche und duerfen nicht beschnitten werden.
   Deshalb hier contain statt cover und kein Platzhaltergrau dahinter. */
.zj-hat-foto--frei { background: transparent; }

/* Standortkarte inline (14.09.2026, Vivi #26). Als <img> lief sie ueber die
   absolute Regel oben; inline ist sie ein normales Blockelement. Breite nach
   der Flaeche, Hoehe aus dem viewBox-Verhaeltnis: damit ist das im SVG
   stehende preserveAspectRatio="none" wirkungsgleich mit "meet" und muss
   nicht angefasst werden (es traegt die Pixelgleichheit des Bestands).
   overflow sichtbar, damit ein Namenskaestchen am Rand nicht abgeschnitten wird. */
.zj-hat-karte { overflow: visible; display: grid; align-content: center; }
.zj-hat-karte > svg, .zj-hat-karte > object { display: block; width: 100%; height: auto;
  max-width: var(--zj-karte-nord-w); aspect-ratio: 773 / 628; justify-self: center; }

/* Freisteller duerfen aus der Karte herausragen (Figma: Roboter oben, Schild
   unten). Dafuer muss die Karte ihren Beschnitt aufgeben; sie behaelt ihn
   ueberall sonst, deshalb haengt die Regel am Bild, nicht an der Karte.
   Der Stapel ist wichtig: die herausragende Kachel liegt UEBER der Nachbarin. */
.zj-karte:has(.zj-hat-foto--ragt) { overflow: visible; position: relative; z-index: 1; }
/* Fix-Runde 15.09.2026 [Opus-B3, zweite Haelfte]: "der Pfosten wird von der
   naechsten Reihe abgeschnitten" REPRODUZIERT NICHT. Gemessen mit
   elementFromPoint(844, y) fuer y = 2170, 2185, 2200, 2220: an jeder Stelle
   liegt das IMG des Ortsschilds zuoberst, keine Karte der Handel-Reihe deckt
   es zu. Der Pfosten endet bei y 2184, weil dort die gezeichnete Stange im
   PNG endet, nicht wegen eines Beschnitts. Die z-index-1-Stufe oben genuegt,
   eine zweite waere eine Regel ohne Befund. */
.zj-hat-foto--ragt { overflow: visible; }
.zj-hat-foto--ragt img {
  max-width: none;
  object-fit: contain;
  /* Zoom und Versatz stehen je Motiv weiter unten. object-fit alleine reicht
     nicht: es passt das Bild IN den Kasten, Figma laesst es darueber hinaus. */
  transform: translate(var(--zj-frei-dx, 0), var(--zj-frei-dy, 0))
             rotate(var(--zj-frei-rot, 0deg))
             scale(var(--zj-frei-zoom, 1));
  transform-origin: center;
}

/* Die drei Motive einzeln, weil sie in Figma verschieden weit herausragen.
   Zoomfaktoren aus dem Groessenvergleich Figma gegen Render [PX:2026-09-09 23:00];
   Richtung und Versatz sind Educated Guess, Vivi korrigiert.
   Ortsschild: Figma dreht GEGEN den Uhrzeigersinn, gemessen -14 Grad an der
   Oberkante des schwarzen Rahmens (Simeon 22:55: "genau andersrum"). */
/* v2, 14.09.2026: Groesse und Beschnitt aus dem Pixelvergleich Figma gegen
   live nachgezogen (_verify/startseite-figma-vs-live-2026-09-14.md).
   Ortsschild #25: in Figma groesser, der Pfosten laeuft unter die
   Kartenunterkante in die Rasterluecke.
   Lkw #1/#16: in Figma etwa auf Kartenbreite mit knappem Ueberstand nach
   links, NICHT die 1,85fache Vergroesserung aus v1, die rund 80 px ueber
   den Rasterrand hinauslief.
   Roboter #14: NICHT gespiegelt (in Figma zeigt der Arm ebenfalls nach
   rechts oben), aber groesser: die Basis sitzt in Figma ohne Abstand auf
   der Kartenunterkante, der Greifer ragt ueber die Oberkante. */
/* Fix-Runde 15.09.2026:
   [Opus-B3] Ortsschild: bei Zoom 1.10 / dx -1% lag der rechte Schildrand bei
   x 997 und damit UEBER der Tablet-Karte (linke Kante 999). Gemessen am
   Vollseiten-Schuss, nicht gerechnet. Jetzt 1.06 / -5%: der Schildrand bleibt
   links der Rasterluecke, der Ueberstand nach UNTEN (dy 10%) bleibt wie Figma.
   [Klaas, Pixelvergleich] Lkw: 1.14 war zu klein und saß zu hoch. Figma-Maß
   ist Kartenbreite plus rund 15 px Ueberstand links, Raeder auf der
   Karten-Unterkante. Aus der Alpha-Box des PNG (sichtbarer Lkw 970 x 578 von
   1200 x 800) und der Bildbox 374 x 344 gerechnet: Zoom 1.29, dx 10%, dy 13%.
   Die Ledger-Zeile "Koffer-Oberkante auf Karten-Oberkante" ist bei
   Kartenbreite nicht erfuellbar: das Seitenverhaeltnis des Freistellers
   (1,68) ergibt bei 389 px Breite 232 px Hoehe, die Karte ist 344 hoch.
   Breite und Unterkante sind gebaut, die Oberkante ist der Rest. */
.zj-hat-foto--kommunen  { --zj-frei-rot: -11deg; --zj-frei-zoom: 1.00; --zj-frei-dx: -8%; --zj-frei-dy: 10%; }
.zj-hat-foto--handel    { --zj-frei-zoom: 1.29; --zj-frei-dx: 7%; --zj-frei-dy: 8%; }
.zj-hat-foto--industrie { --zj-frei-zoom: 1.72; --zj-frei-dy: -4%; }
.zj-hat-foto--frei > img { object-fit: contain; }
/* In einer Karte haelt der Freisteller Abstand zu den Kanten, wie in Figma.
   Als inset, nicht als padding: das Bild ist absolut gesetzt (Abschnitt 27). */
.zj-karte .zj-hat-foto--frei > img { inset: var(--zj-abstand-16); }

/* --- 33. Interaktion: Hover, Fokus, Megamenue (09.09.2026) ---------------

   Bis hierher hatte das System drei :hover-Regeln. Dieser Abschnitt gibt
   jedem bedienbaren Element einen sichtbaren Zustand. Vier Regeln liegen
   darunter:

   1. DIE RUHELAGE BEWEGT SICH NICHT. Kein Hover aendert ein Mass im
      Ruhezustand. Jeder Marker liegt in einem absolut gesetzten
      Pseudo-Element oder als Rahmen, der im Ruhezustand schon da und nur
      durchsichtig ist. Der Pixel-Diff der drei Seiten ohne Zeiger ist 0.
   2. ZWEI ZEICHEN, NIE NUR EINS. Der Text wechselt die Farbe (immer
      kontraststark), dazu kommt ein gelber Marker. Wer den gelben Balken
      auf Grau schlecht sieht, sieht den Farbwechsel. Der Zustand haengt nie
      allein am Gelb.
   3. EINE SCHRAEGE. Das System kennt genau eine Neigung (26 Grad, Backslash).
      Wo ein Marker gross genug ist, dass man sie sieht, traegt er sie:
      der Balken unter einem Navigationslink und an der Kartenunterkante
      haben schraege Enden. Wo sie unsichtbar waere, wird sie weggelassen
      statt vorgetaeuscht.
   4. RUHIG, NICHT VERSPIELT. 160 ms, keine Federung, keine Skalierung einer
      ganzen Flaeche, kein generischer Schlagschatten. Der einzige groessere
      Weg ist der abgetrennte Schraegstrich des Primaerknopfs, der seine
      Luecke schliesst: die Form der Marke wird selbst zur Geste.

   Was hier NICHT steht: eine Abhaengigkeit von system.js. Alle Zustaende
   sind CSS. Das Skript verbessert nur (Klick, Escape, Klick nach aussen).

   :focus-visible ist ueberall an :hover gekoppelt. Der Fokusrahmen aus
   Abschnitt 2 bleibt zusaetzlich stehen; der Marker macht die Tastaturspur
   nur eindeutiger. Reine :focus-Zustaende sind bewusst NICHT gekoppelt,
   sonst blitzt der Marker bei jedem Mausklick auf.
   ------------------------------------------------------------------------ */

/* 33a. Kopfzeile: Links und Menue-Ausloeser --------------------------------
   v2, 14.09.2026. Die Unterstreichung ist ERSATZLOS GESTRICHEN
   [Vivi #5 "beim aktiven Punkt ueberfluessig", #27/#54 "zu viel";
   Entscheid design-entscheide-v2 Punkt 1]. An ihre Stelle tritt die
   flaechige Hinterlegung: vier Zustaende, vier Flaechenfarben, dazu immer
   ein Textfarbwechsel (Regel 2: zwei Zeichen, nie nur eins).

     Ruhe          transparent      Navy
     Hover         Grau  #EDEDED    Elektroblau #0049E3
     Aktiv         Navy  #142864    Weiss
     Aktiv+Hover   Blau  #0049E3    Weiss

   Die Tokens --zj-hover-linie-h und --zj-hover-linie-dx tragen seitdem
   nichts mehr; sie bleiben bis zu einer eigenen Aufraeumrunde stehen. */
.zj-kopfzeile__link {
  --zj-nav-pad: var(--zj-abstand-24); position: relative;
  transition: background-color var(--zj-hover-zeit) var(--zj-hover-kurve),
              color            var(--zj-hover-zeit) var(--zj-hover-kurve);
}
.zj-kopfzeile--flach .zj-kopfzeile__link { --zj-nav-pad: var(--zj-abstand-16); }
.zj-kopfzeile__link:is(:hover, :focus-visible) {
  background: var(--zj-grey); color: var(--zj-hover-text);
}
.zj-kopfzeile__link.is-aktiv:is(:hover, :focus-visible) {
  background: var(--zj-blue); color: var(--zj-white);
}

/* Chevron: nickt beim Ueberfahren 2 px nach unten. Im geoeffneten Zustand
   nicht, dort haelt die 180-Grad-Drehung aus Abschnitt 13 den Platz. */
.zj-kopfzeile__trigger:hover .zj-icon--chevron { transform: translateY(var(--zj-hover-weg-klein)); }
.zj-kopfzeile__trigger[aria-expanded="true"]:hover .zj-icon--chevron { transform: rotate(180deg); }

/* Burger und Logos. Das Logo ist ein Bild, es hat keine Textfarbe;
   der ehrliche Zustand ist eine leichte Abschwaechung. */
.zj-kopfzeile__burger span { transition: background-color var(--zj-hover-zeit) var(--zj-hover-kurve); }
.zj-kopfzeile__burger:is(:hover, :focus-visible) span { background: var(--zj-hover-text); }
.zj-kopfzeile__logo, .zj-fusszeile__logo { transition: opacity var(--zj-hover-zeit) var(--zj-hover-kurve); }
.zj-kopfzeile__logo:is(:hover, :focus-visible),
.zj-fusszeile__logo:is(:hover, :focus-visible) { opacity: .72; }

/* 33b. Megamenue: oeffnen und schliessen mit Weg ---------------------------
   Die Klappe wechselt zwischen display:none und display:block. Damit das
   nicht springt, laeuft der Wechsel ueber transition-behavior: allow-discrete
   plus @starting-style. Das deckt BEIDE Wege ab, ohne dass einer vom anderen
   weiss: den Zeiger (:hover / :focus-within, reines CSS) und die Tastatur und
   den Klick (system.js schaltet nur das hidden-Attribut).
   Ohne Skript bleibt alles wie bisher bedienbar. */
.zj-mega {
  opacity: 1; transform: translateY(0);
  transition: opacity var(--zj-mega-zeit) var(--zj-hover-kurve),
              transform var(--zj-mega-zeit) var(--zj-hover-kurve),
              display var(--zj-mega-zeit) allow-discrete;
}
/* Geschlossen: unsichtbar und 6 px hoeher. display:none aus Abschnitt 13
   bleibt, wird durch allow-discrete aber erst am Ende des Weges wirksam. */
.zj-mega[hidden] { opacity: 0; transform: translateY(calc(-1 * var(--zj-mega-weg))); }
/* Geoeffnet ohne Skript: die Regel aus Abschnitt 13 setzt nur display,
   hier kommen die zwei sichtbaren Eigenschaften dazu. */
.zj-kopfzeile__punkt:hover > .zj-mega[hidden],
.zj-kopfzeile__punkt:focus-within > .zj-mega[hidden] { opacity: 1; transform: translateY(0); }
/* Der Startwert des Weges. Die drei Selektoren stehen hier EINZELN und der
   Block steht HINTER den Regeln oben, beides mit Absicht: der Startwert wird
   auf den Zielwert gestapelt und verliert bei geringerer Spezifitaet oder
   frueherer Position. Mit nur ".zj-mega" schlug die Hover-Regel (0,4,0) den
   Startwert (0,1,0) - das Menue sprang beim Oeffnen per Zeiger auf, waehrend
   der Skriptweg sauber lief. Am laufenden Bild pro Frame gemessen. */
@starting-style {
  .zj-mega,
  .zj-kopfzeile__punkt:hover > .zj-mega[hidden],
  .zj-kopfzeile__punkt:focus-within > .zj-mega[hidden] {
    opacity: 0; transform: translateY(calc(-1 * var(--zj-mega-weg)));
  }
}

/* 33c. Knoepfe ------------------------------------------------------------- */

/* Primaer: der abgetrennte Schraegstrich laeuft beim Ueberfahren nach RECHTS,
   also von der Luecke WEG, und das Gelb wird eine Spur tiefer.
   [Vivi 10.09.2026 #6/#9/#21/#49/#51: "der schraege Balken soll nach vorn
   laufen, heute zieht er sich zusammen."] Bis v1 lief er nach links und
   schloss die Luecke; damit verschwand genau das Zeichen, das die Marke
   ausmacht. Weg bleibt die halbe Luecke (6 von 12 px), nur die Richtung
   dreht: der Strich loest sich weiter ab, statt anzudocken. */
.zj-button--primaer::before,
.zj-button--primaer::after {
  transition: background-color var(--zj-hover-zeit) var(--zj-hover-kurve),
              transform var(--zj-hover-zeit) var(--zj-hover-kurve);
}
.zj-button--primaer:is(:hover, :focus-visible)::before,
.zj-button--primaer:is(:hover, :focus-visible)::after { background: var(--zj-yellow-tief); }
.zj-button--primaer:is(:hover, :focus-visible)::after {
  transform: translateX(calc(var(--zj-btn-slash-gap) / 2));
}

/* Sekundaer: Pfeil laeuft (Bestand seit 08.09.), Farbe wechselt dazu. */
.zj-button--sekundaer { transition: color var(--zj-hover-zeit) var(--zj-hover-kurve); }
.zj-button--sekundaer:is(:hover, :focus-visible) { color: var(--zj-hover-text); }
.zj-button--sekundaer:is(:hover, :focus-visible) .zj-icon--pfeil {
  transform: translateX(var(--zj-hover-weg));
}

/* Umriss: der Rahmen ist im Ruhezustand schon da, er wird nur gefuellt.
   Der Text nimmt die Farbe der Flaeche an, auf der der Knopf steht. */
.zj-button--umriss {
  transition: background-color var(--zj-hover-zeit) var(--zj-hover-kurve),
              color var(--zj-hover-zeit) var(--zj-hover-kurve);
}
.zj-button--umriss:is(:hover, :focus-visible) {
  background: var(--zj-umriss-farbe, var(--zj-navy));
  color: var(--zj-umriss-text, var(--zj-white));
}
/* Auf Blau und Navy ist der Umriss gelb, gefuellt traegt er deshalb Navy. */
.zj-sektion--navy, .zj-sektion--blau, .zj-hero--bild-rechts, .zj-hero--band,
.zj-trust, .zj-ctaband, .zj-standort, .zj-fusszeile,
.zj-kasten--navy, .zj-karte--blau, .zj-kachel--shop, .zj-auf-dunkel { --zj-umriss-text: var(--zj-navy); }

/* 33d. Verlinkte Karten und Megakarten -------------------------------------
   Balken an der Unterkante, waechst von links, mit schraegen Enden.
   Die Karte hat overflow:hidden und einen Radius, der Balken folgt der
   Rundung von selbst. Nichts an der Karte bewegt sich. */
a.zj-karte, .zj-megakarte { position: relative; }
a.zj-karte::after {
  content: ""; position: absolute; pointer-events: none; z-index: 2;
  left: 0; right: 0; bottom: 0;
  height: var(--zj-hover-kante-h);
  background: var(--zj-hover-marke);
  clip-path: polygon(var(--zj-hover-kante-dx) 0, 100% 0,
                     calc(100% - var(--zj-hover-kante-dx)) 100%, 0 100%);
  transform: scaleX(0); transform-origin: left center;
  transition: transform var(--zj-hover-zeit) var(--zj-hover-kurve);
}
a.zj-karte:is(:hover, :focus-visible)::after { transform: scaleX(1); }
a.zj-karte :is(.zj-karte__titel, .zj-h3),
.zj-megakarte__titel { transition: color var(--zj-hover-zeit) var(--zj-hover-kurve); }
a.zj-karte:is(:hover, :focus-visible) :is(.zj-karte__titel, .zj-h3),
.zj-megakarte:is(:hover, :focus-visible) .zj-megakarte__titel { color: var(--zj-hover-text); }

/* v2 (#48, #61): die Karte wechselt zusaetzlich ihren Grund und ihren
   Textlink. Drei Zeichen gleichzeitig, weil Vivi zweimal "reicht nicht"
   geschrieben hat. Nichts bewegt sich, background-color ist kein Mass. */
a.zj-karte { transition: background-color var(--zj-hover-zeit) var(--zj-hover-kurve); }
a.zj-karte:is(:hover, :focus-visible) { background: var(--zj-hellblau); }
a.zj-karte .zj-karte__link,
a.zj-karte .zj-button--sekundaer { transition: color var(--zj-hover-zeit) var(--zj-hover-kurve); }
a.zj-karte:is(:hover, :focus-visible) :is(.zj-karte__link, .zj-button--sekundaer) {
  color: var(--zj-hover-text);
}
/* Gelbe Karte behaelt ihren Grund: ein helleres Gelb gibt es nicht. */
.zj-karte--gelb:is(:hover, :focus-visible) { background: var(--zj-yellow); }

/* Megakarte v2: derselbe Gedanke eine Ebene tiefer. Der gelbe
   Unterkantenbalken entfaellt hier (Entscheid Punkt 1), die Flaeche
   wechselt auf Grau, der Titel auf Elektroblau. Radius bleibt 10 px,
   das ist eine Karte und kein Navigationspunkt. */
.zj-megakarte { transition: background-color var(--zj-hover-zeit) var(--zj-hover-kurve); }
.zj-megakarte:is(:hover, :focus-visible) { background: var(--zj-grey); }
/* Der Pfeil in einer verlinkten Karte laeuft mit, auch wenn der Zeiger
   irgendwo auf der Karte steht und nicht auf dem Link. */
a.zj-karte:is(:hover, :focus-visible) .zj-icon--pfeil { transform: translateX(var(--zj-hover-weg)); }
/* Auf gelbem Grund ist ein gelber Marker unsichtbar: dort Navy. */
.zj-karte--gelb, .zj-kasten--gelb { --zj-hover-marke: var(--zj-navy); }

/* 33e. Kachel mit Foto (Shop-Kachel und Bento) ----------------------------- */
.zj-kachel__link { transition: color var(--zj-hover-zeit) var(--zj-hover-kurve); }
.zj-kachel__link .zj-icon--pfeil { transition: transform var(--zj-hover-zeit) var(--zj-hover-kurve); }
/* Zwei Ausloeser: die ganze Kachel (das Foto ist die Flaeche, die man
   anfaehrt) UND der Link selbst. Ohne den zweiten bleibt der Link ohne
   Zustand, wenn der Zeiger genau auf ihm steht und nicht auf der Kachel -
   im Zensus aufgefallen. */
.zj-kachel:is(:hover, :focus-within) .zj-kachel__link,
.zj-kachel__link:is(:hover, :focus-visible) { color: var(--zj-hover-text); }
.zj-kachel:is(:hover, :focus-within) .zj-kachel__link .zj-icon--pfeil,
.zj-kachel__link:is(:hover, :focus-visible) .zj-icon--pfeil {
  transform: translateX(var(--zj-hover-weg));
}

/* 33f. Pillen, Listen-Chips, Aufklapp-Pfeil --------------------------------
   Die Pille traegt im Ruhezustand schon einen 1 px Rahmen in transparent
   (Abschnitt 8), er wird nur eingefaerbt. Kein Sprung. */
a.zj-pill, button.zj-pill {
  transition: border-color var(--zj-hover-zeit) var(--zj-hover-kurve),
              color var(--zj-hover-zeit) var(--zj-hover-kurve);
}
a.zj-pill:is(:hover, :focus-visible),
button.zj-pill:is(:hover, :focus-visible) { border-color: currentColor; color: var(--zj-hover-text); }
a.zj-pill.is-aktiv:is(:hover, :focus-visible),
button.zj-pill.is-aktiv:is(:hover, :focus-visible) { color: var(--zj-white); border-color: var(--zj-yellow); }

.zj-karte__mehr .zj-icon { transition: transform var(--zj-hover-zeit) var(--zj-hover-kurve); }
:is(a, button).zj-karte__mehr:is(:hover, :focus-visible) .zj-icon,
a.zj-karte:is(:hover, :focus-visible) .zj-karte__mehr .zj-icon {
  transform: translateY(var(--zj-hover-weg-klein));
}

/* 33g. Fusszeile, Tabellenzeilen, Textlinks ohne Klasse --------------------
   Reihenfolge mit Absicht: die Untergrenze fuer klassenlose Links steht
   ZUERST, alles Benannte danach. Beide haben dieselbe Spezifitaet (0,2,1),
   ein Gleichstand wird nach Position entschieden. Stand die Untergrenze
   hinten, gewann sie gegen die Fusszeile - und dort ist ihre Hover-Farbe
   Weiss auf weissem Text, also gar kein Zustand. Im Zensus aufgefallen:
   18 Fusszeilenlinks ohne sichtbare Aenderung. */
a:not([class]) { transition: color var(--zj-hover-zeit) var(--zj-hover-kurve); }
a:not([class]):is(:hover, :focus-visible) { color: var(--zj-hover-flieszlink); }

.zj-fusszeile a { transition: color var(--zj-hover-zeit) var(--zj-hover-kurve); }
.zj-fusszeile a:is(:hover, :focus-visible) { color: var(--zj-hover-flieszlink); }
.zj-tabelle--stellen tbody tr { transition: background-color var(--zj-hover-zeit) var(--zj-hover-kurve); }
.zj-tabelle--stellen td a { transition: color var(--zj-hover-zeit) var(--zj-hover-kurve); }
.zj-tabelle--stellen tbody tr:hover td a { color: var(--zj-hover-text); }

/* 33h. Funktionszeile der Personenkarte ------------------------------------
   Kein Hover, sondern Simeons Vorgabe vom 09.09.: 2 px kleiner als der
   Fliesstext, Zeilenhoehe mitgezogen (25 x 16/18 = 22). Die Karte behaelt
   ihre Hoehe: 20 Polster + 25 Name + 22 Funktion = 67, die Mindesthoehe
   ist 120. */
.zj-person__fn { font-size: var(--zj-person-fn-size); line-height: var(--zj-person-fn-line); }

/* 33i. Wenig Bewegung ------------------------------------------------------
   Abschnitt 30 schaltet transition und animation global ab. Das reicht NICHT:
   ein Hover, der ein Element um 4 px verschiebt, verschiebt es dann eben
   sofort statt weich. Die Vorgabe lautet, Farbwechsel duerfen bleiben, Wege
   nicht. Deshalb hier jeder Weg noch einmal ausdruecklich auf null.
   Die Marker bleiben: ein Balken, der ohne Dauer erscheint, ist ein
   Farbwechsel, kein Weg. */
@media (prefers-reduced-motion: reduce) {
  .zj-button--sekundaer:is(:hover, :focus-visible) .zj-icon--pfeil,
  a.zj-karte:is(:hover, :focus-visible) .zj-icon--pfeil,
  .zj-kachel:is(:hover, :focus-within) .zj-kachel__link .zj-icon--pfeil,
  .zj-kopfzeile__trigger:hover .zj-icon--chevron,
  .zj-button--primaer:is(:hover, :focus-visible)::after,
  :is(a, button).zj-karte__mehr:is(:hover, :focus-visible) .zj-icon,
  a.zj-karte:is(:hover, :focus-visible) .zj-karte__mehr .zj-icon,
  /* v2-Wege: NICHT hier. Ihre Regeln stehen in Abschnitt 34 und damit spaeter
     in der Datei; bei gleichem Selektor und gleicher Spezifitaet haette die
     spaetere Deklaration gewonnen und der Schutz waere wirkungslos gewesen
     (Fix-Runde 15.09.2026, Forge-B1). Sie stehen jetzt in Abschnitt 35 am
     Dateiende. Regel: jeder Bewegungs-Schutz steht HINTER der Bewegung. */
  /* Der Chevron behaelt seine Drehung, sie ist ein Zustand, kein Weg. */
  .zj-kopfzeile__trigger[aria-expanded="true"]:hover .zj-icon--chevron { transform: rotate(180deg); }
  /* Die Klappe erscheint ohne Weg. */
  .zj-mega, .zj-mega[hidden],
  .zj-kopfzeile__punkt:hover > .zj-mega[hidden],
  .zj-kopfzeile__punkt:focus-within > .zj-mega[hidden] { transform: none; }
}

/* --- 34. v2, Vivis Korrekturen vom 10.09.2026 ----------------------------
   Alles, was mehr als eine Bestandszeile berührt, steht hier gesammelt und
   hinter Abschnitt 33, damit die Kaskade eindeutig ist. Jede Regel trägt die
   Kommentarnummer, aus der sie stammt.
   ------------------------------------------------------------------------ */

/* 34a. Die eine Unterstreichungsregel (#23, dazu #36, #43, #44, #58, #59)
   Ein Link wird unterstrichen, wenn er KEINEN eigenen Marker hat. Hat er
   einen Pfeil, einen Knopfkörper, eine Pille oder eine Kartenfläche, wird er
   nicht unterstrichen. Damit fällt Vivis „entweder alle oder keinen" als
   Regel und nicht als Einzelfall.
   text-underline-offset 3px ist Bestand aus .zj-fusszeile__nav a und wird
   hier zur Systemregel. Der Hover ändert die Unterstreichung nicht, nur die
   Farbe (Abschnitt 33g). */
.zj-body a:not(.zj-button),
.zj-lead a:not(.zj-button),
.zj-sektion__fuss a:not(.zj-button),
/* Fix-Runde 15.09.2026 [Opus-S3]: der Selektor sagte "jeder Link in der
   Fusszeile", gemeint war "Link ohne eigenen Marker". Der Logolink traegt
   nur ein Bild; heute unsichtbar, aber ein kuenftiger Icon-Link bekaeme
   einen Strich durchs Icon. */
.zj-fusszeile a:not(.zj-button):not(.zj-fusszeile__logo) {
  font-weight: var(--zj-weight-bold);
  text-decoration: underline;
  text-underline-offset: 3px;
  text-decoration-thickness: 1px;
}

/* 34b. Eyebrow in der Karte (#15) */
.zj-karte__eyebrow { color: var(--zj-eyebrow-karte); }
/* Auf dunklen und farbigen Karten gilt weiter die Flächenfarbe. */
.zj-karte--blau .zj-karte__eyebrow { color: var(--zj-yellow); }
.zj-karte--einfarbig .zj-karte__eyebrow { color: currentColor; }
.zj-sektion--navy .zj-karte--weiss .zj-karte__eyebrow { color: var(--zj-eyebrow-karte); }

/* 34c. Kartentexte nach Kanon (#13)
   Der Kanon sagt „mit Eyebrow (Startseite, Medium 18 über dem Titel, 38 px
   Abstand)"; der Bau setzte 24. Vivi: „Abstände zwischen den Texten weichen
   von Figma ab." Der Kanon hatte recht, wie schon beim Schrägstrich. */
.zj-karte__eyebrow + .zj-karte__titel { margin-top: var(--zj-karte-eyebrow-zu-titel); }

/* 34d. Klickbarkeit: Bento-Kachel (#7)
   Die Ursache war nicht die Animation, sondern die Ruhelage: die Kachel war
   gar kein Link. Sie ist jetzt eines, und die Navy-Leiste trägt im
   Ruhezustand einen weißen Pfeil rechts. */
.zj-hero__kachel-label {
  gap: var(--zj-abstand-12);
  transition: background-color var(--zj-hover-zeit) var(--zj-hover-kurve);
}
.zj-hero__kachel-label .zj-icon--pfeil {
  margin-left: auto;
  transition: transform var(--zj-hover-zeit) var(--zj-hover-kurve);
}
a.zj-hero__kachel { display: block; color: inherit; text-decoration: none; }
.zj-hero__kachel:is(:hover, :focus-within) .zj-hero__kachel-label {
  background: var(--zj-blue);
}
.zj-hero__kachel:is(:hover, :focus-within) .zj-hero__kachel-label .zj-icon--pfeil {
  transform: translateX(var(--zj-hover-weg));
}

/* 34e. Klickbarkeit: Shop-Kachel (#8)
   Der Textlink war da, nur zu leise. Bis v1 schaltete er auf
   --zj-hover-text, also Blau auf Blau: das war kein Zustand, sondern ein
   echter Fehler im Bestand. Jetzt Weiß plus Unterstreichung, und der große
   60-px-Pfeil bekommt den doppelten Weg. */
.zj-kachel--shop .zj-kachel__link,
.zj-kachel--shop:is(:hover, :focus-within) .zj-kachel__link,
.zj-kachel--shop .zj-kachel__link:is(:hover, :focus-visible) {
  text-decoration: none;
}
.zj-kachel--shop:is(:hover, :focus-within) .zj-kachel__link,
.zj-kachel--shop .zj-kachel__link:is(:hover, :focus-visible) {
  color: var(--zj-white);
  text-decoration: underline;
  text-underline-offset: 4px;
  text-decoration-thickness: 2px;
}
.zj-kachel--shop:is(:hover, :focus-within) .zj-kachel__link .zj-icon--pfeil,
.zj-kachel--shop .zj-kachel__link:is(:hover, :focus-visible) .zj-icon--pfeil {
  transform: translateX(var(--zj-hover-weg-gross));
}

/* 34f. Querverweis-Karte: Zeichen in der Ruhelage (#48, #61)
   Vivi: „Textlink fehlt, gelber Balken und Textfarbe reichen nicht."
   Der Wortlaut „Mehr erfahren" aus der Entscheide-Datei ist NICHT gebaut,
   er wäre neuer Text und der Text ist eingefroren (siehe Ledger, Abschnitt
   Abweichungen). Stattdessen trägt die Karte den Pfeil der Komponente
   „Textlink mit Pfeil" schon im Ruhezustand, auf Industrie zusätzlich den
   vorhandenen Wortlaut „Zur Seite →" in Linkfarbe und Bold. */
.zj-querverweis__raster a.zj-karte .zj-karte__pfeil {
  display: block; margin-top: var(--zj-abstand-16); color: var(--zj-navy);
  transition: transform var(--zj-hover-zeit) var(--zj-hover-kurve),
              color var(--zj-hover-zeit) var(--zj-hover-kurve);
}
.zj-querverweis__raster a.zj-karte:is(:hover, :focus-visible) .zj-karte__pfeil {
  color: var(--zj-hover-text); transform: translateX(var(--zj-hover-weg));
}

/* 34g. Nichtumbrechende Wortpaare (#37)
   Simeon 14.09.: keine Silbentrennung, das war ein Umbruch am Bindestrich.
   Als Klasse und nicht als geschütztes Zeichen, damit der Wortlaut im
   Quelltext buchstabengleich bleibt und das Text-Gate weiter greift. */
.zj-nowrap { white-space: nowrap; }

/* 34h. Raster und Abstände (Vivis Block B) */
/* #19 Bild und Text zu gleichen Teilen. War 2fr zu 3fr. */
.zj-bildtext__raster { grid-template-columns: minmax(0, 1fr) minmax(0, 1fr); }
/* #18 Abstand Text zu Buttons. Der Fließtext-Rhythmus 24 reicht vor einer
   Buttonzeile nicht; überall sonst im System stehen davor 48. */
.zj-bildtext__text > * + .zj-buttons { margin-top: var(--zj-abstand-48); }
/* #20 dasselbe in der Standort-Sektion, dort über die Rasterlücke. */
.zj-standort__text > .zj-buttons { margin-top: var(--zj-abstand-24); }
/* #22 Abstände oben und unten zu groß. Nicht das Polster war der Grund,
   sondern die Mindesthöhe 754 aus Figma: der Inhalt ist kürzer, und
   align-content:center verteilt den Rest als Luft. Die Mindesthöhe folgt
   jetzt der Karte (628) plus Polster. */
.zj-standort { min-height: 0; padding-block: var(--zj-abstand-64); }
/* #24 Fußzeile: Text ein Drittel, Links zwei Drittel. War 497px zu 1fr. */
.zj-fusszeile__raster { grid-template-columns: minmax(0, 1fr) minmax(0, 2fr); }
/* #25 Die überstehenden Freisteller dürfen ihre Rasterspalte nicht
   verbreitern. fr-Spuren haben eine automatische Mindestbreite; ohne
   min-width:0 schob der Lkw die erste Spalte um rund 6 px auf und die
   Fragen-Karte stand nicht mehr unter der Tablet-Karte. */
.zj-branchen__reihe > * { min-width: 0; }
/* #12 Kopf der zentrierten Sektion: weniger Luft über dem Text, mehr
   darunter zum Raster. Nur am zentrierten Modifier, damit die von Figma
   gemessenen 40/44 überall sonst stehen bleiben. */
.zj-sektion__kopf--zentriert > .zj-h2 + .zj-lead,
.zj-sektion__kopf--zentriert > .zj-h2 + .zj-body { margin-top: var(--zj-abstand-24); }
.zj-sektion__kopf--zentriert + * { margin-top: var(--zj-abstand-64); }
/* #32 und #35 Ein Sektionsfuß und ein Bild brauchen nach unten Luft,
   wenn noch etwas folgt. */
.zj-sektion__fuss + * { margin-top: var(--zj-abstand-48); }
.zj-body + .zj-bild--breit { margin-top: var(--zj-abstand-32); }
/* #39 Die Personenkarte wächst mit langen Funktionszeilen. Der Text stand
   oben und ließ unten eine Lücke; jetzt sitzt er mittig. */
.zj-person__meta { align-self: center; }
/* #57 Zwei weiße Trust-Karten mit kurzem Text: die Mindesthöhe 219 aus dem
   Dreispalter erzeugt dort unten eine Lücke. Im Zweispalter folgt die Höhe
   dem Inhalt. */
.zj-trust__raster--2 .zj-karte { min-height: 0; }

/* 34i. Freisteller unterhalb des Umbruchpunkts (Nebenbefund 14.09.2026)
   Gemessen an der Startseite bei 700 px: die drei überstehenden Motive
   schoben die Seite um 227 px über den Rand hinaus (Roboter 1121 px breit
   in einer 652 px breiten Karte). Das ist Bestand aus v1 und wurde durch
   die neuen Zoomfaktoren nur deutlicher; bei 1,55 lief er schon über.
   Sobald die Reihen einspaltig stapeln, gibt es die Figma-Komposition
   ohnehin nicht mehr: dort greift wieder der Beschnitt, und der Zoom
   entfällt. Über 900 px bleibt alles wie gebaut. */
@media (max-width: 900px) {
  .zj-karte:has(.zj-hat-foto--ragt) { overflow: hidden; }
  .zj-hat-foto--ragt img { transform: none; max-width: 100%; }
}


/* --- 35. Wenig Bewegung, Nachtrag hinter Abschnitt 34 (15.09.2026) -------
   Forge-B1: der Schutzblock in 33i steht VOR Abschnitt 34. Die vier v2-Wege
   tragen dort zeichengleiche Selektoren, also gleiche Spezifitaet, und bei
   Gleichstand gewinnt die spaetere Deklaration. Der Schutz war damit tot.
   Eine Media Query erhoeht die Spezifitaet nicht, sie ist nur eine Bedingung.
   Dieser Block steht am Dateiende und gewinnt deshalb ohne !important.
   Wer einen neuen Weg baut, haengt seinen Schutz HIER an, nicht in 33i. */
@media (prefers-reduced-motion: reduce) {
  .zj-hero__kachel:is(:hover, :focus-within) .zj-hero__kachel-label .zj-icon--pfeil,
  .zj-kachel--shop:is(:hover, :focus-within) .zj-kachel__link .zj-icon--pfeil,
  .zj-kachel--shop .zj-kachel__link:is(:hover, :focus-visible) .zj-icon--pfeil,
  .zj-querverweis__raster a.zj-karte:is(:hover, :focus-visible) .zj-karte__pfeil {
    transform: none;
  }
}
