Auto Repair & Mechanic Website Prompt — Industrial Dark Design for Lovable, Claude, Bolt and more

Build a complete independent mechanic website with a dramatic charcoal, signal orange, and grey design system. Includes MOT, services grid, transparent pricing, team section, trust marquee, emergency CTA, and a fixed call bar. All copy written.

# Axle & Co Auto Repair — Full Website Prompt # websiteprompts.ai --- ## 1. GOAL STATEMENT Build a complete, production-ready website for **Axle & Co Auto Repair** — an independent mechanic and MOT testing garage — that communicates industrial expertise, honest pricing, and trustworthy service through a dark charcoal, signal orange, and light grey design system with Space Grotesk display type and full Framer Motion animation. --- ## 2. TECH STACK - **Framework:** React 18 + Vite + TypeScript - **Styling:** Tailwind CSS v3 (with custom CSS variables) - **Animation:** Framer Motion (`motion/react`) — import exclusively from `motion/react`, never from `framer-motion` - **UI Components:** shadcn/ui - **Icons:** lucide-react - **Fonts:** Google Fonts (Space Grotesk + Plus Jakarta Sans via `<link>` in index.html) --- ## 3. DESIGN SYSTEM Place these CSS custom properties in `src/index.css` inside `:root {}`: ```css :root { /* Core Palette */ --color-bg: hsl(216, 14%, 10%); /* #111418 — deep charcoal */ --color-surface: hsl(216, 12%, 14%); /* #1c2028 — card background */ --color-surface-mid: hsl(216, 10%, 18%); /* #272d35 — elevated surface */ --color-border: hsl(216, 10%, 22%); /* #313840 — subtle border */ --color-orange: hsl(22, 97%, 47%); /* #e85d04 — signal orange */ --color-orange-hover: hsl(22, 97%, 42%); /* #d15203 — orange hover */ --color-orange-glow: hsla(22, 97%, 47%, 0.18); /* orange ambient glow */ --color-grey-light: hsl(0, 0%, 91%); /* #e8e8e8 — light grey */ --color-grey-mid: hsl(0, 0%, 62%); /* #9e9e9e — mid grey */ --color-grey-dark: hsl(0, 0%, 38%); /* #616161 — dark grey */ --color-white: hsl(0, 0%, 100%); /* Typography Scale */ --text-hero: clamp(50px, 7.5vw, 130px); --text-h2: clamp(32px, 4vw, 60px); --text-h3: clamp(20px, 2.2vw, 28px); --text-body: 16px; --text-small: 14px; --text-label: 12px; /* Spacing */ --section-px: clamp(24px, 5vw, 96px); --section-py: clamp(64px, 8vw, 120px); /* Radius */ --radius-sm: 6px; --radius-md: 12px; --radius-lg: 20px; /* Transitions */ --ease-out: cubic-bezier(0.22, 1, 0.36, 1); --ease-in-out: cubic-bezier(0.65, 0, 0.35, 1); } ``` Set `body { background-color: var(--color-bg); color: var(--color-grey-light); }` globally. --- ## 4. TYPOGRAPHY Add to `index.html` `<head>`: ```html <link rel="preconnect" href="https://fonts.googleapis.com" /> <link rel="preconnect" href="https://fonts.gstatic.com" crossorigin /> <link href="https://fonts.googleapis.com/css2?family=Space+Grotesk:wght@400;500;600;700;800&family=Plus+Jakarta+Sans:wght@300;400;500;600;700&display=swap" rel="stylesheet" /> ``` **Usage rules:** - `font-family: 'Space Grotesk', sans-serif; font-weight: 800;` — ALL display headlines (hero, section heads, emergency CTA, marquee) - `font-family: 'Space Grotesk', sans-serif; font-weight: 700;` — Navbar logo, pricing table headers, trust marquee text - `font-family: 'Plus Jakarta Sans', sans-serif; font-weight: 400;` — Body copy, card descriptions, footer content - `font-family: 'Plus Jakarta Sans', sans-serif; font-weight: 600;` — Service card names, nav links, price chips, CTA labels - `font-family: 'Plus Jakarta Sans', sans-serif; font-weight: 300;` — Subheadlines, captions, supporting text under emergency section - Letter spacing: headlines use `letter-spacing: -0.02em`; labels use `letter-spacing: 0.08em; text-transform: uppercase` --- ## 5. VISUAL EFFECTS ### Effect 1 — Hero Horizontal Gradient ```css background: linear-gradient( to right, rgba(17, 20, 24, 0.96) 0%, rgba(17, 20, 24, 0.80) 40%, rgba(17, 20, 24, 0.40) 65%, rgba(17, 20, 24, 0.00) 100% ); ``` Applied as `absolute inset-0 z-10` over the hero image. Ensures text is readable across all photo compositions without relying on image placement. ### Effect 2 — Background Watermark "AXLE" ```jsx <span className="absolute select-none pointer-events-none" style={{ fontFamily: "'Space Grotesk', sans-serif", fontWeight: 800, fontSize: "clamp(240px, 34vw, 520px)", color: "rgba(232, 232, 232, 0.03)", right: "-2%", top: "50%", transform: "translateY(-50%)", lineHeight: 1, letterSpacing: "-0.04em", zIndex: 5, userSelect: "none", }} > AXLE </span> ``` Sits between the photo layer and the gradient overlay (z-5). Creates brand identity without distracting from content. ### Effect 3 — Orange Glow on Cards (hover state) ```css box-shadow: 0 0 0 0 transparent; transition: box-shadow 0.2s ease, transform 0.2s ease, border-color 0.2s ease; ``` On hover: `box-shadow: 0 8px 32px var(--color-orange-glow), 0 2px 8px rgba(0,0,0,0.4);` — creates a subtle orange ambient halo around hovered cards. ### Effect 4 — Infinite Scrolling Marquee ```css @keyframes marquee-scroll { from { transform: translateX(0); } to { transform: translateX(-50%); } } .marquee-track { display: flex; width: max-content; animation: marquee-scroll 35s linear infinite; } .marquee-track:hover { animation-play-state: paused; } ``` Duplicate the trust text content once so the animation loops seamlessly. ### Effect 5 — Fixed Orange CTA Bar (hero-only) A `position: fixed; bottom: 0; left: 0; right: 0; z-index: 100` bar that renders only when the user is within the hero viewport. Controlled via a `useEffect` + `IntersectionObserver` on a hero sentinel `<div>`. Fades out (`opacity: 0; pointer-events: none`) when hero exits view. --- ## 6. COMPONENT BREAKDOWN --- ### SECTION 1 — NAVBAR **Layout:** `position: sticky; top: 0; z-index: 90` - Background: `var(--color-bg)` with `border-bottom: 1px solid var(--color-border)` - Padding: `16px var(--section-px)` - Flex: `justify-between; align-items: center` **Left — Logo:** ```jsx <div style={{ fontFamily: "'Space Grotesk', sans-serif", fontWeight: 800, fontSize: "22px", color: "var(--color-white)", letterSpacing: "-0.02em" }}> AXLE <span style={{ color: "var(--color-orange)" }}>&</span> CO </div> ``` **Center — Nav Links (desktop only, hidden on mobile):** `Services · About · Pricing · Reviews` — rendered as `<nav>` with `<a>` tags, `color: var(--color-grey-mid)`, `font-family: Plus Jakarta Sans 600`, `font-size: 15px`, `letter-spacing: 0.01em`. On hover: `color: var(--color-grey-light)`, transition `0.15s ease`. **Right — CTA:** ```jsx <a href="#booking" style={{ backgroundColor: "var(--color-orange)", color: "var(--color-white)", fontFamily: "'Plus Jakarta Sans', sans-serif", fontWeight: 600, fontSize: "15px", padding: "10px 20px", borderRadius: "var(--radius-sm)", textDecoration: "none", transition: "background-color 0.15s ease", }} onMouseEnter={e => e.currentTarget.style.backgroundColor = "var(--color-orange-hover)"} onMouseLeave={e => e.currentTarget.style.backgroundColor = "var(--color-orange)"} > Book Online </a> ``` **Mobile:** Hamburger icon (Menu from lucide-react), slides down a full-width drawer with links stacked vertically, same dark background. --- ### SECTION 2 — HERO **Container:** `position: relative; height: 100vh; min-height: 640px; overflow: hidden` **Layer 1 — Photo:** ```jsx {/* Image: Professional mechanic in a clean navy uniform lying beneath a lifted car on a hydraulic ramp, dramatic underlighting from LED inspection lights casting warm orange/white on engine components. Background shows a tidy garage with tools organized on an orange pegboard. Cinematic wide-angle composition, slight grain, warm industrial atmosphere. */} <img src="" alt="Mechanic working beneath a lifted car at Axle & Co garage" className="absolute inset-0 w-full h-full object-cover object-center" style={{ zIndex: 1 }} /> ``` **Layer 2 — Watermark "AXLE"** (z-index: 5, see Effect 2 above) **Layer 3 — Horizontal Gradient Overlay** (z-index: 10, see Effect 1 above) **Layer 4 — Content (z-index: 20):** ```jsx <div className="absolute inset-0 flex flex-col justify-center" style={{ zIndex: 20, paddingLeft: "var(--section-px)", paddingRight: "var(--section-px)", maxWidth: "820px", }} > {/* Eyebrow label */} <motion.p initial={{ opacity: 0, y: 16 }} animate={{ opacity: 1, y: 0 }} transition={{ duration: 0.5, delay: 0.1, ease: [0.22, 1, 0.36, 1] }} style={{ fontFamily: "'Plus Jakarta Sans', sans-serif", fontWeight: 600, fontSize: "13px", letterSpacing: "0.14em", textTransform: "uppercase", color: "var(--color-orange)", marginBottom: "20px", }} > Trusted Independent Garage · Est. 2008 </motion.p> {/* Main Headline */} <motion.h1 initial={{ opacity: 0, y: 24 }} animate={{ opacity: 1, y: 0 }} transition={{ duration: 0.7, delay: 0.2, ease: [0.22, 1, 0.36, 1] }} style={{ fontFamily: "'Space Grotesk', sans-serif", fontWeight: 800, fontSize: "var(--text-hero)", color: "var(--color-white)", lineHeight: 0.92, letterSpacing: "-0.03em", marginBottom: "28px", }} > WE FIX WHAT<br /> <span style={{ color: "var(--color-orange)" }}>OTHERS</span> MISS. </motion.h1> {/* Subheadline */} <motion.p initial={{ opacity: 0, y: 20 }} animate={{ opacity: 1, y: 0 }} transition={{ duration: 0.6, delay: 0.4, ease: [0.22, 1, 0.36, 1] }} style={{ fontFamily: "'Plus Jakarta Sans', sans-serif", fontWeight: 300, fontSize: "clamp(16px, 1.8vw, 22px)", color: "var(--color-grey-light)", maxWidth: "480px", lineHeight: 1.6, marginBottom: "40px", }} > Honest diagnostics. Fair pricing. Guaranteed work. </motion.p> {/* CTA Buttons */} <motion.div initial={{ opacity: 0, y: 20 }} animate={{ opacity: 1, y: 0 }} transition={{ duration: 0.6, delay: 0.55, ease: [0.22, 1, 0.36, 1] }} style={{ display: "flex", gap: "16px", flexWrap: "wrap" }} > <a href="#booking" style={{ backgroundColor: "var(--color-orange)", color: "var(--color-white)", fontFamily: "'Plus Jakarta Sans', sans-serif", fontWeight: 600, fontSize: "16px", padding: "14px 28px", borderRadius: "var(--radius-sm)", textDecoration: "none", display: "inline-flex", alignItems: "center", gap: "8px", }}> Book a Service </a> <a href="tel:02079460823" style={{ border: "1px solid var(--color-border)", color: "var(--color-grey-light)", fontFamily: "'Plus Jakarta Sans', sans-serif", fontWeight: 600, fontSize: "16px", padding: "14px 28px", borderRadius: "var(--radius-sm)", textDecoration: "none", display: "inline-flex", alignItems: "center", gap: "8px", backgroundColor: "rgba(255,255,255,0.04)", }}> 020 7946 0823 </a> </motion.div> </div> ``` **Layer 5 — Scroll indicator (bottom center, z-20):** ```jsx <motion.div animate={{ y: [0, 8, 0] }} transition={{ duration: 2, repeat: Infinity, ease: "easeInOut" }} style={{ position: "absolute", bottom: "80px", left: "50%", transform: "translateX(-50%)", zIndex: 20 }} > <ChevronDown size={28} color="rgba(232,232,232,0.4)" /> </motion.div> ``` **Fixed Call Bar (Layer 6 — separate DOM node at root level):** ```jsx <motion.div initial={{ y: 80, opacity: 0 }} animate={heroVisible ? { y: 0, opacity: 1 } : { y: 80, opacity: 0 }} transition={{ duration: 0.35, ease: [0.22, 1, 0.36, 1] }} style={{ position: "fixed", bottom: 0, left: 0, right: 0, zIndex: 100, backgroundColor: "var(--color-orange)", padding: "14px var(--section-px)", display: "flex", alignItems: "center", justifyContent: "center", gap: "14px", pointerEvents: heroVisible ? "auto" : "none", }} > <PhoneCall size={22} color="white" /> <span style={{ fontFamily: "'Space Grotesk', sans-serif", fontWeight: 800, fontSize: "clamp(18px, 2.2vw, 28px)", color: "var(--color-white)", letterSpacing: "-0.01em", }}> CALL NOW: 020 7946 0823 </span> <span style={{ fontFamily: "'Plus Jakarta Sans', sans-serif", fontWeight: 400, fontSize: "14px", color: "rgba(255,255,255,0.75)", marginLeft: "8px", }}> Mon–Sat 8am–6pm · Emergency callout available </span> </motion.div> ``` Use `useEffect` + `IntersectionObserver` on a `ref` at the bottom of the hero section. Set state `heroVisible: boolean`. When hero exits viewport, bar slides down and becomes non-interactive. --- ### SECTION 3 — SERVICES GRID **Container:** `padding: var(--section-py) var(--section-px); background: var(--color-bg)` **Section heading:** ```jsx <div style={{ marginBottom: "56px" }}> <p style={{ /* orange eyebrow */ fontFamily: "'Plus Jakarta Sans', sans-serif", fontWeight: 600, fontSize: "13px", letterSpacing: "0.14em", textTransform: "uppercase", color: "var(--color-orange)", marginBottom: "12px" }}> What We Do </p> <h2 style={{ fontFamily: "'Space Grotesk', sans-serif", fontWeight: 800, fontSize: "var(--text-h2)", color: "var(--color-white)", letterSpacing: "-0.02em", lineHeight: 1.05 }}> Full-Spectrum<br /> <span style={{ color: "var(--color-grey-mid)" }}>Auto Services</span> </h2> </div> ``` **Grid:** `display: grid; grid-template-columns: repeat(3, 1fr); gap: 2px;` on desktop. Each card shares a continuous surface — the `2px` gap creates thin dark dividers. On mobile: `repeat(1, 1fr)`, stacked. **6 Service Cards — identical structure, staggered reveal (delay: index × 0.08s):** Each card: ```jsx <motion.div initial={{ opacity: 0, y: 32 }} whileInView={{ opacity: 1, y: 0 }} viewport={{ once: true, margin: "-60px" }} transition={{ duration: 0.55, delay: index * 0.08, ease: [0.22, 1, 0.36, 1] }} whileHover={{ y: -3 }} style={{ backgroundColor: "var(--color-surface)", padding: "36px 32px", borderLeft: "3px solid transparent", transition: "border-color 0.2s ease, box-shadow 0.2s ease", cursor: "default", }} onHoverStart={e => { e.currentTarget.style.borderLeftColor = "var(--color-orange)"; e.currentTarget.style.boxShadow = "0 8px 32px var(--color-orange-glow)"; }} onHoverEnd={e => { e.currentTarget.style.borderLeftColor = "transparent"; e.currentTarget.style.boxShadow = "none"; }} > {/* Icon */} <div style={{ marginBottom: "20px" }}> <Icon size={32} color="var(--color-orange)" strokeWidth={1.5} /> </div> {/* Service name */} <h3 style={{ fontFamily: "'Space Grotesk', sans-serif", fontWeight: 700, fontSize: "var(--text-h3)", color: "var(--color-white)", marginBottom: "10px", letterSpacing: "-0.01em" }}> {service.name} </h3> {/* Description */} <p style={{ fontFamily: "'Plus Jakarta Sans', sans-serif", fontWeight: 400, fontSize: "15px", color: "var(--color-grey-mid)", lineHeight: 1.65, marginBottom: "24px" }}> {service.description} </p> {/* Price chip */} <span style={{ display: "inline-block", backgroundColor: "rgba(232, 93, 4, 0.12)", color: "var(--color-orange)", fontFamily: "'Plus Jakarta Sans', sans-serif", fontWeight: 600, fontSize: "13px", letterSpacing: "0.04em", padding: "6px 14px", borderRadius: "100px", border: "1px solid rgba(232, 93, 4, 0.25)", }}> {service.price} </span> </motion.div> ``` **6 Services Data:** ```ts const services = [ { name: "MOT Testing", icon: ClipboardCheck, // lucide-react description: "Class 4 and Class 7 MOT tests on-site. Fast turnaround, same-day results, retest included free within 10 working days.", price: "From £29.99", }, { name: "Engine Repair", icon: Gauge, description: "Full engine diagnostics and repair. From sensor faults to full rebuilds — we get to the root cause, not just the symptom.", price: "From £95", }, { name: "Brake Service", icon: CircleDot, description: "Pad and disc replacement, brake fluid flush, handbrake adjustment. All brake work comes with a 12-month parts guarantee.", price: "From £79 per axle", }, { name: "Tyres", icon: Circle, description: "Supply and fit for all tyre sizes. Budget, mid-range, and premium brands. Free wheel balancing included with every tyre fit.", price: "From £49 fitted", }, { name: "Air Con Regas", icon: Wind, description: "Full air conditioning recharge using R134a or R1234yf refrigerant. Includes system leak check and performance test.", price: "From £49", }, { name: "Diagnostics", icon: ScanLine, description: "OBD2 full-system scan covering engine, ABS, airbag, gearbox, and emissions. We read the codes and explain what they actually mean.", price: "From £35", }, ]; ``` --- ### SECTION 4 — WHY CHOOSE US **Container:** `padding: var(--section-py) var(--section-px); background: var(--color-surface)` **Layout:** Single row on desktop (`display: flex; gap: 40px; flex-wrap: wrap`), stacked on mobile. **Section heading (left-aligned, full width above the row):** ``` Why Axle & Co? ``` Space Grotesk 800, `var(--text-h2)`, white, `-0.02em` letter-spacing, `margin-bottom: 48px`. **4 Trust Points — each:** ```jsx <motion.div initial={{ opacity: 0, x: -20 }} whileInView={{ opacity: 1, x: 0 }} viewport={{ once: true }} transition={{ duration: 0.5, delay: index * 0.1, ease: [0.22, 1, 0.36, 1] }} style={{ flex: "1 1 220px", display: "flex", alignItems: "flex-start", gap: "16px" }} > {/* Orange circle checkmark */} <div style={{ width: "40px", height: "40px", borderRadius: "50%", backgroundColor: "var(--color-orange)", display: "flex", alignItems: "center", justifyContent: "center", flexShrink: 0, marginTop: "2px", }}> <Check size={20} color="white" strokeWidth={2.5} /> </div> <div> <p style={{ fontFamily: "'Space Grotesk', sans-serif", fontWeight: 700, fontSize: "18px", color: "var(--color-white)", marginBottom: "6px" }}> {point.title} </p> <p style={{ fontFamily: "'Plus Jakarta Sans', sans-serif", fontWeight: 400, fontSize: "15px", color: "var(--color-grey-mid)", lineHeight: 1.6 }}> {point.detail} </p> </div> </motion.div> ``` **4 Trust Points Data:** ```ts const trustPoints = [ { title: "No Hidden Charges", detail: "We quote before we touch. If we discover additional work needed, we call you first. Always.", }, { title: "12-Month Parts Guarantee", detail: "Every part we fit is guaranteed for 12 months or 12,000 miles — whichever comes first.", }, { title: "Same-Day Service Available", detail: "Most repairs completed while you wait. Drop off in the morning, collect by afternoon.", }, { title: "Free Collection & Delivery", detail: "Can't get to us? We'll collect your vehicle and return it to your door. Free within 5 miles.", }, ]; ``` --- ### SECTION 5 — THE TEAM **Container:** `padding: var(--section-py) var(--section-px); background: var(--color-bg)` **Section heading:** ``` Meet the Mechanics ``` Space Grotesk 800, white, `var(--text-h2)`, `margin-bottom: 56px`. **Grid:** `display: grid; grid-template-columns: repeat(3, 1fr); gap: 24px` on desktop. `repeat(1, 1fr)` on mobile. **3 Team Cards:** ```jsx <motion.div initial={{ opacity: 0, y: 24 }} whileInView={{ opacity: 1, y: 0 }} viewport={{ once: true, margin: "-40px" }} transition={{ duration: 0.55, delay: index * 0.1, ease: [0.22, 1, 0.36, 1] }} style={{ backgroundColor: "var(--color-surface)", borderRadius: "var(--radius-md)", overflow: "hidden", borderTop: "4px solid transparent", transition: "border-color 0.15s ease", }} onHoverStart={e => e.currentTarget.style.borderTopColor = "var(--color-orange)"} onHoverEnd={e => e.currentTarget.style.borderTopColor = "transparent"} > {/* Photo — 4:3 ratio */} <div style={{ aspectRatio: "4/3", overflow: "hidden", position: "relative" }}> {/* Image: [mechanic portrait — see copy below] */} <img src="" alt="{member.name} — mechanic at Axle & Co" className="w-full h-full object-cover object-center" /> </div> <div style={{ padding: "24px 28px 28px" }}> <h3 style={{ fontFamily: "'Space Grotesk', sans-serif", fontWeight: 700, fontSize: "22px", color: "var(--color-white)", marginBottom: "4px" }}> {member.name} </h3> <p style={{ fontFamily: "'Plus Jakarta Sans', sans-serif", fontWeight: 400, fontSize: "14px", color: "var(--color-grey-mid)", marginBottom: "16px" }}> {member.experience} years experience </p> {/* Speciality chip */} <span style={{ display: "inline-block", backgroundColor: "var(--color-orange)", color: "white", fontFamily: "'Plus Jakarta Sans', sans-serif", fontWeight: 600, fontSize: "12px", letterSpacing: "0.06em", textTransform: "uppercase", padding: "5px 12px", borderRadius: "4px", }}> {member.speciality} </span> </div> </motion.div> ``` **3 Team Members Data:** ```ts const team = [ { name: "Danny Rowe", experience: 18, speciality: "Engine & Transmission", imageDesc: "Mid-30s male mechanic in clean navy uniform, confident expression, arms crossed, workshop background with orange-lit pegboard tools, portrait orientation, warm professional lighting", }, { name: "Priya Mehta", experience: 11, speciality: "Diagnostics & Electronics", imageDesc: "Early 30s female mechanic holding a diagnostic tablet, professional navy uniform, slight smile, clean workshop background, warm studio lighting, portrait orientation", }, { name: "Carl Hutchins", experience: 24, speciality: "Brakes & Suspension", imageDesc: "Late 40s male senior mechanic, weathered hands, confident expression, navy uniform with Axle & Co logo, garage background with lifted vehicle partially visible, portrait orientation, cinematic lighting", }, ]; ``` --- ### SECTION 6 — TRUST MARQUEE **Container:** ```jsx <div style={{ backgroundColor: "var(--color-surface)", borderTop: "1px solid var(--color-border)", borderBottom: "1px solid var(--color-border)", padding: "20px 0", overflow: "hidden", }}> <div className="marquee-track" style={{ display: "flex", alignItems: "center", gap: "0" }}> {/* Render items twice for seamless loop */} {[...items, ...items].map((item, i) => ( <React.Fragment key={i}> <span style={{ fontFamily: "'Space Grotesk', sans-serif", fontWeight: 700, fontSize: "clamp(14px, 1.4vw, 17px)", color: "var(--color-grey-light)", letterSpacing: "0.02em", whiteSpace: "nowrap", padding: "0 40px", }}> {item} </span> <span style={{ color: "var(--color-orange)", fontSize: "22px", lineHeight: 1, flexShrink: 0 }}>·</span> </React.Fragment> ))} </div> </div> ``` **Marquee Items:** ```ts const items = [ "AA Approved Garage", "ASE Certified Technicians", "500+ Five-Star Reviews", "Est. 2008", "IMI Registered", "RAC Approved Garage", "Free MOT Retest", "12-Month Parts Guarantee", ]; ``` Animation: `35s linear infinite`, pauses on hover. CSS defined in `index.css` as shown in Effect 4. --- ### SECTION 7 — TRANSPARENT PRICING **Container:** `padding: var(--section-py) var(--section-px); background: var(--color-bg)` **Section heading:** ``` No Surprises. Just Prices. ``` Space Grotesk 800, white, `var(--text-h2)`, `margin-bottom: 12px`. **Subhead:** "Every price shown is the starting rate — we'll always confirm your exact quote before starting work." — Plus Jakarta Sans 300, `var(--color-grey-mid)`, 17px, `margin-bottom: 48px`. **Table:** ```jsx <div style={{ borderRadius: "var(--radius-md)", overflow: "hidden", border: "1px solid var(--color-border)", }}> {/* Header row */} <div style={{ display: "grid", gridTemplateColumns: "1fr 160px 140px", backgroundColor: "var(--color-orange)", padding: "16px 28px", }}> <span style={{ fontFamily: "'Space Grotesk', sans-serif", fontWeight: 700, fontSize: "14px", color: "white", letterSpacing: "0.08em", textTransform: "uppercase" }}>Service</span> <span style={{ fontFamily: "'Space Grotesk', sans-serif", fontWeight: 700, fontSize: "14px", color: "white", letterSpacing: "0.08em", textTransform: "uppercase" }}>From Price</span> <span style={{ fontFamily: "'Space Grotesk', sans-serif", fontWeight: 700, fontSize: "14px", color: "white", letterSpacing: "0.08em", textTransform: "uppercase" }}>Avg. Time</span> </div> {/* Data rows — alternate between --color-surface and --color-surface-mid */} {pricingRows.map((row, i) => ( <div key={i} style={{ display: "grid", gridTemplateColumns: "1fr 160px 140px", padding: "18px 28px", backgroundColor: i % 2 === 0 ? "var(--color-surface)" : "var(--color-surface-mid)", borderBottom: "1px solid var(--color-border)", }}> <span style={{ fontFamily: "'Plus Jakarta Sans', sans-serif", fontWeight: 500, fontSize: "16px", color: "var(--color-grey-light)" }}>{row.service}</span> <span style={{ fontFamily: "'Plus Jakarta Sans', sans-serif", fontWeight: 600, fontSize: "16px", color: "var(--color-orange)" }}>{row.price}</span> <span style={{ fontFamily: "'Plus Jakarta Sans', sans-serif", fontWeight: 400, fontSize: "15px", color: "var(--color-grey-mid)" }}>{row.time}</span> </div> ))} </div> ``` **8 Pricing Rows:** ```ts const pricingRows = [ { service: "MOT Test (Class 4)", price: "From £29.99", time: "45–60 min" }, { service: "Full Service", price: "From £149", time: "2–3 hrs" }, { service: "Interim Service", price: "From £89", time: "1–2 hrs" }, { service: "Brake Pads (per axle)", price: "From £79", time: "1 hr" }, { service: "Brake Discs + Pads", price: "From £149 axle", time: "1.5 hrs" }, { service: "Air Con Regas", price: "From £49", time: "30–45 min" }, { service: "Diagnostic Scan", price: "From £35", time: "30 min" }, { service: "Tyre Supply & Fit (each)", price: "From £49 fitted", time: "20 min each" }, ]; ``` **Note below table:** "All prices exclude VAT. Prices are indicative starting rates and may vary by vehicle. We confirm all costs before work begins." — Plus Jakarta Sans 300, 13px, `var(--color-grey-dark)`, `margin-top: 16px`. --- ### SECTION 8 — EMERGENCY SECTION **Container:** ```jsx <section style={{ backgroundColor: "var(--color-orange)", padding: "var(--section-py) var(--section-px)", textAlign: "center", position: "relative", overflow: "hidden", }}> {/* Background watermark "24/7" for depth */} <span style={{ position: "absolute", fontFamily: "'Space Grotesk', sans-serif", fontWeight: 800, fontSize: "clamp(180px, 28vw, 400px)", color: "rgba(0,0,0,0.06)", left: "50%", top: "50%", transform: "translate(-50%, -50%)", pointerEvents: "none", userSelect: "none", whiteSpace: "nowrap", }}> 24/7 </span> <div style={{ position: "relative", zIndex: 1 }}> <motion.h2 initial={{ opacity: 0, y: 32 }} whileInView={{ opacity: 1, y: 0 }} viewport={{ once: true }} transition={{ duration: 0.65, ease: [0.22, 1, 0.36, 1] }} style={{ fontFamily: "'Space Grotesk', sans-serif", fontWeight: 800, fontSize: "clamp(36px, 5vw, 80px)", color: "white", letterSpacing: "-0.03em", lineHeight: 0.95, marginBottom: "28px", }} > BROKEN DOWN?<br /> WE COME TO YOU. </motion.h2> <motion.a href="tel:02079460823" initial={{ opacity: 0, scale: 0.95 }} whileInView={{ opacity: 1, scale: 1 }} viewport={{ once: true }} transition={{ duration: 0.5, delay: 0.2, ease: [0.22, 1, 0.36, 1] }} style={{ display: "block", fontFamily: "'Space Grotesk', sans-serif", fontWeight: 800, fontSize: "clamp(44px, 6vw, 90px)", color: "white", letterSpacing: "-0.03em", lineHeight: 1, textDecoration: "none", marginBottom: "20px", }} > 020 7946 0823 </motion.a> <p style={{ fontFamily: "'Plus Jakarta Sans', sans-serif", fontWeight: 300, fontSize: "clamp(15px, 1.6vw, 19px)", color: "rgba(255,255,255,0.82)", letterSpacing: "0.02em", }}> Available 7 days · Usually within 2 hours · No call-out charge within 10 miles </p> </div> </section> ``` --- ### SECTION 9 — FOOTER **Container:** `background: var(--color-surface); border-top: 1px solid var(--color-border); padding: 64px var(--section-px) 32px` **3-Column Grid (`display: grid; grid-template-columns: 1.2fr 1fr 1fr; gap: 48px`):** **Column 1 — Brand:** ``` AXLE & CO Est. 2008 — trusted independent garage serving South London and the surrounding area. MOT, servicing, repairs, and tyres. Unit 4, Grange Road Industrial Estate London, SE1 3BT Open Mon–Fri: 8:00am – 6:00pm Saturday: 8:00am – 4:00pm Sunday: Emergency callout only ``` Logo in Space Grotesk 800, white. Address and hours in Plus Jakarta Sans 400, `var(--color-grey-mid)`, 14px. Map link: "Get Directions →" in orange, 14px. **Column 2 — Opening Hours Table:** ``` Monday 8:00am – 6:00pm Tuesday 8:00am – 6:00pm Wednesday 8:00am – 6:00pm Thursday 8:00am – 6:00pm Friday 8:00am – 6:00pm Saturday 8:00am – 4:00pm Sunday Emergency only ``` Rendered as a `<table>` with `border-collapse: collapse`. Each `<tr>` has `padding: 6px 0`. Day names in Plus Jakarta Sans 600, white; times in Plus Jakarta Sans 400, `var(--color-grey-mid)`. **Column 3 — Certifications & Links:** ``` Certifications AA Approved Garage RAC Approved Garage IMI Registered (No. 123456) ASE Certified Technicians Quick Links Book Online View Pricing Get a Quote Contact Us ``` Certifications with small ShieldCheck icon (lucide, 14px, orange) beside each. Links in Plus Jakarta Sans 400, `var(--color-grey-mid)`, hover orange. **Bottom bar (border-top: 1px solid var(--color-border); padding-top: 24px; margin-top: 40px):** ``` © 2024 Axle & Co Auto Repair Ltd. All rights reserved. · Privacy Policy · Terms of Service ``` Center-aligned, Plus Jakarta Sans 400, 13px, `var(--color-grey-dark)`. --- ## 7. ANIMATIONS | Element | Type | Duration | Delay | Easing | |---|---|---|---|---| | Navbar (on load) | Fade in from y:-8 | 0.4s | 0s | ease-out | | Hero eyebrow | Fade in from y:16 | 0.5s | 0.1s | [0.22,1,0.36,1] | | Hero headline | Fade in from y:24 | 0.7s | 0.2s | [0.22,1,0.36,1] | | Hero subhead | Fade in from y:20 | 0.6s | 0.4s | [0.22,1,0.36,1] | | Hero CTAs | Fade in from y:20 | 0.6s | 0.55s | [0.22,1,0.36,1] | | Scroll chevron | Float y:0→8→0 | 2s | — | ease-in-out, repeat:Infinity | | Fixed call bar | Slide from y:80 | 0.35s | — | [0.22,1,0.36,1] | | Service cards | Fade from y:32, stagger | 0.55s | index×0.08s | [0.22,1,0.36,1] | | Service card (hover) | y:-3 | 0.2s | — | ease | | Trust points | Fade from x:-20, stagger | 0.5s | index×0.1s | [0.22,1,0.36,1] | | Team cards | Fade from y:24, stagger | 0.55s | index×0.1s | [0.22,1,0.36,1] | | Trust marquee | Continuous scroll | 35s | — | linear, infinite | | Pricing table rows | Fade from x:-16, stagger | 0.4s | index×0.06s | [0.22,1,0.36,1] | | Emergency section h2 | Fade from y:32 | 0.65s | 0s | [0.22,1,0.36,1] | | Emergency phone number | Fade + scale from 0.95 | 0.5s | 0.2s | [0.22,1,0.36,1] | All `whileInView` animations use `viewport={{ once: true }}` so they fire once on scroll. --- ## 8. RESPONSIVE SPECIFICATIONS ### Desktop (≥1024px) - Services grid: `grid-template-columns: repeat(3, 1fr)` — 2 rows of 3 cards - Trust points: single horizontal row, `flex-wrap: wrap` - Team cards: `repeat(3, 1fr)` - Pricing table: 3 columns visible - Footer: 3-column grid - Marquee text: 17px - Hero text: full `clamp()` scale ### Tablet (640px–1023px) - Services grid: `repeat(2, 1fr)` — 3 rows of 2 cards - Team cards: `repeat(2, 1fr)` - Footer: `repeat(2, 1fr)`, third column wraps to full width - Navbar: hide center nav links, show hamburger - Fixed call bar: reduce font size to 18px, hide supporting text ### Mobile (<640px) - Services grid: `repeat(1, 1fr)` — stacked - Team cards: `repeat(1, 1fr)` — stacked - Footer: single column, stacked - Hero: `min-height: 100svh`, headline at `clamp(44px, 12vw, 70px)` - Pricing table: hide "Avg. Time" column, show "Service" + "From Price" only - Fixed call bar: full width, `font-size: 18px`, just phone number + icon - Trust points: stacked vertically with `gap: 24px` --- ## 9. FULL COPY ### Navbar - Logo: `AXLE & CO` - Nav: `Services` · `About` · `Pricing` · `Reviews` - CTA: `Book Online` ### Hero - Eyebrow: `Trusted Independent Garage · Est. 2008` - Headline line 1: `WE FIX WHAT` - Headline line 2: `OTHERS MISS.` - Subhead: `Honest diagnostics. Fair pricing. Guaranteed work.` - CTA 1: `Book a Service` - CTA 2: `020 7946 0823` - Fixed bar: `CALL NOW: 020 7946 0823` + `Mon–Sat 8am–6pm · Emergency callout available` ### Services Section - Eyebrow: `What We Do` - Headline: `Full-Spectrum Auto Services` - Services: (see services data above) ### Why Choose Us - Headline: `Why Axle & Co?` - Points: (see trust points data above) ### Team Section - Headline: `Meet the Mechanics` - Members: Danny Rowe / Priya Mehta / Carl Hutchins (see data above) ### Pricing Section - Headline: `No Surprises. Just Prices.` - Subhead: `Every price shown is the starting rate — we'll always confirm your exact quote before starting work.` - Footnote: `All prices exclude VAT. Prices are indicative starting rates and may vary by vehicle. We confirm all costs before work begins.` ### Emergency Section - Headline line 1: `BROKEN DOWN?` - Headline line 2: `WE COME TO YOU.` - Phone: `020 7946 0823` - Subtext: `Available 7 days · Usually within 2 hours · No call-out charge within 10 miles` ### Footer - Tagline: `Est. 2008 — trusted independent garage serving South London and the surrounding area. MOT, servicing, repairs, and tyres.` - Address: `Unit 4, Grange Road Industrial Estate, London, SE1 3BT` - Map link: `Get Directions →` - Hours (see column 2 above) - Copyright: `© 2024 Axle & Co Auto Repair Ltd. All rights reserved. · Privacy Policy · Terms of Service` --- ## 10. KEY DEPENDENCIES ```json { "dependencies": { "react": "^18.3.1", "react-dom": "^18.3.1", "motion": "^11.11.0", "lucide-react": "^0.441.0", "tailwindcss": "^3.4.13", "@shadcn/ui": "latest" }, "devDependencies": { "typescript": "^5.5.3", "vite": "^5.4.8", "@vitejs/plugin-react": "^4.3.2" } } ``` **lucide-react icons used:** - `PhoneCall` — fixed call bar + emergency - `ClipboardCheck` — MOT card - `Gauge` — Engine card - `CircleDot` — Brakes card - `Circle` — Tyres card - `Wind` — Air Con card - `ScanLine` — Diagnostics card - `Check` — trust points - `ChevronDown` — hero scroll indicator - `ShieldCheck` — footer certifications - `Menu`, `X` — mobile nav **Important implementation notes:** 1. Import all Framer Motion components from `motion/react`, not `framer-motion` 2. All `whileHover` inside `whileInView` elements require the parent `motion.div` — do not split into separate divs 3. The `IntersectionObserver` for the fixed call bar should observe a `ref` div placed at the bottom edge of the hero `<section>`, triggering when it exits the top of the viewport (threshold: 0) 4. The marquee CSS animation must be defined in `index.css`, not inline styles, for browser compatibility 5. Pricing table on mobile: wrap in a horizontally scrollable div with `-webkit-overflow-scrolling: touch`

