// landing.jsx — Hero, manifesto, bottom sections + App root
// Assembles everything into the marketing site.

const { useState: useStateL, useRef: useRefL } = React;

// ═════════════════════════════════════════════════════════════
// HERO
// ═════════════════════════════════════════════════════════════

function Hero() {
  return (
    <section className="hero" id="top">
      <div className="hero-eyebrow eyebrow">a field journal, made small</div>
      <h1>
        A quiet place<br/>
        for the places<br/>
        <em>you love.</em>
      </h1>
      <div className="lede">
        Plinn is a small app for keeping track of the bookshops, restaurants, and back-alley museums you actually want to remember — and turning them into a real trip when you're ready.
      </div>
      <div className="cta-row">
        <a className="btn-ink" href="#download">
          Get TestFlight invite <span className="arr">→</span>
        </a>
        <a className="mono-link" href="#what">What it is</a>
      </div>
      <div className="hero-meta">
        <span>iOS · TestFlight beta · spring 2026</span>
        <span>Free · no account to start</span>
        <span>v0.9 · May 2026</span>
      </div>
    </section>
  );
}

// ═════════════════════════════════════════════════════════════
// MANIFESTO — Why Plinn
// ═════════════════════════════════════════════════════════════

function Manifesto() {
  return (
    <section className="section" id="what" style={{ paddingTop: 64 }}>
      <div className="section-head">
        <div>
          <div className="eyebrow">00 · Why Plinn</div>
          <h2>Travel apps got <em>loud</em>.</h2>
        </div>
        <div className="lede">
          The map fills with sponsored pins. The feed scrolls. Every place has stars. We wanted the opposite of that, so we built it.
        </div>
      </div>

      <div className="manifesto-grid">
        <div className="manifesto-quote">
          <div className="pull">
            A list, <em>kept by hand</em>. The places you actually loved. The trips you actually took. Nothing in between.
            <span className="by">— the only line on the back of every Plinn business card</span>
          </div>
        </div>

        <div className="manifesto-side">
          {[
            ['No feed',          'You only see places you, or a friend, put there.'],
            ['No sponsored pins','Nobody pays to appear in your map.'],
            ['No stars',         'Restaurants have hours and addresses. The taste is yours.'],
            ['No streaks',       'No badges, no levels, no weekly streak emails.'],
            ['No tracking',      'Foreground location only. No ad identifiers. No third-party SDKs.'],
          ].map(([k, v], i) => (
            <div key={i} className="manifesto-row">
              <span className="manifesto-x mono accent">—</span>
              <div>
                <div className="serif" style={{ fontSize: 22, letterSpacing: '-0.3px' }}><em>{k}</em></div>
                <div className="manifesto-row-sub">{v}</div>
              </div>
            </div>
          ))}
        </div>
      </div>
    </section>
  );
}

// ═════════════════════════════════════════════════════════════
// INVESTOR snapshot
// ═════════════════════════════════════════════════════════════

function InvestorSnapshot() {
  return (
    <section className="section" id="investors">
      <div className="section-head">
        <div>
          <div className="eyebrow">06 · Investors</div>
          <h2>We're raising a <em>seed</em>.</h2>
        </div>
        <div className="lede">
          Plinn is a long bet on a quieter kind of travel app — and a small, opinionated team building it. If that's the next decade you want to back, we'd like to talk.
        </div>
      </div>

      <div className="invest-grid">
        <div className="invest-cell">
          <div className="mono" style={{ marginBottom: 12 }}>Round</div>
          <div className="serif" style={{ fontSize: 36, letterSpacing: '-0.6px', lineHeight: 1 }}><em>Open.</em></div>
          <div className="invest-sub">Seed round. Quiet for now — talk to us.</div>
        </div>
        <div className="invest-cell">
          <div className="mono" style={{ marginBottom: 12 }}>Traction</div>
          <div className="serif" style={{ fontSize: 32, letterSpacing: '-0.5px', lineHeight: 1, fontStyle: 'italic', color: 'var(--mute)' }}>Coming soon.</div>
          <div className="invest-sub">Numbers we'll share once the beta is bigger.</div>
        </div>
        <div className="invest-cell">
          <div className="mono" style={{ marginBottom: 12 }}>Team</div>
          <div className="serif" style={{ fontSize: 36, letterSpacing: '-0.6px', lineHeight: 1 }}>Small.</div>
          <div className="invest-sub">Design, engineering, AI. Munich and Cape Town.</div>
        </div>
      </div>

      <div className="invest-foot">
        <div className="serif" style={{ fontSize: 26, letterSpacing: '-0.3px', maxWidth: '46ch' }}>
          The deck, the financials, and a thirty-minute call. We'll send all three.
        </div>
        <div style={{ display: 'flex', gap: 12, flexWrap: 'wrap' }}>
          <a className="btn-ink" href="investors.html">
            Read the snapshot <span className="arr">→</span>
          </a>
          <a className="btn-line" href="mailto:invest@plinn.app">
            invest@plinn.app
          </a>
        </div>
      </div>
    </section>
  );
}

