/*
 * Template «normal» — die GESTALTUNG (B4/E4, Vorbild sihlestate).
 *
 * Uebernommen sind die Zuege, die das Vorbild ausmachen: ein dunkles Band als
 * erster Eindruck, eine Pillen-CTA, grosse Prozessziffern, harte Rahmen um die
 * Tabelle, ein dunkler Tabellenkopf, ein dunkler Fuss. NICHT uebernommen sind
 * die zwei Dinge, die dort individuell sind (Peter, 2026-09-16): die Schrift
 * (BVH Eddi, lizenzpflichtig) und der bunte Seitenrahmen.
 *
 * ⚠️ **KEINE FARBE STEHT HIER FEST.** Jede Farbe ist `var(--op-…)`, und die
 * Werte kommen aus `theme.css`, die bei jedem Speichern aus der Farbwahl des
 * Kunden geschrieben wird ({@see \Z77\Shared\Estate\Onepager\OnepagerTheme}).
 * Die Werte im `:root` unten sind nur der RUECKFALL — sie gelten, solange es
 * keine `theme.css` gibt. Welche Farborte es gibt, sagt der `theme`-Block der
 * `template.json`; der b4-Zaun misst beide Haelften (jeder Ort steht in
 * `theme.css`, jede benutzte Variable hat einen Ort).
 *
 * Das dunkle Band ist die UMKEHRUNG der Seite (Grund und Schrift getauscht),
 * nicht ein eigenes Schwarz — so traegt es jede Farbwahl mit, statt eine
 * anzunehmen.
 *
 * ⚠️ Diese Datei IST die Quelle, es gibt keinen Bauschritt. Und sie ist
 * `copyOnce`: eine Aenderung hier erreicht eine BESTEHENDE Seite nur ueber
 * `php override/z77/shared/bin/onepager-entry.php refresh <tenant> <slug>`.
 */

:root {
    /* Die Farben — Rueckfall, siehe Kopf. */
    --op-grund:     #ffffff;
    --op-schrift:   #111111;
    --op-linie:     #d9d9d9;
    --op-akzent:    #1d4ed8;
    --op-aufakzent: #ffffff;
    --op-flaeche:   #f4f4f4;
    --op-leise:     #666666;

    /* Der SCHLEIER hinter dem Filterblatt. Kein Farbort und keine Wahl: ein
       halbdurchsichtiges Schwarz liegt ueber jeder Farbwahl richtig, und der
       `theme`-Block der template.json kennt ihn darum nicht. Er steht
       trotzdem als Variable, weil im Rest dieser Datei keine Farbe fest
       stehen darf — eine Ausnahme im Code waere die erste von vielen. */
    --op-schleier: rgb(0 0 0 / .5);

    /* Das Mass und der Rand. `--op-rand` ist der Mindestabstand zur
       Fensterkante; die Baender sind vollbreit, ihr INHALT liegt auf
       `--op-mass` — siehe die Bandregel weiter unten. */
    --op-mass: 94rem;
    --op-rand: max(1.25rem, 3vw);

    /* Die Ecken. Vorgabe eckig, wie beim Widget (`--axo3-radius`): eine
       gerundete Variante ist eine WAHL und kommt als eigener Schritt. */
    --op-radius: 0px;
}

/* Die SCHRIFTEN der Seite. `schrift` ist die Familie, die `page.php` per
   @font-face anmeldet - sie gibt es nur, wenn der Kunde eine gewaehlt oder
   eine hochgeladen hat; steht keine bereit, greift der Rueckfall, und die
   Seite sieht aus wie vorher.

   ⚠️ NICHT `--op-schrift-*`: `--op-schrift` ist die TEXTFARBE (der `theme`-
   Block der template.json nennt sie so). Zwei Variablen, die fast gleich
   heissen und Verschiedenes meinen, liest niemand richtig.

   `--op-familie-titel` faellt auf `--op-familie-text` zurueck. Eine eigene
   Schrift fuer Ueberschriften gibt es in der Maske noch nicht; die Variable
   steht schon hier, damit sie spaeter keine Datei im Site-Ordner umbenennt. */
:root {
    --op-familie-text:  schrift, system-ui, -apple-system, "Segoe UI", Helvetica, Arial, sans-serif;
    --op-familie-titel: var(--op-familie-text);
}

* { box-sizing: border-box; }

html { scroll-behavior: smooth; }

body.op {
    margin: 0;
    background: var(--op-grund);
    color: var(--op-schrift);
    font: 16px/1.5 var(--op-familie-text);
    /* Der Seitenkoerper scrollt NIE waagrecht — was breit ist, scrollt in
       seinem eigenen Rahmen. */
    overflow-x: hidden;
}

img { max-width: 100%; height: auto; }

a { color: inherit; }

