const { useState, useEffect, useRef, useCallback, useMemo } = React;

// ─── Router (hash-based) ─────────────────────────────────────────────
const useHashRoute = () => {
  const [hash, setHash] = useState(() => window.location.hash.slice(1) || "/");
  useEffect(() => {
    const on = () => {
      setHash(window.location.hash.slice(1) || "/");
      window.scrollTo({ top: 0, behavior: "instant" });
    };
    window.addEventListener("hashchange", on);
    return () => window.removeEventListener("hashchange", on);
  }, []);
  return hash;
};
const navigate = (path) => { window.location.hash = path; };

const Link = ({ to, children, className = "", ...rest }) => (
  <a
    href={`#${to}`}
    onClick={(e) => {
      // let modifier-clicks behave normally
      if (e.metaKey || e.ctrlKey || e.shiftKey) return;
      e.preventDefault();
      if (window.location.hash === `#${to}`) {
        window.scrollTo({ top: 0, behavior: "smooth" });
      } else {
        navigate(to);
      }
    }}
    className={className}
    {...rest}
  >
    {children}
  </a>
);

// ─── Wordmark ────────────────────────────────────────────────────────
const Wordmark = ({ className = "", color = "#2C3E50", small = false }) => (
  <Link to="/" className={`inline-flex items-center ${className}`} aria-label="Chris' Craft home">
    <img
      src="/logo.png"
      alt="Chris' Craft Custom Framing"
      style={{ height: small ? 30 : 40, width: "auto", display: "block" }}
    />
  </Link>
);

// ─── Eyebrow ─────────────────────────────────────────────────────────
const Eyebrow = ({ children, className = "", as: As = "div" }) => (
  <As className={`eyebrow text-navy/80 ${className}`}>{children}</As>
);

// ─── Button ──────────────────────────────────────────────────────────
const Button = ({ children, variant = "primary", href, to, onClick, className = "", small = false, ...rest }) => {
  const base = `inline-flex items-center justify-center gap-2 font-sans font-medium transition-all duration-200 ${small ? "px-5 py-2.5 text-[13px]" : "px-7 py-3.5 text-[14px]"} tracking-[0.08em] uppercase`;
  const styles = {
    primary: "bg-navy text-bg hover:bg-navy-d",
    ghost:   "border border-navy text-navy hover:bg-navy hover:text-bg",
    light:   "border border-white/40 text-white hover:bg-white hover:text-navy",
  }[variant];
  const cls = `${base} ${styles} ${className}`;
  if (to) return <Link to={to} className={cls} {...rest}>{children}</Link>;
  if (href) return <a href={href} className={cls} {...rest}>{children}</a>;
  return <button onClick={onClick} className={cls} {...rest}>{children}</button>;
};

// ─── Utility bar ─────────────────────────────────────────────────────
const UtilityBar = () => (
  <div className="bg-navy text-bg/85 text-[11px]">
    <div className="max-w-wide mx-auto px-5 lg:px-10 h-8 flex items-center justify-between tracking-[0.18em] uppercase">
      <div className="hidden sm:block">Dallas · Park Cities · Since {BIZ.established}</div>
      <div className="sm:hidden">Park Cities · Since {BIZ.established}</div>
      <div className="flex items-center gap-5">
        <a href={BIZ.phoneHref} className="hover:text-white">{BIZ.phone}</a>
        <span className="hidden md:inline opacity-40">·</span>
        <a href={BIZ.instagram} target="_blank" rel="noreferrer" className="hidden md:inline hover:text-white">Instagram</a>
      </div>
    </div>
  </div>
);

// ─── Navbar ──────────────────────────────────────────────────────────
const NAV_ITEMS = [
  { to: "/our-craft", label: "Our Craft" },
  { to: "/behind-the-frame", label: "Behind the Frame" },
  { to: "/reviews", label: "Reviews" },
  { to: "visualizer", label: "Visualizer", external: true },
  { to: "/get-in-touch", label: "Visit" },
];

