// Permit Nav marketing site — shared chrome: Icon, Reveal, Header, BetaSignup, Footer.
// Exported to window so every page script can use them.
const S = window.PermitNavDesignSystem_779430;

// Round every icon tile site-wide: default the DS tile radius to a full circle.
// (Callers can still pass an explicit `radius` to opt out.)
if (S && S.IconTile && !S.__roundTiles) {
  const _IconTile = S.IconTile;
  S.IconTile = (props) => React.createElement(_IconTile, { radius: 'var(--radius-full)', ...props });
  S.__roundTiles = true;
}

function Icon({ n, size = 18, color, style }) {
  return <i data-lucide={n} style={{ width: size, height: size, display: 'inline-flex', color, ...style }}></i>;
}

// ---- Shared photo library (verified Unsplash IDs) ----
const IMG = {
  heroHome: '1568605114967-8130f3a36994', // west-coast modern home, warm dusk
  modernDusk: '1600585154340-be6161a56a0c', // architectural home at dusk
  craftsman: '1572120360610-d971b9d7767c', // craftsman porch home
  whiteHeritage: '1570129477492-45c003edd2be', // classic white heritage house
  redRoof: '1576941089067-2de3c901e126', // white house, red roof, gardens
  suburb: '1592595896551-12b371d546d5', // suburban home + path
  bigHouse: '1605276374104-dee2a0ed3cd6', // larger suburban house
  glassHouse: '1512917774080-9991f1c4c750', // modern glass house
  interior: '1600607687939-ce8a6c25118c', // modern interior
  brickModern: '1600047509807-ba8f99d2cdde', // red-brick modern home
  forest: '1441974231531-c6227db76b6e', // tall forest trees
  aerial: '1500382017468-9049fed747ef', // aerial landscape (drone)
  sketch: '1558655146-9f40138edfeb', // design sketches / wireframes
  blueprints: '1503387762-592deb58ef4e', // hands drawing on plans
  construction: '1541888946425-d81bb19240f5', // construction site, crew
  heroPeople: '1733146670084-d52c6b201806' // family standing in front of their home
};
function img(id, w = 1600, q = 80, crop) {
  if (typeof window !== 'undefined' && window.__resources && window.__resources[id]) return window.__resources[id];
  const key = IMG[id] || id;
  const cropPart = crop ? `&crop=${crop}` : '';
  return `https://images.unsplash.com/photo-${key}?auto=format&fit=crop${cropPart}&w=${w}&q=${q}`;
}

// Photo: cover-fit image with optional gradient scrim + rounded corners.
function Photo({ id, w = 1600, alt = '', radius = 'var(--radius-2xl)', scrim, ratio, style, className, crop }) {
  return (
    <div className={className} style={{ position: 'relative', overflow: 'hidden', borderRadius: radius, aspectRatio: ratio, background: 'var(--surface-muted)', ...style }}>
      <img src={img(id, w, 80, crop)} alt={alt} loading="lazy" style={{ width: '100%', height: '100%', objectFit: 'cover', display: 'block' }} />
      {scrim ? <div style={{ position: 'absolute', inset: 0, background: scrim }}></div> : null}
    </div>);

}

// Re-render Lucide glyphs after React commits.
function useLucide() {
  React.useEffect(() => {if (window.lucide) window.lucide.createIcons();});
}

// useReveal is a no-op kept for backwards compatibility; Reveal manages itself.
function useReveal() {}

// Self-contained scroll-reveal. Owns its visibility through React state so a
// re-render can never strip an imperatively-added class. Falls back to visible
// if observation isn't available.
function Reveal({ children, delay, as = 'div', className = '', style }) {
  const Tag = as;
  const ref = React.useRef(null);
  const [shown, setShown] = React.useState(false);
  React.useEffect(() => {
    if (shown) return;
    const el = ref.current;
    if (!el) return;
    function check() {
      const vh = window.innerHeight || document.documentElement.clientHeight;
      const r = el.getBoundingClientRect();
      if (r.top < vh * 0.92 && r.bottom > 0) {setShown(true);return true;}
      return false;
    }
    if (check()) return;
    const t1 = setTimeout(check, 140);
    const t2 = setTimeout(check, 520);
    window.addEventListener('scroll', check, { passive: true });
    window.addEventListener('resize', check);
    return () => {
      clearTimeout(t1);clearTimeout(t2);
      window.removeEventListener('scroll', check);
      window.removeEventListener('resize', check);
    };
  }, [shown]);
  const d = delay ? ` reveal-d${delay}` : '';
  return <Tag ref={ref} className={`reveal${d}${shown ? ' is-visible' : ''} ${className}`} style={style}>{children}</Tag>;
}