/* ── Das Band ───────────────────────────────────────────────────────────────
   Jedes Band ist VOLLBREIT (damit ein dunkler Grund bis an die Fensterkante
   reicht), sein Inhalt liegt auf `--op-mass`. Das geschieht ueber das
   Innenmass, nicht ueber einen zweiten Wrapper — das Markup hat keinen, und
   `page.php` soll fuer eine Gestaltungsfrage keinen bekommen. */
.op-kopf,
.op main > section,
.op-fuss,
.op-legal {
    padding-block: clamp(2.5rem, 6vw, 4.5rem);
    padding-inline: max(var(--op-rand), calc((100% - var(--op-mass)) / 2));
}

/* ── Kopfzeile ──────────────────────────────────────────────────────────────
   Bleibt beim Scrollen oben, wie im Vorbild. Sie traegt den Seitengrund, damit
   der dunkle Hero unter ihr durchlaeuft statt an ihr zu kleben. */
.op-kopf {
    position: sticky;
    top: 0;
    z-index: 6;
    background: var(--op-grund);
    padding-block: 1rem;
    display: flex;
    align-items: center;
    gap: 1rem;
    flex-wrap: wrap;
}

/* Das Logo ist eine KUNDENDATEI und liegt ausserhalb des Release, im
   Site-Ordner neben dieser Datei. Die Regel steht trotzdem hier: die
   Gestaltung ist unsere, die Datei ist seine. */
.op-kopf__logo { display: block; max-height: 3rem; width: auto; margin: 0; }
.op-kopf__name { margin: 0; font-family: var(--op-familie-titel); font-weight: 800; font-size: clamp(1.15rem, 2.4vw, 1.4rem); }

/* ── Der erste Eindruck ─────────────────────────────────────────────────────
   Das dunkle Band: Grund und Schrift getauscht. */
.op-hero {
    background: var(--op-schrift);
    color: var(--op-grund);
    padding-block: clamp(3.5rem, 10vw, 6.5rem);
}
.op-hero h1 {
    margin: 0 0 2rem;
    font-family: var(--op-familie-titel);
    font-weight: 800;
    font-size: clamp(2.25rem, 6vw, 5.5rem);
    line-height: 1.12;
    letter-spacing: -0.01em;
    max-width: 20ch;
}
.op-hero__lead {
    margin: 0 0 1.5rem;
    font-weight: 800;
    font-size: clamp(1.25rem, 2.6vw, 2.2rem);
    line-height: 1.3;
    max-width: 40ch;
}
.op-hero__text {
    margin: 0;
    font-size: clamp(1.1rem, 2vw, 1.55rem);
    line-height: 1.5;
    max-width: 60ch;
}

/* Die Pille. Sie traegt den Akzent — das ist die Stelle, an der eine Farbwahl
   auf jeder Seite sichtbar wird, auch ohne Stoerer. */
.op-cta {
    display: inline-flex;
    align-items: center;
    margin-top: 2rem;
    padding: 1rem 1.75rem;
    background: var(--op-akzent);
    color: var(--op-aufakzent);
    font-weight: 800;
    font-size: 1.0625rem;
    text-decoration: none;
    border-radius: 999px;
}

/* ── Stoerer ────────────────────────────────────────────────────────────────
   Die Kugel oben rechts, wie im Vorbild: mitlaufend, leicht gedreht, im
   Akzent. Er ist ein Geschwister des Hero, kein Kind — darum `fixed` und die
   eigene Ausrichtung am Mass. */
.op-stoerer {
    position: fixed;
    top: 5.5rem;
    right: max(var(--op-rand), calc((100vw - var(--op-mass)) / 2));
    z-index: 5;
    width: clamp(7rem, 16vw, 13.5rem);
    aspect-ratio: 1 / 1;
    display: flex;
    align-items: center;
    justify-content: center;
    padding: 1.5rem;
    background: var(--op-akzent);
    color: var(--op-aufakzent);
    border-radius: 50%;
    transform: rotate(8deg);
    text-align: center;
    font-weight: 800;
    font-size: clamp(.85rem, 1.9vw, 1.5rem);
    line-height: 1.2;
    text-decoration: none;
}
a.op-stoerer { transition: transform .15s ease; }
a.op-stoerer:hover { transform: rotate(-8deg) scale(1.04); }

/* ── Ablauf ─────────────────────────────────────────────────────────────────
   Drei Spalten mit grossen Ziffern. */
.op-prozess h2,
.op-objekte h2,
.op-kontakt h2 {
    margin: 0 0 2.5rem;
    font-family: var(--op-familie-titel);
    font-weight: 800;
    font-size: clamp(1.9rem, 4vw, 3.25rem);
    line-height: 1.15;
    letter-spacing: -0.01em;
}

