/* global React, ReactDOM */
const { useState, useEffect, useRef } = React;

/* ---------- small helpers ---------- */
function useReveal() {
  const ref = useRef(null);
  useEffect(() => {
    const els = (ref.current || document).querySelectorAll(".reveal");
    if (!("IntersectionObserver" in window) ||
        window.matchMedia("(prefers-reduced-motion: reduce)").matches) {
      els.forEach((e) => e.classList.add("in"));
      return;
    }
    const io = new IntersectionObserver(
      (entries) => entries.forEach((en) => { if (en.isIntersecting) { en.target.classList.add("in"); io.unobserve(en.target); } }),
      { threshold: 0.12, rootMargin: "0px 0px -8% 0px" }
    );
    els.forEach((e) => io.observe(e));
    return () => io.disconnect();
  });
  return ref;
}

function Placeholder({ label, className = "", light = false, style }) {
  return (
    <div className={`ph ${light ? "light" : ""} ${className}`} style={style} role="img" aria-label={label}>
      <span className="ph-label">{label}</span>
    </div>
  );
}

const LOGO_SRC = "https://assets.ls-assets.com/logos/fbfb70f6-7d50-4ade-9611-4bc1ccac7da1/d00f70a5-7e62-46fa-a75a-daad4041dc73.png?w=768";

function Brand() {
  const [failed, setFailed] = useState(false);
  return (
    <a className="brand" href="#top" aria-label="The Essex Will Company, home">
      {failed ? (
        <>
          <span className="brand-mark" aria-hidden="true">E</span>
          <span className="brand-name"><b>The&nbsp;Essex</b>&nbsp;Will&nbsp;Company</span>
        </>
      ) : (
        <img
          className="brand-logo" src={LOGO_SRC} alt="The Essex Will Company"
          referrerPolicy="no-referrer" onError={() => setFailed(true)}
        />
      )}
    </a>
  );
}

/* simple line icons — basic primitives only */
function Icon({ name }) {
  const common = { width: 24, height: 24, viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: 1.6, strokeLinecap: "round", strokeLinejoin: "round" };
  const paths = {
    will: (<><rect x="5" y="3" width="14" height="18" rx="1.5" /><line x1="8.5" y1="8" x2="15.5" y2="8" /><line x1="8.5" y1="12" x2="15.5" y2="12" /><line x1="8.5" y1="16" x2="13" y2="16" /></>),
    lpa: (<><circle cx="8.5" cy="8.5" r="2.6" /><circle cx="16" cy="9.5" r="2.2" /><line x1="8.5" y1="12.5" x2="8.5" y2="18" /><line x1="16" y1="13" x2="16" y2="18" /><line x1="5" y1="15" x2="12" y2="15" /></>),
    home: (<><polyline points="4,11 12,4 20,11" /><rect x="6.5" y="11" width="11" height="9" rx="1" /></>),
    sever: (<><rect x="4" y="4" width="16" height="16" rx="1.5" /><line x1="4.5" y1="19.5" x2="19.5" y2="4.5" /></>),
    trust: (<><circle cx="12" cy="12" r="8" /><circle cx="12" cy="12" r="3" /></>),
    iht: (<><circle cx="9.5" cy="10" r="5" /><circle cx="15" cy="14.5" r="5" /></>),
    clock: (<><circle cx="12" cy="12" r="8" /><line x1="12" y1="8" x2="12" y2="12" /><line x1="12" y1="12" x2="15" y2="14" /></>),
    shield: (<><circle cx="12" cy="12" r="8" /><polyline points="8.5,12 11,14.5 15.5,9.5" /></>),
  };
  return (<svg {...common} aria-hidden="true">{paths[name]}</svg>);
}

