/* global React, UNITS, NEWS, POIS, FROMBERG_SITE, STATUS_LABELS, fmtPrice, Header, Footer, BuildingViewer, UnitCard, UnitModal, FloorplanThumb, Brand, Label, Accent, BuildingIllustration */
const { useState: R_useState, useEffect: R_useEffect, useMemo: R_useMemo, useRef: R_useRef } = React;

/** Eind van kalenderdag (lokale tijd) voor inclusieve vergelijkingen. */
function endOfLocalDay(y, m0, d) {
  return new Date(y, m0, d, 23, 59, 59, 999);
}

/**
 * Vijf geplande mijlpalen; `active` volgt uit `now` (geen vaste "Nu" in content).
 * Sloop én opbouw nov–dec 2026; startbouw vanaf jan 2027 (Q1 2027); oplevering Q1 2028.
 */
const PROJECT_PLANNING_STEPS = [
  {
    start: new Date(2026, 4, 1),
    end: endOfLocalDay(2026, 6, 31),
    dateLabel: 'Mei — juli 2026',
    label: 'Voorinschrijving',
    desc: 'Aanmelden tot en met juli',
  },
  {
    start: new Date(2026, 7, 1),
    end: endOfLocalDay(2026, 9, 31),
    dateLabel: 'Aug — okt 2026',
    label: 'Voorverkoop',
    desc: 'Woningkeuze en reservering; start na de voorinschrijving (communicatie kan al in juli)',
  },
  {
    start: new Date(2026, 10, 1),
    end: endOfLocalDay(2026, 11, 31),
    dateLabel: 'Nov — dec 2026',
    label: 'Sloop & opbouw',
    desc: 'Sloop- en opbouwwerkzaamheden ter plaatse in november en december',
  },
  {
    start: new Date(2027, 0, 1),
    end: endOfLocalDay(2027, 11, 31),
    dateLabel: 'Jan — dec 2027',
    label: 'Startbouw',
    desc: 'Start bouw vanaf januari (Q1 2027); doorlopend tot aan oplevering',
  },
  {
    start: new Date(2028, 0, 1),
    end: endOfLocalDay(2028, 2, 31),
    dateLabel: 'Q1 2028',
    label: 'Oplevering',
    desc: 'Geplande oplevering eerste kwartaal 2028',
  },
];

function getProjectPlanningActiveIndex(now) {
  const t = now.getTime();
  for (let i = 0; i < PROJECT_PLANNING_STEPS.length; i++) {
    const { start, end } = PROJECT_PLANNING_STEPS[i];
    if (t >= start.getTime() && t <= end.getTime()) return i;
  }
  return -1;
}

/** POST naar een gedeelde Supabase Edge Function (lead-intake / contact). */
async function frombergSubmit(fnName, payload) {
  const base = (typeof window !== 'undefined' && window.FROMBERG_SUPABASE_URL) || '';
  if (!base) throw new Error('Formulier is nog niet geconfigureerd. Probeer het later opnieuw.');
  const anon = (typeof window !== 'undefined' && window.FROMBERG_SUPABASE_ANON_KEY) || '';
  const headers = { 'Content-Type': 'application/json' };
  if (anon) {
    headers['Authorization'] = `Bearer ${anon}`;
    headers['apikey'] = anon;
  }
  const res = await fetch(`${base}/functions/v1/${fnName}`, {
    method: 'POST',
    headers,
    body: JSON.stringify(payload),
  });
  let data = {};
  try { data = await res.json(); } catch (_e) { /* leeg antwoord */ }
  if (!res.ok) throw new Error(data.error || 'Verzenden mislukt. Probeer het opnieuw.');
  return data;
}

// Slug waarmee dit project in de gedeelde database staat (consent Supabase).
const FROMBERG_PROJECT_SLUG = 'frombergdwarsstraat-arnhem';

/** Datum → '12 maart 2026' (NL), past bij de stijl van window.NEWS. */
function frombergFormatNewsDate(iso) {
  const d = new Date(iso);
  if (isNaN(d.getTime())) return '';
  return d.toLocaleDateString('nl-NL', { day: 'numeric', month: 'long', year: 'numeric' });
}

/**
 * Haalt gepubliceerde project-updates op uit de gedeelde Supabase (anon REST).
 * Geeft een NEWS-vormige array terug ({date,title,excerpt}) of null bij fout/
 * geen config — dan blijft de hardcoded window.NEWS staan als fallback.
 */
async function frombergLoadNews() {
  const base = (typeof window !== 'undefined' && window.FROMBERG_SUPABASE_URL) || '';
  const anon = (typeof window !== 'undefined' && window.FROMBERG_SUPABASE_ANON_KEY) || '';
  if (!base || !anon) return null;
  const headers = { apikey: anon, Authorization: `Bearer ${anon}` };
  try {
    const projRes = await fetch(
      `${base}/rest/v1/projects?slug=eq.${encodeURIComponent(FROMBERG_PROJECT_SLUG)}&select=id&limit=1`,
      { headers }
    );
    if (!projRes.ok) return null;
    const projects = await projRes.json();
    const projectId = Array.isArray(projects) && projects[0] && projects[0].id;
    if (!projectId) return null;

    const upRes = await fetch(
      `${base}/rest/v1/project_updates?project_id=eq.${projectId}` +
        `&published=eq.true&select=id,title,body,created_at&order=created_at.desc`,
      { headers }
    );
    if (!upRes.ok) return null;
    const rows = await upRes.json();
    if (!Array.isArray(rows) || rows.length === 0) return null;
    return rows.map((r) => ({
      date: frombergFormatNewsDate(r.created_at),
      title: r.title || '',
      excerpt: r.body || '',
    }));
  } catch (_e) {
    return null;
  }
}

/** Laadt Maps JavaScript API één keer (static site zonder bundler). */
let _frombergGmapsLoadPromise = null;
function loadFrombergGoogleMaps(apiKey) {
  if (typeof window === 'undefined') return Promise.reject(new Error('no window'));
  if (window.google && window.google.maps) return Promise.resolve();
  if (_frombergGmapsLoadPromise) return _frombergGmapsLoadPromise;
  _frombergGmapsLoadPromise = new Promise((resolve, reject) => {
    const cbName = '__frombergGmapsCb';
    window[cbName] = () => {
      try {
        delete window[cbName];
      } catch (_) { /* noop */ }
      resolve();
    };
    const script = document.createElement('script');
    script.async = true;
    script.defer = true;
    script.src = `https://maps.googleapis.com/maps/api/js?key=${encodeURIComponent(apiKey)}&callback=${cbName}`;
    script.onerror = () => {
      try {
        delete window[cbName];
      } catch (_) { /* noop */ }
      _frombergGmapsLoadPromise = null;
      reject(new Error('Google Maps script'));
    };
    document.head.appendChild(script);
  });
  return _frombergGmapsLoadPromise;
}

function poiCategoryColor(category) {
  if (category === 'Groen') return '#7D9970';
  if (category === 'OV') return '#4D5C68';
  if (category === 'Stad') return '#6E5B4F';
  if (category === 'Eten') return '#C17F59';
  if (category === 'Winkels') return '#8B6914';
  if (category === 'Sport') return '#3D6F7C';
  if (category === 'Cultuur') return '#6B5B8C';
  return '#A5B4BE';
}

const FILTER_PROJECT = 'De Fromberg';
const OMGEVING_FILTER_CATEGORIES = ['Alle', FILTER_PROJECT, 'Stad', 'OV', 'Groen', 'Winkels', 'Eten', 'Sport', 'Cultuur'];

/**
 * Minimalistisch lijnwerk (24×24 viewBox), afgestemd op Bone & Steel — geen emoji.
 * ctx: categorie uit POI-data, filterwaarde Alle, of FILTER_PROJECT (= huis-symboliek).
 */
function omgevingGlyphDs(ctx) {
  if (ctx === 'Alle') return ['M12 5v4', 'M12 15v4', 'M5 12h4', 'M15 12h4'];
  if (ctx === FILTER_PROJECT) return ['M12 3l9 7.5H19V20H5V10.5H3L12 3z', 'M9 20v-7h6v7'];
  const byCat = {
    Stad: ['M5 18V9h3v9', 'M10 18V5h4v13', 'M16 18v-8h3v8'],
    OV: ['M6 9h12v10H6z', 'M8 6v3', 'M14 6v3', 'M9 13h8'],
    Groen: ['M12 20V11', 'M12 11l-4.5 9', 'M12 11l4.5 9'],
    Eten: ['M8 3.5v18', 'M11.5 3.5v13', 'M15 3.5v18'],
    Winkels: ['M9 8.5V7a3 3 0 016 0v1.5', 'M6.8 11h10.4l-.9 9H7.7l-.9-9z'],
    Sport: ['M5.75 12H4a1.85 1.85 0 100 4h1.75', 'M18.25 12H20a1.85 1.85 0 010 4h-1.75', 'M7.75 12h8.5'],
    Cultuur: ['M12 6L5 14.5h14L12 6z', 'M8.5 14.5V20', 'M12 14.5V20', 'M15.5 14.5V20'],
  };
  return byCat[ctx] || ['M12 18.25a6.25 6.25 0 110-12.5 6.25 6.25 0 010 12.5z', 'M12 14v7'];
}

function glyphPathsMarkup(strokeHex, ds, strokeW) {
  const sw = strokeW != null ? strokeW : 1.75;
  return ds
    .map(
      (d) =>
        `<path d="${d}" fill="none" stroke="${strokeHex}" stroke-width="${sw}" stroke-linecap="round" stroke-linejoin="round"/>`
    )
    .join('');
}

function OmgevingGlyph({ category, color, size, className }) {
  const stroke = color != null ? color : 'currentColor';
  return (
    <svg
      className={className}
      width={size}
      height={size}
      viewBox="0 0 24 24"
      aria-hidden
      style={{ display: 'block' }}
    >
      {omgevingGlyphDs(category).map((d, i) =>
        <path
          key={i}
          d={d}
          fill="none"
          stroke={stroke}
          strokeWidth="1.75"
          strokeLinecap="round"
          strokeLinejoin="round"
        />
      )}
    </svg>
  );
}

function poiSvgMarkerIcon(g, poi) {
  const ring = poiCategoryColor(poi.category);
  const kern = poi.tier === 'kern';
  const size = kern ? 44 : 34;
  const c = size / 2;
  const r = kern ? 16.5 : 12.8;
  const sc = kern ? 0.9 : 0.74;
  const off = 12 * sc;
  const inner = glyphPathsMarkup(ring, omgevingGlyphDs(poi.category), kern ? 1.82 : 1.62);
  const svg =
    `<svg xmlns="http://www.w3.org/2000/svg" width="${size}" height="${size}" viewBox="0 0 ${size} ${size}">` +
    `<circle cx="${c}" cy="${c}" r="${r}" fill="#FFFFFF" stroke="${ring}" stroke-width="${kern ? 3 : 2.5}"/>` +
    `<g transform="translate(${c - off},${c - off}) scale(${sc})">${inner}</g>` +
    `</svg>`;
  const url = 'data:image/svg+xml;charset=UTF-8,' + encodeURIComponent(svg);
  const a = Math.round(c);
  return { url, scaledSize: new g.Size(size, size), anchor: new g.Point(a, a) };
}

function poiMarkerZIndex(p) {
  if (p.tier === 'kern') return 798;
  if (p.category === 'Groen') return 792;
  if (p.category === 'OV') return 788;
  return 782;
}

function frombergSiteMarkerIcon(g) {
  const size = 54;
  const c = 27;
  const sc = 1.07;
  const off = 12 * sc;
  const inner = glyphPathsMarkup('#F5F0E8', omgevingGlyphDs(FILTER_PROJECT), 1.62);
  const svg =
    `<svg xmlns="http://www.w3.org/2000/svg" width="${size}" height="${size}" viewBox="0 0 ${size} ${size}">` +
    `<defs><filter id="fb" x="-20%" y="-20%" width="140%" height="140%"><feDropShadow dx="0" dy="2" stdDeviation="2" flood-color="#1E2D38" flood-opacity="0.35"/></filter></defs>` +
    `<circle cx="${c}" cy="${c}" r="24" fill="#3A4550" stroke="#F5F0E8" stroke-width="4" filter="url(#fb)"/>` +
    `<g transform="translate(${c - off},${c - off}) scale(${sc})">${inner}</g>` +
    `</svg>`;
  const url = 'data:image/svg+xml;charset=UTF-8,' + encodeURIComponent(svg);
  return { url, scaledSize: new g.Size(size, size), anchor: new g.Point(c, c) };
}

function frombergProjectInfoHtml(site) {
  const title = escapeHtmlLite(site.title || 'De Fromberg');
  const tag = escapeHtmlLite(site.tagline || '16 Stads Lofts · Arnhem-Noord');
  const iwHouse =
    '<svg xmlns="http://www.w3.org/2000/svg" width="36" height="36" viewBox="0 0 24 24" aria-hidden="true" style="display:block;margin:0 0 10px">' +
    '<path fill="none" stroke="#4D5C68" stroke-width="1.6" stroke-linecap="round" stroke-linejoin="round" d="M12 3l9 7.5H19V20H5V10.5H3L12 3z"/>' +
    '<path fill="none" stroke="#4D5C68" stroke-width="1.6" stroke-linecap="round" stroke-linejoin="round" d="M9 20v-7h6v7"/></svg>';
  return (
    `<div class="fromberg-map-iw" style="min-width:232px;max-width:288px;padding:12px 14px 14px;font-family:system-ui,-apple-system,sans-serif;color:#3A4550;line-height:1.45">` +
    iwHouse +
    `<div style="font-family:Georgia,'Cormorant Garamond',serif;font-size:21px;font-weight:600;color:#1E2D38;line-height:1.15">${title}</div>` +
    `<div style="margin-top:6px;font-size:11px;font-weight:600;letter-spacing:0.14em;text-transform:uppercase;color:#8B6914">${tag}</div>` +
    `<p style="margin:12px 0 0;font-size:13px;color:#637480">${escapeHtmlLite(
      'Jouw adres op de kaart. Tijden zijn vanaf Frombergdwarsstraat 54 (zelfde berekening als op de site): station, Sonsbeek en supermarkt dichtbij; Valkenhuizen en openluchtmuseum verder.'
    )}</p>` +
    `<div style="margin-top:12px;font-size:11px;color:#A5B4BE">${escapeHtmlLite('Frombergdwarstraat · Arnhem')}</div>` +
    `</div>`
  );
}

