// "Manifesto" file holds two sections in order:
//   II. WITCH IS  — the four organizers who hold Neverland
//   I.  NEVERLAND — the private island (without the treasure-map placeholder)
// (Index renders <Neverland /> before <Manifesto /> to keep the prompt's section order.)

const ORGANIZERS = [
  {
    role: "Witch · Founder",
    name: "Maya",
    portrait: "photos/Maya/WhatsApp%20Image%202026-05-12%20at%2011.25.16.jpeg",
    lines: [
      (<>Founder of Witches <span className="amp">&amp;</span> Bitches. Holosomatic breathwork practitioner. Tarot reader since the year she stopped apologising.</>),
      "Holds the morning breath, the silence days, the closing reading. Reads people like a deck.",
      "She is always there for you whenever you need emotional or spiritual support.",
    ],
    sig: "— Maya",
  },
  {
    role: "Witness · Co-Host",
    name: "Mathias",
    portrait: "photos/01_ready_for_site/Photo%20from%20Mathias%20Risberg-kopia%203.jpg",
    lines: [
      "Holds the witness practice alongside Maya. Calls the silence days, the fire-circles, the closing tarot.",
      "Decides, with you and with Johnny, when the camera comes out — and when it stays in the bag. The witness, not the watcher.",
    ],
    sig: "— Mathias",
  },
  {
    role: "Lens · Third Eye",
    name: "Johnny",
    portrait: "photos/Johnny/portrait.jpeg",
    lines: [
      "Johnny is the island's third eye — moving through moments as they unfold, gently capturing real life without staging it, so presence can be remembered as it truly is.",
      "If you join the island, you join this way of being seen.",
    ],
    sig: "— Johnny",
  },
];

// Lazy-loading video — uses IntersectionObserver to hold off both the
// HTTP request and playback until the section is about to enter view.
// Until then only the poster image renders. Saves the 9 MB clip from
// loading on first paint for users who never scroll this far.
function LazyVideo({ src, poster, className, ...rest }) {
  const wrapRef = React.useRef(null);
  const videoRef = React.useRef(null);
  React.useEffect(() => {
    const wrap = wrapRef.current;
    const vid = videoRef.current;
    if (!wrap || !vid) return;
    const io = new IntersectionObserver(
      (entries) => {
        entries.forEach((e) => {
          if (!e.isIntersecting) return;
          if (!vid.src) vid.src = src;
          vid.play().catch(() => {});
          io.disconnect();
        });
      },
      { rootMargin: "300px 0px" } // start loading 300px before entry
    );
    io.observe(wrap);
    return () => io.disconnect();
  }, [src]);
  return (
    <div ref={wrapRef} className={className}>
      <video ref={videoRef} muted loop playsInline preload="none" poster={poster} {...rest} />
    </div>
  );
}

function OrganizerCard({ o }) {
  return (
    <div className="organizer">
      <div className="organizer__portrait">
        <img src={o.portrait} alt={`${o.name} — ${o.role}`} />
        <span className="organizer__role">{o.role}</span>
      </div>
      <div className="organizer__body">
        <h3 className="organizer__name">{o.name}</h3>
        {o.lines.map((p, i) => (
          <p key={i} className="organizer__bio">{p}</p>
        ))}
        <div className="organizer__sig">{o.sig}</div>
      </div>
    </div>
  );
}

function Manifesto() {
  return (
    <section className="manifesto" id="witch-is">
      <div className="grain"></div>
      <div className="container">
        <SectionHead
          eyebrow="Witch Is · II"
          title={<>
            <img className="title-char title-char--left" src="./characters/smeagol.webp" alt="" aria-hidden="true" />
            Witch Is.
          </>}
          lede="The three who hold Neverland. Witch is Maya. Witch is Mathias. Witch is Johnny. We are the door. You walk through it."
          ornaments={["star-seven", "all-seeing-eye", "star-seven"]}
        />

        <div className="organizers-grid">
          {ORGANIZERS.map((o, i) => (
            <Reveal key={o.name} delay={i * 100}>
              <OrganizerCard o={o} />
            </Reveal>
          ))}
          <Reveal delay={ORGANIZERS.length * 100}>
            <LazyVideo
              className="organizer-video"
              src="./assets/witch-is-island.mp4"
              poster="./photos/island/dock-lanterns.jpeg"
              aria-label="The island, seen from above"
            />
          </Reveal>
        </div>

      </div>
    </section>
  );
}

