// Oceania landing — composer + sections.
// Section markup is keyed to oceania.css class names. Don't rename without
// updating both. Data lives in oceania-data.jsx.

const slugify = (s) => s.toLowerCase().replace(/[^a-z0-9]+/g, "-").replace(/(^-|-$)/g, "");

const OcHero = () => (
  <section className="oc-hero">
    <div className="oc-hero-bg" />
    <div className="oc-hero-collage" aria-hidden="true">
      {OC_HERO_COLLAGE.map((f, i) => (
        <div key={i} className={`frame f${i + 1}`} style={{ backgroundImage: `url('${f.src}')` }} data-cap={f.cap} />
      ))}
    </div>
    <div className="oc-hero-grid">
      <div>
        <div className="oc-hero-trail">
          <a href="/" className="crumb">HowTo: Travel</a>
          <span className="sep">/</span>
          <span>Regions</span>
          <span className="sep">/</span>
          <span>Oceania</span>
        </div>
        <h1>Where the map <em>runs out.</em></h1>
        <p className="lede"><strong>412 guides. 14 destinations. 980 contributors who actually went.</strong> An editorial atlas to the world's largest ocean — Australasia to Melanesia to Polynesia to Micronesia. Reef and atoll, fiord and outback, lagoon and rainforest. Country by country, season by season, the way the ocean actually rewards a traveller.</p>
      </div>
      <aside className="oc-hero-side">
        <div className="oc-hero-stats">
          {OC_HERO_STATS.map((s, i) => (
            <div key={i} className="oc-hero-stat">
              <div className="n">{s.n}</div>
              <div className="l">{s.label}</div>
            </div>
          ))}
        </div>
        <div className="oc-hero-meta">
          {OC_HERO_META.map((m, i) => (
            <div key={i} className="row"><span>{m.k}</span><b>{m.v}</b></div>
          ))}
        </div>
      </aside>
    </div>
    <div className="oc-hero-foot">
      <p className="oc-hero-quote">"Oceania is one ocean and a thousand horizons. The trick is to slow down enough that the islands stop blurring into each other and start telling you what each one is."<span className="by">— Marama Hopoate, Senior Editor · Oceania</span></p>
      <form className="oc-hero-search" onSubmit={(e) => e.preventDefault()}>
        <Icon name="search" size={16} />
        <input placeholder="Search 412 Oceania guides — 'Bora Bora honeymoon', 'Fiordland four days'..." />
        <button>Search</button>
      </form>
    </div>
  </section>
);

const OcPills = () => (
  <nav className="oc-pills" aria-label="Regions">
    <div className="oc-pills-inner">
      <span className="lbl">Regions</span>
      {OC_REGIONS.map((r) => (
        <a key={r.id} href={r.href} className={r.current ? "current" : ""}>{r.name}</a>
      ))}
    </div>
  </nav>
);

const OcAnchor = () => (
  <nav className="oc-anchor" aria-label="On this page">
    <div className="oc-anchor-inner">
      <span className="lbl">In this issue</span>
      {OC_ANCHOR.map((a) => <a key={a.href} href={a.href}>{a.label}</a>)}
    </div>
  </nav>
);

const OcIntro = () => (
  <section className="oc-sec oc-intro" id="intro">
    <div className="container oc-intro-grid">
      <div className="from">
        <div className="lbl">From the Plan Desk</div>
        <div className="name">Marama Hopoate</div>
        <div className="role">Senior Editor · Oceania</div>
        <div className="stamp">Issue<em>Nº 17</em>Autumn '26</div>
      </div>
      <div className="body">
        <p><strong>Oceania is the part of the atlas where the colour stops being green or brown and goes blue.</strong> Twenty-five thousand islands across thirty million square kilometres of ocean — more water than land, more sea than sky on a clear day at the equator. The mistake the first-time visitor makes is treating this as one place. Australia is older than mammals; New Zealand is younger than its first tourist. Fiji and Samoa share a song; Palau and Pohnpei do not. Bora Bora is closer to Los Angeles than to Sydney.</p>
        <p>The map flattens what the water reveals. We split this issue the way the navigators did — <strong>by ocean current and trade wind</strong>, by reef and ridge, by who you'd phone if you broke down at sundown. Read it slow.</p>
        <p>This page is the manual we wished existed when we started — everything we'd send a friend before their first Pacific trip, and a few things only useful on the fifth.</p>
        <div className="sig">— Marama</div>
      </div>
      <aside className="toc">
        <div className="lbl">Table of contents</div>
        <ol>
          {OC_TOC.map((t, i) => (
            <li key={i}>
              <a href={`#${["intro","countries","regions","when","itineraries","food","trains","budget","language","festivals","neighborhoods","packing"][i] || ""}`}>{t.t}</a>
              <span className="pg">{t.pg}</span>
            </li>
          ))}
        </ol>
      </aside>
    </div>
  </section>
);

