// app.jsx — Herely website composition. Sections are mostly static markup
// with a small reveal-on-scroll observer; the live map and hero ambient
// canvas handle motion.

const { useEffect, useRef, useState, useMemo } = React;

const LANDING_MOODS = [
  { key: "open", label: "Open", color: "#3A7FCC", desc: "Open to chat" },
  { key: "building", label: "Building", color: "#00C49A", desc: "Working on something" },
  { key: "curious", label: "Curious", color: "#F5A623", desc: "Exploring ideas" },
  { key: "focused", label: "Focused", color: "#A8A8A8", desc: "Heads-down" },
  { key: "social", label: "Social", color: "#FF6B6B", desc: "Wants energy" }
];

function moodColor(key) {
  return (LANDING_MOODS.find((item) => item.key === key) || LANDING_MOODS[0]).color;
}

const TWEAK_DEFAULTS = /*EDITMODE-BEGIN*/{
  "mode": "midnight",
  "density": 1.0,
  "serifAccents": true,
  "moodFocus": "all"
}/*EDITMODE-END*/;

/* ─── Reveal-on-scroll ─── */
function useReveal(dependency) {
  useEffect(() => {
    const els = document.querySelectorAll(".rv");
    const io = new IntersectionObserver(
      (entries) => {
        for (const e of entries) {
          if (e.isIntersecting) {
            e.target.classList.add("in");
            io.unobserve(e.target);
          }
        }
      },
      { rootMargin: "0px 0px -10% 0px", threshold: 0.05 }
    );
    els.forEach((el) => io.observe(el));
    return () => io.disconnect();
  }, [dependency]);
}

/* ─── Ambient hero canvas — drifting presence specks ─── */
function HeroAmbient({ midnight }) {
  const wrapRef = useRef(null);
  const canvasRef = useRef(null);
  useEffect(() => {
    const wrap = wrapRef.current, canvas = canvasRef.current;
    if (!wrap || !canvas) return;
    let raf = 0;
    const dpr = Math.min(window.devicePixelRatio || 1, 2);
    let w = 0, h = 0;
    const resize = () => {
      const r = wrap.getBoundingClientRect();
      w = r.width; h = r.height;
      canvas.width = Math.floor(w * dpr);
      canvas.height = Math.floor(h * dpr);
      canvas.style.width = w + "px";
      canvas.style.height = h + "px";
    };
    resize();
    const ro = new ResizeObserver(resize);
    ro.observe(wrap);

    // 32 specks across the field, very slow drift
    const N = 36;
    const COLORS = ["#3A7FCC", "#F5A623", "#00C49A", "#FF6B6B", "#A8A8A8"];
    const pts = Array.from({ length: N }, () => ({
      x: Math.random(),
      y: Math.random(),
      vx: (Math.random() - 0.5) * 0.006,
      vy: (Math.random() - 0.5) * 0.006,
      phase: Math.random() * Math.PI * 2,
      r: 2 + Math.random() * 2.5,
      c: COLORS[Math.floor(Math.random() * COLORS.length)],
    }));

    let t0 = performance.now();
    const draw = (t) => {
      const dt = Math.min(0.05, (t - t0) / 1000);
      t0 = t;
      const ctx = canvas.getContext("2d");
      ctx.setTransform(dpr, 0, 0, dpr, 0, 0);
      ctx.clearRect(0, 0, w, h);

      // Very subtle grid — barely there
      ctx.strokeStyle = midnight ? "rgba(255,255,255,0.04)" : "rgba(11,11,13,0.04)";
      ctx.lineWidth = 1;
      const step = 88;
      ctx.beginPath();
      for (let x = 0; x < w; x += step) { ctx.moveTo(x, 0); ctx.lineTo(x, h); }
      for (let y = 0; y < h; y += step) { ctx.moveTo(0, y); ctx.lineTo(w, y); }
      ctx.stroke();

      for (const p of pts) {
        p.x += p.vx * dt; p.y += p.vy * dt;
        if (p.x < 0 || p.x > 1) p.vx *= -1;
        if (p.y < 0 || p.y > 1) p.vy *= -1;
        p.phase += dt * 0.6;
        const pulse = 0.5 + 0.5 * Math.sin(p.phase);
        const px = p.x * w, py = p.y * h;
        const haloR = p.r + 12 + pulse * 6;
        const g = ctx.createRadialGradient(px, py, 0, px, py, haloR);
        g.addColorStop(0, withAlpha(p.c, midnight ? 0.22 : 0.14));
        g.addColorStop(1, withAlpha(p.c, 0));
        ctx.fillStyle = g;
        ctx.beginPath(); ctx.arc(px, py, haloR, 0, Math.PI * 2); ctx.fill();
        ctx.fillStyle = withAlpha(p.c, midnight ? 0.85 : 0.55);
        ctx.beginPath(); ctx.arc(px, py, p.r, 0, Math.PI * 2); ctx.fill();
      }
      raf = requestAnimationFrame(draw);
    };
    raf = requestAnimationFrame(draw);
    return () => { cancelAnimationFrame(raf); ro.disconnect(); };
  }, [midnight]);

  return (
    <div className="hero-canvas" ref={wrapRef}>
      <canvas ref={canvasRef}></canvas>
    </div>
  );
}

function withAlpha(hex, a) {
  const h = hex.replace("#", "");
  const r = parseInt(h.slice(0, 2), 16);
  const g = parseInt(h.slice(2, 4), 16);
  const b = parseInt(h.slice(4, 6), 16);
  return `rgba(${r},${g},${b},${a})`;
}

const Arrow = () => (
  <svg className="arrow" viewBox="0 0 14 14" fill="none">
    <path d="M2 7h10M8 3l4 4-4 4" stroke="currentColor" strokeWidth="1.4" strokeLinecap="round" strokeLinejoin="round"/>
  </svg>
);

/* ─── Nav ─── */
const SunIcon = () => (
  <svg viewBox="0 0 16 16" width="15" height="15" fill="none">
    <circle cx="8" cy="8" r="3" stroke="currentColor" strokeWidth="1.3"/>
    {[0,45,90,135,180,225,270,315].map(a => {
      const rad = (a*Math.PI)/180;
      const x1 = 8 + Math.cos(rad)*5, y1 = 8 + Math.sin(rad)*5;
      const x2 = 8 + Math.cos(rad)*7, y2 = 8 + Math.sin(rad)*7;
      return <line key={a} x1={x1} y1={y1} x2={x2} y2={y2} stroke="currentColor" strokeWidth="1.3" strokeLinecap="round"/>;
    })}
  </svg>
);
const MoonIcon = () => (
  <svg viewBox="0 0 16 16" width="15" height="15" fill="none">
    <path d="M12.5 9.5A5 5 0 1 1 6.5 3.5a4 4 0 0 0 6 6Z" stroke="currentColor" strokeWidth="1.3" strokeLinejoin="round"/>
  </svg>
);

