// sections.jsx — shared page sections for Responsive Hauling.
// Uses globals from primitives.jsx (Logo, icons, Btn, SectionHeading, data helpers).

const { useState: useStateSec, useEffect: useEffectSec, useRef: useRefSec } = React;

/* ───────── Utility bar ───────── */
function UtilityBar() {
  const data = getRHData();
  const bookUrl = (data.booking && data.booking.directUrl) || null;
  return (
    <div className="utility">
      <div className="container utility-inner">
        <div className="utility-left">
          <a href={`tel:${data.phoneHref.replace('tel:', '')}`}>
            <IconPhone size={12} /> Call {data.phone}
          </a>{/* label: "Call (510) 244-0285" */}
          <span className="sep hide-sm"></span>
          <a href={data.phoneHref.replace('tel:', 'sms:')} className="hide-sm">Text Us</a>
          <span className="sep hide-sm"></span>
          {bookUrl && <a href={bookUrl} className="hide-sm">Book Online</a>}
          <span className="sep hide-sm"></span>
          <span className="utility-muted hide-sm">Mon&ndash;Sat, 8 AM &ndash; 6 PM</span>
        </div>
        <div className="utility-right">
          <span className="utility-muted hide-sm"><span className="dot"></span> Based in Hayward, CA</span>
        </div>
      </div>
    </div>
  );
}

/* ───────── Nav ───────── */
// Split-parent disclosure: the LABEL is an <a> to the hub page, the CHEVRON is a
// <button aria-expanded> that opens the panel. One tap navigates, the other
// discloses — so touch works without a hover dependency, and the hub page is
// never unreachable. Deliberately NOT role="menu": these are site links.
function NavDisclosure({ id, label, href: hubHref, open, setOpen, children }) {
  const wrapRef = useRefSec(null);
  const closeTimer = useRefSec(null);
  // hover-capable devices open on hover; touch devices open on first tap
  const canHover = typeof window !== 'undefined' && window.matchMedia('(hover: hover)').matches;

  const openNow = () => { clearTimeout(closeTimer.current); setOpen(id); };
  const closeSoon = () => {
    clearTimeout(closeTimer.current);
    closeTimer.current = setTimeout(() => setOpen((cur) => (cur === id ? null : cur)), 180);
  };

  useEffectSec(() => {
    if (!open) return;
    const onDocDown = (e) => {
      if (wrapRef.current && !wrapRef.current.contains(e.target)) setOpen(null);
    };
    const onKey = (e) => { if (e.key === 'Escape') setOpen(null); };
    document.addEventListener('pointerdown', onDocDown);
    document.addEventListener('keydown', onKey);
    return () => {
      document.removeEventListener('pointerdown', onDocDown);
      document.removeEventListener('keydown', onKey);
    };
  }, [open, id, setOpen]);

  return (
    <div
      className={`has-dropdown${open ? ' is-open' : ''}`}
      ref={wrapRef}
      onMouseEnter={canHover ? openNow : undefined}
      onMouseLeave={canHover ? closeSoon : undefined}
    >
      <a
        href={hubHref}
        className="dd-label"
        aria-expanded={open ? 'true' : 'false'}
        aria-controls={`${id}-panel`}
        onClick={(e) => {
          // touch: first tap opens the panel, the panel's own links navigate
          if (!canHover && !open) { e.preventDefault(); setOpen(id); }
        }}
        onKeyDown={(e) => {
          if (e.key === 'ArrowDown') {
            e.preventDefault();
            setOpen(id);
            setTimeout(() => {
              const first = wrapRef.current && wrapRef.current.querySelector('.dropdown-panel a');
              if (first) first.focus();
            }, 0);
          }
        }}
      >{label}</a>
      <div className="dropdown-panel" id={`${id}-panel`} hidden={!open}>
        {children}
      </div>
    </div>
  );
}

