/* Gilman Construction Media — app components */

const TWEAK_DEFAULTS = /*EDITMODE-BEGIN*/{
  "ctaLabel": "Request a Quote",
  "leadershipLayout": "grid",
  "accentBalance": "balanced",
  "heroVariant": "split"
}/*EDITMODE-END*/;

// ---------- helpers ----------
const cls = (...xs) => xs.filter(Boolean).join(" ");

// ---------- Top bar ----------
function TopBar({ route, setRoute, ctaLabel }) {
  const [openMenu, setOpenMenu] = React.useState(null);
  const [mobileOpen, setMobileOpen] = React.useState(false);
  const menuTimer = React.useRef(null);
  const items = [
    { id: "home", label: "Home" },
    { id: "platform", label: "Platform", isMenu: true, base: "platform", children: [
      { id: "platform", label: "AI Software" },
      { id: "platform-timelapse", label: "Timelapse Videos" },
      { id: "platform-cameras", label: "Cameras" },
      { id: "platform-installation", label: "Installation" },
    ]},
    { id: "cases", label: "Case Studies" },
    { id: "about-menu", label: "About", isMenu: true, base: "about", children: [
      { id: "about", label: "Company" },
      { id: "leadership", label: "Leadership" },
    ]},
    { id: "contact", label: "Contact Us" },
  ];
  const openNow = (id) => { clearTimeout(menuTimer.current); setOpenMenu(id); };
  const closeSoon = () => { menuTimer.current = setTimeout(() => setOpenMenu(null), 140); };
  const isChildActive = (i) => i.children.some(c => c.id === route);
  const go = (id) => { setRoute(id); setMobileOpen(false); setOpenMenu(null); };
  React.useEffect(() => {
    document.body.style.overflow = mobileOpen ? "hidden" : "";
    return () => { document.body.style.overflow = ""; };
  }, [mobileOpen]);
  return (
    <header className="topbar">
      <div className="container topbar-inner">
        <a className="brand" href="#home" onClick={(e) => { e.preventDefault(); go("home"); }}>
          <img src={window.__R("assets/logo-horizontal.png")} alt="Gilman Construction Media" />
        </a>
        <nav className="nav">
          {items.map((i) => i.isMenu ? (
            <span key={i.id} className="nav-menu" onMouseEnter={()=>openNow(i.id)} onMouseLeave={closeSoon} style={{position:"relative", display:"inline-block"}}>
              <a href={`#${i.base}`} className={isChildActive(i) ? "active" : ""}
                 onClick={(e)=>{e.preventDefault(); setRoute(i.base);}}
                 style={{display:"inline-flex", alignItems:"center", gap:6}}>
                {i.label}
                <span style={{fontSize:10, transform: openMenu===i.id?"rotate(180deg)":"none", transition:"transform 0.15s"}}>▾</span>
              </a>
              {openMenu===i.id && (
                <div style={{position:"absolute", top:"100%", left:0, marginTop:8, background:"#fff", border:"1px solid var(--rule)", borderRadius:6, boxShadow:"0 12px 32px rgba(12,35,64,0.12)", minWidth:200, padding:"6px 0", zIndex:50}}>
                  {i.children.map(c => (
                    <a key={c.id} href={`#${c.id}`}
                       onClick={(e)=>{e.preventDefault(); setRoute(c.id); setOpenMenu(null);}}
                       style={{display:"block", padding:"10px 18px", fontFamily:"Lato, sans-serif", fontWeight:700, fontSize:13, letterSpacing:"0.06em", textTransform:"uppercase", color: route===c.id?"var(--red)":"var(--navy)", textDecoration:"none"}}>
                      {c.label}
                    </a>
                  ))}
                </div>
              )}
            </span>
          ) : (
            <a key={i.id} href={`#${i.id}`}
               className={route === i.id ? "active" : ""}
               onClick={(e) => { e.preventDefault(); setRoute(i.id); }}>
              {i.label}
            </a>
          ))}
          <a href="https://dashboard.gilmanconstructionmedia.com/" target="_blank" rel="noopener" className="nav-login"
             style={{background: "#c42026", color: "#fff", padding: "12px 18px", fontFamily: "Lato, sans-serif", fontWeight: 800, fontSize: 13, letterSpacing: "0.1em", textTransform: "uppercase", textDecoration: "none", borderRadius: 2}}>
            Client Log In
          </a>
        </nav>
        <button type="button" className="nav-toggle" aria-label="Open menu" aria-expanded={mobileOpen} onClick={() => setMobileOpen(v => !v)}>
          <span /><span /><span />
        </button>
      </div>

      {mobileOpen && (
        <div className="mobile-drawer">
          {items.map((i) => i.isMenu ? (
            <div key={i.id} className="mobile-group">
              <div className="mobile-group-label">{i.label}</div>
              {i.children.map(c => (
                <a key={c.id} href={`#${c.id}`} className={route===c.id ? "active" : ""}
                   onClick={(e)=>{e.preventDefault(); go(c.id);}}>{c.label}</a>
              ))}
            </div>
          ) : (
            <a key={i.id} href={`#${i.id}`} className={"mobile-link" + (route===i.id ? " active" : "")}
               onClick={(e)=>{e.preventDefault(); go(i.id);}}>{i.label}</a>
          ))}
          <a href="https://dashboard.gilmanconstructionmedia.com/" target="_blank" rel="noopener" className="mobile-login">Client Log In</a>
        </div>
      )}
    </header>
  );
}

