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 &amp; 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>