// SCN2A Family Map — a community connection map of Australia.
//
// Families add themselves via a short external survey; each becomes a pin on
// the map and a card in the list, and its state's count ticks up. Where a
// family opts in, others can send them a private message relayed through the
// organisation (the sender's email is never exposed).
//
// The map starts EMPTY by design: every state shows 0 until families join.
// Reviewed families load from families.json; messages relay via /api/relay.js;
// survey CTAs open FMAP_SURVEY_URL (see the constants below). State geometry is
// baked locally in lib/au-states-geo.js (window.AU_STATES) — no runtime CDN or
// D3 dependency.

// ---- Geometry + projection (baked offline, see lib/au-states-geo.js) ----
const AU = (typeof window !== 'undefined' && window.AU_STATES) || null;
const FMAP_STATES_GEO = AU ? AU.states : [];
const FMAP_ANCHORS = AU ? AU.anchors : {};
const FMAP_PROJ = (AU && AU.proj) || { scale: 1100, tx: 500, ty: 370, lng0: 133, lat0: -27 };
const FMAP_VIEWBOX = (AU && AU.viewBox) || '0 0 1000 780';

const FMAP_D2R = Math.PI / 180;
const fmapMercY = (deg) => Math.log(Math.tan(Math.PI / 4 + (deg * FMAP_D2R) / 2));
const FMAP_MY0 = fmapMercY(FMAP_PROJ.lat0);
// Project [lng,lat] to the same pixel space as the baked polygons/badges.
function fmapProject(lng, lat) {
  return [
    FMAP_PROJ.tx + FMAP_PROJ.scale * ((lng - FMAP_PROJ.lng0) * FMAP_D2R),
    FMAP_PROJ.ty - FMAP_PROJ.scale * (fmapMercY(lat) - FMAP_MY0),
  ];
}

const STATE_NAMES = (AU && AU.names) || {
  NSW: 'New South Wales', VIC: 'Victoria', QLD: 'Queensland', SA: 'South Australia',
  WA: 'Western Australia', TAS: 'Tasmania', NT: 'Northern Territory', ACT: 'Australian Capital Territory',
};
const STATE_ORDER = ['All', 'NSW', 'VIC', 'QLD', 'SA', 'WA', 'TAS', 'NT', 'ACT'];

// External "Add your family" survey form (Google Forms / Jotform / Typeform).
// Paste the form URL here and every survey CTA opens it. Until it is set, the
// CTAs fall back to the Contact page so they are never a dead end.
const FMAP_SURVEY_URL = null;

// Message relay endpoint (the Vercel serverless function in /api/relay.js).
// Receives a family-to-family message and emails it to the org, which
// coordinates the introduction, the sender's details are never shown to the
// recipient. If the POST fails (e.g. local static preview before deploy), the
// modal falls back to a localStorage write so the flow still completes.
const FMAP_RELAY_ENDPOINT = '/api/relay';

// Reviewed families are served from a static JSON file (curated by the team
// after each survey response, per the "we add your pin" step). Ships as [] —
// add approved records to vercel-deploy/families.json and redeploy. Record:
//   { id, name, region, state, role, childAge, connect, since, topics, blurb, lat, lng }
//   state ∈ NSW VIC QLD SA WA TAS NT ACT ; connect controls the "Send a message" button.
// Kept outside /assets so it dodges the year-long immutable cache header.
const FMAP_FAMILIES_URL = 'families.json';

const FMAP_SUPPORT_EMAIL = 'support@scn2aaustralia.org';
const FMAP_MSG_KEY = 'scn2a_au_messages_v1';

// Sample families (NOT shown) — copy any into FAMILIES to preview the populated map.
// eslint-disable-next-line no-unused-vars
const SAMPLE_FAMILIES = [
  { id: 'f1', name: 'The Nguyen', region: 'Western Sydney', state: 'NSW', role: 'Parents', childAge: 6, connect: true, since: '2026', topics: 'Schooling & NDIS', blurb: "Our son was diagnosed at 14 months. We've learned a lot about navigating the NDIS and would love to share notes with other NSW families.", lat: -33.81, lng: 150.92 },
  { id: 'f4', name: 'The Williams', region: 'Inner Melbourne', state: 'VIC', role: 'Dad', childAge: 5, connect: true, since: '2026', topics: 'Therapies & AAC', blurb: "Our daughter uses an AAC device and we're always keen to swap ideas on communication and therapy with other Victorian families.", lat: -37.81, lng: 144.96 },
  { id: 'f12', name: 'The Lee', region: 'Perth', state: 'WA', role: 'Parents', childAge: 5, connect: true, since: '2026', topics: 'WA services', blurb: "Connecting WA families feels important, we're so far from the east coast. Reach out, we'd love to build something local.", lat: -31.95, lng: 115.86 },
];

