// app.jsx — Oakridge Tailors homepage. Depends on window.BookingModal + tweaks helpers.
const { useState, useEffect, useRef } = React;

const ACCENTS = {
  Brass:   "#9c7740",
  Oxblood: "#8a443c",
  Forest:  "#4a5d49",
  Slate:   "#4d5d70",
};
const DISPLAYS = {
  Cormorant: '"Cormorant", Georgia, serif',
  Playfair:  '"Playfair Display", Georgia, serif',
  Spectral:  '"Spectral", Georgia, serif',
};

const TWEAK_DEFAULTS = /*EDITMODE-BEGIN*/{
  "accent": "Brass",
  "display": "Cormorant",
  "heroDark": false
}/*EDITMODE-END*/;

/* ---------- small helpers ---------- */
const IMG = (id) => `https://images.pexels.com/photos/${id}/pexels-photo-${id}.jpeg?auto=compress&cs=tinysrgb&w=1600`;
function Placeholder({ label, dark, style, className, img }) {
  return (
    <div className={`ph ${dark ? "ph-dark" : ""} ${className || ""}`} style={{ position: "relative", overflow: "hidden", ...style }}>
      {img && <img src={img} alt={label} loading="lazy"
        style={{ position: "absolute", inset: 0, width: "100%", height: "100%", objectFit: "cover" }}
        onError={(e) => { e.currentTarget.style.display = "none"; }} />}
      {img && <span aria-hidden="true" style={{ position: "absolute", inset: 0, background: "linear-gradient(to top, rgba(0,0,0,.5), rgba(0,0,0,0) 55%)" }} />}
      <span className="ph-label" style={img ? { position: "relative", color: "#f3ece0", zIndex: 1 } : undefined}>{label}</span>
    </div>
  );
}

function Reveal({ children, delay = 0, style, className }) {
  const ref = useRef(null);
  const [isIn, setIsIn] = useState(false);
  useEffect(() => {
    const el = ref.current;
    if (!el || isIn) return;
    if (!("IntersectionObserver" in window)) { setIsIn(true); return; }
    const io = new IntersectionObserver((es) => {
      es.forEach(e => { if (e.isIntersecting) { setIsIn(true); io.disconnect(); } });
    }, { threshold: 0.12, rootMargin: "0px 0px -7% 0px" });
    io.observe(el);
    // fallback: reveal anything already in view shortly after mount
    const t = setTimeout(() => {
      const r = el.getBoundingClientRect();
      if (r.top < window.innerHeight * 0.96 && r.bottom > 0) setIsIn(true);
    }, 220);
    return () => { io.disconnect(); clearTimeout(t); };
  }, [isIn]);
  return (
    <div ref={ref} className={`reveal ${isIn ? "in" : ""} ${className || ""}`}
         style={{ animationDelay: `${delay}ms`, ...style }}>
      {children}
    </div>
  );
}