const OcCountries = () => (
  <section className="oc-sec oc-countries" id="countries">
    <div className="container">
      <header className="oc-sec-head">
        <div className="ttl">
          <div className="kicker">Chapter 01</div>
          <h2>12 destinations, the <em>honest atlas.</em></h2>
          <p>The Pacific's most-travelled twelve, sorted by guide depth not population or alphabet. Featured below: the country we send first-timers to, every time. Click any tile for the full sub-atlas.</p>
        </div>
        <div className="right"><a className="view-all" href="/en/plan/itineraries/oceania">View all 14 <Icon name="arrow" size={14} /></a></div>
      </header>
      <div className="oc-countries-grid">
        {OC_COUNTRIES.map((c, i) => (
          <a key={i} className={`oc-country${c.featured ? " featured" : ""}`} href={`/oceania/${slugify(c.name)}/`}>
            <div className="country-img" style={{ backgroundImage: `url('${c.img}')` }} />
            <div className="top">
              <div className="flag" style={{ backgroundImage: `url('${c.flag}')`, backgroundSize: "cover" }} aria-hidden="true" />
              <div className="num">{String(i + 1).padStart(2, "0")}</div>
            </div>
            <div className="body">
              <div>
                <h3 className="name">{c.name}</h3>
                <div className="cap">{c.cap}</div>
                {c.featured && <p className="lede">{c.lede}</p>}
              </div>
              <div className="stats">
                <span><b>{c.guides}</b> guides</span>
                <span><b>{c.days}</b> days</span>
              </div>
            </div>
            <span className="arrow">Read →</span>
          </a>
        ))}
      </div>
    </div>
  </section>
);

const OcClusters = () => (
  <section className="oc-sec oc-clusters" id="regions">
    <div className="container">
      <header className="oc-sec-head">
        <div className="ttl">
          <div className="kicker">Chapter 02</div>
          <h2>The Pacific in <em>four clusters.</em></h2>
          <p>Borders are political; weather, food, and the inter-island flight schedule are not. We group Oceania the way travellers actually move through it — by ocean current, by season, by table.</p>
        </div>
      </header>
      {OC_CLUSTERS.map((cl, i) => (
        <div key={i} className="oc-cluster-row">
          <div className="lead">
            <div className="num">{cl.num} · Cluster</div>
            <h3>The <em>{cl.titleEm}</em></h3>
            <p>{cl.blurb}</p>
          </div>
          {cl.cards.map((card, j) => (
            <article key={j} className="oc-cluster-card">
              <div className="top">
                <span className="when">{card.when}</span>
                <span className="pin">{card.pin}</span>
              </div>
              <h4>{card.h4}</h4>
              <p>{card.p}</p>
              <div className="tags">{card.tags.map((t) => <span key={t} className="tag">{t}</span>)}</div>
            </article>
          ))}
        </div>
      ))}
    </div>
  </section>
);

const OcWhen = () => (
  <section className="oc-sec oc-when" id="when">
    <div className="container">
      <header className="oc-sec-head">
        <div className="ttl">
          <div className="kicker">Chapter 03</div>
          <h2>When to go — <em>cyclone vs dry.</em></h2>
          <p>The South Pacific runs on cyclone and dry seasons, and Australasia inverts your hemisphere. Two windows per region, sitting at opposite ends of the calendar depending on which side of the equator you're on. Here is the year, region by region.</p>
        </div>
      </header>
      <div className="oc-when-grid">
        <div className="oc-when-cal">
          <table>
            <thead>
              <tr>
                <th>Region</th>
                {OC_WHEN_HEAD.map((m) => <th key={m}>{m}</th>)}
              </tr>
            </thead>
            <tbody>
              {OC_WHEN_ROWS.map((r) => (
                <tr key={r.region}>
                  <td className="region">{r.region}</td>
                  {r.months.map((m, k) => (
                    <td key={k}><span className={`pill ${m === "P" ? "peak" : m === "S" ? "shoulder" : m === "F" ? "fest" : "low"}`}>{m}</span></td>
                  ))}
                </tr>
              ))}
            </tbody>
          </table>
          <div className="oc-when-cal-legend">
            {OC_WHEN_LEGEND.map((l) => <span key={l.cls}><i className={`pill ${l.cls}`} />{l.label}</span>)}
          </div>
        </div>
        <div className="oc-when-notes">
          {OC_WHEN_NOTES.map((n, i) => (
            <article key={i} className="oc-when-note">
              <h4>{n.h4}</h4>
              <p>{n.p}</p>
              <div className="meta">{n.meta.map((m, k) => <span key={k}>{m}</span>)}</div>
            </article>
          ))}
        </div>
      </div>
    </div>
  </section>
);

