/* Precitaville web demo — app shell, "routes" and page composition */

const { useState } = React;

const EVENTS = [
  { id: "jazz",   dow: "SUNDAY",   day: "26", mon: "MAY", time: "Noon",        glaze: "clay",    kind: "Live music",    place: "Precita Park",       title: "Precita Jazz in the park",     blurb: "Horns, strings, anyone who wants to sit in. Rain, fog, or shine — the butterfly garden has the best seats." },
  { id: "trees",  dow: "SATURDAY", day: "01", mon: "JUN", time: "9:00 a.m.",   glaze: "moss",    kind: "Volunteer",     place: "Folsom & Precita",   title: "Tree planting on Folsom",           blurb: "Coffee from Pinhole, shovels from us. A two-hour shift, then breakfast on the corner." },
  { id: "swap",   dow: "SUNDAY",   day: "09", mon: "JUN", time: "10:00 a.m.",  glaze: "lichen",  kind: "Plant swap",    place: "Precita Park",       title: "Spring plant swap",                 blurb: "Bring a cutting, take one home. No experience required, no money exchanged. Just dirt." },
  { id: "block",  dow: "SATURDAY", day: "22", mon: "JUN", time: "All day",     glaze: "mustard", kind: "Block party",   place: "Precita Avenue",     title: "Precita Block Party",               blurb: "Two blocks closed to cars. Music, food from twelve neighbors, kids' chalk, the fire engine on loan." },
  { id: "film",   dow: "FRIDAY",   day: "12", mon: "JUL", time: "8:30 p.m.",   glaze: "indigo",  kind: "Film night",    place: "Precita Park lawn",  title: "Films on the lawn: a 16mm program", blurb: "We've borrowed a working 16mm projector and three reels from the SF Public Library. Bring a blanket." },
  { id: "vote",   dow: "TUESDAY",  day: "17", mon: "JUL", time: "6:30 p.m.",   glaze: "pacific", kind: "Town meeting",  place: "Bernal Library",     title: "Neighborhood traffic-calming vote", blurb: "We're proposing four daylit intersections on Precita Ave. Come hear the plan, share thoughts, vote." },
];

const POSTS = [
  { id: "coyote", cat: "Field notes",   date: "May 18, 2026", title: "A coyote, a butter-yellow rowhouse, and the best slice on Mission", excerpt: "A short field guide to the corners of the neighborhood you might've walked past for years without really seeing.", body: [
    "If you've lived in Precitaville for longer than a season, you've probably seen her — the coyote, padding across Bonview at dawn, ears back, unhurried, on her way to wherever it is coyotes go.",
    "She's not the only resident worth noticing. There's the butter-yellow Edwardian at the corner of Precita and Folsom, the one with the painted lady trim and the rosebushes that have outlived three owners. There's the slice place on Mission whose menu hasn't changed since 2003 and whose dough hasn't either. There's the woman who hand-letters the chalkboard outside Pinhole every morning.",
    "These aren't landmarks. They're the texture. The neighborhood is made of them. We started this blog to write them down before we forget."
  ], pull: "The neighborhood is made of these things. We started this blog to write them down before we forget." },
  { id: "survey", cat: "Announcements", date: "May 10, 2026", title: "2025 Community Survey — what we heard", excerpt: "Two hundred and forty replies. Here's what neighbors said they want, in their own words.", body: ["Two hundred and forty of you replied, which is more than we expected and also more than the previous record (a 2014 survey about whether to rename Bernal Hill 'Sutrito,' which received seven responses, all from the same person)."] },
  { id: "music",  cat: "Events",        date: "May 03, 2026", title: "Precita Jazz is back for the season",                excerpt: "Sundays at noon, every Sunday, through October. Here's what to know.", body: ["Daniel Dickison and Philip Sossenheimer's Sunday jam in Precita Park has become, somehow, a tradition."] },
  { id: "shacks", cat: "History",       date: "Apr 26, 2026", title: "The earthquake-shack houses, still here",            excerpt: "After 1906, thousands of one-room cottages were built in city parks. A handful made it to Bernal.", body: ["After the 1906 earthquake, the city built thousands of temporary one-room cottages — \"earthquake shacks\" — in places like Golden Gate Park and the Presidio."] },
];

