
/* ============================================================================
   stahl-kupfer — the SHARED DESIGN LANGUAGE.
   This block is generated into all four pages so their styles cannot drift.
   Tokens: gunmetal steel-blue primary + copper CTA + brushed-metal neutrals.
   Every colour pair below is machine-verified — see design.md "Colour".
   ========================================================================== */
:root{
  /* --- surfaces (cool, faintly blue-cast: "brushed metal", never pure grey) --- */
  --bg:#f7f9fb; --surface:#ffffff; --surface-alt:#eef2f6; --steel:#e2e8ee;
  --line:#d2dae2;          /* decorative hairline */
  --line-strong:#7f90a1;   /* 3.28:1 — use when a border is the ONLY signal */
  --dark:#101923; --dark-2:#18232f; --dark-line:#2b3947; --dark-muted:#a3b5c6;

  /* --- ink --- */
  --text:#182430;          /* 15.74:1 on surface */
  --muted:#4a5a6a;         /*  7.09:1 on surface — "muted" is chroma, never contrast */
  --head:#101c28;

  /* --- brand --- */
  --primary:#22415c;       /* gunmetal steel-blue · 10.61:1 on surface */
  --primary-hover:#182f43;
  --primary-subtle:#e6edf3;
  --on-primary:#ffffff;

  /* --- the ONE reserved accent: the phone CTA --- */
  --cta:#b8541c;           /* copper · white on it 4.86:1 · as text on bg 4.60:1 */
  --cta-hover:#9c4415;
  --cta-light:#e8a06a;     /* copper for text ON DARK (8.16:1) — never use --cta there */
  --cta-ink:#a04716;       /* copper for TEXT on any LIGHT band. --cta itself is 4.86:1 on
                              white but only 4.32 on --surface-alt, 4.11 on --primary-subtle
                              and 3.94 on --steel, so it is a FILL token, not a text token.
                              --cta-ink clears 4.5:1 on all five light grounds (worst 4.99). */
  --on-cta:#ffffff;

  --dark-3:#1e2c3a;        /* raised surface ON a dark band (icon badge, ledger key) */
  --dark-4:#22313f;        /* hover surface / ghost graphic on dark */
  --dark-line-2:#41576c;   /* hover border on dark */
  --on-dark:#d6e2ec;       /* body copy on any dark or primary fill (8.06:1 on --primary) */
  --tint-2:#dde7ef;        /* pressed/hover tint on light */
  --cta-tint:#fdf4ef;      /* ground of the info notice + accent hover tint */
  --focus:#0b1a26;         /* always paired with a white inner ring, see :focus-visible */
  --danger:#b3261e; --danger-tint:#fdf1f0;
  --success:#1c6b3f;

  /* --- personality --- */
  --r-xs:2px; --r-sm:4px; --r:8px; --r-lg:14px; --pill:999px;
  --notch:14px;                                   /* the key-bow corner cut */
  --sh-sm:0 1px 2px rgba(16,25,35,.06), 0 2px 6px rgba(16,25,35,.05);
  --sh:0 6px 18px rgba(16,25,35,.08);
  --sh-lg:0 18px 44px rgba(16,25,35,.13);
  --sh-dark:0 18px 44px rgba(0,0,0,.34);

  --c:1180px; --gut:24px;
  --ease:cubic-bezier(.22,.61,.36,1);
  --dur:.22s; --dur-slow:.58s;
  --tap:44px;
  --f:'Segoe UI',system-ui,-apple-system,'Helvetica Neue',Arial,sans-serif;
  --f-num:ui-monospace,'SF Mono','Cascadia Mono','Segoe UI Mono',Menlo,Consolas,monospace;
}

/* ---------------------------------------------------------------- base ---- */
*,*::before,*::after{box-sizing:border-box}
*{margin:0}
html{-webkit-text-size-adjust:100%;scroll-behavior:smooth}
body{
  font-family:var(--f);
  font-size:18px;              /* A10 floor — never drop to 16px */
  line-height:1.7;
  color:var(--text);
  background:var(--bg);
  overflow-x:hidden;
  -webkit-font-smoothing:antialiased;
  text-underline-offset:.18em;
}
img{max-width:100%;height:auto;display:block}
svg{display:block}
a{color:var(--primary);text-decoration-thickness:1px}
/* THE BUG THIS FIXES: a bare `a:hover` is (0,1,1) and beats `.btn{color:var(--btn-fg)}`
   (0,1,0), so on hover every button label turned copper — and on .btn--cta that is
   copper text on a darker-copper wipe, i.e. the label disappears. A link that IS a
   component owns its own colour; only prose links take the copper hover.
   (Same specificity trap as `.section--dark a` further down — attribute/state selectors
   quietly outrank plain class rules.) */
a:not(.btn):not(.callbtn):not(.calltab):not(.chip):not(.brand):not(.ftel):not(.telbig):hover{
  color:var(--cta-ink)}
/* hyphens:auto on a DISPLAY heading produces mid-word breaks that read as a defect
   ("Schließzylin-" / "der" at 48px). Headings get hyphens:manual with overflow-wrap
   as the safety net for a compound too long for its column; body copy — where German
   hyphenation genuinely helps the ragged edge — keeps hyphens:auto. */
h1,h2,h3,h4{color:var(--head);line-height:1.14;letter-spacing:-.018em;font-weight:800;
  overflow-wrap:break-word;hyphens:manual}