/* ---------- nav ---------- */
function Nav({ onBook }) {
  const [solid, setSolid] = useState(false);
  const [menuOpen, setMenuOpen] = useState(false);
  useEffect(() => {
    const onScroll = () => setSolid(window.scrollY > 80);
    window.addEventListener("scroll", onScroll, { passive: true });
    onScroll();
    return () => window.removeEventListener("scroll", onScroll);
  }, []);
  const links = [["Work", "#services"], ["Visit", "#visit"], ["Drop off", "#process"]];
  const showBar = solid || menuOpen;
  return (
    <header style={{ ...nav.bar, ...(showBar ? nav.barSolid : {}) }}>
      <div style={nav.inner}>
        <a href="#top" style={nav.brand} onClick={() => setMenuOpen(false)}>
          <span style={{ ...nav.mark, color: "var(--ink)" }}>OAKRIDGE</span>
          <span style={{ ...nav.sub, color: "var(--accent)" }}>TAILORS ON CAMBIE</span>
        </a>
        <nav className="nav-links" style={nav.links}>
          {links.map(([t, h]) => (
            <a key={t} href={h} className="link-underline"
               style={{ color: "var(--ink)", fontWeight: 500, whiteSpace: "nowrap" }}>{t}</a>
          ))}
          <a href="tel:+16043250545" className="btn"
            style={{ ...nav.cta, ...(solid ? nav.ctaSolid : {}) }}>(604) 325-0545</a>
        </nav>
        <button className="nav-burger" style={nav.burger}
          aria-label={menuOpen ? "Close menu" : "Open menu"} aria-expanded={menuOpen}
          onClick={() => setMenuOpen(o => !o)}>
          <span style={{ ...nav.burgerBar, ...(menuOpen ? { transform: "translateY(6px) rotate(45deg)" } : {}) }} />
          <span style={{ ...nav.burgerBar, opacity: menuOpen ? 0 : 1 }} />
          <span style={{ ...nav.burgerBar, ...(menuOpen ? { transform: "translateY(-6px) rotate(-45deg)" } : {}) }} />
        </button>
      </div>
      {menuOpen && (
        <div className="nav-drawer" style={nav.drawer}>
          {links.map(([t, h]) => (
            <a key={t} href={h} onClick={() => setMenuOpen(false)} style={nav.drawerLink}>{t}</a>
          ))}
          <a href="tel:+16043250545" onClick={() => setMenuOpen(false)} style={nav.drawerCall}>Call (604) 325-0545</a>
        </div>
      )}
    </header>
  );
}

/* ---------- hero ---------- */
function Hero({ onBook, dark }) {
  return (
    <section id="top" style={hero.wrap}>
      <div style={{ ...hero.bg, backgroundImage: "url('https://images.pexels.com/photos/6766284/pexels-photo-6766284.jpeg?auto=compress&cs=tinysrgb&w=1600')", backgroundSize: "cover", backgroundPosition: "center" }} />
      <div className={dark ? "hero-scrim-dark" : "hero-scrim-light"} style={hero.scrim} />
      <div className="container" style={hero.content}>
        <Reveal>
          <p className="eyebrow" style={{ color: "var(--accent)" }}>
            ✪ TAILORING · CAMBIE · 4.7★ ON 117 GOOGLE REVIEWS
          </p>
        </Reveal>
        <Reveal delay={90}>
          <h1 className="display" style={{ ...hero.h1, fontStyle: "italic", color: dark ? "var(--paper)" : "var(--ink)" }}>
            Made to fit.<br /><span style={{ color: "#1B2742" }}>Built to last.</span>
          </h1>
        </Reveal>
        <Reveal delay={180}>
          <p style={{ ...hero.lede, color: dark ? "rgba(243,238,228,0.86)" : "var(--ink-soft)" }}>
            The shop takes in the kind of work other tailors won't — wedding
            dresses, suit jacket reconstructions, the trousers you've had for ten years.
            4.7★ on 117 Google reviews. The shop people send each other to
            for alterations.
          </p>
        </Reveal>
        <Reveal delay={260}>
          <div style={hero.actions}>
            <button className="btn btn-accent" onClick={() => onBook()}>Book a fitting</button>
            <a href="tel:+16043250545" className="btn btn-ghost"
               style={{ borderColor: dark ? "rgba(243,238,228,0.4)" : "var(--line)",
                        color: dark ? "var(--paper)" : "var(--ink)" }}>Call (604) 325-0545</a>
          </div>
        </Reveal>
      </div>
      <div data-hide="mobile" style={{ ...hero.scrollHint, color: dark ? "rgba(243,238,228,0.6)" : "var(--ink-faint)" }}>
        <span style={hero.scrollLine} /> scroll
      </div>
    </section>
  );
}