The generated results may vary

Categories

Categories

FAQ

What is the signature design element that makes this prompt stand out?

Two elements working together: (1) A persistent fixed orange call bar at the bottom of the viewport — showing the phone number in Space Grotesk 800 — that automatically disappears when the user scrolls past the hero using IntersectionObserver. (2) A massive background watermark of "AXLE" at clamp(240px, 34vw, 520px) rendered in charcoal at just 3% opacity between the photo layer and the gradient overlay, creating depth without distraction.

What sections are included in this prompt?

9 fully specified sections: (1) Sticky Navbar; (2) Full-viewport Hero with gradient, watermark, and fixed call bar; (3) Services Grid — 6 cards; (4) Why Choose Us — 4 trust points; (5) The Team — 3 mechanic portrait cards; (6) Trust Marquee — AA/RAC/IMI certifications; (7) Transparent Pricing — 8-row table; (8) Emergency Section — full orange with large phone number; (9) Footer — 3 columns with hours.

Which AI tools can use this prompt?

Compatible with Lovable, Bolt, v0, Claude, Cursor, and any AI coding tool that accepts React + Vite + TypeScript + Tailwind CSS projects. The prompt uses lucide-react icons and Framer Motion (motion/react) for animations.

Can I customize the copy, branding, and colours?