// ---- Per-state count badge (circle + number + abbreviation) ----
function FamilyMapBadge({ abbr, count }) {
  const a = FMAP_ANCHORS[abbr];
  if (!a) return null;
  const has = count > 0;
  return (
    <g aria-hidden="true">
      {a.nudged && <line x1={a.ax} y1={a.ay} x2={a.bx} y2={a.by} stroke="#4A7EC7" strokeWidth="1" />}
      <circle cx={a.bx} cy={a.by} r="19" fill={has ? '#1E3A6E' : '#F2EFE9'} stroke={has ? '#1E3A6E' : '#D5CFBF'} strokeWidth="1.5" />
      <text x={a.bx} y={a.by} textAnchor="middle" dominantBaseline="central" fontSize="17" fontWeight="800" fill={has ? '#FFFFFF' : '#1E3A6E'}>{count}</text>
      <text x={a.bx} y={a.by + 31} textAnchor="middle" fontSize="9.5" fontWeight="700" fill="#6B6659" style={{ letterSpacing: '0.08em' }}>{abbr}</text>
    </g>
  );
}

// ---- Side panel: a selected family's detail card ----
function SelectedFamily({ fam, onMessage }) {
  return (
    <div className="fmap-rise" key={fam.id} style={{ background: '#fff', border: '1px solid #D5CFBF', borderRadius: 8, padding: 24, boxShadow: '0 1px 2px rgba(13,27,42,0.06), 0 1px 3px rgba(13,27,42,0.08)' }}>
      <div style={{ display: 'flex', alignItems: 'center', gap: 8, marginBottom: 16, flexWrap: 'wrap' }}>
        <span style={{ display: 'inline-flex', alignItems: 'center', padding: '4px 10px', borderRadius: 3, background: '#E8E3DA', fontSize: 11, fontWeight: 600, color: '#0D1B2A' }}>{STATE_NAMES[fam.state]}</span>
        <span style={{ fontSize: 12, color: '#6B6659' }}>{fam.region}</span>
        {fam.connect && (
          <span style={{ display: 'inline-flex', alignItems: 'center', gap: 5, marginLeft: 'auto', fontSize: 11, fontWeight: 600, color: '#4A7EC7' }}>
            <span style={{ width: 6, height: 6, borderRadius: 999, background: '#4A7EC7' }} />Open to connect
          </span>
        )}
      </div>
      <h3 style={{ fontSize: 22, fontWeight: 700, letterSpacing: '-0.01em', margin: '0 0 4px', color: '#0D1B2A' }}>{fam.name}'s family</h3>
      <div style={{ fontSize: 13, color: '#6B6659', marginBottom: 16 }}>{fam.role} · child living with SCN2A, age {fam.childAge}</div>
      <p style={{ fontSize: 15, lineHeight: 1.6, color: '#0D1B2A', margin: '0 0 20px' }}>{fam.blurb}</p>
      <div style={{ display: 'grid', gridTemplateColumns: '1fr 1fr', borderTop: '1px solid #D5CFBF', borderBottom: '1px solid #D5CFBF', margin: '0 0 20px', padding: '14px 0' }}>
        <div>
          <div className="eyebrow" style={{ color: '#6B6659', marginBottom: 4 }}>On the map since</div>
          <div style={{ fontSize: 15, fontWeight: 600, color: '#0D1B2A' }}>{fam.since}</div>
        </div>
        <div>
          <div className="eyebrow" style={{ color: '#6B6659', marginBottom: 4 }}>Happy to talk about</div>
          <div style={{ fontSize: 14, color: '#0D1B2A' }}>{fam.topics}</div>
        </div>
      </div>
      {fam.connect ? (
        <>
          <Button variant="navy" full onClick={() => onMessage(fam)}>Send {fam.name} a message</Button>
          <p style={{ fontSize: 11.5, color: '#6B6659', lineHeight: 1.5, margin: '12px 0 0', textAlign: 'center' }}>Messages are private. We never share your email, {fam.name} only sees it if they choose to reply.</p>
        </>
      ) : (
        <div style={{ textAlign: 'center', fontSize: 13, color: '#6B6659', padding: 12, background: '#E8E3DA', borderRadius: 5, lineHeight: 1.5 }}>This family is on the map but has chosen not to receive messages right now.</div>
      )}
    </div>
  );
}

