/* global React, ReactDOM, TweaksPanel, useTweaks, TweakSection, TweakRadio, TweakSelect, TweakColor, TweakToggle */
const { useState, useEffect, useRef, useMemo } = React;

/* ---------- Palettes ---------- */
const PALETTES = {
  "sage-clay": {
    label: "Sage & Clay",
    bg: "#f5f1ea",
    panel: "#ebe4d7",
    ink: "#2b2a26",
    sub: "#6b6557",
    rule: "#d8d0bf",
    accent: "#7c8c6c", // sage
    accent2: "#b56a4a", // clay
    wood: "#b08a63"
  },
  "linen-oak": {
    label: "Linen & Oak",
    bg: "#f4ede1",
    panel: "#e8dcc6",
    ink: "#2a221a",
    sub: "#6e5f4b",
    rule: "#dcc9aa",
    accent: "#9a6b3f",
    accent2: "#a85d3d",
    wood: "#a07349"
  },
  "stone-moss": {
    label: "Stone & Moss",
    bg: "#eeece5",
    panel: "#dedacd",
    ink: "#23241f",
    sub: "#5e6058",
    rule: "#c8c5b4",
    accent: "#586b4a",
    accent2: "#9d6b50",
    wood: "#9a8568"
  }
};

const FONTS = {
  cormorant: { label: "Cormorant + Manrope", heading: "'Cormorant Garamond', Georgia, serif", body: "'Manrope', system-ui, sans-serif", weightH: 500, headingTrack: "-0.01em" },
  dmserif: { label: "DM Serif + DM Sans", heading: "'DM Serif Display', Georgia, serif", body: "'DM Sans', system-ui, sans-serif", weightH: 400, headingTrack: "-0.015em" },
  garamond: { label: "EB Garamond + Manrope", heading: "'EB Garamond', Georgia, serif", body: "'Manrope', system-ui, sans-serif", weightH: 500, headingTrack: "0em" }
};

/* ---------- Defaults (editmode-persisted) ---------- */
const TWEAK_DEFAULTS = /*EDITMODE-BEGIN*/{
  "palette": "sage-clay",
  "font": "cormorant",
  "gallery": "story",
  "hero": "split",
  "density": "airy"
} /*EDITMODE-END*/;

/* ---------- Photo manifest ---------- */
const PHOTOS = [

{ id: "p02", label: "Suite 1908 — at the door", ratio: "4/3", src: "photos/02.jpg" },
{ id: "p03", label: "Foyer", ratio: "4/3", src: "photos/03.jpg" },
{ id: "p04", label: "Hallway through to the great room", ratio: "4/3", src: "photos/04.jpg" },
{ id: "p05", label: "Living / dining — looking west", ratio: "4/3", src: "photos/05.jpg" },
{ id: "p06", label: "Kitchen — pass-through", ratio: "4/3", src: "photos/06.jpg" },
{ id: "p07", label: "Kitchen", ratio: "4/3", featured: true, src: "photos/07.jpg" },
{ id: "p08", label: "Kitchen — double oven & fridge wall", ratio: "4/3", src: "photos/08.jpg" },
{ id: "p09", label: "Kitchen — through the window", ratio: "4/3", src: "photos/09.jpg" },
{ id: "p10", label: "Living room — toward dining", ratio: "4/3", src: "photos/10.jpg" },
{ id: "p11", label: "Second living area", ratio: "4/3", src: "photos/11.jpg" },
{ id: "p12", label: "Living room — corner exposure", ratio: "4/3", src: "photos/12.jpg" },
{ id: "p13", label: "Dining nook", ratio: "4/3", src: "photos/13.jpg" },
{ id: "p14", label: "In-unit laundry & storage", ratio: "4/3", src: "photos/14.jpg" },
{ id: "p15", label: "Bedroom wing hallway", ratio: "4/3", src: "photos/15.jpg" },
{ id: "p16", label: "Main bathroom", ratio: "4/3", src: "photos/16.jpg" },
{ id: "p17", label: "Tub & shower", ratio: "4/3", src: "photos/17.jpg" },
{ id: "p18", label: "Primary bedroom", ratio: "4/3", src: "photos/18.jpg" },
{ id: "p19", label: "Ensuite / powder room", ratio: "4/3", src: "photos/19.jpg" },

{ id: "p20", label: "", ratio: "4/3", src: "photos/20.jpg" },
{ id: "p21", label: "", ratio: "4/3", src: "photos/21.jpg" },
{ id: "p22", label: "", ratio: "4/3", src: "photos/22.jpg" },
{ id: "p23", label: "", ratio: "4/3", src: "photos/23.jpg" },
{ id: "p24", label: "", ratio: "4/3", src: "photos/24.jpg" },
{ id: "p25", label: "", ratio: "4/3", src: "photos/25.jpg" },
{ id: "p26", label: "", ratio: "4/3", src: "photos/26.jpg" },
{ id: "p27", label: "", ratio: "4/3", src: "photos/27.jpg" },
{ id: "p28", label: "", ratio: "4/3", src: "photos/28.jpg" },
{ id: "p29", label: "", ratio: "4/3", src: "photos/29.jpg" },

{ id: "p30", label: "", ratio: "4/3", src: "photos/30.jpg" },
{ id: "p31", label: "", ratio: "4/3", src: "photos/31.jpg" },
{ id: "p32", label: "", ratio: "4/3", src: "photos/32.jpg" },
{ id: "p33", label: "", ratio: "4/3", src: "photos/33.jpg" },
{ id: "p34", label: "", ratio: "4/3", src: "photos/34.jpg" },
{ id: "p35", label: "", ratio: "4/3", src: "photos/35.jpg" }

];