const PAGES = [
{ label: 'Home', href: 'Home.html' },
{ label: 'How It Works', href: 'How%20It%20Works.html' },
{ label: 'Our Story', href: 'About.html' }];


// Open the shared beta modal from anywhere (any page, any button).
window.openBetaModal = function () {window.dispatchEvent(new CustomEvent('pn-open-beta'));};

// The five Metro Vancouver municipalities Permit Nav covers today.
const MUNICIPALITIES = [
{ name: 'City of Vancouver', mark: 'VAN' },
{ name: 'City of North Vancouver', mark: 'CNV' },
{ name: 'District of North Vancouver', mark: 'DNV' },
{ name: 'District of West Vancouver', mark: 'WV' },
{ name: 'City of Burnaby', mark: 'BBY' }];


// ── Site-wide beta modal ───────────────────────────────────
// Listens for the global 'pn-open-beta' event so every "Join the beta"
// button across the site opens this one form. Submits to the Permit Nav
// dashboard API (/api/forms/beta-signup), which stores signups in our DB.
const SIGNUP_ENDPOINT = 'https://dashboard-permitnav.vercel.app/api/forms/beta-signup';
function BetaModal() {
  const { Input, Button } = S;
  const [open, setOpen] = React.useState(false);
  const [firstName, setFirstName] = React.useState('');
  const [city, setCity] = React.useState(MUNICIPALITIES[0].name);
  const [email, setEmail] = React.useState('');
  const [role, setRole] = React.useState('homeowner');
  const [message, setMessage] = React.useState('');
  const [botField, setBotField] = React.useState('');
  const [toast, setToast] = React.useState(false);
  const [toastName, setToastName] = React.useState('');
  const [err, setErr] = React.useState('');

  React.useEffect(() => {
    function onOpen() {setOpen(true);}
    window.addEventListener('pn-open-beta', onOpen);
    return () => window.removeEventListener('pn-open-beta', onOpen);
  }, []);

  React.useEffect(() => {
    function onKey(e) {if (e.key === 'Escape') setOpen(false);}
    if (open) {document.addEventListener('keydown', onKey);document.body.style.overflow = 'hidden';}
    return () => {document.removeEventListener('keydown', onKey);document.body.style.overflow = '';};
  }, [open]);

  React.useEffect(() => {if ((open || toast) && window.lucide) window.lucide.createIcons();});

  React.useEffect(() => {
    if (!toast) return undefined;
    const t = setTimeout(() => setToast(false), 6000);
    return () => clearTimeout(t);
  }, [toast]);

  const roles = [
  { id: 'homeowner', label: 'Homeowner', icon: 'home' },
  { id: 'contractor', label: 'Contractor', icon: 'hard-hat' },
  { id: 'trades', label: 'Trades', icon: 'wrench' },
  { id: 'other', label: 'Other', icon: 'user' }];

  const cities = [...MUNICIPALITIES.map((m) => m.name), 'Other / not listed'];
  const emailOk = /^[^\s@]+@[^\s@]+\.[^\s@]+$/.test(email.trim());

  function submit(e) {
    if (e) e.preventDefault();
    if (!firstName.trim()) {setErr('Please enter your first name.');return;}
    if (!emailOk) {setErr('Enter a valid email address.');return;}
    setErr('');
    const payload = { firstName: firstName.trim(), city, email: email.trim(), role, message: message.trim(), source: 'permitnav.ca', 'bot-field': botField };
    fetch(SIGNUP_ENDPOINT, { method: 'POST', headers: { 'Content-Type': 'application/json' }, body: JSON.stringify(payload) }).
    then(() => {}).catch(() => {});
    setToastName(firstName.trim());
    setOpen(false);
    setToast(true);
    setFirstName('');setEmail('');setRole('homeowner');setCity(MUNICIPALITIES[0].name);setMessage('');setBotField('');
  }

  const pill = { display: 'inline-flex', alignItems: 'center', gap: 7, padding: '5px 11px', borderRadius: 'var(--radius-full)', background: 'var(--blue-50)', color: 'var(--blue-700)', fontSize: 12, fontWeight: 700, letterSpacing: '.06em', textTransform: 'uppercase' };

  return (
    <React.Fragment>
    {toast ?
      <div className="pn-toast" role="status">
        <span className="pn-toast__icon"><Icon n="check" size={18} /></span>
        <div className="pn-toast__body">
          <div className="pn-toast__title">Thanks{toastName ? ', ' + toastName : ''} &mdash; you&rsquo;re on the list.</div>
          <div className="pn-toast__sub">We&rsquo;ll reach out as beta seats open in your area.</div>
        </div>
        <button className="pn-toast__close" onClick={() => setToast(false)} aria-label="Dismiss"><Icon n="x" size={16} /></button>
      </div> : null}
    {open ?
      <div className="pn-modal-scrim" onMouseDown={(e) => {if (e.target === e.currentTarget) setOpen(false);}}>
      <div className="pn-modal" role="dialog" aria-modal="true" aria-label="Join the beta">
        <button className="pn-modal-close" onClick={() => setOpen(false)} aria-label="Close"><Icon n="x" size={18} /></button>
        <React.Fragment>
            <span style={pill}><Icon n="sparkles" size={13} /> Early access &middot; Metro Vancouver</span>
            <h3 style={{ fontFamily: 'var(--font-display)', fontWeight: 800, fontSize: 'clamp(23px,3.2vw,28px)', color: 'var(--ink-900)', margin: '10px 0 6px', letterSpacing: '-.02em' }}>Join the free beta.</h3>
            <p style={{ fontSize: 14.5, color: 'var(--ink-500)', lineHeight: 1.45, margin: '0 0 16px' }}>We'll only contact you for early access and product research. We are real people and we want to work together.

          </p>
            <form onSubmit={submit} name="beta-signup" method="POST">
              <div style={{ marginBottom: 12 }}>
                <label className="pn-field-label">I&rsquo;m a&hellip;</label>
                <div className="pn-role-grid">
                  {roles.map((r) =>
                  <button type="button" key={r.id} className={`pn-role-btn${role === r.id ? ' is-sel' : ''}`} onClick={() => setRole(r.id)}>
                      <Icon n={r.icon} size={15} /> {r.label}
                    </button>
                  )}
                </div>
              </div>
              <div style={{ marginBottom: 12 }}>
                <label className="pn-field-label" htmlFor="bn-first">First name</label>
                <Input id="bn-first" name="firstName" value={firstName} invalid={!!err && !firstName.trim()} onChange={(e) => {setFirstName(e.target.value);setErr('');}} placeholder="Jordan" iconLeft={<Icon n="user" size={18} />} />
              </div>
              <div style={{ marginBottom: 12 }}>
                <label className="pn-field-label" htmlFor="bn-city">Your city</label>
                <select id="bn-city" name="city" className="pn-select" value={city} onChange={(e) => setCity(e.target.value)}>
                  {cities.map((c) => <option key={c} value={c}>{c}</option>)}
                </select>
              </div>
              <div style={{ marginBottom: 4 }}>
                <label className="pn-field-label" htmlFor="bn-email">Email</label>
                <Input id="bn-email" name="email" type="email" value={email} invalid={!!err && !emailOk} onChange={(e) => {setEmail(e.target.value);setErr('');}} placeholder="you@email.com" iconLeft={<Icon n="mail" size={18} />} />
              </div>
              <div style={{ marginTop: 12, marginBottom: 4 }}>
                <label className="pn-field-label" htmlFor="bn-message">Anything you&rsquo;d like us to know? <span style={{ color: 'var(--ink-400)', fontWeight: 400 }}>(optional)</span></label>
                <textarea id="bn-message" name="message" className="pn-select" rows={3} value={message} onChange={(e) => setMessage(e.target.value)} placeholder="Your project, timeline, or a question&hellip;" style={{ resize: 'vertical', minHeight: 76, fontFamily: 'inherit', lineHeight: 1.45 }} />
              </div>
              <p style={{ display: 'none' }} aria-hidden="true"><label>Don&rsquo;t fill this out: <input name="bot-field" tabIndex={-1} autoComplete="off" value={botField} onChange={(e) => setBotField(e.target.value)} /></label></p>
              {err ? <div style={{ color: 'var(--red-600)', fontSize: 13, marginTop: 10, fontWeight: 600 }}>{err}</div> : null}
              <div style={{ marginTop: 16 }}>
                <Button className="pn-sweep" variant="primary" size="lg" type="submit" fullWidth iconRight={<Icon n="arrow-right" size={18} />}>Submit</Button>
              </div>
              <p style={{ fontSize: 11.5, lineHeight: 1.45, color: 'var(--ink-400)', textAlign: 'center', margin: '10px auto 0', maxWidth: 360 }}>
                By signing up, you agree to our <a href="Privacy%20Policy.html" style={{ color: 'var(--ink-500)', fontWeight: 600, textDecoration: 'underline' }}>Privacy Policy</a> and consent to receive Permit Nav updates.
              </p>
            </form>
          </React.Fragment>
      </div>
    </div> : null}
    </React.Fragment>);

}

