| name | frontend-design-complete |
| description | Create distinctive, production-grade frontend interfaces with high design quality. Covers aesthetics, mobile-first patterns, modern CSS, performance (Core Web Vitals), dark mode/theming, AI-era patterns, interaction design, data visualization, fluid typography, responsive images, component architecture, forms, internationalization, cognitive accessibility, design tokens, and cascade layers. Use this as your single frontend design skill. |
Complete Frontend Design Guidelines
This skill guides creation of distinctive, production-grade frontend interfaces that avoid generic "AI slop" aesthetics while ensuring proper mobile responsiveness and cross-element consistency.
Part 1: Design Thinking & Aesthetics
Design Thinking
Before coding, understand the context and commit to a BOLD aesthetic direction:
- Purpose: What problem does this interface solve? Who uses it?
- Tone: Pick an extreme: brutally minimal, maximalist chaos, retro-futuristic, organic/natural, luxury/refined, playful/toy-like, editorial/magazine, brutalist/raw, art deco/geometric, soft/pastel, industrial/utilitarian, etc. There are so many flavors to choose from. Use these for inspiration but design one that is true to the aesthetic direction.
- Constraints: Technical requirements (framework, performance, accessibility).
- Differentiation: What makes this UNFORGETTABLE? What's the one thing someone will remember?
CRITICAL: Choose a clear conceptual direction and execute it with precision. Bold maximalism and refined minimalism both work - the key is intentionality, not intensity.
Then implement working code (HTML/CSS/JS, React, Vue, etc.) that is:
- Production-grade and functional
- Visually striking and memorable
- Cohesive with a clear aesthetic point-of-view
- Meticulously refined in every detail
- Fully mobile responsive (see Part 2)
Frontend Aesthetics Guidelines
Focus on:
- Typography: Choose fonts that are beautiful, unique, and interesting. Avoid generic fonts like Arial and Inter; opt instead for distinctive choices that elevate the frontend's aesthetics; unexpected, characterful font choices. Pair a distinctive display font with a refined body font.
- Color & Theme: Commit to a cohesive aesthetic. Use CSS variables for consistency. Dominant colors with sharp accents outperform timid, evenly-distributed palettes.
- Motion: Use animations for effects and micro-interactions. Prioritize CSS-only solutions for HTML. Use Motion library for React when available. Focus on high-impact moments: one well-orchestrated page load with staggered reveals (animation-delay) creates more delight than scattered micro-interactions. Use scroll-triggering and hover states that surprise.
- Spatial Composition: Unexpected layouts. Asymmetry. Overlap. Diagonal flow. Grid-breaking elements. Generous negative space OR controlled density.
- Backgrounds & Visual Details: Create atmosphere and depth rather than defaulting to solid colors. Add contextual effects and textures that match the overall aesthetic. Apply creative forms like gradient meshes, noise textures, geometric patterns, layered transparencies, dramatic shadows, decorative borders, custom cursors, and grain overlays.
NEVER use generic AI-generated aesthetics like overused font families (Inter, Roboto, Arial, system fonts), cliched color schemes (particularly purple gradients on white backgrounds), predictable layouts and component patterns, and cookie-cutter design that lacks context-specific character.
AI Slop Patterns to Avoid
These specific patterns have become telltale signs of AI-generated design. Avoid them:
Colors:
- Cream/off-white backgrounds (
#f8f6f3, #fdfcfb, #faf8f5 type colors)
- Terracotta/coral/rust accents (
#c45c48, #e07860, #d4715f, #bf4a37)
- Orange and teal combinations
- Purple/blue gradients on white backgrounds
- Warm shadows with colored tints
Layout & Components:
- Generous rounded corners (12-16px+ border-radius)
- Left-border accent lines on cards (the colored vertical stripe)
- Pill-shaped tabs and buttons
- Cards with subtle warm shadows and hover lift effects
- Overly "friendly" and "approachable" feeling
Visual Effects:
- Texture overlays (noise, grain, paper textures)
- Glow effects and colored shadows
- Gradient backgrounds with warm color temperature
- Soft, diffused aesthetic everywhere
Overall Aesthetic:
- The "cozy webapp" look - warm, soft, inviting
- Designs that feel like Notion/Linear clones
- Safe, inoffensive, "premium but accessible" feeling
- Lack of sharp contrast or bold decisions
Instead, make distinctive choices: cooler color temperatures, sharper geometry, unexpected color combinations, higher contrast, or commit fully to a specific design tradition (Swiss, Japanese, Brutalist, Editorial, etc.) rather than the generic "modern SaaS" look.
Interpret creatively and make unexpected choices that feel genuinely designed for the context. No design should be the same. Vary between light and dark themes, different fonts, different aesthetics. NEVER converge on common choices (Space Grotesk, for example) across generations.
IMPORTANT: Match implementation complexity to the aesthetic vision. Maximalist designs need elaborate code with extensive animations and effects. Minimalist or refined designs need restraint, precision, and careful attention to spacing, typography, and subtle details. Elegance comes from executing the vision well.
Part 2: Mobile-First Responsive Patterns
Hero Sections
Problem: 2-column grid layouts leave empty space when one column is hidden on mobile.
.hero {
display: grid;
grid-template-columns: 1fr 1fr;
gap: 64px;
align-items: center;
}
@media (max-width: 768px) {
.hero {
display: flex;
flex-direction: column;
align-items: center;
text-align: center;
padding: 40px 20px;
gap: 24px;
}
.hero-content {
align-items: center;
}
.hero-badge {
align-self: center;
}
.hero-title {
font-size: 32px;
text-align: center;
}
.hero-subtitle {
font-size: 14px;
text-align: center;
}
.hero-cta {
flex-direction: column;
align-items: center;
width: 100%;
}
.hero-cta .btn {
width: 100%;
max-width: 280px;
}
.hero-visual {
display: none;
}
}
Key Rule: When hiding grid columns on mobile, switch from display: grid to display: flex to eliminate reserved empty space.
Large Selection Lists (Accordion Pattern)
Problem: Horizontal scroll for many items (20+) is unusable on mobile - text gets cut off.
Solution: Use collapsible accordion with category headers.
function StyleSelector({ items, categories }) {
const [expandedCategory, setExpandedCategory] = useState(null);
return (
<div className="selector">
{categories.map(category => (
<div key={category.name} className={`category ${expandedCategory === category.name ? 'expanded' : ''}`}>
<button
className="category-header"
onClick={() => setExpandedCategory(
expandedCategory === category.name ? null : category.name
)}
>
<span>{category.name}</span>
<ChevronIcon />
</button>
<div className="category-items">
{category.items.map(item => (
<button key={item.id} className="item">{item.name}</button>
))}
</div>
</div>
))}
</div>
);
}
@media (max-width: 768px) {
.category-items {
display: none;
}
.category.expanded .category-items {
display: flex;
flex-direction: column;
}
.chevron-icon {
transition: transform 0.2s ease;
}
.category.expanded .chevron-icon {
transform: rotate(180deg);
}
}
Form Layouts
Problem: Multi-column form layouts get cut off on mobile.
.form-row {
display: flex;
gap: 16px;
}
@media (max-width: 768px) {
.form-row {
flex-direction: column;
}
.form-group {
width: 100%;
}
}
Status/Alert Cards
Problem: Inconsistent text alignment when stacking horizontally-laid elements vertically.
.alert {
display: flex;
align-items: flex-start;
gap: 12px;
}
@media (max-width: 768px) {
.alert {
flex-direction: column;
align-items: center;
text-align: center;
gap: 8px;
}
.alert strong {
text-align: center;
}
}
Key Rule: Stacked flex items need BOTH align-items: center AND text-align: center for proper centering.
Grid Layouts
@media (max-width: 768px) {
.pricing-grid,
.feature-grid,
.team-grid,
.stats-grid {
grid-template-columns: 1fr;
}
}
Breakpoint Reference
@media (max-width: 1200px) { }
@media (max-width: 768px) { }
@media (max-width: 480px) { }
Mobile Font Scaling
@media (max-width: 768px) {
.hero-title {
font-size: 32px;
}
.section-title {
font-size: 24px;
}
.section-subtitle {
font-size: 14px;
}
}
Modern Alternative: Container queries (Part 18) can replace many media queries by making components responsive to their container width rather than the viewport. For fluid font sizing without breakpoints, see Part 24.
Part 3: Form Element Consistency
Always Style as a Group
Problem: Styling only .input leaves .select and .textarea unstyled.
.style-brutalist .input {
border: 2px solid var(--border);
border-radius: 0;
}
.style-brutalist .input,
.style-brutalist .select,
.style-brutalist .textarea {
border: 2px solid var(--border);
border-radius: 0;
}
Textarea Border Radius Exceptions
Pill-shaped inputs (border-radius: 100px) look wrong on textareas:
.style-kawaii .input,
.style-kawaii .select {
border-radius: 100px;
}
.style-kawaii .textarea {
border-radius: 20px;
}
Dropdown Option Styling
<option> elements can't inherit backdrop-filter or complex backgrounds:
.style-glassmorphism .select {
background: rgba(255, 255, 255, 0.1);
backdrop-filter: blur(10px);
color: white;
}
.style-glassmorphism .select option {
background: #1a1a2e;
color: white;
}
Transparent Border Styles (Neomorphism, Claymorphism)
Problem: Styles with border: transparent make form controls invisible.
.style-neomorphism .radio-mark,
.style-claymorphism .radio-mark {
border: 2px solid #B8BEC7;
background: var(--bg-primary);
box-shadow: inset 2px 2px 4px rgba(163,177,198,0.3),
inset -2px -2px 4px rgba(255,255,255,0.8);
}
Part 4: Color Contrast Rules
Badge/Pill Elements
Always verify badge text contrasts with its background:
.badge {
color: white;
}
.badge {
color: var(--bg-primary);
}
Color Swatches Display
Swatches showing colors need visible borders regardless of swatch color:
.color-swatch {
border: 2px solid rgba(255, 255, 255, 0.15);
box-shadow: 0 0 0 1px rgba(0, 0, 0, 0.3);
}
Dark Theme Form Labels
Problem: Assuming labels should be white/light on dark themes.
.label {
color: white;
}
.label {
color: var(--text-primary);
}
Pre-Implementation Checklist
Before finalizing any frontend design, verify:
Aesthetics
Mobile Responsiveness
Form Elements
Color Contrast
Common Issues Quick Reference
| Issue | Cause | Fix |
|---|
| Hero left-aligned with empty space | Grid reserves hidden column | Switch to flex on mobile |
| Form fields cut off | Fixed-width grid | Stack vertically with flex |
| Inconsistent alert alignment | Missing align-items | Add align-items: center + text-align: center |
| Invisible form controls | Transparent borders | Add explicit borders or shadows |
| White text on light background | Hardcoded colors | Use semantic CSS variables |
| Horizontal scroll on selections | Too many items | Use accordion pattern |
| Textarea looks wrong | Pill border-radius | Use smaller radius for textarea |
| Design looks "AI-generated" | AI slop patterns | Follow aesthetic guidelines, be bold |
| Layout shift on load | Images without dimensions | Add width/height or aspect-ratio (Part 19) |
| Dark mode looks washed out | Colors not desaturated | Reduce saturation ~20% for dark mode (Part 20) |
| AI responses feel broken | No streaming indicator | Add typewriter cursor and phase-based loading (Part 21) |
| Specificity wars in CSS | No cascade management | Use @layer for explicit ordering (Part 31) |
| Content unreadable in translation | Fixed-width containers | Use logical properties and flexible layouts (Part 28) |
| Flash of wrong theme | Theme loads after paint | Run theme script in <head> (Part 20) |
Remember: Claude is capable of extraordinary creative work. Don't hold back, show what can truly be created when thinking outside the box and committing fully to a distinctive vision - while ensuring it works beautifully on every screen size.
Part 5: Design Research & Inspiration Resources
Use these curated resources during the research phase to gather authentic inspiration, study proven patterns, and avoid generic design decisions.
Curation & Reference Platforms
Are.na - https://www.are.na
Visual research tool for building mood boards and connecting ideas. Use for assembling contextual reference libraries, tracking design influences, and creating shareable channels documenting design processes. Think of it as "playlists for ideas" - following genuine curiosity leads to deeper creative engagement than algorithmic suggestions.
Mobbin - https://mobbin.com
UI pattern library with 1,150+ apps, 586,700+ screens, and 312,000+ user flows. Search by screens, UI elements, flows, or text within screenshots. Features apps from Airbnb, Uber, ChatGPT, Dropbox, Nike. Includes Figma plugin for direct download. Use to study how leading apps handle specific design challenges and explore complete user journeys.
Logggos - https://www.logggos.club
Curated logo gallery organized by business sectors (Tech, DTC, Agencies) and filterable by typography styles (sans-serif, script, serif), colors, and geometric shapes. Use when designing logo-adjacent elements or studying brand identity patterns.
Icons & Visual Assets
The Noun Project - https://thenounproject.com
10M+ human-curated icons and photos in SVG/PNG formats. Emphasizes "Made by Humans" curation over algorithmic content. Use for quick icon discovery during design workflows, but consider creating custom icons for distinctive projects.
Artvee - https://artvee.com
High-resolution public domain paintings, posters, and illustrations. Categories include Abstract, Figurative, Landscape, Still Life, Religion, Mythology. All files freely usable for personal and commercial projects. Use for incorporating classical artwork, creating derivative works, or adding historical visual elements.
Mockupworld - https://www.mockupworld.co
Free photo-realistic PSD mockups for devices (iPhone, iPad, MacBook), packaging, print materials, and vehicles. Use to present designs in realistic contexts for client presentations or portfolio pieces.
Site Builders for Reference
Cargo - https://cargo.site
Site builder for designers and artists with strong creative focus. Study Cargo sites for clean portfolio presentations and community-curated examples of quality design.
Readymag - https://readymag.com
Specialized for creating cool animations and extravagant transitions. Study Readymag projects for motion design inspiration and experimental layout approaches.
Web Design Inspiration
Godly.website - https://godly.website
"Astronomically good web design inspiration" - 1,000+ curated exceptional websites spanning diverse industries. Features work from recognized design leaders (Metalab, Lusion, Notion, Stripe) and emerging talent. Use for studying cutting-edge design approaches.
Minimal Gallery - https://minimal.gallery
Hand-picked minimalist web design since 2013. Rigorous human curation (most submissions rejected). Organized by industry and design approach. Use for studying purposeful, clean design that prioritizes both visual elegance and usability.
Brutalist Websites - https://brutalistwebsites.com
Curated collection of brutalist web design with interviews. Key principles: technical honesty over polish, anti-commercial stance, content-first approach, bare-bones functionality. Features magazine sites, portfolios, and experimental platforms. Use to understand deliberate aesthetic rejection and information-first design.
Landingfolio - https://landingfolio.com
Landing page inspiration and templates organized by design approach and industry. Use for studying effective conversion-focused layouts and call-to-action patterns.
Foundational Learning
Degreeless.design - https://degreeless.design
Comprehensive self-directed design education resource. Organized in progressive stages: Basics (typography, color theory, design history), UX Essentials (process, research, design systems), Advanced (industry content from Airbnb, Google). Key philosophy: "Process is the value you bring. Tools change & trends die."
Google Fonts Knowledge - https://fonts.google.com/knowledge
Typography guidance and principles from Google. Covers type design, font selection, pairing strategies, and web font implementation best practices.
Blogs & Analysis
Brand New - https://www.underconsideration.com/brandnew/
Daily updates on logo, identity, and branding projects. Features before-and-after rebrand analysis with critical commentary. Categories: Reviewed (in-depth analysis), Noted (professional observations), Spotted (discovery-focused). Use to study branding decisions and understand what makes identity work succeed or fail.
Experimental Design Tools
Constraint Systems - https://constraint.systems
Collection of experimental creative tools for unique layouts and constraint-based design exploration. Use for breaking out of conventional layout patterns.
Whisk by Google Labs - https://labs.google/whisk
Experimental image generation tool powered by Imagen 4. Enables "prompting with pictures" - upload reference images as creative prompts and mix ideas in new ways. Use for rapid visual exploration and concept iteration during early design phases.
Design Systems to Study
IBM Carbon - https://carbondesignsystem.com
Enterprise design system emphasizing accessibility and consistency. Study for: responsive layout systems (breakpoints xs through 2xl), density options (condensed/normal), data visualization patterns, modular component architecture. Excellent reference for data-heavy applications.
GitHub Primer - https://primer.style
Comprehensive open-source design system with strong accessibility focus. Study for: detailed accessibility patterns and checklists, Octicons SVG icon system, design tokens (color, spacing, typography), component libraries for React/Rails.
Material Design 3 - https://m3.material.io
Google's latest design system. Study for: typography scale (display, headline, title, label, body styles), cohesive color palette with semantic tokens, elevation system for visual hierarchy, CSS custom properties for dynamic theming.
Part 6: Design System Principles
Learn from production design systems to create more cohesive, maintainable interfaces.
Token-Based Design
Use semantic design tokens instead of hardcoded values:
:root {
--color-blue-500: #3b82f6;
--color-gray-900: #111827;
--spacing-4: 1rem;
--color-primary: var(--color-blue-500);
--color-text-primary: var(--color-gray-900);
--spacing-component-padding: var(--spacing-4);
}
.button {
background: var(--color-primary);
color: var(--color-text-on-primary);
padding: var(--spacing-component-padding);
}
Typography Scale
Establish a clear type hierarchy (inspired by Material 3):
:root {
--type-display-large: 57px/64px;
--type-display-medium: 45px/52px;
--type-headline-large: 32px/40px;
--type-headline-medium: 28px/36px;
--type-title-large: 22px/28px;
--type-title-medium: 16px/24px;
--type-body-large: 16px/24px;
--type-body-medium: 14px/20px;
--type-label-large: 14px/20px;
--type-label-medium: 12px/16px;
}
Elevation & Depth
Create visual hierarchy through consistent elevation (from Carbon/Material):
:root {
--elevation-1: 0 1px 2px rgba(0, 0, 0, 0.05);
--elevation-2: 0 4px 6px -1px rgba(0, 0, 0, 0.1);
--elevation-3: 0 10px 15px -3px rgba(0, 0, 0, 0.1);
--elevation-4: 0 20px 25px -5px rgba(0, 0, 0, 0.1);
}
.card { box-shadow: var(--elevation-1); }
.dropdown { box-shadow: var(--elevation-2); }
.modal { box-shadow: var(--elevation-4); }
Density Variants
Support different density contexts (from Carbon):
.component {
--component-padding: var(--spacing-4);
}
.component--condensed {
--component-padding: var(--spacing-2);
}
.data-table--condensed .table-cell {
padding: var(--spacing-1) var(--spacing-2);
}
Accessibility Patterns (from Primer)
.visually-hidden {
position: absolute;
width: 1px;
height: 1px;
padding: 0;
margin: -1px;
overflow: hidden;
clip: rect(0, 0, 0, 0);
white-space: nowrap;
border: 0;
}
.interactive:focus-visible {
outline: 2px solid var(--color-focus);
outline-offset: 2px;
}
@media (prefers-reduced-motion: reduce) {
*, *::before, *::after {
animation-duration: 0.01ms !important;
transition-duration: 0.01ms !important;
}
}
For a full three-tier token architecture (constant → semantic → contextual) with multi-theme mapping, see Part 30. For cascade management of token layers, see Part 31.
Part 7: Brutalist Design Principles
For projects requiring anti-conventional aesthetics, study these brutalist principles:
Core Philosophy
Brutalism in web design is "a reaction by a younger generation to the lightness, optimism, and frivolity of today's web design." Key principles:
- Technical Honesty - Expose the scaffolding of web design rather than masking code and structure
- Anti-Commercial Stance - Reject polish, persuasion, and visual manipulation
- Content-First - Information hierarchy stripped to essentials; aesthetics serve function
- Deliberate Austerity - Uncompromising, deliberately austere, defiantly unfashionable
Implementation Patterns
body {
font-family: monospace;
font-size: 16px;
line-height: 1.4;
}
.container {
max-width: none;
padding: 20px;
}
body {
background: #fff;
color: #000;
}
body.dark {
background: #000;
color: #fff;
}
nav a {
text-decoration: underline;
color: inherit;
}
a:hover {
}
button {
border: 2px solid currentColor;
background: transparent;
padding: 8px 16px;
font-family: inherit;
cursor: pointer;
}
When to Use Brutalism
- Artistic and experimental projects
- Anti-establishment brand positioning
- Developer tools and documentation
- Editorial/magazine content prioritizing text
- Portfolios for designers wanting to stand out
Part 8: Motion Design Principles
Create intentional, impactful animations that enhance rather than distract.
High-Impact Moments
Focus animation budget on key moments:
.hero-content > * {
opacity: 0;
transform: translateY(20px);
animation: fadeInUp 0.6s ease-out forwards;
}
.hero-content > *:nth-child(1) { animation-delay: 0ms; }
.hero-content > *:nth-child(2) { animation-delay: 100ms; }
.hero-content > *:nth-child(3) { animation-delay: 200ms; }
@keyframes fadeInUp {
to {
opacity: 1;
transform: translateY(0);
}
}
Scroll-Triggered Effects
.section {
opacity: 0;
transform: translateY(40px);
transition: opacity 0.6s ease, transform 0.6s ease;
}
.section.visible {
opacity: 1;
transform: translateY(0);
}
Hover States That Surprise
.card {
transition: transform 0.3s ease, box-shadow 0.3s ease;
}
.card:hover {
transform: translateY(-4px) rotate(-1deg);
box-shadow: 8px 8px 0 var(--color-accent);
}
.card:hover {
transform: translate(-4px, -4px);
box-shadow: 4px 4px 0 #000;
}
Performance Considerations
.animate-safe {
transition: transform 0.3s ease, opacity 0.3s ease;
}
.heavy-animation {
will-change: transform;
}
Modern CSS Alternatives: Scroll-driven animations (Part 18) can replace JavaScript Intersection Observer patterns. View Transitions API (Part 18) provides native page transition support. For AI-specific loading and streaming animations, see Part 21.
Part 9: Foundational UX Principles
Master these timeless principles that form the foundation of effective interface design.
Nielsen's 10 Usability Heuristics
1. Visibility of System Status
Keep users informed through appropriate feedback within reasonable time. Show loading states, progress indicators, and confirmation messages.
2. Match Between System and Real World
Use familiar language and concepts. Follow real-world conventions; make information appear in natural, logical order.
3. User Control and Freedom
Provide clear "emergency exits" - undo, redo, cancel buttons. Users often perform actions by mistake and need escape routes.
4. Consistency and Standards
Follow platform conventions. Users shouldn't wonder whether different words, situations, or actions mean the same thing.
5. Error Prevention
Design to prevent errors before they occur. Use confirmation dialogs for destructive actions; provide helpful constraints.
6. Recognition Rather Than Recall
Make elements, actions, and options visible. Minimize memory load by showing information contextually.
7. Flexibility and Efficiency of Use
Offer shortcuts for expert users while keeping the interface simple for novices. Support personalization.
8. Aesthetic and Minimalist Design
Every extra unit of information competes with relevant information. Remove elements that don't serve the user's goals.
9. Help Users Recognize, Diagnose, and Recover from Errors
Express errors in plain language, precisely indicate the problem, and constructively suggest solutions.
10. Help and Documentation
Provide searchable, task-focused documentation accessible in context when users need it.
Key Laws of UX
Cognitive & Attention
- Hick's Law: Decision time increases with choice quantity and complexity. Minimize options to accelerate decisions.
- Miller's Law: Working memory holds ~7±2 items. Present information in groups of 5-9 maximum.
- Cognitive Load: Simplify tasks to reduce mental demand. Users have limited processing capacity.
Visual Perception (Gestalt)
- Law of Proximity: Objects near each other appear grouped. Position related items close together.
- Law of Similarity: Similar elements appear unified. Use consistent styling to show relationships.
- Law of Common Region: Boundaries create perceived grouping. Use borders/backgrounds to organize.
Interaction
- Fitts's Law: Target acquisition time depends on distance and size. Make clickable areas appropriately sized.
- Doherty Threshold: Response times under 400ms improve productivity. Optimize for perceived speed.
- Jakob's Law: Users prefer familiar patterns. Match conventions from platforms users already know.
Memory & Experience
- Peak-End Rule: Users judge experiences by peak moments and conclusions, not averages. Design memorable highs and strong endings.
- Von Restorff Effect: Distinctive items stand out in memory. Highlight important elements through differentiation.
- Serial Position Effect: Users remember first and last items best. Prioritize critical information at boundaries.
Design Philosophy
- Aesthetic-Usability Effect: Beautiful design is perceived as more usable. Visual appeal enhances perceived functionality.
- Occam's Razor: Prefer simpler solutions with fewer assumptions over complex ones.
- Tesler's Law: All systems contain irreducible complexity. Distribute it appropriately between system and user.
- Pareto Principle: 80% of effects stem from 20% of causes. Focus effort on high-impact elements.
Part 10: Humane Design Principles
Design ethically by prioritizing user well-being over engagement metrics.
The 7 Principles
1. Empowering
Prioritize value delivered to users over revenue generation.
- Give users authority over algorithms shaping their experience
- Grant control over personal data and identity management
- Technology should strengthen abilities without intruding unnecessarily
- Maintain user understanding and trust in AI decisions (human in the loop)
2. Finite
Respect users' time and attention as limited resources.
- Show "all caught up" indicators when content is exhausted
- Replace infinite scroll with explicit "load more" controls
- Disable autoplay; require conscious user action
- Design experiences with clear endings, not endless engagement
3. Inclusive
Enable and draw on the full range of human diversity.
- Build diverse teams to create broader perspectives
- Design for disabilities first; solutions often benefit everyone
- Provide control over accessibility preferences (zoom, contrast, animations)
- Don't disable platform features users depend on
4. Intentional
Employ friction to prevent misuse and encourage healthier habits.
- Use confirmation dialogs to minimize mistakes
- Embrace positive friction for more deliberate choices
- Provide mechanisms for users to manage consumption patterns
- Prioritize long-term user benefit over immediate engagement
5. Respectful
Safeguard people's time, attention, and digital well-being.
- Align notification delivery with actual urgency
- Allow personalization of notification sources, timing, formats
- Include full content in notifications rather than requiring app visits
- Design technology that adapts to user context
6. Transparent
Be clear about intentions, honest in actions, free of dark patterns.
- Clearly explain what users commit to when adopting products
- Articulate what data is gathered and why
- Allow users to view collected information
- Provide the right to be forgotten with easy deletion
- Avoid misdirection; separate ads from content clearly
- Make unsubscribe and exit options easily discoverable
7. Resilient
Ensure systems remain stable, reliable, and sustainable.
- Design for long-term user relationships, not exploitation
- Build systems that degrade gracefully
- Support user autonomy rather than dependency
Anti-Patterns to Avoid
These manipulative patterns violate humane design principles:
- Infinite scroll without endpoints (violates Finite)
- Autoplay that consumes attention without consent (violates Respectful)
- Dark patterns that trick users into actions (violates Transparent)
- Notification spam designed to maximize engagement (violates Respectful)
- Hidden unsubscribe options (violates Transparent)
- Confirmation shaming ("No, I don't want to save money") (violates Respectful)
- Forced continuity with difficult cancellation (violates Empowering)
Part 11: Comprehensive Accessibility Checklist
Reference checklist based on WCAG guidelines and A11Y Project standards.
HTML & Structure
Headings
Keyboard Navigation
Images
Forms
Links & Buttons
Color & Contrast
Media
Motion & Animation
Mobile & Touch
Cognitive Accessibility
Part 12: Dieter Rams' 10 Principles for Good Design
These timeless principles from industrial designer Dieter Rams apply directly to interface design:
- Good design is innovative - Push boundaries; don't settle for conventional solutions
- Good design makes a product useful - Every element must serve the user's goals
- Good design is aesthetic - Visual quality is integral, not superficial
- Good design makes a product understandable - The interface explains itself
- Good design is unobtrusive - Serve the user's purpose without demanding attention
- Good design is honest - Don't pretend to be more than you are; no dark patterns
- Good design is long-lasting - Avoid trendy elements that age quickly
- Good design is thorough down to the last detail - Every pixel matters
- Good design is environmentally-friendly - Optimize performance; respect resources
- Good design is as little design as possible - "Less, but better" - only the essential
Part 13: The 8-Point Grid System
Use multiples of 8 for all spacing, sizing, and layout decisions.
Core Rules
:root {
--space-1: 4px;
--space-2: 8px;
--space-3: 16px;
--space-4: 24px;
--space-5: 32px;
--space-6: 48px;
--space-7: 64px;
--space-8: 96px;
}
Why 8pt Works
- Consistency: All measurements follow the same rules
- Reduced decisions: Fewer spacing options = faster design + development
- Multi-platform: Most screen sizes divide evenly by 8 on at least one axis
- Scaling: Works cleanly at 1x, 2x, 3x resolutions
Implementation Methods
Hard Grid: Display actual grid, align all elements to it (like Material Design's 4pt grid)
Soft Grid: Measure 8pt between elements without visible grid (better for iOS, faster workflow)
Typography Exception
Text sizing and line-height don't always conform to 8pt while maintaining readability. Use platform guidelines and typeface-specific metrics, then build UI around established text dimensions.
Part 14: Typography Scale Ratios
Use mathematical ratios for harmonious type hierarchies:
| Ratio | Name | Use Case |
|---|
| 1.067 | Minor Second | Subtle hierarchy, dense UI |
| 1.125 | Major Second | Conservative, professional |
| 1.200 | Minor Third | Balanced, versatile |
| 1.250 | Major Third | Clear distinction |
| 1.333 | Perfect Fourth | Strong hierarchy |
| 1.414 | Augmented Fourth | Dramatic contrast |
| 1.500 | Perfect Fifth | Bold statements |
| 1.618 | Golden Ratio | Classic proportion |
Applying a Scale
:root {
--text-xs: 10px;
--text-sm: 13px;
--text-base: 16px;
--text-lg: 20px;
--text-xl: 25px;
--text-2xl: 31px;
--text-3xl: 39px;
--text-4xl: 49px;
}
Tool: Use https://typescale.com/ to generate scales with different ratios.
For fluid typography that scales smoothly between breakpoints using clamp(), see Part 24. For variable fonts and OpenType features, also Part 24.
Part 15: Spatial System Approaches
Element-First (Strict Sizing)
Prioritize component dimensions matching your spatial system:
.button {
height: 40px;
padding: 0 16px;
}
Best for: Buttons, form inputs, fixed-height components
Content-First (Strict Padding)
Enforce consistent padding, let element sizes adapt:
.card {
padding: 24px;
}
Best for: Cards, tables, variable-length content
Part 16: Settings Philosophy
From Linear: "Settings are not a design failure."
Key Principles
- Distinguish preferences from failures - Some settings address legitimate individual differences, not poor defaults
- Settings as onboarding - Use settings to educate users about capabilities
- Emotional connection through details - Customization creates user attachment
- Respect habits - "Create products that fit into people's lives, not the other way around"
When to Add Settings
- User habits genuinely vary (keyboard shortcuts, themes)
- Platform conventions differ (Mac vs Windows)
- Accessibility needs vary (motion, contrast)
- Power users need efficiency (density, defaults)
When NOT to Add Settings
- You're avoiding a design decision
- The "right" answer is knowable through research
- Adding complexity without clear user benefit
Part 17: Comprehensive Learning Resources
Self-Directed Design Education
Foundational Principles
Design Process & Methodology
Typography
Spacing & Layout
Ethical & Humane Design
Accessibility
Design Systems Reference
Industry Blogs & Publications
Inspiration Galleries
Books (Essential Reading)
Foundations:
- Thinking With Type by Ellen Lupton
- Graphic Design: The New Basics by Ellen Lupton
- Grid Systems by Kimberly Elam
- The Design of Everyday Things by Don Norman
UX & Process:
- Just Enough Research by Erika Hall
- Sprint by Jake Knapp
- The User Experience Team of One by Leah Buley
- Mismatch by Kat Holmes (inclusive design)
Interactive Learning
Newsletters
Courses
Modern CSS
Performance
Fluid Typography
AI Interface Design
Part 18: Modern CSS Techniques
These features are baseline-available in all evergreen browsers (2025-2026). No polyfills needed. Use them to reduce JavaScript dependency and build more resilient interfaces.
Container Queries
Make components responsive to their container, not the viewport. Essential for reusable component libraries.
.card-container {
container-type: inline-size;
container-name: card;
}
@container card (min-width: 400px) {
.card {
display: grid;
grid-template-columns: 200px 1fr;
gap: 16px;
}
}
@container card (max-width: 399px) {
.card {
display: flex;
flex-direction: column;
}
.card img {
width: 100%;
aspect-ratio: 16 / 9;
object-fit: cover;
}
}
Key Rule: Use container queries for component-level responsiveness, media queries for page-level layout. A sidebar card and a main-content card can now use the same component with different layouts.
The :has() Selector
The most powerful CSS selector added in years. Enables parent-aware styling without JavaScript.
.form-group:has(:invalid) {
border-color: var(--color-error);
}
.card:has(> img) {
grid-template-rows: 200px 1fr;
}
.card:not(:has(> img)) {
grid-template-rows: 1fr;
}
.nav:has(.dropdown:focus-within) .overlay {
opacity: 1;
pointer-events: auto;
}
.checkbox:has(:checked) + .label {
text-decoration: line-through;
opacity: 0.6;
}
Key Rule: :has() eliminates many JavaScript DOM manipulation patterns. Before writing classList.toggle() in JS, check if :has() can achieve the same result in CSS.
CSS Subgrid
Align nested grid children to their parent's grid tracks. Solves the perennial "align cards in a grid" problem.
.card-grid {
display: grid;
grid-template-columns: repeat(auto-fill, minmax(280px, 1fr));
gap: 24px;
}
.card {
display: grid;
grid-template-rows: subgrid;
grid-row: span 3;
}
View Transitions API
Animate between view states with native browser support. Replaces complex JavaScript transition libraries.
.product-image {
view-transition-name: product-hero;
}
.product-title {
view-transition-name: product-title;
}
::view-transition-old(product-hero) {
animation: fadeOut 0.3s ease-out;
}
::view-transition-new(product-hero) {
animation: fadeIn 0.3s ease-in;
}
document.startViewTransition(() => {
updateDOM();
});
Cross-reference: Part 8 (Motion Design) for animation principles.
Scroll-Driven Animations
Replace JavaScript Intersection Observer with pure CSS scroll-triggered animations.
.reading-progress {
position: fixed;
top: 0;
left: 0;
height: 3px;
background: var(--color-primary);
transform-origin: left;
animation: growWidth linear;
animation-timeline: scroll();
}
@keyframes growWidth {
from { transform: scaleX(0); }
to { transform: scaleX(1); }
}
.section {
animation: fadeInUp linear both;
animation-timeline: view();
animation-range: entry 0% entry 100%;
}
@keyframes fadeInUp {
from {
opacity: 0;
transform: translateY(40px);
}
to {
opacity: 1;
transform: translateY(0);
}
}
Key Rule: Scroll-driven animations run off-main-thread, making them smoother than JavaScript-based scroll handlers. Always prefer these over Intersection Observer for visual effects.
CSS Nesting
Write nested styles without a preprocessor. Keeps component styles co-located and readable.
.card {
padding: var(--space-4);
border-radius: var(--radius-md);
& .title {
font-size: var(--text-lg);
font-weight: 600;
}
& .description {
color: var(--text-secondary);
}
&:hover {
box-shadow: var(--elevation-2);
}
@media (max-width: 768px) {
padding: var(--space-3);
}
}
Key Rule: Limit nesting to 3 levels maximum. Deeper nesting creates specificity problems and is hard to read.
Anchor Positioning
Position tooltips, popovers, and dropdowns relative to anchor elements without JavaScript positioning libraries.
.trigger {
anchor-name: --tooltip-anchor;
}
.tooltip {
position: fixed;
position-anchor: --tooltip-anchor;
top: anchor(bottom);
left: anchor(center);
translate: -50% 8px;
position-try-fallbacks: flip-block;
}
Popover API
Build dismissable overlays with zero JavaScript. Handles focus trapping, backdrop, and light-dismiss behavior natively.
<button popovertarget="menu">Open Menu</button>
<div id="menu" popover>
<nav>
<a href="/settings">Settings</a>
<a href="/profile">Profile</a>
<a href="/logout">Log out</a>
</nav>
</div>
[popover] {
padding: var(--space-3);
border: 1px solid var(--border);
border-radius: var(--radius-md);
box-shadow: var(--elevation-3);
}
[popover]::backdrop {
background: rgba(0, 0, 0, 0.3);
}
Key Rule: Use Popover API for any light-dismiss behavior (dropdown menus, tooltips, popovers) instead of custom click-outside handlers.
Cascade Layers Preview
Organize CSS priority without fighting specificity. Deep dive in Part 31.
@layer reset, base, tokens, components, utilities, overrides;
@layer components {
.button { background: var(--color-primary); }
}
@layer utilities {
.bg-red { background: red; }
}
Quick Reference
| Feature | Replaces | Use Case |
|---|
| Container queries | Media queries for components | Reusable responsive components |
:has() | JS class toggling | Parent-aware styling |
| Subgrid | Manual alignment hacks | Consistent grid children |
| View Transitions | JS transition libraries | Page/state transitions |
| Scroll-driven animations | Intersection Observer | Scroll-triggered effects |
| CSS nesting | Sass/Less nesting | Scoped component styles |
| Anchor positioning | JS positioning (Popper/Floating UI) | Tooltips, dropdowns |
| Popover API | Custom modal/dropdown JS | Light-dismiss overlays |
@layer | Specificity management hacks | Design system CSS ordering |
Part 19: Performance-First Design (Core Web Vitals)
Beautiful design means nothing if it takes 5 seconds to load. Design decisions directly impact performance metrics.
The Three Metrics
| Metric | Good | Needs Work | Poor | What It Measures |
|---|
| LCP (Largest Contentful Paint) | ≤ 2.5s | ≤ 4.0s | > 4.0s | Largest visible element loads |
| INP (Interaction to Next Paint) | ≤ 200ms | ≤ 500ms | > 500ms | Interactions feel instant |
| CLS (Cumulative Layout Shift) | ≤ 0.1 | ≤ 0.25 | > 0.25 | Nothing jumps around |
CLS Prevention Patterns
Layout shift is the most common design-caused performance issue. Prevent it at the design level.
img {
width: 100%;
height: auto;
aspect-ratio: 16 / 9;
}
.embed-container {
min-height: 300px;
contain: layout;
}
@font-face {
font-family: 'Display';
src: url('/fonts/display.woff2') format('woff2');
font-display: swap;
size-adjust: 105%;
ascent-override: 90%;
descent-override: 20%;
}
Key Rule: Every element that loads asynchronously (images, embeds, fonts, lazy content) must have its space reserved before it arrives.
LCP Optimization
Identify your LCP element (usually a hero image or headline) and prioritize it.
<link rel="preload" as="image" href="/hero.avif" type="image/avif">
<img src="/hero.avif" alt="Hero" fetchpriority="high" width="1200" height="600">
<style>
.hero { display: grid; grid-template-columns: 1fr 1fr; min-height: 80vh; }
.hero-title { font-size: clamp(2rem, 5vw, 4rem); }
</style>
<link rel="stylesheet" href="/styles.css" media="print" onload="this.media='all'">
INP Optimization
Keep interactions feeling instant by yielding to the main thread.
async function handleFilterChange(filters) {
updateFilterUI(filters);
await scheduler.yield();
const results = filterData(filters);
await scheduler.yield();
renderResults(results);
}
details[open] .content {
animation: slideDown 0.2s ease-out;
}
Skeleton Loaders
Skeletons prevent CLS by reserving exact space for incoming content.
.skeleton {
--skeleton-base: hsl(0 0% 88%);
--skeleton-shine: hsl(0 0% 96%);
background: linear-gradient(
90deg,
var(--skeleton-base) 25%,
var(--skeleton-shine) 50%,
var(--skeleton-base) 75%
);
background-size: 200% 100%;
animation: shimmer 1.5s infinite linear;
border-radius: var(--radius-sm);
}
@keyframes shimmer {
to { background-position: -200% 0; }
}
@media (prefers-color-scheme: dark) {
.skeleton {
--skeleton-base: hsl(0 0% 18%);
--skeleton-shine: hsl(0 0% 25%);
}
}
.skeleton-title { height: 28px; width: 60%; }
.skeleton-text { height: 16px; width: 100%; }
.skeleton-avatar { height: 48px; width: 48px; border-radius: 50%; }
Key Rule: Skeletons must match the exact dimensions of the content they replace. A mismatched skeleton is worse than no skeleton because it causes shift when real content arrives.
Animation Performance Budget
.animate-safe {
transition: transform 0.3s ease, opacity 0.3s ease;
}
.heavy-animation {
will-change: transform;
}
.animated-section {
contain: layout paint;
}
Resource Hints
<link rel="preload" as="font" href="/fonts/display.woff2" type="font/woff2" crossorigin>
<link rel="preload" as="image" href="/hero.avif">
<link rel="preconnect" href="https://fonts.googleapis.com">
<link rel="preconnect" href="https://api.example.com">
<link rel="prefetch" href="/dashboard.js">
<link rel="dns-prefetch" href="https://analytics.example.com">
| Hint | When to Use | Impact |
|---|
preload | Critical above-the-fold resources | Reduces LCP |
preconnect | APIs, font hosts, CDNs | Reduces connection time |
prefetch | Next page resources | Faster navigation |
dns-prefetch | Third-party domains | Minor latency reduction |
fetchpriority="high" | LCP image/resource | Browser prioritization |
Performance Checklist
Part 20: Dark Mode & Theming
Dark mode is not "invert the colors." It requires intentional design decisions about depth, contrast, and color behavior.
System Preference Detection
:root {
color-scheme: light dark;
--color-surface-0: #ffffff;
--color-surface-1: #f5f5f5;
--color-surface-2: #ebebeb;
--color-text-primary: #1a1a1a;
--color-text-secondary: #666666;
--color-border: #e0e0e0;
--color-interactive: hsl(220, 90%, 50%);
}
@media (prefers-color-scheme: dark) {
:root {
--color-surface-0: #121212;
--color-surface-1: #1e1e1e;
--color-surface-2: #2a2a2a;
--color-text-primary: #e5e5e5;
--color-text-secondary: #a0a0a0;
--color-border: rgba(255, 255, 255, 0.12);
--color-interactive: hsl(220, 70%, 65%);
}
}
User Override Pattern
Always allow users to override system preference. Use a three-state toggle: System / Light / Dark.
[data-theme="light"] {
--color-surface-0: #ffffff;
--color-text-primary: #1a1a1a;
}
[data-theme="dark"] {
--color-surface-0: #121212;
--color-text-primary: #e5e5e5;
}
function setTheme(preference) {
if (preference === 'system') {
document.documentElement.removeAttribute('data-theme');
localStorage.removeItem('theme');
} else {
document.documentElement.setAttribute('data-theme', preference);
localStorage.setItem('theme', preference);
}
}
const saved = localStorage.getItem('theme');
if (saved) document.documentElement.setAttribute('data-theme', saved);
Key Rule: Always default to system preference. Never force a theme. Run the restore script in <head> to prevent a flash of wrong theme (FOWT).
The light-dark() CSS Function
Concise inline theme switching for simple cases.
:root {
color-scheme: light dark;
}
.text {
color: light-dark(#1a1a1a, #e5e5e5);
}
.surface {
background: light-dark(#ffffff, #121212);
}
.border {
border-color: light-dark(#e0e0e0, rgba(255, 255, 255, 0.12));
}
Use light-dark() for simple one-off values. Use custom properties for values referenced in multiple places.
Color Adjustments for Dark Mode
Colors that look great on light backgrounds often look harsh on dark backgrounds.
:root {
--color-primary: hsl(220, 90%, 50%);
--color-success: hsl(145, 80%, 38%);
--color-error: hsl(0, 85%, 50%);
}
@media (prefers-color-scheme: dark) {
:root {
--color-primary: hsl(220, 70%, 65%);
--color-success: hsl(145, 60%, 55%);
--color-error: hsl(0, 65%, 60%);
}
}
Key Rule: Desaturate colors ~20% and increase lightness for dark mode. Pure white text on pure black is harder to read than off-white on dark gray.
Depth Without Shadows
Shadows are nearly invisible on dark backgrounds. Use surface elevation instead.
:root {
--surface-0: #121212;
--surface-1: #1e1e1e;
--surface-2: #232323;
--surface-3: #292929;
--surface-4: #333333;
}
.card {
background: var(--surface-1);
border: 1px solid rgba(255, 255, 255, 0.08);
}
.modal {
background: var(--surface-3);
border: 1px solid rgba(255, 255, 255, 0.12);
}
@media (prefers-color-scheme: light) {
.card { box-shadow: var(--elevation-1); border: none; }
.modal { box-shadow: var(--elevation-4); border: none; }
}
Multi-Theme Token Architecture
Support more than just light/dark. High-contrast and brand themes use the same token system.
| Token | Light | Dark | High Contrast |
|---|
--surface-0 | #ffffff | #121212 | #000000 |
--text-primary | #1a1a1a | #e5e5e5 | #ffffff |
--border | #e0e0e0 | rgba(255,255,255,0.12) | #ffffff |
--interactive | hsl(220,90%,50%) | hsl(220,70%,65%) | hsl(220,100%,70%) |
@media (forced-colors: active) {
.button {
border: 2px solid ButtonText;
background: ButtonFace;
color: ButtonText;
}
.button:hover {
background: Highlight;
color: HighlightText;
}
}
Cross-reference: Part 30 (Design Token Architecture) for the full three-tier token system.
Image & Media in Dark Mode
@media (prefers-color-scheme: dark) {
img:not([src$=".svg"]) {
filter: brightness(0.85);
}
.icon { color: var(--text-primary); }
}
<picture>
<source srcset="/hero-dark.avif" media="(prefers-color-scheme: dark)">
<img src="/hero-light.avif" alt="Hero illustration">
</picture>
Dark Mode Anti-Patterns
| Anti-Pattern | Problem | Fix |
|---|
Pure black (#000) backgrounds | Harsh contrast, eye strain | Use #121212 or similar dark gray |
| Saturated colors on dark | Optical vibration, fatigue | Desaturate ~20%, increase lightness |
| Inverted shadows | Shadows invisible on dark | Use surface elevation (lighter = higher) |
| Forgetting scrollbar | System scrollbar clashes | color-scheme: dark or custom scrollbar CSS |
| Forgetting form defaults | Native inputs stay light | color-scheme: dark on :root |
| Flash of wrong theme | Theme loads after paint | Run theme script in <head> |
Part 21: AI-Era Design Patterns
AI interfaces break traditional UI conventions: response times are unpredictable, outputs vary in length and quality, and confidence is uncertain. These patterns address the unique UX challenges of AI-powered products.
Streaming UI
Chat and generative interfaces must handle token-by-token output gracefully.
.message.streaming {
}
.message.streaming::after {
content: '|';
color: var(--color-interactive);
animation: blink 1s step-end infinite;
margin-left: 2px;
}
@keyframes blink {
50% { opacity: 0; }
}
.chat-messages {
overflow-y: auto;
overscroll-behavior: contain;
scroll-behavior: smooth;
}
function shouldAutoScroll(container) {
const threshold = 100;
const distanceFromBottom =
container.scrollHeight - container.scrollTop - container.clientHeight;
return distanceFromBottom < threshold;
}
Key Rule: Always auto-scroll during streaming if the user is at the bottom. Stop auto-scrolling if they've scrolled up to read history. Show a "scroll to bottom" button when they're not at the latest message.
AI Loading States
AI loading is different from traditional loading: duration is unpredictable and can range from 1 second to 2 minutes.
.ai-loading {
display: flex;
align-items: center;
gap: 8px;
color: var(--text-secondary);
}
.ai-loading .dots span {
display: inline-block;
width: 6px;
height: 6px;
border-radius: 50%;
background: var(--color-interactive);
animation: pulse 1.4s ease-in-out infinite;
}
.ai-loading .dots span:nth-child(2) { animation-delay: 0.2s; }
.ai-loading .dots span:nth-child(3) { animation-delay: 0.4s; }
@keyframes pulse {
0%, 80%, 100% { opacity: 0.3; transform: scale(0.8); }
40% { opacity: 1; transform: scale(1); }
}
.ai-loading .elapsed {
font-size: var(--text-sm);
color: var(--text-tertiary);
opacity: 0;
animation: fadeIn 0.3s ease forwards 3s;
}
<div class="ai-loading">
<div class="dots"><span></span><span></span><span></span></div>
<span class="phase">Analyzing your request...</span>
<span class="elapsed">12s</span>
<button class="cancel" aria-label="Cancel generation">Stop</button>
</div>
Key Rule: Skeleton loaders are wrong for AI content because the structure is unknown. Use animated indicators with phase text. Always show a cancel button. Show elapsed time after 3+ seconds.
Confidence Indicators
When AI certainty varies, make it visible. Users trust AI more when it admits what it doesn't know.
.confidence {
display: inline-flex;
align-items: center;
gap: 4px;
padding: 2px 8px;
border-radius: var(--radius-sm);
font-size: var(--text-sm);
}
.confidence--high {
background: hsl(145, 60%, 90%);
color: hsl(145, 80%, 25%);
}
.confidence--medium {
background: hsl(40, 80%, 90%);
color: hsl(40, 90%, 25%);
}
.confidence--low {
background: hsl(0, 60%, 92%);
color: hsl(0, 70%, 30%);
}
<p>
The population of Tokyo is approximately 14 million.
<a href="#source-1" class="source-ref" aria-label="Source 1">[1]</a>
</p>
Explainability & Transparency UX
<div class="ai-response">
<div class="response-content">...</div>
<details class="reasoning">
<summary>How AI reached this conclusion</summary>
<ol class="reasoning-steps">
<li>Analyzed 3 data sources for population statistics</li>
<li>Cross-referenced with 2023 census data</li>
<li>Applied seasonal adjustment factor</li>
</ol>
</details>
</div>
.reasoning {
margin-top: var(--space-3);
padding: var(--space-3);
background: var(--surface-1);
border-radius: var(--radius-md);
font-size: var(--text-sm);
}
.reasoning summary {
cursor: pointer;
color: var(--text-secondary);
font-weight: 500;
}
.reasoning summary:hover {
color: var(--text-primary);
}
Human-in-the-Loop Controls
AI output should be editable, not read-only. Users need to correct, refine, and direct.
.response-actions {
display: flex;
gap: 4px;
padding-top: var(--space-2);
border-top: 1px solid var(--border);
margin-top: var(--space-3);
}
.response-actions button {
display: inline-flex;
align-items: center;
gap: 4px;
padding: 4px 8px;
border: none;
background: transparent;
color: var(--text-secondary);
font-size: var(--text-sm);
border-radius: var(--radius-sm);
cursor: pointer;
}
.response-actions button:hover {
background: var(--surface-1);
color: var(--text-primary);
}
<div class="response-actions">
<button aria-label="Copy response"><svg>...</svg> Copy</button>
<button aria-label="Edit response"><svg>...</svg> Edit</button>
<button aria-label="Regenerate response"><svg>...</svg> Regenerate</button>
<button aria-label="Report issue"><svg>...</svg> Report</button>
<div class="feedback" role="group" aria-label="Rate response">
<button aria-label="Good response"><svg>...</svg></button>
<button aria-label="Bad response"><svg>...</svg></button>
</div>
</div>
Error Handling for AI
AI failures need different patterns than traditional errors because users need manual fallback paths.
<div class="ai-error" role="alert">
<div class="error-icon"></div>
<div class="error-content">
<p class="error-title">AI couldn't complete this request</p>
<p class="error-detail">The model is temporarily overloaded. Your input has been saved.</p>
</div>
<div class="error-actions">
<button class="retry">Try again</button>
<button class="manual-fallback">Do it manually</button>
</div>
</div>
Design principles for AI errors:
- Explain what happened in plain language (not error codes)
- Preserve user input so they don't have to re-type
- Offer retry with a single click
- Provide manual fallback so the user isn't stuck
- Show partial results if the AI got partway through
User Control Over AI
<div class="ai-settings">
<label>
Response length
<select>
<option>Concise</option>
<option>Balanced</option>
<option>Detailed</option>
</select>
</label>
<label>
<input type="checkbox" checked>
Show confidence indicators
</label>
<label>
<input type="checkbox" checked>
Show reasoning steps
</label>
<button class="clear-context">Clear conversation history</button>
</div>
Key Rule: User control > perceived AI capability. Explicit controls and predictability matter more than hidden automation. Always let users stop, undo, regenerate, and edit AI output.
AI Interface Quick Reference
| Pattern | Use When | Anti-Pattern |
|---|
| Streaming with cursor | Real-time text generation | Waiting for full response then dumping it |
| Phase-based loading | AI processing > 1 second | Generic spinner with no context |
| Confidence indicators | Output certainty varies | Presenting everything with equal authority |
| Expandable reasoning | Complex multi-step AI decisions | Black-box output with no explanation |
| Response action bar | Users need to act on AI output | Read-only AI responses |
| Manual fallback | AI unavailable or fails | Dead-end error states |
Part 22: Advanced Interaction Design
Good interaction design makes an interface feel alive and responsive. Every component has multiple states, and transitions between them matter as much as the states themselves.
Micro-Interaction Taxonomy
Micro-interactions follow a four-part structure: Trigger → Rules → Feedback → Loops/Modes.
.button {
transition: transform 0.1s ease, box-shadow 0.1s ease;
}
.button:hover {
transform: translateY(-1px);
box-shadow: var(--elevation-2);
}
.button:active {
transform: translateY(0) scale(0.98);
box-shadow: none;
}
.button[aria-busy="true"] {
pointer-events: none;
opacity: 0.7;
}
.button[aria-busy="true"]::after {
content: '';
width: 14px;
height: 14px;
border: 2px solid currentColor;
border-top-color: transparent;
border-radius: 50%;
animation: spin 0.6s linear infinite;
margin-left: 8px;
}
.button.success {
background: var(--color-success);
}
@keyframes spin {
to { transform: rotate(360deg); }
}
Key Rule: Every interactive element needs at least four visual states: default, hover, active/pressed, and disabled. Important actions also need loading and success/error states.
Gesture Design
Design for touch interfaces with gesture alternatives for keyboard/mouse users.
| Gesture | Common Use | Non-Gesture Alternative |
|---|
| Swipe horizontal | Dismiss, navigate | Delete button, back/forward buttons |
| Swipe vertical | Pull-to-refresh, reveal | Refresh button, scroll to load |
| Long-press | Context menu, selection | Right-click, checkbox selection |
| Pinch | Zoom | Zoom buttons, slider |
| Double-tap | Quick action, zoom | Button, toggle |
Key Rule: Every gesture must have a visible, tappable alternative. Gestures are shortcuts, not the only path. Include onboarding hints for discoverable gestures.
Progressive Disclosure
Show only essential options first. Reveal complexity on demand.
<details>
<summary>Advanced settings</summary>
<div class="advanced-options">
</div>
</details>
details .advanced-options {
padding-top: var(--space-3);
animation: slideDown 0.2s ease-out;
}
@keyframes slideDown {
from { opacity: 0; transform: translateY(-8px); }
to { opacity: 1; transform: translateY(0); }
}
summary {
cursor: pointer;
color: var(--color-interactive);
font-weight: 500;
list-style: none;
}
summary::before {
content: '+ ';
}
details[open] summary::before {
content: '− ';
}
State-Based Design
Every component exists in multiple states. Design all of them intentionally.
| State | Design Treatment | Example |
|---|
| Empty | Illustration + CTA + explanation | "No messages yet. Start a conversation." |
| Loading | Skeleton matching content dimensions | Shimmer placeholders |
| Partial | Show what's available + loading indicator | 3 of 10 items loaded |
| Complete | Full content with actions | List with items |
| Error | Explain problem + retry action + manual fallback | "Couldn't load. Retry / Go to settings" |
| Offline | Cached content + offline indicator | "You're offline. Showing saved data." |
.empty-state {
display: flex;
flex-direction: column;
align-items: center;
justify-content: center;
padding: var(--space-8) var(--space-4);
text-align: center;
color: var(--text-secondary);
}
.empty-state .illustration {
width: 200px;
height: 200px;
margin-bottom: var(--space-4);
opacity: 0.6;
}
.empty-state .title {
font-size: var(--text-lg);
color: var(--text-primary);
margin-bottom: var(--space-2);
}
.empty-state .cta {
margin-top: var(--space-4);
}
Key Rule: Empty states and error states are design opportunities, not afterthoughts. A well-designed empty state guides users toward their first action.
State Transitions
Animate between states to help users understand what changed.
.content-area {
transition: opacity 0.3s ease;
}
.content-area[data-state="loading"] {
opacity: 0.6;
}
.content-area[data-state="complete"] {
opacity: 1;
}
.list-item {
opacity: 0;
transform: translateY(10px);
animation: enterItem 0.3s ease forwards;
}
.list-item:nth-child(1) { animation-delay: 0ms; }
.list-item:nth-child(2) { animation-delay: 50ms; }
.list-item:nth-child(3) { animation-delay: 100ms; }
.list-item:nth-child(4) { animation-delay: 150ms; }
@keyframes enterItem {
to { opacity: 1; transform: translateY(0); }
}
Scroll-Based Storytelling
Use scroll position to drive narrative through content sections.
.story-section {
position: relative;
min-height: 100vh;
}
.story-section .sticky-context {
position: sticky;
top: 0;
height: 100vh;
display: flex;
align-items: center;
justify-content: center;
}
.story-section .scroll-content {
position: relative;
z-index: 1;
}
@media (prefers-reduced-motion: no-preference) {
.parallax-element {
animation: parallax linear;
animation-timeline: scroll();
}
@keyframes parallax {
from { transform: translateY(-20px); }
to { transform: translateY(20px); }
}
}
Cross-reference: Part 18 (Modern CSS) for scroll-driven animation syntax. Part 8 (Motion) for performance rules.
Part 23: Data Visualization & Dashboard Design
Data-heavy interfaces require different design principles than marketing pages. Prioritize clarity, information density, and accurate representation.
Tufte's Core Principles
Edward Tufte's foundational rules for honest, effective data graphics:
- Maximize data-ink ratio: every pixel of ink should present data or aid comprehension of data. If a visual element doesn't encode data, remove it.
- Eliminate chart junk: decorative gridlines, 3D effects, excessive legends, gradient fills, and ornamental elements that don't serve the data.