(function(){
function Loader({ onDone }) {
  const reduced = window.matchMedia('(prefers-reduced-motion: reduce)').matches;
  const [pct, setPct] = React.useState(0);
  const [exit, setExit] = React.useState(false);
  const [gone, setGone] = React.useState(reduced);
  React.useEffect(() => {
    if (reduced) { onDone && onDone(); return; }
    document.body.classList.add('mvp-loading');
    const t0 = performance.now(), dur = 1600;
    let raf;
    const tick = (t) => {
      const p = Math.min(1, (t - t0) / dur);
      setPct((1 - Math.pow(1 - p, 3)) * 100);
      if (p < 1) raf = requestAnimationFrame(tick);
      else {
        const finish = () => {
          setExit(true);
          document.body.classList.remove('mvp-loading');
          setTimeout(() => { setGone(true); onDone && onDone(); }, 720);
        };
        if (document.readyState === 'complete') finish();
        else {
          const cap = setTimeout(finish, 2200);
          window.addEventListener('load', () => { clearTimeout(cap); finish(); }, { once: true });
        }
      }
    };
    raf = requestAnimationFrame(tick);
    return () => { cancelAnimationFrame(raf); document.body.classList.remove('mvp-loading'); };
  }, []);
  if (gone) return null;
  const meters = ((pct / 100) * 96.8).toFixed(1).replace('.', ',');
  const label = { font: '700 var(--fs-label)/1 var(--font-mono)', letterSpacing: 'var(--ls-label)', textTransform: 'uppercase' };
  return (
    <div aria-hidden="true" style={{ position: 'fixed', inset: 0, zIndex: 100, pointerEvents: exit ? 'none' : 'auto' }}>
      <div style={{ position: 'absolute', inset: 0, background: 'var(--mv-green)', borderBottom: '3px solid var(--mv-ink)', transform: exit ? 'translateY(-101%)' : 'none', transition: 'transform .5s cubic-bezier(.7,0,.2,1) .13s' }}></div>
      <div style={{ position: 'absolute', inset: 0, background: 'var(--mv-bone)', color: 'var(--mv-ink)', borderBottom: '3px solid var(--mv-ink)', display: 'flex', flexDirection: 'column', justifyContent: 'space-between', padding: 'clamp(1.25rem,3.5vw,2.5rem)', transform: exit ? 'translateY(-101%)' : 'none', transition: 'transform .5s cubic-bezier(.7,0,.2,1)' }}>
        <div style={{ display: 'flex', justifyContent: 'space-between', alignItems: 'flex-start', ...label }}>
          <span>Martini Vastgoed<span style={{ color: 'var(--mv-pink)' }}> · Groningen van boven</span></span>
          <span className="mvl-spin" style={{ display: 'inline-block', font: '900 1.6rem/1 var(--font-display)', color: 'var(--mv-green)', textShadow: '2px 2px 0 var(--mv-ink)' }}>✳</span>
        </div>
        <div style={{ display: 'flex', justifyContent: 'center', alignItems: 'flex-end', gap: 'clamp(1.5rem,4vw,3.5rem)' }}>
          <div style={{ position: 'relative', height: 'clamp(200px,38vh,400px)' }}>
            <img src="assets/tower-upright.webp" alt="" style={{ display: 'block', height: '100%', width: 'auto', opacity: 0.16 }} />
            <img src="assets/tower-upright.webp" alt="" style={{ position: 'absolute', inset: 0, height: '100%', width: 'auto', clipPath: `inset(${100 - pct}% 0 0 0)`, filter: 'drop-shadow(8px 10px 0 var(--mv-green))' }} />
          </div>
          <div style={{ paddingBottom: '0.4rem' }}>
            <div style={{ ...label, color: 'var(--mv-ink-70)', marginBottom: 10 }}>Martinitoren</div>
            <div style={{ font: '900 clamp(2.6rem,7vw,5.5rem)/0.9 var(--font-display)', letterSpacing: 'var(--ls-display)', fontVariantNumeric: 'tabular-nums' }}>{meters}<span style={{ color: 'var(--mv-green)', textShadow: '2px 2px 0 var(--mv-ink)' }}> m</span></div>
          </div>
        </div>
        <div>
          <div style={{ display: 'flex', justifyContent: 'space-between', alignItems: 'flex-end', marginBottom: 10, ...label }}>
            <span style={{ color: 'var(--mv-ink-70)' }}>Laden</span>
            <span>{Math.round(pct)}%</span>
          </div>
          <div style={{ height: 10, border: '2px solid var(--mv-ink)', background: 'transparent' }}>
            <div style={{ height: '100%', width: `${pct}%`, background: 'var(--mv-green)', borderRight: pct > 1 && pct < 99.5 ? '2px solid var(--mv-ink)' : 'none' }}></div>
          </div>
        </div>
      </div>
      <style>{`
        .mvl-spin{animation:mvlSpin 2.2s linear infinite;transform-origin:50% 52%}
        @keyframes mvlSpin{to{transform:rotate(360deg)}}
      `}</style>
    </div>
  );
}
Object.assign(window, { Loader });
})();

(function(){
const { Button } = window.MartiniVastgoedDesignSystem_adb8d1;

function HeaderPlayful({ onValuation }) {
  const links = [['Aanbod', '#aanbod'], ['Verkopen', ''], ['Taxeren', ''], ['Over ons', '#over-ons']];
  const ref = React.useRef(null);
  const [hidden, setHidden] = React.useState(false);
  const [open, setOpen] = React.useState(false);
  React.useEffect(() => {
    let lastY = window.scrollY, up = 0, raf = 0;
    const tick = () => {
      raf = 0;
      const y = window.scrollY, dy = y - lastY;
      lastY = y;
      const h = ref.current ? ref.current.offsetHeight : 70;
      const box = document.getElementById('film-box');
      const engaged = box && box.getBoundingClientRect().top <= h + 1;
      if (!engaged) { up = 0; setHidden(false); }
      else if (dy > 2) { up = 0; setHidden(true); }
      else if (dy < 0) { up -= dy; if (up > 80) setHidden(false); }
    };
    const onScroll = () => { if (!raf) raf = requestAnimationFrame(tick); };
    window.addEventListener('scroll', onScroll, { passive: true });
    return () => { window.removeEventListener('scroll', onScroll); if (raf) cancelAnimationFrame(raf); };
  }, []);
  return (
    <header ref={ref} style={{ position: 'sticky', top: 0, zIndex: 40, background: 'var(--mv-bone)', borderBottom: '3px solid var(--mv-ink)', boxShadow: '0 4px 0 rgba(22,18,58,0.12)', transform: hidden ? 'translateY(-110%)' : 'translateY(0)', transition: 'transform .32s cubic-bezier(.2,.8,.2,1)' }}>
      <div style={{ maxWidth: 'var(--maxw)', margin: '0 auto', display: 'flex', alignItems: 'center', justifyContent: 'space-between', gap: 24, padding: '14px var(--gutter)' }}>
        <a href="#top" style={{ display: 'inline-flex', alignItems: 'center', textDecoration: 'none' }}>
          <img src="assets/logo-lockup-ink.webp" alt="Martini Vastgoed" style={{ display: 'block', height: 30, width: 'auto' }} />
        </a>
        <nav style={{ display: 'flex', alignItems: 'center', gap: 'var(--space-6)' }}>
          <ul className="mvp-links" style={{ display: 'flex', gap: 10, listStyle: 'none', margin: 0, padding: 0 }}>
            {links.map(([l, href]) => (
              <li key={l}><a href={href || '#top'} onClick={(e) => { if (!href) { e.preventDefault(); onValuation && onValuation(); } }} className="mvp-chip" style={{ display: 'inline-block', font: '700 var(--fs-label)/1 var(--font-mono)', letterSpacing: '0.06em', textTransform: 'uppercase', color: 'var(--mv-ink)', textDecoration: 'none', border: '2px solid var(--mv-ink)', padding: '8px 12px', background: 'var(--mv-bone)' }}>{l}</a></li>
            ))}
          </ul>
          <span className="mvp-cta-wide"><Button variant="ink" size="sm" onClick={onValuation} iconRight={<span aria-hidden="true">→</span>}>Waardebepaling</Button></span>
          <button type="button" className="mvp-burger" aria-label="Menu" aria-expanded={open} onClick={() => setOpen(!open)} style={{ display: 'none', width: 46, height: 46, cursor: 'pointer', background: open ? 'var(--mv-green)' : 'var(--mv-bone)', border: '3px solid var(--mv-ink)', boxShadow: '3px 3px 0 var(--mv-ink)', padding: 0, flexDirection: 'column', justifyContent: 'center', alignItems: 'center', gap: 5 }}>
            <span style={{ display: 'block', width: 20, height: 3, background: 'var(--mv-ink)', transform: open ? 'translateY(8px) rotate(45deg)' : 'none', transition: 'transform .2s' }}></span>
            <span style={{ display: 'block', width: 20, height: 3, background: 'var(--mv-ink)', opacity: open ? 0 : 1, transition: 'opacity .2s' }}></span>
            <span style={{ display: 'block', width: 20, height: 3, background: 'var(--mv-ink)', transform: open ? 'translateY(-8px) rotate(-45deg)' : 'none', transition: 'transform .2s' }}></span>
          </button>
        </nav>
      </div>
      {open && (
        <div className="mvp-drawer" style={{ borderTop: '3px solid var(--mv-ink)', background: 'var(--mv-bone)', padding: 'var(--gutter)', display: 'flex', flexDirection: 'column', gap: 10 }}>
          {links.map(([l, href]) => (
            <a key={l} href={href || '#top'} onClick={(e) => { setOpen(false); if (!href) { e.preventDefault(); onValuation && onValuation(); } }} style={{ display: 'flex', alignItems: 'center', minHeight: 48, padding: '0 14px', font: '700 var(--fs-label)/1 var(--font-mono)', letterSpacing: '0.06em', textTransform: 'uppercase', color: 'var(--mv-ink)', textDecoration: 'none', border: '3px solid var(--mv-ink)', background: 'var(--mv-bone)', boxShadow: '4px 4px 0 var(--mv-ink)' }}>{l}</a>
          ))}
          <Button variant="primary" size="lg" full onClick={() => { setOpen(false); onValuation && onValuation(); }} iconRight={<span aria-hidden="true">→</span>}>Gratis waardebepaling</Button>
        </div>
      )}
      <style>{`.mvp-chip{transition:transform .15s,background .15s,box-shadow .15s}.mvp-chip:hover{background:var(--mv-green);transform:translate(-2px,-2px) rotate(-1.5deg);box-shadow:3px 3px 0 var(--mv-ink);color:var(--mv-ink)}@media(max-width:900px){.mvp-links,.mvp-cta-wide{display:none!important}.mvp-burger{display:flex!important}}@media(min-width:901px){.mvp-drawer{display:none!important}}`}</style>
    </header>
  );
}
Object.assign(window, { HeaderPlayful });
})();