/* ---------- the falling-sand hourglass ---------- */
function Hourglass() {
  return (
    <div className="hourglass-wrap" aria-hidden="true">
      <div className="hg-glow"></div>
      <svg className="hourglass" viewBox="0 0 200 340" role="presentation">
        <defs>
          <linearGradient id="sandGrad" x1="0" y1="0" x2="0" y2="1">
            <stop offset="0" stopColor="#E0A24E" />
            <stop offset="1" stopColor="#C8843C" />
          </linearGradient>
          <linearGradient id="frameGrad" x1="0" y1="0" x2="0" y2="1">
            <stop offset="0" stopColor="#E0A24E" />
            <stop offset="1" stopColor="#B0722F" />
          </linearGradient>
          <clipPath id="topGlass"><polygon points="52,58 148,58 100,168" /></clipPath>
          <clipPath id="botGlass"><polygon points="100,172 52,282 148,282" /></clipPath>
        </defs>

        {/* caps & posts */}
        <rect x="40" y="28" width="120" height="12" rx="6" fill="url(#frameGrad)" />
        <rect x="40" y="300" width="120" height="12" rx="6" fill="url(#frameGrad)" />
        <rect x="45" y="38" width="6" height="264" rx="3" fill="url(#frameGrad)" opacity="0.92" />
        <rect x="149" y="38" width="6" height="264" rx="3" fill="url(#frameGrad)" opacity="0.92" />

        {/* glass body */}
        <polygon points="52,58 148,58 100,168" fill="rgba(159,176,192,0.07)" stroke="rgba(159,176,192,0.45)" strokeWidth="1.4" />
        <polygon points="100,172 52,282 148,282" fill="rgba(159,176,192,0.07)" stroke="rgba(159,176,192,0.45)" strokeWidth="1.4" />

        {/* sand */}
        <g className="hg-sand">
          <g clipPath="url(#topGlass)"><rect className="hg-top" x="46" y="50" width="108" height="124" fill="url(#sandGrad)" /></g>
          <g clipPath="url(#botGlass)"><rect className="hg-bot" x="46" y="166" width="108" height="124" fill="url(#sandGrad)" /></g>
          <rect className="hg-stream" x="98" y="164" width="4" height="20" rx="2" fill="#E0A24E" />
        </g>

        {/* neck highlight */}
        <circle cx="100" cy="170" r="3" fill="rgba(224,162,78,0.5)" />
      </svg>
    </div>
  );
}

/* image with a graceful navy→amber gradient fallback */
function SmartImage({ src, alt, className = "", style }) {
  const [failed, setFailed] = useState(false);
  if (failed) return <div className={`img-fallback ${className}`} style={style} role="img" aria-label={alt}></div>;
  return (
    <img className={className} style={style} src={src} alt={alt}
      loading="lazy" referrerPolicy="no-referrer" onError={() => setFailed(true)} />
  );
}

/* soft, varied section dividers */
function Curve({ from, to, flip }) {
  return (
    <div className="divider" style={{ background: from }} aria-hidden="true">
      <svg viewBox="0 0 1440 90" preserveAspectRatio="none" style={flip ? { transform: "scaleX(-1)" } : undefined}>
        <path d="M0,46 C320,96 560,8 780,34 C1010,62 1240,96 1440,40 L1440,90 L0,90 Z" fill={to} />
      </svg>
    </div>
  );
}
function Slant({ from, to, flip }) {
  return (
    <div className="divider" style={{ background: from }} aria-hidden="true">
      <svg viewBox="0 0 1440 64" preserveAspectRatio="none" style={flip ? { transform: "scaleX(-1)" } : undefined}>
        <path d="M0,64 L1440,4 L1440,64 Z" fill={to} />
      </svg>
    </div>
  );
}

/* monogram wax-seal crest — concentric rings, curved text, center initial */
function Seal({ className = "", color = "currentColor" }) {
  return (
    <svg className={`seal ${className}`} viewBox="0 0 220 220" role="img" aria-label="The Essex Will Company seal">
      <defs>
        <path id="seal-top" d="M 40,104 Q 110,44 180,104" />
        <path id="seal-bot" d="M 40,116 Q 110,176 180,116" />
      </defs>
      <g fill="none" stroke={color}>
        <circle cx="110" cy="110" r="104" strokeWidth="1.2" />
        <circle cx="110" cy="110" r="96" strokeWidth="2.4" />
        <circle cx="110" cy="110" r="57" strokeWidth="1.2" />
      </g>
      <text className="seal-text" fill={color}><textPath href="#seal-top" startOffset="50%">THE ESSEX WILL COMPANY</textPath></text>
      <text className="seal-text" fill={color}><textPath href="#seal-bot" startOffset="50%">HULLBRIDGE · ESSEX</textPath></text>
      <g fill={color}>
        <path d="M 20,110 l 5,5 -5,5 -5,-5 z" />
        <path d="M 200,110 l 5,5 -5,5 -5,-5 z" />
      </g>
      <text className="seal-mono" x="110" y="122" fill={color}>E</text>
      <text className="seal-sub" x="110" y="143" fill={color}>WILLS</text>
    </svg>
  );
}

