--- name: responsive-mobile-first description: Mobile-first responsive patterns with sticky headers, floating CTAs, accessible navigation, and touch-friendly interactions. Use when implementing responsive layouts, mobile navigation, or ensuring touch-friendly UI. --- # Responsive Mobile-First ## Breakpoint Strategy ```tsx // Tailwind default breakpoints (mobile-first) // sm: 640px // md: 768px // lg: 1024px // xl: 1280px // 2xl: 1536px // Write base styles for mobile, add breakpoints for larger screens
``` ## Sticky Header ```tsx // components/layout/Header.tsx 'use client'; import { useState, useEffect } from 'react'; import { cn } from '@/lib/utils'; export function Header() { const [isScrolled, setIsScrolled] = useState(false); useEffect(() => { const handleScroll = () => setIsScrolled(window.scrollY > 10); window.addEventListener('scroll', handleScroll); return () => window.removeEventListener('scroll', handleScroll); }, []); return (
); } ``` ## Mobile Navigation Drawer ```tsx 'use client'; import { useState } from 'react'; import { motion, AnimatePresence } from 'framer-motion'; import { X, Menu } from 'lucide-react'; export function MobileNav() { const [isOpen, setIsOpen] = useState(false); return ( <> {isOpen && ( <> {/* Backdrop */} setIsOpen(false)} className="fixed inset-0 bg-black/50 z-50 md:hidden" /> {/* Drawer */}
)}
); } ``` ## Floating Mobile CTA ```tsx // components/FloatingCTA.tsx 'use client'; import { useState, useEffect } from 'react'; import { motion, AnimatePresence } from 'framer-motion'; import Link from 'next/link'; import { useLocale } from 'next-intl'; export function FloatingCTA() { const [isVisible, setIsVisible] = useState(false); const locale = useLocale(); useEffect(() => { const handleScroll = () => { // Show after scrolling past hero setIsVisible(window.scrollY > 500); }; window.addEventListener('scroll', handleScroll); return () => window.removeEventListener('scroll', handleScroll); }, []); return ( {isVisible && ( Book a Session )} ); } ``` ## Responsive Grid Patterns ```tsx // 1-2-3 column grid
{items.map(item => )}
// Sidebar layout
{/* Main content */}
// Hero with text/image
{/* Text content */}
{/* Image */}
``` ## Touch-Friendly Targets ```tsx // Minimum 44x44px touch targets // Adequate spacing between interactive elements
// Large tap areas for cards ``` ## Responsive Typography ```tsx // Heading scale

Main Heading

Section Heading

// Body text

Body content with comfortable reading line height.

// Small text Caption or meta text ``` ## Responsive Spacing ```tsx // Section padding
// Container with responsive padding
// Stack spacing
``` ## Hide/Show Utilities ```tsx // Show only on mobile
Mobile only
// Show only on desktop
Desktop only
// Different content per breakpoint Menu Navigation ``` ## Responsive Images ```tsx import Image from 'next/image'; // Full-width responsive image
Hero
// Responsive sizes attribute Service ``` ## Container Component ```tsx // components/shared/Container.tsx import { cn } from '@/lib/utils'; interface ContainerProps { children: React.ReactNode; className?: string; size?: 'default' | 'narrow' | 'wide'; } export function Container({ children, className, size = 'default' }: ContainerProps) { return (
{children}
); } ```