Yes — all copy is written out in full. Replace the business name, phone number, address, prices, team names, and certifications. The colour system uses CSS custom properties in :root (HSL values) — changing the orange accent to any brand colour updates all cards, chips, borders, and hover states automatically.

Lovable-generated Axle & Co mechanic workshop site in charcoal and signal orange

FAQ

What is the signature design element that makes this prompt stand out?

Two elements working together: (1) A persistent fixed orange call bar at the bottom of the viewport — showing the phone number in Space Grotesk 800 — that automatically disappears when the user scrolls past the hero using IntersectionObserver. (2) A massive background watermark of "AXLE" at clamp(240px, 34vw, 520px) rendered in charcoal at just 3% opacity between the photo layer and the gradient overlay, creating depth without distraction.

What sections are included in this prompt?

9 fully specified sections: (1) Sticky Navbar; (2) Full-viewport Hero with gradient, watermark, and fixed call bar; (3) Services Grid — 6 cards; (4) Why Choose Us — 4 trust points; (5) The Team — 3 mechanic portrait cards; (6) Trust Marquee — AA/RAC/IMI certifications; (7) Transparent Pricing — 8-row table; (8) Emergency Section — full orange with large phone number; (9) Footer — 3 columns with hours.

Which AI tools can use this prompt?

