// Am Waldrain, Lage v3: rein informativ. Karte, Distanzen, Umfeld, keine Bildstrecke.
const {
  SectionWord: LSectionWord, Reveal: LReveal, RevealImage: LRevealImage, LineMask: LLineMask,
} = window.Maison57DesignSystem_40d525;
const LSECTION = 'clamp(4rem, 8vw, 6.5rem)';
const LCountUp = window.Maison57DesignSystem_40d525.CountUp;

/* Distanz-Zeile — Mikroanimation 3: die Hairline zeichnet sich von links,
   die Zahl zählt hoch, gestaffelt 60ms pro Zeile. */
function DistRow({ label, value, index = 0, strong = false }) {
  const ref = React.useRef(null);
  const [vis, setVis] = React.useState(false);
  React.useEffect(() => {
    if (window.matchMedia('(prefers-reduced-motion: reduce)').matches) { setVis(true); return; }
    const el = ref.current;
    if (!el) return;
    let done = false;
    const show = () => { if (!done) { done = true; setVis(true); io.disconnect(); } };
    const io = new IntersectionObserver((es) => { if (es[0].isIntersecting) show(); }, { threshold: 0.4 });
    io.observe(el);
    const t = setTimeout(() => {
      const r = el.getBoundingClientRect();
      const vh = window.innerHeight || 800;
      if (r.top < vh + 80 && r.bottom > -80) show();
    }, 1000);
    return () => { clearTimeout(t); io.disconnect(); };
  }, []);
  const m = String(value).match(/^(\D*?)(\d+)(.*)$/);
  const delay = index * 60;
  return (
    <div ref={ref} style={{ opacity: vis ? 1 : 0, transition: `opacity 500ms ease ${delay}ms` }}>
      <div style={{ display: 'flex', justifyContent: 'space-between', alignItems: 'baseline', gap: 'var(--space-6)', padding: 'var(--space-4) 0' }}>
        <span style={{ fontFamily: 'var(--font-text)', fontSize: 'var(--text-small)', color: 'var(--umbra)' }}>{label}</span>
        <span className="tabular" style={{ fontFamily: strong ? 'var(--font-display)' : 'var(--font-text)', fontSize: strong ? 'clamp(1.1rem, 1.6vw, 1.4rem)' : 'var(--text-small)', color: strong ? 'var(--umbra)' : 'var(--umbra-60)', fontVariantNumeric: 'tabular-nums lining-nums' }}>
          {vis && m ? <><span>{m[1]}</span><LCountUp value={parseInt(m[2], 10)} delay={delay} duration={700} /><span>{m[3]}</span></> : value}
        </span>
      </div>
      <div style={{ borderBottom: '1px solid var(--sandstein)', transform: vis ? 'scaleX(1)' : 'scaleX(0)', transformOrigin: 'left', transition: `transform 700ms var(--ease-reveal) ${delay}ms` }}></div>
    </div>
  );
}

/* 1 · Auftakt ohne Bild: die Lage-Seite ist rein informativ, die Navigation
   steht von Beginn an auf Creme. Headline links, eine Zeile Einordnung rechts. */
function LageHero() {
  return (
    <section style={{ maxWidth: 'var(--content-max)', margin: '0 auto', padding: `clamp(4rem, 8vw, 7rem) var(--page-inset-lg) 0`, boxSizing: 'border-box' }}>
      <div className="m57-lagehero" style={{ display: 'grid', gridTemplateColumns: '1.4fr 1fr', gap: 'clamp(2rem, 5vw, 4rem)', alignItems: 'end' }}>
        <h1 style={{ fontFamily: 'var(--font-display)', fontWeight: 400, color: 'var(--umbra)', fontSize: 'clamp(2.5rem, 5vw, 4.5rem)', lineHeight: 1.08, letterSpacing: '-0.01em', margin: 0, maxWidth: '18ch' }}>
          <LLineMask>Wo der 17. Bezirk in den</LLineMask>
          <LLineMask delay={120}><span style={{ fontStyle: 'italic' }}>Wienerwald</span> übergeht.</LLineMask>
        </h1>
        <LReveal delay={300}>
          <p style={{ fontFamily: 'var(--font-text)', fontSize: 'var(--text-small)', lineHeight: 1.8, color: 'var(--umbra-90)', margin: 0, maxWidth: '38ch' }}>
            Nachreihengasse 5-7, 1170 Wien. Dornbach, am Rand des Wienerwalds, mit der Linie 43 direkt in die Stadt.
          </p>
        </LReveal>
      </div>
      <style>{`@media (max-width: 760px) { .m57-lagehero { grid-template-columns: 1fr !important; align-items: start !important; } }`}</style>
    </section>
  );
}