/* faint estuary / contour line motif */
function Estuary({ className = "" }) {
  const lines = Array.from({ length: 9 }, (_, i) => {
    const y = 18 + i * 26;
    const d = `M0,${y} C200,${y - 16} 400,${y + 16} 600,${y} C800,${y - 16} 1000,${y + 16} 1200,${y}`;
    return <path key={i} d={d} />;
  });
  return (
    <svg className={`estuary ${className}`} viewBox="0 0 1200 260" preserveAspectRatio="none" aria-hidden="true">
      <g fill="none" stroke="currentColor" strokeWidth="1.1">{lines}</g>
    </svg>
  );
}

/* realistic glossy wax-seal stamp (dimensional, on-brand bronze wax) */
function waxBlob(cx, cy, baseR, amp, bumps, points) {
  let d = "";
  for (let i = 0; i <= points; i++) {
    const a = (i / points) * Math.PI * 2;
    const r = baseR + amp * Math.cos(bumps * a);
    const x = (cx + r * Math.cos(a)).toFixed(2);
    const y = (cy + r * Math.sin(a)).toFixed(2);
    d += (i === 0 ? "M" : "L") + x + "," + y + " ";
  }
  return d + "Z";
}
function WaxSeal({ className = "" }) {
  const outer = waxBlob(100, 100, 82, 6.5, 18, 200);
  const lip = waxBlob(100, 100, 70, 4.5, 18, 200);
  return (
    <svg className={`wax-seal ${className}`} viewBox="0 0 200 200" role="img" aria-label="The Essex Will Company wax seal">
      <defs>
        <radialGradient id="waxDome" cx="38%" cy="30%" r="80%">
          <stop offset="0" stopColor="#E9BD80" />
          <stop offset="0.42" stopColor="#D2934A" />
          <stop offset="0.74" stopColor="#B0702C" />
          <stop offset="1" stopColor="#6B3C16" />
        </radialGradient>
        <radialGradient id="waxLip" cx="50%" cy="46%" r="62%">
          <stop offset="0" stopColor="#A4621F" />
          <stop offset="0.62" stopColor="#C2853E" />
          <stop offset="0.9" stopColor="#E3A85A" />
          <stop offset="1" stopColor="#8C521C" />
        </radialGradient>
        <radialGradient id="waxGloss" cx="36%" cy="26%" r="42%">
          <stop offset="0" stopColor="#FFF3DF" stopOpacity="0.75" />
          <stop offset="1" stopColor="#FFF3DF" stopOpacity="0" />
        </radialGradient>
        <filter id="waxDrop" x="-30%" y="-30%" width="160%" height="160%">
          <feDropShadow dx="0" dy="5" stdDeviation="5" floodColor="#1A0E04" floodOpacity="0.4" />
        </filter>
      </defs>
      <path d={outer} fill="url(#waxDome)" filter="url(#waxDrop)" />
      <path d={outer} fill="none" stroke="#5C3211" strokeOpacity="0.35" strokeWidth="1.4" />
      <path d={lip} fill="url(#waxLip)" />
      <path d={lip} fill="none" stroke="#5C3211" strokeOpacity="0.4" strokeWidth="1.4" />
      <text className="wax-mono wax-mono-shadow" x="100" y="120">E</text>
      <text className="wax-mono" x="100" y="119">E</text>
      <path d={outer} fill="url(#waxGloss)" />
    </svg>
  );
}