.op-prozess__liste {
    list-style: none;
    margin: 0;
    padding: 0;
    display: grid;
    grid-template-columns: repeat(3, 1fr);
    gap: 3rem 2.5rem;
}
.op-prozess__nr {
    display: block;
    font-family: var(--op-familie-titel);
    font-weight: 800;
    font-size: clamp(2.5rem, 7.5vw, 7.75rem);
    line-height: 1;
}
.op-prozess__schritt h3 {
    margin: .5rem 0 .5rem;
    font-weight: 800;
    font-size: clamp(1.2rem, 2.2vw, 1.55rem);
}
.op-prozess__schritt p {
    margin: 0;
    font-size: clamp(1.05rem, 2vw, 1.55rem);
    line-height: 1.5;
    hyphens: auto;
    overflow-wrap: break-word;
}

/* ── Die Objekte ────────────────────────────────────────────────────────────*/
.op-objekte { scroll-margin-top: 6rem; }

/* ── Die Filterleiste ───────────────────────────────────────────────────────
   Das MARKUP kommt aus `Estate\Services\FilterBar` und ist Zeichen fuer
   Zeichen dasselbe wie beim Widget — die Klassen und die `data-`Haken sind
   der Vertrag mit `widget-core.js`. Geteilt ist damit die STRUKTUR; wie die
   Leiste aussieht, steht hier, und `widget.css` reist nie mit. Darum stehen
   unten `axo3-`Namen in einer Datei, die sonst nur `op-` kennt: sie gehoeren
   nicht dieser Seite, sie sind der Name des Bauteils.

   Uebersetzt ist die Sprache der Seite: 2 px statt 1 px, fett statt halbfett,
   Ecken aus `--op-radius`, jede Farbe ein Token.

   ⚠️ Der Behaelter braucht die `[hidden]`-Regel. Das Skript blendet Zeilen
   und Gruppen mit `hidden` aus — und eine Klasse mit `display:` (`.op-karte`
   ist Flex, `.op-karten` ein Raster) schlaegt die `[hidden]`-Regel des
   Browsers, weil sie aus einem anderen URSPRUNG kommt, nicht wegen der
   Spezifitaet. Ohne diese Zeile filterte das Skript sichtbar ins Leere.
   Dieselbe Regel steht aus demselben Grund in `widget.css`. */
.op-bestand [hidden] { display: none; }

.axo3-widget__filter {
    display: flex;
    flex-wrap: wrap;
    align-items: stretch;
    gap: .75rem;
    margin-bottom: 2rem;
}

.axo3-filter__reset-row { flex-basis: 100%; }
.axo3-filter__reset {
    display: inline-flex;
    align-items: center;
    height: 2.625rem;
    padding: 0 1.1rem;
    border: 2px solid var(--op-schrift);
    border-radius: var(--op-radius);
    background: var(--op-schrift);
    color: var(--op-grund);
    font: inherit;
    font-size: .8125rem;
    font-weight: 800;
    cursor: pointer;
}
.axo3-filter__reset:hover { background: var(--op-akzent); border-color: var(--op-akzent); color: var(--op-aufakzent); }

/* Hoechstens drei Schachteln nebeneinander, gleiche Breite ueber alle Reihen
   — dieselbe Rechnung wie im Widget (v1.11.6): eine Spalte ist nie schmaler
   als 12rem UND nie schmaler als ein Drittel. */
.axo3-filter__row {
    flex-basis: 100%;
    display: grid;
    grid-template-columns: repeat(auto-fit, minmax(max(12rem, (100% - 1.5rem) / 3), 1fr));
    gap: .75rem;
}

.axo3-filter__box {
    position: relative;
    /* Die Breite sagt das Raster; `min-width: 0` laesst die Zusammenfassung
       kuerzen, statt die Spalte aufzudruecken. */
    min-width: 0;
    border: 2px solid var(--op-schrift);
    border-radius: var(--op-radius);
    background: var(--op-grund);
}
.axo3-filter__toggle {
    width: 100%;
    display: flex;
    align-items: center;
    gap: .75rem;
    padding: .5rem 1rem;
    text-align: left;
    font: inherit;
    color: inherit;
    background: none;
    border: 0;
    cursor: pointer;
}
.axo3-filter__labels { flex: 1; min-width: 0; }
.axo3-filter__label {
    display: block;
    font-size: .6875rem;
    font-weight: 800;
    letter-spacing: .08em;
    text-transform: uppercase;
}
.axo3-filter__summary {
    display: block;
    margin-top: 1px;
    font-size: .95rem;
    white-space: nowrap;
    overflow: hidden;
    text-overflow: ellipsis;
}
.axo3-filter__arrow {
    display: inline-flex;
    flex: 0 0 auto;
    width: .75em;
    height: .7em;
    transition: transform .18s ease;
}
.axo3-filter__arrow svg { display: block; width: 100%; height: 100%; }
.axo3-filter__box.is-open .axo3-filter__arrow { transform: rotate(180deg); }

