// sections2.jsx — living feed, how it works, footer, App.

// AI-generated category photo sets (in assets/). OppCard picks a stable
// variant per opportunity (hash of title) so each listing keeps the same
// photo; an explicit o.img wins, and a user drop on the slot overrides all.
const CAT_IMG = {
  festival:    ['assets/festival-1.jpg', 'assets/festival-2.jpg', 'assets/festival-3.jpg'],
  volunteer:   ['assets/volunteer-1.jpg', 'assets/volunteer-2.jpg', 'assets/volunteer-3.jpg'],
  gig:         ['assets/gig-1.jpg', 'assets/gig-2.jpg', 'assets/gig-3.jpg'],
  hospitality: ['assets/hospitality-1.jpg', 'assets/hospitality-2.jpg', 'assets/hospitality-3.jpg'],
};
function oppImg(o) {
  if (o && o.img) return o.img;
  const set = o && CAT_IMG[o.cat];
  if (!set || !set.length) return undefined;
  const h = [...(o.title || '')].reduce((a, c) => a + c.charCodeAt(0), 0);
  return set[h % set.length];
}

// the rich listing view — opened by clicking any opportunity card
function OppDetailModal({ o, meta, applied, left, busy, note, onClaim, onWithdraw, onClose }) {
  const dialogRef = React.useRef(null);
  // only close on a click that STARTED on the backdrop — releasing a text
  // selection over the backdrop must not dismiss the dialog
  const downOnBackdrop = React.useRef(false);
  React.useEffect(() => {
    const prevFocus = document.activeElement;
    const dlg = dialogRef.current;
    const focusables = () => dlg ? dlg.querySelectorAll('button, [tabindex="0"], a[href], input, select, textarea') : [];
    const firstBtn = dlg && dlg.querySelector('button');
    if (firstBtn) firstBtn.focus();
    const onKey = (e) => {
      if (e.key === 'Escape') onClose();
      if (e.key === 'Tab') {
        const f = [...focusables()];
        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(); }
      }
    };
    window.addEventListener('keydown', onKey);
    const prev = document.body.style.overflow;
    document.body.style.overflow = 'hidden';
    return () => {
      window.removeEventListener('keydown', onKey);
      document.body.style.overflow = prev;
      if (prevFocus && prevFocus.focus) prevFocus.focus();
    };
  }, []);
  const full = left <= 0 && !applied;
  const img = oppImg(o);
  return (
    <div
      onMouseDown={(e) => { downOnBackdrop.current = e.target === e.currentTarget; }}
      onClick={(e) => {
        // the portal still bubbles through the React tree to the card's
        // onClick (which would re-open) — never let clicks escape the modal
        e.stopPropagation();
        if (downOnBackdrop.current && e.target === e.currentTarget) onClose();
      }}
      style={{ position: 'fixed', inset: 0, zIndex: 100, background: 'rgba(42,33,26,0.45)', display: 'grid', placeItems: 'center', padding: 20, overflowY: 'auto' }}>
      <div ref={dialogRef} onClick={(e) => e.stopPropagation()} role="dialog" aria-modal="true" aria-label={o.title}
        style={{ width: '100%', maxWidth: 620, background: PAL.card, border: `1px solid ${PAL.line}`, borderRadius: 22, overflow: 'hidden', boxShadow: '0 30px 70px -20px rgba(42,33,26,0.5)', margin: '30px 0' }}>
        <div style={{ position: 'relative', height: 240, background: tint(meta.color, 0.18), borderBottom: `1px solid ${PAL.line}` }}>
          {img && <img src={img} alt="" style={{ display: 'block', width: '100%', height: '100%', objectFit: 'cover' }} />}
          <span style={{ position: 'absolute', left: 14, top: 14, font: '700 11px/1 var(--mono)', letterSpacing: '0.06em', color: '#fff', background: PAL.ink, padding: '6px 10px', borderRadius: 999 }}>{meta.label}</span>
          <button type="button" onClick={onClose} aria-label="Close"
            style={{ position: 'absolute', right: 12, top: 12, cursor: 'pointer', border: 'none', background: 'rgba(255,255,255,0.92)', borderRadius: 10, width: 34, height: 34, display: 'grid', placeItems: 'center', color: PAL.ink, font: '700 16px/1 var(--body)', boxShadow: '0 2px 8px rgba(42,33,26,0.25)' }}>×</button>
          {(full || left <= 8) && (
            <span style={{ position: 'absolute', right: 12, bottom: 12, display: 'inline-flex', alignItems: 'center', gap: 5,
              font: '700 11px/1 var(--mono)', color: full ? '#fff' : PAL.ink, background: full ? PAL.ink : PAL.sun, border: `1px solid ${PAL.line}`, padding: '5px 9px', borderRadius: 999 }}>
              <Icon name="bolt" size={12} sw={2.6} /> {full ? 'FULL' : `${left} LEFT`}
            </span>
          )}
        </div>
        <div style={{ padding: '26px 30px 30px' }}>
          <h2 style={{ font: '700 28px/1.12 var(--display)', color: PAL.ink, margin: 0, letterSpacing: '-0.02em' }}>{o.title}</h2>
          {o.hook && <p style={{ font: '400 15px/1.55 var(--body)', color: tint(PAL.ink, 0.68), margin: '10px 0 0', textWrap: 'pretty' }}>{o.hook}</p>}
          <div style={{ display: 'flex', flexDirection: 'column', gap: 8, margin: '16px 0' }}>
            {[['pin', o.place], ['cal', o.date]].map(([ic, t]) => (
              <div key={ic} style={{ display: 'flex', alignItems: 'center', gap: 9, font: '500 14px/1.3 var(--body)', color: tint(PAL.ink, 0.7) }}>
                <Icon name={ic} size={16} c={tint(PAL.ink, 0.45)} /> {t}
              </div>
            ))}
          </div>
          <div style={{ display: 'flex', flexWrap: 'wrap', gap: 7, marginBottom: 18 }}>
            {(o.roles || []).map((rr) => <span key={rr} style={{ font: '600 12px/1 var(--body)', color: PAL.ink, background: PAL.paper, border: `1.5px solid ${tint(PAL.ink, 0.18)}`, padding: '7px 11px', borderRadius: 999 }}>{rr}</span>)}
          </div>
          <div style={{ display: 'flex', alignItems: 'center', gap: 10, paddingTop: 16, borderTop: `2px solid ${tint(PAL.ink, 0.1)}` }}>
            <span style={{ font: '700 19px/1 var(--display)', color: o.pay === 'Volunteer' ? PAL.sage : PAL.ink }}>{o.pay}</span>
            <span style={{ font: '600 13px/1 var(--body)', color: tint(PAL.ink, 0.55) }}>· {Math.max(0, left)} of {o.spots} spots open</span>
            <div style={{ marginLeft: 'auto', display: 'flex', alignItems: 'center', gap: 7 }}>
              <span style={{ width: 24, height: 24, borderRadius: 99, background: meta.color, border: `1.5px solid ${PAL.ink}`, display: 'grid', placeItems: 'center', font: '700 11px/1 var(--mono)', color: '#fff' }}>{o.org[0]}</span>
              <span style={{ font: '600 13px/1.1 var(--body)', color: tint(PAL.ink, 0.65) }}>{o.org}</span>
              <Icon name="shield" size={14} c={PAL.sage} />
            </div>
          </div>
          <div style={{ marginTop: 18 }}>
            {applied ? (
              <div style={{ display: 'flex', gap: 10, alignItems: 'center' }}>
                <span style={{ flex: 1, display: 'inline-flex', alignItems: 'center', justifyContent: 'center', gap: 8, font: '700 15px/1 var(--body)', color: PAL.sage, background: tint(PAL.sage, 0.12), border: `1px solid ${tint(PAL.sage, 0.4)}`, borderRadius: 999, padding: '14px 0' }}>
                  <Icon name="check" size={17} sw={2.6} /> You're in — see you there!
                </span>
                <Btn kind="paper" disabled={busy} onClick={onWithdraw}>Withdraw</Btn>
              </div>
            ) : (
              <Btn size="lg" disabled={busy || full} onClick={onClaim}
                style={{ width: '100%', justifyContent: 'center', ...(full ? { background: tint(PAL.ink, 0.25) } : { background: meta.color }) }}>
                {full ? 'Full — check back' : busy ? 'One sec…' : 'Claim a spot'}
              </Btn>
            )}
            {note && <p style={{ font: '600 12.5px/1.4 var(--body)', color: PAL.brick, margin: '10px 0 0', textAlign: 'center' }}>{note}</p>}
          </div>
        </div>
      </div>
    </div>
  );
}

