// ===== Mark.jsx ===== // Veradoma viewfinder mark — copied from v1, unchanged glyph. const Mark = ({ size = 24, inverse = false, accent = "#B68A4E", stroke = "#2B2A28", strokeWidth }) => { const sw = strokeWidth ?? (size <= 20 ? 8 : size <= 32 ? 6 : size <= 64 ? 4.5 : 3.5); const fillColor = inverse ? "#D4B07A" : accent; const strokeColor = inverse ? "#F7F4EE" : stroke; return ( ); }; // Tiny outline icon set used across the kit. 1.5px stroke, currentColor. const Icon = ({ name, size = 18 }) => { const common = { width: size, height: size, viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: 1.5, strokeLinecap: "round", strokeLinejoin: "round", "aria-hidden": true }; switch (name) { case "arrow-right": return ; case "arrow-down": return ; case "camera": return ; case "video": return ; case "drone": return ; case "floor-plan": return ; case "globe": return ; case "social": return ; case "clock": return ; case "check": return ; case "instagram": return ; case "phone": return ; case "mail": return ; case "pin": return ; case "menu": return ; case "close": return ; case "facebook": return ; case "linkedin": return ; case "vimeo": return ; default: return null; } }; Object.assign(window, { Mark, Icon }); // ===== Reveal hooks ===== function useReveal() { const ref = React.useRef(null); React.useEffect(() => { const el = ref.current; if (!el) return; const reduce = window.matchMedia("(prefers-reduced-motion: reduce)").matches; if (reduce) { el.classList.add("is-revealed"); return; } const io = new IntersectionObserver(([entry]) => { if (entry.isIntersecting) { el.classList.add("is-revealed"); io.disconnect(); } }, { threshold: 0.15, rootMargin: "-10% 0px -10% 0px" }); io.observe(el); return () => io.disconnect(); }, []); return ref; } function useRevealOnMount(delayMs = 0) { const ref = React.useRef(null); React.useEffect(() => { const el = ref.current; if (!el) return; const reduce = window.matchMedia("(prefers-reduced-motion: reduce)").matches; if (reduce) { el.classList.add("is-revealed"); return; } const id = window.setTimeout(() => { window.requestAnimationFrame(() => el.classList.add("is-revealed")); }, delayMs); return () => window.clearTimeout(id); }, [delayMs]); return ref; } // Smooth-scroll to a same-page anchor while respecting modifier clicks // (Cmd/Ctrl/Shift → open in new tab; middle-click → open in new tab). const smoothNav = (e, id) => { if (e.metaKey || e.ctrlKey || e.shiftKey || e.button !== 0) return; e.preventDefault(); const el = document.getElementById(id); if (el) el.scrollIntoView({ behavior: "smooth", block: "start" }); }; Object.assign(window, { useReveal, useRevealOnMount, smoothNav }); // ===== Spiro booking ===== // bundleIDs verified against the live Spiro order page on 2026-05-18. // To refresh: GET https://order-api.spiro.media/api/bundle/GetBundles?tenantShortCode=veradoma&orderPageCode=veradoma-order-page const SPIRO = { base: "https://book.veradoma.com/order/veradoma/veradoma-order-page", essential: "30c8a7c5-0ded-473f-9d91-9028647b3712", premium: "d79f1eda-9c33-4366-ad2b-b3eb8ab57dab", luxury: "1025fe9b-91df-4f98-8f5a-612b7e32e3c0", }; const spiroLink = (id) => (id ? `${SPIRO.base}/${id}` : SPIRO.base); // ===== Header.jsx ===== const Header = ({ active = "home" }) => { const [scrolled, setScrolled] = React.useState(false); const [menuOpen, setMenuOpen] = React.useState(false); React.useEffect(() => { const onScroll = () => setScrolled(window.scrollY > 80); onScroll(); window.addEventListener("scroll", onScroll, { passive: true }); return () => window.removeEventListener("scroll", onScroll); }, []); const items = [ { id: "work", label: "Work" }, { id: "services", label: "Services" }, { id: "packages", label: "Packages" }, { id: "book", label: "Book" }, ]; const go = (e, id) => { if (e.metaKey || e.ctrlKey || e.shiftKey || e.button !== 0) return; setMenuOpen(false); smoothNav(e, id); }; return (
{ if (e.metaKey || e.ctrlKey || e.shiftKey || e.button !== 0) return; e.preventDefault(); window.scrollTo({ top: 0, behavior: "smooth" }); }}> Veradoma Media Book a shoot
{menuOpen && (
{items.map(it => ( go(e, it.id)}> {it.label} ))} setMenuOpen(false)}> Book a shoot
)}
); }; Object.assign(window, { Header }); // ===== Hero.jsx ===== const Hero = () => { const eyebrowRef = useRevealOnMount(0); const titleRef = useRevealOnMount(60); const leadRef = useRevealOnMount(120); const ctaRef = useRevealOnMount(180); const statsRef = useRevealOnMount(240); const reduce = React.useMemo( () => typeof window !== "undefined" && window.matchMedia?.("(prefers-reduced-motion: reduce)").matches === true, []); // Phones get a muted autoplay loop; desktop scroll-scrubs the timeline. const isMobile = React.useMemo( () => typeof window !== "undefined" && window.matchMedia?.("(max-width: 767px)").matches === true, []); const sectionRef = React.useRef(null); const videoRef = React.useRef(null); // Force muted at attach time. React's `muted` JSX prop doesn't reliably set // the DOM property, and iOS blocks autoplay unless the element is truly muted. const setVideoEl = React.useCallback((el) => { videoRef.current = el; if (el) { el.muted = true; el.defaultMuted = true; } }, []); React.useEffect(() => { if (reduce) return; const video = videoRef.current; const section = sectionRef.current; if (!video || !section) return; // Scrub the day→evening timeline from the scroll position — on mobile too. // The mobile clip (hero-scrub-mobile.mp4) is encoded with every frame as a // keyframe, so iOS can seek it instantly; a normal sparse-keyframe clip // freezes while scrubbing on iOS. Prime first: a muted play()/pause() // unlocks programmatic currentTime updates on iOS. const prime = () => { video.play().then(() => video.pause()).catch(() => {}); }; if (video.readyState >= 1) prime(); else video.addEventListener('loadedmetadata', prime, { once: true }); let rafId = null; let lastT = -1; const update = () => { rafId = null; const rect = section.getBoundingClientRect(); const scrubRange = Math.max(1, rect.height - window.innerHeight); const progress = Math.max(0, Math.min(1, -rect.top / scrubRange)); const dur = video.duration; if (!dur || !isFinite(dur)) return; const t = progress * dur; if (Math.abs(t - lastT) < 0.03) return; lastT = t; video.currentTime = t; }; const onScroll = () => { if (rafId == null) rafId = requestAnimationFrame(update); }; window.addEventListener('scroll', onScroll, { passive: true }); onScroll(); return () => { window.removeEventListener('scroll', onScroll); if (rafId != null) cancelAnimationFrame(rafId); }; }, [reduce]); return (
{reduce ? ( ) : ( )}
Real estate media · Orange County