const OcItineraries = () => (
  <section className="oc-sec oc-iti" id="itineraries">
    <div className="container">
      <header className="oc-sec-head">
        <div className="ttl">
          <div className="kicker">Chapter 04</div>
          <h2>Four itineraries worth <em>stealing.</em></h2>
          <p>The plans we'd send to a friend, road-tested and updated each spring. Click for day-by-day.</p>
        </div>
        <div className="right"><a className="view-all" href="/en/plan/itineraries/oceania">All 22 itineraries <Icon name="arrow" size={14} /></a></div>
      </header>
      <div className="oc-iti-grid" style={{ gridTemplateColumns: "repeat(auto-fit, minmax(320px, 1fr))" }}>
        {OC_ITIS.map((it, i) => (
          <a key={i} className="oc-iti-card" href={`/en/plan/itineraries/oceania/${slugify(it.h3)}`}>
            <div className="head">
              <div className="days">{it.days}<span>days · nights</span></div>
              <span className="pill">{it.pill}</span>
            </div>
            <h3>{it.h3.includes(",") ? <>{it.h3.split(",")[0]},<br /><em>{it.h3.split(",").slice(1).join(",").trim()}</em></> : it.h3}</h3>
            <p className="lede">{it.lede}</p>
            <ol className="stops">
              {it.stops.map((s, j) => (
                <li key={j}><span className="n">{s.n}</span><span className="place">{s.place}</span><span className="nights">{s.nights}</span></li>
              ))}
            </ol>
            <div className="foot">
              <span className="cost">{it.cost}</span>
              <span>{it.by}</span>
            </div>
          </a>
        ))}
      </div>
    </div>
  </section>
);

const OcFood = () => (
  <section className="oc-sec oc-food" id="food">
    <div className="container">
      <header className="oc-sec-head">
        <div className="ttl">
          <div className="kicker">Chapter 05</div>
          <h2>Food &amp; drink, kitchen <em>by kitchen.</em></h2>
          <p>One immutable rule per kitchen. Order this, drink that, never make the obvious mistake.</p>
        </div>
      </header>
      <div className="oc-food-grid">
        {OC_FOOD.map((f, i) => (
          <article key={i} className={`oc-food-card ${f.span}`}>
            <div className="top">
              <span className="country">{f.country}</span>
              <span className="glyph" aria-hidden="true">{f.glyph}</span>
            </div>
            <div>
              <h4>{f.h4}</h4>
              <p>{f.p}</p>
            </div>
            <div className="pair"><b>{f.pair.a}</b> · with {f.pair.b}</div>
          </article>
        ))}
      </div>
    </div>
  </section>
);

const OcTransport = () => (
  <section className="oc-sec oc-trains" id="trains">
    <div className="container">
      <header className="oc-sec-head">
        <div className="ttl">
          <div className="kicker">Chapter 06</div>
          <h2>Inter-island flights, ferries, <em>campervans.</em></h2>
          <p>Oceania moves on Air New Zealand and Qantas, on Fiji Airways and Air Tahiti, and on the campervan you rent in Christchurch or Cairns. Trains exist in Australia and New Zealand and almost nowhere else. Plan accordingly.</p>
        </div>
      </header>
      <div className="oc-trains-grid">
        <div className="blurb">
          <p><strong>Pacific carriers are the regional metro.</strong> Air New Zealand, Qantas, Fiji Airways, Air Tahiti and Virgin Australia run hub-and-spoke schedules out of Auckland, Sydney, Nadi and Papeete. The Air Tahiti island-hop pass and the Fiji Airways Bula Pass are mandatory if you plan to chain three or more islands.</p>
          <p>Trains are slow but spectacular in NZ — the TranzAlpine through the Southern Alps and the Coastal Pacific along the Kaikoura coast. <strong>Campervans are the cheapest way through both islands of New Zealand and the east coast of Australia</strong>, and the only sane way through the Red Centre and Kakadu. Inter-island ferries run within Fiji, Vanuatu and the Cook Islands but are slow and weather-dependent — fly when you can.</p>
          <div className="compare">
            <h5>Train vs. plane — door to door</h5>
            <div className="compare-row h"><span>Route</span><span className="train">Train</span><span className="plane">Plane</span></div>
            {OC_TRAIN_COMPARE.map((c, i) => (
              <div key={i} className="compare-row"><span>{c.route}</span><span className="train">{c.train}</span><span className="plane">{c.plane}</span></div>
            ))}
          </div>
        </div>
        <div className="oc-routes">
          {OC_ROUTES.map((r, i) => (
            <article key={i} className="oc-route">
              <div className="from"><span className="city">{r.from}</span><span className="code">{r.fromCode}</span></div>
              <div className="line">
                <span className="lbl"><b>{r.t}</b></span>
                <span className="lbl">{r.trains}</span>
              </div>
              <div className="to"><span className="city">{r.to}</span><span className="code">{r.toCode}</span></div>
            </article>
          ))}
        </div>
      </div>
    </div>
  </section>
);

