Disc Selector Tool
<!doctype html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>Find Your Next Disc — Bay Area Disc Golf</title>
<style>
@import url('https://fonts.googleapis.com/css2?family=Space+Grotesk:wght@400;500;600;700&family=Inter:wght@400;500;600&family=JetBrains+Mono:wght@400;500;700&display=swap');
html, body {
background-color: #123252 !important;
margin: 0;
color-scheme: light;
font-family: 'Inter', sans-serif;
}
* { box-sizing: border-box; }
.wrap { max-width: 640px; margin: 0 auto; padding: 40px 20px; }
.logo-row { display: flex; align-items: center; gap: 8px; margin-bottom: 16px; }
.logo-mark {
width: 36px; height: 36px; border-radius: 8px; display: flex; align-items: center;
justify-content: center; color: #0F2A45; font-weight: 700; font-size: 14px;
background-color: #6EC1E4; font-family: 'Space Grotesk', sans-serif;
}
.logo-name { color: #FFFFFF; font-weight: 600; font-size: 14px; font-family: 'Space Grotesk', sans-serif; }
.eyebrow {
color: #FF8F6E; font-family: 'JetBrains Mono', monospace; font-size: 12px;
letter-spacing: 0.15em; text-transform: uppercase; margin: 0 0 8px 0;
}
h1 { color: #FFFFFF; font-size: 36px; margin: 0 0 8px 0; font-family: 'Space Grotesk', sans-serif; font-weight: 700; }
.tagline { color: #AEC6E0; font-size: 14px; line-height: 1.6; margin: 0; }
.card {
display: flex; flex-direction: column; gap: 24px; background-color: #1B3A5C;
border: 1px solid #3E5F87; border-radius: 12px; padding: 20px; margin-top: 32px;
}
.field-label { color: #FFFFFF; font-size: 14px; font-weight: 600; margin: 0 0 8px 0; }
.option-row { display: flex; flex-wrap: wrap; gap: 8px; }
.opt-btn {
padding: 8px 12px; border-radius: 6px; font-size: 14px; font-weight: 500;
border: 1px solid #3E5F87; background-color: #1B3A5C; color: #FFFFFF; cursor: pointer;
font-family: 'Inter', sans-serif;
}
.opt-btn.active { border-color: #6EC1E4; background-color: #6EC1E4; color: #0F2A45; }
.submit-btn {
width: 100%; padding: 12px; border-radius: 6px; font-weight: 600; color: #0F2A45;
background-color: #F2B84B; font-family: 'Space Grotesk', sans-serif; border: none;
cursor: pointer; font-size: 15px;
}
.results { margin-top: 32px; display: flex; flex-direction: column; gap: 16px; }
.results-count {
color: #AEC6E0; font-size: 12px; font-family: 'JetBrains Mono', monospace;
text-transform: uppercase; letter-spacing: 0.1em; margin: 0;
}
.disc-card { background-color: #1B3A5C; border: 1px solid #3E5F87; border-radius: 12px; padding: 20px; }
.disc-head { display: flex; align-items: baseline; justify-content: space-between; margin-bottom: 4px; }
.disc-name { color: #FFFFFF; font-size: 20px; font-family: 'Space Grotesk', sans-serif; font-weight: 600; margin: 0; }
.disc-meta { color: #AEC6E0; font-size: 12px; }
.stats { display: grid; grid-template-columns: 1fr 1fr; column-gap: 16px; row-gap: 6px; margin: 12px 0; }
.stat-row { display: flex; align-items: center; gap: 8px; font-size: 12px; }
.stat-label { width: 40px; color: #AEC6E0; font-family: 'JetBrains Mono', monospace; }
.stat-track { flex: 1; height: 6px; background-color: #284B72; border-radius: 9999px; overflow: hidden; }
.stat-fill { height: 100%; border-radius: 9999px; }
.stat-value { width: 24px; text-align: right; color: #FFFFFF; font-family: 'JetBrains Mono', monospace; }
.reason {
color: #AEC6E0; font-size: 14px; line-height: 1.6; border-top: 1px solid #3E5F87;
padding-top: 12px; margin: 0 0 12px 0;
}
.shop-btn {
display: flex; align-items: center; justify-content: center; width: 100%; padding: 10px;
border-radius: 6px; font-size: 14px; font-weight: 600; color: #0F2A45; background-color: #6EC1E4;
font-family: 'Space Grotesk', sans-serif; text-decoration: none;
}
footer { margin-top: 40px; text-align: center; color: #AEC6E0; font-size: 12px; }
</style>
</head>
<body>
<div class="wrap">
<header>
<div class="logo-row">
<div class="logo-mark">BA</div>
<span class="logo-name">Bay Area Disc Golf</span>
</div>
<p class="eyebrow">Speed · Glide · Turn · Fade</p>
<h1>Find your next disc</h1>
<p class="tagline">Answer three questions and get discs matched to your arm and the flight you're after — each with the flight numbers behind the pick.</p>
</header>
<div class="card">
<div>
<p class="field-label">Experience level</p>
<div class="option-row" data-group="experience">
<button class="opt-btn" data-value="beginner">Beginner</button>
<button class="opt-btn active" data-value="intermediate">Intermediate</button>
<button class="opt-btn" data-value="advanced">Advanced</button>
</div>
</div>
<div>
<p class="field-label">Flight shape you want</p>
<div class="option-row" data-group="shape">
<button class="opt-btn" data-value="turnover">Turns right, flips up</button>
<button class="opt-btn active" data-value="straight">Straight & predictable</button>
<button class="opt-btn" data-value="overstable">Holds a hard fade left</button>
</div>
</div>
<div>
<p class="field-label">Disc type</p>
<div class="option-row" data-group="type">
<button class="opt-btn active" data-value="Any">Any</button>
<button class="opt-btn" data-value="Putter">Putter</button>
<button class="opt-btn" data-value="Midrange">Midrange</button>
<button class="opt-btn" data-value="Fairway Driver">Fairway Driver</button>
<button class="opt-btn" data-value="Distance Driver">Distance Driver</button>
</div>
</div>
<button class="submit-btn" id="submitBtn">Show my discs</button>
</div>
<div class="results" id="results" style="display:none;">
<p class="results-count" id="resultsCount"></p>
<div id="resultsList"></div>
</div>
<footer>Powered by Bay Area Disc Golf</footer>
</div>
<script>
// ---------------------------------------------------------------------
// "Shop this disc" links to Bay Area Disc Golf's own product search.
// ---------------------------------------------------------------------
var STORE_SEARCH_URL = "https://bayareadiscgolf.com/search?q=";
function shopLink(disc) {
var q = encodeURIComponent(disc.brand + " " + disc.name);
return STORE_SEARCH_URL + q;
}
// speed / glide / turn / fade — publicly published flight numbers
var DISCS = [
{ name: "Aviar", brand: "Innova", type: "Putter", speed: 2, glide: 3, turn: 0, fade: 1 },
{ name: "Luna", brand: "Discraft", type: "Putter", speed: 3, glide: 4, turn: 0, fade: 1 },
{ name: "Zone", brand: "Discraft", type: "Putter", speed: 4, glide: 3, turn: 0, fade: 3 },
{ name: "Envy", brand: "Discmania", type: "Putter", speed: 2, glide: 4, turn: 0, fade: 0 },
{ name: "P2", brand: "Discmania", type: "Putter", speed: 2, glide: 3, turn: 0, fade: 1 },
{ name: "Pig", brand: "MVP", type: "Putter", speed: 2, glide: 3, turn: -1, fade: 1 },
{ name: "Judge", brand: "Dynamic Discs", type: "Putter", speed: 2, glide: 4, turn: 0, fade: 1 },
{ name: "Proxy", brand: "Axiom", type: "Putter", speed: 3, glide: 3, turn: 0, fade: 1 },
{ name: "Compass", brand: "Latitude 64", type: "Putter", speed: 3, glide: 3, turn: 0, fade: 1 },
{ name: "Gator", brand: "Innova", type: "Putter", speed: 3, glide: 3, turn: 0, fade: 2 },
{ name: "Harp", brand: "Westside", type: "Putter", speed: 3, glide: 3, turn: 0, fade: 1 },
{ name: "Buzzz", brand: "Discraft", type: "Midrange", speed: 5, glide: 4, turn: -1, fade: 1 },
{ name: "Roc3", brand: "Innova", type: "Midrange", speed: 5, glide: 4, turn: -1, fade: 2 },
{ name: "Mako3", brand: "Discmania", type: "Midrange", speed: 4, glide: 4, turn: -1, fade: 1 },
{ name: "MD3", brand: "Discmania", type: "Midrange", speed: 4, glide: 4, turn: -2, fade: 1 },
{ name: "Truth", brand: "MVP", type: "Midrange", speed: 4, glide: 5, turn: -1, fade: 0 },
{ name: "Nova", brand: "Innova", type: "Midrange", speed: 4, glide: 4, turn: -1, fade: 0 },
{ name: "Comet", brand: "Discraft", type: "Midrange", speed: 5, glide: 5, turn: -3, fade: 0 },
{ name: "Saint", brand: "Latitude 64", type: "Midrange", speed: 5, glide: 5, turn: -1, fade: 1 },
{ name: "Tenacity", brand: "Axiom", type: "Midrange", speed: 4, glide: 4, turn: -2, fade: 1 },
{ name: "Warden", brand: "Dynamic Discs", type: "Midrange", speed: 4, glide: 3, turn: 0, fade: 2 },
{ name: "Motion", brand: "Westside", type: "Midrange", speed: 5, glide: 5, turn: -2, fade: 0 },
{ name: "Leopard", brand: "Innova", type: "Fairway Driver", speed: 6, glide: 5, turn: -2, fade: 1 },
{ name: "Teebird", brand: "Innova", type: "Fairway Driver", speed: 7, glide: 5, turn: 0, fade: 2 },
{ name: "Undertaker", brand: "Discraft", type: "Fairway Driver", speed: 7, glide: 4, turn: 0, fade: 3 },
{ name: "FD", brand: "Discmania", type: "Fairway Driver", speed: 7, glide: 5, turn: -1, fade: 1 },
{ name: "FD3", brand: "Discmania", type: "Fairway Driver", speed: 7, glide: 5, turn: -2, fade: 1 },
{ name: "Volt", brand: "MVP", type: "Fairway Driver", speed: 8, glide: 5, turn: -3, fade: 1 },
{ name: "Escape", brand: "Dynamic Discs", type: "Fairway Driver", speed: 9, glide: 6, turn: -2, fade: 1 },
{ name: "River", brand: "Latitude 64", type: "Fairway Driver", speed: 6, glide: 5, turn: -3, fade: 1 },
{ name: "Insanity", brand: "Axiom", type: "Fairway Driver", speed: 9, glide: 5, turn: -1, fade: 2 },
{ name: "Sword", brand: "Westside", type: "Fairway Driver", speed: 7, glide: 5, turn: -1, fade: 2 },
{ name: "Vulcan", brand: "MVP", type: "Fairway Driver", speed: 8, glide: 5, turn: -1, fade: 2 },
{ name: "Wraith", brand: "Innova", type: "Distance Driver", speed: 11, glide: 5, turn: -1, fade: 3 },
{ name: "Destroyer", brand: "Innova", type: "Distance Driver", speed: 12, glide: 5, turn: -1, fade: 3 },
{ name: "Firebird", brand: "Innova", type: "Distance Driver", speed: 9, glide: 3, turn: -1, fade: 3 },
{ name: "Boss", brand: "Innova", type: "Distance Driver", speed: 13, glide: 5, turn: -2, fade: 3 },
{ name: "Nuke", brand: "Discraft", type: "Distance Driver", speed: 13, glide: 5, turn: -1, fade: 3 },
{ name: "Force", brand: "Discraft", type: "Distance Driver", speed: 12, glide: 4, turn: 0, fade: 3 },
{ name: "PD", brand: "Discmania", type: "Distance Driver", speed: 9, glide: 5, turn: -1, fade: 2 },
{ name: "DD3", brand: "Discmania", type: "Distance Driver", speed: 12, glide: 5, turn: -1, fade: 3 },
{ name: "Ballista Pro", brand: "Latitude 64", type: "Distance Driver", speed: 13, glide: 6, turn: -1, fade: 2 },
{ name: "Tesla", brand: "MVP", type: "Distance Driver", speed: 9, glide: 5, turn: -3, fade: 1 },
{ name: "Instinct", brand: "MVP", type: "Distance Driver", speed: 10, glide: 5, turn: -2, fade: 1 },
{ name: "Sabotage", brand: "Axiom", type: "Distance Driver", speed: 14, glide: 4, turn: -1, fade: 3 },
{ name: "Maverick", brand: "Dynamic Discs", type: "Distance Driver", speed: 11, glide: 5, turn: -2, fade: 2 },
{ name: "Stag", brand: "Westside", type: "Distance Driver", speed: 12, glide: 5, turn: -1, fade: 3 }
];
var ARM_SPEED_CAP = { beginner: 8, intermediate: 12, advanced: 14 };
var SHAPE_TARGET = {
straight: { turn: -1, fade: 1 },
turnover: { turn: -3, fade: 0.5 },
overstable: { turn: 0, fade: 3 }
};
var state = { experience: "intermediate", shape: "straight", type: "Any" };
function scoreDisc(disc, s) {
var cap = ARM_SPEED_CAP[s.experience];
if (disc.speed > cap + 1) return -Infinity;
if (s.type !== "Any" && disc.type !== s.type) return -Infinity;
var target = SHAPE_TARGET[s.shape];
var turnDist = Math.abs(disc.turn - target.turn);
var fadeDist = Math.abs(disc.fade - target.fade);
var speedFit = disc.speed <= cap ? 0 : (disc.speed - cap) * 1.5;
return -(turnDist + fadeDist + speedFit);
}
function reasonFor(disc, s) {
var bit1;
if (s.experience === "beginner") {
bit1 = "its speed " + disc.speed + " rating stays inside the range a beginner arm can actually get flying";
} else if (s.experience === "advanced") {
bit1 = "speed " + disc.speed + " gives a fast arm real distance ceiling without sacrificing control";
} else {
bit1 = "speed " + disc.speed + " sits comfortably in an intermediate power range";
}
var bit2;
if (s.shape === "turnover" && disc.turn <= -2) {
bit2 = "a turn of " + disc.turn + " means it'll flip and glide right, ideal for a gentle turnover look";
} else if (s.shape === "overstable" && disc.fade >= 2) {
bit2 = "a fade of " + disc.fade + " brings it back left hard at the end, holding lines into the wind";
} else {
bit2 = "turn " + disc.turn + " and fade " + disc.fade + " balance out to a mostly straight, predictable flight";
}
return "With " + bit1 + ", " + bit2 + ".";
}
function flightPathSVG(turn, fade, glide, accent) {
var turnBend = Math.max(-3, Math.min(3, -turn)) * 10;
var fadeBend = Math.min(5, fade) * 9;
var glideLift = glide * 1.2;
var path = "M 8,70 C " + (40 + turnBend) + "," + (70 - glideLift) + " " + (90 + turnBend) + "," + (55 - glideLift) +
" " + (130 + turnBend) + ",40 S " + (170 + turnBend - fadeBend) + ",30 " + (192 - fadeBend) + ",18";
return '<svg viewBox="0 0 210 90" style="width:100%;height:64px;" aria-hidden="true">' +
'<line x1="8" y1="78" x2="200" y2="78" stroke="#3E5F87" stroke-width="1" />' +
'<path d="' + path + '" fill="none" stroke="' + accent + '" stroke-width="2.5" stroke-linecap="round" />' +
'<circle cx="8" cy="70" r="3" fill="' + accent + '" /></svg>';
}
function statRow(label, value, max, color) {
var pct = Math.max(4, (Math.abs(value) / max) * 100);
return '<div class="stat-row"><span class="stat-label">' + label + '</span>' +
'<div class="stat-track"><div class="stat-fill" style="width:' + pct + '%;background-color:' + color + ';"></div></div>' +
'<span class="stat-value">' + value + '</span></div>';
}
function renderResults() {
var scored = DISCS.map(function (d) { return Object.assign({}, d, { score: scoreDisc(d, state) }); })
.filter(function (d) { return d.score > -Infinity; })
.sort(function (a, b) { return b.score - a.score; })
.slice(0, 5);
var resultsEl = document.getElementById("results");
var countEl = document.getElementById("resultsCount");
var listEl = document.getElementById("resultsList");
resultsEl.style.display = "flex";
countEl.textContent = scored.length + (scored.length === 1 ? " match" : " matches");
if (scored.length === 0) {
listEl.innerHTML = '<p style="color:#FFFFFF;font-size:14px;">Nothing fits that exact combo — try widening the disc type to "Any".</p>';
return;
}
listEl.innerHTML = scored.map(function (d) {
return '' +
'<div class="disc-card">' +
'<div class="disc-head"><h3 class="disc-name">' + d.name + '</h3>' +
'<span class="disc-meta">' + d.brand + ' · ' + d.type + '</span></div>' +
flightPathSVG(d.turn, d.fade, d.glide, "#6EC1E4") +
'<div class="stats">' +
statRow("Speed", d.speed, 14, "#F2B84B") +
statRow("Glide", d.glide, 7, "#6EC1E4") +
statRow("Turn", d.turn, 5, "#6EC1E4") +
statRow("Fade", d.fade, 5, "#FF8F6E") +
'</div>' +
'<p class="reason">' + reasonFor(d, state) + '</p>' +
'<a class="shop-btn" href="' + shopLink(d) + '" target="_blank" rel="noopener noreferrer">Shop this disc at Bay Area Disc Golf</a>' +
'</div>';
}).join("");
}
document.querySelectorAll(".option-row").forEach(function (row) {
var group = row.getAttribute("data-group");
row.addEventListener("click", function (e) {
var btn = e.target.closest(".opt-btn");
if (!btn) return;
state[group] = btn.getAttribute("data-value");
row.querySelectorAll(".opt-btn").forEach(function (b) { b.classList.remove("active"); });
btn.classList.add("active");
});
});
document.getElementById("submitBtn").addEventListener("click", renderResults);
</script>
</body>
</html>