Some checks failed
CI / check (push) Has been cancelled
Capture uncommitted solver robustness work (regularization, domain errors, linear solver lifecycle, tube DP/MSH), web workbench updates, and synced BMAD skills across IDE agent folders before starting BPHX pressure-drop. Co-authored-by: Cursor <cursoragent@cursor.com>
9.4 KiB
9.4 KiB
Common Rules for Professional UI + Pre-Delivery Checklist
Load this file before final delivery of native/mobile app UI (iOS/Android/React Native/Flutter), or when the user reports the UI "doesn't look professional" and the cause isn't obvious from the priority table in SKILL.md.
Scope notice: everything below targets native/mobile app UI. For web/desktop interaction patterns, use references/quick-reference.md (stack-agnostic) instead — these tables assume touch targets, safe areas, and platform gesture conventions that don't apply 1:1 to desktop web.
These are frequently overlooked issues that make UI look unprofessional.
Icons & Visual Elements
| Rule | Standard | Avoid | Why It Matters |
|---|---|---|---|
| No Emoji as Structural Icons | Use vector-based icons (e.g., Lucide, react-native-vector-icons, @expo/vector-icons). | Using emojis (🎨 🚀 ⚙️) for navigation, settings, or system controls. | Emojis are font-dependent, inconsistent across platforms, and cannot be controlled via design tokens. |
| Vector-Only Assets | Use SVG or platform vector icons that scale cleanly and support theming. | Raster PNG icons that blur or pixelate. | Ensures scalability, crisp rendering, and dark/light mode adaptability. |
| Stable Interaction States | Use color, opacity, or elevation transitions for press states without changing layout bounds. | Layout-shifting transforms that move surrounding content or trigger visual jitter. | Prevents unstable interactions and preserves smooth motion/perceived quality on mobile. |
| Correct Brand Logos | Use official brand assets and follow their usage guidelines (spacing, color, clear space). | Guessing logo paths, recoloring unofficially, or modifying proportions. | Prevents brand misuse and ensures legal/platform compliance. |
| Consistent Icon Sizing | Define icon sizes as design tokens (e.g., icon-sm, icon-md = 24pt, icon-lg). | Mixing arbitrary values like 20pt / 24pt / 28pt randomly. | Maintains rhythm and visual hierarchy across the interface. |
| Stroke Consistency | Use a consistent stroke width within the same visual layer (e.g., 1.5px or 2px). | Mixing thick and thin stroke styles arbitrarily. | Inconsistent strokes reduce perceived polish and cohesion. |
| Filled vs Outline Discipline | Use one icon style per hierarchy level. | Mixing filled and outline icons at the same hierarchy level. | Maintains semantic clarity and stylistic coherence. |
| Touch Target Minimum | Minimum 44×44pt interactive area (use hitSlop if icon is smaller). | Small icons without expanded tap area. | Meets accessibility and platform usability standards. |
| Icon Alignment | Align icons to text baseline and maintain consistent padding. | Misaligned icons or inconsistent spacing around them. | Prevents subtle visual imbalance that reduces perceived quality. |
| Icon Contrast | Follow WCAG contrast standards: 4.5:1 for small elements, 3:1 minimum for larger UI glyphs. | Low-contrast icons that blend into the background. | Ensures accessibility in both light and dark modes. |
Interaction (App)
| Rule | Do | Don't |
|---|---|---|
| Tap feedback | Provide clear pressed feedback (ripple/opacity/elevation) within 80-150ms | No visual response on tap |
| Animation timing | Keep micro-interactions around 150-300ms with platform-native easing | Instant transitions or slow animations (>500ms) |
| Accessibility focus | Ensure screen reader focus order matches visual order and labels are descriptive | Unlabeled controls or confusing focus traversal |
| Disabled state clarity | Use disabled semantics (disabled/native disabled props), reduced emphasis, and no tap action |
Controls that look tappable but do nothing |
| Touch target minimum | Keep tap areas >=44x44pt (iOS) or >=48x48dp (Android), expand hit area when icon is smaller | Tiny tap targets or icon-only hit areas without padding |
| Gesture conflict prevention | Keep one primary gesture per region and avoid nested tap/drag conflicts | Overlapping gestures causing accidental actions |
| Semantic native controls | Prefer native interactive primitives (Button, Pressable, platform equivalents) with proper accessibility roles |
Generic containers used as primary controls without semantics |
Light/Dark Mode Contrast
| Rule | Do | Don't |
|---|---|---|
| Surface readability (light) | Keep cards/surfaces clearly separated from background with sufficient opacity/elevation | Overly transparent surfaces that blur hierarchy |
| Text contrast (light) | Maintain body text contrast >=4.5:1 against light surfaces | Low-contrast gray body text |
| Text contrast (dark) | Maintain primary text contrast >=4.5:1 and secondary text >=3:1 on dark surfaces | Dark mode text that blends into background |
| Border and divider visibility | Ensure separators are visible in both themes (not just light mode) | Theme-specific borders disappearing in one mode |
| State contrast parity | Keep pressed/focused/disabled states equally distinguishable in light and dark themes | Defining interaction states for one theme only |
| Token-driven theming | Use semantic color tokens mapped per theme across app surfaces/text/icons | Hardcoded per-screen hex values |
| Scrim and modal legibility | Use a modal scrim strong enough to isolate foreground content (typically 40-60% black) | Weak scrim that leaves background visually competing |
Layout & Spacing
| Rule | Do | Don't |
|---|---|---|
| Safe-area compliance | Respect top/bottom safe areas for all fixed headers, tab bars, and CTA bars | Placing fixed UI under notch, status bar, or gesture area |
| System bar clearance | Add spacing for status/navigation bars and gesture home indicator | Let tappable content collide with OS chrome |
| Consistent content width | Keep predictable content width per device class (phone/tablet) | Mixing arbitrary widths between screens |
| 8dp spacing rhythm | Use a consistent 4/8dp spacing system for padding/gaps/section spacing | Random spacing increments with no rhythm |
| Readable text measure | Keep long-form text readable on large devices (avoid edge-to-edge paragraphs on tablets) | Full-width long text that hurts readability |
| Section spacing hierarchy | Define clear vertical rhythm tiers (e.g., 16/24/32/48) by hierarchy | Similar UI levels with inconsistent spacing |
| Adaptive gutters by breakpoint | Increase horizontal insets on larger widths and in landscape | Same narrow gutter on all device sizes/orientations |
| Scroll and fixed element coexistence | Add bottom/top content insets so lists are not hidden behind fixed bars | Scroll content obscured by sticky headers/footers |
Pre-Delivery Checklist (canonical — the only one)
Before delivering app UI code, verify every item below. Start with the process steps, then the per-area checkboxes.
Process
- Ran
--domain ux "animation accessibility z-index loading"as a validation pass before implementation - Reviewed
quick-reference.md§1–§3 (CRITICAL + HIGH) as a final pass - Tested on 375px (small phone) and in landscape orientation
- Verified behavior with reduced-motion enabled and Dynamic Type/largest system text size
- Checked dark mode contrast independently (never assume light-mode values carry over)
- Confirmed all touch targets ≥44pt and no content hidden behind safe areas
Visual Quality
- No emojis used as icons (use SVG instead)
- All icons come from a consistent icon family and style
- Official brand assets are used with correct proportions and clear space
- Pressed-state visuals do not shift layout bounds or cause jitter
- Semantic theme tokens are used consistently (no ad-hoc per-screen hardcoded colors)
Interaction
- All tappable elements provide clear pressed feedback (ripple/opacity/elevation)
- Touch targets meet minimum size (>=44x44pt iOS, >=48x48dp Android)
- Micro-interaction timing stays in the 150-300ms range with native-feeling easing
- Disabled states are visually clear and non-interactive
- Screen reader focus order matches visual order, and interactive labels are descriptive
- Gesture regions avoid nested/conflicting interactions (tap/drag/back-swipe conflicts)
Light/Dark Mode
- Primary text contrast >=4.5:1 in both light and dark mode
- Secondary text contrast >=3:1 in both light and dark mode
- Dividers/borders and interaction states are distinguishable in both modes
- Modal/drawer scrim opacity is strong enough to preserve foreground legibility (typically 40-60% black)
- Both themes are tested before delivery (not inferred from a single theme)
Layout
- Safe areas are respected for headers, tab bars, and bottom CTA bars
- Scroll content is not hidden behind fixed/sticky bars
- Verified on small phone, large phone, and tablet (portrait + landscape)
- Horizontal insets/gutters adapt correctly by device size and orientation
- 4/8dp spacing rhythm is maintained across component, section, and page levels
- Long-form text measure remains readable on larger devices (no edge-to-edge paragraphs)
Accessibility
- All meaningful images/icons have accessibility labels
- Form fields have labels, hints, and clear error messages
- Color is not the only indicator
- Reduced motion and dynamic text size are supported without layout breakage