(function(){
const { Button, Select, Input, IndexTag } = window.MartiniVastgoedDesignSystem_adb8d1;

const MVP_KERN = { Va: '-0.05em', VA: '-0.05em' };
function Letters({ text, base }) {
  return text.split('').map((ch, i) => (
    <span key={i} className="mvp-l" style={{ display: 'inline-block', animationDelay: `${base + i * 45}ms`, marginLeft: (i > 0 && MVP_KERN[text[i - 1] + ch]) || 0 }}>{ch}</span>
  ));
}

function Sticker({ children, bg, ink, rotate, style }) {
  return (
    <span className="mvp-sticker" style={{ display: 'inline-block', textAlign: 'center', background: bg, color: ink, border: '3px solid var(--mv-ink)', boxShadow: '5px 5px 0 var(--mv-ink)', padding: '14px 16px', font: '700 var(--fs-label)/1.3 var(--font-mono)', textTransform: 'uppercase', letterSpacing: '0.08em', transform: `rotate(${rotate}deg)`, ...style }}>{children}</span>
  );
}

function Marquee() {
  const items = ['Te huur in Groningen', 'Sinds 1992', 'Appartementen', "Studio's", 'Herenhuizen', 'Kamers', 'Gratis waardebepaling'];
  const innerRef = React.useRef(null);
  React.useEffect(() => {
    const inner = innerRef.current;
    if (!inner) return;
    let target = 0, current = 0, last = window.scrollY, raf = 0;
    const tick = () => {
      raf = 0;
      current += (target - current) * 0.09;
      const track = inner.firstElementChild;
      const w = track ? track.offsetWidth : 1;
      if (w > 0) inner.style.transform = `translate3d(${-(((current % w) + w) % w)}px,0,0)`;
      if (Math.abs(target - current) > 0.2) raf = requestAnimationFrame(tick);
    };
    const onScroll = () => {
      const y = window.scrollY;
      target += (y - last) * 0.28;
      last = y;
      if (!raf) raf = requestAnimationFrame(tick);
    };
    window.addEventListener('scroll', onScroll, { passive: true });
    return () => { window.removeEventListener('scroll', onScroll); if (raf) cancelAnimationFrame(raf); };
  }, []);
  const Track = ({ ariaHidden }) => (
    <div className="mvp-track" aria-hidden={ariaHidden} style={{ display: 'flex', flexShrink: 0, minWidth: '100%', alignItems: 'center', gap: '2.5rem', padding: '14px 1.25rem' }}>
      {items.map((t, i) => (
        <span key={i} style={{ display: 'inline-flex', alignItems: 'center', gap: '2.5rem', font: '800 1.35rem/1 var(--font-display)', textTransform: 'uppercase', letterSpacing: '0.01em', color: 'var(--mv-ink)', whiteSpace: 'nowrap' }}>{t}<span aria-hidden="true">→</span></span>
      ))}
    </div>
  );
  return (
    <div style={{ overflow: 'hidden', background: 'var(--mv-green)', borderTop: '3px solid var(--mv-ink)' }}>
      <div ref={innerRef} style={{ display: 'flex', willChange: 'transform' }}>
        <Track /><Track ariaHidden="true" /><Track ariaHidden="true" />
      </div>
    </div>
  );
}

function HeroPlayful({ onSearch }) {
  const towerRef = React.useRef(null);
  const secRef = React.useRef(null);
  React.useEffect(() => {
    if (window.matchMedia('(prefers-reduced-motion: reduce)').matches) return;
    const sec = secRef.current;
    const onMove = (e) => {
      const r = sec.getBoundingClientRect();
      const dx = (e.clientX - r.left) / r.width - 0.5, dy = (e.clientY - r.top) / r.height - 0.5;
      if (towerRef.current) towerRef.current.style.transform = `translate(${dx * -16}px, ${dy * -10}px)`;
    };
    sec.addEventListener('mousemove', onMove);
    return () => sec.removeEventListener('mousemove', onMove);
  }, []);
  return (
    <section ref={secRef} style={{ position: 'relative', background: 'var(--mv-bone)', borderBottom: '3px solid var(--mv-ink)', overflow: 'hidden' }}>

      <div ref={towerRef} aria-hidden="true" className="mvp-tower-wrap" style={{ position: 'absolute', right: 'clamp(0.5rem,5vw,6rem)', top: '4%', zIndex: 0, pointerEvents: 'none', transition: 'transform .3s ease-out' }}>
        <img src="assets/tower-tilted.webp" alt="" className="mvp-tower" style={{ display: 'block', height: 'clamp(380px,52vw,660px)', width: 'auto', filter: 'drop-shadow(14px 18px 0 var(--mv-pink))' }} />
      </div>

      <Sticker bg="var(--mv-pink)" ink="var(--mv-bone)" rotate={6} style={{ position: 'absolute', right: 'clamp(1rem,20vw,22rem)', top: '9%', zIndex: 2 }}>Nieuw aanbod<br />wekelijks</Sticker>
      <Sticker bg="var(--mv-tangerine)" ink="var(--mv-ink)" rotate={-5} style={{ position: 'absolute', right: 'clamp(0.5rem,7vw,8rem)', bottom: '22%', zIndex: 2 }}>Groningen<br />van boven</Sticker>
      <div style={{ position: 'relative', zIndex: 1, maxWidth: 'var(--maxw)', margin: '0 auto', padding: 'clamp(3rem,7vw,5.5rem) var(--gutter) clamp(2.5rem,5vw,4rem)' }}>
        <IndexTag label="Groningen · sinds 1992" accent="pink" />
        <h1 style={{ margin: '18px 0 0', font: '900 var(--fs-mega)/0.86 var(--font-display)', letterSpacing: 'var(--ls-mega)', color: 'var(--mv-ink)' }}>
          <span className="mvp-mask" style={{ display: 'block', overflow: 'hidden', paddingBottom: '0.04em' }}><Letters text="Martini" base={80} /></span>
          <span className="mvp-mask" style={{ display: 'block', overflow: 'hidden', paddingBottom: '0.24em', marginBottom: '-0.18em' }}><Letters text="Vastgoed" base={420} /><span className="mvp-l" style={{ display: 'inline-block', color: 'var(--mv-green)', animationDelay: '820ms' }}>.</span></span>
        </h1>
        <p style={{ maxWidth: '30ch', margin: '26px 0 0', font: '500 var(--fs-body-xl)/1.35 var(--font-body)', letterSpacing: '-0.01em', color: 'var(--mv-ink)' }}>
          De makelaar die Groningen van boven kent, en daarom precies weet wat elke woning <span style={{ background: 'var(--mv-green)', padding: '0 0.12em', boxDecorationBreak: 'clone', WebkitBoxDecorationBreak: 'clone' }}>beneden waard is</span>.
        </p>
        <form onSubmit={(e) => { e.preventDefault(); onSearch && onSearch(); }} className="mvp-search" style={{ marginTop: 'clamp(2rem,4vw,3rem)', maxWidth: 840, display: 'flex', flexWrap: 'wrap', alignItems: 'flex-end', gap: 14, background: 'var(--mv-ink)', border: '3px solid var(--mv-ink)', boxShadow: '5px 5px 0 var(--mv-ink)', padding: 18, transition: 'transform .18s, box-shadow .18s' }}>
          <PlayfulField label="Wijk"><Select options={['Alle wijken', 'Binnenstad', 'Oosterpoort', 'Helpman', 'Noorderplantsoen']} wrapStyle={{ minWidth: 180 }} /></PlayfulField>
          <PlayfulField label="Type"><Select options={['Alle types', 'Appartement', 'Studio', 'Huis', 'Kamer']} wrapStyle={{ minWidth: 160 }} /></PlayfulField>
          <PlayfulField label="Max. huur"><Input prefix="€" placeholder="1.500" wrapStyle={{ minWidth: 140 }} /></PlayfulField>
          <Button type="submit" variant="primary" size="lg" iconRight={<span aria-hidden="true">→</span>} style={{ flex: 1, minWidth: 150 }}>Zoek woning</Button>
        </form>
      </div>
      <Marquee />
      <style>{`
        .mvp-l{animation:mvpDrop .7s cubic-bezier(.2,.9,.25,1) both;transition:transform .18s,color .18s}
        .mvp-l:hover{transform:translateY(-0.08em) rotate(-4deg);color:var(--mv-pink)}
        @keyframes mvpDrop{from{transform:translateY(110%)}to{transform:translateY(0)}}
        .mvp-tower{animation:mvpSway 8s ease-in-out infinite alternate;transform-origin:50% 95%}
        @keyframes mvpSway{from{transform:rotate(-1.2deg) translateY(0)}to{transform:rotate(1.4deg) translateY(-12px)}}
        .mvp-sticker{animation:mvpPop .5s cubic-bezier(.3,1.6,.5,1) both 1s}
        .mvp-sticker:nth-of-type(2){animation-delay:1.2s}
        @keyframes mvpPop{from{scale:0;rotate:12deg}to{scale:1}}
        .mvp-search:hover{transform:translate(-3px,-3px);box-shadow:8px 8px 0 var(--mv-pink)}
        @media(prefers-reduced-motion:reduce){.mvp-l,.mvp-tower,.mvp-sticker{animation:none}}
        @media(max-width:900px){.mvp-tower-wrap,.mvp-sticker{display:none}}
      `}</style>
    </section>
  );
}

function PlayfulField({ label, children }) {
  return (
    <div style={{ display: 'flex', flexDirection: 'column', gap: 7 }}>
      <span style={{ font: '700 var(--fs-label-sm)/1 var(--font-mono)', letterSpacing: 'var(--ls-label)', textTransform: 'uppercase', color: 'var(--mv-bone)' }}>{label}</span>
      {children}
    </div>
  );
}
Object.assign(window, { HeroPlayful });
})();