// ---------- Footer ----------
function Footer({ setRoute, ctaLabel }) {
  return (
    <footer className="footer">
      <div className="container">
        <div className="footer-grid">
          <div className="footer-brand">
            <img src={window.__R("assets/logo-horizontal.png")} alt="Gilman Construction Media" style={{filter: "brightness(0) invert(1)"}} />
            <p>Gilman Construction Media is the leading construction security camera and time lapse system company. We unify jobsite security cameras, drones, and wearables into a single AI-powered construction camera system — so Owners, GCs, and field teams see the same reality, in real time, on every project.</p>
            <div className="socials">
              <a href="https://www.linkedin.com/company/gilmanconstructionmedia/" target="_blank" rel="noopener noreferrer" aria-label="LinkedIn">
                <svg viewBox="0 0 24 24" fill="currentColor" aria-hidden="true"><path d="M4.98 3.5A2.5 2.5 0 1 1 5 8.5a2.5 2.5 0 0 1-.02-5zM3 9h4v12H3zM9 9h3.8v1.7h.05c.53-1 1.83-2.05 3.77-2.05 4.03 0 4.78 2.65 4.78 6.1V21h-4v-5.35c0-1.28-.02-2.92-1.78-2.92-1.78 0-2.05 1.4-2.05 2.83V21H9z"/></svg>
              </a>
              <a href="https://www.instagram.com/gilmanconstructionmedia/" target="_blank" rel="noopener noreferrer" aria-label="Instagram">
                <svg viewBox="0 0 24 24" fill="none" aria-hidden="true"><rect x="3" y="3" width="18" height="18" rx="5" stroke="currentColor" strokeWidth="2"/><circle cx="12" cy="12" r="4" stroke="currentColor" strokeWidth="2"/><circle cx="17.5" cy="6.5" r="1.3" fill="currentColor"/></svg>
              </a>
              <a href="https://www.youtube.com/channel/UCDXQga0QmqslMVDJ5yNQhCA" target="_blank" rel="noopener noreferrer" aria-label="YouTube">
                <svg viewBox="0 0 24 24" fill="currentColor" aria-hidden="true"><path d="M23 12s0-3.13-.4-4.63a2.51 2.51 0 0 0-1.77-1.78C19.34 5.2 12 5.2 12 5.2s-7.34 0-8.83.39a2.51 2.51 0 0 0-1.77 1.78C1 8.87 1 12 1 12s0 3.13.4 4.63a2.51 2.51 0 0 0 1.77 1.78c1.49.39 8.83.39 8.83.39s7.34 0 8.83-.39a2.51 2.51 0 0 0 1.77-1.78C23 15.13 23 12 23 12zM9.75 15.02V8.98L15.5 12z"/></svg>
              </a>
              <a href="https://vimeo.com/gilmanconstructionmedia" target="_blank" rel="noopener noreferrer" aria-label="Vimeo">
                <svg viewBox="0 0 24 24" fill="currentColor" aria-hidden="true"><path d="M22 7.42c-.1 2.14-1.6 5.06-4.49 8.79C14.53 20.1 12 22 9.9 22c-1.3 0-2.4-1.2-3.3-3.6-.6-2.2-1.2-4.4-1.8-6.6-.67-2.4-1.38-3.6-2.15-3.6-.17 0-.75.35-1.75 1.04L0 7.9c1.05-.92 2.08-1.85 3.1-2.78C4.5 3.9 5.55 3.28 6.25 3.22c1.66-.16 2.68.97 3.06 3.4.42 2.62.7 4.25.87 4.89.5 2.26 1.04 3.39 1.64 3.39.46 0 1.16-.73 2.09-2.2.93-1.46 1.43-2.58 1.5-3.34.14-1.36-.4-2.04-1.6-2.04-.57 0-1.15.13-1.75.39 1.16-3.79 3.37-5.63 6.63-5.53 2.42.07 3.56 1.64 3.42 4.7z"/></svg>
              </a>
            </div>
          </div>
          <div>
            <h5>Explore</h5>
            <a href="#platform" onClick={(e)=>{e.preventDefault();setRoute("platform");}}>Platform</a>
            <a href="#about" onClick={(e)=>{e.preventDefault();setRoute("about");}}>About</a>
            <a href="#leadership" onClick={(e)=>{e.preventDefault();setRoute("leadership");}}>Leadership</a>
            <a href="#cases" onClick={(e)=>{e.preventDefault();setRoute("cases");}}>Case Studies</a>
          </div>
          <div>
            <h5>Contact</h5>
            <a href="tel:8337004426">833.700.4426</a>
            <a href="mailto:info@gilmanconstructionmedia.com">info@gilmanconstructionmedia.com</a>
            <a href="#">San Diego, California</a>
            <a href="https://dashboard.gilmanconstructionmedia.com/" target="_blank">Client Log In →</a>
          </div>
          <div>
            <h5>Ready to start?</h5>
            <p style={{color:"rgba(255,255,255,0.75)", fontSize:15, marginBottom:16}}>
              Get a quote for your jobsite security camera system.
            </p>
            <a className="btn btn-primary" href="#contact" onClick={(e)=>{e.preventDefault();setRoute("contact");}}>
              {ctaLabel}
            </a>
          </div>
        </div>
        <div className="footer-bottom">
          <div>© 2026 Gilman Construction Media. All rights reserved.</div>
          <div><a href="#" style={{display:"inline"}}>Privacy Policy</a></div>
        </div>
      </div>
    </footer>
  );
}

