/* global React */
const { useEffect: useEffectAbout, useRef: useRefAbout, useState: useStateAbout } = React;

/* ----------------------------------------------------------------- */
/*  ASPACE — About / Manifesto                                        */
/* ----------------------------------------------------------------- */

/* Typography reveal — staggered words with mask + blur */
function ManifestoLine({ children, idx = 0, size = 'xl' }) {
  const ref = useRefAbout(null);
  const [seen, setSeen] = useStateAbout(false);

  useEffectAbout(() => {
    if (!ref.current) return;
    const io = new IntersectionObserver(([e]) => { if (e.isIntersecting) setSeen(true); }, { threshold: 0.18 });
    io.observe(ref.current);
    return () => io.disconnect();
  }, []);

  const sizeMap = {
    xl:  'clamp(56px, 11vw, 200px)',
    lg:  'clamp(44px, 8vw, 140px)',
    md:  'clamp(32px, 5.5vw, 96px)',
    sm:  'clamp(24px, 3.6vw, 56px)',
  };

  return (
    <div ref={ref} style={{ overflow: 'hidden', lineHeight: 0.92 }}>
      <div style={{
        fontFamily: "'Inter Tight', sans-serif",
        fontWeight: 500,
        fontSize: sizeMap[size],
        letterSpacing: '-0.035em',
        color: '#0A0A0B',
        transform: seen ? 'translateY(0) scale(1)' : 'translateY(110%) scale(1.02)',
        filter: seen ? 'blur(0)' : 'blur(8px)',
        opacity: seen ? 1 : 0,
        transition: `transform 1100ms cubic-bezier(0.22,1,0.36,1) ${idx * 80}ms, filter 800ms ease ${idx * 80}ms, opacity 800ms ease ${idx * 80}ms`,
      }}>
        {children}
      </div>
    </div>
  );
}

/* Smaller fade-up paragraph */
function FadeUp({ children, delay = 0, style }) {
  const ref = useRefAbout(null);
  const [seen, setSeen] = useStateAbout(false);
  useEffectAbout(() => {
    if (!ref.current) return;
    const io = new IntersectionObserver(([e]) => { if (e.isIntersecting) setSeen(true); }, { threshold: 0.2 });
    io.observe(ref.current);
    return () => io.disconnect();
  }, []);
  return (
    <div ref={ref} style={{
      ...style,
      opacity: seen ? 1 : 0,
      transform: seen ? 'translateY(0)' : 'translateY(20px)',
      transition: `opacity 880ms ease ${delay}ms, transform 880ms cubic-bezier(0.22,1,0.36,1) ${delay}ms`,
    }}>{children}</div>
  );
}

/* Section eyebrow */
function Eyebrow({ idx, label }) {
  return (
    <div style={{
      display: 'flex', alignItems: 'center', gap: 14,
      fontSize: 11, letterSpacing: '0.18em', textTransform: 'uppercase',
      color: 'rgba(10,10,11,0.55)',
      marginBottom: 'clamp(28px, 4vw, 56px)',
    }}>
      <span style={{ width: 8, height: 8, border: '1.5px solid currentColor', borderRadius: '50%' }}/>
      <span>{idx}</span>
      <span style={{ width: 22, height: 1, background: 'currentColor', opacity: 0.6 }}/>
      <span>{label}</span>
    </div>
  );
}

/* ============================ HERO ============================== */
function HeroAbout() {
  const ref = useRefAbout(null);
  const [scroll, setScroll] = useStateAbout(0);
  useEffectAbout(() => {
    const onScroll = () => {
      if (!ref.current) return;
      const r = ref.current.getBoundingClientRect();
      setScroll(Math.max(0, Math.min(1, -r.top / r.height)));
    };
    window.addEventListener('scroll', onScroll, { passive: true });
    onScroll();
    return () => window.removeEventListener('scroll', onScroll);
  }, []);

  return (
    <section ref={ref} data-screen-label="About / Hero" data-aurora="hero" style={{
      position: 'relative',
      minHeight: '110vh',
      background: '#0A0A0B', color: '#fff',
      paddingTop: 'clamp(120px, 16vh, 180px)',
      paddingBottom: 'clamp(80px, 10vh, 140px)',
      overflow: 'hidden',
    }}>
      {/* Top bar info row */}
      <div style={{
        position: 'absolute', top: 'clamp(96px, 12vh, 130px)', left: 0, right: 0,
        padding: '0 clamp(20px, 5vw, 80px)',
        display: 'flex', justifyContent: 'space-between',
        fontSize: 11, letterSpacing: '0.18em', textTransform: 'uppercase',
        color: 'rgba(255,255,255,0.55)',
      }}>
        <span>About — A Manifesto</span>
        <span>Index 00 / 06</span>
      </div>

      {/* Massive type */}
      <div style={{
        padding: '0 clamp(20px, 5vw, 80px)',
        marginTop: 'clamp(60px, 10vh, 140px)',
        display: 'flex', flexDirection: 'column',
        gap: 'clamp(2px, 0.4vw, 10px)',
      }}>
        <div style={{ /* override line color to white via inline children */ }}>
          {[
            'WE BUILT',
            'ASPACE',
            'FOR CREATORS',
            'WHO NEEDED',
            'MORE ROOM',
            'TO BUILD.',
          ].map((line, i) => (
            <div key={i} style={{ overflow: 'hidden', lineHeight: 0.92 }}>
              <div style={{
                fontFamily: "'Inter Tight', sans-serif",
                fontWeight: 500,
                fontSize: 'clamp(56px, 11vw, 200px)',
                letterSpacing: '-0.035em',
                color: i === 5 ? 'var(--aspace-blue)' : '#fff',
                animation: `aboutHeroIn 1200ms cubic-bezier(0.22,1,0.36,1) ${200 + i * 90}ms backwards`,
              }}>{line}</div>
            </div>
          ))}
        </div>
      </div>

      {/* Bottom row */}
      <div style={{
        position: 'absolute', bottom: 'clamp(40px, 6vh, 80px)', left: 0, right: 0,
        padding: '0 clamp(20px, 5vw, 80px)',
        display: 'grid',
        gridTemplateColumns: 'minmax(0,1fr) minmax(0,1fr) auto',
        gap: 24,
        alignItems: 'end',
      }}>
        <div style={{ maxWidth: 380, fontSize: 14, lineHeight: 1.55, color: 'rgba(255,255,255,0.7)' }}>
          A 500m² creative base in Amsterdam-Duivendrecht. Private studios, production rooms and a community of independent makers. Built without the gatekeeping.
        </div>
        <div/>
        <div style={{
          fontSize: 11, letterSpacing: '0.18em', textTransform: 'uppercase',
          color: 'rgba(255,255,255,0.55)', textAlign: 'right',
        }}>
          Scroll to begin<br/>↓
        </div>
      </div>

      {/* Floating accent line */}
      <svg style={{
        position: 'absolute', right: '-6%', top: '20%',
        width: 420, height: 420,
        opacity: 0.4 + scroll * 0.3,
        transform: `rotate(${scroll * 30}deg)`,
        pointerEvents: 'none',
      }} viewBox="0 0 420 420" fill="none">
        <circle cx="210" cy="210" r="208" stroke="var(--aspace-blue)" strokeWidth="1" strokeDasharray="2 8"/>
        <circle cx="210" cy="210" r="140" stroke="var(--aspace-blue)" strokeWidth="1" opacity="0.5"/>
      </svg>

      <style>{`
        @keyframes aboutHeroIn {
          from { transform: translateY(110%) scale(1.02); filter: blur(10px); opacity: 0; }
          to   { transform: translateY(0) scale(1);     filter: blur(0);     opacity: 1; }
        }
      `}</style>
    </section>
  );
}