const Navbar = () => {
  const route = useHashRoute();
  const [scrolled, setScrolled] = useState(false);
  const [open, setOpen] = useState(false);
  useEffect(() => {
    const on = () => setScrolled(window.scrollY > 8);
    on();
    window.addEventListener("scroll", on, { passive: true });
    return () => window.removeEventListener("scroll", on);
  }, []);
  useEffect(() => { setOpen(false); }, [route]);

  return (
    <>
      <UtilityBar />
      <header
        className={`sticky top-0 z-40 transition-all duration-300 ${
          scrolled ? "bg-bg/95 backdrop-blur-md border-b border-hairline" : "bg-bg"
        }`}
      >
        <div className="max-w-wide mx-auto px-5 lg:px-10 h-[78px] flex items-center justify-between">
          <Wordmark />
          <nav className="hidden lg:flex items-center gap-9">
            {NAV_ITEMS.map((it) => {
              const active = route === it.to;
              if (it.external) return (
                <a
                  key={it.to}
                  href={`/${it.to}.html`}
                  className="text-[13px] tracking-[0.04em] transition-colors text-body hover:text-navy"
                >{it.label}</a>
              );
              return (
                <Link
                  key={it.to}
                  to={it.to}
                  className={`text-[13px] tracking-[0.04em] transition-colors ${active ? "text-navy" : "text-body hover:text-navy"}`}
                >
                  <span className="relative">
                    {it.label}
                    <span
                      className="absolute -bottom-1.5 left-0 right-0 h-px bg-navy origin-left transition-transform duration-300"
                      style={{ transform: active ? "scaleX(1)" : "scaleX(0)" }}
                    />
                  </span>
                </Link>
              );
            })}
            <Button to="/get-in-touch" small className="ml-2">Book a Consultation</Button>
          </nav>
          <button
            className="lg:hidden h-10 w-10 flex flex-col items-center justify-center gap-1.5"
            onClick={() => setOpen((o) => !o)}
            aria-label="Menu"
          >
            <span className={`block h-px w-6 bg-navy transition-transform ${open ? "translate-y-[6px] rotate-45" : ""}`}></span>
            <span className={`block h-px w-6 bg-navy transition-opacity ${open ? "opacity-0" : ""}`}></span>
            <span className={`block h-px w-6 bg-navy transition-transform ${open ? "-translate-y-[6px] -rotate-45" : ""}`}></span>
          </button>
        </div>
        {/* mobile drawer */}
        <div
          className={`lg:hidden overflow-hidden transition-[max-height] duration-500 ease-out bg-bg border-b border-hairline ${open ? "max-h-[600px]" : "max-h-0"}`}
        >
          <div className="px-6 py-6 flex flex-col gap-1">
            {NAV_ITEMS.map((it) => (
              <Link key={it.to} to={it.to} className="font-display italic text-2xl text-navy py-3 border-b border-hairline">{it.label}</Link>
            ))}
            <div className="pt-5">
              <Button to="/get-in-touch" small className="w-full">Book a Consultation</Button>
            </div>
            <div className="pt-6 text-xs tracking-[0.18em] uppercase text-muted">
              <a href={BIZ.phoneHref} className="block py-1">{BIZ.phone}</a>
              <a href={BIZ.instagram} target="_blank" rel="noreferrer" className="block py-1">Instagram</a>
            </div>
          </div>
        </div>
      </header>
    </>
  );
};

