A responsive marketing site for a fictional mobile auto detailing business, built as a portfolio project to demonstrate React fundamentals: component architecture, state management, client-side routing, and real form submission, with a deliberate design system rather than a default template look.
Built as part of a return to front-end development after several years in automotive sales. The subject matter, auto detailing, was chosen deliberately to keep the content authentic (real service tiers, realistic pricing, industry-accurate copy) rather than generic placeholder text.
- React (Vite), component architecture, hooks
- React Router, client-side routing with nested layout routes
- Tailwind CSS v4, utility-first styling with a custom theme (colors, fonts defined via
@theme) - Framer Motion, entrance and scroll-triggered animations, with
prefers-reduced-motionsupport - Formspree, working contact form submission (no backend required)
- Vercel, CI/CD deployment (auto-deploys on push to
main)
- Fully responsive layout, including a custom mobile navigation menu
- Data-driven
ServiceCardcomponents rendered from a structured data array, with array-based category tagging to support future filtering - Stateful testimonial carousel with wraparound navigation and dot indicators
- Contact form with controlled inputs, loading/success/error states, and real email delivery via Formspree
- Environment-variable-based configuration (Formspree endpoint is not hardcoded in source)
- Scroll-triggered and page-load animations built with accessibility in mind, all motion respects the user's OS-level reduced-motion preference
- Optimized for performance: images sized and compressed for web,
fetchpriorityused on the largest contentful element
Lighthouse scores (mobile, production build):
| Category | Score |
|---|---|
| Performance | 98 |
| Accessibility | 92 |
| Best Practices | 100 |
| SEO | 92 |
Notably, the initial Performance score was 76 due to an unoptimized 3MB hero image. Resizing and compressing the image, then explicitly prioritizing it with fetchpriority="high" as the page's largest contentful paint element, brought the score to 98.
git clone https://github.com/jnigh-cyber/auto-detail-demo.git
cd auto-detail-demo
npm installCreate a .env file in the project root (see .env.example):
VITE_FORMSPREE_URL=your_formspree_endpoint_here
Then run:
npm run devsrc/
components/ # Navbar, Footer, Hero, ServiceCard, TestimonialCarousel, ContactForm
pages/ # Home, Services, About, Contact
data/ # services.js, testimonials.js
App.jsx
main.jsx
index.css # Tailwind import + custom theme tokens
- Automated tests for core components (ServiceCard rendering, form validation)
- Self-hosted fonts to reduce external requests
- Filterable services view using the existing category data
Built by J Nigh as part of a front-end development portfolio.