/* ====================== THE IDEA ============================== */
function IdeaSection() {
  const points = [
    { n: '01', t: 'Access over gatekeeping', d: 'Equipment, rooms and rates that don\'t require a production company behind you.' },
    { n: '02', t: 'A real space, not a desk', d: 'Lockable rooms, daylight, infrastructure. Not a hotdesk pretending to be something else.' },
    { n: '03', t: 'A creative ecosystem', d: 'Photographers next to designers next to filmmakers. Cross-pollination by proximity.' },
    { n: '04', t: 'Built to evolve', d: 'New tools, new rooms, new collaborations. ASPACE moves with the work.' },
  ];

  return (
    <section data-screen-label="About / Idea" style={{
      background: '#F4F2EC',
      padding: 'clamp(100px, 14vh, 200px) clamp(20px, 5vw, 80px)',
      position: 'relative',
    }}>
      <Eyebrow idx="01" label="The idea behind ASPACE"/>
      <div style={{
        display: 'grid',
        gridTemplateColumns: 'minmax(0, 1.2fr) minmax(0, 1fr)',
        gap: 'clamp(40px, 6vw, 120px)',
        alignItems: 'start',
      }} className="about-split">
        <div>
          <ManifestoLine idx={0}>NOT BUILT</ManifestoLine>
          <ManifestoLine idx={1}>FOR<span style={{ color: 'var(--aspace-blue)' }}>&nbsp;GATE</span>—</ManifestoLine>
          <ManifestoLine idx={2}>KEEPING.</ManifestoLine>
        </div>

        <div style={{ paddingTop: 'clamp(20px, 4vw, 60px)' }}>
          <FadeUp delay={300}>
            <p style={{
              fontFamily: "'Inter Tight',sans-serif",
              fontSize: 'clamp(18px, 1.4vw, 22px)', lineHeight: 1.5,
              letterSpacing: '-0.005em', color: '#0A0A0B',
              maxWidth: 460, marginBottom: 48,
            }}>
              Studios and production tools have been locked behind expensive day rates and friction for too long. We built ASPACE so independent makers can rent real space — by the month, with real keys, real tools, real freedom.
            </p>
          </FadeUp>

          <div style={{ display: 'grid', gap: 28 }}>
            {points.map((p, i) => (
              <FadeUp key={p.n} delay={400 + i * 120}>
                <div style={{
                  display: 'grid',
                  gridTemplateColumns: '60px 1fr',
                  gap: 20,
                  paddingTop: 20,
                  borderTop: '1px solid rgba(10,10,11,0.14)',
                }}>
                  <div style={{ fontSize: 11, letterSpacing: '0.18em', color: 'rgba(10,10,11,0.5)' }}>{p.n}</div>
                  <div>
                    <div style={{ fontFamily: "'Inter Tight',sans-serif", fontWeight: 500, fontSize: 18, letterSpacing: '-0.01em', marginBottom: 6 }}>{p.t}</div>
                    <div style={{ fontSize: 14, lineHeight: 1.55, color: 'rgba(10,10,11,0.65)', maxWidth: 380 }}>{p.d}</div>
                  </div>
                </div>
              </FadeUp>
            ))}
          </div>
        </div>
      </div>

      <style>{`
        @media (max-width: 900px) {
          .about-split { grid-template-columns: 1fr !important; }
        }
      `}</style>
    </section>
  );
}

/* ====================== ATMOSPHERE ============================== */
function AtmosphereSection() {
  const tiles = [
    { scene: 'northLight',  label: 'Daylight', size: 'tall',  offset: 0 },
    { scene: 'atelier',     label: 'Bench',    size: 'wide',  offset: 60 },
    { scene: 'motionLab',   label: 'LED',      size: 'sq',    offset: -40 },
    { scene: 'signalBooth', label: 'Treated',  size: 'tall',  offset: 30 },
    { scene: 'workshop',    label: 'Material', size: 'wide',  offset: -20 },
  ];
  return (
    <section data-screen-label="About / Atmosphere" style={{
      background: '#F4F2EC',
      padding: 'clamp(120px, 16vh, 220px) clamp(20px, 5vw, 80px)',
      position: 'relative',
    }}>
      <Eyebrow idx="02" label="Atmosphere"/>

      <div style={{ marginBottom: 'clamp(80px, 10vw, 140px)', maxWidth: 1400 }}>
        <ManifestoLine idx={0}>NO GATEKEEPING.</ManifestoLine>
        <ManifestoLine idx={1}>NO CORPORATE</ManifestoLine>
        <ManifestoLine idx={2}>ENERGY. JUST</ManifestoLine>
        <ManifestoLine idx={3}><span style={{ color: 'var(--aspace-blue)' }}>SPACE TO MAKE.</span></ManifestoLine>
      </div>

      {/* Editorial collage grid */}
      <div style={{
        display: 'grid',
        gridTemplateColumns: 'repeat(12, 1fr)',
        gap: 'clamp(14px, 1.6vw, 22px)',
        marginBottom: 'clamp(60px, 8vw, 120px)',
      }} className="atmo-collage">
        {tiles.map((t, i) => {
          const Scene = window.STUDIO_SCENES?.[t.scene];
          const span = t.size === 'tall' ? 'span 5' : t.size === 'wide' ? 'span 7' : 'span 4';
          const aspect = t.size === 'tall' ? '3/4' : t.size === 'wide' ? '16/10' : '1/1';
          return (
            <FadeUp key={i} delay={i * 100} style={{
              gridColumn: span,
              transform: `translateY(${t.offset}px)`,
            }}>
              <div className="atmo-tile" style={{
                position: 'relative',
                aspectRatio: aspect,
                background: '#0A0A0B',
                borderRadius: 'clamp(12px, 1.4vw, 20px)',
                overflow: 'hidden',
              }}>
                {Scene && <Scene blue="var(--aspace-blue)"/>}
                <div style={{
                  position: 'absolute', inset: 0,
                  background: 'linear-gradient(180deg, transparent 50%, rgba(0,0,0,0.4) 100%)',
                }}/>
                <div style={{
                  position: 'absolute', left: 16, bottom: 14,
                  fontSize: 10, letterSpacing: '0.18em', color: '#fff',
                  textTransform: 'uppercase',
                }}>{t.label}</div>
              </div>
            </FadeUp>
          );
        })}
      </div>

      {/* Audience callouts */}
      <div style={{ borderTop: '1px solid rgba(10,10,11,0.14)', paddingTop: 'clamp(60px, 8vw, 120px)' }}>
        <div style={{
          fontSize: 11, letterSpacing: '0.18em', textTransform: 'uppercase',
          color: 'rgba(10,10,11,0.55)', marginBottom: 36,
        }}>Built for</div>
        <div>
          {['PHOTOGRAPHERS.','DESIGNERS.','FILMMAKERS.','ARTISTS.','MAKERS BUILDING SOMETHING REAL.'].map((l, i) => (
            <ManifestoLine key={i} idx={i} size="lg">
              <span style={{ color: i === 4 ? 'var(--aspace-blue)' : '#0A0A0B' }}>{l}</span>
            </ManifestoLine>
          ))}
        </div>
      </div>

      <style>{`
        @media (max-width: 900px) {
          .atmo-collage > * { grid-column: span 12 !important; transform: none !important; }
        }
        .atmo-tile { transition: transform 800ms cubic-bezier(0.22,1,0.36,1); }
        .atmo-tile:hover { transform: scale(1.02); }
      `}</style>
    </section>
  );
}

