/* Pricing, Paris audio guide, Languages grid, App-store CTA, Footer */

const { useEffect: appUE, useRef: appUR, useState: appUS, useMemo: appUM } = React;

function Pricing() {
  return (
    <section id="pricing">
      <div className="wrap">
        <div className="section-eyebrow reveal">Honest pricing</div>
        <h2 className="section-title display reveal" style={{ maxWidth: "22ch" }}>
          €4.99 for a city.<br />
          <span style={{ fontFamily: "'Instrument Serif', serif", fontStyle: "italic", fontWeight: 400, letterSpacing: "-0.01em", color: "var(--indigo)" }}>It's almost embarrassing.</span>
        </h2>
        <p className="section-sub reveal">
          A guided tour in Paris runs up to €200 — for one rushed time slot, with whoever the agency sent.
          A walktovisit circuit is €4.99. You pick what you want to see, walk it at your pace, bring whoever you like.
        </p>

        {/* Main VS comparison */}
        <div className="vs-grid reveal stagger">
          <div className="vs-card vs-dim">
            <div className="vs-tag">Private guide tour in Paris</div>
            <div className="vs-price">
              <s>€200</s>
              <span style={{ display: "block", color: "var(--mute)", fontFamily: "'DM Sans'", fontSize: 13, fontWeight: 600, marginTop: 4, letterSpacing: 0 }}>per group · one fixed time slot</span>
            </div>
            <ul className="vs-list vs-list-neg">
              <li><DotX /> Two rushed hours, then it's over</li>
              <li><DotX /> Their script, their pace, their detours</li>
              <li><DotX /> One language only, take it or leave it</li>
              <li><DotX /> No pause, no replay, no second visit</li>
              <li><DotX /> Tip expected on top</li>
            </ul>
          </div>

          <div className="vs-card vs-hero">
            <div className="vs-ribbon">One purchase · yours forever</div>
            <div className="vs-tag" style={{ color: "rgba(255,255,255,0.7)" }}>Walktovisit</div>
            <div className="vs-price vs-price-hero">
              €4.99
              <span style={{ display: "block", fontFamily: "'Instrument Serif', serif", fontStyle: "italic", fontWeight: 400, fontSize: 22, lineHeight: 1.2, marginTop: 8, color: "rgba(255,255,255,0.88)", letterSpacing: 0 }}>
                One circuit. A city's worth of stories.
              </span>
            </div>
            <ul className="vs-list">
              <li><DotCheck /> Hand-crafted circuits — pick what you want to see</li>
              <li><DotCheck /> Pause, replay, walk it again — for life</li>
              <li><DotCheck /> Eight languages, switch any time</li>
              <li><DotCheck /> One purchase, walk it together — bring the family</li>
              <li><DotCheck /> One tap, walking in under two minutes</li>
            </ul>
          </div>
        </div>

        {/* Reassurance row + kebab humor */}
        <div className="reassure-grid reveal stagger">
          <div className="reassure-card">
            <div className="reassure-ico"><IcoInfinity /></div>
            <div className="reassure-title">Pay once. Walk forever.</div>
            <div className="reassure-body">One purchase per city, permanent download. Walk it next summer, lend it to a friend, no extra fee.</div>
          </div>
          <div className="reassure-card">
            <div className="reassure-ico"><IcoPeople /></div>
            <div className="reassure-title">Bring everyone.</div>
            <div className="reassure-body">One €4.99 circuit, one phone — and you walk together. Family of five? Still €4.99.</div>
          </div>
          <div className="reassure-card">
            <div className="reassure-ico"><IcoBolt /></div>
            <div className="reassure-title">Start in two minutes.</div>
            <div className="reassure-body">Choose a circuit, one tap, audio loaded. You're walking before you've finished your coffee.</div>
          </div>
          <div className="reassure-card reassure-humor">
            <div className="reassure-ico" style={{ background: "rgba(255,210,76,0.22)", color: "#9A6E00" }}>
              <svg width="22" height="22" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2" strokeLinecap="round" strokeLinejoin="round">
                <path d="M6 4 H18 V8 Q12 11 6 8 Z" />
                <path d="M5 8 Q12 12 19 8 L18 18 Q12 22 6 18 Z" />
                <path d="M9 12 V18 M12 13 V19 M15 12 V18" opacity=".5" />
              </svg>
            </div>
            <div className="reassure-title">A kebab? <span style={{ fontFamily: "'Instrument Serif', serif", fontStyle: "italic", fontWeight: 400 }}>€9.</span></div>
            <div className="reassure-body">That's two Walktovisits. And it's worse for your heart.</div>
          </div>
        </div>
      </div>
    </section>
  );
}

function DotCheck() {
  return (
    <span className="dot-check">
      <svg width="11" height="11" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="3.5" strokeLinecap="round" strokeLinejoin="round"><polyline points="5 12 10 17 19 7" /></svg>
    </span>
  );
}
function DotX() {
  return (
    <span className="dot-x">
      <svg width="11" height="11" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="3" strokeLinecap="round" strokeLinejoin="round"><path d="M6 6 L18 18 M18 6 L6 18" /></svg>
    </span>
  );
}
function IcoInfinity() {
  return (
    <svg width="22" height="22" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2" strokeLinecap="round">
      <path d="M6 12c0-2 1.5-4 4-4s4 4 4 4 1.5 4 4 4 4-2 4-4-1.5-4-4-4-4 4-4 4-1.5 4-4 4-4-2-4-4z" />
    </svg>
  );
}
function IcoPeople() {
  return (
    <svg width="22" height="22" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2" strokeLinecap="round" strokeLinejoin="round">
      <circle cx="9" cy="8" r="3.2" />
      <path d="M3 20a6 6 0 0 1 12 0" />
      <circle cx="17" cy="9" r="2.4" />
      <path d="M15.5 20a5 5 0 0 1 6-4" />
    </svg>
  );
}
function IcoBolt() {
  return (
    <svg width="22" height="22" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2" strokeLinecap="round" strokeLinejoin="round">
      <path d="M13 2 L4 14 H11 L10 22 L20 10 H13 Z" />
    </svg>
  );
}