const PINNED_TOPICS = [
  { id: "lightingplan",  glaze: "mustard", icon: "💡", title: "Street lighting initiative",  blurb: "Three dark intersections on Precita Ave. We're mapping broken lights and applying for a city grant this summer." },
  { id: "treesplan",     glaze: "moss",    icon: "🌱", title: "Tree canopy expansion",        blurb: "Folsom and Precita have bare stretches. We're partnering with SF Parks to plant street trees where neighbors will water them." },
  { id: "parkupgrades",  glaze: "pacific", icon: "🏞", title: "Park infrastructure work",   blurb: "The bandshell roof, butterfly garden paths, picnic tables — catalogued and prioritized. Grants in progress." },
];

/* ============== Page: Neighbors ============== */
const LEADERS = [
  { name: "Marcus Webb",    role: "Events & Programs",     glaze: "clay",    initial: "M", bio: "Marcus has been organizing Precita Park events since 2019. He runs the Sunday jazz schedule and the annual block party. Come find him at the bandshell." },
  { name: "Sofia Reyes",    role: "The Fund",              glaze: "moss",    initial: "S", bio: "Sofia leads the Precitaville Fund — reaching out to neighbors, tracking investment priorities, and making sure money goes where the block needs it most." },
  { name: "David Lim",      role: "Communications",        glaze: "pacific", initial: "D", bio: "David writes The Precita Post newsletter and this website. He moved here in 2022 from Cole Valley and has been an embarrassingly fast convert to the north slope." },
  { name: "Carmen Ortega",  role: "Park & Infrastructure", glaze: "mustard", initial: "C", bio: "Carmen chairs the Park Committee and tracks every maintenance request, improvement grant, and city planning decision that touches Precita Park." },
  { name: "James Holloway", role: "Outreach",              glaze: "indigo",  initial: "J", bio: "James knocks on doors. Literally. He's mapped nearly every neighbor on Precita, Folsom, and Florida — and he knows who the quiet ones are too." },
  { name: "Aiko Tanaka",    role: "Youth & Schools",       glaze: "blush",   initial: "A", bio: "Aiko runs our school partnerships with Flynn and Revere, coordinates the College Hill Learning Garden days, and is always looking for more kids to get muddy." },
];