(function(){
const { IndexTag } = window.MartiniVastgoedDesignSystem_adb8d1;

function FilmTakeover() {
  const secRef = React.useRef(null);
  const boxRef = React.useRef(null);
  const vidRef = React.useRef(null);
  const capRef = React.useRef(null);
  const [muted, setMuted] = React.useState(true);
  const reduced = window.matchMedia('(prefers-reduced-motion: reduce)').matches;
  React.useEffect(() => {
    if (reduced) return;
    let raf = 0;
    const tick = () => {
      raf = 0;
      const sec = secRef.current, box = boxRef.current, cap = capRef.current;
      if (!sec || !box) return;
      const vh = window.innerHeight;
      const p = Math.min(1, Math.max(0, (window.scrollY - sec.offsetTop) / (sec.offsetHeight - vh)));
      const e = p < 0.5 ? 2 * p * p : 1 - Math.pow(-2 * p + 2, 2) / 2;
      const capH = cap ? cap.offsetHeight : 0;
      const g = Math.min(28, vh * 0.035);
      const startH = vh - capH - g;
      const startW = window.innerWidth < 700 ? 91 : 62;
      box.style.width = `${startW + e * (100 - startW)}vw`;
      box.style.height = `${startH + (vh - startH) * e}px`;
      box.style.top = `${capH * (1 - e)}px`;
      const sh = Math.max(0, 14 * (1 - e * 1.6));
      box.style.boxShadow = `${sh}px ${sh}px 0 var(--mv-pink)`;
      box.style.borderWidth = `${Math.max(0, 3 * (1 - e * 1.4))}px`;
      if (cap) { cap.style.opacity = String(Math.max(0, 1 - p * 3)); cap.style.transform = `translateY(${p * -40}px)`; }
    };
    const onScroll = () => { if (!raf) raf = requestAnimationFrame(tick); };
    window.addEventListener('scroll', onScroll, { passive: true });
    tick();
    return () => { window.removeEventListener('scroll', onScroll); if (raf) cancelAnimationFrame(raf); };
  }, []);
  React.useEffect(() => {
    const v = vidRef.current;
    if (!v) return;
    const io = new IntersectionObserver(([en]) => { en.isIntersecting ? v.play().catch(() => {}) : v.pause(); }, { threshold: 0.15 });
    io.observe(v);
    return () => io.disconnect();
  }, []);
  return (
    <section ref={secRef} data-pin style={{ position: 'relative', height: reduced ? 'auto' : '240vh', background: 'var(--mv-bone)', borderBottom: '3px solid var(--mv-ink)' }}>
      <div style={{ position: reduced ? 'relative' : 'sticky', top: 0, height: '100vh', overflow: 'hidden', display: 'flex', flexDirection: 'column' }}>
        <div ref={capRef} style={{ flex: 'none', display: 'flex', flexDirection: 'column', alignItems: 'center', gap: 'clamp(0.75rem,1.8vh,1.25rem)', textAlign: 'center', padding: 'clamp(2.5rem,7vh,4.5rem) var(--gutter) clamp(2rem,5vh,3.5rem)' }}>
          <IndexTag label="01 · De film" accent="pink" />
          <h2 style={{ margin: 0, font: '900 clamp(2rem,4.6vw,4rem)/0.95 var(--font-display)', letterSpacing: 'var(--ls-display)', color: 'var(--mv-ink)' }}>Zo voelt thuis<span style={{ color: 'var(--mv-pink)' }}>.</span></h2>
          <p style={{ margin: 0, font: '700 var(--fs-label)/1.4 var(--font-mono)', letterSpacing: 'var(--ls-label)', textTransform: 'uppercase', color: 'var(--mv-ink-70)' }}>Scroll om af te spelen ↓</p>
        </div>
        <div style={{ flex: 1, minHeight: 0, display: 'grid', placeItems: 'center' }}>
        <div ref={boxRef} id="film-box" style={reduced ? { position: 'relative', width: '92vw', height: '96%', border: '3px solid var(--mv-ink)', boxShadow: '14px 14px 0 var(--mv-pink)', background: 'var(--mv-ink)', overflow: 'hidden' } : { position: 'absolute', left: '50%', transform: 'translateX(-50%)', top: '30vh', width: '62vw', height: '58vh', border: '3px solid var(--mv-ink)', boxShadow: '14px 14px 0 var(--mv-pink)', background: 'var(--mv-ink)', overflow: 'hidden' }}>
          <video ref={vidRef} src="assets/video-tuin-web.mp4" muted={muted} loop playsInline preload="metadata" style={{ position: 'absolute', inset: 0, width: '100%', height: '100%', objectFit: 'cover' }}></video>
          <span className="mvp-sticker" style={{ position: 'absolute', top: 18, right: 18, display: 'inline-block', background: 'var(--mv-green)', color: 'var(--mv-ink)', border: '3px solid var(--mv-ink)', boxShadow: '4px 4px 0 var(--mv-ink)', padding: '10px 12px', font: '700 var(--fs-label-sm)/1.3 var(--font-mono)', textTransform: 'uppercase', letterSpacing: '0.08em', transform: 'rotate(5deg)' }}>Hond<br />inbegrepen ✳</span>
          <button onClick={() => { setMuted(!muted); const v = vidRef.current; if (v && muted) v.play().catch(() => {}); }} aria-label={muted ? 'Geluid aan' : 'Geluid uit'}
            className="mvp-sound" style={{ position: 'absolute', bottom: 18, right: 18, cursor: 'pointer', background: 'var(--mv-bone)', color: 'var(--mv-ink)', border: '3px solid var(--mv-ink)', boxShadow: '4px 4px 0 var(--mv-ink)', minHeight: 46, padding: '10px 14px', font: '700 var(--fs-label)/1 var(--font-mono)', letterSpacing: '0.08em', textTransform: 'uppercase' }}>
            {muted ? '► Geluid aan' : '◼ Geluid uit'}
          </button>
          <span className="mvp-filmmeta" style={{ position: 'absolute', bottom: 18, left: 18, font: '700 var(--fs-label-sm)/1.4 var(--font-mono)', letterSpacing: '0.08em', textTransform: 'uppercase', color: 'var(--mv-bone)', background: 'var(--mv-ink)', border: '2px solid var(--mv-bone)', padding: '8px 10px' }}>Zomer in de stad · 0:30</span>
        </div>
        </div>
      </div>
      <style>{`@media(max-width:760px){.mvp-filmmeta{display:none!important}}`}</style>
    </section>
  );
}
Object.assign(window, { FilmTakeover });
})();