// ───────────── Hero Building Illustration ─────────────
// A detailed architectural elevation of a 1930s Dutch brick building.
// Warm bone/steel palette — feels like a measured drawing.
function HeroBuildingIllustration() {
  return (
    <svg
      viewBox="0 0 560 780"
      preserveAspectRatio="xMidYMid slice"
      style={{ position: 'absolute', inset: 0, width: '100%', height: '100%' }}
      xmlns="http://www.w3.org/2000/svg">
      
      <defs>
        <linearGradient id="hsky" x1="0" y1="0" x2="0" y2="1">
          <stop offset="0%" stopColor="#3a4550" />
          <stop offset="100%" stopColor="#4a5a68" />
        </linearGradient>
        <linearGradient id="hwall" x1="0" y1="0" x2="0" y2="1">
          <stop offset="0%" stopColor="#c8bfae" />
          <stop offset="100%" stopColor="#a89e8c" />
        </linearGradient>
        <linearGradient id="hwall2" x1="0" y1="0" x2="0" y2="1">
          <stop offset="0%" stopColor="#b5aa98" />
          <stop offset="100%" stopColor="#9a9080" />
        </linearGradient>
        <linearGradient id="hground" x1="0" y1="0" x2="0" y2="1">
          <stop offset="0%" stopColor="#4d5c68" />
          <stop offset="100%" stopColor="#3a4550" />
        </linearGradient>
        <linearGradient id="hwin" x1="0" y1="0" x2="0" y2="1">
          <stop offset="0%" stopColor="#2e3d4a" stopOpacity="0.9" />
          <stop offset="100%" stopColor="#1e2d38" stopOpacity="0.95" />
        </linearGradient>
        <pattern id="brick" x="0" y="0" width="20" height="10" patternUnits="userSpaceOnUse">
          <rect width="20" height="10" fill="none" />
          <rect x="0.5" y="0.5" width="18" height="4" fill="none" stroke="rgba(90,80,68,0.18)" strokeWidth="0.4" />
          <rect x="10.5" y="5.5" width="8" height="4" fill="none" stroke="rgba(90,80,68,0.18)" strokeWidth="0.4" />
          <rect x="0.5" y="5.5" width="8" height="4" fill="none" stroke="rgba(90,80,68,0.18)" strokeWidth="0.4" />
        </pattern>
        <filter id="shadow" x="-5%" y="-5%" width="115%" height="130%">
          <feDropShadow dx="0" dy="4" stdDeviation="6" floodColor="#1e2d38" floodOpacity="0.35" />
        </filter>
      </defs>

      {/* Sky / background */}
      <rect width="560" height="780" fill="url(#hsky)" />

      {/* Distant street / ground plane */}
      <rect x="0" y="680" width="560" height="100" fill="url(#hground)" />
      {/* Pavement line */}
      <line x1="0" y1="680" x2="560" y2="680" stroke="rgba(255,255,255,0.08)" strokeWidth="1" />

      {/* ── Main building body ── */}
      {/* Back wall (slightly darker, creates depth) */}
      <rect x="28" y="100" width="508" height="582" fill="url(#hwall2)" opacity="0.6" />

      {/* Front façade */}
      <rect x="30" y="102" width="500" height="578" fill="url(#hwall)" />
      {/* Brick texture overlay */}
      <rect x="30" y="102" width="500" height="578" fill="url(#brick)" opacity="0.7" />

      {/* ── Roof / cornice ── */}
      {/* Main cornice band */}
      <rect x="22" y="94" width="516" height="16" fill="#8a7f6e" />
      <rect x="22" y="94" width="516" height="4" fill="#9d9281" />
      {/* Decorative dentils */}
      {Array.from({ length: 24 }, (_, i) =>
      <rect key={i} x={30 + i * 21} y={98} width={13} height={9} fill="#7a7060" opacity="0.7" />
      )}
      {/* Parapet / gable suggestion */}
      <path d="M 30 94 L 30 70 L 140 55 L 280 48 L 420 55 L 530 70 L 530 94 Z" fill="#9a9081" opacity="0.5" />
      <path d="M 30 70 L 280 48 L 530 70" fill="none" stroke="#7a7060" strokeWidth="1.5" />
      {/* Roofline ridge ornaments */}
      <rect x="125" y="52" width="8" height="18" fill="#8a7f6e" />
      <rect x="121" y="48" width="16" height="6" fill="#8a7f6e" />
      <rect x="272" y="44" width="16" height="22" fill="#8a7f6e" />
      <rect x="268" y="40" width="24" height="6" fill="#8a7f6e" />
      <rect x="415" y="52" width="8" height="18" fill="#8a7f6e" />
      <rect x="411" y="48" width="16" height="6" fill="#8a7f6e" />

      {/* ── Floor separators ── */}
      <rect x="30" y="295" width="500" height="6" fill="#9a9080" opacity="0.6" />
      <rect x="30" y="301" width="500" height="2" fill="rgba(255,255,255,0.12)" />
      <rect x="30" y="460" width="500" height="6" fill="#9a9080" opacity="0.6" />
      <rect x="30" y="466" width="500" height="2" fill="rgba(255,255,255,0.12)" />

      {/* ── Window helper ── */}
      {/* Top floor windows (4 wide arched windows) */}
      {[55, 175, 320, 420].map((x, i) =>
      <g key={`w2-${i}`}>
          {/* Window recess */}
          <rect x={x} y={130} width={86} height={150} fill="#7a7060" opacity="0.3" />
          {/* Arch */}
          <path d={`M ${x} ${175} L ${x} ${155} Q ${x + 43} ${130} ${x + 86} ${155} L ${x + 86} ${175} Z`} fill="#9a9081" opacity="0.5" />
          {/* Glass */}
          <rect x={x + 4} y={175} width={78} height={100} fill="url(#hwin)" />
          {/* Glazing bars */}
          <line x1={x + 43} y1={175} x2={x + 43} y2={275} stroke="rgba(200,212,218,0.4)" strokeWidth="1.2" />
          <line x1={x + 4} y1={225} x2={x + 82} y2={225} stroke="rgba(200,212,218,0.4)" strokeWidth="1.2" />
          {/* Sill */}
          <rect x={x - 2} y={274} width={90} height={6} fill="#8a7f6e" />
          {/* Subtle light reflection */}
          <rect x={x + 6} y={177} width={22} height={45} fill="rgba(255,255,255,0.04)" rx="1" />
        </g>
      )}

      {/* Middle floor windows (5 rectangular windows) */}
      {[42, 140, 237, 334, 432].map((x, i) =>
      <g key={`w1-${i}`}>
          <rect x={x} y={320} width={76} height={118} fill="#7a7060" opacity="0.25" />
          <rect x={x + 4} y={324} width={68} height={110} fill="url(#hwin)" />
          <line x1={x + 38} y1={324} x2={x + 38} y2={434} stroke="rgba(200,212,218,0.35)" strokeWidth="1.1" />
          <line x1={x + 4} y1={380} x2={x + 72} y2={380} stroke="rgba(200,212,218,0.35)" strokeWidth="1.1" />
          <rect x={x - 2} y={432} width={80} height={5} fill="#8a7f6e" />
          <rect x={x + 6} y={326} width={18} height={36} fill="rgba(255,255,255,0.035)" rx="1" />
          {/* Lintel */}
          <rect x={x - 2} y={318} width={80} height={6} fill="#9a9081" opacity="0.7" />
        </g>
      )}

      {/* Ground floor: shopfront windows + entrance door */}
      {/* Left bay + door */}
      <rect x="42" y="490" width="76" height="165" fill="#5a5045" opacity="0.5" />
      <rect x="46" y="494" width="68" height="157" fill="url(#hwin)" />
      <line x1="80" y1="494" x2="80" y2="651" stroke="rgba(200,212,218,0.3)" strokeWidth="1" />
      <line x1="46" y1="572" x2="114" y2="572" stroke="rgba(200,212,218,0.3)" strokeWidth="1" />

      {/* Central entrance door */}
      <rect x="222" y="510" width="120" height="168" fill="#4a5560" opacity="0.6" />
      <path d="M 222 545 Q 282 510 342 545" fill="#5a6570" opacity="0.5" />
      <rect x="228" y="545" width="52" height="133" fill="url(#hwin)" />
      <rect x="284" y="545" width="52" height="133" fill="url(#hwin)" opacity="0.85" />
      {/* Door handles */}
      <rect x="278" y="610" width="6" height="20" fill="rgba(200,212,218,0.5)" rx="2" />
      <rect x="276" y="628" width="10" height="3" fill="rgba(200,212,218,0.4)" rx="1" />
      {/* Fanlight */}
      <path d="M 228 545 Q 282 515 336 545" fill="none" stroke="rgba(200,212,218,0.3)" strokeWidth="1" />
      {/* Door surround */}
      <rect x="218" y="507" width="128" height="8" fill="#8a7f6e" />
      <rect x="214" y="505" width="6" height="173" fill="#8a7f6e" />
      <rect x="344" y="505" width="6" height="173" fill="#8a7f6e" />

      {/* Right ground bays */}
      <rect x="400" y="490" width="76" height="165" fill="#5a5045" opacity="0.5" />
      <rect x="404" y="494" width="68" height="157" fill="url(#hwin)" />
      <line x1="438" y1="494" x2="438" y2="651" stroke="rgba(200,212,218,0.3)" strokeWidth="1" />
      <line x1="404" y1="572" x2="472" y2="572" stroke="rgba(200,212,218,0.3)" strokeWidth="1" />

      <rect x="134" y="500" width="76" height="155" fill="#5a5045" opacity="0.45" />
      <rect x="138" y="504" width="68" height="147" fill="url(#hwin)" opacity="0.9" />
      <line x1="172" y1="504" x2="172" y2="651" stroke="rgba(200,212,218,0.25)" strokeWidth="1" />

      <rect x="484" y="500" width="44" height="155" fill="#5a5045" opacity="0.45" />
      <rect x="488" y="504" width="36" height="147" fill="url(#hwin)" opacity="0.9" />

      {/* ── Ground floor plinth ── */}
      <rect x="30" y="651" width="500" height="29" fill="#6a6256" />
      <rect x="30" y="651" width="500" height="3" fill="rgba(255,255,255,0.1)" />

      {/* ── Balconies on first floor ── */}
      {[42, 237, 432].map((x, i) =>
      <g key={`bal-${i}`}>
          <rect x={x - 4} y={430} width={84} height={6} fill="#8a7f6e" />
          {/* Railing posts */}
          {Array.from({ length: 9 }, (_, j) =>
        <line key={j} x1={x + j * 10} y1={436} x2={x + j * 10} y2={458} stroke="rgba(200,212,218,0.35)" strokeWidth="1" />
        )}
          <line x1={x - 4} y1={436} x2={x + 80} y2={436} stroke="rgba(200,212,218,0.5)" strokeWidth="1.2" />
          <line x1={x - 4} y1={458} x2={x + 80} y2={458} stroke="rgba(200,212,218,0.35)" strokeWidth="0.8" />
        </g>
      )}

      {/* ── Vertical pilasters ── */}
      {[30, 148, 266, 384, 502, 530].map((x, i) =>
      <rect key={`p-${i}`} x={x} y={102} width={6} height={578} fill="rgba(90,80,68,0.15)" />
      )}

      {/* ── Subtle shadow / depth on facade ── */}
      <rect x="30" y="102" width="10" height="578" fill="rgba(0,0,0,0.08)" />
      <rect x="520" y="102" width="10" height="578" fill="rgba(0,0,0,0.05)" />

      {/* ── Street level details ── */}
      {/* Pavement texture */}
      {Array.from({ length: 12 }, (_, i) =>
      <line key={`pave-${i}`} x1={i * 50} y1={700} x2={i * 50 + 40} y2={700} stroke="rgba(255,255,255,0.04)" strokeWidth="0.5" />
      )}
      {/* Street number plaque */}
      <rect x="264" y="490" width="36" height="16" fill="rgba(200,212,218,0.15)" rx="1" />
      <text x="282" y="501" textAnchor="middle" fontSize="7" fill="rgba(200,212,218,0.7)" fontFamily="ui-sans-serif,system-ui">54</text>

      {/* ── Foreground: subtle vignette at bottom ── */}
      <rect x="0" y="620" width="560" height="160" fill="url(#hsky)" opacity="0.35" />

      {/* ── Light from windows (warm glow) ── */}
      {[58, 178, 323, 423].map((x, i) =>
      <rect key={`glow-${i}`} x={x + 4} y={175} width={78} height={100} fill="rgba(245,240,232,0.03)" rx="1" />
      )}
    </svg>);

}