function Nav({ mode, onToggle, onSignIn }) {
  const midnight = mode === "midnight";
  return (
    <nav className="nav">
      <div className="wrap nav-inner">
        <BrandLogo />
        <div className="nav-links">
          <a href="/#how" onClick={(e) => { e.preventDefault(); document.getElementById("how")?.scrollIntoView({behavior:"smooth"}); }}>How it works</a>
          <a href="/#map" onClick={(e) => { e.preventDefault(); document.getElementById("map")?.scrollIntoView({behavior:"smooth"}); }}>The map</a>
          <a href="/#philosophy" onClick={(e) => { e.preventDefault(); document.getElementById("philosophy")?.scrollIntoView({behavior:"smooth"}); }}>Philosophy</a>
          <a href="/#venues" onClick={(e) => { e.preventDefault(); document.getElementById("venues")?.scrollIntoView({behavior:"smooth"}); }}>For venues</a>
        </div>
        <div className="nav-cta">
          <div className="nav-status"><span className="dot"></span>4 rooms live</div>
          <button
            className="mode-toggle"
            aria-label={midnight ? "Switch to light mode" : "Switch to midnight mode"}
            title={midnight ? "Light mode" : "Midnight mode"}
            onClick={onToggle}
          >
            {midnight ? <SunIcon /> : <MoonIcon />}
          </button>
          {/* PILOT_MODE: sign-in hidden for pilot — restore by uncommenting */}
          {/* <button onClick={onSignIn} className="btn btn-ghost">Sign in <Arrow/></button> */}
        </div>
      </div>
    </nav>
  );
}

/* ─── Hero ─── */
function HeroRadar() {
  const room = useMemo(() => generateRoom(12), []);
  const [time, setTime] = useState(() =>
    new Date().toLocaleTimeString([], { hour: "2-digit", minute: "2-digit" })
  );
  useEffect(() => {
    const i = setInterval(
      () => setTime(new Date().toLocaleTimeString([], { hour: "2-digit", minute: "2-digit" })),
      30000
    );
    return () => clearInterval(i);
  }, []);

  return (
    <div className="mini-room mini-radar" style={{ position: "relative" }}>
      <div className="mr-head">
        <div className="mr-now">
          <span className="mr-dot"></span>Studio 1 · 2F · now
        </div>
        <div className="mr-time">{time}</div>
      </div>

      <div style={{ position: "relative", width: "100%", aspectRatio: "1 / 0.92", overflow: "hidden", background: "#0B0B0D", isolation: "isolate", transform: "translateZ(0)" }}>
        <SpatialMap
          room={room}
          filter={null}
          fullscreen={false}
          tweaks={useMemo(() => ({ motion: 0.6, glow: 0.8 }), [])}
          selectedId={null}
        />
      </div>

      <div className="mr-foot">
        <div className="mr-leg"><span className="mr-sw" style={{ background: "var(--m-blue)" }}></span>{room.counts.open} open</div>
        <div className="mr-leg"><span className="mr-sw" style={{ background: "var(--m-teal)" }}></span>{room.counts.building} building</div>
        <div className="mr-leg"><span className="mr-sw" style={{ background: "var(--m-amber)" }}></span>{room.counts.curious} curious</div>
        <div className="mr-leg"><span className="mr-sw" style={{ background: "var(--m-coral)" }}></span>{room.counts.social} social</div>
      </div>
    </div>
  );
}

function Hero({ midnight, onNavigate }) {
  return (
    <section className="hero">
      <HeroAmbient midnight={midnight} />
      <div className="hero-vignette"></div>
      <div className="wrap hero-inner">
        <div className="hero-grid">
          <div className="hero-text">
            <div className="eyebrow rv">Herely · <span style={{ color: '#ffffff', fontWeight: 700 }}>invite-only</span></div>
            <h1 className="rv d1">
              Presence <span className="ed">before</span> profile.
            </h1>
            <p className="lede rv d2">
              A real-time presence layer for physical spaces. See who's around,
              feel the energy in the room, and discover what people are open to —
              before anyone has to introduce themselves.
            </p>
            <div className="hero-cta rv d3">
              <button onClick={() => onNavigate("/request-access")} className="btn btn-primary">Request Access <Arrow/></button>
              <button onClick={() => onNavigate("/scanqr")} className="btn btn-exp" aria-label="See the live presence experience">
                <span className="exp-sheen" aria-hidden="true"></span>
                <span className="exp-label">
                  <span className="exp-rings" aria-hidden="true"></span>
                  <span className="exp-dot" aria-hidden="true"></span>
                  See the <em>experience</em>
                </span>
              </button>
            </div>
          </div>
          <div className="hero-visual rv d2">
            <HeroRadar />
          </div>
        </div>

        <div className="hero-meta">
          <div className="hero-stats rv d4">
            <div className="hs-cell">
              <div className="mono">Live · last 24h</div>
              <div className="hs-n">2,418</div>
              <div className="hs-l">people quietly present across 14 rooms</div>
            </div>
            <div className="hs-cell">
              <div className="mono">Mutual signals</div>
              <div className="hs-n">57<span style={{fontSize:22, color:"var(--mute)"}}>%</span></div>
              <div className="hs-l">opened to a conversation they wouldn't have started</div>
            </div>
            <div className="hs-cell">
              <div className="mono">Founding rooms</div>
              <div className="hs-n">14<span style={{fontSize:22, color:"var(--mute)"}}> / 200</span></div>
              <div className="hs-l">cities, campuses, and studios already live</div>
            </div>
          </div>
        </div>
      </div>
    </section>
  );
}

/* ─── Problem / contrast ─── */
const OLD = ["Profiles", "Feeds", "Algorithms", "Performance", "Cognitive overload"];
const NEW = [
  { t: "Presence",  c: "var(--m-blue)"  },
  { t: "Intent",    c: "var(--m-amber)" },
  { t: "Energy",    c: "var(--m-teal)"  },
  { t: "Context",   c: "var(--m-coral)" },
  { t: "Resonance", c: "var(--m-grey)"  },
];

function Problem() {
  return (
    <section className="section" id="problem">
      <div className="wrap">
        <div className="section-head">
          <h2 className="rv">
            Herely makes connection<br/>
            <span className="ed">closer</span>, not noisier.
          </h2>
          <div className="meta rv d1">
            <div className="eyebrow">Section 01 · The problem</div>
            <p className="small" style={{maxWidth: "36ch"}}>
              Modern social systems were built for performance and reach.
              The room you're already in deserves something quieter.
            </p>
          </div>
        </div>
        <div className="contrast rv d2">
          <div className="col-old">
            <h4>The old world</h4>
            <ul>
              {OLD.map((t, i) => <li key={i}>{t}</li>)}
            </ul>
          </div>
          <div className="col-new">
            <h4>The Herely layer</h4>
            <ul>
              {NEW.map((n, i) => <li key={i} style={{"--dot": n.c}}>{n.t}</li>)}
            </ul>
          </div>
        </div>
        <div className="pull rv d3">
          <p>
            The algorithms told us who to follow.<br/>
            Herely tells us <span className="a">who is in the room.</span>
          </p>
        </div>
      </div>
    </section>
  );
}