function Header({ active = 'Home' }) {
  const { NavItem, Badge, Button } = S;
  const [menuOpen, setMenuOpen] = React.useState(false);
  React.useEffect(() => {if (window.lucide) window.lucide.createIcons();});
  React.useEffect(() => {
    function onResize() {if (window.innerWidth > 760) setMenuOpen(false);}
    window.addEventListener('resize', onResize);
    return () => window.removeEventListener('resize', onResize);
  }, []);
  return (
    <React.Fragment>
    <BetaModal />
    <header style={{
        position: 'sticky', top: 0, zIndex: 40, background: 'rgba(255,255,255,0.88)',
        backdropFilter: 'saturate(180%) blur(10px)', WebkitBackdropFilter: 'saturate(180%) blur(10px)',
        borderBottom: '1px solid var(--border)'
      }}>
      <div className="pn-container" style={{ display: 'flex', alignItems: 'center', gap: 24, paddingTop: 12, paddingBottom: 12 }}>
        <a href="Home.html" style={{ display: 'flex', alignItems: 'center', gap: 10, flex: '0 0 auto' }}>
          <img src={window.__resources && window.__resources.logoMark || 'assets/logo-mark.png'} alt="Permit Nav" style={{ width: 32, height: 32, objectFit: 'contain', display: 'block' }} />
          <span style={{ fontFamily: 'var(--font-display)', fontWeight: 800, fontSize: 20, color: 'var(--ink-900)', letterSpacing: '-.01em' }}>Permit Nav</span>
        </a>
        <nav className="pn-nav-links" style={{ display: 'flex', alignItems: 'center', gap: 4, flex: '1 1 auto' }}>
          {PAGES.map((p) =>
            <NavItem key={p.label} as="a" href={p.href} active={p.label === active} className={p.label === active ? 'pn-navitem pn-navitem--active' : 'pn-navitem'}>{p.label}</NavItem>
            )}
        </nav>
        <div style={{ flex: '1 1 auto' }} className="pn-nav-spacer"></div>
        <span className="pn-nav-cta">
          <Button className="pn-sweep" variant="primary" size="sm" onClick={() => window.openBetaModal()} iconRight={<Icon n="arrow-right" size={15} />}>Join the beta</Button>
        </span>
        <button className="pn-burger" aria-label="Menu" aria-expanded={menuOpen} onClick={() => setMenuOpen((o) => !o)}>
          <Icon n={menuOpen ? 'x' : 'menu'} size={24} />
        </button>
      </div>
      {menuOpen ?
        <nav className="pn-mobile-menu">
        {PAGES.map((p) =>
          <a key={p.label} href={p.href} className={`pn-mobile-link${p.label === active ? ' is-active' : ''}`}>{p.label}</a>
          )}
        <a href="Privacy%20Policy.html" className="pn-mobile-link">Privacy Policy</a>
        <Button className="pn-sweep" variant="primary" size="lg" fullWidth onClick={() => {setMenuOpen(false);window.openBetaModal();}} iconRight={<Icon n="arrow-right" size={18} />}>Join the beta</Button>
      </nav> : null}
    </header>
    </React.Fragment>);

}