// ---------- Hero ----------
function HeroSlideshow() {
  const slides = [
    window.__R("assets/min/hero-la-skyline.jpg"),
    window.__R("assets/min/hero-overhead.jpg"),
    window.__R("assets/min/hero-sunset.jpg"),
    window.__R("assets/min/hero-steel.jpg"),
  ];
  const [idx, setIdx] = React.useState(0);
  React.useEffect(() => {
    const t = setInterval(() => setIdx((i) => (i + 1) % slides.length), 5000);
    return () => clearInterval(t);
  }, []);
  return (
    <div style={{position:"absolute", inset:0, zIndex:0, overflow:"hidden"}}>
      {slides.map((src, i) => (
        <div key={i} style={{position:"absolute", inset:0, backgroundImage:("url(" + src + ")"), backgroundSize:"cover", backgroundPosition:"center", opacity: i === idx ? 1 : 0, transition:"opacity 1.2s ease-in-out"}} />
      ))}
    </div>
  );
}

function Hero({ ctaLabel, setRoute, variant }) {
  if (variant === "variant-b") {
    return (
      <section className="hero variant-b">
        <div className="hero-image" style={{backgroundImage: ("url(" + window.__R("assets/hero-skyline.png") + ")")}} />
        <div className="container" style={{position:"relative", zIndex:3}}>
          <div className="hero-copy" style={{padding: "120px 0"}}>
            <div className="hero-kicker">Project Visibility + Intelligence</div>
            <h1>
              Every jobsite.<br/>
              <span className="accent">One source of truth.</span>
            </h1>
            <p className="hero-sub">
              Cameras, drones, and wearables — unified into a single intelligence layer powered by SentriOS AI.
              See risk before it costs you. Track progress without the noise. Align owners, GCs, and field teams in real time.
            </p>
            <div className="hero-actions">
              <a className="btn btn-primary btn-arrow" href="#contact" onClick={(e)=>{e.preventDefault();setRoute("contact");}}>
                {ctaLabel}
              </a>
              <a className="btn btn-ghost" href="#platform" onClick={(e)=>{e.preventDefault();setRoute("platform");}}>
                See the Platform
              </a>
            </div>
          </div>
        </div>
      </section>
    );
  }
  return (
    <section className="hero hero-split" style={{position:"relative", minHeight:"min(720px, calc(100dvh - 84px))", overflow:"hidden", display:"flex", alignItems:"center", paddingTop:"60px", paddingBottom:"150px", background:"var(--navy)", color:"#fff"}}>
      <HeroSlideshow />
      <div className="hero-fade"
           style={{position:"absolute", inset:0, zIndex:1,
                   background:"linear-gradient(90deg, rgba(12,35,64,0.55) 0%, rgba(12,35,64,0.3) 55%, rgba(12,35,64,0.08) 100%), linear-gradient(180deg, rgba(12,35,64,0.15) 0%, rgba(12,35,64,0.35) 100%)"}} />
      <div className="hero-wedge"
           style={{position:"absolute", top:0, bottom:0, left:0, width:"62%", zIndex:2,
                   background:"linear-gradient(110deg, rgba(12,35,64,0.78) 0%, rgba(12,35,64,0.62) 55%, transparent 100%)",
                   clipPath:"polygon(0 0, 100% 0, 74% 100%, 0 100%)"}} />

      <div className="container hero-split-inner" style={{position:"relative", zIndex:3, width:"100%"}}>
        <div className="hero-copy">
          <div className="hero-kicker" style={{color:"#c42026", fontSize:20, fontWeight:800, letterSpacing:"0.2em", textTransform:"uppercase", fontFamily:"'Lato', sans-serif", display:"inline-flex", alignSelf:"flex-start", marginBottom:28, background:"transparent", padding:0}}>Project Visibility + Intelligence</div>
          <h1 style={{textTransform: "uppercase", fontFamily: "'Open Sans', sans-serif", fontWeight: 700}}>
            Your Vision.<br/>
            <span className="accent">Our Cameras.</span>
          </h1>
          <p className="hero-sub">
            GCM delivers construction cameras, remote security, reality capture, and Agentic AI through one fully managed solution. From site-specific design and installation to ongoing service and support, we make real-time visibility effortless.
          </p>
          <div className="hero-actions">
            <a className="btn btn-primary btn-arrow" href="#contact" onClick={(e)=>{e.preventDefault();setRoute("contact");}}>
              Request a Quote
            </a>
          </div>
        </div>
      </div>
      <StatStrip variant="hero-overlay" />
    </section>
  );
}