/* ─── How it works ─── */
function StepCard({ n, title, body, children }) {
  return (
    <div className="step rv">
      <div className="row-between">
        <span className="n">{n}</span>
        <span className="mono">Step</span>
      </div>
      <h3>{title}</h3>
      <p>{body}</p>
      <div className="card">{children}</div>
    </div>
  );
}

function HowItWorks() {
  // Step 1 — energy nodes mosaic
  const nodeMosaic = useMemo(() => {
    const pattern = [
      ["o","o",".","b","."],
      ["c",".","f","o","s"],
      [".","b","o",".","c"],
      ["o","s",".","f","."],
    ];
    const cMap = { o:"var(--m-blue)", b:"var(--m-teal)", c:"var(--m-amber)", s:"var(--m-coral)", f:"var(--m-grey)" };
    return pattern.flat().map((k, i) => (
      <div key={i} className={"node" + (k === "." ? "" : " on")} style={{"--c": cMap[k] || "transparent"}}>{k !== "." && (i+1)}</div>
    ));
  }, []);

  return (
    <section className="section" id="how">
      <div className="wrap">
        <div className="section-head">
          <h2 className="rv">Three quiet layers,<br/>revealed in sequence.</h2>
          <div className="meta rv d1">
            <div className="eyebrow">Section 02 · How it works</div>
            <p className="small" style={{maxWidth:"34ch"}}>
              Identity is the reward, not the entry point.
              Each layer asks for mutual consent before unlocking the next.
            </p>
          </div>
        </div>

        <div className="steps">
          <StepCard
            n="01."
            title="See the room by energy."
            body="A soft constellation of moods. No names, no photos — just the texture of who's around right now."
          >
            <div className="row-between">
              <span className="step-tag" style={{"--c":"var(--m-teal)"}}><span className="d"></span>Live</span>
              <span className="mono">24 present</span>
            </div>
            <div className="nodes">
              {nodeMosaic}
            </div>
          </StepCard>

          <StepCard
            n="02."
            title="Discover context."
            body="Tap into a mood cluster. Surface the intent behind a presence — what they're working on, looking for, open to."
          >
            <div className="ctx-row">
              <span className="name">A</span>
              <div className="tags">
                <span className="tag" style={{color:"var(--m-blue)"}}>Open</span>
                <span className="tag">design</span>
                <span className="tag">tools-for-thought</span>
              </div>
            </div>
            <div className="ctx-row">
              <span className="name">M</span>
              <div className="tags">
                <span className="tag" style={{color:"var(--m-teal)"}}>Building</span>
                <span className="tag">robotics</span>
              </div>
            </div>
            <div className="ctx-row">
              <span className="name">K</span>
              <div className="tags">
                <span className="tag" style={{color:"var(--m-amber)"}}>Curious</span>
                <span className="tag">phd · neuro</span>
              </div>
            </div>
            <div className="ctx-row">
              <span className="name">J</span>
              <div className="tags">
                <span className="tag" style={{color:"var(--m-blue)"}}>Open</span>
                <span className="tag">first time here</span>
              </div>
            </div>
          </StepCard>

          <StepCard
            n="03."
            title="Mutual interest unlocks identity."
            body="Two quiet taps, and a thread opens. Only then do names, faces, and conversation appear."
          >
            <div className="reveal-row">
              <span className="ini">A</span>
              <span className="nm">Anya Reyes · designer</span>
              <span className="badge match">Match</span>
            </div>
            <div className="reveal-row">
              <span className="ini">M</span>
              <span className="nm locked">▮▮▮▮▮ ▮▮▮▮▮▮</span>
              <span className="badge">Pending</span>
            </div>
            <div className="reveal-row">
              <span className="ini">K</span>
              <span className="nm locked">▮▮▮▮ ▮▮▮▮▮</span>
              <span className="badge">Pending</span>
            </div>
            <div className="reveal-row">
              <span className="ini">J</span>
              <span className="nm">Jordan Wu · product</span>
              <span className="badge match">Match</span>
            </div>
          </StepCard>
        </div>
      </div>
    </section>
  );
}