// Dark CTA band — a single "Join the beta" button that opens the shared modal.
function BetaSignup({ id = 'beta' }) {
  const { Button } = S;
  return (
    <section id={id} style={{ background: 'var(--surface-dark)' }}>
      <div className="pn-container" style={{ padding: '92px 32px', textAlign: 'center', maxWidth: 720 }}>
        <Reveal>
          <span style={{ display: 'inline-flex', alignItems: 'center', gap: 8, padding: '6px 13px', borderRadius: 'var(--radius-full)', background: 'rgba(255,255,255,0.08)', border: '1px solid rgba(255,255,255,0.16)', color: 'var(--blue-300)', fontSize: 13, fontWeight: 700, letterSpacing: '.06em', textTransform: 'uppercase' }}>
            <Icon n="sparkles" size={14} /> Early access &middot; Metro Vancouver
          </span>
          <h2 className="pn-h2" style={{ color: '#fff', fontSize: 'clamp(32px,4vw,52px)', margin: '20px 0 14px' }}>
            Join the free beta.
          </h2>
          <p style={{ fontSize: 18, color: 'var(--text-on-dark-muted)', margin: '0 auto 30px', maxWidth: 540, lineHeight: 1.5 }}>Get early access and test new features by signing up to our beta mailing list. You won't receive any spam - just a chance to be part of something great.  

          </p>
          <Button className="pn-sweep" variant="primary" size="lg" onClick={() => window.openBetaModal()} iconRight={<Icon n="arrow-right" size={18} />}>Join the beta</Button>
          <div style={{ display: 'flex', gap: 22, justifyContent: 'center', flexWrap: 'wrap', marginTop: 24 }}>
            {['Help shape the product', 'Be first in your city'].map((c) =>
            <span key={c} style={{ display: 'inline-flex', alignItems: 'center', gap: 7, color: 'var(--text-on-dark-muted)', fontSize: "15px" }}>
                <span style={{ color: 'var(--blue-400)', display: 'inline-flex' }}><Icon n="check" size={15} /></span>{c}
              </span>
            )}
          </div>
        </Reveal>
      </div>
    </section>);

}