// ─── Footer ──────────────────────────────────────────────────────────
const Footer = () => (
  <footer className="bg-navy text-bg/85 mt-24">
    <div className="max-w-wide mx-auto px-5 lg:px-10 py-20">
      <div className="grid md:grid-cols-12 gap-12">
        <div className="md:col-span-5">
          <div className="font-display italic text-bg text-4xl md:text-5xl leading-[1.1]">
            Chris' Craft
          </div>
          <div className="mt-3 eyebrow text-bg/60">Custom Framing · Park Cities · Since {BIZ.established}</div>
          <p className="mt-8 text-bg/70 max-w-md leading-relaxed text-[15px]">
            A neighborhood framer in the heart of Dallas — woman-owned, engineering-precise, and proudly carrying forward a 45-year tradition.
          </p>
          <div className="mt-8 flex gap-3">
            <a href={BIZ.instagram} target="_blank" rel="noreferrer" className="h-10 w-10 grid place-items-center border border-bg/30 hover:bg-bg hover:text-navy transition-colors" aria-label="Instagram">
              <svg width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="1.5"><rect x="3" y="3" width="18" height="18" rx="4"/><circle cx="12" cy="12" r="4"/><circle cx="17.5" cy="6.5" r="1" fill="currentColor"/></svg>
            </a>
            <a href={BIZ.facebook} target="_blank" rel="noreferrer" className="h-10 w-10 grid place-items-center border border-bg/30 hover:bg-bg hover:text-navy transition-colors" aria-label="Facebook">
              <svg width="16" height="16" viewBox="0 0 24 24" fill="currentColor"><path d="M13 22v-9h3l.5-4H13V6.5c0-1.2.3-2 2-2H17V1.1C16.6 1 15.5 1 14.3 1 11.7 1 10 2.6 10 5.7V9H7v4h3v9h3z"/></svg>
            </a>
          </div>
        </div>

        <div className="md:col-span-2">
          <Eyebrow className="text-bg/55 mb-5">Sitemap</Eyebrow>
          <ul className="space-y-3 text-[14px]">
            <li><Link to="/" className="hover:text-white">Home</Link></li>
            <li><Link to="/our-craft" className="hover:text-white">Our Craft</Link></li>
            <li><Link to="/behind-the-frame" className="hover:text-white">Behind the Frame</Link></li>
            <li><Link to="/reviews" className="hover:text-white">Reviews</Link></li>
            <li><Link to="/get-in-touch" className="hover:text-white">Visit</Link></li>
          </ul>
        </div>

        <div className="md:col-span-2">
          <Eyebrow className="text-bg/55 mb-5">Visit</Eyebrow>
          <address className="not-italic text-[14px] leading-relaxed text-bg/75">
            {BIZ.address1}<br/>{BIZ.address2}
          </address>
          <div className="mt-4 text-[14px]"><a href={BIZ.phoneHref} className="hover:text-white">{BIZ.phone}</a></div>
          <div className="text-[14px]"><a href={BIZ.emailHref} className="hover:text-white">{BIZ.email}</a></div>
        </div>

        <div className="md:col-span-3">
          <Eyebrow className="text-bg/55 mb-5">Hours</Eyebrow>
          <table className="text-[13.5px] text-bg/75">
            <tbody>
              {BIZ.hours.map(([d, h]) => (
                <tr key={d}>
                  <td className="pr-6 py-1">{d}</td>
                  <td className={`py-1 ${h === "Closed" ? "text-bg/40" : ""}`}>{h}</td>
                </tr>
              ))}
            </tbody>
          </table>
        </div>
      </div>

      <div className="mt-16 pt-8 border-t border-bg/15 flex flex-col md:flex-row justify-between gap-4 text-[12px] text-bg/50">
        <div>© {new Date().getFullYear()} Chris' Craft Custom Framing. All rights reserved.</div>
        <div className="tracking-[0.18em] uppercase">Framing that will last a lifetime.</div>
      </div>
    </div>
  </footer>
);

// ─── Reveal-on-scroll wrapper ────────────────────────────────────────
const Reveal = ({ children, delay = 0, y = 18, className = "", as: As = "div" }) => {
  const ref = useRef(null);
  const [shown, setShown] = useState(false);
  useEffect(() => {
    const el = ref.current;
    if (!el) return;
    const io = new IntersectionObserver(
      (entries) => {
        entries.forEach((e) => { if (e.isIntersecting) { setShown(true); io.disconnect(); } });
      },
      { threshold: 0.12 }
    );
    io.observe(el);
    return () => io.disconnect();
  }, []);
  return (
    <As
      ref={ref}
      className={className}
      style={{
        opacity: shown ? 1 : 0,
        transform: shown ? "translateY(0)" : `translateY(${y}px)`,
        transition: `opacity .8s ease ${delay}ms, transform .8s cubic-bezier(.2,.7,.2,1) ${delay}ms`,
      }}
    >
      {children}
    </As>
  );
};