/* ─── Live Map section ─── */
function MapSection({ isEmbed }) {
  const [filter, setFilter] = useState("all");
  const [density, setDensity] = useState(1.0);
  const [time, setTime] = useState(() =>
    new Date().toLocaleTimeString([], { hour: "2-digit", minute: "2-digit" })
  );

  useEffect(() => {
    const i = setInterval(
      () => setTime(new Date().toLocaleTimeString([], { hour: "2-digit", minute: "2-digit" })),
      30000
    );
    return () => clearInterval(i);
  }, []);

  const room = useMemo(() => generateRoom(Math.round(18 * density)), [density]);
  const activeFilter = useMemo(() => filter === "all" ? null : new Set([filter]), [filter]);

  // Density controlled via tweaks - read once
  useEffect(() => {
    const handler = (e) => {
      if (e.data?.__tweaks?.density) setDensity(e.data.__tweaks.density);
    };
    window.addEventListener("message", handler);
    return () => window.removeEventListener("message", handler);
  }, []);

  if (isEmbed) {
    return (
      <section className="map-section" id="map" style={{ padding: 0, background: "none" }}>
        <div className="wrap">
          <div className="map-shell">
            <div className="radar-stage--lg" style={{ position: "relative", width: "100%", overflow: "hidden", border: "1px solid rgba(255,255,255,0.08)", borderRadius: "24px", isolation: "isolate", transform: "translateZ(0)" }}>
              <div className="stage-chrome">
                <div className="left">
                  <span className="dot"></span>
                  <span>Studio 1 · 2F · live</span>
                </div>
                <div className="right">
                  {time} · {room.people.length} present
                </div>
              </div>
              <SpatialMap
                room={room}
                filter={activeFilter}
                selectedId={null}
              />
              <div className="map-disclaimer" style={{position: 'absolute', bottom: '16px', left: 0, right: 0, textAlign: 'center', fontSize: '10.5px', color: 'rgba(244,242,238,0.35)', pointerEvents: 'none', zIndex: 10, fontStyle: 'italic', letterSpacing: '0.02em'}}>
                *Conceptual live environment visualization
              </div>
            </div>

            <div className="map-readout">
              <div>
                <div className="mono" style={{marginBottom:14,color:"rgba(244,242,238,.55)"}}>Mood signals</div>
                <div className="legend">
                  {LANDING_MOODS.map(m => (
                    <div className="item" key={m.key}>
                      <span className="swatch" style={{background:m.color, boxShadow:`0 0 0 4px ${m.color}22`}}></span>
                      <span style={{minWidth:74}}>{m.label}</span>
                      <span style={{color:"rgba(244,242,238,.45)"}}>{m.desc}</span>
                    </div>
                  ))}
                </div>
              </div>

              <div>
                <div className="mono" style={{marginBottom:12,color:"rgba(244,242,238,.55)"}}>Filter the room</div>
                <div className="filter-row">
                  <button className={"filter" + (filter==="all"?" on":"")} onClick={()=>setFilter("all")}>All</button>
                  {LANDING_MOODS.map(m => (
                    <button key={m.key} className={"filter" + (filter===m.key?" on":"")} onClick={()=>setFilter(m.key)}>
                      <span className="d" style={{background:m.color}}></span>{m.label}
                    </button>
                  ))}
                </div>
              </div>

              <div style={{marginTop:8, display:"flex", flexDirection:"column", gap:12}}>
                <div className="stat"><span className="v">{room.people.length}</span><span className="l">Present</span></div>
                <div className="stat"><span className="v">{room.openToTalk}</span><span className="l">Open to talk</span></div>
                <div className="stat"><span className="v">{room.mutual}</span><span className="l">Mutual signals</span></div>
              </div>

              <p className="small" style={{color:"rgba(244,242,238,.5)",lineHeight:1.55}}>
                Hover any node to see its presence. No names — until both sides say yes.
              </p>
            </div>
          </div>
        </div>
      </section>
    );
  }

  return (
    <section className="map-section" id="map">
      <div className="wrap">
        <div className="section-head">
          <h2 className="rv" style={{color:"#F4F2EE"}}>
            The room itself becomes <span className="ed">discoverable.</span>
          </h2>
          <div className="meta rv d1">
            <div className="eyebrow">Section 03 · The live map</div>
            <p className="small" style={{maxWidth:"34ch",color:"rgba(244,242,238,.62)"}}>
              A living map of a single space. Each soft pulse is a person quietly broadcasting
              their state — open, focused, curious, building, social.
            </p>
          </div>
        </div>

        <div className="map-shell">
          <div className="radar-stage--lg" style={{ position: "relative", width: "100%", overflow: "hidden", border: "1px solid rgba(255,255,255,0.08)", borderRadius: "24px", isolation: "isolate", transform: "translateZ(0)" }}>
            <div className="stage-chrome">
              <div className="left">
                <span className="dot"></span>
                <span>Studio 1 · 2F · live</span>
              </div>
              <div className="right">
                {time} · {room.people.length} present
              </div>
            </div>
            <SpatialMap
              room={room}
              filter={activeFilter}
              selectedId={null}
            />
            <div className="map-disclaimer" style={{position: 'absolute', bottom: '16px', left: 0, right: 0, textAlign: 'center', fontSize: '10.5px', color: 'rgba(244,242,238,0.35)', pointerEvents: 'none', zIndex: 10, fontStyle: 'italic', letterSpacing: '0.02em'}}>
              *Conceptual live environment visualization
            </div>
          </div>

          <div className="map-readout">
            <div>
              <div className="mono" style={{marginBottom:14,color:"rgba(244,242,238,.55)"}}>Mood signals</div>
              <div className="legend">
                {LANDING_MOODS.map(m => (
                  <div className="item" key={m.key}>
                    <span className="swatch" style={{background:m.color, boxShadow:`0 0 0 4px ${m.color}22`}}></span>
                    <span style={{minWidth:74}}>{m.label}</span>
                    <span style={{color:"rgba(244,242,238,.45)"}}>{m.desc}</span>
                  </div>
                ))}
              </div>
            </div>

            <div>
              <div className="mono" style={{marginBottom:12,color:"rgba(244,242,238,.55)"}}>Filter the room</div>
              <div className="filter-row">
                <button className={"filter" + (filter==="all"?" on":"")} onClick={()=>setFilter("all")}>All</button>
                {LANDING_MOODS.map(m => (
                  <button key={m.key} className={"filter" + (filter===m.key?" on":"")} onClick={()=>setFilter(m.key)}>
                    <span className="d" style={{background:m.color}}></span>{m.label}
                  </button>
                ))}
              </div>
            </div>

            <div style={{marginTop:8, display:"flex", flexDirection:"column", gap:12}}>
              <div className="stat"><span className="v">{room.people.length}</span><span className="l">Present</span></div>
              <div className="stat"><span className="v">{room.openToTalk}</span><span className="l">Open to talk</span></div>
              <div className="stat"><span className="v">{room.mutual}</span><span className="l">Mutual signals</span></div>
            </div>

            <p className="small" style={{color:"rgba(244,242,238,.5)",lineHeight:1.55}}>
              Hover any node to see its presence. No names — until both sides say yes.
            </p>
          </div>
        </div>
      </div>
    </section>
  );
}

/* ─── Philosophy ─── */
const PHILO = [
  { over: "Presence", under: "performance" },
  { over: "Intent",   under: "attention"   },
  { over: "Signal",   under: "noise"       },
  { over: "Alignment",under: "scale"       },
  { over: "Context",  under: "virality"    },
];

function Philosophy() {
  return (
    <section className="philo" id="philosophy">
      <div className="wrap">
        <div className="eyebrow rv" style={{marginBottom:64}}>Section 04 · Philosophy</div>
        <div className="lines">
          {PHILO.map((p, i) => (
            <div className="ln rv" key={i} style={{transitionDelay: `${i*120}ms`}}>
              <em>{p.over}</em>
              <span className="sep"></span>
              <span className="over">over {p.under}.</span>
            </div>
          ))}
        </div>
      </div>
    </section>
  );
}