function Nav({ active }) {
  const data = getRHData();
  const categories = data.categories;
  const cities = (data.cities || []);
  const [openMenu, setOpenMenu] = useStateSec(null);
  const [mobileOpen, setMobileOpen] = useStateSec(false);
  const [mobileServicesOpen, setMobileServicesOpen] = useStateSec(false);
  const [mobileAreasOpen, setMobileAreasOpen] = useStateSec(false);

  useEffectSec(() => {
    document.body.style.overflow = mobileOpen ? 'hidden' : '';
    return () => { document.body.style.overflow = ''; };
  }, [mobileOpen]);

  return (
    <header className="nav">
      <div className="container nav-inner">
        <Logo size="md" />
        <nav className="nav-links" aria-label="Primary">
          <a href={href('')} className={active === 'home' ? 'active' : ''}>Home</a>

          <NavDisclosure id="services" label="Services" href={href('services')} open={openMenu === 'services'} setOpen={setOpenMenu}>
            <div className="dd-grid dd-grid-3">
              {categories.map((c) => (
                <a key={c.slug} href={href(c.slug)}>
                  <span className="dd-icon"><CategoryIcon name={c.icon} size={17} /></span>
                  {c.label}
                </a>
              ))}
            </div>
            <a href={href('services')} className="dd-foot">View all services <IconArrow size={12} /></a>
          </NavDisclosure>

          <NavDisclosure id="areas" label="Service Areas" href={href('service-areas')} open={openMenu === 'areas'} setOpen={setOpenMenu}>
            <div className="dd-grid dd-grid-3 dd-grid-plain">
              {cities.map((c) => (
                <a key={c} href={href(citySlug(c))}>{c}</a>
              ))}
            </div>
            <a href={href('service-areas')} className="dd-foot">View all service areas <IconArrow size={12} /></a>
          </NavDisclosure>

          <a href={href('how-we-work')} className={active === 'howwework' ? 'active' : ''}>How We Work</a>
          <a href={href('about')} className={active === 'about' ? 'active' : ''}>About</a>
          <a href={href('contact')} className={active === 'contact' ? 'active' : ''}>Contact</a>
        </nav>
        <div className="nav-cta">
          <a href={`tel:${data.phoneHref.replace('tel:', '')}`} className="nav-phone">
            <IconPhone size={14} /> {data.phone}
          </a>
          <BookBtn variant="cta" size="sm" />
          <button
            type="button"
            className={`nav-burger${mobileOpen ? ' is-open' : ''}`}
            aria-label="Toggle menu"
            aria-expanded={mobileOpen}
            onClick={() => setMobileOpen((v) => !v)}
          >
            <span></span>
          </button>
        </div>
      </div>

      <div className={`mobile-menu${mobileOpen ? ' is-open' : ''}`}>
        <a href={href('')}>Home</a>

        <div className="mm-row">
          <a href={href('services')}>Services</a>
          <button type="button" aria-expanded={mobileServicesOpen} aria-label="Expand services"
                  onClick={() => setMobileServicesOpen((v) => !v)}>
            <span className={`mm-plus${mobileServicesOpen ? ' is-open' : ''}`} aria-hidden="true"></span>
          </button>
        </div>
        <div className={`mobile-submenu${mobileServicesOpen ? ' is-open' : ''}`}>
          {categories.map((c) => (<a key={c.slug} href={href(c.slug)}>{c.label}</a>))}
        </div>

        <div className="mm-row">
          <a href={href('service-areas')}>Service Areas</a>
          <button type="button" aria-expanded={mobileAreasOpen} aria-label="Expand service areas"
                  onClick={() => setMobileAreasOpen((v) => !v)}>
            <span className={`mm-plus${mobileAreasOpen ? ' is-open' : ''}`} aria-hidden="true"></span>
          </button>
        </div>
        <div className={`mobile-submenu${mobileAreasOpen ? ' is-open' : ''}`}>
          {cities.map((c) => (<a key={c} href={href(citySlug(c))}>{c}</a>))}
        </div>

        <a href={href('how-we-work')}>How We Work</a>
        <a href={href('about')}>About</a>
        <a href={href('contact')}>Contact</a>
        <div className="mm-cta">
          <Btn href={`tel:${data.phoneHref.replace('tel:', '')}`} variant="outline" arrow={false} icon={<IconPhone size={15} />}>{data.phone}</Btn>
          <BookBtn variant="cta" />
        </div>
      </div>
    </header>
  );
}

/* ───────── Booking (Housecall Pro) — new in v2 ───────── */

// Direct link to Ricardo's real HCP booking page. Used in nav, CTA rows, and the
// mobile bar. Token/orgName come from RH_DATA.booking (read off the live site).
function BookBtn({ variant = 'cta', size, children }) {
  const b = getRHData().booking || {};
  if (!b.directUrl) return null;
  return (
    <Btn href={b.directUrl} variant={variant} size={size}>
      {children || b.ctaLabel || 'Book Online'}
    </Btn>
  );
}