// ---------- Stat strip ----------
function StatStrip({ variant }) {
  const stats = [
    { num: "10", unit: "+", label: "Years on Jobsites" },
    { num: "500", unit: "+", label: "Projects Monitored" },
    { num: "24", unit: "/7", label: "AI Agents Watching" },
    { num: "1", unit: "", label: "Unified Source of Truth" },
  ];
  return (
    <div className={"stat-strip" + (variant === "hero-overlay" ? " stat-strip-hero" : "")}>
      <div className="container stat-strip-inner">
        {stats.map((s, i) => (
          <div className="stat" key={i}>
            <div className="stat-num">{s.num}<span className="unit">{s.unit}</span></div>
            <div className="stat-label">{s.label}</div>
          </div>
        ))}
      </div>
    </div>
  );
}

// ---------- Pillars ----------
function Pillars() {
  const pillars = [
    {
      num: "01 / MONITOR",
      title: "See risk before it costs you.",
      body: "Your cameras don't just record — they understand the jobsite. AI agents flag PPE misses, perimeter breaches, odd-hour activity, and unsafe conditions, escalating only the events that put people, schedules, or materials at risk."
    },
    {
      num: "02 / DOCUMENT",
      title: "Verify progress with indisputable recordings.",
      body: "Every pour, delivery, lift, and weather delay is auto-captured and time-stamped. Daily timelapse and milestone documentation turn hours of site walks into minutes of clarity for supers, PMs, and owners."
    },
    {
      num: "03 / DELIVER",
      title: "View every camera on every project in one place.",
      body: "Project visibility starts with a single pane of glass. The GCM Dashboard is built to deliver the right information to the right people at the right time."
    },
  ];
  return (
    <section className="pillars-wrap">
      <div className="container">
        <div className="section-head">
          <div className="eyebrow">What We Deliver</div>
          <h2>Three capabilities that replace a dozen disconnected tools.</h2>
          <p>Every deployment is built on the same foundation — actionable intelligence that moves projects forward without disrupting your teams.</p>
        </div>
        <div className="pillars">
          {pillars.map((p, i) => (
            <div className="pillar" key={i}>
              <div className="pillar-mark" />
              <div className="pillar-num">{p.num}</div>
              <h3>{p.title}</h3>
              <p>{p.body}</p>
            </div>
          ))}
        </div>
      </div>
    </section>
  );
}