/* Das Blatt haengt UNTER der Schachtel und deckt die Liste zu — darum ein
   Grund, nie durchsichtig. Die 2 px des Rahmens werden mit negativen Raendern
   zur Deckung gebracht, damit die offene Schachtel eine Saeule bleibt. */
.axo3-filter__panel {
    position: absolute;
    top: 100%;
    left: -2px;
    right: -2px;
    z-index: 5;
    max-height: 60vh;
    margin-top: 2px;
    padding: .4rem 0;
    overflow-y: auto;
    border: 2px solid var(--op-schrift);
    border-radius: var(--op-radius);
    background: var(--op-grund);
}
.axo3-filter__panel[hidden] { display: none; }

.axo3-filter__opt {
    display: flex;
    align-items: center;
    gap: .6rem;
    padding: .35rem 1rem;
    font-size: .9rem;
    cursor: pointer;
}
.axo3-filter__opt:hover { background: var(--op-flaeche); }
/* Der Haken ist unsichtbar, nicht abwesend: er bleibt bedienbar und
   fokussierbar, gezeichnet wird die Marke daneben. */
.axo3-filter__opt input {
    position: absolute;
    width: 1px;
    height: 1px;
    opacity: 0;
    pointer-events: none;
}
.axo3-filter__mark {
    display: inline-flex;
    flex: 0 0 auto;
    align-items: center;
    justify-content: center;
    width: 1rem;
    height: 1rem;
    border: 2px solid var(--op-schrift);
    border-radius: calc(var(--op-radius) / 2);
    background: var(--op-grund);
    color: var(--op-grund);
}
.axo3-filter__mark svg { display: none; }
.axo3-filter__opt input:checked + .axo3-filter__mark { background: var(--op-schrift); }
.axo3-filter__opt input:checked + .axo3-filter__mark svg { display: block; }
.axo3-filter__opt input:focus-visible + .axo3-filter__mark { outline: 2px solid var(--op-akzent); outline-offset: 2px; }
.axo3-filter__opt-text { flex: 1 1 auto; }
.axo3-filter__opt-count { font-size: .8rem; color: var(--op-leise); font-variant-numeric: tabular-nums; }
/* Ein Wert, den das aktuelle Ergebnis nicht mehr enthaelt — waehlbar, aber
   unterschieden. */
.axo3-filter__opt.is-empty .axo3-filter__opt-text,
.axo3-filter__opt.is-empty .axo3-filter__opt-count { color: var(--op-leise); }

.axo3-filter__foot {
    flex-basis: 100%;
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    gap: .6rem;
}
.axo3-widget__count { font-size: .8125rem; color: var(--op-leise); font-variant-numeric: tabular-nums; }
.axo3-filter-chips { display: flex; flex-wrap: wrap; gap: .4rem; }
.axo3-filter-chip {
    display: inline-flex;
    align-items: center;
    gap: .35rem;
    padding: .15rem .6rem;
    border: 2px solid var(--op-schrift);
    border-radius: var(--op-radius);
    background: var(--op-flaeche);
    color: var(--op-schrift);
    font: inherit;
    font-size: .8rem;
    font-weight: 800;
    cursor: pointer;
}
.axo3-filter-chip__x { font-weight: 800; }

/* Die Preisgrenzen — zwei Auswahlfelder, hart wie alles andere. */
.axo3-filter__panel--range { padding: .6rem .8rem; display: grid; gap: .5rem; }
.axo3-filter__range-row { display: flex; align-items: center; gap: .6rem; font-size: .9rem; }
.axo3-filter__range-word { flex: 0 0 2rem; color: var(--op-leise); }
.axo3-filter__range-row select {
    flex: 1;
    min-width: 0;
    padding: .3rem .4rem;
    border: 2px solid var(--op-schrift);
    border-radius: var(--op-radius);
    background: var(--op-grund);
    color: var(--op-schrift);
    font: inherit;
    font-size: .9rem;
}

/* ── Die erweiterte Gestalt ─────────────────────────────────────────────────
   Reiter · Schnell-Schachteln · «Weitere Filter» · die Trefferpille. Die
   Schachtel ist dieselbe wie oben, nur ihr PLATZ ist ein anderer. Sie steht
   hier, bevor eine Maske sie waehlbar macht: eine Gestalt, die der Eintrag
   kennt und die Seite nicht kleidet, waere ein Zaun, den niemand sieht. */
.axo3-filter__bar {
    flex-basis: 100%;
    display: flex;
    flex-wrap: wrap;
    align-items: stretch;
    gap: .75rem;
}
.axo3-filter__bar .axo3-filter__box { flex: 1 1 11rem; min-width: 11rem; max-width: 18rem; }