// ═════════════════════════════════════════════════════════════
// WAITLIST / Newsletter
// ═════════════════════════════════════════════════════════════

function Waitlist() {
  const [email, setEmail] = useStateL('');
  const [sent, setSent] = useStateL(false);
  const [submitting, setSubmitting] = useStateL(false);
  const submit = async (e) => {
    e.preventDefault();
    if (!email.includes('@') || submitting) return;
    setSubmitting(true);
    try {
      await fetch('https://formspree.io/f/9cd2072082524810b4d76442457a2598', {
        method: 'POST',
        headers: { 'Content-Type': 'application/json', Accept: 'application/json' },
        body: JSON.stringify({ email, _subject: 'plinn · newsletter signup', source: 'waitlist' }),
      });
    } catch (_) { /* optimistic */ }
    setSent(true);
    setSubmitting(false);
  };

  return (
    <section className="section" id="waitlist">
      <div className="section-head">
        <div>
          <div className="eyebrow">07 · Field journal</div>
          <h2>The <em>newsletter</em>.</h2>
        </div>
        <div className="lede">
          Every other Sunday. A new city, a few notes from the team, the occasional list. Quiet, like the app.
        </div>
      </div>

      {!sent ? (
        <form className="waitlist-form" onSubmit={submit}>
          <input
            type="email"
            placeholder="your email"
            value={email}
            onChange={(e) => setEmail(e.target.value)}
            required
          />
          <button type="submit" className="btn-ink" disabled={submitting}>
            {submitting ? 'Sending…' : <>Join the field journal <span className="arr">→</span></>}
          </button>
        </form>
      ) : (
        <div className="waitlist-thanks">
          <div className="mono accent" style={{ marginBottom: 10 }}>Saved</div>
          <div className="serif" style={{ fontSize: 32, letterSpacing: '-0.5px' }}>
            Thanks. The first one lands <em>this Sunday</em>.
          </div>
        </div>
      )}

      <div className="waitlist-foot mono">
        No tracking pixels · unsubscribe in one tap · quiet, like the app
      </div>
    </section>
  );
}

// ═════════════════════════════════════════════════════════════
// DOWNLOAD / TestFlight
// ═════════════════════════════════════════════════════════════

