Swap to shadcn components and polish the design

Components (added via the shadcn MCP/CLI):
- Navbar: NavigationMenu on desktop, Sheet on mobile; drops
  Navbar.module.css and the hand-rolled slide-down menu
- Buttons: shadcn Button via a shared ContactButtons component
  (replaces Button.js and its CSS module)
- Card for price cards, testimonials, the business block and plan;
  Table for prices; Input/Textarea/Label/NativeSelect/RadioGroup and
  Alert in the quote form; Separator in the footer
- Components import cn from @/lib/utils (not the new "cn" package);
  accordion moved to the unified radix-ui package

Design tweaks:
- Geist Sans is actually applied (font variables were on <body>, but
  Tailwind reads them on <html>, so the site fell back to system fonts)
- Theme primary set to the existing brand blue; slightly smaller radius
- Balanced, tighter heading tracking; muted secondary text
- 44px contact buttons; 16px FAQ text; tighter homepage spacing
- Full-width selects with 16px text on phones (no iOS zoom)

Co-Authored-By: Claude Opus 5.5 <[email protected]>
This commit is contained in:
asownerytandClaude Opus 5.5 committed 2026-09-30 21:25:07 +13:00
1 parent f6846ebaae
commit f916f058fc
36 files changed
+2888 -823

No files matched your search