// ───────────── HOME ─────────────
function HomePage({ setPage, accents }) {
  return (
    <div className="page">
      {/* Hero — full-bleed illustration, centered text anchored to bottom */}
      <section style={{
        minHeight: '82svh',
        position: 'relative',
        overflow: 'hidden',
        display: 'flex',
        flexDirection: 'column',
        justifyContent: 'flex-end',
        alignItems: 'center',
      }}>
        <div style={{ position: 'absolute', inset: 0 }}>
          <HeroBuildingIllustration />
        </div>
        <div style={{
          position: 'absolute', inset: 0,
          background: 'linear-gradient(to top, rgba(30,45,56,0.90) 0%, rgba(30,45,56,0.50) 40%, rgba(30,45,56,0.20) 100%)'
        }} />
        <div style={{
          position: 'relative', zIndex: 1,
          textAlign: 'center',
          padding: '0 clamp(32px,6vw,96px) clamp(72px,8vw,112px)',
          maxWidth: 760,
          display: 'flex', flexDirection: 'column', alignItems: 'center', gap: 20
        }}>
          <Label steel>Project — Arnhem</Label>
          <h1 style={{
            fontFamily: 'var(--serif)', fontWeight: 300,
            fontSize: 'clamp(52px,6.5vw,88px)',
            lineHeight: 0.95, letterSpacing: '-0.025em',
            color: 'var(--bone-10)'
          }}>De From<em style={{ fontStyle: 'italic', color: 'var(--bone-30)' }}>berg</em></h1>
          <div style={{ display: 'flex', alignItems: 'center', gap: 16, marginTop: 4 }}>
            <span style={{ width: 24, height: 1, background: 'rgba(245,240,232,0.25)', display: 'inline-block' }} />
            <span style={{ fontSize: 13, color: 'var(--bone-30)', fontFamily: 'var(--serif)', fontWeight: 300, letterSpacing: '0.02em' }}>door <em style={{ fontStyle: 'italic' }}>Consent Vastgoed</em></span>
            <span style={{ width: 24, height: 1, background: 'rgba(245,240,232,0.25)', display: 'inline-block' }} />
          </div>
          <p style={{
            color: 'var(--bone-20)', fontSize: 'clamp(15px,1.3vw,18px)',
            lineHeight: 1.7, maxWidth: '40ch', marginTop: 4
          }}>
            Zestien Stads Lofts in een karakteristiek gebouw in Arnhem‑Noord — met respect voor wat er al staat. Geplande oplevering eerste kwartaal 2028.
          </p>
          <div style={{ display: 'flex', gap: 12, flexWrap: 'wrap', justifyContent: 'center', marginTop: 8 }}>
            <button type="button" className="btn btn--cta" onClick={() => setPage('voorinschrijven')}>
              <span className="btn--cta__label">Voorinschrijven</span>
              <span aria-hidden="true" className="btn--cta__arrow">→</span>
            </button>
            <button className="btn btn--secondary-light" onClick={() => setPage('aanbod')}>Het project bekijken</button>
          </div>
          <div style={{ display: 'flex', alignItems: 'center', gap: 12, color: 'var(--bone-30)', fontSize: 11, textTransform: 'uppercase', letterSpacing: '0.18em', marginTop: 8 }}>
            <span style={{ width: 40, height: 1, background: 'var(--bone-30)', display: 'inline-block', animation: 'scrollPulse 2.4s ease-in-out infinite' }}></span>
            <span>Scroll</span>
          </div>
        </div>
      </section>

      {/* 01 — Het project */}
      <section className="bg-bone-00">
        <div className="container">
          <div className="two-col">
            <div>
              <Label>01 — Het project</Label>
              <h2 style={{ marginTop: 24 }}>Een rustige stedelijke <em className="italic-accent-steel">{accents.intro || 'transformatie'}</em></h2>
              <div style={{ marginTop: 32, display: 'flex', flexDirection: 'column', gap: 24 }}>
                <p>De Fromberg transformeert een karakteristiek bestaand gebouw aan de Frombergdwarstraat tot zestien Stads Lofts — eigentijds wonen achter een gevel die haar geschiedenis behoudt.</p>
                <p>De woningen variëren van compacte stadsappartementen tot ruime maisonnettes: acht maisonnettes van circa 78 m² (sectie A) en acht appartementen van circa 56 m² (secties B en C). Sonsbeekpark en Arnhem Centraal liggen beiden op ongeveer vijf fietsminuten; het Rijn- en Korenmarktgebied op ongeveer zeven.</p>
              </div>
            </div>
            <div className="stats">
              <div className="stat">
                <div className="stat__value">16</div>
                <Label>Woningen</Label>
              </div>
              <div className="stat">
                <div className="stat__value">vanaf 56 <em>m²</em></div>
                <Label>Woonoppervlak</Label>
              </div>
              <div className="stat">
                <div className="stat__value">Q1 2028</div>
                <Label>Geplande oplevering</Label>
              </div>
              <div className="stat">
                <div className="stat__value">8</div>
                <Label>Maisonnettes</Label>
              </div>
            </div>
          </div>
        </div>
      </section>

      {/* History — De naam achter het project */}
      <section className="bg-steel-70">
        <div className="container">
          <div className="section-head">
            <Label light>De geschiedenis</Label>
            <h2 style={{ color: 'var(--bone-10)' }}>Arnhem <em className="italic-accent">Fromberg</em></h2>
            <p style={{ color: 'var(--steel-20)', maxWidth: '58ch' }}>
              De Frombergdwarstraat is vernoemd naar <strong style={{ color: 'var(--bone-20)', fontWeight: 500 }}>Hendrik Willem Fromberg (1812–1882)</strong> — Arnhems eerste projectontwikkelaar. Hij bouwde Musis Sacrum, legde Oud-Heijenoord aan en bezat Villa Bronbeek voordat die een koninklijk paleis werd. Zijn straat. Zijn naam. Onze lofts.
            </p>
          </div>
          <div className="history-grid">
            {[
              { year: '1812', title: 'Geboren in Kleef', desc: 'Hendrik Willem Fromberg wordt geboren in het Duitse Kleef, vlak over de grens. In 1840 vestigt hij zich definitief in Arnhem.' },
              { year: '1847', title: 'Musis Sacrum', desc: 'Op zijn initiatief verrijst de bekende Arnhemse concertzaal. In 2020 hernoemd tot de Frombergzaal — zijn naam klinkt er nog steeds.' },
              { year: '1849', title: 'Arnhem-Noord', desc: 'Eerste villa\'s buiten de Janspoort. Fromberg legt de basis voor Oud-Heijenoord als een van de mooiste woonwijken van de stad.' },
              { year: '1853', title: 'Fromberghuizen', desc: 'Vijf neoclassicistische herenhuizen op het Willemsplein — alle vijf tot op de dag van vandaag rijksmonument.' },
              { year: '1874–79', title: 'Deze straat', desc: 'De Frombergdwarstraat wordt aangelegd op zijn landgoed Villa Beaulieu — letterlijk uitgehouwen uit zijn eigen achtertuin.' },
              { year: '1882', title: 'Een blijvende nalatenschap', desc: 'Fromberg overlijdt, maar zijn naam staat in steen: in straten, monumenten en een concertzaal midden in Arnhem.' },
            ].map((item, i) => (
              <div key={i} className="history-card">
                <div className="history-card__year">{item.year}</div>
                <div className="history-card__title">{item.title}</div>
                <div className="history-card__desc">{item.desc}</div>
              </div>
            ))}
          </div>
        </div>
      </section>

      {/* Planning */}
      <section className="bg-bone-00">
        <div className="container">
          <div className="section-head">
            <Label>De planning</Label>
            <h2>Van inschrijving tot <em className="italic-accent-steel">oplevering</em></h2>
          </div>
          <div className="proj-timeline">
            {(() => {
              const activeIdx = getProjectPlanningActiveIndex(new Date());
              return PROJECT_PLANNING_STEPS.map((s, i) => {
                const active = i === activeIdx;
                const dateText = active ? `Nu — ${s.dateLabel}` : s.dateLabel;
                return (
                  <div key={i} className={`proj-step${active ? ' proj-step--active' : ''}`}>
                    <div className="proj-node"><span>{i + 1}</span></div>
                    <div className="proj-body">
                      <div className="proj-date">{dateText}</div>
                      <div className="proj-label">{s.label}</div>
                      <div className="proj-desc">{s.desc}</div>
                    </div>
                  </div>
                );
              });
            })()}
          </div>
        </div>
      </section>

      {/* 02 — Sneak preview */}
      <section className="bg-bone-10">
        <div className="container">
          <div className="section-head">
            <Label>02 — De woningen</Label>
            <h2>Zestien Stads <em className="italic-accent-steel">{accents.lofts || 'Lofts'}</em></h2>
            <p>Zestien woningen achter één gevel — acht ruime maisonnettes (sectie A, circa 78 m²) en acht compacte appartementen (secties B en C, circa 56 m²). Klik op een woning om de plattegrond en specificaties te bekijken.</p>
          </div>
          <div style={{ background: 'var(--bone-00)', padding: 24, border: '1px solid var(--bone-20)', borderRadius: 3 }}>
            <div style={{ position: 'relative', aspectRatio: '16/9', overflow: 'hidden' }}>
              <BuildingIllustration />
              <svg viewBox="0 0 1000 563" preserveAspectRatio="none" style={{ position: 'absolute', inset: 0, width: '100%', height: '100%' }}>
                {window.BUILDING_POLYGONS.voor.map((poly) => {
                  const u = UNITS.find((x) => x.id === poly.id);
                  return <polygon key={poly.id} points={poly.points} fill={window.statusFill(u.status)} stroke="rgba(253,251,247,0.85)" strokeWidth="2" />;
                })}
              </svg>
            </div>
            <div style={{ display: 'flex', justifyContent: 'space-between', alignItems: 'center', marginTop: 24, flexWrap: 'wrap', gap: 16 }}>
              <div style={{ display: 'flex', gap: 24, flexWrap: 'wrap' }}>
                <span className="bv-legend__item"><span className="dot dot--available"></span> Beschikbaar</span>
                <span className="bv-legend__item"><span className="dot dot--option"></span> Onder optie</span>
                <span className="bv-legend__item"><span className="dot dot--sold"></span> Verkocht</span>
              </div>
              <button onClick={() => setPage('aanbod')} className="link">Bekijk alle woningen →</button>
            </div>
          </div>
        </div>
      </section>

      {/* 03 — Omgeving */}
      <section className="bg-bone-00">
        <div className="container">
          <div className="section-head">
            <Label>03 — De omgeving</Label>
            <h2>Wonen in <em className="italic-accent-steel">{accents.area || 'Arnhem-Noord'}</em></h2>
            <p>De Frombergdwarstraat ligt in een levendig deel van Arnhem-Noord — Sonsbeekpark en station op ongeveer vijf fietsminuten, het centrum op ongeveer zeven — tussen groen en stad.</p>
          </div>
          <div className="poi-grid">
            {POIS.slice(0, 4).map((p, i) =>
            <div key={p.name} className="poi-card">
                <div className="poi-card__media">
                  <PoiArt index={i} />
                </div>
                <div className="poi-card__body">
                  <Label>{p.category}</Label>
                  <div className="poi-card__name">{p.name}</div>
                  <div className="poi-card__distance">{p.minutes} min · {p.mode}</div>
                </div>
              </div>
            )}
          </div>
          <div style={{ marginTop: 48 }}>
            <button onClick={() => setPage('omgeving')} className="link">Verken de omgeving →</button>
          </div>
        </div>
      </section>

      <HypotheekSection />

      {/* 04 — Open dag CTA */}
      <section className="bg-steel-70">
        <div className="container">
          <div className="cta-grid">
            <div>
              <Label light>Open dag — September 2026</Label>
              <h2 style={{ marginTop: 24 }}>Wees er als eerste bij op de <em className="italic-accent">{accents.cta || 'open dag'}</em></h2>
              <p style={{ marginTop: 24, fontSize: 17, maxWidth: 480 }}>
                Voorinschrijvers krijgen als eerste een persoonlijke uitnodiging voor de open dag in september 2026. Daar wordt het project gepresenteerd en worden de woningen toegewezen.
              </p>
            </div>
            <div style={{ background: 'rgba(255,255,255,0.04)', padding: 40, border: '1px solid rgba(255,255,255,0.08)', borderRadius: 3 }}>
              <Label light>E-mail</Label>
              <div style={{ display: 'flex', gap: 12, marginTop: 12, flexWrap: 'wrap' }}>
                <input type="email" placeholder="jouw@e-mail.nl" style={{ flex: 1, minWidth: 200, background: 'transparent', border: 0, borderBottom: '1px solid var(--bone-30)', color: 'var(--bone-10)', padding: '10px 0', fontSize: 16 }} />
                <button className="btn btn--primary-light" onClick={() => setPage('voorinschrijven')}>Inschrijven</button>
              </div>
              <p style={{ fontSize: 12, color: 'var(--steel-30)', marginTop: 24, lineHeight: 1.5 }}>We gaan zorgvuldig om met jouw gegevens. Je kunt jouw inschrijving op elk moment intrekken.</p>
            </div>
          </div>
        </div>
      </section>

      {/* 05 — Nieuws */}
      <section className="bg-bone-10">
        <div className="container">
          <div className="section-head">
            <Label>04 — Nieuws</Label>
            <h2>Voortgang & <em className="italic-accent-steel">{accents.news || 'updates'}</em></h2>
          </div>
          <div className="news-grid">
            {NEWS.slice(0, 3).map((n, i) =>
            <div key={n.title} className="news-card">
                <div className="news-card__media"><NewsCardArt index={i} /></div>
                <span className="news-card__date">{n.date}</span>
                <h3 className="news-card__title">{n.title}</h3>
                <p className="news-card__excerpt">{n.excerpt}</p>
                <a href="#" className="link" style={{ alignSelf: 'flex-start', fontSize: 10 }}>Lees verder →</a>
              </div>
            )}
          </div>
          <div style={{ marginTop: 64 }}>
            <button onClick={() => setPage('nieuws')} className="link">Alle berichten →</button>
          </div>
        </div>
      </section>
    </div>);

}