// ---------- Split feature ----------
function PlatformFeature({ setRoute }) {
  return (
    <section style={{background: "var(--paper)"}}>
      <div className="container">
        <div className="split">
          <div className="split-img" style={{backgroundImage: ("url(" + window.__R("assets/timelapse-progress.gif") + ")"), backgroundSize: "cover", backgroundPosition: "center"}} aria-label="Construction time lapse — multifamily project progress over months" />
          <div>
            <div className="eyebrow">Construction Time Lapse + Progress</div>
            <h2>Watch the build come to life — and prove every milestone.</h2>
            <p>Construction time lapse is more than a marketing video. Stitched against your schedule, it becomes a permanent record of progress, weather events, and field decisions — ready for your client, your insurer, and every RFI.</p>
            <ul className="checklist">
              <li>Daily, weekly, and full-project time lapse delivered automatically</li>
              <li>Hi-res construction camera footage tied to milestones, weather, and crew</li>
              <li>Managed end-to-end: install, tuning, support, retire</li>
            </ul>
            <a className="btn btn-dark btn-arrow" href="#platform" onClick={(e)=>{e.preventDefault();setRoute("platform");}}>
              Explore the Platform
            </a>
          </div>
        </div>
      </div>
    </section>
  );
}

// ---------- Clients strip ----------
function Clients() {
  const logos = [
    // Row A (top) — slide 1 unchanged, slide 2 swapped with slide 1 bottom row
    { src: window.__R("assets/logos/kaiser.png"), alt: "Kaiser Permanente" },
    { src: window.__R("assets/logos/swinerton.png"), alt: "Swinerton" },
    { src: window.__R("assets/logos/cbre.png"), alt: "CBRE" },
    { src: window.__R("assets/logos/balfour-beatty.png"), alt: "Balfour Beatty" },
    { src: window.__R("assets/logos/dpr.png"), alt: "DPR Construction" },
    { src: window.__R("assets/logos/bomel.jpeg"), alt: "Bomel Construction" },
    { src: window.__R("assets/logos/centerpointe.jpeg"), alt: "CenterPointe CRE" },
    { src: window.__R("assets/logos/overland-ayres.jpg"), alt: "Overland & Ayres" },
    { src: window.__R("assets/logos/lowe.png"), alt: "Lowe" },
    { src: window.__R("assets/logos/ucsd.png"), alt: "UC San Diego" },
    { src: window.__R("assets/logos/starbucks.png"), alt: "Starbucks" },
    { src: window.__R("assets/logos/pwi.png"), alt: "PWI Construction" },
    { src: window.__R("assets/logos/bernards.jpg"), alt: "Bernards" },
    { src: window.__R("assets/logos/erickson-hall.png"), alt: "Erickson-Hall Construction" },
    { src: window.__R("assets/logos/walton.png"), alt: "Walton Construction" },
    // Row B (bottom) — slide 1 swapped with slide 2 top row, slide 2 unchanged
    { src: window.__R("assets/logos/pcl.svg"), alt: "PCL Construction" },
    { src: window.__R("assets/logos/lax.png"), alt: "Los Angeles World Airports" },
    { src: window.__R("assets/logos/hensel-phelps.png"), alt: "Hensel Phelps" },
    { src: window.__R("assets/logos/trammell-crow.jpeg"), alt: "Trammell Crow Company" },
    { src: window.__R("assets/logos/whiting-turner.png"), alt: "Whiting-Turner" },
    { src: window.__R("assets/logos/sdsu.png"), alt: "San Diego State University" },
    { src: window.__R("assets/logos/uw.png"), alt: "University of Washington" },
    { src: window.__R("assets/logos/sdusd.png"), alt: "San Diego Unified School District" },
    { src: window.__R("assets/logos/dallas-isd.png"), alt: "Dallas Independent School District" },
    { src: window.__R("assets/logos/hotel-del.png"), alt: "Hotel del Coronado" },
    { src: window.__R("assets/logos/venetian.png"), alt: "The Venetian Resort Las Vegas" },
    { src: window.__R("assets/logos/lifetime-fitness.png"), alt: "Life Time Fitness" },
    { src: window.__R("assets/logos/arbys.png"), alt: "Arby's" },
    { src: window.__R("assets/logos/les-schwab.png"), alt: "Les Schwab Tires" },
  ];

  // split into two rows; each row rendered TWICE so a -50% translate loops seamlessly.
  const mid = Math.ceil(logos.length / 2);
  const rowA = logos.slice(0, mid);
  const rowB = logos.slice(mid);

  const scrollerRef = React.useRef(null);
  const rafRef = React.useRef(null);
  const pausedRef = React.useRef(false);
  const nudgeRef = React.useRef(null);

  // keep scrollLeft within one copy-width so it loops forever
  const normalize = React.useCallback(() => {
    const el = scrollerRef.current;
    if (!el) return;
    const half = el.scrollWidth / 2;
    if (half <= 0) return;
    if (el.scrollLeft >= half) el.scrollLeft -= half;
    else if (el.scrollLeft < 0) el.scrollLeft += half;
  }, []);

  // continuous slow auto-scroll
  React.useEffect(() => {
    const el = scrollerRef.current;
    if (!el) return;
    if (window.matchMedia && window.matchMedia("(prefers-reduced-motion: reduce)").matches) return;
    let last = performance.now();
    const SPEED = 28; // px per second
    const tick = (now) => {
      const dt = (now - last) / 1000;
      last = now;
      if (!pausedRef.current) {
        el.scrollLeft += SPEED * dt;
        normalize();
      }
      rafRef.current = requestAnimationFrame(tick);
    };
    rafRef.current = requestAnimationFrame(tick);
    return () => cancelAnimationFrame(rafRef.current);
  }, [normalize]);

  // manual arrow nudge (eased), pauses auto briefly
  const nudge = (dir) => {
    const el = scrollerRef.current;
    if (!el) return;
    cancelAnimationFrame(nudgeRef.current);
    pausedRef.current = true;
    const start = el.scrollLeft;
    const dist = dir * el.clientWidth * 0.8;
    const t0 = performance.now();
    const dur = 450;
    const ease = (p) => 1 - Math.pow(1 - p, 3);
    const step = (now) => {
      const p = Math.min(1, (now - t0) / dur);
      el.scrollLeft = start + dist * ease(p);
      normalize();
      if (p < 1) nudgeRef.current = requestAnimationFrame(step);
      else pausedRef.current = false;
    };
    nudgeRef.current = requestAnimationFrame(step);
  };

  const cellStyle = {
    flex: "0 0 auto",
    width: 180,
    height: 80,
    display: "flex",
    alignItems: "center",
    justifyContent: "center",
    padding: "8px 12px",
    overflow: "hidden",
  };
  const imgStyle = {
    maxWidth: "100%",
    maxHeight: 64,
    width: "auto",
    height: "auto",
    objectFit: "contain",
    display: "block",
  };

  const arrowStyle = (side) => ({
    position: "absolute", [side]: -8, top: "50%", transform: "translateY(-50%)",
    zIndex: 3, width: 44, height: 44, borderRadius: "50%",
    background: "#fff", border: "1px solid rgba(12,35,64,0.15)",
    boxShadow: "0 4px 14px rgba(12,35,64,0.12)",
    display: "flex", alignItems: "center", justifyContent: "center",
    cursor: "pointer", padding: 0,
  });

  return (
    <section className="clients">
      <div className="container">
        <h4>Trusted by Industry Leading Developers & Contractors</h4>

        <div
          className="clients-marquee"
        >
          {/* edge fades */}
          <div aria-hidden="true" className="marquee-fade marquee-fade--left" />
          <div aria-hidden="true" className="marquee-fade marquee-fade--right" />

          {/* manual scroll arrows */}
          <button type="button" aria-label="Scroll logos left" onClick={() => nudge(-1)} className="clients-arrow clients-arrow--left" style={arrowStyle("left")}>
            <svg width="18" height="18" viewBox="0 0 24 24" fill="none" aria-hidden="true">
              <path d="M15 6l-6 6 6 6" stroke="#0c2340" strokeWidth="2.25" strokeLinecap="round" strokeLinejoin="round" />
            </svg>
          </button>
          <button type="button" aria-label="Scroll logos right" onClick={() => nudge(1)} className="clients-arrow clients-arrow--right" style={arrowStyle("right")}>
            <svg width="18" height="18" viewBox="0 0 24 24" fill="none" aria-hidden="true">
              <path d="M9 6l6 6-6 6" stroke="#0c2340" strokeWidth="2.25" strokeLinecap="round" strokeLinejoin="round" />
            </svg>
          </button>

          <div ref={scrollerRef} className="clients-scroller">
            <div className="clients-row">
              {[...rowA, ...rowA].map((l, i) => (
                <div className="client-logo" key={"a"+i} style={cellStyle}>
                  <img src={l.src} alt={l.alt} style={imgStyle} />
                </div>
              ))}
            </div>
            <div className="clients-row">
              {[...rowB, ...rowB].map((l, i) => (
                <div className="client-logo" key={"b"+i} style={cellStyle}>
                  <img src={l.src} alt={l.alt} style={imgStyle} />
                </div>
              ))}
            </div>
          </div>
        </div>
      </div>
    </section>
  );
}

