Purpose: Prevent future UI inconsistencies and maintain design system standards
Created: January 2025
Last Updated: January 2025
The Problem: During development, button height inconsistencies led to poor visual alignment and broken mobile layouts.
The Solution: All buttons MUST use this standardized pattern:
// ✅ CORRECT: Standardized Button Pattern
<button
className="px-3 py-1.5 bg-blue-600 text-white rounded text-sm hover:bg-blue-700 transition-colors min-h-[32px] flex items-center justify-center"
>
Button Text
</button>Required Classes for ALL Buttons:
py-1.5- Vertical padding for consistent heightmin-h-[32px]- Minimum height enforcementflex items-center justify-center- Perfect content centering
Mobile Responsive Buttons:
// ✅ CORRECT: Mobile-responsive with icons
<button
className="px-2 py-1.5 sm:px-3 bg-green-600 text-white rounded text-sm hover:bg-green-700 transition-colors min-h-[32px] flex items-center justify-center"
>
<span className="hidden sm:inline">Save</span>
<span className="sm:hidden">💾</span>
</button>Primary Action Button:
className="px-3 py-1.5 bg-green-600 text-white rounded-lg hover:bg-green-700 focus:outline-none focus:ring-2 focus:ring-green-500 transition-colors text-sm min-h-[32px] flex items-center justify-center"Secondary Button:
className="px-3 py-1.5 bg-gray-600 text-gray-200 rounded text-sm hover:bg-gray-500 transition-colors min-h-[32px] flex items-center justify-center"Danger/Delete Button:
className="px-3 py-1.5 bg-red-600 text-white rounded text-sm hover:bg-red-700 transition-colors min-h-[32px] flex items-center justify-center"Pattern: Use icons on mobile, text on desktop
// ✅ CORRECT
<button className="min-h-[32px] flex items-center justify-center">
<span className="hidden sm:inline">Create New Task</span>
<span className="sm:hidden">+</span>
</button>SVG Icons for Mobile:
// ✅ CORRECT: Proper SVG sizing
<svg className="w-4 h-4 sm:hidden" fill="none" stroke="currentColor" viewBox="0 0 24 24">
<path strokeLinecap="round" strokeLinejoin="round" strokeWidth={2} d="M6 18L18 6M6 6l12 12" />
</svg>// ✅ CORRECT: Responsive title shortening
<h1 className="text-lg md:text-2xl font-bold">
<span className="hidden sm:inline">Agentic Markdown Todos</span>
<span className="sm:hidden">AM Todos</span>
</h1>// ✅ CORRECT: Mobile-only settings button
<button
onClick={() => setShowSettings(true)}
className="sm:hidden px-2 py-1.5 bg-gray-600 text-gray-200 rounded-lg hover:bg-gray-500 min-h-[32px] flex items-center justify-center"
title="Settings"
>
⚙️
</button>Background Overlay:
className="fixed inset-0 bg-black/50 flex items-center justify-center z-50 p-4"Modal Container:
className="bg-gray-800 rounded-lg p-4 sm:p-6 max-w-md w-full"Text Input:
className="w-full p-3 bg-gray-700 border border-gray-600 rounded-md text-white focus:ring-blue-500 focus:border-blue-500"Textarea:
className="w-full h-96 bg-gray-900 text-white p-4 rounded border border-gray-600 focus:outline-none focus:ring-2 focus:ring-blue-500 font-mono text-sm resize-vertical"Desktop Sidebar:
className="w-full bg-gray-800 border-r border-gray-700 flex flex-col h-screen md:h-full md:shadow-none shadow-2xl"Mobile Sidebar:
className="fixed md:relative z-30 md:z-auto transition-all duration-300 ease-in-out w-80 md:w-80 flex-shrink-0 h-full"- P1 (Critical):
bg-red-600 - P2 (High):
bg-orange-600 - P3 (Medium):
bg-yellow-600 - P4 (Low):
bg-blue-600 - P5 (Very Low):
bg-gray-600
- Success:
bg-green-600 - Warning:
bg-yellow-600 - Error:
bg-red-600 - Info:
bg-blue-600 - Neutral:
bg-gray-600
- Primary Background:
bg-gray-900 - Secondary Background:
bg-gray-800 - Tertiary Background:
bg-gray-700 - Border:
border-gray-600orborder-gray-700
- Small:
p-2orm-2(8px) - Medium:
p-4orm-4(16px) - Large:
p-6orm-6(24px)
- Button Gaps:
space-x-2(8px between buttons) - Section Gaps:
space-y-4(16px between sections) - Content Padding:
p-4for mobile,p-6for desktop
- Button Height Check: All buttons must use
py-1.5 min-h-[32px] flex items-center justify-center - Mobile Testing: Test on mobile breakpoint (< 640px)
- Visual Alignment: Verify all interactive elements align properly
- Icon Consistency: SVG icons should be
w-4 h-4unless specifically larger
- All buttons use standardized height classes
- Mobile responsiveness includes proper icon/text switching
- No hardcoded heights that break consistency
- SVG icons have proper sizing classes
- Responsive breakpoints use
sm:,md:,lg:prefixes correctly
// ❌ WRONG: Inconsistent padding
className="px-3 py-2 bg-blue-600" // Different py value
// ❌ WRONG: Missing minimum height
className="px-3 py-1.5 bg-blue-600" // No min-h-[32px]
// ❌ WRONG: Missing flex centering
className="px-3 py-1.5 min-h-[32px] bg-blue-600" // No flex items-center justify-center// ❌ WRONG: Text overflow on mobile
<span>Create New Task with Very Long Name</span>
// ❌ WRONG: Icons without proper sizing
<svg className="w-6 h-6"> // Too large for buttons
// ❌ WRONG: Missing responsive classes
<span>Always Visible Text</span> // Should hide on mobile// ❌ WRONG: Hardcoded heights
style={{ height: '32px' }} // Use min-h-[32px] instead
// ❌ WRONG: Inconsistent spacing
className="p-3" // Should be p-2, p-4, or p-6Since January 2025, users provide their own API keys through the setup wizard:
Setup Form Pattern:
// ✅ CORRECT: Secure API key input
<input
type="password"
className="mt-1 block w-full p-2 bg-gray-700 border border-gray-600 rounded-md focus:ring-blue-500 focus:border-blue-500"
placeholder="AIzaSyxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"
required
/>Security Considerations:
- API keys stored in localStorage (client-side only)
- Server never stores or logs API keys
- Each request includes the key for that user only
- No shared server-side API key configuration
TailwindCSS v4 uses @tailwindcss/vite plugin in vite.config.mjs:
// ✅ CORRECT (vite.config.mjs)
import tailwindcss from '@tailwindcss/vite'
export default defineConfig({
plugins: [react(), tsconfigPaths(), tailwindcss()],
// ...
})CSS imports use new v4 syntax:
/* ✅ CORRECT (src/index.css) */
@import "tailwindcss";Required Breakpoints:
- Mobile: 320px - 639px
- Tablet: 640px - 1023px
- Desktop: 1024px+
Test Commands:
# Build and test
npm run build
npm start
# Check for any styling issues
npm run test:basic// ✅ CORRECT: Responsive edit mode buttons
<div className="flex items-center space-x-2 flex-shrink-0">
<button
onClick={handleCancel}
className="px-2 py-1.5 sm:px-3 bg-gray-600 text-gray-200 rounded text-sm hover:bg-gray-500 transition-colors min-h-[32px] flex items-center justify-center"
>
<span className="hidden sm:inline">Cancel</span>
<svg className="w-4 h-4 sm:hidden" fill="none" stroke="currentColor" viewBox="0 0 24 24">
<path strokeLinecap="round" strokeLinejoin="round" strokeWidth={2} d="M6 18L18 6M6 6l12 12" />
</svg>
</button>
<button
onClick={handleSave}
className="px-2 py-1.5 sm:px-3 rounded text-sm font-medium transition-colors min-h-[32px] flex items-center justify-center bg-green-600 text-white hover:bg-green-700"
>
<span className="hidden sm:inline">Save</span>
<span className="sm:hidden">💾</span>
</button>
</div>// ✅ CORRECT: Mobile project button
<button
onClick={() => setShowCreateModal(true)}
className="flex items-center space-x-1 bg-gray-700 hover:bg-gray-600 text-white px-2 py-1.5 rounded-md text-sm min-h-[32px]"
>
<div className="w-2 h-2 bg-blue-500 rounded-full"></div>
<span className="truncate max-w-20">{currentProject}</span>
<span>+</span>
</button>// ✅ CORRECT: Mobile-only settings access
<button
onClick={() => setShowSettings(true)}
className="sm:hidden px-2 py-1.5 bg-gray-600 text-gray-200 rounded-lg hover:bg-gray-500 focus:outline-none focus:ring-2 focus:ring-gray-400 transition-colors text-sm min-h-[32px] flex items-center justify-center"
title="Settings"
>
⚙️
</button>Implementation Notes:
- Uses
sm:hiddento show only on mobile (< 640px) - Maintains consistent button height with
min-h-[32px] - Positioned next to the + New Task button for easy access
- Complements the desktop settings button in the toolbar
If button heights become inconsistent again:
-
Find all button elements:
grep -r "className.*button\|<button" src/ -
Apply the standard pattern:
- Add
py-1.5 - Add
min-h-[32px] - Add
flex items-center justify-center
- Add
-
Test immediately:
npm start # Check all pages for visual alignment
When to Update This Guide:
- New component patterns are introduced
- TailwindCSS version changes
- Mobile breakpoints change
- New button variants are needed
Quick Reference:
- Standard Button:
py-1.5 min-h-[32px] flex items-center justify-center - Mobile Icon Size:
w-4 h-4 - Responsive Text:
hidden sm:inline/sm:hidden
Style guide maintained for consistency and developer efficiency
Prevents the "button mess" and ensures professional UI standards ✅