/* ---------- Photo placeholder ---------- */
function Photo({ photo, className = "", style = {} }) {
  const { ratio, label, src } = photo;
  return (
    <div
      className={`photo ${className}`}
      style={{ aspectRatio: ratio.replace("/", " / "), ...style }}>
      
      {src ?
      <img src={src} alt={label} loading="lazy" /> :

      <div className="photo-placeholder" aria-label={label}>
          <svg className="photo-stripes" preserveAspectRatio="none" viewBox="0 0 100 100">
            <defs>
              <pattern id={`p-${photo.id}`} width="6" height="6" patternUnits="userSpaceOnUse" patternTransform="rotate(35)">
                <line x1="0" y1="0" x2="0" y2="6" stroke="currentColor" strokeWidth="6" strokeOpacity="0.18" />
              </pattern>
            </defs>
            <rect width="100" height="100" fill={`url(#p-${photo.id})`} />
          </svg>
          <div className="photo-label">
            <span className="dot" />
            <span>{label}</span>
          </div>
        </div>
      }
    </div>);

}

/* ---------- Reveal on scroll ---------- */
function useReveal() {
  useEffect(() => {
    const observe = () => {
      const els = document.querySelectorAll("[data-reveal]:not(.is-revealed)");
      els.forEach((el) => io.observe(el));
    };
    const io = new IntersectionObserver((entries) => {
      entries.forEach((e) => {
        if (e.isIntersecting) {
          e.target.classList.add("is-revealed");
          io.unobserve(e.target);
        }
      });
    }, { threshold: 0.04, rootMargin: "0px 0px 0px 0px" });
    observe();
    // Re-scan when layout swaps (gallery layout, hero, density) add new nodes.
    const mo = new MutationObserver(observe);
    mo.observe(document.body, { childList: true, subtree: true });
    // Final failsafe — anything still hidden after 2.5s gets shown.
    const t = setTimeout(() => {
      document.querySelectorAll("[data-reveal]:not(.is-revealed)").forEach((el) =>
      el.classList.add("is-revealed")
      );
    }, 2500);
    return () => {io.disconnect();mo.disconnect();clearTimeout(t);};
  }, []);
}