// POI photos
function PoiArt({ index }) {
  const imgs = [
    'https://d8j0ntlcm91z4.cloudfront.net/user_3DFgVRESLQIchLGRYxPWZpW6Vre/hf_20260508_124608_38573f50-be9a-497e-8914-e4657487e4d3.png',
    'https://d8j0ntlcm91z4.cloudfront.net/user_3DFgVRESLQIchLGRYxPWZpW6Vre/hf_20260508_124615_52026926-63e1-4a3f-9deb-eb6322e85820.png',
    'https://images.pexels.com/photos/18823964/pexels-photo-18823964.jpeg?auto=compress&cs=tinysrgb&w=600&h=400&fit=crop',
    'https://images.pexels.com/photos/6913563/pexels-photo-6913563.jpeg?auto=compress&cs=tinysrgb&w=600&h=400&fit=crop',
    'https://images.pexels.com/photos/17791636/pexels-photo-17791636.jpeg?auto=compress&cs=tinysrgb&w=600&h=400&fit=crop',
    'https://images.pexels.com/photos/9615249/pexels-photo-9615249.jpeg?auto=compress&cs=tinysrgb&w=600&h=400&fit=crop',
    'https://images.pexels.com/photos/8089275/pexels-photo-8089275.jpeg?auto=compress&cs=tinysrgb&w=600&h=400&fit=crop',
    'https://images.pexels.com/photos/18823964/pexels-photo-18823964.jpeg?auto=compress&cs=tinysrgb&w=600&h=400&fit=crop',
  ];
  return <img src={imgs[index % imgs.length]} alt="" style={{ position: 'absolute', inset: 0, width: '100%', height: '100%', objectFit: 'cover' }} />;
}

// ───────────── News card art ─────────────
function NewsCardArt({ index }) {
  const imgs = [
    'https://images.pexels.com/photos/8089275/pexels-photo-8089275.jpeg?auto=compress&cs=tinysrgb&w=640&h=360&fit=crop',
    'https://images.pexels.com/photos/9615249/pexels-photo-9615249.jpeg?auto=compress&cs=tinysrgb&w=640&h=360&fit=crop',
    'https://images.pexels.com/photos/17791636/pexels-photo-17791636.jpeg?auto=compress&cs=tinysrgb&w=640&h=360&fit=crop',
    'https://d8j0ntlcm91z4.cloudfront.net/user_3DFgVRESLQIchLGRYxPWZpW6Vre/hf_20260508_124304_efd24687-abbc-47a7-a9cb-db3ac5ae5f3d.png',
    'https://images.pexels.com/photos/18823964/pexels-photo-18823964.jpeg?auto=compress&cs=tinysrgb&w=640&h=360&fit=crop',
    'https://d8j0ntlcm91z4.cloudfront.net/user_3DFgVRESLQIchLGRYxPWZpW6Vre/hf_20260508_124304_b9b191c1-c4f6-490a-9564-f8f6adc4e465.png',
  ];
  return <img src={imgs[index % imgs.length]} alt="" style={{ width: '100%', height: '100%', objectFit: 'cover', display: 'block' }} />;
  const arts = [
    // 0 — Voorinschrijving geopend: envelope + form lines
    <svg key={0} viewBox="0 0 320 180" style={{ width:'100%', height:'100%', display:'block' }}>
      <rect width="320" height="180" fill="#4D5C68"/>
      <rect x="60" y="52" width="200" height="130" rx="3" fill="#3A4550" stroke="rgba(245,240,232,0.15)" strokeWidth="1.5"/>
      <path d="M 60 52 L 160 115 L 260 52" fill="none" stroke="rgba(245,240,232,0.35)" strokeWidth="1.5"/>
      <line x1="85" y1="135" x2="155" y2="135" stroke="rgba(245,240,232,0.2)" strokeWidth="1.2"/>
      <line x1="85" y1="148" x2="175" y2="148" stroke="rgba(245,240,232,0.15)" strokeWidth="1.2"/>
      <line x1="85" y1="161" x2="140" y2="161" stroke="rgba(245,240,232,0.1)" strokeWidth="1.2"/>
      <circle cx="235" cy="148" r="22" fill="rgba(126,168,130,0.25)" stroke="rgba(126,168,130,0.5)" strokeWidth="1.5"/>
      <path d="M 226 148 L 232 154 L 244 142" fill="none" stroke="rgba(126,168,130,0.9)" strokeWidth="2" strokeLinecap="round"/>
    </svg>,
    // 1 — Akoestisch onderzoek: sound waves
    <svg key={1} viewBox="0 0 320 180" style={{ width:'100%', height:'100%', display:'block' }}>
      <rect width="320" height="180" fill="#3A4550"/>
      {[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19].map((i) => {
        const x = 20 + i * 14; const h = [18,26,42,30,58,72,60,44,80,90,76,62,48,70,52,36,28,44,24,16][i];
        return <rect key={i} x={x} y={90 - h/2} width={8} height={h} rx="4" fill={`rgba(200,212,218,${0.25 + (h/90)*0.55})`}/>;
      })}
      <line x1="18" y1="90" x2="302" y2="90" stroke="rgba(245,240,232,0.08)" strokeWidth="1"/>
      <text x="160" y="162" textAnchor="middle" fontSize="9" fill="rgba(165,180,190,0.6)" fontFamily="var(--sans)" letterSpacing="0.14em">GELUIDSISOLATIE OVERTREFT NORM</text>
    </svg>,
    // 2 — Definitief ontwerp: blueprint lines
    <svg key={2} viewBox="0 0 320 180" style={{ width:'100%', height:'100%', display:'block' }}>
      <rect width="320" height="180" fill="#4D5C68"/>
      <rect x="50" y="35" width="220" height="110" fill="none" stroke="rgba(245,240,232,0.18)" strokeWidth="1" strokeDasharray="4 3"/>
      <rect x="70" y="55" width="80" height="70" fill="none" stroke="rgba(245,240,232,0.3)" strokeWidth="1.2"/>
      <rect x="170" y="55" width="80" height="70" fill="none" stroke="rgba(245,240,232,0.3)" strokeWidth="1.2"/>
      <line x1="110" y1="55" x2="110" y2="125" stroke="rgba(245,240,232,0.15)" strokeWidth="0.8"/>
      <line x1="210" y1="55" x2="210" y2="125" stroke="rgba(245,240,232,0.15)" strokeWidth="0.8"/>
      <line x1="50" y1="90" x2="270" y2="90" stroke="rgba(245,240,232,0.12)" strokeWidth="0.8"/>
      <line x1="160" y1="25" x2="160" y2="155" stroke="rgba(245,240,232,0.08)" strokeWidth="0.8" strokeDasharray="3 4"/>
      <text x="160" y="162" textAnchor="middle" fontSize="9" fill="rgba(216,206,188,0.55)" fontFamily="var(--sans)" letterSpacing="0.14em">DEFINITIEF ONTWERP — MAARSEN PLAN</text>
    </svg>,
    // 3 — Vergunning verleend: official stamp / circle
    <svg key={3} viewBox="0 0 320 180" style={{ width:'100%', height:'100%', display:'block' }}>
      <rect width="320" height="180" fill="#3A4550"/>
      <circle cx="160" cy="85" r="56" fill="none" stroke="rgba(245,240,232,0.2)" strokeWidth="1.5"/>
      <circle cx="160" cy="85" r="48" fill="none" stroke="rgba(245,240,232,0.12)" strokeWidth="1"/>
      <circle cx="160" cy="85" r="38" fill="rgba(126,168,130,0.12)" stroke="rgba(126,168,130,0.4)" strokeWidth="1.5"/>
      <text x="160" y="79" textAnchor="middle" fontSize="8" fill="rgba(245,240,232,0.7)" fontFamily="var(--sans)" letterSpacing="0.16em">GEMEENTE</text>
      <text x="160" y="92" textAnchor="middle" fontSize="8" fill="rgba(245,240,232,0.7)" fontFamily="var(--sans)" letterSpacing="0.16em">ARNHEM</text>
      <path d="M 148 101 L 155 108 L 172 94" fill="none" stroke="rgba(126,168,130,0.9)" strokeWidth="2.5" strokeLinecap="round"/>
      <text x="160" y="162" textAnchor="middle" fontSize="9" fill="rgba(165,180,190,0.6)" fontFamily="var(--sans)" letterSpacing="0.14em">OMGEVINGSVERGUNNING VERLEEND</text>
    </svg>,
    // 4 — BMV Makelaars: two buildings / handshake
    <svg key={4} viewBox="0 0 320 180" style={{ width:'100%', height:'100%', display:'block' }}>
      <rect width="320" height="180" fill="#4D5C68"/>
      <rect x="60" y="60" width="80" height="90" fill="none" stroke="rgba(245,240,232,0.25)" strokeWidth="1.5"/>
      <rect x="180" y="75" width="80" height="75" fill="none" stroke="rgba(245,240,232,0.25)" strokeWidth="1.5"/>
      {[75,90,105].map(y => <line key={y} x1="68" y1={y} x2="132" y2={y} stroke="rgba(245,240,232,0.12)" strokeWidth="0.8"/>)}
      {[90,105].map(y => <line key={y} x1="188" y1={y} x2="252" y2={y} stroke="rgba(245,240,232,0.12)" strokeWidth="0.8"/>)}
      <line x1="100" y1="150" x2="100" y2="150" stroke="rgba(245,240,232,0)" strokeWidth="0"/>
      <path d="M 140 120 C 150 110 170 110 180 120" fill="none" stroke="rgba(216,206,188,0.5)" strokeWidth="1.5"/>
      <circle cx="140" cy="121" r="3" fill="rgba(216,206,188,0.6)"/>
      <circle cx="180" cy="121" r="3" fill="rgba(216,206,188,0.6)"/>
      <text x="160" y="162" textAnchor="middle" fontSize="9" fill="rgba(165,180,190,0.6)" fontFamily="var(--sans)" letterSpacing="0.14em">VERKOOPMAKELAAR — BMV ARNHEM</text>
    </svg>,
    // 5 — Project aangekondigd: building silhouette
    <svg key={5} viewBox="0 0 320 180" style={{ width:'100%', height:'100%', display:'block' }}>
      <rect width="320" height="180" fill="#3A4550"/>
      <rect x="50" y="55" width="220" height="95" fill="#2e3d4a"/>
      <rect x="50" y="50" width="220" height="8" fill="#4a5a68"/>
      {[0,1,2,3,4].map(i => [0,1,2].map(j => <rect key={`w${i}${j}`} x={68+i*42} y={66+j*24} width={24} height={16} fill="rgba(58,69,80,0.8)" stroke="rgba(200,212,218,0.2)" strokeWidth="0.8"/>))}
      <rect x="136" y="118" width="48" height="32" fill="#2e3d4a" stroke="rgba(200,212,218,0.25)" strokeWidth="0.8"/>
      <path d="M 50 50 L 160 38 L 270 50" fill="none" stroke="rgba(165,180,190,0.35)" strokeWidth="1.2"/>
      <text x="160" y="162" textAnchor="middle" fontSize="9" fill="rgba(165,180,190,0.6)" fontFamily="var(--sans)" letterSpacing="0.14em">FROMBERGDWARSTRAAT 54 — ARNHEM-NOORD</text>
    </svg>,
  ];
  return arts[index % arts.length];
}

// ───────────── AANBOD ─────────────
function AanbodPage({ accents }) {
  const [selected, setSelected] = R_useState(null);
  const [statusFilter, setStatusFilter] = R_useState({ available: true, option: true, sold: true });
  const [filters, setFilters] = R_useState({ A: true, B: true, C: true });

  const filtered = R_useMemo(() => UNITS.filter((u) => {
    if (!statusFilter[u.status]) return false;
    if (!filters[u.id[0]]) return false;
    return true;
  }), [statusFilter, filters]);

  return (
    <div className="page">
      <section className="bg-bone-10">
        <div className="container">
          <div className="section-head" style={{ marginBottom: 0 }}>
            <Label>Aanbod</Label>
            <h1 style={{ fontSize: 'clamp(40px, 5.5vw, 72px)' }}>Zestien woningen, <em className="italic-accent-steel">{accents.aanbod || 'van compact tot royaal'}</em></h1>
            <p style={{ marginTop: 8 }}>Klik op een woning in het gebouw of in de lijst om de plattegrond, specificaties en prijsindicatie te bekijken.</p>
          </div>
        </div>
      </section>

      <section className="bg-bone-00 section-tight">
        <div className="container">
          <BuildingViewer onSelect={setSelected} statusFilter={statusFilter} setStatusFilter={setStatusFilter} filters={filters} setFilters={setFilters} accents={accents} />
        </div>
      </section>

      <section className="bg-bone-00 section-tight" style={{ paddingTop: 0 }}>
        <div className="container">
          <div className="aanbod-layout">
            <div>
              <div style={{ display: 'flex', justifyContent: 'space-between', alignItems: 'baseline', marginBottom: 32 }}>
                <h3>{filtered.length} woningen</h3>
                <span style={{ fontSize: 12, color: 'var(--steel-50)', textTransform: 'uppercase', letterSpacing: '0.14em' }}>Sorteer op woningnummer</span>
              </div>
              <div className="unit-grid">
                {filtered.map((u) => <UnitCard key={u.id} unit={u} onClick={() => setSelected(u)} />)}
                {filtered.length === 0 && <p style={{ gridColumn: '1 / -1', padding: 40, textAlign: 'center' }}>Geen woningen voldoen aan deze filters.</p>}
              </div>
            </div>
            <aside className="filter-panel">
              <h4>Filters</h4>
              <div className="filter-toggles">
                <label className={`filter-toggle ${filters.A ? 'on' : ''}`}>
                  <input type="checkbox" checked={filters.A} onChange={(e) => setFilters({ ...filters, A: e.target.checked })} style={{ display: 'none' }} />
                  <span>Maisonnettes (A)</span>
                </label>
                <label className={`filter-toggle ${filters.B ? 'on' : ''}`}>
                  <input type="checkbox" checked={filters.B} onChange={(e) => setFilters({ ...filters, B: e.target.checked })} style={{ display: 'none' }} />
                  <span>Compact (B)</span>
                </label>
                <label className={`filter-toggle ${filters.C ? 'on' : ''}`}>
                  <input type="checkbox" checked={filters.C} onChange={(e) => setFilters({ ...filters, C: e.target.checked })} style={{ display: 'none' }} />
                  <span>Appartementen (C)</span>
                </label>
              </div>
              <div className="divider"></div>
              <div>
                <h4 style={{ marginBottom: 12 }}>Status</h4>
                <div style={{ display: 'flex', flexDirection: 'column', gap: 8 }}>
                  {['available', 'option', 'sold'].map((s) =>
                  <label key={s} style={{ display: 'flex', alignItems: 'center', gap: 10, cursor: 'pointer', fontSize: 13, color: 'var(--steel-50)' }}>
                      <input type="checkbox" checked={statusFilter[s]} onChange={(e) => setStatusFilter({ ...statusFilter, [s]: e.target.checked })} />
                      <span className={`dot dot--${s}`}></span>
                      <span>{STATUS_LABELS[s]}</span>
                    </label>
                  )}
                </div>
              </div>
            </aside>
          </div>
        </div>
      </section>

      <UnitModal unit={selected} onClose={() => setSelected(null)} />
    </div>);

}

