/* ==========================================================================
   immoclass — Design-System (Welt: "Immobilien-Dossier")
   Ground = Dossier-Papier, Tinte, ein roter Stempel als Signal, Graphit-Hairlines,
   Plan-Linien, präzise Faktentabellen. Bewegung macht der Film; die UI bleibt ruhig.
   ========================================================================== */

/* ---- Fonts -------------------------------------------------------------- */
@font-face {
  font-family: 'Archivo';
  src: url('../fonts/archivo-latin.woff2') format('woff2');
  font-weight: 400 700;
  font-stretch: 100%;
  font-display: swap;
  unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+2000-206F, U+2074, U+20AC, U+2122, U+2212;
}
@font-face {
  font-family: 'Archivo';
  src: url('../fonts/archivo-latin-ext.woff2') format('woff2');
  font-weight: 400 700;
  font-stretch: 100%;
  font-display: swap;
  unicode-range: U+0100-024F, U+0259, U+1E00-1EFF, U+2020, U+20A0-20AB, U+2113;
}

/* ---- Tokens ------------------------------------------------------------- */
:root {
  --paper:    #F4F1EA;   /* Dossier-Stock */
  --paper-2:  #EBE7DC;   /* leicht tiefere Fläche */
  --ink:      #16130F;   /* warmes near-black */
  --ink-2:    #2A251D;
  --meta:     #5A554C;   /* Sekundär/Meta auf Papier (>=4.5:1) */
  --red:      #C8102E;   /* Signal / Stempel — exakter Markenwert noch zu sampeln */
  --red-deep: #A50D26;
  --hair:     #D3CCBD;   /* Hairline auf Papier */
  --hair-2:   #C4BCAA;

  /* Inhaber-Ästhetik: Industrie (Beton, Schwarzstahl) + disziplinierter Pop */
  --steel:    #26262A;   /* Schwarzstahl — strukturelle Linien & Grid-Nodes (USM Haller) */
  --concrete:      #D9D5CB;  /* roher Beton — Material-Fläche */
  --concrete-line: #B7B2A6;  /* Betonton fuer Linien — seit dem Wegfall der
                                Zeilentrenner ungenutzt, als Reserve behalten */
  --pop:      #A13941;   /* Wayfinding-Akzent (Nav-Hover, Link-Unterstrich) — Aktion bleibt --red */
  --pop-hell: #FF6B7D;   /* derselbe Akzent auf dem schwarzen Menuebalken (6.75:1 auf --ink; --red erreicht dort nur 3.15:1) */
  --wood:     #9A7A4E;   /* warmes Holz — sparsamer Material-Akzent */
  --on-ink:      #F4F1EA;
  --on-ink-meta: #B7B0A1;
  --hair-ink: rgba(244,241,234,.16);

  --sans: 'Archivo', system-ui, -apple-system, 'Segoe UI', Roboto, sans-serif;

  --maxw: 1240px;
  --gutter: clamp(1.25rem, 4vw, 4rem);
  --rule: 1px;

  --mast: 4rem;                       /* Hoehe der Menueleiste (gemessen 65–67px); zur Laufzeit genau: --mast-ist (main.js, Stapel) */
  --rahmen-oben: calc(var(--mast) + .5rem);  /* Rahmenkante knapp darunter */
  --step: clamp(5rem, 9vw, 8.5rem);   /* vertikaler Sektionsrhythmus */
  --ease: cubic-bezier(.16, 1, .3, 1); /* exponential ease-out */
}

/* ---- Reset / Base ------------------------------------------------------- */
*, *::before, *::after { box-sizing: border-box; }
* { margin: 0; }
html { -webkit-text-size-adjust: 100%; scroll-behavior: smooth; }
@media (prefers-reduced-motion: reduce) { html { scroll-behavior: auto; } }

body {
  font-family: var(--sans);
  font-weight: 400;
  color: var(--ink);
  background: var(--paper);
  line-height: 1.5;
  font-feature-settings: "kern" 1;
  -webkit-font-smoothing: antialiased;
  text-rendering: optimizeLegibility;
}

img, video { display: block; max-width: 100%; height: auto; }
a { color: inherit; text-decoration: none; }
h1, h2, h3, h4 { font-weight: 700; line-height: 1.02; letter-spacing: -0.03em; text-wrap: balance; }
p { text-wrap: pretty; }

:focus-visible { outline: 2px solid var(--red); outline-offset: 3px; }

/* Sprunglink zum Inhalt: unsichtbar, bis die Tastatur ihn erreicht. */
.skip { position: absolute; left: -9999px; top: 0; z-index: 100;
  padding: .7rem 1rem; background: var(--ink); color: var(--paper); font-weight: 600; }
.skip:focus { left: var(--gutter, 1rem); top: .6rem; outline-color: var(--paper); }

/* Numerische Tabellenziffern für alle Eckdaten/Kennzahlen */
.tnum, .meta, .fact__val, .stat { font-variant-numeric: tabular-nums; }

/* ---- Layout-Helfer ------------------------------------------------------ */
.wrap { max-width: var(--maxw); margin-inline: auto; padding-inline: var(--gutter); }
.section { padding-block: var(--step); }
.rule { border: 0; border-top: var(--rule) solid var(--hair); }
.eyebrow-none {} /* bewusst kein dekorativer Eyebrow */

/* Meta / Marginalien (Dossier-Sprache) */
.meta {
  font-size: .72rem;
  letter-spacing: .14em;
  text-transform: uppercase;
  color: var(--meta);
  font-weight: 500;
}

/* Buttons ---------------------------------------------------------------- */
.btn {
  display: inline-flex; align-items: center; gap: .6em;
  font: inherit; font-weight: 600; letter-spacing: -0.01em;
  padding: .85em 1.4em; border: var(--rule) solid var(--ink);
  background: transparent; color: var(--ink); cursor: pointer;
  transition: background .25s var(--ease), color .25s var(--ease), border-color .25s var(--ease);
}
.btn:hover { background: var(--ink); color: var(--paper); }
.btn--stamp {
  border-color: var(--red); color: var(--paper); background: var(--red);
  position: relative;
}
.btn--stamp:hover { background: var(--red-deep); border-color: var(--red-deep); color: var(--paper); }
.btn--stamp .btn__mark { font-variant-numeric: tabular-nums; opacity: .8; }
.btn--ghost-ink { border-color: var(--hair-ink); color: var(--on-ink); }
.btn--ghost-ink:hover { background: var(--on-ink); color: var(--ink); border-color: var(--on-ink); }

/* Link mit Zeichnungs-Unterstrich */
.ulink { position: relative; font-weight: 600; }
.ulink::after {
  content: ""; position: absolute; left: 0; right: 0; bottom: -3px; height: 2px;
  background: var(--pop); transform: scaleX(0); transform-origin: left;
  transition: transform .35s var(--ease);
}
.ulink:hover::after { transform: scaleX(1); }

/* ==========================================================================
   Masthead / Navigation
   ========================================================================== */
/* Die Leiste ist immer ein deckender Balken: schwarz ueber dem Kopf, Papier
   danach (.is-solid). Was hochscrollt, gleitet darunter hindurch, statt sich
   mit den Menuetexten zu ueberschneiden. Ueber Schwarz keine Haarlinie, der
   Balken geht nahtlos in den schwarzen Kopf ueber. */
.masthead {
  position: fixed; inset: 0 0 auto 0; z-index: 50;
  background: var(--ink); color: var(--on-ink);
  transition: background .3s var(--ease), color .3s var(--ease), border-color .3s var(--ease);
  border-bottom: var(--rule) solid transparent;
}
.masthead.is-solid {
  background: var(--paper); color: var(--ink);
  border-bottom-color: var(--hair);
}
.masthead__bar {
  max-width: var(--maxw); margin-inline: auto; padding: 1rem var(--gutter);
  display: flex; align-items: baseline; justify-content: space-between; gap: 2rem;
}
/* Wortmarke als Bild. Zwei Farbfassungen, gesteuert ueber .is-solid:
   ueber dem dunklen Hero die helle, auf der Papierleiste die dunkle. */
.brand { display: inline-flex; align-items: center; line-height: 0; }
.brand__img { display: block; width: 137px; height: auto; }
/* Desktop: Logo 20 % groesser. Das Polster der Leiste gibt die 5 px Mehrhoehe
   wieder ab, damit die Leiste bei 67 px bleibt — --mast und die Rahmenkanten
   darunter rechnen mit dieser Hoehe. Mobil bleibt alles wie es ist. */
@media (min-width: 861px) {
  .masthead .brand__img { width: 164px; }
  .masthead__bar { padding-block: calc(1rem - 2.5px); }
}
.brand__img--dunkel { display: none; }
.masthead.is-solid .brand__img--hell { display: none; }
.masthead.is-solid .brand__img--dunkel { display: block; }
.masthead.nav-open .brand__img--hell { display: block; }
.masthead.nav-open .brand__img--dunkel { display: none; }
.nav { display: flex; gap: clamp(1rem, 2vw, 2rem); align-items: baseline; }
.nav a { font-size: .95rem; font-weight: 500; transition: color .2s var(--ease);
  padding-block: .2rem; }   /* Trefferflaeche >= 24 px hoch (WCAG 2.5.8) */
/* Über Hero/Subhero (helle Links auf Bild): knalliges Signal-Rot */
.nav a:hover, .nav a[aria-current] { color: var(--pop-hell); }
/* Auf Papier (solide, dunkle Links): gedämpftes Wayfinding-Rot */
.masthead.is-solid .nav a:hover, .masthead.is-solid .nav a[aria-current] { color: var(--pop); }
/* Das offene Handy-Menue ist auch im Papierzustand schwarz. */
.masthead.nav-open .nav a:hover, .masthead.nav-open .nav a[aria-current] { color: var(--pop-hell); }
/* Der Login fuehrt aus der Seite heraus. Eine Hairline links davon sagt das,
   ohne ein Symbol dafuer zu brauchen — auf dem Telefon steht der Eintrag
   ohnehin untereinander, dort traegt die Zeilenlinie die Trennung. */
.nav__extern { padding-left: clamp(1rem, 2vw, 2rem); border-left: var(--rule) solid var(--on-ink);
  transition: color .2s var(--ease), border-color .3s var(--ease); }
/* Die Linie traegt die Farbe der Kopfzeile, nicht die des Links: beim
   Ueberfahren wird «Login» rot, die Linie bleibt. */
.masthead.is-solid .nav__extern { border-left-color: var(--ink); }
@media (max-width: 860px) { .nav__extern { padding-left: 0; border-left: 0; } }

.nav__cta { display: none; }
.nav-toggle { display: none; }

@media (max-width: 860px) {
  .nav { display: none; }
  .nav-toggle {
    display: inline-flex; background: none; border: 0; color: inherit; font: inherit;
    font-weight: 600; cursor: pointer; letter-spacing: .04em;
  }
  .masthead.nav-open { background: var(--ink); color: var(--on-ink); }
  .masthead.nav-open .nav {
    display: flex; position: absolute; top: 100%; left: 0; right: 0;
    flex-direction: column; gap: 0; background: var(--ink); padding: var(--gutter);
    border-top: var(--rule) solid var(--hair-ink);
  }
  .masthead.nav-open .nav a { padding: .9rem 0; border-bottom: var(--rule) solid var(--hair-ink); font-size: 1.1rem; }
}

/* ==========================================================================
   Hero / Dossier-Deckel
   ========================================================================== */
.hero { position: relative; min-height: 100svh; display: flex; flex-direction: column;
        color: var(--on-ink); background: var(--ink); overflow: hidden; }

/* Scroll-Bühne: nur aktiv, wenn JS das Video wirklich scrubben kann.
   Ohne .is-scrub bleibt der Hero exakt wie vorher (Bild, 100svh). */
.herostage { position: relative; }
/* Hoehen setzt das JS in Pixeln aus window.innerHeight — svh/dvh/vh meinen
   auf Android je nach Browser und Version etwas anderes und ein nicht
   unterstuetztes dvh verwirft die ganze Deklaration. --scrub ist der Regler:
   Vielfaches der Viewporthoehe, ueber das der Film abgespielt wird. */
.herostage { --scrub: 2.5; }
.herostage.is-scrub .hero { position: sticky; top: 0; min-height: 0; }
@media (max-width: 760px) { .herostage { --scrub: 1.6; } }

/* Video liegt ueber dem Standbild und blendet erst auf, wenn ein Frame steht.
   Fällt es aus, entfernt JS das Element und hero.jpg bleibt sichtbar. */
.hero__video { opacity: 0; transition: opacity .5s ease; }
.hero__video.is-live { opacity: 1; }
@media (prefers-reduced-motion: reduce) { .hero__video { transition: none; } }
.hero__media, .hero__media video, .hero__media img {
  position: absolute; inset: 0; width: 100%; height: 100%; object-fit: cover;
}
.hero__media::after {
  content: ""; position: absolute; inset: 0;
  background: linear-gradient(180deg, rgba(10,8,6,.55) 0%, rgba(10,8,6,.15) 32%, rgba(10,8,6,.60) 100%);
}
/* Präziser Linienrahmen (Dossier-Deckel) */
/* Die Rahmenkante laeuft knapp UNTER Menue und Wortmarke durch, nicht
   mitten hindurch — der Masthead schwebt darueber. */
.hero__frame {
  position: absolute; inset: clamp(.9rem, 2.4vw, 2rem); top: var(--rahmen-oben);
  border: var(--rule) solid rgba(244,241,234,.5); pointer-events: none; z-index: 3;
}
.hero__frame::before, .hero__frame::after {
  content: ""; position: absolute; background: rgba(244,241,234,.5);
}
/* Registermarken an den Rändern */
.hero__ticks { position: absolute; inset: clamp(.9rem, 2.4vw, 2rem); top: var(--rahmen-oben);
  z-index: 3; pointer-events: none; }
/* Schwarzstahl-Grid-Nodes (USM-Haller-Anmutung) auf der Rahmenlinie */
.hero__ticks span { position: absolute; width: 8px; height: 8px; background: var(--steel);
  border: 1px solid rgba(244,241,234,.7); transform: translate(-50%, -50%); }
.hero__ticks span:nth-child(1){ top:0; left:25%; } .hero__ticks span:nth-child(2){ top:0; left:50%; }
.hero__ticks span:nth-child(3){ top:0; left:75%; }
.hero__ticks span:nth-child(4){ bottom:0; left:25%; } .hero__ticks span:nth-child(5){ bottom:0; left:50%; }
.hero__ticks span:nth-child(6){ bottom:0; left:75%; }
.hero__ticks span:nth-child(4), .hero__ticks span:nth-child(5), .hero__ticks span:nth-child(6){ transform: translate(-50%, 50%); }
/* Rotes Aufblinken einzelner Nodes (main.js, «Rahmen-Quadrate»): an in
   160 ms, aus in 500 ms — die Ausklingzeit liegt unter der kuerzesten Pause
   (700 ms), damit nie zwei Quadrate zugleich rot stehen. Schein und leichtes
   Wachsen geben dem Rot Helligkeit, die das Auge am Rand des Blickfelds
   wahrnimmt; `scale` statt `transform` laesst das translate der Lage stehen.
   Gilt auch fuer .karte__marken. */
.hero__ticks span, .karte__marken span {
  transition: background-color .5s ease-out, box-shadow .5s ease-out, scale .5s ease-out; }
.hero__ticks span.is-blink, .karte__marken span.is-blink { background-color: var(--red);
  scale: 1.25; box-shadow: 0 0 10px 2px rgba(200,16,46,.7); transition-duration: .16s; }
@media (prefers-reduced-motion: reduce) {
  .hero__ticks span, .karte__marken span { transition: none; }
}

.hero__bar {
  position: relative; z-index: 4; margin-top: auto;
  max-width: var(--maxw); margin-inline: auto; width: 100%;
  padding: clamp(2rem,5vw,4rem) calc(var(--gutter) + clamp(.9rem,2.4vw,2rem));
  display: grid; gap: clamp(1.5rem, 3vw, 2.5rem);
}
/* Abwesenheit (Panel, snippets/abwesenheit.php): Hinweis direkt unter dem
   Menue, ueber Film und Rahmen. Papier und Tinte wie die Kopfzeile beim
   Scrollen, roter Rand als Stempel. Schmal zwischen den Rahmenkanten. */