(function(){
function StoryTakeover() {
  const secRef = React.useRef(null);
  const lineRefs = React.useRef([]);
  const starRef = React.useRef(null);
  const reduced = window.matchMedia('(prefers-reduced-motion: reduce)').matches;
  const lines = [
    [{ t: 'Sinds ' }, { t: '1992', c: 'var(--mv-green)' }, { t: ' verhuren wij Groningen.' }],
    [{ t: 'Toen heetten we ' }, { t: 'Bulten', c: 'var(--mv-tangerine)' }, { t: ' Vastgoed.' }],
    [{ t: 'Nu heten we ' }, { t: 'Martini', c: 'var(--mv-pink)' }, { t: '.' }],
    [{ t: 'Zelfde mensen, nieuwe blik. ' }, { t: 'Net zo jong als de stad', c: 'var(--mv-green)' }, { t: '.' }],
  ];
  const lineWords = lines.map((parts) => {
    const words = [];
    parts.forEach((s) => {
      s.t.split(/(\s+)/).forEach((w) => {
        if (!w) return;
        if (/^\s+$/.test(w)) { if (words.length) words[words.length - 1].space = true; return; }
        words.push({ w, color: s.c || 'var(--mv-bone)', space: false });
      });
    });
    return words;
  });
  React.useEffect(() => {
    if (reduced) {
      lineRefs.current.forEach((el) => el && el.querySelectorAll('[data-w],[data-g]').forEach((s) => { s.style.opacity = '1'; s.style.transform = 'none'; }));
      return;
    }
    let raf = 0;
    const ease = (x) => 1 - Math.pow(1 - x, 3);
    const tick = () => {
      raf = 0;
      const vh = window.innerHeight;
      lineRefs.current.forEach((el) => {
        if (!el) return;
        const r = el.getBoundingClientRect();
        const p = Math.min(1, Math.max(0, (vh * 0.88 - r.top) / (vh * 0.46)));
        const spans = el.__w || (el.__w = el.querySelectorAll('[data-w]'));
        const ghosts = el.__g || (el.__g = el.querySelectorAll('[data-g]'));
        const n = spans.length;
        spans.forEach((s, j) => {
          const f = ease(Math.min(1, Math.max(0, p * (n + 3) - j)));
          const done = f >= 1;
          const y = done ? '' : `translate3d(0,${(1 - f) * 0.18}em,0)`;
          s.style.opacity = done ? '' : f;
          s.style.transform = y;
          s.style.willChange = done ? 'auto' : 'opacity, transform';
          if (ghosts[j]) { ghosts[j].style.transform = y; ghosts[j].style.willChange = done ? 'auto' : 'transform'; }
        });
      });
      const sec = secRef.current;
      if (sec && starRef.current) {
        const r = sec.getBoundingClientRect();
        starRef.current.style.transform = `translate3d(0,${((r.top + r.height / 2 - vh / 2) / vh) * -48}px,0)`;
      }
    };
    const onScroll = () => { if (!raf) raf = requestAnimationFrame(tick); };
    window.addEventListener('scroll', onScroll, { passive: true });
    window.addEventListener('resize', onScroll);
    tick();
    return () => { window.removeEventListener('scroll', onScroll); window.removeEventListener('resize', onScroll); if (raf) cancelAnimationFrame(raf); };
  }, []);
  return (
    <section id="verhaal" ref={secRef} data-pin style={{ position: 'relative', background: 'var(--mv-ink)', color: 'var(--mv-bone)', borderBottom: '3px solid var(--mv-ink)', overflow: 'hidden', padding: 'clamp(5rem,14vh,9rem) var(--gutter) clamp(5rem,14vh,9rem)' }}>
      <div ref={starRef} aria-hidden="true" className="mvp-spine" style={{ position: 'absolute', top: 0, right: 'clamp(0.75rem,3vw,2.5rem)', height: '100%', display: 'flex', alignItems: 'center', gap: 'clamp(0.75rem,2vw,1.5rem)', pointerEvents: 'none', willChange: 'transform' }}>
        <span style={{ writingMode: 'vertical-rl', font: '700 var(--fs-label-sm)/1 var(--font-mono)', letterSpacing: '0.42em', textTransform: 'uppercase', color: 'var(--mv-bone)', opacity: 0.34 }}>Vismarkt 32 · Groningen</span>
        <span style={{ display: 'block', width: 2, height: 'clamp(120px,26vh,260px)', background: 'var(--mv-green)', opacity: 0.55 }}></span>
      </div>
      <div className="mvp-story-col" style={{ maxWidth: 'var(--maxw)', margin: '0 auto', width: '100%' }}>
        <p style={{ margin: '0 0 clamp(1.5rem,4vh,3rem)', font: '700 var(--fs-label)/1 var(--font-mono)', letterSpacing: 'var(--ls-label)', textTransform: 'uppercase', color: 'var(--mv-green)' }}>03 · Ons verhaal</p>
        <div style={{ display: 'flex', flexDirection: 'column', gap: 'clamp(0.6rem,2vh,1.4rem)' }}>
          {lineWords.map((words, i) => (
            <div key={i} ref={(el) => { lineRefs.current[i] = el; }} style={{ position: 'relative', font: '900 clamp(2rem,5.4vw,4.6rem)/1.02 var(--font-display)', letterSpacing: 'var(--ls-display)' }}>
              <span aria-hidden="true" style={{ color: 'var(--mv-bone)', opacity: 0.14 }}>{words.map((w, j) => <span key={j} data-g="" style={{ display: 'inline-block', willChange: 'transform' }}>{w.w}{w.space ? '\u00a0' : ''}</span>)}</span>
              <span style={{ position: 'absolute', inset: 0 }}>
                {words.map((w, j) => (
                  <span key={j} data-w="" style={{ display: 'inline-block', color: w.color, opacity: 0, willChange: 'opacity, transform' }}>{w.w}{w.space ? '\u00a0' : ''}</span>
                ))}
              </span>
            </div>
          ))}
        </div>
        <p style={{ margin: 'clamp(2rem,5vh,3.5rem) 0 0', maxWidth: '52ch', font: '400 var(--fs-body-lg)/var(--lh-body) var(--font-body)', color: 'var(--mv-bone-70)' }}>
          Ruim dertig jaar kamers, studio's en appartementen vanaf de Vismarkt. Winkel- en horecapanden ook. De naam is nieuw, het vakwerk niet.
        </p>
      </div>
      <style>{`@media(max-width:900px){.mvp-spine{display:none!important}}@media(min-width:901px){.mvp-story-col{padding-right:clamp(70px,7vw,130px)}}`}</style>
    </section>
  );
}
Object.assign(window, { StoryTakeover });
})();