/* ====================== ECOSYSTEM ============================== */
function EcosystemSection() {
  const items = [
    { label: 'Private studios',     w: 'PRIVATE',  d: 'Lockable rooms 14–24m². Monthly terms.' },
    { label: 'Photo studio',        w: 'PHOTO',    d: 'Daylight + strobes. Cyc available.' },
    { label: 'Video production',    w: 'VIDEO',    d: 'Treated rooms. Grip on hand.' },
    { label: 'LED wall',            w: 'LED',      d: 'Virtual production for shoots.' },
    { label: 'Podcast setup',       w: 'PODCAST',  d: 'Acoustic-treated voice booth.' },
    { label: 'Workshops & events',  w: 'EVENTS',   d: 'Up to 60. Lounge convertible.' },
    { label: 'XR / 3D / future',    w: 'FUTURE',   d: 'Experimental tooling, evolving.' },
  ];

  return (
    <section data-screen-label="About / Ecosystem" style={{
      background: '#F4F2EC',
      padding: 'clamp(100px, 14vh, 200px) clamp(20px, 5vw, 80px)',
      position: 'relative',
      borderTop: '1px solid rgba(10,10,11,0.10)',
    }}>
      <Eyebrow idx="03" label="The creative ecosystem"/>

      <div style={{ marginBottom: 'clamp(80px, 10vw, 140px)' }}>
        <ManifestoLine idx={0}>EVERYTHING</ManifestoLine>
        <ManifestoLine idx={1}>UNDER ONE</ManifestoLine>
        <ManifestoLine idx={2}>ROOF.</ManifestoLine>
      </div>

      <div style={{ display: 'flex', flexDirection: 'column' }}>
        {items.map((it, i) => (
          <FadeUp key={i} delay={i * 60}>
            <div className="eco-row" style={{
              display: 'grid',
              gridTemplateColumns: '60px minmax(0,1.6fr) minmax(0,1fr) 80px',
              gap: 24,
              alignItems: 'center',
              padding: 'clamp(28px, 3.4vw, 44px) 0',
              borderTop: '1px solid rgba(10,10,11,0.14)',
              borderBottom: i === items.length - 1 ? '1px solid rgba(10,10,11,0.14)' : 'none',
              cursor: 'default',
            }}>
              <div style={{ fontSize: 11, letterSpacing: '0.18em', color: 'rgba(10,10,11,0.5)' }}>0{i+1}</div>
              <div style={{
                fontFamily: "'Inter Tight',sans-serif",
                fontWeight: 500,
                fontSize: 'clamp(28px, 4vw, 56px)',
                letterSpacing: '-0.025em',
                lineHeight: 1,
              }}>
                <span className="eco-label">{it.label}</span>
              </div>
              <div style={{ fontSize: 14, color: 'rgba(10,10,11,0.6)', lineHeight: 1.5 }}>{it.d}</div>
              <div style={{ textAlign: 'right', fontSize: 10, letterSpacing: '0.2em', color: 'rgba(10,10,11,0.45)' }}>
                {it.w}
              </div>
            </div>
          </FadeUp>
        ))}
      </div>

      <style>{`
        .eco-row .eco-label {
          background: linear-gradient(var(--aspace-blue), var(--aspace-blue)) no-repeat;
          background-size: 0% 6px;
          background-position: 0 100%;
          padding-bottom: 4px;
          transition: background-size 600ms cubic-bezier(0.22,1,0.36,1);
        }
        .eco-row:hover .eco-label { background-size: 100% 6px; }
        @media (max-width: 760px) {
          .eco-row { grid-template-columns: 40px 1fr !important; }
          .eco-row > :nth-child(3), .eco-row > :nth-child(4) { display: none; }
        }
      `}</style>
    </section>
  );
}

/* ============================================================== */
/*  SPATIAL ARRIVAL — custom cinematic SVG map of ASPACE / Amsterdam */
/*                                                                   */
/*  Replaces the previous utility map with a hand-crafted graphite   */
/*  composition: stylised river Amstel + canals + street grid,       */
/*  topographic contours around ASPACE, a single bright beacon, an   */
/*  animated route line drawn in on entry, four floating glass info  */
/*  chips, and a cursor-reactive blue haze. No third-party tiles —   */
/*  fully self-contained and theme-controlled.                       */
/* ============================================================== */