// Inline SVG glyphs for the Neverland trio (same Happenings style — currentColor + light fills)
const TRIO_SVG = {
  viewBox: "0 0 100 100",
  xmlns: "http://www.w3.org/2000/svg",
  fill: "none",
  stroke: "currentColor",
  strokeWidth: 2,
  strokeLinecap: "round",
  strokeLinejoin: "round",
  "aria-hidden": "true",
};

function TrioIsland() {
  return (
    <svg {...TRIO_SVG}>
      {/* island silhouette — irregular coastline */}
      <path d="M 50 18 Q 66 18 76 26 Q 86 32 88 44 Q 94 54 88 64 Q 86 76 78 84 Q 66 92 50 90 Q 34 92 22 84 Q 14 76 12 64 Q 6 54 12 42 Q 16 28 30 22 Q 40 18 50 18 Z"
            fill="currentColor" fillOpacity="0.16" />
      {/* inland clearing / lake */}
      <ellipse cx="52" cy="54" rx="8" ry="5" fill="currentColor" fillOpacity="0.5" strokeWidth="1.4" />
      {/* forest as dots */}
      {[[38,32],[52,28],[64,34],[30,46],[44,42],[64,46],[74,52],
        [34,62],[44,72],[58,68],[68,62],[44,80],[58,80]].map(([x,y], i) => (
        <circle key={i} cx={x} cy={y} r="1.6" fill="currentColor" stroke="none" />
      ))}
    </svg>
  );
}