function Download() {
  const [email, setEmail] = useStateL('');
  const [sent, setSent] = useStateL(false);
  const [submitting, setSubmitting] = useStateL(false);
  const submit = async (e) => {
    e.preventDefault();
    if (!email.includes('@') || submitting) return;
    setSubmitting(true);
    try {
      await fetch('https://formspree.io/f/9cd2072082524810b4d76442457a2598', {
        method: 'POST',
        headers: { 'Content-Type': 'application/json', Accept: 'application/json' },
        body: JSON.stringify({ email, _subject: 'plinn · TestFlight invite request', source: 'testflight' }),
      });
    } catch (_) { /* optimistic */ }
    setSent(true);
    setSubmitting(false);
  };

  return (
    <section className="section dark-block" id="download" style={{
      maxWidth: 'none',
      padding: '120px var(--gutter)',
    }}>
      <div className="shell" style={{ padding: 0 }}>
        <div className="dl-grid">
          <div>
            <div className="eyebrow" style={{ color: 'rgba(250,250,247,0.55)', marginBottom: 22 }}>08 · TestFlight</div>
            <h2 className="serif" style={{ color: 'var(--paper)', fontSize: 88, letterSpacing: '-2px', lineHeight: 0.95, margin: 0 }}>
              The beta is <em>open</em>.
            </h2>
            <div className="serif" style={{ color: 'rgba(250,250,247,0.85)', fontSize: 22, letterSpacing: '-0.2px', lineHeight: 1.4, maxWidth: '34ch', marginTop: 32 }}>
              We send TestFlight invites in small batches. Drop your email and we'll add you to the next round.
            </div>

            <div className="dl-meta">
              <div>
                <div className="mono" style={{ color: 'rgba(250,250,247,0.55)' }}>iOS</div>
                <div className="serif" style={{ fontSize: 22, color: 'var(--paper)' }}>TestFlight · open</div>
              </div>
              <div>
                <div className="mono" style={{ color: 'rgba(250,250,247,0.55)' }}>Android</div>
                <div className="serif" style={{ fontSize: 22, color: 'var(--paper)' }}>summer 2026</div>
              </div>
              <div>
                <div className="mono" style={{ color: 'rgba(250,250,247,0.55)' }}>Price</div>
                <div className="serif" style={{ fontSize: 22, color: 'var(--paper)' }}>free</div>
              </div>
            </div>
          </div>

          <div className="dl-form-wrap">
            {!sent ? (
              <form className="dl-form" onSubmit={submit}>
                <label className="mono" style={{ color: 'rgba(250,250,247,0.55)', display: 'block', marginBottom: 10 }}>
                  Request invite
                </label>
                <input
                  type="email"
                  placeholder="your apple-id email"
                  value={email}
                  onChange={(e) => setEmail(e.target.value)}
                  required
                />
                <button type="submit" className="dl-submit" disabled={submitting}>
                  {submitting ? 'Sending…' : <>Send me an invite <span className="arr">→</span></>}
                </button>
                <div className="mono" style={{ color: 'rgba(250,250,247,0.45)', marginTop: 14, fontSize: 9 }}>
                  Usually within 48h · we never share your address
                </div>
              </form>
            ) : (
              <div className="dl-thanks">
                <div className="mono" style={{ color: 'var(--loved)', marginBottom: 12 }}>Saved</div>
                <div className="serif" style={{ fontSize: 36, color: 'var(--paper)', letterSpacing: '-0.5px', lineHeight: 1.1 }}>
                  Your invite is <em>on the way</em>.
                </div>
                <div style={{ color: 'rgba(250,250,247,0.6)', fontSize: 14, marginTop: 18, lineHeight: 1.5, maxWidth: '36ch' }}>
                  Check the email you gave us. If you don't see it within 48 hours, write to hello@plinn.app.
                </div>
              </div>
            )}
          </div>
        </div>
      </div>
    </section>
  );
}

// ═════════════════════════════════════════════════════════════
// FAQ
// ═════════════════════════════════════════════════════════════

const FAQ_ITEMS = [
  {
    q: 'Is Plinn free?',
    a: 'Yes. There may be a paid tier later for unlimited trips or family sharing, but the core of the app — saving, loving, composing — will always be free. We will tell you in plain English before that changes.',
  },
  {
    q: 'How is this different from Google Maps or Apple Maps?',
    a: 'They show every place; we show your places. They monetise discovery; we don\'t. Their map labels what a giant index thinks is important; ours labels what you loved first, what you saved second, and what we found for you last.',
  },
  {
    q: 'Is there really no algorithmic feed?',
    a: 'There is no feed at all. The only places you see are ones you saved or a friend shared. The app does compose trips from your saved places using an AI model — and it tells you which places it pulled from, every time.',
  },
  {
    q: 'What does the AI do, and what does it not do?',
    a: 'It does two things: write itinerary text when you press compose, and parse natural-language search ("coffee my friends liked, walkable from here") against your places. It does not browse the open internet for you, recommend strangers\' places, or learn from your behaviour without telling you.',
  },
  {
    q: 'What about my privacy?',
    a: 'We collect the places you save, the trips you make, and your taste signals — that\'s it. No ad IDs, no third-party SDKs, no background location. "Forget everything" is a single tap and we keep no copy. Read the full stance on the privacy page.',
  },
  {
    q: 'When is Android?',
    a: 'Summer 2026, honestly. We are a small team and we wanted to do iOS very well first. If you sign up for the waitlist with an Android email, we will tell you the day it ships.',
  },
  {
    q: 'How do I share a list with a friend?',
    a: 'Tap and hold any list, then "share." Your friend gets a link; they can open it whether or not they have Plinn. If they do have it, they can save any place from your list with one tap — but never your whole list. The notes and order stay yours.',
  },
];