.axo3-filter__tabs {
    display: inline-flex;
    align-items: stretch;
    border: 2px solid var(--op-schrift);
    border-radius: var(--op-radius);
    background: var(--op-grund);
    /* Der RAHMEN rundet, die Reiter bleiben eckig — `overflow` schneidet die
       Fuellung des aktiven an den Aussenecken zu. */
    overflow: hidden;
}
.axo3-filter__tab {
    padding: .5rem 1rem;
    border: 0;
    border-radius: 0;
    background: none;
    color: var(--op-schrift);
    font: inherit;
    font-size: .9rem;
    font-weight: 800;
    cursor: pointer;
}
.axo3-filter__tab + .axo3-filter__tab { border-left: 2px solid var(--op-schrift); }
.axo3-filter__tab.is-active { background: var(--op-schrift); color: var(--op-grund); }

.axo3-filter__more {
    position: relative;
    display: inline-flex;
    align-items: center;
    gap: .4rem;
    padding: .5rem 1rem;
    border: 2px solid var(--op-akzent);
    border-radius: var(--op-radius);
    background: var(--op-grund);
    color: var(--op-akzent);
    font: inherit;
    font-size: .9rem;
    font-weight: 800;
    cursor: pointer;
}
.axo3-filter__more-dot {
    position: absolute;
    top: .3rem;
    right: .3rem;
    width: .45rem;
    height: .45rem;
    border-radius: 50%;
    background: var(--op-akzent);
}
.axo3-filter__more-dot[hidden] { display: none; }

.axo3-filter__hits {
    display: inline-flex;
    align-items: center;
    margin-left: auto;
    padding: .5rem 1rem;
    border: 2px solid var(--op-akzent);
    border-radius: var(--op-radius);
    background: var(--op-akzent);
    color: var(--op-aufakzent);
    font-size: .9rem;
    font-weight: 800;
    white-space: nowrap;
}

/* Das Blatt — eine Lage ueber der Seite. */
.axo3-filter__overlay {
    position: fixed;
    inset: 0;
    z-index: 50;
    display: flex;
    align-items: center;
    justify-content: center;
    padding: 1rem;
    background: var(--op-schleier);
}
.axo3-filter__overlay[hidden] { display: none; }
.axo3-filter__sheet {
    display: flex;
    flex-direction: column;
    width: 100%;
    max-width: 26rem;
    max-height: 90vh;
    border: 2px solid var(--op-schrift);
    border-radius: var(--op-radius);
    background: var(--op-grund);
    color: var(--op-schrift);
}
.axo3-filter__sheet-head {
    display: flex;
    align-items: center;
    gap: .75rem;
    padding: 1rem 1.25rem;
    border-bottom: 2px solid var(--op-linie);
}
.axo3-filter__sheet-title { flex: 1; font-weight: 800; font-size: 1.05rem; }
.axo3-filter__sheet-reset {
    padding: 0;
    border: 0;
    background: none;
    color: var(--op-akzent);
    font: inherit;
    font-size: .8rem;
    text-decoration: underline;
    cursor: pointer;
}
.axo3-filter__sheet-close {
    padding: .1rem .35rem;
    border: 0;
    background: transparent;
    color: var(--op-leise);
    font-size: 1.4rem;
    line-height: 1;
    cursor: pointer;
}
.axo3-filter__sheet-close:hover { color: var(--op-schrift); }
/* ⚠️ Der Koerper scrollt, der Fuss nie — ein Knopf unterhalb des sichtbaren
   Randes ist eine Falle (Lehre aus `be-modal`). */
.axo3-filter__sheet-body { padding: .75rem 1.25rem; overflow-y: auto; }
.axo3-filter__sheet-foot { padding: .9rem 1.25rem; border-top: 2px solid var(--op-linie); }
.axo3-filter__apply {
    width: 100%;
    padding: .6rem 1rem;
    border: 2px solid var(--op-akzent);
    border-radius: var(--op-radius);
    background: var(--op-akzent);
    color: var(--op-aufakzent);
    font: inherit;
    font-size: .95rem;
    font-weight: 800;
    cursor: pointer;
}

/* Ein Abschnitt im Blatt: dieselbe Gruppe, offen, ohne Klappe. */
.axo3-filter__sec { padding: .5rem 0; }
.axo3-filter__sec + .axo3-filter__sec { border-top: 2px solid var(--op-linie); }
.axo3-filter__sec-label {
    display: block;
    padding: .25rem 0 .2rem;
    font-size: .6875rem;
    font-weight: 800;
    letter-spacing: .08em;
    text-transform: uppercase;
}
.axo3-filter__sec .axo3-filter__opt { padding: .35rem .25rem; }