function Footer() {
  return (
    <footer style={{ background: '#161C26', borderTop: '1px solid rgba(255,255,255,0.08)' }}>
      <div className="pn-container" style={{ padding: '52px 32px 40px' }}>
        <div style={{ display: 'flex', flexWrap: 'wrap', gap: 40, justifyContent: 'space-between', alignItems: 'flex-start' }}>
          <div style={{ maxWidth: 320 }}>
            <div style={{ display: 'flex', alignItems: 'center', gap: 10, marginBottom: 14 }}>
              <img src={window.__resources && window.__resources.logoMark || 'assets/logo-mark.png'} alt="" style={{ width: 30, height: 30, objectFit: 'contain' }} />
              <span style={{ fontFamily: 'var(--font-display)', fontWeight: 800, fontSize: 19, color: '#fff' }}>Permit Nav</span>
            </div>
            <p style={{ color: 'var(--text-on-dark-muted)', lineHeight: 1.5, margin: 0, fontSize: "16px" }}>Permits made simple.</p>
          </div>
          <div style={{ display: 'flex', gap: 64, flexWrap: 'wrap' }}>
            <div>
              <div style={{ color: 'var(--ink-400)', fontSize: 12.5, fontWeight: 700, letterSpacing: '.08em', textTransform: 'uppercase', marginBottom: 14 }}>Site</div>
              <div style={{ display: 'flex', flexDirection: 'column', gap: 11 }}>
                {PAGES.map((p) => <a key={p.label} href={p.href} className="pn-foot-link">{p.label}</a>)}
                <a href="Privacy%20Policy.html" className="pn-foot-link">Privacy Policy</a>
              </div>
            </div>
          </div>
        </div>
        <div style={{ marginTop: 44, paddingTop: 22, borderTop: '1px solid rgba(255,255,255,0.08)', display: 'flex', justifyContent: 'space-between', flexWrap: 'wrap', gap: 14 }}>
          <span style={{ color: 'var(--text-on-dark-muted)', fontSize: 14 }}>Questions? Email us at info@permitnav.ca</span>
          <span style={{ color: 'var(--ink-400)', fontSize: 13.5 }}>© 2026 Permit Nav · Early access · Metro Vancouver, BC</span>
        </div>
      </div>
    </footer>);

}

Object.assign(window, { Icon, useLucide, useReveal, Reveal, Header, BetaModal, BetaSignup, Footer, Photo, PN_IMG: IMG, pnImg: img, PN_PAGES: PAGES, PN_MUNICIPALITIES: MUNICIPALITIES });