function SpatialArrival({ blue }) {
  const wrap = useRefAbout(null);
  const haze = useRefAbout(null);
  const [drawn, setDrawn] = useStateAbout(false);

  // ASPACE + station coords inside the 1600×800 viewBox
  const ASPACE  = { x: 980, y: 380 };
  const STATION = { x: 280, y: 620 };

  // Route line length used for the draw-on animation. Approximate path length
  // is well below 1600 — a flat 1600 dasharray comfortably hides it.
  const ROUTE_LEN = 1600;

  // Cursor-reactive blue haze: lerp toward target each frame for a soft drift.
  useEffectAbout(() => {
    const el = wrap.current;
    if (!el || !haze.current) return;
    const reduced = window.matchMedia('(prefers-reduced-motion: reduce)').matches;
    if (reduced) return;

    let tx = 50, ty = 45, x = tx, y = ty;
    let raf;
    const onMove = (e) => {
      const r = el.getBoundingClientRect();
      tx = ((e.clientX - r.left) / r.width)  * 100;
      ty = ((e.clientY - r.top)  / r.height) * 100;
    };
    const onLeave = () => { tx = 50; ty = 45; };
    const tick = () => {
      x += (tx - x) * 0.05;
      y += (ty - y) * 0.05;
      if (haze.current) {
        haze.current.style.background =
          `radial-gradient(38% 34% at ${x.toFixed(2)}% ${y.toFixed(2)}%, rgba(0,194,255,0.18) 0%, rgba(140,180,255,0.06) 38%, transparent 72%)`;
      }
      raf = requestAnimationFrame(tick);
    };
    el.addEventListener('mousemove', onMove);
    el.addEventListener('mouseleave', onLeave);
    raf = requestAnimationFrame(tick);
    return () => {
      cancelAnimationFrame(raf);
      el.removeEventListener('mousemove', onMove);
      el.removeEventListener('mouseleave', onLeave);
    };
  }, []);

  // Trigger the route line draw the first time the map enters the viewport.
  useEffectAbout(() => {
    const el = wrap.current;
    if (!el) return;
    const obs = new IntersectionObserver(([e]) => {
      if (e.isIntersecting) {
        const t = setTimeout(() => setDrawn(true), 280);
        obs.disconnect();
        return () => clearTimeout(t);
      }
    }, { threshold: 0.25 });
    obs.observe(el);
    return () => obs.disconnect();
  }, []);

  // Subtle non-literal hotspots — creative neighbours, not Google Pins.
  const HOTSPOTS = [
    { x: 420,  y: 290, label: 'CAFÉ · PLANTAGE' },
    { x: 740,  y: 180, label: 'GALLERY · NDSM' },
    { x: 1280, y: 250, label: 'STUDIO · OOST' },
    { x: 1100, y: 600, label: 'CANAL · SINGELGRACHT' },
  ];

  const aspaceLabelLeftPct = (ASPACE.x / 1600) * 100;
  const aspaceLabelTopPct  = (ASPACE.y / 800)  * 100;

  return (
    <div ref={wrap} data-aurora="map" className="sp-arrival" style={{
      position: 'relative',
      borderRadius: 'clamp(14px, 1.6vw, 22px)',
      overflow: 'hidden',
      background: '#0B0C10',
      aspectRatio: '21/9',
      isolation: 'isolate',
    }}>
      {/* Base graphite gradient with depth */}
      <div aria-hidden="true" style={{
        position: 'absolute', inset: 0, zIndex: 0,
        background: 'radial-gradient(72% 78% at 60% 40%, #161922 0%, #0A0C12 65%, #06070A 100%)',
      }}/>

      <svg viewBox="0 0 1600 800" preserveAspectRatio="xMidYMid slice"
        style={{ position: 'absolute', inset: 0, width: '100%', height: '100%', display: 'block', zIndex: 1 }}>
        <defs>
          {/* Subtle film noise — adds spatial depth without reading as VFX */}
          <filter id="sp-noise">
            <feTurbulence type="fractalNoise" baseFrequency="0.9" numOctaves="2" seed="7"/>
            <feColorMatrix values="0 0 0 0 0.55  0 0 0 0 0.62  0 0 0 0 0.78  0 0 0 0.18 0"/>
            <feComposite in2="SourceGraphic" operator="in"/>
          </filter>

          {/* Architectural grid */}
          <pattern id="sp-grid" width="64" height="64" patternUnits="userSpaceOnUse">
            <path d="M 64 0 L 0 0 0 64" stroke="rgba(255,255,255,0.030)" strokeWidth="1" fill="none"/>
          </pattern>
          <pattern id="sp-grid-fine" width="16" height="16" patternUnits="userSpaceOnUse">
            <path d="M 16 0 L 0 0 0 16" stroke="rgba(255,255,255,0.013)" strokeWidth="0.5" fill="none"/>
          </pattern>

          {/* Soft glow used for beacon + route */}
          <filter id="sp-glow" x="-50%" y="-50%" width="200%" height="200%">
            <feGaussianBlur stdDeviation="6"/>
          </filter>

          {/* Route gradient — fades in from the station, brightens near ASPACE */}
          <linearGradient id="sp-route" x1="0" y1="0" x2="1" y2="0">
            <stop offset="0%"  stopColor={blue} stopOpacity="0.20"/>
            <stop offset="50%" stopColor={blue} stopOpacity="0.85"/>
            <stop offset="100%" stopColor={blue} stopOpacity="0.95"/>
          </linearGradient>

          {/* Radial vignette around edges — pulls focus inward */}
          <radialGradient id="sp-vignette" cx="50%" cy="50%" r="62%">
            <stop offset="60%"  stopColor="rgba(0,0,0,0)"/>
            <stop offset="100%" stopColor="rgba(0,0,0,0.55)"/>
          </radialGradient>
        </defs>

        {/* Grids */}
        <rect width="1600" height="800" fill="url(#sp-grid-fine)"/>
        <rect width="1600" height="800" fill="url(#sp-grid)"/>

        {/* Topographic contours around ASPACE — architectural detail */}
        {[80, 140, 210, 290, 380, 480].map((r, i) => (
          <circle key={i} cx={ASPACE.x} cy={ASPACE.y} r={r}
            fill="none"
            stroke="rgba(255,255,255,0.045)"
            strokeWidth="0.5"
            strokeDasharray={i % 2 === 0 ? "2 6" : ""}/>
        ))}

        {/* River Amstel — wide soft band, twin-stroked for depth */}
        <path d="M -100,720 C 280,640 540,560 760,500 C 980,440 1240,360 1700,260"
          stroke="rgba(70,100,140,0.10)" strokeWidth="62" fill="none" strokeLinecap="round"/>
        <path d="M -100,720 C 280,640 540,560 760,500 C 980,440 1240,360 1700,260"
          stroke="rgba(120,160,200,0.16)" strokeWidth="20" fill="none" strokeLinecap="round"/>

        {/* Canals — gentle horizontals */}
        <path d="M 100,140 C 460,140 920,160 1500,150" stroke="rgba(255,255,255,0.060)" strokeWidth="2"  fill="none"/>
        <path d="M  60,260 C 460,250 920,270 1540,260" stroke="rgba(255,255,255,0.050)" strokeWidth="2"  fill="none"/>
        <path d="M  50,380 C 420,376 880,390 1560,380" stroke="rgba(255,255,255,0.040)" strokeWidth="1.6" fill="none"/>

        {/* Main streets — slightly brighter */}
        <path d="M 240,0  C 280,260 240,580 320,800" stroke="rgba(255,255,255,0.10)" strokeWidth="1.6" fill="none"/>
        <path d="M 720,0  L 740,800"                  stroke="rgba(255,255,255,0.08)" strokeWidth="1.4" fill="none"/>
        <path d="M 1180,0 C 1140,200 1240,500 1200,800" stroke="rgba(255,255,255,0.08)" strokeWidth="1.4" fill="none"/>
        <path d="M 0,460 L 1600,440" stroke="rgba(255,255,255,0.07)" strokeWidth="1.2" fill="none"/>

        {/* Animated route — Amsterdam Amstel → ASPACE */}
        {/* Glow underlay */}
        <path
          d={`M ${STATION.x},${STATION.y} C ${STATION.x + 220},${STATION.y - 80} ${ASPACE.x - 280},${ASPACE.y + 60} ${ASPACE.x},${ASPACE.y}`}
          stroke={blue} strokeWidth="6" fill="none" strokeLinecap="round"
          opacity="0.20" filter="url(#sp-glow)"
          style={{
            strokeDasharray: ROUTE_LEN,
            strokeDashoffset: drawn ? 0 : ROUTE_LEN,
            transition: 'stroke-dashoffset 4800ms cubic-bezier(0.22,1,0.36,1)',
          }}/>
        {/* Crisp line */}
        <path
          d={`M ${STATION.x},${STATION.y} C ${STATION.x + 220},${STATION.y - 80} ${ASPACE.x - 280},${ASPACE.y + 60} ${ASPACE.x},${ASPACE.y}`}
          stroke="url(#sp-route)" strokeWidth="1.5" fill="none" strokeLinecap="round"
          style={{
            strokeDasharray: ROUTE_LEN,
            strokeDashoffset: drawn ? 0 : ROUTE_LEN,
            transition: 'stroke-dashoffset 4800ms cubic-bezier(0.22,1,0.36,1)',
          }}/>

        {/* Editorial route label, midway above the line */}
        <text
          x={(STATION.x + ASPACE.x) / 2 - 110}
          y={(STATION.y + ASPACE.y) / 2 - 58}
          fill="rgba(255,255,255,0.55)" fontSize="10" letterSpacing="2.6"
          fontFamily="'Inter Tight', sans-serif"
          opacity={drawn ? 1 : 0}
          style={{ transition: 'opacity 1200ms ease 2400ms' }}>
          8 MIN FROM AMSTERDAM AMSTEL
        </text>

        {/* Amstel station marker — quiet, secondary */}
        <g transform={`translate(${STATION.x},${STATION.y})`}>
          <circle r="14" fill="none" stroke="rgba(255,255,255,0.30)" strokeWidth="1"/>
          <circle r="3"  fill="rgba(255,255,255,0.75)"/>
          <text x="22" y="5" fill="rgba(255,255,255,0.55)" fontSize="11" letterSpacing="3"
            fontFamily="'Inter Tight', sans-serif">AMSTEL STATION</text>
        </g>

        {/* Hotspots — quiet pin pairs, label appears via SVG <title> on hover */}
        {HOTSPOTS.map((h, i) => (
          <g key={i} transform={`translate(${h.x},${h.y})`} className="sp-hotspot">
            <circle r="14" fill="none" stroke="rgba(255,255,255,0.10)" strokeWidth="0.5" className="sp-hotspot-ring"/>
            <circle r="3"  fill="rgba(255,255,255,0.40)" className="sp-hotspot-dot"/>
            <text x="20" y="4" fill="rgba(255,255,255,0.0)" fontSize="9" letterSpacing="2.4"
              fontFamily="'Inter Tight', sans-serif" className="sp-hotspot-label">{h.label}</text>
          </g>
        ))}

        {/* ASPACE BEACON — the only bright thing in the composition */}
        <g transform={`translate(${ASPACE.x},${ASPACE.y})`}>
          {/* Outer atmospheric bloom */}
          <circle r="220" fill={blue} opacity="0.04" filter="url(#sp-glow)"/>
          <circle r="120" fill={blue} opacity="0.07" filter="url(#sp-glow)"/>
          <circle r="56"  fill={blue} opacity="0.10"/>
          {/* Architectural concentric rings */}
          <circle r="48" fill="none" stroke={blue} strokeWidth="0.6" opacity="0.32"/>
          <circle r="32" fill="none" stroke={blue} strokeWidth="0.6" opacity="0.45"/>
          <circle r="20" fill="none" stroke={blue} strokeWidth="0.6" opacity="0.60"/>
          {/* Slow pulse — single ring expanding then fading */}
          <circle r="20" fill="none" stroke={blue} strokeWidth="0.8">
            <animate attributeName="r" values="18;78;78" dur="3.6s" repeatCount="indefinite" calcMode="spline" keySplines="0.22 1 0.36 1; 0 0 1 1"/>
            <animate attributeName="opacity" values="0.55;0;0" dur="3.6s" repeatCount="indefinite"/>
          </circle>
          {/* Core */}
          <circle r="4.5" fill="#fff"/>
          <circle r="2.4" fill={blue}/>
        </g>

        {/* Vignette pulls focus toward the centre */}
        <rect width="1600" height="800" fill="url(#sp-vignette)" pointerEvents="none"/>

        {/* Film noise — composited last for organic surface */}
        <rect width="1600" height="800" filter="url(#sp-noise)" opacity="0.45"/>
      </svg>

      {/* Cursor-reactive blue haze layer — soft, mix-blend screen so it only adds light */}
      <div ref={haze} aria-hidden="true" style={{
        position: 'absolute', inset: 0,
        pointerEvents: 'none',
        mixBlendMode: 'screen',
        zIndex: 2,
      }}/>

      {/* ASPACE glass label — overlay HTML for crisp text */}
      <div className="sp-aspace-label" style={{
        position: 'absolute',
        left: `calc(${aspaceLabelLeftPct}% + 38px)`,
        top:  `calc(${aspaceLabelTopPct}% - 18px)`,
        transform: 'translateY(-100%)',
        zIndex: 3,
        pointerEvents: 'none',
      }}>
        <div style={{
          display: 'inline-flex', flexDirection: 'column',
          padding: '8px 14px',
          background: 'rgba(20,22,28,0.50)',
          backdropFilter: 'blur(16px) saturate(140%)',
          WebkitBackdropFilter: 'blur(16px) saturate(140%)',
          border: '1px solid rgba(255,255,255,0.16)',
          borderRadius: 10,
          boxShadow: '0 1px 0 rgba(255,255,255,0.10) inset, 0 12px 32px -16px rgba(0,0,0,0.55), 0 0 28px rgba(0,194,255,0.10)',
        }}>
          <span style={{
            fontFamily: "'Inter Tight', sans-serif",
            fontSize: 9.5, letterSpacing: '0.22em', textTransform: 'uppercase',
            color: 'rgba(255,255,255,0.55)',
          }}>You are arriving</span>
          <span style={{
            fontFamily: "'Inter Tight', sans-serif",
            fontWeight: 500, fontSize: 13.5, letterSpacing: '-0.005em',
            color: '#fff', marginTop: 2,
          }}>ASPACE — Joop Geesinkweg 306</span>
        </div>
      </div>

      {/* Floating glass info chips */}
      <SpatialChip label="24/7 access"        detail="Always open"               style={{ top: '6%',  left: '4%' }}      delay={520}  blue={blue}/>
      <SpatialChip label="Tram + Metro"       detail="5 min walk to Amstel"      style={{ top: '6%',  right: '4%' }}     delay={640}  blue={blue} className="sp-chip-tablet"/>
      <SpatialChip label="Creative district"  detail="40+ studios within 1 km"   style={{ bottom: '8%', left: '4%' }}    delay={760}  blue={blue} className="sp-chip-tablet"/>
      <SpatialChip label="Sound-friendly"     detail="Treated rooms, no permits" style={{ bottom: '8%', right: '4%' }}   delay={880}  blue={blue}/>

      {/* Coordinate badge — bottom centre, micro editorial */}
      <div style={{
        position: 'absolute', left: '50%', bottom: 18, transform: 'translateX(-50%)',
        zIndex: 3, pointerEvents: 'none',
        fontFamily: "'Inter Tight', sans-serif",
        fontSize: 9.5, letterSpacing: '0.28em', textTransform: 'uppercase',
        color: 'rgba(255,255,255,0.32)',
      }}>52.31° N · 4.93° E · OOST · AMSTERDAM</div>

      <style>{`
        .sp-hotspot .sp-hotspot-ring,
        .sp-hotspot .sp-hotspot-dot,
        .sp-hotspot .sp-hotspot-label { transition: all 520ms cubic-bezier(0.22,1,0.36,1); }
        .sp-hotspot:hover .sp-hotspot-ring { stroke: rgba(255,255,255,0.30); r: 18; }
        .sp-hotspot:hover .sp-hotspot-dot  { fill: rgba(255,255,255,0.85); r: 4; }
        .sp-hotspot:hover .sp-hotspot-label{ fill: rgba(255,255,255,0.78); }

        @media (max-width: 900px) {
          .sp-arrival { aspect-ratio: 4 / 5 !important; }
          .sp-aspace-label { left: 50% !important; top: 50% !important; transform: translate(-50%, -180%) !important; }
          .sp-chip-tablet { display: none !important; }
        }
      `}</style>
    </div>
  );
}