// ───────────── Arnhem Map Illustration ─────────────
function ArnhemMapIllustration() {
  return (
    <svg viewBox="0 0 1600 900" preserveAspectRatio="xMidYMid slice"
      style={{ position: 'absolute', inset: 0, width: '100%', height: '100%' }}
      xmlns="http://www.w3.org/2000/svg">
      <defs>
        <linearGradient id="rivergrad" x1="0" y1="0" x2="0" y2="1">
          <stop offset="0%" stopColor="#2A3848" />
          <stop offset="100%" stopColor="#243040" />
        </linearGradient>
        <radialGradient id="mapvign" cx="50%" cy="50%" r="70%">
          <stop offset="0%" stopColor="rgba(0,0,0,0)" />
          <stop offset="100%" stopColor="rgba(10,18,28,0.25)" />
        </radialGradient>
      </defs>

      {/* Background — same steel-70 as hero */}
      <rect width="1600" height="900" fill="#3A4550" />

      {/* ── Sonsbeekpark — large organic shape, west side ── */}
      <path d="M 60 100 Q 180 50 360 80 Q 520 110 590 220 Q 640 310 620 440 Q 600 550 500 600 Q 380 640 240 610 Q 110 580 60 470 Q 10 360 30 240 Q 50 160 60 100 Z"
        fill="#445C52" opacity="0.45" />
      <path d="M 80 120 Q 190 75 355 105 Q 500 135 565 235 Q 605 315 588 435 Q 570 535 480 578 Q 370 615 240 588 Q 125 565 80 462 Q 35 355 55 245 Q 65 168 80 120 Z"
        fill="#4E6859" opacity="0.25" />
      {/* Park label */}
      <text x="300" y="350" textAnchor="middle" fontSize="16" fill="rgba(180,200,188,0.5)"
        fontFamily="var(--serif)" fontStyle="italic" letterSpacing="0.04em">Sonsbeekpark</text>

      {/* ── Rhine / Rijn — flows east-west across south ── */}
      <path d="M -20 830 Q 200 815 500 810 Q 800 805 1100 800 Q 1350 796 1620 808"
        fill="none" stroke="url(#rivergrad)" strokeWidth="68" strokeLinecap="round" />
      <path d="M -20 830 Q 200 815 500 810 Q 800 805 1100 800 Q 1350 796 1620 808"
        fill="none" stroke="#324058" strokeWidth="52" strokeLinecap="round" />
      {/* River highlight */}
      <path d="M 0 818 Q 400 808 800 803 Q 1100 798 1600 806"
        fill="none" stroke="rgba(140,175,200,0.12)" strokeWidth="6" />
      <text x="420" y="828" textAnchor="middle" fontSize="14" fill="rgba(140,175,200,0.4)"
        fontFamily="var(--serif)" fontStyle="italic" letterSpacing="0.14em">Rijn</text>

      {/* ── City block grid — centrum area ── */}
      {Array.from({ length: 7 }, (_, row) =>
        Array.from({ length: 9 }, (_, col) => (
          <rect key={`b${row}-${col}`}
            x={760 + col * 42} y={570 + row * 26}
            width={32} height={18} fill="#4A5662" opacity="0.55" rx="1" />
        ))
      )}
      {/* Centrum label */}
      <text x="940" y="558" textAnchor="middle" fontSize="13" fill="rgba(200,212,218,0.35)"
        fontFamily="var(--sans)" letterSpacing="0.18em" fontWeight="500">CENTRUM</text>

      {/* ── Major roads ── */}
      {/* N-S main artery through centrum */}
      <path d="M 870 0 Q 860 250 855 500 Q 850 650 870 810"
        stroke="rgba(200,212,218,0.14)" strokeWidth="7" fill="none" />
      {/* Velperweg — east into centrum */}
      <path d="M 1600 470 Q 1300 500 1050 520 Q 880 530 800 560"
        stroke="rgba(200,212,218,0.12)" strokeWidth="6" fill="none" />
      {/* Apeldoornseweg / Utrechtseweg — connects project area */}
      <path d="M 480 0 Q 490 200 510 380 Q 530 520 560 680 Q 580 760 600 810"
        stroke="rgba(200,212,218,0.12)" strokeWidth="5" fill="none" />
      {/* Ring/Ringbaan — circular connector */}
      <path d="M 630 360 Q 720 320 860 340 Q 980 360 1020 460 Q 1050 560 980 640 Q 900 710 780 720 Q 680 725 630 660 Q 590 600 610 500 Q 620 430 630 360 Z"
        fill="none" stroke="rgba(200,212,218,0.08)" strokeWidth="5" />
      {/* Connecting road Sonsbeek to center */}
      <path d="M 340 600 Q 480 580 620 570 Q 720 562 800 560"
        stroke="rgba(200,212,218,0.10)" strokeWidth="4" fill="none" />

      {/* ── Railway line ── */}
      <path d="M 0 680 Q 300 670 600 660 Q 800 655 1000 648 Q 1200 642 1620 638"
        stroke="rgba(200,212,218,0.12)" strokeWidth="3" fill="none" strokeDasharray="14 7" />
      {/* Station block */}
      <rect x="840" y="650" width="44" height="22" fill="rgba(200,212,218,0.14)" rx="2" />

      {/* ── Centrum proximity circle ── */}
      <circle cx="900" cy="615" r="160" fill="none"
        stroke="rgba(200,212,218,0.07)" strokeWidth="1.5" strokeDasharray="8 6" />

      {/* ── Project location — Frombergdwarstraat 54 ── */}
      {/* Distance dashed line to centrum */}
      <line x1="594" y1="396" x2="870" y2="595"
        stroke="rgba(245,240,232,0.18)" strokeWidth="1.5" strokeDasharray="6 5" />
      {/* Pin outer pulse */}
      <circle cx="580" cy="390" r="52" fill="none"
        stroke="rgba(245,240,232,0.08)" strokeWidth="1" />
      <circle cx="580" cy="390" r="34" fill="none"
        stroke="rgba(245,240,232,0.14)" strokeWidth="1.5" />
      {/* Pin filled */}
      <circle cx="580" cy="390" r="10" fill="rgba(245,240,232,0.95)" />
      <circle cx="580" cy="390" r="4" fill="#3A4550" />
      {/* Label */}
      <text x="604" y="384" fontSize="13" fill="rgba(245,240,232,0.85)"
        fontFamily="var(--serif)" fontStyle="italic">De Fromberg</text>
      <text x="604" y="400" fontSize="10" fill="rgba(200,212,218,0.55)"
        fontFamily="var(--sans)" letterSpacing="0.10em">Arnhem-Noord</text>

      {/* Distance label */}
      <text x="740" y="506" textAnchor="middle" fontSize="10" fill="rgba(200,212,218,0.35)"
        fontFamily="var(--sans)" letterSpacing="0.10em" transform="rotate(-28 740 506)">± 7 min fiets</text>

      {/* ── North indicator ── */}
      <g transform="translate(1520,70)">
        <line x1="0" y1="-18" x2="0" y2="18" stroke="rgba(200,212,218,0.35)" strokeWidth="1.5" />
        <polygon points="0,-18 -5,-4 5,-4" fill="rgba(200,212,218,0.5)" />
        <text x="0" y="32" textAnchor="middle" fontSize="10" fill="rgba(200,212,218,0.4)"
          fontFamily="var(--sans)" letterSpacing="0.12em">N</text>
      </g>

      {/* ── Scale line ── */}
      <g transform="translate(1400,860)">
        <line x1="0" y1="0" x2="80" y2="0" stroke="rgba(200,212,218,0.3)" strokeWidth="1.5" />
        <line x1="0" y1="-4" x2="0" y2="4" stroke="rgba(200,212,218,0.3)" strokeWidth="1.5" />
        <line x1="80" y1="-4" x2="80" y2="4" stroke="rgba(200,212,218,0.3)" strokeWidth="1.5" />
        <text x="40" y="-8" textAnchor="middle" fontSize="9" fill="rgba(200,212,218,0.3)"
          fontFamily="var(--sans)" letterSpacing="0.10em">1 km</text>
      </g>

      {/* Subtle vignette at edges */}
      <rect width="1600" height="900" fill="url(#mapvign)" />
    </svg>
  );
}

// ───────────── Hypotheek Calculator ─────────────
function HypotheekSection() {
  const [koopsom, setKoopsom] = R_useState(545000);
  const [eigenInbreng, setEigenInbreng] = R_useState(80000);

  const lening = Math.max(0, koopsom - eigenInbreng);
  const r = 0.042 / 12;
  const n = 360;
  const maandlast = lening > 0 ? lening * (r * Math.pow(1 + r, n)) / (Math.pow(1 + r, n) - 1) : 0;

  return (
    <section className="bg-bone-10 hypotheek-section">
      <div className="container">
        <div className="hypotheek-grid">
          <div className="hypotheek-main">
            <Label>Financiering</Label>
            <h2 className="hypotheek-title">Jouw hypotheek <em className="italic-accent-steel">berekenen</em></h2>
            <div className="hypotheek-sliders">
              <div className="field hypotheek-field">
                <label className="hypotheek-field-head">
                  <span>Koopsom</span>
                  <strong className="hypotheek-field-value">{fmtPrice(koopsom)}</strong>
                </label>
                <input className="hypotheek-range" type="range" min={395000} max={825000} step={5000} value={koopsom}
                  onChange={e => setKoopsom(Number(e.target.value))} />
                <div className="hypotheek-range-ticks">
                  <span>€ 395k</span><span>€ 825k</span>
                </div>
              </div>
              <div className="field hypotheek-field">
                <label className="hypotheek-field-head">
                  <span>Eigen inbreng</span>
                  <strong className="hypotheek-field-value">{fmtPrice(eigenInbreng)}</strong>
                </label>
                <input className="hypotheek-range" type="range" min={0} max={250000} step={5000} value={eigenInbreng}
                  onChange={e => setEigenInbreng(Number(e.target.value))} />
                <div className="hypotheek-range-ticks">
                  <span>€ 0</span><span>€ 250k</span>
                </div>
              </div>
            </div>
            <div className="hypotheek-stats-grid">
              <div className="hypotheek-stats-grid__cell">
                <Label>Hypotheekbedrag</Label>
                <div className="hypotheek-kpi-value">
                  {fmtPrice(lening)}
                </div>
              </div>
              <div className="hypotheek-stats-grid__cell">
                <Label>Geschatte maandlast</Label>
                <div className="hypotheek-kpi-value hypotheek-kpi-value--inline">
                  € {Math.round(maandlast).toLocaleString('nl-NL')}
                  <span className="hypotheek-kpi-suffix">/mnd</span>
                </div>
              </div>
            </div>
            <p className="hypotheek-footnote">
              Indicatie bij 4,2% rente, annuïtair, 30 jaar. Werkelijke lasten zijn afhankelijk van je persoonlijke situatie.
            </p>
          </div>

          <div className="hypotheek-aside">
            <Label light>Hypotheekadvies</Label>
            <h3 className="hypotheek-aside__title">
              Laat je persoonlijk <em style={{ fontStyle: 'italic', color: 'var(--bone-30)' }}>adviseren</em>
            </h3>
            <p className="hypotheek-aside__lead">
              Onze hypotheekpartner helpt je van eerste berekening tot passende financiering — speciaal voor kopers van nieuwbouw en transformatieprojecten.
            </p>
            <ul className="hypotheek-aside__list">
              {[
                'Gratis en vrijblijvend eerste gesprek',
                'Ervaring met nieuwbouw en transformatieprojecten',
                'Rechtstreeks gekoppeld aan BMV Makelaars',
              ].map(item => (
                <li key={item} className="hypotheek-aside__list-item">
                  <span className="hypotheek-aside__bullet">—</span>
                  {item}
                </li>
              ))}
            </ul>
            <div className="hypotheek-aside__cta">
              <button type="button" className="btn btn--primary-light hypotheek-aside__btn">
                Neem contact op voor hypotheekadvies
              </button>
              <p className="hypotheek-aside__partner-note">
                In samenwerking met onze hypotheekpartner
              </p>
            </div>

            <div className="hypotheek-aside__contact">
              <div className="hypotheek-aside__avatar" aria-hidden="true">
                <svg viewBox="0 0 56 64" xmlns="http://www.w3.org/2000/svg">
                  <rect width="56" height="64" fill="rgba(255,255,255,0.07)" />
                  <circle cx="28" cy="22" r="11" fill="rgba(255,255,255,0.18)" />
                  <path d="M 4 64 Q 4 44, 28 40 Q 52 44, 52 64 Z" fill="rgba(255,255,255,0.18)" />
                  <rect x="0" y="61" width="56" height="3" fill="rgba(255,255,255,0.12)" />
                </svg>
              </div>
              <div className="hypotheek-aside__contact-text">
                <div className="hypotheek-aside__name">Naam Contactpersoon</div>
                <div className="hypotheek-aside__role">Verkoopmakelaar · BMV Makelaars</div>
                <div className="hypotheek-aside__links">
                  <a href="tel:+31260000000">+31 (0)26 000 00 00</a>
                  <a href="mailto:info@bmvmakelaars.nl">info@bmvmakelaars.nl</a>
                </div>
              </div>
            </div>
          </div>
        </div>

      </div>
    </section>
  );
}