/* ============================================================ HEADER */
function Header() {
  const [scrolled, setScrolled] = useState(false);
  const [open, setOpen] = useState(false);
  useEffect(() => {
    const onScroll = () => setScrolled(window.scrollY > 24);
    onScroll();
    window.addEventListener("scroll", onScroll, { passive: true });
    return () => window.removeEventListener("scroll", onScroll);
  }, []);
  return (
    <header className={`site-header ${scrolled || open ? "scrolled" : ""}`}>
      <div className="wrap nav">
        <Brand />
        <nav className={`nav-links ${open ? "open" : ""}`} aria-label="Primary">
          <a href="#services" onClick={() => setOpen(false)}>Wills</a>
          <a href="#services" onClick={() => setOpen(false)}>Powers of Attorney</a>
          <a href="#visit" onClick={() => setOpen(false)}>Home Visits</a>
          <a href="#reviews" onClick={() => setOpen(false)}>Reviews</a>
          <a href="#contact" onClick={() => setOpen(false)}>Contact</a>
          <a className="nav-phone" href="tel:01702891821">01702&nbsp;891821</a>
        </nav>
        <div className="nav-right">
          <a className="btn btn-amber nav-cta" href="#contact" style={{ padding: "11px 20px" }}>Free home visit</a>
          <button
            type="button" className="nav-toggle" aria-label={open ? "Close menu" : "Open menu"}
            aria-expanded={open} onClick={() => setOpen((o) => !o)}
          >
            <span className={open ? "x" : ""}></span>
          </button>
        </div>
      </div>
    </header>
  );
}

/* ============================================================ HERO (navy) */
function Hero() {
  return (
    <section className="hero grain" id="top">
      <div className="wrap hero-grid">
        <div>
          <p className="eyebrow on-dark load-up" style={{ animationDelay: ".05s" }}>Will writing · Hullbridge · across Essex</p>
          <h1 className="serif load-up" style={{ animationDelay: ".15s" }}>
            It’s never too early to write a Will, <em>but often too late.</em>
          </h1>
          <p className="lede load-up" style={{ animationDelay: ".28s" }}>
            The Essex Will Company comes to you, at home, daytime, evening or weekends, with no
            obligation and no extra cost. Over twenty-five years protecting families across Essex.
          </p>
          <div className="hero-cta load-up" style={{ animationDelay: ".4s" }}>
            <a className="btn btn-amber" href="tel:01702891821">Call 01702 891821</a>
            <a className="btn btn-ghost on-dark" href="#contact">Book a free home visit</a>
          </div>
          <p className="hero-trust load-up" style={{ animationDelay: ".52s", display: "block", color: "var(--mut)", fontSize: 14, marginTop: 30 }}>
            Member of the Society of Will Writers. Over 25 years of experience.
          </p>
        </div>
        <div className="load-up" style={{ animationDelay: ".3s" }}>
          <Hourglass />
        </div>
      </div>
    </section>
  );
}

/* ============================================================ TRUST STRIP */
function TrustStrip() {
  const [badgeFail, setBadgeFail] = useState(false);
  const BADGE = "https://www.essexwills.com/gallery_gen/9902dec23701994a46a10701f51a1e09_62x62_fit.png";
  return (
    <section className="trust-strip">
      <div className="wrap trust-inner">
        <div className="trust-item">
          {badgeFail
            ? <span className="badge-chip">Society of Will Writers member</span>
            : <img className="trust-badge" src={BADGE} alt="Member of the Society of Will Writers" loading="lazy" referrerPolicy="no-referrer" onError={() => setBadgeFail(true)} />}
          <span className="tl">Member of the Society of Will Writers</span>
        </div>
        <div className="trust-item">
          <span className="trust-ic"><Icon name="will" /></span>
          <span className="tl">Bound by their Code of Practice</span>
        </div>
        <div className="trust-item">
          <span className="trust-ic"><Icon name="clock" /></span>
          <span className="tl">Over 25 years’ experience</span>
        </div>
        <div className="trust-item">
          <span className="trust-ic"><Icon name="shield" /></span>
          <span className="tl">Fully insured</span>
        </div>
        <div className="trust-item">
          <span className="trust-ic"><Icon name="home" /></span>
          <span className="tl">Free home visits, evenings and weekends</span>
        </div>
      </div>
    </section>
  );
}

