diff --git a/server/src/html/mod.rs b/server/src/html/mod.rs
index dcf05df143825f4f8ba9ee3b3b5f8ab2e69950c7..588cf62bcea608ed4ede363810f022a67b43b960 100644
--- a/server/src/html/mod.rs
+++ b/server/src/html/mod.rs
@@ -529,5 +529,6 @@ mod tests {
assert!(SORTER_UI_JS.contains("var divisor = gcd(left, right)"));
assert!(SORTER_UI_JS.contains("ratioDisplay.textContent = left + ':' + right"));
assert!(SORTER_UI_JS.contains("--vote-slider-pct"));
+ assert!(SORTER_UI_JS.contains("dataset.winner"));
}
}
diff --git a/server/src/html/vote.rs b/server/src/html/vote.rs
index 872d23ddf6c18fab016a624de85736fdc2dcde63..d32b206e2fb043466c0ce333d7d215dc1a3e91c9 100644
--- a/server/src/html/vote.rs
+++ b/server/src/html/vote.rs
@@ -154,6 +154,7 @@ fn vote_hud_form(
}
label class="vote-hud-slider" {
input type="range" id="vote-preference-slider" min="0" max="100" value="50"
+ data-winner="left"
aria-valuemin="0" aria-valuemax="100" aria-valuenow="50"
aria-label=(format!("Preference: {} vs {}", left.as_str(), right.as_str()));
}
diff --git a/server/static/sorter.css b/server/static/sorter.css
index 50e34484c2b50d2eeb18f8d0ec4f34338363811a..7b485dd232f60363f4eff0c5a362addf191d05c6 100644
--- a/server/static/sorter.css
+++ b/server/static/sorter.css
@@ -316,9 +316,12 @@ h1 {
max-width: 56rem;
margin: 0 auto;
display: grid;
- grid-template-columns: min-content minmax(0, 1fr) auto;
+ /* Fixed side columns so ratio text / buttons never resize the slider track. */
+ grid-template-columns: var(--vote-ratio-col) minmax(0, 1fr) var(--vote-actions-col);
gap: 0.5rem 0.65rem;
align-items: center;
+ --vote-ratio-col: 3.25rem;
+ --vote-actions-col: 11.5rem;
}
.vote-hud #vote-compare-form {
@@ -327,13 +330,23 @@ h1 {
.vote-hud .vote-ratio-readout {
margin: 0;
+ width: var(--vote-ratio-col);
+ min-width: var(--vote-ratio-col);
text-align: center;
+ white-space: nowrap;
+}
+
+.vote-hud .vote-ratio-readout .small {
+ display: none;
}
.vote-hud .vote-compare-actions {
margin-top: 0;
justify-content: flex-end;
gap: 0.5rem;
+ width: var(--vote-actions-col);
+ min-width: var(--vote-actions-col);
+ flex-shrink: 0;
}
.vote-hud .btn-primary,
@@ -416,15 +429,13 @@ h1 {
}
.vote-hud .vote-ratio-readout strong {
+ display: inline-block;
+ min-width: 3ch;
color: var(--accent);
font-variant-numeric: tabular-nums;
font-size: 1.1rem;
}
-.vote-hud .vote-ratio-readout .small {
- font-size: 0.75rem;
-}
-
.vote-compare-next {
color: var(--accent);
text-decoration: none;
@@ -459,7 +470,11 @@ h1 {
cursor: pointer;
}
-.vote-hud-slider input[type="range"]::-webkit-slider-runnable-track {
+.vote-hud-slider input[type="range"] {
+ --vote-track-muted: color-mix(in oklch, var(--muted) 55%, var(--bg));
+}
+
+.vote-hud-slider input[type="range"][data-winner="left"]::-webkit-slider-runnable-track {
height: 0.65rem;
border-radius: 0;
border: 2px solid var(--border);
@@ -467,8 +482,21 @@ h1 {
to right,
var(--accent) 0%,
var(--accent) var(--vote-slider-pct, 50%),
- color-mix(in oklch, var(--muted) 55%, var(--bg)) var(--vote-slider-pct, 50%),
- color-mix(in oklch, var(--muted) 55%, var(--bg)) 100%
+ var(--vote-track-muted) var(--vote-slider-pct, 50%),
+ var(--vote-track-muted) 100%
+ );
+}
+
+.vote-hud-slider input[type="range"][data-winner="right"]::-webkit-slider-runnable-track {
+ height: 0.65rem;
+ border-radius: 0;
+ border: 2px solid var(--border);
+ background: linear-gradient(
+ to right,
+ var(--vote-track-muted) 0%,
+ var(--vote-track-muted) var(--vote-slider-pct, 50%),
+ var(--accent) var(--vote-slider-pct, 50%),
+ var(--accent) 100%
);
}
@@ -484,17 +512,35 @@ h1 {
box-shadow: 0 2px 0 rgba(0, 0, 0, 0.35);
}
-.vote-hud-slider input[type="range"]::-moz-range-track {
+.vote-hud-slider input[type="range"][data-winner="left"]::-moz-range-track,
+.vote-hud-slider input[type="range"][data-winner="right"]::-moz-range-track {
height: 0.65rem;
border-radius: 0;
border: 2px solid var(--border);
- background: color-mix(in oklch, var(--muted) 55%, var(--bg));
+}
+
+.vote-hud-slider input[type="range"][data-winner="left"]::-moz-range-track {
+ background: linear-gradient(
+ to right,
+ var(--accent) 0%,
+ var(--accent) var(--vote-slider-pct, 50%),
+ var(--vote-track-muted) var(--vote-slider-pct, 50%),
+ var(--vote-track-muted) 100%
+ );
+}
+
+.vote-hud-slider input[type="range"][data-winner="right"]::-moz-range-track {
+ background: linear-gradient(
+ to right,
+ var(--vote-track-muted) 0%,
+ var(--vote-track-muted) var(--vote-slider-pct, 50%),
+ var(--accent) var(--vote-slider-pct, 50%),
+ var(--accent) 100%
+ );
}
.vote-hud-slider input[type="range"]::-moz-range-progress {
- height: 0.65rem;
- border-radius: 0;
- background: var(--accent);
+ background: transparent;
}
.vote-hud-slider input[type="range"]::-moz-range-thumb {
@@ -563,6 +609,14 @@ h1 {
grid-template-columns: 1fr;
grid-template-rows: auto auto auto;
gap: 0.35rem;
+ --vote-ratio-col: 100%;
+ --vote-actions-col: 100%;
+ }
+
+ .vote-hud .vote-ratio-readout,
+ .vote-hud .vote-compare-actions {
+ width: auto;
+ min-width: 0;
}
.vote-hud .vote-compare-actions {
diff --git a/server/static/sorter_ui.js b/server/static/sorter_ui.js
index c438851b792ad85f8b6106b7c3fad9ea945275f7..f665b45f4fd4771427dc4c37e563e4976873beee 100644
--- a/server/static/sorter_ui.js
+++ b/server/static/sorter_ui.js
@@ -148,6 +148,7 @@
if (leftInput) leftInput.value = String(left);
if (rightInput) rightInput.value = String(right);
if (ratioDisplay) ratioDisplay.textContent = left + ':' + right;
+ slider.dataset.winner = left >= right ? 'left' : 'right';
}
slider.addEventListener('input', update);
update();