function NeighborsPage({ goto }) {
  return (
    <main>
      <div style={{ background: "var(--bone)", borderBottom: "1px solid var(--hair)", padding: "var(--space-8) 0 var(--space-7)" }}>
        <div className="wrap">
          <div className="eyebrow" style={{ color: "var(--clay-d)", marginBottom: 12 }}>The people behind Precitaville</div>
          <h1 style={{ fontFamily: "var(--font-display)", fontWeight: 300, fontVariationSettings: "'opsz' 72", fontSize: "clamp(44px,6vw,80px)", lineHeight: 0.97, letterSpacing: "-0.025em", margin: "0 0 var(--space-4)" }}>
            Who we <em style={{ fontStyle: "italic", fontWeight: 320, color: "var(--clay-d)" }}>are.</em>
          </h1>
          <p style={{ fontFamily: "var(--font-display)", fontStyle: "italic", fontSize: 20, color: "var(--charcoal)", maxWidth: "54ch", margin: 0 }}>
            Precitaville is run by its neighbors. No paid staff, no office. Just a handful of people who wanted to make the north slope of Bernal better — and then couldn't stop.
          </p>
        </div>
      </div>
      <section className="wrap section">
        <div className="section-head">
          <h2>Committee <em>directors</em></h2>
          <span className="meta">Want to join a committee? <a href="#" style={{ color: "var(--clay-d)" }}>Get in touch</a></span>
        </div>
        <div className="leader-grid">
          {LEADERS.map((l) => (
            <div key={l.name} className="leader-card">
              <div className={"glaze-bar glaze-" + l.glaze}></div>
              <div className="leader-body">
                <div className="leader-avatar" style={{ background: `var(--${l.glaze})`, color: "var(--snow)" }}>{l.initial}</div>
                <h4>{l.name}</h4>
                <div className="role">{l.role}</div>
                <p>{l.bio}</p>
              </div>
            </div>
          ))}
        </div>
      </section>
      <div style={{ background: "var(--mist)", padding: "var(--space-8) 0", borderTop: "1px solid var(--hair)" }}>
        <div className="wrap" style={{ display: "grid", gridTemplateColumns: "1fr 1fr", gap: "var(--space-9)", alignItems: "center" }}>
          <div>
            <div className="eyebrow" style={{ color: "var(--clay-d)", marginBottom: 12 }}>Get involved</div>
            <h2 style={{ fontFamily: "var(--font-display)", fontWeight: 380, fontSize: 44, lineHeight: 1.05, letterSpacing: "-0.015em", margin: "0 0 var(--space-4)" }}>We're always looking for more <em style={{ fontStyle: "italic" }}>good neighbors.</em></h2>
            <p style={{ color: "var(--charcoal)", maxWidth: "48ch", marginBottom: "var(--space-5)" }}>Whether you have two hours a month or twenty, there's a committee that could use you. Come to an event first — the rest tends to follow naturally.</p>
            <button className="btn" onClick={() => goto("join")}>Express interest →</button>
          </div>
          <div style={{ display: "grid", gridTemplateColumns: "1fr 1fr", gap: 12 }}>
            {["Park & green spaces", "Events & programming", "Communications", "The Fund", "Youth & schools", "Outreach"].map((c, i) => (
              <div key={c} style={{ background: "var(--snow)", borderRadius: 8, padding: "14px 16px", fontSize: 14, fontWeight: 500, color: "var(--ink)", boxShadow: "0 1px 2px rgba(31,37,48,0.04), 0 0 0 1px rgba(31,37,48,0.05)" }}>{c}</div>
            ))}
          </div>
        </div>
      </div>
      <Footer />
    </main>
  );
}