(function(){
const { SectionHeading, Button } = window.MartiniVastgoedDesignSystem_adb8d1;

function PlaceholderStripes({ label, img }) {
  return (
    <div style={{ position: 'relative', height: 190, borderBottom: '3px solid var(--mv-ink)', background: 'repeating-linear-gradient(45deg,var(--mv-bone-2) 0 12px,var(--mv-bone) 12px 24px)', display: 'grid', placeItems: 'center', overflow: 'hidden' }}>
      <span style={{ font: '700 var(--fs-label-sm)/1.4 var(--font-mono)', letterSpacing: '0.08em', textTransform: 'uppercase', color: 'var(--mv-ink-70)', background: 'var(--mv-bone)', border: '2px solid var(--mv-ink)', padding: '6px 10px' }}>{label}</span>
      {img && <img src={img} alt={label} onError={(e) => { e.currentTarget.style.display = 'none'; }} style={{ position: 'absolute', inset: 0, width: '100%', height: '100%', objectFit: 'cover', display: 'block' }} />}
    </div>
  );
}

function BuurtCard({ b, i }) {
  const [hover, setHover] = React.useState(false);
  return (
    <article onMouseEnter={() => setHover(true)} onMouseLeave={() => setHover(false)}
      style={{ flex: '0 0 auto', scrollSnapAlign: 'center', width: 'min(380px,82vw)', background: 'var(--mv-bone)', border: '3px solid var(--mv-ink)', boxShadow: hover ? '10px 10px 0 ' + b.c : '6px 6px 0 var(--mv-ink)', transform: hover ? 'translate(-3px,-3px) rotate(-0.5deg)' : 'rotate(' + (i % 2 ? 0.6 : -0.6) + 'deg)', transition: 'transform .18s, box-shadow .18s' }}>
      <PlaceholderStripes label={'foto: ' + b.name} img={b.img} />
      <div style={{ padding: 'var(--space-5)' }}>
        <p style={{ margin: 0, font: '700 var(--fs-label-sm)/1 var(--font-mono)', letterSpacing: 'var(--ls-label)', textTransform: 'uppercase', color: 'var(--mv-ink-70)' }}>{String(i + 1).padStart(2, '0')} · {b.count} woningen</p>
        <h3 style={{ margin: '10px 0 0', font: '900 var(--fs-h3)/1 var(--font-display)', letterSpacing: 'var(--ls-heading)', color: 'var(--mv-ink)' }}>{b.name}</h3>
        <p style={{ margin: '10px 0 0', font: '400 var(--fs-body-sm)/1.5 var(--font-body)', color: 'var(--mv-ink-70)' }}>{b.desc}</p>
        <p style={{ margin: '14px 0 0', font: '700 var(--fs-body)/1 var(--font-mono)', color: 'var(--mv-ink)' }}>v.a. <span style={{ background: b.c, padding: '0 0.15em' }}>{b.from}</span> p/m</p>
      </div>
    </article>
  );
}

function Buurten() {
  const secRef = React.useRef(null);
  const trackRef = React.useRef(null);
  const reducedMotion = window.matchMedia('(prefers-reduced-motion: reduce)').matches;
  const [narrow, setNarrow] = React.useState(window.matchMedia('(max-width:760px)').matches);
  React.useEffect(() => {
    const mq = window.matchMedia('(max-width:760px)');
    const on = () => setNarrow(mq.matches);
    mq.addEventListener('change', on);
    return () => mq.removeEventListener('change', on);
  }, []);
  const reduced = reducedMotion || narrow;
  const buurten = [
    { name: 'Binnenstad', desc: 'Boven de winkels, midden in alles.', from: '€ 895', count: 14, c: 'var(--mv-green)', img: 'assets/buurt-binnenstad.webp' },
    { name: 'Noorderplantsoen', desc: 'Park als voortuin, festival als buurman.', from: '€ 780', count: 8, c: 'var(--mv-pink)', img: 'assets/buurt-noorderplantsoen.webp' },
    { name: 'Oosterpoort', desc: 'Karakter, kroegen en de Euroborg om de hoek.', from: '€ 740', count: 11, c: 'var(--mv-tangerine)', img: 'assets/buurt-oosterpoort.webp' },
    { name: 'Korrewegwijk', desc: 'Studentikoos, betaalbaar, bruisend.', from: '€ 640', count: 17, c: 'var(--mv-green)', img: 'assets/buurt-korrewegwijk.webp' },
    { name: 'Helpman', desc: 'Ruim en groen, tien minuten fietsen.', from: '€ 1.150', count: 6, c: 'var(--mv-pink)', img: 'assets/buurt-helpman.webp' },
    { name: 'Zernike', desc: 'Op rolafstand van de campus.', from: '€ 620', count: 9, c: 'var(--mv-tangerine)', img: 'assets/buurt-zernike.webp' },
  ];
  React.useEffect(() => {
    if (reduced) { const sec = secRef.current, track = trackRef.current; if (sec) sec.style.height = 'auto'; if (track) track.style.transform = 'none'; return; }
    let raf = 0;
    const size = () => {
      const sec = secRef.current, track = trackRef.current;
      if (!sec || !track) return;
      if (reduced) { sec.style.height = 'auto'; return; }
      const max = Math.max(0, track.scrollWidth - track.parentElement.clientWidth);
      sec.style.height = `${window.innerHeight + max}px`;
    };
    const tick = () => {
      raf = 0;
      const sec = secRef.current, track = trackRef.current;
      if (!sec || !track) return;
      const vh = window.innerHeight;
      const p = Math.min(1, Math.max(0, (window.scrollY - sec.offsetTop) / (sec.offsetHeight - vh)));
      const max = Math.max(0, track.scrollWidth - track.parentElement.clientWidth);
      track.style.transform = `translateX(${-p * max}px)`;
    };
    const onScroll = () => { if (!raf) raf = requestAnimationFrame(tick); };
    window.addEventListener('scroll', onScroll, { passive: true });
    window.addEventListener('resize', size);
    window.addEventListener('resize', onScroll);
    size();
    tick();
    return () => { window.removeEventListener('scroll', onScroll); window.removeEventListener('resize', size); window.removeEventListener('resize', onScroll); if (raf) cancelAnimationFrame(raf); };
  }, [reduced]);
  return (
    <section id="buurten" ref={secRef} data-pin style={{ position: 'relative', height: reduced ? 'auto' : '260vh', background: 'var(--mv-bone)', borderBottom: '3px solid var(--mv-ink)' }}>
      <div style={{ position: reduced ? 'relative' : 'sticky', top: 0, minHeight: '100vh', display: 'flex', flexDirection: 'column', justifyContent: 'center', gap: 'var(--space-7)', overflow: 'hidden', padding: 'clamp(2.5rem,6vh,4rem) 0' }}>
        <div style={{ width: '100%', maxWidth: 'var(--maxw)', margin: '0 auto', padding: '0 var(--gutter)', display: 'flex', flexWrap: 'wrap', gap: 'var(--space-5)', alignItems: 'flex-end', justifyContent: 'space-between' }}>
          <SectionHeading num={4} total={5} label="Buurten" title="Kies je stukje Groningen." accent="tangerine" />
          <p style={{ margin: 0, font: '700 var(--fs-label)/1.4 var(--font-mono)', letterSpacing: 'var(--ls-label)', textTransform: 'uppercase', color: 'var(--mv-ink-70)' }}>{narrow ? 'Swipe → de stad schuift mee' : 'Scroll → de stad schuift mee'}</p>
        </div>
        <div className="mvp-buurt-rail" style={{ overflowX: reduced ? 'auto' : 'hidden', overflowY: 'hidden', scrollSnapType: reduced ? 'x mandatory' : 'none', WebkitOverflowScrolling: 'touch' }}>
          <div ref={trackRef} style={{ display: 'flex', gap: reduced ? 'var(--space-5)' : 'var(--space-6)', padding: '14px var(--gutter) 20px', willChange: 'transform' }}>
            {buurten.map((b, i) => <BuurtCard key={b.name} b={b} i={i} />)}
            <div style={{ flex: '0 0 auto', scrollSnapAlign: 'center', width: 'min(380px,82vw)', display: 'grid', placeItems: 'center', background: 'var(--mv-ink)', border: '3px solid var(--mv-ink)', boxShadow: '6px 6px 0 var(--mv-green)', padding: 'var(--space-6)' }}>
              <div style={{ textAlign: 'center', display: 'flex', flexDirection: 'column', gap: 18, alignItems: 'center' }}>
                <p style={{ margin: 0, font: '900 var(--fs-h3)/1.05 var(--font-display)', color: 'var(--mv-bone)' }}>Jouw buurt er niet bij?</p>
                <Button variant="primary" size="lg" onClick={() => { const a = document.getElementById('aanbod'); if (a) window.scrollTo({ top: a.offsetTop - 70, behavior: 'smooth' }); }} iconRight={<span aria-hidden="true">→</span>}>Al het aanbod</Button>
              </div>
            </div>
          </div>
        </div>
      </div>
      <style>{`.mvp-buurt-rail::-webkit-scrollbar{height:0}`}</style>
    </section>
  );
}
Object.assign(window, { Buurten });
})();

