UI Standards Guide for do.dev Application

This document defines the UI/UX standards and patterns to be used consistently across the do.dev application.

Design Principles

  1. Clarity over Cleverness - Interfaces should be immediately understandable
  2. Consistency is Key - Same patterns should work the same way everywhere
  3. Subtle Feedback - Visual feedback should be clear but not distracting
  4. Performance First - Animations and transitions should be fast and smooth
  5. Accessibility Always - All interactions must be keyboard and screen-reader friendly

🚨 CRITICAL: Cursor Pointer Rule

ALL clickable elements MUST have cursor-pointer class. NO EXCEPTIONS.

This includes but is not limited to:

  • Buttons (all variants)
  • Links
  • Clickable cards
  • Dropdown triggers
  • Menu items
  • Interactive list items
  • Tab buttons
  • Modal close buttons
  • Any element with an onClick handler
  • Any element that performs an action when clicked

Example:

// ✅ CORRECT - Always include cursor-pointer
<button onClick={handleClick} className="cursor-pointer">Click me</button>
<Link href="/page" className="cursor-pointer">Navigate</Link>
<div onClick={selectItem} className="cursor-pointer">Select this</div>

// ❌ WRONG - Missing cursor-pointer
<button onClick={handleClick}>Click me</button>
<Link href="/page">Navigate</Link>
<div onClick={selectItem}>Select this</div>

Color Palette