const OcBudget = () => (
  <section className="oc-sec oc-budget" id="budget">
    <div className="container">
      <header className="oc-sec-head">
        <div className="ttl">
          <div className="kicker">Chapter 07</div>
          <h2>Three Pacifics, <em>three budgets.</em></h2>
          <p>The region doesn't share a price list. Fiji and Samoa are among the best value in the world. French Polynesia is the most expensive country in Oceania. Plan for the actual destination you're visiting, not a regional average.</p>
        </div>
      </header>
      <div className="oc-budget-grid">
        {OC_BUDGETS.map((b, i) => (
          <article key={i} className={`oc-budget-card ${b.middle ? "middle" : ""}`}>
            <div className="h">
              <span className="lvl">{b.lvl}</span>
              <span className="day"><em>${b.day}</em><span className="u">/day</span></span>
            </div>
            <h4>{b.title}</h4>
            <ul className="lines">
              {b.lines.map((l, k) => (
                <li key={k}><span>{l[0]}</span><span>{l[1]}</span></li>
              ))}
            </ul>
            <p className="note">{b.note}</p>
          </article>
        ))}
      </div>
    </div>
  </section>
);

const OcLang = () => (
  <section className="oc-sec oc-lang" id="language">
    <div className="container">
      <header className="oc-sec-head">
        <div className="ttl">
          <div className="kicker">Chapter 08</div>
          <h2>Four phrases per <em>language.</em></h2>
          <p>The Pacific runs on hundreds of languages — over 800 in Papua New Guinea alone. The four words that warm a welcome, in the eight you're most likely to need on a trip.</p>
        </div>
      </header>
      <div className="oc-lang-grid">
        {OC_LANG.map((l, i) => (
          <article key={i} className="oc-lang-card">
            <div className="country">{l.country}</div>
            <dl>
              {l.phrases.map((p, k) => (
                <React.Fragment key={k}>
                  <dt>{p.dt}</dt>
                  <dd>{p.dd}</dd>
                </React.Fragment>
              ))}
            </dl>
          </article>
        ))}
      </div>
    </div>
  </section>
);

const OcFestivals = () => (
  <section className="oc-sec oc-fest" id="festivals">
    <div className="container">
      <header className="oc-sec-head">
        <div className="ttl">
          <div className="kicker">Chapter 09</div>
          <h2>Festivals worth a <em>detour.</em></h2>
          <p>Six dates that bend an itinerary. Book early — Heiva and Mount Hagen sell out a year ahead, and the Tonga humpback window is short.</p>
        </div>
      </header>
      <div className="oc-fest-grid">
        {OC_FESTS.map((f, i) => (
          <article key={i} className="oc-fest-card">
            <span className="num">{f.num}</span>
            <div>
              <div className="when">{f.when}</div>
              <div className="where">{f.where}</div>
              <h4>{f.h4}</h4>
              <p>{f.p}</p>
            </div>
            <div className="stars">{f.stars}</div>
          </article>
        ))}
      </div>
    </div>
  </section>
);

const OcNbhd = () => (
  <section className="oc-sec oc-nbhd" id="neighborhoods">
    <div className="container">
      <header className="oc-sec-head">
        <div className="ttl">
          <div className="kicker">Chapter 10</div>
          <h2>Six anchorages we <em>trust.</em></h2>
          <p>Stay here. Eat here. Walk for two days before you do anything else.</p>
        </div>
      </header>
      <div className="oc-nbhd-grid">
        {OC_NEIGHBORHOODS.map((n, i) => (
          <article key={i} className="oc-nbhd-row">
            <div className="num">{n.num}</div>
            <div>
              <h3 className="name"><em>{n.em}</em></h3>
              <div className="city">{n.city}</div>
              <p>{n.p}</p>
              <div className="why">Why · {n.why}</div>
            </div>
          </article>
        ))}
      </div>
    </div>
  </section>
);