.op-liste { margin: 0 0 4rem; }
.op-liste:last-child { margin-bottom: 0; }
.op-liste__titel {
    margin: 0 0 1.5rem;
    font-family: var(--op-familie-titel);
    font-weight: 800;
    font-size: clamp(1.35rem, 2.8vw, 2.1rem);
    letter-spacing: -0.01em;
}
.op-liste__leer {
    margin: 0;
    padding: 2rem 1.5rem;
    border: 2px solid var(--op-linie);
    border-radius: var(--op-radius);
    color: var(--op-leise);
}

/* Eine breite Tabelle scrollt hier drin, nicht im Dokument. Der harte Rahmen
   sitzt am Scrollkasten, damit er die ganze Gruppe fasst. */
.op-tabelle__rahmen {
    overflow-x: auto;
    border: 3px solid var(--op-schrift);
    border-radius: var(--op-radius);
}
.op-tabelle {
    width: 100%;
    border-collapse: collapse;
    font-variant-numeric: tabular-nums;
}
.op-tabelle th,
.op-tabelle td {
    text-align: left;
    padding: 1rem 1.25rem;
    white-space: nowrap;
}
/* Der dunkle Kopf — der markanteste Zug der Vorlage. */
.op-tabelle thead th {
    background: var(--op-schrift);
    color: var(--op-grund);
    font-weight: 800;
    font-size: .95rem;
}
.op-tabelle tbody tr + tr td { border-top: 1px solid var(--op-linie); }
.op-tabelle tbody tr:hover td { background: var(--op-flaeche); }

/* Die Karten — dieselbe harte Sprache wie die Tabelle. */
.op-karten {
    display: grid;
    gap: 1.5rem;
    grid-template-columns: repeat(auto-fill, minmax(18rem, 1fr));
}
.op-karte {
    display: flex;
    flex-direction: column;
    gap: .5rem;
    padding: 1.25rem;
    border: 2px solid var(--op-schrift);
    border-radius: var(--op-radius);
}
.op-karte__bild {
    display: block;
    width: calc(100% + 2.5rem);
    margin: -1.25rem -1.25rem .75rem;
    aspect-ratio: 4 / 3;
    object-fit: cover;
    background: var(--op-flaeche);
}
.op-karte__titel { margin: 0; font-weight: 800; font-size: 1.2rem; }
.op-karte__status { margin: 0; font-size: .95rem; color: var(--op-leise); }
.op-karte__meta { margin: 0; font-size: .95rem; }
.op-karte__preis { margin: 0; font-weight: 800; font-variant-numeric: tabular-nums; }
.op-karte__wege { margin: .75rem 0 0; display: flex; flex-wrap: wrap; gap: .5rem; }

/* Jeder Weg ist ein harter Knopf — in Tabelle und Karte derselbe. */
.op-weg {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    height: 2.625rem;
    padding: 0 .875rem;
    border: 2px solid var(--op-schrift);
    border-radius: var(--op-radius);
    color: var(--op-schrift);
    background: none;
    font-weight: 800;
    font-size: .8125rem;
    white-space: nowrap;
    text-decoration: none;
}
.op-weg:hover {
    background: var(--op-akzent);
    border-color: var(--op-akzent);
    color: var(--op-aufakzent);
}

/* ── Die Isometrie ──────────────────────────────────────────────────────────
   Dieselbe Mechanik wie beim Widget (B6), eine andere Gestalt. Die
   `axo3-iso__*`-Klassen sind der Vertrag mit dem Skript-Kern; gestaltet wird
   ueber die `op-`Klassen daneben, wo eine eigene Sprache noetig ist.

   ⚠️ **Keine grosse Ansicht, kein Griff** (Entscheid 2026-09-16, im Markup
   begruendet): das Widget steckt in einem kleinen Kasten auf einer fremden
   Seite und oeffnet darum eine bildschirmfuellende Lage. Diese Seite IST die
   Seite. Auf schmalen Schirmen steht die Buehne ueber der Liste (`order`),
   auf breiten daneben. Darum fehlen hier alle `--iso-fs`-Regeln des Widgets
   — und darum darf `--axo3-iso-shape` nie `handle` werden: der Kern liest den
   Wert und liesse die Buehne sonst ungeladen (`start()`, drittes Tor). */
.axo3-widget__cols {
    display: grid;
    grid-template-columns: minmax(0, 1fr);
    gap: 2rem;
}
.axo3-widget__main { min-width: 0; }
.axo3-widget__isoside {
    min-width: 0;
    /* Auf schmalen Schirmen ueber der Liste: das Gebaeude ist der Einstieg,
       die Liste die Vertiefung. */
    order: -1;
    --axo3-iso-shape: stage;
}