/* ============== Page: The Fund ============== */
function FundPage({ goto }) {
  const areas = [
    { glaze: "moss",    textColor: "var(--snow)", label: "Infrastructure", title: "Park infrastructure",    body: "The bandshell roof. The butterfly garden path. The picnic tables that have been broken since 2023. We're cataloguing everything and building a repair and improvement list." },
    { glaze: "pacific", textColor: "var(--snow)", label: "Green space",     title: "Street trees",           body: "Folsom and Precita have bare stretches. We're partnering with the city's urban forestry program to plant new trees where neighbors are willing to water them." },
    { glaze: "mustard", textColor: "var(--ink)",  label: "Safety",         title: "Lighting & safety",      body: "Three intersections on Precita Ave have broken lighting. We're mapping the gaps and will apply for a SFMTA grant in Q3 2026 — with neighborhood letters of support." },
    { glaze: "clay",    textColor: "var(--snow)", label: "Community",       title: "Micro-grants",           body: "We want to put small grants ($500–$2k) in the hands of neighbors with ideas — a mural, a community fridge, a tool library. Simple application, neighbor review." },
    { glaze: "indigo",  textColor: "var(--snow)", label: "Events",         title: "Events underwriting",    body: "The block party, the film night, the plant swap — none of these are free to run. The Fund helps cover permits, equipment, and the occasional sound system." },
    { glaze: "blush",   textColor: "var(--ink)",  label: "Youth",          title: "Youth programs",         body: "Partnering with Flynn and Revere to fund after-school garden time, park cleanup days, and neighborhood history walks for 3rd through 5th graders." },
  ];
  return (
    <main>
      <div className="fund-hero">
        <div className="wrap">
          <div className="eyebrow" style={{ color: "var(--lichen)", marginBottom: 12 }}>The Precitaville Fund</div>
          <h1>Investing in <em>the block.</em></h1>
          <p>Neighbors pooling small contributions to make lasting improvements to Precita Park, the surrounding streets, and the programs that make this community worth belonging to. Every dollar raised stays on the north slope.</p>
          <button className="btn fund-btn" onClick={() => goto("join")}>Become a Fund member →</button>
        </div>
      </div>

      <section className="wrap section">
        <div className="section-head">
          <h2>How we invest <em>resources.</em></h2>
          <span className="meta">2026 priorities — capital, time, and neighbor energy</span>
        </div>
        <div style={{ background: "var(--mist)", borderRadius: 8, padding: "var(--space-7) var(--space-6)", marginBottom: "var(--space-8)" }}>
          <div style={{ display: "grid", gridTemplateColumns: "2fr 1fr", gap: "var(--space-9)", alignItems: "start" }}>
            <div>
              <div className="eyebrow" style={{ color: "var(--moss-d)", marginBottom: 12 }}>Precitaville Fund Charter</div>
              <p style={{ color: "var(--charcoal)", fontSize: 16, lineHeight: 1.6, margin: 0, maxWidth: "52ch" }}>We wrote down our principles. How we listen to the neighborhood, how we decide what matters, how we measure impact, and what we won't do (even if someone asks). Mostly, we believe that neighbors with a check in hand — ready, organized, and waiting — can shift what the city prioritizes. Momentum matters. Timing matters. If we wait for the city to move first, the window closes.</p>
            </div>
            <div style={{ textAlign: "center" }}>
              <button className="btn glaze-moss" onClick={() => goto("join")} style={{ width: "100%", justifyContent: "center", marginBottom: 12 }}>Download charter →</button>
              <p style={{ fontSize: 13, color: "var(--stone)", margin: 0 }}>2 min read · PDF</p>
            </div>
          </div>
        </div>
        <div className="fund-areas">
          {areas.map((a) => (
            <div key={a.title} className="fund-area">
              <div className="glaze-tag" style={{ background: `var(--${a.glaze})`, color: a.textColor }}>{a.label}</div>
              <h4>{a.title}</h4>
              <p>{a.body}</p>
            </div>
          ))}
        </div>
        <div className="fund-total">
          <div>
            <div className="eyebrow" style={{ color: "var(--moss-d)", marginBottom: 8 }}>2026 goal</div>
            <h3>$24,000 from 120 neighbors</h3>
          </div>
          <div>
            <p>That's $200 a year per household — less than a dinner out. Every Fund member gets a vote in how the money is allocated and a say in next year's priorities.</p>
          </div>
          <div>
            <button className="btn glaze-moss" onClick={() => goto("join")}>Join the Fund →</button>
          </div>
        </div>
      </section>
      <Newsletter />
      <Footer />
    </main>
  );
}

/* ============== Page: Home ============== */
function HomePage({ goto, openJoin }) {
  const upcoming = EVENTS.slice(0, 5);
  const featured = upcoming[0];
  const rest = upcoming.slice(1);
  return (
    <>
      <Hero onPrimary={() => goto("newsevents")} onSecondary={() => goto("news", POSTS[0])} onFund={() => goto("fund")} onOrganize={() => goto("newsevents")} onConnect={() => goto("neighbors")} />
      <section className="section wrap">
        <div className="section-head">
          <h2>What's on <em>this week</em></h2>
          <span className="meta">Updated Fri · May 23</span>
        </div>
        <div style={{ display: "grid", gap: 24 }}>
          <EventCard ev={featured} featured onClick={(ev) => goto("event", ev)} />
          <div style={{ display: "grid", gridTemplateColumns: "1fr 1fr", gap: 24 }}>
            {rest.map((ev) => <EventCard key={ev.id} ev={ev} onClick={(ev) => goto("event", ev)} />)}
          </div>
        </div>
        <div style={{ marginTop: 48, textAlign: "center" }}>
          <button className="btn secondary" onClick={() => goto("newsevents")}>See the full calendar →</button>
        </div>
      </section>

      <Masthead onClick={openJoin} />

      <section className="section wrap">
        <div className="section-head">
          <h2>From the <em>news desk</em></h2>
          <span className="meta">Field notes, announcements, and history</span>
        </div>
        <div style={{ display: "grid", gridTemplateColumns: "repeat(3, 1fr)", gap: 24 }}>
          {POSTS.slice(0, 3).map((p) => <BlogCard key={p.id} post={p} onClick={(p) => goto("news", p)} />)}
        </div>
      </section>

      <Newsletter />
    </>
  );
}