function OppCard({ o, feature, slot, peek }) {
  const meta = CAT[o.cat];
  const h = feature ? 210 : 150;
  const [applied, setApplied] = React.useState(!!o.applied);
  const [left, setLeft] = React.useState(o.spotsLeft != null ? o.spotsLeft : o.spots);
  const [busy, setBusy] = React.useState(false);
  const [note, setNote] = React.useState('');
  const [open, setOpen] = React.useState(false);
  const full = left <= 0 && !applied;
  async function claim(e) {
    e.stopPropagation();
    if (busy || applied || full || !o.id) return;
    setBusy(true); setNote('');
    try {
      const me = await whoami();
      if (!me) {
        const here = (location.pathname.split('/').pop() || 'index.html') + location.search;
        location.href = 'Login.html?next=' + encodeURIComponent(here);
        return;
      }
      const r = await api.post('/api/opportunities/' + o.id + '/apply');
      setApplied(true);
      setLeft(r.spotsLeft != null ? r.spotsLeft : Math.max(0, left - 1));
    } catch (err) {
      setNote(err.message);
      if (err.status === 409) {
        if (/already/i.test(err.message)) setApplied(true);
        else setLeft(0); // beaten to the last spot — show the FULL state
      }
    } finally {
      setBusy(false);
    }
  }
  async function withdraw(e) {
    if (e) e.stopPropagation();
    if (busy || !applied || !o.id) return;
    setBusy(true); setNote('');
    try {
      const r = await api.del('/api/opportunities/' + o.id + '/apply');
      setApplied(false);
      setLeft(r.spotsLeft != null ? r.spotsLeft : left + 1);
    } catch (err) {
      setNote(err.message);
    } finally {
      setBusy(false);
    }
  }
  return (
    <React.Fragment>
    {/* portal: the card sits inside animated (transformed) wrappers, which
       would trap the fixed overlay in their stacking context */}
    {open && ReactDOM.createPortal(
      <OppDetailModal o={o} meta={meta} applied={applied} left={left} busy={busy} note={note}
        onClaim={claim} onWithdraw={withdraw} onClose={() => setOpen(false)} />,
      document.body
    )}
    <div className="pcard" onClick={() => o.id && setOpen(true)} style={{ display: 'flex', flexDirection: 'column', height: '100%', cursor: o.id ? 'pointer' : 'default',
      background: PAL.card, border: `1px solid ${PAL.line}`, borderRadius: 18, overflow: 'hidden', boxShadow: `0 1px 0 rgba(255,255,255,0.7) inset, 0 8px 20px -10px rgba(42,33,26,0.28)` }}>
      <div style={{ position: 'relative', height: h, borderBottom: `1px solid ${PAL.line}`, background: tint(meta.color, 0.18) }}>
        <image-slot id={slot} shape="rect" fit="cover" src={oppImg(o)} placeholder={`Drop a ${meta.label.split(' ')[0].toLowerCase()} photo`}
          style={{ display: 'block', width: '100%', height: '100%' }}></image-slot>
        {peek && <CornerOrb size={40} fill={peek} pos={{ right: 12, top: 10 }} />}
        <span style={{ position: 'absolute', left: 12, top: 12, font: '700 11px/1 var(--mono)', letterSpacing: '0.06em', color: '#fff', background: PAL.ink, padding: '6px 10px', borderRadius: 999, pointerEvents: 'none' }}>{meta.label.split(' ')[0]}</span>
        {(full || left <= 8) && (
          <span style={{ position: 'absolute', right: 12, bottom: 12, display: 'inline-flex', alignItems: 'center', gap: 5,
            font: '700 11px/1 var(--mono)', color: full ? '#fff' : PAL.ink, background: full ? PAL.ink : PAL.sun, border: `1px solid ${PAL.line}`, padding: '5px 9px', borderRadius: 999 }}>
            <Icon name="bolt" size={12} sw={2.6} /> {full ? 'FULL' : `${left} LEFT`}
          </span>
        )}
      </div>
      <div style={{ padding: feature ? '22px 24px' : '16px 18px', display: 'flex', flexDirection: 'column', flex: 1 }}>
        <h3 style={{ font: `700 ${feature ? 23 : 17}px/1.18 var(--display)`, color: PAL.ink, margin: 0, letterSpacing: '-0.01em' }}>{o.title}</h3>
        {feature && <p style={{ font: '400 14px/1.5 var(--body)', color: tint(PAL.ink, 0.62), margin: '8px 0 0', textWrap: 'pretty' }}>{o.hook}</p>}
        <div style={{ display: 'flex', flexDirection: 'column', gap: 7, margin: '12px 0 13px' }}>
          {[['pin', o.place], ['cal', o.date]].map(([ic, t]) => (
            <div key={ic} style={{ display: 'flex', alignItems: 'center', gap: 8, font: '500 13px/1.2 var(--body)', color: tint(PAL.ink, 0.66) }}>
              <Icon name={ic} size={14} c={tint(PAL.ink, 0.4)} /> {t}
            </div>
          ))}
        </div>
        <div style={{ display: 'flex', flexWrap: 'wrap', gap: 6, marginBottom: 14 }}>
          {o.roles.map((rr) => <span key={rr} style={{ font: '600 11.5px/1 var(--body)', color: PAL.ink, background: PAL.paper, border: `1.5px solid ${tint(PAL.ink, 0.18)}`, padding: '6px 10px', borderRadius: 999 }}>{rr}</span>)}
        </div>
        <div style={{ marginTop: 'auto', paddingTop: 13, borderTop: `2px solid ${tint(PAL.ink, 0.1)}`, display: 'flex', alignItems: 'center', gap: 10 }}>
          <span style={{ font: `700 ${feature ? 17 : 15}px/1 var(--display)`, color: o.pay === 'Volunteer' ? PAL.sage : PAL.ink }}>{o.pay}</span>
          <div style={{ marginLeft: 'auto', display: 'flex', alignItems: 'center', gap: 7 }}>
            <span style={{ width: 22, height: 22, borderRadius: 99, background: meta.color, border: `1.5px solid ${PAL.ink}`, display: 'grid', placeItems: 'center', font: '700 10px/1 var(--mono)', color: '#fff' }}>{o.org[0]}</span>
            <span style={{ font: '600 12px/1.1 var(--body)', color: tint(PAL.ink, 0.6) }}>{o.org}</span>
            <Icon name="shield" size={13} c={PAL.sage} />
          </div>
        </div>
        {o.id && (
          <div style={{ marginTop: 12 }}>
            <Btn size="sm" kind={applied ? 'paper' : 'solid'} disabled={busy || full}
              onClick={applied ? (e) => { e.stopPropagation(); setOpen(true); } : claim}
              style={{ width: '100%', justifyContent: 'center', ...(applied ? { color: PAL.sage, borderColor: tint(PAL.sage, 0.5) } : full ? { background: tint(PAL.ink, 0.25) } : { background: meta.color }) }}>
              {applied ? "✓ You're in" : full ? 'Full — check back' : busy ? 'One sec…' : 'Claim a spot'}
            </Btn>
            {note && <p style={{ font: '600 12px/1.4 var(--body)', color: PAL.brick, margin: '8px 0 0', textAlign: 'center' }}>{note}</p>}
          </div>
        )}
      </div>
    </div>
    </React.Fragment>
  );
}

