diff --git a/frontend/assets/css/historico-scoreboard-detail.css b/frontend/assets/css/historico-scoreboard-detail.css
new file mode 100644
index 0000000..709992f
--- /dev/null
+++ b/frontend/assets/css/historico-scoreboard-detail.css
@@ -0,0 +1,111 @@
+.historical-scoreboard-detail {
+ display: grid;
+ grid-template-columns: minmax(0, 1fr) minmax(180px, 280px) minmax(0, 1fr);
+ align-items: stretch;
+ gap: 14px;
+ margin-bottom: 14px;
+ padding: 18px;
+ border: 1px solid rgba(210, 182, 118, 0.24);
+ border-radius: 22px;
+ background:
+ radial-gradient(circle at top center, rgba(210, 182, 118, 0.14), transparent 44%),
+ linear-gradient(180deg, rgba(29, 34, 24, 0.96), rgba(11, 14, 10, 0.98));
+ box-shadow: var(--shadow-soft);
+}
+
+.historical-scoreboard-detail__side,
+.historical-scoreboard-detail__score {
+ display: grid;
+ align-content: center;
+ justify-items: center;
+ min-height: 142px;
+ padding: 18px;
+ border: 1px solid rgba(159, 168, 141, 0.14);
+ border-radius: 18px;
+ background: rgba(13, 17, 12, 0.48);
+ text-align: center;
+}
+
+.historical-scoreboard-detail__side span,
+.historical-scoreboard-detail__score span,
+.historical-match-compact-meta span {
+ margin-bottom: 7px;
+ color: var(--muted);
+ font-size: 0.72rem;
+ letter-spacing: 0.1em;
+ text-transform: uppercase;
+}
+
+.historical-scoreboard-detail__side strong {
+ color: var(--text);
+ font-size: clamp(1.35rem, 2.8vw, 2.6rem);
+ line-height: 1;
+}
+
+.historical-scoreboard-detail__side em,
+.historical-scoreboard-detail__score em {
+ min-height: 1.2em;
+ margin-top: 10px;
+ color: var(--accent-strong);
+ font-style: normal;
+ font-weight: 800;
+ letter-spacing: 0.08em;
+ text-transform: uppercase;
+}
+
+.historical-scoreboard-detail__side.is-winner {
+ border-color: rgba(210, 182, 118, 0.42);
+ background:
+ radial-gradient(circle at top, rgba(210, 182, 118, 0.14), transparent 55%),
+ rgba(25, 24, 16, 0.7);
+}
+
+.historical-scoreboard-detail__score {
+ border-color: rgba(210, 182, 118, 0.36);
+ background:
+ radial-gradient(circle at center, rgba(210, 182, 118, 0.18), transparent 62%),
+ rgba(11, 14, 10, 0.72);
+}
+
+.historical-scoreboard-detail__score strong {
+ color: var(--text);
+ font-size: clamp(3.4rem, 7vw, 6.2rem);
+ line-height: 0.95;
+ letter-spacing: 0.02em;
+}
+
+.historical-match-compact-meta {
+ display: grid;
+ grid-template-columns: repeat(auto-fit, minmax(min(100%, 170px), 1fr));
+ gap: 12px;
+}
+
+.historical-match-compact-meta article {
+ padding: 13px 14px;
+ border: 1px solid rgba(159, 168, 141, 0.14);
+ border-radius: 16px;
+ background: rgba(13, 17, 12, 0.44);
+}
+
+.historical-match-compact-meta strong {
+ display: block;
+ color: var(--text);
+ font-size: 1rem;
+ line-height: 1.35;
+}
+
+@media (max-width: 720px) {
+ .historical-scoreboard-detail {
+ grid-template-columns: 1fr;
+ padding: 14px;
+ }
+
+ .historical-scoreboard-detail__side,
+ .historical-scoreboard-detail__score {
+ min-height: 112px;
+ }
+
+ .historical-scoreboard-detail__score {
+ order: -1;
+ }
+}
diff --git a/frontend/assets/js/historico-partida.js b/frontend/assets/js/historico-partida.js
index 80dde3a..ae353dc 100644
--- a/frontend/assets/js/historico-partida.js
+++ b/frontend/assets/js/historico-partida.js
@@ -25,7 +25,7 @@ document.addEventListener("DOMContentLoaded", () => {
if (!serverSlug || !matchId) {
nodes.title.textContent = "Partida no seleccionada";
nodes.summary.textContent = "Vuelve al historico y abre una partida registrada.";
- nodes.note.textContent = "Faltan parametros internos para cargar este detalle.";
+ nodes.note.textContent = "";
setState(nodes.state, "No hay una partida seleccionada.", true);
return;
}
@@ -46,8 +46,7 @@ async function loadMatchDetail({ backendBaseUrl, serverSlug, matchId, nodes }) {
nodes.title.textContent = "Detalle no disponible";
nodes.summary.textContent =
"La partida existe como enlace interno, pero todavia no hay detalle suficiente para mostrar.";
- nodes.note.textContent =
- "El historico local puede tener solo una ventana RCON parcial o ningun registro ampliado.";
+ nodes.note.textContent = "";
setState(nodes.state, "Detalle no disponible para esta partida.");
return;
}
@@ -56,7 +55,7 @@ async function loadMatchDetail({ backendBaseUrl, serverSlug, matchId, nodes }) {
} catch (error) {
nodes.title.textContent = "Detalle no disponible";
nodes.summary.textContent = "No se pudo conectar con el backend local.";
- nodes.note.textContent = "Comprueba que el backend este levantado y vuelve a intentarlo.";
+ nodes.note.textContent = "";
setState(nodes.state, "Error al cargar el detalle de la partida.", true);
}
}
@@ -66,31 +65,81 @@ function renderMatchDetail(item, nodes) {
const serverName = item.server?.name || item.server?.slug || "Servidor no disponible";
nodes.title.textContent = mapName;
nodes.summary.textContent = `${serverName} - ${formatDetailSubtitle(item)}`;
- nodes.note.textContent = buildDetailNote(item);
- nodes.grid.innerHTML = [
- renderDetailCard("Servidor", serverName),
- renderDetailCard("Mapa", mapName),
- renderDetailCard("Modo", formatGameMode(item.game_mode || item.gamestate?.game_mode)),
- renderDetailCard("Marcador", formatScore(item.result)),
- renderDetailCard("Ganador", formatWinner(item.winner || item.result?.winner)),
- renderDetailCard("Resultado", formatMatchResult(item.result)),
- renderDetailCard("Inicio", formatMatchTimestamp(item, "start")),
- renderDetailCard("Fin", formatMatchTimestamp(item, "end")),
- renderDetailCard("Duracion", formatDuration(item.duration_seconds)),
- renderDetailCard("Confianza", formatConfidence(item.confidence)),
- renderDetailCard(
- "Fuente",
- formatSourceBasis(item.source_basis || item.result_source) || "No disponible",
- ),
- renderDetailCard("Base", formatCaptureBasis(item.capture_basis)),
- ].join("");
+ nodes.note.textContent = "";
+ nodes.grid.innerHTML = renderScoreboardDetail(item, { mapName, serverName });
renderPlayerSection(item, nodes);
- renderTimelineSection(item, nodes);
+ hideTimelineSection(nodes);
renderActions(item, nodes.actions);
nodes.state.hidden = true;
nodes.grid.hidden = false;
}
+function renderScoreboardDetail(item, { mapName, serverName }) {
+ const result = item.result || {};
+ const alliedScore = Number.isFinite(Number(result.allied_score))
+ ? formatNumber(result.allied_score)
+ : "-";
+ const axisScore = Number.isFinite(Number(result.axis_score))
+ ? formatNumber(result.axis_score)
+ : "-";
+ const winner = String(item.winner || result.winner || "").toLowerCase();
+ const isAlliedWinner = winner === "allies" || winner === "allied";
+ const isAxisWinner = winner === "axis";
+ const metadata = [
+ ["Servidor", serverName],
+ ["Mapa", mapName],
+ ["Modo", formatGameMode(item.game_mode || item.gamestate?.game_mode)],
+ ["Duracion", formatDuration(item.duration_seconds)],
+ ["Inicio", formatMatchTimestamp(item, "start")],
+ ];
+ if (item.ended_at) {
+ metadata.push(["Fin", formatMatchTimestamp(item, "end")]);
+ }
+
+ return `
+ ${escapeHtml(label)}