/* ---- Paris stops shown in the feature block ---- */
const PARIS_STOPS = [
  { name: "Tour Eiffel",      km: 0.2, current: true },
  { name: "Arc de Triomphe",  km: 1.4 },
  { name: "Louvre",           km: 2.5 },
  { name: "Notre-Dame",       km: 3.4 },
  { name: "Panthéon",         km: 4.3 },
  { name: "Sacré-Cœur",        km: 5.4 },
];

const CIRCUIT_STATS = [
  { label: "Total distance",  value: "5.4 km" },
  { label: "Walking time",    value: "≈ 1h45" },
  { label: "Audio narration", value: "38 min" },
  { label: "Stops",           value: "6 POI" },
];

function AudioFeature() {
  return (
    <section id="how">
      <div className="wrap">
        <div className="section-eyebrow reveal">Audio guide</div>
        <h2 className="section-title display reveal">
          Crystal-clear narration.<br />
          <span style={{ fontFamily: "'Instrument Serif', serif", fontStyle: "italic", fontWeight: 400, color: "var(--indigo)" }}>Probably better than the guide.</span>
        </h2>
        <p className="section-sub reveal">
          Studio-grade audio in all eight languages, ready before you arrive at a stop.
          Switch language mid-sentence — the app, the labels, the validate button — everything follows.
        </p>

        <div className="feature-grid">
          <div className="feature reveal">
            <div className="ico">
              <svg width="22" height="22" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2.2" strokeLinecap="round" strokeLinejoin="round"><path d="M9 18V5l12-2v13M9 13l12-2M6 18a3 3 0 1 1-3-3 3 3 0 0 1 3 3zm15-3a3 3 0 1 1-3-3 3 3 0 0 1 3 3z" /></svg>
            </div>
            <h4>The audio is the whole show.</h4>
            <p>Studio-grade voices, mixed with the right pauses and the right pace. It sounds like someone <em style={{ fontFamily: "'Instrument Serif', serif", fontStyle: "italic" }}>who actually loves the place</em> — not a tour guide on their fifth tour of the day.</p>

            <div className="audio-feats">
              <div className="audio-feat">
                <div className="audio-feat-ico">
                  <svg width="18" height="18" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2" strokeLinecap="round" strokeLinejoin="round"><circle cx="12" cy="12" r="9" /><path d="M9 8 L9 16 L17 12 Z" fill="currentColor" /></svg>
                </div>
                <div>
                  <b>Studio-grade audio.</b>
                  <span>Clean recording, no echo from the loudspeaker at the entrance.</span>
                </div>
              </div>
              <div className="audio-feat">
                <div className="audio-feat-ico">
                  <svg width="18" height="18" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2" strokeLinecap="round" strokeLinejoin="round"><path d="M3 12 A9 9 0 1 1 12 21" /><path d="M3 12 H9" /><path d="M21 12 H15" /><path d="M12 3 A9 9 0 0 1 12 21" /></svg>
                </div>
                <div>
                  <b>Tap a flag, the app translates.</b>
                  <span>Switch language mid-sentence — labels, narration, buttons, everything follows.</span>
                </div>
              </div>
              <div className="audio-feat">
                <div className="audio-feat-ico">
                  <svg width="18" height="18" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2" strokeLinecap="round" strokeLinejoin="round"><path d="M6 4 H10 V20 H6 Z" /><path d="M14 4 H18 V20 H14 Z" /></svg>
                </div>
                <div>
                  <b>Pause. Rewind. Replay forever.</b>
                  <span>Hold up at a window, replay the punchline, take the same tour again next summer.</span>
                </div>
              </div>
              <div className="audio-feat">
                <div className="audio-feat-ico">
                  <svg width="18" height="18" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2" strokeLinecap="round" strokeLinejoin="round"><path d="M5 12.5 Q12 6 19 12.5" /><path d="M8 15.5 Q12 12 16 15.5" /><circle cx="12" cy="19" r="1.2" fill="currentColor" /><path d="M3 3 L21 21" /></svg>
                </div>
                <div>
                  <b>Works without signal.</b>
                  <span>Downloaded the second you buy. No data surprise on a foreign SIM.</span>
                </div>
              </div>
            </div>
          </div>

          <div className="feature dark reveal feature-audio-phone">
            <AudioGuidePhone />
          </div>
        </div>
      </div>
    </section>
  );
}

