A modern, responsive website built with Next.js for the ICPC Asia Pacific Championship. This website features a dynamic theme system, responsive design, and a modular architecture.
- Prerequisites
- Getting Started
- Project Structure
- Architecture
- Styling System
- Theme System
- Components
- Assets Management
- Content Management
- URL Shortener
- Deployment
- Node.js 20.0.0 or later
- npm or yarn package manager
- Clone the repository
git clone https://github.com/Si-plus-plus/icpc-apac- Navigate to the project directory
cd icpc-apac- Install dependencies
npm install- Run the development server
npm run dev- For deployment:
- Local deployment:
chmod +x local-start.sh && ./local-start.sh - Server deployment:
chmod +x deploy.sh && ./deploy.sh
- Local deployment:
icpc-apac/
├── src/
│ ├── app/ # Next.js app directory
│ │ ├── _components/ # Reusable React components
│ │ │ └── pages/ # Page-specific components
│ │ ├── _styles/ # CSS modules for styling
│ │ ├── globals.css # Global styles
│ │ ├── layout.tsx # Root layout component
│ │ └── page.tsx # Home page component
│ ├── lib/ # Utility functions and constants
│ └── interfaces/ # TypeScript interfaces
├── public/ # Static assets
│ ├── assets/ # Images and media files
│ └── favicon/ # Favicon files
├── tailwind.config.ts # Tailwind CSS configuration
└── package.json # Project dependencies and scripts
The website is built using:
- Next.js 14: For server-side rendering and routing
- TypeScript: For type safety
- Tailwind CSS: For styling
- Radix UI: For accessible UI components
- Server-side rendering for better performance
- Dynamic theme switching (light/dark mode)
- Responsive design for all screen sizes
- Modular component architecture
- Markdown content support
The project uses a combination of:
- Tailwind CSS: For utility-first styling
- CSS Modules: For component-specific styles
- Global CSS: For base styles and theme variables
- Primary: Dark Blue (rgba(37, 61, 91, 1))
- Primary Accent: Light Green (rgba(110, 231, 183, 1))
- Secondary: Light Gray (rgba(204, 204, 204, 1))
- Secondary Accent: Pale Cyan (rgba(178, 255, 229, 1))
- Background: Off White (rgba(249, 250, 252, 1))
- Primary: Darker Blue (rgba(26, 43, 60, 1))
- Primary Accent: Dark Green (rgba(16, 185, 129, 1))
- Secondary: Medium Gray (rgba(153, 153, 153, 1))
- Secondary Accent: Dark Teal (rgba(26, 105, 76, 1))
- Background: Dark Blue Gray (rgba(31, 41, 55, 1))
- Font Family: Inter (Google Fonts)
- Heading Sizes:
- h1: 2.5rem (40px)
- h2: 2rem (32px)
- h3: 1.75rem (28px)
- Body Text: 1.125rem (18px)
The theme system is implemented using:
- React Context API for state management
- Local storage for theme persistence
- CSS variables for dynamic theme switching
- System preference detection
- Accessible theme switcher component
- Smooth transitions between themes
- Persists user preference
-
Navbar
- Responsive navigation menu
- Dynamic theme switcher
- Mobile-friendly dropdown
-
Footer
- Sponsor showcase
- Contact information
- Social media links
-
Container
- Responsive padding and width
- Maximum width constraints
- Centered content layout
-
Content
- Markdown rendering
- Syntax highlighting
- Responsive images
-
Intro
- Hero section with background image
- Gradient overlay
- Responsive layout
-
Sponsors
- Grid layout for logos
- Responsive sizing
- Category organization
- Use Next.js Image component for optimization
- Recommended formats: WebP, PNG
- Responsive image sizes
- Lazy loading enabled
- Multiple favicon sizes
- SVG icons when possible
- Web app manifest included
For detailed instructions on managing championship content, see CHAMPIONSHIP_CONTENT_GUIDE.md.
The content guide covers:
- Adding new championship years
- Adding pages and subpages
- Managing sponsor logos
- Working with tables and columns
- File naming conventions
- Troubleshooting common issues
- Championship content:
public/pages/championship/{year}/ - Markdown files: Use date prefix format
YYYYMMDD_filename.md - Ordering: Controlled by
order.jsonfiles in each directory - Sponsors: Defined in
public/pages/championship/{year}/sponsors/sponsors.json
The website supports a simple static URL shortener. This is implemented via a client-side check in the 404 page, which works for both development and static builds (output: export).
- Open
src/shortlinks.json. - Add a new key-value pair where the key is the desired slug/path and the value is the target URL.
{
"livestreams2026": "https://www.youtube.com/playlist?list=PLaSPkFE9cpGR1CzyFXhRLYmzS3Blvodn3"
}