/* 2 · Makrolage — Sektionswort "Wien", zwei Textspalten + Distanz-Band. */
function Makrolage() {
  return (
    <section style={{ maxWidth: 'var(--content-max)', margin: '0 auto', padding: `${LSECTION} var(--page-inset-lg)` }}>
      <LSectionWord word="Wien">
        <div className="m57-cols2" style={{ display: 'grid', gridTemplateColumns: '1fr 1fr', gap: 'clamp(1.5rem, 4vw, 3rem)' }}>
          <LReveal>
            <p style={{ fontFamily: 'var(--font-text)', fontSize: 'var(--text-small)', lineHeight: 1.8, color: 'var(--umbra-90)', margin: 0 }}>
              Dornbach liegt am westlichen Stadtrand, dort, wo die Stadt in Weinberge und Wald übergeht. Die Nachreihengasse bildet den Rain davor.
            </p>
          </LReveal>
          <LReveal delay={140}>
            <p style={{ fontFamily: 'var(--font-text)', fontSize: 'var(--text-small)', lineHeight: 1.8, color: 'var(--umbra-90)', margin: 0 }}>
              Trotz der Lage nah am Waldrand sind die Wege kurz: Die Linie 43 fährt direkt Richtung Ring, mit dem Auto erreichen Sie die inneren Bezirke in wenigen Minuten.
            </p>
          </LReveal>
        </div>
        <div style={{ marginTop: 'clamp(2.5rem, 5vw, 4rem)', borderTop: '1px solid var(--sandstein)' }}>
          {window.M57_MACRO.map((m, i) => (
            <DistRow key={m.label} label={m.label} value={m.value} index={i} strong />
          ))}
        </div>
        <LReveal delay={200}>
          <p style={{ fontFamily: 'var(--font-text)', fontSize: 'var(--text-micro)', color: 'var(--umbra-60)', margin: 'var(--space-3) 0 0' }}>
            Richtwerte, abhängig von Tageszeit und Verkehr.
          </p>
        </LReveal>
      </LSectionWord>
      {/* Die Karte steht ausserhalb der Sektionswort-Spalte, damit sie die
          volle Inhaltsbreite bekommt und die linke Haelfte lesbar bleibt. */}
      <LageKarte />
    </section>
  );
}

/* 2b · Lagekarte als Kartenfahrt, wie bei Zimmermannplatz 6.
   Die Karte (assets/lage/lage-karte.svg, erzeugt mit tools/ai2svg.py aus der
   Illustrator-Datei) wird inline geladen, damit W-Pin, Linie 43, Radius, Pins
   und Hinweise einzeln animierbar sind. Ablauf auf der Zeitachse 0 bis 10:
   die Karte zoomt vom W-Pin auf, die Linie 43 und der Radius zeichnen sich,
   die Pins 1 bis 6 erscheinen nacheinander und die Legende geht im Takt mit,
   zum Schluss die Wegezeit-Hinweise.
   Desktop mit genug Hoehe: die Buehne steht (sticky im Scroller) fuer rund
   2,4 Bildschirmhoehen. Schmal: dieselbe Abfolge beim Durchscrollen, ohne
   Stehenbleiben. Reduzierte Bewegung oder Karte nicht geladen: fertige Karte.
   Ohne GSAP, mit demselben Scroller-Fortschritt wie die anderen Module. */
const LKARTE_SVG = '/assets/lage/lage-karte.svg?v=2';
const LKARTE_ORTE = [
  ['1', 'Straßenbahn 43, Station Neuwaldegg', 'direkt Richtung Ring'],
  ['2', 'Krankenhaus Göttlicher Heiland', 'Spital'],
  ['3', 'Schafbergbad', 'Freibad'],
  ['4', 'Sportzentrum Marswiese', 'Sport und Klettern'],
  ['5', 'Klee am Hanslteich', 'Restaurant'],
  ['6', 'Allgemeines Krankenhaus Wien', 'Universitätsklinikum'],
];
// Wegezeiten aus der Karte; auf schmalen Schirmen als Text unter der Legende
const LKARTE_WEGE = ['ca. 10 min zur Westeinfahrt', 'ca. 45 min zum Flughafen', 'ca. 25 min in den 1. Bezirk'];
/* Drei Modi: 'gross' Desktop, Buehne steht, Karte zoomt vom W-Pin auf.
   'mobil' Handy und Tablet hochkant, Buehne steht ebenfalls, aber mit Kamerafahrt:
   erst nah am Radius, wo Pins 1 bis 5 gut lesbar sind, zum Schluss heraus zur
   ganzen Karte mit Pin 6. 'flach' sehr niedrige Bildschirme (Handy quer):
   dieselbe Kamerafahrt beim Durchscrollen, ohne Anheften. */