function SpatialChip({ label, detail, style, delay, blue, className = '' }) {
  const [hover, setHover] = useStateAbout(false);
  const [shown, setShown] = useStateAbout(false);
  useEffectAbout(() => {
    const t = setTimeout(() => setShown(true), delay);
    return () => clearTimeout(t);
  }, [delay]);
  return (
    <div
      onMouseEnter={() => setHover(true)}
      onMouseLeave={() => setHover(false)}
      className={className}
      style={{
        position: 'absolute', ...style, zIndex: 4,
        opacity: shown ? 1 : 0,
        transform: shown ? 'translateY(0)' : 'translateY(8px)',
        transition: 'opacity 800ms cubic-bezier(0.22,1,0.36,1), transform 800ms cubic-bezier(0.22,1,0.36,1)',
      }}
    >
      <div style={{
        display: 'inline-flex', flexDirection: 'column', gap: 4,
        padding: '10px 14px',
        background: hover
          ? 'linear-gradient(180deg, rgba(28,30,38,0.66) 0%, rgba(14,14,16,0.50) 100%)'
          : 'linear-gradient(180deg, rgba(20,22,28,0.50) 0%, rgba(10,10,11,0.40) 100%)',
        backdropFilter: 'blur(16px) saturate(140%)',
        WebkitBackdropFilter: 'blur(16px) saturate(140%)',
        border: hover ? '1px solid rgba(255,255,255,0.20)' : '1px solid rgba(255,255,255,0.10)',
        borderRadius: 10,
        boxShadow: hover
          ? '0 1px 0 rgba(255,255,255,0.12) inset, 0 16px 32px -16px rgba(0,0,0,0.55), 0 0 30px rgba(0,194,255,0.10)'
          : '0 1px 0 rgba(255,255,255,0.08) inset, 0 10px 24px -14px rgba(0,0,0,0.45)',
        transform: hover ? 'translateY(-2px)' : 'translateY(0)',
        transition: 'transform 420ms cubic-bezier(0.22,1,0.36,1), box-shadow 420ms ease, border-color 420ms ease, background 420ms ease',
        cursor: 'default',
      }}>
        <span style={{
          fontFamily: "'Inter Tight', sans-serif",
          fontSize: 9.5, letterSpacing: '0.22em', textTransform: 'uppercase',
          color: 'rgba(255,255,255,0.55)',
          display: 'inline-flex', alignItems: 'center', gap: 8,
        }}>
          <span style={{
            width: 4, height: 4, borderRadius: '50%', background: blue,
            boxShadow: hover ? `0 0 10px ${blue}` : 'none',
            transition: 'box-shadow 320ms ease',
          }}/>
          {label}
        </span>
        <span style={{
          fontFamily: "'Inter Tight', sans-serif",
          fontSize: 12.5, color: '#fff', letterSpacing: '-0.003em',
          opacity: hover ? 1 : 0.78,
          transition: 'opacity 420ms ease',
        }}>{detail}</span>
      </div>
    </div>
  );
}