/* ============================================================ SERVICES (ivory) */
const SERVICES = [
  { icon: "will", t: "Wills", b: "A clear, properly drafted Will tailored to you, so your wishes are followed and your family is protected." },
  { icon: "lpa", t: "Lasting Powers of Attorney", b: "Choose who can act for you, for finances and for health, if you ever cannot act for yourself." },
  { icon: "home", t: "Property Trust and Home Protection", b: "Protect your share of the home for the people you choose." },
  { icon: "sever", t: "Severance of Joint Tenancy", b: "Change how your home is owned so each share can be left as you wish." },
  { icon: "trust", t: "Trusts", b: "Protect an inheritance for children or anyone who cannot manage it themselves." },
  { icon: "iht", t: "Inheritance Tax planning", b: "Sensible, qualified advice to reduce what the taxman takes." },
];
function Services() {
  return (
    <section className="section bg-ivory texture" id="services">
      <div className="wrap">
        <div className="svc-head-row reveal">
          <div className="why-head" style={{ marginBottom: 0 }}>
            <p className="eyebrow">What we do</p>
            <h2 className="serif">Everything in one careful conversation.</h2>
            <p className="lede">One visit covers the documents most Essex families need, explained in plain English with no jargon and no pressure.</p>
          </div>
          <WaxSeal className="svc-seal" />
        </div>
        <div className="svc-grid">
          {SERVICES.map((c, n) => (
            <div className="vcard reveal" key={n} style={{ transitionDelay: `${(n % 3) * 80}ms` }}>
              <div className="vi" aria-hidden="true"><Icon name={c.icon} /></div>
              <h3 className="serif">{c.t}</h3>
              <p>{c.b}</p>
            </div>
          ))}
          <div className="vcard reveal">
            <div className="vi" aria-hidden="true"><Icon name="shield" /></div>
            <h3 className="serif">We can act as your executor too</h3>
            <p>If you would rather not burden family, we can carry out your wishes for you.</p>
          </div>
        </div>
      </div>
    </section>
  );
}

/* ============================================================ WHICH WILL (Q&A accordion) */
const QA = [
  { q: "I am married or have a partner", a: "Mirror Wills leave everything to each other, then to your children or chosen people. If you are not married, your partner has no automatic right to inherit, so a Will matters even more." },
  { q: "I have young children", a: "Your Will names legal guardians for your children. Without one, a court decides who raises them. A trust can also hold any inheritance until they are old enough." },
  { q: "I own my home", a: "You can protect your share of the home for your children, so it is not entirely lost to future care fees or a new marriage. This usually means a property trust and severing the joint tenancy." },
  { q: "I have a blended family or stepchildren", a: "An ordinary Will can accidentally cut out your own children. A trust lets you provide for a new partner during their lifetime while protecting your children’s inheritance." },
  { q: "Someone who will inherit is vulnerable or disabled", a: "A trust within your Will protects their inheritance and can avoid affecting means-tested benefits." },
  { q: "What happens if I die without a Will?", a: "The rules of intestacy decide who inherits, which may not be who you would choose, and an unmarried partner can receive nothing." },
  { q: "Do I also need a Power of Attorney?", a: "A Will takes effect after death. An LPA covers you while you are alive but unable to decide for yourself. Most people set up both." },
];
function QARow({ item, idx, open, onToggle }) {
  const panelId = `qa-panel-${idx}`;
  const btnId = `qa-btn-${idx}`;
  return (
    <div className={`qa-row ${open ? "open" : ""}`}>
      <h3 className="qa-q">
        <button id={btnId} type="button" aria-expanded={open} aria-controls={panelId} onClick={onToggle}>
          <span>{item.q}</span>
          <span className="qa-plus" aria-hidden="true"></span>
        </button>
      </h3>
      <div id={panelId} role="region" aria-labelledby={btnId} className="qa-panel" hidden={!open}>
        <p>{item.a}</p>
      </div>
    </div>
  );
}
function WhichWill() {
  const [open, setOpen] = useState(0);
  const cols = [QA.slice(0, 4), QA.slice(4)];
  let running = -1;
  return (
    <section className="section bg-cloud" id="which-will">
      <div className="wrap">
        <div className="why-head reveal" style={{ marginBottom: 40 }}>
          <p className="eyebrow">Plain English</p>
          <h2 className="serif">Which Will might you need?</h2>
          <p className="lede">
            Most people are not sure where they stand. Here are the situations we help with most.
            There is no obligation, and the first visit is free.
          </p>
        </div>
        <div className="qa-grid reveal">
          {cols.map((col, ci) => (
            <div className="qa-col" key={ci}>
              {col.map((item) => {
                running += 1;
                const idx = running;
                return (
                  <QARow key={idx} item={item} idx={idx} open={open === idx}
                    onToggle={() => setOpen(open === idx ? -1 : idx)} />
                );
              })}
            </div>
          ))}
        </div>
        <div className="qa-cta reveal">
          <p className="serif">Not sure which fits you?</p>
          <a className="btn btn-amber" href="#contact">Book a free home visit and we will talk it through</a>
        </div>
      </div>
    </section>
  );
}