const LK_MQ_GROSS = '(min-width: 1024px) and (min-height: 640px)';
const LK_MQ_MOBIL = '(max-width: 1023px) and (min-height: 560px)';
const lkModus = () => (window.matchMedia(LK_MQ_GROSS).matches ? 'gross' : window.matchMedia(LK_MQ_MOBIL).matches ? 'mobil' : 'flach');
const lkClamp = (v) => Math.max(0, Math.min(1, v));
const lkInOut = (k) => (k < 0.5 ? 2 * k * k : 1 - Math.pow(-2 * k + 2, 2) / 2);
const lkBack = (k, s = 2) => 1 + (s + 1) * Math.pow(k - 1, 3) + s * Math.pow(k - 1, 2);

function LageKarte() {
  const outerRef = React.useRef(null);
  const frameRef = React.useRef(null);
  const mapRef = React.useRef(null);
  const listRef = React.useRef(null);
  const [modus, setModus] = React.useState(lkModus);
  React.useEffect(() => {
    const ms = [LK_MQ_GROSS, LK_MQ_MOBIL].map((q) => window.matchMedia(q));
    const on = () => setModus(lkModus());
    ms.forEach((m) => (m.addEventListener ? m.addEventListener('change', on) : m.addListener(on)));
    return () => ms.forEach((m) => (m.removeEventListener ? m.removeEventListener('change', on) : m.removeListener(on)));
  }, []);

  React.useEffect(() => {
    const host = mapRef.current;
    if (!host) return;
    let aus = false, raf = 0;
    const reduced = window.matchMedia('(prefers-reduced-motion: reduce)').matches;
    const items = listRef.current ? Array.from(listRef.current.querySelectorAll('.lk-item')) : [];
    const alleGesehen = () => items.forEach((it) => it.classList.add('is-seen'));
    let aufraeumen = () => {};

    fetch(LKARTE_SVG).then((r) => (r.ok ? r.text() : Promise.reject(r.status))).then((txt) => {
      if (aus) return;
      host.innerHTML = txt.trim();
      const svg = host.querySelector('svg');
      if (!svg) return alleGesehen();
      svg.setAttribute('preserveAspectRatio', 'xMidYMid meet');
      const pins = Array.from(svg.querySelectorAll('.lmap__pin'));
      const home = svg.querySelector('.lmap__home');
      const radius = svg.querySelector('.lmap__radius path');
      const trams = Array.from(svg.querySelectorAll('.lmap__tram path'));
      const notes = Array.from(svg.querySelectorAll('.lmap__note'));
      const vb = svg.viewBox.baseVal;
      const [hx, hy] = home.dataset.tip.split(' ').map(Number);
      host.style.setProperty('--lk-origin', ((hx - vb.x) / vb.width * 100) + '% ' + ((hy - vb.y) / vb.height * 100) + '%');

      /* Hervorheben: Legende und Pin gegenseitig, Klick haelt fest */
      let fest = null;
      const fokus = (n) => {
        svg.classList.toggle('has-focus', !!n);
        pins.forEach((p) => p.classList.toggle('is-on', p.dataset.pin === String(n)));
        items.forEach((it) => it.classList.toggle('is-on', it.dataset.pin === String(n)));
      };
      const bind = (el, n) => {
        el.addEventListener('mouseenter', () => fokus(n));
        el.addEventListener('mouseleave', () => fokus(fest));
        el.addEventListener('click', () => { fest = fest === n ? null : n; fokus(fest); });
      };
      items.forEach((it) => { bind(it, it.dataset.pin); it.addEventListener('focus', () => fokus(it.dataset.pin)); it.addEventListener('blur', () => fokus(fest)); });
      pins.forEach((p) => bind(p, p.dataset.pin));

      if (reduced) { alleGesehen(); return; }
      host.parentNode.parentNode.classList.add('lk--anim');

      /* Radius zeichnen: Maske mit derselben Linie, deren Strich von 0 auf voll laeuft */
      const NS = 'http://www.w3.org/2000/svg';
      let maskLine = null, radiusLen = 0;
      if (radius) {
        radiusLen = radius.getTotalLength();
        const defs = document.createElementNS(NS, 'defs');
        const mask = document.createElementNS(NS, 'mask');
        mask.setAttribute('id', 'lkRadiusMask'); mask.setAttribute('maskUnits', 'userSpaceOnUse');
        mask.setAttribute('x', vb.x); mask.setAttribute('y', vb.y); mask.setAttribute('width', vb.width); mask.setAttribute('height', vb.height);
        maskLine = radius.cloneNode();
        maskLine.removeAttribute('stroke-dasharray');
        maskLine.setAttribute('stroke', '#fff'); maskLine.setAttribute('stroke-width', '40'); maskLine.setAttribute('fill', 'none');
        maskLine.style.strokeDasharray = radiusLen;
        mask.appendChild(maskLine); defs.appendChild(mask); svg.insertBefore(defs, svg.firstChild);
        radius.parentNode.setAttribute('mask', 'url(#lkRadiusMask)');
      }
      const tramLen = trams.map((t) => t.getTotalLength());
      trams.forEach((t, i) => { t.style.strokeDasharray = tramLen[i]; });

      let zuletzt = { count: -1, cur: -1 };
      const legende = (count, cur) => {
        if (count === zuletzt.count && cur === zuletzt.cur) return;
        zuletzt = { count, cur };
        items.forEach((it) => {
          const n = Number(it.dataset.pin);
          it.classList.toggle('is-seen', n <= count);
          if (!fest) it.classList.toggle('is-on', n === cur);
        });
      };

      /* Kamera fuer 'mobil' und 'flach': Ausschnitte in Kartenkoordinaten (Mitte, Breite) */
      const C0 = { x: hx, y: hy - 80, w: 760 };
      const C1 = { x: 820, y: 900, w: 1700 };
      const C2 = { x: vb.x + vb.width / 2, y: vb.y + vb.height / 2, w: vb.width };
      const mische = (a, b, k) => ({ x: a.x + (b.x - a.x) * k, y: a.y + (b.y - a.y) * k, w: Math.exp(Math.log(a.w) + (Math.log(b.w) - Math.log(a.w)) * k) });
      const kamera = (c) => {
        const fw = frameRef.current.clientWidth, fh = frameRef.current.clientHeight;
        const px = fw / vb.width, sc = vb.width / c.w;
        const tx = fw / 2 - (c.x - vb.x) * px * sc, ty = fh / 2 - (c.y - vb.y) * px * sc;
        host.style.transform = 'translate(' + tx.toFixed(1) + 'px, ' + ty.toFixed(1) + 'px) scale(' + sc.toFixed(4) + ')';
      };

      /* Zeichnet den Zustand fuer t (0 bis 10) */
      const zeichne = (t, modus) => {
        const gross = modus === 'gross';
        const zoomEnd = gross ? 3.8 : 2.4;
        if (gross) {
          const z = lkInOut(lkClamp(t / zoomEnd));
          host.style.transform = 'scale(' + (2.3 + (1 - 2.3) * z).toFixed(4) + ')';
        } else if (t <= 7) kamera(mische(C0, C1, lkInOut(lkClamp(t / zoomEnd))));
        else kamera(mische(C1, C2, lkInOut(lkClamp((t - 7) / 1.3))));
        const kh = lkClamp(t / 0.8);
        home.style.opacity = kh;
        home.style.transform = 'scale(' + (0.6 + 0.4 * lkBack(kh)).toFixed(4) + ')';
        if (maskLine) maskLine.style.strokeDashoffset = radiusLen * (1 - lkClamp((t - 0.3) / zoomEnd));
        trams.forEach((tr, i) => { tr.style.strokeDashoffset = tramLen[i] * (1 - lkClamp((t - 0.5 - i * 0.6) / zoomEnd)); });
        const step = (8.6 - zoomEnd) / pins.length;
        let count = 0;
        pins.forEach((p, i) => {
          // mobil: Pins 1 bis 5 in der Nahansicht, Pin 6 erst, wenn die Kamera herausfaehrt
          const beginn = gross ? zoomEnd + i * step : (i < 5 ? zoomEnd + i * 0.9 : 7.5);
          const dauer = gross ? step * 0.8 : 0.75;
          const k = lkClamp((t - beginn) / dauer);
          if (k >= 0.5) count++;
          p.style.opacity = k;
          p.style.transform = 'translateY(' + (60 * (1 - k)).toFixed(1) + 'px) scale(' + (0.4 + 0.6 * lkBack(k, 2.2)).toFixed(4) + ')';
        });
        notes.forEach((n, i) => {
          const k = lkClamp((t - 8.6 - i * 0.25) / 0.9);
          n.style.opacity = k;
          n.style.transform = 'translateY(' + (30 * (1 - k)).toFixed(1) + 'px)';
        });
        legende(count, t >= 8.6 ? 0 : count);
      };

      /* Scroll-Fortschritt, weich nachgezogen (wie scrub) */
      let ziel = 0, ist = 0;
      const fortschritt = () => {
        const vh = window.innerHeight || 800;
        const m = lkModus();
        if (m !== 'flach') {
          const r = outerRef.current.getBoundingClientRect();
          return { p: lkClamp(-r.top / Math.max(1, r.height - vh)), m };
        }
        const r = frameRef.current.getBoundingClientRect();
        const a = vh * 0.92, e = vh * 0.3 - r.height;
        return { p: lkClamp((a - r.top) / Math.max(1, a - e)), m };
      };
      let modusJetzt = 'gross';
      const tick = () => {
        raf = 0;
        ist += (ziel - ist) * 0.16;
        if (Math.abs(ziel - ist) < 0.0005) ist = ziel;
        zeichne(ist * 10, modusJetzt);
        if (ist !== ziel) raf = requestAnimationFrame(tick);
      };
      const onScroll = () => {
        const f = fortschritt(); ziel = f.p;
        if (f.m !== modusJetzt) { modusJetzt = f.m; zeichne(ist * 10, modusJetzt); }
        if (!raf) raf = requestAnimationFrame(tick);
      };
      const start = fortschritt(); ist = ziel = start.p; modusJetzt = start.m;
      // Erst nach dem Layout des neuen Modus zeichnen (Rahmenmasse fuer die Kamera)
      setTimeout(() => zeichne(ist * 10, modusJetzt), 0);
      // Scroll-Ereignisse in der Capture-Phase am Dokument: greift fuer den Seiten-Scroller
      // (window.__m57Scroller), auch wenn dieser nach einem Seitenwechsel neu angelegt wird.
      const opt = { capture: true, passive: true };
      document.addEventListener('scroll', onScroll, opt);
      window.addEventListener('resize', onScroll);
      aufraeumen = () => { document.removeEventListener('scroll', onScroll, opt); window.removeEventListener('resize', onScroll); };
    }).catch(() => { if (!aus) alleGesehen(); });

    return () => { aus = true; if (raf) cancelAnimationFrame(raf); aufraeumen(); };
  }, []);

  return (
    <React.Fragment>
    <div ref={outerRef} style={{ marginTop: 'clamp(2.5rem, 5vw, 4rem)', height: modus === 'gross' ? '340vh' : modus === 'mobil' ? '300vh' : 'auto' }}>
      <style>{`
        .lk-buehne { display: grid; grid-template-columns: minmax(0, 1fr) minmax(15rem, 19rem); gap: clamp(2rem, 4vw, 4rem); align-items: center; width: 100%; }
        @media (max-width: 1023px), (max-height: 639px) { .lk-buehne { grid-template-columns: 1fr; } }
        .lk-frame { position: relative; margin: 0; width: 100%; aspect-ratio: 2978.1 / 1932.3; overflow: hidden; background: var(--creme); }
        .lk-map { position: absolute; inset: 0; will-change: transform; transform-origin: var(--lk-origin, 25% 50%); }
        .lk-map > svg, .lk-map > img { display: block; width: 100%; height: 100%; }
        /* Kamera-Modus (mobil, flach): Rahmen hochformatiger, Karte in voller Breite darin verschoben */
        .lk-frame--cam { aspect-ratio: 1.3 / 1; }
        .lk-frame--cam .lk-map { inset: auto; left: 0; top: 0; width: 100%; height: auto; aspect-ratio: 2978.1 / 1932.3; transform-origin: 0 0; }
        .lk-frame--cam .lmap__notes { display: none; }
        .lk-frame--cam .lmap__pinbody { transform: scale(1.7); }
        .lk-frame--cam .lmap__pin.is-on .lmap__pinbody { transform: scale(2.1); }
        .lk-frame--cam .lmap__homebody { transform: scale(1.35); }
        .lk-buehne--mobil { gap: var(--space-5); }
        .lk-buehne--mobil .lk-item { padding: 0.45rem 0; }
        /* Handy: Legende kompakt, nur die Namen, damit Karte und Legende zusammen auf den Schirm passen */
        .lk-buehne--mobil .lk-zeile { display: none; }
        .lk-buehne--mobil .lk-name { font-size: var(--text-small); }
        .lmap { overflow: visible; }
        .lmap .lmap__t { font-family: var(--font-text); }
        .lmap .lmap__w { font-family: var(--font-display); }
        .lmap__pin, .lmap__home, .lmap__note { transform-box: fill-box; transform-origin: 50% 100%; }
        .lmap__pin { cursor: pointer; }
        .lmap__pinbody, .lmap__homebody { transform-box: fill-box; transform-origin: 50% 100%; transition: transform 0.45s var(--ease-reveal), opacity 0.45s var(--ease-reveal); }
        .lmap__pinbody { transform: scale(1.35); }
        .lmap__homebody { transform: scale(1.15); }
        .lmap.has-focus .lmap__pin:not(.is-on) .lmap__pinbody { opacity: 0.28; }
        .lmap__pin.is-on .lmap__pinbody { transform: scale(1.75); }
        /* Wegezeit-Hinweise sind fuer Print gesetzt; am Bildschirm vergroessert, vom Kreis weg */
        .lmap__notebody { transform-box: fill-box; }
        .lmap__note[data-note="westeinfahrt"] .lmap__notebody { transform-origin: 0 100%; transform: scale(2.3); }
        .lmap__note[data-note="flughafen"] .lmap__notebody { transform-origin: 0 100%; transform: scale(2.3); }
        .lmap__note[data-note="innenstadt"] .lmap__notebody { transform-origin: 0 0; transform: scale(2.3); }
        .lk-wege { list-style: none; margin: var(--space-4) 0 0; padding: 0; font-family: var(--font-text); font-size: var(--text-label); color: var(--umbra-90); }
        .lk-wege li { padding: 0.2rem 0; }
        .lk-liste { list-style: none; margin: 0; padding: 0; }
        .lk-item { display: grid; grid-template-columns: 2.2rem 1fr; gap: 0.75rem; align-items: baseline; width: 100%; text-align: left; padding: 0.7rem 0; background: none; border: none; border-top: 1px solid var(--sandstein); cursor: pointer; color: var(--umbra); font: inherit; transition: opacity 0.5s var(--ease-reveal); }
        .lk--anim .lk-item { opacity: 0.32; }
        .lk--anim .lk-item.is-seen { opacity: 1; }
        .lk-n { font-family: var(--font-text); font-weight: 600; font-size: var(--text-body); color: var(--waldgruen); font-variant-numeric: tabular-nums; transition: color 0.35s var(--ease-reveal); }
        .lk-item.is-on .lk-n, .lk-item:hover .lk-n, .lk-item:focus-visible .lk-n { color: var(--akzent); }
        .lk-item:focus-visible { outline: 1px solid var(--waldgruen); outline-offset: 2px; }
        .lk-name { display: block; font-family: var(--font-text); font-size: var(--text-body); line-height: 1.35; }
        .lk-zeile { display: block; margin-top: 0.15rem; font-family: var(--font-text); font-size: var(--text-label); color: var(--umbra-60); }
        @media (prefers-reduced-motion: reduce) { .lk--anim .lk-item { opacity: 1; } }
      `}</style>
      <div style={{ position: modus === 'flach' ? 'relative' : 'sticky', top: 0, height: modus === 'flach' ? 'auto' : '100vh', display: 'flex', alignItems: 'center', paddingTop: modus === 'gross' ? '72px' : modus === 'mobil' ? '60px' : 0 }}>
        <div className={'lk-buehne' + (modus === 'gross' ? '' : ' lk-buehne--mobil')}>
          <figure ref={frameRef} className={'lk-frame' + (modus === 'gross' ? '' : ' lk-frame--cam')}>
            <div ref={mapRef} className="lk-map">
              <img src={LKARTE_SVG} alt="Lagekarte Am Waldrain, Nachreihengasse 5-7, mit Straßenbahn 43 Station Neuwaldegg, Krankenhaus Göttlicher Heiland, Schafbergbad, Sportzentrum Marswiese, Klee am Hanslteich und Allgemeines Krankenhaus Wien" />
            </div>
          </figure>
          <div>
            <ol ref={listRef} className="lk-liste" aria-label="Orte auf der Karte" style={{ borderBottom: '1px solid var(--sandstein)' }}>
              {LKARTE_ORTE.map(([n, name, zeile]) => (
                <li key={n}>
                  <button type="button" className="lk-item" data-pin={n}>
                    <span className="lk-n" aria-hidden="true">{n}</span>
                    <span><span className="lk-name">{name}</span><span className="lk-zeile">{zeile}</span></span>
                  </button>
                </li>
              ))}
            </ol>
            {modus === 'gross' && <LkHinweis wege={false} />}
          </div>
        </div>
      </div>
    </div>
    {/* Handy und Tablet: Wegezeiten und Hinweis unter der angehefteten Buehne */}
    {modus !== 'gross' && <div style={{ marginTop: 'var(--space-5)' }}><LkHinweis wege /></div>}
    </React.Fragment>
  );
}

