33 KiB
Responsive Design Guide
Document Overview
This document defines responsive design patterns, breakpoints, and mobile-first strategies for ColaFlow's multi-tenant, SSO, and MCP Token management features.
Version: 1.0 Last Updated: 2025-11-03 Tech Stack: Tailwind CSS 4 + Next.js 16 (App Router) Owner: UX/UI Team
Table of Contents
- Breakpoint System
- Mobile-First Approach
- Registration Flow Responsive Patterns
- Login Pages Responsive Design
- SSO Configuration Responsive Layout
- MCP Token Management Mobile Views
- Component Adaptations
- Performance Considerations
Breakpoint System
Tailwind CSS Breakpoints
Following Tailwind's default breakpoints with custom extensions:
// tailwind.config.ts
const screens = {
'xs': '480px', // Extra small devices (large phones)
'sm': '640px', // Small devices (tablets)
'md': '768px', // Medium devices (landscape tablets)
'lg': '1024px', // Large devices (laptops)
'xl': '1280px', // Extra large devices (desktops)
'2xl': '1536px', // 2X large devices (large desktops)
}
Device Categories
| Breakpoint | Range | Device Type | Typical Width |
|---|---|---|---|
| xs | 480px - 639px | Large phones | 480px - 640px |
| sm | 640px - 767px | Small tablets | 640px - 768px |
| md | 768px - 1023px | Tablets | 768px - 1024px |
| lg | 1024px - 1279px | Laptops | 1024px - 1280px |
| xl | 1280px - 1535px | Desktops | 1280px - 1536px |
| 2xl | 1536px+ | Large desktops | 1536px+ |
Container Max-Widths
// Container sizes per breakpoint
const container = {
center: true,
padding: {
DEFAULT: '1rem', // 16px
sm: '2rem', // 32px
lg: '4rem', // 64px
xl: '5rem', // 80px
'2xl': '6rem', // 96px
},
screens: {
sm: '640px',
md: '768px',
lg: '1024px',
xl: '1280px',
'2xl': '1536px',
},
}
Mobile-First Approach
Core Principles
- Start with mobile (320px+) as the base
- Progressive enhancement for larger screens
- Touch-friendly targets (min 44x44px)
- Readable typography (min 16px body text)
- Simplified navigation on small screens
Example Pattern
// Mobile-first Tailwind classes
<div className="
w-full px-4 py-6 // Mobile default
sm:px-6 sm:py-8 // Small tablets
md:max-w-2xl md:mx-auto // Medium screens
lg:max-w-4xl // Large screens
">
{/* Content */}
</div>
CSS Custom Properties
:root {
--spacing-mobile: 16px;
--spacing-tablet: 24px;
--spacing-desktop: 32px;
--font-size-mobile: 14px;
--font-size-tablet: 15px;
--font-size-desktop: 16px;
}
Registration Flow Responsive Patterns
Multi-Step Form Layout
Desktop (lg+)
┌───────────────────────────────────────────┐
│ [Logo] Step 1 of 3 │
├───────────────────────────────────────────┤
│ │
│ Company Information │
│ │
│ [ ] │
│ [ ] │
│ │
│ [Cancel] [Next →] │
│ │
└───────────────────────────────────────────┘
- Width: 600px max-width, centered
- Padding: 64px
- Form fields: Full width, 24px gap
- Buttons: Right-aligned, 160px width
Tablet (md)
┌─────────────────────────────────┐
│ [Logo] Step 1 of 3 │
├─────────────────────────────────┤
│ │
│ Company Information │
│ │
│ [ ] │
│ [ ] │
│ │
│ [Cancel] [Next →] │
│ │
└─────────────────────────────────┘
- Width: 480px max-width, centered
- Padding: 48px
- Form fields: Full width, 20px gap
- Buttons: Right-aligned, 140px width
Mobile (< sm)
┌─────────────────────────┐
│ [≡] Step 1 of 3 │
├─────────────────────────┤
│ │
│ Company Info │
│ │
│ [ ] │
│ [ ] │
│ │
│ [Cancel] │
│ [Next →] │
│ │
└─────────────────────────┘
- Width: Full width with 16px padding
- Progress: Compact dots only
- Fields: Stacked, full width, 16px gap
- Buttons: Stacked, full width, 12px gap
- Secondary button above primary
Implementation:
<div className="
min-h-screen flex items-center justify-center
px-4 py-6 // Mobile
sm:px-6 sm:py-8 // Tablet
md:px-8 md:py-12 // Desktop
">
<div className="
w-full // Mobile: full width
sm:max-w-md // Tablet: 448px
md:max-w-lg // Desktop: 512px
lg:max-w-xl // Large: 576px
">
{/* Form content */}
<div className="
space-y-4 // Mobile: 16px gap
sm:space-y-5 // Tablet: 20px gap
md:space-y-6 // Desktop: 24px gap
">
{/* Fields */}
</div>
{/* Buttons */}
<div className="
mt-6 space-y-3 // Mobile: stacked
sm:mt-8 sm:flex sm:space-y-0 sm:space-x-4 // Tablet+: horizontal
sm:justify-end
">
<button className="
w-full sm:w-auto // Mobile: full width, Tablet+: auto
">
Cancel
</button>
<button className="
w-full sm:w-auto
">
Next
</button>
</div>
</div>
</div>
Tenant Slug Preview
Desktop
Company Slug *
[acme ]
✓ acme.colaflow.com is available
Mobile
Company Slug *
[acme ]
✓ Available
- Hide full domain, show only "Available" / "Taken"
- Tap to view full domain in bottom sheet
Implementation:
<div>
<Input value={slug} onChange={handleChange} />
{/* Desktop preview */}
<p className="hidden sm:block text-sm text-gray-600">
✓ {slug}.colaflow.com is available
</p>
{/* Mobile preview */}
<p className="sm:hidden text-sm text-green-600">
✓ Available
</p>
</div>
Subscription Plan Cards
Desktop (lg+)
┌─────────┐ ┌─────────┐ ┌─────────┐ ┌─────────┐
│ Free │ │ Starter │ │ Pro │ │Enterprise│
│ $0 │ │ $19 │ │ $49 │ │ Custom │
│ ... │ │ ... │ │ ... │ │ ... │
│ [Start] │ │ [Start] │ │ [Start] │ │[Contact]│
└─────────┘ └─────────┘ └─────────┘ └─────────┘
- 4 columns, equal width
- Side-by-side comparison
Tablet (md)
┌───────────┐ ┌───────────┐
│ Free │ │ Starter │
│ $0 │ │ $19 │
│ ... │ │ ... │
│ [Start] │ │ [Start] │
└───────────┘ └───────────┘
┌───────────┐ ┌───────────┐
│ Pro │ │Enterprise │
│ $49 │ │ Custom │
│ ... │ │ ... │
│ [Start] │ │ [Contact] │
└───────────┘ └───────────┘
- 2 columns, 2 rows
- Grid layout
Mobile (< sm)
┌───────────────┐
│ Free │
│ $0 │
│ ... │
│ [Start] │
└───────────────┘
┌───────────────┐
│ Starter │
│ $19 │
│ ... │
│ [Start] │
└───────────────┘
- 1 column, scrollable
- Cards stacked vertically
- "Compare Plans" button to show comparison table
Implementation:
<div className="
grid gap-4
grid-cols-1 // Mobile: 1 column
sm:grid-cols-2 // Tablet: 2 columns
lg:grid-cols-4 // Desktop: 4 columns
">
{plans.map(plan => (
<SubscriptionPlanCard key={plan.id} {...plan} />
))}
</div>
Login Pages Responsive Design
Login Form Layout
Desktop (md+)
┌──────────────────────────────────────┐
│ │
│ Welcome to Acme Corp │
│ │
│ Email Address │
│ [ ] │
│ │
│ Password │
│ [ ] │
│ │
│ [☐] Remember me Forgot password? │
│ │
│ [Sign In →] │
│ │
│ ────── OR ────── │
│ │
│ [🟦 Continue with Microsoft] │
│ [🔴 Continue with Google] │
│ │
└──────────────────────────────────────┘
- Max-width: 448px, centered
- Vertical spacing: 24px
- SSO buttons: full width
Mobile (< md)
┌────────────────────┐
│ │
│ Welcome │
│ │
│ Email │
│ [ ] │
│ │
│ Password │
│ [ ] │
│ │
│ [☐] Remember me │
│ Forgot password? │
│ │
│ [Sign In →] │
│ │
│ ─── OR ─── │
│ │
│ [Microsoft] │
│ [Google] │
│ │
└────────────────────┘
- Full width with 16px padding
- Smaller fonts (14px body)
- Compact spacing (16px)
- "Remember me" and "Forgot password" stacked
Implementation:
<div className="
min-h-screen flex items-center justify-center
bg-gray-50 px-4 py-8
">
<div className="
w-full max-w-md
bg-white rounded-lg shadow-lg
p-6 sm:p-8
">
<h1 className="
text-2xl sm:text-3xl
font-bold text-center mb-6
">
Welcome to {tenantName}
</h1>
{/* SSO buttons (if configured) */}
{ssoEnabled && (
<div className="
space-y-3 mb-6
">
<SsoButton provider="AzureAD" fullWidth />
<SsoButton provider="Google" fullWidth />
</div>
)}
{ssoEnabled && <LoginDivider />}
{/* Local login form */}
<form className="space-y-4">
<Input label="Email Address" type="email" />
<Input label="Password" type="password" />
<div className="
flex flex-col sm:flex-row
sm:items-center sm:justify-between
space-y-2 sm:space-y-0
">
<Checkbox label="Remember me" />
<Link className="text-sm">Forgot password?</Link>
</div>
<Button type="submit" fullWidth>
Sign In
</Button>
</form>
</div>
</div>
SSO Button Responsive Sizing
Desktop
[🟦 Continue with Microsoft]
│ 24px gap │
- Height: 48px
- Padding: 12px 24px
- Icon: 20x20px
- Font: 16px
Mobile
[🟦 Microsoft]
│ 12px │
- Height: 44px (touch-friendly)
- Padding: 12px 16px
- Icon: 18x18px
- Font: 14px
- Shorter text: "Microsoft" instead of "Continue with Microsoft"
Implementation:
<button className="
w-full flex items-center justify-center gap-3
h-11 sm:h-12 // 44px / 48px
px-4 sm:px-6 // 16px / 24px
text-sm sm:text-base // 14px / 16px
rounded-lg
">
<Icon className="w-5 h-5" />
<span className="
hidden sm:inline // Hide "Continue with" on mobile
">
Continue with
</span>
<span>{providerName}</span>
</button>
SSO Configuration Responsive Layout
Settings Page Structure
Desktop (lg+)
┌─────────────────────────────────────────────────────┐
│ Settings │
├───────────┬─────────────────────────────────────────┤
│ │ │
│ General │ Single Sign-On (SSO) │
│ SSO │ │
│ Billing │ ┌──────────────────────────────────┐ │
│ Usage │ │ General │ │
│ Team │ │ OIDC Config │ │
│ │ │ SAML Config │ │
│ │ │ Users │ │
│ │ │ Test │ │
│ │ └──────────────────────────────────┘ │
│ │ │
│ │ [Tab content...] │
│ │ │
└───────────┴─────────────────────────────────────────┘
- Sidebar: 240px fixed width
- Content: Flexible, max-width 800px
- Tabs: Horizontal
Tablet (md)
┌─────────────────────────────────┐
│ Settings [≡] │
├─────────────────────────────────┤
│ │
│ Single Sign-On (SSO) │
│ │
│ ┌─────────────────────────┐ │
│ │ General │ │
│ │ OIDC Config │ │
│ │ SAML Config │ │
│ │ Users │ │
│ │ Test │ │
│ └─────────────────────────┘ │
│ │
│ [Tab content...] │
│ │
└─────────────────────────────────┘
- No sidebar (hamburger menu)
- Content: Full width with padding
- Tabs: Scrollable horizontal
Mobile (< sm)
┌───────────────────┐
│ SSO Config [≡] │
├───────────────────┤
│ │
│ [General ▼] │
│ │
│ [Tab content...] │
│ │
│ [Save] │
│ │
└───────────────────┘
- No sidebar
- Tabs: Dropdown select
- Sticky footer with save button
- Forms: Stacked fields
Implementation:
<div className="
min-h-screen flex
flex-col lg:flex-row
">
{/* Sidebar (desktop only) */}
<aside className="
hidden lg:block
w-60 border-r bg-gray-50
">
<SettingsSidebar />
</aside>
{/* Mobile header with menu */}
<header className="
lg:hidden
sticky top-0 z-10
bg-white border-b
px-4 py-3
">
<div className="flex items-center justify-between">
<h1>SSO Configuration</h1>
<MenuButton />
</div>
</header>
{/* Main content */}
<main className="
flex-1 p-4 sm:p-6 lg:p-8
">
{/* Desktop tabs */}
<Tabs className="hidden sm:flex">
<Tab>General</Tab>
<Tab>OIDC Config</Tab>
<Tab>SAML Config</Tab>
<Tab>Users</Tab>
<Tab>Test</Tab>
</Tabs>
{/* Mobile dropdown */}
<Select className="sm:hidden mb-4">
<option>General</option>
<option>OIDC Config</option>
<option>SAML Config</option>
<option>Users</option>
<option>Test</option>
</Select>
{/* Tab content */}
<div className="mt-6">
{tabContent}
</div>
</main>
</div>
Form Fields Responsive Stack
Desktop
Authority / Issuer URL *
[ ]
Client ID *
[ ]
Client Secret *
[ ]
- Single column
- Full width inputs
- 24px vertical gap
Mobile
Authority *
[ ]
Client ID *
[ ]
Secret *
[ ]
- Shorter labels
- Smaller inputs
- 16px vertical gap
- Multiline inputs collapse to single line
Implementation:
<div className="space-y-4 sm:space-y-6">
<Input
label={
<span>
<span className="hidden sm:inline">Authority / Issuer URL</span>
<span className="sm:hidden">Authority</span>
</span>
}
required
/>
<Input
label="Client ID"
required
/>
<Input
label={
<span>
<span className="hidden sm:inline">Client Secret</span>
<span className="sm:hidden">Secret</span>
</span>
}
type="password"
required
/>
</div>
MCP Token Management Mobile Views
Token List Responsive Cards
Desktop (md+)
┌────────────────────────────────────────────────┐
│ Claude Desktop [Active] │
│ Permissions: Projects (R), Issues (R/W) │
│ Created: Nov 1 • Last Used: 2 hours ago │
│ Expires: In 30 days │
│ │
│ [View Details] [Revoke] │
└────────────────────────────────────────────────┘
- Horizontal card
- All info visible
- Buttons inline
Mobile (< md)
┌──────────────────────────┐
│ Claude Desktop [●] │
│ │
│ Projects (R) │
│ Issues (R/W) │
│ +2 more │
│ │
│ Last used: 2h ago │
│ Expires: 30d │
│ │
│ [Details] [Revoke] │
└──────────────────────────┘
- Vertical card
- Compact info
- Abbreviated permissions
- Buttons full width
Implementation:
<div className="
rounded-lg border bg-white shadow-sm
p-4 sm:p-6
">
<div className="
flex flex-col sm:flex-row
sm:items-center sm:justify-between
gap-3 sm:gap-4
">
{/* Header */}
<div className="flex-1">
<div className="flex items-center justify-between mb-2">
<h3 className="font-semibold">{token.name}</h3>
<StatusBadge status={token.status} />
</div>
{/* Permissions - desktop */}
<div className="hidden sm:block text-sm text-gray-600">
{formatPermissions(token.permissions)}
</div>
{/* Permissions - mobile (compact) */}
<div className="sm:hidden space-y-1">
{token.permissions.slice(0, 2).map(p => (
<div key={p} className="text-xs text-gray-600">
{p}
</div>
))}
{token.permissions.length > 2 && (
<div className="text-xs text-gray-500">
+{token.permissions.length - 2} more
</div>
)}
</div>
{/* Metadata */}
<div className="
mt-2 flex flex-col sm:flex-row sm:gap-4
text-xs sm:text-sm text-gray-500
">
<span>Created: {formatDate(token.createdAt)}</span>
<span>Last used: {formatRelativeTime(token.lastUsedAt)}</span>
<span>Expires: {formatExpiry(token.expiresAt)}</span>
</div>
</div>
{/* Actions */}
<div className="
flex gap-2
flex-col sm:flex-row
sm:ml-auto
">
<Button
variant="secondary"
size="sm"
className="w-full sm:w-auto"
>
View Details
</Button>
<Button
variant="danger"
size="sm"
className="w-full sm:w-auto"
>
Revoke
</Button>
</div>
</div>
</div>
Permission Matrix Mobile Adaptation
Desktop
┌──────────────────────────────────────────────────┐
│ Resource │ Read │Create│Update│Delete│Search │
│───────────┼──────┼──────┼──────┼──────┼────────│
│ Projects │ ✓ │ │ │ │ ✓ │
│ Issues │ ✓ │ ✓ │ ✓ │ │ ✓ │
│ Documents │ ✓ │ ✓ │ │ │ ✓ │
└──────────────────────────────────────────────────┘
- Full table view
- All columns visible
- Checkboxes
Mobile (< md)
┌─────────────────────────┐
│ [Projects ▼] │
│ ☑ Read │
│ ☐ Create │
│ ☐ Update │
│ ☐ Delete │
│ ☑ Search │
├─────────────────────────┤
│ [Issues ▼] │
│ ☑ Read │
│ ☑ Create │
│ ☑ Update │
│ ☐ Delete │
│ ☑ Search │
└─────────────────────────┘
- Accordion view
- One resource at a time
- Larger touch targets
- Checkbox list
Implementation:
// Desktop view
<table className="hidden md:table w-full">
<thead>
<tr>
<th>Resource</th>
<th>Read</th>
<th>Create</th>
<th>Update</th>
<th>Delete</th>
<th>Search</th>
</tr>
</thead>
<tbody>
{resources.map(resource => (
<tr key={resource}>
<td>{resource}</td>
{operations.map(op => (
<td key={op}>
<Checkbox checked={hasPermission(resource, op)} />
</td>
))}
</tr>
))}
</tbody>
</table>
// Mobile view (accordion)
<div className="md:hidden space-y-2">
{resources.map(resource => (
<Accordion key={resource}>
<AccordionTrigger>
{resource}
<span className="text-xs text-gray-500 ml-2">
({selectedCount(resource)} selected)
</span>
</AccordionTrigger>
<AccordionContent>
<div className="space-y-2 pt-2">
{operations.map(op => (
<label key={op} className="flex items-center gap-3 p-2">
<Checkbox checked={hasPermission(resource, op)} />
<span>{op}</span>
</label>
))}
</div>
</AccordionContent>
</Accordion>
))}
</div>
Audit Log Table Mobile Adaptation
Desktop
┌────────────────────────────────────────────────────┐
│ Timestamp Action Resource Result IP │
│────────────────────────────────────────────────────│
│ Nov 3, 08:15 Read Issue #123 Success 192.168 │
│ Nov 3, 08:10 Create Issue #456 Success 192.168 │
└────────────────────────────────────────────────────┘
- Table layout
- All columns visible
- Horizontal scroll if needed
Mobile
┌────────────────────────┐
│ Nov 3, 08:15 AM │
│ Read Issue #123 │
│ Success • 192.168.1.1 │
├────────────────────────┤
│ Nov 3, 08:10 AM │
│ Create Issue #456 │
│ Success • 192.168.1.1 │
└────────────────────────┘
- Card layout
- Stacked information
- Tap to expand details
Implementation:
// Desktop table
<table className="hidden sm:table w-full">
<thead>
<tr>
<th>Timestamp</th>
<th>Action</th>
<th>Resource</th>
<th>Result</th>
<th>IP Address</th>
</tr>
</thead>
<tbody>
{logs.map(log => (
<tr key={log.id}>
<td>{formatTimestamp(log.timestamp)}</td>
<td>{log.action}</td>
<td>{log.resource}</td>
<td><StatusBadge status={log.result} /></td>
<td>{log.ipAddress}</td>
</tr>
))}
</tbody>
</table>
// Mobile cards
<div className="sm:hidden space-y-2">
{logs.map(log => (
<button
key={log.id}
className="w-full text-left p-4 bg-white rounded border"
onClick={() => showLogDetails(log)}
>
<div className="text-sm text-gray-500 mb-1">
{formatTimestamp(log.timestamp)}
</div>
<div className="font-medium mb-1">
{log.action} {log.resource}
</div>
<div className="flex items-center gap-2 text-sm text-gray-600">
<StatusBadge status={log.result} size="sm" />
<span>•</span>
<span>{log.ipAddress}</span>
</div>
</button>
))}
</div>
Component Adaptations
Modal to Bottom Sheet
On mobile, full-screen modals become bottom sheets for better UX.
Desktop Modal
[Backdrop]
┌──────────────┐
│ Modal │
│ Content │
│ │
│ [Actions] │
└──────────────┘
Mobile Bottom Sheet
┌──────────────────┐
│ │
│ Page content │
│ │
├──────────────────┤ <- Swipe up
│ [Handle] │
│ │
│ Sheet Content │
│ │
│ [Actions] │
└──────────────────┘
Implementation:
<Dialog
className="
fixed inset-0 // Desktop: centered
sm:flex sm:items-center sm:justify-center
// Mobile: bottom sheet
flex items-end
sm:items-center
"
>
<DialogContent
className="
w-full max-w-lg // Desktop: max-width
// Mobile: bottom sheet styling
rounded-t-2xl sm:rounded-lg // Round top only on mobile
max-h-[90vh] // Don't cover entire screen
overflow-y-auto
"
>
{/* Drag handle (mobile only) */}
<div className="
sm:hidden
w-12 h-1 bg-gray-300 rounded-full
mx-auto my-3
" />
{content}
</DialogContent>
</Dialog>
Dropdown to Drawer
Complex dropdowns become side drawers on mobile.
Desktop Dropdown
[Select Provider ▼]
│
├─ Azure AD
├─ Google
├─ Okta
└─ SAML
Mobile Drawer
┌──────────────────┐
│ │
│ Page │
│ │
│ [Select ▼] │
│ │
└──────────────────┘
↓
┌──────────────────┐
│ [× ] Provider │
├──────────────────┤
│ │
│ ○ Azure AD │
│ ○ Google │
│ ○ Okta │
│ ● SAML │
│ │
│ [Confirm] │
└──────────────────┘
Implementation:
// Desktop: native select or dropdown
<Select className="hidden sm:block">
{options.map(opt => (
<option key={opt.value}>{opt.label}</option>
))}
</Select>
// Mobile: drawer
<button
className="sm:hidden"
onClick={() => setDrawerOpen(true)}
>
{selectedOption.label} ▼
</button>
<Drawer open={drawerOpen} onClose={() => setDrawerOpen(false)}>
<DrawerContent>
<DrawerHeader>
Select Provider
</DrawerHeader>
<div className="space-y-2 p-4">
{options.map(opt => (
<button
key={opt.value}
className="w-full text-left p-3 rounded hover:bg-gray-100"
onClick={() => {
setSelectedOption(opt);
setDrawerOpen(false);
}}
>
{opt.label}
</button>
))}
</div>
</DrawerContent>
</Drawer>
Performance Considerations
Image Optimization
import Image from 'next/image';
<Image
src="/logo.svg"
alt="ColaFlow"
width={120}
height={40}
sizes="(max-width: 640px) 100px, 120px" // Smaller on mobile
priority={true} // Above the fold
/>
Lazy Loading
import dynamic from 'next/dynamic';
// Load heavy components only when needed
const PermissionMatrix = dynamic(
() => import('@/components/mcp-tokens/PermissionMatrix'),
{ loading: () => <Skeleton /> }
);
// Mobile-specific components
const MobileDrawer = dynamic(
() => import('@/components/shared/MobileDrawer'),
{ ssr: false } // Client-side only
);
Conditional Rendering
// Don't render desktop components on mobile
const isMobile = useMediaQuery('(max-width: 640px)');
return (
<>
{isMobile ? <MobileView /> : <DesktopView />}
</>
);
Font Loading
// next.config.js
module.exports = {
optimizeFonts: true,
// Font subsets for faster loading
experimental: {
optimizeFonts: ['latin', 'latin-ext'],
},
};
CSS Optimization
/* Critical CSS inline in <head> */
/* Non-critical CSS lazy-loaded */
/* Reduce animations on mobile for performance */
@media (prefers-reduced-motion: reduce) {
* {
animation-duration: 0.01ms !important;
transition-duration: 0.01ms !important;
}
}
/* Disable hover effects on touch devices */
@media (hover: none) {
.hover-effect:hover {
/* No hover effect */
}
}
Testing Guidelines
Responsive Testing Checklist
- Test on real devices (not just browser DevTools)
- iOS Safari (iPhone 13, 14, 15)
- Android Chrome (Samsung, Pixel)
- Tablet: iPad Pro, Android tablet
- Foldable devices (Galaxy Fold, Surface Duo)
- Landscape and portrait orientations
- Text zoom (up to 200%)
- Touch target sizes (min 44x44px)
- Keyboard navigation on tablets
- Screen reader compatibility
Breakpoint Testing Script
// utils/breakpoints.test.ts
import { render } from '@testing-library/react';
import { useMediaQuery } from '@/hooks/useMediaQuery';
describe('Responsive Breakpoints', () => {
const breakpoints = [320, 480, 640, 768, 1024, 1280, 1536];
breakpoints.forEach(width => {
test(`Renders correctly at ${width}px`, () => {
window.innerWidth = width;
window.dispatchEvent(new Event('resize'));
const { container } = render(<YourComponent />);
expect(container).toMatchSnapshot();
});
});
});
Conclusion
This responsive design guide ensures ColaFlow provides an optimal experience across all device sizes. By following mobile-first principles and adapting components appropriately, we maintain usability and performance on every screen.
Key Takeaways:
- Always start with mobile design
- Use appropriate breakpoints for content, not devices
- Simplify UI on small screens
- Optimize performance for mobile networks
- Test on real devices
Next Steps:
- Implement responsive components
- Conduct device testing
- Measure performance metrics
- Gather user feedback
- Iterate and improve
Questions: Contact UX/UI team at ux@colaflow.com