// shown only if the API is unreachable (e.g. opened without the server)
const FEED_FALLBACK = [
  { cat: 'festival', title: 'Riverside Sound & Light Festival', hook: 'Three days of music by the water. A friendly crew for stages, gates, and guest help — meals and a crew shirt included.', place: 'Riverside Park', date: 'Sat–Mon, Jun 21–23', roles: ['Stage crew', 'Ushers', 'Guest help'], pay: '$22/hr', org: 'Roadhouse Events', spots: 8, feature: true },
  { cat: 'volunteer', title: 'Greenway River Cleanup', place: 'Mill Creek', date: 'Sun, Jun 22 · 8am', roles: ['Cleanup crew'], pay: 'Volunteer', org: 'Greenway Conservancy', spots: 24 },
  { cat: 'hospitality', title: 'Rooftop Summer Gala', place: 'Downtown', date: 'Fri, Jul 4 · 5pm', roles: ['Servers', 'Bartenders'], pay: '$25/hr + tips', org: 'Maple & Vine Catering', spots: 6 },
  { cat: 'gig', title: 'Weekend Warehouse Move', place: 'Eastside', date: 'Jun 28–29', roles: ['Movers', 'Loaders'], pay: '$18/hr', org: 'Anchor Logistics', spots: 5 },
  { cat: 'festival', title: 'Taco & Music Street Fest', place: 'Old Town', date: 'Sat, Jul 12', roles: ['Brand ambassadors'], pay: '$20/hr', org: 'Cornerstone Fests', spots: 16 },
  { cat: 'volunteer', title: 'Community Food Bank Sort-a-thon', place: 'Northgate', date: 'Sat, Jun 28 · 9am', roles: ['Sorting', 'Packing'], pay: 'Volunteer', org: 'City Food Bank', spots: 40 },
];