// Call + Book, side by side. Steven's ask: keep the CALL CTA primary, add HCP booking
// alongside it — never instead of it.
function CtaRow({ size = 'lg' }) {
  const data = getRHData();
  return (
    <div className="ctarow">
      <div className="container ctarow-inner">
        <Btn tel={data.phoneHref.replace('tel:', '')} variant="primary" size={size} icon={<IconPhone size={16} />}>
          Call {data.phone}
        </Btn>
        <Btn href={data.phoneHref.replace('tel:', 'sms:')} variant="outline" size={size}>Text Us</Btn>
        <BookBtn variant="cta" size={size}>Book Online</BookBtn>
        <span className="ctarow-note">Free on-site estimate · Mon&ndash;Sat, 8 AM &ndash; 6 PM</span>
      </div>
    </div>
  );
}

// Housecall Pro booking, inline.
//
// NOT their script.js — that one renders a floating button + modal, which is a worse
// experience on a page whose entire job is booking. Instead we iframe the same URL
// their own widget iframes (…/book/<org>/<token>?v2=true, read out of their minified
// source). Verified: 200, and no X-Frame-Options / CSP frame-ancestors, so framing is
// permitted. If the frame is ever blocked, the direct-link fallback is revealed rather
// than leaving the visitor staring at an empty box.
function BookingEmbed() {
  const data = getRHData();
  const b = data.booking || {};
  const [loaded, setLoaded] = useStateSec(false);
  const [failed, setFailed] = useStateSec(false);

  // If nothing has loaded after 8s, treat it as blocked and show the fallback.
  useEffectSec(() => {
    const t = setTimeout(() => { if (!loaded) setFailed(true); }, 8000);
    return () => clearTimeout(t);
  }, [loaded]);

  if (!b.iframeUrl) return null;

  return (
    <div className="booking-embed">
      {!loaded && !failed && <div className="booking-loading">Loading the booking calendar…</div>}
      <iframe
        className={`booking-frame${loaded ? ' is-loaded' : ''}`}
        src={b.iframeUrl}
        title="Book your junk removal, Responsive Hauling"
        loading="lazy"
        onLoad={() => { setLoaded(true); setFailed(false); }}
        allow="payment"
      />
      {failed && !loaded && (
        <div className="booking-fallback">
          <p>The booking calendar didn&rsquo;t load, it may be blocked by a browser extension.</p>
          <BookBtn variant="cta" size="lg">Open the booking page</BookBtn>
        </div>
      )}
      <p className="booking-note">
        Booking is handled by {b.provider || 'our scheduler'}. Prefer the phone? Call{' '}
        <a href={data.phoneHref}>{data.phone}</a>.
      </p>
    </div>
  );
}

/* ───────── Steps band (reusable) ───────── */
function StepsBand() {
  return (
    <section className="section section-alt">
      <div className="container">
        <SectionHeading eyebrow="How it works" title="From call to clean, in 4 steps." />
        <StepsRow compact />
      </div>
    </section>
  );
}

/* ───────── Hero — home variant ───────── */
function HeroHome() {
  const data = getRHData();
  return (
    <section className="hero-home">
      <div className="container hero-grid">
        <div>
          <div className="hero-badge"><span className="pip"></span> Same-day pickups</div>
          <h1 className="h-display h1" style={{ marginTop: 18 }}>
            Big Jobs. One Call. <span className="hi-accent">Gone Today.</span>
          </h1>
          <p className="hero-sub">
            Estate cleanouts, hoarder cleanouts, construction debris, and full-load junk removal
            across Hayward and the East Bay. <strong>Text a photo</strong> and we&rsquo;ll price it on the spot.
          </p>
          <div className="hero-ctas">
            <Btn tel={data.phoneHref.replace('tel:', '')} variant="cta" size="lg" icon={<IconPhone size={16} />}>Call {data.phone}</Btn>
            <Btn href={data.phoneHref.replace('tel:', 'sms:')} variant="outline-light" size="lg">Text a Photo</Btn>
            <BookBtn variant="outline-light" size="lg">Book Online</BookBtn>
          </div>
          <div className="hero-trustline">
            <span><span className="pip"></span> Free on-site estimate</span>
            <span><span className="pip"></span> All-inclusive pricing</span>
            <span><span className="pip"></span> Licensed &amp; insured</span>
          </div>
        </div>
        <div className="hero-visual">
          <img className="hero-ghost" src={imgSrc('Recycle-Icon-2-1920w.png')} alt="" aria-hidden="true" loading="eager" />
          <div className="hero-ground"></div>
          <div className="hero-photo-wrap">
            <img src={imgSrc('truck-loaded-1400w.jpg')} alt="A Responsive Hauling truck loaded on an East Bay job" loading="eager" />
          </div>
          <div className="hero-chip">
            <div className="num">19</div>
            <div className="sub">yards per truck<br />16ft &middot; 8ft &middot; 4ft</div>
          </div>
        </div>
      </div>
      <picture>
        <source srcSet={imgSrc('truck-cutout.webp')} type="image/webp" />
        <img className="hero-road-truck" src={imgSrc('truck-cutout.png')} alt="" aria-hidden="true" loading="eager" />
      </picture>
    </section>
  );
}