// ───────────── OMGEVING ─────────────
function OmgevingPage({ accents }) {
  const [activeCat, setActiveCat] = R_useState('Alle');
  const [focusedPoi, setFocusedPoi] = R_useState(null);
  const cats = OMGEVING_FILTER_CATEGORIES;
  const filtered =
    activeCat === 'Alle' ? POIS
      : activeCat === FILTER_PROJECT ? []
        : POIS.filter((p) => p.category === activeCat);
  const siteMeta =
    typeof FROMBERG_SITE !== 'undefined' && FROMBERG_SITE
      ? FROMBERG_SITE
      : { title: 'De Fromberg', tagline: '16 Stads Lofts · Arnhem-Noord' };

  R_useEffect(() => {
    setFocusedPoi(null);
  }, [activeCat]);

  return (
    <div className="page">
      <section style={{ minHeight: '72vh', position: 'relative', overflow: 'hidden', display: 'flex', alignItems: 'center' }}>
        <div style={{ position: 'absolute', inset: 0 }}><ArnhemMapIllustration /></div>
        <div style={{ position: 'absolute', inset: 0, background: 'linear-gradient(to right, rgba(30,45,56,0.96) 0%, rgba(30,45,56,0.82) 45%, rgba(30,45,56,0.40) 75%, rgba(30,45,56,0.10) 100%)' }} />
        <div className="container" style={{ position: 'relative', zIndex: 1 }}>
          <Label steel>Omgeving</Label>
          <h1 style={{ marginTop: 24, color: 'var(--bone-10)' }}>Aan de <em className="italic-accent">{accents.omgeving || 'rand'}</em><br />van het centrum</h1>
          <p style={{ marginTop: 32, color: 'var(--bone-20)', maxWidth: 560, fontSize: 19 }}>
            De Frombergdwarstraat ligt in Arnhem-Noord — waar het stadsleven dichtbij blijft. Sonsbeekpark en Arnhem Centraal op ongeveer vijf fietsminuten, Korenmarkt en Rijnkade op ongeveer zeven; winkelstraten met karakter om de hoek.
          </p>
        </div>
      </section>

      {[
      { label: 'Sonsbeekpark', title: 'Een park dat zich laat verdwalen', body: ['Het 200 jaar oude Sonsbeekpark begint vijf fietsminuten van jouw voordeur. Een Engelse landschapstuin met vijvers, watervallen en eeuwenoude bomen — geliefd door wandelaars, hardlopers en lezers met een dekentje.', 'In het seizoen vinden hier evenementen plaats: van openluchttheater tot het bijzondere Sonsbeekfestival.'], bg: 'bg-bone-00', poiIdx: 0 },
      { label: 'Bereikbaarheid', title: 'Ongeveer vijf minuten naar het station', body: ['Met de fiets sta je in ongeveer vijf minuten bij Arnhem Centraal. Vandaar ben je in 35 minuten op Schiphol, in 65 minuten in Utrecht en in 90 minuten in Düsseldorf. De A12 ligt op enkele autominuten.', 'In de buurt rijdt buslijn 3, met haltes op loopafstand.'], bg: 'bg-bone-10', poiIdx: 1 },
      { label: 'Eten & drinken', title: 'Het Sonsbeekkwartier', body: ['Het Sonsbeekkwartier ligt direct tegen het project aan: horeca op ongeveer vijf fietsminuten (Steijnstraat, Zijpendaalseweg). Een levendige driehoek met restaurants, koffiezaken, wijnbars en delicatessen — geen toeristenboulevard, wél vaste gezichten.', 'Op de Apeldoornseweg vind je de dagelijkse winkels — ongeveer vijf fietsminuten.'], bg: 'bg-bone-00', poiIdx: 2 },
      { label: 'Cultuur', title: 'Museum om de hoek, erfgoed in de buurt', body: ['Museum Arnhem staat aan de Utrechtseweg in Heijenoord — op ongeveer drie fietsminuten. Burgers\u2019 Zoo en het Nederlands Openluchtmuseum liggen noordelijker (ongeveer veertien respectievelijk zestien fietsminuten vanaf het project).', 'In de stad vind je verder theater, bioscopen, het Concertgebouw en een actieve poppodium-scene.'], bg: 'bg-bone-10', poiIdx: 3 }].
      map((s, i) =>
      <section key={s.label} className={s.bg}>
          <div className="container">
            <div className="two-col">
              <div style={{ order: i % 2 ? 2 : 1 }}>
                <Label>{s.label}</Label>
                <h2 style={{ marginTop: 24 }}>{s.title}</h2>
                <div style={{ marginTop: 32, display: 'flex', flexDirection: 'column', gap: 16 }}>
                  {s.body.map((p, j) => <p key={j}>{p}</p>)}
                </div>
              </div>
              <div className="editorial-img" style={{ order: i % 2 ? 1 : 2, aspectRatio: '5/4' }}>
                <PoiArt index={s.poiIdx} />
              </div>
            </div>
          </div>
        </section>
      )}

      <section className="bg-bone-10 omgeving-map-section">
        <div className="container">
          <div className="section-head">
            <Label>Op de kaart</Label>
            <h2 className="omgeving-map-title"><em className="italic-accent-steel">Fiets- en loopminuten</em> vanaf het project</h2>
            <p className="omgeving-map-intro">
              De <strong>projectmarker</strong> (strak lijn-huisje in staal-tinten) is Frombergdwarsstraat 54 — alle tijden op de kaart zijn ingeschat vanaf dat punt (vogelvlucht + route; afgerond naar hele minuten).
              Kernplekken als station, Sonsbeek en supermarkt zijn dichtbij; zwemmen en fitness in Valkenhuizen zit verder weg. Gebruik de filters om categorieën te vergelijken.
            </p>
          </div>
          <div className="poi-filter-chips" role="toolbar" aria-label="Filter plaatsen op categorie">
            {cats.map((c) =>
            <button
              key={c}
              type="button"
              className={`chip ${activeCat === c ? 'on' : ''}${c === FILTER_PROJECT ? ' chip--filter-fromberg' : ''}`}
              aria-pressed={activeCat === c}
              onClick={() => setActiveCat(c)}
            >
                <span className="chip__glyph" aria-hidden><OmgevingGlyph category={c} size={15} /></span>
                {' '}{c === 'Alle' ? 'Alle' : c}
              </button>
            )}
          </div>
          <div className="poi-filter-select">
            <p className="omgeving-map-project-hint-mobile" aria-live="polite">
              Op de kaart: <strong>de donkere marker met lijn-huisje</strong> is <strong>De Fromberg</strong> — daar vergelijk je alle afstanden mee.
            </p>
            <label htmlFor="omgeving-cat-filter" className="visually-hidden">Filter categorie</label>
            <select id="omgeving-cat-filter" value={activeCat} aria-label="Filter categorie op de kaart" onChange={(e) => setActiveCat(e.target.value)}>
              {cats.map((c) =>
              <option key={c} value={c}>{c === 'Alle' ? 'Alle categorieën' : c}</option>
              )}
            </select>
          </div>
          <div className="map-grid">
            <div className="map-placeholder map-placeholder--google">
              <OmgevingMapBox
                pois={filtered}
                focusedName={focusedPoi}
                projectFilterOnly={activeCat === FILTER_PROJECT}
              />
            </div>
            <div className="map-grid__list map-grid__list--pois">
              {activeCat === FILTER_PROJECT ?
              <div className="poi-list-fromberg-card">
                <span className="poi-list-fromberg-card__house" aria-hidden>
                  <OmgevingGlyph category={FILTER_PROJECT} size={34} />
                </span>
                <span className="poi-list-fromberg-card__label">Jouw adres op de kaart</span>
                <h3 className="poi-list-fromberg-card__title">{siteMeta.title || FILTER_PROJECT}</h3>
                <p className="poi-list-fromberg-card__tag">{siteMeta.tagline || ''}</p>
                <p className="poi-list-fromberg-card__desc">
                  Alleen het project wordt getoond — zoom naar je toekomstige plek.
                  Schakel naar <strong>Alle</strong> of een categorie om buurtplekken te vergelijken.
                </p>
              </div> :
              filtered.length === 0 ?
              <p className="poi-list-empty">Geen plekken in deze categorie.</p> :
              filtered.map((p) =>
              <button
                key={p.name}
                type="button"
                className={`poi-list-card${focusedPoi === p.name ? ' poi-list-card--active' : ''}${p.tier === 'kern' ? ' poi-list-card--kern' : ''}`}
                onClick={() => setFocusedPoi(p.name)}
              >
                  <span className="poi-list-card__glyph" style={{ borderColor: poiCategoryColor(p.category), color: poiCategoryColor(p.category) }} aria-hidden>
                    <OmgevingGlyph category={p.category} size={22} color={poiCategoryColor(p.category)} />
                  </span>
                  <span className="poi-list-card__body">
                    <Label>{p.category}{p.tier === 'kern' ? ' · in de buurt' : ''}</Label>
                    <span className="poi-list-card__name">{p.name}</span>
                    <span className="poi-list-card__meta">{p.minutes} min · {p.mode}</span>
                    <span className="poi-list-card__desc">{p.desc}</span>
                  </span>
                </button>
              )
              }
            </div>
          </div>
        </div>
      </section>
    </div>);

}

function SchematicMap({ pois }) {
  const positions = {
    Sonsbeekpark:                [69, 20],
    'Centraal Station':          [46, 66],
    'Arnhem centrum':            [68, 72],
    'Albert Heijn Sonsbeek':     [44, 36],
    Sonsbeekkwartier:            [52, 44],
    'Rijn- en Korenmarkt':       [71, 70],
    Apeldoornseweg:              [48, 40],
    'Burgers\u2019 Zoo':         [12, 14],
    Openluchtmuseum:             [8, 28],
    'Museum Arnhem':             [33, 37],
    'Sportcentrum Valkenhuizen': [88, 18],
    'Healthclub Heijenoord':     [36, 34],
  };
  const PX = 32, PY = 40;
  return (
    <svg viewBox="0 0 100 82" preserveAspectRatio="xMidYMid meet" style={{ width: '100%', height: '100%', display: 'block' }} xmlns="http://www.w3.org/2000/svg">
      <defs>
        <radialGradient id="mapBg" cx="40%" cy="50%" r="70%">
          <stop offset="0%" stopColor="#F5F0E8" />
          <stop offset="100%" stopColor="#E4EAED" />
        </radialGradient>
      </defs>
      <rect width="100" height="82" fill="url(#mapBg)" />

      {/* Sonsbeekpark */}
      <ellipse cx="68" cy="20" rx="24" ry="15" fill="#9BAD8A" opacity="0.20" />
      <ellipse cx="68" cy="20" rx="17" ry="10" fill="#9BAD8A" opacity="0.18" />

      {/* Nederrijn */}
      <path d="M 0 78 Q 30 74 55 76 Q 78 78 100 74 L 100 82 L 0 82 Z" fill="#A5B4BE" opacity="0.28" />
      <path d="M 0 77 Q 32 73 56 75 Q 80 77 100 73" fill="none" stroke="#B8C8D4" strokeWidth="0.5" />

      {/* Railway */}
      <path d="M 0 64 L 100 62" fill="none" stroke="#C4B8A8" strokeWidth="0.9" strokeDasharray="2.5 1.5" opacity="0.50" />

      {/* N224 main road */}
      <path d="M 0 50 Q 30 48 62 50 T 100 52" fill="none" stroke="#C8D4DA" strokeWidth="1.4" />
      {/* Apeldoornseweg N-S */}
      <path d="M 40 0 L 38 82" fill="none" stroke="#C8D4DA" strokeWidth="0.9" />
      {/* Sonsbeeksingel */}
      <path d="M 60 0 L 62 82" fill="none" stroke="#C8D4DA" strokeWidth="0.7" />
      {/* Street south to station */}
      <path d="M 32 40 Q 36 54 44 68" fill="none" stroke="#D8CEBC" strokeWidth="0.6" />
      {/* Rozenstraat west */}
      <path d="M 0 38 Q 18 37 32 40" fill="none" stroke="#D8CEBC" strokeWidth="0.6" />

      {/* Distance rings */}
      <circle cx={PX} cy={PY} r="14" fill="none" stroke="#7D909E" strokeWidth="0.3" strokeDasharray="1 2" opacity="0.38" />
      <circle cx={PX} cy={PY} r="26" fill="none" stroke="#7D909E" strokeWidth="0.2" strokeDasharray="0.8 2.5" opacity="0.20" />
      <text x={PX + 15} y={PY - 1} fontSize="2.2" fill="#A5B4BE" fontFamily="ui-sans-serif,system-ui">5 min</text>
      <text x={PX + 27} y={PY - 1} fontSize="2.2" fill="#C8D4DA" fontFamily="ui-sans-serif,system-ui">10 min</text>

      {/* POI dots */}
      {pois.map((p) => {
        const [x, y] = positions[p.name] || [55, 35];
        const col = poiCategoryColor(p.category);
        return (
          <g key={p.name}>
            <circle cx={x} cy={y} r="1.5" fill={col} opacity="0.90" />
            <text x={x + 2.4} y={y + 0.8} fontSize="2.3" fill="#637480" fontFamily="ui-sans-serif,system-ui">{p.name}</text>
          </g>
        );
      })}

      {/* Project pin */}
      <circle cx={PX} cy={PY} r="7.5" fill="#3A4550" opacity="0.05" />
      <circle cx={PX} cy={PY} r="4.5" fill="#3A4550" opacity="0.09" />
      <circle cx={PX} cy={PY} r="3" fill="#3A4550" />
      <circle cx={PX} cy={PY} r="1.2" fill="#F5F0E8" />
      <g transform={`translate(${PX - 1.44}, ${PY - 9.08}) scale(0.12)`} fill="none" stroke="#F5F0E8" strokeWidth={2} strokeLinecap="round" strokeLinejoin="round">
        <path d="M12 3l9 7.5H19V20H5V10.5H3L12 3z" />
        <path d="M9 20v-7h6v7" />
      </g>
      <text x={PX} y={PY + 7} fontSize="3" fill="#1E2D38" fontFamily="'Cormorant Garamond',Georgia,serif" fontStyle="italic" textAnchor="middle" fontWeight="300">De Fromberg</text>
    </svg>
  );
}