/* ---------- marquee strip ---------- */
function Strip() {
  const items = ["Wedding dress alterations", "·", "Suit jackets", "·", "Daily wear", "·",
    "Cambie St · Vancouver", "·", "4.7★ on 117 Google", "·", "Walk-in fittings Tue–Sat"];
  const run = [...items, ...items];
  return (
    <div style={strip.wrap}>
      <div style={strip.track}>
        {run.map((t, i) => (
          <span key={i} style={t === "·" ? strip.dot : strip.item}>{t}</span>
        ))}
      </div>
    </div>
  );
}

/* ---------- about the shop ---------- */
function House() {
  return (
    <section id="house" className="section container">
      <div style={house.grid} data-grid="house">
        <Reveal style={{ gridColumn: "span 1" }}>
          <p className="eyebrow">The shop</p>
        </Reveal>
        <div style={house.right}>
          <div style={house.aboutGrid} data-grid="about">
            <Reveal>
              <p className="serif-lead">
                A small shop on Cambie that takes in the work other tailors won't —
                wedding dresses, formalwear, suit alterations. The kind of place
                people quietly send each other to.
              </p>
              <div style={house.stats} data-grid="stats">
                <Stat n="4.7★" l="117 Google reviews" />
                <Stat n="Tue–Sat" l="walk-in fittings" />
              </div>
            </Reveal>
            <Reveal delay={120}>
              <Placeholder label="at the cutting table · owner supplies real photo" img={IMG(3972467)} style={house.portrait} />
            </Reveal>
          </div>
        </div>
      </div>
    </section>
  );
}
function Stat({ n, l }) {
  return (
    <div style={house.stat}>
      <div style={house.statN} className="display">{n}</div>
      <div style={house.statL}>{l}</div>
    </div>
  );
}

/* ---------- services ---------- */
const SVC = [
  { id: "wedding", n: "Wedding dress", d: "Bustles, bodice take-in, hem, sleeves. We've done hundreds.", price: "quote on site", img: "garments on the rack", imgUrl: IMG(994523) },
  { id: "suit", n: "Suit jackets", d: "Shoulder reconstruction, sleeve adjust, side seams. Two-week turn.", price: "quote on site", img: "tailored jacket", imgUrl: IMG(6046226) },
  { id: "daily", n: "Daily wear", d: "Trouser hems, jean tapers, dress side seams. Same-week.", price: "quote on site", img: "trousers & denim", imgUrl: IMG(7679454) },
];
function Services({ onBook }) {
  return (
    <section id="services" className="section" style={{ background: "var(--paper-2)" }}>
      <div className="container">
        <Reveal style={services.head}>
          <p className="eyebrow">The work</p>
          <h2 className="display" style={services.h2}>What you can bring in.</h2>
        </Reveal>
        <div style={services.grid} data-grid="services">
          {SVC.map((s, i) => (
            <Reveal key={s.id} delay={(i % 2) * 90}>
              <article style={services.card}
                onClick={() => onBook(s.id)}
                tabIndex={0}
                onKeyDown={e => { if (e.key === "Enter") onBook(s.id); }}>
                <Placeholder label={s.img} img={s.imgUrl} style={services.cardImg} />
                <div style={services.cardBody}>
                  <span style={services.num}>{String(i + 1).padStart(2, "0")}</span>
                  <h3 className="display" style={services.cardTitle}>{s.n}</h3>
                  <p className="muted" style={services.cardText}>{s.d}</p>
                  <div style={services.cardFoot}>
                    <span style={services.price}>{s.price}</span>
                    <span className="link-underline" style={{ color: "var(--accent)" }}>Book this →</span>
                  </div>
                </div>
              </article>
            </Reveal>
          ))}
        </div>
      </div>
    </section>
  );
}

