5.7 KiB
5.7 KiB
Story 9.3: Logo Integration
Epic Reference
Epic 9: Design & Branding Implementation
User Story
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 (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 width (desktop), 80px width (mobile)
- Clear space: 20px padding minimum around logo
Format Support
- SVG primary (scalable, preferred)
- PNG fallback (for email clients that don't support SVG)
Color Variations
- 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 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 implementationresources/views/components/app-logo-icon.blade.php- Update or removeresources/views/components/layouts/app/header.blade.php- Update logo usage (lines 11, 96)
Files to create:
public/images/logo.svg- Full color logopublic/images/logo-reversed.svg- Reversed color logopublic/images/logo-mono.svg- Monochrome logopublic/images/logo.png- PNG fallback
Logo Component Implementation
<!-- resources/views/components/app-logo.blade.php -->
@props([
'size' => 'default',
'variant' => 'full',
'showText' => true
])
@php
$sizes = [
'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 = [
'full' => 'logo.svg',
'reversed' => 'logo-reversed.svg',
'mono' => 'logo-mono.svg',
];
$sizeClass = $sizes[$size] ?? $sizes['default'];
$logoFile = $variants[$variant] ?? $variants['full'];
@endphp
<div {{ $attributes->merge(['class' => 'flex items-center gap-2 p-5']) }}>
<img
src="{{ asset('images/' . $logoFile) }}"
alt="{{ __('Libra Law Firm') }}"
class="{{ $sizeClass }} w-auto object-contain"
onerror="this.onerror=null; this.src='{{ asset('images/logo.png') }}';"
/>
@if($showText)
<span class="font-semibold text-sm truncate">{{ __('Libra Law Firm') }}</span>
@endif
</div>
Logo Asset Fallback Strategy
If final logo assets are not yet available:
- Create a placeholder SVG using Libra scales icon from Heroicons or similar
- Use the brand colors (Gold #D4AF37, Navy #0A1F44)
- 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
use function Pest\Laravel\get;
test('logo component renders with default props', function () {
$view = $this->blade('<x-app-logo />');
$view->assertSee('Libra Law Firm');
$view->assertSee('logo.svg');
});
test('logo component renders small size variant', function () {
$view = $this->blade('<x-app-logo size="small" />');
$view->assertSee('h-8');
});
test('logo component renders reversed color variant', function () {
$view = $this->blade('<x-app-logo variant="reversed" />');
$view->assertSee('logo-reversed.svg');
});
test('logo component renders without text when showText is false', function () {
$view = $this->blade('<x-app-logo :showText="false" />');
$view->assertDontSee('<span');
});
test('logo has accessible alt text', function () {
$view = $this->blade('<x-app-logo />');
$view->assertSee('alt="Libra Law Firm"', false);
});
Browser Tests (Pest v4)
Create tests/Browser/LogoTest.php:
<?php
it('displays logo in navigation on desktop', function () {
$page = visit('/');
$page->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 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-3 hours