/* ─── Venue partners ─── */
function Venues() {
  return (
    <section className="section" id="venues">
      <div className="wrap">
        <div className="section-head">
          <h2 className="rv">
            Activate the invisible<br/>
            social layer of your <span className="ed">space.</span>
          </h2>
          <div className="meta rv d1">
            <div className="eyebrow">Section 05 · For venues</div>
            <p className="small" style={{maxWidth:"34ch"}}>
              A presence layer that lives lightly inside the rooms you already host.
              No new screens, no new platform — just the room, made legible.
            </p>
          </div>
        </div>

        <div className="venues">
          <div className="v-card rv">
            <div className="tag">Innovation hubs · Labs</div>
            <h3>For places where strangers <br/>are already building together.</h3>
            <p className="small" style={{maxWidth:"38ch", color:"var(--mute)"}}>
              Help residents and visitors find each other without forcing introductions.
              See who's deep in a build, who's between thoughts, who'd say yes to a coffee.
            </p>
            <div className="row">
              <span className="chip">Daily presence</span>
              <span className="chip">Mood clusters</span>
              <span className="chip">Quiet matchmaking</span>
            </div>
          </div>

          <div className="v-card rv d1">
            <div className="tag">Universities · Research</div>
            <h3>For campuses where the <br/>good encounters never happen.</h3>
            <p className="small" style={{maxWidth:"38ch", color:"var(--mute)"}}>
              A library that knows three thesis writers are present.
              A studio that knows a guest critic just walked in. The room as the directory.
            </p>
            <div className="row">
              <span className="chip">Cross-discipline signals</span>
              <span className="chip">Cohort discovery</span>
              <span className="chip">Office-hours layer</span>
            </div>
          </div>

          <div className="v-card rv d2">
            <div className="tag">Coworking · Creative communities</div>
            <h3>For coworking that wants <br/>to feel like a community again.</h3>
            <p className="small" style={{maxWidth:"38ch", color:"var(--mute)"}}>
              A floor that surfaces its own members — quietly. The shared kitchen
              becomes a place to actually meet your neighbor.
            </p>
            <div className="row">
              <span className="chip">Floor maps</span>
              <span className="chip">Member discovery</span>
              <span className="chip">Event mode</span>
            </div>
          </div>

          <div className="v-card rv d3">
            <div className="tag">Conferences · Salons · Studios</div>
            <h3>For temporary rooms <br/>that deserve permanent value.</h3>
            <p className="small" style={{maxWidth:"38ch", color:"var(--mute)"}}>
              Spin up a Herely room for a weekend. Let 200 people find each other by
              what they're carrying, not by who has the loudest badge.
            </p>
            <div className="row">
              <span className="chip">Pop-up rooms</span>
              <span className="chip">Intent tags</span>
              <span className="chip">After-room threads</span>
            </div>
          </div>
        </div>

        <div className="partner-row rv">
          <span className="mono" style={{color:"var(--mute)"}}>In quiet pilots with</span>
          <span className="p">Studio 1</span>
          <span className="p">Coworking 1</span>
          <span className="p">Studio 2</span>
          <span className="p">Studio 3</span>
          <span className="p">Coworking 2</span>
          <span className="p">Coworking 3</span>
        </div>
      </div>
    </section>
  );
}

/* ─── Final CTA ─── */
function FinalCTA({ midnight, onNavigate }) {
  return (
    <section className="final" id="access">
      <HeroAmbient midnight={midnight} />
      <div className="wrap">
        <div className="eyebrow rv">A small invitation</div>
        <h2 className="rv d1" style={{marginTop:32}}>
          The map lights up<br/>when <span className="ed">people do.</span>
        </h2>
        <div className="row rv d2">
          <button onClick={() => onNavigate("/request-access")} className="btn btn-primary">Request Access <Arrow/></button>
          <p className="small">
            Limited to 200 founding rooms in 2026.
            One short form, one quiet reply.
          </p>
        </div>
      </div>
    </section>
  );
}

/* ─── Footer ─── */
function Footer({ onNavigate }) {
  return (
    <footer>
      <div className="wrap foot">
        <BrandLogo />
        <div className="col">
          <h5>Product</h5>
          <a href="/#how" onClick={(e) => { e.preventDefault(); document.getElementById("how")?.scrollIntoView({behavior:"smooth"}); }}>How it works</a>
          <a href="/#map" onClick={(e) => { e.preventDefault(); document.getElementById("map")?.scrollIntoView({behavior:"smooth"}); }}>The live map</a>
          <a href="/#philosophy" onClick={(e) => { e.preventDefault(); document.getElementById("philosophy")?.scrollIntoView({behavior:"smooth"}); }}>Philosophy</a>
        </div>
        <div className="col">
          <h5>Network</h5>
          <a href="/#venues" onClick={(e) => { e.preventDefault(); document.getElementById("venues")?.scrollIntoView({behavior:"smooth"}); }}>Venues</a>
          <a href="/#venues" onClick={(e) => { e.preventDefault(); document.getElementById("venues")?.scrollIntoView({behavior:"smooth"}); }}>Universities</a>
          <a href="/#venues" onClick={(e) => { e.preventDefault(); document.getElementById("venues")?.scrollIntoView({behavior:"smooth"}); }}>Coworking</a>
        </div>
        <div className="col">
          <h5>Company</h5>
          <a href="/about" onClick={(e) => { e.preventDefault(); onNavigate && onNavigate("/about"); }}>About</a>
          <a href="#">Writing</a>
          <a href="#">Careers</a>
        </div>
        <div className="col">
          <h5>Contact</h5>
          <a href="#">hello@herely.ai</a>
          <a href="#">Press</a>
        </div>
      </div>
      <div className="wrap foot-base">
        <div>© 2026 Herely. A quieter layer of reality.</div>
        <div className="mono">Made with intention · Berlin · NYC</div>
      </div>
    </footer>
  );
}

/* ─── Room Experience Components ─── */
const Close = () => (
  <svg viewBox="0 0 16 16" width="14" height="14" fill="none">
    <path d="M4 4l8 8M12 4l-8 8" stroke="currentColor" strokeWidth="1.4" strokeLinecap="round"/>
  </svg>
);

function RoomNav({ onNavigate }) {
  const goHome = (e) => { e.preventDefault(); if (onNavigate) onNavigate("/home"); };
  return (
    <nav className="nav">
      <div className="wrap nav-inner">
        <BrandLogo href="/home" onClick={goHome} />
        <div className="nav-links">
          <a href="/home" onClick={goHome}>Home</a>
          <a href="/#how" onClick={(e) => { e.preventDefault(); if (onNavigate) onNavigate("/"); window.setTimeout(() => { document.getElementById("how")?.scrollIntoView({behavior:"smooth"}); }, 100); }}>How it works</a>
          <a href="/#philosophy" onClick={(e) => { e.preventDefault(); if (onNavigate) onNavigate("/"); window.setTimeout(() => { document.getElementById("philosophy")?.scrollIntoView({behavior:"smooth"}); }, 100); }}>Philosophy</a>
        </div>
        <div className="nav-cta">
          <div className="nav-status"><span className="dot"></span>Studio 1 · 2F · live</div>
          <a href="/home" onClick={goHome} className="btn btn-ghost">Leave room <Arrow/></a>
        </div>
      </div>
    </nav>
  );
}

