/* Verbundsystem, Produkte, Objekte pages. */
(function () {
  const { useState, useEffect } = React;
  const Icon = window.Icon;
  const { Reveal, Btn, SectionHead, Tag } = window;

  /* 3D stone viewer (Three.js + STL) with scroll-coupled rotation + fall-in */
  function initSysStone(el) {
    const THREE = window.THREE;
    const w = () => el.clientWidth || 480, h = () => el.clientHeight || 480;
    const renderer = new THREE.WebGLRenderer({ alpha: true, antialias: true, preserveDrawingBuffer: true });
    renderer.setPixelRatio(Math.min(window.devicePixelRatio || 1, 2));
    renderer.shadowMap.enabled = true; renderer.shadowMap.type = THREE.VSMShadowMap;
    renderer.setSize(w(), h());
    const cv = renderer.domElement; cv.style.width = '100%'; cv.style.height = '100%'; cv.style.display = 'block';
    el.appendChild(cv);
    const scene = new THREE.Scene();
    const camera = new THREE.PerspectiveCamera(32, w() / h(), 0.1, 100);
    camera.position.set(0.7, 2.5, 6.0); camera.lookAt(1.25, -0.1, 0);
    scene.add(new THREE.AmbientLight(0xffffff, 0.1));
    scene.add(new THREE.HemisphereLight(0xf2f5f8, 0x33363b, 0.34));
    const key = new THREE.DirectionalLight(0xfff6ec, 0.72); key.position.set(-3.6, 7.5, 4.2); key.castShadow = true; key.shadow.mapSize.set(2048, 2048); key.shadow.radius = 12; key.shadow.camera.near = 0.5; key.shadow.camera.far = 30; key.shadow.camera.left = -4.5; key.shadow.camera.right = 4.5; key.shadow.camera.top = 4.5; key.shadow.camera.bottom = -4.5; key.shadow.bias = -0.0005; scene.add(key);
    const fill = new THREE.DirectionalLight(0xdce6f2, 0.4); fill.position.set(5.5, 2.2, 3); scene.add(fill);
    const back = new THREE.DirectionalLight(0xffffff, 0.42); back.position.set(1.5, 3.5, -5.5); scene.add(back);
    const rim = new THREE.PointLight(0xc41e3a, 0.35, 60); rim.position.set(3.2, -0.6, -4.5); scene.add(rim);
    const TS = 2048;
    const tcv = document.createElement('canvas'); tcv.width = tcv.height = TS;
    (function () {
      const x = tcv.getContext('2d');
      x.fillStyle = '#b4b2ac'; x.fillRect(0, 0, TS, TS);
      // multi-octave low-frequency tone drift so no area looks like another (kills perceived tiling)
      for (let oct = 0; oct < 4; oct++) {
        const cells = 3 + oct * 3, cs = TS / cells;
        const grid = [];
        for (let gy = 0; gy <= cells; gy++) { grid[gy] = []; for (let gx = 0; gx <= cells; gx++) grid[gy][gx] = (Math.random() - 0.5); }
        const amp = 16 / (oct + 1);
        const im0 = x.getImageData(0, 0, TS, TS), dd = im0.data;
        for (let py = 0; py < TS; py++) {
          const fy = py / cs, iy = Math.floor(fy), ty = fy - iy;
          for (let px = 0; px < TS; px++) {
            const fx = px / cs, ix = Math.floor(fx), tx = fx - ix;
            const a = grid[iy][ix], b = grid[iy][ix + 1], c = grid[iy + 1][ix], e = grid[iy + 1][ix + 1];
            const top = a + (b - a) * tx, bot = c + (e - c) * tx, val = (top + (bot - top) * ty) * amp;
            const o = (py * TS + px) * 4; dd[o] += val; dd[o + 1] += val; dd[o + 2] += val;
          }
        }
        x.putImageData(im0, 0, 0);
      }
      // fine per-pixel grain
      const im = x.getImageData(0, 0, TS, TS), d = im.data;
      for (let i = 0; i < d.length; i += 4) { const n = (Math.random() - 0.5) * 30; d[i] += n; d[i + 1] += n; d[i + 2] += n; }
      x.putImageData(im, 0, 0);
      // scattered aggregate speckles
      for (let k = 0; k < 64000; k++) { const r = Math.random() * 2.4 + 0.3; x.beginPath(); x.arc(Math.random() * TS, Math.random() * TS, r, 0, 7); const tt = Math.random(); x.fillStyle = tt < 0.45 ? 'rgba(86,84,80,' + (0.12 + Math.random() * 0.22) + ')' : tt < 0.8 ? 'rgba(228,226,220,' + (0.12 + Math.random() * 0.26) + ')' : 'rgba(150,140,128,' + (0.08 + Math.random() * 0.14) + ')'; x.fill(); }
      for (let k = 0; k < 1300; k++) { const r = Math.random() * 4 + 1.6; x.beginPath(); x.arc(Math.random() * TS, Math.random() * TS, r, 0, 7); x.fillStyle = Math.random() < 0.5 ? 'rgba(70,68,64,0.18)' : 'rgba(236,234,228,0.2)'; x.fill(); }
    })();
    const tex = new THREE.CanvasTexture(tcv); tex.wrapS = tex.wrapT = THREE.ClampToEdgeWrapping; tex.repeat.set(1, 1); tex.anisotropy = 8;
    let pivot = null, raf = 0, targetRot = 0, curRot = 0, appear = 0, t0 = performance.now();
    const loader = new THREE.STLLoader();
    loader.load('assets/einstein-stein.stl', function (geo) {
      try {
        geo.computeVertexNormals(); geo.center(); geo.computeBoundingBox();
        const size = new THREE.Vector3(); geo.boundingBox.getSize(size);
        const baseScale = 2.7 / Math.max(size.x, size.y, size.z);
        const sx = size.x || 1, sy = size.y || 1, sz = size.z || 1;
        const pos = geo.attributes.position, nrm = geo.attributes.normal, uv = new Float32Array(pos.count * 2);
        for (let i = 0; i < pos.count; i++) {
          const nx = Math.abs(nrm.getX(i)), ny = Math.abs(nrm.getY(i)), nz = Math.abs(nrm.getZ(i));
          let u, v; const px = pos.getX(i), py = pos.getY(i), pz = pos.getZ(i);
          if (nx >= ny && nx >= nz) { u = pz / sz + 0.5; v = py / sy + 0.5; } else if (ny >= nx && ny >= nz) { u = px / sx + 0.5; v = pz / sz + 0.5; } else { u = px / sx + 0.5; v = py / sy + 0.5; }
          uv[i * 2] = u; uv[i * 2 + 1] = v;
        }
        geo.setAttribute('uv', new THREE.BufferAttribute(uv, 2));
        const mat = new THREE.MeshStandardMaterial({ map: tex, bumpMap: tex, bumpScale: 0.32, roughness: 0.96, metalness: 0.0 });
        const mesh = new THREE.Mesh(geo, mat);
        mesh.scale.setScalar(baseScale); mesh.castShadow = true; mesh.receiveShadow = true;
        mesh.rotation.x = -Math.PI / 2;
        pivot = new THREE.Group(); pivot.add(mesh); pivot.position.x = 2.35; scene.add(pivot);
        pivot.updateMatrixWorld(true);
        const bb = new THREE.Box3().setFromObject(mesh);
        const groundY = bb.min.y - 0.04;
        const cxW = (bb.max.x + bb.min.x) / 2, czW = (bb.max.z + bb.min.z) / 2;
        const ground = new THREE.Mesh(new THREE.PlaneGeometry(20, 20), new THREE.ShadowMaterial({ opacity: 0.32 }));
        ground.rotation.x = -Math.PI / 2; ground.position.set(cxW, groundY, czW); ground.receiveShadow = true; scene.add(ground);
        // soft radial contact shadow so the stone reads as resting on a floor
        const csCv = document.createElement('canvas'); csCv.width = csCv.height = 256;
        (function () { const g = csCv.getContext('2d'); const rg = g.createRadialGradient(128, 128, 8, 128, 128, 128); rg.addColorStop(0, 'rgba(8,9,10,0.5)'); rg.addColorStop(0.45, 'rgba(8,9,10,0.26)'); rg.addColorStop(1, 'rgba(8,9,10,0)'); g.fillStyle = rg; g.fillRect(0, 0, 256, 256); })();
        const csTex = new THREE.CanvasTexture(csCv);
        const fp = Math.max(bb.max.x - bb.min.x, bb.max.z - bb.min.z) * 2.0;
        const contact = new THREE.Mesh(new THREE.PlaneGeometry(fp, fp), new THREE.MeshBasicMaterial({ map: csTex, transparent: true, depthWrite: false, opacity: 0.95 }));
        contact.rotation.x = -Math.PI / 2; contact.position.set(cxW, groundY + 0.006, czW); contact.renderOrder = -1; scene.add(contact);
      } catch (e) { console.error('STONE3D onload err', e); }
    }, undefined, function (e) { console.error('STONE3D load err', e); });
    const onResize = () => { camera.aspect = w() / h(); camera.updateProjectionMatrix(); renderer.setSize(w(), h()); };
    window.addEventListener('resize', onResize);
    const onScroll = () => { targetRot = window.scrollY * 0.0014; };
    window.addEventListener('scroll', onScroll, { passive: true }); onScroll();
    const ease = (x) => 1 - Math.pow(1 - x, 3);
    const loop = () => {
      raf = requestAnimationFrame(loop);
      const el2 = (performance.now() - t0) / 1000;
      if (pivot) {
        appear = Math.min(1, appear + 0.016); const a = ease(appear);
        pivot.scale.setScalar(0.72 + 0.28 * a);
        pivot.position.y = (1 - a) * 1.1;
        curRot += (targetRot - curRot) * 0.06;
        pivot.rotation.y = curRot + el2 * 0.012;
      }
      renderer.render(scene, camera);
    };
    loop();
    return () => { cancelAnimationFrame(raf); window.removeEventListener('resize', onResize); window.removeEventListener('scroll', onScroll); renderer.dispose(); if (cv.parentNode) cv.parentNode.removeChild(cv); };
  }

  /* Generic federal attestation seal — German national colours in a shield.
     NOT the protected Bundesadler state emblem; a neutral "tested-for" mark. */
  const FEDERAL_SEAL =
    '<svg viewBox="0 0 64 64" width="100%" height="100%" role="img" aria-hidden="true">' +
      '<circle cx="32" cy="32" r="30.5" fill="#F4F1EA" stroke="#141414" stroke-width="1.25"/>' +
      '<circle cx="32" cy="32" r="25.5" fill="none" stroke="#141414" stroke-width="0.6" opacity="0.4"/>' +
      '<defs><clipPath id="fedShield"><path d="M32 18 L44 21.8 V33.4 C44 40.4 38.8 44.6 32 47.6 C25.2 44.6 20 40.4 20 33.4 V21.8 Z"/></clipPath></defs>' +
      '<g clip-path="url(#fedShield)">' +
        '<rect x="20" y="18" width="24" height="10" fill="#141414"/>' +
        '<rect x="20" y="28" width="24" height="9.6" fill="#C8102E"/>' +
        '<rect x="20" y="37.6" width="24" height="10" fill="#F4C20D"/>' +
      '</g>' +
      '<path d="M32 18 L44 21.8 V33.4 C44 40.4 38.8 44.6 32 47.6 C25.2 44.6 20 40.4 20 33.4 V21.8 Z" fill="none" stroke="#141414" stroke-width="1.1"/>' +
    '</svg>';

  const PageHead = ({ lang, eyebrow, title, lead, className = '', sticky }) =>
    React.createElement('section', { className: 'hero hero--light ' + className + (sticky ? ' pagehead--sticky' : ''), style: { borderBottom: '1px solid var(--border-subtle)' } },
      React.createElement('div', { className: 'container hero__inner', style: { paddingBlock: 'clamp(48px,8vh,88px)' } },
        React.createElement('p', { className: 'eyebrow' }, eyebrow),
        React.createElement('h1', { className: 'display display--xl', style: { marginTop: 14 } }, title),
        lead ? React.createElement('p', { className: 'hero__lead', style: { color: 'var(--text-muted)' } }, lead) : null
      )
    );

  /* ---------- Verbundsystem ---------- */
  const System = ({ lang, navigate }) => {
    const t = (v) => window.tr(lang, v);
    const Sy = window.SITE.system;
    const P = window.SITE.proof;
    const V = Sy.versatility;
    useEffect(() => {
      let cancelled = false, cleanup = () => {};
      const loadScript = (src, check) => new Promise((res) => {
        if (check()) { res(); return; }
        const sc = document.createElement('script'); sc.src = src; sc.onload = res; sc.onerror = res; document.head.appendChild(sc);
      });
      (async () => {
        await loadScript('https://unpkg.com/three@0.128.0/build/three.min.js', () => !!window.THREE);
        await loadScript('https://unpkg.com/three@0.128.0/examples/js/loaders/STLLoader.js', () => !!(window.THREE && window.THREE.STLLoader));
        if (cancelled) return;
        const el = document.getElementById('sysStone3D');
        if (el && !el.dataset.init && window.THREE && window.THREE.STLLoader) { el.dataset.init = '1'; cleanup = initSysStone(el); }
      })();
      return () => { cancelled = true; cleanup(); };
    }, []);
    const statEl = (s, center) => React.createElement('div', { className: 'sys-stat' + (center ? ' sys-stat--center' : '') },
      React.createElement('div', { className: 'sys-stat__row' },
        React.createElement('span', { className: 'sys-stat__val' }, s.value),
        React.createElement('span', { className: 'sys-stat__unit' }, t(s.unit))),
      React.createElement('span', { className: 'sys-stat__note' }, t(s.note)));
    const renderBlock = (b) => {
      if (b.layout === 'wide') {
        return React.createElement('section', { key: b.id, className: 'section sys-block sys-block--wide' },
          React.createElement('div', { className: 'container' },
            React.createElement(Reveal, { className: 'sys-wide__head' },
              React.createElement('h2', { className: 'display display--lg', style: { textAlign: 'center' } }, t(b.title)),
              React.createElement('p', { className: 'lead', style: { marginTop: 16, textAlign: 'center' } }, t(b.body)),
              b.stat ? statEl(b.stat, true) : null),
            React.createElement(Reveal, { delay: 120, className: 'sys-figure sys-figure--wide' },
              React.createElement('img', { src: b.img, alt: t(b.title) }))));
      }
      if (b.layout === 'text') {
        return React.createElement('section', { key: b.id, className: 'section sys-block sys-block--text' },
          React.createElement('div', { className: 'container' },
            React.createElement(Reveal, { className: 'sys-text' },
              React.createElement('h2', { className: 'display display--lg' }, t(b.title)),
              React.createElement('p', { className: 'lead', style: { marginTop: 16, maxWidth: '64ch' } }, t(b.body)))));
      }
      const textRight = b.layout === 'right';
      const media = React.createElement(Reveal, { key: 'm', className: 'sys-figure', delay: textRight ? 0 : 120 },
        React.createElement('img', { src: b.img, alt: t(b.title) }));
      const text = React.createElement(Reveal, { key: 't', delay: textRight ? 120 : 0, className: 'sys-block__text' },
        React.createElement('h2', { className: 'display display--lg' }, t(b.title)),
        React.createElement('p', { className: 'lead', style: { marginTop: 16 } }, t(b.body)),
        b.stat ? statEl(b.stat) : null);
      return React.createElement('section', { key: b.id, className: 'section sys-block' },
        React.createElement('div', { className: 'container' },
          React.createElement('div', { className: 'sys-block__grid' }, textRight ? [media, text] : [text, media])));
    };
    return React.createElement(React.Fragment, null,
      React.createElement('section', { className: 'sys-immersive' },
        React.createElement('div', { id: 'sysStone3D', className: 'sys-immersive__scene', role: 'img', 'aria-label': 'EINSTEIN® Pflasterstein — 3D' }),
        React.createElement('div', { className: 'container sys-immersive__inner' },
          React.createElement('div', { className: 'sys-immersive__copy' },
            React.createElement('h1', { className: 'sys-immersive__title' }, t({ de: 'Ein System.', en: 'One system.' }), React.createElement('br'), t({ de: 'Neue Maßstäbe.', en: 'New standards.' })),
            React.createElement('div', { className: 'prose sys-immersive__prose' },
              Sy.intro.map((p, i) => React.createElement('p', { key: i, className: i === 0 ? 'sys-hero__lead' : null }, t(p)))),
            React.createElement('div', { className: 'sys-immersive__chips' },
              Sy.features.map((f, i) => React.createElement('span', { key: i, className: 'sys-chip' },
                React.createElement(Icon, { name: f.icon, size: 15 }),
                React.createElement('span', null, t(f.title)))))))
      ),

      Sy.blocks.map(renderBlock),

      React.createElement('section', { className: 'section section--sunken sys-versatility' },
        React.createElement('div', { className: 'container', style: { textAlign: 'center', maxWidth: 820, marginLeft: 'auto', marginRight: 'auto' } },
          React.createElement(Reveal, null,
            React.createElement('h2', { className: 'display display--lg' }, t(V.title)),
            React.createElement('p', { className: 'lead', style: { marginTop: 20 } }, t(V.body)),
            React.createElement('div', { style: { marginTop: 28 } },
              React.createElement(Btn, { variant: 'primary', iconRight: 'arrow', onClick: () => navigate('products') }, t(V.cta))))
        )
      ),

      /* Proof / Versuchsreihe */
      React.createElement('section', { className: 'section section--ink', id: 'proof' },
        React.createElement('div', { className: 'container' },
          React.createElement('div', { style: { maxWidth: 760, marginBottom: 'var(--space-8)' } },
            React.createElement('p', { className: 'eyebrow' }, t(P.eyebrow)),
            React.createElement('h2', { className: 'display display--lg', style: { marginTop: 12 } }, t(P.title)),
            React.createElement('p', { className: 'lead', style: { marginTop: 16 } }, t(P.lead))),
          React.createElement('div', { className: 'stat-grid' },
            P.stats.map((s, i) => React.createElement('div', { key: i, className: 'stat' + (i === 1 ? ' stat--hi' : '') + (i === 2 ? ' stat--muted' : '') },
              React.createElement('p', { className: 'stat__label' }, t(s.label)),
              React.createElement('div', { className: 'stat__val' }, s.value, React.createElement('span', { className: 'u' }, t(s.unit))),
              React.createElement('p', { className: 'stat__note' }, t(s.note))))),
          React.createElement('p', { className: 'source-note' }, t(P.source)),
          React.createElement('figure', { className: 'proof-chart' },
            React.createElement('img', { src: 'assets/versuchsergebnisse.png', alt: 'Versuchsergebnisse: bleibende Horizontalverschiebung nach 1 Mio. Lastwechsel' }),
            React.createElement('figcaption', { className: 'proof-chart__cap' }, t({ de: 'Bleibende Horizontalverschiebung verschiedener Pflasterverbände nach 1 Mio. Lastwechsel — die EINSTEIN®-Technologie (gelb) bleibt nahezu bei null, während herkömmliche Verbände deutlich stärker wandern.', en: 'Residual horizontal displacement of various paving bonds after 1 million load cycles — EINSTEIN® technology (yellow) stays close to zero, while conventional bonds shift markedly more.' })))
        )
      ),

      React.createElement('section', { className: 'section section--tight cta-band' },
        React.createElement('div', { className: 'container', style: { display: 'flex', flexWrap: 'wrap', gap: 16, alignItems: 'center', justifyContent: 'space-between' } },
          React.createElement('h2', { className: 'display display--md', style: { whiteSpace: 'nowrap' } }, t({ de: 'Das System hat Ihr Interesse geweckt?', en: 'Has the system caught your interest?' })),
          React.createElement('div', { style: { display: 'flex', gap: 12, flexWrap: 'wrap' } },
            React.createElement(Btn, { variant: 'primary', icon: 'map-pin', onClick: () => navigate('contact') }, t(window.SITE.ui.cta.partner)))
        )
      )
    );
  };

  /* ---------- Produkte ---------- */
  const Produkte = ({ lang, navigate }) => {
    const t = (v) => window.tr(lang, v);
    const S = window.SITE.ui;
    const products = window.SITE.products;
    return React.createElement(React.Fragment, null,
      React.createElement(PageHead, {
        lang, eyebrow: t({ de: 'Produkte', en: 'Products' }),
        title: t({ de: 'Die aktive EINSTEIN®-Produktlinie.', en: 'The active EINSTEIN® product line.' }),
        lead: t(window.SITE.productsIntro), className: 'headbg prodhead', sticky: true,
      }),
      React.createElement('section', { className: 'section prodflow prodflow--sheet' },
        React.createElement('div', { className: 'prodflow__bg', 'aria-hidden': true },
          React.createElement('span', { className: 'blob-a' }),
          React.createElement('span', { className: 'blob-b' }),
          React.createElement('span', { className: 'blob-c' })),
        React.createElement('div', { className: 'container' },
          products.map((p, i) => React.createElement(Reveal, { key: p.id, delay: i * 90, as: 'article', className: 'prodrow' },
            React.createElement('div', { className: 'prodrow__visual' },
              React.createElement('img', {
                className: 'prodrow__stone' + (p.id === 'trecona' ? ' prodrow__stone--xs' : (p.id === 'segmentbogen' ? ' prodrow__stone--sm' : '')),
                src: p.img, alt: t(p.name), loading: 'lazy',
                style: { animationDelay: (i * -1.6) + 's' },
              })),
            React.createElement('div', { className: 'prodrow__text' },
              React.createElement('h2', { className: 'prodrow__name' }, t(p.name)),
              React.createElement('div', { className: 'prodrow__tags' },
                p.tags.map((tg, j) => React.createElement('span', { key: j, className: 'prodrow__pill' }, t(tg)))),
              React.createElement('p', { className: 'prodrow__desc' }, t(p.desc)),
              React.createElement('button', { className: 'prodrow__cta', onClick: () => navigate('product', { id: p.id }) },
                React.createElement('span', null, t(S.cta.more)),
                React.createElement(Icon, { name: 'arrow', size: 18 }))))),
          React.createElement('div', { className: 'prodflow__note' },
            React.createElement('span', { className: 'prodflow__note-dot' }),
            React.createElement('p', { className: 'mono' },
              t({ de: 'Trotz unterschiedlicher Erscheinungsbilder verfügen alle Varianten über den Vollverbund mit D-Punkt. Weitere Formate, Oberflächen und Farben auf Anfrage über Ihren Lizenzpartner.', en: 'Despite their different looks, all variants share the full bond with D-point. Further formats, surfaces and colours on request via your licence partner.' })))
        )
      )
    );
  };

  /* ---------- Objekte ---------- */
  const Objekte = ({ lang, navigate, initialCat }) => {
    const t = (v) => window.tr(lang, v);
    const cats = window.SITE.categories;
    const reports = window.SITE.reports;
    const [active, setActive] = useState(initialCat || 'all');
    const filterRef = React.useRef(null);
    useEffect(() => { if (initialCat) setActive(initialCat); }, [initialCat]);
    const pick = (id) => {
      setActive(id);
      requestAnimationFrame(() => {
        const el = filterRef.current; if (!el) return;
        const header = document.querySelector('.site-header');
        const hH = header ? header.offsetHeight : 80;
        const targetY = Math.max(0, el.getBoundingClientRect().top + window.scrollY - hH - 16);
        const startY = window.scrollY; const diff = targetY - startY;
        if (Math.abs(diff) < 2) return;
        const dur = 1100; const t0 = performance.now();
        const ease = (x) => (x < 0.5 ? 4 * x * x * x : 1 - Math.pow(-2 * x + 2, 3) / 2);
        const step = (now) => {
          const p = Math.min(1, (now - t0) / dur);
          window.scrollTo(0, startY + diff * ease(p));
          if (p < 1) requestAnimationFrame(step);
        };
        requestAnimationFrame(step);
      });
    };

    const catName = (id) => { const c = cats.find((x) => x.id === id); return c ? t(c.title) : ''; };
    const shown = active === 'all' ? reports : reports.filter((r) => (r.categories ? r.categories.includes(active) : r.category === active));
    const chips = [['all', { de: 'Alle', en: 'All' }]].concat(cats.map((c) => [c.id, c.title]));

    return React.createElement(React.Fragment, null,
      React.createElement(PageHead, {
        lang, eyebrow: t({ de: 'Objekte', en: 'Projects' }),
        title: t({ de: 'Referenzen, die tragen.', en: 'References that carry the load.' }),
        lead: t({ de: 'Eine Auswahl realisierter EINSTEIN®-Flächen — filterbar nach Anwendungsfeld.', en: 'A selection of realised EINSTEIN® surfaces — filter by field of application.' }),
        className: 'headbg objhead', sticky: true,
      }),

      /* Everything below the sticky header rides on ONE sheet so the header stays covered */
      React.createElement('div', { className: 'reveal-sheet' },

      /* Filterable report grid */
      React.createElement('section', { className: 'section' },
        React.createElement('div', { className: 'container' },
          React.createElement('div', { className: 'filterbar', ref: filterRef },
            chips.map(([id, label]) => React.createElement('button', {
              key: id, className: 'chip ' + (active === id ? 'is-active' : ''), onClick: () => pick(id),
            }, t(label)))),
          shown.length ? React.createElement('div', { className: 'report-grid' },
            shown.map((r) => React.createElement('article', { key: r.id, className: 'report', style: { cursor: 'pointer' }, onClick: () => navigate('object', { id: r.id }) },
              React.createElement('div', { className: 'report__img' }, React.createElement('img', { src: r.img, alt: t(r.title) })),
              React.createElement('div', { className: 'report__body' },
                React.createElement('p', { className: 'report__meta' }, React.createElement('span', null, r.place), React.createElement('span', null, r.year)),
                React.createElement('h3', { className: 'report__title' }, t(r.title)),
                React.createElement('p', { className: 'report__excerpt' }, t(r.excerpt)),
                React.createElement('span', { className: 'tag report__cat' }, catName(r.category))))))
            : React.createElement('p', { className: 'lead' }, t({ de: 'Noch keine Objekte in dieser Kategorie.', en: 'No projects in this category yet.' }))
        )
      )
      )
    );
  };

  /* ---------- Produkt-Detail (Platzhalter, später ausgestalten) ---------- */
  const ProductDetail = ({ lang, navigate, id }) => {
    const t = (v) => window.tr(lang, v);
    const S = window.SITE.ui;
    const products = window.SITE.products;
    const p = products.find((x) => x.id === id) || products[0];
    return React.createElement(React.Fragment, null,
      React.createElement('section', { className: 'section prodflow', style: { paddingBottom: 'var(--space-9)' } },
        React.createElement('div', { className: 'prodflow__bg', 'aria-hidden': true },
          React.createElement('span', { className: 'blob-a' }),
          React.createElement('span', { className: 'blob-b' })),
        React.createElement('div', { className: 'container' },
          React.createElement('button', {
            className: 'prodrow__cta', onClick: () => navigate('products'),
            style: { marginTop: 0, marginBottom: 'var(--space-6)', flexDirection: 'row-reverse' },
          }, React.createElement('span', null, t({ de: 'Alle Produkte', en: 'All products' })),
             React.createElement(Icon, { name: 'arrow', size: 18, style: { transform: 'rotate(180deg)' } })),
          React.createElement('div', { className: 'prodrow', style: { paddingBlock: 0 } },
            React.createElement('div', { className: 'prodrow__visual' },
              React.createElement('img', { className: 'prodrow__stone', src: p.img, alt: t(p.name) })),
            React.createElement('div', { className: 'prodrow__text' },
              React.createElement('p', { className: 'eyebrow' }, t({ de: 'Produkt', en: 'Product' })),
              React.createElement('h1', { className: 'prodrow__name', style: { fontSize: 'clamp(34px,4.4vw,60px)', marginTop: 12 } }, t(p.name)),
              React.createElement('div', { className: 'prodrow__tags' },
                p.tags.map((tg, j) => React.createElement('span', { key: j, className: 'prodrow__pill' }, t(tg)))),
              React.createElement('p', { className: 'prodrow__desc' }, t(p.desc))))
        )
      ),
      React.createElement('section', { className: 'section section--tight' },
        React.createElement('div', { className: 'container', style: { maxWidth: 720 } },
          React.createElement('div', {
            style: {
              display: 'flex', alignItems: 'flex-start', gap: 16, padding: 'var(--space-6)',
              borderRadius: '20px', background: 'var(--surface-subtle)', border: '1px dashed var(--border-default)',
            },
          },
            React.createElement('span', { className: 'prodflow__note-dot', style: { marginTop: 6 } }),
            React.createElement('div', null,
              React.createElement('h3', { style: { margin: '0 0 6px', fontFamily: 'var(--font-display)', fontWeight: 'var(--fw-bold)', fontSize: 'var(--text-lg)', color: 'var(--text-strong)' } },
                t({ de: 'Detailseite folgt.', en: 'Detail page coming.' })),
              React.createElement('p', { className: 'mono', style: { margin: 0, fontSize: 13, color: 'var(--text-muted)', lineHeight: 1.65 } },
                t({ de: 'Diese Produktseite wird in einem nächsten Schritt ausgestaltet — mit Formaten, Oberflächen, Farben, Verlegemustern und technischen Daten.', en: 'This product page will be fleshed out next — formats, surfaces, colours, laying patterns and technical data.' }))))
        )
      )
    );
  };

  Object.assign(window, { System, Produkte, ProductDetail, Objekte });
})();