// ---- Private-message relay modal (compose + sent) ----
function MessageModal({ family, onClose }) {
  const [draft, setDraft] = React.useState({ name: '', state: '', contact: '', message: '', allowEmail: true, error: '' });
  const [sent, setSent] = React.useState(false);
  const [sending, setSending] = React.useState(false);
  const dialogRef = React.useRef(null);
  const restoreRef = React.useRef(null);

  // Focus trap + Escape + restore focus, matching the site's other dialogs.
  React.useEffect(() => {
    restoreRef.current = document.activeElement;
    const dlg = dialogRef.current;
    const focusable = () => dlg ? Array.from(dlg.querySelectorAll('a[href], button, input, textarea, [tabindex]:not([tabindex="-1"])')).filter(el => !el.disabled && el.offsetParent !== null) : [];
    const els = focusable();
    if (els.length) els[0].focus();
    const onKey = (e) => {
      if (e.key === 'Escape') { onClose(); return; }
      if (e.key === 'Tab') {
        const f = focusable(); if (!f.length) return;
        const first = f[0], last = f[f.length - 1];
        if (e.shiftKey && document.activeElement === first) { e.preventDefault(); last.focus(); }
        else if (!e.shiftKey && document.activeElement === last) { e.preventDefault(); first.focus(); }
      }
    };
    document.addEventListener('keydown', onKey);
    return () => { document.removeEventListener('keydown', onKey); if (restoreRef.current && restoreRef.current.focus) restoreRef.current.focus(); };
  }, [onClose]);

  const send = async () => {
    if (!draft.message || draft.message.trim().length < 4) {
      setDraft({ ...draft, error: 'Please write a short message before sending.' });
      return;
    }
    if (draft.contact && !/^[^@\s]+@[^@\s]+\.[^@\s]+$/.test(draft.contact.trim())) {
      setDraft({ ...draft, error: 'That email address does not look right, please check it.' });
      return;
    }
    const payload = {
      to: family.id, toName: family.name,
      fromName: draft.name || 'A family', fromState: draft.state || '',
      contact: draft.contact.trim(), message: draft.message.trim(), allowEmail: draft.allowEmail,
    };
    setSending(true);
    try {
      // Relay through the org. The endpoint emails our inbox; the sender's
      // details are never exposed to the recipient family.
      const res = await fetch(FMAP_RELAY_ENDPOINT, {
        method: 'POST', headers: { 'Content-Type': 'application/json' }, body: JSON.stringify(payload),
      });
      if (!res.ok) throw new Error('relay-failed');
      setSent(true);
    } catch (e) {
      // Fallback for static previews / before the relay is deployed: store the
      // message locally so the flow still completes. Remove once /api/relay is live.
      try {
        const prev = JSON.parse(localStorage.getItem(FMAP_MSG_KEY) || '[]');
        prev.push({ ...payload, ts: Date.now() });
        localStorage.setItem(FMAP_MSG_KEY, JSON.stringify(prev));
      } catch (e2) { /* ignore storage errors */ }
      setSent(true);
    } finally {
      setSending(false);
    }
  };

  const inputStyle = { width: '100%', boxSizing: 'border-box', padding: '10px 12px', border: '1px solid #D5CFBF', borderRadius: 5, fontFamily: 'inherit', fontSize: 14, color: '#0D1B2A', background: '#fff' };

  return (
    <div className="fmap-overlay" role="presentation" onClick={onClose}
      style={{ position: 'fixed', inset: 0, zIndex: 120, background: 'rgba(13,27,42,0.55)', display: 'flex', alignItems: 'center', justifyContent: 'center', padding: 24 }}>
      <div ref={dialogRef} role="dialog" aria-modal="true" aria-label={`Send ${family.name}'s family a private message`} onClick={(e) => e.stopPropagation()}
        style={{ background: '#F7F4F0', borderRadius: 8, maxWidth: 520, width: '100%', boxShadow: '0 8px 24px rgba(13,27,42,0.12)', overflow: 'hidden' }}>
        <div style={{ background: '#1E3A6E', color: '#F7F4F0', padding: '22px 28px' }}>
          <div style={{ display: 'flex', justifyContent: 'space-between', alignItems: 'flex-start', gap: 16 }}>
            <div>
              <div className="eyebrow" style={{ color: '#4A7EC7', marginBottom: 8 }}>Private message</div>
              <h3 style={{ fontSize: 20, fontWeight: 700, margin: 0, color: '#fff' }}>Reach {family.name}'s family</h3>
              <div style={{ fontSize: 13, color: '#B9C2D6', marginTop: 4 }}>{STATE_NAMES[family.state]} · {family.region}</div>
            </div>
            <button onClick={onClose} aria-label="Close" style={{ background: 'none', border: 'none', color: '#B9C2D6', fontSize: 24, lineHeight: 1, cursor: 'pointer', padding: 0 }}>×</button>
          </div>
        </div>

        {!sent ? (
          <div style={{ padding: '24px 28px' }}>
            <div style={{ display: 'flex', gap: 10, padding: '12px 14px', background: '#E5EDF8', borderRadius: 5, marginBottom: 20 }}>
              <span style={{ color: '#4A7EC7', fontWeight: 700, fontSize: 14, flexShrink: 0 }}>✓</span>
              <p style={{ fontSize: 12.5, lineHeight: 1.5, color: '#0D1B2A', margin: 0 }}>We pass your message to {family.name} through SCN2A Australia. They see your first name and message, never your email, until they choose to reply.</p>
            </div>
            <div style={{ display: 'grid', gridTemplateColumns: '1fr 1fr', gap: 14, marginBottom: 16 }}>
              <div>
                <label style={{ display: 'block', fontSize: 11, fontWeight: 600, color: '#0D1B2A', marginBottom: 6 }}>Your first name</label>
                <input type="text" value={draft.name} onChange={(e) => setDraft({ ...draft, name: e.target.value, error: '' })} placeholder="e.g. Sam" style={inputStyle} />
              </div>
              <div>
                <label style={{ display: 'block', fontSize: 11, fontWeight: 600, color: '#0D1B2A', marginBottom: 6 }}>Your state</label>
                <input type="text" value={draft.state} onChange={(e) => setDraft({ ...draft, state: e.target.value, error: '' })} placeholder="e.g. NSW" style={inputStyle} />
              </div>
            </div>
            <div style={{ marginBottom: 16 }}>
              <label style={{ display: 'block', fontSize: 11, fontWeight: 600, color: '#0D1B2A', marginBottom: 6 }}>Your email <span style={{ fontWeight: 500, color: '#6B6659' }}>(so we can pass on a reply)</span></label>
              <input type="email" value={draft.contact} onChange={(e) => setDraft({ ...draft, contact: e.target.value, error: '' })} placeholder="you@example.com" style={inputStyle} />
            </div>
            <label style={{ display: 'block', fontSize: 11, fontWeight: 600, color: '#0D1B2A', marginBottom: 6 }}>Your message</label>
            <textarea value={draft.message} onChange={(e) => setDraft({ ...draft, message: e.target.value, error: '' })} placeholder="Hi, we're also an SCN2A family and would love to connect…" rows="4" style={{ ...inputStyle, lineHeight: 1.5, resize: 'vertical' }} />
            <label style={{ display: 'flex', alignItems: 'flex-start', gap: 9, margin: '16px 0 0', cursor: 'pointer' }}>
              <input type="checkbox" checked={draft.allowEmail} onChange={(e) => setDraft({ ...draft, allowEmail: e.target.checked })} style={{ marginTop: 2, width: 16, height: 16, accentColor: '#1E3A6E' }} />
              <span style={{ fontSize: 12.5, lineHeight: 1.5, color: '#0D1B2A' }}>Let {family.name} reply to me by email if they'd like to.</span>
            </label>
            {draft.error && <div role="alert" style={{ fontSize: 12.5, color: '#8E3B5E', marginTop: 14 }}>{draft.error}</div>}
            <div style={{ display: 'flex', gap: 10, justifyContent: 'flex-end', marginTop: 22 }}>
              <Button variant="outline" onClick={onClose}>Cancel</Button>
              <Button variant="navy" onClick={send}>{sending ? 'Sending…' : 'Send message'}</Button>
            </div>
          </div>
        ) : (
          <div style={{ padding: '36px 28px', textAlign: 'center' }}>
            <div style={{ width: 52, height: 52, borderRadius: 999, background: '#E5EDF8', display: 'flex', alignItems: 'center', justifyContent: 'center', margin: '0 auto 18px', color: '#4A7EC7', fontSize: 24, fontWeight: 700 }}>✓</div>
            <h3 style={{ fontSize: 20, fontWeight: 700, margin: '0 0 10px', color: '#0D1B2A' }}>Your message is on its way</h3>
            <p style={{ fontSize: 14.5, lineHeight: 1.6, color: '#0D1B2A', margin: '0 auto 22px', maxWidth: '38ch' }}>We've passed it to {family.name}'s family through SCN2A Australia. If they'd like to connect, you'll hear back from them directly. Thank you for reaching out.</p>
            <Button variant="navy" onClick={onClose}>Done</Button>
          </div>
        )}
      </div>
    </div>
  );
}

