1164 lines
36 KiB
Markdown
1164 lines
36 KiB
Markdown
# UI Design Principles Documentation
|
|
|
|
## School For Schools Interface Design System
|
|
|
|
This document serves as a comprehensive reference guide for understanding and implementing the design principles, visual elements, and user experience patterns used throughout the School For Schools interface.
|
|
|
|
---
|
|
|
|
## Table of Contents
|
|
|
|
1. [Core Design Principles](#core-design-principles)
|
|
2. [Visual Design Elements](#visual-design-elements)
|
|
3. [Component Patterns](#component-patterns)
|
|
4. [User Experience Principles](#user-experience-principles)
|
|
5. [Implementation Examples](#implementation-examples)
|
|
6. [Design System Architecture](#design-system-architecture)
|
|
|
|
---
|
|
|
|
## Core Design Principles
|
|
|
|
### 1. Minimalism & Clarity
|
|
|
|
The interface prioritizes **clarity over decoration**. This philosophy manifests through:
|
|
|
|
- **Clean layouts** with generous white space
|
|
- **Focused content** that eliminates visual noise
|
|
- **Purposeful elements** where every component serves a clear function
|
|
- **Reduced cognitive load** through simplified navigation and information architecture
|
|
|
|
**Rationale**: Educational platforms require users to process complex information. Minimalist design reduces distractions and helps users focus on essential content.
|
|
|
|
### 2. Visual Hierarchy
|
|
|
|
Content is organized through **systematic visual weighting**:
|
|
|
|
- **Typography scale** creates clear information levels (headings, body, captions)
|
|
- **Color contrast** distinguishes primary actions from secondary elements
|
|
- **Spatial relationships** guide the eye through content flow
|
|
- **Size and weight** emphasize importance without overwhelming
|
|
|
|
**Implementation**: The design uses a consistent type scale (4xl-7xl for hero headings, base for body text) and strategic use of the brand orange (`#F48120`) for emphasis.
|
|
|
|
### 3. Consistency & Standards
|
|
|
|
**Unified design language** across all components:
|
|
|
|
- **Shared color palette** applied consistently
|
|
- **Standardized spacing** using Tailwind's spacing scale
|
|
- **Component patterns** reused throughout the interface
|
|
- **Interaction patterns** that users can predict and learn
|
|
|
|
**Rationale**: Consistency reduces learning curve and builds user confidence. Once users understand one section, they can navigate the entire platform intuitively.
|
|
|
|
### 4. Accessibility First
|
|
|
|
Design decisions prioritize **inclusive user experience**:
|
|
|
|
- **Semantic HTML** structure for screen readers
|
|
- **Color contrast ratios** that meet WCAG standards
|
|
- **Keyboard navigation** support throughout
|
|
- **Focus indicators** visible for keyboard users
|
|
- **ARIA labels** where appropriate
|
|
|
|
### 5. Progressive Enhancement
|
|
|
|
The interface is built with **graceful degradation**:
|
|
|
|
- **Core functionality** works without JavaScript
|
|
- **Enhanced interactions** layer on top of base functionality
|
|
- **Responsive design** adapts to all device sizes
|
|
- **Performance optimization** ensures fast load times
|
|
|
|
---
|
|
|
|
## Visual Design Elements
|
|
|
|
### Color Palette
|
|
|
|
The design system uses a **dual-tone color approach** with OKLCH color space for modern color management and perceptual uniformity.
|
|
|
|
#### Brand Colors
|
|
|
|
```css
|
|
--color-orange: #f48120 /* Primary accent, CTAs, hover states */
|
|
--color-dark-grey: #353535 /* Primary text, headings */
|
|
--color-black: #000000 /* Deep emphasis */
|
|
--color-hero-bg: #eaeaea /* Section backgrounds, cards */
|
|
```
|
|
|
|
**Usage Guidelines**:
|
|
|
|
- **Orange (`#F48120`)**: Used sparingly for primary actions, hover states, active navigation items, and key accents. Creates visual interest without overwhelming.
|
|
- **Dark Grey (`#353535`)**: Primary text color, headings, and important UI elements. Provides excellent readability.
|
|
- **Hero Background (`#EAEAEA`)**: Section backgrounds and card containers. Creates subtle separation without harsh contrast.
|
|
- **Black (`#000000`)**: Maximum emphasis, reserved for critical text and deep UI elements.
|
|
|
|
#### Semantic Color System
|
|
|
|
The system includes a comprehensive semantic color palette based on OKLCH:
|
|
|
|
**Light Mode**:
|
|
- `--background`: Pure white (`oklch(1 0 0)`)
|
|
- `--foreground`: Near-black (`oklch(0.145 0 0)`)
|
|
- `--primary`: Dark (`oklch(0.205 0 0)`)
|
|
- `--secondary`: Light grey (`oklch(0.97 0 0)`)
|
|
- `--muted`: Light grey (`oklch(0.97 0 0)`)
|
|
- `--accent`: Light grey (`oklch(0.97 0 0)`)
|
|
- `--border`: Light border (`oklch(0.922 0 0)`)
|
|
- `--destructive`: Red accent (`oklch(0.577 0.245 27.325)`)
|
|
|
|
**Dark Mode**:
|
|
- Complete color inversion while maintaining contrast ratios
|
|
- Perceptually uniform transitions between light and dark themes
|
|
- Consistent brand orange remains prominent
|
|
|
|
#### Color Usage Examples
|
|
|
|
```typescript
|
|
// Primary Action Button
|
|
className="bg-[#F48120] hover:bg-[#F48120]/90"
|
|
|
|
// Text Emphasis
|
|
className="text-[#353535]"
|
|
|
|
// Section Background
|
|
className="bg-[#EAEAEA]"
|
|
|
|
// Card Container
|
|
className="bg-white border border-gray-300"
|
|
```
|
|
|
|
### Typography
|
|
|
|
#### Font Family
|
|
|
|
**Primary Font**: `DIN Alternate`
|
|
|
|
```css
|
|
--font-sans: "DIN Alternate", "Geist", "Geist Fallback"
|
|
```
|
|
|
|
**Rationale**: DIN Alternate provides:
|
|
- **Professional authority** appropriate for educational technology
|
|
- **Excellent readability** at various sizes
|
|
- **Geometric clarity** that aligns with technical content
|
|
- **Modern aesthetic** without being overly decorative
|
|
|
|
**Fallback Chain**: Geist and system fallbacks ensure graceful degradation across platforms.
|
|
|
|
#### Type Scale
|
|
|
|
The typography system uses a **responsive scale** that adapts to screen size:
|
|
|
|
| Element | Mobile | Tablet | Desktop | Usage |
|
|
|---------|--------|--------|---------|-------|
|
|
| Hero Heading | `text-5xl` | `text-6xl` | `text-7xl` | Main page titles |
|
|
| Section Heading | `text-4xl` | `text-5xl` | `text-6xl` | Section titles |
|
|
| Card Title | `text-lg` | `text-xl` | `text-2xl` | Card headings |
|
|
| Body Text | `text-sm` | `text-base` | `text-base` | Paragraph content |
|
|
| Small Text | `text-xs` | `text-sm` | `text-sm` | Captions, meta |
|
|
|
|
**Implementation Example**:
|
|
|
|
```tsx
|
|
<h1 className="text-5xl md:text-6xl lg:text-7xl font-bold text-[#353535]">
|
|
Learning
|
|
</h1>
|
|
```
|
|
|
|
#### Font Weights
|
|
|
|
- **400 (Regular)**: Body text, descriptions
|
|
- **700 (Bold)**: Headings, emphasis, important information
|
|
|
|
**Usage Pattern**: Minimal weight variation maintains clarity while creating hierarchy through size and color.
|
|
|
|
#### Line Height
|
|
|
|
- **Tight** (`leading-tight`): Headings for compact, impactful display
|
|
- **Relaxed** (`leading-relaxed`): Body text for comfortable reading
|
|
- **Normal**: Default for UI elements
|
|
|
|
### Spacing & Layout System
|
|
|
|
#### Container System
|
|
|
|
The layout uses a **constrained width container system**:
|
|
|
|
```tsx
|
|
// Standard Container
|
|
<div className="max-w-7xl mx-auto px-4 sm:px-6 lg:px-8">
|
|
|
|
// Wide Container (for hero sections)
|
|
<div className="max-w-[1200px] mx-auto px-4 sm:px-6 lg:px-8">
|
|
|
|
// Extra Wide Container
|
|
<div className="max-w-[1400px] mx-auto px-4 sm:px-6 lg:px-8">
|
|
```
|
|
|
|
**Rationale**:
|
|
- Prevents content from stretching too wide on large screens
|
|
- Maintains optimal reading line length
|
|
- Creates consistent margins across sections
|
|
|
|
#### Responsive Padding
|
|
|
|
Padding scales with screen size to optimize space usage:
|
|
|
|
- **Mobile**: `px-4` (1rem / 16px)
|
|
- **Tablet**: `sm:px-6` (1.5rem / 24px)
|
|
- **Desktop**: `lg:px-8` (2rem / 32px)
|
|
|
|
#### Vertical Spacing
|
|
|
|
Section spacing follows a consistent rhythm:
|
|
|
|
```tsx
|
|
// Standard Section
|
|
className="py-12 md:py-20 lg:py-24"
|
|
|
|
// Compact Section
|
|
className="py-8 md:py-16"
|
|
|
|
// Hero Section
|
|
className="py-16 md:py-24"
|
|
```
|
|
|
|
**Principle**: Vertical rhythm creates visual breathing room and clearly separates content sections.
|
|
|
|
#### Grid System
|
|
|
|
The interface uses **CSS Grid** for two-dimensional layouts and **Flexbox** for one-dimensional alignment:
|
|
|
|
```tsx
|
|
// Responsive Grid (Why SFS Section)
|
|
<div className="grid grid-cols-1 md:grid-cols-2 lg:grid-cols-5 gap-4">
|
|
|
|
// Card Grid (Offerings)
|
|
<div className="grid grid-cols-1 md:grid-cols-2 gap-8">
|
|
|
|
// Testimonial Grid
|
|
<div className="grid grid-cols-1 md:grid-cols-3 gap-6">
|
|
```
|
|
|
|
**Breakpoint Strategy**:
|
|
- **Mobile First**: Base styles target mobile, then enhance for larger screens
|
|
- **Breakpoints**: `sm:` (640px), `md:` (768px), `lg:` (1024px)
|
|
- **Gap Scaling**: Gap sizes increase with container size
|
|
|
|
### Visual Hierarchy Techniques
|
|
|
|
#### Size Hierarchy
|
|
|
|
1. **Primary**: Hero headings (7xl) - Most important content
|
|
2. **Secondary**: Section headings (4xl-6xl) - Section identification
|
|
3. **Tertiary**: Card titles (lg-xl) - Content grouping
|
|
4. **Body**: Paragraph text (base) - Content consumption
|
|
5. **Meta**: Captions, labels (xs-sm) - Supporting information
|
|
|
|
#### Color Hierarchy
|
|
|
|
- **High Contrast**: Brand orange on key interactive elements
|
|
- **Medium Contrast**: Dark grey for primary content
|
|
- **Low Contrast**: Muted colors for secondary information
|
|
|
|
#### Spatial Hierarchy
|
|
|
|
- **Grouping**: Related items grouped with consistent spacing
|
|
- **Separation**: Sections separated by background colors or significant spacing
|
|
- **Alignment**: Consistent alignment creates visual structure
|
|
|
|
#### Motion Hierarchy
|
|
|
|
Animations are **purposeful and restrained**:
|
|
|
|
- **Micro-interactions**: Hover states, transitions (300ms duration)
|
|
- **Content transitions**: Animated content changes (500-800ms)
|
|
- **Page transitions**: Smooth, non-distracting animations
|
|
|
|
---
|
|
|
|
## Component Patterns
|
|
|
|
### 1. Navigation Pattern
|
|
|
|
The navigation follows a **horizontal menu pattern** with mobile-first responsive behavior:
|
|
|
|
**Desktop**:
|
|
- Horizontal menu with equal spacing (`space-x-8`)
|
|
- Active state indicated by orange color
|
|
- Hover transitions for feedback
|
|
|
|
**Mobile**:
|
|
- Hamburger menu icon
|
|
- Collapsible drawer navigation
|
|
- Full-width touch targets
|
|
|
|
```12:48:components/navbar.tsx
|
|
{/* Desktop Navigation */}
|
|
<div className="hidden md:flex items-center space-x-8">
|
|
{navItems.map((item) => (
|
|
<Link
|
|
key={item.label}
|
|
href={item.href}
|
|
className={`text-sm font-medium transition-colors whitespace-nowrap ${item.isActive ? "text-[#F48120]" : "text-[#353535] hover:text-[#F48120]"
|
|
}`}
|
|
>
|
|
{item.label}
|
|
</Link>
|
|
))}
|
|
</div>
|
|
```
|
|
|
|
**Design Decisions**:
|
|
- **Fixed height** (`h-20`) maintains consistency across pages
|
|
- **Border separation** (`border-b border-gray-200`) subtly separates navigation from content
|
|
- **Transition animations** (`transition-colors`) provide smooth feedback
|
|
|
|
### 2. Hero Section Pattern
|
|
|
|
Hero sections use a **split-screen layout** with animated content:
|
|
|
|
**Characteristics**:
|
|
- Large, bold typography (5xl-7xl)
|
|
- Animated content rotation (4.5s intervals)
|
|
- SVG iconography with drawing animations
|
|
- Fixed-height containers to prevent layout shift
|
|
|
|
```100:130:components/main-hero.tsx
|
|
<section className="relative w-full bg-[#EAEAEA] py-8 md:py-16 overflow-hidden min-h-[600px] flex items-center justify-center">
|
|
<div className="w-full max-w-[1200px] mx-auto px-4 sm:px-6 lg:px-8">
|
|
<div className="grid grid-cols-1 lg:grid-cols-2 gap-4 lg:gap-0 items-center">
|
|
|
|
{/* --- Left Column: Text --- */}
|
|
<div className="flex flex-col justify-center text-center lg:text-left z-10 lg:pl-12">
|
|
<h1 className="text-5xl md:text-6xl lg:text-7xl font-bold text-[#353535] leading-tight">
|
|
Learning
|
|
</h1>
|
|
|
|
{/* Fixed Height Text Container to prevent jumping */}
|
|
<div className="relative h-[220px]">
|
|
<AnimatePresence mode="wait">
|
|
<motion.div
|
|
key={currentContent.id}
|
|
initial={{ opacity: 0, y: 15 }}
|
|
animate={{ opacity: 1, y: 0 }}
|
|
exit={{ opacity: 0, y: -15 }}
|
|
transition={{ duration: 0.5, ease: "easeOut" }}
|
|
className="absolute inset-0 flex flex-col justify-start"
|
|
>
|
|
```
|
|
|
|
**Key Features**:
|
|
- **Fixed-height container** prevents content jumping during animations
|
|
- **Fade + slide transitions** create smooth content changes
|
|
- **Responsive grid** adapts from stacked (mobile) to side-by-side (desktop)
|
|
|
|
### 3. Feature Card Pattern
|
|
|
|
Feature cards use a **hover transformation pattern**:
|
|
|
|
```97:112:components/hero-section.tsx
|
|
<div
|
|
key={index}
|
|
className="group bg-[#E8E8E8] hover:bg-[#F48120] p-6 flex flex-col justify-start transition-colors duration-300 min-h-[220px]"
|
|
>
|
|
<div className="mb-6">
|
|
<div className="w-12 h-12 flex items-center justify-start">
|
|
<Icon className="w-10 h-10 text-[#353535] group-hover:text-white transition-colors duration-300" />
|
|
</div>
|
|
</div>
|
|
<h3 className="text-lg font-bold mb-4 leading-tight text-[#353535] group-hover:text-white transition-colors duration-300">
|
|
{feature.title}
|
|
</h3>
|
|
<p className="text-sm leading-relaxed text-[#353535]/80 group-hover:text-white/90 transition-colors duration-300">
|
|
{feature.description}
|
|
</p>
|
|
</div>
|
|
```
|
|
|
|
**Pattern Elements**:
|
|
- **Group hover**: Entire card responds to hover
|
|
- **Color transformation**: Background shifts from grey to orange
|
|
- **Text inversion**: Text changes to white for contrast
|
|
- **Smooth transitions**: 300ms duration for polished feel
|
|
- **Minimum height**: Ensures consistent card sizing
|
|
|
|
### 4. Offering Card Pattern
|
|
|
|
Larger offering cards use an **aspect-ratio square pattern**:
|
|
|
|
```33:63:components/our-offerings.tsx
|
|
<div
|
|
key={offering.id}
|
|
className="group relative bg-[#EAEAEA] hover:bg-[#353535] transition-colors duration-300 overflow-hidden aspect-square flex flex-col justify-center p-8 md:p-12"
|
|
>
|
|
{/* Icon */}
|
|
<div className="mb-6">
|
|
<offering.icon
|
|
size={48}
|
|
strokeWidth={1.5}
|
|
className="text-[#353535] group-hover:text-[#F48120] transition-colors duration-300"
|
|
/>
|
|
</div>
|
|
|
|
{/* Title */}
|
|
<h3 className="text-3xl font-bold text-[#353535] group-hover:text-white mb-4 transition-colors duration-300">
|
|
{offering.title}
|
|
</h3>
|
|
|
|
{/* Description */}
|
|
<p className="text-base text-[#353535] group-hover:text-white/90 mb-8 leading-relaxed transition-colors duration-300 max-w-sm">
|
|
{offering.description}
|
|
</p>
|
|
|
|
{/* Link */}
|
|
<Link
|
|
href={offering.href}
|
|
className="inline-block text-xs font-bold uppercase tracking-wider text-[#353535] group-hover:text-[#F48120] transition-colors duration-300"
|
|
>
|
|
{offering.linkText}
|
|
</Link>
|
|
</div>
|
|
```
|
|
|
|
**Design Decisions**:
|
|
- **Square aspect ratio**: Creates visual balance and consistency
|
|
- **Centered content**: Uses flexbox to center content vertically
|
|
- **Icon → Title → Description → Link**: Clear information hierarchy
|
|
- **Dark hover state**: Inverts to dark background for dramatic effect
|
|
|
|
### 5. Testimonial Carousel Pattern
|
|
|
|
Testimonials use a **sliding window carousel** with navigation controls:
|
|
|
|
```104:201:components/testimonials.tsx
|
|
<section className="w-full bg-[#EAEAEA] py-16 px-4 md:py-24">
|
|
<div className="max-w-[1100px] mx-auto">
|
|
<h2 className="text-4xl md:text-5xl font-bold text-[#353535] text-center mb-16">
|
|
Testimonials
|
|
</h2>
|
|
|
|
<div className="relative flex items-center justify-center">
|
|
{/* Navigation Buttons */}
|
|
<button
|
|
onClick={handlePrev}
|
|
className="absolute left-0 lg:-left-16 z-10 p-3 rounded-full bg-[#353535] text-white hover:bg-[#F48120] transition-colors"
|
|
aria-label="Previous testimonial"
|
|
>
|
|
<ChevronLeft size={24} />
|
|
</button>
|
|
|
|
<button
|
|
onClick={handleNext}
|
|
className="absolute right-0 lg:-right-16 z-10 p-3 rounded-full bg-[#353535] text-white hover:bg-[#F48120] transition-colors"
|
|
aria-label="Next testimonial"
|
|
>
|
|
<ChevronRight size={24} />
|
|
</button>
|
|
|
|
{/* Carousel Viewport */}
|
|
<div className="w-full overflow-hidden">
|
|
<div className="grid grid-cols-1 md:grid-cols-3 gap-6">
|
|
<AnimatePresence mode="popLayout">
|
|
{visibleTestimonials.map((testimonial) => (
|
|
<motion.div
|
|
key={`${testimonial.id}-${startIndex}`}
|
|
initial={{ opacity: 0, x: 20 }}
|
|
animate={{ opacity: 1, x: 0 }}
|
|
exit={{ opacity: 0, x: -20 }}
|
|
transition={{ duration: 0.3 }}
|
|
className="h-full"
|
|
>
|
|
{/*
|
|
Card Design:
|
|
- White background
|
|
- Padding around
|
|
- Inner border that changes color on hover
|
|
*/}
|
|
<div className="group bg-white p-4 h-full cursor-pointer transition-shadow hover:shadow-lg">
|
|
<div className="w-full h-full min-h-[480px] border border-gray-300 group-hover:border-[#F48120] transition-colors duration-300 p-6 md:p-8 flex flex-col items-center text-center">
|
|
```
|
|
|
|
**Pattern Features**:
|
|
- **External navigation**: Buttons positioned outside content area
|
|
- **Sliding animation**: Smooth fade + slide transitions
|
|
- **Border hover effect**: Border color changes on hover
|
|
- **Fixed card height**: Prevents layout shift during transitions
|
|
- **Touch-friendly**: Large hit targets for mobile users
|
|
|
|
### 6. Infinite Marquee Pattern
|
|
|
|
The "Trusted By" section uses a **seamless infinite scroll**:
|
|
|
|
```22:60:components/trusted-by.tsx
|
|
{/* Infinite Marquee Container */}
|
|
<div className="relative w-full flex overflow-hidden">
|
|
{/* We need two sets of logos for seamless looping */}
|
|
<motion.div
|
|
className="flex gap-12 items-center"
|
|
animate={{
|
|
x: ["0%", "-50%"],
|
|
}}
|
|
transition={{
|
|
x: {
|
|
repeat: Infinity,
|
|
repeatType: "loop",
|
|
duration: 20, // Adjust speed here
|
|
ease: "linear",
|
|
},
|
|
}}
|
|
style={{ width: "max-content" }}
|
|
>
|
|
{/* Set 1 */}
|
|
{SCHOOLS.map((school) => (
|
|
<div key={`a-${school.id}`} className="min-w-[280px] h-[160px] flex items-center justify-center">
|
|
<img
|
|
src="/images/partnerSchool.png"
|
|
alt="Partner School"
|
|
className="max-h-full w-auto object-contain"
|
|
/>
|
|
</div>
|
|
))}
|
|
{/* Set 2 (Duplicate) */}
|
|
{SCHOOLS.map((school) => (
|
|
<div key={`b-${school.id}`} className="min-w-[280px] h-[160px] flex items-center justify-center">
|
|
<img
|
|
src="/images/partnerSchool.png"
|
|
alt="Partner School"
|
|
className="max-h-full w-auto object-contain"
|
|
/>
|
|
</div>
|
|
))}
|
|
</motion.div>
|
|
</div>
|
|
```
|
|
|
|
**Implementation Strategy**:
|
|
- **Duplicate content**: Two identical sets of logos
|
|
- **50% translation**: Animation moves exactly one set width
|
|
- **Linear easing**: Creates seamless, continuous motion
|
|
- **Performance**: Uses GPU-accelerated transforms
|
|
|
|
### 7. Button Component Pattern
|
|
|
|
Buttons follow a **variant-based system** using class-variance-authority:
|
|
|
|
```7:37:components/ui/button.tsx
|
|
const buttonVariants = cva(
|
|
"inline-flex items-center justify-center gap-2 whitespace-nowrap rounded-md text-sm font-medium transition-all disabled:pointer-events-none disabled:opacity-50 [&_svg]:pointer-events-none [&_svg:not([class*='size-'])]:size-4 shrink-0 [&_svg]:shrink-0 outline-none focus-visible:border-ring focus-visible:ring-ring/50 focus-visible:ring-[3px] aria-invalid:ring-destructive/20 dark:aria-invalid:ring-destructive/40 aria-invalid:border-destructive",
|
|
{
|
|
variants: {
|
|
variant: {
|
|
default: 'bg-primary text-primary-foreground hover:bg-primary/90',
|
|
destructive:
|
|
'bg-destructive text-white hover:bg-destructive/90 focus-visible:ring-destructive/20 dark:focus-visible:ring-destructive/40 dark:bg-destructive/60',
|
|
outline:
|
|
'border bg-background shadow-xs hover:bg-accent hover:text-accent-foreground dark:bg-input/30 dark:border-input dark:hover:bg-input/50',
|
|
secondary:
|
|
'bg-secondary text-secondary-foreground hover:bg-secondary/80',
|
|
ghost:
|
|
'hover:bg-accent hover:text-accent-foreground dark:hover:bg-accent/50',
|
|
link: 'text-primary underline-offset-4 hover:underline',
|
|
},
|
|
size: {
|
|
default: 'h-9 px-4 py-2 has-[>svg]:px-3',
|
|
sm: 'h-8 rounded-md gap-1.5 px-3 has-[>svg]:px-2.5',
|
|
lg: 'h-10 rounded-md px-6 has-[>svg]:px-4',
|
|
icon: 'size-9',
|
|
'icon-sm': 'size-8',
|
|
'icon-lg': 'size-10',
|
|
},
|
|
},
|
|
defaultVariants: {
|
|
variant: 'default',
|
|
size: 'default',
|
|
},
|
|
},
|
|
)
|
|
```
|
|
|
|
**Design Principles**:
|
|
- **Accessibility**: Focus states, ARIA support, keyboard navigation
|
|
- **Consistency**: Standardized sizes and spacing
|
|
- **Flexibility**: Multiple variants for different contexts
|
|
- **Icon support**: Automatic spacing adjustments for icons
|
|
|
|
### 8. Card Component Pattern
|
|
|
|
Cards provide a **composable container system**:
|
|
|
|
```5:15:components/ui/card.tsx
|
|
function Card({ className, ...props }: React.ComponentProps<'div'>) {
|
|
return (
|
|
<div
|
|
data-slot="card"
|
|
className={cn(
|
|
'bg-card text-card-foreground flex flex-col gap-6 rounded-xl border py-6 shadow-sm',
|
|
className,
|
|
)}
|
|
{...props}
|
|
/>
|
|
)
|
|
}
|
|
```
|
|
|
|
**Composition Pattern**:
|
|
- **Card**: Base container
|
|
- **CardHeader**: Header section with title/description
|
|
- **CardTitle**: Heading within card
|
|
- **CardDescription**: Supporting text
|
|
- **CardContent**: Main content area
|
|
- **CardFooter**: Footer actions/info
|
|
|
|
**Usage**: Allows flexible composition while maintaining consistent styling.
|
|
|
|
---
|
|
|
|
## User Experience Principles
|
|
|
|
### Navigation Structure
|
|
|
|
#### Information Architecture
|
|
|
|
The site follows a **shallow navigation hierarchy**:
|
|
|
|
```
|
|
Home
|
|
├── About
|
|
├── ERP
|
|
├── Tech Lab Setup
|
|
├── Resources
|
|
└── Contact
|
|
```
|
|
|
|
**Rationale**: Flat structure reduces cognitive load and allows quick access to any section.
|
|
|
|
#### Navigation Patterns
|
|
|
|
1. **Primary Navigation**: Horizontal menu (desktop), hamburger (mobile)
|
|
2. **Section Navigation**: Anchor links for long pages
|
|
3. **Breadcrumbs**: Not implemented (shallow structure doesn't require them)
|
|
4. **Footer Navigation**: Quick links for common destinations
|
|
|
|
#### Mobile Navigation
|
|
|
|
- **Hamburger menu**: Collapses navigation to save screen space
|
|
- **Full-width items**: Touch-friendly targets
|
|
- **Smooth transitions**: Slide-in animation for drawer
|
|
- **Overlay behavior**: Menu overlays content when open
|
|
|
|
### Interaction Patterns
|
|
|
|
#### Hover States
|
|
|
|
**Consistent hover feedback** across all interactive elements:
|
|
|
|
- **Links**: Color change to brand orange (300ms transition)
|
|
- **Buttons**: Background opacity change (10% darker)
|
|
- **Cards**: Background color transformation + shadow
|
|
- **Icons**: Color change matching context
|
|
|
|
**Implementation**:
|
|
|
|
```tsx
|
|
// Link hover
|
|
className="text-[#353535] hover:text-[#F48120] transition-colors"
|
|
|
|
// Button hover
|
|
className="bg-[#353535] hover:bg-[#F48120] transition-colors"
|
|
|
|
// Card hover
|
|
className="group hover:bg-[#F48120] transition-colors duration-300"
|
|
```
|
|
|
|
#### Click Feedback
|
|
|
|
- **Visual feedback**: Immediate color change on click
|
|
- **Transition animations**: Smooth state changes
|
|
- **Loading states**: Spinners or disabled states for async actions
|
|
- **Success feedback**: Visual confirmation when actions complete
|
|
|
|
#### Animation Philosophy
|
|
|
|
**Principle**: Animations should feel **natural and purposeful**, not decorative.
|
|
|
|
**Guidelines**:
|
|
- **Duration**: 300ms for micro-interactions, 500-800ms for content transitions
|
|
- **Easing**: `ease-out` for most transitions (feels responsive)
|
|
- **Reduced motion**: Respects `prefers-reduced-motion` media query
|
|
- **Performance**: Uses GPU-accelerated properties (transform, opacity)
|
|
|
|
**Example Implementation**:
|
|
|
|
```tsx
|
|
// Smooth content transition
|
|
<motion.div
|
|
initial={{ opacity: 0, y: 15 }}
|
|
animate={{ opacity: 1, y: 0 }}
|
|
exit={{ opacity: 0, y: -15 }}
|
|
transition={{ duration: 0.5, ease: "easeOut" }}
|
|
>
|
|
```
|
|
|
|
### Accessibility Considerations
|
|
|
|
#### Semantic HTML
|
|
|
|
All components use **appropriate semantic elements**:
|
|
|
|
- `<nav>` for navigation
|
|
- `<main>` for main content
|
|
- `<section>` for content sections
|
|
- `<article>` for independent content blocks
|
|
- `<header>` and `<footer>` for page structure
|
|
|
|
#### ARIA Labels
|
|
|
|
Interactive elements include descriptive labels:
|
|
|
|
```tsx
|
|
<button
|
|
onClick={handlePrev}
|
|
aria-label="Previous testimonial"
|
|
>
|
|
```
|
|
|
|
#### Keyboard Navigation
|
|
|
|
- **Tab order**: Logical flow through interactive elements
|
|
- **Focus indicators**: Visible focus rings on all interactive elements
|
|
- **Skip links**: Allows bypassing navigation (when implemented)
|
|
- **Keyboard shortcuts**: Standard browser shortcuts work throughout
|
|
|
|
#### Color Contrast
|
|
|
|
All text meets **WCAG AA standards**:
|
|
|
|
- **Normal text**: Minimum 4.5:1 contrast ratio
|
|
- **Large text**: Minimum 3:1 contrast ratio
|
|
- **Interactive elements**: Clear visual distinction from non-interactive
|
|
|
|
#### Screen Reader Support
|
|
|
|
- **Alt text**: All images include descriptive alt attributes
|
|
- **Heading hierarchy**: Proper h1-h6 structure
|
|
- **Form labels**: Associated with form controls
|
|
- **Live regions**: Announce dynamic content changes
|
|
|
|
### Responsive Design Approach
|
|
|
|
#### Mobile-First Strategy
|
|
|
|
Design starts with **mobile constraints**, then enhances for larger screens:
|
|
|
|
1. **Base styles**: Target mobile (320px+)
|
|
2. **Tablet enhancements**: `md:` breakpoint (768px+)
|
|
3. **Desktop enhancements**: `lg:` breakpoint (1024px+)
|
|
|
|
#### Breakpoint System
|
|
|
|
| Breakpoint | Min Width | Usage |
|
|
|------------|-----------|-------|
|
|
| `sm:` | 640px | Small tablets |
|
|
| `md:` | 768px | Tablets, small desktops |
|
|
| `lg:` | 1024px | Desktop |
|
|
| `xl:` | 1280px | Large desktop (when needed) |
|
|
|
|
#### Responsive Patterns
|
|
|
|
**Typography Scaling**:
|
|
```tsx
|
|
className="text-4xl md:text-5xl lg:text-6xl"
|
|
```
|
|
|
|
**Layout Adaptation**:
|
|
```tsx
|
|
// Stacked on mobile, side-by-side on desktop
|
|
className="grid grid-cols-1 lg:grid-cols-2"
|
|
```
|
|
|
|
**Spacing Adjustment**:
|
|
```tsx
|
|
className="px-4 sm:px-6 lg:px-8 py-12 md:py-20 lg:py-24"
|
|
```
|
|
|
|
**Navigation Transformation**:
|
|
- Mobile: Hamburger menu
|
|
- Desktop: Horizontal navigation bar
|
|
|
|
#### Touch Targets
|
|
|
|
- **Minimum size**: 44x44px for touch targets (iOS/Android guidelines)
|
|
- **Spacing**: Adequate space between interactive elements
|
|
- **Gestures**: Support standard swipe and pinch gestures
|
|
|
|
### Content Strategy
|
|
|
|
#### Progressive Disclosure
|
|
|
|
Complex information is **revealed progressively**:
|
|
|
|
- **Hero sections**: High-level value proposition
|
|
- **Feature sections**: Detailed benefits
|
|
- **Testimonials**: Social proof
|
|
- **Contact**: Call-to-action
|
|
|
|
#### Content Hierarchy
|
|
|
|
1. **Headline**: Captures attention (hero heading)
|
|
2. **Subheadline**: Provides context (section description)
|
|
3. **Body**: Detailed information (feature cards, descriptions)
|
|
4. **Actions**: Clear next steps (CTA buttons, links)
|
|
|
|
#### Reading Patterns
|
|
|
|
Layout respects **common reading patterns**:
|
|
|
|
- **F-pattern**: Top-heavy content placement
|
|
- **Z-pattern**: For pages with strong CTAs
|
|
- **Visual flow**: Eye follows natural progression
|
|
|
|
---
|
|
|
|
## Implementation Examples
|
|
|
|
### Color System Implementation
|
|
|
|
The color system uses **CSS custom properties** for theme support:
|
|
|
|
```css
|
|
:root {
|
|
--color-orange: #f48120;
|
|
--color-dark-grey: #353535;
|
|
--color-hero-bg: #eaeaea;
|
|
}
|
|
|
|
.dark {
|
|
/* Dark mode color overrides */
|
|
}
|
|
```
|
|
|
|
**Usage in Components**:
|
|
|
|
```tsx
|
|
// Direct color usage
|
|
className="bg-[#F48120] text-[#353535]"
|
|
|
|
// CSS variable usage (when implemented)
|
|
className="bg-[var(--color-orange)]"
|
|
```
|
|
|
|
### Typography Implementation
|
|
|
|
Font family is set globally in the root layout:
|
|
|
|
```20:20:app/layout.tsx
|
|
<body className="font-sans antialiased" style={{ fontFamily: "DIN Alternate, sans-serif" }} suppressHydrationWarning>
|
|
```
|
|
|
|
**Responsive Typography**:
|
|
|
|
```tsx
|
|
<h1 className="text-5xl md:text-6xl lg:text-7xl font-bold">
|
|
Learning
|
|
</h1>
|
|
```
|
|
|
|
### Component Composition Example
|
|
|
|
**Feature Card Component**:
|
|
|
|
```tsx
|
|
<div className="group bg-[#E8E8E8] hover:bg-[#F48120] p-6
|
|
flex flex-col justify-start transition-colors
|
|
duration-300 min-h-[220px]">
|
|
{/* Icon */}
|
|
<div className="mb-6">
|
|
<Icon className="w-10 h-10 text-[#353535]
|
|
group-hover:text-white transition-colors
|
|
duration-300" />
|
|
</div>
|
|
|
|
{/* Title */}
|
|
<h3 className="text-lg font-bold mb-4 leading-tight
|
|
text-[#353535] group-hover:text-white
|
|
transition-colors duration-300">
|
|
{title}
|
|
</h3>
|
|
|
|
{/* Description */}
|
|
<p className="text-sm leading-relaxed text-[#353535]/80
|
|
group-hover:text-white/90 transition-colors
|
|
duration-300">
|
|
{description}
|
|
</p>
|
|
</div>
|
|
```
|
|
|
|
**Key Patterns**:
|
|
- **Group hover**: Entire card responds to hover
|
|
- **Consistent transitions**: All color changes use 300ms
|
|
- **Minimum height**: Prevents layout shift
|
|
- **Opacity variations**: Uses `/80` and `/90` for text hierarchy
|
|
|
|
### Animation Implementation
|
|
|
|
**Content Transition** (Hero Section):
|
|
|
|
```tsx
|
|
<AnimatePresence mode="wait">
|
|
<motion.div
|
|
key={currentContent.id}
|
|
initial={{ opacity: 0, y: 15 }}
|
|
animate={{ opacity: 1, y: 0 }}
|
|
exit={{ opacity: 0, y: -15 }}
|
|
transition={{ duration: 0.5, ease: "easeOut" }}
|
|
>
|
|
{/* Content */}
|
|
</motion.div>
|
|
</AnimatePresence>
|
|
```
|
|
|
|
**SVG Drawing Animation**:
|
|
|
|
```tsx
|
|
<motion.path
|
|
d={shape.path}
|
|
fill="currentColor"
|
|
initial={{ pathLength: 0, fillOpacity: 0 }}
|
|
animate={{ pathLength: 1, fillOpacity: 1 }}
|
|
transition={{ duration: 0.8, ease: "easeInOut" }}
|
|
/>
|
|
```
|
|
|
|
### Responsive Grid Implementation
|
|
|
|
```tsx
|
|
// Adaptive grid: 1 column mobile, 2 tablet, 5 desktop
|
|
<div className="grid grid-cols-1 md:grid-cols-2 lg:grid-cols-5 gap-4">
|
|
{items.map(item => (
|
|
<Card key={item.id} {...item} />
|
|
))}
|
|
</div>
|
|
```
|
|
|
|
---
|
|
|
|
## Design System Architecture
|
|
|
|
### Technology Stack
|
|
|
|
- **Framework**: Next.js 16 (React 19)
|
|
- **Styling**: Tailwind CSS 4.x
|
|
- **UI Components**: shadcn/ui (New York variant)
|
|
- **Animations**: Framer Motion
|
|
- **Icons**: Lucide React
|
|
- **Form Handling**: React Hook Form + Zod
|
|
- **Theme**: next-themes (dark mode support)
|
|
|
|
### File Structure
|
|
|
|
```
|
|
components/
|
|
├── ui/ # Base UI components (shadcn/ui)
|
|
├── navbar.tsx # Navigation component
|
|
├── main-hero.tsx # Hero section
|
|
├── hero-section.tsx # Why SFS section
|
|
├── our-offerings.tsx
|
|
├── testimonials.tsx
|
|
└── footer.tsx
|
|
|
|
app/
|
|
├── globals.css # Global styles, CSS variables
|
|
└── layout.tsx # Root layout
|
|
|
|
lib/
|
|
└── utils.ts # Utility functions (cn helper)
|
|
```
|
|
|
|
### CSS Architecture
|
|
|
|
**Layers** (using Tailwind's layer system):
|
|
|
|
1. **Base**: Reset styles, typography defaults
|
|
2. **Components**: Reusable component styles
|
|
3. **Utilities**: Utility classes (Tailwind)
|
|
|
|
**Custom Properties**:
|
|
|
|
```css
|
|
:root {
|
|
/* Color tokens */
|
|
--color-orange: #f48120;
|
|
|
|
/* Spacing tokens */
|
|
--radius: 0.625rem;
|
|
|
|
/* Typography tokens */
|
|
--font-sans: "DIN Alternate", ...;
|
|
}
|
|
```
|
|
|
|
### Component Architecture
|
|
|
|
**Pattern**: Compound components with composition
|
|
|
|
```tsx
|
|
// Base component
|
|
<Card>
|
|
<CardHeader>
|
|
<CardTitle>Title</CardTitle>
|
|
<CardDescription>Description</CardDescription>
|
|
</CardHeader>
|
|
<CardContent>
|
|
{/* Content */}
|
|
</CardContent>
|
|
</Card>
|
|
```
|
|
|
|
**Benefits**:
|
|
- **Flexibility**: Mix and match sub-components
|
|
- **Consistency**: Shared styling through base component
|
|
- **Maintainability**: Single source of truth for styles
|
|
|
|
### Theme System
|
|
|
|
**Implementation**: CSS custom properties + class-based dark mode
|
|
|
|
```css
|
|
:root {
|
|
--background: oklch(1 0 0); /* Light mode */
|
|
}
|
|
|
|
.dark {
|
|
--background: oklch(0.145 0 0); /* Dark mode */
|
|
}
|
|
```
|
|
|
|
**Switching**: Uses `next-themes` for persistent theme preference
|
|
|
|
### Utility Functions
|
|
|
|
**Class Name Merging**:
|
|
|
|
```1:6:lib/utils.ts
|
|
import { clsx, type ClassValue } from 'clsx'
|
|
import { twMerge } from 'tailwind-merge'
|
|
|
|
export function cn(...inputs: ClassValue[]) {
|
|
return twMerge(clsx(inputs))
|
|
}
|
|
```
|
|
|
|
**Usage**: Ensures Tailwind classes merge correctly and resolves conflicts.
|
|
|
|
---
|
|
|
|
## Design Rationale: Before & After Examples
|
|
|
|
### Example 1: Feature Card Hover State
|
|
|
|
**Before**: Static cards with no interaction feedback
|
|
|
|
**After**: Interactive cards with:
|
|
- Background color transformation (grey → orange)
|
|
- Text color inversion (dark → white)
|
|
- Smooth 300ms transitions
|
|
- Visual feedback that guides user attention
|
|
|
|
**Impact**:
|
|
- **Engagement**: Users understand cards are interactive
|
|
- **Visual interest**: Hover states add dynamism
|
|
- **Hierarchy**: Active cards stand out
|
|
|
|
### Example 2: Hero Section Layout
|
|
|
|
**Before**: Single-column text-only hero
|
|
|
|
**After**: Two-column split layout with:
|
|
- Large typography for impact
|
|
- Animated SVG icons for visual interest
|
|
- Content rotation for engagement
|
|
- Fixed-height containers for stability
|
|
|
|
**Impact**:
|
|
- **Visual balance**: Text and graphics create harmony
|
|
- **Information density**: More content in same space
|
|
- **Engagement**: Animations keep users interested
|
|
|
|
### Example 3: Responsive Navigation
|
|
|
|
**Before**: Horizontal menu that overflows on mobile
|
|
|
|
**After**: Adaptive navigation with:
|
|
- Horizontal menu on desktop
|
|
- Collapsible hamburger menu on mobile
|
|
- Touch-friendly full-width targets
|
|
- Smooth slide-in animation
|
|
|
|
**Impact**:
|
|
- **Usability**: Navigation accessible on all devices
|
|
- **Space efficiency**: Mobile menu doesn't clutter screen
|
|
- **Consistency**: Same functionality across breakpoints
|
|
|
|
---
|
|
|
|
## Best Practices & Guidelines
|
|
|
|
### When Adding New Components
|
|
|
|
1. **Follow existing patterns**: Use similar component structure
|
|
2. **Maintain color consistency**: Use established color palette
|
|
3. **Implement hover states**: All interactive elements need feedback
|
|
4. **Ensure accessibility**: ARIA labels, keyboard navigation, focus states
|
|
5. **Test responsive behavior**: Verify mobile, tablet, desktop views
|
|
6. **Use semantic HTML**: Appropriate HTML elements
|
|
7. **Add animations thoughtfully**: Purposeful, not decorative
|
|
|
|
### Color Usage Guidelines
|
|
|
|
- **Brand Orange**: Primary actions, hover states, active states
|
|
- **Dark Grey**: Text, headings, primary UI elements
|
|
- **Light Grey**: Backgrounds, subtle separations
|
|
- **White**: Card backgrounds, contrast elements
|
|
|
|
### Typography Guidelines
|
|
|
|
- **Headings**: Use font-bold with appropriate size scale
|
|
- **Body text**: Use default weight (400) with leading-relaxed
|
|
- **Small text**: Use text-xs or text-sm for captions
|
|
- **Line height**: Tight for headings, relaxed for body
|
|
|
|
### Spacing Guidelines
|
|
|
|
- **Between sections**: py-12 md:py-20 lg:py-24
|
|
- **Within cards**: p-6 or p-8
|
|
- **Grid gaps**: gap-4, gap-6, or gap-8 depending on content
|
|
- **Container padding**: px-4 sm:px-6 lg:px-8
|
|
|
|
### Animation Guidelines
|
|
|
|
- **Micro-interactions**: 300ms duration
|
|
- **Content transitions**: 500-800ms duration
|
|
- **Easing**: ease-out or ease-in-out
|
|
- **Reduce motion**: Respect user preferences
|
|
|
|
---
|
|
|
|
## Conclusion
|
|
|
|
This design system prioritizes **clarity, consistency, and user experience**. By following these principles and patterns, new features and components will integrate seamlessly with the existing interface while maintaining the professional, modern aesthetic that defines School For Schools.
|
|
|
|
The system is built on **solid foundations** (Tailwind CSS, shadcn/ui, React) that provide flexibility while enforcing consistency. As the platform evolves, these principles should guide design decisions to ensure the interface remains cohesive and user-friendly.
|
|
|
|
---
|
|
|
|
**Document Version**: 1.0
|
|
**Last Updated**: 2025
|
|
**Maintained By**: Design & Development Team
|
|
|
|
|