/* ---------- Hero ---------- */
function Hero({ hero }) {
  const heroPhoto = PHOTOS.find(p => p.id === "p07");
  if (hero === "fullbleed") {
    return (
      <section className="hero hero--fullbleed" data-reveal>
        <Photo photo={heroPhoto} className="hero-photo" />
        <div className="hero-overlay">
          <div className="hero-eyebrow">
            <span className="dot dot--accent" />
            <span>For lease · Available July 1, 2026</span>
          </div>
          <h1 className="hero-title">
            Welcome to <em>470&nbsp;Laurier&nbsp;W</em>
          </h1>
          <p className="hero-sub">
            A two-bedroom corner suite, eleven hundred square feet of warm oak and river light, perched above downtown Ottawa.
          </p>
          <div className="hero-meta">
            <span>2&nbsp;BD</span><i /><span>1.5&nbsp;BA</span><i /><span>~1,000&nbsp;sqft</span><i /><span>River&nbsp;view</span>
          </div>
        </div>
      </section>);

  }
  return (
    <section className="hero hero--split" data-reveal>
      <div className="hero-text">
        <div className="hero-eyebrow">
          <span className="dot dot--accent" />
          <span>For lease · Available July 1, 2026</span>
        </div>
        <h1 className="hero-title">
          Welcome to<br /><em>470&nbsp;Laurier&nbsp;W</em>
        </h1>
        <p className="hero-sub">A spacious two-bedroom corner suite with river views.

        </p>
        <div className="hero-meta">
          <span>2&nbsp;BD</span><i />
		  <span>1.5&nbsp;BA</span><i />
		  <span>~1,000&nbsp;sqft</span><i />
		  <span>Parking</span><i />
		  <span>River&nbsp;view
		  
		  </span>
        </div>
        <a className="btn-primary" href="#inquire">Inquire about this home →</a>
      </div>
      <div className="hero-art">
        <Photo photo={heroPhoto} className="hero-photo" />
        <div className="hero-stamp">
          <div className="stamp-line">Downtown</div>
          <div className="stamp-line stamp-big">Ottawa</div>
          <div className="stamp-line">FLOOR 19 · NORTH-WEST FACING</div>
        </div>
      </div>
    </section>);

}

/* ---------- Specs strip ---------- */

function Specs() {
  const items = [
  { k: "Bedrooms", v: "2" },
  { k: "Bathrooms", v: "1.5" },
  { k: "Floor area", v: "~1,000 sqft" },
  { k: "Walk-in closets", v: "2" },
  { k: "Parking", v: "Underground" },
  { k: "Outlook", v: "Ottawa River" }];

  return (
    <section className="specs" data-reveal>
      <div className="specs-grid">
        {items.map((it) =>
        <div key={it.k} className="spec">
            <div className="spec-v">{it.v}</div>
            <div className="spec-k">{it.k}</div>
          </div>
        )}
      </div>
    </section>);

}

/* ---------- Neighborhood ---------- */
function Neighborhood() {
  const items = [
  { t: "Lyon LRT Station", d: "Two blocks north. Across town in minutes; airport without driving.", w: "6 min walk" },
  { t: "Grocery Store", d: "Full grocery store nearby. Coffee, pharmacy, and the Sparks Street market all within reach.", w: "6 min walk" },
  { t: "Ādisōke — New Central Library", d: "Ottawa's new landmark library outside the window, opening soon.", w: "8 min walk" },
  { t: "Ottawa River pathway", d: "Cycling, paddling, and the Gatineau hills across the water.", w: "8 min walk" },
  
  { t: "Parliament Hill", d: "An eight-minute walk along Wellington - the kind of commute people from other cities don't believe.", w: "15 min walk" }];

  return (
    <section className="section neighborhood" data-reveal>
      <div className="section-head">
        <div className="eyebrow">02 — The neighbourhood</div>
        <h2>A quiet block, in the middle of everything.</h2>
        <p className="lede">Laurier Avenue West sits close to Parliament and the river, on the edge of downtown's calmest stretch. Most days you won't need the car.

        </p>
      </div>
      <ul className="hood-list">
        {items.map((it) =>
        <li key={it.t} className="hood-row">
            <div className="hood-walk">{it.w}</div>
            <div className="hood-title">{it.t}</div>
            <div className="hood-desc">{it.d}</div>
          </li>
        )}
      </ul>
    </section>);

}

