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

8.0 KiB

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

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

<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