/* ---- Audio guide: live narration that cycles 8 languages, app UI follows ---- */
const NARRATIONS = [
  { code: "FR", flag: "🇫🇷", name: "Français",
    ui: { nowPlaying: "Audio guide en cours", validate: "Valider la visite", subtitle: "Paris · Montmartre" },
    text: "Perchée au sommet de Montmartre, la basilique du Sacré-Cœur fut commencée en 1875 et achevée seulement en 1914. Sa pierre de travertin blanchit au contact de la pluie — c'est pourquoi elle scintille après chaque averse, comme une promesse renouvelée à la ville." },
  { code: "EN", flag: "🇬🇧", name: "English",
    ui: { nowPlaying: "Audio guide playing", validate: "Validate visit", subtitle: "Paris · Montmartre" },
    text: "Perched at the summit of Montmartre, the Sacré-Cœur basilica was begun in 1875 and only completed in 1914. Its travertine stone whitens when it meets the rain — which is why the church glows after every shower, like a promise renewed to the city below." },
  { code: "DE", flag: "🇩🇪", name: "Deutsch",
    ui: { nowPlaying: "Audioführer läuft", validate: "Besuch bestätigen", subtitle: "Paris · Montmartre" },
    text: "Auf dem Gipfel des Montmartre thronend, wurde die Basilika Sacré-Cœur 1875 begonnen und erst 1914 vollendet. Ihr Travertin-Stein wird beim Kontakt mit Regen weißer — deshalb leuchtet sie nach jedem Schauer, wie ein erneuertes Versprechen an die Stadt." },
  { code: "ES", flag: "🇪🇸", name: "Español",
    ui: { nowPlaying: "Audioguía en curso", validate: "Validar visita", subtitle: "París · Montmartre" },
    text: "Encaramada en la cima de Montmartre, la basílica del Sacré-Cœur se comenzó en 1875 y se completó en 1914. Su piedra de travertino se blanquea al contacto con la lluvia — por eso brilla después de cada chubasco, como una promesa renovada a la ciudad." },
  { code: "IT", flag: "🇮🇹", name: "Italiano",
    ui: { nowPlaying: "Audioguida in riproduzione", validate: "Convalida visita", subtitle: "Parigi · Montmartre" },
    text: "Arroccata sulla cima di Montmartre, la basilica del Sacré-Cœur fu iniziata nel 1875 e completata solo nel 1914. La sua pietra di travertino sbianca al contatto con la pioggia — per questo brilla dopo ogni acquazzone, come una promessa rinnovata alla città." },
  { code: "NL", flag: "🇳🇱", name: "Nederlands",
    ui: { nowPlaying: "Audiogids speelt", validate: "Bezoek bevestigen", subtitle: "Parijs · Montmartre" },
    text: "Hoog op de top van Montmartre begonnen ze in 1875 met de Sacré-Cœur basiliek, voltooid in 1914. Haar travertijnsteen wordt witter bij elke regenbui — daarom schittert ze na elke bui, als een vernieuwde belofte aan de stad." },
  { code: "PT", flag: "🇵🇹", name: "Português",
    ui: { nowPlaying: "Audioguia a tocar", validate: "Validar visita", subtitle: "Paris · Montmartre" },
    text: "Empoleirada no topo de Montmartre, a basílica do Sacré-Cœur foi iniciada em 1875 e concluída em 1914. A sua pedra de travertino branqueia ao contacto com a chuva — por isso brilha após cada aguaceiro, como uma promessa renovada à cidade." },
  { code: "ZH", flag: "🇨🇳", name: "中文",
    ui: { nowPlaying: "正在播放音频导览", validate: "确认参观", subtitle: "巴黎 · 蒙马特" },
    text: "矗立在蒙马特之巅的圣心大教堂始建于1875年，直到1914年才落成。它的石灰华石与雨水接触后会变得更白，因此每场雨后都会熠熠生辉，如同向城市许下的新承诺。" },
];

function AudioGuidePhone() {
  const [langIdx, setLangIdx] = appUS(0);
  const [progress, setProgress] = appUS(0);
  const [audioT, setAudioT] = appUS(0);
  const [fade, setFade] = appUS(0);

  appUE(() => {
    let raf;
    let langStart = performance.now();
    const LANG_MS = 5200;          // longer dwell so users actually read
    const FADE_IN_MS = 280;
    const FADE_OUT_AT = 4800;
    let curIdx = 0;
    const audioStart = performance.now();
    function tick(now) {
      const elapsed = now - langStart;
      if (elapsed >= LANG_MS) {
        curIdx = (curIdx + 1) % NARRATIONS.length;
        setLangIdx(curIdx);
        langStart = now;
        setProgress(0);
        setFade(0);
      } else if (elapsed < FADE_IN_MS) {
        setFade(elapsed / FADE_IN_MS);
        setProgress(0);
      } else if (elapsed < FADE_OUT_AT) {
        setFade(1);
        setProgress((elapsed - FADE_IN_MS) / (FADE_OUT_AT - FADE_IN_MS));
      } else {
        setFade(1 - (elapsed - FADE_OUT_AT) / (LANG_MS - FADE_OUT_AT));
        setProgress(1);
      }
      const totalSec = 102;
      setAudioT((((now - audioStart) / 1000) % totalSec) / totalSec);
      raf = requestAnimationFrame(tick);
    }
    raf = requestAnimationFrame(tick);
    return () => cancelAnimationFrame(raf);
  }, []);

  const lang = NARRATIONS[langIdx];
  const isCJK = lang.code === "ZH";
  const tokens = isCJK
    ? Array.from(lang.text).map((c) => ({ str: c, isWord: !/\s/.test(c) }))
    : lang.text.split(/(\s+)/).filter((t) => t !== "").map((t) => ({ str: t, isWord: !/^\s+$/.test(t) }));
  const wordCount = tokens.filter((t) => t.isWord).length;
  const activeCount = Math.floor(progress * (wordCount + 0.5));
  let wIdx = 0;

  const audioSec = audioT * 102;
  const mm = Math.floor(audioSec / 60);
  const ss = Math.floor(audioSec) % 60;
  const audioTime = `${mm}:${ss.toString().padStart(2, "0")}`;

  return (
    <div className="audio-phone">
      <div className="audio-phone-screen">
        <div className="audio-phone-notch" />

        {/* Map background showing the user is in visit mode */}
        <AudioMapBackdrop />

        {/* Top: live pill (label translates) + flag pill (animates on change) */}
        <div className="audio-top-row">
          <div className="audio-live-pill" key={lang.code + "-live"}>
            <span className="audio-rec-dot" />
            <span className="audio-live-label">{lang.ui.nowPlaying}</span>
          </div>
          <div className="audio-flag-pill" key={lang.code + "-flag"}>
            <span className="audio-flag-emoji">{lang.flag}</span>
            <span className="audio-flag-code">{lang.code}</span>
          </div>
        </div>

        {/* Drawer covering the bottom — the focus */}
        <div className="audio-drawer">
          <div className="audio-drawer-grip" />

          <div className="audio-drawer-head">
            <div>
              <div className="audio-monument-eyebrow" key={lang.code + "-sub"}>{lang.ui.subtitle}</div>
              <div className="audio-monument-name">Sacré-Cœur</div>
            </div>
            <div className="audio-hd-pill">
              <svg width="11" height="11" viewBox="0 0 24 24" fill="currentColor"><path d="M12 2 L14.5 9 L22 9 L16 13.5 L18.5 21 L12 16.5 L5.5 21 L8 13.5 L2 9 L9.5 9 Z" /></svg>
              <span>HD · Studio quality</span>
            </div>
          </div>

          <div
            className={"audio-narration" + (isCJK ? " audio-narration-cjk" : "")}
            style={{ opacity: 0.35 + 0.65 * fade }}
            key={lang.code + "-text"}
          >
            {tokens.map((tok, i) => {
              if (!tok.isWord) return <span key={i}>{tok.str}</span>;
              const idx = wIdx++;
              const on = idx < activeCount;
              return <span key={i} className={"nw" + (on ? " nw-on" : "")}>{tok.str}</span>;
            })}
          </div>

          <div className="audio-bottom-bar">
            <button className="audio-ctrl-play" aria-label="play">
              <svg width="16" height="16" viewBox="0 0 24 24" fill="currentColor"><path d="M6 4v16l14-8z" /></svg>
            </button>
            <div className="audio-progress">
              <div className="audio-progress-fill" style={{ width: `${audioT * 100}%` }} />
              <div className="audio-progress-knob" style={{ left: `${audioT * 100}%` }} />
            </div>
            <span className="audio-time-text">{audioTime}</span>
          </div>

          <button className="audio-validate" key={lang.code + "-btn"}>
            <svg width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="3" strokeLinecap="round" strokeLinejoin="round"><polyline points="5 12 10 17 19 7" /></svg>
            <span>{lang.ui.validate}</span>
          </button>
        </div>
      </div>
    </div>
  );
}