function OmgevingMapBox({ pois, focusedName, projectFilterOnly }) {
  const [fallbackSvg, setFallbackSvg] = R_useState(false);
  const hasKey =
    typeof window !== 'undefined' && !!String(window.FROMBERG_GOOGLE_MAPS_API_KEY || '').trim();

  if (!hasKey || fallbackSvg) return <SchematicMap pois={pois} />;

  return (
    <OmgevingGoogleMap
      pois={pois}
      focusedName={focusedName}
      projectFilterOnly={projectFilterOnly}
      onFailure={() => setFallbackSvg(true)}
    />
  );
}

function escapeHtmlLite(s) {
  return String(s)
    .replace(/&/g, '&amp;')
    .replace(/</g, '&lt;')
    .replace(/>/g, '&gt;')
    .replace(/"/g, '&quot;');
}

function poiInfoHtml(p) {
  return `
    <div style="font-family:system-ui,-apple-system,sans-serif;padding:6px 4px 2px;max-width:268px;line-height:1.35;color:#3A4550">
      <div style="font-family:Georgia,'Cormorant Garamond',serif;font-size:17px;font-weight:500;margin-bottom:4px">${escapeHtmlLite(p.name)}</div>
      <div style="font-size:12px;color:#637480">${escapeHtmlLite(p.category)} · ${escapeHtmlLite(p.minutes)} min (${escapeHtmlLite(p.mode)})</div>
      <p style="font-size:12px;margin-top:8px;color:#637480">${escapeHtmlLite(p.desc)}</p>
    </div>`;
}

function OmgevingGoogleMap({ pois, focusedName, projectFilterOnly, onFailure }) {
  const elRef = R_useRef(null);
  const mapRef = R_useRef(null);
  const infoRef = R_useRef(null);
  const markersRef = R_useRef([]);
  const poiMarkersRef = R_useRef(new Map());
  const onFailureRef = R_useRef(onFailure);
  onFailureRef.current = onFailure;

  const apiKey =
    typeof window !== 'undefined' ? String(window.FROMBERG_GOOGLE_MAPS_API_KEY || '').trim() : '';

  const [map, setMap] = R_useState(null);

  const validPois = R_useMemo(
    () => pois.filter((p) => typeof p.lat === 'number' && typeof p.lng === 'number'),
    [pois]
  );

  R_useEffect(() => {
    let cancelled = false;

    loadFrombergGoogleMaps(apiKey)
      .then(() => {
        if (cancelled || !elRef.current || !window.google?.maps) return;
        try {
          const site =
            typeof FROMBERG_SITE !== 'undefined' && FROMBERG_SITE
              ? FROMBERG_SITE
              : { lat: 51.9869696, lng: 5.895966, title: 'De Fromberg' };
          const m = new google.maps.Map(elRef.current, {
            center: { lat: site.lat, lng: site.lng },
            zoom: 13,
            mapTypeControl: false,
            streetViewControl: false,
            fullscreenControl: true,
            gestureHandling: 'greedy'
          });
          mapRef.current = m;
          infoRef.current = new google.maps.InfoWindow({ maxWidth: 340 });
          setMap(m);
          google.maps.event.addListenerOnce(m, 'idle', () => google.maps.event.trigger(m, 'resize'));
        } catch (_) {
          if (!cancelled) onFailureRef.current?.();
        }
      })
      .catch(() => {
        if (!cancelled) onFailureRef.current?.();
      });

    return () => {
      cancelled = true;
      markersRef.current.forEach((mk) => mk.setMap(null));
      markersRef.current = [];
      poiMarkersRef.current.clear();
      infoRef.current = null;
      mapRef.current = null;
      setMap(null);
    };
  }, [apiKey]);

  R_useEffect(() => {
    if (!map || !window.google?.maps) return undefined;
    const g = google.maps;
    const site =
      typeof FROMBERG_SITE !== 'undefined' && FROMBERG_SITE
        ? FROMBERG_SITE
        : { lat: 51.9869696, lng: 5.895966, title: 'De Fromberg' };

    markersRef.current.forEach((marker) => marker.setMap(null));
    markersRef.current = [];
    poiMarkersRef.current.clear();

    const info = infoRef.current;

    const sitePos = { lat: site.lat, lng: site.lng };

    const siteGlow = new g.Marker({
      map,
      position: sitePos,
      zIndex: 1080,
      clickable: false,
      icon: {
        path: g.SymbolPath.CIRCLE,
        scale: 32,
        fillColor: '#E8A849',
        fillOpacity: 0.14,
        strokeWeight: 0,
      },
    });
    markersRef.current.push(siteGlow);

    const siteRing = new g.Marker({
      map,
      position: sitePos,
      zIndex: 1095,
      clickable: false,
      icon: {
        path: g.SymbolPath.CIRCLE,
        scale: 22,
        fillColor: '#3A4550',
        fillOpacity: 0,
        strokeColor: '#F5F0E8',
        strokeWeight: 4,
        strokeOpacity: 0.95,
      },
    });
    markersRef.current.push(siteRing);

    const siteMarker = new g.Marker({
      map,
      position: sitePos,
      title: `${site.title || 'De Fromberg'} — jouw project`,
      zIndex: 1100,
      optimized: false,
      icon: frombergSiteMarkerIcon(g),
    });
    siteMarker.addListener('click', () => {
      if (!info) return;
      info.setContent(frombergProjectInfoHtml(site));
      info.open({ map, anchor: siteMarker });
    });
    markersRef.current.push(siteMarker);

    validPois.forEach((p) => {
      const marker = new g.Marker({
        map,
        position: { lat: p.lat, lng: p.lng },
        title: p.name,
        zIndex: poiMarkerZIndex(p),
        optimized: false,
        icon: poiSvgMarkerIcon(g, p),
      });
      marker.addListener('click', () => {
        if (!info) return;
        info.setContent(poiInfoHtml(p));
        info.open({ map, anchor: marker });
      });
      markersRef.current.push(marker);
      poiMarkersRef.current.set(p.name, marker);
    });

    const bounds = new g.LatLngBounds();
    bounds.extend({ lat: site.lat, lng: site.lng });
    validPois.forEach((p) => bounds.extend({ lat: p.lat, lng: p.lng }));

    google.maps.event.addListenerOnce(map, 'idle', () => g.event.trigger(map, 'resize'));

    requestAnimationFrame(() => {
      if (!mapRef.current) return;
      const mm = mapRef.current;
      if (projectFilterOnly) {
        mm.setCenter({ lat: site.lat, lng: site.lng });
        mm.setZoom(16);
      } else if (validPois.length === 0) {
        mm.setCenter({ lat: site.lat, lng: site.lng });
        mm.setZoom(14);
      } else {
        mm.fitBounds(bounds, { top: 56, right: 56, bottom: 56, left: 56 });
        google.maps.event.addListenerOnce(mm, 'idle', () => {
          const z = mm.getZoom();
          if (z > 15) mm.setZoom(15);
          if (z < 11) mm.setZoom(11);
        });
      }
    });

    return undefined;
  }, [map, validPois, projectFilterOnly]);

  R_useEffect(() => {
    if (!map || !focusedName || !infoRef.current) return;
    const marker = poiMarkersRef.current.get(focusedName);
    const p = validPois.find((x) => x.name === focusedName);
    if (!marker || !p) return;
    const pos = marker.getPosition();
    if (pos) {
      map.panTo(pos);
      const cz = map.getZoom();
      if (!cz || cz < 14) map.setZoom(14);
      infoRef.current.setContent(poiInfoHtml(p));
      infoRef.current.open({ map, anchor: marker });
    }
  }, [map, focusedName, validPois]);

  R_useEffect(() => {
    if (!map || !window.google?.maps) return undefined;
    const fn = () => google.maps.event.trigger(map, 'resize');
    window.addEventListener('resize', fn);
    fn();
    return () => window.removeEventListener('resize', fn);
  }, [map]);

  return (
    <>
      <div ref={elRef} className="omgeving-gmap" aria-label="Kaart met project De Fromberg en omgeving" />
      {!map ?
        <div className="omgeving-map-loading">Kaart laden…</div> :
      null}
    </>
  );
}

// ───────────── NIEUWS ─────────────
function NieuwsPage({ accents }) {
  return (
    <div className="page">
      <section className="bg-bone-10">
        <div className="container">
          <Label>Nieuws</Label>
          <h1 style={{ marginTop: 24 }}>Voortgang & <em className="italic-accent-steel">{accents.news || 'updates'}</em></h1>
          <p style={{ marginTop: 24, maxWidth: 600 }}>Een rustige stroom van berichten over het project — vergunning, ontwerp, planning en mijlpalen.</p>
        </div>
      </section>
      <section className="bg-bone-00">
        <div className="container">
          {NEWS.map((n, i) =>
          <div key={n.title} className="news-list-item">
              <div className="news-list__media"><NewsCardArt index={i} /></div>
              <div>
                <span className="news-card__date">{n.date}</span>
                <h3 className="news-card__title" style={{ marginTop: 8, marginBottom: 12 }}>{n.title}</h3>
                <p style={{ fontSize: 15 }}>{n.excerpt}</p>
              </div>
              <a href="#" className="link" style={{ alignSelf: 'start' }}>Lees verder →</a>
            </div>
          )}
        </div>
      </section>
    </div>);

}

// ───────────── STEPS ROADMAP ─────────────
function StepsTimeline() {
  const STEPS = [
    { period: 'Voorjaar 2026', title: 'Voorinschrijving', desc: 'Je schrijft je in via dit formulier.' },
    { period: 'Zomer 2026', title: 'Updates ontvangen', desc: 'Je krijgt het projectdossier en updates over de planning.' },
    { period: 'September 2026', title: 'Open dag', desc: 'Persoonlijke rondleiding en presentatie van het project.' },
    { period: 'Najaar 2026', title: 'Toewijzing & koop', desc: 'De woningen worden in één keer verloot/toegewezen.' },
  ];
  return (
    <div className="roadmap">
      {STEPS.map((s, i) => {
        const isLeft = i % 2 === 0;
        const content = (
          <div className={`roadmap-content roadmap-content--${isLeft ? 'left' : 'right'}`}>
            <div className="roadmap-period">{s.period}</div>
            <div className="roadmap-title">{i + 1}. {s.title}</div>
            <div className="roadmap-desc">{s.desc}</div>
          </div>
        );
        return (
          <div key={i} className="roadmap-step">
            {isLeft ? content : <div className="roadmap-spacer" />}
            <div className="roadmap-node-wrap">
              <div className="roadmap-node"><span>0{i + 1}</span></div>
            </div>
            {isLeft ? <div className="roadmap-spacer" /> : content}
          </div>
        );
      })}
    </div>
  );
}

// ───────────── VOORINSCHRIJVEN ─────────────
function VoorinschrijvenPage({ accents }) {
  const [form, setForm] = R_useState({ voornaam: '', achternaam: '', email: '', tel: '', budget: '', source: '', remark: '', consent: false });
  const [types, setTypes] = R_useState(new Set());
  const [submitted, setSubmitted] = R_useState(false);
  const [submitting, setSubmitting] = R_useState(false);
  const [error, setError] = R_useState(null);
  const toggleType = (t) => setTypes((prev) => {const n = new Set(prev);n.has(t) ? n.delete(t) : n.add(t);return n;});

  const handleSubmit = async (e) => {
    e.preventDefault();
    if (submitting) return;
    setError(null);
    setSubmitting(true);
    try {
      await frombergSubmit('lead-intake', {
        project_slug: 'frombergdwarsstraat-arnhem',
        inquiry_type: 'voorinschrijving',
        email: form.email,
        first_name: form.voornaam,
        last_name: form.achternaam,
        phone: form.tel,
        unit_type_preference: [...types],
        budget_range: form.budget,
        source: form.source || 'fromberg-site',
        notes: form.remark,
        consent_given: form.consent,
      });
      setSubmitted(true);
      window.scrollTo({ top: 0, behavior: 'smooth' });
    } catch (err) {
      setError(err.message || 'Er ging iets mis. Probeer het opnieuw.');
    } finally {
      setSubmitting(false);
    }
  };

  return (
    <div className="page">
      <section className="bg-steel-70 hero" style={{ minHeight: '72vh' }}>
        <div className="container">
          <Label steel>Voorinschrijving</Label>
          <h1 style={{ marginTop: 24, color: 'var(--bone-10)' }}>Wees erbij in <em className="italic-accent">{accents.september || 'september'}</em></h1>
          <p style={{ marginTop: 32, color: 'var(--bone-20)', maxWidth: 580, fontSize: 19 }}>
            Voorinschrijvers krijgen als eerste een persoonlijke uitnodiging voor de open dag in september 2026. Daar wordt het project gepresenteerd en worden de woningen toegewezen.
          </p>
        </div>
      </section>

      <section className="bg-bone-00">
        <div className="container">
          <div className="benefits-grid">
            {[
            ['01', 'Vroege toegang', 'Je ontvangt het volledige projectdossier en de plattegronden voor publieke release. Geen wachten, geen ruis.'],
            ['02', 'Persoonlijke uitnodiging', 'Een uitnodiging voor de open dag in september 2026, inclusief een persoonlijk tijdslot voor een rondleiding.'],
            ['03', 'Updates over voortgang', 'Met regelmaat een rustige update over ontwerp, planning en mijlpalen — alleen wat ertoe doet.']].
            map(([num, t, d]) =>
            <div key={num} style={{ display: 'flex', flexDirection: 'column', gap: 12 }}>
                <span style={{ fontFamily: 'var(--serif)', fontSize: 32, fontWeight: 300, color: 'var(--bone-30)' }}>{num}</span>
                <h3 style={{ fontSize: 24 }}>{t}</h3>
                <p style={{ fontSize: 14 }}>{d}</p>
              </div>
            )}
          </div>
        </div>
      </section>

      <section className="bg-bone-10">
        <div className="container">
          <div className="section-head">
            <Label>Hoe werkt het</Label>
            <h2>Vier stappen tot <em className="italic-accent-steel">jouw woning</em></h2>
          </div>
          <StepsTimeline />
        </div>
      </section>

      <section className="bg-bone-00">
        <div className="container">
          <div className="inschrijven-grid" style={{ display: 'grid', gridTemplateColumns: '1fr 1fr', gap: '80px 96px', alignItems: 'start' }}>

            {/* Left — sticky project panel */}
            <div style={{ position: 'sticky', top: 92 }}>
              <div style={{ borderRadius: 3, overflow: 'hidden', background: 'var(--steel-70)', aspectRatio: '4/3', position: 'relative' }}>
                <HeroBuildingIllustration />
                <div style={{ position: 'absolute', inset: 0, background: 'linear-gradient(to top, rgba(30,45,56,0.85) 0%, transparent 55%)' }} />
                <div style={{ position: 'absolute', bottom: 0, left: 0, right: 0, padding: '28px 32px' }}>
                  <div style={{ fontFamily: 'var(--serif)', fontWeight: 300, fontSize: 26, color: 'var(--bone-10)', lineHeight: 1.1 }}>
                    De From<em style={{ fontStyle: 'italic', color: 'var(--bone-30)' }}>berg</em>
                  </div>
                  <div style={{ fontSize: 11, textTransform: 'uppercase', letterSpacing: '0.16em', color: 'var(--steel-20)', marginTop: 6 }}>Frombergdwarstraat 54 · Arnhem-Noord</div>
                </div>
              </div>
              <div style={{ display: 'grid', gridTemplateColumns: '1fr 1fr', gap: 1, marginTop: 1, background: 'var(--bone-20)' }}>
                {[['16', 'Woningen'], ['Q1 2028', 'Oplevering'], ['50–102 m²', 'Woonoppervlak'], ['Sep 2026', 'Open dag']].map(([val, lbl]) => (
                  <div key={lbl} style={{ background: 'var(--bone-10)', padding: '20px 24px' }}>
                    <div style={{ fontFamily: 'var(--serif)', fontWeight: 300, fontSize: 28, color: 'var(--steel-70)', lineHeight: 1 }}>{val}</div>
                    <div style={{ fontSize: 11, textTransform: 'uppercase', letterSpacing: '0.14em', color: 'var(--steel-40)', marginTop: 6 }}>{lbl}</div>
                  </div>
                ))}
              </div>
              <p style={{ marginTop: 24, fontSize: 14, color: 'var(--steel-50)', fontStyle: 'italic', fontFamily: 'var(--serif)', lineHeight: 1.6, borderLeft: '2px solid var(--bone-30)', paddingLeft: 16 }}>
                "Een karakteristiek gebouw dat zijn geschiedenis behoudt — en tegelijk ruimte maakt voor eigentijds wonen."
              </p>
            </div>

            {/* Right — form */}
            <div>
            {submitted ?
            <div style={{ padding: '60px 0' }}>
                <Label>Ingeschreven</Label>
                <h2 style={{ marginTop: 16 }}>Dank je — jouw <em className="italic-accent-steel">inschrijving</em> is ontvangen</h2>
                <p style={{ marginTop: 24 }}>Je ontvangt binnen enkele minuten een bevestiging op {form.email || 'jouw e-mailadres'}. We nemen op tijd contact met je op met meer informatie over de open dag.</p>
              </div> :

            <form onSubmit={handleSubmit}>
                <Label>Inschrijven</Label>
                <h2 style={{ marginTop: 16, marginBottom: 40 }}>Schrijf je in</h2>
                <div className="form-grid">
                  <div className="field">
                    <label>Voornaam</label>
                    <input required value={form.voornaam} onChange={(e) => setForm({ ...form, voornaam: e.target.value })} />
                  </div>
                  <div className="field">
                    <label>Achternaam</label>
                    <input required value={form.achternaam} onChange={(e) => setForm({ ...form, achternaam: e.target.value })} />
                  </div>
                  <div className="field full">
                    <label>E-mail</label>
                    <input type="email" required value={form.email} onChange={(e) => setForm({ ...form, email: e.target.value })} />
                  </div>
                  <div className="field full">
                    <label>Telefoon</label>
                    <input type="tel" value={form.tel} onChange={(e) => setForm({ ...form, tel: e.target.value })} />
                  </div>
                  <div className="field full">
                    <label>Gewenst type woning</label>
                    <div className="chip-group">
                      {['Maisonnette (A)', 'Compact (B)', 'Appartement (C)', 'Geen voorkeur'].map((t) =>
                    <button type="button" key={t} className={`chip ${types.has(t) ? 'on' : ''}`} onClick={() => toggleType(t)}>{t}</button>
                    )}
                    </div>
                  </div>
                  <div className="field">
                    <label>Budget</label>
                    <select value={form.budget} onChange={(e) => setForm({ ...form, budget: e.target.value })}>
                      <option value="">Kies een richting</option>
                      <option>Tot € 350.000</option>
                      <option>€ 350.000 — € 450.000</option>
                      <option>Boven € 450.000</option>
                    </select>
                  </div>
                  <div className="field">
                    <label>Hoe heb je over ons gehoord?</label>
                    <select value={form.source} onChange={(e) => setForm({ ...form, source: e.target.value })}>
                      <option value="">Selecteer</option>
                      <option>Funda</option>
                      <option>BMV Makelaars</option>
                      <option>Via via</option>
                      <option>Sociale media</option>
                      <option>Anders</option>
                    </select>
                  </div>
                  <div className="field full">
                    <label>Opmerking (optioneel)</label>
                    <textarea value={form.remark} onChange={(e) => setForm({ ...form, remark: e.target.value })} placeholder="Vertel ons wat je zoekt." />
                  </div>
                  <label className="full" style={{ display: 'flex', alignItems: 'flex-start', gap: 12, fontSize: 13, color: 'var(--steel-50)', cursor: 'pointer', marginTop: 8 }}>
                    <input type="checkbox" required checked={form.consent} onChange={(e) => setForm({ ...form, consent: e.target.checked })} style={{ marginTop: 4 }} />
                    <span>Ik ga akkoord met de verwerking van mijn gegevens conform het privacybeleid. Mijn inschrijving kan ik altijd intrekken.</span>
                  </label>
                  {error &&
                  <p className="full" style={{ color: '#b91c1c', fontSize: 14, marginTop: 4 }}>{error}</p>
                  }
                  <button type="submit" disabled={submitting} className="btn btn--primary btn--block full" style={{ marginTop: 16, opacity: submitting ? 0.7 : 1 }}>{submitting ? 'Bezig…' : 'Inschrijven'}</button>
                </div>
                <p style={{ fontSize: 12, color: 'var(--steel-40)', marginTop: 24, textAlign: 'center' }}>
                  Inschrijving is vrijblijvend en geeft je voorrang op informatie. Aan de inschrijving kunnen geen rechten worden ontleend.
                </p>
              </form>
            }
            </div>
          </div>
        </div>
      </section>
    </div>);

}

// ───────────── CONTACT ─────────────
function ContactPage({ accents }) {
  const [sent, setSent] = R_useState(false);
  const [form, setForm] = R_useState({ naam: '', email: '', bericht: '' });
  const [submitting, setSubmitting] = R_useState(false);
  const [error, setError] = R_useState(null);

  const handleSubmit = async (e) => {
    e.preventDefault();
    if (submitting) return;
    setError(null);
    setSubmitting(true);
    try {
      await frombergSubmit('contact', {
        name: form.naam,
        email: form.email,
        subject: 'project-info',
        message: form.bericht,
      });
      setSent(true);
    } catch (err) {
      setError(err.message || 'Er ging iets mis. Probeer het opnieuw.');
    } finally {
      setSubmitting(false);
    }
  };

  return (
    <div className="page">
      <section className="bg-bone-10">
        <div className="container">
          <Label>Contact</Label>
          <h1 style={{ marginTop: 24 }}>Neem <em className="italic-accent-steel">contact</em> op</h1>
          <p style={{ marginTop: 24, maxWidth: 580 }}>BMV Makelaars uit Arnhem begeleidt de verkoop. Heb je vragen over een specifieke woning of het project? Neem direct contact op met het verkoopteam.</p>
        </div>
      </section>

      <section className="bg-bone-00">
        <div className="container">
          <div className="two-col">
            <div>
              <h3>Stuur een bericht</h3>
              {sent ?
              <p style={{ marginTop: 24 }}>Bedankt — jouw bericht is verstuurd. We nemen binnen twee werkdagen contact op.</p> :

              <form onSubmit={handleSubmit} style={{ marginTop: 32, display: 'flex', flexDirection: 'column', gap: 20 }}>
                  <div className="field"><label>Naam</label><input required value={form.naam} onChange={(e) => setForm({ ...form, naam: e.target.value })} /></div>
                  <div className="field"><label>E-mail</label><input type="email" required value={form.email} onChange={(e) => setForm({ ...form, email: e.target.value })} /></div>
                  <div className="field"><label>Bericht</label><textarea required value={form.bericht} onChange={(e) => setForm({ ...form, bericht: e.target.value })} /></div>
                  {error && <p style={{ color: '#b91c1c', fontSize: 14 }}>{error}</p>}
                  <button className="btn btn--primary" type="submit" disabled={submitting} style={{ opacity: submitting ? 0.7 : 1 }}>{submitting ? 'Bezig…' : 'Verstuur'}</button>
                </form>
              }
            </div>
            <div>
              <h3>BMV Makelaars</h3>
              <div style={{ marginTop: 32, display: 'flex', flexDirection: 'column', gap: 24 }}>
                <div>
                  <Label>Bezoekadres</Label>
                  <p style={{ marginTop: 8, color: 'var(--steel-70)' }}>Frombergdwarstraat 54<br />6814 DZ Arnhem</p>
                </div>
                <div>
                  <Label>E-mail</Label>
                  <p style={{ marginTop: 8, color: 'var(--steel-70)' }}><a href="mailto:defromberg@bmv.nl" style={{ borderBottom: '1px solid var(--steel-30)' }}>defromberg@bmv.nl</a></p>
                </div>
                <div>
                  <Label>Telefoon</Label>
                  <p style={{ marginTop: 8, color: 'var(--steel-70)' }}>026 — 370 17 00</p>
                </div>
                <div>
                  <Label>Openingstijden</Label>
                  <p style={{ marginTop: 8, color: 'var(--steel-70)' }}>Maandag — vrijdag · 09.00 — 17.30<br />Zaterdag op afspraak</p>
                </div>
              </div>
            </div>
          </div>
        </div>
      </section>

      <section className="bg-bone-10" style={{ paddingTop: 0 }}>
        <div className="container">
          <div className="map-placeholder" style={{ aspectRatio: '21/9' }}>
            <SchematicMap pois={POIS.slice(0, 4)} />
          </div>
        </div>
      </section>
    </div>);

}


// ───────────── Kopersportaal ─────────────
function PortaalPage() {
  // Het echte portaal draait als aparte app (zelfde codebase/design als de admin).
  // Standaarddomein staat vast; overschrijfbaar via window.FROMBERG_PORTAL_URL.
  const PORTAL_URL =
    (typeof window !== 'undefined' && window.FROMBERG_PORTAL_URL) ||
    'https://portal.consentvastgoed.nl';
  return (
    <div className="page">
      <section className="bg-steel-70" style={{ paddingTop: 'clamp(96px, 12vw, 160px)', paddingBottom: 'clamp(96px, 12vw, 160px)' }}>
        <div className="container">
          <div style={{ maxWidth: 720, display: 'flex', flexDirection: 'column', gap: 24 }}>
            <Label light>Kopersportaal</Label>
            <h1 style={{
              fontFamily: 'var(--serif)', fontWeight: 300,
              fontSize: 'clamp(40px, 5vw, 68px)', lineHeight: 1.05,
              letterSpacing: '-0.02em', color: 'var(--bone-10)'
            }}>
              Jouw <em style={{ fontStyle: 'italic', color: 'var(--bone-30)' }}>aankoop</em>, op één plek
            </h1>
            <p style={{ color: 'var(--bone-20)', fontSize: 16, lineHeight: 1.7, maxWidth: '52ch' }}>
              In het kopersportaal van Consent Vastgoed vind je alles over jouw woning in De Fromberg op één plek. Log in met je persoonlijke account voor je documenten, planning en de laatste bouwupdates.
            </p>
            <ul style={{ listStyle: 'none', padding: 0, margin: '8px 0 0', display: 'flex', flexDirection: 'column', gap: 14 }}>
              {[
                'Inzicht in jouw woning en bijbehorende documenten',
                'Live bouwupdates en milestones',
                'Direct contact met de verkoopmakelaar',
                'Veilige inlog met persoonlijk account',
              ].map(item => (
                <li key={item} style={{ display: 'flex', gap: 14, alignItems: 'flex-start', color: 'var(--bone-20)', fontSize: 14, lineHeight: 1.55 }}>
                  <span style={{ color: 'var(--steel-30)', marginTop: 2, flexShrink: 0 }}>—</span>
                  {item}
                </li>
              ))}
            </ul>
            <div style={{ marginTop: 20, display: 'flex', gap: 12, flexWrap: 'wrap' }}>
              <a href={`${PORTAL_URL}/login`} className="btn btn--primary-light">
                Inloggen op het kopersportaal
              </a>
              <a href={`${PORTAL_URL}/registreren`} className="btn btn--secondary-light">
                Account aanmaken
              </a>
            </div>
            <p style={{ color: 'var(--steel-30)', fontSize: 12, marginTop: 12, lineHeight: 1.6, maxWidth: '52ch' }}>
              Heb je een woning gereserveerd en nog geen toegang? Neem dan contact op met BMV Makelaars via <a href="mailto:defromberg@bmv.nl" style={{ color: 'var(--bone-20)', borderBottom: '1px solid var(--steel-40)' }}>defromberg@bmv.nl</a>.
            </p>
          </div>
        </div>
      </section>
    </div>
  );
}

Object.assign(window, { HomePage, AanbodPage, OmgevingPage, NieuwsPage, VoorinschrijvenPage, ContactPage, PortaalPage, HeroBuildingIllustration });