function Feed() {
  const [opps, setOpps] = React.useState(null);
  React.useEffect(() => {
    api.get('/api/opportunities?limit=6')
      .then((d) => setOpps(d.opportunities))
      .catch(() => setOpps(FEED_FALLBACK));
  }, []);
  if (!opps) return null;
  // left-to-right, row-by-row reveal (the +1 slot is the "See more" tile)
  const feedDelay = rowMajorDelays([...opps, {}], 4, 90);
  return (
    <section style={{ position: 'relative', marginTop: 60, borderTop: `1px solid ${PAL.line}`, borderBottom: `1px solid ${PAL.line}`, background: PAL.paper }}>
      <div style={{ maxWidth: 1200, margin: '0 auto', padding: '64px 30px' }}>
        <div style={{ display: 'flex', alignItems: 'flex-end', justifyContent: 'space-between', gap: 20, marginBottom: 28, flexWrap: 'wrap' }}>
          <Reveal style={{ maxWidth: 560 }}>
            <Label>The feed</Label>
            <h2 style={{ font: '700 40px/1.04 var(--display)', color: PAL.ink, margin: '12px 0 10px', letterSpacing: '-0.02em' }}>Opportunities that come alive</h2>
            <p style={{ font: '400 16.5px/1.5 var(--body)', color: tint(PAL.ink, 0.66), margin: 0, textWrap: 'pretty' }}>
              Photos, roles, pay and timing — all upfront.
            </p>
          </Reveal>
          <div style={{ display: 'flex', gap: 8 }}>
            {['Soonest', 'Nearest', 'Best paid'].map((t, i) => (
              <span key={t} style={{ font: '700 13px/1 var(--body)', padding: '10px 15px', borderRadius: 999, border: `1px solid ${PAL.line}`,
                background: i === 0 ? PAL.ink : PAL.card, color: i === 0 ? PAL.card : PAL.ink }}>{t}</span>
            ))}
          </div>
        </div>
        <div className="g-feed" style={{ display: 'grid', gridTemplateColumns: 'repeat(4,1fr)', gap: 18 }}>
          {opps.map((o, i) => (
            <Reveal key={o.id || i} variant="rise" d={feedDelay[i]} style={{ gridColumn: o.feature ? 'span 2' : 'auto' }}><OppCard o={o} feature={o.feature} slot={`feed-${i}`} /></Reveal>
          ))}
          <Reveal variant="rise" d={feedDelay[opps.length]}>
            <a href="Discover.html" className="pcard" style={{ display: 'flex', flexDirection: 'column', alignItems: 'center', justifyContent: 'center', textAlign: 'center', height: '100%', minHeight: 220, textDecoration: 'none',
              background: tint(PAL.orange, 0.08), border: `1.5px dashed ${tint(PAL.orange, 0.5)}`, borderRadius: 18, padding: 24 }}>
              <span style={{ width: 52, height: 52, borderRadius: 14, background: tint(PAL.orange, 0.16), display: 'grid', placeItems: 'center', color: PAL.orange }}><Icon name="arrow" size={26} sw={2.4} /></span>
              <h3 style={{ font: '700 19px/1.15 var(--display)', color: PAL.ink, margin: '14px 0 4px' }}>See more</h3>
              <p style={{ font: '400 13.5px/1.45 var(--body)', color: tint(PAL.ink, 0.6), margin: '0 0 14px' }}>More opportunities near you.</p>
              <span style={{ display: 'inline-flex', alignItems: 'center', gap: 7, font: '700 13px/1 var(--body)', color: PAL.orange }}>Browse all <Icon name="arrow" size={16} c={PAL.orange} sw={2.6} /></span>
            </a>
          </Reveal>
        </div>
      </div>
    </section>
  );
}