function IDCard({ person, onClose }) {
  if (!person) return null;
  const col = moodColor(person.mood);
  const mood = LANDING_MOODS.find(m => m.key === person.mood) || {};
  const initial = person.name.charAt(0).toUpperCase();
  const location = person.location || "Studio 1 · 2F";
  const openTo = person.openTo || person.open_to || "a quick intro";
  const bio = person.bio || `${person.name} is a ${person.role} focused on ${person.tags.join(', ')}.`;

  return (
    <aside className="id-card" role="dialog" aria-label={person.name + " · presence card"}>
      <button className="id-close" onClick={onClose} aria-label="Close"><Close/></button>
      <div className="id-avatar" style={{"--c": col}}>
        <div className="id-avatar-bg"></div>
        <div className="id-avatar-grain"></div>
        <div className="id-avatar-ring" aria-hidden="true">
          {[0,1,2].map(i => <span key={i} style={{"--i":i}}></span>)}
        </div>
        <span className="id-initial">{initial}</span>
        <span className="id-mood-pill"><span className="d" style={{background: col}}></span>{mood.label}</span>
        <span className="id-presence"><span className="d"></span>Present · 4 min</span>
      </div>
      <div className="id-body">
        <div className="id-head">
          <h3 className="id-name">{person.name}</h3>
          <p className="id-role">{person.role}</p>
        </div>
        <div className="id-meta">
          <div className="id-meta-row"><span className="id-meta-l">Status</span><span className="id-meta-v">{person.status}</span></div>
          <div className="id-meta-row"><span className="id-meta-l">Where</span><span className="id-meta-v">{location}</span></div>
          <div className="id-meta-row"><span className="id-meta-l">Open to</span><span className="id-meta-v">{openTo}</span></div>
        </div>
        <p className="id-bio">{bio}</p>
        <div className="id-tags">{person.tags.map((t, i) => <span key={i} className="id-tag">{t}</span>)}</div>
        <div className="id-actions">
          <button className="btn btn-ghost id-btn-ghost" onClick={onClose}>Close</button>
        </div>
      </div>
    </aside>
  );
}

function Room({ onNavigate }) {
  const [selectedId, setSelectedId] = useState(null);
  const [filter, setFilter] = useState("all");

  const room = useMemo(() => generateRoom(80), []);
  const activeFilter = useMemo(() => filter === "all" ? null : new Set([filter]), [filter]);

  const selected = useMemo(() => {
    return selectedId !== null ? room.people.find(p => p.id === selectedId) : null;
  }, [selectedId, room.people]);

  const apiRef = useRef(null);
  const [toastText, setToastText] = useState(null);
  const [time, setTime] = useState(() =>
    new Date().toLocaleTimeString([], { hour: "2-digit", minute: "2-digit" })
  );

  useEffect(() => {
    const i = setInterval(
      () => setTime(new Date().toLocaleTimeString([], { hour: "2-digit", minute: "2-digit" })),
      30000
    );
    return () => clearInterval(i);
  }, []);

  useEffect(() => {
    const onKey = (e) => { if (e.key === "Escape") setSelectedId(null); };
    window.addEventListener("keydown", onKey);
    return () => window.removeEventListener("keydown", onKey);
  }, []);

  return (
    <>
      <RoomNav onNavigate={onNavigate}/>
      <main className="room-page">
        <div className="wrap room-head">
          <div className="eyebrow">Studio 1 · 2F · live room</div>
          <h1 className="room-title">Who's <span className="ed">here</span>, right now.</h1>
          <p className="lede" style={{marginTop:18,maxWidth:"56ch"}}>
            Tap any name to see their presence card. Send a quiet signal —
            they'll only know who you are if they signal back.
          </p>
        </div>

        <div className="wrap">
          <div className="room-shell" data-selected={selected ? "true" : "false"}>
            <div className="room-stage">
              <div className="room-content">
                <div className="room-map">
                  <div className="radar-stage--lg" style={{ position: "relative", width: "100%", overflow: "hidden", border: "1px solid var(--line)", borderRadius: "24px", isolation: "isolate", transform: "translateZ(0)" }}>
                    <div className="stage-chrome">
                      <div className="left">
                        <span className="dot"></span>
                        <span>Studio 1 · 2F · live</span>
                      </div>
                      <div className="right">
                        {time} · {room.people.length} present
                      </div>
                    </div>
                    <SpatialMap
                      room={room}
                      filter={activeFilter}
                      selectedId={selectedId}
                      onSelect={setSelectedId}
                      onLOD={(lod) => console.log("LOD:", lod)}
                      onReshuffle={(count) => {
                        setToastText(`Orbit Shift: ${count} participants moved`);
                        const timer = setTimeout(() => setToastText(null), 3000);
                        return () => clearTimeout(timer);
                      }}
                      apiRef={apiRef}
                    />
                    <div className="map-disclaimer" style={{position: 'absolute', bottom: '16px', left: 0, right: 0, textAlign: 'center', fontSize: '10.5px', color: 'rgba(244,242,238,0.35)', pointerEvents: 'none', zIndex: 10, fontStyle: 'italic', letterSpacing: '0.02em'}}>
                      *Conceptual live environment visualization
                    </div>
                    {toastText && (
                      <div className="reshuffle-toast">
                        <span className="rt-dot"></span>
                        {toastText}
                      </div>
                    )}
                  </div>
                </div>
                <div className="room-readout">
                  <div>
                    <div className="mono" style={{marginBottom:14}}>Mood signals</div>
                    <div className="legend">
                      {LANDING_MOODS.map(m => (
                        <div className="item" key={m.key}>
                          <span className="swatch" style={{background:m.color, boxShadow:`0 0 0 4px ${m.color}22`}}></span>
                          <span style={{minWidth:74}}>{m.label}</span>
                          <span style={{color:'var(--mute)'}}>{m.desc}</span>
                        </div>
                      ))}
                    </div>
                  </div>
                  <div>
                    <div className="mono" style={{marginBottom:12}}>Filter the room</div>
                    <div className="filter-row">
                      <button className={"filter" + (filter==="all"?" on":"")} onClick={()=>setFilter("all")}>All</button>
                      {LANDING_MOODS.map(m => (
                        <button key={m.key} className={"filter" + (filter===m.key?" on":"")} onClick={()=>setFilter(m.key)}>
                          <span className="d" style={{background:m.color}}></span>{m.label}
                        </button>
                      ))}
                    </div>
                  </div>
                  <div style={{marginBottom: 12}}>
                    <div className="mono" style={{marginBottom:12}}>Map Controls</div>
                    <div style={{display: "flex", gap: "8px"}}>
                      <button className="filter" onClick={() => apiRef.current?.resetView()}>Recenter View</button>
                      <button className="filter" onClick={() => apiRef.current?.triggerReshuffle()}>Reshuffle Orbits</button>
                    </div>
                  </div>
                  <div style={{marginTop:8, display:"flex", flexDirection:"column", gap:12}}>
                    <div className="stat"><span className="v">{room.people.length}</span><span className="l">Present</span></div>
                    <div className="stat"><span className="v">{room.openToTalk}</span><span className="l">Open to talk</span></div>
                    <div className="stat"><span className="v">{room.mutual}</span><span className="l">Mutual signals</span></div>
                  </div>
                </div>
              </div>

              <div className="room-card-wrap" aria-hidden={!selected}>
                <IDCard person={selected} onClose={() => setSelectedId(null)}/>
              </div>
            </div>
          </div>
        </div>
      </main>
    </>
  );
}