// ─── Lightbox ────────────────────────────────────────────────────────
const Lightbox = ({ images, index, onClose, onPrev, onNext }) => {
  useEffect(() => {
    if (index == null) return;
    const onKey = (e) => {
      if (e.key === "Escape") onClose();
      if (e.key === "ArrowLeft") onPrev();
      if (e.key === "ArrowRight") onNext();
    };
    window.addEventListener("keydown", onKey);
    document.body.style.overflow = "hidden";
    return () => {
      window.removeEventListener("keydown", onKey);
      document.body.style.overflow = "";
    };
  }, [index, onClose, onPrev, onNext]);

  // Touch swipe
  const touchRef = useRef({ x: 0 });
  if (index == null) return null;
  return (
    <div className="lb-overlay fixed inset-0 z-50 flex items-center justify-center p-4 sm:p-10" onClick={onClose}>
      <button
        className="absolute top-5 right-5 h-11 w-11 text-bg border border-bg/20 hover:bg-bg hover:text-navy grid place-items-center"
        onClick={(e) => { e.stopPropagation(); onClose(); }}
        aria-label="Close"
      >×</button>
      <button
        className="absolute left-3 sm:left-8 top-1/2 -translate-y-1/2 h-11 w-11 text-bg border border-bg/20 hover:bg-bg hover:text-navy grid place-items-center"
        onClick={(e) => { e.stopPropagation(); onPrev(); }}
        aria-label="Previous"
      >‹</button>
      <button
        className="absolute right-3 sm:right-8 top-1/2 -translate-y-1/2 h-11 w-11 text-bg border border-bg/20 hover:bg-bg hover:text-navy grid place-items-center"
        onClick={(e) => { e.stopPropagation(); onNext(); }}
        aria-label="Next"
      >›</button>
      <div
        className="max-w-[1100px] max-h-[85vh] w-full h-full flex items-center justify-center"
        onClick={(e) => e.stopPropagation()}
        onTouchStart={(e) => { touchRef.current.x = e.touches[0].clientX; }}
        onTouchEnd={(e) => {
          const dx = e.changedTouches[0].clientX - touchRef.current.x;
          if (dx > 40) onPrev(); else if (dx < -40) onNext();
        }}
      >
        <img
          src={images[index]}
          alt=""
          className="max-w-full max-h-[85vh] object-contain shadow-2xl"
          style={{ background: "#1A2530" }}
        />
      </div>
      <div className="absolute bottom-5 left-0 right-0 text-center text-bg/60 text-xs tracking-[0.18em] uppercase">
        {index + 1} / {images.length}
      </div>
    </div>
  );
};

const useLightbox = (images) => {
  const [idx, setIdx] = useState(null);
  const open = (i) => setIdx(i);
  const close = () => setIdx(null);
  const prev = () => setIdx((i) => (i - 1 + images.length) % images.length);
  const next = () => setIdx((i) => (i + 1) % images.length);
  const node = <Lightbox images={images} index={idx} onClose={close} onPrev={prev} onNext={next} />;
  return { open, node };
};

// ─── Portfolio Grid (masonry-ish) ────────────────────────────────────
const PortfolioGrid = ({ images, onOpen, columns = 4, gap = "gap-3 md:gap-5" }) => {
  // distribute images into N columns to fake masonry
  const cols = useMemo(() => {
    const c = Array.from({ length: columns }, () => []);
    images.forEach((src, i) => c[i % columns].push({ src, idx: i }));
    return c;
  }, [images, columns]);
  return (
    <div className={`flex ${gap}`}>
      {cols.map((col, ci) => (
        <div key={ci} className={`flex-1 flex flex-col ${gap}`}>
          {col.map(({ src, idx }) => (
            <button
              key={idx}
              className="group block overflow-hidden bg-hairline relative"
              onClick={() => onOpen(idx)}
              aria-label={`Open image ${idx + 1}`}
            >
              <img
                src={src}
                loading="lazy"
                alt=""
                className="block w-full h-auto img-fade group-hover:scale-[1.03] group-hover:opacity-90 transition-all duration-700"
              />
              <span className="absolute inset-0 ring-0 ring-navy/0 group-hover:ring-1 group-hover:ring-navy/10 transition-all"/>
            </button>
          ))}
        </div>
      ))}
    </div>
  );
};

// ─── Quote / Pull quote ──────────────────────────────────────────────
const PullQuote = ({ children, attribution }) => (
  <figure className="my-12 md:my-20 text-center px-4">
    <svg width="36" height="28" viewBox="0 0 36 28" className="mx-auto mb-6 text-sand" fill="currentColor">
      <path d="M0 28V14C0 6 4 1 14 0v6c-5 1-7 4-7 8h7v14H0zm22 0V14c0-8 4-13 14-14v6c-5 1-7 4-7 8h7v14H22z"/>
    </svg>
    <blockquote className="font-display italic text-ink text-2xl md:text-4xl leading-[1.3] max-w-3xl mx-auto" style={{ textWrap: "balance" }}>
      "{children}"
    </blockquote>
    {attribution && (
      <figcaption className="mt-6 eyebrow text-muted">— {attribution}</figcaption>
    )}
  </figure>
);