Primary Colors

  • Blue: Primary actions and selections
    • blue-500 - Primary blue (#3B82F6)
    • blue-600 - Hover state (#2563EB)
    • blue-50 - Light background tint

Neutral Colors

  • Gray: Text and borders
    • gray-900 - Primary text
    • gray-700 - Secondary text
    • gray-500 - Tertiary text / placeholders
    • gray-300 - Borders (list items, form inputs)
    • gray-100 - Dividers
    • gray-50 - Background tints (list items, subtle backgrounds)

Semantic Colors

  • Green: Success states

    • green-600 - Success text/icons
    • green-100 - Success backgrounds
    • green-800 - Success text on light backgrounds
  • Red: Error/Danger states

    • red-600 - Error text/delete actions
    • red-100 - Error backgrounds

Typography

Font Sizes

  • text-3xl - Page titles (30px)
  • text-xl - Section headers (20px)
  • text-lg - Subsection headers (18px)
  • text-base - Body text (16px)
  • text-sm - Secondary text (14px)
  • text-xs - Labels and metadata (12px)

Font Weights

  • font-semibold - Headers and emphasis
  • font-medium - Subheaders and important text
  • font-normal - Body text

Font Families

  • font-mono - Code, technical values (domains, IPs, ports)
  • Default sans-serif for all other text

Component Patterns

Cards

Selectable Cards

Used for items that can be selected (DNS zones, projects, locations):

Selected State:

className="shadow-lg border-2 border-blue-500 bg-gradient-to-br from-white to-gray-50"

Default State:

className="hover:shadow-md hover:border-gray-300 bg-white border"

Complete Example:

<Card
  className={`p-5 cursor-pointer transition-all ${
    isSelected
      ? "shadow-lg border-2 border-blue-500 bg-gradient-to-br from-white to-gray-50"
      : "hover:shadow-md hover:border-gray-300 bg-white border"
  }`}
  onClick={() => handleSelect(item.id)}
>
  {/* Card content */}
</Card>

Static Cards

For non-interactive content display:

<Card className="p-6 bg-white">
  {/* Content */}
</Card>

Buttons

Important: All buttons and clickable elements MUST include the cursor-pointer class to ensure proper user feedback.

Primary Button

For main actions:

<Button size="sm" className="cursor-pointer">
  <Plus className="w-4 h-4 mr-2" />
  Add Item
</Button>

Secondary Button

For secondary actions:

<Button variant="outline" size="sm" className="cursor-pointer">
  <Settings className="w-4 h-4 mr-2" />
  Settings
</Button>

Danger Button

For destructive actions:

<Button
  variant="ghost"
  size="sm"
  className="text-red-600 hover:text-red-700 cursor-pointer"
>
  <Trash2 className="w-4 h-4" />
</Button>

All clickable elements (links, buttons, interactive cards, etc.) must include cursor-pointer:

<Link href="/path" className="cursor-pointer">
  Click me
</Link>

<div onClick={handleClick} className="cursor-pointer">
  Interactive element
</div>

List Items

List Item Containers

For lists of items (routes, upstreams, configurations):

Standard List Item:

<div className="p-4 bg-gray-50 border border-gray-300 rounded-lg">
  {/* Item content */}
</div>

Grid Layout Lists: For displaying multiple items per row:

<div className="grid grid-cols-1 md:grid-cols-2 lg:grid-cols-3 gap-3">
  {items.map(item => (
    <div className="p-4 bg-gray-50 border border-gray-300 rounded-lg">
      {/* Item content */}
    </div>
  ))}
</div>

Key specifications:

  • Background: bg-gray-50 - Light gray background for subtle contrast
  • Border: border border-gray-300 - Darker gray border for clear definition
  • Padding: p-4 - Consistent internal spacing
  • Border radius: rounded-lg - Rounded corners for modern look
  • Grid layout: Responsive columns (1 on mobile, 2 on medium, 3 on large screens)
  • Gap: gap-3 - Consistent spacing between grid items

Forms

Input Fields

All inputs should have white backgrounds in light mode:

<Input
  type="text"
  placeholder="Search..."
  className="bg-white"
/>

Select Dropdowns

<Select>
  <SelectTrigger className="w-[200px] bg-white">
    <SelectValue placeholder="Select option" />
  </SelectTrigger>
  <SelectContent>
    <SelectItem value="option1">Option 1</SelectItem>
  </SelectContent>
</Select>

Tables

Header Style

<thead>
  <tr className="border-b border-gray-200 bg-gray-50">
    <th className="text-left text-xs font-medium text-gray-600 uppercase tracking-wider py-3 px-6">
      Column Name
    </th>
  </tr>
</thead>

Row Style

<tr className="hover:bg-gray-50 transition-colors cursor-pointer">
  <td className="py-3 px-6">
    <span className="font-mono text-sm text-gray-900">{value}</span>
  </td>
</tr>

Status Indicators

Status Pills

// Active/Success
<span className="inline-flex items-center px-2 py-0.5 rounded-full text-xs font-medium bg-green-100 text-green-800">
  Active
</span>

// Inactive/Neutral
<span className="inline-flex items-center px-2 py-0.5 rounded-full text-xs font-medium bg-gray-100 text-gray-800">
  Inactive
</span>

// Error/Warning
<span className="inline-flex items-center px-2 py-0.5 rounded-full text-xs font-medium bg-red-100 text-red-800">
  Error
</span>

Type Badges

For categorization (e.g., DNS record types):

<span className="inline-flex items-center px-2 py-0.5 rounded text-xs font-medium bg-blue-100 text-blue-800">
  A
</span>

Icons

Icon Sizing

  • w-3 h-3 - Inline with small text
  • w-4 h-4 - Standard button/inline icons
  • w-5 h-5 - Card headers and emphasis
  • w-6 h-6 - Feature icons
  • w-12 h-12 - Empty state icons

Icon Colors

  • text-gray-400 - Default/inactive
  • text-gray-600 - Secondary
  • text-blue-600 - Primary/active
  • text-green-600 - Success
  • text-red-600 - Danger/delete

Loading States

Full Page Loader

<div className="flex items-center justify-center min-h-[400px]">
  <Loader2 className="w-8 h-8 animate-spin text-gray-400" />
</div>

Inline Loader

<Loader2 className="w-4 h-4 animate-spin" />

Empty States

<div className="text-center py-12">
  <Database className="w-12 h-12 text-gray-300 mx-auto mb-4" />
  <h3 className="text-lg font-medium text-gray-900 mb-2">No items found</h3>
  <p className="text-gray-500 mb-4">Create your first item to get started</p>
  <Button>
    <Plus className="w-4 h-4 mr-2" />
    Create Item
  </Button>
</div>

Layout Patterns

Page Headers

<div className="border-b border-gray-200 pb-5">
  <div className="flex items-center justify-between">
    <div>
      <h1 className="text-3xl font-semibold text-gray-900">Page Title</h1>
      <p className="text-sm text-gray-500 mt-1">Page description goes here</p>
    </div>
    <div className="flex items-center gap-3">
      {/* Actions */}
    </div>
  </div>
</div>

Section Headers

<div className="flex items-center justify-between mb-4">
  <h2 className="text-xl font-semibold text-gray-900">Section Title</h2>
  <Button size="sm">Action</Button>
</div>

Spacing Guidelines

Padding

  • p-3 - Compact padding
  • p-4 - Small padding
  • p-5 - Medium padding (cards)
  • p-6 - Large padding (sections)
  • p-8 - Extra large (empty states)

Margins

  • gap-1 - Tight grouping (icon buttons)
  • gap-2 - Close related items
  • gap-3 - Standard spacing
  • gap-4 - Section spacing
  • gap-6 - Major sections

Common Patterns

  • space-y-4 - Vertical form fields
  • space-y-6 - Page sections
  • mb-4 - After headers
  • mt-1 - Descriptions after titles

Animation & Transitions

Standard Transitions

Always include smooth transitions for interactive elements:

className="transition-all"        // For multiple properties
className="transition-colors"     // For color changes only
className="transition-shadow"     // For shadow changes only

Hover States

  • Scale: Avoid scaling unless for specific emphasis
  • Colors: Subtle color shifts (e.g., gray-600 to gray-700)
  • Shadows: Add depth on hover with hover:shadow-md

Accessibility Standards

  1. Keyboard Navigation

    • All interactive elements must be keyboard accessible
    • Include visible focus states
    • Logical tab order
  2. ARIA Labels

    • Use semantic HTML where possible
    • Add aria-labels for icon-only buttons
    • Include screen reader only text when needed
  3. Color Contrast

    • Ensure WCAG AA compliance minimum
    • Don't rely solely on color for information
  4. Click Targets

    • Minimum 44x44px click areas
    • Adequate spacing between interactive elements

Code Patterns

Conditional Classes

Use template literals for complex conditionals:

className={`
  base-classes
  ${condition ? "true-classes" : "false-classes"}
  ${anotherCondition && "additional-classes"}
`}

Icon + Text Patterns

Always include margin between icon and text:

<Button>
  <IconName className="w-4 h-4 mr-2" />
  Button Text
</Button>

Responsive Design

Mobile-first approach with Tailwind breakpoints:

  • Default: Mobile styles
  • sm: - 640px and up
  • md: - 768px and up
  • lg: - 1024px and up
  • xl: - 1280px and up

Do's and Don'ts

Do's ✅

  • Use consistent spacing throughout
  • Provide clear visual feedback for all interactions
  • Keep animations subtle and fast
  • Use semantic color choices
  • Test with keyboard navigation
  • Consider loading and error states

Don'ts ❌

  • Don't use more than 2-3 font sizes per page
  • Don't mix button styles in the same context
  • Don't use pure black (#000) for text
  • Don't rely only on hover states for important information
  • Don't create custom colors outside the palette
  • Don't use inline styles

Implementation Notes

  1. All components should use the shared UI package from @workspace/ui
  2. Custom components should follow these patterns
  3. When in doubt, check existing implementations
  4. Document any deviations from these standards

This is a living document. Update it when new patterns emerge or existing ones need refinement.

On this page