strat-gameplay-webapp/docs/runner-display-alternatives.md
Cal Corum 5d20d84568 CLAUDE: Add RunnersOnBase component with expanding cards and runner/catcher matchup
- Created RunnersOnBase.vue component with split layout (runners left, catcher right)
- Created RunnerCard.vue for individual runner cards with expand-in-place functionality
- Integrated component into GamePlay.vue (mobile and desktop layouts)
- Added team color computed properties for batting/fielding teams
- Component only shows when runners on base (hasRunners computed)
- Click runner card to expand in place and show full player card + catcher matchup
- Smooth CSS transitions and animations matching pitcher/batter card style
- Includes design documentation and HTML mockup for reference
2026-02-06 19:13:52 -06:00

205 lines
8.0 KiB
Markdown

# Runner Display Alternatives - Design Proposals
## Current Implementation Issues
- Baseball diamond is visually cluttered
- Runners are represented by small numbered circles that are hard to see
- Player information is not immediately accessible
- Takes up significant vertical space
- Doesn't provide quick access to runner card details
- UX is confusing - users want to quickly glance at cards for each runner
## Design Goals
- **Glanceable**: See runner status instantly without searching
- **Compact**: Use less vertical space (mobile-first)
- **Card Access**: Quick access to view runner player cards
- **Clear State**: Immediately obvious which bases are occupied
- **Professional**: Modern, polished appearance
---
## Option 1: Horizontal Runner Card Bar
### Visual Description
A sleek horizontal bar showing 3 slots (1st, 2nd, 3rd) with mini player cards that expand on tap/click.
```
┌────────────────────────────────────────────────────────┐
│ RUNNERS ON BASE │
│ ┌──────┐ ┌──────┐ ┌──────┐ │
│ │ 1B │ │ 2B │ │ 3B │ │
│ │ ──── │ │[IMG] │ │ ──── │ │
│ │ │ │ J.D. │ │ │ │
│ │ Empty│ │ │ │ Empty│ │
│ └──────┘ └──────┘ └──────┘ │
└────────────────────────────────────────────────────────┘
```
### Features
- **Empty State**: Gray/muted card with dashed border and "Empty" text
- **Occupied State**: Player headshot, name, and team color border
- **Tap to Expand**: Shows full player card modal
- **Visual Hierarchy**: Occupied bases use team colors and are visually prominent
- **Badge Indicator**: Small circular badge with base number (1/2/3) on top-right
### Pros
- ✅ Very compact (single row)
- ✅ Clear visual distinction between empty/occupied
- ✅ Easy touch targets for mobile
- ✅ Horizontally balanced layout
- ✅ Player images make it personal/engaging
### Cons
- ❌ May be cramped on very small screens
- ❌ Requires good player headshots for best effect
### CSS Approach
- Grid layout with 3 equal columns
- Card-style mini containers
- Smooth hover/tap states with scale transform
- Team color accent on occupied cards
---
## Option 2: Compact Diamond Indicator Strip
### Visual Description
Minimalist strip showing bases as dots/indicators with runner names inline.
```
┌────────────────────────────────────────────────────────┐
│ ○ 1B Empty ● 2B J. Doe (#24) ○ 3B Empty │
│ Tap any runner to view card │
└────────────────────────────────────────────────────────┘
```
### Features
- **Dot Indicators**: Hollow circle = empty, filled circle = occupied
- **Inline Text**: Base label + player name (abbreviated) + jersey number
- **Color Coding**: Dot and text use team color when occupied
- **Single Line**: Extremely compact
- **Hover State**: Underline runner names, show "tap to view card" tooltip
### Pros
- ✅ Absolute minimal space usage
- ✅ Text-based, works without images
- ✅ Extremely fast to scan
- ✅ Works well in both light/dark mode
### Cons
- ❌ Less visually engaging
- ❌ No player images visible
- ❌ May feel too minimal/plain
- ❌ Harder to tap on mobile (smaller targets)
### CSS Approach
- Flexbox with space-between
- Dot using ::before pseudo-element
- Text truncation for long names
- Underline decoration on hover/active
---
## Option 3: Stacked Runner Cards (Recommended)
### Visual Description
Card-based interface showing only occupied bases as expandable cards in a horizontal stack. Empty bases are represented by small placeholder chips.
```
┌────────────────────────────────────────────────────────┐
│ RUNNERS ON BASE │
│ │
│ 1B: ─ 2B: [Card] 3B: ─ │
│ ┌──────────┐ │
│ │ [IMG] │ │
│ │ J. Doe │ │
│ │ #24 2B │ │
│ │ [View] │ │
│ └──────────┘ │
└────────────────────────────────────────────────────────┘
```
### Features
- **Empty Bases**: Small chip/badge showing "1B: —" (muted, minimal)
- **Occupied Bases**: Full mini card with:
- Player headshot (circular)
- Player name (bold)
- Jersey number + position
- Team color accent/border
- "View Card" button
- **Responsive**: Cards stack vertically on narrow screens
- **Visual Priority**: Occupied bases are much larger and more prominent
- **Quick Actions**: Button directly on card for instant access
### Pros
- ✅ Best balance of compact + informative
- ✅ Only shows detail where needed (occupied bases)
- ✅ Clear call-to-action with "View Card" button
- ✅ Player images add personality
- ✅ Responsive layout adapts well to mobile
- ✅ Professional, modern card-based UI pattern
### Cons
- ❌ Slightly more vertical space when bases loaded
- ❌ Requires player headshots for best experience
### CSS Approach
- Flexbox/Grid hybrid (flex-wrap for responsive)
- Empty bases: inline-flex badge (h-8, minimal)
- Occupied bases: w-32 card with padding
- Shadow and border-radius for card depth
- Team color as left border accent (4px)
### Implementation Details
```vue
<div class="runners-container">
<!-- Empty Base -->
<div class="runner-empty">
<span class="base-label">1B:</span>
<span class="empty-indicator"></span>
</div>
<!-- Occupied Base -->
<div class="runner-card" :style="{ borderColor: teamColor }">
<img :src="player.headshot" class="runner-avatar" />
<div class="runner-info">
<p class="runner-name">{{ player.name }}</p>
<p class="runner-meta">#{{ player.jersey }} 2B</p>
</div>
<button @click="viewCard(player)" class="btn-view-card">
View Card
</button>
</div>
</div>
```
---
## Recommendation: Option 3 (Stacked Runner Cards)
### Why This Is Best
1. **Optimizes for the common case**: Most at-bats have 0-1 runners, so minimizing empty state is key
2. **Mobile-first**: Large tap targets, clear hierarchy, easy to use one-handed
3. **Information density**: Shows exactly what's needed without clutter
4. **Modern UX**: Card-based pattern is familiar and professional
5. **Scalable**: Works equally well with 1, 2, or 3 runners on base
### Responsive Behavior
- **Mobile (< 640px)**: Stack cards vertically, full width
- **Tablet (640-1024px)**: Horizontal row, cards side-by-side
- **Desktop (> 1024px)**: Same as tablet, more breathing room
### Accessibility
- Semantic HTML with proper ARIA labels
- Keyboard navigation support
- High contrast for empty vs occupied states
- Screen reader announces "Runner on second base: J. Doe, number 24"
---
## Next Steps
1. Choose preferred option (or hybrid approach)
2. Create Vue component implementation
3. Test on mobile devices
4. Gather user feedback
5. Iterate based on real gameplay usage