/* ─── Bridge Animation to Room ─── */
function BridgeToRoom({ onNavigate }) {
  const [step, setStep] = useState("bridging"); // bridging, complete, room

  useEffect(() => {
    // Show "Bridge Established" after loading animation
    const timer1 = setTimeout(() => {
      setStep("complete");
    }, 1200);

    // Show room after success state
    const timer2 = setTimeout(() => {
      setStep("room");
    }, 2400);

    return () => {
      clearTimeout(timer1);
      clearTimeout(timer2);
    };
  }, []);

  if (step === "bridging" || step === "complete") {
    return (
      <div className="scanqr-experience midnight">
        <HeroAmbient midnight={true} />
        <div className="hero-vignette"></div>
        
        <div className="wrap scanqr-inner">
          {step === "bridging" && (
            <main className="scanqr-main">
              <div className="scanqr-loading rv in">
                <div className="loading-visual">
                  <div className="loading-rings">
                    <div className="l-ring r1"></div>
                    <div className="l-ring r2"></div>
                    <div className="l-ring r3"></div>
                  </div>
                  <div className="loading-dots">
                    <span className="l-dot blue"></span>
                    <span className="l-dot amber"></span>
                    <span className="l-dot teal"></span>
                  </div>
                </div>
                <div className="loading-text">
                  <div className="mono">Bridging spatial identities...</div>
                </div>
              </div>
            </main>
          )}

          {step === "complete" && (
            <main className="scanqr-main">
              <div className="scanqr-complete rv in">
                <div className="success-icon">
                  <svg viewBox="0 0 24 24" fill="none">
                     <path d="M20 6L9 17L4 12" stroke="var(--m-teal)" strokeWidth="2" strokeLinecap="round" strokeLinejoin="round" />
                  </svg>
                </div>
                <h2 className="ed">Bridge Established.</h2>
                <div className="mono">Entering the presence layer...</div>
              </div>
            </main>
          )}
        </div>

        <style>{`
          .scanqr-experience {
            height: 100vh;
            height: 100svh;
            background: var(--bg);
            color: var(--ink);
            display: flex;
            flex-direction: column;
            position: relative;
            overflow: hidden;
          }

          .scanqr-inner {
            z-index: 10;
            flex: 1;
            display: flex;
            flex-direction: column;
            padding-top: 20px;
            padding-bottom: 20px;
            justify-content: center;
          }

          .scanqr-main {
            flex: 1;
            display: flex;
            align-items: center;
            justify-content: center;
            max-width: 800px;
            margin: 0 auto;
            width: 100%;
          }

          .scanqr-loading, .scanqr-complete {
            text-align: center;
            display: flex;
            flex-direction: column;
            align-items: center;
            gap: 16px;
          }

          .loading-visual {
            width: 120px;
            height: 120px;
            position: relative;
            display: flex;
            align-items: center;
            justify-content: center;
            z-index: 1;
          }

          .loading-rings {
            position: absolute;
            width: 100%;
            height: 100%;
          }

          .l-ring {
            position: absolute;
            border: 2px solid transparent;
            border-radius: 50%;
            top: 50%;
            left: 50%;
            transform: translate(-50%, -50%);
            box-shadow: inset 0 0 15px rgba(58, 127, 204, 0.3);
          }

          .l-ring.r1 {
            width: 100%;
            height: 100%;
            border-top-color: var(--m-blue);
            border-right-color: var(--m-blue);
            animation: ring-spin 2s linear infinite;
          }

          .l-ring.r2 {
            width: 75%;
            height: 75%;
            border-bottom-color: var(--m-amber);
            border-left-color: var(--m-amber);
            animation: ring-spin-reverse 3s linear infinite;
          }

          .l-ring.r3 {
            width: 50%;
            height: 50%;
            border-top-color: var(--m-teal);
            border-right-color: var(--m-teal);
            animation: ring-spin 4s linear infinite;
          }

          @keyframes ring-spin {
            0% { transform: translate(-50%, -50%) rotate(0deg); }
            100% { transform: translate(-50%, -50%) rotate(360deg); }
          }

          @keyframes ring-spin-reverse {
            0% { transform: translate(-50%, -50%) rotate(0deg); }
            100% { transform: translate(-50%, -50%) rotate(-360deg); }
          }

          .loading-dots {
            display: flex;
            gap: 12px;
            z-index: 2;
          }

          .l-dot {
            width: 8px;
            height: 8px;
            border-radius: 50%;
            animation: dot-drift 3s infinite ease-in-out;
          }

          .l-dot.blue { background: var(--m-blue); box-shadow: 0 0 15px var(--m-blue); animation-delay: 0s; }
          .l-dot.amber { background: var(--m-amber); box-shadow: 0 0 15px var(--m-amber); animation-delay: 1s; }
          .l-dot.teal { background: var(--m-teal); box-shadow: 0 0 15px var(--m-teal); animation-delay: 2s; }

          @keyframes dot-drift {
            0%, 100% { transform: translateY(0) scale(1); opacity: 0.5; }
            50% { transform: translateY(-10px) scale(1.2); opacity: 1; }
          }

          .loading-text {
            text-align: center;
            display: flex;
            flex-direction: column;
            gap: 8px;
          }

          .success-icon {
            width: 64px;
            height: 64px;
            border-radius: 50%;
            background: rgba(0, 196, 154, 0.1);
            border: 1px solid var(--m-teal);
            display: flex;
            align-items: center;
            justify-content: center;
            margin-bottom: 24px;
            animation: success-pop 0.6s cubic-bezier(0.175, 0.885, 0.32, 1.275) forwards;
          }

          .success-icon svg {
            width: 32px;
            height: 32px;
          }

          @keyframes success-pop {
            0% { transform: scale(0); opacity: 0; }
            100% { transform: scale(1); opacity: 1; }
          }
        `}</style>
      </div>
    );
  }

  // Show the room view
  return (
    <div className="midnight" style={{ backgroundColor: "#0B0B0D", minHeight: "100vh" }}>
      <Room onNavigate={onNavigate} />
    </div>
  );
}