/* ====================== AMSTERDAM ============================== */
function AmsterdamSection() {
  return (
    <section data-screen-label="About / Amsterdam" style={{
      background: '#F4F2EC',
      padding: 'clamp(120px, 16vh, 220px) clamp(20px, 5vw, 80px)',
      borderTop: '1px solid rgba(10,10,11,0.10)',
      position: 'relative',
    }}>
      <Eyebrow idx="04" label="Locale"/>

      <div style={{
        display: 'grid',
        gridTemplateColumns: 'minmax(0, 1.4fr) minmax(0, 1fr)',
        gap: 'clamp(40px, 6vw, 120px)',
        alignItems: 'end',
      }} className="ams-split">
        <div>
          <ManifestoLine idx={0} size="lg">AMSTERDAM</ManifestoLine>
          <ManifestoLine idx={1} size="lg">WITHOUT</ManifestoLine>
          <ManifestoLine idx={2} size="lg">THE <span style={{ color: 'var(--aspace-blue)' }}>FILTER.</span></ManifestoLine>
        </div>

        <FadeUp delay={300}>
          <div style={{ paddingBottom: 'clamp(20px, 3vw, 40px)' }}>
            <p style={{
              fontFamily: "'Inter Tight',sans-serif",
              fontSize: 'clamp(18px, 1.4vw, 22px)', lineHeight: 1.5,
              color: '#0A0A0B', maxWidth: 440, marginBottom: 36,
            }}>
              We chose Duivendrecht on purpose. Five minutes from Amsterdam Centraal, away from the polished tourist core, in the middle of where people actually make things — warehouses, studios, fabrication.
            </p>
            <div style={{ display: 'grid', gap: 18, fontSize: 14, color: 'rgba(10,10,11,0.7)', lineHeight: 1.6 }}>
              <div style={{ paddingTop: 14, borderTop: '1px solid rgba(10,10,11,0.14)' }}>
                <div style={{ fontSize: 10, letterSpacing: '0.18em', color: 'rgba(10,10,11,0.5)', textTransform: 'uppercase', marginBottom: 6 }}>Address</div>
                Joop Geesinkweg 306<br/>1114 AB Amsterdam-Duivendrecht
              </div>
              <div style={{ paddingTop: 14, borderTop: '1px solid rgba(10,10,11,0.14)' }}>
                <div style={{ fontSize: 10, letterSpacing: '0.18em', color: 'rgba(10,10,11,0.5)', textTransform: 'uppercase', marginBottom: 6 }}>Reach</div>
                5 min to Centraal · A2 / A10 access · Bike lanes from De Pijp
              </div>
            </div>
          </div>
        </FadeUp>
      </div>

      {/* Spatial arrival experience — replaces the utility map */}
      <FadeUp delay={400} style={{ marginTop: 'clamp(60px, 8vw, 100px)' }}>
        <SpatialArrival blue="#00C2FF"/>
      </FadeUp>

      <style>{`
        @media (max-width: 900px) { .ams-split { grid-template-columns: 1fr !important; } }
      `}</style>
    </section>
  );
}