/* ============================================================ WE COME TO YOU (light, 2-col + image) */
const STEPS = [
  { n: "1", t: "A free visit", b: "We come to your home, daytime, evening or weekend, with no obligation." },
  { n: "2", t: "A careful conversation", b: "We listen, advise on every option, and keep it private." },
  { n: "3", t: "Drafted and checked", b: "Your documents are prepared, explained, and signed correctly." },
];
function ComeToYou() {
  return (
    <section className="section bg-cloud" id="visit">
      <div className="wrap comeyou-grid">
        <div className="comeyou-text reveal">
          <p className="eyebrow">We come to you</p>
          <h2 className="comeyou-tagline serif">
            An hour of your time now can prevent years of grief and considerable expense for <em>your loved ones.</em>
          </h2>
          <p className="lede" style={{ marginTop: 18 }}>
            We do the travelling, so you can stay comfortable at your own table. Most of Essex is
            covered, from Southend to Epping, and the first visit is always free.
          </p>
          <ol className="steps-list">
            {STEPS.map((s) => (
              <li className="step-li reveal" key={s.n}>
                <span className="step-num serif" aria-hidden="true">{s.n}</span>
                <div>
                  <h3>{s.t}</h3>
                  <p>{s.b}</p>
                </div>
              </li>
            ))}
          </ol>
          <a className="btn btn-amber" href="#contact" style={{ marginTop: 8 }}>Book a free home visit</a>
        </div>
        <div className="comeyou-media reveal">
          <SmartImage
            className="media-img"
            src="https://images.ctfassets.net/x1xkqhj4w3lh/510cb4bb-1f25-4f3f-89f9-d630ba918368/8338b28966ae2654355bd53504569291/will4.jpg?fm=jpg&w=650&q=80&fl=progressive"
            alt="Will writer visiting a couple at home in Essex"
          />
          {/* TODO PLACEHOLDER: confirm licence or replace with the client's own photo of the adviser. */}
          <div className="media-badge">
            <span className="serif">25+</span>
            <span>years visiting homes across Essex</span>
          </div>
        </div>
      </div>
    </section>
  );
}

/* ============================================================ REVIEWS (cloud) */
const REVIEWS = [
  { q: "Unbeatable service and quality.", who: "Phillip & Jane", town: "Southend" },
  { q: "Had the Will back in a couple of days, nice and easy to understand.", who: "Paul", town: "Epping" },
  { q: "Unbeatable price and quality.", who: "Simon & Susan", town: "Stanford-le-Hope" },
  { q: "Very impressed with the service.", who: "Steven & Julia", town: "Ilford" },
  { q: "Very impressed with the gentleman who came to see us, made it very easy to understand.", who: "Sarah & David", town: "Grays" },
];
function Reviews() {
  return (
    <section className="section bg-cloud" id="reviews">
      <div className="wrap">
        <p className="eyebrow reveal">What clients say</p>
        <h2 className="serif reveal" style={{ fontSize: "clamp(28px,3.8vw,44px)", color: "var(--navy)", maxWidth: "22ch" }}>
          Trusted by families from Southend to Ilford.
        </h2>
        <div className="reviews-grid">
          {REVIEWS.map((r, i) => (
            <figure className="quote reveal" key={i} style={{ transitionDelay: `${(i % 3) * 80}ms`, margin: 0 }}>
              <div className="stars" aria-label="Five out of five">★★★★★</div>
              <div className="mark" aria-hidden="true">“</div>
              <blockquote style={{ margin: 0 }}><p>{r.q}</p></blockquote>
              <figcaption className="who">
                <b>{r.who}</b><span aria-hidden="true">·</span><span>{r.town}</span>
              </figcaption>
            </figure>
          ))}
        </div>
      </div>
    </section>
  );
}

