strat-gameplay-webapp/mockups/defensive-setup-compact.html
Cal Corum 2d4dbe82eb CLAUDE: Compact defensive setup UI with glowing ring turn indicator
- Rewrite DefensiveSetup as inline segmented controls (~120px vs ~340px)
- Fix bug: read game state from useGameStore() instead of never-passed prop
- Remove turn indicator banner from DecisionPanel (replaced by green glow ring)
- Emoji fix: shield -> baseball glove
- Confirm button matches Roll Dice style (full-width, prominent)
- Infield options only show IF In/Corners when runner on 3rd
- Outfield row only renders in walk-off scenarios
- Hold pills only render for occupied bases
- 20 tests rewritten with Pinia store integration

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-12 14:44:46 -06:00

388 lines
22 KiB
HTML

<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Defensive Setup - Compact Design Mockups</title>
<script src="https://cdn.tailwindcss.com"></script>
<style>
body { background: #111827; }
.mockup-card { max-width: 400px; margin: 0 auto; }
/* Simulate the primary blue gradient for selected buttons */
.btn-selected { background: linear-gradient(to right, #1e40af, #2563eb); }
</style>
</head>
<body class="text-gray-100 p-4">
<div class="max-w-lg mx-auto space-y-12">
<h1 class="text-2xl font-bold text-center text-white mb-2">Defensive Setup — Compact Mockups</h1>
<p class="text-sm text-gray-400 text-center mb-8">Mobile-first (400px max). Dark mode only for brevity.</p>
<!-- ============================================================ -->
<!-- SCENARIO: NO CHOICES (bases empty, normal game state) -->
<!-- ============================================================ -->
<div class="border-t border-gray-700 pt-6">
<h2 class="text-lg font-bold text-yellow-400 mb-1">Scenario: No Choices Available</h2>
<p class="text-xs text-gray-400 mb-4">Bases empty, not a walk-off situation. Both infield and outfield only have "Normal".</p>
<div class="mockup-card space-y-4">
<h3 class="text-sm font-semibold text-gray-500">ALL DESIGNS → Component hidden entirely</h3>
<div class="bg-gray-800 rounded-xl p-4 text-center border border-dashed border-gray-600">
<p class="text-sm text-gray-500 italic">Nothing renders here. The defensive setup component is completely removed from the DOM.</p>
<p class="text-xs text-gray-600 mt-2">The DecisionPanel auto-submits default values (normal/normal/no holds) and skips to offensive phase.</p>
</div>
</div>
</div>
<!-- ============================================================ -->
<!-- SCENARIO: RUNNER ON 3RD ONLY (infield choices) -->
<!-- ============================================================ -->
<div class="border-t border-gray-700 pt-6">
<h2 class="text-lg font-bold text-yellow-400 mb-1">Scenario: Runner on 3rd</h2>
<p class="text-xs text-gray-400 mb-6">Infield depth matters (3 options). Outfield still only "Normal". Hold runners available for R3.</p>
<!-- DESIGN A: Inline Segmented Control -->
<div class="mockup-card mb-8">
<h3 class="text-sm font-semibold text-emerald-400 mb-3">Design A — Inline Segmented Controls</h3>
<div class="bg-gray-800 rounded-xl shadow-lg p-4 space-y-3">
<!-- Header row: icon + title + submit in one line -->
<div class="flex items-center justify-between">
<h3 class="text-base font-bold text-white flex items-center gap-2">
🛡️ Defense
</h3>
<button class="px-4 py-1.5 text-sm font-semibold bg-green-600 hover:bg-green-700 text-white rounded-lg transition-colors">
Confirm
</button>
</div>
<!-- Infield: label + horizontal pill buttons -->
<div class="flex items-center gap-2">
<span class="text-xs font-medium text-gray-400 w-14 flex-shrink-0">Infield</span>
<div class="flex flex-1 rounded-lg overflow-hidden border border-gray-600">
<button class="flex-1 py-2 text-xs font-medium bg-gray-700 text-gray-300 hover:bg-gray-600 border-r border-gray-600">Normal</button>
<button class="flex-1 py-2 text-xs font-medium btn-selected text-white">IF In</button>
<button class="flex-1 py-2 text-xs font-medium bg-gray-700 text-gray-300 hover:bg-gray-600">Corners</button>
</div>
</div>
<!-- Hold runners: inline toggle chips -->
<div class="flex items-center gap-2">
<span class="text-xs font-medium text-gray-400 w-14 flex-shrink-0">Hold</span>
<div class="flex gap-1.5">
<button class="px-3 py-1.5 text-xs font-medium rounded-full border border-gray-600 bg-gray-700 text-gray-400 opacity-40 cursor-not-allowed" disabled>1B</button>
<button class="px-3 py-1.5 text-xs font-medium rounded-full border border-gray-600 bg-gray-700 text-gray-400 opacity-40 cursor-not-allowed" disabled>2B</button>
<button class="px-3 py-1.5 text-xs font-medium rounded-full border border-blue-500 btn-selected text-white">3B</button>
</div>
</div>
</div>
</div>
<!-- DESIGN B: Single-Row Compact -->
<div class="mockup-card mb-8">
<h3 class="text-sm font-semibold text-emerald-400 mb-3">Design B — Ultra Compact (Single Card Row)</h3>
<div class="bg-gray-800 rounded-xl shadow-lg p-3 space-y-2">
<!-- Everything stacked tightly -->
<div class="flex items-center justify-between">
<span class="text-sm font-bold text-white">🛡️ Defense</span>
<button class="px-3 py-1 text-xs font-semibold bg-green-600 text-white rounded-md">Confirm</button>
</div>
<div class="flex gap-2">
<!-- Infield as compact segmented -->
<div class="flex-1">
<div class="text-[10px] font-medium text-gray-500 uppercase tracking-wider mb-1">Infield</div>
<div class="flex rounded-md overflow-hidden border border-gray-600 text-xs">
<button class="flex-1 py-1.5 bg-gray-700 text-gray-400 border-r border-gray-600">Norm</button>
<button class="flex-1 py-1.5 btn-selected text-white border-r border-gray-600">IF In</button>
<button class="flex-1 py-1.5 bg-gray-700 text-gray-400">Corn</button>
</div>
</div>
<!-- Hold as compact chips -->
<div class="flex-shrink-0">
<div class="text-[10px] font-medium text-gray-500 uppercase tracking-wider mb-1">Hold</div>
<div class="flex gap-1">
<button class="w-8 h-8 text-[10px] font-bold rounded-md border border-gray-600 bg-gray-700 text-gray-500 opacity-40" disabled>1B</button>
<button class="w-8 h-8 text-[10px] font-bold rounded-md border border-gray-600 bg-gray-700 text-gray-500 opacity-40" disabled>2B</button>
<button class="w-8 h-8 text-[10px] font-bold rounded-md border border-blue-500 btn-selected text-white">3B</button>
</div>
</div>
</div>
</div>
</div>
<!-- DESIGN C: Toolbar Style -->
<div class="mockup-card">
<h3 class="text-sm font-semibold text-emerald-400 mb-3">Design C — Toolbar Strip</h3>
<div class="bg-gray-800 rounded-xl shadow-lg overflow-hidden">
<!-- Single toolbar bar -->
<div class="flex items-center gap-3 px-3 py-2.5 border-b border-gray-700">
<span class="text-sm font-bold text-white flex-shrink-0">🛡️</span>
<!-- Infield segment -->
<div class="flex items-center gap-1.5">
<span class="text-[10px] text-gray-500 font-medium">IF:</span>
<div class="flex rounded-md overflow-hidden border border-gray-600">
<button class="px-2 py-1 text-[11px] bg-gray-700 text-gray-400 border-r border-gray-600">Norm</button>
<button class="px-2 py-1 text-[11px] btn-selected text-white border-r border-gray-600">In</button>
<button class="px-2 py-1 text-[11px] bg-gray-700 text-gray-400">Corn</button>
</div>
</div>
<!-- Divider -->
<div class="w-px h-5 bg-gray-700"></div>
<!-- Hold toggles -->
<div class="flex items-center gap-1.5">
<span class="text-[10px] text-gray-500 font-medium">Hold:</span>
<button class="w-6 h-6 text-[10px] font-bold rounded border border-blue-500 btn-selected text-white">3</button>
</div>
<!-- Spacer + confirm -->
<div class="flex-1"></div>
<button class="px-3 py-1 text-xs font-semibold bg-green-600 text-white rounded-md"></button>
</div>
</div>
</div>
</div>
<!-- ============================================================ -->
<!-- SCENARIO: FULL OPTIONS (R1+R3, walk-off) -->
<!-- ============================================================ -->
<div class="border-t border-gray-700 pt-6">
<h2 class="text-lg font-bold text-yellow-400 mb-1">Scenario: Full Options (R1 + R3, Walk-off)</h2>
<p class="text-xs text-gray-400 mb-6">All infield options + shallow outfield + hold runners on 1st and 3rd.</p>
<!-- DESIGN A: Inline Segmented Control -->
<div class="mockup-card mb-8">
<h3 class="text-sm font-semibold text-emerald-400 mb-3">Design A — Inline Segmented Controls</h3>
<div class="bg-gray-800 rounded-xl shadow-lg p-4 space-y-3">
<div class="flex items-center justify-between">
<h3 class="text-base font-bold text-white flex items-center gap-2">
🛡️ Defense
</h3>
<button class="px-4 py-1.5 text-sm font-semibold bg-green-600 hover:bg-green-700 text-white rounded-lg transition-colors">
Confirm
</button>
</div>
<!-- Infield -->
<div class="flex items-center gap-2">
<span class="text-xs font-medium text-gray-400 w-14 flex-shrink-0">Infield</span>
<div class="flex flex-1 rounded-lg overflow-hidden border border-gray-600">
<button class="flex-1 py-2 text-xs font-medium btn-selected text-white border-r border-gray-600">Normal</button>
<button class="flex-1 py-2 text-xs font-medium bg-gray-700 text-gray-300 hover:bg-gray-600 border-r border-gray-600">IF In</button>
<button class="flex-1 py-2 text-xs font-medium bg-gray-700 text-gray-300 hover:bg-gray-600">Corners</button>
</div>
</div>
<!-- Outfield -->
<div class="flex items-center gap-2">
<span class="text-xs font-medium text-gray-400 w-14 flex-shrink-0">Outfield</span>
<div class="flex flex-1 rounded-lg overflow-hidden border border-gray-600">
<button class="flex-1 py-2 text-xs font-medium btn-selected text-white border-r border-gray-600">Normal</button>
<button class="flex-1 py-2 text-xs font-medium bg-gray-700 text-gray-300 hover:bg-gray-600">Shallow</button>
</div>
</div>
<!-- Hold runners -->
<div class="flex items-center gap-2">
<span class="text-xs font-medium text-gray-400 w-14 flex-shrink-0">Hold</span>
<div class="flex gap-1.5">
<button class="px-3 py-1.5 text-xs font-medium rounded-full border border-blue-500 btn-selected text-white">1B</button>
<button class="px-3 py-1.5 text-xs font-medium rounded-full border border-gray-600 bg-gray-700 text-gray-400 opacity-40 cursor-not-allowed" disabled>2B</button>
<button class="px-3 py-1.5 text-xs font-medium rounded-full border border-blue-500 btn-selected text-white">3B</button>
</div>
</div>
</div>
</div>
<!-- DESIGN B: Ultra Compact -->
<div class="mockup-card mb-8">
<h3 class="text-sm font-semibold text-emerald-400 mb-3">Design B — Ultra Compact</h3>
<div class="bg-gray-800 rounded-xl shadow-lg p-3 space-y-2">
<div class="flex items-center justify-between">
<span class="text-sm font-bold text-white">🛡️ Defense</span>
<button class="px-3 py-1 text-xs font-semibold bg-green-600 text-white rounded-md">Confirm</button>
</div>
<div class="grid grid-cols-2 gap-2">
<!-- Infield -->
<div>
<div class="text-[10px] font-medium text-gray-500 uppercase tracking-wider mb-1">Infield</div>
<div class="flex rounded-md overflow-hidden border border-gray-600 text-xs">
<button class="flex-1 py-1.5 btn-selected text-white border-r border-gray-600">Norm</button>
<button class="flex-1 py-1.5 bg-gray-700 text-gray-400 border-r border-gray-600">In</button>
<button class="flex-1 py-1.5 bg-gray-700 text-gray-400">Corn</button>
</div>
</div>
<!-- Outfield -->
<div>
<div class="text-[10px] font-medium text-gray-500 uppercase tracking-wider mb-1">Outfield</div>
<div class="flex rounded-md overflow-hidden border border-gray-600 text-xs">
<button class="flex-1 py-1.5 btn-selected text-white border-r border-gray-600">Norm</button>
<button class="flex-1 py-1.5 bg-gray-700 text-gray-400">Shallow</button>
</div>
</div>
</div>
<!-- Hold runners - full width row below -->
<div class="flex items-center gap-2">
<div class="text-[10px] font-medium text-gray-500 uppercase tracking-wider">Hold</div>
<div class="flex gap-1">
<button class="w-8 h-7 text-[10px] font-bold rounded-md border border-blue-500 btn-selected text-white">1B</button>
<button class="w-8 h-7 text-[10px] font-bold rounded-md border border-gray-600 bg-gray-700 text-gray-500 opacity-40" disabled>2B</button>
<button class="w-8 h-7 text-[10px] font-bold rounded-md border border-blue-500 btn-selected text-white">3B</button>
</div>
</div>
</div>
</div>
<!-- DESIGN C: Toolbar Strip -->
<div class="mockup-card">
<h3 class="text-sm font-semibold text-emerald-400 mb-3">Design C — Toolbar Strip</h3>
<div class="bg-gray-800 rounded-xl shadow-lg overflow-hidden">
<!-- Row 1: Infield + Outfield -->
<div class="flex items-center gap-2 px-3 py-2 border-b border-gray-700">
<span class="text-sm font-bold text-white flex-shrink-0">🛡️</span>
<div class="flex items-center gap-1.5">
<span class="text-[10px] text-gray-500 font-medium">IF:</span>
<div class="flex rounded-md overflow-hidden border border-gray-600">
<button class="px-2 py-1 text-[11px] btn-selected text-white border-r border-gray-600">Norm</button>
<button class="px-2 py-1 text-[11px] bg-gray-700 text-gray-400 border-r border-gray-600">In</button>
<button class="px-2 py-1 text-[11px] bg-gray-700 text-gray-400">Corn</button>
</div>
</div>
<div class="w-px h-5 bg-gray-700"></div>
<div class="flex items-center gap-1.5">
<span class="text-[10px] text-gray-500 font-medium">OF:</span>
<div class="flex rounded-md overflow-hidden border border-gray-600">
<button class="px-2 py-1 text-[11px] btn-selected text-white border-r border-gray-600">Norm</button>
<button class="px-2 py-1 text-[11px] bg-gray-700 text-gray-400">Shal</button>
</div>
</div>
<div class="w-px h-5 bg-gray-700"></div>
<div class="flex items-center gap-1.5">
<span class="text-[10px] text-gray-500 font-medium">Hold:</span>
<button class="w-5 h-5 text-[9px] font-bold rounded border border-blue-500 btn-selected text-white">1</button>
<button class="w-5 h-5 text-[9px] font-bold rounded border border-blue-500 btn-selected text-white">3</button>
</div>
<div class="flex-1"></div>
<button class="px-3 py-1 text-xs font-semibold bg-green-600 text-white rounded-md"></button>
</div>
</div>
</div>
</div>
<!-- ============================================================ -->
<!-- SIDE-BY-SIDE SIZE COMPARISON -->
<!-- ============================================================ -->
<div class="border-t border-gray-700 pt-6">
<h2 class="text-lg font-bold text-yellow-400 mb-1">Size Comparison: Current vs Design A</h2>
<p class="text-xs text-gray-400 mb-6">Same scenario (R3 only) showing height saved.</p>
<div class="grid grid-cols-2 gap-4">
<!-- CURRENT -->
<div>
<h3 class="text-xs font-semibold text-red-400 mb-2 text-center">CURRENT (~340px tall)</h3>
<div class="bg-gray-800 rounded-xl shadow-lg p-6">
<div class="flex items-center justify-between mb-6">
<h3 class="text-lg font-bold text-white flex items-center gap-2">
<span class="text-xl">🛡️</span> Defensive Setup
</h3>
</div>
<div class="space-y-6">
<div>
<label class="block text-sm font-semibold text-gray-300 mb-3">Infield Depth</label>
<div class="flex flex-col w-full">
<button class="w-full py-2.5 text-sm btn-selected text-white rounded-t-lg border border-blue-600">• Normal</button>
<button class="w-full py-2.5 text-sm bg-white text-gray-700 border border-gray-300">⬆️ Infield In</button>
<button class="w-full py-2.5 text-sm bg-white text-gray-700 border border-gray-300 rounded-b-lg">◀️▶️ Corners In</button>
</div>
</div>
<div>
<label class="block text-sm font-semibold text-gray-300 mb-3">Outfield Depth</label>
<div class="flex">
<button class="flex-1 py-2.5 text-sm btn-selected text-white rounded-lg border border-blue-600">• Normal</button>
</div>
</div>
<div class="bg-gray-700 rounded-lg p-4">
<h4 class="text-sm font-semibold text-gray-300 mb-2">Current Setup</h4>
<div class="grid grid-cols-2 gap-2 text-xs">
<div><span class="text-gray-400">Infield:</span> <span class="text-white">Normal</span></div>
<div><span class="text-gray-400">Outfield:</span> <span class="text-white">Normal</span></div>
<div class="col-span-2"><span class="text-gray-400">Holding:</span> <span class="text-white">None</span></div>
</div>
</div>
<button class="w-full py-3 text-base font-semibold bg-green-600 text-white rounded-lg">Submit Defensive Setup</button>
</div>
</div>
</div>
<!-- DESIGN A -->
<div>
<h3 class="text-xs font-semibold text-emerald-400 mb-2 text-center">DESIGN A (~120px tall)</h3>
<div class="bg-gray-800 rounded-xl shadow-lg p-4 space-y-3">
<div class="flex items-center justify-between">
<h3 class="text-base font-bold text-white flex items-center gap-2">🛡️ Defense</h3>
<button class="px-4 py-1.5 text-sm font-semibold bg-green-600 text-white rounded-lg">Confirm</button>
</div>
<div class="flex items-center gap-2">
<span class="text-xs font-medium text-gray-400 w-14 flex-shrink-0">Infield</span>
<div class="flex flex-1 rounded-lg overflow-hidden border border-gray-600">
<button class="flex-1 py-2 text-xs font-medium btn-selected text-white border-r border-gray-600">Normal</button>
<button class="flex-1 py-2 text-xs font-medium bg-gray-700 text-gray-300 border-r border-gray-600">IF In</button>
<button class="flex-1 py-2 text-xs font-medium bg-gray-700 text-gray-300">Corners</button>
</div>
</div>
<div class="flex items-center gap-2">
<span class="text-xs font-medium text-gray-400 w-14 flex-shrink-0">Hold</span>
<div class="flex gap-1.5">
<button class="px-3 py-1.5 text-xs font-medium rounded-full border border-gray-600 bg-gray-700 text-gray-400 opacity-40" disabled>1B</button>
<button class="px-3 py-1.5 text-xs font-medium rounded-full border border-gray-600 bg-gray-700 text-gray-400 opacity-40" disabled>2B</button>
<button class="px-3 py-1.5 text-xs font-medium rounded-full border border-blue-500 btn-selected text-white">3B</button>
</div>
</div>
</div>
</div>
</div>
</div>
<!-- ============================================================ -->
<!-- RECOMMENDATION -->
<!-- ============================================================ -->
<div class="border-t border-gray-700 pt-6 pb-12">
<h2 class="text-lg font-bold text-white mb-4">Recommendation</h2>
<div class="bg-gray-800 rounded-xl p-4 space-y-3 text-sm text-gray-300">
<p><strong class="text-emerald-400">Design A (Inline Segmented)</strong> is the best balance of compactness and usability:</p>
<ul class="list-disc list-inside space-y-1 text-xs text-gray-400">
<li>~65% height reduction vs current design</li>
<li>All options visible at a glance — no scrolling needed</li>
<li>Touch targets still meet 44px minimum on the segmented buttons</li>
<li>Labels (Infield/Outfield/Hold) provide clear context without verbose headers</li>
<li>Confirm button in the header row saves a full row of vertical space</li>
<li>Removes redundant "Current Setup" preview — the buttons <em>are</em> the preview</li>
<li>Horizontal layout works well on mobile portrait (400px fits 3 segments comfortably)</li>
</ul>
<p class="text-xs text-gray-500 mt-3"><strong>Design B</strong> is even more compact but abbreviates labels (Norm/In/Corn) which hurts readability.<br>
<strong>Design C</strong> is the most compact but gets cramped in the full-options scenario and doesn't scale well.</p>
<div class="mt-4 p-3 bg-gray-700/50 rounded-lg">
<p class="text-xs font-semibold text-yellow-400 mb-1">Auto-hide logic:</p>
<p class="text-xs text-gray-400">When <code class="bg-gray-700 px-1 rounded">hasDefensiveChoices</code> is false (no runner on 3rd AND not walk-off), auto-submit defaults and skip to offensive phase. The component never renders.</p>
</div>
</div>
</div>
</div>
</body>
</html>