feat: battlefield UI overhaul — life panels, card sizing, layout

- Move life/cmd-dmg/poison into 3-box life panels as a top-level
  overlay (z-index 50) centered at quadrant intersections
- Remove center emblem
- Match battlefield card size to hand cards (63x84px)
- Overlay zone-row and commander-row on battlefield edges to
  eliminate dead space and maximize battlefield area
- Restructure poison badges from per-player absolute positioning
  into life-panel counters box

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
rgriffithandClaude Opus 4.6 committed 2026-04-04 15:50:35 -04:00
1 parent db3675aa6a
commit 52d51ebd5e
2 files changed
+175 -56

No files matched your search

+76 -30
View File
@@ -67,15 +67,6 @@
<div class="corner-accent bl"></div>
<div class="corner-accent br"></div>
<!-- CENTER EMBLEM -->
<div class="center-emblem">
<svg viewBox="0 0 100 100" fill="none">
<circle cx="50" cy="50" r="42" stroke="rgba(255,255,255,0.2)" stroke-width="1.5"/>
<circle cx="50" cy="50" r="28" stroke="rgba(255,255,255,0.1)" stroke-width="1"/>
<polygon points="50,15 58.5,37 82,37 63,51 69,74 50,60 31,74 37,51 18,37 41.5,37"
fill="rgba(255,255,255,0.1)" stroke="rgba(255,255,255,0.2)" stroke-width="0.8"/>
</svg>
</div>
<!-- ================================================
4-QUADRANT BATTLEFIELD
@@ -85,12 +76,6 @@
<!-- PLAYER 1: Top-Left (Crimson) -->
<div class="player-area p1" id="player-area-1">
<span class="player-label" id="player-label-1">Player 1</span>
<div class="life-counter" id="life-counter-1">
<button onclick="adjustLife(0,-1)" aria-label="Decrease P1 life">&#x2212;</button>
<span class="life-counter-value" id="life-0" onclick="showSetLifeDialog(0)">40</span>
<button onclick="adjustLife(0,1)" aria-label="Increase P1 life">+</button>
</div>
<div class="poison-badge" id="poison-0" style="display:none;" onclick="adjustPoison(0,1)" title="Poison counters (click +1, right-click -1)" oncontextmenu="event.preventDefault();adjustPoison(0,-1)">0 poison</div>
<!-- Zone Row: Library, Exile, Graveyard, Hand -->
<div class="zone-row" id="zone-row-1">
@@ -139,12 +124,6 @@
<!-- PLAYER 2: Top-Right (Sapphire) -->
<div class="player-area p2" id="player-area-2">
<span class="player-label" id="player-label-2">Player 2</span>
<div class="life-counter" id="life-counter-2">
<button onclick="adjustLife(1,-1)" aria-label="Decrease P2 life">&#x2212;</button>
<span class="life-counter-value" id="life-1" onclick="showSetLifeDialog(1)">40</span>
<button onclick="adjustLife(1,1)" aria-label="Increase P2 life">+</button>
</div>
<div class="poison-badge" id="poison-1" style="display:none;" onclick="adjustPoison(1,1)" oncontextmenu="event.preventDefault();adjustPoison(1,-1)">0 poison</div>
<div class="zone-row" id="zone-row-2">
<div class="zone library" id="lib-zone-2" data-player="2" data-zone="library"
@@ -229,12 +208,6 @@
</div>
<span class="player-label" id="player-label-3">Player 3</span>
<div class="life-counter" id="life-counter-3">
<button onclick="adjustLife(2,-1)" aria-label="Decrease P3 life">&#x2212;</button>
<span class="life-counter-value" id="life-2" onclick="showSetLifeDialog(2)">40</span>
<button onclick="adjustLife(2,1)" aria-label="Increase P3 life">+</button>
</div>
<div class="poison-badge" id="poison-2" style="display:none;" onclick="adjustPoison(2,1)" oncontextmenu="event.preventDefault();adjustPoison(2,-1)">0 poison</div>
</div>
<!-- PLAYER 4: Bottom-Right (Gold) -->
@@ -279,15 +252,88 @@
</div>
<span class="player-label" id="player-label-4">Player 4</span>
</div>
</div><!-- /.battlefield -->
<!-- LIFE PANELS OVERLAY (top-most layer) -->
<div id="life-panels-overlay">
<div class="life-panel lp-p1" id="life-panel-1">
<div class="life-panel-box life-box">
<span class="life-panel-label">Life</span>
<div class="life-counter" id="life-counter-1">
<button onclick="adjustLife(0,-1)" aria-label="Decrease P1 life">&#x2212;</button>
<span class="life-counter-value" id="life-0" onclick="showSetLifeDialog(0)">40</span>
<button onclick="adjustLife(0,1)" aria-label="Increase P1 life">+</button>
</div>
</div>
<div class="life-panel-box cmd-dmg-box" id="cmd-dmg-inline-0">
<span class="life-panel-label">Cmd Dmg</span>
<div class="cmd-dmg-inline-row">&#8212;</div>
</div>
<div class="life-panel-box counters-box">
<span class="life-panel-label">Counters</span>
<div class="poison-badge" id="poison-0" onclick="adjustPoison(0,1)" title="Poison counters (click +1, right-click -1)" oncontextmenu="event.preventDefault();adjustPoison(0,-1)">0 poison</div>
</div>
</div>
<div class="life-panel lp-p2" id="life-panel-2">
<div class="life-panel-box life-box">
<span class="life-panel-label">Life</span>
<div class="life-counter" id="life-counter-2">
<button onclick="adjustLife(1,-1)" aria-label="Decrease P2 life">&#x2212;</button>
<span class="life-counter-value" id="life-1" onclick="showSetLifeDialog(1)">40</span>
<button onclick="adjustLife(1,1)" aria-label="Increase P2 life">+</button>
</div>
</div>
<div class="life-panel-box cmd-dmg-box" id="cmd-dmg-inline-1">
<span class="life-panel-label">Cmd Dmg</span>
<div class="cmd-dmg-inline-row">&#8212;</div>
</div>
<div class="life-panel-box counters-box">
<span class="life-panel-label">Counters</span>
<div class="poison-badge" id="poison-1" onclick="adjustPoison(1,1)" oncontextmenu="event.preventDefault();adjustPoison(1,-1)">0 poison</div>
</div>
</div>
<div class="life-panel lp-p3" id="life-panel-3">
<div class="life-panel-box life-box">
<span class="life-panel-label">Life</span>
<div class="life-counter" id="life-counter-3">
<button onclick="adjustLife(2,-1)" aria-label="Decrease P3 life">&#x2212;</button>
<span class="life-counter-value" id="life-2" onclick="showSetLifeDialog(2)">40</span>
<button onclick="adjustLife(2,1)" aria-label="Increase P3 life">+</button>
</div>
</div>
<div class="life-panel-box cmd-dmg-box" id="cmd-dmg-inline-2">
<span class="life-panel-label">Cmd Dmg</span>
<div class="cmd-dmg-inline-row">&#8212;</div>
</div>
<div class="life-panel-box counters-box">
<span class="life-panel-label">Counters</span>
<div class="poison-badge" id="poison-2" onclick="adjustPoison(2,1)" oncontextmenu="event.preventDefault();adjustPoison(2,-1)">0 poison</div>
</div>
</div>
<div class="life-panel lp-p4" id="life-panel-4">
<div class="life-panel-box life-box">
<span class="life-panel-label">Life</span>
<div class="life-counter" id="life-counter-4">
<button onclick="adjustLife(3,-1)" aria-label="Decrease P4 life">&#x2212;</button>
<span class="life-counter-value" id="life-3" onclick="showSetLifeDialog(3)">40</span>
<button onclick="adjustLife(3,1)" aria-label="Increase P4 life">+</button>
</div>
<div class="poison-badge" id="poison-3" style="display:none;" onclick="adjustPoison(3,1)" oncontextmenu="event.preventDefault();adjustPoison(3,-1)">0 poison</div>
</div>
</div><!-- /.battlefield -->
<div class="life-panel-box cmd-dmg-box" id="cmd-dmg-inline-3">
<span class="life-panel-label">Cmd Dmg</span>
<div class="cmd-dmg-inline-row">&#8212;</div>
</div>
<div class="life-panel-box counters-box">
<span class="life-panel-label">Counters</span>
<div class="poison-badge" id="poison-3" onclick="adjustPoison(3,1)" oncontextmenu="event.preventDefault();adjustPoison(3,-1)">0 poison</div>
</div>
</div>
</div>
<!-- COMBAT SVG OVERLAY (arrows) -->
<svg id="combat-overlay" xmlns="http://www.w3.org/2000/svg" style="position:absolute;inset:44px 0 0 0;pointer-events:none;z-index:30;">
+99 -26
View File
@@ -68,8 +68,8 @@
/* Card dimensions */
--card-w: 63px;
--card-h: 88px;
--bf-card-w: 100px;
--bf-card-h: 140px;
--bf-card-w: 63px;
--bf-card-h: 84px;
--zone-radius: 8px;
/* Game UI colors */
@@ -639,9 +639,79 @@ input { font-family: inherit; }
.p3 .player-label { bottom: 6px; left: 6px; color: var(--p3-text); background: var(--p3-soft); }
.p4 .player-label { bottom: 6px; right: 6px; color: var(--p4-text); background: var(--p4-soft); }
/* Life counters */
.life-counter {
/* Life Panels Overlay — sits above everything */
#life-panels-overlay {
position: absolute;
inset: 44px 0 0 0;
z-index: 50;
pointer-events: none;
}
.life-panel {
position: absolute;
display: flex;
flex-direction: column;
gap: 2px;
width: 130px;
pointer-events: auto;
}
/* Position each panel near the center crossing */
.lp-p1 { bottom: calc(50% + 4px); right: calc(50% + 4px); }
.lp-p2 { bottom: calc(50% + 4px); left: calc(50% + 4px); }
.lp-p3 { top: calc(50% + 4px); right: calc(50% + 4px); }
.lp-p4 { top: calc(50% + 4px); left: calc(50% + 4px); }
.life-panel-box {
border-radius: 4px;
padding: 3px 6px;
display: flex;
align-items: center;
justify-content: space-between;
gap: 4px;
}
.life-panel-label {
font-size: 7px;
font-weight: 700;
letter-spacing: 0.5px;
text-transform: uppercase;
color: rgba(255,255,255,0.35);
flex-shrink: 0;
}
/* Top box: Life */
.life-box {
background: rgba(0,0,0,0.5);
border: 1px solid rgba(255,255,255,0.12);
}
/* Middle box: Commander Damage */
.cmd-dmg-box {
background: rgba(0,0,0,0.4);
border: 1px solid rgba(255,255,255,0.08);
flex-direction: column;
align-items: stretch;
gap: 2px;
}
.cmd-dmg-inline-row {
display: flex;
gap: 4px;
flex-wrap: wrap;
font-size: 9px;
color: rgba(255,255,255,0.5);
}
/* Bottom box: Counters (poison, etc.) */
.counters-box {
background: rgba(0,0,0,0.35);
border: 1px solid rgba(255,255,255,0.06);
}
/* Life counters (now inside life-panel) */
.life-counter {
position: relative;
z-index: 20;
display: flex;
align-items: center;
@@ -672,10 +742,10 @@ input { font-family: inherit; }
color: rgba(255,255,255,0.8);
}
.p1 .life-counter { top: 6px; right: 6px; color: var(--p1-text); }
.p2 .life-counter { top: 6px; left: 6px; color: var(--p2-text); }
.p3 .life-counter { bottom: 6px; right: 6px; color: var(--p3-text); }
.p4 .life-counter { bottom: 6px; left: 6px; color: var(--p4-text); }
.lp-p1 .life-counter { color: var(--p1-text); }
.lp-p2 .life-counter { color: var(--p2-text); }
.lp-p3 .life-counter { color: var(--p3-text); }
.lp-p4 .life-counter { color: var(--p4-text); }
.life-counter-value {
cursor: pointer;
@@ -683,39 +753,42 @@ input { font-family: inherit; }
}
.life-counter-value:hover { transform: scale(1.1); }
/* Poison counter badge */
/* Poison counter badge (now inside life-panel) */
.poison-badge {
position: absolute;
z-index: 21;
position: relative;
font-size: 10px;
font-weight: 700;
padding: 1px 5px;
border-radius: var(--radius-full);
cursor: pointer;
color: #c45fd6;
background: rgba(142,68,173,0.2);
border: 1px solid rgba(142,68,173,0.4);
}
.p1 .poison-badge { top: 30px; right: 6px; color: #c45fd6; background: rgba(142,68,173,0.2); border: 1px solid rgba(142,68,173,0.4); }
.p2 .poison-badge { top: 30px; left: 6px; color: #c45fd6; background: rgba(142,68,173,0.2); border: 1px solid rgba(142,68,173,0.4); }
.p3 .poison-badge { bottom: 30px; right: 6px; color: #c45fd6; background: rgba(142,68,173,0.2); border: 1px solid rgba(142,68,173,0.4); }
.p4 .poison-badge { bottom: 30px; left: 6px; color: #c45fd6; background: rgba(142,68,173,0.2); border: 1px solid rgba(142,68,173,0.4); }
/* Zone rows */
/* Zone rows — overlaid on battlefield edge */
.zone-row {
position: absolute;
z-index: 10;
display: flex;
align-items: center;
gap: 4px;
flex-shrink: 0;
}
.p1 .zone-row, .p3 .zone-row { flex-direction: row; }
.p2 .zone-row, .p4 .zone-row { flex-direction: row-reverse; }
.p1 .zone-row { top: 6px; left: 6px; flex-direction: row; }
.p2 .zone-row { top: 6px; right: 6px; flex-direction: row-reverse; }
.p3 .zone-row { bottom: 6px; left: 6px; flex-direction: row; }
.p4 .zone-row { bottom: 6px; right: 6px; flex-direction: row-reverse; }
/* Commander row */
/* Commander row — overlaid on battlefield edge */
.commander-row {
position: absolute;
z-index: 10;
display: flex;
flex-shrink: 0;
margin: 3px 0;
}
.p1 .commander-row, .p3 .commander-row { justify-content: flex-start; }
.p2 .commander-row, .p4 .commander-row { justify-content: flex-end; }
.p1 .commander-row { top: 6px; left: 6px; margin-top: calc(var(--card-h) + 10px); }
.p2 .commander-row { top: 6px; right: 6px; margin-top: calc(var(--card-h) + 10px); }
.p3 .commander-row { bottom: 6px; left: 6px; margin-bottom: calc(var(--card-h) + 10px); }
.p4 .commander-row { bottom: 6px; right: 6px; margin-bottom: calc(var(--card-h) + 10px); }
/* Battle zone */
.battle-zone {
@@ -2547,8 +2620,8 @@ kbd {
:root {
--card-w: 42px;
--card-h: 58px;
--bf-card-w: 72px;
--bf-card-h: 100px;
--bf-card-w: 42px;
--bf-card-h: 56px;
}
.player-label { font-size: 7px; letter-spacing: 1px; padding: 1px 5px; }
.life-counter { font-size: 14px; }