// ─── Testimonial card ────────────────────────────────────────────────
const TestimonialCard = ({ t, large = false }) => (
  <article className={`bg-surface border border-hairline p-7 md:p-10 flex flex-col ${large ? "" : "h-full"}`}>
    <div className="flex items-center gap-1 mb-6 text-sand" aria-label="5 out of 5 stars">
      {[0,1,2,3,4].map((i) => (
        <svg key={i} width="14" height="14" viewBox="0 0 24 24" fill="currentColor"><path d="M12 2l3 7h7l-5.5 4.5L18 21l-6-4-6 4 1.5-7.5L2 9h7z"/></svg>
      ))}
    </div>
    <blockquote className={`font-display italic text-ink ${large ? "text-xl md:text-2xl" : "text-lg md:text-xl"} leading-[1.5] flex-1`}>
      "{t.quote}"
    </blockquote>
    <div className="mt-8 pt-6 border-t border-hairline">
      <div className="font-display text-ink text-lg" style={{ fontWeight: 500 }}>{t.name}</div>
      <div className="mt-1 eyebrow text-muted">{t.source} · {t.role}</div>
    </div>
  </article>
);

// ─── Section header ──────────────────────────────────────────────────
const PageHeader = ({ eyebrow, italicLead, rest, sub }) => (
  <div className="max-w-wide mx-auto px-5 lg:px-10 pt-16 md:pt-24 pb-12 md:pb-16">
    <Reveal>
      <Eyebrow>{eyebrow}</Eyebrow>
      <h1 className="font-display text-ink mt-5 text-[44px] sm:text-[64px] md:text-[88px] leading-[0.95]" style={{ fontWeight: 400, textWrap: "balance" }}>
        <span className="italic" style={{ fontWeight: 500 }}>{italicLead}</span>{rest && <span> {rest}</span>}
      </h1>
      {sub && (
        <p className="mt-8 max-w-[60ch] text-body text-[17px] leading-[1.75]">{sub}</p>
      )}
    </Reveal>
  </div>
);

// ─── Consultation Form ───────────────────────────────────────────────
const ConsultationForm = ({ compact = false }) => {
  const [state, setState] = useState({ first: "", last: "", email: "", message: "" });
  const [sent, setSent] = useState(false);
  const submit = (e) => {
    e.preventDefault();
    setSent(true);
    setTimeout(() => setSent(false), 4000);
  };
  if (sent) {
    return (
      <div className="border border-navy bg-sand-l/40 p-8 md:p-10">
        <Eyebrow className="text-navy">Sent</Eyebrow>
        <p className="font-display italic text-ink text-2xl md:text-3xl mt-3 leading-tight">Thanks — Maureen will be in touch.</p>
        <p className="mt-4 text-body text-[15px]">We'll reach out within one business day to coordinate a time for your private consultation.</p>
      </div>
    );
  }
  return (
    <form onSubmit={submit} className={`${compact ? "" : "border border-hairline bg-surface p-8 md:p-10"}`}>
      <div className={`grid ${compact ? "" : "gap-x-6 md:grid-cols-2"} gap-y-1`}>
        <label className="block">
          <span className="eyebrow text-muted">First Name</span>
          <input className="field" required value={state.first} onChange={(e) => setState({ ...state, first: e.target.value })} />
        </label>
        <label className="block">
          <span className="eyebrow text-muted">Last Name</span>
          <input className="field" required value={state.last} onChange={(e) => setState({ ...state, last: e.target.value })} />
        </label>
        <label className={`block ${compact ? "" : "md:col-span-2"}`}>
          <span className="eyebrow text-muted">Email</span>
          <input type="email" className="field" required value={state.email} onChange={(e) => setState({ ...state, email: e.target.value })} />
        </label>
        {!compact && (
          <label className="block md:col-span-2">
            <span className="eyebrow text-muted">Tell us about your piece (optional)</span>
            <textarea className="field" rows={3} value={state.message} onChange={(e) => setState({ ...state, message: e.target.value })} />
          </label>
        )}
      </div>
      <div className="mt-6">
        <Button>Request Consultation</Button>
      </div>
    </form>
  );
};