/* ───────── Hero — service landing variant ─────────
   Ads land here. Photo-led split hero: the category photo carries the page,
   call/text/book sit above the fold, review numbers give instant proof. */
function HeroService({ category }) {
  const data = getRHData();
  const total = YELP_STATS.count + GOOGLE_STATS.count;
  return (
    <section className="hero-home hero-service">
      <div className="container hero-grid">
        <div>
          <div className="hero-badge"><span className="pip"></span> Same-day pickups</div>
          <h1 className="h-display h1" style={{ marginTop: 16 }}>{category.label}</h1>
          <p className="hero-sub">{category.blurb || `Professional ${category.label.toLowerCase()} across the Bay Area, fast, friendly, and all-inclusive.`}</p>
          <div className="hero-ctas">
            <Btn tel={data.phoneHref.replace('tel:', '')} variant="cta" size="lg" icon={<IconPhone size={16} />}>Call {data.phone}</Btn>
            <Btn href={data.phoneHref.replace('tel:', 'sms:')} variant="outline-light" size="lg">Text a Photo</Btn>
            <BookBtn variant="outline-light" size="lg">Book Online</BookBtn>
          </div>
          <div className="hero-trustline">
            <span><Stars n={5} size={13} /></span>
            <span><strong>5.0</strong>&nbsp;&middot;&nbsp;{total} reviews on Yelp &amp; Google</span>
            <span><span className="pip"></span> Free on-site estimate</span>
          </div>
        </div>
        <div className="hero-visual">
          <div className="hero-photo-wrap hero-photo-service">
            <img src={imgSrc(category.photo || 'truck-loaded-1400w.jpg')} alt={`${category.label}, a real Responsive Hauling job`} loading="eager" />
          </div>
          <div className="hero-chip">
            <div className="num">$0</div>
            <div className="sub">estimate fee<br />no obligation</div>
          </div>
        </div>
      </div>
    </section>
  );
}

/* ───────── Service-area map (SVG, no embed) ─────────
   Pin positions come from real lat/lon projected once — relative geography
   is honest, labelled not-to-scale. Current city highlighted in green. */