Cinematic listings,
delivered next morning.

Photo, drone, video, and floor plans. Polished work, predictable turnaround, easy to book.

{[ { v: "24 hr", l: "Gallery turnaround" }, { v: "500+", l: "Listings shot" }, { v: "OC", l: "Orange County" }, ].map(s => (
{s.v}
{s.l}
))}
); }; Object.assign(window, { Hero }); // ===== FeaturedWork.jsx ===== const WORK = [ { id: 1, title: "Bayside Twilight", loc: "Newport Beach", tag: "Twilight", deliverables: "32 photos · drone", turn: "Delivered 24 hr", src: "assets/photos/portfolio-bayside-twilight.png", alt: "Newport Beach waterfront home at twilight" }, { id: 2, title: "Linden Cottage", loc: "Costa Mesa", tag: "Photography", deliverables: "28 photos", turn: "Delivered 24 hr", src: "assets/photos/portfolio-linden-cottage.png", alt: "Costa Mesa cottage at golden hour" }, { id: 3, title: "Ridgeline", loc: "Laguna Beach", tag: "Drone", deliverables: "Aerial stills + 30s clip", turn: "Delivered 24 hr", src: "assets/photos/portfolio-ridgeline-aerial.png", alt: "Aerial view of a Laguna Beach hillside home" }, { id: 4, title: "The Crescent", loc: "Corona del Mar", tag: "Photography", deliverables: "35 photos · floor plan", turn: "Delivered 24 hr", src: "assets/photos/portfolio-the-crescent.png", alt: "Corona del Mar exterior in late-afternoon light" }, { id: 5, title: "Whitewater House", loc: "Laguna Niguel", tag: "Video", deliverables: "60s walkthrough · 30 photos", turn: "Delivered 24 hr", src: "assets/photos/portfolio-whitewater-house.png", alt: "Modern kitchen interior in Laguna Niguel" }, { id: 6, title: "Magnolia Estate", loc: "Newport Coast", tag: "Twilight", deliverables: "50 photos · drone · 3D plan", turn: "Same-day rush", src: "assets/photos/portfolio-magnolia-estate.png", alt: "Newport Coast estate at dusk" }, ]; const WorkCard = ({ work, index }) => { const ref = useReveal(); return (
{work.alt} {work.tag}
{work.loc}

{work.title}

{work.deliverables}
{work.turn}
); }; const FeaturedWork = () => { const headRef = useReveal(); return (
Recent work

From the last few weeks.

{WORK.map((w, i) => )}
); }; Object.assign(window, { FeaturedWork }); // ===== Services.jsx ===== const SERVICES = [ { icon: "camera", name: "Photography", desc: "Interior and exterior, MLS-ready, color-corrected, next morning." }, { icon: "drone", name: "Drone", desc: "FAA-licensed aerial stills and short clips of home + lot." }, { icon: "video", name: "Video", desc: "Gimbal walkthroughs and twilight cinematic edits." }, { icon: "floor-plan", name: "Floor plans", desc: "Accurate 2D and 3D floor plans with room dimensions." }, { icon: "globe", name: "Property site",desc: "Single-property site with your branding and full gallery." }, { icon: "social", name: "Reels", desc: "Vertical reels and square highlights for Instagram." }, ]; const ServiceTile = ({ s, index }) => { const ref = useReveal(); return (

