Dating — Filters Preferences
A playful mobile-app filters and preferences sheet for a dating product: a dual-handle age range slider, a distance radius slider, gender and looking-for pill toggles, an interests multiselect, and a verified-only switch. A live match counter recalculates on every change, so users instantly see how many people fit their criteria before hitting apply or resetting everything back to defaults.
MCP
Code
:root {
--bg: #fff5f6;
--surface: #ffffff;
--ink: #2a1a2e;
--ink-2: #5a4a55;
--muted: #8a7a85;
--coral: #ff5e6c;
--coral-d: #e63950;
--violet: #8b5cf6;
--violet-d: #7c3aed;
--pink: #ff8fb1;
--grad: linear-gradient(135deg, #ff5e6c, #8b5cf6);
--line: rgba(42, 26, 46, 0.10);
--white: #fff;
--r-sm: 12px;
--r-md: 20px;
--r-lg: 28px;
--shadow: 0 20px 50px -18px rgba(124, 58, 237, 0.35);
}
* { box-sizing: border-box; }
html { -webkit-text-size-adjust: 100%; }
body {
margin: 0;
min-height: 100vh;
font-family: "Inter", system-ui, -apple-system, sans-serif;
line-height: 1.5;
color: var(--ink);
background:
radial-gradient(1200px 500px at 15% -10%, rgba(255, 143, 177, 0.35), transparent 60%),
radial-gradient(1000px 500px at 100% 0%, rgba(139, 92, 246, 0.22), transparent 55%),
var(--bg);
display: flex;
justify-content: center;
align-items: flex-start;
padding: 32px 16px 48px;
-webkit-font-smoothing: antialiased;
-moz-osx-font-smoothing: grayscale;
}
/* Phone frame */
.phone {
width: 100%;
max-width: 430px;
background: var(--surface);
border-radius: var(--r-lg);
box-shadow: var(--shadow);
border: 1px solid var(--line);
overflow: hidden;
display: flex;
flex-direction: column;
max-height: calc(100vh - 64px);
position: relative;
}
/* Header */
.sheet-head {
padding: 14px 22px 16px;
background: var(--grad);
color: var(--white);
flex: 0 0 auto;
}
.grip {
width: 42px;
height: 5px;
border-radius: 99px;
background: rgba(255, 255, 255, 0.55);
margin: 0 auto 12px;
}
.head-row {
display: flex;
align-items: center;
justify-content: space-between;
gap: 12px;
}
.eyebrow {
margin: 0 0 2px;
font-size: 12px;
font-weight: 600;
letter-spacing: 0.06em;
text-transform: uppercase;
color: rgba(255, 255, 255, 0.82);
}
.sheet-head h1 {
margin: 0;
font-family: "Fraunces", serif;
font-size: 24px;
font-weight: 700;
letter-spacing: -0.01em;
}
.spark-badge {
width: 42px;
height: 42px;
border-radius: 50%;
display: grid;
place-items: center;
font-size: 20px;
background: rgba(255, 255, 255, 0.2);
border: 1px solid rgba(255, 255, 255, 0.35);
backdrop-filter: blur(4px);
}
/* Body */
.sheet-body {
padding: 20px 22px 8px;
overflow-y: auto;
flex: 1 1 auto;
display: flex;
flex-direction: column;
gap: 22px;
}
.block {
display: flex;
flex-direction: column;
gap: 12px;
}
.block h2 {
margin: 0;
font-size: 15px;
font-weight: 700;
color: var(--ink);
}
.block-head {
display: flex;
align-items: baseline;
justify-content: space-between;
gap: 12px;
}
.readout {
font-size: 14px;
font-weight: 700;
color: var(--coral-d);
font-variant-numeric: tabular-nums;
}
.readout.muted { color: var(--muted); font-weight: 600; }
/* Range sliders */
.range, .single {
position: relative;
height: 30px;
display: flex;
align-items: center;
}
.range-track {
position: absolute;
left: 0;
right: 0;
height: 7px;
border-radius: 99px;
background: rgba(42, 26, 46, 0.10);
}
.range-fill {
position: absolute;
height: 100%;
border-radius: 99px;
background: var(--grad);
}
.range input[type="range"],
.single input[type="range"] {
position: absolute;
left: 0;
width: 100%;
margin: 0;
background: none;
pointer-events: none;
-webkit-appearance: none;
appearance: none;
height: 30px;
}
.single input[type="range"] { pointer-events: auto; }
input[type="range"]::-webkit-slider-thumb {
-webkit-appearance: none;
appearance: none;
width: 24px;
height: 24px;
border-radius: 50%;
background: var(--white);
border: 3px solid var(--coral);
box-shadow: 0 3px 8px rgba(230, 57, 80, 0.35);
cursor: grab;
pointer-events: auto;
transition: transform 0.12s ease, box-shadow 0.12s ease;
}
input[type="range"]::-moz-range-thumb {
width: 24px;
height: 24px;
border-radius: 50%;
background: var(--white);
border: 3px solid var(--coral);
box-shadow: 0 3px 8px rgba(230, 57, 80, 0.35);
cursor: grab;
pointer-events: auto;
}
input[type="range"]:active::-webkit-slider-thumb { transform: scale(1.12); cursor: grabbing; }
input[type="range"]:focus-visible::-webkit-slider-thumb {
outline: 3px solid rgba(139, 92, 246, 0.5);
outline-offset: 2px;
}
input[type="range"]:focus-visible::-moz-range-thumb {
outline: 3px solid rgba(139, 92, 246, 0.5);
outline-offset: 2px;
}
input[type="range"]::-moz-range-track { background: transparent; }
.scale {
display: flex;
justify-content: space-between;
font-size: 12px;
color: var(--muted);
margin-top: -4px;
}
/* Pills */
.pills {
display: flex;
flex-wrap: wrap;
gap: 10px;
}
.pill {
font: inherit;
font-size: 14px;
font-weight: 600;
padding: 10px 18px;
border-radius: 99px;
border: 1.5px solid var(--line);
background: var(--white);
color: var(--ink-2);
cursor: pointer;
transition: transform 0.12s ease, border-color 0.15s ease, background 0.15s ease, color 0.15s ease;
}
.pill:hover { border-color: var(--pink); transform: translateY(-1px); }
.pill:active { transform: translateY(0) scale(0.97); }
.pill[aria-checked="true"],
.pill[aria-pressed="true"] {
background: var(--grad);
border-color: transparent;
color: var(--white);
box-shadow: 0 6px 14px -4px rgba(230, 57, 80, 0.5);
}
/* Chips */
.chips {
display: flex;
flex-wrap: wrap;
gap: 9px;
}
.chip {
font: inherit;
font-size: 13.5px;
font-weight: 600;
padding: 8px 14px;
border-radius: 99px;
border: 1.5px solid var(--line);
background: var(--white);
color: var(--ink-2);
cursor: pointer;
transition: transform 0.12s ease, border-color 0.15s ease, background 0.15s ease, color 0.15s ease;
}
.chip:hover { border-color: var(--violet); transform: translateY(-1px); }
.chip:active { transform: scale(0.96); }
.chip[aria-pressed="true"] {
background: rgba(139, 92, 246, 0.12);
border-color: var(--violet);
color: var(--violet-d);
}
/* Toggle */
.toggle-block {
flex-direction: row;
align-items: center;
justify-content: space-between;
gap: 16px;
padding: 14px 16px;
background: rgba(255, 143, 177, 0.10);
border: 1px solid var(--line);
border-radius: var(--r-md);
}
.toggle-copy h2 { font-size: 15px; }
.toggle-copy p {
margin: 2px 0 0;
font-size: 13px;
color: var(--muted);
}
.switch {
flex: 0 0 auto;
width: 54px;
height: 32px;
border-radius: 99px;
border: none;
background: rgba(42, 26, 46, 0.18);
cursor: pointer;
position: relative;
transition: background 0.2s ease;
padding: 0;
}
.switch .knob {
position: absolute;
top: 3px;
left: 3px;
width: 26px;
height: 26px;
border-radius: 50%;
background: var(--white);
box-shadow: 0 2px 6px rgba(0, 0, 0, 0.25);
transition: transform 0.2s cubic-bezier(0.34, 1.56, 0.64, 1);
}
.switch[aria-checked="true"] { background: var(--grad); }
.switch[aria-checked="true"] .knob { transform: translateX(22px); }
/* Focus */
.pill:focus-visible,
.chip:focus-visible,
.switch:focus-visible,
.btn:focus-visible {
outline: 3px solid rgba(139, 92, 246, 0.5);
outline-offset: 2px;
}
/* Footer */
.sheet-foot {
flex: 0 0 auto;
padding: 14px 22px 18px;
border-top: 1px solid var(--line);
background: var(--surface);
display: flex;
flex-direction: column;
gap: 12px;
}
.match {
display: flex;
align-items: baseline;
gap: 8px;
font-size: 14px;
color: var(--ink-2);
}
.match .dot {
width: 9px;
height: 9px;
border-radius: 50%;
background: #22c55e;
box-shadow: 0 0 0 4px rgba(34, 197, 94, 0.18);
align-self: center;
}
.match strong {
font-size: 20px;
color: var(--ink);
font-variant-numeric: tabular-nums;
transition: color 0.2s ease;
}
.match.bump strong { color: var(--coral-d); }
.match-label { color: var(--muted); }
.actions {
display: flex;
gap: 10px;
}
.btn {
font: inherit;
font-weight: 700;
font-size: 15px;
padding: 13px 20px;
border-radius: 99px;
cursor: pointer;
border: none;
transition: transform 0.12s ease, box-shadow 0.15s ease, background 0.15s ease;
}
.btn:active { transform: scale(0.97); }
.btn.ghost {
flex: 0 0 auto;
background: var(--white);
border: 1.5px solid var(--line);
color: var(--ink-2);
}
.btn.ghost:hover { border-color: var(--muted); }
.btn.primary {
flex: 1 1 auto;
background: var(--grad);
color: var(--white);
box-shadow: 0 10px 22px -8px rgba(230, 57, 80, 0.6);
}
.btn.primary:hover { box-shadow: 0 14px 26px -8px rgba(230, 57, 80, 0.7); }
/* Toast */
.toast {
position: fixed;
left: 50%;
bottom: 28px;
transform: translate(-50%, 20px);
background: var(--ink);
color: var(--white);
padding: 12px 20px;
border-radius: 99px;
font-size: 14px;
font-weight: 600;
box-shadow: 0 12px 30px -8px rgba(0, 0, 0, 0.45);
opacity: 0;
pointer-events: none;
transition: opacity 0.25s ease, transform 0.25s ease;
z-index: 50;
}
.toast.show {
opacity: 1;
transform: translate(-50%, 0);
}
@media (max-width: 520px) {
body { padding: 0; align-items: stretch; }
.phone {
max-width: none;
max-height: none;
min-height: 100vh;
border-radius: 0;
border: none;
}
.sheet-head h1 { font-size: 21px; }
.actions { flex-wrap: wrap; }
.btn.ghost { flex: 1 1 100%; order: 2; }
}(function () {
"use strict";
/* ---------- Fictional profile dataset ---------- */
var INTERESTS = ["coffee", "hiking", "music", "cooking", "gaming", "art", "travel", "yoga", "dogs", "film"];
var GENDERS = ["women", "men", "everyone"];
function pick(arr, n) {
var copy = arr.slice(), out = [];
for (var i = 0; i < n && copy.length; i++) {
out.push(copy.splice(Math.floor(Math.random() * copy.length), 1)[0]);
}
return out;
}
// Deterministic-ish pseudo population of 420 fictional profiles.
var PROFILES = [];
var seed = 7;
function rnd() { seed = (seed * 1103515245 + 12345) & 0x7fffffff; return seed / 0x7fffffff; }
for (var i = 0; i < 420; i++) {
var g = rnd() < 0.5 ? "women" : (rnd() < 0.7 ? "men" : "everyone");
PROFILES.push({
age: 19 + Math.floor(rnd() * 45),
distance: 1 + Math.floor(rnd() * 148),
gender: g,
verified: rnd() < 0.42,
interests: (function () {
var s = {};
var k = 1 + Math.floor(rnd() * 4);
for (var j = 0; j < k; j++) { s[INTERESTS[Math.floor(rnd() * INTERESTS.length)]] = true; }
return Object.keys(s);
})()
});
}
/* ---------- DOM ---------- */
var $ = function (id) { return document.getElementById(id); };
var ageLow = $("ageLow"), ageHigh = $("ageHigh"), ageOut = $("ageOut");
var dist = $("dist"), distOut = $("distOut"), distFill = $("distFill");
var intOut = $("intOut");
var verified = $("verified");
var matchCount = $("matchCount"), matchWrap = matchCount.closest(".match");
var toastEl = $("toast");
var ageRange = document.querySelector('[data-range="age"]');
var ageFill = ageRange.querySelector("[data-fill]");
var AGE_MIN = 18, AGE_MAX = 70, GAP = 1;
/* ---------- Toast ---------- */
var toastT;
function toast(msg) {
toastEl.textContent = msg;
toastEl.classList.add("show");
clearTimeout(toastT);
toastT = setTimeout(function () { toastEl.classList.remove("show"); }, 2200);
}
/* ---------- Dual age slider ---------- */
function pct(v, min, max) { return ((v - min) / (max - min)) * 100; }
function updateAge() {
var lo = parseInt(ageLow.value, 10);
var hi = parseInt(ageHigh.value, 10);
if (hi - lo < GAP) {
if (document.activeElement === ageHigh) { lo = hi - GAP; ageLow.value = lo; }
else { hi = lo + GAP; ageHigh.value = hi; }
}
var pl = pct(lo, AGE_MIN, AGE_MAX), ph = pct(hi, AGE_MIN, AGE_MAX);
ageFill.style.left = pl + "%";
ageFill.style.width = (ph - pl) + "%";
var label = hi >= AGE_MAX ? lo + " – " + hi + "+" : lo + " – " + hi;
ageOut.textContent = label;
ageLow.setAttribute("aria-valuetext", "Minimum age " + lo);
ageHigh.setAttribute("aria-valuetext", "Maximum age " + hi);
}
/* ---------- Distance slider ---------- */
function updateDist() {
var v = parseInt(dist.value, 10);
distFill.style.width = pct(v, 1, 150) + "%";
distOut.textContent = v + " km";
dist.setAttribute("aria-valuetext", v + " kilometres");
}
/* ---------- Selection readers ---------- */
function selectedSeek() {
return Array.prototype.filter.call(
document.querySelectorAll('[data-group="seek"] .pill'),
function (b) { return b.getAttribute("aria-pressed") === "true"; }
).map(function (b) { return b.dataset.value; });
}
function selectedInterests() {
return Array.prototype.filter.call(
document.querySelectorAll("#interests .chip"),
function (b) { return b.getAttribute("aria-pressed") === "true"; }
).map(function (b) { return b.dataset.value; });
}
/* ---------- Match count ---------- */
var animRaf;
function animateCount(to) {
var from = parseInt(matchCount.textContent.replace(/\D/g, ""), 10) || 0;
if (from === to) { matchCount.textContent = to; return; }
cancelAnimationFrame(animRaf);
var start = performance.now(), dur = 340;
function step(now) {
var t = Math.min(1, (now - start) / dur);
var eased = 1 - Math.pow(1 - t, 3);
matchCount.textContent = Math.round(from + (to - from) * eased);
if (t < 1) { animRaf = requestAnimationFrame(step); }
}
animRaf = requestAnimationFrame(step);
matchWrap.classList.add("bump");
setTimeout(function () { matchWrap.classList.remove("bump"); }, 400);
}
function recompute() {
var lo = parseInt(ageLow.value, 10), hi = parseInt(ageHigh.value, 10);
var maxDist = parseInt(dist.value, 10);
var seek = selectedSeek();
var ints = selectedInterests();
var vOnly = verified.getAttribute("aria-checked") === "true";
var everyone = seek.indexOf("everyone") !== -1;
var count = PROFILES.filter(function (p) {
if (p.age < lo || p.age > hi) return false;
if (p.distance > maxDist) return false;
if (vOnly && !p.verified) return false;
if (!everyone && seek.length && seek.indexOf(p.gender) === -1 && p.gender !== "everyone") return false;
if (ints.length) {
var hit = ints.some(function (x) { return p.interests.indexOf(x) !== -1; });
if (!hit) return false;
}
return true;
}).length;
animateCount(count);
}
/* ---------- Wiring ---------- */
[ageLow, ageHigh].forEach(function (el) {
el.addEventListener("input", function () { updateAge(); recompute(); });
});
dist.addEventListener("input", function () { updateDist(); recompute(); });
// Gender radiogroup (single select)
document.querySelectorAll('[data-group="gender"] .pill').forEach(function (btn) {
btn.addEventListener("click", function () {
document.querySelectorAll('[data-group="gender"] .pill').forEach(function (b) {
b.setAttribute("aria-checked", b === btn ? "true" : "false");
});
});
});
// Looking-for group (multi toggle, keep at least one)
document.querySelectorAll('[data-group="seek"] .pill').forEach(function (btn) {
btn.addEventListener("click", function () {
var on = btn.getAttribute("aria-pressed") === "true";
if (on && selectedSeek().length === 1) {
toast("Pick at least one preference");
return;
}
btn.setAttribute("aria-pressed", on ? "false" : "true");
recompute();
});
});
// Interests
document.querySelectorAll("#interests .chip").forEach(function (btn) {
btn.addEventListener("click", function () {
var on = btn.getAttribute("aria-pressed") === "true";
btn.setAttribute("aria-pressed", on ? "false" : "true");
intOut.textContent = selectedInterests().length + " selected";
recompute();
});
});
// Verified switch
function toggleSwitch() {
var on = verified.getAttribute("aria-checked") === "true";
verified.setAttribute("aria-checked", on ? "false" : "true");
recompute();
}
verified.addEventListener("click", toggleSwitch);
verified.addEventListener("keydown", function (e) {
if (e.key === " " || e.key === "Enter") { e.preventDefault(); toggleSwitch(); }
});
// Apply
$("apply").addEventListener("click", function () {
toast("Filters applied · " + matchCount.textContent + " matches");
});
// Reset to defaults
var DEFAULTS = {
ageLow: 24, ageHigh: 38, dist: 25,
gender: "woman",
seek: ["women", "men"],
interests: ["coffee", "hiking", "cooking"],
verified: false
};
$("reset").addEventListener("click", function () {
ageLow.value = DEFAULTS.ageLow;
ageHigh.value = DEFAULTS.ageHigh;
dist.value = DEFAULTS.dist;
document.querySelectorAll('[data-group="gender"] .pill').forEach(function (b) {
b.setAttribute("aria-checked", b.dataset.value === DEFAULTS.gender ? "true" : "false");
});
document.querySelectorAll('[data-group="seek"] .pill').forEach(function (b) {
b.setAttribute("aria-pressed", DEFAULTS.seek.indexOf(b.dataset.value) !== -1 ? "true" : "false");
});
document.querySelectorAll("#interests .chip").forEach(function (b) {
b.setAttribute("aria-pressed", DEFAULTS.interests.indexOf(b.dataset.value) !== -1 ? "true" : "false");
});
verified.setAttribute("aria-checked", DEFAULTS.verified ? "true" : "false");
intOut.textContent = DEFAULTS.interests.length + " selected";
updateAge();
updateDist();
recompute();
toast("Filters reset to defaults");
});
/* ---------- Init ---------- */
updateAge();
updateDist();
recompute();
})();<!doctype html>
<html lang="en">
<head>
<meta charset="utf-8" />
<meta name="viewport" content="width=device-width, initial-scale=1" />
<title>Filters & Preferences — Spark</title>
<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=Inter:wght@400;500;600;700;800&family=Fraunces:opsz,[email protected],600;9..144,700&display=swap" rel="stylesheet" />
<link rel="stylesheet" href="style.css" />
</head>
<body>
<div class="phone" role="region" aria-label="Filters and preferences">
<header class="sheet-head">
<div class="grip" aria-hidden="true"></div>
<div class="head-row">
<div>
<p class="eyebrow">Discovery settings</p>
<h1>Filters & Preferences</h1>
</div>
<span class="spark-badge" aria-hidden="true">✦</span>
</div>
</header>
<main class="sheet-body">
<!-- Age range -->
<section class="block" aria-labelledby="age-label">
<div class="block-head">
<h2 id="age-label">Age range</h2>
<output class="readout" id="ageOut">24 – 38</output>
</div>
<div class="range" data-range="age" data-min="18" data-max="70">
<div class="range-track"><div class="range-fill" data-fill></div></div>
<input type="range" id="ageLow" min="18" max="70" value="24" step="1"
aria-label="Minimum age" />
<input type="range" id="ageHigh" min="18" max="70" value="38" step="1"
aria-label="Maximum age" />
</div>
</section>
<!-- Distance -->
<section class="block" aria-labelledby="dist-label">
<div class="block-head">
<h2 id="dist-label">Maximum distance</h2>
<output class="readout" id="distOut">25 km</output>
</div>
<div class="single">
<div class="range-track"><div class="range-fill" id="distFill"></div></div>
<input type="range" id="dist" min="1" max="150" value="25" step="1"
aria-label="Maximum distance in kilometres" />
</div>
<div class="scale"><span>1 km</span><span>150 km</span></div>
</section>
<!-- Gender -->
<section class="block" aria-labelledby="gender-label">
<h2 id="gender-label">I am</h2>
<div class="pills" role="radiogroup" aria-labelledby="gender-label" data-group="gender">
<button class="pill" role="radio" aria-checked="true" data-value="woman">Woman</button>
<button class="pill" role="radio" aria-checked="false" data-value="man">Man</button>
<button class="pill" role="radio" aria-checked="false" data-value="nonbinary">Non-binary</button>
</div>
</section>
<!-- Looking for -->
<section class="block" aria-labelledby="seek-label">
<h2 id="seek-label">Looking for</h2>
<div class="pills" role="group" aria-labelledby="seek-label" data-group="seek">
<button class="pill" aria-pressed="true" data-value="women">Women</button>
<button class="pill" aria-pressed="true" data-value="men">Men</button>
<button class="pill" aria-pressed="false" data-value="everyone">Everyone</button>
</div>
</section>
<!-- Interests -->
<section class="block" aria-labelledby="int-label">
<div class="block-head">
<h2 id="int-label">Shared interests</h2>
<output class="readout muted" id="intOut">3 selected</output>
</div>
<div class="chips" role="group" aria-labelledby="int-label" id="interests">
<button class="chip" aria-pressed="true" data-value="coffee">☕ Coffee</button>
<button class="chip" aria-pressed="true" data-value="hiking">🥾 Hiking</button>
<button class="chip" aria-pressed="false" data-value="music">🎧 Live music</button>
<button class="chip" aria-pressed="true" data-value="cooking">🍜 Cooking</button>
<button class="chip" aria-pressed="false" data-value="gaming">🎮 Gaming</button>
<button class="chip" aria-pressed="false" data-value="art">🎨 Art</button>
<button class="chip" aria-pressed="false" data-value="travel">✈️ Travel</button>
<button class="chip" aria-pressed="false" data-value="yoga">🧘 Yoga</button>
<button class="chip" aria-pressed="false" data-value="dogs">🐕 Dogs</button>
<button class="chip" aria-pressed="false" data-value="film">🎬 Film</button>
</div>
</section>
<!-- Verified -->
<section class="block toggle-block">
<div class="toggle-copy">
<h2>Verified profiles only</h2>
<p>Show people who passed photo verification.</p>
</div>
<button class="switch" id="verified" role="switch" aria-checked="false" aria-label="Verified profiles only">
<span class="knob"></span>
</button>
</section>
</main>
<footer class="sheet-foot">
<div class="match" aria-live="polite">
<span class="dot" aria-hidden="true"></span>
<strong id="matchCount">0</strong>
<span class="match-label">people match</span>
</div>
<div class="actions">
<button class="btn ghost" id="reset" type="button">Reset</button>
<button class="btn primary" id="apply" type="button">Apply filters</button>
</div>
</footer>
</div>
<div class="toast" id="toast" role="status" aria-live="polite"></div>
<script src="script.js"></script>
</body>
</html>A phone-framed filters sheet for a dating app, built to feel like a native preferences screen. The panel stacks a set of clearly separated controls: a dual-handle age range slider that keeps its two thumbs from crossing, a distance radius slider with a live kilometre readout, gender and looking-for pill groups, an interests multiselect chip cloud, and a verified-only toggle switch. Everything is wrapped in a rounded ~430px container with gradient accents and soft shadows.
The heart of the screen is a live match counter pinned to the sticky footer. Every interaction — dragging a handle, tapping a chip, flipping the verified switch — recomputes an estimated “X people match” figure against a small fictional dataset of profiles, animating the number as it changes. This gives immediate feedback so users understand how each choice widens or narrows their pool.
The footer also carries Apply and Reset actions. Apply confirms the current selection with a toast, while Reset restores every control to its default state and recalculates the count. All controls are keyboard operable with visible focus rings, the sliders expose ARIA range attributes, and the layout collapses gracefully on very small screens.