shredbx logo
shredbx shredbx shredbx shredbx Personal
  • Home
  • Lab
  • Portfolio
  • Experience
  • Services
  • Profile
  • Contact
AClaude
  • Home
  • Lab
  • Portfolio
  • Experience
  • Services
  • Profile
  • Contact
Andrei Solovev
Knowledge
Search knowledge... ⌘K
Knowledge · Rules · Development

Ui Design Standard

UI/UX design rules for spacing, typography, color, animation, responsive, accessibility, and grid

Andrei Solovev

Tags

rule

Overview

Purpose

UI/UX design rules for spacing, typography, color, animation, responsive, accessibility, and grid

Rules

SPC-001: All spacing values MUST be multiples of 4px (the base unit from brand.yml)

Verification: Check CSS for hardcoded spacing values not in the 4px scale

SPC-002: Use named spacing tokens, not raw pixel values

Verification: Grep for hardcoded px values in component CSS

SPC-003: Apply spacing by context

Verification: Review component padding against context classification

SPC-004: Elements with no visual boundary (borders, background) MAY use 0 spacing on one axis to visually merge with adjacent elements

Verification: Check that zero-spacing is intentional, not missing

TYP-001: All font sizes MUST use typography tokens from brand.yml (--type-{category}-{size}-size)

Verification: Check CSS for hardcoded font-size values

TYP-002: Line height follows the token scale. Dense UIs use tighter line-height.

Verification: Check line-height values against token scale

TYP-003: Use consistent font weights to establish visual hierarchy

Verification: Check that heavier weights correspond to higher hierarchy levels

TYP-004: Body text MUST be >= 16px (brand.yml base_size). Label text MUST be >= 11px.

Verification: Check CSS for font sizes below minimums

TYP-005: Every font-family declaration MUST include system fallback stack

Verification: Check font-family declarations for fallback stacks