function How() {
  const helper = [['search', 'Discover', 'Browse or filter the feed.'],
    ['ticket', 'Explore', 'Open a rich, photo-led listing.'],
    ['bolt', 'Join', 'Apply, or claim a spot instantly.'],
    ['star', 'Get rated', 'Do the work, build your rep.']];
  const org = [['shield', 'Register', 'Set up a verified profile.'],
    ['plus', 'Post', 'List photos, roles and timing.'],
    ['msg', 'Manage', 'Invite, review and message.'],
    ['check', 'Grow', 'Earn ratings, staff faster.']];
  const Col = ({ tag, title, steps, accent, orbMood }) => (
    <div style={{ background: PAL.card, border: `1px solid ${PAL.line}`, borderRadius: 20, padding: '32px 30px', boxShadow: `0 1px 0 rgba(255,255,255,0.7) inset, 0 8px 20px -10px rgba(42,33,26,0.28)` }}>
      <span style={{ display: 'inline-flex', alignItems: 'center', font: '700 12px/1 var(--mono)', letterSpacing: '0.1em', textTransform: 'uppercase', color: '#fff', background: accent, border: `1px solid ${PAL.line}`, padding: '7px 12px', borderRadius: 999 }}>{tag}</span>
      <h3 style={{ font: '700 26px/1.1 var(--display)', color: PAL.ink, margin: '16px 0 20px', letterSpacing: '-0.01em' }}>{title}</h3>
      <div>
        {steps.map(([ic, t, d], i) => (
          <div key={i} style={{ display: 'flex', gap: 15, padding: '13px 0', borderTop: i ? `1.5px solid ${tint(PAL.ink, 0.1)}` : 'none' }}>
            <span style={{ flex: 'none', width: 42, height: 42, borderRadius: 12, background: tint(accent, 0.18), border: `1px solid ${PAL.line}`, display: 'grid', placeItems: 'center', color: accent }}><Icon name={ic} size={20} /></span>
            <div><div style={{ display: 'flex', alignItems: 'center', gap: 9 }}><span style={{ font: '700 12px/1 var(--mono)', color: tint(PAL.ink, 0.34) }}>{String(i + 1).padStart(2, '0')}</span><span style={{ font: '700 16px/1.1 var(--display)', color: PAL.ink }}>{t}</span></div>
              <p style={{ font: '400 13.5px/1.5 var(--body)', color: tint(PAL.ink, 0.62), margin: '4px 0 0', textWrap: 'pretty' }}>{d}</p></div>
          </div>
        ))}
      </div>
    </div>
  );
  return (
    <section id="how" style={{ maxWidth: 1200, margin: '0 auto', padding: '76px 30px 20px' }}>
      <Reveal style={{ textAlign: 'center', maxWidth: 620, margin: '0 auto 38px' }}>
        <Label style={{ display: 'inline-block' }}>How it works</Label>
        <h2 style={{ font: '700 42px/1.04 var(--display)', color: PAL.ink, margin: '12px 0 0', letterSpacing: '-0.025em' }}>Built for both sides</h2>
        <p style={{ font: '400 16.5px/1.5 var(--body)', color: tint(PAL.ink, 0.66), margin: '14px 0 0', textWrap: 'pretty' }}>For the people joining — and the ones posting.</p>
      </Reveal>
      <div className="g-two" style={{ display: 'grid', gridTemplateColumns: '1fr 1fr', gap: 20 }}>
        <Reveal variant="left"><Col tag="For helpers" title="Find work & give back" steps={helper} accent={PAL.orange} orbMood="joyful" /></Reveal>
        <Reveal variant="right" d={120}><Col tag="For organizers" title="Staff your event, fast" steps={org} accent={PAL.sage} orbMood="determined" /></Reveal>
      </div>
    </section>
  );
}