// ─── Inquiry Form (Get in Touch) ─────────────────────────────────────
const InquiryForm = () => {
  const [state, setState] = useState({
    first: "", last: "", email: "", phone: "",
    subject: "Custom Framing", message: "",
  });
  const [sent, setSent] = useState(false);
  const submit = (e) => {
    e.preventDefault();
    setSent(true);
  };
  if (sent) {
    return (
      <div className="border border-navy bg-sand-l/40 p-10">
        <Eyebrow className="text-navy">Message Received</Eyebrow>
        <p className="font-display italic text-ink text-3xl mt-3 leading-tight">Thanks, {state.first || "friend"}.</p>
        <p className="mt-4 text-body">We'll get back to you within one business day. For anything urgent, give us a ring at <a href={BIZ.phoneHref} className="underline">{BIZ.phone}</a>.</p>
      </div>
    );
  }
  return (
    <form onSubmit={submit}>
      <div className="grid md:grid-cols-2 gap-x-6 gap-y-1">
        <label className="block">
          <span className="eyebrow text-muted">First Name</span>
          <input className="field" required value={state.first} onChange={(e) => setState({ ...state, first: e.target.value })} />
        </label>
        <label className="block">
          <span className="eyebrow text-muted">Last Name</span>
          <input className="field" required value={state.last} onChange={(e) => setState({ ...state, last: e.target.value })} />
        </label>
        <label className="block">
          <span className="eyebrow text-muted">Email</span>
          <input type="email" className="field" required value={state.email} onChange={(e) => setState({ ...state, email: e.target.value })} />
        </label>
        <label className="block">
          <span className="eyebrow text-muted">Phone (optional)</span>
          <input className="field" value={state.phone} onChange={(e) => setState({ ...state, phone: e.target.value })} />
        </label>
        <label className="block md:col-span-2">
          <span className="eyebrow text-muted">Subject</span>
          <select className="field" value={state.subject} onChange={(e) => setState({ ...state, subject: e.target.value })}>
            <option>Custom Framing</option>
            <option>Private Consultation</option>
            <option>Business Inquiry</option>
            <option>Other</option>
          </select>
        </label>
        <label className="block md:col-span-2">
          <span className="eyebrow text-muted">Message</span>
          <textarea className="field" rows={5} required value={state.message} onChange={(e) => setState({ ...state, message: e.target.value })} />
        </label>
      </div>
      <div className="mt-8">
        <Button>Send Message</Button>
      </div>
    </form>
  );
};

// ─── Map embed ───────────────────────────────────────────────────────
const MapEmbed = () => (
  <div className="relative bg-sand-l/30 border border-hairline overflow-hidden" style={{ aspectRatio: "16/9" }}>
    <iframe
      title="Chris' Craft on Google Maps"
      src="https://maps.google.com/maps?q=5211%20West%20Lovers%20Lane%20Dallas%20TX%2075209&t=&z=15&ie=UTF8&iwloc=&output=embed"
      width="100%" height="100%"
      style={{ border: 0, filter: "grayscale(0.2) contrast(0.95)" }}
      loading="lazy"
      referrerPolicy="no-referrer-when-downgrade"
    />
  </div>
);

// ─── Section heading utility ─────────────────────────────────────────
const SectionHead = ({ eyebrow, italic, rest, sub, className = "", center = false }) => (
  <div className={`${center ? "text-center mx-auto" : ""} ${className}`}>
    {eyebrow && <Eyebrow>{eyebrow}</Eyebrow>}
    <h2 className="font-display text-ink mt-4 text-3xl sm:text-5xl md:text-6xl leading-[1.02]" style={{ textWrap: "balance", fontWeight: 400 }}>
      <span className="italic" style={{ fontWeight: 500 }}>{italic}</span>{rest && <span> {rest}</span>}
    </h2>
    {sub && <p className={`mt-6 text-body text-[17px] leading-[1.75] ${center ? "max-w-2xl mx-auto" : "max-w-2xl"}`}>{sub}</p>}
  </div>
);

// Export
Object.assign(window, {
  useHashRoute, navigate, Link,
  Wordmark, Eyebrow, Button, Navbar, Footer,
  Reveal, Lightbox, useLightbox, PortfolioGrid,
  PullQuote, TestimonialCard, PageHeader,
  ConsultationForm, InquiryForm, MapEmbed, SectionHead,
});