Compatible with Lovable, Bolt, v0, Claude, Cursor, and any AI coding tool that accepts React + Vite + TypeScript + Tailwind CSS projects. The prompt uses lucide-react icons and Framer Motion (motion/react) for animations.

Can I customize the copy, branding, and colours?

Yes — all copy is written out in full. Replace the business name, phone number, address, prices, team names, and certifications. The colour system uses CSS custom properties in :root (HSL values) — changing the orange accent to any brand colour updates all cards, chips, borders, and hover states automatically.

Frequently asked questions

What is websiteprompts.ai?

websiteprompts.ai is a free library of AI website prompts. Each prompt is a ready-to-use text instruction that generates a complete website design when used with an AI website builder like Lovable, Claude, Bolt, v0, or similar tools.

How do I use these prompts?

Copy any prompt from websiteprompts.ai, open your AI website builder of choice — Lovable, Bolt, v0, Claude, ChatGPT, or any other tool — paste the prompt, and let the AI generate your website. No coding or design experience needed.

Are the prompts free?

Yes — every prompt on websiteprompts.ai is completely free. Copy and use them as many times as you like, for personal or commercial projects.

Which AI tools do the prompts work with?

The prompts are designed primarily for Lovable and Bolt, but they work with any AI tool that can generate websites — including v0, Claude, ChatGPT, Cursor, Framer AI, and others.