function CTA() {
  return (
    <section style={{ maxWidth: 1200, margin: '0 auto', padding: '76px 30px' }}>
      <Reveal variant="zoom">
        <div style={{ position: 'relative', overflow: 'hidden', background: PAL.orange, border: `1px solid ${PAL.line}`, borderRadius: 24, padding: '54px 48px', boxShadow: `0 6px 22px rgba(42,33,26,0.10)` }}>
          <div style={{ position: 'absolute', right: -40, top: -40, opacity: 0.5 }}><Sunburst r={240} fill={tint('#FFFFFF', 0.5)} rays={18} /></div>
          <div style={{ position: 'relative', maxWidth: 560 }}>
            <Label c="rgba(255,255,255,0.85)">For organizers & nonprofits</Label>
            <h2 style={{ font: '700 44px/1.02 var(--display)', color: '#fff', margin: '12px 0 14px', letterSpacing: '-0.025em' }}>Need a crew? Post in minutes.</h2>
            <p style={{ font: '400 17px/1.5 var(--body)', color: 'rgba(255,255,255,0.92)', margin: '0 0 24px', maxWidth: 460, textWrap: 'pretty' }}>
              Post a photo-led listing and manage your crew in one place.
            </p>
            <div style={{ display: 'flex', gap: 12, flexWrap: 'wrap' }}>
              <a href="Organizers.html#post" style={{ textDecoration: 'none' }}><Btn kind="paper" size="lg" icon="arrow">Post an opportunity</Btn></a>
              <a href="Organizers.html" style={{ textDecoration: 'none' }}><Btn kind="ink" size="lg">See organizer tools</Btn></a>
            </div>
          </div>
        </div>
      </Reveal>
    </section>
  );
}