function CityMap({ highlight }) {
  const pins = CITY_MAP_PINS;
  const hay = pins.find((p) => p.name === 'Hayward');
  const cur = pins.find((p) => p.name === highlight);
  return (
    <div className="citymap-frame">
      <svg viewBox="0 0 800 520" role="img" aria-label={`Map of the Alameda County service area${highlight ? `, highlighting ${highlight}` : ''}`}>
        <circle cx={hay.x} cy={hay.y} r="90" fill="none" stroke="#2C568F" strokeWidth="1.5" opacity=".5" />
        <circle cx={hay.x} cy={hay.y} r="180" fill="none" stroke="#2C568F" strokeWidth="1.5" opacity=".35" />
        <circle cx={hay.x} cy={hay.y} r="290" fill="none" stroke="#2C568F" strokeWidth="1.5" opacity=".22" />
        {pins.filter((p) => p.name !== 'Hayward').map((p) => (
          <line key={'l' + p.name} x1={hay.x} y1={hay.y} x2={p.x} y2={p.y}
                stroke={p.name === highlight ? '#70D070' : '#3D6FB4'}
                strokeWidth={p.name === highlight ? 2.5 : 1}
                strokeDasharray={p.name === highlight ? 'none' : '4 5'}
                opacity={p.name === highlight ? .9 : .5} />
        ))}
        {pins.map((p) => {
          const isHay = p.name === 'Hayward';
          const isCur = p.name === highlight;
          const anchorEnd = p.x > 640;
          return (
            <g key={p.name}>
              {(isHay || isCur) && <circle cx={p.x} cy={p.y} r="17" fill={isCur && !isHay ? '#70D070' : '#2FA84F'} opacity=".22" />}
              <circle cx={p.x} cy={p.y} r={isHay || isCur ? 9 : 5.5}
                      fill={isCur && !isHay ? '#70D070' : isHay ? '#2FA84F' : '#1E5FBF'}
                      stroke={isHay || isCur ? '#fff' : '#9EC4F5'} strokeWidth={isHay || isCur ? 2.5 : 1.5} />
              <text x={anchorEnd ? p.x - 14 : p.x + 14} y={p.y + 4}
                    fill={isCur ? '#EAFBEC' : isHay ? '#B9E8BE' : '#C7D8F0'}
                    fontFamily="Barlow, sans-serif" fontSize={isHay || isCur ? 16 : 13}
                    fontWeight={isHay || isCur ? 700 : 600}
                    textAnchor={anchorEnd ? 'end' : 'start'}>{p.name}</text>
              {isHay && <text x={p.x + 14} y={p.y + 20} fill="#70D070" fontFamily="Barlow, sans-serif"
                    fontSize="10.5" fontWeight="700" letterSpacing="1.5">HOME BASE</text>}
            </g>
          );
        })}
      </svg>
      <div className="citymap-note">Alameda County &middot; relative positions, not to scale</div>
    </div>
  );
}

/* ───────── Hero — compact variant (subpages) ───────── */
function HeroCompact({ eyebrow, title, sub }) {
  return (
    <section className="hero-compact">
      <div className="container hero-compact-inner">
        {eyebrow && <div className="hero-breadcrumb">{eyebrow}</div>}
        <h1 className="h-display h1">{title}</h1>
        {sub && <p className="hero-sub">{sub}</p>}
      </div>
    </section>
  );
}

/* ───────── USP strip ───────── */
function UspStrip() {
  return (
    <section className="section">
      <div className="container">
                <h2 className="sr-only">Why choose Responsive Hauling</h2>
<div className="usp-grid">
          {USPS.map((u) => (
            <div className="usp-card" key={u.title}>
              <IconChip tone="blue"><u.icon size={22} /></IconChip>
              <h3>{u.title}</h3>
              <p>{u.blurb}</p>
            </div>
          ))}
        </div>
      </div>
    </section>
  );
}

/* ───────── Category grid (8 cards, balanced 4x2 / 2x4) ───────── */
function CategoryGrid({ heading = true }) {
  const data = getRHData();
  return (
    <section className="section section-alt" id="services">
      <div className="container">
        {heading && (
          <SectionHeading
            eyebrow="What we haul"
            title="Name it. We haul it."
            sub="From a single mattress to a full property cleanout, pick your service, or call and we'll sort it out."
          />
        )}
        <div className="category-grid">
          {data.categories.map((c) => (
            <a className={`category-card${c.photo ? ' has-photo' : ''}`} href={href(c.slug)} key={c.slug}>
              {c.photo
                ? <div className="cc-photo"><img src={imgSrc(c.photo)} alt={c.label} loading="lazy" /></div>
                : <IconChip tone="green"><CategoryIcon name={c.icon} size={24} /></IconChip>}
              <h3>{c.label}</h3>
              <p>{c.blurb || 'We load it, haul it, and sweep up after.'}</p>
              <span className="cc-more">What we take <IconArrow size={12} /></span>
            </a>
          ))}
        </div>
      </div>
    </section>
  );
}

/* ───────── Balanced service/related grid (dynamic column count) ───────── */
function ServiceGrid({ items }) {
  const cols = pickGridCols(items.length);
  return (
    <div className={`service-grid cols-${cols}`}>
      {items.map((it) => (
        <a className="service-card-sm" href={href(it.slug)} key={it.slug}>
          <h4>{it.label}</h4>
          <p>{it.paragraphs && it.paragraphs[0] ? it.paragraphs[0].slice(0, 96) + (it.paragraphs[0].length > 96 ? '…' : '') : `Learn more about ${it.label.toLowerCase()}.`}</p>
          <span className="sc-link">View details <IconArrow size={11} /></span>
        </a>
      ))}
    </div>
  );
}