// ---------- Testimonials ----------
function Testimonials() {
  const items = [
    {
      quote: "I have enough on my plate trying to get my project built. One phone call to Gilman, and I know my construction cameras are taken care of and my client will be excited to watch their project come to life.",
      name: "Brent Beveroth",
      role: "Project Superintendent",
      client: "Hensel Phelps",
      logo: window.__R("assets/logos/hensel-phelps.png"),
    },
    {
      quote: "Gilman Construction Media is one of our best partners. From project start to finish, they are there for us every step of the way. One of the best calls I ever made.",
      name: "Jason Picasso",
      role: "Construction Manager",
      client: "Trammell Crow Residential",
      logo: window.__R("assets/logos/trammell-crow-res.jpeg"),
    },
    {
      quote: "It's obvious they have a team of people with a ton of real-world construction experience. They see things the way I do, ask the right questions, and they truly understand my projects, my teams, and my needs.",
      name: "Cameron Hawkins",
      role: "Senior Project Manager",
      client: "Walton",
      logo: window.__R("assets/logos/walton.png"),
    },
  ];
  return (
    <section className="testimonials">
      <div className="container">
        <div className="section-head">
          <div className="eyebrow">What They Have to Say</div>
          <h2>Owners, developers, and general contractors on working with Gilman.</h2>
        </div>
        <div className="testimonial-grid">
          {items.map((t, i) => (
            <div className="testimonial" key={i}>
              <blockquote>"{t.quote}"</blockquote>
              <div className="attrib">
                <div>
                  <strong>{t.name}</strong>
                  <span>{t.role}</span>
                </div>
                <div className="client-tag" style={{display:"flex", alignItems:"center", justifyContent:"flex-start", height:40, maxWidth:140}}>
                  {t.logo
                    ? <img src={t.logo} alt={t.client} style={{maxHeight:36, maxWidth:140, width:"auto", height:"auto", objectFit:"contain", display:"block"}} />
                    : t.client}
                </div>
              </div>
            </div>
          ))}
        </div>
      </div>
    </section>
  );
}

// ---------- CTA band ----------
function CtaBand({ ctaLabel, setRoute }) {
  return (
    <section className="cta-band tight">
      <div className="container">
        <div className="cta-inner">
          <div>
            <div className="eyebrow" style={{color: "#e86a6f"}}>Your Next Project</div>
            <h2>Let's build a visual source of truth together.</h2>
            <p>Partner with Gilman Construction Media to turn every jobsite into actionable intelligence — safer projects, faster decisions, stronger margins.</p>
          </div>
          <div className="cta-actions">
            <a className="btn btn-primary btn-arrow" href="#contact" onClick={(e)=>{e.preventDefault();setRoute("contact");}}>
              Contact Us
            </a>
            <a className="btn btn-ghost" href="tel:8337004426">Call 833.700.4426</a>
          </div>
        </div>
      </div>
    </section>
  );
}

Object.assign(window, {
  TopBar, Footer, Hero, HeroSlideshow, StatStrip, Pillars, PlatformFeature, Clients, Testimonials, CtaBand, cls
});