function TrioBoats() {
  // Two pirate ships — Jolly Roger flags, tattered sails, bowsprits,
  // crow's nests, cannon ports, dramatic galleon hulls.
  return (
    <svg {...TRIO_SVG}>
      {/* Ship 1 — larger, in front */}
      <g>
        {/* Jolly Roger flag — solid black with skull + crossbones */}
        <path d="M 27 6 L 43 7 L 43 18 L 27 18 Z" fill="currentColor" strokeWidth="0.8" />
        {/* Skull head */}
        <circle cx="35" cy="11" r="2.2" fill="currentColor" stroke="none" opacity="0.0001" />
        <path d="M 32.8 11 a 2.2 2.2 0 1 0 4.4 0 a 2.2 2.2 0 1 0 -4.4 0" fill="#f5f0e6" stroke="none" />
        {/* Eye sockets */}
        <circle cx="34.2" cy="10.6" r="0.5" fill="currentColor" stroke="none" />
        <circle cx="35.8" cy="10.6" r="0.5" fill="currentColor" stroke="none" />
        {/* Jaw notch */}
        <rect x="34.5" y="12.3" width="1" height="0.9" fill="currentColor" stroke="none" />
        {/* Crossbones — two thin X-crossing bones below skull */}
        <line x1="31.5" y1="14.5" x2="38.5" y2="17" stroke="#f5f0e6" strokeWidth="0.7" />
        <line x1="38.5" y1="14.5" x2="31.5" y2="17" stroke="#f5f0e6" strokeWidth="0.7" />

        {/* Mast */}
        <line x1="28" y1="7" x2="28" y2="57" strokeWidth="1.4" />

        {/* Crow's nest — small platform on the mast */}
        <path d="M 24 22 L 32 22 L 31 25 L 25 25 Z" fill="currentColor" fillOpacity="0.5" strokeWidth="0.9" />
        <line x1="26" y1="22" x2="26" y2="20" strokeWidth="0.6" />
        <line x1="30" y1="22" x2="30" y2="20" strokeWidth="0.6" />

        {/* Yard (horizontal beam) */}
        <line x1="12" y1="28" x2="44" y2="28" strokeWidth="1.3" />

        {/* Main square sail — tattered bottom edge (zig-zag) */}
        <path d="M 12 28 L 44 28 L 42 46 L 39 43 L 36 46 L 33 43 L 30 46 L 27 43 L 24 46 L 21 43 L 18 46 L 15 43 L 14 46 Z"
              fill="currentColor" fillOpacity="0.32" strokeWidth="1.1" />
        {/* Sail seam */}
        <line x1="28" y1="28" x2="28" y2="45" strokeWidth="0.7" opacity="0.5" />
        {/* Sail tear hole */}
        <path d="M 21 35 Q 22 37 23.5 36.5 Q 22.5 35 21 35 Z" fill="currentColor" fillOpacity="0.65" strokeWidth="0.5" />

        {/* Bowsprit — angled spar at front */}
        <line x1="6" y1="56" x2="-1" y2="48" strokeWidth="1.2" />
        {/* Tiny jib sail on bowsprit */}
        <path d="M 2 56 L 6 56 L 4 50 Z" fill="currentColor" fillOpacity="0.22" strokeWidth="0.7" />

        {/* Hull — galleon with raised stern */}
        <path d="M 4 56 Q 4 52 8 52 L 44 52 Q 50 52 50 60 L 48 67 Q 28 73 8 67 L 4 60 Z"
              fill="currentColor" fillOpacity="0.45" strokeWidth="1.4" />

        {/* Cannon ports (3 hollow squares along hull) */}
        <rect x="13" y="58.5" width="1.6" height="1.6" fill="none" strokeWidth="0.6" />
        <rect x="22" y="58.5" width="1.6" height="1.6" fill="none" strokeWidth="0.6" />
        <rect x="31" y="58.5" width="1.6" height="1.6" fill="none" strokeWidth="0.6" />

        {/* Hull plank line */}
        <line x1="7" y1="63" x2="48" y2="63" strokeWidth="0.6" opacity="0.5" />
      </g>

      {/* Ship 2 — smaller, behind/right */}
      <g opacity="0.88">
        {/* Smaller Jolly Roger pennant — triangular tail */}
        <path d="M 65 28 L 80 29 L 80 36 L 65 36 Z" fill="currentColor" strokeWidth="0.7" />
        {/* Mini skull */}
        <path d="M 70.8 31.5 a 1.6 1.6 0 1 0 3.2 0 a 1.6 1.6 0 1 0 -3.2 0" fill="#f5f0e6" stroke="none" />
        <circle cx="72" cy="31.2" r="0.35" fill="currentColor" stroke="none" />
        <circle cx="72.8" cy="31.2" r="0.35" fill="currentColor" stroke="none" />
        {/* Mini crossbones */}
        <line x1="70.5" y1="33.8" x2="74.5" y2="35.2" stroke="#f5f0e6" strokeWidth="0.55" />
        <line x1="74.5" y1="33.8" x2="70.5" y2="35.2" stroke="#f5f0e6" strokeWidth="0.55" />

        {/* Mast */}
        <line x1="67" y1="29" x2="67" y2="68" strokeWidth="1.1" />
        {/* Small crow's nest */}
        <path d="M 64 40 L 70 40 L 69.5 42 L 64.5 42 Z" fill="currentColor" fillOpacity="0.45" strokeWidth="0.7" />
        {/* Yard */}
        <line x1="55" y1="44" x2="79" y2="44" strokeWidth="1" />
        {/* Sail with tattered bottom */}
        <path d="M 55 44 L 79 44 L 77.5 58 L 75 55.5 L 72.5 58 L 70 55.5 L 67 58 L 64 55.5 L 61.5 58 L 58.5 55.5 L 56 58 Z"
              fill="currentColor" fillOpacity="0.24" strokeWidth="0.9" />
        <line x1="67" y1="44" x2="67" y2="57" strokeWidth="0.55" opacity="0.4" />

        {/* Bowsprit */}
        <line x1="53" y1="64" x2="48" y2="59" strokeWidth="0.95" />

        {/* Hull */}
        <path d="M 51 64 Q 51 61 55 61 L 84 61 Q 88 61 88 66 L 86 72 Q 70 76 56 72 L 51 68 Z"
              fill="currentColor" fillOpacity="0.36" strokeWidth="1.1" />
        {/* Mini cannon ports */}
        <rect x="58" y="66" width="1.2" height="1.2" fill="none" strokeWidth="0.5" />
        <rect x="65" y="66" width="1.2" height="1.2" fill="none" strokeWidth="0.5" />
        <rect x="72" y="66" width="1.2" height="1.2" fill="none" strokeWidth="0.5" />
      </g>

      {/* Waterlines */}
      <path d="M 2 80 Q 14 76 26 80 T 52 80 T 78 80 T 98 80" strokeWidth="1.4" opacity="0.7" />
      <path d="M 8 90 Q 20 86 32 90 T 58 90 T 84 90 T 96 90" strokeWidth="1.2" opacity="0.45" />
    </svg>
  );
}