How often are new prompts added?

New prompts are added every day. The library is constantly growing with prompts for different industries, website types, and design styles.

Do I need any technical skills to use these prompts?

No technical skills required. Copy the prompt, paste it into any AI website builder, and the AI handles the rest. websiteprompts.ai is built for anyone who wants a professional website without writing code.

Frequently asked questions

What is websiteprompts.ai?

websiteprompts.ai is a free library of AI website prompts. Each prompt is a ready-to-use text instruction that generates a complete website design when used with an AI website builder like Lovable, Claude, Bolt, v0, or similar tools.

How do I use these prompts?

Copy any prompt from websiteprompts.ai, open your AI website builder of choice — Lovable, Bolt, v0, Claude, ChatGPT, or any other tool — paste the prompt, and let the AI generate your website. No coding or design experience needed.

Are the prompts free?

Yes — every prompt on websiteprompts.ai is completely free. Copy and use them as many times as you like, for personal or commercial projects.

Which AI tools do the prompts work with?

The prompts are designed primarily for Lovable and Bolt, but they work with any AI tool that can generate websites — including v0, Claude, ChatGPT, Cursor, Framer AI, and others.

How often are new prompts added?

New prompts are added every day. The library is constantly growing with prompts for different industries, website types, and design styles.

Do I need any technical skills to use these prompts?