// Auf dem Desktop stehen die Wegezeiten in der Karte, sonst als Text darunter.
function LkHinweis({ wege }) {
  return (
    <React.Fragment>
      {wege && (
        <ul className="lk-wege" aria-label="Wegezeiten">
          {LKARTE_WEGE.map((w) => <li key={w}>{w}</li>)}
        </ul>
      )}
      <p style={{ fontFamily: 'var(--font-text)', fontSize: 'var(--text-micro)', color: 'var(--umbra-60)', margin: 'var(--space-4) 0 0' }}>
        Schematische Darstellung, Wege und Zeiten gerundet.
      </p>
    </React.Fragment>
  );
}

/* Mikrolage als Liste: grosse Serife links, rechts Gehminuten und Entfernung.
   Ohne Bilder, die Seite bleibt informativ. */
function Mikrolage() {
  const items = [
    // Nur belegte Entfernungen (Kunde 03.09., Viola Dollinger 08.09.); Gehminuten
    // daraus mit rund 80 m pro Minute gerechnet, die Fussnote sagt das dazu.
    { label: 'Wienerwald', min: 4, m: '300 m' },
    { label: 'Supermarkt', min: 7, m: 'ca. 500 m, BILLA' },
    { label: 'Kindergarten', min: 11, m: 'ca. 850 m, Casa Dornbach' },
    { label: 'Straßenbahn 43', min: null, m: 'Station Neuwaldegg' },
  ];
  return (
    <section style={{ maxWidth: 'var(--content-max)', margin: '0 auto', padding: `${LSECTION} var(--page-inset-lg) 0` }}>
      <LSectionWord word="Ums Eck">
        <div style={{ maxWidth: '760px' }}>
          {items.map((it, i) => (
            <LReveal key={it.label} delay={i * 70}>
              <div style={{ display: 'flex', alignItems: 'baseline', justifyContent: 'space-between', gap: 'var(--space-5)', padding: 'clamp(0.7rem, 1.4vw, 1.1rem) 0', borderBottom: '1px solid var(--sandstein-40)' }}>
                <span style={{ fontFamily: 'var(--font-display)', fontWeight: 400, fontSize: 'clamp(1.5rem, 3vw, 2.5rem)', lineHeight: 1.1, color: 'var(--umbra)' }}>{it.label}</span>
                <span className="tabular" style={{ flex: 'none', fontFamily: 'var(--font-text)', fontSize: 'var(--text-small)', color: 'var(--umbra-90)', fontVariantNumeric: 'tabular-nums', textAlign: 'right' }}>{it.min ? <>{it.min} Min. zu Fuß<br /><span style={{ fontSize: 'var(--text-micro)', color: 'var(--umbra-60)' }}>{it.m}</span></> : it.m}</span>
              </div>
            </LReveal>
          ))}
        </div>
        <p style={{ fontFamily: 'var(--font-text)', fontSize: 'var(--text-micro)', color: 'var(--umbra-60)', margin: 'var(--space-4) 0 0' }}>Gehzeiten gerundet, bei rund 80 m pro Minute.</p>
        <div style={{ marginTop: 'clamp(2.5rem, 5vw, 4rem)' }}>
          <window.Maison57DesignSystem_40d525.Button variant="filled" onClick={() => window.__m57ToFinder && window.__m57ToFinder()}>Wohnung anfragen</window.Maison57DesignSystem_40d525.Button>
        </div>
      </LSectionWord>
    </section>
  );
}