CLR-001: Components MUST use semantic color tokens (--color-primary, --color-surface). NEVER use primitive color names (--blue-500,

Verification: Grep for hex values, rgb(), hsl() in component CSS (brand-bridge.css is exempt)

CLR-002: Text on background MUST meet WCAG 2.1 AA contrast ratios: - Normal text (< 18px or < 14px bold): 4.5:1 minimum - Large text (>= 18px or >= 14px bold): 3:1 minimum - UI components and graphical objects: 3:1 minimum

Verification: Use contrast checker tool on all text/background combinations

CLR-003: When defining NEW color tokens, prefer OKLCH color model for perceptual uniformity. Existing hex values remain for backward compatibility.

OKLCH provides uniform perceptual lightness across hues (Radix Colors approach)

Verification: New color definitions should use oklch() or reference an OKLCH-derived value

CLR-004: Status colors (success, warning, error, info) MUST be distinct in hue, not just lightness. Each status color MUST pass contrast on both light and dark backgrounds.

Verification: Check status colors are distinct in hue and pass contrast

CLR-005: Dark mode is NOT just inverted colors. Follow Linear/Vercel aesthetic: - Background: near-black (#0F0F10 range), not pure black (#000000) - Text: off-white (#EEEFF1), not pure white (#FFFFFF) - Reduced saturation on accent colors - Elevated surfaces use slightly lighter backgrounds (not shadows)

Verification: Compare dark mode palette against these rules

CLR-006: Focus ring color (--color-border-focus) MUST be visible against ALL backgrounds in the current theme. Use a contrasting outline with offset.

Verification: Tab through all interactive elements and verify focus visibility

ANI-001: Prefer CSS native animation mechanisms before JavaScript libraries: 1. CSS transitions (simple state changes) 2. CSS @keyframes (looping, complex sequences) 3. View Transitions API (page/component transitions) 4. Scroll-driven animations (scroll-linked effects) 5. Motion.dev / GSAP (physics, complex orchestration) — last resort

Verification: Check if CSS native could replace JS animation library usage

ANI-002: All animation durations MUST use brand.yml motion tokens

Verification: Grep for hardcoded ms/s values in transitions/animations

ANI-003: Use brand.yml easing tokens for consistent motion character

Verification: Check that easing functions use tokens, not hardcoded cubic-bezier

ANI-004: ALL animations MUST respect prefers-reduced-motion. Use var(--duration-reduced) which resolves to 0ms when reduced-motion is active. This is NOT optional — brand.yml requires reduced_motion_duration.

Verification: Toggle prefers-reduced-motion in browser and verify all animations stop

ANI-005: Page load MUST NOT trigger entrance animations. Content should appear immediately. Animations activate only on user interaction or scroll.

First Contentful Paint should not be delayed by decorative animation

Verification: Load page with animations disabled and compare FCP times

RSP-001: CSS MUST be authored mobile-first. Use min-width media queries to add complexity.

Verification: Check media queries use min-width, not max-width

RSP-002: Use these breakpoints consistently across all components

Verification: Grep for non-standard breakpoint values

RSP-003: For component-level responsiveness, prefer CSS container queries over viewport media queries. Components should adapt to their container, not the viewport.

Verification: Check if viewport query could be replaced with container query

RSP-004: Page-level margins and large gaps SHOULD use clamp() for fluid scaling between breakpoints

Verification: Check page margins and section gaps for clamp() usage

RSP-005: Interactive elements MUST have minimum 44x44px touch target on mobile (WCAG 2.5.8). Use padding or min-width/min-height.

Verification: Check interactive element dimensions on mobile breakpoint

A11Y-001: ALL interactive elements MUST be keyboard accessible: - Tab: move between focusable elements - Enter/Space: activate buttons and links - Arrow keys: navigate within composite widgets (tabs, menus, trees) - Escape: close overlays, cancel actions

Verification: Tab through all interactive elements without using mouse

A11Y-002: Focus MUST be visible and logical: - Focus ring visible on ALL interactive elements (CLR-006) - Focus order follows visual order (no tabindex > 0) - Focus trapped in modals/dialogs - Focus restored to trigger element when overlay closes

Verification: Tab through page and verify focus ring and order

A11Y-003: Pages MUST use semantic HTML and ARIA landmarks: - <nav> or role="navigation" — primary navigation - <main> — primary content area - <aside> or role="complementary" — sidebars, panels - <header> / <footer> — page header/footer - role="tablist" / role="tab" — tab interfaces

Verification: Check page structure for landmark roles

A11Y-004: Dynamic UI MUST announce changes: - aria-live="polite" for non-urgent updates (loading states, status messages) - aria-live="assertive" for urgent updates (errors, critical alerts) - aria-expanded for collapsible sections - aria-selected for selectable items (tabs, list items) - aria-disabled for disabled elements (prefer disabled attribute when available)

Verification: Check dynamic content changes with screen reader

A11Y-005: - Meaningful images: alt text describing content - Decorative images: alt="" (empty alt) - Icon-only buttons: aria-label describing the action - SVG icons: role="img" + aria-label, or aria-hidden="true" if decorative - Alt MUST NOT duplicate adjacent visible text: when an image sits inside a link/card whose caption already names it, an identical alt makes a screen reader read the name twice. Use alt="" (decorative — the caption carries it) or a DISTINCT descriptive alt (e.g. "Bestie Real Estate — property listing UI" next to the "Bestie Real Estate" label), never a verbatim repeat of the label.

Verification: Check all images and icons for appropriate alternative text; flag any alt string that exactly equals adjacent link/caption text

A11Y-006: Forms MUST have: - Visible <label> associated via htmlFor/for - Error messages linked via aria-describedby - Required fields marked with aria-required="true" - Form validation errors announced with aria-live

Verification: Submit forms with errors and verify screen reader announces them

A11Y-007: Information MUST NOT be conveyed by color alone. Use text labels, icons, or patterns in addition to color.

Verification: View page in grayscale and verify all information is still conveyed

GRD-001: Page-level layout MUST use CSS Grid with named areas. Flexbox for component-level layout.

Verification: Check page layout uses CSS Grid, not float or absolute positioning

GRD-002: Text and content MUST align to a consistent vertical rhythm within sections. Use the 4px grid (SPC-001) for vertical alignment.

Verification: Enable grid overlay in browser DevTools and check alignment

GRD-003: Body text content SHOULD have max-width of 65-75ch for readability. Full-width layouts use the grid to constrain content columns.

Verification: Check content width on large screens

GRD-004: Standard sidebar widths for IDE-style layouts: - Collapsed: 48px (icon only) - Default: 240-280px - Wide: 320-360px - Max: 50% of viewport

Verification: Check sidebar widths against conventions

GRD-005: Prefer CSS gap property over individual margins for spacing between siblings. gap works with both Grid and Flexbox and produces more predictable spacing.

Verification: Check for margin-based sibling spacing that could use gap

LYT-001: Every page descriptor with UI components SHOULD have a layout_requirements section. Pages without layout_requirements skip FDD4.UI.VERIFY with a warning — spatial bugs go undetected.

Verification: Check page descriptor for layout_requirements section during FDD2.PAGE

LYT-002: Layout requirements MUST use content-based selectors (text content, alt attributes, tag hierarchy) as primary strategy. Svelte scopes CSS classes with hash suffixes, making exact class selectors unreliable. Use [class*="partial"] only as fallback.

Verification: Check selectors in layout_requirements for exact class matches

LYT-003: Alignment constraints (eq) use 2px tolerance by default. Spacing constraints (gap) use 4px tolerance. Explicit tolerance overrides defaults. Tolerance of 0px is valid for pixel-perfect requirements.

Verification: Check tolerance values are reasonable — sub-pixel (< 1px) is too tight, > 8px is too loose

LYT-004: FDD4.UI.VERIFY MUST use evaluate_script with getBoundingClientRect() for spatial assertions. Screenshots are evidence for human review, not measurement tools. JSON coordinates are the source of truth.

Verification: VERIFY step output must contain JSON measurements, not screenshot-only evidence

LYT-005: If layout requirements fail after 3 fix iterations, escalate to user with measurement evidence. Infinite fix loops waste context. The JSON diff between expected and actual is the escalation artifact.

Verification: Count fix iterations in VERIFY step — escalate at 3

LYT-006: When layout_requirements include a breakpoint field, VERIFY must resize the viewport (resize_page) and re-measure at that width. Common breakpoints — mobile (375px), tablet (768px), desktop (1024px).

Verification: Check for breakpoint fields in layout_requirements and verify measurements at each

LYT-007: Every page SHOULD have at least one contain constraint checking that content does not overflow its container (scrollWidth <= clientWidth). Horizontal overflow is the most common undetected layout bug.

Verification: Check for at least one contain constraint in layout_requirements

LYT-008: Layout requirement IDs (LR-NNN) must be unique within a page descriptor. IDs are referenced in verification reports for traceability.

Verification: Check for duplicate LR-NNN IDs in layout_requirements

shredbx logo shredbx shredbx shredbx shredbx Andrei Solovev

Solution Architect & Lead Software Engineer

ExperiencePortfolioResearch & ExperimentsEducationCertificationSkills
GitHub ↗LinkedIn ↗Email ↗
AVAILABLE FOR NEW PROJECTS
// MY LATEST BEATS
Hobby & Interests

Lab

  • The Lab
  • Framework
  • Components
  • Packages
  • Games
  • Process (SDLC)
  • Knowledge
  • Blog

Andrei

  • Portfolio
  • Experience
  • Services
  • Profile
  • Contact
  • Lifestyle

Team

  • Team
  • Andrei
  • Claude

Legal

  • Privacy
  • Terms
  • Cookies
© 2026 shredbx.com. All rights reserved. — Andrei Solovev |