Next.js 15 · TypeScript · Tailwind CSS v4 · shadcn/ui · Motion
- Node.js v22+
- npm
git clone https://github.com/ausracing/ausracingv2.git
cd ausracingv2
npm install
npm run dev- Branch off main:
git checkout -b feature/your-feature - Commit clearly:
git commit -m "component-name: what you did" - Push and open a PR — at least one review before merging
- Never push directly to main
This project uses the Next.js App Router. Every folder inside src/app/ that has a page.tsx becomes a route automatically.
src/app/
├── page.tsx → / (homepage)
├── layout.tsx → wraps every page (Header + Footer live here)
├── car-concept/
│ └── page.tsx → /car-concept
├── team/
│ └── page.tsx → /team
├── sponsors/
│ └── page.tsx → /sponsors
└── media/
└── page.tsx → /medialayout.tsx is the global wrapper. Hashir owns this file — it imports Header and Footer so they appear on every page automatically. Do not add page-specific content here.
| Type | When to use | How |
|---|---|---|
| Server component | Default. Static layout, cards, grids, pages | Nothing — just write your component normally |
| Client component | Needs state, onClick, animations, hooks | Add "use client" as the very first line |
| Dynamic import | Heavy client components (carousel, modal) | const X = dynamic(() => import(...), { ssr: false }) |
Rule of thumb: if it doesn't need interactivity, keep it a server component.
This is js a skeleton Use the current dir structure as a reference on where you are meant to work, as a starting base, as different tasks are delegated the requirements may change, you are free to navigate and work in different parts of the repositry at your own risk
src/
├── app/
│ ├── layout.tsx ← Hashir (global layout)
│ ├── page.tsx ← Everyone adds their section here
│ ├── car-concept/page.tsx ← Yusuf
│ ├── team/page.tsx ← Hashir
│ ├── sponsors/page.tsx ← Yasmeen
│ └── media/page.tsx ← Adam
│
├── components/
│ ├── car-concept/ ← Yusuf
│ │ ├── CarTeaser.tsx
│ │ ├── DepartmentCard.tsx
│ │ └── DepartmentModal.tsx
│ ├── hero/ ← Hashir
│ │ ├── HeroVideo.tsx
│ │ ├── Loader.tsx
│ │ └── AUSParagraph.tsx
│ ├── sponsors/ ← Yasmeen
│ │ ├── SponsorSlider.tsx
│ │ ├── FundingBar.tsx
│ │ ├── QuoteSection.tsx
│ │ └── SponsorTiers.tsx
│ ├── newsletter/ ← Adam
│ │ ├── NewsletterSignup.tsx
│ │ └── NewsletterCard.tsx
│ ├── shared/ ← Hashir (Header), Adam (Footer)
│ │ ├── Header.tsx
│ │ └── Footer.tsx
│ └── ui/ ← shadcn auto-generated. Do not edit manually.
│
public/
├── images/
│ ├── car/ ← car photos (WebP)
│ ├── team/ ← team member photos (WebP)
│ └── sponsors/ ← sponsor logos (WebP)
└── fonts/Defined in src/app/globals.css. The site is always dark themed.
| Utility class | Value | Use for |
|---|---|---|
bg-background |
#000000 |
page backgrounds |
text-foreground |
white | body text |
text-primary |
#F5B041 |
gold accents, headings |
bg-primary |
#F5B041 |
gold buttons, highlights |
text-brand-primary |
#F5B041 |
same gold via brand token |
Check what's already installed:
ls src/components/ui/Add a new component if it's not there:
npx shadcn@latest add <component-name>
# examples:
npx shadcn@latest add carousel
npx shadcn@latest add input
npx shadcn@latest add sonnerFull list: https://ui.shadcn.com/docs/components
Commit the generated file in src/components/ui/ — do not gitignore it.
- Format: WebP only. Convert before adding to
public/. - Always use
next/image, never<img>tags. - Hero/above-fold images: add
priorityprop. - Everything else: add
loading="lazy"(default in next/image). - Always include
alttext — no exceptions.
| Name | Branch | Owns |
|---|---|---|
| Yusuf | feature/car-concept |
CarTeaser, DepartmentCard, DepartmentModal, /car-concept page |
| Hashir | feature/hero |
HeroVideo, Loader, AUSParagraph, Header, layout.tsx, /team page |
| Yasmeen | feature/sponsors |
SponsorSlider, FundingBar, QuoteSection, SponsorTiers, /sponsors page |
| Adam | feature/newsletter |
NewsletterSignup, NewsletterCard, Footer, /media page, performance |
Deploys to Vercel on merge to main. Test your build locally before opening a PR:
npm run build
npm run start