/* ───────── Steps row (teaser or full) ───────── */
function StepsRow({ compact = false, steps = HOW_STEPS }) {
  return (
    <div className={`steps-row${compact ? ' compact' : ''}`}>
      {steps.map((s) => (
        <div className="step-card" key={s.num}>
          <div className="step-num">{s.num}</div>
          <h3>{s.title}</h3>
          <p>{s.blurb}</p>
        </div>
      ))}
    </div>
  );
}

/* ───────── Eco / recycle band ───────── */
function EcoBand() {
  return (
    <section className="eco-band">
      <img className="eco-stencil" src={imgSrc('Recycle-Icon-2-1920w.png')} alt="" aria-hidden="true" loading="lazy" />
      <div className="container eco-inner">
        <div className="eco-media">
          <img src={imgSrc('job-storage-1400w.jpg')} alt="A storage unit emptied and swept by the Responsive Hauling crew" loading="lazy" />
          <div className="eco-badge"><RecycleMark size={16} /> Recycle &amp; donate first</div>
        </div>
        <div>
          <div className="eyebrow on-dark">Where it goes</div>
          <h2 className="h-display h2" style={{ marginTop: 10 }}>We recycle and donate before anything hits a landfill.</h2>
          <p className="lede" style={{ marginTop: 16 }}>
            Every load gets sorted, usable items are donated, recyclables are routed to the right facility, and landfill is always our last resort.
          </p>
        </div>
      </div>
    </section>
  );
}

/* ───────── Before / after gallery ───────── */
function BeforeAfterGallery() {
  return (
    <section className="section">
      <div className="container">
        <SectionHeading
          eyebrow="Job log"
          title="Before we showed up. After we left."
          sub="Three recent jobs. Every one swept before we left."
        />
        <div className="ba-grid">
          {BEFORE_AFTER_PAIRS.map((p, i) => (
            <div className="ba-pair" key={p.label}>
              <div className="ba-plate">JOB {String(i + 1).padStart(2, '0')} &middot; {p.label.toUpperCase()}</div>
              <div className="ba-imgs">
                <figure>
                  <img src={imgSrc(p.before)} alt={`${p.label}, before`} loading="lazy" />
                  <figcaption>Before</figcaption>
                </figure>
                <figure className="after">
                  <img src={imgSrc(p.after)} alt={`${p.label}, after`} loading="lazy" />
                  <figcaption>After</figcaption>
                </figure>
              </div>
            </div>
          ))}
        </div>
      </div>
    </section>
  );
}

/* ───────── Review badges (platform badges — no fabricated quotes) ───────── */
/* ───────── Review badges band — slim, sits under the hero ───────── */
function ReviewBadgesBand() {
  return (
    <div className="badges-band">
      <div className="container review-platforms trust-lift">
        <a className="review-badge" href={SOCIAL_LINKS.yelp} target="_blank" rel="noreferrer">
          <Stars n={5} />
          <span className="rb-name">{YELP_STATS.rating.toFixed(1)} on Yelp &middot; {YELP_STATS.count} reviews</span>
        </a>
        <a className="review-badge" href={SOCIAL_LINKS.google} target="_blank" rel="noreferrer">
          <Stars n={5} />
          <span className="rb-name">{GOOGLE_STATS.rating.toFixed(1)} on Google &middot; {GOOGLE_STATS.count} reviews</span>
        </a>
      </div>
    </div>
  );
}

