diff --git a/src/mobile-hud.js b/src/mobile-hud.js
index 5e86af3..777da56 100644
--- a/src/mobile-hud.js
+++ b/src/mobile-hud.js
@@ -263,6 +263,29 @@ if (!isDesktopPointer.matches) {
clip-path: circle(49% at 50% 50%);
}
+ .steam-reload-track {
+ position: absolute;
+ left: 12%;
+ right: 12%;
+ bottom: -7%;
+ height: 5px;
+ border: 1px solid rgba(232, 184, 91, .42);
+ border-radius: 999px;
+ background: rgba(8, 25, 31, .72);
+ overflow: hidden;
+ pointer-events: none;
+ }
+
+ .steam-reload-fill {
+ display: block;
+ width: 100%;
+ height: 100%;
+ transform: scaleX(1);
+ transform-origin: left center;
+ background: rgba(255, 224, 140, .92);
+ transition: transform 60ms linear;
+ }
+
.steam-action-label {
position: absolute;
left: 50%;
@@ -566,7 +589,7 @@ if (!isDesktopPointer.matches) {
`);
const enemyHealthPiece = addHealthPiece('steam-enemy-card', enemyHealthSrc, `
- PIRATE
+ PIRATE
CLEAR
`);
@@ -601,10 +624,12 @@ if (!isDesktopPointer.matches) {
addPiece('steam-cannon-port', cannonRoundelSrc, `
PORT
+
`);
addPiece('steam-cannon-starboard', cannonRoundelSrc, `
STBD
+
`);
const status = document.createElement('div');
@@ -713,6 +738,8 @@ if (!isDesktopPointer.matches) {
const range = nearest.range;
const playerHull = Math.max(0, scene.playerHull ?? 100);
const enemyHull = pirate ? Math.max(0, pirate.getData?.('hull') ?? 0) : 0;
+ const enemyMaxHull = pirate ? Math.max(1, pirate.getData?.('maxHull') ?? 120) : 120;
+ const enemyName = pirate ? (pirate.getData?.('classLabel') || 'PIRATE') : 'PIRATE';
fields.speed.textContent = `${Math.abs(scene.playerSpeed || 0).toFixed(0)}${scene.playerSpeed < 0 ? 'R' : ''}`;
fields.heading.textContent = `${heading.toFixed(0).padStart(3, '0')}°`;
@@ -721,7 +748,8 @@ if (!isDesktopPointer.matches) {
fields.kills.textContent = String(scene.defeated || 0);
fields.range.textContent = Number.isFinite(range) ? `${Math.round(range)}m` : '--';
fields['player-hull'].textContent = `${playerHull}/100`;
- fields['enemy-hull'].textContent = pirate ? `${enemyHull}/120` : 'CLEAR';
+ fields['enemy-name'].textContent = enemyName;
+ fields['enemy-hull'].textContent = pirate ? `${enemyHull}/${enemyMaxHull}` : 'CLEAR';
const playerPct = clamp01(playerHull / 100);
fields['player-health-cover'].style.width = `${(1 - playerPct) * 49}%`;
fields['player-health-tint'].style.transform = `scaleX(${playerPct})`;
@@ -730,7 +758,14 @@ if (!isDesktopPointer.matches) {
: playerPct > 0.33
? 'rgba(255, 210, 0, .58)'
: 'rgba(255, 45, 18, .72)';
- setHealthFrame(enemyHealthPiece, pirate ? healthFrame(enemyHull, 120) : 11);
+ setHealthFrame(enemyHealthPiece, pirate ? healthFrame(enemyHull, enemyMaxHull) : 11);
+
+ const reloadMs = Math.max(1, scene.playerBroadsideReloadMs || 850);
+ const now = scene.time?.now ?? 0;
+ const portReady = clamp01((now - (scene.lastPlayerShot?.port ?? -Infinity)) / reloadMs);
+ const starboardReady = clamp01((now - (scene.lastPlayerShot?.starboard ?? -Infinity)) / reloadMs);
+ fields['port-reload'].style.transform = `scaleX(${portReady})`;
+ fields['starboard-reload'].style.transform = `scaleX(${starboardReady})`;
const statusText = scene.status?.text?.trim?.() || '';
fields.status.textContent = statusText;