/* Infrastruktur: die Liste des Vertriebs (08.09.2026) als sechs Cluster auf
   zwei Spalten. Zeilen mit Entfernung zaehlen hoch, alle anderen tragen nur
   eine Beschreibung; erfunden wird nichts. */
function Infrastruktur() {
  const cluster = window.M57_DISTANCES || [];
  return (
    <section style={{ maxWidth: 'var(--content-max)', margin: '0 auto', padding: `${LSECTION} var(--page-inset-lg) 0` }}>
      <LSectionWord word="Alltag">
        {/* Die U5-Verlaengerung wird bewusst gross gefuehrt (Kundenwunsch 25.09.2026). */}
        <LReveal>
          <div className="m57-u5" style={{ display: 'grid', gridTemplateColumns: 'auto 1fr', gap: 'clamp(1.25rem, 3vw, 2.5rem)', alignItems: 'center', background: 'var(--waldgruen)', color: 'var(--creme)', padding: 'clamp(1.5rem, 3vw, 2.5rem)', marginBottom: 'clamp(2.5rem, 5vw, 4rem)' }}>
            <span style={{ fontFamily: 'var(--font-display)', fontSize: 'clamp(3rem, 7vw, 5.5rem)', lineHeight: 0.9 }}>U5</span>
            <div>
              <div style={{ fontFamily: 'var(--font-display)', fontSize: 'clamp(1.3rem, 2.4vw, 2rem)', lineHeight: 1.2 }}>Die U-Bahn kommt nach Hernals.</div>
              <p style={{ fontFamily: 'var(--font-text)', fontSize: 'var(--text-small)', lineHeight: 1.7, color: 'rgba(245,241,232,0.85)', margin: 'var(--space-3) 0 0', maxWidth: '52ch' }}>
                Die Verlängerung der U5 bis Hernals ist für Mitte der 2030er-Jahre geplant. Heute erreichen Sie die U6 und die S45 in Hernals und an der Alser Straße.
              </p>
            </div>
          </div>
        </LReveal>
        <p style={{ fontFamily: 'var(--font-display)', fontSize: 'clamp(1.15rem, 1.7vw, 1.45rem)', color: 'var(--umbra)', margin: '0 0 clamp(1.75rem, 3vw, 2.5rem)' }}>Best of Elisabeth Rohr Real Estate</p>
        <div className="m57-infra" style={{ display: 'grid', gridTemplateColumns: '1fr 1fr', gap: 'clamp(2rem, 4vw, 3.5rem) clamp(2rem, 5vw, 4rem)', alignItems: 'start' }}>
          {cluster.map((c, ci) => (
            <div key={c.word}>
              <LReveal delay={ci * 60}>
                <h3 style={{ fontFamily: 'var(--font-display)', fontWeight: 400, fontSize: 'clamp(1.15rem, 1.7vw, 1.45rem)', color: 'var(--umbra)', margin: '0 0 var(--space-3)' }}>{c.word}</h3>
              </LReveal>
              <div style={{ borderTop: '1px solid var(--sandstein)' }}>
                {c.items.map((it, i) => <DistRow key={it.label} label={it.label} value={it.value} index={i} />)}
              </div>
            </div>
          ))}
        </div>
        <p style={{ fontFamily: 'var(--font-text)', fontSize: 'var(--text-micro)', color: 'var(--umbra-60)', margin: 'var(--space-5) 0 0' }}>
          Stand September 2026.
        </p>
        <style>{`@media (max-width: 760px) { .m57-infra { grid-template-columns: 1fr !important; } .m57-u5 { grid-template-columns: 1fr !important; } }`}</style>
      </LSectionWord>
    </section>
  );
}

function LageScreen() {
  return (
    <div>
      <LageHero />
      <Makrolage />
      <Mikrolage />
      <Infrastruktur />
      {window.M57_KONTAKTFORMULAR !== false && <VormerkungSection />}
    </div>
  );
}

window.LageScreen = LageScreen;