function FamilyMapPage({ navigate }) {
  const [families, setFamilies] = React.useState([]);
  const [selectedId, setSelectedId] = React.useState(null);
  const [hoverId, setHoverId] = React.useState(null);
  const [hoverState, setHoverState] = React.useState(null);
  const [filter, setFilter] = React.useState('All');
  const [modalFamily, setModalFamily] = React.useState(null);

  // Load the reviewed families list. Ships empty; the team adds approved
  // records to families.json. Failure (or a missing file) leaves the map empty.
  React.useEffect(() => {
    let alive = true;
    fetch(FMAP_FAMILIES_URL, { cache: 'no-cache' })
      .then(r => (r.ok ? r.json() : []))
      .then(d => { if (alive && Array.isArray(d)) setFamilies(d); })
      .catch(() => { /* keep empty on error */ });
    return () => { alive = false; };
  }, []);

  const startSurvey = (e) => {
    if (e && e.preventDefault) e.preventDefault();
    if (FMAP_SURVEY_URL) window.open(FMAP_SURVEY_URL, '_blank', 'noopener');
    else navigate('contact'); // graceful fallback until the survey URL is set
  };
  const scrollToMap = (e) => {
    if (e && e.preventDefault) e.preventDefault();
    const el = document.getElementById('family-map');
    if (el) el.scrollIntoView({ behavior: 'smooth' });
  };

  // Derived data
  const counts = families.reduce((a, f) => { a[f.state] = (a[f.state] || 0) + 1; return a; }, {});
  const statesWithFamilies = Object.keys(counts).length;
  const visible = families.filter(f => filter === 'All' || f.state === filter);
  const selected = families.find(f => f.id === selectedId) || null;
  const selPin = selected ? fmapProject(selected.lng, selected.lat) : null;
  const hasFamilies = families.length > 0;

  const stat = (n) => (n === 0 ? '0' : String(n));

  return (
    <div data-screen-label="SCN2A Family Map">

      {/* ============ HERO (navy feature band) ============ */}
      <section style={{ background: '#1E3A6E', color: '#F7F4F0', position: 'relative', overflow: 'hidden' }}>
        <div style={{ position: 'absolute', top: 0, left: 0, right: 0, height: 6, background: '#8E3B5E', zIndex: 2 }} />
        <NetworkMotif opacity={0.12} stroke="#fff" dense />
        <div className="container" style={{ position: 'relative', zIndex: 2, padding: '72px 32px 64px' }}>
          <div style={{ display: 'grid', gridTemplateColumns: '1.25fr 1fr', gap: 56, alignItems: 'center' }} className="stack-mobile">
            <div>
              <div className="eyebrow" style={{ color: '#4A7EC7', marginBottom: 20 }}>The SCN2A family map · Australia</div>
              <h1 className="hero-h1-mobile-lg" style={{ fontSize: 'clamp(34px, 4.2vw, 44px)', fontWeight: 800, letterSpacing: '-0.02em', lineHeight: 1.12, margin: '0 0 20px', color: '#fff', textWrap: 'balance' }}>You are not the only family. Let's find each other.</h1>
              <p className="hero-sub-mobile" style={{ fontSize: 17, lineHeight: 1.6, color: '#B9C2D6', maxWidth: '52ch', margin: '0 0 28px' }}>SCN2A is rare, and Australian families are spread across a vast country. This map brings us together. Add your family, see how many families are in your state, and reach others near you, privately, on your terms.</p>
              <div style={{ display: 'flex', flexWrap: 'wrap', gap: 12, alignItems: 'center' }}>
                <Button size="lg" variant="mulberry" onClick={startSurvey}>Put your family on the map →</Button>
                <Button size="lg" variant="outlineLight" onClick={scrollToMap}>See the map</Button>
              </div>
              <p style={{ fontSize: 12, color: '#B9C2D6', margin: '18px 0 0', opacity: 0.85 }}>Adding your family takes a short survey. You choose exactly what is shown and who can reach you.</p>
            </div>
            <div style={{ display: 'grid', gridTemplateColumns: '1fr 1fr', gap: 14 }}>
              <div style={{ background: '#18305B', border: '1px solid #26467F', borderRadius: 8, padding: 22 }}>
                <div style={{ fontSize: 38, fontWeight: 800, letterSpacing: '-0.02em', lineHeight: 1, color: '#fff' }}>{stat(families.length)}</div>
                <div style={{ fontSize: 13, color: '#B9C2D6', marginTop: 10, lineHeight: 1.45 }}>Families on the map across Australia.</div>
              </div>
              <div style={{ background: '#18305B', border: '1px solid #26467F', borderRadius: 8, padding: 22 }}>
                <div style={{ fontSize: 38, fontWeight: 800, letterSpacing: '-0.02em', lineHeight: 1, color: '#fff' }}>{stat(statesWithFamilies)}</div>
                <div style={{ fontSize: 13, color: '#B9C2D6', marginTop: 10, lineHeight: 1.45 }}>States &amp; territories with families so far.</div>
              </div>
              <div style={{ gridColumn: 'span 2', background: '#18305B', border: '1px solid #26467F', borderRadius: 8, padding: '18px 22px', display: 'flex', alignItems: 'center', gap: 14 }}>
                <span style={{ width: 8, height: 8, borderRadius: 999, background: '#4A7EC7', flexShrink: 0 }} />
                <span style={{ fontSize: 13, color: '#B9C2D6', lineHeight: 1.45 }}>The map starts empty. Every number grows as families add themselves, be one of the first.</span>
              </div>
            </div>
          </div>
        </div>
      </section>

      <Breadcrumbs items={[{ label: 'Support', to: 'support' }, { label: 'Family map' }]} navigate={navigate} />

      {/* ============ MAP + SIDE PANEL ============ */}
      <section id="family-map" style={{ background: '#F7F4F0', padding: '56px 0 32px' }}>
        <div className="container">
          <div style={{ display: 'flex', alignItems: 'flex-end', justifyContent: 'space-between', gap: 24, marginBottom: 24, flexWrap: 'wrap' }}>
            <div>
              <div className="eyebrow" style={{ color: '#6B6659', marginBottom: 10 }}>Families by state</div>
              <h2 className="h2-mobile" style={{ fontSize: 28, fontWeight: 700, letterSpacing: '-0.01em', margin: 0, color: '#0D1B2A' }}>SCN2A families across Australia</h2>
            </div>
            <div role="group" aria-label="Filter families by state" style={{ display: 'flex', gap: 8, flexWrap: 'wrap' }}>
              {STATE_ORDER.map(s => {
                const active = s === filter;
                const count = s === 'All' ? families.length : (counts[s] || 0);
                return (
                  <button key={s} onClick={() => setFilter(s)} aria-pressed={active}
                    style={{ background: active ? '#1E3A6E' : 'transparent', color: active ? '#F7F4F0' : '#0D1B2A', border: `1px solid ${active ? '#1E3A6E' : '#D5CFBF'}`, padding: '7px 13px', borderRadius: 999, fontFamily: 'inherit', fontSize: 12.5, fontWeight: 600, cursor: 'pointer' }}>
                    {s === 'All' ? 'All families' : s}<span style={{ opacity: 0.55, fontWeight: 500 }}> · {count}</span>
                  </button>
                );
              })}
            </div>
          </div>

          <div style={{ display: 'grid', gridTemplateColumns: '1fr 380px', gap: 24, alignItems: 'start' }} className="stack-mobile">

            {/* MAP CARD */}
            <div style={{ position: 'relative', background: '#fff', border: '1px solid #D5CFBF', borderRadius: 8, padding: 20, boxShadow: '0 1px 2px rgba(13,27,42,0.06), 0 1px 3px rgba(13,27,42,0.08)' }}>
              <svg viewBox={FMAP_VIEWBOX} style={{ width: '100%', height: 'auto', display: 'block' }} preserveAspectRatio="xMidYMid meet"
                role="img" aria-label={hasFamilies
                  ? `Map of Australia showing ${families.length} SCN2A families across ${statesWithFamilies} states and territories.`
                  : 'Map of Australia. No families are on the map yet, every state shows zero.'}>
                {/* state polygons */}
                <g>
                  {FMAP_STATES_GEO.map(st => (
                    <path key={st.abbr} className="fmap-state" d={st.d}
                      fill={hoverState === st.abbr ? '#E7ECF5' : '#E6DECF'}
                      stroke="#1E3A6E" strokeOpacity="0.55" strokeWidth="1.25" strokeLinejoin="round" strokeLinecap="round" vectorEffect="non-scaling-stroke"
                      onMouseEnter={() => setHoverState(st.abbr)} onMouseLeave={() => setHoverState(null)} />
                  ))}
                </g>
                {/* per-state count badges (incl. ACT leader line) */}
                <g>
                  {STATE_ORDER.filter(s => s !== 'All').map(abbr => (
                    <FamilyMapBadge key={abbr} abbr={abbr} count={counts[abbr] || 0} />
                  ))}
                </g>
                {/* faint halos behind pins */}
                <g aria-hidden="true">
                  {visible.map(f => {
                    const [x, y] = fmapProject(f.lng, f.lat);
                    const isSel = f.id === selectedId;
                    return <circle key={'h' + f.id} cx={x} cy={y} r={isSel ? 16 : 9} fill={isSel ? '#8E3B5E' : '#1E3A6E'} opacity="0.14" />;
                  })}
                </g>
                {/* selected pin pulse ring */}
                {selPin && <circle cx={selPin[0]} cy={selPin[1]} r="9" fill="#8E3B5E" className="fmap-pulse" />}
                {/* family pins */}
                <g>
                  {families.map(f => {
                    const [x, y] = fmapProject(f.lng, f.lat);
                    const isSel = f.id === selectedId;
                    const isHover = f.id === hoverId;
                    const dimmed = filter !== 'All' && f.state !== filter;
                    return (
                      <circle key={f.id} cx={x} cy={y} r={isSel ? 8 : (isHover ? 7 : 5.5)}
                        fill={isSel ? '#8E3B5E' : (isHover ? '#4A7EC7' : '#1E3A6E')} stroke="#FFFFFF" strokeWidth="2"
                        opacity={dimmed ? 0.22 : 1} style={{ cursor: 'pointer' }}
                        onClick={() => setSelectedId(f.id)} onMouseEnter={() => setHoverId(f.id)} onMouseLeave={() => setHoverId(null)} />
                    );
                  })}
                </g>
              </svg>

              {!AU && (
                <div style={{ position: 'absolute', inset: 20, display: 'flex', alignItems: 'center', justifyContent: 'center', background: 'rgba(247,244,240,0.7)' }}>
                  <span className="eyebrow" style={{ color: '#6B6659' }}>Map unavailable</span>
                </div>
              )}

              <div style={{ display: 'flex', justifyContent: 'space-between', alignItems: 'center', flexWrap: 'wrap', gap: 10, marginTop: 8, padding: '12px 4px 0', borderTop: '1px solid #D5CFBF' }}>
                <span style={{ display: 'inline-flex', alignItems: 'center', gap: 7, fontSize: 12, color: '#6B6659' }}>
                  <span style={{ display: 'inline-flex', alignItems: 'center', justifyContent: 'center', width: 18, height: 18, borderRadius: 999, background: '#E8E3DA', border: '1px solid #D5CFBF', fontSize: 9, fontWeight: 800, color: '#1E3A6E' }}>0</span>
                  The number in each state is how many families are on the map there
                </span>
                <span style={{ fontSize: 12, color: '#6B6659' }}>{visible.length} families shown</span>
              </div>
            </div>

            {/* SIDE PANEL */}
            <aside style={{ position: 'sticky', top: 92 }}>
              {selected ? (
                <SelectedFamily fam={selected} onMessage={setModalFamily} />
              ) : (
                <div style={{ background: '#fff', border: '1px solid #D5CFBF', borderRadius: 8, padding: '28px 24px', boxShadow: '0 1px 2px rgba(13,27,42,0.06), 0 1px 3px rgba(13,27,42,0.08)', textAlign: 'center' }}>
                  <div style={{ width: 48, height: 48, borderRadius: 999, background: '#E5EDF8', display: 'flex', alignItems: 'center', justifyContent: 'center', margin: '0 auto 16px' }}>
                    <i data-lucide="map-pin" style={{ width: 22, height: 22, color: '#1E3A6E' }} />
                  </div>
                  <h3 style={{ fontSize: 19, fontWeight: 700, letterSpacing: '-0.01em', margin: '0 0 8px', color: '#0D1B2A' }}>No families on the map, yet</h3>
                  <p style={{ fontSize: 14, lineHeight: 1.6, color: '#0D1B2A', margin: '0 0 20px' }}>Be one of the first. Add your family and start the SCN2A Australia community map for everyone who comes after you.</p>
                  <Button variant="navy" full onClick={startSurvey}>Add your family</Button>
                  <p style={{ fontSize: 11.5, color: '#6B6659', lineHeight: 1.5, margin: '14px 0 0' }}>Pins and family details appear here once families begin to join.</p>
                </div>
              )}
            </aside>
          </div>
        </div>
      </section>

      {/* ============ FAMILIES LIST ============ */}
      <section style={{ background: '#F7F4F0', padding: '24px 0 64px' }}>
        <div className="container">
          <div style={{ display: 'flex', alignItems: 'baseline', justifyContent: 'space-between', gap: 16, marginBottom: 22, paddingBottom: 16, borderBottom: '1px solid #D5CFBF', flexWrap: 'wrap' }}>
            <h2 style={{ fontSize: 20, fontWeight: 700, margin: 0, color: '#0D1B2A' }}>{filter === 'All' ? 'Families on the map' : `Families in ${STATE_NAMES[filter]}`}</h2>
            <span style={{ fontSize: 13, color: '#6B6659' }}>Tap a family to see them on the map</span>
          </div>

          {!hasFamilies ? (
            <div style={{ background: '#E8E3DA', border: '1px dashed #D5CFBF', borderRadius: 8, padding: '40px 32px', textAlign: 'center' }}>
              <p style={{ fontSize: 15, lineHeight: 1.6, color: '#0D1B2A', margin: '0 auto 6px', maxWidth: '46ch', fontWeight: 600 }}>Families will appear here as they join.</p>
              <p style={{ fontSize: 14, lineHeight: 1.6, color: '#6B6659', margin: '0 auto 20px', maxWidth: '46ch' }}>Once you complete the survey, your family becomes a card here and a pin on the map above.</p>
              <Button variant="mulberry" onClick={startSurvey}>Add your family →</Button>
            </div>
          ) : (
            <div style={{ display: 'grid', gridTemplateColumns: 'repeat(auto-fill, minmax(270px, 1fr))', gap: 14 }}>
              {visible.map(f => (
                <button key={f.id} className="card-hover" onClick={() => setSelectedId(f.id)}
                  style={{ display: 'flex', flexDirection: 'column', gap: 10, padding: 18, border: '1px solid #D5CFBF', borderRadius: 5, background: '#fff', cursor: 'pointer', fontFamily: 'inherit', textAlign: 'left' }}>
                  <div style={{ display: 'flex', alignItems: 'center', justifyContent: 'space-between' }}>
                    <span className="eyebrow" style={{ color: '#6B6659' }}>{STATE_NAMES[f.state]}</span>
                    {f.connect && <span style={{ width: 8, height: 8, borderRadius: 999, background: '#4A7EC7' }} />}
                  </div>
                  <div>
                    <div style={{ fontSize: 17, fontWeight: 700, letterSpacing: '-0.01em', color: '#0D1B2A', lineHeight: 1.2 }}>{f.name}'s family</div>
                    <div style={{ fontSize: 13, color: '#6B6659', marginTop: 3 }}>{f.region} · child age {f.childAge}</div>
                  </div>
                  <div style={{ display: 'flex', justifyContent: 'space-between', alignItems: 'center', paddingTop: 10, borderTop: '1px solid #D5CFBF', fontSize: 12.5 }}>
                    <span style={{ color: '#6B6659' }}>{f.connect ? 'Open to messages' : 'Listening only'}</span>
                    <span style={{ color: '#1E3A6E', fontWeight: 600 }}>View →</span>
                  </div>
                </button>
              ))}
            </div>
          )}
        </div>
      </section>

      {/* ============ HOW THE MAP WORKS (sandstone band) ============ */}
      <section style={{ background: '#E8E3DA', padding: '64px 0' }}>
        <div className="container">
          <div className="eyebrow" style={{ color: '#6B6659', marginBottom: 12 }}>How the map works</div>
          <h2 className="h2-mobile" style={{ fontSize: 28, fontWeight: 700, letterSpacing: '-0.01em', margin: '0 0 36px', maxWidth: '24ch', color: '#0D1B2A' }}>Three steps, and you decide every detail.</h2>
          <div style={{ display: 'grid', gridTemplateColumns: 'repeat(3, 1fr)', gap: 20 }} className="stack-mobile-2">
            {[
              { n: '01', title: 'Fill in the short survey', body: 'Tell us your first name, your state and a little about your family. You choose what appears publicly, your suburb is shown as a general area, never your address.' },
              { n: '02', title: 'We add your pin', body: "Our team reviews each response and places your family on the map in your region. Your state's number ticks up by one. Pins are approximate by design, so no one can be identified by location." },
              { n: '03', title: 'Connect in your state', body: 'If you opt in, other families can send you a private message through us. Your email stays hidden until you decide to reply, you are always in control.' },
            ].map(s => (
              <div key={s.n} style={{ background: '#fff', border: '1px solid #D5CFBF', borderRadius: 8, padding: 28, borderTop: '3px solid #4A7EC7' }}>
                <div style={{ fontSize: 13, fontWeight: 800, color: '#4A7EC7', marginBottom: 14 }}>{s.n}</div>
                <h3 style={{ fontSize: 17, fontWeight: 700, margin: '0 0 10px', color: '#0D1B2A' }}>{s.title}</h3>
                <p style={{ fontSize: 14.5, lineHeight: 1.6, color: '#0D1B2A', margin: 0 }}>{s.body}</p>
              </div>
            ))}
          </div>
        </div>
      </section>

      {/* ============ BEREAVED FAMILIES (warm canvas) ============ */}
      <section style={{ background: '#F7F4F0', padding: '72px 0' }}>
        <div className="container">
          <div style={{ background: '#E8E3DA', border: '1px solid #D5CFBF', borderTop: '3px solid #4A7EC7', borderRadius: 8, padding: '48px 48px 44px' }} className="pad-mobile">
            <div style={{ display: 'grid', gridTemplateColumns: '1fr 1fr', gap: 48, alignItems: 'start' }} className="stack-mobile">
              <div>
                <div className="eyebrow" style={{ color: '#4A7EC7', marginBottom: 14 }}>For bereaved families</div>
                <h2 className="h2-mobile" style={{ fontSize: 28, fontWeight: 700, letterSpacing: '-0.01em', lineHeight: 1.2, margin: '0 0 18px', color: '#0D1B2A', textWrap: 'balance' }}>When a child dies, you are still part of this community.</h2>
                <p style={{ fontSize: 15.5, lineHeight: 1.7, color: '#0D1B2A', margin: '0 0 16px', maxWidth: '52ch' }}>SCN2A and the DEEs take some of the children we love. If your family has lost a child, you remain one of us, for as long as you want to be. There is no time limit on grief here, and no expectation on you.</p>
                <p style={{ fontSize: 15.5, lineHeight: 1.7, color: '#0D1B2A', margin: '0 0 24px', maxWidth: '52ch' }}>You can stay on the map, step back, or simply stay in touch. Whatever feels right for your family is right.</p>
                <Button variant="navy" as="a" href={`mailto:${FMAP_SUPPORT_EMAIL}`} icon="mail">Talk to our family support coordinator</Button>
                <p style={{ fontSize: 12, color: '#6B6659', lineHeight: 1.55, margin: '14px 0 0', maxWidth: '46ch' }}>These conversations are gentle and at your pace. Nothing is shared without your say-so.</p>
              </div>
              <div style={{ display: 'flex', flexDirection: 'column', gap: 12 }}>
                {[
                  { icon: 'map-pin', title: 'Keep your pin, in memory', body: 'Some families choose to remain on the map with a remembrance marker. Others prefer to step away. Tell us what feels okay, you can change your mind any time.' },
                  { icon: 'users', title: 'Meet families who understand', body: "We can introduce you, privately, to other Australian families who have lived this particular loss, only if and when you'd like that." },
                  { icon: 'heart', title: 'Remember their name', body: 'We remember the children of our community. With your permission, we honour their names, at our gatherings and in our work.' },
                ].map(c => (
                  <div key={c.title} style={{ display: 'flex', gap: 16, background: '#fff', border: '1px solid #D5CFBF', borderRadius: 5, padding: '18px 20px' }}>
                    <span style={{ flexShrink: 0, color: '#1E3A6E' }}><i data-lucide={c.icon} style={{ width: 22, height: 22 }} /></span>
                    <div>
                      <h3 style={{ fontSize: 15, fontWeight: 700, margin: '0 0 5px', color: '#0D1B2A' }}>{c.title}</h3>
                      <p style={{ fontSize: 13.5, lineHeight: 1.6, color: '#0D1B2A', margin: 0 }}>{c.body}</p>
                    </div>
                  </div>
                ))}
              </div>
            </div>
          </div>
        </div>
      </section>

      {/* ============ CTA BAND (navy) ============ */}
      <section style={{ background: '#1E3A6E', color: '#F7F4F0', padding: '64px 0', position: 'relative', overflow: 'hidden' }}>
        <NetworkMotif opacity={0.14} stroke="#E8E3DA" />
        <div className="container" style={{ position: 'relative' }}>
          <div style={{ display: 'grid', gridTemplateColumns: '1.3fr 1fr', gap: 40, alignItems: 'center' }} className="stack-mobile">
            <div>
              <h2 className="h2-mobile" style={{ fontSize: 'clamp(28px, 3.4vw, 32px)', fontWeight: 800, letterSpacing: '-0.02em', lineHeight: 1.1, margin: '0 0 14px', color: '#fff' }}>Are you an SCN2A family in Australia?</h2>
              <p style={{ fontSize: 16, lineHeight: 1.6, color: '#B9C2D6', maxWidth: '50ch', margin: 0 }}>One family's story matters. One hundred families on a map change what's possible, for connection, for research, for advocacy. Add yours.</p>
            </div>
            <div style={{ justifySelf: 'end', display: 'flex', flexDirection: 'column', gap: 12, alignItems: 'flex-start' }}>
              <Button size="lg" variant="mulberry" onClick={startSurvey}>Start the survey →</Button>
              <span style={{ fontSize: 12, color: '#B9C2D6' }}>Private, secure, and reviewed by our team before you appear.</span>
            </div>
          </div>
        </div>
      </section>

      {modalFamily && <MessageModal family={modalFamily} onClose={() => setModalFamily(null)} />}
    </div>
  );
}

Object.assign(window, { FamilyMapPage });