/* ---------- Floor plan ---------- */
function FloorPlan() {
  return (
    <section className="section floorplan" data-reveal>
      <div className="section-head">
        <div className="eyebrow">03 — Floor plan</div>
        <h2>Spacious corner unit.</h2>
        <p className="lede">A true two-bedroom plan, with a generous living/dining great room facing the river.

        </p>
      </div>
      <div className="fp-wrap">
        <img className="fp-img" src="photos/floorplan.png" alt="Floor plan — Suite 1908, 470 Laurier West" loading="lazy" />
        <div className="fp-key">
          <div className="fp-key-row"><span>Total</span><b><em className="fp-num">~1,000</em> sqft</b></div>
          <div className="fp-key-row"><span>Bedrooms</span><b><em className="fp-num">2</em> - with WIC</b></div>
          <div className="fp-key-row"><span>Bathrooms</span><b><em className="fp-num">1</em> full + <em className="fp-num">1</em> powder</b></div>
		  <div className="fp-key-row"><span>Utility Room</span><b><em className="fp-num">1</em> - laundry, pantry and storage</b></div>
          <div className="fp-key-row"><span>Exposure</span><b>West / North</b></div>
          <div className="fp-key-row"><span>Floor</span><b><em className="fp-num">19</em><sup className="fp-num-sup">th</sup>, corner unit</b></div>
        </div>
      </div>
    </section>);

}

/* ---------- Amenities ---------- */
function Amenities() {
  const groups = [
  {
    h: "In the suite",
    items: ["In-unit laundry", "Two walk-in closets", "Smart thermostats", "Pantry/utility room", "River + city views"]
  },
  {
    h: "In the building",
    items: ["Large storage locker", "Secure bike storage", "Indoor pool, jacuzzi & sauna", "Party room", "Rooftop and backyard patios with BBQ"]
  }];

  return (
    <section className="section amenities" data-reveal>
      <div className="section-head">
        <div className="eyebrow">04 — What's included</div>
        <h2>Everything you'd expect, plus the things you don't always get.</h2>
      </div>
      <div className="amen-grid">
        {groups.map((g) =>
        <div key={g.h} className="amen-col">
            <h3 className="amen-h">{g.h}</h3>
            <ul className="amen-list">
              {g.items.map((x) =>
            <li key={x}>
                  <span className="tick" aria-hidden>✦</span>
                  <span>{x}</span>
                </li>
            )}
            </ul>
          </div>
        )}
      </div>
    </section>);

}

/* ---------- Gallery (3 layouts) ---------- */
function Gallery({ layout }) {
  return (
    <section className="section gallery" data-reveal>
      <div className="section-head">
        <div className="eyebrow">05 — A walk through the home</div>
        <h2>Step inside.</h2>
        <p className="lede">A quick tour, room by room.

        </p>
      </div>
      {layout === "story" && <GalleryStory />}
      {layout === "mosaic" && <GalleryMosaic />}
      {layout === "grid" && <GalleryGrid />}
    </section>);

}

function GalleryStory() {
  // Uniform 4:3 photos stacked vertically, captions always below.
  return (
    <div className="story">
      {PHOTOS.map((p, i) =>
      <figure key={p.id} className="story-fig" data-reveal>
          <Photo photo={{ ...p, ratio: "4/3" }} />
          {p.caption &&
        <figcaption className="story-cap">
              <span className="cap-num">{String(i + 1).padStart(2, "0")}</span>
              <span className="cap-text">{p.caption}</span>
            </figcaption>
        }
        </figure>
      )}
    </div>);

}

function GalleryMosaic() {
  // Editorial mosaic — varied sizes via CSS grid spans
  const spans = ["sp-2x2", "sp-1x1", "sp-1x2", "sp-2x1", "sp-1x1", "sp-2x2", "sp-1x1", "sp-1x2", "sp-1x1", "sp-2x1", "sp-1x1", "sp-1x1", "sp-2x2", "sp-1x1", "sp-1x1", "sp-2x1", "sp-1x1"];
  return (
    <div className="mosaic">
      {PHOTOS.map((p, i) =>
      <figure key={p.id} className={`mos-fig ${spans[i % spans.length]}`} data-reveal>
          <Photo photo={p} style={{ aspectRatio: "auto", height: "100%" }} />
          {p.caption && <figcaption className="mos-cap">{p.caption}</figcaption>}
        </figure>
      )}
    </div>);

}

function GalleryGrid() {
  return (
    <div className="grid">
      {PHOTOS.map((p) =>
      <figure key={p.id} className="grid-fig" data-reveal>
          <Photo photo={{ ...p, ratio: "4/3" }} />
          <figcaption className="grid-cap">{p.label}</figcaption>
        </figure>
      )}
    </div>);

}