function ReviewBadges() {
  return (
    <section className="section review-band">
      <div className="container">
        <SectionHeading
          align="center"
          eyebrow="Yelp &amp; Google"
          title={`Five stars. All ${YELP_STATS.count + GOOGLE_STATS.count} of them.`}
          sub={`${YELP_STATS.count} on Yelp. ${GOOGLE_STATS.count} on Google. Read them yourself.`}
        />
      </div>

      <div className="rev-rail-wrap">
        <ul className="rev-rail" tabIndex={0} aria-label="Recent Yelp and Google reviews, scrollable">
          {[...GOOGLE_REVIEWS.map(r => ({...r, src: "Google"})), ...YELP_REVIEWS.map(r => ({...r, src: "Yelp"}))].map((r) => (
            <li className="rev-card" key={r.name + r.date}>
              <Stars n={r.rating} />
              <blockquote>{r.text}</blockquote>
              <footer>
                <span className="rev-who">{r.name}</span>
                <span className="rev-src">{r.src}{r.date ? ` · ${r.date}` : ""}</span>
              </footer>
            </li>
          ))}
          <li className="rev-card rev-card-cta">
            <div className="rev-cta-num">{YELP_STATS.count + GOOGLE_STATS.count}</div>
            <div className="rev-cta-lbl">five-star reviews on Yelp &amp; Google</div>
            <div style={{ display: 'flex', gap: 10 }}>
              <a className="btn btn-cta btn-sm" href={SOCIAL_LINKS.yelp} target="_blank" rel="noreferrer">Yelp</a>
              <a className="btn btn-outline-light btn-sm" href={SOCIAL_LINKS.google} target="_blank" rel="noreferrer">Google</a>
            </div>
          </li>
        </ul>
      </div>
    </section>
  );
}

/* ───────── City chips (12 cities — linked to city pages where one exists) ───────── */
function CityChips({ dark = false }) {
  const data = getRHData();
  const cityPages = (typeof window !== 'undefined' && window.RH_DATA && window.RH_DATA.cityPages) || {};
  return (
    <section className={`section-tight${dark ? '' : ' section-alt'}`}>
      <div className="container">
        <div className="city-label">
          <span className="eyebrow">Service area</span>
          <span className="city-label-note">Alameda County, one Hayward yard. Close by? Call anyway.</span>
        </div>
        <div className="city-grid">
          {data.cities.map((c) => {
            const slug = citySlug(c);
            return cityPages[slug] ? (
              <a className="city-chip city-chip-link" href={href(slug)} key={c}>{c}</a>
            ) : (
              <span className="city-chip" key={c}>{c}</span>
            );
          })}
        </div>
      </div>
    </section>
  );
}

/* ───────── CTA band ───────── */
function CtaBand({ title = "Haul It All With One Call!", sub = "Free estimate, upfront price, no obligation." }) {
  const data = getRHData();
  return (
    <section className="cta-band">
      <div className="container cta-inner">
        <div>
          <h2 className="h-display">{title}</h2>
          <p>{sub}</p>
        </div>
        <div className="cta-actions">
          <Btn tel={data.phoneHref.replace('tel:', '')} variant="cta" size="lg" icon={<IconPhone size={16} />}>{data.phone}</Btn>
          <BookBtn variant="outline-light" size="lg" />
        </div>
      </div>
    </section>
  );
}