/* Faded map background hint, behind the audio drawer.
   Simplified: just a soft city map with one big purple circular pin
   marking the 3rd point of visit. No fake circuit. */
function AudioMapBackdrop() {
  return (
    <div className="audio-map-bg">
      <div className="audio-map-inner">
        {/* base + parks */}
        <div className="audio-map-park" style={{ left: "8%", top: "10%", width: "55%", height: "40%", borderRadius: "55% 45% 60% 40% / 50%" }} />
        <div className="audio-map-park" style={{ right: "-8%", top: "35%", width: "40%", height: "30%", borderRadius: "60% 40% 55% 45% / 50%" }} />
        <svg className="audio-map-svg" viewBox="0 0 200 240" preserveAspectRatio="none">
          {/* streets — quiet grid only */}
          <g stroke="#F2F4F8" strokeWidth="6" fill="none" strokeLinecap="round">
            <path d="M 0 60 L 200 70" />
            <path d="M 0 150 L 200 130" />
            <path d="M 60 0 L 80 240" />
            <path d="M 140 0 L 130 240" />
          </g>
          {/* tiny building blocks */}
          <g fill="#FFFFFF" stroke="#E0E2EC" strokeWidth=".5">
            <rect x="20" y="40"  width="14" height="12" rx="1" />
            <rect x="46" y="30"  width="10" height="10" rx="1" />
            <rect x="100" y="46" width="14" height="12" rx="1" />
            <rect x="150" y="30" width="14" height="12" rx="1" />
            <rect x="22" y="170" width="14" height="10" rx="1" />
            <rect x="154" y="170" width="14" height="10" rx="1" />
            <rect x="70" y="100" width="10" height="10" rx="1" />
          </g>
        </svg>

        {/* single numbered pin — 3rd point of visit */}
        <div className="audio-map-numpin" style={{ left: "55%", top: "32%" }}>
          <div className="audio-map-numpin-pulse" />
          <div className="audio-map-numpin-dot">3</div>
        </div>
      </div>
    </div>
  );
}

function AudioBars({ progress }) {
  const BARS = 36;
  // Pre-computed pseudo-waveform heights (deterministic, varied)
  const heights = appUM(() => {
    const out = [];
    for (let i = 0; i < BARS; i++) {
      const a = Math.sin(i * 0.6) * 0.4;
      const b = Math.sin(i * 0.13 + 1.5) * 0.3;
      const c = Math.sin(i * 0.07) * 0.2;
      out.push(Math.max(0.18, Math.min(1, 0.55 + a + b + c)));
    }
    return out;
  }, []);
  return (
    <div className="audio-bars">
      {heights.map((h, i) => {
        const played = i / BARS <= progress;
        return (
          <span
            key={i}
            className={"audio-bar" + (played ? " audio-bar-played" : "")}
            style={{
              height: `${Math.round(h * 100)}%`,
              animationDelay: `${(i % 8) * 0.08}s`,
            }}
          />
        );
      })}
    </div>
  );
}