/* ---------- Pricing & contact ---------- */
function Pricing() {
  return (
    <section id="inquire" className="section pricing" data-reveal>
      <div className="pricing-card">
        <div className="pricing-left">
          <div className="eyebrow">06 — Lease & availability</div>
          <h2>Make it yours.</h2>
          <p className="lede">Available beginning July 1, 2026.</p>
          
		  <a className="btn-primary" href="https://www.realtor.ca/">
            Coming soon to Realtor.ca →
          </a>
		  
		  
        </div>
        <div className="pricing-right">
          <div className="price-row">
            <span className="price-k">Monthly rent</span>
            <span className="price-v">
              <em>$2,750</em>
              <small>/ month</small>
            </span>
          </div>
          <div className="price-row">
            <span className="price-k">Available</span>
            <span className="price-v"><em>July 1</em><small>2026</small></span>
          </div>
          <div className="price-row">
            <span className="price-k">Parking</span>
            <span className="price-v"><em>Included</em><small>underground</small></span>
          </div>
        </div>
      </div>
      <footer className="site-foot">
        <span>470 Laurier Avenue West · Ottawa, ON</span>
        <span>COMING SOON TO REALTOR.CA </span>
      </footer>
    </section>);

}

/* ---------- Tweaks UI ---------- */
function Tweaks({ t, setTweak }) {
  return (
    <TweaksPanel title="Tweaks">
      <TweakSection title="Palette">
        <TweakRadio
          value={t.palette}
          onChange={(v) => setTweak("palette", v)}
          options={Object.entries(PALETTES).map(([k, p]) => ({ value: k, label: p.label }))} />
        
      </TweakSection>
      <TweakSection title="Typography">
        <TweakSelect
          value={t.font}
          onChange={(v) => setTweak("font", v)}
          options={Object.entries(FONTS).map(([k, f]) => ({ value: k, label: f.label }))} />
        
      </TweakSection>
      <TweakSection title="Hero composition">
        <TweakRadio
          value={t.hero}
          onChange={(v) => setTweak("hero", v)}
          options={[
          { value: "split", label: "Split" },
          { value: "fullbleed", label: "Full-bleed" }]
          } />
        
      </TweakSection>
      <TweakSection title="Gallery layout">
        <TweakRadio
          value={t.gallery}
          onChange={(v) => setTweak("gallery", v)}
          options={[
          { value: "story", label: "Story" },
          { value: "mosaic", label: "Mosaic" },
          { value: "grid", label: "Grid" }]
          } />
        
      </TweakSection>
      <TweakSection title="Density">
        <TweakRadio
          value={t.density}
          onChange={(v) => setTweak("density", v)}
          options={[
          { value: "airy", label: "Airy" },
          { value: "compact", label: "Compact" }]
          } />
        
      </TweakSection>
    </TweaksPanel>);

}

/* ---------- App ---------- */
function App() {
  const [t, setTweak] = useTweaks(TWEAK_DEFAULTS);
  useReveal();

  const palette = PALETTES[t.palette] || PALETTES["sage-clay"];
  const font = FONTS[t.font] || FONTS.cormorant;

  const cssVars = useMemo(
    () => ({
      "--bg": palette.bg,
      "--panel": palette.panel,
      "--ink": palette.ink,
      "--sub": palette.sub,
      "--rule": palette.rule,
      "--accent": palette.accent,
      "--accent2": palette.accent2,
      "--wood": palette.wood,
      "--font-h": font.heading,
      "--font-b": font.body,
      "--weight-h": font.weightH,
      "--track-h": font.headingTrack,
      "--gap": t.density === "compact" ? "64px" : "60px",
      "--gap-mobile": t.density === "compact" ? "48px" : "72px",
      "--pad": t.density === "compact" ? "40px" : "56px"
    }),
    [palette, font, t.density]
  );

  return (
    <div className="root" style={cssVars} data-density={t.density}>
      <header className="topnav">
        <div className="topnav-mark">
          <span className="mark-num">470</span>
          <span className="mark-name">Laurier&nbsp;West</span>
        </div>
        <nav>
          <a href="#inquire">Inquire</a>
        </nav>
      </header>

      <main>
        <Hero hero={t.hero} />
		<Specs />
        <Neighborhood />
        <FloorPlan />
        <Amenities />
        <Gallery layout={t.gallery} />
        <Pricing />
      </main>

      <Tweaks t={t} setTweak={setTweak} />
    </div>);

}

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