{s.name}

{s.desc}

); }; const Services = () => { const headRef = useReveal(); return (
What we shoot

Everything a listing needs.

Book one service or the whole set. Most agents pair photography with a floor plan and a short walkthrough — three deliverables, one shoot.

{SERVICES.map((s, i) => )}
); }; Object.assign(window, { Services }); // ===== WhyPickUs.jsx ===== const REASONS = [ { icon: "clock", name: "Always on time", desc: "We arrive at the scheduled minute, with the crew and gear the brief calls for." }, { icon: "check", name: "24-hour gallery", desc: "Standard 24-hour turnaround. Twilight and same-day available for a small uplift." }, { icon: "camera", name: "Consistent edit", desc: "Warm white-balance, vertical lines, no over-cooked HDR. Every shoot looks like the last." }, { icon: "arrow-right", name: "Easy to book", desc: "One link, three fields. Confirmation in the hour, calendar invite the same day." }, ]; const ReasonTile = ({ r, index }) => { const ref = useReveal(); return (

{r.name}

{r.desc}

); }; const WhyPickUs = () => { const headRef = useReveal(); return (
Why agents pick us

The boring parts, done right.

Most of what makes media work for a listing is consistency, not flash. Punctual crews, predictable color, files where you expect them.

{REASONS.map((r, i) => )}
); }; Object.assign(window, { WhyPickUs }); // ===== Packages.jsx ===== const PACKAGES = [ { name: "Essential", price: "from $225", featured: false, desc: "For standard listings. Photo, drone, and the basics that make a clean gallery.", features: [ "MLS-ready listing photos", "Drone photos (all standard angles)", "Basic 2D floor plan", "TV screens replaced", "Single-property website", ], bundleId: SPIRO.essential, }, { name: "Premium", price: "from $299", featured: true, desc: "What most agents book. Adds 3D tour and a twilight image.", features: [ "MLS-ready listing photos", "Drone photos", "Zillow 3D Tour", "Virtual twilight image", "TV screens replaced", "2D floor plan with measurements", "Single-property website", ], bundleId: SPIRO.premium, }, { name: "Luxury", price: "from $650", featured: false, desc: "For homes that need a marketing campaign. Adds cinematic video and four twilight images.", features: [ "MLS-ready listing photos", "Drone photos", "Cinematic video (incl. drone video)", "30s social-media reel", "Zillow 3D Tour", "4 virtual twilight photos", "TV screens replaced", "2D floor plan with measurements", "Single-property website", ], bundleId: SPIRO.luxury, }, ]; const PackageCard = ({ pkg, index }) => { const ref = useReveal(); return (
{pkg.featured && ( Most booked )}
{pkg.name}
{pkg.price} / shoot

{pkg.desc}

Book {pkg.name.toLowerCase()}
); }; const Packages = () => { const headRef = useReveal(); const live = useSpiroBundles(); const cards = PACKAGES.map(p => { const liveData = live?.get(p.bundleId); if (!liveData) return p; return { ...p, price: liveData.price || p.price, features: liveData.features.length ? liveData.features : p.features, }; }); return (
Simple packages

Pick the one that fits the listing.

Final price depends on square footage and add-ons; the exact quote appears in the booking flow.

{cards.map((p, i) => )}
); }; Object.assign(window, { Packages }); // ===== BookCTA.jsx ===== const BookCTA = () => { const eyebrowRef = useReveal(); const titleRef = useReveal(); const contactRef = useReveal(); const ctaRef = useReveal(); const contacts = [ { icon: "phone", label: "747-243-8969", href: "tel:7472438969", external: false }, { icon: "mail", label: "vlad@veradoma.com", href: "mailto:vlad@veradoma.com", external: false }, { icon: "instagram", label: "@veradoma_media", href: "https://instagram.com/veradoma_media", external: true }, ]; return (
Ready when you are

Book a shoot.

{contacts.map(c => ( {c.label} ))}
Orange County · CA
Start booking

Or pick a specific package above — each opens the booking flow preselected.

); }; Object.assign(window, { BookCTA }); // ===== Footer.jsx ===== const FOOTER_COLS = { Services: ["Photography", "Drone", "Video", "Floor plans", "Property sites", "Reels"], "Get in touch": [ { label: "747-243-8969", href: "tel:7472438969" }, { label: "vlad@veradoma.com", href: "mailto:vlad@veradoma.com" }, { label: "@veradoma_media", href: "https://instagram.com/veradoma_media" }, { label: "book.veradoma.com", href: "https://book.veradoma.com" }, ], Locations: ["Newport Beach", "Costa Mesa", "Laguna Beach", "Irvine", "Corona del Mar", "Newport Coast"], }; const Footer = () => { const brandRef = useReveal(); return ( ); }; Object.assign(window, { Footer }); // ===== App entry ===== const App = () => { return (