function TrioExplorers() {
  // 12 jigsaw puzzle pieces — all identical shape, arranged in a 4×3
  // grid so each piece's right tab inserts into the next piece's left
  // blank, and each piece's top tab inserts into the piece above's
  // bottom blank. Visually interlocks like a real puzzle.
  //
  // Each piece: 20×20 base with
  //   • top edge:   tab bulging UP    (out by 5 units)
  //   • right edge: tab bulging RIGHT (out by 5 units)
  //   • bottom:     blank notched UP into piece (mirror of top tab)
  //   • left:       blank notched RIGHT into piece (mirror of right tab)
  // Tab and blank shapes are identical → strokes overlap cleanly,
  // tabs visually fill the adjacent blanks.
  const piecePath =
    "M 0 0 " +
    "L 6 0 C 6 -5, 14 -5, 14 0 L 20 0 " +     // top edge with tab
    "L 20 6 C 25 6, 25 14, 20 14 L 20 20 " +  // right edge with tab
    "L 14 20 C 14 15, 6 15, 6 20 L 0 20 " +   // bottom edge with blank
    "L 0 14 C 5 14, 5 6, 0 6 Z";              // left edge with blank
  // 4 cols × 3 rows = 12 pieces, 20-unit grid. Translate(8, 22) centers
  // the puzzle in the 100×100 viewBox (puzzle spans x=0..84, y=-4..60).
  const offsetX = 8;
  const offsetY = 22;
  const pieces = [];
  for (let r = 0; r < 3; r++) {
    for (let c = 0; c < 4; c++) {
      pieces.push({ x: offsetX + c * 20, y: offsetY + r * 20 });
    }
  }
  return (
    <svg {...TRIO_SVG}>
      {pieces.map(({ x, y }, i) => (
        <g key={i} transform={`translate(${x} ${y})`}>
          <path d={piecePath}
                fill="currentColor" fillOpacity="0.42"
                stroke="currentColor" strokeWidth="1.1" strokeLinejoin="round" />
        </g>
      ))}
    </svg>
  );
}

// Cross-fading island slideshow — stacks images in the same frame and rotates
// every `interval` ms with a magical fade + slow Ken Burns drift. Accepts any
// number of slides (add more by appending to ISLAND_SLIDES below).
const ISLAND_SLIDES = [
  { src: "photos/island/dock-lanterns.jpeg",         alt: "The island dock at dusk — lanterns + boats on a still Swedish lake" },
  { src: "photos/island/drone-holmen-cabins.jpeg",   alt: "Aerial view of the island — red cabins among birch trees, boats at the dock" },
  { src: "photos/island/drone-holmen-overview.jpeg", alt: "Wider aerial of the island — Holmen surrounded by reed channels and open lake at sunset" },
  { src: "photos/island/drone-reed-channels.jpeg",   alt: "Drone view — reed channels cutting through the lake, summer sky and clouds" },
  { src: "photos/island/shoreline-forest-path.jpeg", alt: "Wooded shoreline path on the island — trees, rocks, lake glinting through the leaves" },
  { src: "photos/island/lake-sauna-deck.jpeg",       alt: "Wooden sauna and deck by the lake — reeds, blue chairs, spring forest behind" },
];