/* ====================== FUTURE / DARK ============================== */
function FutureSection() {
  const ref = useRefAbout(null);
  const [scroll, setScroll] = useStateAbout(0);
  useEffectAbout(() => {
    const onScroll = () => {
      if (!ref.current) return;
      const r = ref.current.getBoundingClientRect();
      const vh = window.innerHeight;
      setScroll(Math.max(0, Math.min(1, (vh - r.top) / (vh + r.height))));
    };
    window.addEventListener('scroll', onScroll, { passive: true });
    onScroll();
    return () => window.removeEventListener('scroll', onScroll);
  }, []);

  return (
    <section ref={ref} data-screen-label="About / Future" style={{
      background: '#0A0A0B', color: '#fff',
      padding: 'clamp(140px, 18vh, 240px) clamp(20px, 5vw, 80px)',
      position: 'relative',
      overflow: 'hidden',
    }}>
      {/* ambient blue field */}
      <div style={{
        position: 'absolute', inset: 0,
        background: `radial-gradient(circle at ${30 + scroll * 30}% ${50 + scroll * 20}%, var(--aspace-blue), transparent 55%)`,
        opacity: 0.10 + scroll * 0.08,
        filter: 'blur(60px)',
        pointerEvents: 'none',
      }}/>

      <div style={{
        position: 'relative', zIndex: 1,
        display: 'flex', justifyContent: 'space-between',
        alignItems: 'center', marginBottom: 'clamp(60px, 8vw, 100px)',
        fontSize: 11, letterSpacing: '0.18em', textTransform: 'uppercase',
        color: 'rgba(255,255,255,0.55)',
      }}>
        <span>05 — Forward</span>
        <span>The future is in the room</span>
      </div>

      <div style={{ position: 'relative', zIndex: 1 }}>
        {['THIS IS','ONLY THE','BEGINNING.'].map((line, i) => (
          <div key={i} style={{ overflow: 'hidden', lineHeight: 0.92 }}>
            <div style={{
              fontFamily: "'Inter Tight', sans-serif",
              fontWeight: 500,
              fontSize: 'clamp(56px, 12vw, 220px)',
              letterSpacing: '-0.035em',
              color: i === 2 ? 'var(--aspace-blue)' : '#fff',
              transform: `translateY(${(1 - Math.min(1, scroll * 1.6 - i * 0.08)) * 100}%) scale(${1 + (1 - Math.min(1, scroll * 1.6)) * 0.02})`,
              filter: `blur(${(1 - Math.min(1, scroll * 1.6 - i * 0.08)) * 8}px)`,
              transition: 'none',
            }}>{line}</div>
          </div>
        ))}
      </div>

      <div style={{
        position: 'relative', zIndex: 1,
        marginTop: 'clamp(80px, 10vw, 140px)',
        display: 'grid',
        gridTemplateColumns: 'repeat(auto-fit, minmax(240px, 1fr))',
        gap: 'clamp(20px, 2.4vw, 40px)',
      }}>
        {[
          { t: 'Immersive production', d: 'LED virtual sets, motion capture and XR pipelines arriving as the work demands them.' },
          { t: 'Tools shared', d: 'Equipment libraries and shared rigs so independent makers don\'t buy what they only need sometimes.' },
          { t: 'Programming', d: 'Workshops, residencies and crits run by the people working here. Not a top-down curriculum.' },
          { t: 'Open ecosystem', d: 'Collaboration with studios, labels and brands across Amsterdam and beyond.' },
        ].map((c, i) => (
          <FadeUp key={i} delay={i * 100}>
            <div style={{ paddingTop: 22, borderTop: '1px solid rgba(255,255,255,0.18)' }}>
              <div style={{ fontSize: 10, letterSpacing: '0.18em', color: 'var(--aspace-blue)', marginBottom: 16 }}>0{i+1}</div>
              <div style={{ fontFamily: "'Inter Tight',sans-serif", fontWeight: 500, fontSize: 22, letterSpacing: '-0.01em', marginBottom: 12 }}>{c.t}</div>
              <div style={{ fontSize: 14, lineHeight: 1.6, color: 'rgba(255,255,255,0.65)' }}>{c.d}</div>
            </div>
          </FadeUp>
        ))}
      </div>
    </section>
  );
}

/* ====================== FINAL CTA ============================== */
function FinalCtaAbout() {
  return (
    <section data-screen-label="About / Final CTA" style={{
      background: '#F4F2EC',
      padding: 'clamp(140px, 18vh, 240px) clamp(20px, 5vw, 80px) clamp(80px, 10vh, 140px)',
      position: 'relative',
      overflow: 'hidden',
    }}>
      <Eyebrow idx="06" label="Enter ASPACE"/>

      <div style={{ marginBottom: 'clamp(60px, 8vw, 120px)' }}>
        <ManifestoLine idx={0}>READY TO</ManifestoLine>
        <ManifestoLine idx={1}>BUILD</ManifestoLine>
        <ManifestoLine idx={2}>SOMETHING</ManifestoLine>
        <ManifestoLine idx={3}><span style={{ color: 'var(--aspace-blue)' }}>BIGGER?</span></ManifestoLine>
      </div>

      <FadeUp delay={400}>
        <div style={{
          display: 'flex', flexWrap: 'wrap', gap: 16,
          alignItems: 'center',
        }}>
          <a href="#contact" data-open-contact className="cta-pill cta-dark">
            <span>Book a viewing</span>
            <span className="cta-arrow">
              <svg width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2"><path d="M7 17L17 7M9 7h8v8"/></svg>
            </span>
          </a>
          <a href="#contact" data-open-contact className="cta-pill cta-light">
            <span>Start your project</span>
            <span className="cta-arrow">
              <svg width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2"><path d="M5 12h14M13 6l6 6-6 6"/></svg>
            </span>
          </a>
        </div>
      </FadeUp>

      {/* Watermark */}
      <div aria-hidden="true" style={{
        position: 'absolute',
        left: '-2%', right: '-2%', bottom: '-12%',
        fontFamily: "'Inter Tight',sans-serif",
        fontWeight: 600,
        fontSize: 'clamp(160px, 28vw, 520px)',
        letterSpacing: '-0.05em',
        lineHeight: 0.85,
        color: 'rgba(10,10,11,0.05)',
        pointerEvents: 'none',
        userSelect: 'none',
      }}>ASPACE</div>

      <style>{`
        .cta-pill {
          display: inline-flex; align-items: center; gap: 14px;
          padding: 14px 14px 14px 26px;
          border-radius: 999px;
          font-family: 'Inter Tight', sans-serif;
          font-weight: 500;
          font-size: 15px;
          text-decoration: none;
          transition: transform 360ms cubic-bezier(0.22,1.2,0.36,1), background 320ms ease, color 320ms ease;
          cursor: pointer;
        }
        .cta-pill:hover { transform: translateY(-2px); }
        .cta-pill .cta-arrow {
          width: 36px; height: 36px; border-radius: 50%;
          display: inline-flex; align-items: center; justify-content: center;
          transition: transform 360ms cubic-bezier(0.22,1.2,0.36,1);
        }
        .cta-pill:hover .cta-arrow { transform: rotate(-45deg); }
        .cta-dark { background: #0A0A0B; color: #fff; }
        .cta-dark .cta-arrow { background: var(--aspace-blue); color: #000; }
        .cta-light { background: transparent; color: #0A0A0B; border: 1px solid rgba(10,10,11,0.18); }
        .cta-light .cta-arrow { background: #0A0A0B; color: #fff; }
      `}</style>
    </section>
  );
}

/* ============================================================== */
/*  TCL SIGNATURE — hidden studio credit, bottom-right of footer     */
/*                                                                   */
/*  Default state is nearly invisible (opacity ~0.42). On hover the   */
/*  primary line sharpens, an underline slides in, a faint blue       */
/*  atmospheric bloom appears behind, and the secondary line          */
/*  ("The Creativity Lab — Amsterdam") softly reveals via opacity +   */
/*  blur unblur. Restraint is the brief: it should reward attention,  */
/*  not demand it.                                                    */
/* ============================================================== */