/* ───────── Footer ───────── */
function Footer() {
  const data = getRHData();
  return (
    <footer className="footer">
      <div className="container">
        <div className="footer-grid">
          <div>
            <Logo size="lg" />
            <p className="footer-tagline">"Haul it all with one call!" Locally owned, Bay Area operated since 2018.</p>
            <div className="footer-contact">
              <a href={`tel:${data.phoneHref.replace('tel:', '')}`}><IconPhone size={13} /> {data.phone}</a>
              <a href={`mailto:${data.email}`}><IconMail size={13} /> {data.email}</a>
              <span><IconClock size={13} /> Mon&ndash;Sat &middot; 8 AM &ndash; 6 PM</span>
            </div>
            <div className="footer-social">
              <a href={SOCIAL_LINKS.facebook} target="_blank" rel="noreferrer" aria-label="Facebook">
                <svg width="17" height="17" viewBox="0 0 24 24" fill="currentColor" aria-hidden="true"><path d="M13.5 21v-7h2.4l.4-3h-2.8V9.1c0-.9.3-1.5 1.6-1.5h1.3V4.9c-.3 0-1.1-.1-2-.1-2 0-3.4 1.2-3.4 3.5V11H8.5v3H11v7h2.5Z"/></svg>
              </a>
              <a href={SOCIAL_LINKS.instagram} target="_blank" rel="noreferrer" aria-label="Instagram">
                <svg width="17" height="17" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="1.8" aria-hidden="true"><rect x="3.5" y="3.5" width="17" height="17" rx="4.5"/><circle cx="12" cy="12" r="4"/><circle cx="17.2" cy="6.8" r="1.1" fill="currentColor" stroke="none"/></svg>
              </a>
              <a href={SOCIAL_LINKS.yelp} target="_blank" rel="noreferrer" aria-label="Yelp">
                <svg width="17" height="17" viewBox="0 0 24 24" fill="currentColor" aria-hidden="true"><path d="M11.1 3.2c.5-.6 1.5-.3 1.6.5l.5 6.7c.1.8-.9 1.3-1.5.7L7.4 7c-.5-.5-.4-1.3.2-1.6l3.5-2.2ZM17.9 10.5c.8-.2 1.5.6 1.1 1.3l-1.5 2.8c-.4.7-1.4.6-1.7-.1l-.9-2.3c-.3-.7.3-1.4 1-1.3l2-.4ZM16.9 17.2c.7.4.6 1.5-.2 1.7l-3 1c-.8.3-1.5-.5-1.2-1.2l1-2.4c.3-.7 1.2-.9 1.7-.4l1.7 1.3ZM9.5 14.5c.7-.3 1.4.4 1.2 1.1l-1.1 3.8c-.2.8-1.3 1-1.7.2l-1.6-3c-.4-.7.1-1.5.9-1.5l2.3-.6Z"/></svg>
              </a>
              <a href={SOCIAL_LINKS.google} target="_blank" rel="noreferrer" aria-label="Google">
                <svg width="17" height="17" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="1.9" aria-hidden="true"><path d="M20.5 12.2c0-.7-.1-1.2-.2-1.8H12v3.4h4.8a4.2 4.2 0 0 1-1.8 2.8v2.3h2.9c1.7-1.6 2.6-3.9 2.6-6.7Z" fill="currentColor" stroke="none" opacity=".9"/><path d="M12 21c2.4 0 4.5-.8 6-2.2l-2.9-2.3c-.8.6-1.9.9-3.1.9-2.4 0-4.4-1.6-5.1-3.8H3.9v2.4A9 9 0 0 0 12 21Z"/><path d="M6.9 13.6a5.4 5.4 0 0 1 0-3.4V7.8H3.9a9 9 0 0 0 0 8.2l3-2.4Z"/><path d="M12 6.6c1.3 0 2.5.5 3.4 1.4l2.6-2.6A9 9 0 0 0 3.9 7.8l3 2.4c.7-2.2 2.7-3.6 5.1-3.6Z"/></svg>
              </a>
            </div>
          </div>
          <div>
            <h3 className="foot-h">Services</h3>
            <ul>
              {data.categories.slice(0, 6).map((c) => (
                <li key={c.slug}><a href={href(c.slug)}>{c.label}</a></li>
              ))}
            </ul>
          </div>
          <div>
            <h3 className="foot-h">Company</h3>
            <ul>
              <li><a href={href('about')}>About Us</a></li>
              <li><a href={href('how-we-work')}>How We Work</a></li>
              <li><a href={href('contact')}>Contact</a></li>
              <li><a href={href('accessibility-statement')}>Accessibility Statement</a></li>
              <li><a href={href('privacy-policy')}>Privacy Policy</a></li>
              <li><a href={href('terms-of-service')}>Terms of Service</a></li>
            </ul>
          </div>
          <div>
            <h3 className="foot-h">Service Area</h3>
            <div className="footer-cities-list">
              {data.cities.map((c) => (<span key={c}>{c}</span>))}
            </div>
          </div>
        </div>
        <div className="footer-bottom">
          <div>© 2026 Responsive Hauling. All rights reserved.</div>
          <div>Site by 510tech</div>
        </div>
      </div>
    </footer>
  );
}

/* ───────── Mobile call bar ───────── */
function MobileCallBar() {
  const data = getRHData();
  return (
    <div className="mobile-call-bar">
      <Btn tel={data.phoneHref.replace('tel:', '')} variant="primary" arrow={false} icon={<IconPhone size={14} />}>Call (510) 244-0285</Btn>
      <Btn href={data.phoneHref.replace('tel:', 'sms:')} variant="outline" arrow={false}>Text Us</Btn>
      <BookBtn variant="cta" arrow={false}>Book Online</BookBtn>
    </div>
  );
}

Object.assign(window, {
  UtilityBar, Nav, HeroHome, HeroCompact, HeroService, UspStrip, CategoryGrid, ServiceGrid,
  StepsRow, EcoBand, BeforeAfterGallery, ReviewBadges, CityChips, CtaBand,
  Footer, MobileCallBar, BookBtn, CtaRow, BookingEmbed, StepsBand, CityMap
});