No technical skills required. Copy the prompt, paste it into any AI website builder, and the AI handles the rest. websiteprompts.ai is built for anyone who wants a professional website without writing code.

Frequently asked questions

What is websiteprompts.ai?

websiteprompts.ai is a free library of AI website prompts. Each prompt is a ready-to-use text instruction that generates a complete website design when used with an AI website builder like Lovable, Claude, Bolt, v0, or similar tools.

How do I use these prompts?

Copy any prompt from websiteprompts.ai, open your AI website builder of choice — Lovable, Bolt, v0, Claude, ChatGPT, or any other tool — paste the prompt, and let the AI generate your website. No coding or design experience needed.

Are the prompts free?

Yes — every prompt on websiteprompts.ai is completely free. Copy and use them as many times as you like, for personal or commercial projects.

Which AI tools do the prompts work with?

The prompts are designed primarily for Lovable and Bolt, but they work with any AI tool that can generate websites — including v0, Claude, ChatGPT, Cursor, Framer AI, and others.

How often are new prompts added?

New prompts are added every day. The library is constantly growing with prompts for different industries, website types, and design styles.

Do I need any technical skills to use these prompts?

No technical skills required. Copy the prompt, paste it into any AI website builder, and the AI handles the rest. websiteprompts.ai is built for anyone who wants a professional website without writing code.

Get new AI website prompts every week — straight to your inbox.

Every Friday we drop a fresh batch of AI website prompts and tips to help you build better websites faster.

Join 1,000+ AI enthusiasts

liquid metallic gradient

Get new AI website prompts every week — straight to your inbox.

Every Friday we drop a fresh batch of AI website prompts and tips to help you build better websites faster.

Join 1,000+ AI enthusiasts

liquid metallic gradient

Get new AI website prompts every week — straight to your inbox.

Every Friday we drop a fresh batch of AI website prompts and tips to help you build better websites faster.

Join 1,000+ AI enthusiasts