(function(){
const { PillRow, Button, IndexTag } = window.MartiniVastgoedDesignSystem_adb8d1;

function Zakelijk() {
  const vidRef = React.useRef(null);
  const [muted, setMuted] = React.useState(true);
  React.useEffect(() => {
    const v = vidRef.current;
    if (!v) return;
    const io = new IntersectionObserver(([en]) => { en.isIntersecting ? v.play().catch(() => {}) : v.pause(); }, { threshold: 0.15 });
    io.observe(v);
    return () => io.disconnect();
  }, []);
  return (
    <section id="zakelijk" style={{ background: 'var(--mv-ink)', color: 'var(--mv-bone)', borderTop: '3px solid var(--mv-pink)', borderBottom: '3px solid var(--mv-pink)', padding: 'var(--section-y) var(--gutter)' }}>
      <div style={{ maxWidth: 'var(--maxw)', margin: '0 auto', display: 'grid', gridTemplateColumns: 'repeat(auto-fit,minmax(min(320px,100%),1fr))', gap: 'var(--space-8)', alignItems: 'center' }}>
        <div>
          <IndexTag label="05 · Zakelijk" accent="pink" style={{ color: 'var(--mv-bone)' }} />
          <h2 style={{ margin: '18px 0 0', font: '900 var(--fs-h1)/0.96 var(--font-display)', letterSpacing: 'var(--ls-display)' }}>Ook zakelijk<span style={{ color: 'var(--mv-pink)' }}>.</span></h2>
          <p style={{ margin: '20px 0 0', maxWidth: '46ch', font: '400 var(--fs-body-lg)/var(--lh-body) var(--font-body)', color: 'var(--mv-bone-70)' }}>
            Winkelpand op de Vismarkt, horeca in de Oosterstraat of een kantoor met uitzicht op de toren. Bedrijfsruimte verhuren en verkopen we ook, al sinds 1992.
          </p>
          <div style={{ marginTop: 22 }}><PillRow items={['Winkel', 'Horeca', 'Kantoor', 'Belegging']} color="bone" /></div>
          <div style={{ marginTop: 26 }}><Button variant="pink" size="lg" iconRight={<span aria-hidden="true">→</span>}>Bekijk zakelijk aanbod</Button></div>
        </div>
        <div className="mvp-zak-frame" style={{ position: 'relative', border: '3px solid var(--mv-pink)', boxShadow: '10px 10px 0 var(--mv-pink)', background: 'var(--mv-ink)', aspectRatio: '16/10', overflow: 'visible', transition: 'transform .18s, box-shadow .18s' }}>
          <video ref={vidRef} src="assets/video-zakelijk-web.mp4" muted={muted} loop playsInline preload="metadata" style={{ position: 'absolute', inset: 0, width: '100%', height: '100%', objectFit: 'cover' }}></video>
          <button onClick={() => { setMuted(!muted); const v = vidRef.current; if (v && muted) v.play().catch(() => {}); }} aria-label={muted ? 'Geluid aan' : 'Geluid uit'}
            style={{ position: 'absolute', bottom: 14, right: 14, cursor: 'pointer', background: 'var(--mv-bone)', color: 'var(--mv-ink)', border: '3px solid var(--mv-ink)', boxShadow: '4px 4px 0 var(--mv-ink)', minHeight: 46, padding: '8px 12px', font: '700 var(--fs-label-sm)/1 var(--font-mono)', letterSpacing: '0.08em', textTransform: 'uppercase' }}>
            {muted ? '► Geluid aan' : '◼ Geluid uit'}
          </button>
          <span style={{ position: 'absolute', top: -16, right: 22, background: 'var(--mv-green)', color: 'var(--mv-ink)', border: '3px solid var(--mv-ink)', boxShadow: '4px 4px 0 var(--mv-ink)', padding: '8px 12px', font: '700 var(--fs-label-sm)/1 var(--font-mono)', letterSpacing: '0.08em', textTransform: 'uppercase', transform: 'rotate(4deg)' }}>Te huur ✳</span>
        </div>
      </div>
      <style>{`.mvp-zak-frame:hover{transform:translate(-3px,-3px);box-shadow:13px 13px 0 var(--mv-pink)}`}</style>
    </section>
  );
}
Object.assign(window, { Zakelijk });
})();

(function(){
const { ListingCard, Tag, SectionHeading } = window.MartiniVastgoedDesignSystem_adb8d1;

function Listings({ listings, num = 1, total = 3 }) {
  const filters = ['Alle', 'Appartement', 'Studio', 'Huis', 'Kamer'];
  const [active, setActive] = React.useState('Alle');
  const shown = active === 'Alle' ? listings : listings.filter((l) => l.type === active);
  return (
    <section id="aanbod" style={{ background: 'var(--mv-bone)', padding: 'var(--section-y) var(--gutter)' }}>
      <div style={{ maxWidth: 'var(--maxw)', margin: '0 auto' }}>
        <div style={{ display: 'flex', flexWrap: 'wrap', gap: 'var(--space-6)', alignItems: 'flex-end', justifyContent: 'space-between' }}>
          <SectionHeading num={num} total={total} label="Aanbod" title="Woningen te huur in Groningen." accent="green" />
          <div style={{ display: 'flex', flexWrap: 'wrap', gap: 10 }}>
            {filters.map((f) => (
              <FilterChip key={f} active={active === f} onClick={() => setActive(f)}>{f}</FilterChip>
            ))}
          </div>
        </div>
        <div style={{ marginTop: 'var(--space-7)', display: 'grid', gridTemplateColumns: 'repeat(auto-fill,minmax(300px,1fr))', gap: 'var(--space-6)' }}>
          {shown.map((l) => (
            <ListingCard key={l.id} image={l.img} status={l.status} statusColor={l.statusColor} address={l.address} title={l.title} area={l.area} rooms={l.rooms} beds={l.beds} price={l.price} />
          ))}
        </div>
        {shown.length === 0 && <p style={{ marginTop: 'var(--space-6)', font: '500 var(--fs-body)/1.5 var(--font-body)', color: 'var(--mv-ink-70)' }}>Geen woningen in deze categorie. Probeer een ander filter.</p>}
      </div>
    </section>
  );
}

function FilterChip({ children, active, onClick }) {
  const [hover, setHover] = React.useState(false);
  return (
    <button onClick={onClick} onMouseEnter={() => setHover(true)} onMouseLeave={() => setHover(false)}
      style={{
        minHeight: 44, padding: '9px 16px', border: '2px solid var(--mv-ink)', borderRadius: 0, cursor: 'pointer',
        font: '700 var(--fs-label)/1 var(--font-mono)', letterSpacing: 'var(--ls-label)', textTransform: 'uppercase',
        background: active ? 'var(--mv-ink)' : (hover ? 'var(--mv-bone-2)' : 'transparent'),
        color: active ? 'var(--mv-bone)' : 'var(--mv-ink)',
        boxShadow: active ? 'var(--shadow-xs)' : 'none',
        transition: 'background var(--dur-fast), color var(--dur-fast)',
      }}>{children}</button>
  );
}
Object.assign(window, { Listings });
})();

(function(){
const { Asterisk } = window.MartiniVastgoedDesignSystem_adb8d1;

function Impact() {
  const stats = [
    { n: '1992', l: 'Actief sinds', c: 'var(--mv-green)' },
    { n: '96m', l: 'Martinitoren, ons uitzicht', c: 'var(--mv-tangerine)' },
    { n: '500+', l: 'Woningen verhuurd', c: 'var(--mv-pink)' },
    { n: '4.9', l: 'Gemiddelde beoordeling', c: 'var(--mv-green)' },
  ];
  return (
    <section id="over-ons" style={{ background: 'var(--mv-bone)', color: 'var(--mv-ink)', borderBottom: '3px solid var(--mv-ink)', padding: 'var(--section-y) var(--gutter)' }}>
      <div style={{ maxWidth: 'var(--maxw)', margin: '0 auto', display: 'grid', gridTemplateColumns: 'repeat(auto-fit,minmax(280px,1fr))', gap: 'var(--space-8)', alignItems: 'center' }}>
        <div>
          <p style={{ margin: 0, font: '700 var(--fs-label)/1 var(--font-mono)', letterSpacing: 'var(--ls-label)', textTransform: 'uppercase', color: 'var(--mv-pink)' }}>Groningen van boven</p>
          <h2 style={{ margin: '20px 0 0', font: '900 var(--fs-h1)/0.98 var(--font-display)', letterSpacing: 'var(--ls-display)' }}>
            Wij kennen elke straat, elk plein en elke <span style={{ background: 'var(--mv-tangerine)', padding: '0 0.1em' }}>toren.</span>
          </h2>
          <p style={{ margin: '22px 0 0', maxWidth: '48ch', font: '400 var(--fs-body-lg)/var(--lh-body) var(--font-body)', color: 'var(--mv-ink-70)' }}>
            Verhuur, verkoop, aankoop en taxaties van kamers, studio's, appartementen en beleggingspanden. Al ruim 30 jaar vanuit het hart van Groningen. Lokale kennis, scherpe waardebepaling, en een merk dat net zo fris is als de stad zelf.
          </p>
        </div>
        <div style={{ display: 'grid', gridTemplateColumns: '1fr 1fr', gap: 'var(--space-4)' }}>
          {stats.map((s, i) => (
            <div key={i} style={{ border: '3px solid var(--mv-ink)', boxShadow: `6px 6px 0 ${s.c}`, padding: 'var(--space-5)', background: 'var(--mv-bone)' }}>
              <p style={{ margin: 0, font: '900 clamp(2rem,4vw,3rem)/0.9 var(--font-display)', letterSpacing: '-0.02em', color: 'var(--mv-ink)' }}>{s.n}</p>
              <p style={{ margin: '10px 0 0', font: '700 var(--fs-label-sm)/1.3 var(--font-mono)', letterSpacing: '0.1em', textTransform: 'uppercase', color: 'var(--mv-ink-70)' }}>{s.l}</p>
            </div>
          ))}
        </div>
      </div>
    </section>
  );
}
Object.assign(window, { Impact });
})();

