From 8431194c9a90b0592abfee17d0c89e03138f2070 Mon Sep 17 00:00:00 2001 From: Naser Mansour Date: Sun, 21 Dec 2025 13:26:15 +0200 Subject: [PATCH] reviewed epic 9 stories --- .../story-9.1-color-system-implementation.md | 74 +++- .../story-9.10-accessibility-compliance.md | 91 +++- ...tory-9.11-animations-micro-interactions.md | 89 +++- docs/stories/story-9.2-typography-system.md | 59 ++- docs/stories/story-9.3-logo-integration.md | 175 ++++++-- .../story-9.4-component-styling-buttons.md | 193 +++++++-- .../story-9.5-component-styling-forms.md | 220 +++++++++- ...-9.6-component-styling-cards-containers.md | 45 ++ .../story-9.7-navigation-footer-styling.md | 392 +++++++++++++++--- .../story-9.8-rtl-ltr-layout-perfection.md | 296 ++++++++++--- ...ry-9.9-responsive-design-implementation.md | 268 ++++++++++-- 11 files changed, 1651 insertions(+), 251 deletions(-) diff --git a/docs/stories/story-9.1-color-system-implementation.md b/docs/stories/story-9.1-color-system-implementation.md index da22b65..573b402 100644 --- a/docs/stories/story-9.1-color-system-implementation.md +++ b/docs/stories/story-9.1-color-system-implementation.md @@ -2,6 +2,10 @@ ## Epic Reference **Epic 9:** Design & Branding Implementation +**Epic File:** `docs/epics/epic-9-design-branding.md` + +## Dependencies +- **Epic 1:** Base Tailwind/Flux setup must be complete (Tailwind CSS 4, Flux UI installed) ## User Story As a **developer**, @@ -27,40 +31,88 @@ So that **brand colors are consistently applied throughout the application**. - [ ] Color variables for easy maintenance - [ ] Semantic color aliases (primary, accent, etc.) +### Dark Mode +- [ ] Dark mode is **deferred** to a future story +- [ ] Document that dark mode will require additional color mappings later + ## Technical Notes -```css -/* resources/css/app.css */ -@import "tailwindcss"; +### Existing Code Context +The file `resources/css/app.css` already exists with: +- Tailwind and Flux CSS imports (PRESERVE these) +- Zinc color palette (can be REMOVED - not used in brand) +- Accent color variables using neutral-800 (REPLACE with brand colors) +- Flux field/label/control selectors (PRESERVE these) +### Merge Strategy +- Keep all `@import` statements at the top +- Keep `@source` directives +- Keep `@custom-variant dark` definition +- Replace the `@theme` block content with brand colors below +- Keep `@layer theme`, `@layer base`, and Flux selectors intact + +### Color Implementation +```css +/* resources/css/app.css - REPLACE the @theme block with this content */ @theme { - /* Primary */ + /* Keep existing font if needed, or update in typography story */ + --font-sans: 'Instrument Sans', ui-sans-serif, system-ui, sans-serif; + + /* Primary Brand Colors */ --color-navy: #0A1F44; --color-gold: #D4AF37; - /* Supporting */ + /* Supporting Colors */ --color-gold-light: #F4E4B8; --color-cream: #F9F7F4; --color-charcoal: #2C3E50; - /* Status */ + /* Status Colors */ --color-success: #27AE60; --color-danger: #E74C3C; --color-warning: #F39C12; - /* Semantic aliases */ + /* Semantic Aliases - used by components */ --color-primary: var(--color-navy); --color-accent: var(--color-gold); + --color-accent-content: var(--color-gold); + --color-accent-foreground: var(--color-navy); --color-background: var(--color-cream); --color-text: var(--color-charcoal); } ``` +**Note:** The `--color-accent-content` and `--color-accent-foreground` variables are used by Flux UI components and must be updated to use brand colors. + +## Testing Requirements + +### Build Verification +- [ ] Run `npm run build` - must complete without errors +- [ ] Verify CSS output contains the new color variables + +### Utility Class Verification +Create a temporary test view or use browser dev tools to verify: +- [ ] `bg-navy` applies background color #0A1F44 +- [ ] `text-gold` applies text color #D4AF37 +- [ ] `bg-cream` applies background color #F9F7F4 +- [ ] `text-charcoal` applies text color #2C3E50 +- [ ] `bg-success` applies background color #27AE60 +- [ ] `bg-danger` applies background color #E74C3C +- [ ] `bg-warning` applies background color #F39C12 +- [ ] Semantic aliases work: `bg-primary`, `text-accent`, `bg-background` + +### Regression Check +- [ ] Existing Flux UI components still render correctly +- [ ] No visual regressions on existing pages + ## Definition of Done -- [ ] All colors defined in Tailwind -- [ ] Colors work with utility classes (bg-navy, text-gold) -- [ ] Dark mode consideration documented -- [ ] Tests pass +- [ ] All colors defined in Tailwind @theme block +- [ ] Colors work with utility classes (bg-navy, text-gold, etc.) +- [ ] Semantic aliases configured (primary, accent, background, text) +- [ ] Dark mode explicitly documented as deferred +- [ ] Existing Flux UI styling preserved +- [ ] `npm run build` succeeds +- [ ] Manual verification of utility classes complete - [ ] Code formatted with Pint ## Estimation diff --git a/docs/stories/story-9.10-accessibility-compliance.md b/docs/stories/story-9.10-accessibility-compliance.md index 1f14780..6b6a0c8 100644 --- a/docs/stories/story-9.10-accessibility-compliance.md +++ b/docs/stories/story-9.10-accessibility-compliance.md @@ -3,6 +3,18 @@ ## Epic Reference **Epic 9:** Design & Branding Implementation +## Dependencies +- **Story 9.1:** Color System Implementation (provides `gold`, `navy` Tailwind color classes used in focus styles) +- **Stories 9.4-9.7:** Component Styling (all styled components require accessibility review) +- **Story 9.8:** RTL/LTR Layout (accessibility must work in both directions) + +## Scope +This story applies to **all pages and components**: +- Public pages (landing, posts, booking) +- Authentication pages (login, register, password reset) +- Client dashboard and all client-facing views +- Admin dashboard and all admin-facing views + ## User Story As a **user with disabilities**, I want **the platform to be accessible**, @@ -10,10 +22,12 @@ So that **I can use it regardless of my abilities**. ## Acceptance Criteria -### Color Contrast -- [ ] Body text: 4.5:1 minimum -- [ ] Large text: 3:1 minimum -- [ ] UI elements: 3:1 minimum +### Color Contrast (WCAG AA Standard) +- [ ] Body text: 4.5:1 minimum contrast ratio +- [ ] Large text (18px+ bold or 24px+ regular): 3:1 minimum +- [ ] UI elements (buttons, form borders, icons): 3:1 minimum +- [ ] Verify gold (#D4AF37) on navy (#0A1F44) meets requirements +- [ ] Verify text colors on cream (#F9F7F4) backgrounds ### Focus Indicators - [ ] Visible focus outline (gold) @@ -34,8 +48,27 @@ So that **I can use it regardless of my abilities**. - [ ] Respect prefers-reduced-motion - [ ] No auto-playing animations +## Files to Modify + +| File | Changes | +|------|---------| +| `resources/css/app.css` | Add global focus styles and reduced-motion media query | +| `resources/views/components/layouts/app.blade.php` | Add skip link and `
` landmark | +| `resources/views/components/layouts/guest.blade.php` | Add skip link and main landmark for auth pages | +| `lang/en/accessibility.php` | Add translation: `'skip_to_content' => 'Skip to main content'` | +| `lang/ar/accessibility.php` | Add translation: `'skip_to_content' => 'تخطي إلى المحتوى الرئيسي'` | + +### Components to Audit +- All Flux UI form components (verify label associations) +- All image usages (verify alt text present) +- Navigation components (verify logical tab order) +- Modal components (verify focus trapping) + ## Technical Notes +### Global Accessibility Styles +Add to `resources/css/app.css`: + ```css /* Focus styles */ :focus-visible { @@ -80,10 +113,40 @@ So that **I can use it regardless of my abilities**. ``` ### Testing Tools -- axe DevTools -- WAVE -- Lighthouse -- Screen reader (VoiceOver/NVDA) +- **axe DevTools** - Browser extension for automated accessibility testing +- **WAVE** - Web accessibility evaluation tool +- **Lighthouse** - Chrome DevTools accessibility audit (target: >90 score) +- **Screen reader** - VoiceOver (macOS) or NVDA (Windows) for manual testing + +### Test Scenarios +1. **Keyboard Navigation Test:** + - Tab through entire booking form without mouse + - Verify all buttons, links, and inputs are reachable + - Confirm focus order is logical (top-to-bottom, start-to-end) + +2. **Skip Link Test:** + - Press Tab on page load + - Skip link should appear and be focusable + - Activating skip link jumps to main content + +3. **Screen Reader Test:** + - Navigate landing page with VoiceOver/NVDA + - Verify headings announced in correct order (h1 → h2 → h3) + - Verify form labels read correctly + - Verify images have meaningful alt text + +4. **Color Contrast Test:** + - Run Lighthouse on: `/`, `/login`, `/dashboard`, `/admin` + - All pages must score >90 accessibility + +5. **Reduced Motion Test:** + - Enable "Reduce motion" in OS settings + - Verify no animations play on page load or interactions + +6. **RTL Accessibility Test:** + - Switch to Arabic language + - Verify skip link position (start = right in RTL) + - Verify tab order follows RTL reading direction ## Definition of Done - [ ] Color contrast passes @@ -95,5 +158,17 @@ So that **I can use it regardless of my abilities**. - [ ] Lighthouse accessibility > 90 - [ ] Tests pass +## References +- **PRD Section 7.1:** Brand Identity - Accessibility Compliance subsection +- **Epic 9:** `docs/epics/epic-9-design-branding.md` - Story 9.10 acceptance criteria +- **Story 9.1:** Color values defined (gold: #D4AF37, navy: #0A1F44) +- **WCAG 2.1 AA Guidelines:** https://www.w3.org/WAI/WCAG21/quickref/ + ## Estimation **Complexity:** Medium | **Effort:** 4-5 hours + +## Notes for Developer +- Flux UI components generally have good accessibility built-in; focus on custom components +- If Flux components don't meet contrast requirements, create custom CSS overrides +- The `!important` in reduced-motion CSS is intentional to override all animations +- Use `focus:start-4` (not `focus:left-4`) for RTL compatibility diff --git a/docs/stories/story-9.11-animations-micro-interactions.md b/docs/stories/story-9.11-animations-micro-interactions.md index ee0cae9..8cf0dde 100644 --- a/docs/stories/story-9.11-animations-micro-interactions.md +++ b/docs/stories/story-9.11-animations-micro-interactions.md @@ -3,6 +3,13 @@ ## Epic Reference **Epic 9:** Design & Branding Implementation +## Dependencies +- **Story 9.4** (Buttons): Button components must be styled before adding transitions +- **Story 9.5** (Forms): Form components must be complete for error shake animations +- **Story 9.6** (Cards): Card components must be styled before adding hover/lift effects +- **Story 9.7** (Navigation): Navigation must be complete for link transitions +- **Story 9.10** (Accessibility): Coordinates with `prefers-reduced-motion` requirements + ## User Story As a **user**, I want **subtle, professional animations**, @@ -38,6 +45,26 @@ So that **the interface feels polished and responsive**. ## Technical Notes +### Files to Create/Modify + +| File | Action | Purpose | +|------|--------|---------| +| `resources/css/app.css` | Modify | Add animation utility classes and keyframes | +| `resources/views/components/skeleton.blade.php` | Create | Skeleton loader component | +| `resources/views/components/spinner.blade.php` | Create | Loading spinner component | +| `resources/views/components/toast.blade.php` | Create | Toast notification with slide-in animation | +| `resources/views/components/icons/checkmark.blade.php` | Create | Animated success checkmark SVG | + +### Component Integration Points + +- **Buttons** (``): Add `transition-colors duration-150` to existing button styles +- **Cards**: Apply `.card-hover` class to interactive card components +- **Forms**: Use `.shake` class on form fields when validation fails (triggered via Alpine.js) +- **Livewire Loading**: Use `` component with `wire:loading` directive +- **Toast Notifications**: Integrate with Livewire event dispatch for flash messages + +### Animation CSS + ```css /* Base transitions */ .transition-default { @@ -95,6 +122,29 @@ So that **the interface feels polished and responsive**. .shake { animation: shake 0.3s ease-in-out; } + +/* Reduced motion support - REQUIRED for accessibility */ +@media (prefers-reduced-motion: reduce) { + .transition-default, + .transition-slow, + .card-hover, + .btn { + transition: none !important; + } + + .skeleton { + animation: none !important; + } + + .checkmark-animated path, + .shake { + animation: none !important; + } + + .toast-enter-active { + transition: none !important; + } +} ``` ```blade @@ -117,6 +167,42 @@ So that **the interface feels polished and responsive**. ``` +## Testing Requirements + +### Testing Approach +- **Visual Inspection**: Manual browser testing for animation smoothness and timing +- **Pest Browser Tests**: Automated tests to verify animation classes are applied +- **Cross-Browser Testing**: Chrome, Firefox, Safari (animations can vary) +- **Reduced Motion Testing**: Verify animations disabled when preference is set + +### Key Test Scenarios + +| Scenario | Expected Result | +|----------|-----------------| +| Hover over button | Background color transitions smoothly (150ms) | +| Hover over card | Card lifts slightly with shadow increase (200ms) | +| Form validation fails | Input field shakes briefly | +| Content loading | Skeleton pulses until content loads | +| Action in progress | Spinner displays with `wire:loading` | +| Toast notification triggered | Toast slides in from right edge | +| `prefers-reduced-motion: reduce` enabled | All animations/transitions disabled | + +### Pest Browser Test Example + +```php +// tests/Browser/AnimationsTest.php +it('applies hover transition to buttons', function () { + visit('/login') + ->assertPresent('button.transition-colors'); +}); + +it('respects reduced motion preference', function () { + visit('/') + ->withReducedMotion() + ->assertStyleContains('.btn', 'transition', 'none'); +}); +``` + ## Definition of Done - [ ] Button transitions work - [ ] Card hover effects work @@ -125,7 +211,8 @@ So that **the interface feels polished and responsive**. - [ ] Toast animations work - [ ] All animations subtle - [ ] Reduced motion respected -- [ ] Tests pass +- [ ] Pest browser tests pass +- [ ] Cross-browser tested (Chrome, Firefox, Safari) ## Estimation **Complexity:** Medium | **Effort:** 4 hours diff --git a/docs/stories/story-9.2-typography-system.md b/docs/stories/story-9.2-typography-system.md index 74d4bf7..b4888b8 100644 --- a/docs/stories/story-9.2-typography-system.md +++ b/docs/stories/story-9.2-typography-system.md @@ -3,6 +3,12 @@ ## Epic Reference **Epic 9:** Design & Branding Implementation +## Dependencies +- **Story 9.1 (Color System)** must be complete - this story extends the existing `@theme` block in `resources/css/app.css` + +## PRD Reference +- **Section 7.1.C:** Typography specifications (font families, weights, hierarchy) + ## User Story As a **user**, I want **professional, readable typography**, @@ -32,8 +38,12 @@ So that **the platform feels polished and content is easy to read**. ## Technical Notes +**Target File:** `resources/css/app.css` + +**Implementation:** Add the font imports and extend the existing `@theme` block from Story 9.1 with typography variables. + ```css -/* Google Fonts import */ +/* Google Fonts import - add at top of file */ @import url('https://fonts.googleapis.com/css2?family=Cairo:wght@300;400;600;700&family=Montserrat:wght@300;400;600;700&display=swap'); @theme { @@ -60,13 +70,48 @@ html[lang="en"] body { } ``` +## Testing Approach + +### Visual Verification +- [ ] Font hierarchy renders at correct sizes (H1=40px, H2=32px, H3=24px, Body=16px, Small=14px) +- [ ] Line heights display correctly (1.6 for body, 1.3 for headings) +- [ ] Font weights display correctly (Light 300, Regular 400, SemiBold 600, Bold 700) + +### RTL/LTR Testing +- [ ] Arabic pages (`html[lang="ar"]`) use Cairo/Tajawal font family +- [ ] English pages (`html[lang="en"]`) use Montserrat/Lato font family +- [ ] Language toggle switches fonts correctly without page reload issues + +### Performance Testing +- [ ] Network tab confirms `font-display=swap` in Google Fonts URL +- [ ] No FOIT (Flash of Invisible Text) - text displays with fallback then swaps +- [ ] Font files load from Google Fonts CDN successfully + +### Browser Compatibility +- [ ] Fonts render correctly in Chrome, Firefox, Safari, Edge +- [ ] Fallback fonts (`sans-serif`) work if Google Fonts fails to load + ## Definition of Done -- [ ] Fonts load correctly -- [ ] Arabic fonts work with RTL -- [ ] English fonts work with LTR -- [ ] Font hierarchy applied -- [ ] Performance optimized -- [ ] Tests pass +- [ ] Font imports added to `resources/css/app.css` +- [ ] Typography variables added to `@theme` block +- [ ] Dynamic font selection CSS rules implemented +- [ ] Arabic fonts render correctly with RTL layout +- [ ] English fonts render correctly with LTR layout +- [ ] Font hierarchy visually verified on test pages +- [ ] Performance optimized (font-display: swap confirmed) +- [ ] All testing scenarios above pass +- [ ] Code formatted with Pint +- [ ] Assets rebuilt with `npm run build` + +## Assumptions +- Google Fonts CDN is acceptable for font hosting (no self-hosting requirement) +- The `html[lang]` attribute is already set by the existing i18n system +- Story 9.1's `@theme` block is in place and working + +## Notes for Developer +- **Extend, don't replace:** Add font variables to the existing `@theme` block from Story 9.1 +- **Import order matters:** Place Google Fonts `@import` before the `@import "tailwindcss"` statement +- **Fallback fonts:** The CSS includes fallbacks (`'Tajawal'`, `'Lato'`, `sans-serif`) - these are intentional for graceful degradation ## Estimation **Complexity:** Medium | **Effort:** 3 hours diff --git a/docs/stories/story-9.3-logo-integration.md b/docs/stories/story-9.3-logo-integration.md index c855dce..dcddbe4 100644 --- a/docs/stories/story-9.3-logo-integration.md +++ b/docs/stories/story-9.3-logo-integration.md @@ -8,45 +8,67 @@ As a **visitor**, I want **to see the Libra scales logo prominently displayed**, So that **I recognize the firm's branding**. +## Dependencies +- **Story 9.1:** Color System Implementation (for brand colors) +- **Prerequisite:** Logo SVG/PNG assets must be provided or placeholder created +- **Note:** Footer integration deferred to Story 9.7; Email templates to Epic 8 + ## Acceptance Criteria ### Logo Placement - [ ] Navigation: Top left (desktop), centered (mobile) -- [ ] Footer: Smaller version -- [ ] Email templates: Header -- [ ] PDF exports: Header +- [ ] Footer: Smaller version (integrated when footer created in Story 9.7) +- [ ] Email templates: Header (integrated when email templates created in Epic 8) +- [ ] PDF exports: Header (integrated when PDF exports created) ### Logo Specifications -- [ ] Minimum size: 120px (desktop), 80px (mobile) -- [ ] Clear space: 20px padding minimum +- [ ] Minimum size: 120px width (desktop), 80px width (mobile) +- [ ] Clear space: 20px padding minimum around logo ### Format Support -- [ ] SVG primary (scalable) -- [ ] PNG fallback +- [ ] SVG primary (scalable, preferred) +- [ ] PNG fallback (for email clients that don't support SVG) ### Color Variations -- [ ] Full color (gold on navy) -- [ ] Reversed (navy on light) -- [ ] Monochrome gold +- [ ] **Full color:** Gold (#D4AF37) logo on Navy (#0A1F44) background +- [ ] **Reversed:** Navy (#0A1F44) logo on light/cream (#F9F7F4) background +- [ ] **Monochrome:** Single-color gold (#D4AF37) version ### Features -- [ ] Responsive sizing -- [ ] Accessible alt text +- [ ] Responsive sizing based on viewport +- [ ] Accessible alt text: "Libra Law Firm" (translatable) ## Technical Notes +### Existing Component +An `app-logo.blade.php` component already exists at `resources/views/components/app-logo.blade.php`. This story will **replace** it with a more robust implementation supporting variants and sizes. + +**Files to modify:** +- `resources/views/components/app-logo.blade.php` - Replace with new implementation +- `resources/views/components/app-logo-icon.blade.php` - Update or remove +- `resources/views/components/layouts/app/header.blade.php` - Update logo usage (lines 11, 96) + +**Files to create:** +- `public/images/logo.svg` - Full color logo +- `public/images/logo-reversed.svg` - Reversed color logo +- `public/images/logo-mono.svg` - Monochrome logo +- `public/images/logo.png` - PNG fallback + +### Logo Component Implementation + ```blade - + @props([ 'size' => 'default', - 'variant' => 'full' + 'variant' => 'full', + 'showText' => true ]) @php $sizes = [ - 'small' => 'h-8', - 'default' => 'h-12', - 'large' => 'h-16', + 'small' => 'h-8 min-w-[80px]', // Mobile minimum + 'default' => 'h-12 min-w-[120px]', // Desktop default + 'large' => 'h-16 min-w-[160px]', // Large displays ]; $variants = [ @@ -54,23 +76,116 @@ $variants = [ 'reversed' => 'logo-reversed.svg', 'mono' => 'logo-mono.svg', ]; + +$sizeClass = $sizes[$size] ?? $sizes['default']; +$logoFile = $variants[$variant] ?? $variants['full']; @endphp -{{ __('Libra Law Firm') }}merge(['class' => $sizes[$size]]) }} -/> +
merge(['class' => 'flex items-center gap-2 p-5']) }}> + {{ __('Libra Law Firm') }} + @if($showText) + {{ __('Libra Law Firm') }} + @endif +
+``` + +### Logo Asset Fallback Strategy +If final logo assets are not yet available: +1. Create a placeholder SVG using Libra scales icon from Heroicons or similar +2. Use the brand colors (Gold #D4AF37, Navy #0A1F44) +3. Replace with final assets when provided + +### Color Reference (from Story 9.1) +| Color | Hex | Usage | +|-------|-----|-------| +| Dark Navy Blue | #0A1F44 | Primary background | +| Gold/Brass | #D4AF37 | Primary accent, logo | +| Off-White/Cream | #F9F7F4 | Light backgrounds | + +## Testing Requirements + +### Unit Tests +Create `tests/Feature/Components/LogoComponentTest.php`: + +```php +blade(''); + + $view->assertSee('Libra Law Firm'); + $view->assertSee('logo.svg'); +}); + +test('logo component renders small size variant', function () { + $view = $this->blade(''); + + $view->assertSee('h-8'); +}); + +test('logo component renders reversed color variant', function () { + $view = $this->blade(''); + + $view->assertSee('logo-reversed.svg'); +}); + +test('logo component renders without text when showText is false', function () { + $view = $this->blade(''); + + $view->assertDontSee('blade(''); + + $view->assertSee('alt="Libra Law Firm"', false); +}); +``` + +### Browser Tests (Pest v4) +Create `tests/Browser/LogoTest.php`: + +```php +assertVisible('img[alt="Libra Law Firm"]') + ->assertNoJavascriptErrors(); +}); + +it('logo is responsive on mobile viewport', function () { + $page = visit('/') + ->viewport(375, 812); // iPhone viewport + + $page->assertVisible('img[alt="Libra Law Firm"]'); +}); ``` ## Definition of Done -- [ ] Logo displays in navigation -- [ ] Logo displays in footer -- [ ] Logo in email templates -- [ ] Responsive sizing works -- [ ] All color variants available -- [ ] Alt text correct -- [ ] Tests pass +- [ ] Logo component created with size and variant props +- [ ] Logo displays correctly in navigation header +- [ ] All three color variants available and working +- [ ] PNG fallback works when SVG fails to load +- [ ] Responsive sizing works across breakpoints +- [ ] Alt text is present and translatable +- [ ] Existing header.blade.php updated to use new component +- [ ] Unit tests pass +- [ ] Browser tests pass +- [ ] Code formatted with Pint + +## Out of Scope (Deferred) +- Footer logo placement → Story 9.7 +- Email template logo → Epic 8 (Story 8.1+) +- PDF export logo → Future story ## Estimation -**Complexity:** Low | **Effort:** 2 hours +**Complexity:** Low | **Effort:** 2-3 hours diff --git a/docs/stories/story-9.4-component-styling-buttons.md b/docs/stories/story-9.4-component-styling-buttons.md index 9ab8de9..7d38cd0 100644 --- a/docs/stories/story-9.4-component-styling-buttons.md +++ b/docs/stories/story-9.4-component-styling-buttons.md @@ -3,25 +3,38 @@ ## 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 (#D4AF37) -- [ ] Text: Dark Navy Blue -- [ ] Hover: Light Gold (#F4E4B8) -- [ ] Border-radius: 6px -- [ ] Padding: 12px 24px +- [ ] 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 -- [ ] Text: Gold -- [ ] Hover: Gold background, Navy text +- [ ] 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 @@ -30,50 +43,178 @@ So that **interactive elements are clear and visually appealing**. - [ ] Cursor: not-allowed ### Danger Button -- [ ] Background: #E74C3C +- [ ] 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 spinner -- [ ] Focus states for accessibility -- [ ] Flux UI button integration +- [ ] 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 -/* Extend Flux UI buttons */ +/* 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 hover:bg-gold hover:text-navy rounded-md px-6 py-3 font-semibold transition-colors; + @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; + @apply relative pointer-events-none opacity-75; } -.btn-loading::after { - content: ''; - @apply absolute inset-0 flex items-center justify-center; - /* Spinner styles */ -} +/* 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 -- [ ] Secondary button styled -- [ ] Danger button styled -- [ ] Disabled states work -- [ ] Loading states work -- [ ] Focus states accessible +- [ ] 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 diff --git a/docs/stories/story-9.5-component-styling-forms.md b/docs/stories/story-9.5-component-styling-forms.md index b0946e4..fcf78a3 100644 --- a/docs/stories/story-9.5-component-styling-forms.md +++ b/docs/stories/story-9.5-component-styling-forms.md @@ -8,45 +8,82 @@ As a **user**, I want **consistent, accessible form styling**, So that **data entry is intuitive and error states are clear**. +## Dependencies +- **Story 9.1 (Color System)** - Must be completed first; provides Tailwind color aliases used below +- **Story 9.2 (Typography System)** - Font weights for labels + +## Color Reference (from Story 9.1) +For quick reference, this story uses these colors defined in the Tailwind theme: +- `gold` (#D4AF37) - Focus states, checkbox accents +- `charcoal` (#2C3E50) - Default borders, label text +- `danger` (#E74C3C) - Error states +- `cream` (#F9F7F4) - Input backgrounds (if needed) + ## Acceptance Criteria ### Input Fields -- [ ] Border: Charcoal Gray -- [ ] Focus: Gold border -- [ ] Border-radius: 6px -- [ ] Padding: 12px 16px +- [ ] Border: Charcoal Gray (`border-charcoal/30`) +- [ ] Focus: Gold border with subtle ring (`focus:border-gold focus:ring-gold/20`) +- [ ] Border-radius: 6px (`rounded-md`) +- [ ] Padding: 12px 16px (`px-4 py-3`) ### Textareas - [ ] Same styling as inputs -- [ ] Minimum height: 120px +- [ ] Minimum height: 120px (`min-h-[120px]`) ### Select Dropdowns -- [ ] Custom styled (not native) -- [ ] Consistent with inputs +- [ ] Custom styled using Flux UI (not native browser) +- [ ] Consistent border/focus styling with inputs ### Checkboxes & Radios -- [ ] Custom styled with gold accent -- [ ] Clear checked state +- [ ] Custom styled with gold accent when checked +- [ ] Clear visual distinction between checked/unchecked states ### Labels -- [ ] SemiBold weight -- [ ] Required indicator (*) +- [ ] SemiBold weight (`font-semibold`) +- [ ] Required indicator (*) in danger color ### Error States -- [ ] Red border -- [ ] Error message below field +- [ ] Red border (`border-danger`) +- [ ] Error message displayed below field +- [ ] Error ring on focus (`focus:ring-danger/20`) ### RTL Support -- [ ] All fields align correctly in RTL +- [ ] Labels align to the right in RTL mode +- [ ] Input text direction follows locale +- [ ] Error messages align correctly +- [ ] Padding swaps appropriately (use `ps-4 pe-4` instead of `px-4` if needed) -## Technical Notes +## Files to Create/Modify + +### Primary Files +- `resources/css/app.css` - Add form component utility classes + +### Flux UI Integration +Flux UI Free includes these form components that need styling customization: +- `flux:input` - Text inputs +- `flux:textarea` - Multiline text +- `flux:select` - Dropdown selects +- `flux:checkbox` - Checkboxes +- `flux:radio` - Radio buttons +- `flux:field` - Field wrapper with label/error support + +### Existing Forms to Audit +Review and update existing forms in: +- `resources/views/livewire/` - Any Volt components with forms +- Authentication views (login, register, password reset) +- Contact/booking forms + +## Technical Implementation + +### CSS Classes (add to `resources/css/app.css`) ```css /* Form field styling */ .input-field { @apply w-full border border-charcoal/30 rounded-md px-4 py-3 focus:border-gold focus:ring-2 focus:ring-gold/20 - transition-colors outline-none; + transition-colors outline-none bg-white; } .input-error { @@ -66,21 +103,158 @@ So that **data entry is intuitive and error states are clear**. @apply text-sm text-danger mt-1; } +/* Textarea specific */ +.textarea-field { + @apply input-field min-h-[120px] resize-y; +} + /* Custom checkbox */ .checkbox-custom { @apply w-5 h-5 rounded border-charcoal/30 text-gold focus:ring-gold focus:ring-offset-0; } + +/* Custom radio */ +.radio-custom { + @apply w-5 h-5 border-charcoal/30 text-gold + focus:ring-gold focus:ring-offset-0; +} +``` + +### Flux UI Component Usage Examples + +```blade +{{-- Basic input with label --}} + + Email + + + +{{-- Required field with error --}} + + Name + + @error('name') + {{ $message }} + @enderror + + +{{-- Textarea --}} + + Message + + + +{{-- Select dropdown --}} + + Category + + Select... + Legal + General + + + +{{-- Checkbox with gold accent --}} + + + I agree to the terms + + +{{-- Radio group --}} + + Preferred Contact +
+ + +
+
+``` + +### RTL Considerations +- Use logical properties where possible (`ps-`, `pe-`, `ms-`, `me-` instead of `pl-`, `pr-`, `ml-`, `mr-`) +- Flux components should handle RTL automatically with `dir="rtl"` on the HTML element +- Test label positioning in Arabic locale + +## Testing Requirements + +### Manual Testing Checklist +1. **Visual Inspection (both locales)** + - [ ] Switch to Arabic - verify RTL alignment + - [ ] Switch to English - verify LTR alignment + - [ ] All form elements match design specs + +2. **Interactive States** + - [ ] Click into each field type - verify gold focus ring appears + - [ ] Tab through form - verify focus order is logical + - [ ] Submit with errors - verify error styling appears + +3. **Accessibility** + - [ ] Labels are associated with inputs (clicking label focuses input) + - [ ] Error messages are announced to screen readers + - [ ] Focus indicators are clearly visible + +### Automated Tests +Create feature test for form styling verification: + +```php +// tests/Feature/FormStylingTest.php +test('form fields render with correct classes', function () { + // Test that forms include the expected CSS classes + $this->get('/contact') + ->assertSee('input-field') + ->assertSee('form-label'); +}); + +test('form error states display correctly', function () { + // Submit form with invalid data and check error styling + Livewire::test('contact-form') + ->set('email', 'invalid') + ->call('submit') + ->assertSee('input-error') + ->assertSee('error-message'); +}); +``` + +### Browser Testing (RTL Verification) +```php +// tests/Browser/FormRtlTest.php +it('displays form labels on the right in RTL mode', function () { + visit('/ar/contact') + ->assertPresent('[dir="rtl"]') + ->assertVisible('.form-label'); + // Visual inspection for alignment +}); ``` ## Definition of Done -- [ ] Input styling consistent -- [ ] Textarea styling consistent -- [ ] Select styling works -- [ ] Checkbox/radio styled -- [ ] Error states clear -- [ ] RTL alignment correct -- [ ] Tests pass +- [ ] CSS classes added to `resources/css/app.css` +- [ ] Input styling matches specs (border, focus, padding, radius) +- [ ] Textarea styling consistent with inputs, min-height 120px +- [ ] Select dropdowns styled consistently (not native) +- [ ] Checkboxes show gold accent when checked +- [ ] Radio buttons show gold accent when selected +- [ ] Labels are semibold with required indicator working +- [ ] Error states show red border and message below +- [ ] RTL alignment verified in Arabic locale +- [ ] LTR alignment verified in English locale +- [ ] Existing forms updated to use new classes +- [ ] Feature tests pass +- [ ] Code formatted with Pint ## Estimation **Complexity:** Medium | **Effort:** 3-4 hours + +## Dev Notes +- Check Flux UI docs for any built-in theming options before adding custom CSS +- If Flux components don't accept className props well, may need to use CSS selectors targeting Flux's rendered HTML +- Run `npm run build` after CSS changes to see updates diff --git a/docs/stories/story-9.6-component-styling-cards-containers.md b/docs/stories/story-9.6-component-styling-cards-containers.md index cd653f0..f96e231 100644 --- a/docs/stories/story-9.6-component-styling-cards-containers.md +++ b/docs/stories/story-9.6-component-styling-cards-containers.md @@ -3,6 +3,9 @@ ## Epic Reference **Epic 9:** Design & Branding Implementation +## Dependencies +- **Story 9.1:** Color System Implementation (required - provides Tailwind color classes used in this story) + ## User Story As a **user**, I want **consistent card and container styling**, @@ -38,6 +41,19 @@ So that **content is well-organized and visually appealing**. ## Technical Notes +### Color Classes Reference (from Story 9.1) +| Class | Color | Hex | +|-------|-------|-----| +| `bg-cream` | Off-white/Cream | #F9F7F4 | +| `text-gold` / `border-gold` | Gold | #D4AF37 | +| `bg-gold/10` | Gold at 10% opacity | - | +| `text-navy` | Dark Navy Blue | #0A1F44 | +| `text-charcoal` | Charcoal Gray | #2C3E50 | +| `text-success` | Success Green | #27AE60 | +| `text-danger` | Warning Red | #E74C3C | + +### Component Implementation + ```blade @props([ @@ -79,6 +95,35 @@ So that **content is well-organized and visually appealing**. ``` +### Edge Cases +- **Null/Zero Trend:** Stat card should gracefully handle `null` trend (hidden) and `0` trend (show as neutral) +- **RTL Layout:** Cards with `border-s-4` will automatically flip border to right side in RTL mode +- **Container Overflow:** Content exceeding max-width should be contained; consider horizontal scroll for tables +- **Missing Icon:** Handle gracefully if Flux icon name doesn't exist (fallback or hide icon container) +- **Empty Cards:** Ensure cards maintain minimum height even with minimal content + +## Testing Requirements + +### Unit Tests +- [ ] Card component renders with default variant +- [ ] Card component renders with `elevated` variant +- [ ] Card component applies hover classes when `hover=true` +- [ ] Card component applies highlight border when `highlight=true` +- [ ] Stat card displays value and label correctly +- [ ] Stat card shows positive trend with `+` prefix and success color +- [ ] Stat card shows negative trend with danger color +- [ ] Stat card hides trend indicator when `trend=null` + +### Visual/Browser Tests +- [ ] Hover lift effect animates smoothly +- [ ] Shadow transitions on hover +- [ ] Cards display correctly in RTL layout +- [ ] Container centers content and respects max-width +- [ ] Responsive behavior at all breakpoints + +### Test File Location +`tests/Feature/Components/CardComponentTest.php` + ## Definition of Done - [ ] Card component created - [ ] Shadow and radius consistent diff --git a/docs/stories/story-9.7-navigation-footer-styling.md b/docs/stories/story-9.7-navigation-footer-styling.md index f50cfd9..231996d 100644 --- a/docs/stories/story-9.7-navigation-footer-styling.md +++ b/docs/stories/story-9.7-navigation-footer-styling.md @@ -3,6 +3,12 @@ ## Epic Reference **Epic 9:** Design & Branding Implementation +## Story Dependencies +- **Story 9.1:** Color System Implementation (provides `bg-navy`, `text-gold`, `text-cream` classes) +- **Story 9.3:** Logo Integration (provides `` component with variants) +- **Story 1.3:** Bilingual Infrastructure (provides language toggle mechanism) +- **Story 1.4:** Base UI Navigation (provides existing header structure) + ## User Story As a **user**, I want **professional navigation and footer styling**, @@ -11,94 +17,376 @@ So that **I can easily navigate the site and find information**. ## Acceptance Criteria ### Navigation Bar -- [ ] Fixed top position -- [ ] Navy blue background +- [ ] Fixed top position with `z-50` +- [ ] Navy blue background (`bg-navy`) - [ ] Logo left (desktop), centered (mobile) -- [ ] Gold text for links -- [ ] Active link indicator -- [ ] Language toggle styled +- [ ] Gold text for links (`text-gold`) +- [ ] Active link indicator (gold underline or background) +- [ ] Language toggle styled consistently - [ ] Responsive mobile menu ### Mobile Menu -- [ ] Full-width dropdown/slide -- [ ] Navy background -- [ ] Clear touch targets (44px+) -- [ ] Smooth animation +- [ ] Full-width dropdown/slide from left +- [ ] Navy background (`bg-navy`) +- [ ] Clear touch targets (44px+ minimum) +- [ ] Smooth animation (200-300ms) +- [ ] Close button visible ### Footer -- [ ] Navy blue background -- [ ] Logo and firm info -- [ ] Contact details -- [ ] Links to Terms/Privacy -- [ ] Copyright notice -- [ ] Sticky footer (always at bottom) +- [ ] Navy blue background (`bg-navy`) +- [ ] Logo and firm info (using ``) +- [ ] Contact details section +- [ ] Links to Terms/Privacy pages +- [ ] Copyright notice with dynamic year +- [ ] Sticky footer (always at bottom even on short pages) -## Technical Notes +### Edge Cases +- [ ] Guest navigation: Show Home, Posts, Contact, Login/Register +- [ ] Authenticated navigation: Show Home, Dashboard, Posts, user menu +- [ ] RTL layout: Logo moves to right, menu items reverse order +- [ ] Empty page content: Footer stays at viewport bottom + +## Technical Implementation + +### Files to Modify + +| File | Action | Purpose | +|------|--------|---------| +| `resources/views/components/layouts/app/header.blade.php` | Modify | Update nav styling to brand colors | +| `resources/views/components/layouts/app.blade.php` | Modify | Add footer component, ensure sticky footer | +| `resources/views/components/layouts/auth.blade.php` | Modify | Add footer for auth pages | +| `resources/css/app.css` | Modify | Add nav-specific utilities if needed | + +### Files to Create + +| File | Purpose | +|------|---------| +| `resources/views/components/footer.blade.php` | Reusable footer component | +| `resources/views/components/nav-link.blade.php` | Styled navigation link with active state | +| `resources/views/components/mobile-menu.blade.php` | Mobile navigation drawer (optional - can inline) | + +### Color Reference (from Story 9.1) +``` +Navy Blue: bg-navy (#0A1F44) - nav/footer background +Gold: text-gold (#D4AF37) - links, accents +Light Gold: text-gold-light (#F4E4B8) - hover states +Cream: text-cream (#F9F7F4) - footer text +``` + +### Navigation Structure ```blade - - + +
+
+ + {{ __('nav.home') }} + + + {{ __('nav.posts') }} + + @guest + + {{ __('nav.login') }} + + + {{ __('nav.register') }} + + @else + + {{ __('nav.dashboard') }} + + @endguest +
+
+ - + +
+ + +
+ {{ $slot }} +
+ + + + + @fluxScripts + + +``` + +### Nav Link Component + +```blade + +@props(['active' => false, 'mobile' => false]) + +@php +$baseClasses = $mobile + ? 'block px-4 py-3 min-h-[44px] text-base font-medium transition-colors duration-150' + : 'text-sm font-medium transition-colors duration-150'; + +$activeClasses = $active + ? 'text-gold-light' + : 'text-gold hover:text-gold-light'; +@endphp + +merge(['class' => "$baseClasses $activeClasses"]) }} wire:navigate> + {{ $slot }} + +``` + +### Footer Component + +```blade +
+
-

{{ __('footer.description') }}

+

+ {{ __('footer.description') }} +

+ + + +

{{ __('footer.contact') }}

- +
    +
  • + + {{ config('libra.contact.email', 'info@libra.ps') }} +
  • +
  • + + {{ config('libra.contact.phone', '+970 2 123 4567') }} +
  • +
  • + + {{ config('libra.contact.address', 'Ramallah, Palestine') }} +
  • +
+ +
- © {{ date('Y') }} {{ __('footer.copyright') }} + © {{ date('Y') }} {{ __('footer.copyright', ['name' => config('app.name')]) }}
``` +### Sticky Footer CSS (if needed) + +```css +/* resources/css/app.css - add if flex approach insufficient */ +body { + display: flex; + flex-direction: column; + min-height: 100vh; +} + +main { + flex: 1; +} +``` + +## RTL Considerations + +1. **Logo Position:** Use `rtl:order-last` if logo should move to right in RTL +2. **Menu Items:** Flex containers with `rtl:flex-row-reverse` or use logical properties +3. **Icons:** Some icons (arrows, chevrons) may need flipping with `rtl:scale-x-[-1]` +4. **Spacing:** Use `ms-*`/`me-*` (margin-start/end) instead of `ml-*`/`mr-*` +5. **Text Alignment:** Use `text-start`/`text-end` instead of `text-left`/`text-right` + +## Translation Keys Required + +```php +// resources/lang/en/nav.php +return [ + 'home' => 'Home', + 'posts' => 'Posts', + 'login' => 'Login', + 'register' => 'Register', + 'dashboard' => 'Dashboard', +]; + +// resources/lang/en/footer.php +return [ + 'description' => 'Professional legal services in Palestine.', + 'links' => 'Quick Links', + 'terms' => 'Terms of Service', + 'privacy' => 'Privacy Policy', + 'contact' => 'Contact Us', + 'copyright' => 'All rights reserved. :name', +]; +``` + ## Definition of Done -- [ ] Navigation styled correctly -- [ ] Mobile menu works -- [ ] Footer styled correctly -- [ ] Sticky footer works -- [ ] Links functional -- [ ] RTL layout works +- [ ] Navigation styled with navy background and gold links +- [ ] Mobile menu works with smooth animation +- [ ] Footer styled and positioned correctly +- [ ] Sticky footer works on short-content pages +- [ ] All navigation links functional +- [ ] RTL layout mirrors correctly (logo right, reversed order) +- [ ] Guest vs authenticated nav items display correctly +- [ ] Language toggle integrated and styled +- [ ] Touch targets meet 44px minimum on mobile - [ ] Tests pass +## Testing Requirements + +### Feature Tests +```php +// tests/Feature/NavigationTest.php +test('navigation displays home link', function () { + $this->get('/') + ->assertSee(__('nav.home')); +}); + +test('guest sees login link in navigation', function () { + $this->get('/') + ->assertSee(__('nav.login')); +}); + +test('authenticated user sees dashboard link', function () { + $user = User::factory()->create(); + + $this->actingAs($user) + ->get('/') + ->assertSee(__('nav.dashboard')) + ->assertDontSee(__('nav.login')); +}); + +test('footer displays on all pages', function () { + $this->get('/') + ->assertSee(__('footer.copyright')); +}); + +test('footer links to terms and privacy', function () { + $this->get('/') + ->assertSee(__('footer.terms')) + ->assertSee(__('footer.privacy')); +}); +``` + +### Browser Tests (Pest v4) +```php +// tests/Browser/NavigationTest.php +it('mobile menu toggles correctly', function () { + visit('/') + ->resize(375, 812) // iPhone viewport + ->assertNotVisible('[x-show="mobileMenu"]') + ->click('[aria-label="Toggle menu"]') + ->assertVisible('[x-show="mobileMenu"]') + ->click('[aria-label="Toggle menu"]') + ->assertNotVisible('[x-show="mobileMenu"]'); +}); + +it('navigation renders correctly in RTL', function () { + visit('/?lang=ar') + ->assertAttribute('html', 'dir', 'rtl'); +}); +``` + +### Manual Testing Checklist +- [ ] Desktop: Nav links visible, hover states work +- [ ] Mobile: Menu toggle works, touch targets adequate +- [ ] RTL (Arabic): Layout mirrors correctly +- [ ] LTR (English): Standard layout +- [ ] Short page: Footer at viewport bottom +- [ ] Long page: Footer at content bottom +- [ ] Guest user: Login/Register visible +- [ ] Logged in: Dashboard/user menu visible + ## Estimation **Complexity:** Medium | **Effort:** 4 hours + +## References +- Epic 9 Definition: `docs/epics/epic-9-design-branding.md` +- Color System: Story 9.1 +- Logo Component: Story 9.3 +- Existing Header: `resources/views/components/layouts/app/header.blade.php` +- PRD Design Section: `docs/prd.md#design-requirements` diff --git a/docs/stories/story-9.8-rtl-ltr-layout-perfection.md b/docs/stories/story-9.8-rtl-ltr-layout-perfection.md index d758575..53a0b17 100644 --- a/docs/stories/story-9.8-rtl-ltr-layout-perfection.md +++ b/docs/stories/story-9.8-rtl-ltr-layout-perfection.md @@ -3,88 +3,286 @@ ## Epic Reference **Epic 9:** Design & Branding Implementation +## Story Dependencies +- **Story 9.1** (Color System) - Must be complete; RTL audit needs final color variables +- **Story 9.4** (Button Styling) - Buttons must use logical properties +- **Story 9.5** (Form Styling) - Forms require RTL label/error positioning +- **Story 9.6** (Cards & Containers) - Cards need directional border handling +- **Story 9.7** (Navigation & Footer) - Navigation mirroring depends on this work + ## User Story As a **user**, I want **perfect RTL layout for Arabic and LTR for English**, So that **the content is natural to read in my language**. +## Background Context + +### Current State (from codebase analysis) +The application already has partial RTL support: +- `app()->getLocale()` sets `lang` attribute on `` +- Some logical properties already in use: `border-e`, `me-5`, `rtl:space-x-reverse` +- **Missing:** `dir` attribute is NOT set on `` element +- **Missing:** Systematic RTL audit of all components + +### PRD Requirements (Section 4.2) +- Primary Language: Arabic (default) with RTL layout +- Secondary Language: English with LTR layout +- Full site language toggle +- All UI elements in both languages + ## Acceptance Criteria ### RTL (Arabic) -- [ ] Text aligns right -- [ ] Navigation mirrors (logo right) -- [ ] Form labels on right -- [ ] Icons/arrows flip appropriately -- [ ] Margins/paddings swap +- [ ] `dir="rtl"` dynamically set on `` when locale is `ar` +- [ ] Text aligns right naturally +- [ ] Navigation mirrors (sidebar on right for RTL) +- [ ] Form labels on right side of inputs +- [ ] Icons/arrows flip appropriately (chevrons, arrows) +- [ ] Margins/paddings swap using logical properties ### LTR (English) +- [ ] `dir="ltr"` set on `` when locale is `en` - [ ] Standard left-to-right layout - [ ] Proper text alignment ### Transitions -- [ ] Seamless language toggle +- [ ] Seamless language toggle without page reload issues - [ ] No layout breaks on switch +- [ ] No flash of wrong direction on page load ### Component Support -- [ ] Calendar RTL support -- [ ] Tables RTL support -- [ ] All components tested in both modes +- [ ] Calendar component RTL support (date picker) +- [ ] Tables RTL support (horizontal scroll direction) +- [ ] Dropdowns open in correct direction +- [ ] Modals position correctly +- [ ] All Flux UI components tested in both modes -## Technical Notes +## Technical Implementation -```css -/* Use logical properties */ -.card { - margin-inline-start: 1rem; /* margin-left in LTR, margin-right in RTL */ - padding-inline-end: 1rem; /* padding-right in LTR, padding-left in RTL */ -} +### Key Files to Modify -/* RTL-aware utilities */ -[dir="rtl"] .flip-rtl { - transform: scaleX(-1); -} - -/* Tailwind RTL plugin configuration */ -@theme { - /* Use logical properties by default */ -} +#### 1. Layout Files (Add `dir` attribute) +``` +resources/views/components/layouts/app/sidebar.blade.php +resources/views/components/layouts/auth/simple.blade.php +resources/views/components/layouts/auth/card.blade.php +resources/views/components/layouts/auth/split.blade.php ``` +**Change:** Update `` tag in each layout: +```blade + +``` + +#### 2. CSS Configuration +``` +resources/css/app.css +``` + +**Add RTL utilities in `@theme` or `@layer`:** +```css +/* RTL-aware icon flipping */ +[dir="rtl"] .flip-rtl { + transform: scaleX(-1); +} + +/* Force LTR for numbers/code */ +.ltr-content { + direction: ltr; + unicode-bidi: embed; +} +``` + +#### 3. Navigation Component +``` +resources/views/components/layouts/app/sidebar.blade.php +``` + +**Audit and update:** +- Sidebar position (currently uses `border-e` - good) +- Logo placement +- Menu item icons +- Dropdown positions + +#### 4. Form Components (Flux UI overrides if needed) +``` +resources/views/livewire/auth/*.blade.php +resources/views/livewire/settings/*.blade.php +``` + +**Ensure all forms use:** +- `text-start` instead of `text-left` +- `ms-*` / `me-*` instead of `ml-*` / `mr-*` +- `ps-*` / `pe-*` instead of `pl-*` / `pr-*` +- `start-*` / `end-*` instead of `left-*` / `right-*` + +### Tailwind CSS 4 RTL Approach + +Tailwind CSS 4 supports logical properties natively. **Do NOT install a separate RTL plugin.** + +**Logical Property Mapping:** +| Physical | Logical (Use This) | +|----------|-------------------| +| `left-*` | `start-*` | +| `right-*` | `end-*` | +| `ml-*` | `ms-*` | +| `mr-*` | `me-*` | +| `pl-*` | `ps-*` | +| `pr-*` | `pe-*` | +| `text-left` | `text-start` | +| `text-right` | `text-end` | +| `border-l-*` | `border-s-*` | +| `border-r-*` | `border-e-*` | +| `rounded-l-*` | `rounded-s-*` | +| `rounded-r-*` | `rounded-e-*` | + +**For directional icons that must flip:** ```blade - app()->getLocale() === 'ar']) + name="chevron-right" + class="{{ app()->getLocale() === 'ar' ? 'flip-rtl' : '' }}" /> +``` - -
- -
+**Better: Use bidirectional-aware icons when available:** +- Use `chevron-end` concept or flip via CSS - -
- +### Edge Cases to Handle + +#### Numbers in RTL +Numbers should remain LTR even in Arabic context: +```blade +{{ $consultation->id }} +``` + +#### Mixed Content (Arabic with English) +Wrap English phrases in LTR spans when embedded in Arabic: +```blade +

{{ __('Contact us at') }} info@libra.ps

+``` + +#### Form Validation Errors +Ensure error messages appear on the correct side: +```blade + + + {{ __('Email') }} + + + +``` + +#### Toast Notifications +Verify toast position respects direction: +- LTR: Appear from right +- RTL: Appear from left (or respect `start`/`end`) + +#### Tables with Horizontal Scroll +```blade +
+ + +
``` -### Testing Checklist -- [ ] Navigation layout -- [ ] Form layouts -- [ ] Card layouts -- [ ] Table layouts -- [ ] Modal layouts -- [ ] Dropdown menus -- [ ] Pagination +## Testing Checklist + +### Manual Visual Testing (Required) +Test each in **both Arabic and English**: + +- [ ] **Navigation layout** + - Sidebar appears on correct side + - Logo position correct + - Menu items align properly + - Dropdown menus open correct direction + +- [ ] **Form layouts** + - Labels align correctly + - Input text direction correct + - Error messages position correctly + - Submit buttons align properly + +- [ ] **Card layouts** + - Content aligns correctly + - Border highlights on correct side + - Action buttons position correctly + +- [ ] **Table layouts** + - Headers align correctly + - Cell content respects direction + - Horizontal scroll works + +- [ ] **Modal layouts** + - Close button position correct + - Content alignment correct + - Action buttons order correct (Cancel/Confirm) + +- [ ] **Dropdown menus** + - Open in correct direction + - Items align correctly + +- [ ] **Pagination** + - Previous/Next arrows correct + - Page numbers display correctly + +### Automated Testing (Recommended) +Create Pest browser tests for critical RTL scenarios: + +```php +// tests/Browser/RtlLayoutTest.php +it('displays RTL layout for Arabic locale', function () { + // Set locale to Arabic + // Visit dashboard + // Assert dir="rtl" on html element + // Assert sidebar is on right side +}); +``` + +### Browser Testing +Test in: +- [ ] Chrome (Windows/Mac) +- [ ] Firefox +- [ ] Safari +- [ ] Mobile Safari (iOS) +- [ ] Chrome Mobile (Android) ## Definition of Done -- [ ] RTL renders correctly -- [ ] LTR renders correctly -- [ ] Language switch seamless -- [ ] Icons flip correctly -- [ ] All components tested -- [ ] No layout breaks +- [ ] `dir` attribute dynamically set based on locale +- [ ] RTL renders correctly in Arabic +- [ ] LTR renders correctly in English +- [ ] Language switch is seamless (no layout flash) +- [ ] Icons flip correctly where appropriate +- [ ] All components from Testing Checklist verified +- [ ] No layout breaks on language switch +- [ ] Numbers and emails display correctly (LTR in RTL context) +- [ ] Code formatted with Pint - [ ] Tests pass +## Dev Notes + +### Flux UI RTL Support +Flux UI components generally support RTL well when `dir="rtl"` is set on ``. However, audit each component for: +- Icon positions +- Dropdown directions +- Border placements + +### Avoid These Patterns +```blade + +
+ + +
+``` + +### Resources +- Tailwind CSS Logical Properties: Check `search-docs` for latest Tailwind 4 docs +- Flux UI RTL: Test each component, file issues if needed + ## Estimation **Complexity:** High | **Effort:** 5-6 hours diff --git a/docs/stories/story-9.9-responsive-design-implementation.md b/docs/stories/story-9.9-responsive-design-implementation.md index 8759ba1..b56f37b 100644 --- a/docs/stories/story-9.9-responsive-design-implementation.md +++ b/docs/stories/story-9.9-responsive-design-implementation.md @@ -3,52 +3,138 @@ ## Epic Reference **Epic 9:** Design & Branding Implementation +## Dependencies +- **Story 9.1:** Color System Implementation (colors must be defined) +- **Story 9.2:** Typography System (fonts and hierarchy must be in place) +- **Story 9.4-9.6:** Component Styling (buttons, forms, cards must be styled) +- **Story 9.7:** Navigation & Footer Styling (navigation responsive behavior) +- **Story 9.8:** RTL/LTR Layout Perfection (responsive must work in both directions) + +## References +- **PRD Section 7.4:** Responsive Breakpoints (`docs/prd.md#74-responsive-breakpoints`) +- **PRD Section 5.1:** Landing page responsive requirements +- **PRD Section 5.7-5.8:** Dashboard responsive requirements (admin/client) +- **Epic 9:** Full acceptance criteria (`docs/epics/epic-9-design-branding.md`) + ## User Story As a **user**, I want **the platform to work perfectly on all device sizes**, So that **I can use it on my phone, tablet, or desktop**. +## Scope + +### Pages/Components Requiring Responsive Work +1. **Public Pages:** + - Landing page (hero, about sections, booking form) + - Posts/blog listing and detail pages + - Login page + - Terms of Service / Privacy Policy pages + +2. **Client Dashboard:** + - Overview/stats cards + - Consultations list and detail views + - Case timelines view + - Booking form with calendar + - Profile view + +3. **Admin Dashboard:** + - Statistics cards and charts + - User management tables + - Booking management views + - Timeline management + - Posts management + - Working hours configuration + - Settings pages + +4. **Shared Components:** + - Navigation bar (already handled in 9.7, verify integration) + - Footer + - Modal dialogs + - Form components + - Tables + - Cards + ## Acceptance Criteria -### Breakpoints -- [ ] Mobile: < 576px -- [ ] Tablet: 576px - 991px -- [ ] Desktop: 992px - 1199px -- [ ] Large Desktop: >= 1200px +### Breakpoints (per PRD Section 7.4) +- [ ] Mobile: < 576px (single column, stacked layouts) +- [ ] Tablet: 576px - 991px (two columns where appropriate) +- [ ] Desktop: 992px - 1199px (full layouts with sidebars) +- [ ] Large Desktop: >= 1200px (max-width container: 1200px) -### Mobile Optimizations -- [ ] Touch-friendly targets (44px+) -- [ ] Readable font sizes -- [ ] Single column layouts -- [ ] Collapsible sections +### Mobile Optimizations (< 576px) +- [ ] Touch-friendly targets minimum 44px height/width for all interactive elements +- [ ] Font sizes remain readable (minimum 16px for body text to prevent iOS zoom) +- [ ] Single column layouts for all content sections +- [ ] Collapsible/accordion sections for long content +- [ ] Navigation collapses to hamburger menu +- [ ] Forms stack labels above inputs +- [ ] Cards display full-width -### Tablet Optimizations -- [ ] Two-column where appropriate -- [ ] Sidebar collapsible +### Tablet Optimizations (576px - 991px) +- [ ] Two-column grid layouts where appropriate (dashboard stats, post listings) +- [ ] Sidebar collapsible via toggle (not permanently visible) +- [ ] Tables may show reduced columns or scroll horizontally +- [ ] Calendar shows week view or scrollable month -### Desktop Optimizations -- [ ] Full layouts with sidebars -- [ ] Multi-column grids +### Desktop Optimizations (992px+) +- [ ] Full layouts with persistent sidebars +- [ ] Multi-column grids (3-4 columns for dashboard stats) +- [ ] Tables show all columns +- [ ] Calendar shows full month view +- [ ] Max container width: 1200px centered -### Specific Features -- [ ] All forms usable on mobile -- [ ] Calendar usable on mobile -- [ ] Tables scroll horizontally -- [ ] No horizontal scroll on any viewport +### Specific Feature Requirements +- [ ] **Forms:** All forms (booking, login, user management) fully usable on mobile with proper input sizing +- [ ] **Calendar:** Booking calendar functional on mobile (touch-friendly date selection, scrollable) +- [ ] **Tables:** All data tables have horizontal scroll wrapper, pinned first column if needed +- [ ] **No horizontal scroll:** Page-level horizontal scroll must never occur on any viewport +- [ ] **Modals:** Modal dialogs responsive (full-screen on mobile, centered on desktop) +- [ ] **Charts:** Dashboard charts resize appropriately or stack on mobile + +### RTL Considerations +- [ ] All responsive layouts tested in both LTR (English) and RTL (Arabic) +- [ ] Sidebar collapses from correct side (start-0 not left-0) +- [ ] Horizontal scroll direction correct for RTL ## Technical Notes +### Technology Stack +- **Tailwind CSS 4:** Using CSS-first configuration with `@theme` directive +- **Flux UI Free:** Leverage built-in responsive behavior for available components +- **Alpine.js:** For mobile menu toggles and collapsible sections (included with Livewire) + +### Key Files to Modify + +``` +resources/css/app.css # Responsive utility classes +resources/views/components/layouts/ # Layout templates + - app.blade.php # Main layout wrapper + - guest.blade.php # Public pages layout +resources/views/livewire/ + - Various dashboard components # Component-specific responsive styles +resources/views/components/ + - card.blade.php # Card responsive variants + - table.blade.php # Table wrapper component +``` + +### Tailwind 4 Responsive Approach + +Use mobile-first with Tailwind's responsive prefixes: + ```css -/* Mobile-first approach */ +/* In resources/css/app.css - add to @theme if needed */ + +/* Mobile-first grid example */ .dashboard-grid { @apply grid gap-4; - @apply grid-cols-1; /* Mobile */ - @apply sm:grid-cols-2; /* Tablet */ - @apply lg:grid-cols-3; /* Desktop */ - @apply xl:grid-cols-4; /* Large */ + @apply grid-cols-1; /* Mobile: single column */ + @apply sm:grid-cols-2; /* Tablet: 2 columns */ + @apply lg:grid-cols-3; /* Desktop: 3 columns */ + @apply xl:grid-cols-4; /* Large: 4 columns */ } -/* Touch targets */ +/* Touch-friendly targets */ .touch-target { @apply min-h-[44px] min-w-[44px]; } @@ -56,36 +142,130 @@ So that **I can use it on my phone, tablet, or desktop**. /* Responsive table wrapper */ .table-responsive { @apply overflow-x-auto -mx-4 px-4; + @apply sm:mx-0 sm:px-0; /* Remove negative margin on larger screens */ } -/* Collapsible sidebar */ +/* Collapsible sidebar - uses logical properties for RTL */ @media (max-width: 991px) { .sidebar { - @apply fixed inset-y-0 start-0 w-64 transform -translate-x-full transition-transform z-40; + @apply fixed inset-y-0 start-0 w-64; + @apply transform -translate-x-full transition-transform duration-200; + @apply z-40 bg-navy-900; } .sidebar.open { @apply translate-x-0; } + /* RTL: sidebar comes from right */ + [dir="rtl"] .sidebar { + @apply end-0 start-auto translate-x-full; + } + [dir="rtl"] .sidebar.open { + @apply translate-x-0; + } } ``` -### Testing Devices -- iPhone SE (375px) -- iPhone 14 (390px) -- iPad (768px) -- iPad Pro (1024px) -- Desktop (1280px) -- Large Desktop (1920px) +### Flux UI Responsive Behavior +- Flux UI components have built-in responsive behavior +- `` automatically handles responsive sizing +- `` positions correctly on mobile +- Override with Tailwind classes when Flux defaults insufficient + +### Preventing Horizontal Scroll +```css +/* Add to base styles */ +html, body { + @apply overflow-x-hidden; +} + +/* Ensure images/media don't overflow */ +img, video, iframe { + @apply max-w-full h-auto; +} +``` + +## Testing Strategy + +### Testing Approach +1. **Browser DevTools:** Primary method for rapid iteration +2. **Real Devices:** Final verification on actual phones/tablets +3. **Both Languages:** Test each breakpoint in English (LTR) AND Arabic (RTL) + +### Test Devices/Viewports +| Device | Width | Type | +|--------|-------|------| +| iPhone SE | 375px | Mobile | +| iPhone 14 | 390px | Mobile | +| iPhone 14 Pro Max | 430px | Mobile (large) | +| iPad | 768px | Tablet | +| iPad Pro | 1024px | Tablet (large) | +| Desktop | 1280px | Desktop | +| Large Desktop | 1920px | Large Desktop | + +### Key Test Scenarios + +**Mobile (375px - English & Arabic):** +- [ ] Navigate from landing page to login +- [ ] Complete full booking flow (select date, fill form, submit) +- [ ] View consultation list and detail +- [ ] View case timeline +- [ ] Open and close mobile navigation menu +- [ ] Submit a form with validation errors +- [ ] Scroll through long table (user list) + +**Tablet (768px - English & Arabic):** +- [ ] Toggle sidebar open/closed +- [ ] View dashboard with 2-column stat cards +- [ ] Use calendar in booking flow +- [ ] Manage users in table view + +**Desktop (1280px - English & Arabic):** +- [ ] Verify sidebar is persistent +- [ ] Dashboard shows 3-4 column grids +- [ ] Full table columns visible +- [ ] Calendar shows month view + +### Automated Testing (Optional) +Consider Pest browser tests for critical flows: +```php +it('booking form works on mobile', function () { + $this->browse(function ($browser) { + $browser->resize(375, 667) + ->visit('/booking') + ->assertVisible('.booking-form') + ->type('summary', 'Test consultation') + ->press('Submit') + ->assertSee('Request submitted'); + }); +}); +``` ## Definition of Done -- [ ] Mobile layout works -- [ ] Tablet layout works -- [ ] Desktop layout works -- [ ] No horizontal scroll -- [ ] Touch targets 44px+ -- [ ] Forms usable on mobile -- [ ] Calendar usable on mobile -- [ ] Tests pass +- [ ] All pages render correctly at mobile breakpoint (375px) in both LTR and RTL +- [ ] All pages render correctly at tablet breakpoint (768px) in both LTR and RTL +- [ ] All pages render correctly at desktop breakpoint (1280px) in both LTR and RTL +- [ ] No horizontal page scroll at any viewport width from 320px to 1920px +- [ ] All interactive elements meet 44px minimum touch target +- [ ] Booking form with calendar fully functional on mobile +- [ ] All data tables horizontally scrollable without breaking layout +- [ ] Mobile navigation menu opens/closes smoothly +- [ ] Sidebar collapses correctly on tablet (from correct side for RTL) +- [ ] Modal dialogs display correctly on all breakpoints +- [ ] Code formatted with `vendor/bin/pint --dirty` +- [ ] Manual testing completed on at least one real mobile device + +## Out of Scope +- Native mobile app development +- Print stylesheets +- Email template responsiveness (covered in separate story) +- Performance optimization (separate concern) ## Estimation **Complexity:** High | **Effort:** 5-6 hours + +## Notes for Developer +- Start with mobile layouts, then progressively enhance for larger screens +- Use Tailwind's responsive prefixes (`sm:`, `md:`, `lg:`, `xl:`) consistently +- Prefer logical properties (`start-`, `end-`, `ms-`, `me-`) over directional (`left-`, `right-`, `ml-`, `mr-`) for RTL compatibility +- Test frequently in browser DevTools during development +- If a component from Flux UI doesn't behave responsively as expected, check Flux docs first before overriding