Skills
ui-ux-guidelines
ui-ux-guidelines
npx @loomcraft/cli add skill ui-ux-guidelinesFrontmatter
Name
ui-ux-guidelines
Description
UI/UX design rules for accessibility, interaction, typography, color, and animation. Use when building user-facing interfaces, reviewing designs, checking accessibility compliance, or choosing fonts and color palettes.
Content
# UI/UX Design Guidelines Comprehensive design guide covering accessibility, interaction, layout, typography, color, and animation — prioritized by impact. ## Critical Rules - **Color contrast**: minimum 4.5:1 for normal text, 3:1 for large text. - **Touch targets**: minimum 44x44px on mobile. - **No `h-screen`** — use `h-dvh` for correct mobile viewport. - **No animation unless requested** — respect `prefers-reduced-motion`. - **Empty states must have one clear next action** — never blank screens. - **All icon-only buttons must have `aria-label`**. ## Priority 1 — Accessibility (CRITICAL) - **Color is not enough**: never convey information by color alone — add icons or text. - **Alt text**: descriptive alt for all meaningful images. Use `alt=""` only for decorative images. - **Heading hierarchy**: sequential h1 → h2 → h3, one `<h1>` per page. - **Keyboard navigation**: tab order matches visual order, no keyboard traps. - **Focus states**: visible focus rings on all interactive elements — never `outline-none` without replacement. - **Form labels**: every input must have a visible `<label>` — placeholder alone is never enough. - **Error announcements**: use `aria-live="polite"` or `role="alert"` for dynamic errors. - **Skip links**: provide "Skip to main content" on navigation-heavy pages. - **Motion sensitivity**: always respect `prefers-reduced-motion` — disable parallax and scroll-jacking. ## Priority 2 — Touch & Interaction (CRITICAL) - **Touch spacing**: minimum 8px gap between adjacent touch targets. - **Hover vs tap**: never rely on hover for primary interactions — use click/tap. - **Cursor pointer**: add `cursor-pointer` to all clickable elements. - **Focus states**: `focus:ring-2 focus:ring-primary` on interactive elements. - **Hover states**: `hover:bg-accent cursor-pointer` for visual feedback. - **Active states**: `active:scale-95` for press feedback. - **Disabled states**: `opacity-50 cursor-not-allowed pointer-events-none`. - **Loading buttons**: disable button and show spinner during async actions — prevent double submission. - **Error feedback**: show clear error message near the problem — never silent failures. - **Success feedback**: always confirm completed actions with toast or visual change. - **Confirmation dialogs**: require confirmation before any destructive/irreversible action. ## Priority 3 — Layout & Responsive (HIGH) - **Mobile first**: base styles for mobile, `md:` and `lg:` for larger screens. - **Viewport**: always set `<meta name="viewport" content="width=device-width, initial-scale=1">`. - **No horizontal scroll**: ensure all content fits viewport — `max-w-full overflow-x-hidden`. - **Viewport units**: use `min-h-dvh` not `h-screen` — mobile browser chrome breaks `100vh`. - **Container width**: limit text to 65-75 characters per line — `max-w-prose`. - **Content jumping**: reserve space for async content — use `aspect-ratio` or fixed dimensions. - **Z-index scale**: use a fixed scale (10, 20, 30, 50) — never `z-[9999]`. - **Fixed elements**: account for safe areas, never stack multiple fixed elements carelessly. - **Breakpoint testing**: always test at 375px, 768px, 1024px, 1440px. - **Image scaling**: `max-w-full h-auto` on all images. - **Table handling**: wrap tables in `overflow-x-auto` for mobile. ## Priority 4 — Typography (MEDIUM) - **Body font size**: minimum 16px (`text-base`) on mobile — never `text-xs` for body. - **Line height**: 1.5–1.75 for body text — `leading-relaxed`. - **Line length**: 65-75 characters max — `max-w-prose` or `max-w-3xl`. - **Heading hierarchy**: clear size/weight difference from body text. - **Font loading**: use `font-display: swap` with similar fallback to prevent layout shift. - **Numeric data**: use `tabular-nums` for aligned numbers in tables and dashboards. - **Text wrapping**: use `text-balance` for headings, `text-pretty` for paragraphs. - **Truncation**: `truncate` or `line-clamp-2` with expand option for long content. ### Recommended Font Pairings | Style | Heading | Body | Best For | |-------|---------|------|----------| | Modern Professional | Poppins | Open Sans | SaaS, corporate, startups | | Tech Startup | Space Grotesk | DM Sans | Tech, developer tools, AI | | Minimal Swiss | Inter | Inter | Dashboards, admin panels, docs | | Friendly SaaS | Plus Jakarta Sans | Plus Jakarta Sans | Web apps, productivity tools | | Classic Elegant | Playfair Display | Inter | Luxury, fashion, editorial | | Bold Statement | Bebas Neue | Source Sans 3 | Marketing, portfolios, agencies | | Developer Mono | JetBrains Mono | IBM Plex Sans | Dev tools, documentation, CLI | | Playful Creative | Fredoka | Nunito | Children's apps, gaming, education | | Corporate Trust | Lexend | Source Sans 3 | Enterprise, government, healthcare | ## Priority 5 — Color Palettes by Product Type (MEDIUM) | Product | Primary | CTA | Background | Text | |---------|---------|-----|------------|------| | SaaS (General) | `#2563EB` blue | `#F97316` orange | `#F8FAFC` | `#1E293B` | | Micro SaaS | `#6366F1` indigo | `#10B981` emerald | `#F5F3FF` | `#1E1B4B` | | E-commerce | `#059669` green | `#F97316` orange | `#ECFDF5` | `#064E3B` | | E-commerce Luxury | `#1C1917` black | `#CA8A04` gold | `#FAFAF9` | `#0C0A09` | | Landing Page | `#0EA5E9` sky | `#F97316` orange | `#F0F9FF` | `#0C4A6E` | | Financial Dashboard | `#0F172A` navy | `#22C55E` green | `#020617` | `#F8FAFC` | | Healthcare | `#0891B2` cyan | `#059669` green | `#ECFEFF` | `#164E63` | | Education | `#4F46E5` indigo | `#F97316` orange | `#EEF2FF` | `#1E1B4B` | | Creative Agency | `#EC4899` pink | `#06B6D4` cyan | `#FDF2F8` | `#831843` | | Portfolio | `#18181B` zinc | `#2563EB` blue | `#FAFAFA` | `#09090B` | | AI / Chatbot | `#7C3AED` purple | `#06B6D4` cyan | `#FAF5FF` | `#1E1B4B` | | Productivity | `#0D9488` teal | `#F97316` orange | `#F0FDFA` | `#134E4A` | > Use these as starting points. Always map to your design system's semantic tokens (`bg-primary`, `text-foreground`, etc.) rather than hardcoding hex values. ## Priority 6 — Animation (MEDIUM) - **Only when needed**: never add animation unless explicitly requested. - **Timing**: 150-300ms for micro-interactions — never exceed 500ms for UI. - **Performance**: animate only `transform` and `opacity` — never `width`, `height`, `top`, `left`, `margin`, `padding`. - **Easing**: `ease-out` for entering, `ease-in` for exiting — never `linear` for UI. - **Continuous animation**: only for loading indicators — never for decorative elements. - **Reduced motion**: always check `prefers-reduced-motion` and disable non-essential animation. - **Maximum scope**: animate 1-2 key elements per view — never everything. - **No layout shift**: hover states must not cause layout shift — use `transform` not size changes. ## Priority 7 — Forms (MEDIUM) - **Labels**: always visible above or beside input — never placeholder-only. - **Error placement**: show error directly below the related input, not at form top. - **Inline validation**: validate on blur for most fields, not only on submit. - **Input types**: use `email`, `tel`, `number`, `url` — not `text` for everything. - **Autofill**: use `autocomplete` attribute properly — never `autocomplete="off"` everywhere. - **Required fields**: mark clearly with asterisk `*` or "(required)" text. - **Password visibility**: always provide a show/hide toggle. - **Mobile keyboards**: use `inputmode="numeric"` for number-only inputs. - **Submit feedback**: show loading state → success/error — never no feedback. ## Priority 8 — Feedback & Empty States (LOW-MEDIUM) - **Loading indicators**: show spinner/skeleton for operations > 300ms — never frozen UI. - **Empty states**: show helpful message + one clear action — never blank screen. - **Error recovery**: provide clear next steps — "Try again" button + help link. - **Progress indicators**: show "Step 2 of 4" for multi-step processes. - **Toast notifications**: auto-dismiss after 3-5 seconds — never persistent. - **Truncation**: handle long content gracefully with `line-clamp` + expand. - **No results**: show suggestions when search yields nothing — never just "0 results". ## Do - Meet WCAG 2.1 AA contrast ratios: 4.5:1 for normal text, 3:1 for large text. - Make all touch targets at least 44x44px with 8px minimum spacing between them. - Use `h-dvh` or `min-h-dvh` instead of `h-screen` for correct mobile viewport behavior. - Provide visible `<label>` for every form input — never rely on placeholder text alone. - Use `aria-label` on every icon-only button. - Show loading indicators (spinner or skeleton) for operations exceeding 300ms. - Include one clear call-to-action in every empty state. - Reserve `AlertDialog` for destructive or irreversible actions. - Use `tabular-nums` for numeric data in tables and dashboards. - Respect `prefers-reduced-motion` — disable parallax, auto-play, and scroll-jacking. ## Don't - Don't convey information by color alone — always add an icon or text label. - Don't use `outline-none` without providing an alternative visible focus indicator. - Don't rely on hover for primary interactions — mobile users cannot hover. - Don't add animation unless explicitly requested by the user or spec. - Don't use `linear` easing for UI transitions — use `ease-out` for enters, `ease-in` for exits. - Don't animate `width`, `height`, `margin`, or `padding` — use `transform` and `opacity`. - Don't use `z-[9999]` — follow a fixed z-index scale (10, 20, 30, 50). - Don't show validation errors only on submit — validate on blur for better UX. - Don't auto-dismiss toasts for error messages — only auto-dismiss success toasts. - Don't use `text-xs` for body text on mobile — minimum `text-base` (16px). ## Anti-Patterns | Anti-Pattern | Problem | Fix | |-------------|---------|-----| | **Color-only status indicators** | Inaccessible for colorblind users | Add icon or text label alongside color | | **`h-screen` for full-height layouts** | Broken on mobile (browser chrome overlaps content) | Use `min-h-dvh` or `h-dvh` | | **Placeholder as label** | Disappears on focus, fails accessibility audits | Use visible `<label>` above or beside input | | **Hover-dependent interactions** | Non-functional on touch devices | Make all interactions work via click/tap | | **Silent form failures** | User has no idea what went wrong | Show inline error near the problem field | | **Blank empty states** | User is confused, no path forward | Show message + one clear action button | | **Animating layout properties** | Jank and repaints, poor performance | Animate only `transform` and `opacity` | | **No loading feedback** | UI appears frozen during async operations | Show spinner/skeleton after 300ms threshold | | **`z-[9999]` stacking** | Z-index wars, unpredictable layering | Use a fixed scale: `z-10`, `z-20`, `z-30`, `z-50` | | **Missing `aria-label` on icon buttons** | Screen readers announce nothing useful | Add descriptive `aria-label` to every icon-only button | ## Pre-Delivery Checklist ### Visual Quality - [ ] No emoji icons — use Lucide, Heroicons, or SF Symbols (SVG) - [ ] Consistent icon set throughout the interface - [ ] Hover states without layout shift - [ ] Semantic color tokens used (not hardcoded hex) - [ ] No purple/multicolor gradients unless explicitly requested - [ ] No glow effects as primary affordances - [ ] Empty states have one clear next action ### Interaction - [ ] All clickable elements have `cursor-pointer` - [ ] Clear visual hover feedback on interactive elements - [ ] Smooth transitions (150-300ms) - [ ] Visible keyboard focus states - [ ] Destructive actions require `AlertDialog` confirmation - [ ] Loading buttons disabled during async actions ### Light/Dark Mode - [ ] Light text contrast: 4.5:1 minimum - [ ] Borders visible in both modes - [ ] Test both themes before delivery ### Layout - [ ] No content hidden behind fixed navbars - [ ] Responsive: 375px, 768px, 1024px, 1440px - [ ] No horizontal scroll on mobile - [ ] `min-h-dvh` used instead of `h-screen` - [ ] `safe-area-inset` respected for fixed elements ### Accessibility - [ ] All images have alt text - [ ] All form inputs have labels - [ ] Color is not the sole indicator of state - [ ] `prefers-reduced-motion` respected - [ ] Icon-only buttons have `aria-label` - [ ] Skip link present on nav-heavy pages ### Performance - [ ] Images optimized (WebP/AVIF, `srcset`, lazy loading) - [ ] No `will-change` outside active animations - [ ] No large `blur()` or `backdrop-filter` surfaces animated - [ ] No `useEffect` for what can be render logic
Files
No additional files