/* Mini Mapbox-style map inside the phone (matches the in-app validate screen, no Eiffel photo) */
function PhoneMiniMap() {
  return (
    <div style={{ position: "absolute", inset: "14px 14px 0 14px", height: "58%", borderRadius: "24px 24px 0 0", overflow: "hidden",
         background: "linear-gradient(180deg, #DDEEDF, #C8E4CE)" }}>
      {/* park splotches */}
      <div style={{ position: "absolute", left: "-10%", top: "45%", width: "60%", height: "45%", background: "#B3D9BA", borderRadius: "55% 45% 60% 40% / 50%" }} />
      <div style={{ position: "absolute", right: "-5%", top: "60%", width: "40%", height: "35%", background: "#A8D2B0", borderRadius: "50% 60% 45% 55% / 50%" }} />
      {/* river */}
      <svg viewBox="0 0 200 240" preserveAspectRatio="none" style={{ position: "absolute", inset: 0, width: "100%", height: "100%" }}>
        <path d="M -10 60 C 60 40 90 90 200 70" stroke="#BFE3F2" strokeWidth="14" fill="none" strokeLinecap="round" />
        {/* side streets */}
        <g stroke="#F2F4F8" strokeWidth="6" fill="none" strokeLinecap="round">
          <path d="M 0 140 L 200 130" />
          <path d="M 60 0 L 80 240" />
          <path d="M 140 0 L 130 240" />
        </g>
        {/* main road background */}
        <path d="M 30 220 C 60 180 100 160 120 120 S 160 80 200 60" stroke="#EBEDF3" strokeWidth="16" fill="none" strokeLinecap="round" />
        {/* indigo route */}
        <path d="M 30 220 C 60 180 100 160 120 120 S 160 80 200 60" stroke="#6E5BFF" strokeWidth="7" fill="none" strokeLinecap="round" />
        <path d="M 30 220 C 60 180 100 160 120 120 S 160 80 200 60" stroke="#fff" strokeWidth="1.6" fill="none" strokeLinecap="round" strokeDasharray="1 6" opacity=".6" />
        {/* tiny building blocks */}
        <g fill="#FFFFFF" stroke="#E0E2EC" strokeWidth=".5">
          <rect x="22" y="40" width="14" height="10" rx="1" />
          <rect x="42" y="30" width="10" height="10" rx="1" />
          <rect x="100" y="40" width="14" height="12" rx="1" />
          <rect x="150" y="30" width="16" height="10" rx="1" />
          <rect x="22" y="160" width="14" height="10" rx="1" />
          <rect x="154" y="160" width="14" height="10" rx="1" />
        </g>
      </svg>
      {/* Pin for current stop — Tour Eiffel, with mini icon */}
      <div style={{ position: "absolute", left: "58%", top: "22%", transform: "translate(-50%, -100%)", display: "flex", flexDirection: "column", alignItems: "center", gap: 4 }}>
        <div style={{ width: 48, height: 60, padding: 4, background: "#fff", borderRadius: 10, boxShadow: "0 8px 18px rgba(20,18,58,0.18), 0 0 0 2px #6E5BFF" }}>
          <svg viewBox="0 0 100 140" fill="none" stroke="#0E1235" strokeWidth="3" strokeLinecap="round" strokeLinejoin="round" style={{ width: "100%", height: "100%" }}>
            <path d="M8 134 C 22 110 32 90 38 78" /><path d="M92 134 C 78 110 68 90 62 78" />
            <path d="M34 134 L36 78 M66 134 L64 78" /><path d="M22 78 L78 78" />
            <path d="M38 78 L46 38 M62 78 L54 38" /><path d="M44 38 L56 38" /><path d="M50 38 L50 8" />
          </svg>
        </div>
        <div style={{ width: 0, height: 0, borderLeft: "5px solid transparent", borderRight: "5px solid transparent", borderTop: "6px solid #6E5BFF", marginTop: -2 }} />
      </div>
      {/* You-are-here puck */}
      <div style={{ position: "absolute", left: "22%", top: "82%", width: 22, height: 22, borderRadius: "50%", background: "#6E5BFF", border: "3px solid #fff", boxShadow: "0 4px 10px rgba(110,91,255,0.5)" }}>
        <div style={{ position: "absolute", inset: -6, borderRadius: "50%", border: "2px solid rgba(110,91,255,.4)", animation: "puckPulse 2.2s ease-out infinite" }} />
      </div>
      {/* compass */}
      <div style={{ position: "absolute", top: 8, right: 8, width: 26, height: 26, borderRadius: "50%", background: "#fff", boxShadow: "0 2px 6px rgba(20,18,58,.15)", display: "grid", placeItems: "center", fontSize: 9, fontWeight: 700, color: "#0E1235", fontFamily: "'JetBrains Mono'" }}>N</div>
    </div>
  );
}

/* kept for legacy: not used anymore */
function PhoneEiffelImage_unused() {
  return (
    <div style={{ position: "absolute", inset: "14px 14px 14px", height: "calc(100% - 28px)", borderRadius: 24, overflow: "hidden", background: "linear-gradient(180deg, #C7DCEF 0%, #E8C788 60%, #A26C49 100%)" }}>
      {/* sun */}
      <div style={{ position: "absolute", right: "16%", top: "12%", width: 38, height: 38, borderRadius: "50%", background: "radial-gradient(circle, #FFE7BB, #FFC773 70%, transparent 75%)" }} />
      {/* ground/grass */}
      <div style={{ position: "absolute", left: 0, right: 0, bottom: 0, height: "26%", background: "linear-gradient(180deg, #82A86A, #4F7644)" }} />
      {/* Tour Eiffel silhouette */}
      <div style={{ position: "absolute", left: "50%", bottom: "12%", transform: "translateX(-50%)", height: "72%", aspectRatio: "400 / 1000", color: "#1E2440" }}>
        <svg viewBox="0 0 400 1000" fill="currentColor" style={{ width: "100%", height: "100%", filter: "drop-shadow(0 6px 10px rgba(0,0,0,0.3))" }}>
          <path fillRule="evenodd" d="M 10 1000 Q 40 945 70 890 Q 88 862 95 840 L 132 645 L 175 150 L 197 82 L 200 10 L 203 82 L 225 150 L 268 645 L 305 840 Q 312 862 330 890 Q 360 945 390 1000 Z M 132 1000 L 130 884 Q 148 845 200 832 Q 252 845 270 884 L 268 1000 Z" />
          <rect x="80" y="822" width="240" height="18" />
          <rect x="128" y="638" width="144" height="11" />
          <rect x="170" y="146" width="60" height="9" />
        </svg>
      </div>
      {/* clouds */}
      <div style={{ position: "absolute", left: "10%", top: "20%", width: 60, height: 14, background: "rgba(255,255,255,0.7)", borderRadius: 999, filter: "blur(2px)" }} />
      <div style={{ position: "absolute", right: "8%", top: "32%", width: 44, height: 10, background: "rgba(255,255,255,0.6)", borderRadius: 999, filter: "blur(2px)" }} />
    </div>
  );
}

