// Shared layout: Logo, Nav, Footer, Reveal, helpers const { useEffect, useState, useRef, useMemo, useCallback } = React; // Hash-based router function useHashRoute() { const parse = () => { const h = window.location.hash.replace(/^#\/?/, '') || 'home'; const [path, query] = h.split('?'); return { path: path || 'home', query: query || '' }; }; const [route, setRoute] = useState(parse()); useEffect(() => { const handler = () => { setRoute(parse()); window.scrollTo({ top: 0, behavior: 'instant' }); }; window.addEventListener('hashchange', handler); return () => window.removeEventListener('hashchange', handler); }, []); return route; } function navigate(path) { window.location.hash = '/' + path; } // Logo mark — replicated abstract square (4 panel grid in diamond) function LogoMark({ size = 38, dark = false }) { const ink = dark ? '#F5F1EA' : '#2B1F18'; const sky = '#4A90C7'; const tan = '#C9A97A'; return ( ); } function Wordmark({ dark = false }) { const ink = dark ? '#F5F1EA' : '#2B1F18'; return ( SKY flooring ); } function Nav({ current }) { const [scrolled, setScrolled] = useState(false); const [drawerOpen, setDrawerOpen] = useState(false); useEffect(() => { const onScroll = () => setScrolled(window.scrollY > 12); window.addEventListener('scroll', onScroll, { passive: true }); onScroll(); return () => window.removeEventListener('scroll', onScroll); }, []); useEffect(() => { setDrawerOpen(false); }, [current]); const links = [ { id: 'home', label: 'Home' }, { id: 'services', label: 'Services' }, { id: 'gallery', label: 'Gallery' }, { id: 'about', label: 'About' }, { id: 'contact', label: 'Contact' }, ]; return ( <>
{links.map(l => ( { e.preventDefault(); navigate(l.id); }}>{l.label} ))}
Call for a Free Quote (226) 988-7694
Call for a Free Quote (226) 988-7694 → ); } function Footer() { return ( ); } // Reveal-on-scroll (scroll-listener based; IO unreliable in some iframe contexts) function Reveal({ children, delay = 0, as = 'div', className = '', ...rest }) { const ref = useRef(null); const [shown, setShown] = useState(false); useEffect(() => { const el = ref.current; if (!el) return; let raf = 0; const check = () => { raf = 0; if (!ref.current) return; const r = ref.current.getBoundingClientRect(); const vh = window.innerHeight || document.documentElement.clientHeight; if (r.top < vh - 40 && r.bottom > 0) { setShown(true); cleanup(); } }; const onScroll = () => { if (!raf) raf = requestAnimationFrame(check); }; const cleanup = () => { window.removeEventListener('scroll', onScroll); window.removeEventListener('resize', onScroll); }; window.addEventListener('scroll', onScroll, { passive: true }); window.addEventListener('resize', onScroll); // Initial check (after layout) requestAnimationFrame(check); // Safety fallback — show after 600ms regardless const t = setTimeout(() => setShown(true), 600); return () => { cleanup(); clearTimeout(t); if (raf) cancelAnimationFrame(raf); }; }, []); const Tag = as; return ( {children} ); } // Photo with subtle zoom on scroll function ParallaxPhoto({ src, alt, className = '', style = {}, loading = 'lazy', decoding = 'async' }) { const ref = useRef(null); useEffect(() => { const el = ref.current; if (!el) return; const onScroll = () => { const r = el.getBoundingClientRect(); const vh = window.innerHeight; const p = (r.top + r.height/2 - vh/2) / vh; // -1..1 const y = Math.max(-30, Math.min(30, p * 30)); el.style.setProperty('--py', y + 'px'); }; window.addEventListener('scroll', onScroll, { passive: true }); onScroll(); return () => window.removeEventListener('scroll', onScroll); }, []); return (
{alt}
); } // SVG icons (small set) const Icon = { Plank: () => ( ), Tile: () => ( ), Refresh: () => ( ), Layers: () => ( ), Check: () => ( ), Pin: () => ( ), Star: () => ( ), Quote: () => ( ), }; // Reveal helpers shared window.Sky = { useHashRoute, navigate, Nav, Footer, Reveal, ParallaxPhoto, LogoMark, Wordmark, Icon };