/* ---------- process ---------- */
const STEPS = [
  { n: "01", t: "Try it on. We pin it." },
  { n: "02", t: "We quote on the spot." },
  { n: "03", t: "You leave it. 1–3 weeks typical." },
  { n: "04", t: "Final fitting before you take it home." },
];
function Process() {
  return (
    <section id="process" className="section container">
      <Reveal style={{ marginBottom: 60 }}>
        <p className="eyebrow">The process</p>
        <h2 className="display" style={{ fontSize: "clamp(2.4rem,5vw,4rem)", marginTop: 12 }}>
          How drop-off works.
        </h2>
      </Reveal>
      <div style={proc.grid} data-grid="proc">
        {STEPS.map((s, i) => (
          <Reveal key={s.n} delay={i * 80}>
            <div style={proc.step}>
              <span className="display" style={proc.stepN}>{s.n}</span>
              <hr className="hairline" style={{ margin: "18px 0 20px" }} />
              <p style={proc.stepT}>{s.t}</p>
            </div>
          </Reveal>
        ))}
      </div>
    </section>
  );
}

/* ---------- craft strip (dark, full-bleed) ---------- */
function Craft() {
  return (
    <section style={craft.wrap}>
      <div style={craft.grid} data-grid="craft">
        <Placeholder dark label="detail · the measuring tape" img={IMG(6766283)} style={craft.tall} />
        <div style={craft.col}>
          <Placeholder dark label="detail · fabric swatches" img={IMG(276267)} style={craft.short} />
          <Placeholder dark label="detail · folded wool" img={IMG(6045248)} style={craft.short} />
        </div>
        <div style={craft.text}>
          <Reveal>
            <p className="eyebrow" style={{ color: "var(--accent)" }}>In the shop</p>
            <p className="serif-lead" style={{ color: "var(--paper)", marginTop: 18 }}>
              The kind of work other tailors won't take on — a wedding dress two weeks
              before the day, a jacket reset through the shoulder. High-stakes garments,
              handled like they're our own.
            </p>
          </Reveal>
        </div>
      </div>
    </section>
  );
}

/* ---------- proof ---------- */
const PROOF = [
  { q: "OWNER TO SUPPLY — pull a verified 5★ Google review here.", s: "Google" },
  { q: "OWNER TO SUPPLY — a wedding-dress or formalwear review.", s: "Google" },
  { q: "OWNER TO SUPPLY — a suit or daily-wear review.", s: "Google" },
];
function Quote() {
  return (
    <section id="proof" className="section container">
      <Reveal style={{ marginBottom: 48 }}>
        <p className="eyebrow">Proof</p>
        <h2 className="display" style={{ fontSize: "clamp(2.2rem,4.5vw,3.6rem)", marginTop: 12 }}>
          What people actually say.
        </h2>
      </Reveal>
      <div style={proof.grid} data-grid="proof">
        {PROOF.map((p, i) => (
          <Reveal key={i} delay={i * 90}>
            <figure style={proof.card}>
              <blockquote className="display" style={proof.q}>“{p.q}”</blockquote>
              <figcaption style={proof.s}>{p.s}</figcaption>
            </figure>
          </Reveal>
        ))}
      </div>
    </section>
  );
}

/* ---------- booking CTA ---------- */
function CTA({ onBook }) {
  return (
    <section style={cta.wrap}>
      <div className="container" style={cta.inner}>
        <Reveal>
          <p className="eyebrow" style={{ color: "var(--accent)" }}>Drop it off</p>
          <h2 className="display" style={cta.h2}>
            Bring it in.<br />We'll take a look.
          </h2>
          <p style={cta.sub}>
            Wedding dresses, formalwear, suit and daily-wear alterations. We pin it,
            quote on the spot, and you're on your way.
          </p>
          <div style={cta.actions}>
            <button className="btn btn-accent" onClick={() => onBook()}>Book a fitting</button>
            <a href="tel:+16043250545" className="btn btn-ghost"
               style={{ borderColor: "rgba(243,238,228,0.4)", color: "var(--paper)" }}>
              Call (604) 325-0545
            </a>
          </div>
        </Reveal>
      </div>
    </section>
  );
}

