-
![]()
-
- Right image
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
![]()
+
+ Right image
+
-
-
-
-
-
@@ -1123,14 +1217,22 @@ watch(
.scoreboard-preview__side {
display: flex;
- flex-direction: column;
- gap: 8px;
- align-items: flex-start;
+ align-items: center;
+}
+
+.scoreboard-preview__side-inner {
+ width: 100%;
+ display: flex;
+ align-items: center;
+ gap: 10px;
}
.scoreboard-preview__side--right {
text-align: right;
- align-items: flex-end;
+}
+
+.scoreboard-preview__side--right .scoreboard-preview__side-inner {
+ justify-content: flex-end;
}
.scoreboard-preview__image-wrap {
@@ -1161,15 +1263,8 @@ watch(
font-weight: 600;
}
-.scoreboard-preview__name {
- font-size: 1.1rem;
- font-weight: 700;
- line-height: 1.2;
-}
-
-
.scoreboard-preview__controls {
- width: min(100%, 320px);
+ width: min(100%, 260px);
display: flex;
flex-direction: column;
gap: 6px;
@@ -1268,9 +1363,17 @@ watch(
width: min(100%, 280px);
}
+ .scoreboard-preview__side-inner {
+ flex-direction: column;
+ align-items: flex-start;
+ }
+
.scoreboard-preview__side--right {
text-align: left;
- align-items: flex-start;
+ }
+
+ .scoreboard-preview__side--right .scoreboard-preview__side-inner {
+ justify-content: flex-start;
}
}
From 0d40b8ed6a7e59c979b5acc2e606a6f8a844bb5b Mon Sep 17 00:00:00 2001
From: Pandipipas <62224708+Pandipipas@users.noreply.github.com>
Date: Fri, 13 Feb 2026 00:54:44 +0100
Subject: [PATCH 03/10] Center preview metadata between image and score
---
src/dashboard/example/components/ScoreboardPanel.vue | 12 +++++++-----
1 file changed, 7 insertions(+), 5 deletions(-)
diff --git a/src/dashboard/example/components/ScoreboardPanel.vue b/src/dashboard/example/components/ScoreboardPanel.vue
index 5e1ae49..02c81a8 100644
--- a/src/dashboard/example/components/ScoreboardPanel.vue
+++ b/src/dashboard/example/components/ScoreboardPanel.vue
@@ -1222,9 +1222,10 @@ watch(
.scoreboard-preview__side-inner {
width: 100%;
- display: flex;
+ display: grid;
+ grid-template-columns: auto minmax(0, 1fr);
align-items: center;
- gap: 10px;
+ gap: 12px;
}
.scoreboard-preview__side--right {
@@ -1232,7 +1233,7 @@ watch(
}
.scoreboard-preview__side--right .scoreboard-preview__side-inner {
- justify-content: flex-end;
+ grid-template-columns: minmax(0, 1fr) auto;
}
.scoreboard-preview__image-wrap {
@@ -1265,6 +1266,7 @@ watch(
.scoreboard-preview__controls {
width: min(100%, 260px);
+ justify-self: center;
display: flex;
flex-direction: column;
gap: 6px;
@@ -1364,7 +1366,7 @@ watch(
}
.scoreboard-preview__side-inner {
- flex-direction: column;
+ grid-template-columns: 1fr;
align-items: flex-start;
}
@@ -1373,7 +1375,7 @@ watch(
}
.scoreboard-preview__side--right .scoreboard-preview__side-inner {
- justify-content: flex-start;
+ grid-template-columns: 1fr;
}
}
From 63c4daf7416d7462f7ec09205e748137f9f52616 Mon Sep 17 00:00:00 2001
From: Pandipipas <62224708+Pandipipas@users.noreply.github.com>
Date: Fri, 13 Feb 2026 01:02:26 +0100
Subject: [PATCH 04/10] Fix preview spacing so controls sit between image and
score
---
.../example/components/ScoreboardPanel.vue | 20 +++++++++----------
1 file changed, 10 insertions(+), 10 deletions(-)
diff --git a/src/dashboard/example/components/ScoreboardPanel.vue b/src/dashboard/example/components/ScoreboardPanel.vue
index 02c81a8..5872b50 100644
--- a/src/dashboard/example/components/ScoreboardPanel.vue
+++ b/src/dashboard/example/components/ScoreboardPanel.vue
@@ -1209,8 +1209,8 @@ watch(
.scoreboard-preview {
display: grid;
- grid-template-columns: minmax(0, 1fr) auto minmax(0, 1fr);
- gap: 10px;
+ grid-template-columns: minmax(0, 1fr) minmax(320px, auto) minmax(0, 1fr);
+ gap: 18px;
padding: 16px;
align-items: center;
}
@@ -1222,10 +1222,10 @@ watch(
.scoreboard-preview__side-inner {
width: 100%;
- display: grid;
- grid-template-columns: auto minmax(0, 1fr);
+ display: flex;
align-items: center;
- gap: 12px;
+ justify-content: space-between;
+ gap: 14px;
}
.scoreboard-preview__side--right {
@@ -1233,7 +1233,7 @@ watch(
}
.scoreboard-preview__side--right .scoreboard-preview__side-inner {
- grid-template-columns: minmax(0, 1fr) auto;
+ justify-content: space-between;
}
.scoreboard-preview__image-wrap {
@@ -1266,7 +1266,6 @@ watch(
.scoreboard-preview__controls {
width: min(100%, 260px);
- justify-self: center;
display: flex;
flex-direction: column;
gap: 6px;
@@ -1299,7 +1298,7 @@ watch(
display: flex;
align-items: center;
justify-content: center;
- gap: 10px;
+ gap: 18px;
}
.scoreboard-preview__score-side {
@@ -1366,8 +1365,9 @@ watch(
}
.scoreboard-preview__side-inner {
- grid-template-columns: 1fr;
+ flex-direction: column;
align-items: flex-start;
+ justify-content: flex-start;
}
.scoreboard-preview__side--right {
@@ -1375,7 +1375,7 @@ watch(
}
.scoreboard-preview__side--right .scoreboard-preview__side-inner {
- grid-template-columns: 1fr;
+ justify-content: flex-start;
}
}
From 818ac56f533913a27f6527430ddc6bba1906f277 Mon Sep 17 00:00:00 2001
From: Pandipipas <62224708+Pandipipas@users.noreply.github.com>
Date: Fri, 13 Feb 2026 01:08:24 +0100
Subject: [PATCH 05/10] Stabilize preview control centering across zoom levels
---
.../example/components/ScoreboardPanel.vue | 22 ++++++++++++++-----
1 file changed, 16 insertions(+), 6 deletions(-)
diff --git a/src/dashboard/example/components/ScoreboardPanel.vue b/src/dashboard/example/components/ScoreboardPanel.vue
index 5872b50..0bb2f0f 100644
--- a/src/dashboard/example/components/ScoreboardPanel.vue
+++ b/src/dashboard/example/components/ScoreboardPanel.vue
@@ -1222,9 +1222,9 @@ watch(
.scoreboard-preview__side-inner {
width: 100%;
- display: flex;
+ display: grid;
+ grid-template-columns: minmax(220px, 320px) minmax(180px, 1fr);
align-items: center;
- justify-content: space-between;
gap: 14px;
}
@@ -1233,7 +1233,16 @@ watch(
}
.scoreboard-preview__side--right .scoreboard-preview__side-inner {
- justify-content: space-between;
+ grid-template-columns: minmax(180px, 1fr) minmax(220px, 320px);
+}
+
+
+.scoreboard-preview__side .scoreboard-preview__image-wrap {
+ justify-self: start;
+}
+
+.scoreboard-preview__side--right .scoreboard-preview__image-wrap {
+ justify-self: end;
}
.scoreboard-preview__image-wrap {
@@ -1266,6 +1275,7 @@ watch(
.scoreboard-preview__controls {
width: min(100%, 260px);
+ justify-self: center;
display: flex;
flex-direction: column;
gap: 6px;
@@ -1365,9 +1375,9 @@ watch(
}
.scoreboard-preview__side-inner {
- flex-direction: column;
+ grid-template-columns: 1fr;
align-items: flex-start;
- justify-content: flex-start;
+ justify-items: flex-start;
}
.scoreboard-preview__side--right {
@@ -1375,7 +1385,7 @@ watch(
}
.scoreboard-preview__side--right .scoreboard-preview__side-inner {
- justify-content: flex-start;
+ grid-template-columns: 1fr;
}
}
From 26855eb43f679973984d4ada9a9117836b90fe85 Mon Sep 17 00:00:00 2001
From: Pandipipas <62224708+Pandipipas@users.noreply.github.com>
Date: Fri, 13 Feb 2026 14:08:40 +0100
Subject: [PATCH 06/10] Add character selectors under preview images and center
actions
---
.../example/components/ScoreboardPanel.vue | 199 ++++++++++++------
1 file changed, 139 insertions(+), 60 deletions(-)
diff --git a/src/dashboard/example/components/ScoreboardPanel.vue b/src/dashboard/example/components/ScoreboardPanel.vue
index 0bb2f0f..98b4b2f 100644
--- a/src/dashboard/example/components/ScoreboardPanel.vue
+++ b/src/dashboard/example/components/ScoreboardPanel.vue
@@ -648,19 +648,39 @@ watch(
>
-
-
![]()
-
- Left image
+
+
+
![]()
+
+ Left image
+
+
-
-
-
-
{{ scoreboardStore.scoreboard.leftScore }}
-
+
+
+
+
+ {{ scoreboardStore.scoreboard.leftScore }}
+
+
+
+
-
+
+
+
+ {{ scoreboardStore.scoreboard.rightScore }}
+
+
-
-
-
-
+
- {{ scoreboardStore.scoreboard.rightScore }}
@@ -873,19 +912,39 @@ watch(
-
-
![]()
-
- Right image
+
+
+
![]()
+
+ Right image
+
+
@@ -1220,6 +1279,13 @@ watch(
align-items: center;
}
+.scoreboard-preview__image-column {
+ width: min(100%, 320px);
+ display: flex;
+ flex-direction: column;
+ gap: 8px;
+}
+
.scoreboard-preview__side-inner {
width: 100%;
display: grid;
@@ -1237,11 +1303,11 @@ watch(
}
-.scoreboard-preview__side .scoreboard-preview__image-wrap {
+.scoreboard-preview__side .scoreboard-preview__image-column {
justify-self: start;
}
-.scoreboard-preview__side--right .scoreboard-preview__image-wrap {
+.scoreboard-preview__side--right .scoreboard-preview__image-column {
justify-self: end;
}
@@ -1304,6 +1370,13 @@ watch(
color: rgba(255, 255, 255, 0.92);
}
+.scoreboard-preview__center {
+ display: flex;
+ flex-direction: column;
+ align-items: center;
+ gap: 10px;
+}
+
.scoreboard-preview__score-controls {
display: flex;
align-items: center;
@@ -1311,6 +1384,12 @@ watch(
gap: 18px;
}
+.scoreboard-preview__actions {
+ display: flex;
+ align-items: center;
+ gap: 10px;
+}
+
.scoreboard-preview__score-side {
display: inline-flex;
flex-direction: column;
@@ -1365,7 +1444,7 @@ watch(
gap: 12px;
}
- .scoreboard-preview__score-controls {
+ .scoreboard-preview__center {
order: -1;
justify-self: center;
}
From 1fda5c99e8b28e5a13b0f493c9dae17be8258332 Mon Sep 17 00:00:00 2001
From: Pandipipas <62224708+Pandipipas@users.noreply.github.com>
Date: Fri, 13 Feb 2026 14:17:24 +0100
Subject: [PATCH 07/10] Tune preview action icons and character filter behavior
---
.../example/components/ScoreboardPanel.vue | 61 ++++++++++++++++---
1 file changed, 53 insertions(+), 8 deletions(-)
diff --git a/src/dashboard/example/components/ScoreboardPanel.vue b/src/dashboard/example/components/ScoreboardPanel.vue
index 98b4b2f..f04f02e 100644
--- a/src/dashboard/example/components/ScoreboardPanel.vue
+++ b/src/dashboard/example/components/ScoreboardPanel.vue
@@ -41,6 +41,9 @@ const fightingGameOptions = [
}));
const characterOptions = computed(() => getCharactersByGame(scoreboardStore.scoreboard.game));
+type CharacterOption = ReturnType
[number];
+const leftCharacterOptions = ref([]);
+const rightCharacterOptions = ref([]);
const leftCharacterImage = computed(() => {
const match = characterOptions.value.find((option) => option.value === scoreboardStore.scoreboard.leftCharacter);
@@ -93,6 +96,30 @@ const onRightCountryFilter = (value: string, update: (callback: () => void) => v
filterCountries(value, update, rightCountryOptions);
};
+
+const filterCharacters = (
+ value: string,
+ update: (callback: () => void) => void,
+ target: Ref,
+) => {
+ update(() => {
+ const needle = value.toLowerCase().trim();
+ if (!needle) {
+ target.value = characterOptions.value;
+ return;
+ }
+ target.value = characterOptions.value.filter((character) => character.label.toLowerCase().includes(needle));
+ });
+};
+
+const onLeftCharacterFilter = (value: string, update: (callback: () => void) => void) => {
+ filterCharacters(value, update, leftCharacterOptions);
+};
+
+const onRightCharacterFilter = (value: string, update: (callback: () => void) => void) => {
+ filterCharacters(value, update, rightCharacterOptions);
+};
+
const playerOptions = computed(() => {
const base = [{ label: '(Sin asignar)', value: '' }];
const entries = Object.entries(playersStore.players) as [string, Schemas.Players[string]][];
@@ -598,6 +625,8 @@ watch(
() => scoreboardStore.scoreboard.game,
() => {
const options = getCharactersByGame(scoreboardStore.scoreboard.game);
+ leftCharacterOptions.value = options;
+ rightCharacterOptions.value = options;
const allowed = new Set(options.map((option) => option.value));
if (!allowed.has(scoreboardStore.scoreboard.leftCharacter)) {
@@ -666,7 +695,7 @@ watch(
@@ -813,17 +843,17 @@ watch(
@@ -930,7 +960,7 @@ watch(
@@ -1351,6 +1382,10 @@ watch(
margin: 0;
}
+.scoreboard-preview__character-field {
+ margin-top: 2px;
+}
+
.scoreboard-preview__field :deep(.q-field__control) {
min-height: 28px;
padding: 0;
@@ -1390,6 +1425,16 @@ watch(
gap: 10px;
}
+.scoreboard-preview__action-btn {
+ color: #fff;
+ opacity: 0.85;
+}
+
+.scoreboard-preview__action-btn:hover {
+ opacity: 1;
+ text-shadow: 0 0 10px rgba(255, 255, 255, 0.45);
+}
+
.scoreboard-preview__score-side {
display: inline-flex;
flex-direction: column;
From 494a6c42a6f26920c8a9fae84680aa7a772a3e96 Mon Sep 17 00:00:00 2001
From: Pandipipas <62224708+Pandipipas@users.noreply.github.com>
Date: Fri, 13 Feb 2026 14:48:45 +0100
Subject: [PATCH 08/10] Add underlined game selector with typed filtering in
preview center
---
.../example/components/ScoreboardPanel.vue | 46 ++++++++++++++++++-
1 file changed, 45 insertions(+), 1 deletion(-)
diff --git a/src/dashboard/example/components/ScoreboardPanel.vue b/src/dashboard/example/components/ScoreboardPanel.vue
index f04f02e..4a0c3f0 100644
--- a/src/dashboard/example/components/ScoreboardPanel.vue
+++ b/src/dashboard/example/components/ScoreboardPanel.vue
@@ -26,8 +26,9 @@ const rightCountryOptions = ref(countryOptions);
const leftCharacterInput = ref('');
const rightCharacterInput = ref('');
+const gameInput = ref('');
-const fightingGameOptions = [
+const allFightingGameOptions = [
'Street Fighter 6',
'TEKKEN 8',
'Guilty Gear -Strive-',
@@ -40,6 +41,8 @@ const fightingGameOptions = [
value: game,
}));
+const fightingGameOptions = ref(allFightingGameOptions);
+
const characterOptions = computed(() => getCharactersByGame(scoreboardStore.scoreboard.game));
type CharacterOption = ReturnType
[number];
const leftCharacterOptions = ref([]);
@@ -120,6 +123,17 @@ const onRightCharacterFilter = (value: string, update: (callback: () => void) =>
filterCharacters(value, update, rightCharacterOptions);
};
+const onGameFilter = (value: string, update: (callback: () => void) => void) => {
+ update(() => {
+ const needle = value.toLowerCase().trim();
+ if (!needle) {
+ fightingGameOptions.value = allFightingGameOptions;
+ return;
+ }
+ fightingGameOptions.value = allFightingGameOptions.filter((game) => game.label.toLowerCase().includes(needle));
+ });
+};
+
const playerOptions = computed(() => {
const base = [{ label: '(Sin asignar)', value: '' }];
const entries = Object.entries(playersStore.players) as [string, Schemas.Players[string]][];
@@ -621,6 +635,16 @@ watchEffect(() => {
}
});
+
+watch(
+ () => scoreboardStore.scoreboard.game,
+ (value) => {
+ const match = allFightingGameOptions.find((option) => option.value === value);
+ gameInput.value = match?.label ?? '';
+ },
+ { immediate: true },
+);
+
watch(
() => scoreboardStore.scoreboard.game,
() => {
@@ -797,6 +821,22 @@ watch(
+
+
Date: Fri, 13 Feb 2026 14:54:59 +0100
Subject: [PATCH 09/10] Pin preview game selector to top with larger score gap
---
src/dashboard/example/components/ScoreboardPanel.vue | 4 ++++
1 file changed, 4 insertions(+)
diff --git a/src/dashboard/example/components/ScoreboardPanel.vue b/src/dashboard/example/components/ScoreboardPanel.vue
index 4a0c3f0..9b77e4a 100644
--- a/src/dashboard/example/components/ScoreboardPanel.vue
+++ b/src/dashboard/example/components/ScoreboardPanel.vue
@@ -1449,11 +1449,15 @@ watch(
display: flex;
flex-direction: column;
align-items: center;
+ align-self: stretch;
+ justify-content: flex-start;
+ padding-top: 2px;
gap: 10px;
}
.scoreboard-preview__game-field {
width: min(100%, 240px);
+ margin-bottom: 56px;
}
.scoreboard-preview__score-controls {
From 6756832f33b9408c1443580acbaf60a0f232cf2a Mon Sep 17 00:00:00 2001
From: Pandipipas <62224708+Pandipipas@users.noreply.github.com>
Date: Fri, 13 Feb 2026 15:01:09 +0100
Subject: [PATCH 10/10] Remove legacy side panels and old center controls
---
.../example/components/ScoreboardPanel.vue | 347 +-----------------
1 file changed, 4 insertions(+), 343 deletions(-)
diff --git a/src/dashboard/example/components/ScoreboardPanel.vue b/src/dashboard/example/components/ScoreboardPanel.vue
index 9b77e4a..596ee88 100644
--- a/src/dashboard/example/components/ScoreboardPanel.vue
+++ b/src/dashboard/example/components/ScoreboardPanel.vue
@@ -1020,312 +1020,6 @@ watch(
-
-
-
-
-
-
- Left side
-
-
-
-
-
-
-
-
-
-
-
-
![Left character preview]()
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- Right side
-
-
-
-
-
-
-
-
-
-
-
-
![Right character preview]()
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
@@ -1504,31 +1198,11 @@ watch(
font-weight: 700;
}
-.scoreboard-grid {
- display: grid;
- grid-template-columns: 1fr;
- gap: 24px;
- align-items: start;
-}
-.scoreboard-grid__side,
-.scoreboard-grid__center {
- min-width: 0;
-}
-
-.character-preview {
- width: 100%;
- border-radius: 8px;
- overflow: hidden;
- border: 1px solid rgba(255, 255, 255, 0.12);
- background: rgba(0, 0, 0, 0.25);
-}
-
-.character-preview img {
- display: block;
- width: 100%;
- height: 88px;
- object-fit: cover;
+@media (min-width: 1024px) {
+ .scoreboard-preview {
+ grid-template-columns: minmax(0, 1fr) minmax(320px, auto) minmax(0, 1fr);
+ }
}
@media (max-width: 900px) {
@@ -1561,17 +1235,4 @@ watch(
}
}
-@media (min-width: 1024px) {
- .scoreboard-preview {
- grid-template-columns: minmax(0, 1fr) auto minmax(0, 1fr);
- }
-
- .scoreboard-grid {
- grid-template-columns: minmax(0, 1fr) auto minmax(0, 1fr);
- }
-
- .scoreboard-grid__center {
- width: 220px;
- }
-}