// ===== src/logo.jsx ===== const PrimeLogo = ({ size = 28, accent = "var(--accent)", ink = "var(--ink)", showWordmark = true, wordmarkSize }) => { const s = size; const ws = wordmarkSize || Math.round(size * 0.78); return (
{/* core */} {/* 8 rays as short capsule strokes */} {Array.from({ length: 8 }).map((_, i) => { const angle = i * 45 * (Math.PI / 180); const x1 = 16 + Math.cos(angle) * 9; const y1 = 16 + Math.sin(angle) * 9; const x2 = 16 + Math.cos(angle) * 13.5; const y2 = 16 + Math.sin(angle) * 13.5; return ( ); })} {showWordmark && Prime Solar }
); }; window.PrimeLogo = PrimeLogo; // ===== src/nav.jsx ===== const Nav = () => { const [scrolled, setScrolled] = React.useState(false); React.useEffect(() => { const onScroll = () => setScrolled(window.scrollY > 24); window.addEventListener("scroll", onScroll, { passive: true }); return () => window.removeEventListener("scroll", onScroll); }, []); const links = [ { label: "How it works", href: "#why" }, { label: "Reviews", href: "#reviews" }, { label: "Contact", href: "#contact" } ]; return (
{ e.currentTarget.style.background = "var(--accent)"; }} onMouseLeave={(e) => { e.currentTarget.style.background = "var(--ink)"; }}> Get a quote →
); }; window.Nav = Nav; // ===== src/hero.jsx ===== const HERO_VARIANTS = { pays: { a: "Solar that pays for itself,", b: "and then some." }, simple: { a: "Solar, made", b: "refreshingly simple." }, straight: { a: "Straightforward solar", b: "for Northeast homes." } }; const Hero = () => { const [, force] = React.useReducer((x) => x + 1, 0); React.useEffect(() => { const handler = () => force(); window.addEventListener("tweaks-changed", handler); return () => window.removeEventListener("tweaks-changed", handler); }, []); const variantKey = window.__heroVariant || "pays"; const variant = HERO_VARIANTS[variantKey] || HERO_VARIANTS.pays; return (
{/* sun glow backdrop */}
{/* Unified hero: headline overlays image, copy in sidebar */}
{/* Image + overlaid headline */}
Colonial home in the Northeast with rooftop solar panels {/* warm wash for legibility at bottom where headline sits */}
{/* subtle warm accent tint at top */}
{/* overlaid headline */}

{variant.a} {variant.b}

{/* Side column: copy + CTA */}
{/* Trust bar below */}
No upfront cost options
25-year performance warranty
LOCALLY OWNED AND OPERATED
); }; window.Hero = Hero; // ===== src/why.jsx ===== const PILLARS = [ { k: "01", title: "Engineer-led design, every roof", blurb: "Every system is designed by a certified engineer for your exact roof pitch, orientation, and shading — not a sales template.", detail: "We use drone scans and irradiance modeling to predict year-one production within ±3%. Get the full design before any work is completed." }, { k: "02", title: "Straight pricing, in writing", blurb: "One fixed quote. One line item. No teaser rates, no mystery fees, no pressure to close in 24 hours.", detail: "Your proposal shows total system cost, federal tax credit (up to 30%), state incentives you qualify for, and net monthly cost compared to your current utility bill. Apples to apples." }, { k: "03", title: "25-year performance guarantee", blurb: "Panels, inverter, and production — all covered for 25 years. If your system underproduces, we write you a check.", detail: "Get the best warranties on the highest quality equipment. If real-world production falls below our modeled estimate in any year, we reimburse the shortfall at your utility's rate." }, { k: "04", title: "Local crews in every state", blurb: "Crews that live in the area, understand local codes, and make sure your system is installed the right way the first time.", detail: "Permitting, installation, interconnection, and warranty service all run through the same team. Get updates quickly on the status of your project at any time." } ]; const Pillar = ({ p, open, onToggle }) => { return (
{p.k}

{p.title}

{p.blurb}

{p.detail}
); }; const Why = () => { const [openIdx, setOpenIdx] = React.useState(0); return (
— Why Prime Solar

Four commitments that separate us from the rest of the industry.

{PILLARS.map((p, i) => setOpenIdx(openIdx === i ? -1 : i)} /> )}
); }; window.Why = Why; // ===== src/testimonials.jsx ===== const REVIEWS = [ { quote: "Six quotes in, Prime provided the simplest quote, with the lowest pressure to sign. They gave me a simple, clear payment I could easily compare with my utility bill.", name: "Dana R.", meta: "Silver Spring, MD · 9.2 kW install", tag: "Installed Mar 2024" }, { quote: "I'd been burned by a leased system at my last house. The Prime team walked me through ownership vs. PPA math on a single page. No pressure. We own our system outright and the break-even is year seven.", name: "Marcus & Jen L.", meta: "Richmond, VA · 11.6 kW install", tag: "Installed Aug 2023" }, { quote: "They flagged that half my roof was too shaded to pay off, and proposed a smaller system than anyone else. Honest math. That's why they got the job.", name: "Tom H.", meta: "Charlottesville, VA · 6.4 kW install", tag: "Installed Jun 2024" } ]; const Testimonials = () => { const [idx, setIdx] = React.useState(0); const count = REVIEWS.length; const go = (d) => setIdx((prev) => (prev + d + count) % count); React.useEffect(() => { const t = setInterval(() => setIdx((i) => (i + 1) % count), 9000); return () => clearInterval(t); }, [count]); const r = REVIEWS[idx]; return (
— Homeowner reviews

