2025-10-20 21:32:45 -04:00
|
|
|
<!DOCTYPE html>
|
|
|
|
|
<html lang="en">
|
|
|
|
|
<head>
|
|
|
|
|
<meta charset="UTF-8" />
|
|
|
|
|
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
|
2026-02-11 11:57:27 -05:00
|
|
|
<title>SoccerCloud Web</title>
|
2026-02-11 12:26:25 -05:00
|
|
|
<script>
|
|
|
|
|
(function () {
|
|
|
|
|
var key = "soccercloud.web.theme";
|
|
|
|
|
var allowed = {
|
|
|
|
|
"default-light": true,
|
|
|
|
|
dark: true,
|
|
|
|
|
matcha: true,
|
|
|
|
|
"black-mesa": true,
|
|
|
|
|
};
|
|
|
|
|
try {
|
|
|
|
|
var saved = localStorage.getItem(key);
|
|
|
|
|
if (saved && allowed[saved]) {
|
|
|
|
|
document.documentElement.setAttribute("data-theme", saved);
|
|
|
|
|
}
|
|
|
|
|
} catch (_) {}
|
|
|
|
|
})();
|
|
|
|
|
</script>
|
2026-02-11 11:57:27 -05:00
|
|
|
<link rel="preconnect" href="https://fonts.googleapis.com" />
|
|
|
|
|
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin />
|
|
|
|
|
<link href="https://fonts.googleapis.com/css2?family=Space+Grotesk:wght@400;500;600;700&family=Sora:wght@500;600;700&display=swap" rel="stylesheet" />
|
2025-10-20 21:32:45 -04:00
|
|
|
<style>
|
2026-02-11 11:57:27 -05:00
|
|
|
:root {
|
|
|
|
|
--bg: #f4f6f8;
|
|
|
|
|
--surface: #ffffff;
|
|
|
|
|
--surface-soft: #f9fbff;
|
|
|
|
|
--text: #111827;
|
|
|
|
|
--muted: #667085;
|
|
|
|
|
--line: #d0d8e2;
|
|
|
|
|
--brand: #0f766e;
|
|
|
|
|
--brand-strong: #0b5f58;
|
|
|
|
|
--warn: #b42318;
|
|
|
|
|
--pending: #6b7280;
|
|
|
|
|
--running: #1d4ed8;
|
|
|
|
|
--completed: #047857;
|
|
|
|
|
--shadow: 0 24px 64px rgba(15, 23, 42, 0.12);
|
2026-02-11 12:26:25 -05:00
|
|
|
--bg-radial-1: rgba(15, 118, 110, 0.12);
|
|
|
|
|
--bg-radial-2: rgba(29, 78, 216, 0.11);
|
|
|
|
|
--bg-start: #eef2f8;
|
|
|
|
|
--bg-end: #f8fafc;
|
|
|
|
|
--hero-grad-start: #ffffff;
|
|
|
|
|
--hero-grad-end: #f7fbff;
|
|
|
|
|
--hero-border: rgba(15, 23, 42, 0.08);
|
|
|
|
|
--card-border: rgba(15, 23, 42, 0.08);
|
|
|
|
|
--card-shadow: 0 10px 28px rgba(15, 23, 42, 0.08);
|
|
|
|
|
--btn-secondary-bg: #ffffff;
|
|
|
|
|
--btn-secondary-hover: rgba(255, 255, 255, 0.66);
|
|
|
|
|
--btn-secondary-shadow: 0 8px 18px rgba(15, 23, 42, 0.12), inset 0 1px 0 rgba(255, 255, 255, 0.34);
|
|
|
|
|
--btn-warn-bg: #ffffff;
|
|
|
|
|
--btn-warn-hover: rgba(255, 255, 255, 0.66);
|
|
|
|
|
--btn-warn-shadow: 0 8px 18px rgba(180, 35, 24, 0.16), inset 0 1px 0 rgba(255, 255, 255, 0.34);
|
|
|
|
|
--empty-bg: rgba(255, 255, 255, 0.72);
|
|
|
|
|
--modal-backdrop: rgba(4, 10, 22, 0.62);
|
|
|
|
|
--modal-border: rgba(15, 23, 42, 0.08);
|
|
|
|
|
--modal-header-bg: rgba(255, 255, 255, 0.9);
|
|
|
|
|
--mono-text: #122033;
|
|
|
|
|
--scoreboard-bg: #ffffff;
|
|
|
|
|
--field-bg: #ffffff;
|
|
|
|
|
--field-text: var(--text);
|
|
|
|
|
--field-border: var(--line);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
:root[data-theme="dark"] {
|
|
|
|
|
--bg: #10161f;
|
|
|
|
|
--surface: #151d28;
|
|
|
|
|
--surface-soft: #1a2431;
|
|
|
|
|
--text: #e6edf7;
|
|
|
|
|
--muted: #9aa8bc;
|
|
|
|
|
--line: #2a374a;
|
|
|
|
|
--brand: #4aa3ff;
|
|
|
|
|
--brand-strong: #2d8ae8;
|
|
|
|
|
--warn: #ff7d72;
|
|
|
|
|
--pending: #708090;
|
|
|
|
|
--running: #60a5fa;
|
|
|
|
|
--completed: #34d399;
|
|
|
|
|
--shadow: 0 24px 64px rgba(0, 0, 0, 0.35);
|
|
|
|
|
--bg-radial-1: rgba(43, 105, 173, 0.22);
|
|
|
|
|
--bg-radial-2: rgba(25, 43, 73, 0.34);
|
|
|
|
|
--bg-start: #0d141d;
|
|
|
|
|
--bg-end: #141d29;
|
|
|
|
|
--hero-grad-start: #162130;
|
|
|
|
|
--hero-grad-end: #182536;
|
|
|
|
|
--hero-border: rgba(130, 157, 191, 0.18);
|
|
|
|
|
--card-border: rgba(130, 157, 191, 0.18);
|
|
|
|
|
--card-shadow: 0 10px 28px rgba(0, 0, 0, 0.32);
|
|
|
|
|
--btn-secondary-bg: #1b2533;
|
|
|
|
|
--btn-secondary-hover: rgba(70, 91, 118, 0.38);
|
|
|
|
|
--btn-secondary-shadow: 0 8px 18px rgba(0, 0, 0, 0.32), inset 0 1px 0 rgba(255, 255, 255, 0.08);
|
|
|
|
|
--btn-warn-bg: #231f22;
|
|
|
|
|
--btn-warn-hover: rgba(120, 53, 53, 0.38);
|
|
|
|
|
--btn-warn-shadow: 0 8px 18px rgba(0, 0, 0, 0.32), inset 0 1px 0 rgba(255, 255, 255, 0.08);
|
|
|
|
|
--empty-bg: rgba(21, 29, 40, 0.82);
|
|
|
|
|
--modal-backdrop: rgba(3, 6, 10, 0.72);
|
|
|
|
|
--modal-border: rgba(130, 157, 191, 0.2);
|
|
|
|
|
--modal-header-bg: rgba(18, 26, 37, 0.92);
|
|
|
|
|
--mono-text: #cad7e8;
|
|
|
|
|
--scoreboard-bg: #182231;
|
|
|
|
|
--field-bg: #1a2533;
|
|
|
|
|
--field-text: #e6edf7;
|
|
|
|
|
--field-border: #324359;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
:root[data-theme="matcha"] {
|
|
|
|
|
--bg: #edf3ea;
|
|
|
|
|
--surface: #f6fbf1;
|
|
|
|
|
--surface-soft: #edf5e7;
|
|
|
|
|
--text: #223328;
|
|
|
|
|
--muted: #4f6a58;
|
|
|
|
|
--line: #c8d9c7;
|
|
|
|
|
--brand: #5e8c55;
|
|
|
|
|
--brand-strong: #4f7a47;
|
|
|
|
|
--warn: #a03b2b;
|
|
|
|
|
--pending: #6c7a6f;
|
|
|
|
|
--running: #4d7196;
|
|
|
|
|
--completed: #3f7b57;
|
|
|
|
|
--shadow: 0 24px 64px rgba(45, 71, 52, 0.12);
|
|
|
|
|
--bg-radial-1: rgba(128, 171, 116, 0.18);
|
|
|
|
|
--bg-radial-2: rgba(194, 211, 150, 0.22);
|
|
|
|
|
--bg-start: #ebf2e5;
|
|
|
|
|
--bg-end: #f5f8ee;
|
|
|
|
|
--hero-grad-start: #f8fdf2;
|
|
|
|
|
--hero-grad-end: #eef6e6;
|
|
|
|
|
--hero-border: rgba(77, 112, 84, 0.15);
|
|
|
|
|
--card-border: rgba(77, 112, 84, 0.15);
|
|
|
|
|
--card-shadow: 0 10px 24px rgba(59, 98, 66, 0.1);
|
|
|
|
|
--btn-secondary-bg: #f6fbf1;
|
|
|
|
|
--btn-secondary-hover: rgba(246, 251, 241, 0.86);
|
|
|
|
|
--btn-secondary-shadow: 0 8px 18px rgba(76, 110, 84, 0.14), inset 0 1px 0 rgba(255, 255, 255, 0.42);
|
|
|
|
|
--btn-warn-bg: #f8f1ec;
|
|
|
|
|
--btn-warn-hover: rgba(248, 241, 236, 0.86);
|
|
|
|
|
--btn-warn-shadow: 0 8px 18px rgba(150, 88, 74, 0.15), inset 0 1px 0 rgba(255, 255, 255, 0.4);
|
|
|
|
|
--empty-bg: rgba(246, 251, 241, 0.8);
|
|
|
|
|
--modal-backdrop: rgba(30, 40, 29, 0.48);
|
|
|
|
|
--modal-border: rgba(77, 112, 84, 0.17);
|
|
|
|
|
--modal-header-bg: rgba(246, 251, 241, 0.92);
|
|
|
|
|
--mono-text: #2e4a37;
|
|
|
|
|
--scoreboard-bg: #f8fcf4;
|
|
|
|
|
--field-bg: #f8fcf4;
|
|
|
|
|
--field-text: #223328;
|
|
|
|
|
--field-border: #c8d9c7;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
:root[data-theme="black-mesa"] {
|
|
|
|
|
--bg: #21262c;
|
|
|
|
|
--surface: #2b3139;
|
|
|
|
|
--surface-soft: #323a44;
|
|
|
|
|
--text: #e6e8ea;
|
|
|
|
|
--muted: #b3bcc7;
|
|
|
|
|
--line: #46505c;
|
|
|
|
|
--brand: #d7832f;
|
|
|
|
|
--brand-strong: #bc6f23;
|
|
|
|
|
--warn: #ff8f5d;
|
|
|
|
|
--pending: #8b95a2;
|
|
|
|
|
--running: #f39b4a;
|
|
|
|
|
--completed: #84c98b;
|
|
|
|
|
--shadow: 0 24px 64px rgba(0, 0, 0, 0.34);
|
|
|
|
|
--bg-radial-1: rgba(215, 131, 47, 0.18);
|
|
|
|
|
--bg-radial-2: rgba(83, 94, 111, 0.3);
|
|
|
|
|
--bg-start: #1f242a;
|
|
|
|
|
--bg-end: #2a3038;
|
|
|
|
|
--hero-grad-start: #313844;
|
|
|
|
|
--hero-grad-end: #2a3038;
|
|
|
|
|
--hero-border: rgba(215, 131, 47, 0.24);
|
|
|
|
|
--card-border: rgba(215, 131, 47, 0.2);
|
|
|
|
|
--card-shadow: 0 10px 28px rgba(0, 0, 0, 0.31);
|
|
|
|
|
--btn-secondary-bg: #343c47;
|
|
|
|
|
--btn-secondary-hover: rgba(90, 103, 121, 0.45);
|
|
|
|
|
--btn-secondary-shadow: 0 8px 18px rgba(0, 0, 0, 0.3), inset 0 1px 0 rgba(255, 255, 255, 0.08);
|
|
|
|
|
--btn-warn-bg: #3b3230;
|
|
|
|
|
--btn-warn-hover: rgba(137, 91, 69, 0.42);
|
|
|
|
|
--btn-warn-shadow: 0 8px 18px rgba(0, 0, 0, 0.31), inset 0 1px 0 rgba(255, 255, 255, 0.08);
|
|
|
|
|
--empty-bg: rgba(43, 49, 57, 0.84);
|
|
|
|
|
--modal-backdrop: rgba(10, 12, 15, 0.74);
|
|
|
|
|
--modal-border: rgba(215, 131, 47, 0.24);
|
|
|
|
|
--modal-header-bg: rgba(43, 49, 57, 0.94);
|
|
|
|
|
--mono-text: #d9dee6;
|
|
|
|
|
--scoreboard-bg: #303742;
|
|
|
|
|
--field-bg: #353e49;
|
|
|
|
|
--field-text: #e6e8ea;
|
|
|
|
|
--field-border: #505a67;
|
2026-02-11 11:57:27 -05:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
* { box-sizing: border-box; }
|
|
|
|
|
|
|
|
|
|
body {
|
|
|
|
|
margin: 0;
|
|
|
|
|
min-height: 100vh;
|
|
|
|
|
font-family: "Space Grotesk", "Segoe UI", sans-serif;
|
|
|
|
|
color: var(--text);
|
|
|
|
|
background:
|
2026-02-11 12:26:25 -05:00
|
|
|
radial-gradient(1200px 640px at -8% -12%, var(--bg-radial-1), transparent 58%),
|
|
|
|
|
radial-gradient(980px 680px at 110% -18%, var(--bg-radial-2), transparent 55%),
|
|
|
|
|
linear-gradient(180deg, var(--bg-start) 0%, var(--bg-end) 100%);
|
2026-02-11 11:57:27 -05:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
.app {
|
|
|
|
|
max-width: 1200px;
|
|
|
|
|
margin: 0 auto;
|
|
|
|
|
padding: 28px 18px 42px;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
.hero {
|
|
|
|
|
display: grid;
|
|
|
|
|
grid-template-columns: 1.2fr 0.8fr;
|
|
|
|
|
gap: 18px;
|
|
|
|
|
margin-bottom: 18px;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
.hero-card {
|
2026-02-11 12:26:25 -05:00
|
|
|
background: linear-gradient(145deg, var(--hero-grad-start), var(--hero-grad-end));
|
|
|
|
|
border: 1px solid var(--hero-border);
|
2026-02-11 11:57:27 -05:00
|
|
|
border-radius: 18px;
|
|
|
|
|
padding: 20px;
|
|
|
|
|
box-shadow: var(--shadow);
|
|
|
|
|
animation: rise 420ms ease both;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
.eyebrow {
|
|
|
|
|
font-size: 12px;
|
|
|
|
|
text-transform: uppercase;
|
|
|
|
|
letter-spacing: 0.14em;
|
|
|
|
|
color: var(--brand);
|
|
|
|
|
margin: 0 0 8px;
|
|
|
|
|
font-weight: 700;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
h1 {
|
|
|
|
|
font-family: "Sora", "Space Grotesk", sans-serif;
|
|
|
|
|
margin: 0;
|
|
|
|
|
font-size: clamp(28px, 5vw, 42px);
|
|
|
|
|
line-height: 1.05;
|
|
|
|
|
letter-spacing: -0.02em;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
.lead {
|
|
|
|
|
margin: 12px 0 0;
|
|
|
|
|
color: var(--muted);
|
|
|
|
|
font-size: 15px;
|
|
|
|
|
max-width: 56ch;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
.stat-grid {
|
|
|
|
|
display: grid;
|
|
|
|
|
grid-template-columns: 1fr 1fr;
|
|
|
|
|
gap: 10px;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
.stat {
|
|
|
|
|
border: 1px solid var(--line);
|
|
|
|
|
background: var(--surface-soft);
|
|
|
|
|
border-radius: 12px;
|
|
|
|
|
padding: 10px 12px;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
.stat .label {
|
|
|
|
|
color: var(--muted);
|
|
|
|
|
font-size: 12px;
|
|
|
|
|
margin-bottom: 6px;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
.stat .value {
|
|
|
|
|
font-family: "Sora", "Space Grotesk", sans-serif;
|
|
|
|
|
font-size: 24px;
|
|
|
|
|
line-height: 1;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
.toolbar {
|
|
|
|
|
display: flex;
|
|
|
|
|
justify-content: space-between;
|
|
|
|
|
align-items: center;
|
|
|
|
|
gap: 12px;
|
|
|
|
|
margin: 18px 0;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
.status-text {
|
|
|
|
|
margin: 0;
|
|
|
|
|
color: var(--muted);
|
|
|
|
|
font-size: 13px;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
.btn {
|
|
|
|
|
border: 1px solid transparent;
|
|
|
|
|
background: var(--brand);
|
|
|
|
|
color: white;
|
|
|
|
|
border-radius: 10px;
|
|
|
|
|
padding: 10px 14px;
|
|
|
|
|
font-family: inherit;
|
|
|
|
|
font-size: 14px;
|
|
|
|
|
font-weight: 600;
|
|
|
|
|
cursor: pointer;
|
|
|
|
|
transition: background-color 180ms ease, border-color 180ms ease, box-shadow 180ms ease, opacity 180ms ease;
|
|
|
|
|
box-shadow: 0 12px 24px rgba(15, 118, 110, 0.25);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
.btn:hover {
|
|
|
|
|
background: rgba(15, 118, 110, 0.72);
|
|
|
|
|
border-color: rgba(255, 255, 255, 0.45);
|
|
|
|
|
box-shadow: 0 10px 26px rgba(15, 118, 110, 0.28), inset 0 1px 0 rgba(255, 255, 255, 0.28);
|
|
|
|
|
backdrop-filter: blur(8px) saturate(135%);
|
|
|
|
|
-webkit-backdrop-filter: blur(8px) saturate(135%);
|
|
|
|
|
}
|
|
|
|
|
.btn:active {
|
|
|
|
|
opacity: 0.96;
|
|
|
|
|
box-shadow: 0 6px 16px rgba(15, 118, 110, 0.2);
|
|
|
|
|
}
|
|
|
|
|
.btn.secondary {
|
2026-02-11 12:26:25 -05:00
|
|
|
background: var(--btn-secondary-bg);
|
2026-02-11 11:57:27 -05:00
|
|
|
color: var(--text);
|
|
|
|
|
border-color: var(--line);
|
|
|
|
|
box-shadow: none;
|
|
|
|
|
}
|
|
|
|
|
.btn.secondary:hover {
|
2026-02-11 12:26:25 -05:00
|
|
|
background: var(--btn-secondary-hover);
|
2026-02-11 11:57:27 -05:00
|
|
|
border-color: rgba(148, 163, 184, 0.7);
|
2026-02-11 12:26:25 -05:00
|
|
|
box-shadow: var(--btn-secondary-shadow);
|
2026-02-11 11:57:27 -05:00
|
|
|
}
|
|
|
|
|
.btn.warn {
|
2026-02-11 12:26:25 -05:00
|
|
|
background: var(--btn-warn-bg);
|
2026-02-11 11:57:27 -05:00
|
|
|
color: var(--warn);
|
|
|
|
|
border-color: rgba(180, 35, 24, 0.34);
|
|
|
|
|
box-shadow: none;
|
|
|
|
|
}
|
|
|
|
|
.btn.warn:hover {
|
2026-02-11 12:26:25 -05:00
|
|
|
background: var(--btn-warn-hover);
|
2026-02-11 11:57:27 -05:00
|
|
|
border-color: rgba(180, 35, 24, 0.45);
|
2026-02-11 12:26:25 -05:00
|
|
|
box-shadow: var(--btn-warn-shadow);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
.toolbar-actions {
|
|
|
|
|
display: flex;
|
|
|
|
|
align-items: center;
|
|
|
|
|
gap: 10px;
|
|
|
|
|
flex-wrap: wrap;
|
|
|
|
|
justify-content: flex-end;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
.theme-control {
|
|
|
|
|
display: flex;
|
|
|
|
|
align-items: center;
|
|
|
|
|
gap: 8px;
|
|
|
|
|
color: var(--muted);
|
|
|
|
|
font-size: 13px;
|
|
|
|
|
white-space: nowrap;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
.theme-control select {
|
|
|
|
|
min-width: 190px;
|
|
|
|
|
padding: 9px 10px;
|
2026-02-11 11:57:27 -05:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
.dashboard {
|
|
|
|
|
display: grid;
|
|
|
|
|
grid-template-columns: repeat(auto-fill, minmax(300px, 1fr));
|
|
|
|
|
gap: 14px;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
.card {
|
|
|
|
|
background: var(--surface);
|
2026-02-11 12:26:25 -05:00
|
|
|
border: 1px solid var(--card-border);
|
2026-02-11 11:57:27 -05:00
|
|
|
border-radius: 14px;
|
|
|
|
|
padding: 14px;
|
2026-02-11 12:26:25 -05:00
|
|
|
box-shadow: var(--card-shadow);
|
2026-02-11 11:57:27 -05:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
.card-top {
|
|
|
|
|
display: flex;
|
|
|
|
|
justify-content: space-between;
|
|
|
|
|
align-items: flex-start;
|
|
|
|
|
gap: 8px;
|
|
|
|
|
margin-bottom: 10px;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
.card-title {
|
|
|
|
|
margin: 0;
|
|
|
|
|
font-size: 16px;
|
|
|
|
|
line-height: 1.2;
|
|
|
|
|
font-family: "Sora", "Space Grotesk", sans-serif;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
.card-id {
|
|
|
|
|
margin: 6px 0 0;
|
|
|
|
|
color: var(--muted);
|
|
|
|
|
font-size: 12px;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
.pill {
|
|
|
|
|
border-radius: 999px;
|
|
|
|
|
padding: 4px 10px;
|
|
|
|
|
font-size: 12px;
|
|
|
|
|
font-weight: 700;
|
|
|
|
|
text-transform: uppercase;
|
|
|
|
|
letter-spacing: 0.04em;
|
|
|
|
|
color: #fff;
|
|
|
|
|
}
|
|
|
|
|
.pill.pending { background: var(--pending); }
|
|
|
|
|
.pill.running { background: var(--running); }
|
|
|
|
|
.pill.completed { background: var(--completed); }
|
|
|
|
|
|
|
|
|
|
.card-line {
|
|
|
|
|
margin: 8px 0;
|
|
|
|
|
color: var(--muted);
|
|
|
|
|
font-size: 13px;
|
|
|
|
|
min-height: 1.3em;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
.card-score {
|
|
|
|
|
margin: 8px 0;
|
|
|
|
|
font-size: 14px;
|
|
|
|
|
color: var(--text);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
.card-actions {
|
|
|
|
|
display: flex;
|
|
|
|
|
flex-wrap: wrap;
|
|
|
|
|
gap: 8px;
|
|
|
|
|
margin-top: 12px;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
.empty {
|
2026-02-11 12:26:25 -05:00
|
|
|
background: var(--empty-bg);
|
2026-02-11 11:57:27 -05:00
|
|
|
border: 1px dashed var(--line);
|
|
|
|
|
border-radius: 14px;
|
|
|
|
|
padding: 26px;
|
|
|
|
|
text-align: center;
|
|
|
|
|
color: var(--muted);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
.modal {
|
|
|
|
|
position: fixed;
|
|
|
|
|
inset: 0;
|
|
|
|
|
display: none;
|
|
|
|
|
align-items: center;
|
|
|
|
|
justify-content: center;
|
2026-02-11 12:26:25 -05:00
|
|
|
background: var(--modal-backdrop);
|
2026-02-11 11:57:27 -05:00
|
|
|
backdrop-filter: blur(4px);
|
|
|
|
|
z-index: 40;
|
|
|
|
|
padding: 16px;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
.modal.open { display: flex; }
|
|
|
|
|
|
|
|
|
|
.modal-panel {
|
|
|
|
|
width: min(980px, 100%);
|
|
|
|
|
max-height: 92vh;
|
|
|
|
|
overflow: auto;
|
|
|
|
|
background: var(--surface);
|
|
|
|
|
border-radius: 16px;
|
2026-02-11 12:26:25 -05:00
|
|
|
border: 1px solid var(--modal-border);
|
2026-02-11 11:57:27 -05:00
|
|
|
box-shadow: 0 24px 64px rgba(2, 6, 23, 0.28);
|
|
|
|
|
animation: pop 220ms ease both;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
.modal-header {
|
|
|
|
|
display: flex;
|
|
|
|
|
justify-content: space-between;
|
|
|
|
|
align-items: center;
|
|
|
|
|
gap: 10px;
|
|
|
|
|
border-bottom: 1px solid var(--line);
|
|
|
|
|
padding: 14px 16px;
|
|
|
|
|
position: sticky;
|
|
|
|
|
top: 0;
|
2026-02-11 12:26:25 -05:00
|
|
|
background: var(--modal-header-bg);
|
2026-02-11 11:57:27 -05:00
|
|
|
backdrop-filter: blur(2px);
|
|
|
|
|
z-index: 3;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
.modal-title {
|
|
|
|
|
margin: 0;
|
|
|
|
|
font-family: "Sora", "Space Grotesk", sans-serif;
|
|
|
|
|
font-size: 18px;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
.modal-body {
|
|
|
|
|
padding: 14px 16px 18px;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
.field-grid {
|
|
|
|
|
display: grid;
|
|
|
|
|
grid-template-columns: 1fr 1fr;
|
|
|
|
|
gap: 12px;
|
|
|
|
|
margin-bottom: 12px;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
label {
|
|
|
|
|
display: flex;
|
|
|
|
|
flex-direction: column;
|
|
|
|
|
gap: 6px;
|
|
|
|
|
font-size: 13px;
|
|
|
|
|
color: var(--muted);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
select,
|
|
|
|
|
input[type="checkbox"] {
|
|
|
|
|
font: inherit;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
select {
|
|
|
|
|
padding: 10px;
|
|
|
|
|
border-radius: 10px;
|
2026-02-11 12:26:25 -05:00
|
|
|
border: 1px solid var(--field-border);
|
|
|
|
|
background: var(--field-bg);
|
|
|
|
|
color: var(--field-text);
|
2026-02-11 11:57:27 -05:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
.inline {
|
|
|
|
|
display: flex;
|
|
|
|
|
align-items: center;
|
|
|
|
|
gap: 8px;
|
|
|
|
|
flex-wrap: wrap;
|
|
|
|
|
margin-bottom: 12px;
|
|
|
|
|
font-size: 14px;
|
|
|
|
|
color: var(--muted);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
.detail-grid {
|
|
|
|
|
display: grid;
|
|
|
|
|
grid-template-columns: 1fr 1fr;
|
|
|
|
|
gap: 12px;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
.panel {
|
|
|
|
|
border: 1px solid var(--line);
|
|
|
|
|
border-radius: 12px;
|
|
|
|
|
padding: 10px;
|
|
|
|
|
background: var(--surface-soft);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
.panel h3 {
|
|
|
|
|
margin: 0 0 8px;
|
|
|
|
|
font-size: 13px;
|
|
|
|
|
text-transform: uppercase;
|
|
|
|
|
letter-spacing: 0.06em;
|
|
|
|
|
color: var(--brand);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
.mono {
|
|
|
|
|
margin: 0;
|
|
|
|
|
font-family: ui-monospace, SFMono-Regular, Menlo, Consolas, monospace;
|
|
|
|
|
font-size: 12px;
|
|
|
|
|
line-height: 1.42;
|
|
|
|
|
white-space: pre-wrap;
|
2026-02-11 12:26:25 -05:00
|
|
|
color: var(--mono-text);
|
2026-02-11 11:57:27 -05:00
|
|
|
max-height: 260px;
|
|
|
|
|
overflow: auto;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
.scoreboard {
|
|
|
|
|
margin: 0 0 12px;
|
|
|
|
|
font-family: "Sora", "Space Grotesk", sans-serif;
|
|
|
|
|
font-size: 17px;
|
|
|
|
|
padding: 10px 12px;
|
|
|
|
|
border: 1px solid var(--line);
|
|
|
|
|
border-radius: 12px;
|
2026-02-11 12:26:25 -05:00
|
|
|
background: var(--scoreboard-bg);
|
2026-02-11 11:57:27 -05:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
@keyframes rise {
|
|
|
|
|
from { opacity: 0; transform: translateY(8px); }
|
|
|
|
|
to { opacity: 1; transform: translateY(0); }
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
@keyframes pop {
|
|
|
|
|
from { opacity: 0; transform: translateY(10px) scale(0.98); }
|
|
|
|
|
to { opacity: 1; transform: translateY(0) scale(1); }
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
@media (max-width: 920px) {
|
|
|
|
|
.hero,
|
|
|
|
|
.detail-grid,
|
|
|
|
|
.field-grid {
|
|
|
|
|
grid-template-columns: 1fr;
|
|
|
|
|
}
|
|
|
|
|
|
2026-02-11 12:26:25 -05:00
|
|
|
.toolbar {
|
|
|
|
|
align-items: flex-start;
|
|
|
|
|
flex-direction: column;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
.toolbar-actions {
|
|
|
|
|
width: 100%;
|
|
|
|
|
justify-content: space-between;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
.theme-control select {
|
|
|
|
|
min-width: 160px;
|
|
|
|
|
}
|
|
|
|
|
|
2026-02-11 11:57:27 -05:00
|
|
|
.app { padding: 18px 12px 32px; }
|
|
|
|
|
}
|
|
|
|
|
</style>
|
2025-10-20 21:32:45 -04:00
|
|
|
</head>
|
|
|
|
|
<body>
|
2026-02-11 11:57:27 -05:00
|
|
|
<main class="app">
|
|
|
|
|
<section class="hero">
|
|
|
|
|
<article class="hero-card">
|
|
|
|
|
<p class="eyebrow">Rust Backend</p>
|
|
|
|
|
<h1>SoccerCloud Web Control Room</h1>
|
|
|
|
|
<p class="lead">A modern web frontend backed by the same Rust simulation engine used in CLI and TUI modes.</p>
|
|
|
|
|
</article>
|
|
|
|
|
<article class="hero-card">
|
|
|
|
|
<div class="stat-grid">
|
|
|
|
|
<div class="stat">
|
|
|
|
|
<div class="label">Instances</div>
|
|
|
|
|
<div class="value" id="statInstances">0</div>
|
|
|
|
|
</div>
|
|
|
|
|
<div class="stat">
|
|
|
|
|
<div class="label">Running</div>
|
|
|
|
|
<div class="value" id="statRunning">0</div>
|
|
|
|
|
</div>
|
|
|
|
|
<div class="stat">
|
|
|
|
|
<div class="label">Completed</div>
|
|
|
|
|
<div class="value" id="statCompleted">0</div>
|
|
|
|
|
</div>
|
|
|
|
|
<div class="stat">
|
|
|
|
|
<div class="label">Available Teams</div>
|
|
|
|
|
<div class="value" id="statTeams">0</div>
|
|
|
|
|
</div>
|
2025-10-20 21:32:45 -04:00
|
|
|
</div>
|
2026-02-11 11:57:27 -05:00
|
|
|
</article>
|
2025-10-20 21:32:45 -04:00
|
|
|
</section>
|
|
|
|
|
|
2026-02-11 11:57:27 -05:00
|
|
|
<div class="toolbar">
|
|
|
|
|
<p class="status-text" id="statusText">Connecting to backend...</p>
|
2026-02-11 12:26:25 -05:00
|
|
|
<div class="toolbar-actions">
|
|
|
|
|
<label class="theme-control" for="themeSelect">
|
|
|
|
|
Options / Theme
|
|
|
|
|
<select id="themeSelect">
|
|
|
|
|
<option value="default-light">Default (Light)</option>
|
|
|
|
|
<option value="dark">Dark</option>
|
|
|
|
|
<option value="matcha">Matcha</option>
|
|
|
|
|
<option value="black-mesa">Black Mesa</option>
|
|
|
|
|
</select>
|
|
|
|
|
</label>
|
|
|
|
|
<button class="btn" id="openCreateBtn" type="button">Create Simulation</button>
|
|
|
|
|
</div>
|
2026-02-11 11:57:27 -05:00
|
|
|
</div>
|
|
|
|
|
|
|
|
|
|
<section class="dashboard" id="dashboard"></section>
|
|
|
|
|
</main>
|
|
|
|
|
|
|
|
|
|
<div class="modal" id="createModal" aria-hidden="true">
|
|
|
|
|
<div class="modal-panel">
|
2025-10-20 21:32:45 -04:00
|
|
|
<div class="modal-header">
|
2026-02-11 11:57:27 -05:00
|
|
|
<h2 class="modal-title">Create Simulation</h2>
|
|
|
|
|
<button class="btn secondary" data-close="createModal" type="button">Close</button>
|
2025-10-20 21:32:45 -04:00
|
|
|
</div>
|
|
|
|
|
<div class="modal-body">
|
2026-02-11 11:57:27 -05:00
|
|
|
<div class="field-grid">
|
|
|
|
|
<label>
|
|
|
|
|
Mode
|
2025-10-20 21:32:45 -04:00
|
|
|
<select id="modeSelect">
|
|
|
|
|
<option value="single">Single Match</option>
|
2026-02-11 11:57:27 -05:00
|
|
|
<option value="league4">4-Team League</option>
|
|
|
|
|
<option value="knockout4">4-Team Knockout</option>
|
|
|
|
|
</select>
|
|
|
|
|
</label>
|
|
|
|
|
<label>
|
|
|
|
|
Team Count
|
|
|
|
|
<select id="teamCount" disabled>
|
|
|
|
|
<option value="2">2</option>
|
2025-10-20 21:32:45 -04:00
|
|
|
</select>
|
|
|
|
|
</label>
|
|
|
|
|
</div>
|
2026-02-11 11:57:27 -05:00
|
|
|
|
|
|
|
|
<label class="inline">
|
|
|
|
|
<input id="autoFill" type="checkbox" checked />
|
|
|
|
|
Auto-fill missing teams using deterministic Rust seed
|
|
|
|
|
</label>
|
|
|
|
|
|
|
|
|
|
<div class="field-grid" id="teamSelectWrap"></div>
|
|
|
|
|
|
|
|
|
|
<button class="btn" id="createBtn" type="button">Create Instance</button>
|
2025-10-20 21:32:45 -04:00
|
|
|
</div>
|
|
|
|
|
</div>
|
|
|
|
|
</div>
|
|
|
|
|
|
2026-02-11 11:57:27 -05:00
|
|
|
<div class="modal" id="detailModal" aria-hidden="true">
|
|
|
|
|
<div class="modal-panel">
|
2025-10-20 21:32:45 -04:00
|
|
|
<div class="modal-header">
|
2026-02-11 11:57:27 -05:00
|
|
|
<h2 class="modal-title" id="detailTitle">Simulation Detail</h2>
|
|
|
|
|
<button class="btn secondary" data-close="detailModal" type="button">Close</button>
|
2025-10-20 21:32:45 -04:00
|
|
|
</div>
|
|
|
|
|
<div class="modal-body">
|
2026-02-11 11:57:27 -05:00
|
|
|
<p class="scoreboard" id="detailScoreboard">Waiting for updates...</p>
|
|
|
|
|
<div class="detail-grid">
|
|
|
|
|
<section class="panel">
|
|
|
|
|
<h3>Match Log</h3>
|
|
|
|
|
<pre class="mono" id="detailLogs"></pre>
|
|
|
|
|
</section>
|
|
|
|
|
<section class="panel">
|
|
|
|
|
<h3>Stats</h3>
|
|
|
|
|
<pre class="mono" id="detailStats"></pre>
|
|
|
|
|
</section>
|
|
|
|
|
<section class="panel">
|
|
|
|
|
<h3>Competition</h3>
|
|
|
|
|
<pre class="mono" id="detailCompetition"></pre>
|
|
|
|
|
</section>
|
|
|
|
|
<section class="panel">
|
|
|
|
|
<h3>History</h3>
|
|
|
|
|
<pre class="mono" id="detailHistory"></pre>
|
|
|
|
|
</section>
|
|
|
|
|
</div>
|
2025-10-20 21:32:45 -04:00
|
|
|
</div>
|
|
|
|
|
</div>
|
|
|
|
|
</div>
|
|
|
|
|
|
2026-02-11 11:57:27 -05:00
|
|
|
<script src="data.js"></script>
|
2025-10-20 21:32:45 -04:00
|
|
|
</body>
|
|
|
|
|
</html>
|