/* ============================================================ FEES (ivory, three cards) */
const FEES = [
  { icon: "home", t: "Free home consultation", b: "We visit you at home, daytime, evening or weekend, with no obligation and no extra cost." },
  { icon: "will", t: "A fixed quote, agreed up front", b: "Every Will is different, so we agree one fixed price at your consultation. No hidden costs." },
  { icon: "shield", t: "Nothing to pay until you are happy", b: "There is no obligation to proceed, and nothing to pay until you are ready to go ahead." },
];
function Fees() {
  return (
    <section className="section bg-ivory fees-cert" id="fees">
      <div className="wrap">
        <div className="why-head reveal" style={{ marginBottom: 44 }}>
          <p className="eyebrow">Clear fixed fees</p>
          <h2 className="serif">You will know the cost before any work begins.</h2>
          <p className="lede">
            Every Will is different, so we agree a fixed price with you at your free consultation.
            No hidden costs, nothing to pay until you are happy to go ahead.
          </p>
        </div>
        <div className="svc-grid">
          {FEES.map((c, n) => (
            <div className="vcard reveal" key={n} style={{ transitionDelay: `${n * 80}ms` }}>
              <div className="vi" aria-hidden="true"><Icon name={c.icon} /></div>
              <h3 className="serif">{c.t}</h3>
              <p>{c.b}</p>
            </div>
          ))}
        </div>
        {/* TODO: the client has no published prices. Drop in the real fixed prices here once supplied. */}
        <div className="guarantee reveal">
          <Seal className="guarantee-seal" color="var(--amber)" />
          <div className="guarantee-body">
            <p className="guarantee-line">Your fixed quote, agreed and put in writing.</p>
            <p className="guarantee-sub">Nothing to pay until you are happy to go ahead. That is our promise to every Essex family.</p>
            <span className="signature">The Essex Will Company</span>
          </div>
        </div>
      </div>
    </section>
  );
}

/* ============================================================ CONTACT (navy) */
function Contact() {
  const [form, setForm] = useState({ name: "", email: "", mobile: "", message: "" });
  const [errors, setErrors] = useState({});
  const [sent, setSent] = useState(false);
  const upd = (k) => (e) => setForm((f) => ({ ...f, [k]: e.target.value }));

  const validate = () => {
    const er = {};
    if (!form.name.trim()) er.name = "Please tell us your name.";
    if (!form.email.trim() && !form.mobile.trim()) {
      er.email = "Please leave an email or a mobile number.";
    } else if (form.email.trim() && !/^[^\s@]+@[^\s@]+\.[^\s@]+$/.test(form.email)) {
      er.email = "That email address doesn’t look right.";
    }
    return er;
  };

  const submit = (e) => {
    e.preventDefault();
    const er = validate();
    setErrors(er);
    if (Object.keys(er).length) return;
    // TODO: wire to a real endpoint or info@essexwills.com
    setSent(true);
  };

  return (
    <section className="section bg-cloud contact" id="contact">
      <Estuary className="contact-estuary" />
      <div className="wrap contact-grid">
        <div className="reveal">
          <p className="eyebrow">Get in touch</p>
          <h2 className="serif" style={{ color: "var(--navy)", fontSize: "clamp(30px,4vw,46px)" }}>Arrange your free home visit.</h2>
          <p className="lede">
            Call <a href="tel:01702891821" style={{ color: "var(--amber)", textDecoration: "none", fontWeight: 600 }}>01702&nbsp;891821</a>,
            or send a message and we will call you back to arrange a time that suits you,
            daytime, evening or weekend.
          </p>

          {sent ? (
            <div className="sent" role="status" style={{ marginTop: 30 }}>
              <strong>Thank you, {form.name.split(" ")[0] || "and speak soon"}.</strong>
              <p>We have your message and will call you back shortly to arrange your free home visit.</p>
            </div>
          ) : (
            <form className="form" onSubmit={submit} noValidate>
              <div className={`field ${errors.name ? "invalid" : ""}`}>
                <label htmlFor="cn">Your name</label>
                <input id="cn" type="text" value={form.name} onChange={upd("name")} placeholder="First and last name" autoComplete="name" />
                {errors.name && <span className="err">{errors.name}</span>}
              </div>
              <div className="form-row">
                <div className={`field ${errors.email ? "invalid" : ""}`}>
                  <label htmlFor="ce">Email</label>
                  <input id="ce" type="email" value={form.email} onChange={upd("email")} placeholder="you@example.com" autoComplete="email" />
                  {errors.email && <span className="err">{errors.email}</span>}
                </div>
                <div className="field">
                  <label htmlFor="cm">Mobile</label>
                  <input id="cm" type="tel" value={form.mobile} onChange={upd("mobile")} placeholder="07…" autoComplete="tel" />
                </div>
              </div>
              <div className="field">
                <label htmlFor="cmsg">Message</label>
                <textarea id="cmsg" rows="4" value={form.message} onChange={upd("message")} placeholder="A little about what you need, and the best time to reach you." />
              </div>
              <div>
                <button type="submit" className="btn btn-amber">Request my call back</button>
              </div>
            </form>
          )}
        </div>

        <aside className="contact-info reveal">
          <h3 className="serif">The Essex Will Company Ltd</h3>
          <div className="info-row"><span className="il">Visit</span><span className="iv">23 Crouch Ave, Hullbridge,<br />Essex, SS5 6BS</span></div>
          <div className="info-row"><span className="il">Call</span><span className="iv"><a href="tel:01702891821">01702&nbsp;891821</a></span></div>
          <div className="info-row"><span className="il">Email</span><span className="iv"><a href="mailto:info@essexwills.com">info@essexwills.com</a></span></div>
          <div className="info-row"><span className="il">Hours</span><span className="iv">Daytime, evening &amp; weekend visits</span></div>

          <iframe
            className="contact-map"
            src="https://maps.google.com/maps?q=Hullbridge%2C%20Essex%20SS5%206BS&output=embed"
            loading="lazy"
            title="The Essex Will Company location, Hullbridge, Essex"
          ></iframe>

          <p className="areas">
            Serving Southend, Rochford, Rayleigh, Basildon, Chelmsford, Epping, Grays, Ilford and all of Essex.
          </p>

          <SmartImage
            className="essex-accent"
            src="https://i2-prod.essexlive.news/article9206179.ece/ALTERNATES/s1200f/0_WhatsApp-Image-2024-04-04-at-22523-PM-1jpeg.jpg"
            alt="The Essex coast near Southend"
          />
          {/* TODO replace with a properly licensed Essex image. */}
        </aside>
      </div>
    </section>
  );
}