(function(){
const { Button, Input, Select, IconButton, Asterisk, IndexTag } = window.MartiniVastgoedDesignSystem_adb8d1;

function ValuationBand({ onOpen }) {
  return (
    <section id="waardebepaling" style={{ background: 'var(--mv-ink)', color: 'var(--mv-bone)', borderTop: '3px solid var(--mv-ink)', borderBottom: '3px solid var(--mv-ink)', padding: 'clamp(3rem,6vw,5rem) var(--gutter)' }}>
      <div style={{ maxWidth: 'var(--maxw)', margin: '0 auto', display: 'flex', flexWrap: 'wrap', gap: 'var(--space-7)', alignItems: 'center', justifyContent: 'space-between' }}>
        <div>
          <p style={{ margin: 0, font: '700 var(--fs-label)/1 var(--font-mono)', letterSpacing: 'var(--ls-label)', textTransform: 'uppercase', color: 'var(--mv-green)' }}>Gratis &amp; vrijblijvend</p>
          <h2 style={{ margin: '16px 0 0', maxWidth: '18ch', font: '900 var(--fs-h1)/0.96 var(--font-display)', letterSpacing: 'var(--ls-display)' }}>Benieuwd wat jouw woning waard is?</h2>
        </div>
        <Button variant="primary" size="lg" onClick={onOpen} iconRight={<span aria-hidden="true">→</span>}>Start waardebepaling</Button>
      </div>
    </section>
  );
}

function ValuationModal({ open, onClose }) {
  const [done, setDone] = React.useState(false);
  React.useEffect(() => { if (!open) setDone(false); }, [open]);
  if (!open) return null;
  return (
    <div role="dialog" aria-modal="true" onClick={onClose}
      style={{ position: 'fixed', inset: 0, zIndex: 90, background: 'rgba(22,18,58,0.55)', display: 'grid', placeItems: 'center', padding: 20 }}>
      <div onClick={(e) => e.stopPropagation()}
        style={{ width: 'min(520px,100%)', maxHeight: '90vh', overflow: 'auto', background: 'var(--mv-bone)', border: '3px solid var(--mv-ink)', boxShadow: 'var(--shadow-xl)' }}>
        <div style={{ display: 'flex', alignItems: 'center', justifyContent: 'space-between', padding: '18px 22px', borderBottom: '3px solid var(--mv-ink)', background: 'var(--mv-ink)', color: 'var(--mv-bone)' }}>
          <IndexTag label="Waardebepaling" accent="green" style={{ color: 'var(--mv-bone)' }} />
          <IconButton label="Sluiten" variant="ghost" size="sm" onClick={onClose} style={{ color: 'var(--mv-bone)' }}><span>✕</span></IconButton>
        </div>
        <div style={{ padding: 22 }}>
          {done ? (
            <div style={{ textAlign: 'center', padding: '20px 0' }}>
              <Asterisk size="3.5rem" color="var(--mv-green)" spin />
              <h3 style={{ margin: '18px 0 8px', font: '900 var(--fs-h3)/1 var(--font-display)', letterSpacing: 'var(--ls-heading)', color: 'var(--mv-ink)' }}>Dank je wel!</h3>
              <p style={{ margin: 0, font: '400 var(--fs-body)/1.5 var(--font-body)', color: 'var(--mv-ink-70)' }}>We nemen binnen één werkdag contact op met een scherpe waardebepaling van jouw woning.</p>
              <div style={{ marginTop: 22 }}><Button variant="ink" onClick={onClose}>Sluiten</Button></div>
            </div>
          ) : (
            <form onSubmit={(e) => { e.preventDefault(); setDone(true); }} style={{ display: 'flex', flexDirection: 'column', gap: 'var(--space-5)' }}>
              <p style={{ margin: 0, font: '500 var(--fs-body)/1.5 var(--font-body)', color: 'var(--mv-ink)' }}>Vul je gegevens in. Je krijgt binnen één werkdag een gratis waardebepaling.</p>
              <Input label="Adres" placeholder="Straatnaam + huisnummer" required />
              <div style={{ display: 'flex', gap: 14, flexWrap: 'wrap' }}>
                <Input label="Postcode" placeholder="9711 AA" wrapStyle={{ flex: '1 1 130px' }} required />
                <Select label="Type" options={['Appartement', 'Studio', 'Huis', 'Kamer']} wrapStyle={{ flex: '1 1 150px' }} />
              </div>
              <Input label="E-mail" type="email" placeholder="jij@voorbeeld.nl" required />
              <Button type="submit" variant="primary" size="lg" full iconRight={<span aria-hidden="true">→</span>}>Vraag waardebepaling aan</Button>
            </form>
          )}
        </div>
      </div>
    </div>
  );
}
Object.assign(window, { ValuationBand, ValuationModal });
})();