/* ---------- visit + footer ---------- */
function Visit() {
  return (
    <section id="visit" className="section container">
      <div style={visit.grid} data-grid="visit">
        <div>
          <Reveal>
            <p className="eyebrow">Visit the shop</p>
            <h2 className="display" style={visit.h2}>6371 Cambie St.<br />Vancouver BC.</h2>
          </Reveal>
          <Reveal delay={100} style={{ marginTop: 36 }}>
            <div style={visit.rows}>
              <VRow k="Find us" v={["6371 Cambie St, Vancouver, BC V5Z 0G7"]} />
              <VRow k="Reach us" v={["(604) 325-0545"]} />
              <VRow k="Reviews" v={["4.7★ · 117 on Google"]} />
            </div>
          </Reveal>
        </div>
        <Reveal delay={140}>
          <div style={{ ...visit.map, overflow: "hidden" }}>
            <iframe
              title="Oakridge Tailors — 6371 Cambie St, Vancouver, BC"
              src="https://maps.google.com/maps?q=6371+Cambie+St+Vancouver+BC&output=embed&z=15"
              width="100%" height="100%" frameBorder="0"
              style={{ border: 0, display: "block", width: "100%", height: "100%" }}
              loading="lazy"
              referrerPolicy="no-referrer-when-downgrade"
              allowFullScreen></iframe>
          </div>
        </Reveal>
      </div>
    </section>
  );
}
function VRow({ k, v }) {
  return (
    <div style={visit.row}>
      <span style={visit.rowK}>{k}</span>
      <div style={visit.rowV}>{v.map((line, i) => <span key={i}>{line}</span>)}</div>
    </div>
  );
}

function Footer({ onBook }) {
  return (
    <footer style={foot.wrap}>
      <div className="container" style={foot.inner}>
        <div>
          <div style={foot.mark} className="display">Oakridge Tailors</div>
          <p style={foot.tag}>Alterations on Cambie.</p>
        </div>
        <div style={foot.right}>
          <button className="btn link-underline" onClick={() => onBook()} style={{ color: "var(--paper)" }}>Book a fitting</button>
          <a href="#services" className="link-underline" style={{ color: "rgba(243,238,228,0.7)" }}>Work</a>
          <a href="#process" className="link-underline" style={{ color: "rgba(243,238,228,0.7)" }}>Drop off</a>
          <a href="#visit" className="link-underline" style={{ color: "rgba(243,238,228,0.7)" }}>Visit</a>
        </div>
      </div>
      <div className="container" style={foot.base}>
        <span>© Oakridge Tailors · On Cambie</span>
        <span style={{ color: "rgba(243,238,228,0.4)" }}>Concept by X9 Lab Media · 2026</span>
      </div>
    </footer>
  );
}

/* ===================== STYLES ===================== */
const nav = {
  bar: { position: "fixed", top: 0, left: 0, right: 0, zIndex: 100, transition: "background .4s ease, box-shadow .4s ease, padding .4s ease", padding: "26px 0" },
  barSolid: { background: "rgba(243,238,228,0.92)", backdropFilter: "blur(10px)", boxShadow: "0 1px 0 var(--line)", padding: "16px 0" },
  inner: { maxWidth: "var(--maxw)", margin: "0 auto", paddingInline: "var(--gut)", display: "flex", alignItems: "center", justifyContent: "space-between", gap: 24 },
  brand: { display: "flex", flexDirection: "column", lineHeight: 1 },
  mark: { fontFamily: "var(--body)", fontWeight: 800, letterSpacing: "0.16em", fontSize: "1.06rem", transition: "color .4s" },
  sub: { fontSize: "0.58rem", letterSpacing: "0.3em", fontWeight: 600, marginTop: 4, transition: "color .4s" },
  links: { display: "flex", gap: 34, alignItems: "center" },
  cta: { border: "1px solid var(--line)", color: "var(--ink)", padding: "11px 22px", borderRadius: 2, transition: "all .35s ease" },
  ctaSolid: { background: "var(--ink)", borderColor: "var(--ink)", color: "var(--paper)" },
  burger: { flexDirection: "column", justifyContent: "center", alignItems: "center", gap: 5, width: 44, height: 44, background: "none", border: "none", cursor: "pointer", padding: 9, margin: "-4px -9px -4px 0" },
  burgerBar: { display: "block", width: 24, height: 2, background: "var(--ink)", borderRadius: 2, transition: "transform .3s ease, opacity .25s ease" },
  drawer: { display: "flex", flexDirection: "column", background: "var(--paper)", borderTop: "1px solid var(--line)", boxShadow: "0 18px 40px rgba(20,16,12,0.12)", padding: "6px var(--gut) 18px" },
  drawerLink: { display: "flex", alignItems: "center", minHeight: 52, fontSize: "1.15rem", fontWeight: 500, color: "var(--ink)", borderBottom: "1px solid var(--line-soft)" },
  drawerCall: { display: "flex", alignItems: "center", minHeight: 52, fontSize: "1.15rem", fontWeight: 600, color: "var(--accent)", letterSpacing: "0.01em" },
};

