diff --git a/docs/COMPACT_CARDS.md b/docs/COMPACT_CARDS.md new file mode 100644 index 0000000..743cfb3 --- /dev/null +++ b/docs/COMPACT_CARDS.md @@ -0,0 +1,324 @@ +# Compact Info Card Design + +## Problem Statement + +The original design used large square photo grids that consumed excessive screen space, making it difficult to scan through multiple dogs quickly. Photos were displayed at 1:1 aspect ratio taking up 50-100% of card width. + +## Solution: Horizontal Info Cards + +Transformed to a **compact horizontal card layout** with small avatar photos and prominent metadata, optimized for information scanning and list navigation. + +--- + +## Design Specifications + +### Layout Structure +``` +┌─────────────────────────────────────────────────────────────────┐ +│ [Avatar] Name ♂ Breed • Age • Color → │ +│ 80x80 Golden Retriever #REG-12345 │ +└─────────────────────────────────────────────────────────────────┘ +``` + +### Card Components + +#### 1. Avatar Photo (80x80px) +- **Size:** Fixed 80px × 80px +- **Shape:** Rounded corners (var(--radius)) +- **Border:** 2px solid var(--border) +- **Background:** var(--bg-primary) when no photo +- **Fallback:** Dog icon at 32px, muted color +- **Object Fit:** cover (crops to fill square) + +#### 2. Info Section (Flex: 1) +- **Name:** 1.125rem, bold, truncate with ellipsis +- **Sex Icon:** Colored ♂/♀ (blue for male, pink for female) +- **Metadata Row:** + - Breed name + - Age (calculated, with calendar icon) + - Color (if available) + - Separated by bullets (•) +- **Registration Badge:** + - Monospace font + - Hash icon prefix + - Dark background pill + - 1px border + +#### 3. Arrow Indicator +- **Icon:** ArrowRight at 20px +- **Color:** var(--text-muted) +- **Opacity:** 0.5 default, increases on hover +- **Purpose:** Visual affordance for clickability + +--- + +## Space Comparison + +### Before (Square Grid) +``` +[===============] +[ Photo ] +[ 300x300 ] +[===============] +Name +Breed • Sex +``` +**Height:** ~380px per card +**Width:** 280-300px +**Photos per viewport:** 2-3 (desktop) + +### After (Horizontal Card) +``` +[Avatar] Name, Breed, Age, Badge → + 80x80 +``` +**Height:** ~100px per card +**Width:** Full container width +**Cards per viewport:** 6-8 (desktop) + +### Metrics +| Metric | Before | After | Improvement | +|--------|--------|-------|-------------| +| Card height | 380px | 100px | **-74%** | +| Photo area | 90,000px² | 6,400px² | **-93%** | +| Scannable info | 2-3 cards | 6-8 cards | **+200%** | +| Scroll distance | 760px | 200px | **-74%** | + +--- + +## Implementation Details + +### React Component Structure +```jsx + + {/* Avatar */} +
+ {photo ? : } +
+ + {/* Info */} +
+

{name} {sex icon}

