BUY-2236: Fashion & Apparel Category Page Template — Design Specification
Overview
This document specifies the design for the Fashion & Apparel category page template (/category/fashion). It is part of 5 category template designs owed in the sprint (per BUY-2235). Template #2 (Electronics) follows this one.
Page Structure
┌─────────────────────────────────────────────────────────────┐
│ HEADER (site-wide) │
├─────────────────────────────────────────────────────────────┤
│ CATEGORY HERO │
│ ├─ Breadcrumb │
│ ├─ Dynamic Title (e.g., "Fashion & Apparel") │
│ └─ Product Count │
├─────────────────────────────────────────────────────────────┤
│ SUBCATEGORY NAV (horizontal pill tabs) │
├──────────────┬──────────────────────────────────────────────┤
│ FILTER RAIL │ PRODUCT AREA │
│ (left, 280px)│ ├─ Toolbar (sort, view toggle, result count)│
│ │ └─ Product Grid / List │
│ - Brand │ │
│ - Price │ │
│ - Size │ │
│ - Color │ │
│ - Avail. │ │
│ - Region │ │
└──────────────┴──────────────────────────────────────────────┘
Design Tokens (Reference: Iris Design System BUY-2150)
Color Palette
| Token | Hex | Usage |
|---|---|---|
--color-primary | #1a1a2e | Text, headings |
--color-accent | #e94560 | CTAs, active states, price discount |
--color-surface | #ffffff | Card backgrounds |
--color-bg | #f8f9fa | Page background |
--color-muted | #6c757d | Secondary text, metadata |
--color-border | #dee2e6 | Dividers, card borders |
--color-success | #28a745 | In-stock indicator |
--color-warning | #ffc107 | Low stock |
--color-error | #dc3545 | Out of stock, errors |
Typography
| Token | Value | Usage |
|---|---|---|
--font-heading | Inter, -apple-system, sans-serif | H1, H2, H3 |
--font-body | Inter, -apple-system, sans-serif | Body text |
--font-mono | SFMono-Regular, monospace | Price, SKU |
Type Scale
| Token | Size | Weight | Line Height | Usage |
|---|---|---|---|---|
--text-xs | 12px | 400 | 1.4 | Badges, captions |
--text-sm | 14px | 400 | 1.5 | Secondary text |
--text-base | 16px | 400 | 1.5 | Body |
--text-lg | 18px | 500 | 1.4 | Card titles |
--text-xl | 20px | 600 | 1.3 | Section headings |
--text-2xl | 24px | 700 | 1.2 | Category title |
--text-3xl | 32px | 700 | 1.1 | Hero title |
Spacing Scale
| Token | Value | Usage |
|---|---|---|
--space-1 | 4px | Tight gaps |
--space-2 | 8px | Icon gaps |
--space-3 | 12px | Card padding (sm) |
--space-4 | 16px | Card padding, gaps |
--space-5 | 20px | Section padding |
--space-6 | 24px | Container padding |
--space-8 | 32px | Section gaps |
--space-10 | 40px | Large section gaps |
--space-12 | 48px | Hero padding |
Border Radius
| Token | Value | Usage |
|---|---|---|
--radius-sm | 4px | Buttons, inputs |
--radius-md | 8px | Cards |
--radius-lg | 12px | Modals, panels |
--radius-full | 9999px | Pills, swatches |
Shadows
| Token | Value | Usage |
|---|---|---|
--shadow-sm | 0 1px 3px rgba(0,0,0,0.08) | Card hover |
--shadow-md | 0 4px 12px rgba(0,0,0,0.10) | Dropdowns, modals |
--shadow-lg | 0 8px 24px rgba(0,0,0,0.12) | Sticky headers |
Breakpoints
| Name | Width | Usage |
|---|---|---|
| sm | 640px | Large phones |
| md | 768px | Tablets, mobile |
| lg | 1024px | Small laptops |
| xl | 1280px | Desktops |
Component Specifications
1. Category Hero
Desktop (height: 160px)
- Background:
--color-bgwith subtle gradient overlay - Breadcrumb:
Home / Fashion / Women's Clothing- Font:
--text-sm,--color-muted - Separator:
›(Unicode \u203A) - Current page:
--color-primary, no link
- Font:
- Title: Dynamic from category (e.g., "Women's Clothing")
- Font:
--text-3xl,--font-heading,--color-primary
- Font:
- Product count: "{{ total }} products"
- Font:
--text-sm,--color-muted - Position: Below title
- Font:
Mobile (height: 120px)
- Title:
--text-2xl - Breadcrumb collapsed to Home > [Category]
2. Subcategory Navigation
Horizontal scrollable pill tabs
- Container: Full width,
--space-4vertical padding - Background:
--color-surface - Border bottom: 1px
--color-border
Pill Style
- Default: Transparent bg,
--color-mutedtext,--radius-full - Hover:
--color-bgbg,--color-primarytext - Active:
--color-primarybg, white text - Font:
--text-sm, weight 500 - Padding:
--space-2--space-4 - Gap:
--space-2
Subcategories for Fashion:
- All
- Women's Clothing
- Men's Clothing
- Shoes
- Bags & Luggage
- Accessories
Mobile: Same pills, horizontally scrollable with fade edges
3. Filter Rail (Desktop)
Position: Left sidebar, sticky, 280px width
Container:
- Background:
--color-surface - Border right: 1px
--color-border - Padding:
--space-5 - Height: Fill viewport minus header
Filter Section:
- Title:
--text-sm, weight 600,--color-primary, uppercase, letter-spacing 0.5px - Margin bottom:
--space-3 - Margin top:
--space-5(first section: 0)
Checkbox Filters (Brand, Platform, Availability)
- Checkbox: 16x16px,
--radius-sm, accent color when checked - Label:
--text-sm,--color-primary - Count badge:
--text-xs,--color-muted, parentheses
Price Range Filter
- Dual-handle range slider
- Min/Max input fields: 64px width each
- Labels:
--text-xs,--color-muted - Range: S$0 – S$500+ (for Fashion)
Color Swatch Filter
- Swatches: 24x24px,
--radius-full - Border: 1px
--color-border - Selected: 2px accent ring with 2px gap
- Label below:
--text-xs
Size Filter
- Chip style buttons:
XS S M L XL XXL - Default:
--color-bgbg,--color-primarytext,--radius-sm - Selected:
--color-primarybg, white text - Disabled (out of stock): 50% opacity
Region Filter
- Dropdown or checkbox list
- Regions: Singapore, Malaysia, Indonesia, Thailand, Philippines
Clear Filters Button:
- Text button,
--color-accent,--text-sm - Position: Bottom of filter rail
4. Product Grid
Grid Layout:
- Columns: 4 (desktop), 3 (tablet), 2 (mobile)
- Gap:
--space-4 - Container padding:
--space-5
Product Card (Grid View) — Reference BUY-2130 Iris Cards
┌─────────────────────────────┐
│ [Image - 4:5 aspect ratio] │
│ [Wishlist heart - top right]│
│ [Badge - top left] │
├─────────────────────────────┤
│ Brand Name │
│ Product Name (2 lines max) │
│ S$ 49.90 │
│ [★★★★☆] (42 reviews) │
│ ✓ In Stock │
└─────────────────────────────┘
Card Specs:
- Background:
--color-surface - Border: 1px
--color-border - Border radius:
--radius-md - Padding:
--space-3 - Image: Object-fit cover,
--radius-sm - Wishlist button: 32x32px, top-right absolute, white bg, shadow
- Badge:
--text-xs,--color-accentbg, white text,--radius-sm
Card Typography:
- Brand:
--text-xs,--color-muted, uppercase - Title:
--text-sm, weight 500,--color-primary, 2-line clamp - Price:
--text-lg, weight 700,--color-primary - Original price:
--text-sm,--color-muted, strikethrough - Rating:
--text-xs, gold stars + review count
5. Product List View (Toggle)
When list view is active:
┌──────────────────────────────────────────────────────────────────┐
│ [Image] Brand Name S$ 49.90 [Buy] │
│ 64x80 Product Name with description... ★★★★☆ (42) │
│ px ✓ In Stock [♡] │
└──────────────────────────────────────────────────────────────────┘
List Item Specs:
- Flex row, align center
- Image: 64x80px,
--radius-sm - Brand:
--text-xs,--color-muted - Title:
--text-base, weight 500 - Price block: Right aligned
- Buy button:
--color-accentbg, white text,--radius-sm - Wishlist: Icon button, right side
6. Toolbar (Above Grid)
Layout: Flex row, space-between, center
Left side:
- Result count: "{{ total }} results"
- Font:
--text-sm,--color-muted
Right side:
-
Sort dropdown:
- Options: Relevance, Price: Low to High, Price: High to Low, Newest, Top Rated
- Default: Relevance
- Style:
--radius-sm, border,--space-3padding
-
View toggle:
- Two icon buttons: Grid icon, List icon
- Active:
--color-primarybg, white icon - Inactive: Transparent bg,
--color-mutedicon
7. Empty / No-Results State
Layout: Centered, max-width 400px
Icon: Search icon with "X", 64x64px, --color-muted
Heading: --text-xl, "No products found"
Body: --text-base, "Try adjusting your filters or search terms."
Suggestions:
- "Clear all filters" button: Outlined,
--color-accent - "Browse other categories" link
8. Loading / Skeleton States
Skeleton Card:
- Background:
--color-bgwith animated shimmer - Shimmer: Linear gradient animation, left to right, 1.5s duration
- Card shape matches actual card dimensions
- Elements: Image placeholder, 3 text lines, price placeholder
Skeleton for filter rail:
- Rectangle placeholders for each filter section
- Checkbox placeholders (small squares)
Page skeleton:
- Hero: Full width, 160px height shimmer
- Filter rail: 280px shimmer
- Grid: 8 skeleton cards (4x2)
9. Mobile Breakpoint (≤768px)
Layout Changes:
-
Filter Rail: Becomes bottom sheet/drawer
- "Filters" button in toolbar: Shows count of active filters
- Bottom sheet: 80vh max height,
--radius-lgtop corners - Close button: Top right "X"
- Apply button: Fixed bottom, full width,
--color-accent
-
Subcategory Nav: Horizontal scroll with fade
-
Product Grid: 2 columns
- Gap:
--space-3 - Card padding:
--space-2
- Gap:
-
Toolbar: Stacks vertically
- Row 1: Results count + Filters button
- Row 2: Sort dropdown + View toggle (right aligned)
-
Product Card (Mobile):
- Smaller image: 1:1 aspect ratio
- Simplified info: Brand, Name, Price only
- No review count in grid view
Interaction Behaviors
Facet Filter Behavior
-
Checkbox filters (Brand, Platform):
- Instant filtering on check/uncheck
- URL updates with filter params
- Result count updates in toolbar
- 300ms debounce on URL update
-
Price Range:
- Drag handles or type in fields
- "Apply" button to confirm (mobile)
- Instant on desktop with 500ms debounce
- Invalid range shows error state
-
Color Swatches:
- Single select (one color at a time)
- Click to toggle, click again to deselect
- "Clear" link appears when color selected
-
Size Chips:
- Multi-select
- Disabled sizes (out of stock) non-clickable with tooltip
-
Availability Toggle:
- "In Stock Only" checkbox
- Instant filter
-
Active Filter Pills:
- Show above grid when filters active
- Each pill: Filter name + "X" to remove
- "Clear all" at end
Infinite Scroll / Pagination
- Initial load: 24 products
- "Load More" button at bottom OR infinite scroll
- Loading indicator: Spinner or skeleton cards
- Scroll position preserved on back navigation
Image Loading
- Lazy load images below fold
- Low-res placeholder blur-up effect
- "Add to Wishlist" on hover (desktop)
Accessibility Requirements
- All interactive elements keyboard accessible
- Focus visible: 2px
--color-accentoutline, 2px offset - ARIA labels on icon buttons
- Filter sections:
role="group",aria-labelledby - Live region for result count updates
- Color contrast: WCAG AA minimum
- Skip to main content link
States Reference
| State | Visual Treatment |
|---|---|
| Default | Base card styles |
| Hover | Shadow --shadow-sm, slight scale (1.02) |
| Active/Pressed | Scale (0.98) |
| Disabled | 50% opacity, cursor not-allowed |
| Loading | Shimmer skeleton animation |
| Empty | Centered empty state illustration |
| Error | Error message, retry button |
| Out of Stock | Grayscale image, "Out of Stock" badge |
API Data Contract (Reference)
interface CategoryPageData {
category: {
id: string;
name: string;
slug: string;
};
breadcrumb: Array<{ name: string; url: string }>;
subcategories: Array<{ id: string; name: string; product_count: number }>;
products: Array<{
id: number;
name: string;
brand: string;
price: number;
currency: string;
original_price?: number;
image_url: string;
url: string;
rating?: number;
review_count?: number;
in_stock: boolean;
badges?: Array<{ type: string; text: string }>;
colors?: Array<{ id: string; name: string; hex: string }>;
sizes?: Array<{ code: string; available: boolean }>;
}>;
facets: {
brands: Array<{ value: string; count: number }>;
price_ranges: Array<{ range: string; count: number; min: number; max: number }>;
colors: Array<{ value: string; hex: string; count: number }>;
sizes: Array<{ code: string; count: number; available: boolean }>;
availability: Array<{ value: string; count: number }>;
regions: Array<{ value: string; count: number }>;
};
pagination: {
total: number;
page: number;
per_page: number;
total_pages: number;
};
sort_options: Array<{ value: string; label: string }>;
active_filters: Record<string, Array<string | number>>;
}
Responsive Breakpoints
| Breakpoint | Width | Filter Rail | Grid Columns | Card Padding |
|---|---|---|---|---|
| Desktop | ≥1024px | Sticky left | 4 | --space-3 |
| Tablet | 768-1023px | Collapsible | 3 | --space-3 |
| Mobile | <768px | Bottom sheet | 2 | --space-2 |
Implementation Notes
-
Figma Frames Needed:
Category-Fashion-Desktop— Full page desktop viewCategory-Fashion-Mobile— Full page mobile viewCategory-Fashion-Desktop-Filters— Filter rail detailCategory-Fashion-Mobile-Filters— Bottom sheet filter stateCategory-Fashion-States— All card states (hover, loading, empty)Category-Fashion-ProductCard— Component specs
-
Handoff Ready Specs:
- All spacing uses the token system above
- Fonts: Inter (Google Fonts)
- Icons: Lucide React icon set
- Image aspect ratios: 4:5 (grid), 1:1 (mobile grid), 4:5 (list)
-
Dependencies:
- Iris design system tokens (BUY-2150)
- Product card component from BUY-2130
- Icon set: Lucide (consistent with design system)