@media (min-width: 62rem) {
    .axo3-widget__cols { grid-template-columns: minmax(0, 3fr) minmax(19rem, 1fr); align-items: start; }
    /* ⚠️ `is-solo` setzt der Kern, wenn das Ergebnis keine gebundene
       Liegenschaft mehr traegt: die Spalte faellt weg und die Liste nimmt die
       volle Breite. Ohne diese Zeile bliebe ein reservierter Streifen Nichts
       stehen. */
    .axo3-widget__cols.is-solo { grid-template-columns: minmax(0, 1fr); }
    .axo3-widget__isoside {
        order: 0;
        position: sticky;
        /* Die Kopfzeile klebt oben und ist rund 5rem hoch — die Buehne darf
           nicht darunter verschwinden. */
        top: 5.5rem;
    }
}

.axo3-iso__title {
    margin: 0 0 .6rem;
    font-family: var(--op-familie-titel);
    font-weight: 800;
    font-size: 1.1rem;
}

/* Der Anreisser steht anstelle der Buehne, solange das Ergebnis mehr als eine
   Liegenschaft traegt — ein Kurzweg in den Filter, kein eigener Zustand. */
.axo3-iso__teaser { display: grid; gap: .75rem; }
.axo3-iso__pick {
    display: grid;
    gap: .15rem;
    width: 100%;
    padding: .9rem 1rem;
    border: 2px solid var(--op-schrift);
    border-radius: var(--op-radius);
    background: var(--op-grund);
    color: var(--op-schrift);
    font: inherit;
    text-align: left;
    cursor: pointer;
}
.axo3-iso__pick:hover { background: var(--op-flaeche); }
.axo3-iso__pick-name { font-weight: 800; }
.axo3-iso__pick-ort,
.axo3-iso__pick-count { font-size: .85em; color: var(--op-leise); }
.axo3-iso__pick-word { margin-top: .25rem; font-size: .85em; font-weight: 800; color: var(--op-akzent); }

.axo3-iso__widget { position: relative; }

/* ⚠️ Das Embed fuehrt KEINE Wohnungsliste, nirgends (Entscheid Peter,
   2026-09-03): das Panel «Einheiten» ist Generator-Chrome, das jedes Polygon
   aufzaehlt — ohne Sichtbarkeit, ohne Filter, ohne Status. Die Quelle der
   Wahrheit sind die ZEILEN dieser Seite. Bis der Generator es weglaesst,
   versteckt das Blatt es; ein Satz von frueher faellt damit nicht aus dem
   Rahmen. Der 3D-Fuss (Dreh-Regler) geht denselben Weg — unsere Leiste hat
   «Drehen» und die vier Ecken. */
/* ⚠️ DREI Klassen in der Kette, und das ist tragend, nicht Geschmack: das
   Blatt des Satzes (`iso2d.css`, `iso3d.css`) wird zur LAUFZEIT geladen und
   steht damit NACH dieser Datei. Es scoped auf `.iso-app .panel` — zwei
   Klassen. Eine Regel mit ebenfalls zwei Klassen verliert dann bei gleicher
   Spezifitaet gegen die spaeter geladene, und das Panel steht da. Genau so
   gemessen am 2026-09-16, im Bild: «EINHEITEN», 60 Wohnungen, unter der
   Buehne. Das Widget hat die dritte Klasse aus demselben Grund. */
.op-bestand .axo3-widget__isoside .iso-foot,
.op-bestand .axo3-widget__isoside .grab,
.op-bestand .axo3-widget__isoside .panel,
.op-bestand .axo3-widget__isoside .i3grab,
.op-bestand .axo3-widget__isoside .i3panel,
.op-bestand .axo3-widget__isoside .i3footer { display: none; }

/* ⚠️ Kein `transform: scale` auf der Buehne — das 3D-Picking rechnet in
   CSS-Pixeln —, und beide Buehnen tragen DIESELBE Box (Fit-Box-Paritaet
   2D/3D), sonst springt das Gebaeude beim Umschalten. */
.axo3-widget__isoside .stage,
.axo3-widget__isoside .i3stage { min-height: 22rem; min-width: 0; }

.axo3-iso__bar {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    gap: .4rem;
    margin-top: .75rem;
}
/* ⚠️ `inline-flex` und nicht `none` wie im Widget: dort ist der Umschalter
   der grossen Ansicht vorbehalten, weil die Spalte im Kasten zu schmal ist.
   Hier gibt es keine grosse Ansicht — also stehen 2D/3D und die vier Ecken
   da, wo sie hingehoeren. Die Sichtbarkeit je Satz-Variante zieht der Kern
   ueber `style="display:…"` nach; diese Regel ist nur der Ausgangspunkt. */
.axo3-iso__switch { display: inline-flex; gap: .25rem; }
/* Die vier Ecken sind AXO3-Chrome ueber die Init-API (`setView` fuer 2D,
   `rotateTo` fuer 3D) — der Embed wird seit 2026-08-18 kopflos gebaut. Im
   Widget stehen sie nur in der grossen Ansicht; hier gibt es keine, also
   stehen sie an der Leiste. Die Regel steht ausdruecklich da, obwohl sie
   dasselbe sagt wie die Zeile darueber: sie ist die STELLE, an der der
   Unterschied zum Widget nachzulesen ist. */