const hero = {
  wrap: { position: "relative", minHeight: "100vh", display: "flex", alignItems: "flex-end", overflow: "hidden" },
  bg: { position: "absolute", inset: 0, zIndex: 1 },
  scrim: { position: "absolute", inset: 0, zIndex: 2 },
  content: { position: "relative", zIndex: 3, paddingBottom: "clamp(80px, 12vh, 150px)", paddingTop: 140, width: "100%" },
  h1: { fontSize: "clamp(3rem, 6.6vw, 6.5rem)", margin: "18px 0 0", maxWidth: "16ch" },
  lede: { fontSize: "clamp(1.05rem, 1.6vw, 1.32rem)", lineHeight: 1.6, maxWidth: 540, marginTop: 30 },
  actions: { display: "flex", gap: 14, marginTop: 38, flexWrap: "wrap" },
  scrollHint: { position: "absolute", zIndex: 3, bottom: 30, right: "var(--gut)", display: "flex", alignItems: "center", gap: 10, fontSize: "0.68rem", letterSpacing: "0.22em", textTransform: "uppercase" },
  scrollLine: { display: "inline-block", width: 40, height: 1, background: "currentColor", opacity: 0.6 },
};

const strip = {
  wrap: { background: "var(--ink)", color: "var(--paper)", overflow: "hidden", padding: "16px 0", borderBlock: "1px solid rgba(243,238,228,0.1)" },
  track: { display: "flex", gap: 28, alignItems: "center", whiteSpace: "nowrap", width: "max-content", animation: "marquee 38s linear infinite" },
  item: { fontSize: "0.74rem", letterSpacing: "0.22em", textTransform: "uppercase", fontWeight: 500, color: "rgba(243,238,228,0.9)" },
  dot: { color: "var(--accent)", fontSize: "0.9rem" },
};

const house = {
  grid: { display: "grid", gridTemplateColumns: "minmax(120px, 1fr) 3fr", gap: "clamp(24px, 6vw, 90px)" },
  right: {},
  aboutGrid: { display: "grid", gridTemplateColumns: "1.15fr 1fr", gap: "clamp(24px, 4vw, 56px)", alignItems: "center" },
  portrait: { aspectRatio: "4 / 5", width: "100%", borderRadius: 4 },
  stats: { display: "flex", gap: "clamp(28px, 5vw, 60px)", borderTop: "1px solid var(--line)", paddingTop: 28, marginTop: 36 },
  stat: {},
  statN: { fontSize: "clamp(2.2rem, 4vw, 3.4rem)", fontWeight: 500, lineHeight: 1, color: "var(--accent)" },
  statL: { fontSize: "0.82rem", color: "var(--ink-soft)", marginTop: 8, letterSpacing: "0.01em" },
};