/* ============== Page: News & Events ============== */
function NewsEventsPage({ goto }) {
  const [tab, setTab] = React.useState("events");
  
  return (
    <main className="wrap section">
      <div className="section-head">
        <h2>News <em>& Events</em></h2>
        <span className="meta">What's happening on the north slope</span>
      </div>

      {/* Pinned topics — horizontal scroll below title */}
      <div style={{ marginBottom: "var(--space-8)", overflow: "hidden" }}>
        <div style={{ display: "flex", alignItems: "baseline", gap: 16, marginBottom: 16 }}>
          <h3 style={{ fontFamily: "var(--font-display)", fontWeight: 320, fontSize: 20, margin: 0, letterSpacing: "-0.02em" }}>Longer-term <em style={{ fontStyle: "italic", color: "var(--clay-d)" }}>initiatives</em></h3>
          <span className="meta">Ongoing efforts</span>
        </div>
        <div style={{ overflowX: "auto", marginRight: "calc(var(--space-6) * -1)", paddingRight: "var(--space-6)", paddingBottom: 4 }}>
          <div style={{ display: "flex", gap: 16, width: "max-content" }}>
            {PINNED_TOPICS.map((t) => (
              <div key={t.id} style={{ background: `var(--${t.glaze})`, color: t.glaze === "mustard" || t.glaze === "blush" || t.glaze === "lichen" ? "var(--ink)" : "var(--snow)", borderRadius: 8, padding: "22px 26px", display: "flex", flexDirection: "column", gap: 10, width: 300, flexShrink: 0 }}>
                <h4 style={{ fontFamily: "var(--font-display)", fontWeight: 400, fontSize: 19, margin: 0, lineHeight: 1.1 }}>{t.title}</h4>
                <p style={{ margin: 0, fontSize: 14, lineHeight: 1.5, opacity: 0.92 }}>{t.blurb}</p>
              </div>
            ))}
          </div>
        </div>
      </div>

      {/* Filter tabs */}
      <div style={{ display: "flex", gap: 16, marginBottom: 48, borderBottom: "1px solid var(--hair)", paddingBottom: 16 }}>
        <button onClick={() => setTab("events")} style={{ 
          background: "none", border: "none", padding: 0, fontSize: 15, fontWeight: 500, color: tab === "events" ? "var(--ink)" : "var(--charcoal)", 
          cursor: "pointer", paddingBottom: 8, borderBottom: tab === "events" ? "2px solid var(--clay)" : "none", transition: "all var(--t-fast) var(--ease)"
        }}>Events</button>
        <button onClick={() => setTab("news")} style={{ 
          background: "none", border: "none", padding: 0, fontSize: 15, fontWeight: 500, color: tab === "news" ? "var(--ink)" : "var(--charcoal)", 
          cursor: "pointer", paddingBottom: 8, borderBottom: tab === "news" ? "2px solid var(--clay)" : "none", transition: "all var(--t-fast) var(--ease)"
        }}>News</button>
      </div>

      {/* Events tab */}
      {tab === "events" && (
        <div style={{ display: "grid", gridTemplateColumns: "repeat(2, 1fr)", gap: 24, marginBottom: 48 }}>
          {EVENTS.map((ev) => <EventCard key={ev.id} ev={ev} onClick={(ev) => goto("event", ev)} />)}
        </div>
      )}

      {/* News tab */}
      {tab === "news" && (
        <div style={{ display: "grid", gridTemplateColumns: "repeat(3, 1fr)", gap: 24, marginBottom: 48 }}>
          {POSTS.map((p) => <BlogCard key={p.id} post={p} onClick={(p) => goto("news", p)} />)}
        </div>
      )}
    </main>
  );
}