The best sales pitch is a working system.

{String(idx + 1).padStart(2, "0")} / {String(count).padStart(2, "0")}
{/* 5 stars */}
{Array.from({ length: 5 }).map((_, i) => )}
"{r.quote}"
{r.name.split(" ").map((s) => s[0]).slice(0, 2).join("")}
{r.name}
{r.meta}
{r.tag}
{/* progress dots */}
{REVIEWS.map((_, i) =>
); }; window.Testimonials = Testimonials; // ===== src/footer.jsx ===== const Footer = () => { const [email, setEmail] = React.useState(""); const [sent, setSent] = React.useState(false); const linkGroups = [ { title: "Company", links: [ { label: "About", href: "about.html" }, { label: "Contact", href: "contact.html" } ] } ]; return ( <> {/* Final CTA band */}
{/* faint sun */}

See your roof's numbers in about ten minutes.

Send us your address and last month's utility bill. We'll come back with a production model, a fixed quote, and a break-even year — no sales call required.

{ e.preventDefault(); setSent(true); }} style={{ background: "var(--paper)", borderRadius: 16, padding: 24, boxShadow: "0 30px 80px -40px rgba(120, 60, 20, 0.4)" }}> setEmail(e.target.value)} disabled={sent} style={{ width: "100%", padding: "14px 16px", border: "1px solid var(--rule)", borderRadius: 10, fontSize: 15, fontFamily: "inherit", color: "var(--ink)", background: sent ? "var(--paper-2)" : "var(--paper)", outline: "none", transition: "border-color 150ms" }} onFocus={(e) => e.target.style.borderColor = "var(--accent)"} onBlur={(e) => e.target.style.borderColor = "var(--rule)"} />

No sales calls. No spam. Unsubscribe anytime.

); }; window.Footer = Footer; // ===== src/tweaks.jsx ===== const TWEAK_DEFAULTS = { "accent": "clay", "heroVariant": "pays", "heading_font": "instrument" }; const ACCENTS = { clay: { accent: "#C8502B", soft: "#E8B094", label: "Clay (default)" }, amber: { accent: "#D97706", soft: "#F3C98B", label: "Amber" }, ember: { accent: "#A94826", soft: "#D9A285", label: "Ember (deep)" }, honey: { accent: "#B87333", soft: "#E3B98A", label: "Honey" }, forest: { accent: "#3A6B46", soft: "#A8C9B0", label: "Forest (cool)" } }; const FONTS = { instrument: { label: "Instrument Sans", value: "\"Instrument Sans\", sans-serif" }, bricolage: { label: "Bricolage Grotesque", value: "\"Bricolage Grotesque\", sans-serif" }, familjen: { label: "Familjen Grotesk", value: "\"Familjen Grotesk\", sans-serif" }, intertight: { label: "Inter Tight", value: "\"Inter Tight\", sans-serif" } }; const applyTweaks = (vals) => { const accent = ACCENTS[vals.accent] || ACCENTS.clay; document.documentElement.style.setProperty("--accent", accent.accent); document.documentElement.style.setProperty("--accent-soft", accent.soft); const font = FONTS[vals.heading_font] || FONTS.instrument; document.documentElement.style.setProperty("--serif", font.value); window.__heroVariant = vals.heroVariant; window.dispatchEvent(new Event("tweaks-changed")); }; const Tweaks = () => { const [vals, setVals] = React.useState(TWEAK_DEFAULTS); const [open, setOpen] = React.useState(true); const [active, setActive] = React.useState(false); React.useEffect(() => { if (document.getElementById("tweak-fonts")) return; const l = document.createElement("link"); l.id = "tweak-fonts"; l.rel = "stylesheet"; l.href = "https://fonts.googleapis.com/css2?family=Bricolage+Grotesque:opsz,wght@12..96,400;12..96,500;12..96,600&family=Familjen+Grotesk:wght@400;500;600&display=swap"; document.head.appendChild(l); }, []); React.useEffect(() => { applyTweaks(vals); }, [vals]); React.useEffect(() => { const onMsg = (e) => { if (e.data?.type === "__activate_edit_mode") setActive(true); if (e.data?.type === "__deactivate_edit_mode") setActive(false); }; window.addEventListener("message", onMsg); window.parent.postMessage({ type: "__edit_mode_available" }, "*"); return () => window.removeEventListener("message", onMsg); }, []); const update = (key, value) => { const next = { ...vals, [key]: value }; setVals(next); window.parent.postMessage({ type: "__edit_mode_set_keys", edits: { [key]: value } }, "*"); }; if (!active) return null; return (
{open &&
{/* Accent */}
Accent color
{Object.entries(ACCENTS).map(([k, a]) =>
{/* Hero headline */}
Hero headline
{Object.entries(HERO_VARIANTS).map(([k, h]) => )}
{/* Heading font */}
Heading font
{Object.entries(FONTS).map(([k, f]) => )}
}
); }; window.Tweaks = Tweaks; window.HERO_VARIANTS = HERO_VARIANTS; // ===== src/app.jsx ===== const App = () => { return ( <>