function IslandSlideshow({ images, interval = 5000 }) {
  const [active, setActive] = React.useState(0);
  React.useEffect(() => {
    if (images.length <= 1) return;
    const prefersReduced = window.matchMedia("(prefers-reduced-motion: reduce)").matches;
    if (prefersReduced) return;
    const id = setInterval(() => setActive((a) => (a + 1) % images.length), interval);
    return () => clearInterval(id);
  }, [images.length, interval]);
  return (
    <React.Fragment>
      {images.map((img, i) => (
        <img
          key={img.src}
          src={img.src}
          alt={img.alt}
          className={"island-fade" + (i === active ? " is-active" : "")}
          loading={i === 0 ? "eager" : "lazy"}
        />
      ))}
    </React.Fragment>
  );
}

// Neverland (I. THE PLACE) — image + copy + stats. Treasure-map removed (photos arrive later).
function Neverland() {
  return (
    <section className="dark" id="neverland">
      <div className="grain"></div>
      <div className="vignette"></div>
      <div className="container">
        <SectionHead
          eyebrow="The Place · I"
          title={<>
            A private{" "}
            <span className="title-word">
              <img className="word-char" src="./characters/peter-pan.webp" alt="" aria-hidden="true" />
              island
            </span>{" "}
            in Sweden.
          </>}
          lede="No address. We send the map after you are chosen."
          ornaments={["moon-full", "star-seven", "moon-star"]}
        />

        <Reveal className="neverland-trio" delay={80}>
          <div className="trio-cell">
            <div className="trio-icon"><TrioIsland /></div>
            <span className="trio-label">A private island</span>
          </div>
          <div className="trio-cell">
            <div className="trio-icon"><TrioBoats /></div>
            <span className="trio-label">Two Boats</span>
          </div>
          <div className="trio-cell">
            <div className="trio-icon"><TrioExplorers /></div>
            <span className="trio-label">Twelve explorers</span>
          </div>
        </Reveal>

        <Reveal className="neverland-grid" delay={120}>
          <div className="neverland-img">
            <IslandSlideshow images={ISLAND_SLIDES} />
            <div className="credit">© Johnny</div>
          </div>
          <div className="neverland-copy">
            <p className="neverland-copy__lead">
              Our event will happen on a beautiful <em>private island</em> in Sweden, surrounded by a
              great lake and untouched nature. For these days, the whole island is <em>only for us</em>.
            </p>
            <p>
              The island is peaceful, wild, and full of natural beauty. Water everywhere, trees
              around us, fresh air, open sky, silence, birds, wind, fire, and the rhythm of nature.
              It is a place where mornings can begin by the lake, days can be spent outside, and
              evenings can end around the fire.
            </p>
            <p>
              We will have our own boats, so the lake becomes part of the place too. We can move
              through the water, explore, swim, look at the horizon, and feel the freedom of being
              surrounded by nature from every side. And if you feel like swimming naked, you can.
              <em> Nature does not care about dress codes.</em>
            </p>
            <p>
              Every day will begin with <em>breathwork</em>, helping us arrive in the body, clear the
              mind, and open the day with presence. There will also be space for <em>yoga or dance</em>,
              depending on what the body needs that day. Later, we will share delicious, healthy food
              prepared with care, nourishing the body and giving us energy for the day.
            </p>
            <div className="neverland-stats">
              <div className="stat"><span className="num">VII</span><span className="lbl">Days · Nights</span></div>
              <div className="stat"><span className="num">12</span><span className="lbl">Explorers</span></div>
              <div className="stat"><span className="num">14–21</span><span className="lbl">August 2026</span></div>
            </div>
          </div>
        </Reveal>

        <div className="ornament-row-deco" aria-hidden="true">
          <img src="./assets/ornaments/manicule-right.svg" alt="" />
          <img src="./assets/ornaments/butterfly.svg" alt="" />
        </div>
      </div>
    </section>
  );
}

Object.assign(window, { Manifesto, Neverland });