/* ============== Page: Event detail ============== */
function EventPage({ ev, goto, openRsvp }) {
  return (
    <main className="wrap">
      <a href="#" className="page-back" onClick={(e) => { e.preventDefault(); goto("events"); }}>← Back to events</a>
      <section className="detail-hero">
        <div className="eyebrow" style={{ color: "var(--clay-d)" }}>{ev.kind} · Free · All ages</div>
        <h1>{ev.title}</h1>
        <div className="detail-meta">
          <div className="item"><span className="k">When</span><span className="v">{ev.dow.charAt(0) + ev.dow.slice(1).toLowerCase()}, {ev.mon} {ev.day} · {ev.time}</span></div>
          <div className="item"><span className="k">Where</span><span className="v">{ev.place}</span></div>
          <div className="item"><span className="k">Cost</span><span className="v">Free</span></div>
          <div className="item"><span className="k">Hosted by</span><span className="v">Friends of Precitaville</span></div>
        </div>
      </section>
      <section className="detail-body">
        <article>
          <div className="full-bleed-photo" />
          <p className="lede" style={{ fontSize: 22, marginBottom: 32 }}>{ev.blurb}</p>
          <p>The bandshell is the small wooden one near the eastern playground, the one with the painted-green roof. It's older than most of us — built in the 1950s, repainted four times, repaired more often than the city would prefer to admit. On Sundays from noon to about two, Precita Jazz Collective sets up under it. Daniel on guitar, Philip on bass, and a rotating cast of neighbors and ringers on horns, keys, and voice.</p>
          <p>You don't need to RSVP. You don't need to bring anything except a chair if you want a seat. The butterfly garden, on the south side of the park, is the unofficial premium section — slightly elevated, in the shade, with a clear sight line.</p>
          <blockquote>"Bring an instrument or just yourself. The jam is open to anyone."<br/><span style={{ fontSize: 14, fontStyle: "normal", display: "block", marginTop: 8, color: "var(--stone)" }}>— Daniel Dickison, Precita Jazz Collective</span></blockquote>
          <p>If it's raining hard, we move to the Bernal Library community room across Folsom. Light rain, we stay put — the bandshell roof handles it.</p>
          <div style={{ marginTop: 32 }}><button className="btn" onClick={() => openRsvp(ev)}>RSVP for {ev.mon} {ev.day} →</button></div>
        </article>
        <aside className="aside">
          <div className="panel">
            <h4>Where</h4>
            <ParkMap mapId="aside" />
            <p style={{ fontSize: 14, color: "var(--charcoal)", marginTop: 14, marginBottom: 0, lineHeight: 1.5 }}>Precita Park is the long rectangular park bounded by Precita, Folsom, Alabama, and Florida streets.</p>
          </div>
          <div className="panel">
            <h4>Bring</h4>
            <ul style={{ fontSize: 14, color: "var(--charcoal)", marginTop: 8, lineHeight: 1.5, paddingLeft: "1.1em" }}>
              <li>A folding chair or a blanket</li>
              <li>Sunglasses (it's the sunny side of the city)</li>
              <li>An instrument, if you have one</li>
              <li>A friend, especially a new one</li>
            </ul>
          </div>
        </aside>
      </section>
    </main>
  );
}

/* ============== Page: News post ============== */
function NewsPage({ post, goto }) {
  return (
    <main className="wrap">
      <a href="#" className="page-back" onClick={(e) => { e.preventDefault(); goto("home"); }}>← Back home</a>
      <section className="detail-hero">
        <div className="eyebrow" style={{ color: "var(--clay-d)" }}>{post.cat} · {post.date}</div>
        <h1>{post.title}</h1>
        <div className="detail-meta">
          <div className="item"><span className="k">Written by</span><span className="v">Mike Doherty</span></div>
          <div className="item"><span className="k">Read time</span><span className="v">4 minutes</span></div>
          <div className="item"><span className="k">Filed under</span><span className="v">{post.cat}</span></div>
        </div>
      </section>
      <section className="detail-body">
        <article>
          <div className="full-bleed-photo" />
          <p className="lede" style={{ fontSize: 24, marginBottom: 32 }}>{post.excerpt}</p>
          {post.body.map((para, i) => <p key={i}>{para}</p>)}
          {post.pull && <blockquote>{post.pull}</blockquote>}
          <p>If you've got a corner you love — a place, a person, a tradition we should write up next — drop us a note at <a href="mailto:hi@precitaville.org">hi@precitaville.org</a>. We read everything.</p>
          <hr />
          <div className="eyebrow" style={{ marginTop: 24, marginBottom: 16 }}>More news</div>
          <div style={{ display: "grid", gridTemplateColumns: "1fr 1fr", gap: 20 }}>
            {POSTS.filter((p) => p.id !== post.id).slice(0, 2).map((p) => <BlogCard key={p.id} post={p} onClick={(p) => goto("news", p)} />)}
          </div>
        </article>
        <aside className="aside">
          <div className="panel">
            <h4>About the author</h4>
            <p style={{ fontSize: 14, color: "var(--charcoal)", margin: "8px 0 0", lineHeight: 1.5 }}>Mike runs the Bernal Connect newsletter and lives three blocks from the park. He's been writing about the neighborhood since 2019.</p>
          </div>
          <div className="panel">
            <h4>Subscribe</h4>
            <p style={{ fontSize: 14, color: "var(--charcoal)", margin: "8px 0 14px", lineHeight: 1.5 }}>Get The Precita Post in your inbox once a month.</p>
            <button className="btn" style={{ width: "100%", justifyContent: "center" }}>Sign up →</button>
          </div>
        </aside>
      </section>
    </main>
  );
}

/* ============== App shell ============== */
function App() {
  const [route, setRoute] = useState({ page: "home" });
  const [join, setJoin] = useState(false);
  const [rsvpEv, setRsvpEv] = useState(null);

  const goto = (page, data) => {
    if (page === "join") { setJoin(true); return; }
    if (page === "event") { setRoute({ page: "event", ev: data }); window.scrollTo(0, 0); return; }
    if (page === "news")  { setRoute({ page: "news",  post: data || POSTS[0] }); window.scrollTo(0, 0); return; }
    setRoute({ page });
    window.scrollTo(0, 0);
  };
  const openRsvp = (ev) => setRsvpEv(ev);
  const navPage = route.page === "event" ? "newsevents" : route.page === "news" ? "newsevents" : route.page;

  return (
    <>
      <Nav page={navPage} onNavigate={(p) => goto(p === "newsevents" ? "newsevents" : p)} />
      {route.page === "home"      && <HomePage      goto={goto} openJoin={() => setJoin(true)} />}
      {route.page === "newsevents" && <NewsEventsPage goto={goto} />}
      {route.page === "event"     && <EventPage     ev={route.ev}   goto={goto} openRsvp={openRsvp} />}
      {route.page === "news"      && <NewsPage      post={route.post} goto={goto} />}
      {route.page === "neighbors" && <NeighborsPage goto={goto} />}
      {route.page === "fund"      && <FundPage      goto={goto} />}
      {route.page !== "home" && route.page !== "newsevents" && route.page !== "event" && route.page !== "news" && route.page !== "neighbors" && route.page !== "fund" && (
        <main className="wrap section">
          <div className="section-head"><h2>{route.page}</h2><span className="meta">Coming soon</span></div>
        </main>
      )}
      {route.page !== "neighbors" && route.page !== "fund" && <Footer />}
      <JoinModal open={join} onClose={() => setJoin(false)} />
      <RsvpModal ev={rsvpEv} onClose={() => setRsvpEv(null)} />
    </>
  );
}

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