function FAQ() {
  const [open, setOpen] = useStateL(0);
  return (
    <section className="section" id="faq">
      <div className="section-head">
        <div>
          <div className="eyebrow">09 · Questions</div>
          <h2>The <em>honest</em> ones.</h2>
        </div>
        <div className="lede">
          What people actually ask us, and what we actually say back. No hedges.
        </div>
      </div>

      <div className="faq-list">
        {FAQ_ITEMS.map((item, i) => (
          <div key={i} className={`faq-item ${open === i ? 'open' : ''}`}>
            <button className="faq-q" onClick={() => setOpen(open === i ? -1 : i)}>
              <span className="serif">{item.q}</span>
              <span className="faq-arr mono">{open === i ? '−' : '+'}</span>
            </button>
            <div className="faq-a-wrap">
              <div className="faq-a">{item.a}</div>
            </div>
          </div>
        ))}
      </div>

      <div className="faq-foot mono">
        Something else? <a href="mailto:hello@plinn.app">hello@plinn.app</a>
      </div>
    </section>
  );
}

// ═════════════════════════════════════════════════════════════
// PHOTO BAND — full-bleed cover under the hero
// ═════════════════════════════════════════════════════════════

function PhotoBand() {
  return (
    <section className="photo-band" aria-label="A place someone kept">
      <img
        src="photos/berlin.jpg"
        alt="The Brandenburg Gate at blue hour, lit warm against a cool Berlin sky"
        loading="lazy"
      />
      <div className="photo-band-cap">
        <span className="serif">Somebody's, <em>kept by hand</em>.</span>
        <span className="mono">Berlin · 21:40 · blue hour</span>
      </div>
    </section>
  );
}

// ═════════════════════════════════════════════════════════════
// WORTH KEEPING — editorial photo pairing
// ═════════════════════════════════════════════════════════════

function WorthKeeping() {
  return (
    <section className="section" id="places">
      <div className="section-head">
        <div>
          <div className="eyebrow">Worth the detour</div>
          <h2>Places worth <em>keeping</em>.</h2>
        </div>
        <div className="lede">
          Not the first result. The one a friend mentioned once, that you finally went to, that you'd go back to. <em>Those</em> are the ones Plinn is for.
        </div>
      </div>

      <div className="keep-grid">
        <figure className="keep-photo">
          <img
            src="photos/guggenheim.jpg"
            alt="The Solomon R. Guggenheim Museum's white spiral against a clear sky, New York"
            loading="lazy"
          />
          <figcaption>
            <span className="serif"><em>The spiral.</em></span>
            <span className="mono">New York · 13:02 · art-leaning</span>
          </figcaption>
        </figure>
        <figure className="keep-photo tall">
          <img
            src="photos/neuschwanstein.jpg"
            alt="Neuschwanstein castle on a wooded hill above the Bavarian valley"
            loading="lazy"
          />
          <figcaption>
            <span className="serif"><em>The climb.</em></span>
            <span className="mono">Schwangau · 16:30 · worth it</span>
          </figcaption>
        </figure>
      </div>
    </section>
  );
}

function App() {
  return (
    <>
      <Nav/>
      <Hero/>
      <PhotoBand/>
      <hr className="divider"/>
      <Manifesto/>
      <hr className="divider"/>
      <AskDemo/>
      <hr className="divider"/>
      <MapDemo/>
      <hr className="divider"/>
      <TripDemo/>
      <hr className="divider"/>
      <WorthKeeping/>
      <hr className="divider"/>
      <PhoneTour/>
      <MemorySection/>
      <InvestorSnapshot/>
      <hr className="divider"/>
      <Waitlist/>
      <Download/>
      <FAQ/>
      <Footer/>
    </>
  );
}

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