/* ---- Languages: grid of 8 cards, no more globe ---- */
const LANGS = [
  { code: "FR", name: "Français",   greet: "Bonjour Paris", flag: "🇫🇷" },
  { code: "EN", name: "English",    greet: "Hello, Paris",  flag: "🇬🇧" },
  { code: "DE", name: "Deutsch",    greet: "Hallo, Paris",  flag: "🇩🇪" },
  { code: "NL", name: "Nederlands", greet: "Hallo, Parijs", flag: "🇳🇱" },
  { code: "ZH", name: "中文",         greet: "你好，巴黎",     flag: "🇨🇳" },
  { code: "PT", name: "Português",  greet: "Olá, Paris",    flag: "🇵🇹" },
  { code: "ES", name: "Español",    greet: "Hola, París",   flag: "🇪🇸" },
  { code: "IT", name: "Italiano",   greet: "Ciao, Parigi",  flag: "🇮🇹" },
];

function Languages() {
  const [active, setActive] = appUS(0);
  return (
    <section id="languages">
      <div className="wrap">
        <div className="section-eyebrow reveal">Eight languages, one app</div>
        <h2 className="section-title display reveal">
          Every traveller hears their<br />own mother tongue.
        </h2>
        <p className="section-sub reveal">
          Walktovisit speaks French, English, German, Dutch, Chinese, Portuguese, Spanish and Italian — switch any time, even mid-tour.
        </p>

        <div className="lang-grid reveal stagger">
          {LANGS.map((l, i) => (
            <button
              key={l.code}
              className={"lang-card" + (i === active ? " active" : "")}
              onMouseEnter={() => setActive(i)}
              onFocus={() => setActive(i)}
              type="button"
            >
              <div className="lang-card-top">
                <span className="lang-flag">{l.flag}</span>
                <span className="lang-code">{l.code}</span>
              </div>
              <div className="lang-card-mid">
                <div className="lang-name">{l.name}</div>
                <div className="lang-greet">{l.greet}</div>
              </div>
              <div className="lang-card-bot">
                <svg width="14" height="14" viewBox="0 0 24 24" fill="currentColor" aria-hidden="true">
                  <path d="M8 5v14l11-7z" />
                </svg>
                <div className="lang-waves" aria-hidden="true">
                  {[5, 9, 14, 7, 12, 16, 10, 6, 12, 9, 14, 8].map((h, k) => (
                    <span key={k} style={{ height: `${h}px`, animationDelay: `${k * 0.08}s` }} />
                  ))}
                </div>
              </div>
            </button>
          ))}
        </div>
      </div>
    </section>
  );
}

function FinalCTA() {
  return (
    <section id="download" className="cta-final">
      <div className="cta-final-bg" aria-hidden="true" />
      <div className="wrap cta-final-wrap">
        <div className="cta-final-text reveal">
          <div className="cta-final-eyebrow">
            <span className="dot" /> Available on iOS &amp; Android
          </div>
          <h2 className="cta-final-title display">
            An original way<br />
            to visit a city.<br />
            <span className="serif-italic">At your pace.</span>
            <span className="serif-italic"> In your language.</span>
          </h2>
          <p className="cta-final-lede">
            No bus. No badge. No guide hurrying you along.
            Just a city, an audio guide in your pocket, and the time to taste every street of it.
          </p>
          <div className="cta-final-actions">
            <a className="store-badge" href="#">
              <svg width="26" height="26" viewBox="0 0 24 24" fill="#0E1235"><path d="M17.5 12.5c0-3 2.5-4.4 2.6-4.5-1.4-2.1-3.7-2.3-4.5-2.4-1.9-.2-3.7 1.1-4.7 1.1s-2.5-1.1-4.1-1.1c-2.1 0-4 1.2-5.1 3.1-2.2 3.8-.6 9.3 1.5 12.4 1 1.5 2.3 3.1 3.9 3.1 1.6-.1 2.2-1 4.1-1s2.4 1 4.1 1c1.7 0 2.8-1.5 3.8-3 1.2-1.7 1.7-3.4 1.7-3.5-.1 0-3.3-1.3-3.3-5.2zM14.4 4.5c.9-1 1.4-2.5 1.3-3.9-1.2.1-2.7.8-3.6 1.8-.8.9-1.5 2.3-1.3 3.7 1.3.1 2.7-.7 3.6-1.6z" /></svg>
              <span className="label"><small>Download on the</small><b>App Store</b></span>
            </a>
            <a className="store-badge" href="#">
              <svg width="24" height="24" viewBox="0 0 24 24">
                <path d="M3.6 2.7L13.5 12.5 3.6 22.3c-.4-.3-.6-.7-.6-1.2V3.9c0-.5.2-.9.6-1.2z" fill="#6E5BFF" />
                <path d="M17.5 8.6l-3-1.7L3.6 2.7l9.9 9.8 4-3.9z" fill="#FFD24C" />
                <path d="M17.5 16.4l3-1.7c.9-.5.9-1.9 0-2.4l-3-1.7-4 3.9z" fill="#FF6B6B" />
                <path d="M3.6 22.3L14.5 17l3-1.7-4-3.9-9.9 10.9z" fill="#3DDC84" />
              </svg>
              <span className="label"><small>Get it on</small><b>Google Play</b></span>
            </a>
          </div>
          <div className="cta-final-trust">
            <span><b>€4.99</b> per circuit</span>
            <span className="cta-dot" />
            <span><b>8</b> languages</span>
            <span className="cta-dot" />
            <span>No subscription</span>
            <span className="cta-dot" />
            <span>No tracking</span>
          </div>

          <div className="cta-final-quote">
            <span className="cta-final-mark serif-italic">"</span>
            <span>Pack light. <span className="serif-italic">Walk slow.</span> Listen close.</span>
          </div>
        </div>

        <div className="cta-final-device reveal">
          <CtaHomePhone />
        </div>
      </div>
    </section>
  );
}