const services = {
  head: { marginBottom: 56 },
  h2: { fontSize: "clamp(2.4rem, 5vw, 4rem)", marginTop: 12 },
  grid: { display: "grid", gridTemplateColumns: "repeat(3, 1fr)", gap: "clamp(20px, 2.4vw, 32px)" },
  card: { cursor: "pointer", outline: "none", display: "flex", flexDirection: "column", background: "var(--paper)", border: "1px solid var(--line)", borderRadius: 4, overflow: "hidden", transition: "transform .4s cubic-bezier(.2,.7,.2,1), box-shadow .4s" },
  cardImg: { aspectRatio: "4 / 3", width: "100%" },
  cardBody: { padding: "28px 28px 30px", position: "relative", display: "flex", flexDirection: "column", flex: 1 },
  num: { position: "absolute", top: 28, right: 28, fontFamily: "ui-monospace, 'SF Mono', Menlo, monospace", fontSize: "0.72rem", letterSpacing: "0.1em", color: "var(--ink-faint)", fontWeight: 600 },
  cardTitle: { fontSize: "1.9rem", fontWeight: 500, marginBottom: 12 },
  cardText: { fontSize: "0.96rem", marginBottom: 22, maxWidth: "40ch" },
  cardFoot: { display: "flex", justifyContent: "space-between", alignItems: "center", marginTop: "auto", paddingTop: 16, borderTop: "1px dashed var(--line)" },
  price: { fontFamily: "ui-monospace, 'SF Mono', Menlo, monospace", fontSize: "0.82rem", letterSpacing: "0.02em", color: "var(--ink)", textTransform: "uppercase" },
};

const proc = {
  grid: { display: "grid", gridTemplateColumns: "repeat(4, 1fr)", gap: "clamp(20px, 3vw, 44px)" },
  step: {},
  stepN: { fontSize: "3rem", fontWeight: 500, color: "var(--accent)", lineHeight: 1 },
  stepT: { fontFamily: "ui-monospace, 'SF Mono', Menlo, monospace", fontSize: "1.02rem", lineHeight: 1.45, color: "var(--ink)", margin: 0, letterSpacing: "0.01em" },
};

const proof = {
  grid: { display: "grid", gridTemplateColumns: "repeat(auto-fit, minmax(248px, 1fr))", gap: "clamp(18px, 2.4vw, 32px)" },
  card: { background: "var(--paper-2)", border: "1px solid var(--line)", borderRadius: 4, padding: "34px 32px", margin: 0, display: "flex", flexDirection: "column", gap: 22 },
  q: { fontSize: "clamp(1.4rem, 2vw, 1.7rem)", fontWeight: 500, lineHeight: 1.32, fontStyle: "italic", margin: 0, textWrap: "pretty" },
  s: { fontFamily: "ui-monospace, 'SF Mono', Menlo, monospace", fontSize: "0.7rem", letterSpacing: "0.08em", textTransform: "uppercase", color: "var(--ink-faint)", marginTop: "auto" },
};

const craft = {
  wrap: { background: "var(--ink)", padding: "clamp(40px, 6vw, 90px) 0" },
  grid: { maxWidth: "var(--maxw)", margin: "0 auto", paddingInline: "var(--gut)", display: "grid", gridTemplateColumns: "1.2fr 1fr 1.2fr", gap: "clamp(16px, 2vw, 28px)", alignItems: "stretch" },
  tall: { borderRadius: 4, minHeight: 440 },
  col: { display: "flex", flexDirection: "column", gap: "clamp(16px, 2vw, 28px)" },
  short: { borderRadius: 4, flex: 1, minHeight: 200 },
  text: { display: "flex", alignItems: "center", paddingLeft: "clamp(0px, 2vw, 30px)" },
};

const quote = {
  q: { fontSize: "clamp(1.7rem, 3.6vw, 3.1rem)", fontWeight: 500, lineHeight: 1.26, margin: "28px auto 0", maxWidth: "20ch", fontStyle: "italic", textWrap: "balance" },
  cite: { marginTop: 30, fontSize: "0.84rem", letterSpacing: "0.06em", color: "var(--ink-faint)", textTransform: "uppercase" },
};

