# Story 9.4: Component Styling - Buttons ## Epic Reference **Epic 9:** Design & Branding Implementation ## Dependencies - **Story 9.1: Color System Implementation** - Must be complete (this story uses the color variables defined there) ## User Story As a **user**, I want **consistent, professional button styling**, So that **interactive elements are clear and visually appealing**. ## Context This story implements the button styling system that will be used throughout the application. Buttons appear in: - Forms (submit, cancel actions) - Modals (confirm, dismiss) - Navigation (CTAs) - Admin dashboards (CRUD operations) - Client booking flow The implementation extends Flux UI's button component with brand colors rather than replacing it, ensuring we maintain Flux's built-in accessibility and functionality. ## Acceptance Criteria ### Primary Button - [ ] Background: Gold (`bg-gold` / #D4AF37) - [ ] Text: Dark Navy Blue (`text-navy`) - [ ] Hover: Light Gold (`hover:bg-gold-light` / #F4E4B8) - [ ] Border-radius: 6px (`rounded-md`) - [ ] Padding: 12px 24px (`px-6 py-3`) ### Secondary Button - [ ] Background: Transparent - [ ] Border: 2px solid Gold (`border-2 border-gold`) - [ ] Text: Gold (`text-gold`) - [ ] Hover: Gold background, Navy text (`hover:bg-gold hover:text-navy`) ### Disabled State - [ ] Background: #CCCCCC - [ ] Text: #666666 - [ ] No hover effect - [ ] Cursor: not-allowed ### Danger Button - [ ] Background: #E74C3C (`bg-danger`) - [ ] Text: White - [ ] Hover: Slightly darker (`hover:bg-danger/90`) ### Button Sizes - [ ] Small: `px-4 py-2 text-sm` (for compact UI areas) - [ ] Default: `px-6 py-3 text-base` (standard usage) - [ ] Large: `px-8 py-4 text-lg` (hero CTAs) ### Features - [ ] Loading states with Flux spinner component - [ ] Focus states: Gold outline ring for accessibility (`focus:ring-2 focus:ring-gold focus:ring-offset-2`) - [ ] Icon support: Buttons with leading/trailing icons - [ ] Full-width variant for mobile forms - [ ] Button groups with proper border-radius handling ## Files to Create/Modify | File | Action | Purpose | |------|--------|---------| | `resources/css/app.css` | Modify | Add button variant styles in @theme or as Tailwind components | ## Technical Notes ### Flux UI Integration Approach Flux UI buttons accept a `variant` prop. We extend Flux by: 1. Using Flux's `` component as-is for structure 2. Applying brand colors via the `variant` prop or custom CSS classes 3. NOT creating wrapper components unless absolutely necessary Reference: Use `search-docs` tool with query "button" and package "livewire/flux" for current Flux button API. ### CSS Implementation ```css /* resources/css/app.css - Add after @import "tailwindcss" and @theme block */ /* Primary button - Gold background */ .btn-primary { @apply bg-gold text-navy hover:bg-gold-light rounded-md px-6 py-3 font-semibold transition-colors; @apply focus:outline-none focus:ring-2 focus:ring-gold focus:ring-offset-2; } /* Secondary button - Outlined */ .btn-secondary { @apply bg-transparent border-2 border-gold text-gold rounded-md px-6 py-3 font-semibold transition-colors; @apply hover:bg-gold hover:text-navy; @apply focus:outline-none focus:ring-2 focus:ring-gold focus:ring-offset-2; } /* Danger button */ .btn-danger { @apply bg-danger text-white hover:bg-danger/90 rounded-md px-6 py-3 font-semibold transition-colors; @apply focus:outline-none focus:ring-2 focus:ring-danger focus:ring-offset-2; } /* Disabled state - applies to all variants */ .btn-disabled, button:disabled, [disabled] { @apply bg-gray-300 text-gray-500 cursor-not-allowed; @apply hover:bg-gray-300; /* Override hover */ } /* Size variants */ .btn-sm { @apply px-4 py-2 text-sm; } .btn-lg { @apply px-8 py-4 text-lg; } /* Full width for mobile */ .btn-full { @apply w-full; } /* Loading state */ .btn-loading { @apply relative pointer-events-none opacity-75; } /* Icon spacing within buttons */ .btn-icon-left { @apply flex items-center gap-2; } .btn-icon-right { @apply flex items-center gap-2 flex-row-reverse; } ``` ### Usage Examples ```blade {{-- Primary button with Flux --}} {{ __('Submit') }} {{-- Secondary button --}} {{ __('Cancel') }} {{-- Danger button --}} {{ __('Delete') }} {{-- Button with icon --}} {{ __('Add New') }} {{-- Loading state --}} {{ __('Save') }} {{ __('Saving...') }} {{-- Full width on mobile --}} {{ __('Book Consultation') }} ``` ### Edge Cases to Handle - **Icon-only buttons**: Ensure adequate touch target (44px minimum) - **Long button text**: Text should not overflow; consider truncation or wrapping - **RTL layout**: Icons should flip position appropriately (use logical `start`/`end` if needed) - **Button groups**: First/last buttons need adjusted border-radius ## Testing Requirements ### Test Approach - **Visual testing**: Verify all button states render correctly - **Accessibility testing**: Validate focus states and contrast ratios - **RTL testing**: Confirm buttons display correctly in Arabic mode ### Test Scenarios ```php // tests/Feature/Components/ButtonStylingTest.php test('primary button has correct styling classes', function () { $this->get('/') ->assertSee('btn-primary'); }); test('disabled button prevents interaction', function () { // Verify disabled state renders with correct cursor and no hover }); test('buttons are keyboard accessible', function () { // Verify focus states are visible }); test('buttons render correctly in RTL mode', function () { // Set locale to Arabic and verify button layout }); ``` ### Accessibility Checklist - [ ] Focus indicator visible (gold ring) - [ ] Color contrast meets WCAG AA (4.5:1 for text) - [ ] Touch targets minimum 44x44px on mobile - [ ] Disabled state communicated to screen readers ## Definition of Done - [ ] Primary button styled per acceptance criteria - [ ] Secondary button styled per acceptance criteria - [ ] Danger button styled per acceptance criteria - [ ] Disabled states work correctly - [ ] Loading states work with Flux spinner - [ ] Focus states visible and accessible - [ ] Size variants (sm, default, lg) implemented - [ ] Icon buttons work correctly - [ ] Full-width variant works on mobile - [ ] RTL layout tested - [ ] Tests pass - [ ] Code formatted with Pint ## Estimation **Complexity:** Medium | **Effort:** 3 hours