const OcPack = () => (
  <section className="oc-sec oc-pack" id="packing">
    <div className="container">
      <header className="oc-sec-head">
        <div className="ttl">
          <div className="kicker">Chapter 11</div>
          <h2>Pack for reef, rain, <em>and outback.</em></h2>
          <p>Oceania runs hot, wet and bright on the islands; cold, alpine and rainy in the South Island. Trade the bright kit for two long quick-dry shirts you actually like — they'll work on the reef, in the Highlands, and at midnight on a Maori marae.</p>
        </div>
      </header>
      <div className="oc-pack-grid">
        {OC_PACK_LISTS.map((p, i) => (
          <article key={i} className="oc-pack-list">
            <h4>{p.h4.split(p.em).map((part, j, arr) => j < arr.length - 1 ? <React.Fragment key={j}>{part}<em>{p.em}</em></React.Fragment> : part)}</h4>
            <div className="sub">{p.sub}</div>
            <ul>
              {p.items.map((it, k) => (
                <li key={k} className={it.startsWith("Tip") ? "tip" : undefined}>{it}</li>
              ))}
            </ul>
          </article>
        ))}
      </div>
    </div>
  </section>
);

const OcFAQ = () => (
  <section className="oc-sec oc-faq" id="faq">
    <div className="container">
      <header className="oc-sec-head">
        <div className="ttl">
          <div className="kicker">Chapter 12</div>
          <h2>The questions, <em>answered.</em></h2>
          <p>The eight questions every reader sends before a first Oceania trip. Updated April 2026.</p>
        </div>
      </header>
      <div className="oc-faq-grid">
        <aside className="aside">
          <p>If your question isn't here, the team answers reader mail every Thursday — write us at <strong>letters@howtotraveledition.com</strong> and we'll point you at the right guide, or write a new one.</p>
          <p>For visa, vaccination, and entry-stamp questions: the visas page is updated monthly with the latest from each country's foreign-affairs ministry and the WHO.</p>
        </aside>
        <div>
          {OC_FAQS.map((f, i) => (
            <details key={i} className="oc-faq-item" open={i === 0 || undefined}>
              <summary>{f.q}</summary>
              <div className="a" dangerouslySetInnerHTML={{ __html: f.a }} />
            </details>
          ))}
        </div>
      </div>
    </div>
  </section>
);

const OcRelated = () => (
  <section className="oc-sec oc-related" id="related">
    <div className="container">
      <header className="oc-sec-head">
        <div className="ttl">
          <div className="kicker">Keep reading</div>
          <h2>Four more <em>dispatches.</em></h2>
          <p>From the Plan Desk and the field — recent pieces worth a slow morning.</p>
        </div>
      </header>
      <div className="oc-related-grid">
        {OC_RELATED.map((r, i) => (
          <a key={i} className="oc-related-card" href={r.href}>
            <span className="lbl">{r.lbl}</span>
            <h4 dangerouslySetInnerHTML={{ __html: r.h4 }} />
            <span className="by">{r.by}</span>
          </a>
        ))}
      </div>
    </div>
  </section>
);

const OcSignoff = () => (
  <section className="oc-signoff">
    <div className="oc-signoff-inner container">
      <span className="kicker">— End of Issue Nº 17 · Oceania —</span>
      <Marquee
        items={["Kava bowl, three rounds", "Bula on landing", "Reef shoes always", "Hāngī by the marae", "Air Tahiti pass", "Don't rush the lagoon"]}
        variant="giant"
        separator="✦"
        speed={50}
      />
      <div className="oc-signoff-meta">
        <span>HowTo: Travel Edition</span>
        <span className="dash">—</span>
        <span>Issue Nº 017</span>
        <span className="dash">—</span>
        <span>Autumn 2026</span>
        <span className="dash">—</span>
        <span>Field desk Sydney / Auckland / Suva</span>
        <span className="dash">—</span>
        <span>980 contributors strong</span>
      </div>
    </div>
  </section>
);

const OceaniaApp = () => (
  <div data-screen-label="Oceania Landing">
    <Nav />
    <OcHero />
    <OcPills />
    <OcAnchor />
    <OcIntro />
    <OcCountries />
    <OcClusters />
    <OcWhen />
    <OcItineraries />
    <OcFood />
    <OcTransport />
    <OcBudget />
    <OcLang />
    <OcFestivals />
    <OcNbhd />
    <OcPack />
    <OcFAQ />
    <OcRelated />
    <OcSignoff />
    <Footer />
  </div>
);

ReactDOM.createRoot(document.getElementById("root")).render(<OceaniaApp />);