.abwesenheiten { position: absolute; z-index: 6; top: calc(var(--rahmen-oben) + 1rem);
  left: calc(clamp(.9rem, 2.4vw, 2rem) + 1rem); right: calc(clamp(.9rem, 2.4vw, 2rem) + 1rem);
  display: grid; gap: .6rem; justify-items: start; pointer-events: none; }
.abwesenheit { position: relative; pointer-events: auto; width: 100%; max-width: 32rem;
  padding: .9rem 3rem .95rem 1.1rem; background: var(--paper); color: var(--ink);
  border-left: 4px solid var(--red); box-shadow: 0 10px 30px -18px rgba(0,0,0,.6); }
.abwesenheit__titel { font-weight: 700; font-size: 1.05rem; line-height: 1.25; }
.abwesenheit__text { margin-top: .25rem; font-size: .95rem; line-height: 1.4; }
.abwesenheit__wann { margin-top: .45rem; color: var(--ink); }
.abwesenheit__zu { position: absolute; top: .35rem; right: .35rem; width: 2.25rem; height: 2.25rem;
  display: grid; place-items: center; font-size: 1.5rem; line-height: 1; color: var(--ink);
  background: transparent; border: 0; cursor: pointer; }
.abwesenheit__zu:hover { color: var(--red); }
.abwesenheit__zu:focus-visible { outline: 2px solid var(--red); outline-offset: 2px; }
.hero__meta { display: flex; gap: 1.5rem; flex-wrap: wrap; color: var(--on-ink-meta); }
.hero__claim {
  font-size: clamp(2.75rem, 8.5vw, 6rem); line-height: .95; letter-spacing: -0.045em;
}
.hero__claim em { font-style: normal; color: var(--red); }
.hero__lede { max-width: 46ch; font-size: clamp(1.05rem, 1.6vw, 1.25rem); color: #E9E4D9; }
.hero__actions { display: flex; gap: 1rem; flex-wrap: wrap; align-items: center; }
.hero__scroll { position: absolute; right: calc(var(--gutter) + 1rem); bottom: 1.4rem; z-index:4;
  writing-mode: vertical-rl; font-size:.7rem; letter-spacing:.2em; text-transform:uppercase;
  color: var(--on-ink-meta); }

/* ==========================================================================
   Vorwort / Positionierung
   ========================================================================== */
.foreword__grid { display: grid; grid-template-columns: 1fr; gap: clamp(2rem,5vw,4rem); }
@media (min-width: 900px){ .foreword__grid { grid-template-columns: 1.15fr 1fr; align-items: start; } }
.foreword__lead { font-size: clamp(1.5rem, 2.8vw, 2.35rem); line-height: 1.14; letter-spacing: -0.025em; font-weight: 500; }
.foreword__lead strong { font-weight: 700; }
.foreword__body { color: var(--ink); max-width: 62ch; }
.foreword__body p + p { margin-top: 1rem; }

.pillars { margin-top: clamp(2.5rem,5vw,4rem); border-top: var(--rule) solid var(--hair); }
.pillar { display: grid; grid-template-columns: 3ch 1fr; column-gap: clamp(1rem,3vw,2rem); row-gap: .5rem;
  padding: clamp(1.4rem,2.5vw,2rem) 0; border-bottom: var(--rule) solid var(--hair); }
.pillar__no { color: var(--red); font-weight: 700; font-size: 1rem; grid-column: 1; }
.pillar__t { font-size: clamp(1.15rem,1.8vw,1.4rem); grid-column: 2; }
.pillar__d { color: var(--meta); max-width: 60ch; grid-column: 2; }
@media (min-width:900px){
  .pillar { grid-template-columns: 3ch minmax(0,1fr) minmax(0,1.7fr); align-items: baseline; column-gap: clamp(1.5rem,3vw,2.5rem); }
  .pillar__t { grid-column: 2; }
  .pillar__d { grid-column: 3; }
}

/* ---- Projektband (Startseite) -----------------------------------------
   Bilder nahtlos und alle gleich hoch; main.js verschiebt die Spur beim
   Scrollen. Das Band ersetzt den doppelten Sektionsabstand: halber Rhythmus
   davor und danach statt zweimal --step Leere. */
.section--vor-band { padding-bottom: calc(var(--step) / 2); }
.projektband { position: relative; overflow: hidden; }
/* Feine rote Linie oben und unten grenzt die Bilder vom Papier ab. */
.projektband__bilder { height: clamp(170px, 20vw, 300px); background: var(--hair);
  border-block: var(--rule) solid var(--red); }
.projektband__spur { display: flex; height: 100%; width: max-content; }
.projektband__spur img { display: block; flex: none; height: 100%; width: auto; max-width: none; }
.projektband + .section { padding-top: calc(var(--step) / 2); }
/* Über uns: die Chronik folgt dem Band mit einem vollen Schritt. */
.projektband + .section--nach-band { padding-top: var(--step); }
/* Pfeile zum Blaettern: nur in der Standansicht. Waehrend gescrollt wird,
   nimmt main.js .is-ruhe weg; die Tastatur holt sie per Fokus immer hervor.
   Der Fokusring liegt innen, auf der dunklen Flaeche — ueber einem Foto
   waere sein Kontrast Zufall. */
.projektband__pfeil { position: absolute; top: 50%; translate: 0 -50%; z-index: 1;
  display: grid; place-items: center; width: 44px; height: 44px; padding: 0;
  border: 0; background: var(--ink); color: var(--on-ink); cursor: pointer;
  opacity: 0; pointer-events: none; transition: opacity .2s var(--ease), background .2s var(--ease); }
.projektband__pfeil[hidden] { display: none; }
.projektband__pfeil--zurueck { left: calc(var(--gutter) / 2); }
.projektband__pfeil--weiter { right: calc(var(--gutter) / 2); }
.projektband.is-ruhe .projektband__pfeil, .projektband__pfeil:focus-visible { opacity: 1; pointer-events: auto; }
.projektband__pfeil:hover { background: var(--red); }
.projektband__pfeil:focus-visible { outline: 2px solid var(--on-ink); outline-offset: -6px; }
@media (prefers-reduced-motion: reduce) { .projektband__pfeil { transition: none; } }

/* ==========================================================================
   Leistungs-Register (funktionaler Index)
   ========================================================================== */
/* ---- Registerflaeche ---------------------------------------------------
   Ruhige Tonflaeche als Traeger der Leistungsliste. Die frueheren sechs
   Betonlagen (Poren, Koernung, Laufspuren, Fleckigkeit, Ankerloecher,
   Schalungsfugen) und das Schablonen-Motiv sind auf Kundenwunsch entfernt.
   Beides liegt in der Historie: git log assets/css/main.css. */
/* Registerflaeche: ruhige Betonflaeche unter den Leistungskarten */

.reg { border-top: 2px solid var(--steel);
  padding: clamp(.4rem,2vw,1rem) clamp(1.1rem,3vw,2rem); }

/* ---- Register als Aufklapp-Liste --------------------------------------
   Die Ueberschriften bilden eine ruhige Liste mit gleich hohen Zeilen, die
   Beschreibung liegt darunter und klappt auf Klick auf. Traeger ist das
   native <details>: kein Skript, per Tastatur bedienbar, korrekte Semantik
   ohne ARIA-Bastelei. */
/* Sprungziel unter dem fixen Masthead freistellen: genau Menuehoehe, sonst
   schaut darueber noch ein Streifen des Projektbands herein. Luft zur
   Ueberschrift gibt das Padding der Sektion. */
#leistungen { scroll-margin-top: var(--mast-ist, var(--mast)); }
/* Über uns: die Team-Sektion hat oben kein Padding — 1,5rem Luft unter dem
   Menü, weniger als der Leerraum unter der Chronik, also bleibt „Ihr Team“
   der oberste sichtbare Inhalt. */
#team { scroll-margin-top: calc(var(--mast-ist, var(--mast)) + 1.5rem); }

/* ==========================================================================
   Leistungen: Wendekarten
   Sieben Karten in der Aufteilung 2 – 3 – 2. Das Raster hat sechs Spalten,
   damit beide Reihenformen darin aufgehen: breit ist drei Spalten, schmal
   zwei. Eine Reihe wird so hoch wie ihr laengster Webtext — deshalb gehoeren
   die langen Texte auf die breiten Plaetze.
   ========================================================================== */
.svcgrid__lead { margin-top: 1.2rem; color: var(--meta); max-width: 62ch; }

.svcgrid {
  display: grid; gap: clamp(1rem, 2vw, 1.6rem);
  grid-template-columns: 1fr;
  margin-top: clamp(1.6rem, 3vw, 2.4rem);
}
@media (min-width: 620px) { .svcgrid { grid-template-columns: repeat(2, 1fr); } }
@media (min-width: 1000px) {
  .svcgrid { grid-template-columns: repeat(3, 1fr); }
  /* Vier Karten stehen als 2 + 2. Bei drei Spalten bliebe die vierte allein
     in der zweiten Reihe — fuenf ergeben dagegen sauber 3 + 2. */
  .svcgrid[data-count="2"], .svcgrid[data-count="4"] { grid-template-columns: repeat(2, 1fr); }
}
/* Sieben Karten: 2 + 3 + 2 — ab dem Tablet hochkant (760) wie auf dem Desktop,
   keine Karte allein in der letzten Reihe. */
@media (min-width: 760px) {
  .svcgrid[data-count="7"] { grid-template-columns: repeat(6, 1fr); }
  .svcgrid[data-count="7"] .svc { grid-column: span 2; }
  .svcgrid[data-count="7"] .svc:nth-child(-n+2),
  .svcgrid[data-count="7"] .svc:nth-child(n+6) { grid-column: span 3; }
}
/* 620–759 (grosse Handys quer): zwei Spalten, die siebte Karte ueber beide */
@media (min-width: 620px) and (max-width: 759.98px) {
  .svcgrid[data-count="7"] .svc:last-child { grid-column: 1 / -1; }
}

.svc {
  /* display:flex, weil ein <button> seinen Inhalt sonst in eine anonyme,
     schrumpfende Box legt — die Karte fiele auf Mindestbreite zusammen. */
  display: flex; width: 100%; perspective: 1400px;
  background: none; border: 0; padding: 0; font: inherit;
  text-align: left; cursor: pointer;
}
.svc__inner {
  flex: 1 1 auto;
  display: grid; min-height: 12.5rem;
  transform-style: preserve-3d;
  transition: transform .55s var(--ease);
}
.svc__face {
  grid-area: 1 / 1;                          /* beide Seiten im selben Feld:
                                                die hoehere bestimmt die Hoehe */
  -webkit-backface-visibility: hidden; backface-visibility: hidden;
  border: var(--rule) solid var(--hair-2);
  padding: clamp(1.1rem, 2vw, 1.6rem);
  display: flex; flex-direction: column; justify-content: space-between; gap: 1.2rem;
}
.svc__front { background: var(--concrete); color: var(--ink); }
.svc__back  { background: var(--ink); color: var(--on-ink); border-color: var(--ink);
              transform: rotateY(180deg); }
.svc__t { font-size: clamp(1.1rem, 1.7vw, 1.35rem); font-weight: 700; letter-spacing: -0.03em; }
/* Vorne stehen drei Dinge, nicht zwei: Titel und Kurztext gehoeren als Block
   nach oben, der Hinweis ans Fussende. space-between wuerde sie gleichmaessig
   auseinanderziehen. */
.svc__front { justify-content: flex-start; gap: .55rem; position: relative; }
.svc__front .svc__mark { margin-top: auto; }
/* Symbol der Leistung als Wasserzeichen, mittig hinter dem Text. Reine
   Dekoration (aria-hidden); Farbe aus der gelieferten Wasserzeichen-Variante. */
.svc__symbol { position: absolute; inset: 0; display: grid; place-items: center; pointer-events: none; color: #C6C0B4; }
.svc__symbol svg { width: min(9rem, 55%); height: auto; }
/* Ein Lichthof in der Grundfarbe loest die Schrift von den Symbollinien:
   Kurztext direkt auf einer Linie haette sonst 4.1:1 statt 5.05:1. Auf freiem
   Grund ist er unsichtbar. */
.svc__front > :not(.svc__symbol) { position: relative;
  text-shadow: 0 0 2px var(--concrete), 0 0 3px var(--concrete), 0 0 4px var(--concrete); }
.svc__k { font-size: .95rem; color: var(--meta); }
.svc__back .svc__t { font-size: .78rem; letter-spacing: .12em; text-transform: uppercase;
                     color: var(--on-ink-meta); font-weight: 600; }
.svc__d { font-size: .95rem; color: #E9E4D9; }
.svc__mark { color: var(--meta); }
.svc__back .svc__mark { color: var(--on-ink-meta); }
.svc:hover .svc__inner,
.svc:focus-visible .svc__inner,
.svc.is-pinned .svc__inner { transform: rotateY(180deg); }
@media (prefers-reduced-motion: reduce) { .svc__inner { transition: none; } }
/* Unter 1000 px (Handy und Tablet hochkant): vorne alle Karten gleich hoch,
   die Rueckseite waechst erst beim Wenden (Kundenwunsch). Ungewendet liegt
   sie ausserhalb des Flusses, die Hoehe kommt nur von vorne; --svc-vorne
   setzt main.js auf die hoechste Vorderseite. Das Symbol steht im Fluss
   zwischen Kurztext und Hinweis und kann den Text so nie beruehren. */
@media (max-width: 999.98px) {
  .svc__inner { position: relative; min-height: var(--svc-vorne, 12.5rem); }
  .svc__back { position: absolute; inset: 0; overflow: hidden; }
  .svc:hover .svc__back,
  .svc:focus-visible .svc__back,
  .svc.is-pinned .svc__back { position: static; overflow: visible; }
  /* Das Symbol bekommt in jeder Karte denselben Platz: eine feste Box, unten
     ueber dem Hinweis verankert — so stehen alle Symbole gleich gross auf
     gleicher Hoehe, egal wie lang der Text darueber ist. */
  .svc__symbol { position: static; inset: auto; order: 1; margin-top: auto; margin-bottom: 0;
    height: 8rem; box-sizing: content-box; padding-block: .75rem 1rem; }
  .svc__symbol svg { width: auto; height: 100%; max-width: 100%; }
  .svc__front .svc__mark { order: 2; margin-top: 0; }
  /* Dreierreihe (Karten 3–5): der Innenraum ist 187–250 px breit, ein
     Titelwort wie «Immobilienbewirtschaftung» 217 px. Ungetrennt dehnt es
     die Karte von innen auf — der Titel laeuft bis an die Kante, das Symbol
     rueckt aus der Mitte. Trennen duerfen nur Woerter ab 16 Zeichen, kurze
     Titelwoerter bleiben ganz; overflow-wrap faengt den Browser ohne
     Trennwoerterbuch. */
  .svcgrid[data-count="7"] .svc:nth-child(n+3):nth-child(-n+5) .svc__t {
    hyphens: auto; hyphenate-limit-chars: 16 6 6; overflow-wrap: anywhere; }
}

/* ==========================================================================
   Referenz-Dossiers (dunkle Platte)
   ========================================================================== */
.plate { background: var(--ink); color: var(--on-ink); }
.plate .rule { border-top-color: var(--hair-ink); }
.plate .meta { color: var(--on-ink-meta); }
.refs__head { display:flex; justify-content: space-between; align-items:baseline; gap:2rem; flex-wrap:wrap;
  margin-bottom: clamp(2rem,4vw,3.5rem); }
.refs__title { font-size: clamp(1.8rem,4vw,3rem); }
.refs { display: grid; gap: clamp(1.5rem,3vw,2.5rem); grid-template-columns: 1fr; }
@media (min-width: 720px){ .refs { grid-template-columns: 1fr 1fr; } }
.ref { position: relative; display: block; }
.ref--wide { grid-column: 1 / -1; }
.ref__img { aspect-ratio: 16 / 10; overflow: hidden; background: var(--ink-2); border: var(--rule) solid var(--hair-ink); }
.ref--wide .ref__img { aspect-ratio: 21 / 9; }
.ref__img img { width:100%; height:100%; object-fit: cover; transition: transform .8s var(--ease); filter: saturate(.92); }
.ref:hover .ref__img img { transform: scale(1.04); }
.ref__cap { display:flex; justify-content: space-between; align-items:baseline; gap:1rem;
  padding-top: .9rem; border-top: var(--rule) solid var(--hair-ink); margin-top: .9rem; }
.ref__no { color: var(--on-ink-meta); font-weight:600; }
.ref__name { font-size: clamp(1.15rem,2vw,1.5rem); font-weight: 700; letter-spacing:-0.03em; }
.ref__role { color: var(--on-ink-meta); font-size:.9rem; margin-top:.2rem; }

/* ---- Projekte als Vollbild-Stapel (Startseite) --------------------------
   Jedes Dossier klebt unter dem Menue und fuellt den Rest bis zum unteren
   Rand, das naechste schiebt sich darueber; main.js laesst es einrasten.
   Ohne JS bleiben Stapel und Fotos. Der Film blendet erst auf, wenn ein
   Bild steht (.is-live, main.js). Eigener
   Namensraum: .dossier ist das Kartenfenster auf /referenzen. */
.stapel { background: var(--ink); color: var(--on-ink); }
.stapel .meta { color: var(--on-ink-meta); }
/* Oben nur der halbe Sektionsabstand: der schwarze Balken bleibt schlank. */
.stapel__kopf { padding-top: calc(var(--step) / 2); padding-bottom: clamp(1rem, 2vw, 1.5rem); }
.stapel__panel { position: sticky; top: var(--mast-ist, var(--mast));
  min-height: calc(100svh - var(--mast-ist, var(--mast))); overflow: hidden;
  display: flex; align-items: flex-end; background: var(--ink);
  box-shadow: 0 -1.5rem 3rem rgba(10,8,6,.35); }
.stapel__media, .stapel__media img, .stapel__media video {
  position: absolute; inset: 0; width: 100%; height: 100%; object-fit: cover; }
.stapel__media video { opacity: 0; transition: opacity .6s ease; }
.stapel__media video.is-live { opacity: 1; }
.stapel__media::after { content: ""; position: absolute; inset: 0;
  background: linear-gradient(180deg, rgba(10,8,6,.3) 0%, rgba(10,8,6,.12) 22%, rgba(10,8,6,.62) 48%, rgba(10,8,6,.9) 100%); }
.stapel__inhalt { position: relative; z-index: 2; width: 100%; padding-block: clamp(3rem, 8vw, 6rem); }
/* Die Nummer steht hoch im Panel, wo der Verlauf noch hell ist (Himmel):
   eigene dunkle Marke statt Verlass auf das Bild. */
.stapel__panel .stapel__nr { display: inline-block; margin-bottom: 1rem; padding: .4rem .7rem;
  background: rgba(10,8,6,.72); color: var(--on-ink); }
.stapel__nr .sep, .stapel__meta .sep { color: var(--red); }
.stapel__titel { font-size: clamp(2.6rem, 8.5vw, 7.5rem); line-height: .92; letter-spacing: -0.045em; max-width: 14ch; }
.stapel__panel .stapel__meta { margin-top: 1.1rem; color: var(--on-ink); }
.stapel__lede { margin-top: 1rem; max-width: 46ch; color: #E9E4D9; font-size: clamp(1rem, 1.4vw, 1.15rem); }
.stapel__inhalt .btn { margin-top: 1.8rem; }
@media (prefers-reduced-motion: reduce) { .stapel__media video { transition: none; } }
/* Sehr niedrige Fenster (Handy quer): kein Kleben — sonst kaeme der untere
   Teil eines Panels mit dem Knopf nie ins Bild. */
@media (max-height: 34rem) { .stapel__panel { position: relative; top: auto; } }
/* Dasselbe, wenn ein Panel mehr Inhalt hat als Platz unter dem Menue (main.js). */
.stapel--frei .stapel__panel { position: relative; top: auto; }
/* Rahmen und Registermarken des Heros auf jedem Panel. Das Panel beginnt an
   der Menuekante, die Rahmenkante liegt wie beim Hero knapp darunter. */
.stapel__rahmen { top: .5rem; }
/* Ohne Kopf (/projekte): die Seite beginnt mit dem ersten Film, der schon
   bei Scroll 0 in seiner Ruhelage unter dem Menue liegt. Die Ueberschrift
   bleibt fuer Screenreader. */
.stapel--ohne-kopf { padding-top: var(--mast-ist, var(--mast)); }
.stapel--ohne-kopf .stapel__kopf { position: absolute; width: 1px; height: 1px; padding: 0; margin: -1px;
  overflow: hidden; clip-path: inset(50%); white-space: nowrap; border: 0; }

/* ==========================================================================
   25-Jahre-Einlage
   ========================================================================== */
.anniv { display: grid; gap: clamp(2rem,4vw,3rem); grid-template-columns: 1fr; align-items: end; }
@media (min-width: 900px){ .anniv { grid-template-columns: auto 1fr; gap: clamp(3rem,6vw,6rem); } }
.anniv__figure { line-height: .8; }
.anniv__num { font-size: clamp(7rem, 22vw, 17rem); font-weight: 700; letter-spacing: -0.06em; color: var(--red); }
.anniv__unit { font-size: clamp(1rem,2vw,1.4rem); font-weight:600; color: var(--ink); letter-spacing: .02em; }
.anniv__text { max-width: 54ch; }
.anniv__text h2 { font-size: clamp(1.6rem,3vw,2.4rem); margin-bottom: 1rem; }
.anniv__text p { color: var(--ink); }
.anniv__line { margin-top: 1.5rem; display:flex; gap: 1.5rem; flex-wrap:wrap; }
.anniv__span { font-variant-numeric: tabular-nums; font-weight:700; }
.anniv__span .sep { color: var(--red); }

/* ==========================================================================
   Team-Teaser
   ========================================================================== */
.team__grid { display:flex; justify-content: space-between; align-items: end; gap: 2rem; flex-wrap: wrap; }
/* 24ch stammte von der frueheren vierteiligen Namensliste und zwang die
   kurze Fassung in zwei Zeilen. Die Namen selbst haengen im Markup an
   geschuetzten Leerzeichen, damit nie mitten im Namen getrennt wird. */
.team__names { font-size: clamp(1.4rem,2.6vw,2.1rem); font-weight:700; letter-spacing:-0.03em; max-width: 46ch; line-height:1.1; }
.team__names .sep { color: var(--red); font-weight: 400; }

/* ==========================================================================
   Kontakt / Antwortkarte
   ========================================================================== */
/* Home-Abschluss: assertiver Rot-Stempel at scale (Pop, aber geordnet) */
.reply { background: var(--red); color: var(--paper); }
.reply .reply__title, .reply .reply__lede { color: var(--paper); }
.reply .reply__title em { color: var(--ink); }
.reply .facts { border-top-color: rgba(244,241,234,.35); }
.reply .fact { border-bottom-color: rgba(244,241,234,.22); }
.reply .fact__k { color: var(--paper); }   /* deckend: 5.2:1 statt 3.2:1 auf Rot */
.reply .fact__val, .reply .fact__val a { color: var(--paper); }
/* Tinte auf Rot hat nur 3.1:1 — die Rueckmeldung im Hover ist der Strich. */
.reply .fact__val a:hover, .reply .fact__val a:focus-visible {
  color: var(--paper); text-decoration: underline; text-underline-offset: .2em; }   /* sonst greift .fact__val a:hover (Rot auf Rot) */
/* Der Fokusring in Rot waere auf Rot unsichtbar (1:1); Papier hat 5.2:1. */
.reply :focus-visible { outline-color: var(--paper); }
/* Der Pop-Unterstrich verschwindet auf dem roten Grund — auf der Flaeche
   zeichnet er in Tinte, wie der Stempel-Button eine Zeile weiter unten. */
.reply .ulink::after { background: var(--ink); }
.reply .btn--stamp { background: var(--ink); border-color: var(--ink); color: var(--paper); }
.reply .btn--stamp:hover { background: var(--steel); border-color: var(--steel); }
.reply__grid { display:grid; gap: clamp(2rem,4vw,3rem); grid-template-columns:1fr; }
@media (min-width: 860px){ .reply__grid { grid-template-columns: 1.2fr 1fr; align-items: start; } }
.reply__title { font-size: clamp(2rem,4.5vw,3.4rem); letter-spacing:-0.04em; }
.reply__title em { font-style: normal; color: var(--red); }
.reply__lede { margin-top: 1.2rem; max-width: 46ch; font-size: 1.1rem; color: var(--ink); }
.reply__actions { margin-top: 2rem; display:flex; gap: 1rem; flex-wrap: wrap; }
/* Die Zeilen teilen ein Raster (subgrid): die Beschriftungsspalte ist so breit
   wie die laengste Beschriftung der Liste (mindestens 12ch), alle Werte stehen
   buendig. «Postanschrift» und «Auftraggeberschaft» passen nicht in 12ch; bei
   wenig Platz geben die Werte nach (minmax(0, 1fr)), nicht die Beschriftung. */
.facts { display:grid; grid-template-columns: max-content minmax(0, 1fr); gap: 0; align-self: start; border-top: var(--rule) solid var(--hair); }
.fact { display:grid; grid-column: 1 / -1; grid-template-columns: subgrid; column-gap: 1rem; padding: .95rem 0; border-bottom: var(--rule) solid var(--hair); }
.fact__k { color: var(--meta); font-size:.8rem; letter-spacing:.1em; text-transform: uppercase; padding-top:.15rem; min-width: 12ch; }
/* Sehr schmal (320 px) bliebe neben «Auftraggeberschaft» kaum Platz fuer den
   Wert: dort steht die Beschriftung ueber dem Wert. */
@media (max-width: 359.98px) {
  .facts { grid-template-columns: minmax(0, 1fr); }
  .fact { row-gap: .3rem; }
}
.fact__val { font-weight:600; min-width: 0; overflow-wrap: break-word; hyphens: auto; }   /* lange Woerter (Arealtransformation) neben langer Beschriftung */
.fact__val a:hover { color: var(--red); }
.ph { color: var(--meta); font-style: italic; font-weight: 400; }

/* ==========================================================================
   Footer / Kolophon
   ========================================================================== */
.colophon { background: var(--ink); color: var(--on-ink); padding-block: clamp(3rem,6vw,5rem); }
.colophon__grid { display:grid; gap: 2rem; grid-template-columns: 1fr; }
@media (min-width: 760px){ .colophon__grid { grid-template-columns: 2fr 1fr 1fr; } }
.colophon .brand { color: var(--on-ink); }
.colophon a { color: var(--on-ink-meta); }
.colophon a:hover { color: var(--on-ink); }
.colophon__slogan { font-size: clamp(1.4rem,3vw,2.2rem); font-weight:700; letter-spacing:-0.03em; max-width: 20ch; }
.colophon__titel { line-height: 1.02; font-size:.75rem; letter-spacing:.14em; text-transform:uppercase; color: var(--on-ink-meta); margin-bottom: 1rem; font-weight:600;}
.colophon__col ul { list-style:none; padding:0; display:grid; gap:.6rem; }
/* Partnerlogos: einfarbig in der Linkfarbe, damit sie dem eigenen Logo und
   dem Rotakzent nicht die Schau stehlen. Ab 760px fuellen sie die sonst leere
   Flaeche links unter dem Slogan, unten buendig mit der Navigationsspalte —
   der Footer wird dadurch nicht hoeher. Masse fest (aus der viewBox), damit
   kein Browser die Breite eines Inline-SVG im Flex selbst herleiten muss. */
.colophon__logos { display:flex; flex-wrap: wrap; align-items:center; gap: 1.75rem; color: var(--on-ink-meta); }
/* Passen die vier Logos nicht auf eine Zeile (zusammen rund 26.3rem), stehen
   sie zu zweit: SVIT + SRO oben, OBT + M-Co darunter — statt eines einzelnen
   Logos auf der letzten Zeile. Gemessen an der eigenen Spalte, nicht am
   Fenster: der Footer ist ab 760px mehrspaltig und dort ebenfalls zu schmal. */
.colophon__partner { container-type: inline-size; }
@container (max-width: 26.5rem) {
  .colophon__logos { display: grid; grid-template-columns: auto auto; justify-content: start; }
}
.partner-logo { flex: none; display:block; }
.partner-logo--svit { height: 2.75rem; width: 3.89rem; }
.partner-logo--sro  { height: 3.6rem; width: 9.43rem; }
.partner-logo--obt  { height: 1.75rem; width: 3.88rem; }
.partner-logo--mco  { height: 2.04rem; width: 3.88rem; }
@media (min-width: 760px){
  .colophon__col { grid-row: 1 / span 2; }
  .colophon__partner { grid-column: 1; grid-row: 2; align-self: end; }
}
.colophon__bottom { margin-top: clamp(2.5rem,5vw,4rem); padding-top: 1.5rem; border-top: var(--rule) solid var(--hair-ink);
  display:flex; justify-content: space-between; gap:1rem; flex-wrap:wrap; color: var(--on-ink-meta); font-size:.85rem; }

/* ==========================================================================
   Reveal-Motion (ein orchestrierter Moment, exponential ease-out)
   ========================================================================== */
/* Ausgeblendet wird nur, wenn JavaScript laeuft (kopf.js setzt html.js) —
   ohne JS bleibt jeder Block sichtbar, statt auf ein .in zu warten, das
   nie kommt. */
.js .reveal { opacity: 0; transform: translateY(18px); transition: opacity .8s var(--ease), transform .8s var(--ease); }
.js .reveal.in { opacity: 1; transform: none; }
.js .reveal-rule { transform: scaleX(0); transform-origin: left; transition: transform .9s var(--ease); }
.js .reveal-rule.in { transform: scaleX(1); }
[data-delay="1"]{ transition-delay:.06s; } [data-delay="2"]{ transition-delay:.12s; }
[data-delay="3"]{ transition-delay:.18s; } [data-delay="4"]{ transition-delay:.24s; }

@media (prefers-reduced-motion: reduce) {
  .reveal, .reveal-rule { opacity: 1 !important; transform: none !important; transition: none !important; }
}

/* ==========================================================================
   Unterseiten (Referenz-Detail, Angebote, Objekt-Detail)
   ========================================================================== */

/* Seiten-Hero (kleiner als Home-Deckel) */
.subhero { position: relative; background: var(--ink); color: var(--on-ink); overflow: hidden;
  padding-top: 5.5rem; }
.subhero__media { position:absolute; inset:0; }
.subhero__media img, .subhero__media video { position:absolute; inset:0; width:100%; height:100%; object-fit: cover; filter: saturate(.9); }
.subhero__media::after { content:""; position:absolute; inset:0;
  background: linear-gradient(180deg, rgba(10,8,6,.5), rgba(10,8,6,.78)); }
.subhero__frame { position:absolute; inset: clamp(.9rem,2.4vw,2rem); top: var(--rahmen-oben);
  border:var(--rule) solid rgba(244,241,234,.4); pointer-events:none; z-index:2; }
.subhero__inner { position:relative; z-index:3; max-width: var(--maxw); margin-inline:auto;
  padding: clamp(3rem,7vw,6rem) calc(var(--gutter) + clamp(.9rem,2.4vw,2rem)); }
.subhero__meta { display:flex; gap:1.4rem; flex-wrap:wrap; color: var(--on-ink-meta); margin-bottom: 1.4rem; }
/* Textseiten ohne Bild (Angebote, Kontakt, Impressum …): weniger Kopfhoehe,
   aber genug Abstand unter der fixierten Kopfleiste. */
.subhero--kompakt .subhero__inner { padding-top: clamp(6rem,10vw,8rem); }
/* Meta-Zeile unter dem Zurueck-Link */
.subhero__meta--abgesetzt { margin-top: 1.4rem; }
.subhero__title { font-size: clamp(2.2rem,6vw,4.5rem); line-height:.98; letter-spacing:-0.04em; max-width: 18ch; }
.subhero__sub { margin-top: 1rem; color:#E9E4D9; max-width: 52ch; font-size: clamp(1.05rem,1.5vw,1.2rem); }

/* Zurück-/Crumb-Link */
.crumb { display:inline-flex; gap:.5em; align-items:center; font-weight:600; font-size:.9rem; color: var(--on-ink-meta); }
.crumb:hover { color: var(--on-ink); }
.crumb--ink { color: var(--meta); } .crumb--ink:hover { color: var(--ink); }

/* Prosa-Block */
.prose { max-width: 65ch; }
.prose p + p { margin-top: 1.1rem; }
.prose h2 { font-size: clamp(1.5rem,2.6vw,2rem); margin: 2.2rem 0 1rem; }
.prose h2:first-child { margin-top: 0; }
.prose ul { list-style: none; padding: 0; margin-top: 1.1rem; display: grid; gap: .55rem; }
.prose ul > li { position: relative; padding-left: 1.5em; }
.prose ul > li::before { content: ""; position: absolute; left: 0; top: .7em; width: .8em; height: 2px; background: var(--red); }

/* Zweispaltig: Inhalt + Eckdaten-Sidebar */
.detail { display:grid; gap: clamp(2rem,5vw,4rem); grid-template-columns: 1fr; }
@media (min-width: 940px){ .detail { grid-template-columns: 1.5fr 1fr; align-items: start; } }
.detail__aside { align-self: start; }
@media (min-width: 940px){ .detail__aside { position: sticky; top: 6rem; } }
.aside__title { font-size:.78rem; letter-spacing:.14em; text-transform:uppercase; color:var(--meta); margin-bottom: .8rem; font-weight:600; }

/* Galerie */
.gallery { display:grid; gap: clamp(.5rem,1.2vw,1rem); grid-template-columns: repeat(2, 1fr); }
@media (min-width: 720px){ .gallery { grid-template-columns: repeat(3, 1fr); } }
.gallery figure { margin:0; overflow:hidden; background: var(--paper-2); border: var(--rule) solid var(--hair); aspect-ratio: 4/3; }
.gallery img { width:100%; height:100%; object-fit: cover; transition: transform .7s var(--ease); }
.gallery figure:hover img { transform: scale(1.05); }

/* ---- Dossier-Seite (Top-Projekte) ---------------------------------------
   Vollbild-Kopf mit Film, Leitsatz auf Tinte, Bildteil (unten), Drohnenfilm
   als Finale, Teaser auf das naechste Dossier. Randlos heisst width:100% ausserhalb von .wrap, nie
   100vw: mit klassischen Scrollbalken schiebt 100vw die Seite seitlich. */
.subhero--voll { min-height: 100svh; display: flex; flex-direction: column; justify-content: flex-end; }
.subhero--voll .subhero__inner { width: 100%; padding-bottom: clamp(4.5rem, 9vw, 7rem); }
.subhero--voll .subhero__media::after {
  background: linear-gradient(180deg, rgba(10,8,6,.45) 0%, rgba(10,8,6,.15) 22%, rgba(10,8,6,.62) 45%, rgba(10,8,6,.9) 100%); }
.subhero--voll .subhero__meta, .subhero--voll .crumb { color: var(--on-ink); }
.subhero--voll .subhero__title { font-size: clamp(2.8rem, 9vw, 8rem); line-height: .92; letter-spacing: -0.045em; max-width: 14ch; }
.subhero__mandat { margin-top: 1.4rem; color: var(--on-ink); }
/* Meta-Werte wie «Seit 2016 – heute» brechen als Ganzes um, nie in sich. */
.am-stueck { display: inline-block; }
@media (max-width: 760px) { .subhero--voll .hero__scroll { display: none; } }
.subhero__media video { opacity: 0; transition: opacity .6s ease; }
.subhero__media video.is-live { opacity: 1; }
@media (prefers-reduced-motion: reduce) { .subhero__media video { transition: none; } }

.leitsatz__text { font-size: clamp(1.6rem, 3.6vw, 3rem); line-height: 1.14; letter-spacing: -0.025em;
  font-weight: 600; max-width: 30ch; }

/* ---- Bildteil der Dossiers ----------------------------------------------
   Gemeinsamer Rahmen: Kapitelkopf mit roter Haarlinie, Tafeln mit Nummer und
   Bildbeschreibung. Alle Dossiers als Filmstreifen (icInszenierung). Bewegung
   nur unter .bildteil--bewegt (bildteil.js: breit, ohne reduzierte Bewegung);
   ohne die Klasse — auch ohne JS — steht alles ruhig da. Auf Tinte steht die
   Tafelnummer in --pop-hell (--red erreicht dort nur 3.15:1). */
.bildteil { position: relative; }
.bildteil__kopf { display: grid; gap: .55rem; max-width: 26rem; padding-top: 1.1rem;
  border-top: var(--rule) solid var(--red); margin-bottom: clamp(2rem, 4vw, 3.5rem); }
.bildteil__titel { font-size: clamp(2rem, 4.6vw, 3.6rem); font-weight: 700; line-height: .95; letter-spacing: -0.04em; }
.bildteil__meta { color: var(--meta); }
.tafel { margin: 0; }
.tafel__bild { overflow: hidden; background: var(--ink); }
.tafel__bild img { display: block; width: 100%; height: 100%; object-fit: cover; }
.tafel__unter { display: grid; gap: .2rem; padding-top: .7rem; font-size: .92rem; line-height: 1.35; }
.tafel__nr { font-size: .68rem; font-weight: 600; letter-spacing: .14em; text-transform: uppercase; color: var(--red); }
.tafel__ort { font-size: .68rem; letter-spacing: .14em; text-transform: uppercase; color: var(--meta); }
.bildteil--filmstreifen { background: var(--ink); color: var(--on-ink); }
.bildteil--filmstreifen .bildteil__meta { color: var(--on-ink-meta); }
.bildteil--filmstreifen .tafel__nr { color: var(--pop-hell); }
.bildteil__fortschritt { display: none; }
/* Bilder folgen noch: ruhige Flaeche statt eines fremden Bildes. Im Vollbild
   steht der Hinweis oben rechts, frei vom Text unten; ueber dem Verlauf. */
.bildplatzhalter { position: absolute; inset: 0; display: flex; justify-content: flex-end; align-items: flex-start;
  padding: calc(var(--rahmen-oben, 5rem) + 1.5rem) clamp(2rem, 5vw, 4rem) 0; background: var(--ink-2); }
.bildplatzhalter__text { position: relative; z-index: 1; color: var(--on-ink); }
.bildteil--leer { padding-block: clamp(3rem, 7vw, 6rem); }
.bildteil__platz { position: relative; width: 100%; aspect-ratio: 21 / 9; min-height: 13rem; overflow: hidden; }
.bildteil__platz .bildplatzhalter { justify-content: center; align-items: center; padding: 0; }

/* Filmstreifen (alle Dossiers): ruhig eine Wischleiste, bewegt faehrt die Spur
   quer, waehrend die Buehne unter dem Menue steht (Hoehe: bildteil.js). */
.bildteil--filmstreifen { padding-block: var(--step); }
.filmstreifen__fenster { overflow-x: auto; overscroll-behavior-x: contain; scroll-snap-type: x mandatory;
  scroll-padding-inline: var(--gutter); scrollbar-width: thin; scrollbar-color: var(--hair-ink) transparent; }
.filmstreifen__fenster:focus-visible { outline: 2px solid var(--on-ink); outline-offset: -2px; }
.filmstreifen__spur { display: flex; align-items: flex-start; gap: clamp(.75rem, 1.6vw, 1.5rem);
  width: max-content; padding-inline: var(--gutter); padding-bottom: 1rem; }
.filmstreifen__kopf { flex: 0 0 auto; width: min(20rem, 70vw); margin: 0; scroll-snap-align: start; }
.bildteil--filmstreifen .tafel { --h: min(56svh, calc(82vw / var(--ar))); flex: 0 0 auto;
  width: calc(var(--h) * var(--ar)); scroll-snap-align: start; }
.bildteil--filmstreifen .tafel__bild { height: var(--h); }
.bildteil--filmstreifen .tafel__bild img { object-position: var(--fpos, 50% 50%); }
.bildteil--bewegt.bildteil--filmstreifen { padding-block: 0; }
.bildteil--bewegt .filmstreifen__buehne { position: sticky; top: var(--mast-ist, var(--mast));
  height: calc(100svh - var(--mast-ist, var(--mast))); display: flex; flex-direction: column; justify-content: center; overflow: hidden; }
.bildteil--bewegt .filmstreifen__fenster { overflow: clip; scroll-snap-type: none; }
.bildteil--bewegt .filmstreifen__spur { padding-bottom: 0; will-change: transform; }
.bildteil--bewegt.bildteil--filmstreifen .tafel { --h: calc((100svh - var(--mast-ist, var(--mast))) * .64); }
@media (max-width: 859.98px) {
  /* Handy: hohe Ausschnitte statt kleiner Querformate, damit die Bühne voll wirkt */
  .bildteil--bewegt.bildteil--filmstreifen .tafel { --h: calc((100svh - var(--mast-ist, var(--mast))) * .58); width: 84vw; }
}
/* Die Bilder driften im eigenen Rahmen leicht gegen die Fahrt: Tiefe. Mit
   Fokuspunkt (--fpos, --drift: 0 aus tafel.php) sitzt die Vergroesserung am
   Fokus und das Bild steht, damit der Fokus im Rahmen bleibt. */
.bildteil--bewegt.bildteil--filmstreifen .tafel__bild img { transform-origin: var(--fpos, 50% 50%);
  transform: scale(1.12) translateX(calc((var(--p, 0) - .5) * -7% * var(--drift, 1))); }
.bildteil--bewegt .bildteil__fortschritt { display: block; position: absolute; left: var(--gutter); right: var(--gutter);
  bottom: clamp(1.2rem, 3svh, 2rem); height: 1px; background: var(--hair-ink); }
.bildteil--bewegt .bildteil__fortschritt span { display: block; height: 100%; background: var(--red);
  transform-origin: left; transform: scaleX(var(--p, 0)); }

/* Sanfter Zug ins Luftbild hinter dem Drohnenfilm. Ohne scroll-getriebene
   Animation steht das Bild einfach still — sichtbar ist es in jedem Fall. */
@supports (animation-timeline: view()) {
  @media (prefers-reduced-motion: no-preference) {
    .flug__media img { animation: flug-zoom linear both; animation-timeline: view(); animation-range: entry 0% cover 50%; }
  }
}
@keyframes flug-zoom { from { transform: scale(1.12); } to { transform: scale(1); } }

.flug { position: relative; height: 100svh; min-height: 24rem; overflow: hidden; background: var(--ink); }
.flug__media, .flug__media img, .flug__media video {
  position: absolute; inset: 0; width: 100%; height: 100%; object-fit: cover; }
.flug__media video { opacity: 0; transition: opacity .6s ease; }
.flug__media video.is-live { opacity: 1; }
.flug__label { position: absolute; left: var(--gutter); bottom: 1.6rem; z-index: 2;
  background: rgba(10,8,6,.72); color: var(--on-ink); padding: .45rem .75rem; }

.weiter { position: relative; display: flex; align-items: flex-end; min-height: 70svh; overflow: hidden;
  background: var(--ink); color: var(--on-ink); }
.weiter__media, .weiter__media img { position: absolute; inset: 0; width: 100%; height: 100%; object-fit: cover; }
.weiter__media img { transition: transform .9s var(--ease); }
.weiter__media::after { content: ""; position: absolute; inset: 0;
  background: linear-gradient(180deg, rgba(10,8,6,.25) 0%, rgba(10,8,6,.55) 55%, rgba(10,8,6,.88) 100%); }
.weiter__inhalt { position: relative; z-index: 2; width: 100%; display: grid; gap: .8rem;
  padding-block: clamp(3rem, 7vw, 5rem); }
.weiter__meta { color: var(--on-ink-meta); }
.weiter__titel { font-size: clamp(2.2rem, 7vw, 6rem); font-weight: 700; line-height: .95; letter-spacing: -0.04em; }
.weiter__pfeil { display: inline-block; color: var(--on-ink-meta); transition: transform .4s var(--ease), color .4s; }
.weiter:hover .weiter__media img { transform: scale(1.04); }
.weiter:hover .weiter__pfeil, .weiter:focus-visible .weiter__pfeil { transform: translateX(.2em); color: var(--on-ink); }

/* Pager (nächste Referenz/Objekt) */
.pager { display:flex; justify-content: space-between; gap:1rem; border-top: var(--rule) solid var(--hair); padding-top: 1.5rem; }
.pager a { font-weight:600; }
.pager a:hover { color: var(--red); }

/* ---- Angebote: Übersicht ---- */
.objgrid { display:grid; gap: clamp(1.5rem,3vw,2.5rem); grid-template-columns: 1fr; }
@media (min-width: 640px){ .objgrid { grid-template-columns: 1fr 1fr; } }
@media (min-width: 1000px){ .objgrid { grid-template-columns: 1fr 1fr 1fr; } }
.objcard { display:block; border-top: var(--rule) solid var(--ink); padding-top: .9rem; }
.objcard__img { aspect-ratio: 4/3; overflow:hidden; background: var(--paper-2); border: var(--rule) solid var(--hair); position: relative; }
.objcard__img img { width:100%; height:100%; object-fit: cover; transition: transform .7s var(--ease); }
.objcard:hover .objcard__img img { transform: scale(1.04); }
.objcard__head { display:flex; justify-content: space-between; align-items:baseline; gap:1rem; margin-top: .9rem; }
.objcard__name { font-size: 1.35rem; font-weight:700; letter-spacing:-0.03em; }
.objcard__loc { color: var(--meta); font-size:.9rem; margin-top:.15rem; }
.objcard__meta { margin-top:.7rem; padding-top:.7rem;
  border-top: var(--rule) solid var(--hair); font-variant-numeric: tabular-nums; font-size:.9rem; color: var(--ink); }
.objcard__meta b { font-weight:700; } .objcard__meta span { color: var(--meta); }
.objcard__price { display:block; margin-top:.5rem; font-weight:700; font-size:1.1rem; font-variant-numeric: tabular-nums; }

/* Status-Badge */
.badge { display:inline-flex; align-items:center; gap:.4em; font-size:.68rem; font-weight:700;
  letter-spacing:.08em; text-transform:uppercase; padding:.3em .6em; border:var(--rule) solid currentColor; }
.badge::before { content:""; width:.5em; height:.5em; border-radius:50%; background: currentColor; }
.badge--frei { color: #1F7A46; } .badge--res { color: #8F5E10; }   /* 4.9:1 auf Papier (war #B4791A, 3.3:1) */ .badge--verkauft { color: var(--meta); }
.badge--muster { color: var(--red); }

/* Muster-Hinweis (Platzhalterobjekte) */
.notice { background: var(--ink); color: var(--on-ink); padding: .9rem var(--gutter); text-align:center;
  font-size:.85rem; letter-spacing:.02em; }
.notice b { color: #E9E4D9; }
a.notice:hover { background: var(--steel); }

/* Objekt-Detail: Eckdaten-Panel Preis */
.price-line { display:flex; align-items:baseline; gap:.6rem; margin: 1.2rem 0; }
.price-line .amount { font-size: clamp(1.8rem,3.5vw,2.6rem); font-weight:700; letter-spacing:-0.03em; font-variant-numeric: tabular-nums; }
.price-line .on-req { color: var(--meta); font-style: italic; }

/* Ansprechperson */
.agent { display:flex; gap:1rem; align-items:center; border-top: var(--rule) solid var(--hair); padding-top: 1.2rem; margin-top: 1.2rem; }
.agent__av { width:44px; height:44px; border-radius:50%; background: var(--red); color: var(--paper);
  display:grid; place-items:center; font-weight:700; flex:0 0 auto; }
.agent__name { font-weight:700; } .agent__role { color: var(--meta); font-size:.85rem; }

/* Doc-Download */
.docrow { display:flex; justify-content: space-between; align-items:center; gap:1rem;
  border:var(--rule) solid var(--ink); padding: 1rem 1.2rem; margin-top: 1rem; font-weight:600; }
.docrow:hover { background: var(--ink); color: var(--paper); }
/* Die Meta-Zeile darf auf Tinte nicht grau bleiben (2.5:1). */
.docrow:hover .meta, .docrow:focus-visible .meta { color: var(--on-ink-meta); }

/* ---- Jubiläums-Timeline ---- */
/* ---- Chronik ----
   Zwei Spalten: links eine Marke, die beim Scrollen stehen bleibt und das Jahr
   wechselt, rechts die Stationen als Editorial-Liste. Gescrollt wird die Seite
   selbst — kein eigener Scrollbereich, in dem der Besucher haengen bleibt. */
.chronik { display: grid; grid-template-columns: 1fr; gap: clamp(1.5rem,4vw,3rem);
  border-top: var(--rule) solid var(--ink); padding-top: clamp(1.5rem,3vw,2.5rem); }
@media (min-width: 860px) {
  .chronik { grid-template-columns: minmax(11rem, 30%) 1fr; gap: clamp(2rem,4vw,4rem); }
}

/* --- Die stehende Marke --- */
.chronik__marke { position: sticky; z-index: 2;
  top: calc(var(--mast) + clamp(1rem,3vw,2.5rem));
  align-self: start;
  /* Keine feste Hoehe: als 100vh hoher Block haengt die Marke beim Hineinscrollen
     mit ihrem unteren Ende in den Abschnitt, bevor sie klebt. Sie ist jetzt genau
     so hoch wie ihr Inhalt, und die Zahl bekommt ihr Mass vom Skript. */
  display: grid; gap: .8rem;
  /* Damit die Liste beim Vorbeiziehen nicht durch die Marke schimmert. */
  background: var(--paper); padding-bottom: .6rem; }

/* Das Jahr steht hochkant und laeuft ueber die Hoehe des Lesefensters, von unten
   nach oben gelesen. Die Groesse setzt das Skript, weil sie an der Fensterhoehe
   haengt, die CSS hier nicht in eine Schriftgroesse umrechnen kann. */
.chronik__jahr { writing-mode: vertical-rl; transform: rotate(180deg);
  justify-self: start; min-height: 0; overflow: hidden;
  font-weight: 700; letter-spacing: -0.05em; line-height: 1;
  font-variant-numeric: tabular-nums; }
/* Beim Wechsel steht das neue Jahr sofort da und blendet nur kurz auf (main.js
   startet die Animation je Wechsel neu). Kein Versatz: er wuerde gegen die
   Drehung arbeiten. */
.chronik__jahr.wechselt { animation: chronik-ein .16s var(--ease); }
@keyframes chronik-ein { from { opacity: .35; } }

.chronik__zaehler { font-variant-numeric: tabular-nums; }

/* Die Schiene zeigt, wie weit man in 25 Jahren ist. */
.chronik__schiene { display: block; height: var(--rule); background: var(--hair); position: relative; }
.chronik__fortschritt { position: absolute; inset: 0 auto 0 0; width: 0; background: var(--red);
  transition: width .45s var(--ease); }

/* --- Die Stationen --- */
.chronik__liste { list-style: none; margin: 0; padding: 0; }
/* Alle Eintraege tragen denselben seitlichen Einzug, damit der Text nicht
   springt, wenn die Kachel der aktuellen Station erscheint. */
.chronik__eintrag { --pad: clamp(1.1rem,2.4vw,1.8rem);
  display: grid; grid-template-columns: 1fr; gap: .3rem;
  padding: var(--pad) clamp(.9rem, 2vw, 1.25rem); border-top: var(--rule) solid var(--hair);
  transition: background-color .3s var(--ease), box-shadow .3s var(--ease); }
.chronik__eintrag:first-child { border-top: 0; }
/* Die aktuelle Station liegt als weisse Kachel auf dem Papier; die Linien
   ober- und unterhalb treten zurueck. Die uebrigen Texte gehen in die
   Meta-Farbe (6.56:1, bleiben lesbar), die Jahreszahl wird rot (5.88:1 auf
   Weiss). Ohne JavaScript gibt es keine aktive Station — alles bleibt gleich. */
.chronik__eintrag.ist-aktiv { background: #fff; border-top-color: transparent;
  box-shadow: 0 10px 30px -12px rgba(22,19,15,.35); }
.chronik__eintrag.ist-aktiv + .chronik__eintrag { border-top-color: transparent; }
.js .chronik__eintrag:not(.ist-aktiv) .chronik__text { color: var(--meta); }
@media (prefers-reduced-motion: reduce) {
  .chronik__eintrag, .chronik__text { transition: none; }
}
@media (min-width: 620px) {
  .chronik__eintrag { grid-template-columns: 11rem 1fr; gap: clamp(1rem,2.5vw,2rem); align-items: baseline; }
}

.chronik__wann { font-size: .84rem; letter-spacing: .08em; text-transform: uppercase;
  font-weight: 600; color: var(--meta); white-space: nowrap;
  transition: color .25s var(--ease); }
.chronik__wann-jahr { font-variant-numeric: tabular-nums; }
.chronik__eintrag.ist-aktiv .chronik__wann { color: var(--red); }

/* --- Geklebte Buehne (Desktop, main.js setzt .ist-geklebt) ---
   Titel und Chronik stehen still unter dem Menue, solange die Buehne
   durchscrollt; die Liste rueckt darin nach oben und verschwindet an der
   Linie unter dem Titel. Hoehe, top und Verschiebung setzt das Skript. */
.chronik-buehne.ist-geklebt .chronik-rahmen { position: sticky; display: flex; flex-direction: column;
  padding-top: 1.5rem; box-sizing: border-box; }
.chronik-buehne.ist-geklebt .chronik { flex: 1 1 auto; min-height: 0; overflow: hidden; }
.chronik-buehne.ist-geklebt .chronik__marke { position: static; }
.chronik-buehne.ist-geklebt .chronik__liste { transition: transform .15s linear; }
/* Fenster (Desktop ab 1024, main.js setzt .ist-fenster): so hoch wie die
   Jahreszahl-Spalte links. Die aktive Station steht oben darin, die folgenden
   darunter; nichts ragt unter die Jahreszahl, und was frueher war, rollt beim
   Scrollen oben an der Linie hinaus. Die Hoehe setzt das Skript. */
.chronik-buehne.ist-fenster .chronik__fenster { overflow: hidden; transition: height .15s linear; }
.chronik-buehne.ist-fenster .chronik__eintrag { border-top-color: transparent; }
@media (prefers-reduced-motion: reduce) {
  .chronik-buehne.ist-geklebt .chronik__liste, .chronik-buehne.ist-fenster .chronik__fenster { transition: none; }
}

.chronik__text { margin: 0; max-width: 62ch; font-size: clamp(1.02rem,1.3vw,1.15rem); line-height: 1.5;
  transition: color .25s var(--ease); }
.chronik__mehr { display: block; margin-top: .35rem; font-size: .92rem; color: var(--meta); }

@media (max-width: 859px) {
  /* Auf schmalen Geraeten legt sich die Marke als schmale Zeile ueber die Liste. */
  .chronik__marke { grid-template-columns: auto 1fr; align-items: center; gap: .8rem 1rem;
    top: var(--mast-ist, var(--mast)); padding: .6rem 0; }
  /* Auf dem Telefon liegt das Jahr wieder flach — hochkant gibt es dort keine Hoehe. */
  .chronik__jahr { writing-mode: horizontal-tb; transform: none; overflow: visible;
    font-size: clamp(1.5rem,6vw,2rem) !important; }
  .chronik__zaehler { justify-self: end; }
  .chronik__schiene { grid-column: 1 / -1; }
}

/* ---- Team-Grid ---- */
.team-grid { display:grid; gap: clamp(1.2rem,2.5vw,2rem); grid-template-columns: 1fr; }
@media (min-width: 560px){ .team-grid { grid-template-columns: 1fr 1fr; } }
@media (min-width: 900px){ .team-grid { grid-template-columns: 1fr 1fr 1fr; } }
.member { border-top: var(--rule) solid var(--ink); padding-top: 1rem; }
.member__mono { width:100%; aspect-ratio: 4/5; background: var(--paper-2); border: var(--rule) solid var(--hair);
  display:grid; place-items:center; overflow:hidden; }
.member__mono span { font-size: clamp(2.5rem,7vw,4rem); font-weight:700; color: var(--hair-2); letter-spacing:-0.04em; }
.member__mono { position: relative; }

/* Das Monogramm liegt immer im Rahmen; das Foto materialisiert sich darueber,
   sobald es wirklich geladen ist. So ist das Kuerzel zugleich Platzhalter —
   und Karten mit und ohne Foto sind dieselbe Sorte, nicht zwei.

   Die vier Stellschrauben stehen als Variablen, damit jeder Zustand nur die
   aendert, die er meint — die Filterkette bleibt in Reihenfolge und Laenge
   gleich und laesst sich deshalb sauber ueberblenden. */
.member__mono img {
  --sw: 1;          /* Entsaettigung: haelt gemischtes Material zusammen */
  --licht: .92;     /* im Ruhezustand leicht zurueckgenommen */
  --kontrast: 1.02;
  --weich: 14px;
  --zoom: 1.06;
  position: absolute; inset: 0; width: 100%; height: 100%; object-fit: cover;
  opacity: 0;
  transform: scale(var(--zoom));
  /* Haelt das Bild dauerhaft auf einer eigenen Compositor-Ebene. Sonst wird die
     Ebene am Ende des Uebergangs aufgeloest und das Bild auf ganze
     Geraetepixel gerundet neu gezeichnet — ein Sprung um einen halben Pixel,
     weil die Rasterspalten auf krummen Breiten sitzen (351.594 px). */
  will-change: transform, filter;
  filter: grayscale(var(--sw)) brightness(var(--licht)) contrast(var(--kontrast)) blur(var(--weich));
}

/* Uebergaenge erst im Zielzustand — sonst blendet das Bild beim Laden sichtbar aus. */
.member__mono img.ist-da { --weich: 0px; --zoom: 1; opacity: 1;
  transition: opacity .5s var(--ease), transform .6s var(--ease), filter .6s var(--ease); }

.member__name { font-size: 1.2rem; font-weight:700; letter-spacing:-0.02em; margin-top: .9rem; }
.member__role { color: var(--meta); font-size:.88rem; margin-top:.2rem; min-height: 2.4em; }
.member__contact { margin-top:.7rem; padding-top:.7rem; border-top: var(--rule) solid var(--hair);
  display:flex; flex-direction:column; gap:.25rem; font-variant-numeric: tabular-nums; font-size:.9rem; }
.member__contact a:hover { color: var(--red); }

/* Kontaktbogen: wer eine Person greift, laesst die anderen zuruecktreten.
   Kein Layoutwechsel, nur Licht. Die Bilder werden abgedunkelt statt
   ausgeblendet — Schwarz mal 0.5 bleibt Schwarz, waehrend Deckkraft das
   Schwarz zum Papier hin aufhellen und wie ein Fehler aussehen wuerde. */
@media (hover: hover) {
  .team-grid:hover .member__mono img.ist-da { --licht: .5; --kontrast: .98; }
  .team-grid:hover .member__mono span,
  .team-grid:hover .member__name,
  .team-grid:hover .member__role,
  .team-grid:hover .member__contact { opacity: .5; transition: opacity .3s var(--ease); }

  /* Die angefahrene Person tritt ins Licht — und zeigt Farbe, wenn welche da ist. */
  .team-grid .member:hover .member__mono img.ist-da,
  .team-grid .member:focus-within .member__mono img.ist-da {
    --sw: 0; --licht: 1.06; --kontrast: 1.04; --zoom: 1.03;
    transition-duration: .45s; }
  .team-grid .member:hover .member__mono span,
  .team-grid .member:hover .member__name,
  .team-grid .member:hover .member__role,
  .team-grid .member:hover .member__contact,
  .team-grid .member:focus-within .member__mono span,
  .team-grid .member:focus-within .member__name,
  .team-grid .member:focus-within .member__role,
  .team-grid .member:focus-within .member__contact { opacity: 1; }
}

/* Ohne Zeigegeraet gibt es kein Hover — dort steht das Bild gleich im vollen
   Licht. Die Entsaettigung bleibt: sie haelt gemischtes Material zusammen,
   und das ist auf dem Telefon so noetig wie am Schreibtisch. */
@media (hover: none) {
  .member__mono img.ist-da { --licht: 1; }
}

/* Reduzierte Bewegung behaelt Licht und Farbe, wirft Zoom und Unschaerfe weg. */
@media (prefers-reduced-motion: reduce) {
  .member__mono img { --weich: 0px; --zoom: 1; }
  .member__mono img.ist-da { transition: opacity .2s linear, filter .2s linear; }
  .team-grid .member:hover .member__mono img.ist-da,
  .team-grid .member:focus-within .member__mono img.ist-da { --zoom: 1; }
}

/* ---- Formular ---- */
.form { display:grid; gap: 1.1rem; }
.field { display:grid; gap:.4rem; }
.field label { font-size:.78rem; letter-spacing:.1em; text-transform:uppercase; color: var(--meta); font-weight:600; }
.field input, .field textarea {
  font: inherit; color: var(--ink); background: var(--paper); border: var(--rule) solid var(--meta);
  padding: .8em .9em; border-radius: 0; width: 100%;
  transition: border-color .2s var(--ease); }
/* Fokus deutlich: 2 px Tinte statt eines blossen Farbwechsels der Kante. */
.field input:focus, .field textarea:focus { outline: none; border-color: var(--ink); box-shadow: 0 0 0 1px var(--ink); }
.field textarea { resize: vertical; min-height: 8em; }
.field--row { display:grid; gap:1.1rem; grid-template-columns: 1fr; }
@media (min-width: 560px){ .field--row { grid-template-columns: 1fr 1fr; } }
.form__hp { position:absolute; left:-9999px; width:1px; height:1px; overflow:hidden; }
.form__submit { justify-self: start; }
.form__note { color: var(--meta); font-size:.85rem; }
.field__error { color: var(--red); font-size:.85rem; }
/* Pflichtfeld: Stern am Label (Panel entscheidet, ob Telefon dazugehoert) */
.field__pflicht { color: var(--red); font-weight: 700; letter-spacing: 0; }
.form__pflicht { margin-top: -.25rem; }
.field [aria-invalid="true"] { border-color: var(--red); }
.form__body { display:grid; gap:1.1rem; }
.form__ok { display:none; padding: 1rem 1.2rem; border: var(--rule) solid #1F7A46; color:#1F7A46; font-weight:600; }
.form.sent .form__ok { display:block; } .form.sent .form__body { display:none; }

/* ---- Kartenkasten (Kontakt) ----
   Das Gebaeude; beim Ueberfahren oder Fokus zoomt es weg und die Google-
   Maps-Ansicht darunter zoomt ein (man «fliegt hinein»). Der Klick oeffnet
   Google Maps; auf Touch-Geraeten direkt. */
.mapbox { position: relative; display: block; margin-top: 1.4rem; aspect-ratio: 4 / 3; overflow: hidden;
  border: var(--rule) solid var(--hair-2); background: var(--ink); }
.mapbox img { position: absolute; inset: 0; width: 100%; height: 100%; object-fit: cover;
  transition: transform .9s var(--ease), opacity .6s ease;
  /* Dauerhafte 3D-Ebene, auch in Ruhe und am Ende des Zooms: sonst rastet der
     Browser das Bild nach der Animation auf ganze Bildschirmpixel ein — je nach
     Skalierung und Grafikkarte springt es dann sichtbar zur Seite. */
  transform: translate3d(0, 0, 0); will-change: transform; backface-visibility: hidden; }
/* Ursprung am roten Pin der Google-Ansicht (Oberdorfstrasse 2): man fliegt genau darauf zu */
.mapbox__karte { object-position: 46% 50%; transform: translate3d(0, 0, 0) scale(1.25); transform-origin: 46% 32%; }
.mapbox:hover .mapbox__gebaeude, .mapbox:focus-visible .mapbox__gebaeude { transform: translate3d(0, 0, 0) scale(1.35); opacity: 0; }
.mapbox:hover .mapbox__karte, .mapbox:focus-visible .mapbox__karte { transform: translate3d(0, 0, 0) scale(1); }
.mapbox__marke { position: absolute; left: .75rem; bottom: .75rem; z-index: 2; padding: .4rem .65rem;
  background: rgba(10,8,6,.85); color: var(--on-ink); transition: color .3s; }
/* .85 statt .72: auch ueber einem weissen Bildteil bleibt --pop-hell bei 5.00:1 (bei .72 nur 3.06:1) */
.mapbox:hover .mapbox__marke, .mapbox:focus-visible .mapbox__marke { color: var(--pop-hell); }
@media (prefers-reduced-motion: reduce) {
  .mapbox img { transition: opacity .4s ease; }
  .mapbox__karte, .mapbox:hover .mapbox__gebaeude, .mapbox:focus-visible .mapbox__gebaeude { transform: translate3d(0, 0, 0); }
}

/* ---- Direktwahl-Liste (Kontakt) ---- */
.dial { border-top: var(--rule) solid var(--hair); }
.dial__row { display:flex; flex-wrap: wrap; justify-content: space-between; gap:.2rem 1rem; padding:.8rem 0;
  border-bottom: var(--rule) solid var(--hair); font-variant-numeric: tabular-nums; }
.dial__row b { font-weight:600; }
.dial__row a { white-space: nowrap; }   /* Nummer nie mitten drin umbrechen */
.dial__row a:hover { color: var(--red); }

/* ==========================================================================
   Karte: vom Relief in die Strassenkarte
   Grund sind OSM-Vektorkacheln in der Dossier-Palette; darueber liegt die
   Reliefschattierung von swisstopo, die beim Hineinzoomen ausblendet. Kein
   Umschalten, eine Ueberblendung.
   ========================================================================== */
.karte { position: relative; height: 100svh; min-height: 32rem; background: var(--paper); }
.karte__buehne { position: absolute; inset: 0; background: var(--paper); }
/* Papier-Vorhang ueber Leinwand und Markern, bis das Relief steht (ist-bereit,
   karte.js): kein aufblitzender Strassenplan, kein halbes Relief. Titel und
   Legende liegen ausserhalb der Buehne und stehen sofort. Die Blende liegt
   bewusst auf diesem Element, nicht auf der WebGL-Leinwand (Pixel-Rueckleser). */
.karte__vorhang { position: absolute; inset: 0; z-index: 3; background: var(--paper); pointer-events: none;
  transition: opacity .6s var(--ease), visibility 0s linear .6s; }
.karte__buehne.ist-bereit .karte__vorhang { opacity: 0; visibility: hidden; }

.karte .maplibregl-ctrl-attrib { background: rgba(244,241,234,.9); font-size: .68rem; }
/* Jeder Zoomknopf mit eigener Kante >= 3:1 — Weiss auf Papier allein hat 1.1:1. */
.karte .maplibregl-ctrl-group { border-radius: 0; border: 0; box-shadow: none; background: transparent; }
.karte .maplibregl-ctrl-group button { background-color: var(--paper); border: var(--rule) solid var(--meta); }
.karte .maplibregl-ctrl-group button + button { border-top: 0; }
/* Steuerung und Quellenangaben ueber Rahmen, Legende und Kopf — sonst
   verdecken sie den Fokus auf schmalen Schirmen (WCAG 2.4.11). */
.karte .maplibregl-ctrl-bottom-right, .karte .maplibregl-ctrl-bottom-left { z-index: 7; }
.karte .maplibregl-ctrl-group button { border-radius: 0; }
.karte .maplibregl-ctrl-bottom-right { margin-bottom: 3.2rem; }
/* Die Herkunftsangabe darf nicht unter dem Hinweis liegen. */
.karte .maplibregl-ctrl-bottom-left { margin-left: 0; }
.karte .maplibregl-ctrl-attrib.maplibregl-compact { margin: 0; }

/* Betreute Liegenschaft: erst ab mittlerem Zoom, dann ruhig im Hintergrund. */
/* Die betreuten Liegenschaften zeichnet MapLibre selbst als geclusterte
   Ebene — kein DOM-Marker mehr. Hier bleibt nur das Muster der Legende. */

/* Projekt: der rote Stempel, jederzeit sichtbar. */
/* Kein eigenes position hier! MapLibre setzt den Marker auf absolute und
   verschiebt ihn per transform. Seit das Fremd-CSS vor main.css geladen wird,
   gewinnt jede eigene position-Angabe — der Marker bliebe im Textfluss und
   truege einen Grundversatz mit sich, der beim Zoomen sichtbar wandert.
   Fuer das ::after genuegt MapLibres absolute als Bezug. */
/* Trefferflaeche 24 px (WCAG 2.5.8), gezeichnet wird unveraendert ein Ring
   von 18 px mit Punkt — der Rand bleibt durchsichtig. */
.karte__pj { width: 24px; height: 24px; border-radius: 50%;
  border: 0; background: radial-gradient(circle, var(--red) 0 4px, var(--paper) 4px 7px, var(--red) 7px 9px, transparent 9px);
  box-sizing: border-box; padding: 0; font: inherit; cursor: pointer; }
.karte__pj:focus-visible { outline: 2px solid var(--ink); outline-offset: 4px; }
.karte__pj:hover, .karte__pj:focus-visible { z-index: 2; }   /* das beruehrte Faehnchen ueber den Nachbarn */
.karte__blattname { display: block; font-weight: 700; font-size: 1rem;
  letter-spacing: -.02em; color: var(--ink); }

/* Nadel und Faehnchen (karte.js nadelnSetzen setzt --nadel-winkel, 0deg =
   senkrecht nach oben, und --nadel-laenge). Die Nadel waechst aus der
   Ringmitte; das Faehnchen steht an ihrer Spitze, aufrecht, und haengt je
   nach Seite nach aussen (--links / --rechts) oder mittig darueber. Ohne
   ist-nadel ist die Nadel 0 lang und das Faehnchen weg. */
.karte__nadel { position: absolute; left: 50%; bottom: 50%; width: 1.5px; height: 0; margin-left: -.75px;
  transform-origin: 50% 100%; transform: rotate(var(--nadel-winkel, 0deg)); background: var(--ink);
  pointer-events: none; transition: height .4s var(--ease); }
.karte__pj.ist-nadel .karte__nadel { height: var(--nadel-laenge, 0px); }
.karte__fahne { position: absolute; left: 50%; top: 50%; width: max-content; max-width: 14rem;
  transform: translate(-50%, -50%) rotate(var(--nadel-winkel, 0deg)) translateY(calc(-1 * var(--nadel-laenge, 0px)))
             rotate(calc(-1 * var(--nadel-winkel, 0deg))) var(--fahne-versatz, translateY(-50%));
  box-sizing: border-box; min-height: 24px; padding: .25rem .5rem; line-height: 1.2;
  font-size: .78rem; font-weight: 600; letter-spacing: .01em; text-align: left; white-space: nowrap;
  color: var(--ink); background: var(--paper); border: var(--rule) solid var(--ink);
  opacity: 0; pointer-events: none; transition: opacity .4s var(--ease), transform .4s var(--ease),
  border-color .2s var(--ease), color .2s var(--ease); }
.karte__pj.ist-nadel .karte__fahne { opacity: 1; pointer-events: auto; }
.karte__pj--links  { --fahne-versatz: translateX(-50%); }
.karte__pj--rechts { --fahne-versatz: translateX(50%); }
.karte__pj--mitte.karte__pj--unten { --fahne-versatz: translateY(50%); }   /* Faehnchen unter der Spitze */
.karte__pj:hover .karte__fahne, .karte__pj:focus-visible .karte__fahne { border-color: var(--red); color: var(--red); }
@media (max-width: 599.98px) { .karte__fahne { white-space: normal; max-width: 8rem; font-size: .72rem; } }

/* Standbild am Faehnchen — Hairline-Rahmen wie ein Dossier-Beleg, kein Schatten.
   Es haengt unter dem Faehnchen, an dessen Aussenkante ausgerichtet. */
.karte__blatt { position: absolute; left: 0; top: calc(100% + 6px); width: 232px; text-align: left;
  white-space: normal; font-weight: 400; letter-spacing: 0; color: var(--ink);
  border: var(--rule) solid var(--ink); background: var(--paper); padding: 5px;
  opacity: 0; transform: translateY(-6px); pointer-events: none;
  transition: opacity .28s var(--ease), transform .28s var(--ease); }
.karte__pj--links .karte__blatt { left: auto; right: 0; }
.karte__blatt img { display: block; width: 100%; aspect-ratio: 16/9; object-fit: cover; }
.karte__blatt span { display: block; margin-top: .45rem; }
.karte__blatt .karte__blattname + .meta { margin-top: .2rem; }
.karte__pj:hover .karte__blatt, .karte__pj:focus-visible .karte__blatt { opacity: 1; transform: none; }
/* Escape schliesst das Blatt, bis Zeiger oder Fokus den Marker verlassen (WCAG 1.4.13). */
.karte__pj.ist-zu .karte__blatt { opacity: 0; transform: translateY(-6px); transition: none; }   /* sofort, nicht ausblenden */

/* Liegenschaften als Liste: optisch verborgen, fuer Screenreader und ohne
   JavaScript aber vorhanden. Sehende Tastaturnutzer gehen auf der Karte
   selbst durch (Pfeiltasten, karte.js tastatur()). */
.liste { position: absolute; width: 1px; height: 1px; padding: 0; margin: -1px;
  overflow: hidden; clip-path: inset(50%); white-space: nowrap; border: 0; }

/* Kartenflaeche im Tastaturfokus: deutlicher Rahmen nach innen. */
.karte .maplibregl-canvas:focus-visible { outline: 3px solid var(--ink); outline-offset: -3px; }
.karte__tastatur { position: absolute; z-index: 5; left: 50%; bottom: 1.2rem; transform: translateX(-50%);
  background: var(--paper); border: var(--rule) solid var(--ink); padding: .45rem .8rem;
  opacity: 0; pointer-events: none; transition: opacity .2s var(--ease);
  width: max-content; max-width: calc(100% - 2.4rem); text-align: center; }   /* bricht auf schmalen Schirmen um (320 px: kein Ueberhang) */
/* Nur wenn die Flaeche selbst den Tastaturfokus hat — nicht bei einem Projekt-Marker. */
.karte__buehne:has(.maplibregl-canvas:focus-visible) ~ .karte__tastatur { opacity: 1; }

/* Dossier-Deckel: derselbe Linienrahmen mit Registermarken wie auf dem Hero,
   nur in Tinte statt Papier — hier liegt er auf hellem Grund. */
.karte__rahmen { position: absolute; inset: clamp(.9rem, 2.4vw, 2rem); top: var(--rahmen-oben);
  z-index: 6; border: var(--rule) solid var(--hair-2); pointer-events: none; }
.karte__marken { position: absolute; inset: clamp(.9rem, 2.4vw, 2rem); top: var(--rahmen-oben);
  z-index: 6; pointer-events: none; }
.karte__marken span { position: absolute; width: 8px; height: 8px; background: var(--steel);
  border: 1px solid var(--paper); transform: translate(-50%, -50%); }
.karte__marken span:nth-child(1) { top: 0; left: 25%; }
.karte__marken span:nth-child(2) { top: 0; left: 50%; }
.karte__marken span:nth-child(3) { top: 0; left: 75%; }
.karte__marken span:nth-child(4) { bottom: 0; left: 25%; }
.karte__marken span:nth-child(5) { bottom: 0; left: 50%; }
.karte__marken span:nth-child(6) { bottom: 0; left: 75%; }
.karte__marken span:nth-child(n+4) { transform: translate(-50%, 50%); }

/* Die Karte als letztes Panel im Stapel (/projekte): so hoch wie die
   Film-Panels, Rahmen und Kopf beginnen an der Panelkante statt unter einem
   daruebergelegten Menue. */
.stapel__panel.karte { position: sticky; display: block; height: calc(100svh - var(--mast-ist, var(--mast)));
  min-height: 0; background: var(--paper); color: var(--ink); }
.stapel__panel.karte .meta { color: var(--meta); }
.stapel--frei .stapel__panel.karte { position: relative; }
@media (max-height: 34rem) { .stapel__panel.karte { position: relative; } }
.stapel__panel .karte__rahmen, .stapel__panel .karte__marken { top: .5rem; }
.stapel__panel .karte__kopf { padding-top: clamp(2rem, 4.5vw, 3.5rem); }
.stapel__panel .karte__zurueck { top: clamp(2rem, 4.5vw, 3.5rem); }
.stapel__panel .dossier { top: 1.5rem; max-height: calc(100% - 10.5rem); }
/* Schmal bricht die Herkunftsangabe auf zwei Zeilen um: die Legende steht darueber. */
@media (max-width: 600px) { .stapel__panel .karte__legende { bottom: 6.4rem; } }

/* Bedienelemente und Beschriftung ruecken hinter den Rahmen. */
.karte .maplibregl-ctrl-bottom-right,
.karte .maplibregl-ctrl-bottom-left { margin-right: clamp(.9rem,2.4vw,2rem); margin-left: clamp(.9rem,2.4vw,2rem); }

/* In der Uebersicht faengt die Karte keine Mausrad-Gesten ab und zeigt den
   Zeiger als Einladung: ein Klick oeffnet sie. */
.karte__buehne { cursor: zoom-in; }
.karte__buehne.ist-karte { cursor: grab; }
.karte__buehne.ist-karte:active { cursor: grabbing; }

/* Rueckweg in die Uebersicht — nur sichtbar, solange die Karte offen ist. */
.karte__zurueck { position: absolute; z-index: 5; left: clamp(1.25rem,4vw,4rem);
  top: clamp(5rem,9vw,7rem); background: var(--paper);
  opacity: 0; visibility: hidden; transition: opacity .4s var(--ease), visibility .4s; }
.karte__buehne.ist-karte ~ .karte__zurueck { opacity: 1; visibility: visible; }

/* Der Kopf gehoert zum Landesueberblick. Wer in eine Strasse hineingeht,
   will die Karte sehen, nicht die Ueberschrift. */
.karte__kopf { position: absolute; z-index: 5; top: 0; left: 0; right: 0;
  padding: clamp(5rem,9vw,7rem) clamp(1.25rem,4vw,4rem) 0; pointer-events: none;
  transition: opacity .5s var(--ease); }
.karte__buehne.ist-karte ~ .karte__kopf { opacity: 0; }
.karte__titel { font-size: clamp(2rem,5vw,3.6rem); letter-spacing: -.04em; max-width: 16ch; }
.karte__lede { margin-top: .9rem; max-width: 46ch; color: var(--meta); }

.karte__legende { position: absolute; z-index: 5; left: clamp(1.25rem,4vw,4rem);
  bottom: clamp(1.25rem,4vw,3rem); background: var(--paper);
  border: var(--rule) solid var(--hair); padding: .85rem 1.1rem; }
.karte__legende div { display: flex; align-items: center; gap: .6rem; font-size: .85rem; }
.karte__legende div + div { margin-top: .45rem; }
.karte__i { display: block; width: 11px; height: 11px; border-radius: 50%; flex: none; }
.karte__i--pj { border: 2px solid var(--red); }
.karte__i--pf { background: var(--ink); border: 2px solid var(--paper); box-shadow: 0 0 0 1px var(--hair); }

/* Der Hinweis sitzt ueber der Herkunftsangabe, nicht darauf. */
.karte__hinweis { position: absolute; z-index: 5; right: clamp(1.25rem,4vw,4rem);
  bottom: calc(clamp(1.25rem,4vw,3rem) + 1.6rem); color: var(--meta);
  transition: opacity .5s var(--ease); }
.karte__buehne.ist-karte ~ .karte__hinweis { opacity: 0; }
@media (max-width: 860px) { .karte__hinweis { display: none; } }

/* ---- Dossier-Fenster: die Liegenschaft unter der Maus ---- */
.dossier { position: absolute; z-index: 7; top: calc(var(--rahmen-oben) + 1rem);
  right: calc(clamp(.9rem,2.4vw,2rem) + 1.5rem); width: min(20rem, 34vw);
  /* Nicht bis in die Zoomknoepfe reichen — die sitzen unten rechts. */
  max-height: calc(100% - var(--rahmen-oben) - 9rem); overflow-y: auto;
  background: var(--paper); border: var(--rule) solid var(--ink);
  opacity: 0; visibility: hidden; transform: translateX(.75rem);
  transition: opacity .3s var(--ease), transform .3s var(--ease), visibility .3s; }
.dossier.ist-offen { opacity: 1; visibility: visible; transform: none; }
/* Der Schliessknopf gehoert nur zum festgehaltenen Fenster. */
.dossier__zu { display: none; }
.dossier.ist-fest .dossier__zu { display: block; }

.dossier__bild { position: relative; aspect-ratio: 16/10; background: var(--paper-2);
  border-bottom: var(--rule) solid var(--hair); display: grid; place-items: center; }
.dossier__bild img { width: 100%; height: 100%; object-fit: cover; display: block; }
.dossier__leer { color: var(--meta); }

.dossier__inhalt { padding: 1.1rem 1.2rem 1rem; }
.dossier__titel { font-size: 1.25rem; line-height: 1.2; letter-spacing: -.02em; margin-top: .35rem;
  text-wrap: balance; }
/* Bezeichnung ueber dem Wert statt daneben: «Auftraggeber» in Versalien mit
   Sperrung braucht mehr Breite, als eine feste Spalte im schmalen Fenster
   hergibt — nebeneinander liefen die beiden ineinander. */
.dossier__fakten { margin: 1rem 0 0; border-top: var(--rule) solid var(--hair); }
.dossier__fakt { display: grid; gap: .25rem; padding: .65rem 0;
  border-bottom: var(--rule) solid var(--hair); }
.dossier__fakt dt { font-size: .68rem; line-height: 1.2; letter-spacing: .12em;
  text-transform: uppercase; color: var(--meta); }
.dossier__fakt dd { margin: 0; font-size: .95rem; line-height: 1.4; font-weight: 500;
  font-variant-numeric: tabular-nums; }
.dossier__fuss { margin-top: .8rem; font-size: .68rem; }

.dossier.ist-fest .dossier__zu { position: absolute; top: .4rem; right: .4rem; z-index: 2;
  background: var(--paper); border: var(--rule) solid var(--hair); color: var(--ink);
  font: inherit; font-size: 1.1rem; line-height: 1; padding: .25rem .5rem; cursor: pointer; }
.dossier__zu:hover { background: var(--ink); color: var(--paper); }

/* Auf schmalen Schirmen faende das Fenster rechts keinen Platz — dort legt es
   sich als Leiste an den unteren Rand. */
@media (max-width: 780px) {
  .dossier { top: auto; bottom: calc(clamp(1.25rem,4vw,3rem) + 4.5rem);
    left: clamp(.9rem,2.4vw,2rem); right: clamp(.9rem,2.4vw,2rem); width: auto;
    display: grid; grid-template-columns: 7rem 1fr; }
  .dossier__bild { aspect-ratio: 1; border-bottom: 0; border-right: var(--rule) solid var(--hair); }
  .dossier__fakten { display: flex; flex-wrap: wrap; gap: 0 1.5rem; border-top: 0; }
  .dossier__fakt { border-bottom: 0; grid-template-columns: none; padding: .3rem 0; }
}
@media (prefers-reduced-motion: reduce) { .dossier { transition: none; } }

/* ---- Kino: der Projektfilm ueber der ganzen Flaeche ---- */
.kino { position: fixed; inset: 0; z-index: 900; background: var(--ink);
  opacity: 0; transition: opacity .42s var(--ease); }
.kino.ist-offen { opacity: 1; }
.kino__film { width: 100%; height: 100%; object-fit: cover; }

/* Ueber dem Film sitzt dasselbe Dossier-Fenster wie bei den Liegenschaften,
   nur fest offen. Sein Kreuz schliesst den Film gleich mit. */
.dossier--kino { position: absolute; z-index: 2; top: clamp(1rem,3vw,2rem);
  right: clamp(1rem,3vw,2rem); max-height: calc(100% - 6rem); }
.dossier__link { display: inline-block; margin-top: 1rem; }
/* Auf dem Handy nimmt das volle Fenster dem Film die halbe Flaeche. Dort
   bleibt nur, was man ueber dem Film wirklich braucht: der Weg ins Dossier
   und das Kreuz. Bild, Titel und Eckdaten stehen ohnehin im Dossier selbst. */
@media (max-width: 780px) {
  .dossier.dossier--kino { top: clamp(.75rem,3vw,1.5rem); right: clamp(.75rem,3vw,1.5rem);
    bottom: auto; left: auto; width: auto; max-height: none;
    display: flex; align-items: stretch; }
  .dossier--kino .dossier__bild,
  .dossier--kino .dossier__titel,
  .dossier--kino .dossier__fakten,
  .dossier--kino .dossier__inhalt > .meta { display: none; }
  .dossier--kino .dossier__inhalt { padding: 0; display: flex; align-items: center; }
  .dossier--kino .dossier__link { margin: 0; padding: .65rem .9rem; white-space: nowrap; }
  /* Das Kreuz gehoert rechts — im Markup steht es zuerst, damit es per
     Tastatur zuerst erreichbar bleibt. */
  .dossier.dossier--kino .dossier__zu { position: static; border: 0; order: 2;
    border-left: var(--rule) solid var(--hair); padding: .65rem .8rem; }
  .dossier--kino .dossier__inhalt { order: 1; }
}
@media (prefers-reduced-motion: reduce) {
  .kino, .karte__blatt, .karte__pf, .karte__nadel, .karte__fahne, .karte__vorhang { transition: none; }
}

/* ---- Fremdinhalt hinter einem Vorschaltfeld ----
   Der Rahmen laedt erst auf Klick. Bis dahin steht hier eine Karte in
   unserer Sprache statt eines leeren Kastens mit fremdem Logo. */
.extern { border: var(--rule) solid var(--ink); background: var(--paper-2); }
.extern__tor { padding: clamp(1.6rem,4vw,3rem); max-width: 46ch; }
.extern__text { color: var(--ink); }
.extern__tor .btn { margin-top: 1.4rem; }
.extern__fuss { margin-top: 1.2rem; }
.extern__nachsatz { margin-top: 1.2rem; }

/* Nach dem Laden traegt der Rahmen den Fremdinhalt. Feste Hoehe, weil
   homegate.ch seine eigene Hoehe nicht meldet — der iframeResizer der alten
   Seite wartet dort vergeblich. Innen wird gescrollt. */
.extern.ist-geladen { background: var(--paper); }
.extern iframe { display: block; width: 100%; height: clamp(40rem, 88vh, 62rem); border: 0; }

/* ---- Kennzahlen (Ueber uns) ----
   Vier Zahlen nebeneinander, jede unter einer Hairline. Kein Rot: vier grosse
   rote Zahlen waeren flaechig, und Rot bleibt in dieser Welt das Signal — nur die eine beruehrte Zahl
   wird rot (Effekte unten). */
.kennzahlen__lede { max-width: 56ch; color: var(--meta); margin-top: 1.2rem; }
.kennzahlen { display: grid; gap: 0 clamp(1.5rem,3vw,3rem);
  grid-template-columns: 1fr 1fr; margin: clamp(2rem,4vw,3rem) 0 0; }
@media (min-width: 900px) { .kennzahlen { grid-template-columns: repeat(4, 1fr); } }
/* Bei 320 px ragten die grossen Zahlen aus der halben Spalte (WCAG 1.4.10). */
@media (max-width: 420px) { .kennzahlen { grid-template-columns: 1fr; } }
.kennzahl { border-top: 2px solid var(--ink); padding: 1rem 0 clamp(1.5rem,3vw,2rem); }
.kennzahl__wert { font-size: clamp(2.2rem,4.5vw,3.4rem); font-weight: 700;
  letter-spacing: -.04em; line-height: 1; }
.kennzahl__text { margin: .7rem 0 0; color: var(--meta); font-size: .92rem; max-width: 24ch; }
/* Effekte (Kundenwunsch): Titel und Lede stehen sofort; die vier Felder
   fliegen von unten heran, links nach rechts gestaffelt (--staffel; als
   Animation, damit die Verzoegerung nicht auch jeden Hover-Uebergang
   bremst — die allgemeine [data-delay]-Regel verliert ohnehin gegen
   .js .reveal). Mit der Maus zoomt das beruehrte Feld leicht und wird rot,
   die drei anderen treten zurueck; ohne Maus (Touch) nur der Anflug;
   reduzierte Bewegung: kein Anflug, kein Zoom, nur Farbe. */
.js .kennzahl.reveal { transform: translateY(56px); }
.kennzahl[data-delay="1"] { --staffel: .12s; } .kennzahl[data-delay="2"] { --staffel: .24s; } .kennzahl[data-delay="3"] { --staffel: .36s; }
.js .kennzahl.reveal.in { opacity: 1; transform: none;
  animation: kennzahl-anflug .9s var(--ease) backwards; animation-delay: var(--staffel, 0s);
  transition: opacity .35s var(--ease), transform .35s var(--ease), border-color .35s var(--ease); }
@keyframes kennzahl-anflug { from { opacity: 0; transform: translateY(56px); } to { opacity: 1; transform: none; } }
.kennzahl__wert { transition: color .35s var(--ease); }
@media (hover: hover) {
  .js .kennzahlen:hover .kennzahl.reveal.in { opacity: .55; transform: scale(.97); }
  .js .kennzahlen .kennzahl.reveal.in:hover { opacity: 1; transform: scale(1.05); position: relative; z-index: 1; border-top-color: var(--red); }
  .js .kennzahlen .kennzahl.reveal.in:hover .kennzahl__wert { color: var(--red); }
}
@media (prefers-reduced-motion: reduce) {
  .js .kennzahl.reveal.in { animation: none; }
  .js .kennzahlen:hover .kennzahl.reveal.in, .js .kennzahlen .kennzahl.reveal.in:hover { opacity: 1 !important; transform: none !important; }
}

/* ---- Mieterservice: die App ---- */
.app { display: grid; gap: clamp(1.5rem,3vw,2.5rem); align-items: start;
  border-top: 2px solid var(--steel); padding-top: clamp(1.4rem,3vw,2rem); }
@media (min-width: 820px) { .app { grid-template-columns: 1fr auto; align-items: center; } }
.app__titel { font-size: clamp(1.5rem,3vw,2.1rem); letter-spacing: -.03em; }
.app__text { margin-top: .8rem; max-width: 52ch; color: var(--meta); }
.app__laden { display: flex; flex-wrap: wrap; gap: .8rem; }
/* Das passende System steht vorn — gesetzt vom Skript, ohne es bleibt die
   Reihenfolge aus dem Markup. */
.app__knopf.ist-passend { order: -1; border-color: var(--red); background: var(--red); color: var(--paper); }
.app__knopf.ist-passend:hover { background: var(--red-deep); border-color: var(--red-deep); }

/* ---- Mieterservice: Anmeldeformulare ---- */
.formulare { display: grid; gap: clamp(1.5rem,3vw,2.5rem); }
@media (min-width: 820px) { .formulare { grid-template-columns: 1fr 1fr; } }
.formular { border-top: var(--rule) solid var(--hair); padding-top: 1.2rem; min-width: 0; }
.formular__fuer { font-size: clamp(1.15rem,2vw,1.4rem); letter-spacing: -.02em; }
/* «Geschäftsräumlichkeiten» ist bei 320 px fast so breit wie die Zeile: dann
   rutscht die PDF-Angabe ungetrennt darunter, statt die Spalte zu sprengen. */
.formular .docrow { margin-top: .9rem; flex-wrap: wrap; }
.formular .docrow .meta { white-space: nowrap; }

/* ---- Legal (Impressum / Datenschutz) ---- */
.legal { max-width: 68ch; }
.legal h2 { font-size: clamp(1.4rem,2.4vw,1.9rem); margin: 2.4rem 0 .8rem; letter-spacing:-0.02em; }
.legal h3 { font-size: 1.1rem; margin: 1.6rem 0 .5rem; }
.legal p { margin-bottom: 1rem; color: var(--ink); }
.legal p.meta { color: var(--meta); }
.legal a { color: var(--red); } .legal a:hover { text-decoration: underline; }
.legal ul { margin: 0 0 1rem 1.2rem; color: var(--ink); } .legal li { margin-bottom:.3rem; }

/* ---- Datenschutz --------------------------------------------------------
   Breit zwei Spalten: links das klebende Inhaltsverzeichnis (selbst
   scrollend, Markierung per datenschutz.js), rechts Stelle und Text.
   Schmal ein aufklappbarer Kasten ueber dem Text. Kapitel mit grosser roter
   Nummer und Haarlinie, Unterpunkte mit roter Nummer. */
.dsg { display: grid; gap: clamp(2rem, 5vw, 4rem); }
@media (min-width: 980px) {
  .dsg { grid-template-columns: 17rem minmax(0, 1fr); align-items: start; }
  .dsg__inhalt { position: sticky; top: calc(var(--mast-ist, var(--mast)) + 1.5rem);
    max-height: calc(100svh - var(--mast-ist, var(--mast)) - 3rem); overflow-y: auto; overscroll-behavior: contain; }
}
.dsg__inhalt { border-top: var(--rule) solid var(--red); padding-top: .6rem; }
.dsg__kasten > summary { display: flex; justify-content: space-between; align-items: center; min-height: 44px;
  cursor: pointer; list-style: none; font-weight: 600; }
.dsg__kasten > summary::-webkit-details-marker { display: none; }
.dsg__kasten > summary::after { content: "+"; color: var(--red); font-size: 1.4rem; line-height: 1; }
.dsg__kasten[open] > summary::after { content: "–"; }
.dsg--breit .dsg__kasten > summary { display: none; }
.dsg__liste { list-style: none; margin: .4rem 0 0; padding: 0; }
.dsg__liste a { display: grid; grid-template-columns: 2.6rem minmax(0, 1fr); gap: .3rem; padding: .28rem .5rem .28rem .65rem;
  border-left: 2px solid transparent; font-size: .86rem; line-height: 1.3; color: var(--ink); }
.dsg__liste .ebene-2 a { font-weight: 600; margin-top: .55rem; }
.dsg__liste li:first-child a { margin-top: 0; }
.dsg__liste .dsg__nr { color: var(--meta); font-variant-numeric: tabular-nums; }
.dsg__liste a:hover { color: var(--pop); }
.dsg__liste a[aria-current] { border-left-color: var(--red); color: var(--red); }
.dsg__liste a[aria-current] .dsg__nr { color: var(--red); }
.dsg [id^="k-"] { scroll-margin-top: calc(var(--mast-ist, var(--mast)) + 1rem); }
.dsg__haupt { min-width: 0; }
.dsg__haupt h2 { padding-top: 1.1rem; border-top: var(--rule) solid var(--red); margin: 3.2rem 0 1.4rem;
  font-size: clamp(1.5rem, 2.8vw, 2.2rem); line-height: 1.1; letter-spacing: -0.02em; }
.dsg__stelle h2 { margin-top: 0; }
.dsg__haupt h2 .dsg__nr { display: block; margin-bottom: .35rem; color: var(--red); font-size: clamp(2.4rem, 5vw, 3.6rem);
  font-weight: 700; line-height: 1; letter-spacing: -0.04em; }
.dsg__text h3 { margin: 2rem 0 .55rem; }
.dsg__text h3 .dsg__nr { margin-right: .35em; color: var(--red); font-variant-numeric: tabular-nums; }
.dsg__text ul { list-style: none; margin-left: 0; }
.dsg__text li { display: grid; grid-template-columns: 1.2rem minmax(0, 1fr); }
.dsg__text li::before { content: "–"; color: var(--red); }
.dsg__text a { overflow-wrap: anywhere; }
.dsg__stelle .facts { max-width: 36rem; }
.dsg__schluss { max-width: 68ch; margin-top: 3rem; padding-top: 1rem; border-top: var(--rule) solid var(--hair); color: var(--meta); }

/* ==========================================================================
   Rueckmeldung beim Druecken
   Die Reaktion gehoert auf den Fingerdruck, nicht auf das Loslassen. Auf
   Zeigegeraeten uebernimmt das hover; auf dem Handy gab es zwischen
   Beruehrung und Ergebnis bisher gar nichts.

   Der Block steht bewusst am Schluss: mehrere dieser Elemente werden weiter
   oben kontextabhaengig umgefaerbt (der Stempel im roten Abschlussfeld, das
   Kreuz im festgehaltenen Dossier). Bei gleicher Spezifitaet gewinnt die
   spaetere Regel — nur so schlaegt der Druckzustand seine eigene Ruhefarbe.
   ========================================================================== */
.btn, .svc, .karte__pj, .docrow, .ref, .objcard,
.nav a, .nav-toggle, .ulink, .dial__row a, .crumb,
.dossier .dossier__zu {
  /* Eigene Rueckmeldung statt des grauen Systemblitzes, und kein Warten auf
     einen moeglichen Doppeltipp. */
  -webkit-tap-highlight-color: transparent;
  touch-action: manipulation;
}

/* Flaechige Elemente geben nach. 1.5 % sind kaum messbar und trotzdem
   spuerbar; mehr waere in dieser ruhigen Welt ein Fremdkoerper. */
.btn:active, .docrow:active, .objcard:active, .ref:active {
  transform: scale(.985);
  transition-duration: .09s;   /* beim Druecken kurz, beim Loslassen wieder lang */
}

/* Die Wendekarte traegt eine 3D-Perspektive — ein transform darauf wuerde
   die Drehung stoeren. Stattdessen zieht die Kante an. */
.svc:active .svc__face { border-color: var(--ink); transition-duration: .09s; }

/* Der Kartenmarker wird von MapLibre per transform positioniert; auch dort
   ist die Kante der Weg. Der Ring fuellt sich. */
.karte__pj:active { background: radial-gradient(circle, var(--red) 0 9px, transparent 9px); transition: background .09s var(--ease); }


/* Schrift-Elemente wechseln die Farbe — sofort, ohne Weg. */
.ulink:active, .dial__row a:active, .crumb:active { color: var(--red); }
.nav a:active { color: var(--pop-hell); }
/* Wo der Grund selbst rot oder dunkel ist, waere Rot unlesbar
   (Rot auf Rot 1:1, Rot auf dem dunklen Kopf 3.2:1). */
.reply .ulink:active, .reply .fact__val a:active { color: var(--paper); text-decoration: underline; }
.crumb:active { color: var(--on-ink); }
.crumb--ink:active { color: var(--ink); }
.masthead.is-solid .nav a:active { color: var(--pop); }
.masthead.nav-open .nav a:active { color: var(--pop-hell); }   /* offenes Handy-Menue: immer schwarz */
.nav-toggle:active { opacity: .6; }

.dossier .dossier__zu:active { background: var(--ink); color: var(--paper); }

/* Reduzierte Bewegung heisst nicht: keine Rueckmeldung. Das Nachgeben faellt
   weg, die Farbe bleibt — sie ist die eigentliche Auskunft. */
@media (prefers-reduced-motion: reduce) {
  .btn:active, .docrow:active, .objcard:active, .ref:active { transform: none; }
}

/* ==========================================================================
   404-Bühne (.fehler) — Umzugs-Runner, Spiel in fehler.js
   ========================================================================== */
/* Bleibt ein .subhero, damit die Kopfleiste darüber wie auf jeder dunklen
   Kopfzone durchsichtig steht. Die Bühne beginnt direkt unter der Leiste. */
.fehler { padding-top: var(--mast-ist, var(--mast)); }
/* Höhe: mindestens 15rem (Handy), sonst 35% der Breite; nach oben durch die
   Fensterhöhe begrenzt, aber nie unter 30vw — darunter schnitte „slice“ auf
   breiten, flachen Fenstern die Dächer der 404-Türme ab (sichtbar bleiben
   immer mindestens 360 der 420 Einheiten). */
.buehne { position: relative; height: clamp(15rem, 35vw, max(58svh, 30vw)); background: var(--ink); overflow: hidden; }
.js .buehne { cursor: pointer; touch-action: manipulation; user-select: none; -webkit-tap-highlight-color: transparent; }
.buehne__svg [hidden] { display: none; }   /* das hidden-Attribut wirkt in SVG nicht von selbst */
/* Fokusring als eigene Ebene über SVG und Anzeige: ein outline der Bühne
   läge unter ihren absolut positionierten Kindern (gemessen: kein Pixel rot).
   Innen, weil .subhero überstehendes abschneidet; hell, weil Rot auf der
   Strasse (--ink-2) nur 2.6:1 erreicht. */
.buehne:focus-visible { outline: none; }
.buehne:focus-visible::after { content: ""; position: absolute; inset: 0; z-index: 2; pointer-events: none;
  border: 3px solid var(--on-ink); }
.buehne__svg { position: absolute; inset: 0; width: 100%; height: 100%; display: block; }

.b-himmel { fill: var(--ink); }
.b-stern { fill: var(--on-ink-meta); }
.b-mond { fill: var(--paper); }
.b-fern { fill: var(--ink-2); }
.b-fernlicht { fill: #F0C870; opacity: .35; }   /* Fensterlicht: einziges Gelb, nur als Licht */
.b-turm { fill: var(--steel); stroke: rgba(244,241,234,.22); stroke-width: 1.5; }
.b-antenne { stroke: rgba(244,241,234,.35); stroke-width: 2; }
.b-leuchte { fill: var(--red); }
.fenster { fill: #3A342B; }
.fenster--an { fill: #F0C870; }
.b-rand { fill: #2F2A22; }
.b-mast { stroke: #4A443A; stroke-width: 3; }
.b-lampe { fill: #F0C870; }
.b-schein { fill: #F0C870; opacity: .12; }
.b-strasse { fill: var(--ink-2); }
.b-kante { stroke: var(--hair-ink); stroke-width: 2; }
.b-markierung { fill: var(--on-ink-meta); opacity: .45; }
.b-karton { fill: var(--wood); }
.b-klappe { fill: #7E6440; }
.b-band { fill: var(--red); }
.b-etikett { fill: var(--paper); opacity: .85; }
.b-auge { fill: var(--ink); }
.b-bein { stroke: var(--on-ink-meta); stroke-width: 3; stroke-linecap: round; }
.b-kegel { fill: var(--red); }
.b-streifen, .b-brett { fill: var(--paper); }
.b-sockel { fill: var(--red-deep); }
.b-fuss { fill: var(--on-ink-meta); }
.b-tonne { fill: #4E6B55; }
.b-tonne-rippe { fill: #3E5644; }
.b-deckel { fill: #5D7D64; }
.b-rad, .b-tv-fuss { fill: #1E1A15; }
.b-ball { fill: var(--paper); }
.b-naht { fill: none; stroke: var(--red); stroke-width: 2; }
.b-tv { fill: #5A4A36; stroke: #2F2A22; stroke-width: 1.5; }
.b-tv-bild { fill: #CFE3E6; }
.b-tv-logo { color: var(--ink); }
.b-tv-knopf { fill: #2F2A22; }
.b-leuchtstern__form { fill: #F0C870; }
.b-leuchtstern__schein { fill: #F0C870; opacity: .22; }
.b-leuchtstern--boost .b-leuchtstern__form { fill: var(--red); }
.b-leuchtstern--boost .b-leuchtstern__schein { fill: var(--red); opacity: .3; }
.b-bonus { fill: #F0C870; font-size: 18px; font-weight: 700; }

/* Bewegung nur mit JS (kopf.js setzt html.js) und ohne Bewegungsreduktion */
.js .fenster--flacker { animation: b-flackern 7s steps(1, end) infinite; animation-delay: var(--v, 0s); }
.js .b-leuchte { animation: b-blinken 1.6s steps(1, end) infinite; }
.ist-gestossen { animation: b-wackeln .4s linear; }
@keyframes b-flackern { 0%, 62% { fill: #3A342B; } 63%, 88% { fill: #F0C870; } 89%, 100% { fill: #3A342B; } }
@keyframes b-blinken { 0%, 50% { opacity: 1; } 51%, 100% { opacity: .2; } }
@keyframes b-wackeln { 0%, 100% { transform: translateX(0); } 20% { transform: translateX(-5px); } 40% { transform: translateX(5px); }
  60% { transform: translateX(-3px); } 80% { transform: translateX(3px); } }
/* Turbo: der Karton blinkt 2.5-mal pro Sekunde — unter der Grenze von drei
   Blitzen (WCAG 2.3.1). Bei Bewegungsreduktion leuchtet er ruhig. */
.ist-boost [data-wackel] { animation: b-turbo .4s steps(1, end) infinite; }
.js .b-leuchtstern--boost .b-leuchtstern__schein { animation: b-blinken .8s steps(1, end) infinite; }
@keyframes b-turbo { 0%, 50% { opacity: 1; } 51%, 100% { opacity: .25; } }
@media (prefers-reduced-motion: reduce) {
  .js .fenster--flacker, .js .b-leuchte, .ist-gestossen, .ist-boost [data-wackel], .js .b-leuchtstern--boost .b-leuchtstern__schein { animation: none; }
  .ist-boost .b-karton { fill: #F0C870; }
}

/* Pause-Symbol (WCAG 2.2.2): einziges Bedienelement in der Bühne, 32 px Ziel,
   links vor der Anzeige. Ohne JS bleibt es verborgen. */
.buehne__pause { position: absolute; z-index: 3; top: .25rem; left: calc(var(--gutter) - .5rem); width: 2rem; height: 2rem;
  display: grid; place-items: center; padding: 0; background: none; border: 0; color: var(--on-ink-meta); cursor: pointer;
  scroll-margin-top: var(--mast-ist, var(--mast)); }
.buehne__pause[hidden] { display: none; }
.buehne__pause svg { width: 1rem; height: 1rem; fill: currentColor; }
.buehne__pause:hover, .buehne__pause:focus-visible { color: var(--on-ink); }
.buehne__pause:focus-visible { outline: 2px solid var(--on-ink); outline-offset: -2px; }
.buehne__pause-aus, .buehne__pause[aria-pressed="true"] .buehne__pause-an { display: none; }
.buehne__pause[aria-pressed="true"] .buehne__pause-aus { display: inline; }
.buehne__hud { position: absolute; top: .75rem; left: calc(var(--gutter) + 2rem); display: flex; gap: 1.25rem; pointer-events: none;
  font-size: .8rem; font-weight: 600; letter-spacing: .12em; text-transform: uppercase; color: var(--on-ink-meta);
  font-variant-numeric: tabular-nums; }
.buehne__hud b { color: var(--on-ink); }
.buehne__hinweis { position: absolute; left: 0; right: 0; bottom: .6rem; text-align: center; pointer-events: none;
  font-size: .8rem; color: var(--on-ink-meta); transition: opacity .4s; }
.buehne__hinweis.ist-weg { opacity: 0; }
.buehne__meldung { position: absolute; top: 42%; left: 50%; transform: translate(-50%, -50%); pointer-events: none;
  padding: .5rem 1rem; background: var(--ink); border: var(--rule) solid var(--hair-ink); color: var(--on-ink); font-weight: 700; }
.buehne__meldung[hidden] { display: none; }

.fehler__text { padding-top: clamp(1.5rem, 4vw, 3rem); padding-bottom: clamp(2.5rem, 6vw, 5rem); }
.fehler__spruch { margin-top: 1rem; max-width: 30ch; font-size: clamp(1.25rem, 2.4vw, 1.8rem); font-weight: 700;
  letter-spacing: -0.02em; line-height: 1.15; color: var(--on-ink); }
.fehler__signatur { margin-top: clamp(2rem, 5vw, 3.5rem); display: inline-flex; align-items: center; gap: .75rem;
  font-size: .85rem; color: var(--on-ink-meta); }
.fehler__signatur .partner-logo--mco { width: 57px; height: 30px; }
.fehler__signatur:hover { color: var(--on-ink); }

/* ---- Angebote: Referenz-Mosaik ------------------------------------------
   Vollflaechig vor dem Footer, Kante an Kante; oben und unten grenzt eine
   feine rote Linie es vom Papier ab wie das Projektband der Startseite.
   Hoehe: Fenster minus Menue und ein Footer-Streifen — eingerastet (Oberkante
   an der Menuekante) steht so alles im Bild (mosaik.js setzt den genauen
   Wert, festgehalten beim Laden).
   Standbild (ohne JS, reduzierte Bewegung): Grid, das mit column dense jede
   Luecke stopft. Bewegtes Feld: ein Kachelraster, Schiebestreifen aus durchgehenden Linien, nur transform
   und opacity, kein Zoom. */
.mosaik { --mh: max(20rem, calc(100svh - 6.4rem)); --r: 5;
  position: relative; height: var(--mh); overflow: hidden; background: var(--ink); }
/* Ueber den Kacheln gezeichnet, damit Hoehe und Raster unveraendert bleiben. */
.mosaik::before, .mosaik::after { content: ""; position: absolute; left: 0; right: 0; z-index: 4;
  height: var(--rule); background: var(--red); pointer-events: none; }
.mosaik::before { top: 0; }
.mosaik::after { bottom: 0; }
@media (max-height: 700px) { .mosaik { --r: 4; } }
@media (max-height: 480px) { .mosaik { --r: 3; } }
@media (min-height: 1000px) { .mosaik { --r: 6; } }
.mosaik__sr { position: absolute; width: 1px; height: 1px; padding: 0; margin: -1px;
  overflow: hidden; clip-path: inset(50%); white-space: nowrap; border: 0; }
.mosaik__still { display: grid; height: 100%; grid-template-rows: repeat(var(--r), 1fr);
  grid-auto-columns: calc(var(--mh) / var(--r)); grid-auto-flow: column dense; }
.mosaik.ist-lebendig .mosaik__still { display: none; }
.mosaik__feld { position: absolute; inset: 0; }
.mosaik:not(.ist-lebendig) .mosaik__feld { display: none; }
.kachel { position: relative; overflow: hidden; background: var(--ink-2); }
.mosaik__feld .kachel { position: absolute; perspective: 1200px; }
.kachel img { display: block; width: 100%; height: 100%; object-fit: cover; transition: opacity .6s ease; }
.kachel img.laedt { opacity: 0; }
.kachel--grau img, .kachel__seite--grau img { filter: grayscale(1); }
.kachel__innen { position: absolute; inset: 0; transform-style: preserve-3d; }
.kachel__seite { position: absolute; inset: 0; backface-visibility: hidden; -webkit-backface-visibility: hidden; }
.kachel__seite--hinten { transform: rotateY(180deg); }
.kachel--text { display: flex; align-items: flex-end; padding: .55em .65em; font-weight: 700;
  letter-spacing: -0.02em; line-height: 1.02; hyphens: manual; overflow-wrap: normal;
  font-size: clamp(.9rem, 1.6vw, 1.4rem); }
.kachel--text span { display: block; max-width: 100%; }
/* Im bewegten Feld ist der Text ein eigener Kasten mit festen Massen (mosaik.js);
   hochkant: vertauschte Masse, unten links angesetzt, 90° nach links gedreht
   (Einzeleigenschaft rotate — Animationen setzen transform). */
.mosaik__feld .kachel--text { padding: 0; }
.mosaik__feld .kachel--text span { position: absolute; left: 0; top: 0; max-width: none; display: flex;
  align-items: flex-end; padding: .55em .65em; overflow: hidden; }
.mosaik__feld .kachel--hoch span { top: 100%; rotate: -90deg; transform-origin: 0 0; align-items: flex-start; }
.kachel--ink { background: var(--ink); color: var(--on-ink); }
.kachel--papier { background: var(--paper); color: var(--ink); }
.kachel--rot { background: var(--red); color: #fff; }
.splitter { position: absolute; background-repeat: no-repeat; pointer-events: none; }
.mosaik__pause { position: absolute; z-index: 5; right: var(--gutter); bottom: .75rem; width: 2rem; height: 2rem;
  display: grid; place-items: center; padding: 0; background: var(--ink); border: var(--rule) solid var(--hair-ink);
  color: var(--on-ink-meta); cursor: pointer; }
.mosaik__pause[hidden] { display: none; }
.mosaik__pause svg { width: 1rem; height: 1rem; fill: currentColor; }
.mosaik__pause:hover, .mosaik__pause:focus-visible { color: var(--on-ink); }
.mosaik__pause:focus-visible { outline: 2px solid var(--on-ink); outline-offset: 2px; }
.mosaik__pause-aus, .mosaik__pause[aria-pressed="true"] .mosaik__pause-an { display: none; }
.mosaik__pause[aria-pressed="true"] .mosaik__pause-aus { display: inline; }