/* ============================================================ FOOTER */
function Footer() {
  return (
    <footer className="footer">
      <Seal className="footer-watermark" color="var(--amber)" />
      <div className="wrap">
        <div className="footer-grid">
          <div>
            <Brand />
            <p className="footer-bio">
              The Essex Will Company Ltd. Home-visit Will writers based in Hullbridge,
              serving families across the whole of Essex.
            </p>
          </div>
          <div>
            <h4>Contact</h4>
            <p>23 Crouch Ave, Hullbridge,<br />Essex, SS5 6BS</p>
            <p><a href="tel:01702891821">01702&nbsp;891821</a><br /><a href="mailto:info@essexwills.com">info@essexwills.com</a></p>
          </div>
          <div>
            <h4>Areas served</h4>
            <p className="footer-areas">
              Southend · Rochford · Rayleigh · Basildon · Chelmsford · Epping · Grays · Ilford · all of Essex
            </p>
          </div>
        </div>
        <div className="footer-bottom">
          <span className="cred">
            <Seal className="cred-seal" color="var(--amber-bright)" />
            Member of the Society of Will Writers. Fully insured.
          </span>
          <span>
            © {new Date().getFullYear()} The Essex Will Company Ltd ·{" "}
            <a href="#top">Privacy policy</a>
          </span>
        </div>
      </div>
    </footer>
  );
}

/* ============================================================ APP */
function App() {
  const ref = useReveal();
  return (
    <div ref={ref}>
      <Header />
      <main>
        <Hero />
        <Curve from="var(--navy)" to="var(--ivory)" />
        <TrustStrip />
        <WhichWill />
        <Curve from="var(--cloud)" to="var(--ivory)" flip />
        <Services />
        <Slant from="var(--ivory)" to="var(--cloud)" />
        <ComeToYou />
        <Reviews />
        <Slant from="var(--cloud)" to="var(--ivory)" flip />
        <Fees />
        <Curve from="var(--ivory)" to="var(--cloud)" flip />
        <Contact />
        <Curve from="var(--cloud)" to="var(--navy)" />
      </main>
      <Footer />
    </div>
  );
}

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