const cta = {
  wrap: { background: "var(--ink)", color: "var(--paper)", padding: "clamp(80px, 12vw, 160px) 0" },
  inner: {},
  h2: { fontSize: "clamp(2.6rem, 6vw, 5rem)", color: "var(--paper)", marginTop: 14 },
  sub: { fontSize: "1.1rem", color: "rgba(243,238,228,0.78)", maxWidth: 500, marginTop: 26, lineHeight: 1.6 },
  actions: { display: "flex", gap: 14, marginTop: 38, flexWrap: "wrap" },
};

const visit = {
  grid: { display: "grid", gridTemplateColumns: "1fr 1fr", gap: "clamp(30px, 5vw, 70px)", alignItems: "center" },
  h2: { fontSize: "clamp(2.2rem, 4.5vw, 3.6rem)", marginTop: 14 },
  rows: { display: "flex", flexDirection: "column" },
  row: { display: "grid", gridTemplateColumns: "120px 1fr", gap: 20, padding: "20px 0", borderTop: "1px solid var(--line)" },
  rowK: { fontSize: "0.72rem", letterSpacing: "0.1em", textTransform: "uppercase", color: "var(--accent)", fontWeight: 600, paddingTop: 3 },
  rowV: { display: "flex", flexDirection: "column", gap: 4, fontSize: "1rem", color: "var(--ink-soft)" },
  map: { aspectRatio: "4 / 5", width: "100%", borderRadius: 4 },
};

const foot = {
  wrap: { background: "var(--ink)", color: "var(--paper)", paddingTop: 60, borderTop: "1px solid rgba(243,238,228,0.12)" },
  inner: { display: "flex", justifyContent: "space-between", alignItems: "flex-start", gap: 30, flexWrap: "wrap", paddingBottom: 50 },
  mark: { fontSize: "2rem", fontWeight: 500 },
  tag: { color: "rgba(243,238,228,0.6)", fontSize: "0.92rem", marginTop: 8 },
  right: { display: "flex", gap: 28, alignItems: "center", flexWrap: "wrap" },
  base: { display: "flex", justifyContent: "space-between", gap: 16, flexWrap: "wrap", paddingBottom: 30, fontSize: "0.78rem", color: "rgba(243,238,228,0.55)", borderTop: "1px solid rgba(243,238,228,0.1)", paddingTop: 24 },
};

/* ===================== APP ===================== */
function App() {
  const [t, setTweak] = useTweaks(TWEAK_DEFAULTS);
  const [booking, setBooking] = useState({ open: false, svc: null });

  const accent = ACCENTS[t.accent] || ACCENTS.Brass;
  const display = DISPLAYS[t.display] || DISPLAYS.Cormorant;

  useEffect(() => {
    document.documentElement.style.setProperty("--accent", accent);
    document.documentElement.style.setProperty("--display", display);
  }, [accent, display]);

  const openBooking = (svc) => setBooking({ open: true, svc: svc || null });
  const closeBooking = () => setBooking(b => ({ ...b, open: false }));

  return (
    <div>
      <Nav onBook={openBooking} />
      <Hero onBook={openBooking} dark={t.heroDark} />
      <Strip />
      <House />
      <Services onBook={openBooking} />
      <Process />
      <Craft />
      <Quote />
      <CTA onBook={openBooking} />
      <Visit />
      <Footer onBook={openBooking} />

      <BookingModal open={booking.open} onClose={closeBooking} initialService={booking.svc} />

      <TweaksPanel>
        <TweakSection label="Palette" />
        <TweakRadio label="Accent" value={t.accent}
          options={Object.keys(ACCENTS)} onChange={v => setTweak("accent", v)} />
        <TweakSection label="Type" />
        <TweakRadio label="Display face" value={t.display}
          options={Object.keys(DISPLAYS)} onChange={v => setTweak("display", v)} />
        <TweakSection label="Hero" />
        <TweakToggle label="Dark hero" value={t.heroDark} onChange={v => setTweak("heroDark", v)} />
      </TweaksPanel>
    </div>
  );
}

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