function Footer() {
  const cols = [['For helpers', [['Browse opportunities', 'Discover.html'], ['Categories', 'Categories.html'], ['Who we are', 'WhoWeAre.html'], ['Your profile', 'Profile.html']]],
    ['For organizers', [['Post an opportunity', 'Organizers.html#post'], ['Find helpers', 'Organizers.html'], ['Organizer tools', 'Organizers.html'], ['Pricing', 'Organizers.html']]],
    ['Company', [['About Team Orange', 'WhoWeAre.html'], ['Our mission', 'WhoWeAre.html'], ['Terms & guidelines', 'Terms.html'], ['Contact', 'WhoWeAre.html']]]];
  return (
    <footer style={{ background: PAL.ink, color: PAL.card }}>
      <div className="g-footer" style={{ maxWidth: 1200, margin: '0 auto', padding: '54px 30px 30px', display: 'grid', gridTemplateColumns: '1.6fr 1fr 1fr 1fr', gap: 30 }}>
        <div>
          <div style={{ display: 'flex', alignItems: 'center', gap: 10, marginBottom: 14 }}>
            <LogoOrb size={30} />
            <span style={{ font: '700 22px/1 var(--display)', color: PAL.card }}>orange<span style={{ color: PAL.sun }}>.</span></span>
          </div>
          <p style={{ font: '400 14px/1.55 var(--body)', color: tint(PAL.card, 0.65), margin: 0, maxWidth: 290, textWrap: 'pretty' }}>The warm, energetic heartbeat of how communities get things done together.</p>
          <span style={{ display: 'inline-flex', alignItems: 'center', gap: 7, marginTop: 18, font: '700 12px/1 var(--mono)', color: PAL.sun }}><Icon name="star" size={13} sw={2.2} /> MADE WITH CARE</span>
        </div>
        {cols.map(([h, links]) => (
          <div key={h}>
            <h4 style={{ font: '700 12px/1 var(--mono)', letterSpacing: '0.1em', textTransform: 'uppercase', color: tint(PAL.card, 0.5), margin: '0 0 16px' }}>{h}</h4>
            <div style={{ display: 'flex', flexDirection: 'column', gap: 11 }}>{links.map(([l, href]) => <a key={l} href={href} style={{ font: '400 14px/1 var(--body)', color: tint(PAL.card, 0.8), textDecoration: 'none' }}>{l}</a>)}</div>
          </div>
        ))}
      </div>
      <div style={{ maxWidth: 1200, margin: '0 auto', padding: '20px 30px 38px', borderTop: `1.5px solid ${tint(PAL.card, 0.14)}`, font: '400 13px/1 var(--body)', color: tint(PAL.card, 0.55) }}>
        © 2026 Team Orange — representing people. v1.0.0
      </div>
    </footer>
  );
}

function App() {
  return <div><Nav /><Hero /><Stats /><Categories /><Feed /><How /><CTA /><Footer /></div>;
}
Object.assign(window, { OppCard, Feed, How, CTA, Footer, App });