function TCLSignature() {
  const [hover, setHover] = useStateAbout(false);
  return (
    <a
      href="https://thecreativitylab.studio"
      target="_blank" rel="noreferrer noopener"
      onMouseEnter={() => setHover(true)}
      onMouseLeave={() => setHover(false)}
      onFocus={() => setHover(true)}
      onBlur={() => setHover(false)}
      aria-label="Spatial experience designed by The Creativity Lab — Amsterdam"
      style={{
        position: 'relative',
        display: 'inline-flex', flexDirection: 'column', alignItems: 'flex-end',
        gap: 6,
        textDecoration: 'none', cursor: 'pointer',
        padding: '4px 0',
        outline: 'none',
      }}
    >
      {/* Atmospheric blue bloom — light through glass, only on hover */}
      <span aria-hidden="true" style={{
        position: 'absolute',
        right: -36, top: '50%',
        width: 240, height: 90,
        transform: 'translateY(-50%)',
        pointerEvents: 'none',
        background: 'radial-gradient(58% 58% at 70% 50%, rgba(0,194,255,0.16) 0%, rgba(120,160,255,0.06) 40%, transparent 72%)',
        opacity: hover ? 1 : 0,
        filter: 'blur(8px)',
        transition: 'opacity 760ms cubic-bezier(0.22,1,0.36,1)',
        zIndex: 0,
      }}/>

      {/* Primary line — always visible at low opacity */}
      <span style={{
        position: 'relative',
        fontFamily: "'Inter Tight', sans-serif",
        fontSize: 10,
        letterSpacing: '0.22em',
        textTransform: 'uppercase',
        color: 'rgba(255,255,255,0.92)',
        opacity: hover ? 0.94 : 0.42,
        // Sub-pixel blur on rest creates the "nearly hidden" softness without
        // breaking text rendering when sharp. 0.18px is just enough to feel
        // discovered, not announced.
        filter: hover ? 'blur(0)' : 'blur(0.18px)',
        transition: 'opacity 720ms cubic-bezier(0.22,1,0.36,1), filter 720ms cubic-bezier(0.22,1,0.36,1)',
        zIndex: 1,
      }}>
        Spatial experience by TCL®
        {/* Hairline underline — slides in from left */}
        <span aria-hidden="true" style={{
          position: 'absolute', left: 0, bottom: -3,
          height: 1, background: 'rgba(255,255,255,0.55)',
          width: hover ? '100%' : '0%',
          transition: 'width 760ms cubic-bezier(0.22,1,0.36,1)',
        }}/>
      </span>

      {/* Secondary line — softly reveals beneath */}
      <span style={{
        position: 'relative',
        fontFamily: "'Inter Tight', sans-serif",
        fontSize: 9.5,
        letterSpacing: '0.18em',
        textTransform: 'uppercase',
        color: 'rgba(255,255,255,0.78)',
        opacity: hover ? 1 : 0,
        transform: hover ? 'translateY(0)' : 'translateY(-4px)',
        filter: hover ? 'blur(0)' : 'blur(2px)',
        // Slight delay so the primary line moves first, then the secondary
        // joins — gives the reveal a soft cadence instead of a single beat.
        transition:
          'opacity 760ms cubic-bezier(0.22,1,0.36,1) 80ms, ' +
          'transform 760ms cubic-bezier(0.22,1,0.36,1) 80ms, ' +
          'filter 760ms cubic-bezier(0.22,1,0.36,1) 80ms',
        whiteSpace: 'nowrap',
        zIndex: 1,
      }}>
        The Creativity Lab — Amsterdam
      </span>
    </a>
  );
}

/* ====================== FOOTER ============================== */
function FooterAbout() {
  // Each item: [label, href]. Hrefs starting with '#contact' open the panel
  // (handled by the global delegated click listener); '/site/...' jump to pages;
  // 'https://...' open in a new tab.
  const COLUMNS = [
    {
      h: 'Space',
      items: [
        ['Private studios', '/site/studios.html'],
        ['Studio bookings', '#contact'],
        ['Workshops & events', '#contact'],
        ['Programming', '#contact'],
      ],
    },
    {
      h: 'Studio',
      items: [
        ['About', '/site/about.html'],
        ['Journal', '/site/journal.html'],
        ['Contact', '#contact'],
        ['Careers', '#contact'],
      ],
    },
    {
      h: 'Follow',
      items: [
        ['Instagram', 'https://instagram.com'],
        ['LinkedIn', 'https://linkedin.com'],
        ['Newsletter', '#contact'],
        ['Vimeo', 'https://vimeo.com'],
      ],
    },
  ];

  const linkProps = (href) => {
    if (href === '#contact') return { href, 'data-open-contact': true };
    if (href.startsWith('http')) return { href, target: '_blank', rel: 'noreferrer noopener' };
    return { href };
  };

  return (
    <footer style={{
      background: '#0A0A0B', color: '#fff',
      padding: 'clamp(80px, 10vh, 120px) clamp(20px, 5vw, 80px) clamp(40px, 5vh, 60px)',
    }}>
      <div style={{
        display: 'grid',
        gridTemplateColumns: 'repeat(auto-fit, minmax(180px, 1fr))',
        gap: 'clamp(40px, 5vw, 80px)',
        marginBottom: 'clamp(60px, 8vw, 100px)',
      }}>
        <div>
          <a href="/site/homepage.html" style={{ fontFamily: "'Inter Tight',sans-serif", fontWeight: 600, fontSize: 28, letterSpacing: '-0.02em', color: '#fff', textDecoration: 'none' }}>ASPACE</a>
          <div style={{ fontSize: 13, color: 'rgba(255,255,255,0.55)', marginTop: 14, lineHeight: 1.6 }}>
            Joop Geesinkweg 306<br/>1114 AB Amsterdam-Duivendrecht
          </div>
        </div>
        {COLUMNS.map((c, i) => (
          <div key={i}>
            <div style={{ fontSize: 11, letterSpacing: '0.18em', color: 'rgba(255,255,255,0.45)', textTransform: 'uppercase', marginBottom: 18 }}>{c.h}</div>
            <ul style={{ listStyle: 'none', padding: 0, margin: 0, display: 'grid', gap: 12 }}>
              {c.items.map(([label, href]) => (
                <li key={label}><a {...linkProps(href)} style={{ color: '#fff', textDecoration: 'none', fontSize: 14, opacity: 0.85 }}>{label}</a></li>
              ))}
            </ul>
          </div>
        ))}
      </div>
      <div style={{
        display: 'flex', justifyContent: 'space-between', alignItems: 'center',
        paddingTop: 28, borderTop: '1px solid rgba(255,255,255,0.12)',
        fontSize: 11, letterSpacing: '0.14em', color: 'rgba(255,255,255,0.5)', textTransform: 'uppercase',
        flexWrap: 'wrap', gap: 16,
      }}>
        <span>© 2026 ASPACE Amsterdam</span>
        <span style={{ display: 'inline-flex', gap: 18, flexWrap: 'wrap' }}>
          <a href="/site/privacy.html" style={{ color: 'inherit', textDecoration: 'none' }}>Privacy</a>
          <a href="/site/terms.html" style={{ color: 'inherit', textDecoration: 'none' }}>Terms</a>
          <a href="/site/cookies.html" style={{ color: 'inherit', textDecoration: 'none' }}>Cookies</a>
        </span>
        <TCLSignature/>
      </div>
    </footer>
  );
}

window.SiteFooter = FooterAbout;

/* ====================== PAGE ============================== */
function AboutPage() {
  return (
    <main>
      <HeroAbout/>
      <IdeaSection/>
      <AtmosphereSection/>
      <EcosystemSection/>
      <AmsterdamSection/>
      <FutureSection/>
      <FinalCtaAbout/>
      <FooterAbout/>
    </main>
  );
}

window.AboutPage = AboutPage;