+
+ {breed} • {age} • {color} +
+
+ {registration} +
+
+ + {/* Arrow */} + + +``` + +### CSS Styling +```css +.card { + display: flex; + gap: 1rem; + align-items: center; + padding: 1rem; + transition: all 0.2s; +} + +.card:hover { + border-color: var(--primary); + transform: translateY(-2px); + box-shadow: 0 8px 16px rgba(0,0,0,0.3); +} + +.avatar-80 { + width: 80px; + height: 80px; + border-radius: var(--radius); + border: 2px solid var(--border); + overflow: hidden; +} + +.info-section { + flex: 1; + min-width: 0; /* Allow text truncation */ +} +``` + +--- + +## Age Calculation + +Dynamic age display from birth date: + +```javascript +const calculateAge = (birthDate) => { + const today = new Date() + const birth = new Date(birthDate) + let years = today.getFullYear() - birth.getFullYear() + let months = today.getMonth() - birth.getMonth() + + if (months < 0) { + years-- + months += 12 + } + + // Format: "2y 3mo" or "8mo" or "3y" + if (years === 0) return `${months}mo` + if (months === 0) return `${years}y` + return `${years}y ${months}mo` +} +``` + +--- + +## Interactive States + +### Default +- Border: var(--border) +- Shadow: var(--shadow-sm) +- Transform: none + +### Hover +- Border: var(--primary) +- Shadow: 0 8px 16px rgba(0,0,0,0.3) +- Transform: translateY(-2px) +- Arrow opacity: 1.0 +- Transition: 0.2s cubic-bezier + +### Active/Click +- Navigate to detail page +- Maintains selection state in history + +--- + +## Responsive Behavior + +### Desktop (>768px) +- Full horizontal layout +- All metadata visible +- Hover effects enabled + +### Tablet (768px - 1024px) +- Slightly smaller avatar (70px) +- Abbreviated metadata +- Touch-friendly spacing + +### Mobile (<768px) +- Avatar: 60px +- Name on top line +- Metadata stacks below +- Registration badge wraps +- Larger tap targets + +--- + +## Accessibility + +### Keyboard Navigation +- Cards are focusable links +- Tab order follows visual order +- Enter/Space to activate +- Focus ring with primary color + +### Screen Readers +- Semantic HTML (Link + heading structure) +- Alt text on avatar images +- Icon meanings in aria-labels +- Registration formatted as code + +### Color Contrast +- Name: High contrast (var(--text-primary)) +- Metadata: Medium contrast (var(--text-secondary)) +- Icons: Sufficient contrast ratios +- Sex icons: Color + symbol (not color-only) + +--- + +## Benefits + +### User Experience +1. **Faster Scanning** - See 3x more dogs without scrolling +2. **Quick Comparison** - All key info visible at once +3. **Less Cognitive Load** - Consistent layout, predictable +4. **Better Navigation** - Clear visual hierarchy + +### Performance +1. **Smaller Images** - Avatar size reduces bandwidth +2. **Lazy Loading** - Efficient with IntersectionObserver +3. **Less Rendering** - Simpler DOM structure +4. **Faster Scrolling** - Fewer pixels to paint + +### Mobile +1. **Touch Targets** - Full card width clickable +2. **Vertical Real Estate** - More content on screen +3. **Thumb-Friendly** - No precise tapping required +4. **Data Efficient** - Smaller photo downloads + +--- + +## Usage Context + +### Dashboard +- Shows 6-8 recent dogs +- "View All" button to Dogs page +- Provides quick overview + +### Dogs List +- Full searchable/filterable catalog +- Horizontal scroll on mobile +- Infinite scroll potential +- Batch operations possible + +### NOT Used For +- Dog detail page (uses full photo gallery) +- Pedigree tree (uses compact nodes) +- Print layouts (uses different format) + +--- + +## Future Enhancements + +### Planned +- [ ] Checkbox selection mode (bulk actions) +- [ ] Drag-to-reorder in custom lists +- [ ] Quick actions menu (edit, delete) +- [ ] Photo upload from card +- [ ] Inline editing of name/breed + +### Considered +- Multi-select with Shift+Click +- Card density options (compact/comfortable/spacious) +- Alternative views (grid toggle) +- Column sorting (name, age, breed) +- Grouping (by breed, age range) + +--- + +## Examples + +### Example 1: Male with Photo +``` +┌───────────────────────────────────────────────────────────┐ +│ [Photo] Max ♂ → │ +│ Golden Retriever • 2y 3mo • Golden │ +│ #AKC-SR123456 │ +└───────────────────────────────────────────────────────────┘ +``` + +### Example 2: Female No Photo +``` +┌───────────────────────────────────────────────────────────┐ +│ [🐶] Bella ♀ → │ +│ icon Labrador Retriever • 8mo • Black │ +└───────────────────────────────────────────────────────────┘ +``` + +### Example 3: Puppy No Registration +``` +┌───────────────────────────────────────────────────────────┐ +│ [Photo] Rocky ♂ → │ +│ German Shepherd • 3mo │ +└───────────────────────────────────────────────────────────┘ +``` + +--- + +*Last Updated: March 8, 2026* \ No newline at end of file