.axo3-iso__views { display: inline-flex; }
.axo3-iso__mode {
    padding: .3rem .7rem;
    border: 2px solid var(--op-schrift);
    border-radius: var(--op-radius);
    background: var(--op-grund);
    color: var(--op-schrift);
    font: inherit;
    font-size: .8rem;
    font-weight: 800;
    cursor: pointer;
}
.axo3-iso__mode.is-on { background: var(--op-schrift); color: var(--op-grund); }

/* Die gekoppelte Zeile (Isometrie → Liste). Ein Strich am Rand, keine
   Flaeche: in der Tabelle traegt schon der Hover eine. */
.op-bestand [data-axo3-unit].axo3-row-hl {
    background: var(--op-flaeche);
    box-shadow: inset 3px 0 0 var(--op-akzent);
}

/* ⚠️ Die Wartemarke schaltet ueber `hidden`. Sie steht darum auf einem Element
   OHNE display-Regel — eine Klasse mit `display:` wuerde `[hidden]` schlagen
   (Ursprung, nicht Spezifitaet), und das Skript schaltete ins Leere. */
.op-warte { color: var(--op-leise); }

/* ── Kontakt und Fuss ───────────────────────────────────────────────────────
   Das zweite dunkle Band, wie im Vorbild bis zum Seitenende durchgehend. */
.op-kontakt,
.op-fuss {
    background: var(--op-schrift);
    color: var(--op-grund);
}
.op-kontakt p { margin: 0; font-size: 1.25rem; max-width: 40ch; }
.op-kontakt a { font-weight: 800; }

.op-fuss { padding-block: 2rem; }
.op-fuss p { margin: 0 0 .75rem; font-size: .875rem; color: var(--op-leise); }
.op-fuss__wege { display: flex; flex-wrap: wrap; gap: 1.5rem; }
.op-fuss__wege a { font-size: .875rem; text-decoration: none; }
.op-fuss__wege a:hover { text-decoration: underline; }

/* ── Das Detail ─────────────────────────────────────────────────────────────
   Das Fragment aus `/detail` — heute noch von keinem Skript geholt; die Regeln
   stehen hier, damit es nicht ungestaltet erscheint, sobald es geholt wird. */
.op-detail {
    background: var(--op-flaeche);
    border: 3px solid var(--op-schrift);
    border-radius: var(--op-radius);
    padding: 1.5rem;
}
.op-detail__titel { margin: 0 0 1rem; font-family: var(--op-familie-titel); font-weight: 800; font-size: clamp(1.35rem, 3vw, 1.875rem); }
.op-detail__bilder { display: grid; gap: .5rem; grid-template-columns: repeat(auto-fill, minmax(12rem, 1fr)); }
.op-detail__fakten { display: grid; grid-template-columns: repeat(auto-fit, minmax(9.5rem, 1fr)); gap: 1rem 1.5rem; margin: 1.5rem 0; }
.op-detail__fakten dt { font-weight: 800; font-size: .75rem; text-transform: uppercase; letter-spacing: .03em; }
.op-detail__fakten dd { margin: .25rem 0 0; font-variant-numeric: tabular-nums; }
.op-detail__text { margin: 0; line-height: 1.6; }

/* ── Impressum und Datenschutz ──────────────────────────────────────────────
   Ruhiger Satz nach dem Vorbild: schmales Mass, und die Ueberschriften sind so
   gross wie der Fliesstext — nur schwerer. */
.op-legal {
    --op-mass: 50rem;
    padding-block: clamp(3rem, 8vw, 5.5rem);
}
.op-legal h1 { margin: 0 0 1em; font-family: var(--op-familie-titel); font-weight: 800; font-size: 1em; }
.op-legal h2 { margin: 2em 0 .25em; font-weight: 800; font-size: 1em; }
.op-legal__text { margin: 0 0 1em; line-height: 1.45; }
.op-legal__text:last-child { margin-bottom: 0; }
.op-legal a { text-decoration: underline; }

/* ── Schmale Fenster ────────────────────────────────────────────────────────*/
@media (max-width: 45rem) {
    :root { --op-rand: 7vw; }

    .op-prozess__liste { grid-template-columns: 1fr; gap: 2rem; }

    .op-stoerer { top: 4.5rem; }

    /* Die Tabelle bleibt eine Tabelle und scrollt in ihrem Rahmen — sie hier
       aufzubrechen hiesse, die Spaltenueberschriften zu verlieren, und welche
       Spalten es gibt, entscheidet der Kunde im Katalog. Wer Karten will,
       waehlt Karten. */
    .op-tabelle th,
    .op-tabelle td { padding: .75rem 1rem; }
}