/* ─── Main Site Component ─── */
function MainSite({ mode, onModeToggle, tweaks, onTweakChange, onAuthSuccess, currentPath, onNavigate }) {
  const showAuth = currentPath === "/sign-in" || currentPath === "/sign-up";
  const authView = currentPath === "/sign-up" ? "signup" : "login";

  useReveal(currentPath);
  const midnight = mode === "midnight";

  useEffect(() => {
    const map = {
      "section.hero": "01 Hero",
      "#problem": "02 Problem",
      "#how": "03 How it works",
      "#map": "04 Live map",
      "#philosophy": "05 Philosophy",
      "#venues": "06 Venues",
      "#access": "07 Final CTA",
    };
    for (const [sel, label] of Object.entries(map)) {
      const el = document.querySelector(sel);
      if (el) el.setAttribute("data-screen-label", label);
    }
  }, []);

  if (showAuth) {
    return (
      <div style={{position: "fixed", inset: 0, zIndex: 9999, overflow: "auto"}}>
        <AuthApp onSuccess={onAuthSuccess} initialView={authView} onNavigate={onNavigate} />
        <button 
          onClick={() => onNavigate("/")}
          style={{
            position: "fixed",
            top: "24px",
            left: "24px",
            zIndex: 10000,
            background: "rgba(11,11,13,.08)",
            border: "1px solid rgba(11,11,13,.10)",
            borderRadius: "50%",
            width: "32px",
            height: "32px",
            display: "flex",
            alignItems: "center",
            justifyContent: "center",
            cursor: "pointer",
            color: "var(--ink)",
            fontSize: "18px",
            lineHeight: "1",
            padding: "0"
          }}
          aria-label="Close"
        >
          ✕
        </button>
      </div>
    );
  }

  return (
    <>
      <Nav mode={mode} onToggle={onModeToggle} onSignIn={() => onNavigate("/sign-in")} />
      <Hero midnight={midnight} onNavigate={onNavigate} />
      <Problem />
      <HowItWorks />
      <MapSection />
      <Philosophy />
      <Venues />
      <FinalCTA midnight={midnight} onNavigate={onNavigate} />
      <Footer onNavigate={onNavigate} />

      <TweaksPanel title="Tweaks">
        <TweakSection label="Palette" />
        <TweakRadio
          label="Mode"
          value={mode}
          options={["light", "midnight"]}
          onChange={(v) => onModeToggle(v)}
        />
        <TweakSection label="Map" />
        <TweakSlider
          label="Presence density"
          value={tweaks.density}
          min={0.4}
          max={1.2}
          step={0.05}
          onChange={(v) => {
            onTweakChange("density", v);
            window.postMessage({ __tweaks: { density: v } }, "*");
          }}
        />
        <TweakSection label="Typography" />
        <TweakToggle
          label="Serif accents"
          value={tweaks.serifAccents}
          onChange={(v) => {
            onTweakChange("serifAccents", v);
            document.documentElement.classList.toggle("no-serif", !v);
          }}
        />
      </TweaksPanel>

      <style>{`
        .no-serif .ed { font-family: var(--sans) !important; font-style: normal !important; font-weight: 400; letter-spacing: -0.03em; }
        .no-serif .philo .ln em { font-family: var(--sans) !important; font-style: normal !important; }
      `}</style>
    </>
  );
}

/* ─── App ─── */
function App() {
  const [t, setTweak] = useTweaks(TWEAK_DEFAULTS);
  const [currentPath, setCurrentPath] = useState(window.location.pathname);
  const [onboardingComplete, setOnboardingComplete] = useState(false);

  // Derive route state purely from the current pathname.
  const isScanQR          = currentPath === "/scanqr";
  const isJoinPath        = currentPath.startsWith("/join/");
  const isHomeRoute       = currentPath === "/home";
  const isAboutRoute      = currentPath === "/about";
  const isRoomRoute       = currentPath.startsWith("/room/");
  const isAuthCallback    = currentPath === "/auth/callback";
  const isRequestAccess   = currentPath === "/request-access";
  const isCopacabanaRoute = currentPath.toUpperCase() === "/NYC51";
  const midnight        = t.mode === "midnight";
  const shouldBeMidnight = isScanQR ? true : midnight;

  // Listen for browser back/forward navigation.
  useEffect(() => {
    const onPop = () => setCurrentPath(window.location.pathname);
    window.addEventListener("popstate", onPop);
    return () => window.removeEventListener("popstate", onPop);
  }, []);

  // Reset onboarding state whenever the user navigates to a new join path.
  useEffect(() => {
    if (isJoinPath) setOnboardingComplete(false);
  }, [currentPath, isJoinPath]);

  useEffect(() => {
    document.documentElement.classList.toggle("midnight", shouldBeMidnight);
    document.body.style.background = "var(--bg)";
  }, [shouldBeMidnight]);

  // Single, canonical navigate function — always uses pushState so deep links
  // and refreshes work correctly (Express serves index.html for all routes).
  const navigate = (path) => {
    window.history.pushState({}, "", path);
    setCurrentPath(path);
    window.scrollTo(0, 0);
  };

  // Auto-redirect authenticated users away from the landing page.
  // Run once on mount only — subsequent navigation is intentional.
  useEffect(() => {
    const hasSession = !!localStorage.getItem("herely.session");
    if (hasSession && !isHomeRoute && !isRoomRoute && !isScanQR && !isJoinPath && !isAuthCallback && !isAboutRoute && !isCopacabanaRoute) {
      navigate("/home");
    }
  // eslint-disable-next-line react-hooks/exhaustive-deps
  }, []);

  if (isAuthCallback) {
    return <AuthCallback onNavigate={navigate} />;
  }

  if (isRequestAccess) {
    return (
      <RequestAccess
        mode={t.mode}
        onModeToggle={() => setTweak("mode", midnight ? "light" : "midnight")}
        onNavigate={navigate}
      />
    );
  }

  if (isScanQR) {
    const session = JSON.parse(localStorage.getItem("herely.session") || "null");
    const userName = session?.user?.name || "";
    const activeRoomId = localStorage.getItem("herely.activeRoomId") || "studio4";
    return (
      <>
        <style>{window.HomeStyles}</style>
        <HomeNav
          mode={t.mode}
          onToggle={() => setTweak("mode", midnight ? "light" : "midnight")}
          userName={userName}
          activeRoomId={activeRoomId}
          onOpenRoom={null}
          onProfile={null}
          onNavigate={navigate}
        />
        <ScanQR onNavigate={navigate} />
      </>
    );
  }

  if (isAboutRoute) {
    return (
      <>
        <Nav mode={t.mode} onToggle={() => setTweak("mode", midnight ? "light" : "midnight")} onSignIn={() => navigate("/sign-in")} />
        <AboutPage onNavigate={navigate} />
      </>
    );
  }

  if (isCopacabanaRoute) {
    return <CopacabanaPage onNavigate={navigate} />;
  }

  if (isHomeRoute) {
    // PILOT_MODE: skip auth guard — everyone can access home
    // Original: if (!hasSession) { navigate("/sign-in"); return null; }
    return (
      <HomePage
        mode={t.mode}
        onModeToggle={() => setTweak("mode", midnight ? "light" : "midnight")}
        onNavigate={navigate}
      />
    );
  }

  if (isRoomRoute) {
    return <RoomPage onNavigate={navigate} />;
  }

  if (isJoinPath) {
    if (!onboardingComplete) {
      return <Onboarding onComplete={() => setOnboardingComplete(true)} />;
    }
    // Show bridge animation after onboarding, then room
    return <BridgeToRoom onNavigate={navigate} />;
  }

  return (
    <MainSite 
      mode={t.mode} 
      onModeToggle={() => setTweak("mode", midnight ? "light" : "midnight")}
      tweaks={t}
      onTweakChange={setTweak}
      onAuthSuccess={() => navigate("/home")}
      currentPath={currentPath}
      onNavigate={navigate}
    />
  );
}

ReactDOM.createRoot(document.getElementById("root")).render(<App />);
