This is the official website for UCI Design-a-thon, built with Next.js 15 and TypeScript. The site is organized by seasons (currently 2025), allowing for easy updates each year while preserving previous years' content.
- Framework: Next.js 15.1.6 with App Router
- Language: TypeScript
- Styling: Tailwind CSS 4.0 with CSS variables
- UI Components: Radix UI + shadcn/ui
- Animation: Framer Motion
- Package Manager: pnpm
- Deployment: Vercel
src/
├── app/
│ ├── (landing)/
│ │ └── (2025)/ # Active season - main landing at /
│ │ ├── fonts/ # Custom fonts
│ │ ├── layout.tsx # Season-specific layout
│ │ └── page.tsx # Landing page
│ ├── archive/ # Archived seasons (when 2026 is live)
│ │ └── 2025/ # Past season accessible at /archive/2025
│ ├── globals.css # Global styles
│ ├── layout.tsx # Root layout
│ ├── robots.ts # SEO
│ └── sitemap.ts # Sitemap
├── components/
│ ├── seasons/
│ │ └── 2025/
│ │ ├── blocks/ # Page sections
│ │ ├── landing/ # Main landing component
│ │ └── navigation/ # Navigation
│ ├── ui/ # Reusable UI components
│ └── common/ # Shared components
└── lib/
└── utils.ts # Utility functions
Each year gets its own folder under src/app/(landing)/ for the active season. You can move previous seasons to src/app/archive/ to remain accessible.
Active Season (src/app/(landing)/(YEAR)/):
- Serves as the main landing page at
/ - Should be the current/upcoming year
Archived Seasons (src/app/archive/YEAR/):
- Past seasons moved here when they're no longer current
- Accessible at
/archive/YEAR - Can be referenced for content or design patterns
To create a new season:
- Archive the current season to
src/app/archive/ - Copy the archived season as starting point
- Update content for the new year
blocks/: Major page sections (Hero, About, Judges, etc.)landing/: Main landing page component that composes all blocksnavigation/: Navigation barui/: Reusable shadcn components
Each season defines its own fonts in the layout file:
- Satoshi: Primary font (variable)
- Radey: Decorative font
- Sour Gummy: Google font
Themes are controlled via data-theme attribute on the body element.
pnpm installpnpm devVisit http://localhost:3000
pnpm buildpnpm lint # ESLint
pnpm format # PrettierFirst, move the current season to the archive so it remains accessible:
mkdir -p src/app/archive
mv src/app/(landing)/(2025) src/app/archive/2025This makes the 2025 site accessible at /archive/2025 instead of /. Update the archive routing if needed by modifying src/app/archive/2025/page.tsx.
Copy the archived season as a starting point:
cp -r src/app/archive/2025 src/app/(landing)/(2026)Edit src/app/(landing)/(2026)/layout.tsx:
- Update title and description
- Update OpenGraph image path
- Modify fonts if needed
- Update
data-themeattribute
Each block in src/components/seasons/2026/blocks/ needs updates:
- Hero: Event date, theme, CTA
- About: Theme description
- Prompt: Design prompt
- Itinerary: Event schedule
- FAQ: Frequently asked questions
- Judges: Judge profiles
- Sponsors: Sponsor logos and links
- Team: Team members
- Past Events: Previous year results
Replace images in public/images/seasons/2026/:
- Landing page images
- Judge photos
- Sponsor logos
- Team photos
Edit src/components/seasons/2026/navigation/landing-navigation.tsx for menu items and links.
Copy season components:
cp -r src/components/seasons/2025 src/components/seasons/2026Then update imports and content in the new season components.
- Main landing page:
src/components/seasons/2025/landing/landing-2025.tsx - Global styles:
src/app/globals.css - Type aliases:
tsconfig.json(paths section) - UI config:
components.json
- Add judge photo to
public/images/seasons/2025/landing/judges/ - Import and add to
src/components/seasons/2025/blocks/judges/index.tsx
- Add logo to
public/images/seasons/2025/landing/sponsors/logos/ - Update
src/components/seasons/2025/blocks/sponsors/index.tsx
Edit the team tabs in src/components/seasons/2025/blocks/team/tabs/:
directors.tsdesign.tsmarketing.tsoperations.tsfinance.tscorporate.ts
- Uses CSS variables for theming
- Custom colors defined in
globals.css - Theme-specific styles via
data-themeattribute
Components use Tailwind utility classes with conditional styles via cn() helper from @/lib/utils.
- Create component in
src/components/seasons/2025/blocks/ - Import in
src/components/seasons/2025/landing/landing-2025.tsx - Add to the render order
Edit src/components/seasons/2025/blocks/itinerary/itinerary-dates.tsx for the schedule.
Edit src/components/seasons/2025/blocks/faq/index.tsx
Update CSS variables in src/app/globals.css under the [data-theme="2025"] selector.
This project is deployed on Vercel. Pushes to main auto-deploy. To manually deploy:
vercel --prodhuskyis configured for pre-commit hookscommitlintenforces conventional commits- Main branch auto-deploys to production
Check font paths in src/app/(landing)/(2025)/layout.tsx and ensure files exist in public/ or fonts/.
Verify image paths in public/images/seasons/2025/ match imports.
Run pnpm install to ensure dependencies are up to date.
| Path | Purpose |
|---|---|
src/app/(landing)/(2025)/page.tsx |
Route entry point |
src/components/seasons/2025/landing/landing-2025.tsx |
Main component |
src/components/ui/ |
Reusable UI components |
public/images/seasons/2025/ |
Season assets |
src/app/globals.css |
Global styles |
When transitioning from 2025 to 2026:
- The 2025 components remain in
src/components/seasons/2025/- only create new ones for 2026 - Update references in
src/app/(landing)/(2026)/page.tsxto import from the new season - Assets can remain in
public/images/seasons/2025/if reused, or copy to 2026 folder - The archived 2025 site will still use
src/components/seasons/2025/components
- Check existing season implementation in
(2025)folder (orarchive/2025once archived) - Review component patterns in
blocks/ - Consult Next.js docs: https://nextjs.org/docs
- Tailwind docs: https://tailwindcss.com/docs