p{max-width:68ch;hyphens:auto}
ul,ol{margin:0;padding:0}
strong{color:var(--head);font-weight:700}
::selection{background:var(--cta);color:#fff}

/* one focus treatment that survives EVERY band: white inner ring + dark outer */
:where(a,button,summary,[tabindex]):focus-visible{
  outline:none;
  box-shadow:0 0 0 3px var(--surface),0 0 0 6px var(--focus);
  border-radius:var(--r-sm);
}
.section--dark :where(a,button,summary):focus-visible{
  box-shadow:0 0 0 3px var(--dark),0 0 0 6px var(--cta-light);
}

/* ------------------------------------------------------------ structure --- */
.wrap{max-width:var(--c);margin-inline:auto;padding-inline:var(--gut)}
.wrap--narrow{max-width:860px}
.wrap--wide{max-width:1320px}
.section{padding:clamp(58px,7.2vw,104px) 0;position:relative}
.section--tight{padding:clamp(40px,4.6vw,64px) 0}
.section--alt{background:var(--surface-alt)}
.section--surface{background:var(--surface)}
.section--dark{background:var(--dark);color:var(--dark-muted)}
.section--dark h1,.section--dark h2,.section--dark h3,.section--dark h4{color:#fff}
/* ROOT-CAUSE FIX: a bare `.section--dark a` is (0,1,1) and silently beat every
   button's own (0,1,0) colour, so .btn/.callbtn inside a dark band rendered their
   label in --cta-light — copper-on-copper at ~1.4:1 on the CTA fill. A link that is
   a BUTTON carries its own colour; only prose links take the dark-band link colour. */
.section--dark a:not(:where(.btn,.callbtn,.calltab,.chip,.brand,.ftel)){
  color:var(--cta-light)}
.section--dark .lead{color:var(--on-dark)}

/* the SIGNATURE band: brushed steel. A material texture (german-design.md §4.3),
   not a decorative gradient — fine vertical hairlines at 2.5% over a flat tint. */
.section--steel{
  background:
    repeating-linear-gradient(90deg,
      rgba(34,65,92,.022) 0 1px, rgba(255,255,255,0) 1px 6px),
    repeating-linear-gradient(90deg,
      rgba(255,255,255,.42) 0 1px, rgba(255,255,255,0) 1px 14px),
    var(--steel);
}
.section--dark.section--steel{
  background:
    repeating-linear-gradient(90deg,
      rgba(255,255,255,.035) 0 1px, rgba(255,255,255,0) 1px 4px),
    var(--dark);
}

/* --------------------------------------------------------- typography ----- */
.display{
  font-size:clamp(34px,5.6vw,62px);font-weight:800;line-height:1.05;
  letter-spacing:-.026em;color:var(--head);
}
.display .l2{display:block;color:var(--primary)}
.section--dark .display,.hero--dark .display{color:#fff}
.section--dark .display .l2,.hero--dark .display .l2{color:var(--cta-light)}
.display--long{font-size:clamp(30px,4.4vw,48px)}

.stitle{font-size:clamp(27px,3.3vw,42px);font-weight:800;letter-spacing:-.022em}
.h3{font-size:clamp(19px,1.5vw,22px);font-weight:700;letter-spacing:-.012em;line-height:1.28}
.lead{font-size:clamp(18px,1.35vw,20.5px);line-height:1.66;color:var(--muted)}
.small{font-size:16.5px;line-height:1.6}
.vh{position:absolute;width:1px;height:1px;overflow:hidden;clip:rect(0 0 0 0);white-space:nowrap}

/* section head — the eyebrow + title + optional lead, three rhythms */
.shead{margin-bottom:clamp(30px,3.4vw,50px);max-width:760px}
.shead--center{margin-inline:auto;text-align:center}
.shead--split{display:grid;gap:22px clamp(28px,4vw,64px);align-items:end;max-width:none;
  grid-template-columns:minmax(0,1fr)}
@media(min-width:900px){.shead--split{grid-template-columns:minmax(0,1.05fr) minmax(0,.95fr)}}
.shead .stitle+.lead{margin-top:15px}

/* eyebrow — variant A: copper key-bit mark + label */
.eyebrow{display:inline-flex;align-items:center;gap:10px;font-size:13px;font-weight:800;
  letter-spacing:.15em;text-transform:uppercase;color:var(--cta-ink);margin-bottom:15px}
.section--dark .eyebrow{color:var(--cta-light)}
/* the key-bitting mark — 4 teeth at 30x12. Measured: a 7-tooth profile at 26x9 renders
   as an illegible smear, so the tooth count is capped at what survives at this size. */
.eyebrow::before{content:"";width:30px;height:12px;flex:none;background:currentColor;
  clip-path:polygon(0 100%,0 42%,20% 42%,20% 8%,40% 8%,40% 58%,60% 58%,60% 22%,80% 22%,80% 70%,100% 70%,100% 100%)}
/* eyebrow — variant B: boxed, for use where a rule would be too quiet */
.eyebrow--box{border:1.5px solid var(--line-strong);color:var(--primary);
  padding:7px 14px;letter-spacing:.13em;font-size:12px}
.eyebrow--box::before{display:none}
.section--dark .eyebrow--box{border-color:var(--dark-line);color:var(--cta-light)}
/* eyebrow — variant C: the pin-tumbler rule. Pins HANG from a shear line rather than
   standing on a baseline — bottom-anchored bars read as signal-strength bars, which is
   the wrong object entirely. Top-anchored under a rule reads as a lock cross-section. */
.pinrule{display:flex;align-items:flex-start;gap:5px;height:24px;margin-bottom:16px;
  padding-top:4px;border-top:2px solid var(--cta);width:45px}
.pinrule i{width:4px;background:var(--cta);display:block;border-radius:0 0 2px 2px}
.pinrule i:nth-child(1){height:13px}.pinrule i:nth-child(2){height:7px}
.pinrule i:nth-child(3){height:17px}.pinrule i:nth-child(4){height:10px}
.pinrule i:nth-child(5){height:15px}
.section--dark .pinrule{border-top-color:var(--cta-light)}
.section--dark .pinrule i{background:var(--cta-light)}

/* ------------------------------------------------------------- buttons ---- */
.btn{
  --btn-bg:var(--primary); --btn-fg:var(--on-primary); --btn-bg-h:var(--primary-hover);
  position:relative;display:inline-flex;align-items:center;justify-content:center;gap:11px;
  min-height:var(--tap);padding:14px 26px;border:0;border-radius:var(--r-sm);
  background:var(--btn-bg);color:var(--btn-fg);
  font:700 17px/1.2 var(--f);letter-spacing:.005em;text-decoration:none;cursor:pointer;
  transition:background var(--dur) var(--ease),transform var(--dur) var(--ease),
             box-shadow var(--dur) var(--ease);
  overflow:hidden;isolation:isolate;
}
/* The wipe MUST be z-index:-1, not 0. CSS paint order puts a positioned descendant at
   z-index:0 ABOVE the element's own inline content — so a button whose label is a bare
   text node (most of them) had its text painted over by the wipe on hover. `.btn>*`
   cannot rescue it: a text node is not an element and can never be lifted.
   At -1, and with `isolation:isolate` on .btn keeping it inside this stacking context,
   the wipe paints above the button's background and below the label, wrapped or not. */
.btn>*{position:relative;z-index:1}
.btn::before{content:"";position:absolute;inset:0;z-index:-1;background:var(--btn-bg-h);
  transform:scaleX(0);transform-origin:left;transition:transform .3s var(--ease)}
.btn:hover::before{transform:scaleX(1)}
.btn:hover{box-shadow:var(--sh)}
.btn:active{transform:translateY(1px)}
.btn--cta{--btn-bg:var(--cta);--btn-fg:var(--on-cta);--btn-bg-h:var(--cta-hover)}
.btn--ghost{--btn-bg:transparent;--btn-fg:var(--primary);--btn-bg-h:var(--primary);
  box-shadow:inset 0 0 0 1.5px var(--line-strong)}
.btn--ghost:hover{color:#fff}
.section--dark .btn--ghost{--btn-fg:#fff;--btn-bg-h:#fff;box-shadow:inset 0 0 0 1.5px var(--dark-line)}
.section--dark .btn--ghost:hover{color:var(--dark)}
.btn--lg{padding:18px 32px;font-size:18.5px}
.btn--block{display:flex;width:100%}
.btn svg{width:20px;height:20px;flex:none}

/* the call button: label above the number, icon disc at the left.
   Lifted from the Dexon hero treatment, re-coloured to copper. */
.callbtn{
  display:inline-flex;align-items:center;gap:14px;min-height:var(--tap);
  padding:11px 26px 11px 11px;border-radius:var(--pill);
  background:var(--cta);color:#fff;text-decoration:none;
  transition:background var(--dur) var(--ease),transform var(--dur) var(--ease),box-shadow var(--dur) var(--ease);
}
.callbtn:hover{background:var(--cta-hover);color:#fff;transform:translateY(-2px);box-shadow:var(--sh-lg)}
.callbtn .disc{width:46px;height:46px;flex:none;border-radius:50%;background:rgba(255,255,255,.19);
  display:grid;place-items:center}
.callbtn .disc svg{width:21px;height:21px;stroke:#fff}
/* opacity:.86 white over copper blends to #f5e7df = 4.02:1 — under AA for 12px text.
   Full white is 4.86:1. Never dim text on the accent fill to "soften" it. */
.callbtn .cap{display:block;font-size:12px;font-weight:700;letter-spacing:.14em;
  text-transform:uppercase;line-height:1}
.callbtn .num{display:block;font-size:21px;font-weight:800;letter-spacing:-.01em;margin-top:3px;
  font-variant-numeric:tabular-nums}
/* Specificity note: `.section--dark a` is (0,1,1) and would otherwise win over a
   plain `.callbtn--dark` (0,1,0), painting this white-ground button in --cta-light
   at ~1.9:1. Doubling the class to (0,2,0) is what keeps it readable on a dark band. */
.callbtn.callbtn--dark{background:var(--surface);color:var(--primary)}
.callbtn.callbtn--dark:hover{background:var(--surface);color:var(--primary)}
.callbtn--dark .disc{background:var(--cta)}
.callbtn--dark .cap{color:var(--muted);opacity:1}

/* ------------------------------------------------------- icon badges ------ */
.ibadge{width:54px;height:54px;flex:none;border-radius:var(--r);display:grid;place-items:center;
  background:var(--primary-subtle);color:var(--primary);
  transition:background var(--dur) var(--ease),color var(--dur) var(--ease),transform var(--dur) var(--ease)}
.ibadge svg{width:26px;height:26px;stroke-width:1.7}
.ibadge--cta{background:var(--cta);color:#fff}
.ibadge--dark{background:var(--primary);color:#fff}
.ibadge--outline{background:transparent;box-shadow:inset 0 0 0 1.5px var(--line-strong)}
.ibadge--round{border-radius:50%}
.ibadge--lg{width:70px;height:70px}.ibadge--lg svg{width:32px;height:32px}
.ibadge--sm{width:40px;height:40px;border-radius:var(--r-sm)}.ibadge--sm svg{width:20px;height:20px}
.section--dark .ibadge{background:var(--dark-3);color:var(--cta-light)}

/* --------------------------------------------------------------- cards ---- */
.card{background:var(--surface);border:1px solid var(--line);border-radius:var(--r);
  padding:clamp(22px,2.2vw,30px);position:relative;
  transition:border-color var(--dur) var(--ease),box-shadow var(--dur) var(--ease),
             transform var(--dur) var(--ease)}
.card:hover{border-color:var(--line-strong);box-shadow:var(--sh);transform:translateY(-3px)}
.card h3,.card .h3{margin-bottom:9px}
.card p{color:var(--muted);font-size:17px}
.section--dark .card{background:var(--dark-2);border-color:var(--dark-line);color:var(--dark-muted)}
.section--dark .card:hover{border-color:var(--dark-line-2)}
.section--dark .card p{color:var(--dark-muted)}

/* the key-bow NOTCH — the style's structural signature: one cut top-right corner.
   NOTE: clip-path also clips border AND box-shadow, so a notched box can never carry
   either. Two forms exist, and both are honest about that:
     .card--notch  — a FILLED notched card (no edge). Only legible on a band that
                     contrasts its fill, so it ships on tint/steel/dark bands.
     .notch/.notch__in — a two-element notched card WITH a hairline edge: the outer
                     box is the line colour, the inner is inset 1px and re-clipped.
   Elevation on a clipped box must use filter:drop-shadow(), which is applied after
   clipping and therefore traces the notch; box-shadow would be cut away. */
.card--notch{
  clip-path:polygon(0 0,calc(100% - var(--notch)) 0,100% var(--notch),100% 100%,0 100%);
  border:0;background:var(--primary-subtle);box-shadow:none;
  transition:background var(--dur) var(--ease),transform var(--dur) var(--ease),filter var(--dur) var(--ease)}
.card--notch:hover{background:var(--tint-2);filter:drop-shadow(0 10px 20px rgba(16,25,35,.13))}
.section--dark .card--notch{background:var(--dark-2)}
.section--dark .card--notch:hover{background:var(--dark-4);filter:none}

.notch{--notch-line:var(--line);
  clip-path:polygon(0 0,calc(100% - var(--notch)) 0,100% var(--notch),100% 100%,0 100%);
  background:var(--notch-line);padding:1px;
  transition:background var(--dur) var(--ease),filter var(--dur) var(--ease)}
.notch:hover{--notch-line:var(--line-strong);filter:drop-shadow(0 10px 20px rgba(16,25,35,.12))}
.notch__in{
  clip-path:polygon(0 0,calc(100% - var(--notch)) 0,100% calc(var(--notch) - 1px),100% 100%,0 100%);
  background:var(--surface);padding:clamp(22px,2.2vw,30px);height:100%}
.section--dark .notch{--notch-line:var(--dark-line)}
.section--dark .notch:hover{--notch-line:var(--dark-line-2);filter:none}
.section--dark .notch__in{background:var(--dark-2)}

/* the COPPER INLAY — a 3px leading edge marking the emphasis card in a set */
.card--inlay{border-top:3px solid var(--cta)}
.card--lead{background:var(--primary);border-color:var(--primary);color:var(--on-dark)}
.card--lead h3,.card--lead .h3{color:#fff}
.card--lead p{color:var(--on-dark)}

/* -------------------------------------------------------------- grids ----- */
.grid{display:grid;gap:clamp(16px,1.7vw,24px)}
.g2{grid-template-columns:minmax(0,1fr)}
.g3{grid-template-columns:minmax(0,1fr)}
.g4{grid-template-columns:minmax(0,1fr)}
@media(min-width:640px){.g2{grid-template-columns:repeat(2,minmax(0,1fr))}.g3{grid-template-columns:repeat(2,minmax(0,1fr))}.g4{grid-template-columns:repeat(2,minmax(0,1fr))}}
@media(min-width:980px){.g3{grid-template-columns:repeat(3,minmax(0,1fr))}.g4{grid-template-columns:repeat(4,minmax(0,1fr))}}
.split{display:grid;gap:clamp(28px,4vw,60px);align-items:center;grid-template-columns:1fr}
@media(min-width:900px){
  .split{grid-template-columns:minmax(0,1fr) minmax(0,1fr)}
  .split--wide-l{grid-template-columns:minmax(0,1.22fr) minmax(0,.78fr)}
  .split--wide-r{grid-template-columns:minmax(0,.78fr) minmax(0,1.22fr)}
  .split--flip>*:first-child{order:2}
}

/* --------------------------------------------------------------- chips ---- */
.chips{display:flex;flex-wrap:wrap;gap:9px;padding:0;list-style:none}
.chip{display:inline-flex;align-items:center;gap:8px;padding:9px 15px;border-radius:var(--pill);
  background:var(--surface);border:1px solid var(--line);font-size:16px;font-weight:600;color:var(--text);
  transition:border-color var(--dur) var(--ease),background var(--dur) var(--ease)}
.chip:hover{border-color:var(--cta);background:var(--cta-tint)}
.chip--solid{background:var(--primary-subtle);border-color:transparent;color:var(--primary)}
.section--dark .chip{background:var(--dark-3);border-color:var(--dark-line);color:var(--on-dark)}

/* ------------------------------------------------------- image slots ------ */
.imgph{position:relative;display:block;width:100%;background:var(--steel);border-radius:var(--r);
  overflow:hidden;color:var(--muted)}
.imgph img{width:100%;height:100%;object-fit:cover}
.imgph--notch{clip-path:polygon(0 0,calc(100% - 22px) 0,100% 22px,100% 100%,0 100%);border-radius:0}
.ratio-16x9{aspect-ratio:16/9}.ratio-4x3{aspect-ratio:4/3}.ratio-1x1{aspect-ratio:1/1}
.ratio-3x4{aspect-ratio:3/4}.ratio-3x2{aspect-ratio:3/2}

/* ------------------------------------------------------------- motion ----- */
.reveal{opacity:0;transform:translateY(18px);
  transition:opacity var(--dur-slow) var(--ease),transform var(--dur-slow) var(--ease)}
.reveal.in{opacity:1;transform:none}
.reveal.d1{transition-delay:.08s}.reveal.d2{transition-delay:.16s}
.reveal.d3{transition-delay:.24s}.reveal.d4{transition-delay:.32s}
/* one-shot clip reveal for images — fires from the same observer */
.wipe{clip-path:inset(0 0 100% 0);transition:clip-path .8s var(--ease)}
.wipe.in{clip-path:inset(0 0 0 0)}

@media (prefers-reduced-motion:reduce){
  html{scroll-behavior:auto}
  *,*::before,*::after{animation:none!important;transition:none!important}
  .reveal{opacity:1;transform:none}
  .wipe{clip-path:none}
}

/* ======================================================================== */
/*  SHARED CHROME — identical on every page (navbar, call bar, to-top,      */
/*  footer). Built once here so the four pages cannot drift.                */
/* ======================================================================== */

/* --- topbar: the number is ALWAYS visible, never behind the hamburger --- */
.topbar{background:var(--dark);color:var(--dark-muted);font-size:15.5px}
.topbar .wrap{display:flex;align-items:center;justify-content:space-between;gap:16px;
  min-height:var(--tap);flex-wrap:wrap}
.topbar a{color:#fff;text-decoration:none;display:inline-flex;align-items:center;gap:9px;
  min-height:var(--tap);font-weight:600}
.topbar a:hover{color:var(--cta-light)}
.topbar svg{width:17px;height:17px;stroke:var(--cta-light);flex:none}
.topbar .tb-note{display:none}
@media(min-width:760px){.topbar .tb-note{display:inline-flex;align-items:center;gap:9px}}

/* --- header --- */
header{position:sticky;top:0;z-index:120;background:var(--surface);
  border-bottom:1px solid var(--line);transition:box-shadow var(--dur) var(--ease)}
header.stuck{box-shadow:0 6px 20px rgba(16,25,35,.09)}
.navrow{display:flex;align-items:center;gap:18px;min-height:74px}
.brand{display:inline-flex;align-items:center;gap:11px;text-decoration:none;margin-right:auto}
.brand .bmark{width:40px;height:40px;flex:none;border-radius:var(--r-sm);background:var(--primary);
  display:grid;place-items:center}
.brand .bmark svg{width:23px;height:23px;stroke:var(--cta-light)}
.brand b{font-size:20px;font-weight:800;color:var(--head);letter-spacing:-.02em;line-height:1.1}
@media(max-width:400px){
  /* the lockup alone was 229px, overflowing a 320px viewport once the burger
     and gutters were counted. */
  .brand b{font-size:16.5px}.brand span{font-size:11px}
  .brand .bmark{width:34px;height:34px}.brand .bmark svg{width:19px;height:19px}
  .navrow{gap:10px}
}
.brand span{display:block;font-size:12.5px;font-weight:600;letter-spacing:.1em;
  text-transform:uppercase;color:var(--muted)}
.nav{display:none;gap:4px;list-style:none}
.nav a{display:inline-flex;align-items:center;min-height:var(--tap);padding:0 11px;
  font-size:16.2px;font-weight:600;color:var(--text);text-decoration:none;border-radius:var(--r-sm);
  white-space:nowrap;
  transition:color var(--dur) var(--ease),background var(--dur) var(--ease)}
.nav a:hover,.nav a[aria-current="page"]{color:var(--primary);background:var(--primary-subtle)}
.navcall{display:none}
.navcall span{white-space:nowrap}
/* raised from 1040: with four items plus the brand and the call button, the bar
   only genuinely fits from ~1120px. Below that the burger is the honest answer. */
@media(min-width:1120px){.nav{display:flex}.navcall{display:inline-flex}
  .brand b{white-space:nowrap}}
/* flex:none is load-bearing — as a flex item in .navrow the burger shrank to 38px
   wide at tablet widths, i.e. under the 44px floor for the ONE control that opens
   the menu. Width alone does not protect a flex item. */
.burger{display:inline-grid;place-items:center;flex:none;
  width:var(--tap);height:var(--tap);min-width:var(--tap);
  border:1px solid var(--line);border-radius:var(--r-sm);background:var(--surface);cursor:pointer}
.burger svg{width:24px;height:24px;stroke:var(--head)}
@media(min-width:1120px){.burger{display:none}}
/* THE DRAWER IS DRIVEN BY THE `hidden` ATTRIBUTE, NOT BY A CLASS.
   The reference chrome toggled `.open`; this build toggles `hidden` instead, so that the
   links are genuinely out of the tab order while closed. Leaving `display:none` on the
   bare class meant the attribute came off, aria-expanded flipped, the links became
   focusable — and the panel still had zero height, because nothing ever put `display`
   back. One source of truth: the attribute. */
.mobmenu{display:block;border-top:1px solid var(--line);background:var(--surface)}
.mobmenu[hidden],.mobmenu[hidden].open{display:none}
.mobmenu ul{list-style:none;padding:10px 0 18px}
.mobmenu a{display:flex;align-items:center;min-height:52px;font-size:17.5px;font-weight:600;
  color:var(--text);text-decoration:none;border-bottom:1px solid var(--line)}
.mobmenu a:hover{color:var(--cta-ink)}

/* --- sticky mobile call bar (C2: class matches (call|tel|phone|anruf) + position:fixed) --- */
.callbar{position:fixed;left:0;right:0;bottom:0;z-index:150;display:none;
  background:var(--surface);border-top:1px solid var(--line);
  box-shadow:0 -6px 22px rgba(16,25,35,.15);padding:9px 14px calc(9px + env(safe-area-inset-bottom))}
.callbar a{display:flex;align-items:center;justify-content:center;gap:11px;min-height:52px;
  border-radius:var(--r-sm);background:var(--cta);color:#fff;text-decoration:none;
  font-size:18.5px;font-weight:800;letter-spacing:.01em}
.callbar a svg{width:22px;height:22px;stroke:#fff;flex:none}
@media(max-width:1119px){.callbar{display:block}body{padding-bottom:84px}}

/* --- scroll to top --- */
.totop{position:fixed;right:16px;bottom:96px;z-index:140;width:48px;height:48px;
  display:grid;place-items:center;border:1px solid var(--line);border-radius:50%;
  background:var(--surface);color:var(--primary);cursor:pointer;
  opacity:0;visibility:hidden;transform:translateY(9px);
  transition:opacity var(--dur) var(--ease),transform var(--dur) var(--ease),
             visibility var(--dur) var(--ease),box-shadow var(--dur) var(--ease)}
.totop.show{opacity:1;visibility:visible;transform:none}
.totop:hover{box-shadow:var(--sh);border-color:var(--line-strong)}
.totop svg{width:22px;height:22px;stroke:currentColor}
@media(min-width:1120px){.totop{bottom:24px}}

/* --- footer --- */
footer{background:var(--dark);color:var(--dark-muted);padding-top:clamp(48px,5.4vw,76px)}
footer h3{color:#fff;font-size:17px;letter-spacing:.09em;text-transform:uppercase;margin-bottom:17px}
.fgrid{display:grid;gap:34px clamp(24px,3vw,48px);grid-template-columns:1fr}
@media(min-width:700px){.fgrid{grid-template-columns:repeat(2,1fr)}}
@media(min-width:1020px){.fgrid{grid-template-columns:1.4fr 1fr 1fr 1.1fr}}
footer ul{list-style:none}
/* 44px floor on footer links too: A11 only WARNS on non-call controls, but this
   audience is older and often one-handed on a phone, so the floor is worth the height. */
footer li{margin-bottom:0}
footer a{color:var(--dark-muted);text-decoration:none;
  display:inline-flex;align-items:center;min-height:var(--tap)}
footer a:hover{color:var(--cta-light);text-decoration:underline}
footer .ftel{display:inline-flex;align-items:center;gap:11px;min-height:var(--tap);
  color:#fff;font-size:21px;font-weight:800;font-variant-numeric:tabular-nums}
footer .ftel svg{width:21px;height:21px;stroke:var(--cta-light);flex:none}
.fbase{margin-top:clamp(34px,4vw,52px);border-top:1px solid var(--dark-line);
  padding:22px 0 26px;display:flex;flex-wrap:wrap;gap:10px 22px;
  align-items:center;justify-content:space-between;font-size:15.5px}
.fbase ul{display:flex;flex-wrap:wrap;gap:2px 20px}
.fbase li{margin:0}
.fbase a{min-height:var(--tap)}

/* skip link — visible only on focus, above the sticky header.
   NOT left:-9999px: an element parked far off-canvas is a real box in the layout, it
   shows up in every geometry sweep as "something crosses the viewport edge", and it
   masks the element that actually does. The 1px clip technique occupies nothing. */
.skip{position:absolute;left:0;top:0;z-index:400;width:1px;height:1px;overflow:hidden;
  clip-path:inset(50%);white-space:nowrap;background:var(--cta);color:#fff;
  padding:13px 20px;font-weight:700;text-decoration:none;border-radius:0 0 var(--r-sm) 0}
.skip:focus{width:auto;height:auto;overflow:visible;clip-path:none;color:#fff}

/* footer lockup reuses .brand with dark-band colours */
.brand--foot b{color:#fff}
.brand--foot span span{color:var(--dark-muted)}
.brand--foot .bmark{background:var(--dark-2);border:1px solid var(--dark-line)}

/* ======================================================================== */
/*  Two late primitives, both from the hotlock/dexon reads.                 */
/* ======================================================================== */

/* THE KEYPAD GRID — the layout lines ARE the design. One `gap:1px` over a line-
   coloured ground, cells painted in the surface colour, so the rules are drawn by
   the gap rather than by per-cell borders (the source hand-tuned border-width per
   cell at every breakpoint; this needs no arithmetic and reflows for free).
   Reads unmistakably as security hardware — the closest thing this style has to a
   trade-specific structure. Also the mechanism behind the segmented assurance slab:
   three cells at gap:2px read as ONE slab, not three cards. */
.keypad{display:grid;gap:1px;background:var(--line);border:1px solid var(--line)}
.keypad>*{background:var(--surface);padding:clamp(20px,2.2vw,30px);margin:0}
.keypad--tight{gap:2px;background:var(--line-strong);border:0}
.keypad--cta{gap:2px;background:var(--cta-hover);border:0}
.keypad--cta>*{background:var(--cta);color:#fff}
.keypad--cta>* :where(h2,h3,h4,.h3,strong){color:#fff}
.section--dark .keypad{background:var(--dark-line);border-color:var(--dark-line)}
.section--dark .keypad>*{background:var(--dark-2)}
@media(min-width:640px){.keypad--2{grid-template-columns:repeat(2,1fr)}
  .keypad--3{grid-template-columns:repeat(2,1fr)}.keypad--4{grid-template-columns:repeat(2,1fr)}}
@media(min-width:980px){.keypad--3{grid-template-columns:repeat(3,1fr)}
  .keypad--4{grid-template-columns:repeat(4,1fr)}.keypad--6{grid-template-columns:repeat(6,1fr)}}

/* PHONE NUMBER AS DISPLAY TYPE — no button chrome at all. On a page where the call
   IS the only conversion channel, a huge tappable number outranks another square
   button, and it still clears the 44px target by a wide margin. */
.telbig{display:inline-flex;align-items:center;gap:14px;text-decoration:none;
  font-size:clamp(30px,4.4vw,54px);font-weight:800;line-height:1.06;
  letter-spacing:-.025em;font-variant-numeric:tabular-nums;color:var(--head);
  transition:color var(--dur) var(--ease)}
.telbig:hover{color:var(--cta-ink)}
.telbig svg{width:.72em;height:.72em;flex:none;stroke:var(--cta);stroke-width:1.8}
.section--dark .telbig{color:#fff}
.section--dark .telbig:hover{color:var(--cta-light)}
.section--dark .telbig svg{stroke:var(--cta-light)}

/* THE CALL TAB — a copper block that reads as die-cut out of the image above it:
   one rounded corner, zero top radius, and a negative pull so it bites into the
   photo's bottom edge. From the `blocks` kit, where it is a generic tab; the recon
   flagged it as "the best-shaped button in the corpus and it wants a phone number",
   so here it only ever carries the number. Unlike .btn it has NO hover wipe —
   design-tokens.md §5 forbids animating the CTA; the hover is colour only. */
.calltab{
  display:inline-flex;align-items:center;gap:13px;position:relative;z-index:2;
  margin-top:-34px;padding:20px 30px 20px 26px;
  border-radius:0 var(--r-lg) 0 0;
  background:var(--cta);color:#fff;text-decoration:none;
  font-size:clamp(19px,1.7vw,24px);font-weight:800;letter-spacing:-.01em;
  font-variant-numeric:tabular-nums;min-height:var(--tap);
  transition:background var(--dur) var(--ease)}
.calltab:hover{background:var(--cta-hover);color:#fff}
.calltab svg{width:1.05em;height:1.05em;flex:none;stroke:currentColor;stroke-width:1.9}
.calltab .cap{display:block;font-size:12px;font-weight:700;letter-spacing:.14em;
  text-transform:uppercase;line-height:1;margin-bottom:4px}

/* TAP-TARGET FLOOR for every click-to-call, whatever a page happens to call it.
   A11 measures the rendered box, so a number styled as pure display type still has
   to clear 44px. min-height only bites on a flex/block box, hence the display switch;
   verified that no tel: link on any page sits inline inside a <p>, so this is safe. */
/* :not(.navcall) is load-bearing: this rule is (0,1,1) and would otherwise beat
   `.navcall{display:none}` (0,1,0) below 1040px, resurrecting the desktop call
   button and pushing the burger off-screen on every phone <=390px. */
a[href^="tel:"]:not(.navcall){display:inline-flex;align-items:center;min-height:var(--tap)}
/* ============================================================================
   stahl-kupfer — SHARED LANGUAGE, PART 2.
   Section + layout primitives and the widget set, all drawn from the recon
   catalogue (`_recon-catalogue.md`). Neutral, composable bricks — never finished
   templates. Every value is a token; nothing here introduces a new theme value.
   ========================================================================== */

/* ------------------------------------------------------------------------- */
/*  A · THE SEAM HELPERS — the overlap grammar, made hard to get wrong.       */
/*  Rule 1 of the style is "every other band has exactly one element crossing  */
/*  its boundary". Two traps make it easy to botch by hand: the crossing       */
/*  element must be the FIRST or LAST child of its band (pulling up a mid-     */
/*  section element just collides with the heading above it), and it needs a   */
/*  z-index or the next band paints over it. These encode both.               */
/* ------------------------------------------------------------------------- */
.seam-up{position:relative;z-index:2;margin-top:calc(-1 * var(--seam,54px))}
.seam-down{position:relative;z-index:2;margin-bottom:calc(-1 * var(--seam,54px))}
.seam-sm{--seam:32px} .seam-lg{--seam:82px}
/* A .seam-down is only half the mechanism and on its own it does NOTHING: the pull is
   smaller than the band's own bottom padding, so the element never reaches the seam.
   It takes THREE classes, and all three are required:
     .section--hang   on the band the element hangs OUT of  (drops its bottom padding)
     .seam-down       on that band's LAST child
     .section--catch  on the following band                 (makes room for the overhang)
   The .seam-up counterpart needs only .seam-up on the next band's FIRST child, plus
   enough bottom padding on the band above for the element to sit in. */
.section--hang{padding-bottom:0}
.section--catch{padding-top:calc(clamp(58px,7.2vw,104px) + var(--seam,54px))}
@media(max-width:699px){
  /* below 700px the bands are too short for a crossing element to read as
     deliberate — it just looks like a mistake. Collapse them. */
  .seam-up,.seam-down{margin-top:0;margin-bottom:0}
  .section--catch{padding-top:clamp(58px,7.2vw,104px)}
}

/* ------------------------------------------------------------------------- */
/*  B · SECTION + LAYOUT PRIMITIVES                                           */
/* ------------------------------------------------------------------------- */

/* B1 · DIPTYCH — zero-gutter two-column band, each half carrying its OWN fill,
   meeting at the exact centreline with no divider. Off-centre text comes from
   asymmetric percentage padding, so it stays optically centred at every width
   with no media query for position. (hotlock: three visually different bands
   from one grid rule.) */
.diptych{display:grid;grid-template-columns:minmax(0,1fr)}
.diptych__half{padding:clamp(38px,5vw,72px) var(--gut)}
@media(min-width:900px){
  .diptych{grid-template-columns:minmax(0,1fr) minmax(0,1fr)}
  .diptych__half{padding:clamp(52px,6vw,92px) 8% clamp(52px,6vw,92px) 14%}
  .diptych__half+.diptych__half{padding:clamp(52px,6vw,92px) 14% clamp(52px,6vw,92px) 8%}
}
.diptych__half--dark{background:var(--dark);color:var(--dark-muted)}
.diptych__half--dark :where(h2,h3,h4){color:#fff}
.diptych__half--steel{background:var(--steel)}
.diptych__half--primary{background:var(--primary);color:var(--on-dark)}
.diptych__half--primary :where(h2,h3,h4){color:#fff}
/* steel ground so a slow or failed image reads as an empty slot, not a black void */
.diptych__half--media{padding:0;position:relative;min-height:320px;background:var(--steel)}
.diptych__half--media img,.diptych__half--media .imgph{
  position:absolute;inset:0;width:100%;height:100%;object-fit:cover;border-radius:0}

/* B2 · LEDGER — one hairline frame around rows whose narrow cell is a label tab
   and whose wide cell carries the content. A ruled register reads as a record;
   a card grid reads as marketing. Right for Öffnungszeiten, coverage, liability
   splits, credential lists. (dexon: 20% white label cell / 80% filled cell.) */
.ledger{border:1px solid var(--line);background:var(--surface)}
.ledger__row{display:grid;grid-template-columns:minmax(0,1fr);border-top:1px solid var(--line)}
.ledger__row:first-child{border-top:0}
.ledger__k{padding:16px clamp(16px,2vw,24px);font-weight:700;color:var(--head);
  background:var(--surface-alt);font-size:16.5px;display:flex;align-items:center}
.ledger__v{padding:16px clamp(16px,2vw,24px);color:var(--muted);font-size:16.8px;line-height:1.55}
@media(min-width:700px){
  .ledger__row{grid-template-columns:minmax(180px,.26fr) 1fr}
  .ledger__k{border-right:1px solid var(--line)}
}
.ledger--dark{border-color:var(--dark-line);background:var(--dark-2)}
.ledger--dark .ledger__row{border-top-color:var(--dark-line)}
.ledger--dark .ledger__k{background:var(--dark-3);color:#fff;border-right-color:var(--dark-line)}
.ledger--dark .ledger__v{color:var(--dark-muted)}

/* B3 · SIDE RAIL — a sticky column against a single-file stack. The spine of a
   long service page: the number stays reachable through explanatory copy.
   Single-viewport sticky only — never a multi-viewport scroll sequence. */
.rail{display:grid;gap:clamp(28px,4vw,54px);grid-template-columns:1fr;align-items:start}
@media(min-width:1000px){
  .rail{grid-template-columns:minmax(0,.4fr) minmax(0,1fr)}
  .rail__side{position:sticky;top:108px}
  .rail--right .rail__side{order:2}
}
.rail__main{display:grid;gap:clamp(30px,3.6vw,52px)}

/* B4 · OFFSET GRID — hand-placed masonry rhythm with zero JS and no library.
   Every nth item drops, so the grid reads composed rather than tabulated.
   (ekvator built this with presentational spacer divs; nth-child is cleaner.) */
.offgrid{display:grid;gap:clamp(16px,1.8vw,26px);grid-template-columns:minmax(0,1fr);align-items:start}
@media(min-width:640px){
  .offgrid{grid-template-columns:repeat(2,minmax(0,1fr))}
  .offgrid>*:nth-child(2n){margin-top:clamp(20px,3vw,44px)}
}
@media(min-width:980px){
  .offgrid--3{grid-template-columns:repeat(3,minmax(0,1fr))}
  .offgrid--3>*:nth-child(2n){margin-top:0}
  .offgrid--3>*:nth-child(3n-1){margin-top:clamp(24px,3.4vw,52px)}
}

/* B5 · PEEK RAIL — user-driven horizontal scroll with the next card bleeding off
   the edge as the affordance. scroll-snap, NOT an auto-carousel: nothing moves
   until the reader moves it, and every card is keyboard-reachable. */
.peek{display:flex;gap:clamp(14px,1.6vw,22px);overflow-x:auto;scroll-snap-type:x mandatory;
  padding-bottom:14px;scrollbar-width:thin}
.peek>*{flex:0 0 clamp(250px,74vw,330px);scroll-snap-align:start}
@media(min-width:760px){.peek>*{flex-basis:330px}}
.peek::-webkit-scrollbar{height:8px}
.peek::-webkit-scrollbar-thumb{background:var(--line-strong);border-radius:var(--pill)}
.peek::-webkit-scrollbar-track{background:var(--surface-alt)}

/* B6 · MOSAIC — one tall image beside two stacked halves. An asymmetric 1+2
   composition out of a plain two-column grid. */
.mosaic{display:grid;gap:14px;grid-template-columns:minmax(0,1fr)}
@media(min-width:700px){.mosaic{grid-template-columns:minmax(0,1.25fr) minmax(0,1fr)}}
.mosaic__col{display:grid;gap:14px;grid-template-rows:1fr 1fr}
.mosaic .imgph{height:100%}
.mosaic--flip>*:first-child{order:2}

/* B7 · COMPARE — a static two-up with a shared centre rule. This is the LEGAL
   form of a before/after: the source templates build that with <input
   type="range">, which the validator hard-fails. Nothing here is interactive. */
.compare{display:grid;grid-template-columns:minmax(0,1fr);border:1px solid var(--line);
  background:var(--surface)}
.compare__side{padding:clamp(22px,2.6vw,34px)}
.compare__side+.compare__side{border-top:1px solid var(--line)}
@media(min-width:760px){
  .compare{grid-template-columns:minmax(0,1fr) minmax(0,1fr)}
  .compare__side+.compare__side{border-top:0;border-left:1px solid var(--line)}
}
.compare__tag{display:inline-flex;align-items:center;gap:9px;margin-bottom:13px;
  font-size:12.5px;font-weight:800;letter-spacing:.13em;text-transform:uppercase}
.compare__side--a .compare__tag{color:var(--success)}
.compare__side--b .compare__tag{color:var(--danger)}

/* B8 · TIMELINE — vertical connected steps. Order matters, so a stepper, not a
   grid. The connector is a pseudo-element so no extra markup carries it. */
.timeline{list-style:none;display:grid;gap:clamp(20px,2.4vw,32px);counter-reset:tl}
.timeline>li{position:relative;padding-left:64px;counter-increment:tl}
.timeline>li::before{content:counter(tl,decimal-leading-zero);position:absolute;left:0;top:0;
  width:44px;height:44px;border-radius:50%;display:grid;place-items:center;
  background:var(--surface);color:var(--primary);box-shadow:inset 0 0 0 1.5px var(--line-strong);
  font:800 14px/1 var(--f-num);letter-spacing:.02em}
.timeline>li::after{content:"";position:absolute;left:21.5px;top:52px;bottom:calc(-1 * clamp(20px,2.4vw,32px));
  width:1px;background:var(--line)}
.timeline>li:last-child::after{display:none}
.section--dark .timeline>li::before{background:var(--dark-2);color:var(--cta-light);
  box-shadow:inset 0 0 0 1.5px var(--dark-line)}
.section--dark .timeline>li::after{background:var(--dark-line)}

/* B9 · STEPPER — the horizontal counterpart, for a sibling page that must not
   repeat the timeline's shape. */
.stepper{list-style:none;display:grid;gap:clamp(18px,2vw,26px);grid-template-columns:minmax(0,1fr);
  counter-reset:st}
@media(min-width:820px){.stepper{grid-template-columns:repeat(4,minmax(0,1fr))}}
.stepper>li{counter-increment:st;position:relative;padding-top:56px}
.stepper>li::before{content:counter(st,decimal-leading-zero);position:absolute;left:0;top:0;
  width:42px;height:42px;border-radius:var(--r-sm);display:grid;place-items:center;
  background:var(--primary);color:#fff;font:800 14px/1 var(--f-num)}
.stepper>li::after{content:"";position:absolute;left:52px;top:20px;right:0;height:1px;
  background:var(--line)}
.stepper>li:last-child::after{display:none}
@media(max-width:819px){.stepper>li::after{display:none}}

/* B10 · NOTICE — a real callout, never a paragraph. --danger is the safety
   register (gas, electrical, 110/112); --info carries the copper. */
.notice{border:1px solid var(--danger);border-left-width:5px;background:var(--danger-tint);
  padding:clamp(22px,2.6vw,34px);border-radius:var(--r-sm)}
.notice__head{display:flex;align-items:center;gap:13px;margin-bottom:12px}
.notice__ic{width:40px;height:40px;flex:none;border-radius:50%;display:grid;place-items:center;
  background:var(--danger);color:#fff}
.notice__ic svg{width:22px;height:22px;stroke:currentColor}
.notice h2,.notice h3,.notice .h3{color:var(--danger)}
.notice--info{border-color:var(--cta);background:var(--cta-tint)}
.notice--info .notice__ic{background:var(--cta)}
.notice--info :where(h2,h3,.h3){color:var(--cta-ink)}

/* B11 · STAT RAIL — static figures only. The sources animate these with
   odometers; counters are on the banlist and an invented figure breaks iron
   rule 4, so a figure appears here only if the partner can defend it. */
.stats{display:grid;gap:1px;background:var(--line);border:1px solid var(--line);
  grid-template-columns:repeat(2,minmax(0,1fr))}
@media(min-width:820px){.stats{grid-template-columns:repeat(4,minmax(0,1fr))}}
.stats>div{background:var(--surface);padding:clamp(20px,2.4vw,30px)}
.stats b{display:block;font-size:clamp(28px,3.4vw,40px);font-weight:800;color:var(--primary);
  letter-spacing:-.025em;font-variant-numeric:tabular-nums;line-height:1.05}
.stats span{display:block;margin-top:7px;font-size:16px;color:var(--muted);line-height:1.4}
.section--dark .stats{background:var(--dark-line);border-color:var(--dark-line)}
.section--dark .stats>div{background:var(--dark-2)}
.section--dark .stats b{color:var(--cta-light)}
.section--dark .stats span{color:var(--dark-muted)}

/* B12 · INDEX ROWS — the hover-flood service index. Three independent sources
   converged on this shape, and it is the answer to "never a bare <ul>": a list
   that is also a gallery. Four coordinated changes, all pure CSS. */
.rows{list-style:none;border-top:1px solid var(--line)}
.rows>li{position:relative;isolation:isolate;border-bottom:1px solid var(--line);
  transition:border-color var(--dur) var(--ease)}
.rows__flood{position:absolute;inset:auto 0 0 0;height:0;z-index:-1;background:var(--primary);
  transition:height .34s var(--ease)}
.rows>li:hover .rows__flood,.rows>li:focus-within .rows__flood{height:100%}
.rows__link{display:grid;gap:6px 20px;align-items:center;padding:clamp(20px,2.4vw,30px) 0;
  text-decoration:none;color:inherit;min-height:var(--tap)}
.rows__link::after{content:"";position:absolute;inset:0;z-index:1}
.rows>li:hover :where(.rows__t,.rows__d),.rows>li:focus-within :where(.rows__t,.rows__d){color:#fff}
.rows__t{font-size:clamp(19px,1.6vw,23px);font-weight:700;color:var(--head);
  transition:color var(--dur) var(--ease)}
.rows__d{font-size:16.8px;color:var(--muted);line-height:1.55;max-width:62ch;
  transition:color var(--dur) var(--ease)}
.rows__n{font:800 13px/1 var(--f-num);color:var(--muted);letter-spacing:.08em}
.rows__thumb{position:absolute;right:clamp(16px,2.4vw,36px);top:50%;translate:0 -50%;
  width:180px;aspect-ratio:16/11;overflow:hidden;border-radius:var(--r-sm);
  opacity:0;scale:.86;transition:opacity .3s var(--ease),scale .3s var(--ease);
  pointer-events:none;display:none}
@media(min-width:1040px){
  .rows__thumb{display:block}
  .rows__link{padding-right:230px}
  .rows>li:hover .rows__thumb,.rows>li:focus-within .rows__thumb{opacity:1;scale:1}
}

/* B13 · BAND STRIP — a full-bleed accent rule between sections, carrying the
   service vocabulary. The source MARQUEES this; continuous motion is banned, so
   it is static and reads as a hard divider. */
.strip{background:var(--cta);padding:22px 0}
.strip ul{list-style:none;display:flex;flex-wrap:wrap;justify-content:center;
  align-items:center;gap:12px clamp(16px,2vw,26px)}
.strip li{color:#fff;font-size:clamp(15px,1.5vw,19px);font-weight:800;letter-spacing:.06em;
  text-transform:uppercase;display:inline-flex;align-items:center;gap:12px clamp(16px,2vw,26px)}
.strip li:not(:last-child)::after{content:"";width:26px;height:11px;flex:none;background:#fff;
  opacity:.62;
  clip-path:polygon(0 100%,0 42%,20% 42%,20% 8%,40% 8%,40% 58%,60% 58%,60% 22%,80% 22%,80% 70%,100% 70%,100% 100%)}
.strip--dark{background:var(--dark)}
.strip--steel{background:var(--steel)}
.strip--steel li{color:var(--head)}
.strip--steel li:not(:last-child)::after{background:var(--cta);opacity:1}

/* ------------------------------------------------------------------------- */
/*  C · WIDGETS                                                              */
/* ------------------------------------------------------------------------- */

/* C1 · numeral pill — the step marker. Reads better than a bare digit or a
   filled circle, and it is the right shape for a numbered flow. */
.numpill{display:inline-flex;align-items:center;justify-content:center;min-width:44px;
  min-height:30px;padding:5px 14px;border-radius:var(--pill);border:1px solid var(--line);
  background:var(--surface-alt);color:var(--primary);font:800 13.5px/1 var(--f-num);
  letter-spacing:.04em}
.numpill--cta{background:var(--cta);border-color:var(--cta);color:#fff}
.section--dark .numpill{background:var(--dark-2);border-color:var(--dark-line);color:var(--cta-light)}

/* C2 · seal — a circular CREDENTIAL mark, sized to straddle a band seam.
   Deliberately NOT a rating badge: the sources put "4.5 (1,200 reviews)" in this
   slot, and a rating may only appear if it is real, attributable and evidenced. */
.seal{width:clamp(120px,12vw,148px);height:clamp(120px,12vw,148px);border-radius:50%;
  background:var(--cta);color:#fff;display:grid;place-content:center;justify-items:center;
  gap:3px;text-align:center;padding:12px;border:6px solid var(--surface)}
.seal svg{width:25px;height:25px;stroke:currentColor}
.seal b{font-size:12.5px;font-weight:800;line-height:1.15}
/* opacity:.92 white over copper blends to #f9f1ed = 4.35:1 — under AA for 11px text, and
   axe flags every seal on the page. Same trap the .callbtn .cap comment names: never dim
   text on the accent fill to "soften" it. Full white is 4.86:1. */
.seal i{font-style:normal;font-size:11px;font-weight:700;letter-spacing:.12em;
  text-transform:uppercase}
.seal--on-dark{border-color:var(--dark)}
.seal--primary{background:var(--primary)}

/* C3 · caption chip welded to an image corner — one widget, two content types
   (a Stadtteil on a job photo, a date on an article), which is where a gallery
   and a blog grid start reading as one family. */
.capchip{position:absolute;left:0;bottom:0;z-index:2;background:var(--surface);color:var(--head);
  padding:9px 15px;font-size:14px;font-weight:800;letter-spacing:.05em;text-transform:uppercase;
  border-radius:0 var(--r-sm) 0 0;max-width:calc(100% - 22px)}
.capchip--cta{background:var(--cta);color:#fff}
.capchip--tr{left:auto;right:0;bottom:auto;top:0;border-radius:0 0 0 var(--r-sm)}

/* C4 · avatar cluster ending in a quote mark — the only social-proof widget in
   the whole corpus that carries zero numbers and zero stars, which is why it is
   the one that ports into a German trade site untouched. */
.avatars{display:flex;align-items:center;flex-wrap:wrap}
.avatars img,.avatars .avatars__q{width:56px;height:56px;border-radius:50%;object-fit:cover;
  border:3px solid var(--surface);flex:none}
.avatars>*+*{margin-left:-15px}
.avatars__q{background:var(--cta);color:#fff;display:grid;place-items:center}
.avatars__q svg{width:22px;height:22px}
.section--dark .avatars img,.section--dark .avatars .avatars__q{border-color:var(--dark)}

/* C5 · quote card — a speech card with a tail. No stars, no counts, no rating. */
.quote{position:relative;background:var(--surface);border:1px solid var(--line);
  border-radius:var(--r);padding:clamp(22px,2.4vw,30px)}
.quote p{font-size:17.2px;line-height:1.62;color:var(--text)}
.quote__by{margin-top:16px;padding-top:14px;border-top:1px solid var(--line);
  font-size:14px;font-weight:800;letter-spacing:.08em;text-transform:uppercase;color:var(--cta-ink)}
.section--dark .quote{background:var(--dark-2);border-color:var(--dark-line)}
.section--dark .quote p{color:var(--on-dark)}
.section--dark .quote__by{color:var(--cta-light);border-top-color:var(--dark-line)}

/* C6 · flanked hairline — centred text with two rules growing to fill the row.
   Three declarations, and nothing like the usual border-top. */
.hrule{display:flex;align-items:center;gap:18px;font-size:14px;font-weight:800;
  letter-spacing:.14em;text-transform:uppercase;color:var(--muted)}
.hrule::before,.hrule::after{content:"";flex:1;height:1px;background:var(--line)}
/* the LABEL needs the dark-band colour too, not only the two rules — --muted on --dark
   is 2.49:1. Every widget below that paints text in --muted needs the same partner rule. */
.section--dark .hrule{color:var(--dark-muted)}
.section--dark .hrule::before,.section--dark .hrule::after{background:var(--dark-line)}

/* C7 · colophon chip — a bordered circle holding one letter, beside a name.
   Pure editorial garnish; the right home for a Meister/Innung mark in a hero. */
.colophon{display:inline-flex;align-items:center;gap:10px;font-size:12.5px;font-weight:700;
  letter-spacing:.05em;color:var(--muted)}
.colophon i{font-style:normal;width:22px;height:22px;flex:none;border-radius:50%;
  border:1.6px solid var(--line-strong);display:grid;place-items:center;
  font:800 11px/1 var(--f-num);color:var(--primary)}
.section--dark .colophon{color:var(--dark-muted)}
.section--dark .colophon i{border-color:var(--dark-line);color:var(--cta-light)}

/* C8 · double-framed card — an outer tinted frame at 10px padding with an inner
   hairline. Two rules, and every card stops looking flat. */
.framed{background:var(--surface-alt);border-radius:var(--r-lg);padding:10px}
.framed__in{background:var(--surface);border:1px solid var(--line);border-radius:var(--r);
  padding:clamp(20px,2.2vw,28px);height:100%}
.section--dark .framed{background:var(--dark-3)}
.section--dark .framed__in{background:var(--dark-2);border-color:var(--dark-line)}

/* C9 · expanding hover pill — an arrow square at rest that grows into a labelled
   button. max-width (not width) so there is no layout shift. */
.hpill{display:inline-flex;align-items:center;gap:0;min-height:var(--tap);
  border-radius:var(--pill);background:var(--primary);color:#fff;text-decoration:none;
  padding:6px;overflow:hidden}
.hpill__ic{width:32px;height:32px;flex:none;display:grid;place-items:center}
.hpill__ic svg{width:18px;height:18px;stroke:currentColor}
.hpill__t{max-width:0;opacity:0;white-space:nowrap;overflow:hidden;font-weight:700;font-size:16px;
  transition:max-width .34s var(--ease),opacity .28s var(--ease),padding .34s var(--ease);padding:0}
.hpill:hover,.hpill:focus-visible{color:#fff;background:var(--cta)}
.hpill:hover .hpill__t,.hpill:focus-visible .hpill__t{max-width:16rem;opacity:1;padding:0 12px 0 4px}

/* C10 · eyebrow variant D — a bordered chip with a solid accent disc flush in
   its left cap. Gives a section a coloured anchor without a coloured band. */
.eyebrow--cap{border:1.5px solid var(--line);border-radius:var(--pill);
  padding:4px 16px 4px 4px;color:var(--primary);letter-spacing:.11em;gap:11px}
.eyebrow--cap::before{width:28px;height:28px;border-radius:50%;background:var(--cta);
  clip-path:none}
.section--dark .eyebrow--cap{border-color:var(--dark-line);color:#fff}

/* C11 · crushed numeral — one deliberate break in the type system. A token-driven
   design with no exceptions reads machine-made; exactly one exception reads
   art-directed. Use it ONCE per page, never twice.
   THE NUMERAL IS DECORATION, AND THE MARKUP HAS TO SAY SO. At --line it carries
   1.41:1 (--dark-4 on --dark: 1.33:1) and could never clear AA as text — 3:1 is the
   floor even for display sizes. So the digits are passed in `data-n` and painted by the
   pseudo-element, the same move .timeline already makes for its step counters: a graphic
   in numeral form, not text a reader must decipher. Meaning belongs in the heading
   beside it. Written as <span class="bignum" data-n="01" aria-hidden="true"></span>. */
.bignum{font-size:clamp(56px,8vw,104px);font-weight:800;line-height:.72;letter-spacing:-.04em;
  color:var(--line);font-variant-numeric:tabular-nums;display:block}
.bignum::before{content:attr(data-n)}
.bignum--cta{color:var(--cta)}
.section--dark .bignum{color:var(--dark-4)}

/* C12 · hours rows — opening times as a real record, not a paragraph. */
.hours{list-style:none;display:grid;gap:0}
.hours li{display:flex;justify-content:space-between;gap:18px;padding:12px 0;
  border-bottom:1px solid var(--line);font-size:16.8px}
.hours li:last-child{border-bottom:0}
.hours b{color:var(--head);font-weight:700}
.hours span{color:var(--muted);text-align:right}
.section--dark .hours li{border-bottom-color:var(--dark-line)}
.section--dark .hours b{color:#fff}
.section--dark .hours span{color:var(--dark-muted)}

/* C13 · breadcrumbs */
.crumbs{list-style:none;display:flex;flex-wrap:wrap;align-items:center;gap:2px 4px;font-size:15.5px}
.crumbs li{display:inline-flex;align-items:center;gap:4px;color:var(--muted)}
.crumbs li+li::before{content:"";width:6px;height:6px;flex:none;border-right:1.5px solid var(--line-strong);
  border-top:1.5px solid var(--line-strong);rotate:45deg;margin-right:4px}
.crumbs a{display:inline-flex;align-items:center;min-height:var(--tap);min-width:var(--tap);
  color:var(--muted);text-decoration:none}
.crumbs a:hover{color:var(--cta-ink);text-decoration:underline}
.crumbs [aria-current="page"]{color:var(--head);font-weight:700}

/* C14 · in-page index — the sticky rail's table of contents. */
.toc{list-style:none;display:grid;gap:2px;border-left:2px solid var(--line)}
.toc a{display:flex;align-items:center;min-height:var(--tap);padding:6px 0 6px 16px;
  margin-left:-2px;border-left:2px solid transparent;color:var(--muted);text-decoration:none;
  font-size:16.5px;transition:color var(--dur) var(--ease),border-color var(--dur) var(--ease)}
.toc a:hover,.toc a[aria-current="true"]{color:var(--primary);border-left-color:var(--cta);
  font-weight:700}

/* C15 · tab switcher — buttons with the real roles. The sources build this from
   radio inputs; any <input> is a hard validator fail, and site.js already wires
   [data-switcher] with roving focus. */
.tabs{display:grid;gap:clamp(24px,3vw,44px);grid-template-columns:minmax(0,1fr);align-items:start}
@media(min-width:900px){.tabs{grid-template-columns:minmax(0,1fr) minmax(0,1fr)}}
.tabs__list{display:grid;gap:0;list-style:none}
/* The source dims the inactive tab with opacity:.45. That cannot be rescued: --muted at
   .45 over white is 2.07:1, and even at .9 it is still 4.63:1 on --steel — an opacity
   veil scales the CONTRAST down along with the colour, so no value both dims visibly and
   clears AA on every band this style ships. The inactive state is therefore carried by
   colour and border, the way the rest of the style carries state. */
.tabs__btn{display:block;width:100%;text-align:left;background:none;border:0;cursor:pointer;
  padding:18px 0;border-bottom:1px solid var(--line);color:inherit;font:inherit;
  min-height:var(--tap);transition:color var(--dur) var(--ease),border-color var(--dur) var(--ease)}
.tabs__btn:hover{border-bottom-color:var(--line-strong)}
.tabs__btn[aria-selected="true"]{border-bottom-color:var(--cta);border-bottom-width:2px}
.tabs__btn b{display:block;font-size:clamp(18px,1.5vw,21px);font-weight:700;color:var(--muted);
  margin-bottom:5px;transition:color var(--dur) var(--ease)}
.tabs__btn:hover b,.tabs__btn[aria-selected="true"] b{color:var(--head)}
.tabs__btn span{display:block;font-size:16.4px;color:var(--muted);line-height:1.55}
.section--dark .tabs__btn b,.section--dark .tabs__btn span{color:var(--dark-muted)}
.section--dark .tabs__btn:hover b,.section--dark .tabs__btn[aria-selected="true"] b{color:#fff}
.tabs__panel[hidden]{display:none}

/* C16 · FAQ accordion — native <details>, so it works with JS off; site.js only
   adds the one-open-at-a-time behaviour. */
.faq{display:grid;gap:12px}
.faq details{border:1px solid var(--line-strong);border-radius:var(--r-sm);
  background:var(--surface);overflow:hidden}
.faq summary{display:flex;align-items:center;gap:14px;justify-content:space-between;
  padding:18px clamp(16px,2vw,24px);min-height:var(--tap);cursor:pointer;list-style:none;
  font-size:clamp(17px,1.4vw,19.5px);font-weight:700;color:var(--head)}
.faq summary::-webkit-details-marker{display:none}
.faq summary::after{content:"";width:12px;height:12px;flex:none;
  border-right:2px solid var(--cta);border-bottom:2px solid var(--cta);rotate:45deg;
  translate:0 -3px;transition:rotate var(--dur) var(--ease)}
.faq details[open] summary::after{rotate:-135deg;translate:0 3px}
.faq details[open]{border-color:var(--cta)}
.faq__a{padding:0 clamp(16px,2vw,24px) 20px;color:var(--muted);font-size:17px;line-height:1.62}
.section--dark .faq details{background:var(--dark-2);border-color:var(--dark-line)}
.section--dark .faq summary{color:#fff}
.section--dark .faq summary::after{border-color:var(--cta-light)}

/* C17 · check / icon list — the default treatment for factors, symptoms and
   benefits. Never a <ul> with the bullets deleted. */
.iclist{list-style:none;display:grid;gap:clamp(14px,1.7vw,22px)}
.iclist--2{grid-template-columns:minmax(0,1fr)}
@media(min-width:700px){.iclist--2{grid-template-columns:repeat(2,minmax(0,1fr))}}
.iclist li{display:grid;grid-template-columns:auto 1fr;gap:14px;align-items:start}
.iclist__ic{width:34px;height:34px;flex:none;border-radius:50%;display:grid;place-items:center;
  background:var(--primary-subtle);color:var(--primary)}
.iclist__ic svg{width:18px;height:18px;stroke:currentColor;stroke-width:2.2}
.iclist--cta .iclist__ic{background:var(--cta);color:#fff}
.iclist b{display:block;color:var(--head);font-weight:700;font-size:17.5px;margin-bottom:3px}
.iclist p{font-size:16.6px;color:var(--muted);line-height:1.55}
.section--dark .iclist__ic{background:var(--dark-3);color:var(--cta-light)}
.section--dark .iclist b{color:#fff}
.section--dark .iclist p{color:var(--dark-muted)}

/* C18 · media frame — an image with the notch, a seam badge slot and a caption
   chip, so a photo is a composed object rather than a rectangle. */
.frame{position:relative}
.frame__seal{position:absolute;left:50%;bottom:0;translate:-50% 50%;z-index:3}
.frame__seal--r{left:auto;right:clamp(16px,4vw,54px);translate:0 50%}

/* ============================================================================
   bremen-schloss24.de — PART 3: what this site adds to the shared language.
   Nothing here introduces a new theme value: every colour, radius, shadow and
   duration is a var() from Part 1. Part 3 is (a) the WordPress-block reset,
   (b) four hardening fixes for traps that pass every automated check, and
   (c) the composable section bricks this site's forty pages are built from.
   ========================================================================== */

/* ------------------------------------------------------------------------- */
/*  0 · WORDPRESS BLOCK RESET                                                 */
/*  Every bespoke section is a core/html block, so WP wraps nothing — but the  */
/*  template-part and query wrappers still land in the DOM and must not carry  */
/*  layout of their own.                                                       */
/* ------------------------------------------------------------------------- */
.wp-block-template-part{display:contents}
.wp-site-blocks>*{margin-block:0}
main#main{display:block}
main#main:focus{outline:none}

/* ------------------------------------------------------------------------- */
/*  1 · FOUR HARDENING FIXES                                                  */
/* ------------------------------------------------------------------------- */

/* 1a · THE SEAM ACTUALLY HAS TO CROSS.
   A `.seam-up` first child is eaten by the receiving band's own top padding
   (54px pull against a clamp(58px,7.2vw,104px) padding), so at desktop it lands
   BELOW the seam and crosses nothing. Dropping that padding then exposes the
   second trap: the negative margin collapses THROUGH the parent, so the band's
   background boundary travels with the element and still nothing crosses.
   `display:flow-root` establishes a BFC and stops the collapse. Encoded with
   :has() so forgetting the explicit class cannot silently kill the overlap. */
.section:has(> .wrap > .seam-up:first-child),
.section:has(> .seam-up:first-child){padding-top:0;display:flow-root}
.section--hang,.section--catch{display:flow-root}

/* 1b · A DARK PANEL INSIDE A LIGHT BAND gets none of the `.section--dark`
   rules — it is dark by its OWN background. Every descendant colour therefore
   has to be re-declared, or body copy lands at 1.02:1 and axe only catches it
   where that text happens to exist. `.on-dark` is that re-declaration; put it
   on any dark box that is not inside a `.section--dark`. */
.on-dark{background:var(--dark);color:var(--on-dark)}
.on-dark :where(h1,h2,h3,h4,.h3,strong,b){color:#fff}
.on-dark p,.on-dark li,.on-dark .lead{color:var(--on-dark)}
.on-dark .eyebrow{color:var(--cta-light)}
.on-dark .pinrule{border-top-color:var(--cta-light)}
.on-dark .pinrule i{background:var(--cta-light)}
.on-dark .telbig{color:#fff}
.on-dark .telbig:hover{color:var(--cta-light)}
.on-dark .telbig svg{stroke:var(--cta-light)}
.on-dark .ibadge{background:var(--dark-3);color:var(--cta-light)}
.on-dark .chip{background:var(--dark-3);border-color:var(--dark-line);color:var(--on-dark)}
.on-dark .hours li{border-bottom-color:var(--dark-line)}
.on-dark .hours span{color:var(--dark-muted)}
.on-dark .numpill{background:var(--dark-2);border-color:var(--dark-line);color:var(--cta-light)}
.on-dark .hrule{color:var(--dark-muted)}
.on-dark .hrule::before,.on-dark .hrule::after{background:var(--dark-line)}
/* a link inside a coloured slab that says color:inherit inherits the BAND's
   colour, not the slab's — so prose links inside .on-dark are named explicitly,
   and component links keep their own colour exactly as on a .section--dark. */
.on-dark a:not(.btn):not(.callbtn):not(.calltab):not(.chip):not(.brand):not(.ftel):not(.telbig){
  color:var(--cta-light)}
.on-dark :where(a,button,summary):focus-visible{
  box-shadow:0 0 0 3px var(--dark),0 0 0 6px var(--cta-light)}

/* 1c · THE GUTTER SURVIVES A SECOND CLASS.
   `.hero{padding:X 0}` on the same element as `.wrap{padding:0 22px}` is equal
   specificity and, declared later, silently zeroes the horizontal gutter — H1s
   then sit on the viewport edge at 375px. Every class that may be combined with
   a container uses the logical longhands only. */
.wrap{padding-inline:var(--gut);padding-block:0}
@media(max-width:400px){:root{--gut:18px}}

/* 1d · NOTHING SCROLLS SIDEWAYS AT 320px.
   `1fr` and `auto` grid tracks take a min-content minimum, so one German
   compound (Zentralschließanlage, Legitimationsprüfung) can set the page's
   minimum width. `body{overflow-x:hidden}` from Part 1 would hide the evidence
   rather than fix it, so the tracks are fixed at the source. */
.grid>*,.split>*,.rail>*,.iclist li,.compare__side,.keypad>*,.ledger__v,.stats>div{min-width:0}
:where(h1,h2,h3,h4,.h3,.display,.stitle,.telbig,.rows__t){overflow-wrap:break-word}
.telbig{max-width:100%}

/* ------------------------------------------------------------------------- */
/*  2 · TREATMENT BRICKS                                                      */
/*  One brick per content SHAPE in the section plan. They are neutral: a page  */
/*  composes them, sizes them and orders them, and per-page CSS may change     */
/*  only layout — never a theme value.                                         */
/* ------------------------------------------------------------------------- */

/* 2a · HERO — five families. Every one carries the H1 and a click-to-call
   inside the first viewport; they differ in ground, geometry and what sits
   beside the copy. `layout-variety.md` Lever 1. */
.hero{position:relative;padding-block:clamp(44px,5.4vw,80px)}
.hero__grid{display:grid;gap:clamp(28px,3.6vw,54px);grid-template-columns:minmax(0,1fr);
  align-items:center}
@media(min-width:960px){
  .hero__grid{grid-template-columns:minmax(0,1.06fr) minmax(0,.94fr)}
  .hero__grid--wide{grid-template-columns:minmax(0,1.3fr) minmax(0,.7fr)}
  .hero__grid--even{grid-template-columns:minmax(0,1fr) minmax(0,1fr)}
  .hero__grid--flip>*:first-child{order:2}
}
.hero__copy>*+*{margin-top:clamp(14px,1.5vw,20px)}
.hero__actions{display:flex;flex-wrap:wrap;align-items:center;gap:14px 20px;
  margin-top:clamp(20px,2.4vw,30px)}
.hero__note{font-size:16.4px;color:var(--muted);max-width:46ch}
.section--dark .hero__note,.hero--dark .hero__note{color:var(--dark-muted)}
/* the colour-panel display hero — this site's signature opening: a solid
   primary panel carrying the H1, with the page's own object beside or under it */
.hero--panel{background:var(--primary);color:var(--on-dark)}
.hero--panel .display,.hero--panel h1{color:#fff}
.hero--panel .display .l2{color:var(--cta-light)}
.hero--panel .lead,.hero--panel .hero__note{color:var(--on-dark)}
.hero--panel .eyebrow{color:var(--cta-light)}
.hero--panel .chip{background:rgba(255,255,255,.1);border-color:rgba(255,255,255,.24);color:#fff}
.hero--dark{background:var(--dark);color:var(--dark-muted)}
.hero--dark .lead{color:var(--on-dark)}
.hero--dark .eyebrow{color:var(--cta-light)}
.hero--steel{background:
  repeating-linear-gradient(90deg,rgba(34,65,92,.022) 0 1px,rgba(255,255,255,0) 1px 6px),
  repeating-linear-gradient(90deg,rgba(255,255,255,.42) 0 1px,rgba(255,255,255,0) 1px 14px),
  var(--steel)}
/* the building-type card row that rides under the panel on the home page */
.hero__row{display:grid;gap:1px;background:var(--line);border:1px solid var(--line);
  grid-template-columns:minmax(0,1fr)}
@media(min-width:640px){.hero__row{grid-template-columns:repeat(2,minmax(0,1fr))}}
@media(min-width:1000px){.hero__row--3{grid-template-columns:repeat(3,minmax(0,1fr))}
  .hero__row--4{grid-template-columns:repeat(4,minmax(0,1fr))}}
.hero__row>*{background:var(--surface);padding:clamp(18px,2vw,26px);margin:0}
.hero__row b{display:block;color:var(--head);font-size:17.5px;font-weight:800;margin-bottom:5px}
.hero__row p{font-size:16.2px;color:var(--muted);line-height:1.5}

/* 2b · THE PHONE CARD — the free-consultation block. Always the dark object in
   a light band (the style's own rule: make the dark card the phone card, every
   time), so the eye lands on the only action the page has. */
.phonecard{background:var(--dark);color:var(--on-dark);border-radius:var(--r);
  padding:clamp(26px,3vw,42px);position:relative;overflow:hidden}
.phonecard--notch{border-radius:0;
  clip-path:polygon(0 0,calc(100% - 22px) 0,100% 22px,100% 100%,0 100%)}
.phonecard>*+*{margin-top:16px}
.phonecard__grid{display:grid;gap:clamp(22px,2.6vw,40px);grid-template-columns:minmax(0,1fr);
  align-items:center}
@media(min-width:860px){.phonecard__grid{grid-template-columns:minmax(0,1.15fr) minmax(0,.85fr)}}
.phonecard--light{background:var(--surface);color:var(--text);border:1px solid var(--line-strong)}
.phonecard--light :where(h2,h3,.h3){color:var(--head)}
.phonecard--light p{color:var(--muted)}
.phonecard--copper{background:var(--cta);color:#fff}
.phonecard--copper :where(h2,h3,.h3,strong,b){color:#fff}
.phonecard--copper p{color:#fff}
.phonecard--copper .telbig{color:#fff}
.phonecard--copper .telbig svg{stroke:#fff}
.phonecard--copper a:not(.btn):not(.callbtn):not(.telbig){color:#fff;text-decoration:underline}

/* 2c · CTA BAND — the closing call. One action, nothing competing. */
.ctaband{display:grid;gap:clamp(22px,2.6vw,38px);grid-template-columns:minmax(0,1fr);
  align-items:center}
@media(min-width:900px){.ctaband{grid-template-columns:minmax(0,1.25fr) minmax(0,.75fr)}
  .ctaband--even{grid-template-columns:minmax(0,1fr) minmax(0,1fr)}}
.ctaband__act{display:flex;flex-direction:column;align-items:flex-start;gap:12px}
@media(min-width:900px){.ctaband--right .ctaband__act{align-items:flex-end;text-align:right}}

/* 2d · TRUST STRIP — confirmable mechanisms only, never a badge wall. */
.trust{display:grid;gap:clamp(16px,1.8vw,26px);grid-template-columns:minmax(0,1fr)}
@media(min-width:700px){.trust{grid-template-columns:repeat(2,minmax(0,1fr))}}
@media(min-width:1000px){.trust--3{grid-template-columns:repeat(3,minmax(0,1fr))}
  .trust--4{grid-template-columns:repeat(4,minmax(0,1fr))}}
.trust li{display:grid;grid-template-columns:auto minmax(0,1fr);gap:14px;align-items:start;
  list-style:none}
.trust b{display:block;color:var(--head);font-size:17px;font-weight:800;margin-bottom:3px}
.trust span{display:block;font-size:16.4px;color:var(--muted);line-height:1.5}
.section--dark .trust b,.on-dark .trust b{color:#fff}
.section--dark .trust span,.on-dark .trust span{color:var(--dark-muted)}
/* the ruled variant — one register, not four floating cards */
.trust--ruled{gap:0;grid-template-columns:minmax(0,1fr);border-top:1px solid var(--line)}
.trust--ruled li{border-bottom:1px solid var(--line);padding:clamp(16px,1.8vw,22px) 0}
.section--dark .trust--ruled{border-top-color:var(--dark-line)}
.section--dark .trust--ruled li{border-bottom-color:var(--dark-line)}

/* 2e · USP PANEL — a stance, argued. Not a feature row. */
.usp{display:grid;gap:clamp(22px,2.6vw,38px);grid-template-columns:minmax(0,1fr)}
@media(min-width:900px){.usp{grid-template-columns:minmax(0,.82fr) minmax(0,1.18fr)}
  .usp--flip>*:first-child{order:2}}
.usp__list{display:grid;gap:clamp(18px,2vw,28px);list-style:none}
.usp__list li{padding-left:26px;position:relative}
.usp__list li::before{content:"";position:absolute;left:0;top:.62em;width:12px;height:2px;
  background:var(--cta)}
.section--dark .usp__list li::before,.on-dark .usp__list li::before{background:var(--cta-light)}
.usp__list b{display:block;color:var(--head);font-size:18px;font-weight:800;margin-bottom:5px}
.usp__list p{font-size:16.8px;color:var(--muted);line-height:1.58}
.section--dark .usp__list b,.on-dark .usp__list b{color:#fff}
.section--dark .usp__list p,.on-dark .usp__list p{color:var(--dark-muted)}

/* 2f · GLOSSARY LIST — anchorable term groups, ruled like a register. */
.glossar{display:grid;gap:0;border-top:1px solid var(--line-strong)}
.glossar>div{border-bottom:1px solid var(--line);padding:clamp(22px,2.4vw,32px) 0;
  display:grid;gap:8px clamp(24px,3vw,48px);grid-template-columns:minmax(0,1fr)}
@media(min-width:820px){.glossar>div{grid-template-columns:minmax(200px,.28fr) minmax(0,1fr)}}
.glossar dt,.glossar h3{color:var(--head);font-size:clamp(19px,1.6vw,22px);font-weight:800;
  letter-spacing:-.012em;scroll-margin-top:120px}
.glossar dd,.glossar p{margin:0;color:var(--muted);font-size:17px;line-height:1.62}
.glossar dd+dd,.glossar p+p{margin-top:10px}
/* the alphabet / index rail above it */
.termrail{display:flex;flex-wrap:wrap;gap:8px;list-style:none;padding:0}
.termrail a{display:inline-flex;align-items:center;min-height:var(--tap);padding:8px 15px;
  border:1px solid var(--line-strong);border-radius:var(--pill);font-size:16px;font-weight:700;
  color:var(--primary);text-decoration:none;
  transition:background var(--dur) var(--ease),color var(--dur) var(--ease)}
.termrail a:hover{background:var(--primary);color:#fff}
.section--dark .termrail a,.hero--panel .termrail a{border-color:rgba(255,255,255,.3);color:#fff}
.section--dark .termrail a:hover,.hero--panel .termrail a:hover{background:#fff;color:var(--primary)}

/* 2g · PROSE — the lead/argument block. One column, real measure, nothing else. */
.prose{max-width:70ch}
.prose>*+*{margin-top:clamp(14px,1.4vw,20px)}
.prose p{font-size:clamp(17.5px,1.25vw,19px);line-height:1.68;color:var(--text)}
.prose--muted p{color:var(--muted)}
.section--dark .prose p,.on-dark .prose p{color:var(--on-dark)}
.prose--wide{max-width:none}
.prose--two{max-width:none}
@media(min-width:900px){.prose--two{columns:2;column-gap:clamp(34px,4vw,64px)}
  .prose--two p{break-inside:avoid;max-width:none}
  .prose--two>*+*{margin-top:0}
  .prose--two p+p{margin-top:1em}}

/* 2h · FEATURE SPLIT — one idea, argued beside its object. */
.fsplit{display:grid;gap:clamp(28px,3.6vw,58px);grid-template-columns:minmax(0,1fr);
  align-items:center}
@media(min-width:900px){
  .fsplit{grid-template-columns:minmax(0,1fr) minmax(0,1fr)}
  .fsplit--wide-l{grid-template-columns:minmax(0,1.24fr) minmax(0,.76fr)}
  .fsplit--wide-r{grid-template-columns:minmax(0,.76fr) minmax(0,1.24fr)}
  .fsplit--flip>*:first-child{order:2}
  .fsplit--top{align-items:start}
}
.fsplit__body>*+*{margin-top:clamp(13px,1.3vw,18px)}

/* 2i · THE L-FRAME PAIR — two cards overlapping a photo from opposite corners,
   each showing only the two borders facing away, so together they read as one
   frame around the image. (dexon §1.) */
.lframe{position:relative}
@media(min-width:1000px){
  .lframe__a,.lframe__b{position:absolute;z-index:2;max-width:340px;background:var(--surface);
    padding:clamp(18px,1.9vw,26px)}
  .lframe__a{left:0;top:clamp(16px,3vw,42px);border-top:2px solid var(--cta);
    border-left:2px solid var(--cta)}
  .lframe__b{right:0;bottom:clamp(16px,3vw,42px);border-bottom:2px solid var(--primary);
    border-right:2px solid var(--primary)}
  .lframe__pad{padding:clamp(30px,4vw,58px) clamp(40px,7vw,110px)}
}
.lframe__a,.lframe__b{background:var(--surface);border-radius:var(--r-sm)}
@media(max-width:999px){
  .lframe__a,.lframe__b{border:1px solid var(--line);padding:clamp(18px,2.2vw,24px);margin-top:14px}
  .lframe__a{border-top:2px solid var(--cta)}
  .lframe__b{border-top:2px solid var(--primary)}
}
.lframe b{display:block;color:var(--head);font-size:17px;font-weight:800;margin-bottom:5px}
.lframe p{font-size:16.2px;color:var(--muted);line-height:1.52}

/* 2j · THE THREE-PANE CABINET — ONE bordered object internally ruled, never
   three floating cards. Reads as an established trade business. (voltsflow §2.) */
.cabinet{border:1px solid var(--line-strong);background:var(--surface);
  display:grid;grid-template-columns:minmax(0,1fr)}
.cabinet>*{padding:clamp(24px,2.8vw,38px)}
.cabinet>*+*{border-top:1px solid var(--line)}
@media(min-width:900px){
  .cabinet--3{grid-template-columns:repeat(3,minmax(0,1fr))}
  .cabinet--2{grid-template-columns:repeat(2,minmax(0,1fr))}
  .cabinet--3>*+*,.cabinet--2>*+*{border-top:0;border-left:1px solid var(--line)}
}
.section--dark .cabinet{border-color:var(--dark-line);background:var(--dark-2)}
.section--dark .cabinet>*+*{border-color:var(--dark-line)}

/* 2k · SPLIT-TONE HAIRLINE FRAME — a narrow label cell against a filled cell.
   Makes a two-term distinction structural rather than prose. (dexon §6.) */
.duo{border:1px solid var(--line-strong);display:grid;grid-template-columns:minmax(0,1fr);
  background:var(--surface)}
@media(min-width:760px){.duo{grid-template-columns:minmax(0,1fr) minmax(0,1fr)}}
.duo__side{padding:clamp(24px,2.8vw,38px)}
.duo__side+.duo__side{border-top:1px solid var(--line-strong);background:var(--surface-alt)}
@media(min-width:760px){.duo__side+.duo__side{border-top:0;border-left:1px solid var(--line-strong)}}
.duo__tag{display:inline-flex;align-items:center;gap:9px;margin-bottom:12px;font-size:12.5px;
  font-weight:800;letter-spacing:.13em;text-transform:uppercase;color:var(--cta-ink)}
.duo__side+.duo__side .duo__tag{color:var(--primary)}
.duo h3,.duo .h3{margin-bottom:9px}
.duo p{color:var(--muted);font-size:17px;line-height:1.6}
.duo p+p{margin-top:10px}

/* 2l · MEDIA — a real picture, sized, with an honest caption chip. */
.media{position:relative;display:block;background:var(--steel);overflow:hidden;
  border-radius:var(--r)}
/* height:100% of an AUTO-height parent computes to 0, so a .media with no ratio
   rendered a zero-height image — invisible, and nothing in any checker notices.
   The image sizes itself by default; only a box that fixes its own height (a ratio
   class, or --fill inside a grid cell) asks the image to cover. */
.media img{display:block;width:100%;height:auto;object-fit:cover}
.media[class*="ratio-"] img,.media--fill img{height:100%}
.media--fill{height:100%}
.media--notch{border-radius:0;
  clip-path:polygon(0 0,calc(100% - 22px) 0,100% 22px,100% 100%,0 100%)}
.media--square{border-radius:0}
.media__cap{position:absolute;left:0;bottom:0;z-index:2;background:var(--surface);
  color:var(--head);padding:9px 15px;font-size:14px;font-weight:800;letter-spacing:.04em;
  border-radius:0 var(--r-sm) 0 0;max-width:calc(100% - 22px)}

/* 2m · THE VERTICAL RAIL over a hero image (dexon §3) — qualifications, never
   a counter and never a rating. */
.vrail{background:var(--dark);color:var(--dark-muted);padding:clamp(20px,2.2vw,28px);
  border-bottom:3px solid var(--cta)}
.vrail ul{list-style:none;display:grid;gap:16px}
.vrail li{display:grid;gap:3px}
.vrail b{color:#fff;font-size:16px;font-weight:800}
.vrail span{color:var(--dark-muted);font-size:15.4px;line-height:1.45}

/* 2n · SECTION-LEVEL RHYTHM HELPERS */
.section--first{padding-top:clamp(34px,3.6vw,56px)}
.stack{display:grid;gap:clamp(24px,2.8vw,40px)}
.stack--sm{gap:clamp(14px,1.6vw,22px)}
.stack--lg{gap:clamp(34px,4vw,60px)}
.center{text-align:center}
.measure{max-width:62ch}
.measure--wide{max-width:78ch}
.mt-lg{margin-top:clamp(24px,3vw,44px)}
.bleed{margin-inline:calc(50% - 50vw);width:100vw;max-width:100vw}

/* 2o · JUMP LINKS / index strips used by several heroes */
.jumps{display:flex;flex-wrap:wrap;gap:10px;list-style:none;padding:0}
.jumps a{display:inline-flex;align-items:center;min-height:var(--tap);padding:9px 16px;
  border-radius:var(--r-sm);background:var(--surface);border:1px solid var(--line-strong);
  color:var(--primary);font-size:16.2px;font-weight:700;text-decoration:none;
  transition:background var(--dur) var(--ease),color var(--dur) var(--ease)}
.jumps a:hover{background:var(--primary);color:#fff;border-color:var(--primary)}
.hero--panel .jumps a,.section--dark .jumps a,.hero--dark .jumps a{
  background:rgba(255,255,255,.08);border-color:rgba(255,255,255,.28);color:#fff}
.hero--panel .jumps a:hover,.section--dark .jumps a:hover,.hero--dark .jumps a:hover{
  background:#fff;color:var(--primary);border-color:#fff}

/* 2p · CONTENT-INTERNAL LEAD-IN — the sentence that introduces a treatment. */
.leadin{max-width:66ch;color:var(--muted);font-size:clamp(17px,1.25vw,18.6px);line-height:1.62}
.section--dark .leadin,.on-dark .leadin{color:var(--dark-muted)}

/* ------------------------------------------------------------------------- */
/*  3 · NARROW-VIEWPORT HARDENING (320 / 360 / 375)                          */
/* ------------------------------------------------------------------------- */
@media(max-width:420px){
  /* the sticky call bar must never force a layout viewport wider than the
     device: a nowrap label plus the number plus the icon overflows at 360px. */
  .callbar a{font-size:17px;gap:9px;flex-wrap:wrap;line-height:1.2;padding-inline:10px}
  .callbar a .cap{flex-basis:100%;text-align:center;font-size:11px}
  .telbig{font-size:clamp(26px,7.6vw,34px);gap:10px}
  .callbtn{padding:10px 18px 10px 10px;gap:11px}
  .callbtn .disc{width:40px;height:40px}
  .callbtn .num{font-size:19px}
  .btn{padding:13px 20px;font-size:16.4px}
  .hero__actions{gap:12px}
}
@media(max-width:360px){
  .callbtn .num{font-size:17.5px}
  .display{font-size:clamp(28px,8.4vw,34px)}
}

/* ------------------------------------------------------------------------- */
/*  4 · NOSCRIPT GUARD                                                        */
/*  `.reveal{opacity:0}` with a JS-only `.in` blanks most of a page when       */
/*  scripting is off. The chrome ships the counter-rule inline; this is the    */
/*  same rule for the print stylesheet.                                        */
/* ------------------------------------------------------------------------- */
@media print{
  .reveal{opacity:1;transform:none}
  .callbar,.totop,.burger,.mobmenu,header{position:static}
  .section--dark,.on-dark,.hero--panel{background:#fff !important;color:#000 !important}
}

/* ============================================================================
   PART 4 — the chrome this site adds on top of Part 1's shared chrome:
   the Leistungen submenu, the grouped mobile menu, the breadcrumb band and the
   four-column footer. Layout and state only; every value is a Part 1 token.
   ========================================================================== */

/* --- the header sits in a display:contents template-part wrapper, so it is
   still the sticky element itself and still the direct child of the page. --- */
.navwrap{display:contents}
@media(min-width:1120px){.navwrap{display:block;margin-right:auto}}

/* --- the Leistungen submenu --------------------------------------------- */
.nav__has{position:relative;display:flex;align-items:center}
.nav__toggle{display:inline-grid;place-items:center;width:32px;height:var(--tap);
  border:0;background:none;color:var(--muted);cursor:pointer;margin-left:-6px;border-radius:var(--r-sm)}
.nav__toggle svg{width:16px;height:16px;transition:rotate var(--dur) var(--ease)}
.nav__toggle[aria-expanded="true"] svg{rotate:180deg}
.nav__toggle:hover{color:var(--primary)}
.submenu{position:absolute;top:100%;left:0;z-index:130;min-width:268px;margin:0;padding:8px;
  list-style:none;background:var(--surface);border:1px solid var(--line-strong);
  border-radius:var(--r-sm);box-shadow:var(--sh-lg);
  /* visibility, not display: a transitioned display never animates, and an
     aria-hidden subtree whose links stay focusable is an axe SERIOUS finding. */
  visibility:hidden;opacity:0;translate:0 6px;
  transition:opacity var(--dur) var(--ease),translate var(--dur) var(--ease),visibility 0s linear var(--dur)}
/* Driven by aria-expanded ALONE. A `:focus-within` on the whole item kept the panel
   open after Escape, because Escape puts focus back on the toggle — which is inside the
   item — so the keyboard could open the submenu but never close it. theme.js sets
   aria-expanded on focusin/focusout instead, which is the same behaviour and reversible. */
.nav__has:has(.nav__toggle[aria-expanded="true"]) .submenu{
  visibility:visible;opacity:1;translate:0;transition-delay:0s}
.submenu a{display:flex;align-items:center;min-height:var(--tap);padding:0 12px;
  font-size:16.4px;font-weight:600;color:var(--text);text-decoration:none;border-radius:var(--r-sm)}
.submenu a:hover{background:var(--primary-subtle);color:var(--primary)}
@media(max-width:1119px){.submenu,.nav__toggle{display:none}}

/* --- mobile menu: grouped, and the number never hides inside it ---------- */
.mobmenu[hidden]{display:none}
/* The drawer ends at the viewport bottom, where the sticky call bar sits — so its last
   item was underneath the bar and unreachable. The padding lets the content scroll clear
   of it; the bar itself must never move, it is the one thing that always has to be there. */
.mobmenu{max-height:calc(100dvh - 112px);overflow-y:auto;overscroll-behavior:contain;
  padding-bottom:88px}
@media(min-width:1120px){.mobmenu{padding-bottom:0}}

/* the burger swaps its glyph, so the same button visibly means "close" while open */
.burger__close{display:none}
.burger[aria-expanded="true"] .burger__open{display:none}
.burger[aria-expanded="true"] .burger__close{display:block}
.burger[aria-expanded="true"]{background:var(--primary);border-color:var(--primary)}
.burger[aria-expanded="true"] svg{stroke:#fff}
.mobmenu__lab{margin:20px 0 4px;font-size:12.5px;font-weight:800;letter-spacing:.14em;
  text-transform:uppercase;color:var(--cta-ink)}
.mobmenu__call{padding:20px 0 8px}
@media(min-width:1120px){.mobmenu{display:none !important}}

/* --- breadcrumb band ------------------------------------------------------ */
.crumbnav{background:var(--surface);border-bottom:1px solid var(--line);padding:6px 0}
.crumbnav .crumbs{padding:0;margin:0}
.crumbnav span[aria-current]{display:inline-flex;align-items:center;min-height:var(--tap);
  color:var(--head);font-weight:700}

/* --- footer additions ----------------------------------------------------- */
.fnote{color:var(--dark-muted);font-size:16.4px;line-height:1.6;margin-top:16px;max-width:44ch}
.fnote--sm{font-size:15.2px;margin-top:12px}
footer .ftel{margin-top:18px}
footer h3.mt{margin-top:30px}
.fgroup{margin:14px 0 4px;font-size:12.5px;font-weight:800;letter-spacing:.12em;
  text-transform:uppercase;color:var(--cta-light)}
.fchips{display:flex;flex-wrap:wrap;gap:2px 6px}
.fchips li{margin:0}
.fchips a{min-height:38px;padding:2px 0}
.fchips li:not(:last-child) a::after{content:" ·";color:var(--dark-line);margin-left:6px}
.fbase p{margin:0;color:var(--dark-muted)}

/* --- the sticky call bar's two-line label -------------------------------- */
.callbar a .cap{font-size:12px;font-weight:800;letter-spacing:.1em;text-transform:uppercase;
  opacity:1;display:none}
@media(min-width:520px){.callbar a .cap{display:inline}}

/* ============================================================================
   PART 5 — bricks introduced while composing the pages. Layout and state only;
   every value is a Part 1 token.
   ========================================================================== */

/* --- hero internals -------------------------------------------------------- */
/* `.hero` is declared after `.section--hang`, so its own padding shorthand would
   silently resurrect the bottom padding the hang class just removed. Doubling
   the class is what keeps the overhang alive. */
.hero.section--hang{padding-bottom:0}
.hero__kurz{border-left:3px solid var(--cta);padding-left:16px;font-size:17.4px;line-height:1.6;
  max-width:52ch}
.hero--panel .hero__kurz{border-left-color:var(--cta-light);color:#fff}
.hero--panel .hero__kurz b,.hero__kurz b{font-weight:800}
.hero--panel .hero__kurz b{color:#fff}
.hero__media{position:relative}
@media(min-width:960px){
  .hero__media .vrail{position:absolute;left:-28px;top:clamp(24px,4vw,56px);width:250px;z-index:2}
}
@media(max-width:959px){.hero__media .vrail{margin-top:-24px;position:relative;z-index:2;
  margin-inline:14px}}
.hero--panel .hero__row>*{background:var(--surface)}
.hero__row{box-shadow:var(--sh-lg)}

/* --- the trust slab's cells ------------------------------------------------ */
.keypad--tight>li{list-style:none;display:grid;gap:9px;align-content:start}
.keypad--tight b{display:block;color:var(--head);font-size:17px;font-weight:800}
.keypad--tight>li>span:last-child{font-size:16.2px;color:var(--muted);line-height:1.5}

/* --- the service index rows ----------------------------------------------- */
.rows__link{grid-template-columns:auto minmax(0,1fr)}
.rows__n{grid-row:1 / span 3;align-self:start;padding-top:5px}
.rows__chips{display:flex;flex-wrap:wrap;gap:7px;margin-top:4px}
.rows__chip{display:inline-flex;align-items:center;padding:3px 11px;border-radius:var(--pill);
  border:1px solid var(--line-strong);font-size:13.6px;font-weight:700;color:var(--muted);
  letter-spacing:.02em;transition:color var(--dur) var(--ease),border-color var(--dur) var(--ease)}
.rows>li:hover .rows__chip,.rows>li:focus-within .rows__chip{color:#fff;border-color:rgba(255,255,255,.45)}
.rows__thumb img{width:100%;height:100%;object-fit:cover}

/* --- the phone card's action column --------------------------------------- */
.phonecard__act{display:grid;gap:10px;justify-items:start}
.phonecard__cap{font-size:12.5px;font-weight:800;letter-spacing:.14em;text-transform:uppercase;
  color:var(--cta-light);margin:0}
.phonecard--light .phonecard__cap{color:var(--cta-ink)}
.phonecard--copper .phonecard__cap{color:#fff}
@media(min-width:860px){.ctaband--right .phonecard__act{justify-items:end}}

/* --- grouped chip clusters ------------------------------------------------- */
.chipgroups{display:grid;gap:clamp(22px,2.6vw,36px);grid-template-columns:minmax(0,1fr)}
@media(min-width:820px){.chipgroups{grid-template-columns:repeat(2,minmax(0,1fr))}
  .chipgroups--3{grid-template-columns:repeat(3,minmax(0,1fr))}}
.chipgroups .hrule{margin-bottom:14px}
.chip svg{width:17px;height:17px;flex:none;stroke:var(--cta-ink)}
.section--dark .chip svg,.on-dark .chip svg{stroke:var(--cta-light)}

/* --- timeline / stepper bodies -------------------------------------------- */
.timeline b.h3,.stepper b.h3{display:block;color:var(--head);margin-bottom:6px}
.section--dark .timeline b.h3,.on-dark .timeline b.h3,
.section--dark .stepper b.h3{color:#fff}
.timeline p,.stepper p{color:var(--muted);font-size:17px;line-height:1.58;max-width:66ch}
.section--dark .timeline p,.on-dark .timeline p,.section--dark .stepper p{color:var(--dark-muted)}

/* --- faq summary wraps instead of pushing the chevron off ------------------ */
.faq summary>span{flex:1 1 auto;min-width:0}
.faq summary::after{flex:none}


/* --- PART 6 · nav fits its own container -----------------------------------
   Six items plus the brand lockup plus the call capsule only genuinely fit from
   ~1180px, and a flex item with white-space:nowrap does not shrink to make room —
   it pushes the row past the container instead, which body{overflow-x:hidden}
   then hides. Measured at 1440: the call button ended 103px outside the viewport. */
.navrow{max-width:100%}
.nav a{padding:0 9px;font-size:16px}
.navcall{flex:none}
.brand{min-width:0}
@media(min-width:1120px) and (max-width:1259px){
  .brand b{font-size:17.5px}
  .brand span{font-size:11px}
  .nav a{padding:0 7px;font-size:15.4px}
  .callbtn.navcall{padding:9px 18px 9px 9px;gap:10px}
  .callbtn.navcall .disc{width:38px;height:38px}
  .callbtn.navcall .num{font-size:18px}
}


/* --- PART 7 · fixes found by rendering ------------------------------------- */

/* A ghost button on the colour panel inherited --btn-fg:var(--primary) — dark blue
   on a dark blue band, i.e. an empty box where a label should be. `.section--dark`
   already has this rule; a panel hero and a dark card are dark by their OWN
   background and get none of it, which is the same trap `.on-dark` exists for. */
.hero--panel .btn--ghost,.on-dark .btn--ghost,.hero--dark .btn--ghost{
  --btn-fg:#fff;--btn-bg-h:#fff;box-shadow:inset 0 0 0 1.5px rgba(255,255,255,.36)}
.hero--panel .btn--ghost:hover,.on-dark .btn--ghost:hover,.hero--dark .btn--ghost:hover{
  color:var(--primary)}

/* the hero rail: narrower, further out, and the photo keeps a real aspect ratio */
@media(min-width:960px){
  .hero__media .vrail{left:-54px;width:236px;top:clamp(32px,5vw,72px)}
}

/* the L-frame is a FULL-WIDTH object. Two 340px cards at opposite corners of a
   430px column overlap each other into an unreadable stack — measured. */
.lframe--wide{margin-top:clamp(26px,3vw,40px)}
@media(min-width:1000px){
  .lframe--wide .lframe__a{max-width:380px}
  .lframe--wide .lframe__b{max-width:380px}
}
.media-note{margin-top:12px;font-size:15.6px;color:var(--muted);max-width:56ch}

/* A <ul> used as a layout brick still draws its markers: Part 1 zeroes margin and
   padding on ul/ol but never touches list-style, so the disc reappeared as a stray
   dot beside every hero-row cell. Named per brick rather than globally, so a real
   prose list inside legal text keeps its markers. */
.hero__row,.keypad,.trust,.usp__list,.chips,.jumps,.termrail,.fchips,.vrail ul,
.rows,.timeline,.stepper,.iclist,.hours,.crumbs,.strip ul,.nav,.submenu,.mobmenu ul,
footer ul,.toc,.tabs__list{list-style:none}
.vrail ul{padding:0;margin:0}

/* the rail must not crowd the lead's right edge at the breakpoint where the grid is
   tightest — 54px of overhang measured within 6px of the text column */
@media(min-width:960px){.hero__media .vrail{left:-32px}}
@media(min-width:1200px){.hero__media .vrail{left:-54px}}

/* a two-line cap on the call capsule collided with the number: line-height:1 leaves
   no room between the wrapped lines and the 3px margin above the digits. */
.callbtn .cap{line-height:1.25}
.callbtn .num{margin-top:5px}
/* below the desktop breakpoint the rail sits UNDER the photo rather than over it —
   at 390px an overlay covers half the image and reads as a rendering fault. */
@media(max-width:959px){
  .hero__media .vrail{margin-top:0;margin-inline:0}
}

/* --- the three legal slots: long, plain, lawyer-supplied prose ------------- */
.legaltext h2{font-size:clamp(21px,1.9vw,26px);margin-top:clamp(28px,3vw,44px);margin-bottom:10px}
.legaltext h3{font-size:clamp(18px,1.5vw,20px);margin-top:26px;margin-bottom:8px}
.legaltext p+p{margin-top:14px}
.legaltext ul,.legaltext ol{margin:14px 0 14px 22px;list-style:disc}
.legaltext ol{list-style:decimal}
.legaltext li{margin-bottom:7px}
.legaltext address{font-style:normal}
.legaltext table{width:100%;border-collapse:collapse;margin:18px 0;font-size:16.6px}
.legaltext th,.legaltext td{border:1px solid var(--line);padding:10px 12px;text-align:left;
  vertical-align:top}
.legaltext th{background:var(--surface-alt);font-weight:700;color:var(--head)}

/* A11 measures the rendered box: a chip at 9px padding and 16px type is 40px tall, four
   short of the floor. This audience is older and often one-handed on a phone, so the
   floor applies to a coverage chip exactly as it applies to a call button. */
.chip,.termrail a,.jumps a{min-height:44px}
.fchips a{min-height:44px;padding-block:2px}
.fchips{gap:0 4px}

/* --- PART 8 · every dark ground needs its own link colour ------------------
   `a{color:var(--primary)}` from Part 1 is the base rule, and `.section--dark a`
   and `.on-dark a` override it — but a PANEL hero is `--primary` by its own
   background and matched neither, so a prose link inside it rendered
   #22415C on #22415C: 1:1, literally invisible, and axe only sees it where such
   a link happens to exist. Measured on stadtteil--mitte. Every coloured ground
   the style owns is named here, once. */
.hero--panel,.hero--dark,.diptych__half--primary,.diptych__half--dark,
.phonecard:not(.phonecard--light),.vrail,.strip,.keypad--cta,.card--lead{
  --link-on-ground:var(--cta-light);
}
/* the (0,8,1) version of this block moved to Part 10 as :not(:where(...)) so a
   component rule such as .hero--panel .jumps a can win the cascade again. */
/* …and the hover, which a bare a:hover would otherwise repaint to --cta-ink
   (4.9:1 on light, 2.6:1 on --primary). Written with :not(:where(…)) so the
   exclusion costs nothing in specificity and a component's own hover still wins —
   the (0,8,2) version of this rule painted an index chip white on white. */
.hero--panel a:not(:where(.btn,.callbtn,.calltab,.chip,.brand,.ftel,.telbig)):hover,
.hero--dark a:not(:where(.btn,.callbtn,.calltab,.chip,.brand,.ftel,.telbig)):hover,
.diptych__half--primary a:not(:where(.btn,.callbtn,.calltab,.chip,.brand,.ftel,.telbig)):hover,
.diptych__half--dark a:not(:where(.btn,.callbtn,.calltab,.chip,.brand,.ftel,.telbig)):hover,
.on-dark a:not(:where(.btn,.callbtn,.calltab,.chip,.brand,.ftel,.telbig)):hover,
.section--dark a:not(:where(.btn,.callbtn,.calltab,.chip,.brand,.ftel,.telbig)):hover{
  color:#fff;
}
/* the copper strip and the CTA keypad are the accent FILL — white is the only
   readable ink on them (4.86:1); --cta-light on copper is 1.7:1. */
.strip a,.keypad--cta a{color:#fff;text-decoration:underline}
/* focus ring on a primary panel: a single dark ring is 1.66:1 on --primary */
.hero--panel :where(a,button,summary):focus-visible,
.diptych__half--primary :where(a,button,summary):focus-visible{
  box-shadow:0 0 0 3px var(--primary),0 0 0 6px #fff;
}

/* --- PART 9 · a coloured hero paints its own ink, so .on-dark is never needed on one
   Observed while building: a page added `.on-dark` to a `.hero--panel` purely to get the
   descendant ink rules — and `.on-dark{background:var(--dark)}` then repainted the panel
   from steel-blue to near-black, silently changing the page's opening band. The ink rules
   belong to the coloured grounds themselves; `.on-dark` stays what it is, a dark BOX. */
.hero--panel :where(p,li,dd,figcaption,.small,.leadin,.hero__note),
.hero--dark   :where(p,li,dd,figcaption,.small,.leadin,.hero__note),
.diptych__half--primary :where(p,li,dd,.small,.leadin),
.diptych__half--dark    :where(p,li,dd,.small,.leadin){color:var(--on-dark)}
.hero--panel :where(h1,h2,h3,h4,.h3,strong,b),
.hero--dark  :where(h1,h2,h3,h4,.h3,strong,b),
.diptych__half--primary :where(h1,h2,h3,h4,.h3,strong,b),
.diptych__half--dark    :where(h1,h2,h3,h4,.h3,strong,b){color:#fff}
.hero--panel .eyebrow,.hero--dark .eyebrow,
.diptych__half--primary .eyebrow,.diptych__half--dark .eyebrow{color:var(--cta-light)}
.hero--panel .pinrule,.hero--dark .pinrule{border-top-color:var(--cta-light)}
.hero--panel .pinrule i,.hero--dark .pinrule i{background:var(--cta-light)}
.hero--panel .ibadge,.hero--dark .ibadge{background:rgba(255,255,255,.12);color:var(--cta-light)}
.hero--panel .numpill,.hero--dark .numpill{background:rgba(255,255,255,.1);
  border-color:rgba(255,255,255,.26);color:var(--cta-light)}
/* A LIGHT ISLAND inside a coloured band must contain its own ink completely.
   Flipping only the background leaves every band-scoped descendant rule in force:
   measured, a keypad cell repainted white inside a `.section--dark` hero kept
   `.section--dark a{color:var(--cta-light)}` and rendered its link at 2.17:1.
   `.hero--dark:not(.section--dark)` is load-bearing — a hero that carries BOTH
   classes stays dark, and its keypad stays dark with it. */
.hero--panel .keypad,.hero--dark:not(.section--dark) .keypad{
  background:rgba(255,255,255,.22);border-color:transparent}
.hero--panel .keypad>*,.hero--dark:not(.section--dark) .keypad>*{
  background:var(--surface);color:var(--text)}
.light-island,
.hero--panel .keypad>*,.hero--dark:not(.section--dark) .keypad>*{
  --island-ink:var(--text);
}
:where(.light-island,.hero--panel .keypad>*,.hero--dark:not(.section--dark) .keypad>*)
  :where(h2,h3,h4,.h3,strong,b){color:var(--head)}
:where(.light-island,.hero--panel .keypad>*,.hero--dark:not(.section--dark) .keypad>*)
  :where(p,span,li,dd){color:var(--muted)}
.light-island a:not(.btn):not(.callbtn):not(.calltab):not(.telbig),
.hero--panel .keypad>* a:not(.btn):not(.callbtn):not(.calltab):not(.telbig),
.hero--dark:not(.section--dark) .keypad>* a:not(.btn):not(.callbtn):not(.calltab):not(.telbig){
  color:var(--primary)}
.light-island a:not(.btn):not(.callbtn):not(.calltab):not(.telbig):hover,
.hero--panel .keypad>* a:not(.btn):not(.callbtn):not(.calltab):not(.telbig):hover,
.hero--dark:not(.section--dark) .keypad>* a:not(.btn):not(.callbtn):not(.calltab):not(.telbig):hover{
  color:var(--cta-ink)}
.light-island .numpill,
.hero--panel .keypad>* .numpill,.hero--dark:not(.section--dark) .keypad>* .numpill{
  background:var(--surface-alt);border-color:var(--line);color:var(--primary)}
.light-island .eyebrow,
.hero--panel .keypad>* .eyebrow,.hero--dark:not(.section--dark) .keypad>* .eyebrow{
  color:var(--cta-ink)}
/* the exclusions are load-bearing: without them this (0,3,0) rule beats .ibadge--cta
   and every copper check mark inside a light island renders as a pale grey square with
   a pale grey tick — an SVG carries no text, so nothing but an eye catches it. */
.light-island .ibadge:not(.ibadge--cta):not(.ibadge--dark),
.hero--panel .keypad>* .ibadge:not(.ibadge--cta):not(.ibadge--dark),
.hero--dark:not(.section--dark) .keypad>* .ibadge:not(.ibadge--cta):not(.ibadge--dark){
  background:var(--primary-subtle);color:var(--primary)}
.light-island :where(a,button,summary):focus-visible,
.hero--panel .keypad>* :where(a,button,summary):focus-visible{
  box-shadow:0 0 0 3px var(--surface),0 0 0 6px var(--focus)}
/* combined on the same element, the hero family owns the ground */
.hero--panel.on-dark{background:var(--primary)}
.hero--steel.on-dark{background:var(--steel);color:var(--text)}
.hero--steel.on-dark :where(h1,h2,h3,h4,.h3,p,li){color:inherit}
.hero--steel.on-dark :where(h1,h2,h3,h4,.h3){color:var(--head)}
/* a hero that is BOTH .section--dark and .hero--panel: dark wins, and it should, but the
   panel's own display colours must not fight it */
.section--dark.hero--panel{background:var(--dark)}

/* ============================================================================
   PART 10 — the corrections the rendered audit forced. Every one of these was
   invisible in the source and only showed up as a measured colour or a measured
   box. Appended last, so a tie on specificity resolves here.
   ========================================================================== */

/* 10a · A LIGHT BOX INSIDE A COLOURED BAND OWNS ITS INK.
   Part 9 gives `.hero--panel` / `.hero--dark` their own descendant ink so a page
   never needs `.on-dark` on a hero. The cost: those rules also reach INTO any
   light box the hero contains. Measured — a `.keypad` cell repainted white inside
   a panel hero still rendered its <strong> in #fff (1:1) and its `.hrule` in
   --on-dark (1.32:1). The first attempt at this block wrapped the island selector
   in `:where()`, which zeroes specificity and lost every tie; these are written out.
   `.hero--dark:not(.section--dark)` is load-bearing: a hero carrying BOTH classes
   stays dark, and its cells stay dark with it. */
.light-island,
.hero--panel .keypad > *,
.hero--dark:not(.section--dark) .keypad > *,
.hero--panel .card, .hero--dark:not(.section--dark) .card,
.hero--panel .framed__in, .hero--dark:not(.section--dark) .framed__in,
.hero--panel .notch__in, .hero--dark:not(.section--dark) .notch__in,
.hero--panel .quote, .hero--dark:not(.section--dark) .quote,
.hero--panel .duo__side, .hero--dark:not(.section--dark) .duo__side,
.hero--panel .compare__side, .hero--dark:not(.section--dark) .compare__side,
.hero--panel .ledger, .hero--dark:not(.section--dark) .ledger,
.hero--panel .cabinet, .hero--dark:not(.section--dark) .cabinet,
.hero--panel .phonecard--light, .hero--dark:not(.section--dark) .phonecard--light {
  color: var(--text);
}

.light-island :where(h1,h2,h3,h4,.h3,strong,b),
.hero--panel .keypad > * :where(h1,h2,h3,h4,.h3,strong,b),
.hero--dark:not(.section--dark) .keypad > * :where(h1,h2,h3,h4,.h3,strong,b),
.hero--panel .card :where(h2,h3,h4,.h3,strong,b),
.hero--dark:not(.section--dark) .card :where(h2,h3,h4,.h3,strong,b),
.hero--panel .framed__in :where(h2,h3,h4,.h3,strong,b),
.hero--dark:not(.section--dark) .framed__in :where(h2,h3,h4,.h3,strong,b),
.hero--panel .notch__in :where(h2,h3,h4,.h3,strong,b),
.hero--dark:not(.section--dark) .notch__in :where(h2,h3,h4,.h3,strong,b),
.hero--panel .duo__side :where(h2,h3,h4,.h3,strong,b),
.hero--dark:not(.section--dark) .duo__side :where(h2,h3,h4,.h3,strong,b),
.hero--panel .compare__side :where(h2,h3,h4,.h3,strong,b),
.hero--dark:not(.section--dark) .compare__side :where(h2,h3,h4,.h3,strong,b),
.hero--panel .cabinet :where(h2,h3,h4,.h3,strong,b),
.hero--dark:not(.section--dark) .cabinet :where(h2,h3,h4,.h3,strong,b),
.hero--panel .phonecard--light :where(h2,h3,h4,.h3,strong,b),
.hero--dark:not(.section--dark) .phonecard--light :where(h2,h3,h4,.h3,strong,b) {
  color: var(--head);
}

.light-island :where(p,li,dd,span,.small,.leadin,.hrule,.hero__note),
.hero--panel .keypad > * :where(p,li,dd,span,.small,.leadin,.hrule),
.hero--dark:not(.section--dark) .keypad > * :where(p,li,dd,span,.small,.leadin,.hrule),
.hero--panel .card :where(p,li,dd,.small,.leadin,.hrule),
.hero--dark:not(.section--dark) .card :where(p,li,dd,.small,.leadin,.hrule),
.hero--panel .framed__in :where(p,li,dd,.small,.leadin,.hrule),
.hero--dark:not(.section--dark) .framed__in :where(p,li,dd,.small,.leadin,.hrule),
.hero--panel .notch__in :where(p,li,dd,.small,.leadin,.hrule),
.hero--dark:not(.section--dark) .notch__in :where(p,li,dd,.small,.leadin,.hrule),
.hero--panel .duo__side :where(p,li,dd,.small,.leadin,.hrule),
.hero--dark:not(.section--dark) .duo__side :where(p,li,dd,.small,.leadin,.hrule),
.hero--panel .compare__side :where(p,li,dd,.small,.leadin,.hrule),
.hero--dark:not(.section--dark) .compare__side :where(p,li,dd,.small,.leadin,.hrule),
.hero--panel .cabinet :where(p,li,dd,.small,.leadin,.hrule),
.hero--dark:not(.section--dark) .cabinet :where(p,li,dd,.small,.leadin,.hrule),
.hero--panel .ledger__v, .hero--dark:not(.section--dark) .ledger__v,
.hero--panel .phonecard--light :where(p,li,dd,.small,.leadin),
.hero--dark:not(.section--dark) .phonecard--light :where(p,li,dd,.small,.leadin) {
  color: var(--muted);
}

.light-island .hrule::before, .light-island .hrule::after,
.hero--panel .keypad > * .hrule::before, .hero--panel .keypad > * .hrule::after,
.hero--panel .framed__in .hrule::before, .hero--panel .framed__in .hrule::after,
.hero--dark:not(.section--dark) .framed__in .hrule::before,
.hero--dark:not(.section--dark) .framed__in .hrule::after {
  background: var(--line);
}

.light-island .eyebrow,
.hero--panel .keypad > * .eyebrow,
.hero--panel .card .eyebrow, .hero--panel .framed__in .eyebrow,
.hero--dark:not(.section--dark) .keypad > * .eyebrow,
.hero--dark:not(.section--dark) .card .eyebrow,
.hero--dark:not(.section--dark) .framed__in .eyebrow { color: var(--cta-ink); }

.light-island .numpill,
.hero--panel .keypad > * .numpill, .hero--panel .framed__in .numpill,
.hero--dark:not(.section--dark) .keypad > * .numpill,
.hero--dark:not(.section--dark) .framed__in .numpill {
  background: var(--surface-alt); border-color: var(--line); color: var(--primary);
}

.light-island .ibadge:not(.ibadge--cta):not(.ibadge--dark),
.hero--panel .keypad > * .ibadge:not(.ibadge--cta):not(.ibadge--dark),
.hero--panel .card .ibadge:not(.ibadge--cta):not(.ibadge--dark),
.hero--dark:not(.section--dark) .keypad > * .ibadge:not(.ibadge--cta):not(.ibadge--dark),
.hero--dark:not(.section--dark) .card .ibadge:not(.ibadge--cta):not(.ibadge--dark) {
  background: var(--primary-subtle); color: var(--primary);
}

/* 10b · THE EXCLUSION LISTS MUST NOT OUTRANK THE COMPONENT THEY EXCLUDE FOR.
   `a:not(.btn):not(.callbtn):not(.calltab):not(.chip):not(.brand):not(.ftel):not(.telbig)`
   is (0,8,1) — it beat `.hero--panel .jumps a` (0,2,1) and painted an index chip
   copper-on-translucent-white at 3.87:1. `:not(:where(…))` keeps the exclusion and
   drops the argument's specificity to zero, so a component rule wins again. */
.hero--panel a:not(:where(.btn,.callbtn,.calltab,.chip,.brand,.ftel,.telbig)),
.hero--dark a:not(:where(.btn,.callbtn,.calltab,.chip,.brand,.ftel,.telbig)),
.diptych__half--primary a:not(:where(.btn,.callbtn,.calltab,.chip,.brand,.ftel,.telbig)),
.diptych__half--dark a:not(:where(.btn,.callbtn,.calltab,.chip,.brand,.ftel,.telbig)) {
  color: var(--cta-light);
}
/* the index / alphabet rails carry their own ink on every coloured ground */
.hero--panel .jumps a, .hero--dark .jumps a, .section--dark .jumps a, .on-dark .jumps a,
.hero--panel .termrail a, .hero--dark .termrail a, .section--dark .termrail a,
.on-dark .termrail a, .diptych__half--primary .jumps a, .diptych__half--dark .jumps a {
  color: #fff;
}
.hero--panel .jumps a:hover, .hero--dark .jumps a:hover, .section--dark .jumps a:hover,
.on-dark .jumps a:hover, .hero--panel .termrail a:hover, .hero--dark .termrail a:hover,
.section--dark .termrail a:hover, .on-dark .termrail a:hover {
  color: var(--primary);
}
/* a light island's own prose links */
.light-island a:not(:where(.btn,.callbtn,.calltab,.telbig,.chip)),
.hero--panel .keypad > * a:not(:where(.btn,.callbtn,.calltab,.telbig,.chip)),
.hero--panel .card a:not(:where(.btn,.callbtn,.calltab,.telbig,.chip)),
.hero--panel .framed__in a:not(:where(.btn,.callbtn,.calltab,.telbig,.chip)),
.hero--dark:not(.section--dark) .keypad > * a:not(:where(.btn,.callbtn,.calltab,.telbig,.chip)),
.hero--dark:not(.section--dark) .card a:not(:where(.btn,.callbtn,.calltab,.telbig,.chip)) {
  color: var(--primary);
}

/* 10c · NOTHING SCROLLS THE DOCUMENT SIDEWAYS.
   A wide table inside `overflow-x:auto` still forces the page wider when an
   ancestor grid track has no `min-width:0` — measured 524px of document overflow
   at 320px from a Schließplan schema that was already inside its own scroller. */
.hero__grid > *, .fsplit > *, .usp > *, .ctaband > *, .phonecard__grid > *,
.duo > *, .cabinet > *, .chipgroups > *, .mosaic > *, .tabs > *, .lframe > * { min-width: 0; }
[class*="__scroll"], .tablescroll { overflow-x: auto; max-width: 100%; }

/* 10d · A SCROLLABLE REGION MUST BE KEYBOARD-REACHABLE (axe: scrollable-region-focusable).
   theme.js gives every overflowing .peek a tabindex; this is the visible affordance. */
.peek:focus-visible, [class*="__scroll"]:focus-visible {
  outline: none; box-shadow: 0 0 0 3px var(--surface), 0 0 0 6px var(--focus);
}
.section--dark .peek:focus-visible, .section--dark [class*="__scroll"]:focus-visible {
  box-shadow: 0 0 0 3px var(--dark), 0 0 0 6px var(--cta-light);
}

/* 10e · the same specificity correction for the two Part 1 exclusion chains.
   They are (0,8,1) and would otherwise still outrank every component rule on a
   dark band — the exact bug 10b fixes for the panel hero. The originals stay in
   place (harmless: identical declarations), these simply add the low-specificity
   twin so a component can win. */
.section--dark a:not(:where(.btn,.callbtn,.calltab,.chip,.brand,.ftel,.telbig)),
.on-dark a:not(:where(.btn,.callbtn,.calltab,.chip,.brand,.ftel,.telbig)){
  color:var(--cta-light);
}

/* 10f · a light phone card inside a coloured hero is a light island too */
.hero--panel .phonecard--light a:not(:where(.btn,.callbtn,.calltab,.telbig)),
.hero--dark .phonecard--light a:not(:where(.btn,.callbtn,.calltab,.telbig)),
.section--dark .phonecard--light a:not(:where(.btn,.callbtn,.calltab,.telbig)),
.on-dark .phonecard--light a:not(:where(.btn,.callbtn,.calltab,.telbig)){
  color:var(--primary);
}
.hero--panel .phonecard--light .telbig,
.hero--dark .phonecard--light .telbig,
.section--dark .phonecard--light .telbig{color:var(--head)}
.hero--panel .phonecard--light .telbig svg,
.hero--dark .phonecard--light .telbig svg,
.section--dark .phonecard--light .telbig svg{stroke:var(--cta)}
.hero--panel .phonecard--light .phonecard__cap,
.hero--dark .phonecard--light .phonecard__cap,
.section--dark .phonecard--light .phonecard__cap{color:var(--cta-ink)}

/* 10g · a hero's own sub-heading. A real <h2> styled as a 13px all-caps eyebrow is a
   readability downgrade for the older reader this site is written for — the eyebrow is
   a LABEL, not a heading. */
.hero__subhead{margin-top:6px;margin-bottom:4px;font-size:clamp(18px,1.5vw,21px);
  font-weight:700;letter-spacing:-.008em;max-width:44ch}
.hero--panel .hero__subhead,.hero--dark .hero__subhead{color:var(--cta-light)}

/* 10h · height:100% and aspect-ratio cannot both win.
   `.media--fill` fixes the height to its grid row; an aspect-ratio class then derives
   the WIDTH from that height and the box grows past its track — measured 452px inside a
   ~300px column, 115px of it off the viewport. Inside a fill box the ratio yields. */
.media.media--fill[class*="ratio-"]{aspect-ratio:auto}
.mosaic .media{height:100%}
.mosaic .media img{height:100%;object-fit:cover}

/* 10i · a hero grid whose two columns differ a lot in height should align at the TOP.
   `align-items:center` is right for copy-beside-photo; where the left column is much
   taller it drops that column by half the difference and leaves a hole under the H1.
   Measured on ratgeber/abzocke: 210px of empty band before the first paragraph. */
.hero__grid--top{align-items:start}

/* 10j · a hero's generic icon-badge tint must not swallow the badge VARIANTS.
   `.hero--panel .ibadge` is (0,2,0) and beat `.ibadge--cta` (0,1,0), so every copper
   check mark inside a panel hero rendered as a pale grey square with a pale grey tick.
   An SVG carries no text, so no contrast checker sees it — only an eye does. */
.hero--panel .ibadge--cta,.hero--dark .ibadge--cta{background:var(--cta);color:#fff}
.hero--panel .ibadge--dark,.hero--dark .ibadge--dark{background:var(--primary);color:#fff}
.hero--panel .ibadge--outline,.hero--dark .ibadge--outline{
  background:transparent;box-shadow:inset 0 0 0 1.5px rgba(255,255,255,.4);color:#fff}
