libra/docs/stories/story-9.6-component-styling...

4.1 KiB

Story 9.6: Component Styling - Cards & Containers

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, So that content is well-organized and visually appealing.

Acceptance Criteria

Card Styling

  • Background: Off-white/cream
  • Box-shadow: 0 2px 8px rgba(0,0,0,0.1)
  • Border-radius: 8px
  • Padding: 24px

Gold Border Highlight

  • Optional gold top/left border
  • For featured/important cards

Hover States

  • Subtle lift effect
  • Shadow increase

Dashboard Stat Cards

  • Icon with gold accent
  • Large number display
  • Trend indicator

List Cards

  • Consistent item spacing
  • Clear click targets

Containers

  • Max-width: 1200px, centered

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

<!-- resources/views/components/card.blade.php -->
@props([
    'variant' => 'default',
    'hover' => false,
    'highlight' => false
])

<div {{ $attributes->merge([
    'class' => collect([
        'bg-cream rounded-lg p-6',
        'shadow-sm' => $variant === 'default',
        'shadow-md' => $variant === 'elevated',
        'hover:shadow-md hover:-translate-y-0.5 transition-all cursor-pointer' => $hover,
        'border-s-4 border-gold' => $highlight,
    ])->filter()->implode(' ')
]) }}>
    {{ $slot }}
</div>

<!-- Stat card component -->
@props(['icon', 'value', 'label', 'trend' => null])

<x-card>
    <div class="flex items-center gap-4">
        <div class="p-3 bg-gold/10 rounded-lg">
            <flux:icon :name="$icon" class="w-6 h-6 text-gold" />
        </div>
        <div>
            <div class="text-2xl font-bold text-navy">{{ $value }}</div>
            <div class="text-sm text-charcoal/70">{{ $label }}</div>
            @if($trend)
                <div class="text-xs {{ $trend > 0 ? 'text-success' : 'text-danger' }}">
                    {{ $trend > 0 ? '+' : '' }}{{ $trend }}%
                </div>
            @endif
        </div>
    </div>
</x-card>

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
  • Hover effects work
  • Stat cards work
  • Highlight variant works
  • Container max-width applied
  • Tests pass

Estimation

Complexity: Medium | Effort: 3 hours