/* Premium phone mock for the CTA: reproduces the app's Explorer screen */
const EXPLORER_NEARBY = [
  { city: "Annecy",   count: 4, country: "France",
    // photo intentionally omitted — gradient + Alpine-lake silhouette below
    photo: null,
    overlay: "lake",
    fallback: "linear-gradient(160deg, #BFE4EE 0%, #5FA9C0 45%, #1F4A66 100%)" },
  { city: "Grenoble", count: 2, country: "France",
    photo: null,
    overlay: "alps",
    fallback: "linear-gradient(170deg, #D7DCE3 0%, #7E8EA0 45%, #2C3849 100%)" },
  { city: "Genève",   count: 1, country: "Suisse",
    photo: "https://images.unsplash.com/photo-1573593930664-46c2c5c81ab8?w=600&q=80",
    fallback: "linear-gradient(135deg, #B7D8E5, #5B7A93 70%, #2F415A)" },
];
const EXPLORER_NEW = [
  { city: "Paris",     count: 5, country: "France",
    photo: "https://images.unsplash.com/photo-1502602898657-3e91760cbb34?w=600&q=80",
    fallback: "linear-gradient(160deg, #F4B879, #C5764A 50%, #4B2D38)" },
  { city: "Rome",      count: 4, country: "Italie",
    photo: "https://images.unsplash.com/photo-1552832230-c0197dd311b5?w=600&q=80",
    fallback: "linear-gradient(135deg, #E8C28D, #A86E3C 70%, #3D2818)" },
  { city: "Barcelone", count: 3, country: "Espagne",
    photo: "https://images.unsplash.com/photo-1583422409516-2895a77efded?w=600&q=80",
    fallback: "linear-gradient(135deg, #F5C589, #C97A4B 70%, #5B2C2C)" },
  { city: "Amsterdam", count: 3, country: "Pays-Bas",
    photo: "https://images.unsplash.com/photo-1534351450181-ea9f78427fe8?w=600&q=80",
    fallback: "linear-gradient(135deg, #A0BAA8, #4F6E5F 70%, #243530)" },
  { city: "Nice",      count: 2, country: "France",
    photo: "https://images.unsplash.com/photo-1491166617655-0723a0a1d3a0?w=600&q=80",
    fallback: "linear-gradient(135deg, #87BFD9, #2F6E94 70%, #133248)" },
];

function CityOverlay({ kind }) {
  if (kind === "alps") {
    // Layered alpine mountain silhouettes with snow caps
    return (
      <svg viewBox="0 0 200 240" preserveAspectRatio="xMidYMax slice"
           style={{ position:"absolute", inset:0, width:"100%", height:"100%", pointerEvents:"none" }}>
        {/* far range */}
        <path d="M0 170 L40 130 L70 155 L110 110 L150 145 L200 105 L200 240 L0 240 Z"
              fill="rgba(255,255,255,0.18)" />
        {/* mid range */}
        <path d="M0 200 L30 165 L60 185 L95 145 L130 180 L170 150 L200 175 L200 240 L0 240 Z"
              fill="rgba(20,30,55,0.35)" />
        {/* snow caps on peaks */}
        <path d="M105 117 L110 110 L118 120 L114 122 Z M193 113 L200 105 L200 119 Z"
              fill="rgba(255,255,255,0.7)" />
        {/* foreground */}
        <path d="M0 220 L50 200 L110 215 L170 195 L200 210 L200 240 L0 240 Z"
              fill="rgba(15,22,40,0.55)" />
      </svg>
    );
  }
  if (kind === "lake") {
    // Lake with reflected mountains
    return (
      <svg viewBox="0 0 200 240" preserveAspectRatio="xMidYMax slice"
           style={{ position:"absolute", inset:0, width:"100%", height:"100%", pointerEvents:"none" }}>
        {/* distant mountains */}
        <path d="M0 130 L40 95 L70 115 L110 80 L150 110 L200 90 L200 150 L0 150 Z"
              fill="rgba(20,40,70,0.30)" />
        <path d="M105 86 L110 80 L116 88 Z" fill="rgba(255,255,255,0.55)" />
        {/* lake surface */}
        <rect x="0" y="150" width="200" height="90" fill="rgba(8,30,55,0.45)" />
        {/* reflection — softer & inverted */}
        <path d="M0 150 L40 175 L70 162 L110 185 L150 168 L200 180 L200 150 Z"
              fill="rgba(255,255,255,0.10)" />
        {/* ripple highlights */}
        <g stroke="rgba(255,255,255,0.32)" strokeWidth="0.8" fill="none">
          <path d="M10 200 Q40 197 70 200" />
          <path d="M90 215 Q120 212 150 215" />
          <path d="M30 225 Q60 222 90 225" />
        </g>
      </svg>
    );
  }
  return null;
}

function ExplorerCard({ data }) {
  const hasPhoto = !!data.photo;
  const bg = hasPhoto
    ? {
        backgroundImage: `linear-gradient(180deg, rgba(0,0,0,0) 30%, rgba(0,0,0,0.65) 100%), url("${data.photo}"), ${data.fallback}`,
        backgroundSize: "cover, cover, cover",
        backgroundPosition: "center, center, center",
      }
    : { backgroundImage: data.fallback };
  return (
    <div className="ex-card" style={{ background: data.fallback, ...bg, position: "relative" }}>
      {!hasPhoto && <CityOverlay kind={data.overlay} />}
      {/* gradient overlay for readability on overlay cards */}
      {!hasPhoto && (
        <div style={{ position: "absolute", inset: 0,
                      background: "linear-gradient(180deg, rgba(0,0,0,0) 40%, rgba(0,0,0,0.55) 100%)",
                      pointerEvents: "none" }} />
      )}
      <div className="ex-card-meta">
        <div className="ex-card-country">{data.country.toUpperCase()}</div>
        <div className="ex-card-city">{data.city}</div>
        <div className="ex-card-circuits">{data.count} circuit{data.count > 1 ? "s" : ""}</div>
      </div>
    </div>
  );
}