(function(){
const { Asterisk, Button } = window.MartiniVastgoedDesignSystem_adb8d1;

function FootLetters({ text }) {
  const kern = { Va: '-0.05em' };
  return text.split('').map((ch, i) => (
    <span key={i} className="mvpf-l" style={{ display: 'inline-block', marginLeft: (i > 0 && kern[text[i - 1] + ch]) || 0 }}>{ch === ' ' ? '\u00A0' : ch}</span>
  ));
}

function FootMarquee() {
  const items = ['Bel 050 230 74 21', 'Mail info@martinivastgoed.nl', 'Kom langs op de Vismarkt 32', 'Sinds 1992'];
  const Track = ({ ariaHidden }) => (
    <div className="mvpf-track" aria-hidden={ariaHidden} style={{ display: 'flex', flexShrink: 0, minWidth: '100%', alignItems: 'center', gap: '2.5rem', padding: '13px 1.25rem' }}>
      {items.map((t, i) => (
        <span key={i} style={{ display: 'inline-flex', alignItems: 'center', gap: '2.5rem', font: '800 1.25rem/1 var(--font-display)', textTransform: 'uppercase', color: 'var(--mv-ink)', whiteSpace: 'nowrap' }}>{t}<span aria-hidden="true">✳</span></span>
      ))}
    </div>
  );
  return (
    <div style={{ display: 'flex', overflow: 'hidden', background: 'var(--mv-tangerine)', borderTop: '3px solid var(--mv-ink)', borderBottom: '3px solid var(--mv-ink)' }}>
      <Track /><Track ariaHidden="true" />
    </div>
  );
}

function FooterPlayful() {
  const wmRef = React.useRef(null);
  React.useEffect(() => {
    const el = wmRef.current;
    if (!el) return;
    const fit = () => {
      const avail = el.clientWidth;
      el.style.fontSize = '100px';
      const w = el.scrollWidth;
      el.style.fontSize = Math.max(30, Math.floor((avail / w) * 100 * 0.99)) + 'px';
    };
    fit();
    if (document.fonts && document.fonts.ready) document.fonts.ready.then(fit);
    window.addEventListener('resize', fit);
    return () => window.removeEventListener('resize', fit);
  }, []);
  const cols = [
    { h: 'Diensten', items: ['Verhuur', 'Verkopen', 'Kopen', 'Taxeren', 'Waardebepaling'] },
    { h: 'Martini', items: ['Over ons', 'Team', 'Werkgebied', 'Reviews', 'Contact'] },
    { h: 'Volg ons', items: ['Instagram', 'LinkedIn', 'Facebook', 'YouTube'] },
  ];
  return (
    <footer style={{ background: 'var(--mv-ink)', color: 'var(--mv-bone)' }}>
      <FootMarquee />
      <div style={{ maxWidth: 'var(--maxw)', margin: '0 auto', padding: 'clamp(3rem,7vh,5rem) var(--gutter) var(--space-6)' }}>
        <div style={{ display: 'flex', flexWrap: 'wrap', gap: 'var(--space-7)', alignItems: 'flex-start', justifyContent: 'space-between' }}>
          <div>
            <p style={{ margin: 0, font: '700 var(--fs-label)/1 var(--font-mono)', letterSpacing: 'var(--ls-label)', textTransform: 'uppercase', color: 'var(--mv-green)' }}>Benieuwd wat er kan?</p>
            <a href="mailto:info@martinivastgoed.nl" className="mvpf-cta" style={{ display: 'inline-block', margin: '14px 0 0', font: '900 clamp(1.6rem,3.4vw,2.8rem)/1.05 var(--font-display)', letterSpacing: 'var(--ls-display)', color: 'var(--mv-bone)', textDecoration: 'none', borderBottom: '4px solid var(--mv-pink)' }}>Stuur ons een berichtje <span aria-hidden="true" className="mvpf-arrow" style={{ display: 'inline-block' }}>→</span></a>
            <p style={{ margin: '22px 0 0', font: '400 var(--fs-body-sm)/1.7 var(--font-mono)', color: 'var(--mv-bone-70)' }}>Vismarkt 32 · 9711 KT Groningen<br />050 230 74 21 · info@martinivastgoed.nl</p>
          </div>
          <div style={{ display: 'flex', flexWrap: 'wrap', gap: 'var(--space-8)' }}>
            {cols.map((c) => (
              <div key={c.h}>
                <p style={{ margin: '0 0 16px', font: '700 var(--fs-label-sm)/1 var(--font-mono)', letterSpacing: 'var(--ls-label)', textTransform: 'uppercase', color: 'var(--mv-green)' }}>{c.h}</p>
                <ul style={{ listStyle: 'none', margin: 0, padding: 0, display: 'flex', flexDirection: 'column', gap: 10 }}>
                  {c.items.map((i) => (
                    <li key={i}><a href="#" className="mvpf-link" style={{ display: 'inline-block', font: '500 var(--fs-body-sm)/1 var(--font-body)', color: 'var(--mv-bone)', textDecoration: 'none' }}>{i}</a></li>
                  ))}
                </ul>
              </div>
            ))}
          </div>
        </div>
        <div aria-hidden="true" ref={wmRef} style={{ marginTop: 'clamp(2.5rem,6vh,4rem)', display: 'flex', alignItems: 'center', gap: '0.18em', fontSize: 'clamp(3rem,9vw,9.5rem)' }}>
          <span className="mvpf-flag" aria-hidden="true" style={{ display: 'grid', gridTemplateRows: 'repeat(3,1fr)', gap: '0.035em', width: '0.34em', height: '0.66em', flex: 'none' }}>
            <i className="mvpf-bar" style={{ background: 'var(--mv-green)' }}></i>
            <i className="mvpf-bar" style={{ background: 'var(--mv-pink)' }}></i>
            <i className="mvpf-bar" style={{ background: 'var(--mv-tangerine)' }}></i>
          </span>
          <p style={{ margin: 0, font: '900 1em/0.9 var(--font-display)', letterSpacing: '-0.02em', textTransform: 'uppercase', whiteSpace: 'nowrap', color: 'var(--mv-bone)' }}>
            <FootLetters text="Martini Vastgoed" /><span className="mvpf-l" style={{ display: 'inline-block', color: 'var(--mv-pink)' }}>.</span>
          </p>
        </div>
        <div style={{ marginTop: 'var(--space-6)', paddingTop: 'var(--space-5)', borderTop: '2px solid var(--mv-bone-70)', display: 'flex', flexWrap: 'wrap', gap: 12, justifyContent: 'space-between', font: '400 var(--fs-label-sm)/1.4 var(--font-mono)', letterSpacing: '0.08em', textTransform: 'uppercase', color: 'var(--mv-bone-70)' }}>
          <span>© 2026 Martini Vastgoed · Vismarkt 32, Groningen</span>
          <span>KvK 01234567 · NVM Makelaar</span>
        </div>
      </div>
      <style>{`
        .mvpf-track{animation:mvpfScroll 20s linear infinite}
        @keyframes mvpfScroll{to{transform:translateX(-100%)}}
        .mvpf-l{transition:transform .18s cubic-bezier(.3,1.6,.5,1),color .18s}
        .mvpf-l:hover{transform:translateY(-0.1em) rotate(-5deg);color:var(--mv-green)}
        .mvpf-l:nth-child(3n):hover{color:var(--mv-pink)}
        .mvpf-l:nth-child(3n+1):hover{color:var(--mv-tangerine)}
        .mvpf-link{transition:transform .16s,color .16s}
        @media(max-width:760px){.mvpf-link{min-height:44px;display:flex!important;align-items:center}.mvpf-cta{line-height:1.2}}
        .mvpf-link:hover{color:var(--mv-green);transform:translateX(6px) rotate(-1deg)}
        .mvpf-cta .mvpf-arrow{transition:transform .18s}
        .mvpf-cta:hover{color:var(--mv-pink)}
        .mvpf-cta:hover .mvpf-arrow{transform:translateX(10px)}
        .mvpf-bar{display:block;transition:transform .28s cubic-bezier(.3,1.4,.5,1)}
        .mvpf-flag:hover .mvpf-bar:nth-child(1){transform:translateX(-14%)}
        .mvpf-flag:hover .mvpf-bar:nth-child(2){transform:translateX(22%)}
        .mvpf-flag:hover .mvpf-bar:nth-child(3){transform:translateX(-8%)}
        @media(prefers-reduced-motion:reduce){.mvpf-track{animation:none}.mvpf-l,.mvpf-link,.mvpf-arrow,.mvpf-bar{transition:none}}
      `}</style>
    </footer>
  );
}
Object.assign(window, { FooterPlayful });
})();

(function(){
const LISTINGS = [
  { id: 1, type: 'Appartement', status: 'Te huur', statusColor: 'green', address: 'Oosterstraat 12, Groningen', title: 'Licht 2-kamer appartement in de Binnenstad', area: 68, rooms: 3, price: '€ 1.450', img: 'assets/interior-01.webp' },
  { id: 2, type: 'Studio', status: 'Nieuw', statusColor: 'pink', address: 'Hereweg 88, Groningen', title: 'Studio aan het Noorderplantsoen', area: 34, rooms: 1, price: '€ 895', img: 'assets/interior-05.webp' },
  { id: 3, type: 'Huis', status: 'Te huur', statusColor: 'green', address: 'Zuiderpark 5, Groningen', title: 'Karakteristiek herenhuis met tuin', area: 142, rooms: 5, beds: 3, price: '€ 2.650', img: 'assets/interior-06.webp' },
  { id: 4, type: 'Kamer', status: 'Te huur', statusColor: 'green', address: 'Nieuwe Ebbingestraat 40, Groningen', title: 'Ruime studentenkamer, gemeubileerd', area: 22, rooms: 1, price: '€ 640', img: 'assets/interior-04.webp' },
  { id: 5, type: 'Appartement', status: 'Verhuurd', statusColor: 'ink', address: 'Kwinkenplein 3, Groningen', title: 'Modern 3-kamer appartement, dakterras', area: 88, rooms: 4, beds: 2, price: '€ 1.895', img: 'assets/interior-02.webp' },
  { id: 6, type: 'Studio', status: 'Nieuw', statusColor: 'pink', address: 'Steentilstraat 21, Groningen', title: 'Compacte studio boven het café', area: 29, rooms: 1, price: '€ 780', img: 'assets/interior-03.webp' },
];

function App() {
  const [modal, setModal] = React.useState(false);
  React.useEffect(() => {
    if (window.matchMedia('(prefers-reduced-motion: reduce)').matches) return;
    const els = [...document.querySelectorAll('main > *:not(:first-child):not([data-pin])')];
    els.forEach((el) => el.classList.add('mvp-pre'));
    let raf = 0;
    const check = () => {
      raf = 0;
      const vh = window.innerHeight;
      for (const el of els) {
        if (el.classList.contains('mvp-in')) continue;
        const r = el.getBoundingClientRect();
        if (r.top < vh * 0.88 && r.bottom > 0) el.classList.add('mvp-in');
      }
    };
    const onScroll = () => { if (!raf) raf = requestAnimationFrame(check); };
    window.addEventListener('scroll', onScroll, { passive: true });
    check();
    return () => { window.removeEventListener('scroll', onScroll); if (raf) cancelAnimationFrame(raf); };
  }, []);
  return (
    <React.Fragment>
      <Loader />
      <HeaderPlayful onValuation={() => setModal(true)} />
      <main>
        <HeroPlayful onSearch={() => { const a = document.getElementById('aanbod'); if (a) window.scrollTo({ top: a.offsetTop - 70, behavior: 'smooth' }); }} />
        <FilmTakeover />
        <Listings listings={LISTINGS} num={2} total={5} />
        <StoryTakeover />
        <Buurten />
        <Zakelijk />
        <Impact />
      </main>
      <FooterPlayful />
      <ValuationModal open={modal} onClose={() => setModal(false)} />
    </React.Fragment>
  );
}
ReactDOM.createRoot(document.getElementById('root')).render(<App />);
})();