+44 -49
View File
@@ -2,8 +2,9 @@ import Image from "next/image";
import Link from "next/link";
import styles from "./page.module.css";
import bgimage from "./assets/header-bg.jpg";
import Button from "./components/Button";
import ContactButtons from "./components/ContactButtons";
import MapEmbed from "./components/MapEmbed";
import { Card, CardContent } from "@/components/ui/card";
import ContactForm from "./components/ContactForm";
import FaqList from "./components/FaqList";
import CtaBand from "./components/CtaBand";
@@ -18,10 +19,8 @@ import {
HardDrive,
Laptop,
MapPin,
MessageSquare,
Monitor,
MonitorCog,
Phone,
Power,
ShieldAlert,
Star,
@@ -103,7 +102,7 @@ const steps = [
function SectionCta() {
return (
<p className="text-center mt-8">
<a href={links.tel} className="font-bold text-sky-800 hover:underline">
<a href={links.tel} className="font-semibold text-primary hover:underline">
Call or text {business.phone}
</a>
</p>
@@ -138,16 +137,7 @@ export default function Home() {
tell you what it costs before I start. Local, honest help
for West Auckland.
</p>
<div className="flex flex-col sm:flex-row gap-3 mb-6">
<Button href={links.tel}>
<Phone aria-hidden="true" />
Call {business.phone}
</Button>
<Button href={links.sms} variant="outline">
<MessageSquare aria-hidden="true" />
Text me
</Button>
</div>
<ContactButtons onDark className="mb-6" />
<p className="flex flex-wrap items-center gap-x-2 gap-y-1 text-sm">
<Star
aria-hidden="true"
@@ -169,30 +159,31 @@ export default function Home() {
</div>
</section>
<section className="container mx-auto mb-32">
<section className="container mx-auto mb-24">
<h2 className="text-center text-3xl font-bold mb-2">
Common fixes & prices
</h2>
<p className="text-center mb-8 text-slate-600">
<p className="text-center mb-8 text-muted-foreground">
Labour prices. Parts are extra, and I&apos;ll always quote before
starting.
</p>
<ul className="grid grid-cols-1 sm:grid-cols-2 lg:grid-cols-4 gap-4">
{commonFixes.map(({ icon: Icon, title, price, href }) => (
<li key={title}>
<Link
href={href}
className="flex h-full items-center gap-4 rounded-lg border p-4 transition hover:border-sky-800 hover:shadow-sm"
>
<Icon
aria-hidden="true"
className="size-8 shrink-0 text-sky-800"
strokeWidth={1.5}
/>
<span>
<span className="block font-bold">{title}</span>
<span className="block text-sky-800">{price}</span>
</span>
<Link href={href} className="group block h-full rounded-xl">
<Card className="h-full flex-row items-center gap-4 p-4 shadow-none transition-colors group-hover:border-primary">
<Icon
aria-hidden="true"
className="size-7 shrink-0 text-primary"
strokeWidth={1.5}
/>
<span>
<span className="block font-semibold">{title}</span>
<span className="block text-sm text-muted-foreground">
{price}
</span>
</span>
</Card>
</Link>
</li>
))}
@@ -200,7 +191,7 @@ export default function Home() {
<SectionCta />
<Link
href="/windows-10"
className="mt-8 flex items-center justify-between gap-4 rounded-lg bg-sky-900 p-4 text-white hover:bg-sky-800"
className="mt-8 flex items-center justify-between gap-4 rounded-lg bg-sky-900 p-4 text-white transition-colors hover:bg-primary"
>
<span>
<span className="block font-bold">Still on Windows 10?</span>
@@ -212,15 +203,15 @@ export default function Home() {
</Link>
</section>
<section className="bg-slate-100 py-16 mb-32">
<section className="bg-slate-100 py-16 mb-24">
<div className="container mx-auto">
<h2 className="text-center text-3xl font-bold mb-8">
How it works
</h2>
<ol className="grid grid-cols-1 md:grid-cols-3 gap-8">
{steps.map(({ title, text }, i) => (
<li key={title} className="text-center max-w-sm mx-auto">
<span className="mx-auto mb-4 flex size-12 items-center justify-center rounded-full bg-sky-800 text-xl font-bold text-white">
<li key={title} className="border-t border-slate-300 pt-4">
<span className="mb-3 flex size-8 items-center justify-center rounded-full bg-primary text-sm font-semibold text-primary-foreground">
{i + 1}
</span>
<h3 className="text-xl font-bold mb-2">{title}</h3>
@@ -232,7 +223,7 @@ export default function Home() {
</div>
</section>
<section className="container mx-auto mb-32 max-w-3xl text-center">
<section className="container mx-auto mb-24 max-w-3xl text-center">
<h2 className="text-3xl font-bold mb-4">
Hi, I&apos;m {business.ownerName}
</h2>
@@ -249,22 +240,26 @@ export default function Home() {
<SectionCta />
</section>
<section className="container mx-auto mb-32">
<section className="container mx-auto mb-24">
<h2 className="text-center text-3xl font-bold mb-8">
What customers say
</h2>
<div className="grid grid-cols-1 md:grid-cols-2 gap-6 max-w-4xl mx-auto">
{business.testimonials.map(({ name, quote }) => (
<figure key={name} className="rounded-lg border p-6">
<blockquote className="mb-3">&ldquo;{quote}&rdquo;</blockquote>
<figcaption className="font-bold">{name}</figcaption>
</figure>
<Card key={name} className="shadow-none">
<CardContent>
<figure>
<blockquote className="mb-3">&ldquo;{quote}&rdquo;</blockquote>
<figcaption className="font-semibold">{name}</figcaption>
</figure>
</CardContent>
</Card>
))}
</div>
<p className="text-center mt-8">
<a
href={business.googleBusinessProfileUrl}
className="inline-flex items-center gap-1 font-bold text-sky-800 hover:underline"
className="inline-flex items-center gap-1 font-semibold text-primary hover:underline"
>
Read all reviews on Google
<ArrowRight aria-hidden="true" className="size-4" />
@@ -272,7 +267,7 @@ export default function Home() {
</p>
</section>
<section className="container mx-auto mb-32 flex flex-col gap-8 lg:flex-row">
<section className="container mx-auto mb-24 flex flex-col gap-8 lg:flex-row">
<div className="w-full">
<h2 className="text-3xl font-bold mb-4">Areas I serve</h2>
<p className="mb-4 flex items-start gap-2">
@@ -293,7 +288,7 @@ export default function Home() {
{page ? (
<Link
href={`/areas/${page.slug}`}
className="text-sky-800 hover:underline"
className="text-primary hover:underline"
>
{area}
</Link>
@@ -311,7 +306,7 @@ export default function Home() {
<p className="mt-4">
<a
href={links.tel}
className="font-bold text-sky-800 hover:underline"
className="font-semibold text-primary hover:underline"
>
Call or text {business.phone}
</a>
@@ -322,11 +317,11 @@ export default function Home() {
</div>
</section>
<section className="container mx-auto mb-32">
<div className="rounded-lg border p-6 md:p-8 flex flex-col md:flex-row gap-6 md:items-center">
<section className="container mx-auto mb-24">
<Card className="flex-col gap-6 p-6 shadow-none md:flex-row md:items-center md:p-8">
<Briefcase
aria-hidden="true"
className="size-12 shrink-0 text-sky-800"
className="size-12 shrink-0 text-primary"
strokeWidth={1.5}
/>
<div className="flex-1">
@@ -339,16 +334,16 @@ export default function Home() {
</div>
<Link
href="/business"
className="inline-flex items-center gap-1 font-bold text-sky-800 hover:underline"
className="inline-flex items-center gap-1 font-semibold text-primary hover:underline"
>
Business IT plans
<ArrowRight aria-hidden="true" className="size-4" />
</Link>
</div>
</Card>
</section>
<section
className="container mx-auto max-w-3xl mb-32 scroll-mt-20"
className="container mx-auto max-w-3xl mb-24 scroll-mt-20"
id="faq"
>
<h2 className="text-center text-3xl font-bold mb-8">