function CtaHomePhone() {
  return (
    <div className="cta-phone-frame">
      <div className="cta-phone-screen ex-screen">
        {/* iOS status bar — matches the screenshot's "23:16" with location arrow + signal/wifi/97% battery */}
        <div className="ex-status">
          <div className="ex-status-l">
            <span>23:16</span>
            <svg width="11" height="11" viewBox="0 0 24 24" fill="#0E1235"><path d="M2 12 L22 4 L14 22 L12 14 Z" /></svg>
          </div>
          <div className="ex-notch" />
          <div className="ex-status-r">
            {/* signal bars */}
            <svg width="16" height="10" viewBox="0 0 16 10" fill="#0E1235">
              <rect x="0"  y="7" width="3" height="3" rx="0.6" />
              <rect x="4"  y="5" width="3" height="5" rx="0.6" />
              <rect x="8"  y="3" width="3" height="7" rx="0.6" />
              <rect x="12" y="1" width="3" height="9" rx="0.6" opacity="0.35" />
            </svg>
            {/* wifi */}
            <svg width="14" height="10" viewBox="0 0 16 12" fill="none" stroke="#0E1235" strokeWidth="1.5" strokeLinecap="round">
              <path d="M2 5 Q8 0 14 5" />
              <path d="M4 7.5 Q8 4 12 7.5" />
              <circle cx="8" cy="10.5" r="1" fill="#0E1235" />
            </svg>
            {/* battery (97 % green) */}
            <div className="ex-battery">
              <span>97</span>
              <div className="ex-battery-shell">
                <div className="ex-battery-fill" />
              </div>
              <div className="ex-battery-cap" />
            </div>
          </div>
        </div>

        <div className="ex-body">
          {/* Location pin */}
          <div className="ex-loc">
            <svg width="12" height="14" viewBox="0 0 24 24" fill="var(--indigo)"><path d="M12 22s7-7.5 7-13a7 7 0 0 0-14 0c0 5.5 7 13 7 13z" /><circle cx="12" cy="10" r="2.5" fill="#fff" /></svg>
            <span>Lyon</span>
          </div>
          <h1 className="ex-title">Explorer</h1>

          {/* Search bar */}
          <div className="ex-search">
            <svg width="15" height="15" viewBox="0 0 24 24" fill="none" stroke="#8E94A8" strokeWidth="2" strokeLinecap="round"><circle cx="11" cy="11" r="6" /><path d="M16 16 L21 21" /></svg>
            <span className="ex-search-text">Où souhaitez-vous aller ?</span>
          </div>

          {/* À PROXIMITÉ */}
          <div className="ex-section-head">À PROXIMITÉ</div>
          <div className="ex-card-row">
            {EXPLORER_NEARBY.map((d, i) => <ExplorerCard key={i} data={d} />)}
          </div>

          {/* NOUVELLES DÉCOUVERTES */}
          <div className="ex-section-head">NOUVELLES DÉCOUVERTES</div>
          <div className="ex-card-row">
            {EXPLORER_NEW.map((d, i) => <ExplorerCard key={i} data={d} />)}
          </div>
        </div>

        {/* Bottom tab bar */}
        <div className="ex-tabs">
          <div className="ex-tab ex-tab-on">
            <svg width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2.2" strokeLinecap="round" strokeLinejoin="round"><circle cx="12" cy="10" r="3" /><path d="M12 22s7-7.5 7-13a7 7 0 0 0-14 0c0 5.5 7 13 7 13z" /></svg>
            <span>Explorer</span>
          </div>
          <div className="ex-tab">
            <svg width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2" strokeLinecap="round" strokeLinejoin="round"><path d="M3 6 L9 4 L15 6 L21 4 V18 L15 20 L9 18 L3 20 Z" /><path d="M9 4 V18 M15 6 V20" /></svg>
            <span>Mes Circuits</span>
          </div>
          <div className="ex-tab">
            <svg width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2" strokeLinecap="round" strokeLinejoin="round"><path d="M7 4 H17 V8 A5 5 0 0 1 7 8 Z" /><path d="M7 6 H4 V8 A3 3 0 0 0 7 11" /><path d="M17 6 H20 V8 A3 3 0 0 1 17 11" /><path d="M12 13 V18 M9 20 H15" /></svg>
            <span>Badges</span>
          </div>
          <div className="ex-tab">
            <svg width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2" strokeLinecap="round" strokeLinejoin="round"><circle cx="12" cy="8" r="4" /><path d="M4 21a8 8 0 0 1 16 0" /></svg>
            <span>Profil</span>
          </div>
        </div>

        {/* iOS home indicator */}
        <div className="ex-home-indicator" />
      </div>
    </div>
  );
}

function Footer() {
  return (
    <footer>
      <div className="wrap foot-grid">
        <div className="logo" style={{ fontSize: 15 }}>
          <div className="logo-mark" style={{ width: 26, height: 26, borderRadius: 8 }}>
            <svg viewBox="0 0 24 24" fill="none" stroke="white" strokeWidth="2.6" strokeLinecap="round" strokeLinejoin="round" style={{ width: 14, height: 14 }}>
              <path d="M12 2 L4 7 V17 L12 22 L20 17 V7 Z" />
            </svg>
          </div>
          walktovisit · © 2026
        </div>
        <div className="foot-links">
          <a href="#">Privacy</a>
          <a href="#">Terms</a>
          <a href="#">Press kit</a>
          <a href="#">hello@walktovisit.app</a>
        </div>
      </div>
      <div className="wrap" style={{ marginTop: 18, fontSize: 11.5, color: "var(--mute)", opacity: 0.7, lineHeight: 1.5 }}>
        Eiffel Tower 3D model by{" "}
        <a href="https://sketchfab.com/dr490n" target="_blank" rel="noopener noreferrer" style={{ textDecoration: "underline" }}>VRJuice</a>
        {" "}— licensed under{" "}
        <a href="http://creativecommons.org/licenses/by/4.0/" target="_blank" rel="noopener noreferrer" style={{ textDecoration: "underline" }}>CC-BY 4.0</a>.
      </div>
    </footer>
  );
}

function App() {
  return (
    <>
      <EiffelHero />
      <Pricing />
      <MapScene />
      <AudioFeature />
      <Languages />
      <FinalCTA />
      <Footer />
    </>
  );
}

function __mountApp() {
  ReactDOM.createRoot(document.getElementById("root")).render(<App />);
}
if (window.__threeReady) __mountApp();
else window.addEventListener("three-ready", __mountApp, { once: true });
