{
  "version": 3,
  "sources": ["/cdn/shop/t/77/assets/lux-build-lite.js?cb=24513"],
  "sourcesContent": ["/*\n  Light bike builder (sections/lux-build-lite.liquid), and the same builder\n  for custom wheels.\n\n  The section's Builder setting picks which (cfg.kind). \"wheels\" swaps the\n  slots for a wheel build: front and rear, or one end, each a hub and a rim,\n  then spokes and nipples, with tyres and tubes as optional add-ons and the\n  workshop's wheel build service once per wheel. No build offer, assembly or\n  giveaway there, its own saved build (WHEEL_KEY), and it never writes the\n  Dream Build export. Its cart lines carry _wheel_build, not _build.\n\n  One tile per part. Picking a product and variant drops its photo into the\n  tile, and the progress panel counts what is still needed. The page doesn't\n  check fit: any part of the right type can go in any slot. The workshop\n  checks every build after the order and gets in touch if anything won't\n  work together, and the page says so (the section's check note).\n\n  Parts come from Shopify's product type collections, best sellers first\n  (templates/collection.build.liquid), or from search when the rider types\n  (templates/search.build.liquid). Sold-out products are left out there.\n\n  Options the rider sets:\n    - Freestyle or race bike. Race swaps pegs for a number plate, adds a\n      rear cog, calls the sprocket a chainring and makes brakes part of the\n      bike: disc (brake, rotor and mount) or V-brake (brake, lever and\n      cable). It also ticks Race in the picker's Discipline filter.\n    - Headset, bottom bracket, seat post and nipples can be ticked as\n      included with another part. Ticked counts as done and adds nothing.\n      On a race bike the fork can be ticked as coming with the frame, and a\n      frame and fork kit (titled \"Frame/Fork Kit\" or \"Frame & Fork Kit\", or\n      tagged includes-fork) fills the fork itself. The Custom bike build\n      discount reads kits the same way; a plain frame ticked by hand still\n      needs a fork in the cart for the 10%.\n    - Custom wheel build swaps the two complete wheels for hubs, a front and\n      a rear rim (they can differ; \"Same as front rim\" copies one across),\n      spokes and nipples, and adds the workshop's wheel build service for\n      each wheel. A hub set fills both hubs.\n    - Brakes (optional) come as a kit or as separate lever, cable and caliper.\n    - Pegs (optional) come as 2, 3 or 4; \"(Pair)\" products are counted in pairs.\n\n  The picker filters like the category pages (Discipline, Brand, Colour =\n  the variant's colour group, Available today = on the shelf at LUXBMX) and, once a product is open, shows the buy\n  grid's stock line, from templates/product.build-status.liquid. One\n  discipline on its own is filtered by the feed, so race parts come straight\n  back instead of after pages of freestyle best sellers: the type collection's\n  own discipline filter (custom.discipline, still best sellers first), or the\n  discipline-* tag when the rider searches. With Available today or a colour\n  ticked, cards show only the swatches and options that fit, and the quick\n  view opens on a matching variant. Ticked colours carry from slot to slot,\n  so an all-black build stays all black. Brake parts sit in catch-all types (Braking\n  holds rotors, mounts, V-brakes and gyro parts alike), so some slots also\n  match on the product title.\n\n  Parts already in the cart fill their empty slots when the page opens (and\n  again when the cart changes), marked \"In your cart\". Add to cart then only\n  adds what the cart doesn't already hold, so nothing doubles up.\n\n  The build is kept in localStorage, so it survives a reload, with a plain\n  copy of its parts (\"lux-build-lite-export\") that the Dream Build entry form\n  offers as the rider's build. It can also be saved as a named Swym wishlist\n  or added to the cart in one go.\n*/\n(function () {\n  'use strict';\n\n  // Every slot. `req` slots count towards a complete bike; `when` hides a\n  // slot unless the rider's options call for it, and `mode` unless it's that\n  // kind of bike; `incl` lets the rider tick the part as coming with another\n  // one (only on that kind of bike when `inclMode` is set); `match` and `not` keep a slot to the product titles that suit it.\n  var SLOTS = [\n    { id: 'frame', label: 'Frame', group: 'frame', types: ['Frames'], req: true },\n    { id: 'fork', label: 'Fork', group: 'frame', types: ['Forks'], req: true, incl: 'Comes with my frame', inclMode: 'race',\n      not: /top cap|adapt|spacer|\\bbolt\\b/i },\n    { id: 'headset', label: 'Headset', group: 'frame', types: ['Headsets'], req: true, incl: 'Comes with my frame',\n      not: /spacer|star nut|top cap|\\bshim\\b|compression|lock ?nut|stem lock|adapter|not compatible/i },\n\n    { id: 'bars', label: 'Bars', group: 'cockpit', types: ['Bars'], req: true },\n    { id: 'stem', label: 'Stem', group: 'cockpit', types: ['Stems'], req: true, not: /stem bolts?\\b|top cap|spacer|\\bshim\\b/i },\n    { id: 'grips', label: 'Grips', group: 'cockpit', types: ['Grips'], req: true, not: /donut|lock ring/i },\n\n    { id: 'cranks', label: 'Cranks', group: 'drive', types: ['Cranks'], req: true, not: /^(?!.*crank).*spindle/i },\n    { id: 'bb', label: 'Bottom bracket', group: 'drive', types: ['Bottom Brackets'], req: true, incl: 'Comes with my frame or cranks', not: /spacer/i },\n    { id: 'sprocket', label: 'Sprocket', raceLabel: 'Chainring', group: 'drive', types: ['Sprockets', 'Chainrings'], req: true,\n      not: /\\bspider\\b|replacement guard|guard only|utility sprocket guard|sprocket bolt\\b/i },\n    { id: 'chain', label: 'Chain', group: 'drive', types: ['Chains'], req: true, not: /connecting link|master link|missing link|quick link/i },\n    { id: 'pedals', label: 'Pedals', group: 'drive', types: ['Pedals'], req: true,\n      not: /replacement pins|pedal pins|spindle|springs?\\b|cleats?\\b|washer|lock ?nut|bearing kit|o-ring/i },\n    { id: 'cog', label: 'Rear cog', group: 'drive', types: ['Rear Cogs', 'Freewheels', 'Drivers'], req: true, mode: 'race', incl: 'Comes with my rear wheel or hub',\n      match: /\\bcogs?\\b|sprocket|freewheel/i, not: /lock ?ring|driver|drive unit|coaster|clutch/i },\n\n    { id: 'front', label: 'Front wheel', group: 'wheels', types: ['Front Wheels', 'Wheel Sets'], req: true, when: 'stock', hint: 'A wheel set fills both wheels' },\n    { id: 'rear', label: 'Rear wheel', group: 'wheels', types: ['Rear Wheels', 'Wheel Sets'], req: true, when: 'stock', hint: 'A wheel set fills both wheels' },\n    { id: 'fhub', label: 'Front hub', group: 'wheels', types: ['Front Hubs', 'Hub Sets'], req: true, when: 'custom', hint: 'A hub set fills both hubs' },\n    { id: 'rhub', label: 'Rear hub', group: 'wheels', types: ['Rear Hubs', 'Hub Sets'], req: true, when: 'custom', hint: 'A hub set fills both hubs' },\n    { id: 'frim', label: 'Front rim', group: 'wheels', types: ['Rims'], req: true, when: 'custom', same: 'rrim' },\n    { id: 'rrim', label: 'Rear rim', group: 'wheels', types: ['Rims'], req: true, when: 'custom', same: 'frim' },\n    { id: 'spokes', label: 'Spokes', group: 'wheels', types: ['Spokes'], req: true, when: 'custom', count: 'spokes', hint: 'Enough for both wheels. We confirm lengths before building.' },\n    { id: 'nipples', label: 'Nipples', group: 'wheels', types: ['Nipples'], req: true, when: 'custom', count: 'spokes', incl: 'Come with my spokes' },\n    { id: 'ftyre', label: 'Front tyre', group: 'wheels', types: ['Tyres'], req: true, same: 'rtyre' },\n    { id: 'rtyre', label: 'Rear tyre', group: 'wheels', types: ['Tyres'], req: true, same: 'ftyre' },\n    { id: 'tubes', label: 'Tubes', group: 'wheels', types: ['Tubes'], req: true, count: 'tubes', hint: 'Two tubes. A pair or pack counts once',\n      not: /repair|adaptor|adapter|rim tape|valve system|tubeless|insert only/i },\n\n    { id: 'seat', label: 'Seat', group: 'seat', types: ['Seats'], req: true },\n    { id: 'seatpost', label: 'Seat post', group: 'seat', types: ['Seat Posts'], req: true, incl: 'Comes with my seat or frame', not: /extender|\\bshim\\b/i },\n\n    // Race brakes: part of the bike, disc or V-brake.\n    { id: 'dbrake', label: 'Disc brake', group: 'brakes', types: ['Braking', 'Brake Kits', 'Brake Calipers'], req: true, mode: 'race', when: 'disc', hint: 'Lever, hose and caliper',\n      match: /\\b(disc|disk)\\b.*(brake kit|call?iper)/i, not: /bleed|hose|rotor|pads?\\b/i },\n    { id: 'rotor', label: 'Rotor', group: 'brakes', types: ['Braking', 'Brake Accessories'], req: true, mode: 'race', when: 'disc',\n      match: /rotor|wave disc/i, not: /gyro|geo rotor|spacer|rotor bolt|cable|mount|adapt/i },\n    { id: 'dmount', label: 'Disc mount', group: 'brakes', types: ['Brake Mounts', 'Braking', 'Brake Accessories'], req: true, mode: 'race', when: 'disc', incl: 'Built into my frame',\n      match: /(disc|disk).*(mount|adapt)|(mount|adapt).*(disc|disk)/i, not: /brake kit|brake call?iper|(disc|brake) rotor|bolts?\\b|screw/i },\n    { id: 'vbrake', label: 'V-brake', group: 'brakes', types: ['Braking', 'Brake Calipers', 'Brake Kits'], req: true, mode: 'race', when: 'v',\n      match: /\\bv[- ]?brake|\\bmini v\\b/i, not: /lever|mount|boot|plug|cable|pads?\\b|shoe/i },\n    { id: 'vlever', label: 'Brake lever', group: 'brakes', types: ['Brake Levers', 'Braking'], req: true, mode: 'race', when: 'v', incl: 'Comes with my V-brake',\n      match: /lever/i, not: /hydraulic|clamp|screw|plug|adjuster|gyro/i },\n    { id: 'vcable', label: 'Brake cable', group: 'brakes', types: ['Brake Cables', 'Braking'], req: true, mode: 'race', when: 'v', incl: 'Comes with my V-brake',\n      match: /cable|kable/i, not: /hanger|guide|\\bends?\\b|hose|bridge|rotor|gyro|tensioner|lever|straddle|call?iper|hydraulic/i },\n\n    { id: 'pegs', label: 'Pegs', group: 'extras', types: ['Pegs'], count: 'pegs', mode: 'freestyle', not: /\\bsleeves?\\b/i },\n    { id: 'plate', label: 'Number plate', group: 'extras', types: ['Number Plates'], mode: 'race', not: /insert|race number/i },\n    { id: 'brakekit', label: 'Brake kit', group: 'extras', types: ['Brake Kits'], mode: 'freestyle', when: 'kit', not: /\\b(disc|disk)\\b/i },\n    { id: 'lever', label: 'Brake lever', group: 'extras', types: ['Brake Levers'], mode: 'freestyle', when: 'parts' },\n    { id: 'cable', label: 'Brake cable', group: 'extras', types: ['Brake Cables'], mode: 'freestyle', when: 'parts', not: /hose|tubing/i },\n    { id: 'caliper', label: 'Brake caliper', group: 'extras', types: ['Brake Calipers'], mode: 'freestyle', when: 'parts', not: /\\b(disc|disk)\\b/i },\n    // Freestyle frames with a disc mount: the race disc parts, as optional extras.\n    { id: 'fdbrake', label: 'Disc brake', group: 'extras', types: ['Braking', 'Brake Kits', 'Brake Calipers'], mode: 'freestyle', when: 'fdisc', hint: 'Lever, hose and caliper',\n      match: /\\b(disc|disk)\\b.*(brake kit|call?iper)/i, not: /bleed|hose|rotor|pads?\\b/i },\n    { id: 'frotor', label: 'Rotor', group: 'extras', types: ['Braking', 'Brake Accessories'], mode: 'freestyle', when: 'fdisc',\n      match: /rotor|wave disc/i, not: /gyro|geo rotor|spacer|rotor bolt|cable|mount|adapt/i },\n    { id: 'fdmount', label: 'Disc mount', group: 'extras', types: ['Brake Mounts', 'Braking', 'Brake Accessories'], mode: 'freestyle', when: 'fdisc', incl: 'Built into my frame',\n      match: /(disc|disk).*(mount|adapt)|(mount|adapt).*(disc|disk)/i, not: /brake kit|brake call?iper|(disc|brake) rotor|bolts?\\b|screw/i }\n  ];\n  var GROUPS = [\n    { id: 'frame', label: 'Frame and fork' },\n    { id: 'cockpit', label: 'Cockpit' },\n    { id: 'drive', label: 'Drivetrain' },\n    { id: 'wheels', label: 'Wheels' },\n    { id: 'seat', label: 'Seat' },\n    { id: 'brakes', label: 'Brakes' },\n    { id: 'extras', label: 'Extras', note: 'optional' },\n    { id: 'workshop', label: 'Assembly' }\n  ];\n  // Levels by share of required parts done.\n  var LEVELS = [\n    { at: 0, name: 'Select your first part' },\n    { at: 0.01, name: 'Bare bones' },\n    { at: 0.3, name: 'Taking shape' },\n    { at: 0.6, name: 'Nearly rideable' },\n    { at: 1, name: 'Ready to ride' }\n  ];\n  var KEY = 'lux-build-lite-v2';\n  var WHEELS_PER_BUILD = 2;\n\n  // The wheel builder (cfg.kind 'wheels'). `end` keeps a slot to the wheel\n  // it belongs to when the rider builds one wheel. Tyres and tubes aren't\n  // `req`: they're add-ons and don't count towards a complete build.\n  var WHEEL_SLOTS = [\n    { id: 'fhub', label: 'Front hub', group: 'front', types: ['Front Hubs', 'Hub Sets'], req: true, end: 'front', hint: 'A hub set fills both hubs' },\n    { id: 'frim', label: 'Front rim', group: 'front', types: ['Rims'], req: true, end: 'front', same: 'rrim', hint: 'Same hole count as the hub' },\n    { id: 'rhub', label: 'Rear hub', group: 'rear', types: ['Rear Hubs', 'Hub Sets'], req: true, end: 'rear', hint: 'A hub set fills both hubs' },\n    { id: 'rrim', label: 'Rear rim', group: 'rear', types: ['Rims'], req: true, end: 'rear', same: 'frim', hint: 'Same hole count as the hub' },\n    { id: 'spokes', label: 'Spokes', group: 'lacing', types: ['Spokes'], req: true, count: 'spokes', hint: 'Enough for your wheels. We confirm lengths before building.' },\n    { id: 'nipples', label: 'Nipples', group: 'lacing', types: ['Nipples'], req: true, count: 'spokes', incl: 'Come with my spokes' },\n    { id: 'ftyre', label: 'Front tyre', group: 'extras', types: ['Tyres'], end: 'front', same: 'rtyre' },\n    { id: 'rtyre', label: 'Rear tyre', group: 'extras', types: ['Tyres'], end: 'rear', same: 'ftyre' },\n    { id: 'tubes', label: 'Tubes', group: 'extras', types: ['Tubes'], count: 'tubes', hint: 'One a wheel. A pair or pack counts once',\n      not: /repair|adaptor|adapter|rim tape|valve system|tubeless|insert only/i }\n  ];\n  var WHEEL_GROUPS = [\n    { id: 'front', label: 'Front wheel' },\n    { id: 'rear', label: 'Rear wheel' },\n    { id: 'lacing', label: 'Spokes and nipples' },\n    { id: 'extras', label: 'Tyres and tubes', note: 'optional' },\n    { id: 'workshop', label: 'Wheel build' }\n  ];\n  var WHEEL_LEVELS = [\n    { at: 0, name: 'Select your first part' },\n    { at: 0.01, name: 'Started' },\n    { at: 0.3, name: 'Taking shape' },\n    { at: 0.6, name: 'Nearly there' },\n    { at: 1, name: 'Ready to build' }\n  ];\n  var WHEEL_KEY = 'lux-wheel-build-v1';\n  var KIND = 'bike';\n\n  function esc(s) {\n    return String(s == null ? '' : s).replace(/[&<>\"']/g, function (c) {\n      return { '&': '&amp;', '<': '&lt;', '>': '&gt;', '\"': '&quot;', \"'\": '&#39;' }[c];\n    });\n  }\n  // For attribute values in querySelector.\n  function cssEsc(v) { return window.CSS && CSS.escape ? CSS.escape(v) : String(v).replace(/[\"\\\\]/g, '\\\\$&'); }\n  function money(cents) {\n    return '$' + (Number(cents || 0) / 100).toLocaleString('en-AU', { minimumFractionDigits: 2, maximumFractionDigits: 2 });\n  }\n  function slotById(id) {\n    for (var i = 0; i < SLOTS.length; i++) if (SLOTS[i].id === id) return SLOTS[i];\n    return null;\n  }\n  // Front and rear slots that one product can fill together: a wheel set\n  // covers both wheels, a hub set both hubs, a tyre sold as a pair both tyres.\n  var PAIRS = { front: 'rear', rear: 'front', fhub: 'rhub', rhub: 'fhub', ftyre: 'rtyre', rtyre: 'ftyre' };\n  var SET_WORD = { front: 'wheel set', rear: 'wheel set', fhub: 'hub set', rhub: 'hub set', ftyre: 'pair', rtyre: 'pair' };\n  function fillsBoth(slotId, p) {\n    if (slotId === 'front' || slotId === 'rear') return p.ty === 'Wheel Sets';\n    if (slotId === 'fhub' || slotId === 'rhub') return p.ty === 'Hub Sets';\n    if (slotId === 'ftyre' || slotId === 'rtyre') return /\\bpair\\b/i.test(p.t);\n    return false;\n  }\n  // The rear of a pair: a set there is the same item as the front's.\n  function isRearOfPair(id) { return id === 'rear' || id === 'rhub' || id === 'rtyre'; }\n  // A frame sold with its fork (the discount function reads it the same way):\n  // \"Frame/Fork Kit\", \"Frame & Fork Kit\", \"Frame Kit\", \"Frameset\".\n  var FRAME_FORK_KIT = /frame\\s*(\\/|&|\\+|and)\\s*fork|\\bframe\\s*kit\\b|\\bframesets?\\b/i;\n\n  // Pack sizes as titles (and, for spokes and nipples, descriptions) write\n  // them: \"40 Pack\", \"(144pcs)\", \"(40pk)\", \"(Pack of 50)\", \"set of 40\",\n  // \"packets of 144\", \"150 per pack\". 0 when it doesn't say.\n  function packSize(text) {\n    var m = /(\\d+)\\s*(?:pack|pk|pcs|pieces|per pack)\\b|\\b(?:pack|set|packets?|bag|box) of (\\d+)/i.exec(text || '');\n    return m ? +(m[1] || m[2]) : 0;\n  }\n  function packOf(p) { return (p && (p.pack || packSize((p.title || '') + ' ' + (p.variantTitle || '')))) || 0; }\n\n  // Whether a product title suits the slot (see `match` and `not`).\n  function fits(s, title) {\n    return (!s.match || s.match.test(title || '')) && (!s.not || !s.not.test(title || ''));\n  }\n\n  // Wheel fit, in the wheel builder. A variant's \"f\" in the feed is its fit\n  // fields [holes, bsd, valve, tyre width], each a \"|\" list or null.\n  var FIT_KEYS = ['holes', 'bsd', 'valve', 'width'];\n  function fitOf(v) {\n    if (!v || !v.f) return null;\n    var out = {}, any = false;\n    FIT_KEYS.forEach(function (k, i) {\n      var list = v.f[i] ? String(v.f[i]).split('|').filter(Boolean) : [];\n      if (list.length) { out[k] = list; any = true; }\n    });\n    return any ? out : null;\n  }\n  // Slots that have to agree, and on what (docs/fit-fields.md): rim holes =\n  // hub holes, rim size = tyre = tube, tube valve = rim valve hole. Tubes\n  // cover both wheels.\n  var FIT_PAIRS = [\n    ['holes', 'fhub', 'frim'], ['holes', 'rhub', 'rrim'],\n    ['bsd', 'frim', 'ftyre'], ['bsd', 'rrim', 'rtyre'],\n    ['bsd', 'frim', 'tubes'], ['bsd', 'rrim', 'tubes'],\n    ['bsd', 'ftyre', 'tubes'], ['bsd', 'rtyre', 'tubes'],\n    ['valve', 'frim', 'tubes'], ['valve', 'rrim', 'tubes']\n  ];\n  var BSD_NAME = { 203: '12 in', 254: '14 in', 305: '16 in', 349: '16 \\u00d7 1 3/8', 355: '18 in', 406: '20 in', 451: '20 \\u00d7 1 3/8',\n    457: '22 in', 507: '24 in', 559: '26 in', 584: '27.5 in', 622: '29 in' };\n  function fitWords(field, list) {\n    if (field === 'holes') return list.join(' or ') + ' holes';\n    if (field === 'bsd') return list.map(function (b) { return BSD_NAME[b] ? BSD_NAME[b] + ' (' + b + ' mm)' : b + ' mm'; }).join(' or ');\n    if (field === 'valve') return list.map(function (x) { return x.charAt(0).toUpperCase() + x.slice(1); }).join(' or ') + ' valve';\n    return list.join(' or ');\n  }\n  // How each side of a clash reads: \"This has 32 holes, your front hub has 36 holes.\"\n  var FIT_VERB = { holes: ['has', 'has'], bsd: ['is', 'is'], valve: ['is', 'takes a'] };\n  function overlap(a, b) { return a.some(function (x) { return b.indexOf(x) !== -1; }); }\n\n  // The spoke calculator's maths (assets/lux-calculators.js): one spoke from\n  // rim ERD, flange diameter, centre to flange distance, holes and crosses.\n  var SPOKE_HOLE = 2.5, SPOKE_TOL = 1;\n  function spokeLength(erd, pcd, d, spokes, crosses) {\n    var R = erd / 2, r = pcd / 2;\n    var a = (2 * Math.PI * crosses) / (spokes / 2);\n    var sq = R * R + r * r + d * d - 2 * R * r * Math.cos(a);\n    return sq < 0 ? NaN : Math.sqrt(sq) - SPOKE_HOLE / 2;\n  }\n  // A lux-wheel-data hub row's flanges as drive and non-drive side, the way\n  // the calculator's hub picker reads them (applyHub).\n  function hubSides(h) {\n    var pl = h[3], pr = h[4], sp = h[5], aL = h[6], aR = h[7], isF2L = h[8];\n    var driveRight = true;\n    if (h[11] !== 1) {\n      if (pl !== pr) driveRight = pr > pl;\n      else if (aL !== aR) {\n        var rightCloser = isF2L ? aR > aL : aR < aL;\n        driveRight = /\\bdisc\\b/i.test(String(h[0])) ? !rightCloser : rightCloser;\n      }\n    }\n    var aD = driveRight ? aR : aL, aN = driveRight ? aL : aR;\n    var g = { pD: driveRight ? pr : pl, pN: driveRight ? pl : pr, dD: isF2L ? sp / 2 - aD : aD, dN: isF2L ? sp / 2 - aN : aN };\n    return g.pD > 0 && g.pN > 0 && g.dD > 0 && g.dN > 0 && (!isF2L || sp > 0) ? g : null;\n  }\n  function normTitle(t) { return String(t || '').toLowerCase().replace(/[^a-z0-9]+/g, ' ').trim(); }\n  // A part's row in the wheel data: by handle, else by the same title. For\n  // hubs, front is 1 or 0: a hub set has a row for each end under its handle.\n  function dataRow(rows, p, front) {\n    if (!rows || !p || !p.handle) return null;\n    var t = normTitle(p.title), byTitle = null;\n    for (var i = 0; i < rows.length; i++) {\n      if (front != null && rows[i][2] !== front) continue;\n      if (rows[i][1] && rows[i][1] === p.handle) return rows[i];\n      if (!byTitle && normTitle(rows[i][0]) === t) byTitle = rows[i];\n    }\n    return byTitle;\n  }\n  // The variant of the chosen spokes for a length: a stocked length within\n  // a millimetre (in stock first, then the closest), else one cut to size\n  // that covers it. Null when they don't come in that length.\n  function snapLength(len, lens) {\n    var fixed = [], cut = null;\n    lens.forEach(function (x) {\n      var val = String(x.o || '').trim();\n      var one = /^(\\d+(?:\\.\\d+)?)\\s*mm$/i.exec(val);\n      if (one) { if (Math.abs(+one[1] - len) <= SPOKE_TOL + 1e-9) fixed.push({ v: x, len: +one[1] }); return; }\n      var range = /(\\d+)\\s*mm\\s*(?:to|-)\\s*(\\d+)\\s*mm/i.exec(val);\n      var fitsRange = range ? len >= +range[1] && len <= +range[2] : /cut/i.test(val);\n      if (fitsRange && (!cut || (x.a && !cut.v.a))) cut = { v: x, len: Math.round(len), cut: true };\n    });\n    if (fixed.length) {\n      fixed.sort(function (a, b) { return (b.v.a ? 1 : 0) - (a.v.a ? 1 : 0) || Math.abs(a.len - len) - Math.abs(b.len - len) || a.len - b.len; });\n      return fixed[0];\n    }\n    return cut;\n  }\n\n  function init(root) {\n    var cfg = {};\n    try { cfg = JSON.parse(root.getAttribute('data-config') || '{}'); } catch (e) { /* defaults */ }\n    // One builder per page, so the wheel builder swaps the slot set outright.\n    if (cfg.kind === 'wheels') {\n      KIND = 'wheels'; SLOTS = WHEEL_SLOTS; GROUPS = WHEEL_GROUPS; LEVELS = WHEEL_LEVELS; KEY = WHEEL_KEY;\n    }\n    var hud = root.querySelector('[data-build-hud]');\n    var board = root.querySelector('[data-build-board]');\n    var actions = root.querySelector('[data-build-actions]');\n    var dialog = root.querySelector('[data-build-dialog]');\n    var picker = root.querySelector('[data-build-picker]');\n    var toastEl = root.querySelector('[data-build-toast]');\n\n    var saved = load();\n    var picks = saved.picks || {};\n    var opts = saved.opts || {};\n    if (!opts.brakes) opts.brakes = 'kit';\n    if (opts.mode !== 'race') opts.mode = 'freestyle';\n    if (!opts.raceBrakes) opts.raceBrakes = 'disc';\n    applyMode();\n    if (picks.tyres) {\n      // Saved before front and rear tyres were separate: same tyre both ends,\n      // or one pair product across both.\n      var oldTyre = picks.tyres;\n      if (/\\bpair\\b/i.test(oldTyre.title || '')) oldTyre.set = true;\n      if (!picks.ftyre) picks.ftyre = oldTyre;\n      if (!picks.rtyre) picks.rtyre = oldTyre;\n      delete picks.tyres;\n    }\n    if (picks.rims) {\n      // Saved before front and rear rims were separate: same rim both ends.\n      if (!picks.frim) picks.frim = picks.rims;\n      if (!picks.rrim) picks.rrim = picks.rims;\n      delete picks.rims;\n    }\n    if (!opts.pegs) opts.pegs = 2;\n    if (['pair', 'front', 'rear'].indexOf(opts.wheels) === -1) opts.wheels = 'pair';\n    // Sent here from the wheel builder (?wheels=custom): its hubs, rims and\n    // spokes are in the cart, so the bike takes custom wheels and the cart\n    // fills them in.\n    if (KIND === 'bike' && /[?&]wheels=custom(&|$)/.test(location.search)) { opts.customWheels = true; opts.wheelsSet = true; }\n    if (opts.assembly === undefined) opts.assembly = true;\n    var celebrated = progress().done === progress().need;\n    var justFilled = null;\n    var msg = null;          // { ok, html } after save or cart\n    var busy = false;        // adding to the cart\n    var listBusy = false;    // saving to the wishlist\n    var wheelBuild = null;   // the workshop's wheel build service, from cfg.wheelBuildHandle\n    var inCart = {};         // variant id -> quantity already in the cart\n    var cartShare = {};      // slot id -> how much of its quantity the cart holds\n\n    // Picker state\n    var open = null;         // slot id\n    var view = 'list';       // 'list' | 'detail'\n    var term = '';\n    var sort = 'popular';\n    var cache = {};          // key -> { items, seen, next: {type: page}, pages: {type: n}, loading, error }\n    var extraSel = {};       // slot id -> { filter param: [values] }, the Search & Discovery filters\n    var slotFilters = {};    // slot id -> that type's filters, from the feed's page 1\n    var chosen = null;       // { product, sel: [option values], stage: photo url }\n    var stock = {};          // handle -> { loading, error, byId: { variant id: buy grid status } }\n    var brandSel = [];       // brands ticked in the open picker (reset per slot)\n    var menu = null;         // 'disc' | 'brand': which filter dropdown is open\n    if (!Array.isArray(opts.disc)) opts.disc = [];\n    if (!Array.isArray(opts.colours)) opts.colours = [];\n\n    // ------------------------------------------------------------ storage\n\n    function load() {\n      try {\n        var raw = JSON.parse(localStorage.getItem(KEY) || '{}');\n        return raw && typeof raw === 'object' ? raw : {};\n      } catch (e) { return {}; }\n    }\n    function save() {\n      try { localStorage.setItem(KEY, JSON.stringify({ picks: picks, opts: opts })); } catch (e) { /* private mode: build lasts this visit */ }\n      exportBuild();\n      emit();\n    }\n    // The build's parts, as they'd go in the cart, for the Dream Build entry\n    // form (assets/lux-dream-build.js), which can't run the slot rules.\n    // Prices in cents, in this visit's currency.\n    function exportBuild() {\n      if (KIND === 'wheels') return; // the giveaway is for bikes\n      try {\n        localStorage.setItem('lux-build-lite-export', JSON.stringify({\n          at: new Date().toISOString(),\n          currency: cfg.currency || 'AUD',\n          items: partLines().map(function (l) {\n            var p = l.pick;\n            return {\n              title: p.title, variantTitle: p.variantTitle && p.variantTitle !== 'Default Title' ? p.variantTitle : '',\n              variantId: +p.variantId, productId: +p.productId, price: p.price, qty: l.qty,\n              slot: l.slot.label, url: p.url, handle: p.handle, image: p.img || ''\n            };\n          })\n        }));\n      } catch (e) { /* private mode, or storage full */ }\n    }\n    // Tells the page what's in the build (the 3D preview in the corner\n    // listens, assets/lux-bike-preview.js). Picks are shared, not copied.\n    // `shown` is the slots on the board now: picks kept for hidden slots\n    // (complete wheels while custom wheels are on, pegs on a race bike)\n    // aren't part of the bike.\n    function emit() {\n      var state = { picks: picks, opts: opts, shown: visible().map(function (s) { return s.id; }) };\n      window.luxBuildState = state;\n      try { document.dispatchEvent(new CustomEvent('lux:build:change', { detail: state })); } catch (e) { /* no CustomEvent: the preview reads storage instead */ }\n      loadPreview();\n    }\n\n    // The ghost bike (three.js and a 1.7 MB model) loads once the build has a\n    // part in it, so a visit that never picks anything doesn't pay for it.\n    // Until then the tile shows a still of the same bike (assets/lux-bike-ghost.webp).\n    // Data saver keeps the still unless the rider asks for the bigger view.\n    var previewLoaded = false;\n    function loadPreview(asked) {\n      if (previewLoaded || (!asked && !Object.keys(picks).length)) return;\n      var el = document.querySelector('[data-build-preview][data-script]');\n      if (!el) return;\n      var conn = navigator.connection;\n      if (!asked && conn && conn.saveData) return;\n      previewLoaded = true;\n      var tag = document.createElement('script');\n      tag.src = el.getAttribute('data-script');\n      tag.async = true;\n      document.head.appendChild(tag);\n    }\n    function showPreviewStill() {\n      var el = document.querySelector('[data-build-preview][data-script]');\n      if (!el) return;\n      el.classList.add('is-still');\n      el.hidden = false;\n      // The bigger view before the 3D bike has loaded: open it on the still\n      // and load the bike. Once loaded, the preview script runs this button.\n      var size = el.querySelector('[data-bp-size]');\n      if (size) size.addEventListener('click', function () {\n        if (previewLoaded) return;\n        el.classList.add('is-large');\n        size.setAttribute('aria-pressed', 'true');\n        loadPreview(true);\n      }, { once: true });\n    }\n\n    // ------------------------------------------------------------ model\n\n    // Race calls the sprocket a chainring.\n    function applyMode() {\n      SLOTS.forEach(function (s) {\n        if (!s.raceLabel) return;\n        if (!s.baseLabel) s.baseLabel = s.label;\n        s.label = opts.mode === 'race' ? s.raceLabel : s.baseLabel;\n      });\n    }\n\n    function canInclude(s) { return !!s.incl && (!s.inclMode || s.inclMode === opts.mode); }\n\n    // A frame and fork kit fills the fork; picking a plain frame, or removing\n    // the kit, takes that back. Returns the slot it filled, if any.\n    function frameHasFork() {\n      var f = picks.frame;\n      return !!(f && !f.included && (f.kit || FRAME_FORK_KIT.test(f.title || '')));\n    }\n    function syncForkKit() {\n      if (frameHasFork()) {\n        if (!picks.fork) { picks.fork = { included: true, kit: true }; return 'fork'; }\n      } else if (picks.fork && picks.fork.kit) {\n        delete picks.fork;\n      }\n      return null;\n    }\n\n    function shown(s) {\n      if (s.mode && s.mode !== opts.mode) return false;\n      if (s.end && KIND === 'wheels' && opts.wheels !== 'pair' && s.end !== opts.wheels) return false;\n      if (!s.when) return true;\n      if (s.when === 'stock') return !opts.customWheels;\n      if (s.when === 'custom') return !!opts.customWheels;\n      if (s.when === 'kit') return opts.brakes === 'kit';\n      if (s.when === 'parts') return opts.brakes === 'parts';\n      if (s.when === 'fdisc') return opts.brakes === 'disc';\n      if (s.when === 'disc') return opts.raceBrakes !== 'v';\n      if (s.when === 'v') return opts.raceBrakes === 'v';\n      return true;\n    }\n    function visible() { return SLOTS.filter(shown); }\n    function required() { return visible().filter(function (s) { return s.req; }); }\n    function progress() {\n      var need = required();\n      var done = need.filter(function (s) { return picks[s.id]; }).length;\n      return { done: done, need: need.length, missing: need.filter(function (s) { return !picks[s.id]; }) };\n    }\n\n    // Spokes for both wheels: each rim's hole count (36 if it isn't picked\n    // or doesn't say), front plus rear.\n    function holes(r) {\n      if (r && r.fit && r.fit.holes && r.fit.holes.length === 1) return +r.fit.holes[0];\n      var m = r && /(\\d+)\\s*(?:hole|h\\b)/i.exec((r.variantTitle || '') + ' ' + (r.title || ''));\n      return m ? +m[1] : 36;\n    }\n    // Rims on the board only: one wheel needs one rim's worth.\n    function spokeCount() {\n      return ['frim', 'rrim'].filter(function (id) { var r = slotById(id); return !r || shown(r) || KIND !== 'wheels'; })\n        .reduce(function (n, id) { return n + holes(picks[id]); }, 0);\n    }\n    // Wheels being built: both on a bike, one or two in the wheel builder.\n    function wheelCount() { return KIND === 'wheels' && opts.wheels !== 'pair' ? 1 : WHEELS_PER_BUILD; }\n    // The workshop's wheel build applies: always in the wheel builder, on a\n    // bike when the rider turns on custom wheels.\n    function customOn() { return KIND === 'wheels' || !!opts.customWheels; }\n    // Pegs per product: a pair or a peg set is two, \"N pack\" is N, else one.\n    function pegsPer(p) { return packOf(p) || (/\\bpair\\b|\\bpeg set\\b/i.test(p.title || '') ? 2 : 1); }\n    // Tubes per product: a pair is two, \"N pack\" is N, else one.\n    function tubesPer(p) { return packOf(p) || (/\\bpair\\b/i.test(p.title || '') ? 2 : 1); }\n    // Spokes and nipples sold one by one: the title says \"each\", or a low\n    // price with no pack size. A pack of unknown size counts once, and the\n    // workshop confirms the count before building.\n    function perSpoke(p) { return /\\beach\\b/i.test((p.title || '') + ' ' + (p.variantTitle || '')) || (!packOf(p) && p.price < 1000); }\n    // How many of a product to buy for this slot.\n    function qtyFor(s, p) {\n      if (s.qty) return s.qty;\n      if (s.count === 'pegs') return Math.ceil(opts.pegs / pegsPer(p));\n      if (s.count === 'tubes') return Math.ceil(wheelCount() / tubesPer(p));\n      if (s.count === 'spokes') {\n        var pack = packOf(p);\n        if (pack) return Math.ceil(spokeCount() / pack);\n        return perSpoke(p) ? spokeCount() : 1;\n      }\n      return 1;\n    }\n    // \"72 spokes x $1.99\", \"4 packs x $19.99 (72 spokes)\", \"2 x $59.99\": what\n    // a card's line total is made of. Spoke cutting is included in the price of\n    // cut-to-size spokes, so nothing is added for it.\n    function unitLine(s, p, q) {\n      if (s.count === 'spokes') {\n        return perSpoke(p) && !packOf(p) ? q + ' spokes \\u00d7 ' + money(p.price) : q + ' pack' + (q === 1 ? '' : 's') + ' \\u00d7 ' + money(p.price) + ' (' + spokeCount() + ' spokes)';\n      }\n      if (s.count === 'pegs') {\n        return pegsPer(p) > 1 ? q + ' set' + (q === 1 ? '' : 's') + ' \\u00d7 ' + money(p.price) + ' (' + opts.pegs + ' pegs)' : q + ' pegs \\u00d7 ' + money(p.price);\n      }\n      return q + ' \\u00d7 ' + money(p.price);\n    }\n    function qtyNote(s, p) {\n      var q = qtyFor(s, p);\n      if (s.count === 'pegs') return opts.pegs + ' pegs' + (pegsPer(p) > 1 ? ' (' + q + ' set' + (q === 1 ? '' : 's') + ')' : '');\n      if (s.count === 'tubes') return tubesPer(p) > 1 && wheelCount() > 1 ? 'Covers both wheels' : '';\n      if (s.count === 'spokes') {\n        if (packOf(p)) return spokeCount() + ' needed, ' + q + ' pack' + (q === 1 ? '' : 's');\n        return perSpoke(p) ? spokeCount() + ' needed' : 'One pack. We confirm the count before building';\n      }\n      return q > 1 ? '\u00D7' + q : '';\n    }\n\n    // ------------------------------------------------------------ fit\n\n    // The other slots a slot has to agree with, on the board now.\n    function pairsFor(id) {\n      if (KIND !== 'wheels') return [];\n      return FIT_PAIRS.filter(function (r) { return r[1] === id || r[2] === id; }).map(function (r) {\n        return { field: r[0], other: r[1] === id ? r[2] : r[1] };\n      }).filter(function (x) { var o = slotById(x.other); return o && shown(o); });\n    }\n    // A part's fit in slot id against the rest of the build: 'no' (and why)\n    // when a field clashes, 'yes' when one matches, '?' when nothing's known.\n    function fitCheck(id, fit) {\n      var out = { state: '?', why: null };\n      if (!fit) return out;\n      pairsFor(id).forEach(function (x) {\n        var o = picks[x.other];\n        if (!o || o.included || !o.fit || out.state === 'no') return;\n        var mine = fit[x.field], theirs = o.fit[x.field];\n        if (!mine || !theirs) return;\n        if (overlap(mine, theirs)) out.state = 'yes';\n        else out = { state: 'no', why: { other: x.other, field: x.field, mine: mine, theirs: theirs } };\n      });\n      return out;\n    }\n    function misfitText(why, brief) {\n      var o = slotById(why.other).label.toLowerCase();\n      if (brief) return 'Doesn\\u2019t fit your ' + o;\n      var verb = FIT_VERB[why.field] || ['is', 'is'];\n      return 'Doesn\\u2019t fit your ' + o + '. This ' + verb[0] + ' ' + fitWords(why.field, why.mine) + ', your ' + o + ' ' + verb[1] + ' ' + fitWords(why.field, why.theirs) + '.';\n    }\n    // A product in the picker: its best variant decides.\n    var FIT_RANK = { yes: 0, '?': 1, no: 2 };\n    function productFit(id, p) {\n      if (id === 'spokes') return spokeFit(p);\n      if (!pairsFor(id).length) return { state: '?' };\n      var pool = p.vs.filter(sells);\n      if (!pool.length) pool = p.vs;\n      var best = null;\n      pool.forEach(function (v) {\n        var r = fitCheck(id, fitOf(v));\n        if (!best || FIT_RANK[r.state] < FIT_RANK[best.state]) best = r;\n      });\n      return best || { state: '?' };\n    }\n    // Spokes against the lengths the wheels need: any colour that comes in\n    // every length counts.\n    function spokeFit(p) {\n      var w = KIND === 'wheels' ? wheelLengths() : null;\n      if (!w || w.why || lengthIndex(p) === -1) return { state: '?' };\n      var pool = p.vs.filter(sells);\n      if (!pool.length) pool = p.vs;\n      var pack = packSize(p.t) || packSize(p.ds);\n      var ok = pool.some(function (v) { var r = spokePlan({ title: p.t, pack: pack, lens: lensFor(p, v) }); return r && r.ok; });\n      return ok ? { state: 'yes', label: 'Comes in your lengths' } : { state: 'no', label: 'Not in your lengths' };\n    }\n    // What fits first, then what isn't known, then what doesn't fit.\n    function fitFirst(list) {\n      if (!pairsFor(open).length && open !== 'spokes') return list;\n      return list.map(function (p, i) { return { p: p, i: i, r: FIT_RANK[productFit(open, p).state] }; })\n        .sort(function (a, b) { return a.r - b.r || a.i - b.i; }).map(function (x) { return x.p; });\n    }\n    function misfit(s) {\n      var p = picks[s.id];\n      return p && !p.included ? fitCheck(s.id, p.fit) : { state: '?' };\n    }\n\n    // ------------------------------------------------------------ spoke lengths\n\n    // Hub flanges and rim ERDs from the spoke calculator's data page.\n    var wheelData = null, WHEEL_DATA_CACHE = 'luxWheelData_v1';\n    function loadWheelData() {\n      if (KIND !== 'wheels' || !cfg.wheelData || wheelData) return;\n      try { wheelData = JSON.parse(sessionStorage.getItem(WHEEL_DATA_CACHE) || 'null'); } catch (e) { /* fetch it */ }\n      if (wheelData) return;\n      fetch(cfg.wheelData, { credentials: 'same-origin' })\n        .then(function (r) { if (!r.ok) throw new Error(r.status); return r.text(); })\n        .then(function (html) {\n          var tag = new DOMParser().parseFromString(html, 'text/html').getElementById('lux-wheel-data');\n          wheelData = JSON.parse(tag.textContent);\n          try { sessionStorage.setItem(WHEEL_DATA_CACHE, JSON.stringify(wheelData)); } catch (e) { /* fine */ }\n          render();\n        })\n        .catch(function () { /* lengths stay with the workshop */ });\n    }\n    function activeEnds() { return opts.wheels === 'pair' ? ['front', 'rear'] : [opts.wheels]; }\n    // Each wheel's exact spoke lengths, side by side. Null until the hubs and\n    // rims are picked; { why } when a part has no measurements.\n    function wheelLengths() {\n      if (KIND !== 'wheels' || !wheelData) return null;\n      var out = [];\n      var ends = activeEnds();\n      for (var i = 0; i < ends.length; i++) {\n        var end = ends[i], hub = picks[end === 'front' ? 'fhub' : 'rhub'], rim = picks[end === 'front' ? 'frim' : 'rrim'];\n        if (!hub || !rim || hub.included || rim.included) return null;\n        var h = dataRow(wheelData.h, hub, end === 'front' ? 1 : 0), r = dataRow(wheelData.r, rim);\n        var g = h ? hubSides(h) : null;\n        if (!g) return { why: 'We don\\u2019t have measurements for your ' + end + ' hub yet' };\n        if (!r || !(r[2] > 0)) return { why: 'We don\\u2019t have the ERD of your ' + end + ' rim yet' };\n        var n = holes(rim), cross = n >= 48 ? 4 : Math.min(3, Math.floor(n / 8));\n        var lD = spokeLength(r[2], g.pD, g.dD, n, cross), lN = spokeLength(r[2], g.pN, g.dN, n, cross);\n        if (!(lD > 0) || !(lN > 0)) return { why: 'Your ' + end + ' hub and rim measurements don\\u2019t add up' };\n        out.push({ end: end, holes: n, cross: cross, d: lD, nd: lN });\n      }\n      return out;\n    }\n    // A spoke product's lengths in one colour (the variant's other options).\n    function lengthIndex(p) { return (p.o || []).map(function (n) { return String(n).toLowerCase(); }).indexOf('length'); }\n    function lensFor(p, v) {\n      var li = lengthIndex(p);\n      if (li === -1 || !v) return null;\n      return p.vs.filter(function (x) { return x.o.every(function (val, k) { return k === li || val === v.o[k]; }); })\n        .map(function (x) { return { id: x.id, t: x.t, o: x.o[li], p: x.p, a: x.a }; });\n    }\n    // The spokes to buy: each side's length snapped to the spokes' lengths\n    // (the build's spokes, or a product being looked at in the picker).\n    // { ok: true, ends, lines } or { why } or null.\n    function spokePlan(sp) {\n      sp = sp || picks.spokes;\n      if (KIND !== 'wheels' || !sp || sp.included) return null;\n      var w = wheelLengths();\n      if (!w || w.why) return w;\n      if (!sp.lens) return { why: 'These spokes don\\u2019t list lengths' };\n      var ends = [], byId = {}, list = [];\n      for (var i = 0; i < w.length; i++) {\n        var e = w[i], half = e.holes / 2, rear = e.end === 'rear';\n        var sD = snapLength(e.d, sp.lens), sN = snapLength(e.nd, sp.lens);\n        if (!sD || !sN) return { why: 'These don\\u2019t come in the ' + Math.round(!sD ? e.d : e.nd) + ' mm your ' + e.end + ' wheel needs', missing: true };\n        var sides = sD.v.id === sN.v.id && sD.len === sN.len\n          ? [{ label: 'both sides', n: e.holes, s: sD }]\n          : [{ label: rear ? 'drive side' : 'one side', n: half, s: sD }, { label: rear ? 'non-drive side' : 'other side', n: half, s: sN }];\n        sides.forEach(function (x) {\n          if (!byId[x.s.v.id]) { byId[x.s.v.id] = { v: x.s.v, count: 0, cuts: [] }; list.push(byId[x.s.v.id]); }\n          byId[x.s.v.id].count += x.n;\n          if (x.s.cut) byId[x.s.v.id].cuts.push(e.end + ' ' + x.n + ' at ' + x.s.len + ' mm');\n        });\n        ends.push({ end: e.end, cross: e.cross, sides: sides });\n      }\n      list.forEach(function (l) {\n        var probe = { title: sp.title, variantTitle: l.v.t, price: l.v.p, pack: sp.pack };\n        var pack = packOf(probe);\n        l.qty = pack ? Math.ceil(l.count / pack) : (perSpoke(probe) ? l.count : 1);\n      });\n      return { ok: true, ends: ends, lines: list };\n    }\n    // \"Front: 36 at 184 mm. Rear: 18 at 186 mm (drive side), 18 at 184 mm. 3 cross.\"\n    function planText(plan) {\n      var cross = plan.ends.map(function (e) { return e.cross; });\n      return plan.ends.map(function (e) {\n        return e.end.charAt(0).toUpperCase() + e.end.slice(1) + ': ' + e.sides.map(function (x) {\n          return x.n + ' at ' + x.s.len + ' mm' + (e.sides.length > 1 ? ' (' + x.label + ')' : '');\n        }).join(', ');\n      }).join('. ') + '. Laced ' + (cross.every(function (c) { return c === cross[0]; }) ? cross[0] : cross.join(' and ')) + ' cross.';\n    }\n    // The cart note when the build can't take the lengths itself.\n    function unconfirmedText(plan) {\n      var w = wheelLengths();\n      var need = w && !w.why ? ' Needs ' + w.map(function (e) {\n        return e.end + ' ' + (Math.abs(e.d - e.nd) < 0.5 ? e.d.toFixed(1) + ' mm' : e.d.toFixed(1) + ' and ' + e.nd.toFixed(1) + ' mm');\n      }).join(', ') + '.' : '';\n      return 'To confirm before building. ' + (plan && plan.why ? plan.why + '.' : 'Not worked out from the hubs and rims.') + need;\n    }\n    function planPick(p, l) {\n      var q = {};\n      Object.keys(p).forEach(function (k) { q[k] = p[k]; });\n      q.variantId = l.v.id; q.variantTitle = l.v.t; q.price = l.v.p; q.colourGroups = l.v.g || null; q.swatch = l.v.sw || null;\n      return q;\n    }\n\n    // The wheel build service joins the build with the first wheel part.\n    function wheelsStarted() {\n      return ['fhub', 'rhub', 'frim', 'rrim', 'spokes'].some(function (id) { return picks[id] && !picks[id].included; });\n    }\n\n    // One line per product. A wheel set sits in both wheel slots but is one\n    // item; the same rim front and rear is one line of two.\n    function lines() {\n      var out = [], seen = {};\n      var plan = spokePlan();\n      visible().forEach(function (s) {\n        var p = picks[s.id];\n        if (!p || p.included) return;\n        // Spokes with worked-out lengths: a line for each length.\n        if (s.id === 'spokes' && plan && plan.ok) {\n          // The lengths go on the first spoke line, for the workshop.\n          plan.lines.forEach(function (l, i) {\n            var props = {};\n            if (!i) props['Spoke lengths'] = planText(plan);\n            if (l.cuts.length) props['Cut to'] = l.cuts.join(', ');\n            out.push({ slot: s, pick: planPick(p, l), qty: l.qty, props: props });\n          });\n          return;\n        }\n        var key = (p.set ? 'set:' : 'v:') + p.variantId;\n        if (seen[key]) {\n          if (!p.set) {\n            // Same rim or tyre front and rear: one line, labelled \"Rims\", \"Tyres\".\n            var base = s.label.replace(/^(Front|Rear) /i, '');\n            seen[key].qty += qtyFor(s, p);\n            seen[key].slot = { id: seen[key].slot.id, label: base.charAt(0).toUpperCase() + base.slice(1) + 's' };\n          }\n          return;\n        }\n        seen[key] = { slot: s, pick: p, qty: qtyFor(s, p) };\n        // Spokes without worked-out lengths: the cart line says so, for the workshop.\n        if (s.id === 'spokes' && KIND === 'wheels') seen[key].props = { 'Spoke lengths': unconfirmedText(plan) };\n        out.push(seen[key]);\n      });\n      if (customOn() && wheelBuild && wheelsStarted()) {\n        out.push({ slot: { id: 'wheelbuild', label: 'Wheel build' }, pick: wheelBuild, qty: wheelCount(), service: true });\n      }\n      // Assembly needs a bike to assemble: it joins with the frame.\n      if (cfg.assembly && opts.assembly && picks.frame && !picks.frame.included) {\n        out.push({ slot: { id: 'assembly', label: 'Assembly' }, pick: cfg.assembly, qty: 1, service: true });\n      }\n      return out;\n    }\n    function partLines() { return lines().filter(function (l) { return !l.service; }); }\n    function total() {\n      return lines().reduce(function (sum, l) { return sum + l.pick.price * l.qty; }, 0);\n    }\n    // Parts only, without workshop services: what the offer's percentage and\n    // the giveaway's cap are measured against.\n    function partsTotal() {\n      return lines().reduce(function (sum, l) { return l.service ? sum : sum + l.pick.price * l.qty; }, 0);\n    }\n    // What the Custom bike build discount takes off at checkout once every\n    // part is in: the percentage of the parts, plus the assembly when it's\n    // free. An estimate: checkout rounds each line.\n    // Complete for the discount, which needs a fork in the cart unless the\n    // frame is a frame and fork kit: a fork ticked by hand doesn't count.\n    function forkByHand() { return !!(picks.fork && picks.fork.included && !frameHasFork()); }\n    function offerEarned() { var pr = progress(); return pr.done === pr.need && !forkByHand(); }\n    function offerSavings() {\n      var pct = Number(cfg.offerPercent || 0);\n      if (!pct || !offerEarned()) return 0;\n      var asm = cfg.offerAssembly && cfg.assembly && opts.assembly ? cfg.assembly.price : 0;\n      return Math.round(partsTotal() * pct / 100) + asm;\n    }\n    // The build is complete: what the status line says.\n    function doneLine() {\n      if (!Number(cfg.offerPercent || 0)) return 'Every part is in. Save it or add it to your cart.';\n      if (offerEarned()) return 'Every part is in. ' + esc(offerWords()) + ' apply at checkout.';\n      return 'Every slot is filled. Add a fork to get ' + esc(offerWords()) + ', unless your frame is sold as a frame and fork kit.';\n    }\n    function offerWords() {\n      var pct = Number(cfg.offerPercent || 0);\n      return pct + '% off' + (cfg.offerAssembly && cfg.assembly && opts.assembly ? ' and free assembly' : '');\n    }\n    function level(share) {\n      var lv = LEVELS[0];\n      LEVELS.forEach(function (l) { if (share >= l.at) lv = l; });\n      return lv;\n    }\n\n    // ------------------------------------------------------------ render\n\n    var CUR = cfg.currency || 'AUD';\n    function price(cents) { return money(cents) + ' ' + esc(CUR); }\n    function plus() {\n      return '<svg focusable=\"false\" width=\"16\" height=\"16\" viewBox=\"0 0 16 16\" fill=\"none\" aria-hidden=\"true\"><path d=\"M8 2.5v11M2.5 8h11\" stroke=\"currentColor\" stroke-width=\"1.5\" stroke-linecap=\"round\"/></svg>';\n    }\n    function cross() {\n      return '<svg focusable=\"false\" width=\"12\" height=\"12\" viewBox=\"0 0 12 12\" fill=\"none\" aria-hidden=\"true\"><path d=\"M2 2l8 8M10 2l-8 8\" stroke=\"currentColor\" stroke-width=\"1.5\" stroke-linecap=\"round\"/></svg>';\n    }\n\n    // What the total is made of. Assembly joins with the frame, so a frame on\n    // its own reads \"1 part + $200.00 assembly\", not a mystery $200. Phones\n    // get the short form.\n    function includes(count) {\n      var services = lines().filter(function (l) { return l.service; });\n      var long = count + ' part' + (count === 1 ? '' : 's') + services.map(function (l) {\n        return ' + ' + money(l.pick.price * l.qty) + ' ' + esc(l.slot.label.toLowerCase());\n      }).join('');\n      var short = services.length ? 'incl. ' + esc(services.map(function (l) { return l.slot.label.toLowerCase(); }).join(' and ')) : '';\n      return '<span class=\"lux-bl__count\">' + long + '</span>' + (short ? '<span class=\"lux-bl__count-short\">' + short + '</span>' : '');\n    }\n\n    function render() {\n      var pr = progress();\n      var share = pr.need ? pr.done / pr.need : 0;\n      var C = 2 * Math.PI * 19;\n      var sum = total();\n      var parts = partsTotal();\n      var saving = offerSavings();\n      var budget = Number(cfg.budget || 0);\n      var count = partLines().length;\n\n      var html =\n        '<div class=\"lux-bl__ring\" aria-hidden=\"true\">' +\n          '<svg width=\"46\" height=\"46\" viewBox=\"0 0 46 46\"><circle cx=\"23\" cy=\"23\" r=\"19\" fill=\"none\" stroke=\"#eee\" stroke-width=\"5\"/>' +\n          '<circle cx=\"23\" cy=\"23\" r=\"19\" fill=\"none\" stroke=\"' + (share === 1 ? '#16a34a' : '#95b675') + '\" stroke-width=\"5\" stroke-linecap=\"round\" stroke-dasharray=\"' + C.toFixed(1) + '\" stroke-dashoffset=\"' + (C * (1 - share)).toFixed(1) + '\"/></svg>' +\n          '<span class=\"lux-bl__ring-num\">' + pr.done + '/' + pr.need + '</span>' +\n        '</div>' +\n        '<div class=\"lux-bl__status\"><p class=\"lux-bl__level\">' + esc(level(share).name) + '</p>' +\n          '<p class=\"lux-bl__need\">' + (pr.missing.length\n            ? '<span class=\"lux-bl__need-long\">Still needed: ' + esc(pr.missing.map(function (s) { return s.label.toLowerCase(); }).join(', ')) + '</span>' +\n              '<span class=\"lux-bl__need-short\">' + pr.missing.length + ' part' + (pr.missing.length === 1 ? '' : 's') + ' to go</span>'\n            : '<span class=\"lux-bl__need-long\">' + doneLine() + '</span><span class=\"lux-bl__need-short\">' + (forkByHand() && cfg.offerPercent ? 'Add a fork for ' + esc(cfg.offerPercent) + '% off' : 'All parts in') + '</span>') + '</p></div>' +\n        '<div class=\"lux-bl__total\"><strong>' + money(sum - saving) + '<small>' + esc(CUR) + '</small></strong>' + (saving ? '<s>' + money(sum) + '</s>' : '') +\n          (saving ? '<span class=\"lux-bl__save\">' + esc(offerWords()) + ' at checkout</span>' : includes(count)) +\n          '</div>';\n      // The giveaway is about a cool complete bike, not spending up to the\n      // cap, so the cap only shows when a build goes over it. It's measured\n      // on parts at full price: services and the build offer don't count.\n      if (budget > 0 && parts > budget) {\n        html += '<div class=\"lux-bl__budget is-over\"><p><span>' + price(parts - budget) + ' over the ' + price(budget) +\n          ' giveaway cap. If it wins, you can pay the difference or remove parts until it\\u2019s under.</span></p></div>';\n      }\n      hud.innerHTML = html;\n\n      // Share what's in the cart across the slots that use it, in board\n      // order, so the same rim front and rear with one in the cart reads\n      // \"In your cart\" on one and \"Added\" on the other.\n      var left = {};\n      Object.keys(inCart).forEach(function (k) { left[k] = inCart[k]; });\n      cartShare = {};\n      var plan = spokePlan();\n      visible().forEach(function (s) {\n        var p = picks[s.id];\n        if (!p || p.included) return;\n        if (p.set && isRearOfPair(s.id)) { cartShare[s.id] = cartShare[PAIRS[s.id]]; return; }\n        if (s.id === 'spokes' && plan && plan.ok) {\n          cartShare[s.id] = plan.lines.reduce(function (got, l) {\n            var t = Math.min(left[l.v.id] || 0, l.qty);\n            left[l.v.id] = (left[l.v.id] || 0) - t;\n            return got + t;\n          }, 0);\n          return;\n        }\n        var take = Math.min(left[p.variantId] || 0, qtyFor(s, p));\n        cartShare[s.id] = take;\n        left[p.variantId] = (left[p.variantId] || 0) - take;\n      });\n\n      var next = pr.missing.length ? pr.missing[0].id : null;\n      board.innerHTML = modeRow() + GROUPS.map(function (g) {\n        var slots = visible().filter(function (s) { return s.group === g.id; });\n        var cards = slots.map(function (s) { return tile(s, s.id === next); });\n        if (g.id === 'wheels' && opts.customWheels) cards.push(serviceTile());\n        if (g.id === 'workshop') {\n          if (KIND === 'wheels') cards.push(serviceTile());\n          else if (!cfg.assembly) return '';\n          else cards.push(assemblyTile());\n        }\n        if (!cards.length) return '';\n        return '<div class=\"lux-bl__group\"><div class=\"lux-bl__group-head\"><h2 class=\"heading h4\">' + esc(g.label) + (g.note ? ' <small>(' + esc(g.note) + ')</small>' : '') + '</h2>' + groupControls(g.id) + '</div>' +\n          '<div class=\"lux-bl__cards\">' + cards.join('') + '</div></div>';\n      }).join('');\n      justFilled = null;\n\n      var has = count > 0;\n      var anyShort = partLines().some(function (l) { return shortOf(l.pick); });\n      var anyMisfit = visible().some(function (s) { return misfit(s).state === 'no'; });\n      actions.innerHTML =\n        (anyShort ? '<p class=\"lux-bl__msg is-bad\">Some parts don\\u2019t have enough stock for this build (marked in red). Swap them, or add to cart and we\\u2019ll add as many as we have.</p>' : '') +\n        (anyMisfit ? '<p class=\"lux-bl__msg is-bad\">Some parts don\\u2019t fit each other (marked in red). Swap one of them, or add to cart and we\\u2019ll check with you before building.</p>' : '') +\n        cartButton(has) +\n        (KIND === 'wheels' && cfg.bikeBuilderUrl ? '<button type=\"button\" class=\"button lux-bl__to-bike\" data-act=\"cart-bike\"' + (has && !busy ? '' : ' disabled') + '>Add to cart and build a bike</button>' : '') +\n        '<button type=\"button\" class=\"button button--secondary\" data-act=\"wishlist\"' + (has && !listBusy ? '' : ' disabled') + '>Save to wishlist</button>' +\n        (cfg.giveawayUrl ? '<button type=\"button\" class=\"button lux-bl__enter\" data-act=\"enter\"' + (has && !listBusy ? '' : ' disabled') + '>Save and enter the giveaway</button>' : '') +\n        (has || Object.keys(picks).length ? '<button type=\"button\" class=\"lux-bl__reset\" data-act=\"reset\">Start again</button>' : '') +\n        (cfg.checkNote ? '<p class=\"lux-bl__check\">' + tick() + '<span>' + esc(cfg.checkNote) + '</span></p>' : '') +\n        (msg ? '<p class=\"lux-bl__msg' + (msg.ok ? '' : ' is-bad') + '\">' + msg.html + '</p>' : '');\n    }\n\n    // Freestyle or race, above the board; in the wheel builder, which wheels.\n    function modeRow() {\n      if (KIND === 'wheels') {\n        return '<div class=\"lux-bl__choice lux-bl__mode\" role=\"radiogroup\" aria-label=\"Which wheels\"><span>Building</span>' +\n          [['pair', 'Front and rear'], ['front', 'Front only'], ['rear', 'Rear only']].map(function (o) {\n            return '<label class=\"filter-pills text--strong\"><input type=\"radio\" name=\"lux-bl-wheels\" value=\"' + o[0] + '\" data-wheels' + (opts.wheels === o[0] ? ' checked' : '') + '><span>' + o[1] + '</span></label>';\n          }).join('') + '</div>';\n      }\n      return '<div class=\"lux-bl__choice lux-bl__mode\" role=\"radiogroup\" aria-label=\"Kind of bike\"><span>Building a</span>' +\n        [['freestyle', 'Freestyle bike'], ['race', 'Race bike']].map(function (o) {\n          return '<label class=\"filter-pills text--strong\"><input type=\"radio\" name=\"lux-bl-mode\" value=\"' + o[0] + '\" data-mode' + (opts.mode === o[0] ? ' checked' : '') + '><span>' + o[1] + '</span></label>';\n        }).join('') + '</div>';\n    }\n    function tick() {\n      return '<svg focusable=\"false\" width=\"16\" height=\"16\" viewBox=\"0 0 16 16\" fill=\"none\" aria-hidden=\"true\"><path d=\"M3 8.5l3.2 3L13 4.5\" stroke=\"currentColor\" stroke-width=\"1.8\" stroke-linecap=\"round\" stroke-linejoin=\"round\"/></svg>';\n    }\n\n    // The filter row's controls: the \"Available today\" toggle for custom\n    // wheels, and filter pills for the brake choices.\n    // A group's option, as a full-width panel under the heading: what it is,\n    // what it does, then the control. Riders missed the small pill version.\n    function optPanel(title, text, control, on) {\n      return '<div class=\"lux-bl__opt' + (on ? ' is-on' : '') + '\"><div class=\"lux-bl__opt-text\"><strong>' + title + '</strong><span>' + text + '</span></div>' + control + '</div>';\n    }\n    function groupControls(id) {\n      // The bike's panels (custom wheels, brakes) aren't for the wheel builder,\n      // whose add-ons group shares the id \"extras\".\n      if (KIND === 'wheels') return '';\n      if (id === 'wheels') {\n        var cw = !!opts.customWheels;\n        return optPanel('Custom wheel build',\n          cw ? 'On: pick your own hubs, rims, spokes and nipples, and our workshop laces them into wheels.'\n             : 'Want your own hubs, rims and spokes? Switch this on and our workshop builds the wheels.',\n          '<label class=\"lux-bl__opt-switch\"><input type=\"checkbox\" class=\"ready-toggle__input\" data-opt=\"customWheels\"' + (cw ? ' checked' : '') + '>' +\n            '<span class=\"lux-bl__opt-state\">' + (cw ? 'On' : 'Off') + '</span><span class=\"ready-toggle__switch\" aria-hidden=\"true\"><span class=\"ready-toggle__knob\"></span></span>' +\n            '<span class=\"visually-hidden\">Custom wheel build</span></label>', cw);\n      }\n      if (id === 'brakes') {\n        return optPanel('Brake type', 'Disc or V-brake. The brake parts below change to match.',\n          '<div class=\"lux-bl__choice\" role=\"radiogroup\" aria-label=\"Brake type\">' +\n          [['disc', 'Disc'], ['v', 'V-brake']].map(function (o) {\n            return '<label class=\"filter-pills text--strong\"><input type=\"radio\" name=\"lux-bl-race-brakes\" value=\"' + o[0] + '\" data-race-brakes' + (opts.raceBrakes === o[0] ? ' checked' : '') + '><span>' + o[1] + '</span></label>';\n          }).join('') + '</div>', false);\n      }\n      if (id === 'extras' && opts.mode !== 'race') {\n        return optPanel('Brakes', 'Buy a complete brake kit, pick the lever, cable and caliper separately, or go disc if your frame takes one.',\n          '<div class=\"lux-bl__choice\" role=\"radiogroup\" aria-label=\"Brakes\">' +\n          [['kit', 'Kit'], ['parts', 'Separate parts'], ['disc', 'Disc']].map(function (o) {\n            return '<label class=\"filter-pills text--strong\"><input type=\"radio\" name=\"lux-bl-brakes\" value=\"' + o[0] + '\" data-brakes' + (opts.brakes === o[0] ? ' checked' : '') + '><span>' + o[1] + '</span></label>';\n          }).join('') + '</div>', false);\n      }\n      return '';\n    }\n\n    function tile(s, isNext) {\n      var p = picks[s.id];\n      var label = s.label.toLowerCase();\n      var cls = 'lux-bl__card';\n      var media, info, corner, extra = '', badge = '';\n      if (p && p.included) {\n        cls += ' is-included';\n        media = '';\n        info = '<span class=\"lux-bl__slot-name\">' + esc(s.label) + '</span><span class=\"lux-bl__name\">Included</span><span class=\"lux-bl__hint\">' + esc(s.incl) +\n          (s.id === 'fork' && forkByHand() && Number(cfg.offerPercent || 0) > 0 ? '. The ' + esc(cfg.offerPercent) + '% needs a fork in the cart unless the frame is a frame and fork kit.' : '') + '</span>';\n        corner = '<button type=\"button\" class=\"lux-bl__corner lux-bl__corner--remove\" data-remove=\"' + s.id + '\" aria-label=\"Undo: ' + esc(label) + ' isn\u2019t included\">' + cross() + '</button>';\n      } else if (p) {\n        cls += ' is-filled' + (justFilled && justFilled.indexOf(s.id) !== -1 ? ' is-new' : '');\n        // Bought in quantity: the card shows the line total, with what it's made of.\n        var qn = qtyFor(s, p);\n        var note = qn > 1 ? unitLine(s, p, qn) : qtyNote(s, p);\n        var cost = p.price * qn, vt = p.variantTitle, want = qn;\n        var lack = shortOf(p);\n        // Spokes with worked-out lengths: the lengths, and the lines they make.\n        var plan = s.id === 'spokes' ? spokePlan() : null;\n        if (plan && plan.ok) {\n          var parts = plan.lines.map(function (l) { return planPick(p, l); });\n          cost = 0; want = 0; lack = null;\n          plan.lines.forEach(function (l, i) { cost += l.v.p * l.qty; want += l.qty; lack = lack || shortOf(parts[i]); });\n          vt = String(vt || '').split(' / ').filter(function (x) { return !/\\d\\s*mm|cut to size/i.test(x); }).join(' / ');\n          var packs = packOf({ title: p.title, variantTitle: '', pack: p.pack });\n          note = planText(plan) + (packs ? ' ' + want + ' pack' + (want === 1 ? '' : 's') + '.' : '');\n        } else if (plan && plan.why) {\n          note = (note ? note + '. ' : '') + plan.why + ', so we confirm lengths before building.';\n        }\n        media = p.img ? '<img src=\"' + esc(p.img) + '\" alt=\"\" loading=\"lazy\">' : '';\n        info = '<span class=\"lux-bl__slot-name\">' + esc(s.label) + '</span>' +\n          '<span class=\"lux-bl__name\">' + esc(p.title) + '</span>' +\n          (vt && vt !== 'Default Title' ? '<span class=\"lux-bl__variant\">' + esc(vt) + '</span>' : '') +\n          '<span class=\"lux-bl__price\">' + price(cost) + '</span>' +\n          (note || p.set ? '<span class=\"lux-bl__hint\">' + esc(note) + (p.set ? (note ? ', ' : '') + (SET_WORD[s.id] || 'set') : '') + '</span>' : '');\n        if (lack) {\n          cls += ' is-short';\n          info += '<span class=\"lux-bl__short\">' + (lack.have ? 'Only ' + lack.have + ' in stock. This build needs ' + lack.need + '.' : 'Out of stock. Swap this part.') + '</span>';\n        }\n        var mis = misfit(s);\n        if (mis.state === 'no') {\n          cls += ' is-short';\n          info += '<span class=\"lux-bl__short\">' + esc(misfitText(mis.why)) + '</span>';\n        }\n        var twinSlot = s.same ? slotById(s.same) : null;\n        // One rim or tyre from the cart could be for either wheel: the card asks.\n        if (p.fromCart && !p.endSet && twinSlot && shown(twinSlot) && !picks[s.same]) {\n          var here = s.end || (/^r/.test(s.id) ? 'rear' : 'front');\n          extra = '<div class=\"lux-bl__end\" role=\"group\" aria-label=\"Which wheel is it for?\"><span class=\"lux-bl__end-q\">From your cart. Which wheel?</span>' +\n            [['front', 'Front'], ['rear', 'Rear'], ['both', 'Both']].map(function (o) {\n              var on = o[0] === here;\n              return '<button type=\"button\" class=\"filter-pills lux-bl__end-pill' + (on ? ' is-on' : '') + '\" data-end=\"' + s.id + ':' + o[0] + '\" aria-pressed=\"' + on + '\">' + o[1] + '</button>';\n            }).join('') + '</div>';\n        }\n        var have = cartShare[s.id] || 0;\n        badge = '<div class=\"label-list\">' + (have\n          ? '<span class=\"lux-bl__label lux-bl__label--cart\">' + (have >= want ? 'In your cart' : have + ' of ' + want + ' in your cart') + '</span>'\n          : '<span class=\"lux-bl__label\">Added</span>') + '</div>';\n        corner = '<button type=\"button\" class=\"lux-bl__corner lux-bl__corner--remove\" data-remove=\"' + s.id + '\" aria-label=\"Remove ' + esc(label) + '\">' + cross() + '</button>';\n      } else {\n        cls += ' is-empty' + (isNext ? ' is-next' : '');\n        media = '<span class=\"lux-bl__ghost\">' + esc(s.label) + '</span>';\n        info = '<span class=\"lux-bl__slot-name\">' + (s.req ? 'Needed' : 'Optional') + '</span>' +\n          '<span class=\"lux-bl__name\">Choose ' + esc(label) + '</span>' +\n          (s.hint ? '<span class=\"lux-bl__hint\">' + esc(s.hint) + '</span>' : '');\n        corner = '<button type=\"button\" class=\"lux-bl__corner\" data-open=\"' + s.id + '\" aria-label=\"Choose ' + esc(label) + '\" tabindex=\"-1\">' + plus() + '</button>';\n        if (canInclude(s)) extra = '<button type=\"button\" class=\"filter-pills lux-bl__incl\" data-include=\"' + s.id + '\">' + esc(s.incl) + '</button>';\n        var twin = s.same && picks[s.same] && !picks[s.same].included && shown(slotById(s.same)) ? slotById(s.same) : null;\n        if (twin) extra = '<button type=\"button\" class=\"filter-pills lux-bl__incl lux-bl__incl--copy\" data-same=\"' + s.id + '\">Same as ' + esc(twin.label.toLowerCase()) + '</button>';\n      }\n      return '<div class=\"' + cls + '\">' + badge + corner +\n        '<button type=\"button\" class=\"lux-bl__hit\" data-open=\"' + s.id + '\" aria-label=\"' + (p ? 'Change ' : 'Choose ') + esc(label) + (p && !p.included ? ': ' + esc(p.title) : '') + '\">' +\n          '<span class=\"lux-bl__media\">' + media + '</span><span class=\"lux-bl__info\">' + info + '</span></button>' +\n        extra + '</div>';\n    }\n\n    // The workshop's wheel build, added for each wheel when custom wheels\n    // are on. Not a pick: it comes and goes with the switch.\n    function serviceTile() {\n      var w = wheelBuild;\n      if (!wheelsStarted()) {\n        return '<div class=\"lux-bl__card is-empty\"><div class=\"lux-bl__hit\" style=\"cursor:default\"><span class=\"lux-bl__media\"><span class=\"lux-bl__ghost\">Wheel build</span></span>' +\n          '<span class=\"lux-bl__info\"><span class=\"lux-bl__slot-name\">Workshop</span><span class=\"lux-bl__name\">Wheel build</span>' +\n          '<span class=\"lux-bl__hint\">Added with your first wheel part' + (w ? ', ' + price(w.price) + ' a wheel' : '') + '</span></span></div></div>';\n      }\n      return '<div class=\"lux-bl__card is-filled\"><div class=\"label-list\"><span class=\"lux-bl__label\">Added</span></div>' +\n        '<div class=\"lux-bl__hit\" style=\"cursor:default\"><span class=\"lux-bl__media\">' + (w && w.img ? '<img src=\"' + esc(w.img) + '\" alt=\"\" loading=\"lazy\">' : '') + '</span>' +\n        '<span class=\"lux-bl__info\"><span class=\"lux-bl__slot-name\">Wheel build</span><span class=\"lux-bl__name\">Built by our workshop</span>' +\n        (w ? '<span class=\"lux-bl__price\">' + price(w.price * wheelCount()) + '</span><span class=\"lux-bl__hint\">' + (wheelCount() > 1 ? price(w.price) + ' a wheel, \\u00d7' + wheelCount() : 'One wheel') + '</span>' : '<span class=\"lux-bl__hint\">' + (wheelCount() > 1 ? 'Both wheels' : 'One wheel') + '</span>') +\n        '</span></div></div>';\n    }\n\n    // The assembly service: its own cart line, on by default. While the offer\n    // makes it free, the card shows the price struck through, and checkout\n    // shows the full amount coming off.\n    function assemblyTile() {\n      var a = cfg.assembly;\n      var free = cfg.offerAssembly && opts.assembly;\n      var earned = free && offerEarned() && Number(cfg.offerPercent || 0) > 0;\n      // It joins the build with the frame (lines()).\n      var on = opts.assembly && !!(picks.frame && !picks.frame.included);\n      return '<div class=\"lux-bl__card' + (on ? ' is-filled' : ' is-empty') + '\">' +\n        (on ? '<div class=\"label-list\"><span class=\"lux-bl__label\">' + (earned ? 'Free' : 'Added') + '</span></div>' : '') +\n        '<div class=\"lux-bl__hit\" style=\"cursor:default\"><span class=\"lux-bl__media\">' + (a.img ? '<img src=\"' + esc(a.img) + '\" alt=\"\" loading=\"lazy\">' : '<span class=\"lux-bl__ghost\">Assembly</span>') + '</span>' +\n        '<span class=\"lux-bl__info\"><span class=\"lux-bl__slot-name\">Workshop</span><span class=\"lux-bl__name\">Assembled by our workshop</span>' +\n          '<span class=\"lux-bl__price\">' + (earned ? 'Free <s>' + price(a.price) + '</s>' : price(a.price)) + '</span>' +\n          '<span class=\"lux-bl__hint\">' + (opts.assembly && !on ? 'Added with your frame' : cfg.offerAssembly ? (earned ? 'With your complete build' : 'Free with a complete build') : '') + '</span>' +\n        '</span></div>' +\n        '<label class=\"filter-pills ready-toggle text--strong\"><input type=\"checkbox\" class=\"ready-toggle__input\" data-opt=\"assembly\"' + (opts.assembly ? ' checked' : '') + '>' +\n          '<span>Assemble my bike</span><span class=\"ready-toggle__switch\" aria-hidden=\"true\"><span class=\"ready-toggle__knob\"></span></span></label>' +\n      '</div>';\n    }\n\n    // Saved picks keep the price they were picked at. On load, each one is\n    // priced again from its product (in this visit's currency), so a sale\n    // ending, a price change or a country switch doesn't leave a stale total.\n    function reprice() {\n      var todo = Object.keys(picks).filter(function (id) { var p = picks[id]; return p && !p.included && p.handle && p.variantId; });\n      var handles = todo.map(function (id) { return picks[id].handle; }).filter(function (h, i, all) { return all.indexOf(h) === i; });\n      if (!handles.length) return;\n      var changed = false, left = handles.slice();\n      function next() {\n        var h = left.shift();\n        if (!h) return Promise.resolve();\n        return fetch('/products/' + encodeURIComponent(h) + '.js', { credentials: 'same-origin' })\n          .then(function (r) { return r.ok ? r.json() : null; })\n          .then(function (prod) {\n            if (!prod) return;\n            todo.forEach(function (id) {\n              var p = picks[id];\n              if (p.handle !== h) return;\n              var v = prod.variants.filter(function (x) { return String(x.id) === String(p.variantId); })[0];\n              if (v && v.price !== p.price) { p.price = v.price; changed = true; }\n            });\n          })\n          .catch(function () { /* keep the saved price */ })\n          .then(next);\n      }\n      Promise.all([next(), next(), next()]).then(function () { if (changed) { save(); render(); } else exportBuild(); });\n    }\n\n    function loadWheelBuild() {\n      if (wheelBuild || !cfg.wheelBuildHandle) return;\n      fetch('/products/' + encodeURIComponent(cfg.wheelBuildHandle) + '.js', { credentials: 'same-origin' })\n        .then(function (r) { if (!r.ok) throw new Error(r.status); return r.json(); })\n        .then(function (prod) {\n          var v = prod.variants.filter(function (x) { return x.available; })[0] || prod.variants[0];\n          wheelBuild = {\n            handle: prod.handle, productId: prod.id, variantId: v.id, title: prod.title,\n            variantTitle: v.title, price: v.price, url: prod.url || '/products/' + prod.handle,\n            img: (v.featured_image && v.featured_image.src) || prod.featured_image || null\n          };\n          render();\n        })\n        .catch(function () { /* tile says what's included; nothing to add */ });\n    }\n\n    // ------------------------------------------------------------ picker data\n\n    // One discipline ticked on its own is filtered by the feed.\n    function narrowDisc() { return opts.disc.length === 1 ? String(opts.disc[0]) : ''; }\n    // The Search & Discovery filters ticked for a slot, as feed URL params.\n    function extraQS(id) {\n      var sel = extraSel[id] || {};\n      return Object.keys(sel).sort().map(function (prm) {\n        return sel[prm].map(function (v) { return '&' + prm + '=' + encodeURIComponent(v); }).join('');\n      }).join('');\n    }\n    function extraCount(id) { var sel = extraSel[id] || {}; return Object.keys(sel).length; }\n    // slot | search | discipline | filter params (encoded, so no \"|\" inside)\n    function cacheKey() { return open + '|' + term.trim().toLowerCase() + '|' + narrowDisc() + '|' + extraQS(open); }\n    function slotKey(id) { return id + '||' + narrowDisc() + '|' + extraQS(id); }\n\n    // The type collection, best sellers first, with its discipline filter;\n    // a search (which can't sort by best selling) when the rider types,\n    // narrowed by the discipline's tag.\n    // The type collection pages sold-out products too (the feed then drops\n    // them), so it asks for the stock filter the category pages use: the\n    // \"In stock at LUXBMX\" and \"Available to order\" groups of the\n    // variant.availability filter in Search & Discovery. That halves the pages\n    // for frames. If those groups are ever edited, their ids change and the\n    // filter matches nothing; loadPage then drops it for the visit.\n    var STOCK_GROUPS = ['218628397', '218661165'];\n    var stockFilterOff = false;\n    function feedUrl(type, page, q, disc, inStock, extra) {\n      q = q.replace(/[\"()]/g, '');\n      if (!q) {\n        return '/collections/types?q=' + encodeURIComponent(type) + '&sort_by=best-selling&view=build&page=' + page +\n          (disc ? '&filter.p.m.custom.discipline=' + encodeURIComponent(disc) : '') + (extra || '') +\n          (inStock ? STOCK_GROUPS.map(function (g) { return '&filter.v.m.variant.availability=' + encodeURIComponent('gid://shopify/FilterSettingGroup/' + g); }).join('') : '');\n      }\n      var terms = [q];\n      if (disc) terms.push('tag:\"discipline-' + disc.toLowerCase().replace(/\\s+/g, '-') + '\"');\n      terms.push('product_type:\"' + type + '\"');\n      return '/search?type=product&options%5Bprefix%5D=last&view=build&page=' + page +\n        '&q=' + encodeURIComponent(terms.join(' AND ')) + (extra || '');\n    }\n\n    // Loads every part for the open slot and search. The first page shows as\n    // soon as it lands; the rest load in the background, several pages at a\n    // time, without redrawing, and the list is drawn once more when the set\n    // is complete. Until then the filters and sort are locked, so nothing\n    // moves under the rider. Each load keeps the slot and search it started\n    // with, so switching slots mid-load can't mix results.\n    function fetchMore() {\n      if (!open) return;\n      loadPage(cacheKey(), slotById(open), term.trim());\n    }\n    var MAX_PAGES = 25;   // per type: every frame on the site with room to spare\n    var PAGES_AT_ONCE = 6; // per type, per round, once the page count is known\n    var STEP = 24;         // cards shown at first and per \"Show more\"\n\n    // A prefetch (once) loads page 1 of each type and stops there, unless the\n    // rider opens that slot meanwhile; opening the picker loads the rest.\n    function loadPage(key, slot, q, once) {\n      var c = cache[key] || (cache[key] = { items: [], seen: {}, next: {}, pages: {}, inStock: {}, loading: false, error: false, limit: STEP, drawn: false });\n      if (c.loading) return;\n      var bits = key.split('|');\n      var disc = bits[2] || '', extra = bits.slice(3).join('|');\n      // Page 1 of each type first (its page count is unknown until then),\n      // then up to PAGES_AT_ONCE pages of each type together.\n      var jobs = [];\n      slot.types.forEach(function (t) {\n        var from = c.next[t] || 1;\n        if (c.pages[t] === undefined) { if (from === 1) jobs.push({ t: t, page: 1 }); return; }\n        var to = Math.min(c.pages[t], MAX_PAGES, from + PAGES_AT_ONCE - 1);\n        for (var pg = from; pg <= to; pg++) jobs.push({ t: t, page: pg });\n      });\n      if (!jobs.length) return;\n      c.loading = true;\n      c.error = false;\n      if (key === cacheKey()) { if (!c.drawn) renderPicker(); else paintLoading(c, slot); }\n      // Each page settles on its own; a type stops at its first failed page,\n      // which keeps its place and is tried again later.\n      function get(job, inStock) {\n        return fetch(feedUrl(job.t, job.page, q, disc, inStock, extra), { credentials: 'same-origin' })\n          .then(function (r) { if (!r.ok) throw new Error('HTTP ' + r.status); return r.text(); })\n          .then(function (txt) { return JSON.parse(txt); });\n      }\n      Promise.all(jobs.map(function (job) {\n        // Each type keeps the filter it started with, so its pages line up.\n        if (job.page === 1) c.inStock[job.t] = !q && !stockFilterOff;\n        var inStock = !!c.inStock[job.t];\n        return get(job, inStock)\n          .then(function (j) {\n            if (!inStock || job.page !== 1 || (j.products || []).length) return j;\n            // Nothing in stock on page 1: the filter may be stale. Ask again\n            // without it; the feed leaves sold-out parts out either way.\n            return get(job, false).then(function (all) {\n              if ((all.products || []).length) stockFilterOff = true;\n              c.inStock[job.t] = false;\n              return all;\n            });\n          })\n          .then(function (j) { return { t: job.t, page: job.page, ok: true, pages: j.pages || 1, products: j.products || [], filters: j.filters }; })\n          .catch(function () { return { t: job.t, page: job.page, ok: false }; });\n      })).then(function (res) {\n        var batches = [];\n        slot.types.forEach(function (t) {\n          var mine = res.filter(function (x) { return x.t === t; }).sort(function (a, b) { return a.page - b.page; });\n          var keepAll = [];\n          for (var k = 0; k < mine.length; k++) {\n            var x = mine[k];\n            if (!x.ok) { c.error = true; break; }\n            c.pages[t] = x.pages;\n            c.next[t] = x.page + 1;\n            // The slot's filter list follows its main type's latest page 1.\n            if (x.page === 1 && x.filters && t === slot.types[0]) slotFilters[slot.id] = x.filters;\n            var keep = x.products.filter(function (p) {\n              if (c.seen[p.h]) return false;\n              c.seen[p.h] = true;\n              return fits(slot, p.t) && matchesTerm(p, q);\n            });\n            keepAll = keepAll.concat(keep);\n            // Search ranks rather than filters: once a page has nothing for\n            // the words typed, the pages after it won't either.\n            if (q && !keep.length && (c.items.length || keepAll.length || x.page > 1)) { c.next[t] = x.pages + 1; break; }\n          }\n          batches.push(keepAll);\n        });\n        // Interleave types so a mixed slot (sprocket and chainring) keeps\n        // each type's best sellers near the top.\n        var longest = Math.max.apply(null, batches.map(function (b) { return b.length; }).concat(0));\n        for (var i = 0; i < longest; i++) {\n          batches.forEach(function (b) { if (b[i]) c.items.push(b[i]); });\n        }\n        c.loading = false;\n        var more = !c.error && hasMore(c, slot);\n        // The first products show straight away; later rounds stay quiet\n        // until the set is complete.\n        if (key === cacheKey() && (!c.drawn || !more)) renderPicker();\n        if (more && (!once || key === cacheKey())) loadPage(key, slot, q);\n      });\n    }\n    // Still loading the rest of this slot's parts: filters and sort wait.\n    function stillLoading(c, slot) { return !!c && !c.error && (c.loading || hasMore(c, slot)); }\n    // Updates the loading note without redrawing the list.\n    function paintLoading(c, slot) {\n      var n = picker.querySelector('[data-load-note]');\n      if (n) n.textContent = 'Loading every ' + slot.label.toLowerCase() + ' option\\u2026 ' + c.items.length + ' so far';\n    }\n    // Every word typed appears in the title or brand.\n    function matchesTerm(p, q) {\n      if (!q) return true;\n      var hay = ((p.t || '') + ' ' + (p.b || '')).toLowerCase();\n      return q.toLowerCase().split(/\\s+/).filter(Boolean).every(function (w) { return hay.indexOf(w) !== -1; });\n    }\n\n    function hasMore(c, slot) {\n      return slot.types.some(function (t) { return c.pages[t] === undefined || (c.next[t] || 1) <= Math.min(c.pages[t], MAX_PAGES); });\n    }\n\n    // The price a card shows: the cheapest variant the filters allow, else\n    // the cheapest in stock, else the product's own.\n    function shownPrice(p) {\n      var pool = p.vs.filter(sells);\n      if (!pool.length) pool = p.vs.filter(function (v) { return v.a; });\n      return pool.length ? Math.min.apply(null, pool.map(function (v) { return v.p; })) : p.p;\n    }\n    function sorted(items) {\n      var list = items.slice();\n      if (sort === 'low') list.sort(function (a, b) { return shownPrice(a) - shownPrice(b); });\n      else if (sort === 'high') list.sort(function (a, b) { return shownPrice(b) - shownPrice(a); });\n      return list;\n    }\n\n    // ------------------------------------------------------------ picker render\n\n    var lastOpen = null;    // the slot the picker last opened on, for focus on close\n    function openPicker(id) {\n      open = id;\n      lastOpen = id;\n      view = 'list';\n      term = '';\n      brandSel = [];\n      menu = null;\n      chosen = null;\n      if (typeof dialog.showModal === 'function') dialog.showModal(); else dialog.setAttribute('open', '');\n      renderPicker();\n      var had = cache[cacheKey()];\n      if (had && had.error) had.error = false;\n      // A prefetch stops after page 1: carry on from there.\n      if (!had || !had.items.length || (!had.loading && hasMore(had, slotById(id)))) fetchMore();\n      var input = picker.querySelector('[data-term]');\n      if (input && window.matchMedia('(pointer: fine)').matches) input.focus();\n    }\n    // After a filter change that may change what the feed returns.\n    function refreshPicker() {\n      renderPicker();\n      if (open && !cache[cacheKey()]) fetchMore();\n    }\n    function closePicker() {\n      if (dialog.open) { if (typeof dialog.close === 'function') dialog.close(); else dialog.removeAttribute('open'); }\n      open = null;\n    }\n    // Loads the first page of the next empty slot's parts while the rider is\n    // busy elsewhere, so its picker opens with parts already there. One slot\n    // at a time; the rest load when the picker opens.\n    var prefetchTimer = null;\n    function prefetchNext() {\n      clearTimeout(prefetchTimer);\n      prefetchTimer = setTimeout(function () {\n        var next = progress().missing.filter(function (s) { return s.id !== open && !cache[slotKey(s.id)]; })[0];\n        if (next) loadPage(slotKey(next.id), next, '', true);\n      }, 1500);\n    }\n\n    // A card from the category grid (snippets/product-item.liquid): swipeable\n    // photos with dots and hover arrows (lux-tile-gallery.css), the brand\n    // logo, price rules, then colour swatches and option pills (custom.css).\n    // Its price rules: the \"Save $x\" badge needs the product more than 2.5%\n    // off; the struck-through price follows the cheapest in-stock variant (or\n    // the first in-stock one when prices don't vary) and needs more than a\n    // dollar off. Sold-out option values are left off, as on the category page.\n    function small(url) { return url ? String(url).replace(/width=\\d+/, 'width=500') : url; }\n    // lead: a photo to put first (the filtered colour's variant photo).\n    function photos(p, lead) {\n      var out = [];\n      [lead, p.img].concat(p.im || []).forEach(function (u) {\n        var k = u && String(u).split('?')[0];\n        if (u && !out.some(function (x) { return x.split('?')[0] === k; }) && out.length < 6) out.push(u);\n      });\n      return out;\n    }\n    function colourIndex(p) {\n      for (var i = 0; i < (p.o || []).length; i++) if (/^colou?r$/i.test(p.o[i])) return i;\n      return -1;\n    }\n    function card(p) {\n      var inStock = p.vs.filter(function (v) { return v.a; });\n      var pool = inStock.length ? inStock : p.vs;\n      var varies = pool.some(function (v) { return v.p !== pool[0].p; });\n      var shown = varies ? pool.slice().sort(function (a, b) { return a.p - b.p; })[0] : pool[0];\n      var struck = shown.c - shown.p > 100;\n      var badge = p.c > p.p && (p.c - p.p) * 1000 / p.c > 25;\n      // A colour ticked in the filters: the card leads with the first matching\n      // in-stock variant's own photo, that swatch reads as picked, and the\n      // card opens on that colour.\n      var ci = colourIndex(p);\n      var lead = opts.colours.length ? p.vs.filter(function (v) { return sells(v) && v.img; })[0] : null;\n      var pics = photos(p, lead && lead.img);\n      var fit = productFit(open, p);\n      var media = '<div class=\"lux-bl__pmedia\">' +\n        '<div class=\"lux-tile-media lux-bl__track\" data-track>' + pics.map(function (u, i) {\n          return '<div class=\"lux-tile-media__slide\"><img src=\"' + esc(small(u)) + '\" alt=\"\" loading=\"' + (i ? 'lazy' : 'eager') + '\"></div>';\n        }).join('') + '</div>' +\n        (pics.length > 1 ? '<div class=\"lux-tile-media__dots\"><span class=\"lux-tile-media__dots-track\">' + pics.map(function (u, i) {\n            return '<span class=\"lux-tile-media__dot' + (i ? '' : ' is-active') + '\"></span>';\n          }).join('') + '</span></div>' +\n          '<button type=\"button\" class=\"lux-tile-media__arrow lux-tile-media__arrow--prev\" data-slide=\"-1\" aria-label=\"Previous photo\" disabled><svg focusable=\"false\" width=\"14\" height=\"14\" viewBox=\"0 0 16 16\" fill=\"none\" aria-hidden=\"true\"><path d=\"M10 3L5 8l5 5\" stroke=\"currentColor\" stroke-width=\"1.6\"/></svg></button>' +\n          '<button type=\"button\" class=\"lux-tile-media__arrow lux-tile-media__arrow--next\" data-slide=\"1\" aria-label=\"Next photo\"><svg focusable=\"false\" width=\"14\" height=\"14\" viewBox=\"0 0 16 16\" fill=\"none\" aria-hidden=\"true\"><path d=\"M6 3l5 5-5 5\" stroke=\"currentColor\" stroke-width=\"1.6\"/></svg></button>' : '') +\n        '</div>';\n\n      // Colour swatches, then the first other option as pills. Sold-out values\n      // are left off, and anything the filters rule out (sells).\n      var lists = '';\n      if (hasOptions(p) && ci !== -1) {\n        var sw = valuesOf(p, ci).map(function (val) {\n          var withImg = p.vs.filter(function (v) { return v.o[ci] === val && v.img; })[0];\n          var any = p.vs.some(function (v) { return v.o[ci] === val && sells(v); });\n          if (!any) return '';\n          return '<div class=\"color-swatch\" data-tooltip=\"' + esc(val) + '\">' + (withImg\n            ? '<button type=\"button\" class=\"color-swatch__item color-swatch__item--image' + (lead && ci !== -1 && lead.o[ci] === val ? ' is-active' : '') + '\" data-swatch=\"' + ci + '\" data-v=\"' + esc(val) + '\" data-img=\"' + esc(small(withImg.img)) + '\" aria-label=\"' + esc(p.t + ' - ' + val) + '\"><img src=\"' + esc(small(withImg.img).replace('width=500', 'width=120')) + '\" alt=\"\" loading=\"lazy\"></button>'\n            : '<button type=\"button\" class=\"card-option-pill\" data-swatch=\"' + ci + '\" data-v=\"' + esc(val) + '\">' + esc(val) + '</button>') + '</div>';\n        }).join('');\n        if (sw) lists += '<div class=\"product-item-meta__swatch-list lux-scroller color-swatch-list color-swatch-list--mini lux-bl__swatches\">' + sw + '</div>';\n      }\n      if (hasOptions(p)) {\n        var oi = -1;\n        for (var i = 0; i < p.o.length; i++) if (i !== ci) { oi = i; break; }\n        if (oi !== -1) {\n          var pills = valuesOf(p, oi).filter(function (val) {\n            return p.vs.some(function (v) { return v.o[oi] === val && sells(v); });\n          }).map(function (val) {\n            return '<button type=\"button\" class=\"card-option-pill\" data-pill=\"' + oi + '\" data-v=\"' + esc(val) + '\">' + esc(val) + '</button>';\n          }).join('');\n          if (pills) lists += '<div class=\"product-item-meta__swatch-list lux-scroller product-item-meta__options-list color-swatch-list--mini lux-bl__swatches\">' + pills + '</div>';\n        }\n      }\n\n      // The card opens on a click anywhere; for keyboards and screen readers\n      // the name is the button, so the swatches, pills and photo arrows\n      // inside stay buttons of their own.\n      return '<div class=\"lux-bl__card lux-bl__pcard' + (fit.state === 'no' ? ' is-misfit' : '') + '\" data-product=\"' + esc(p.h) + '\"' + (lead && ci !== -1 ? ' data-pre-' + ci + '=\"' + esc(lead.o[ci]) + '\"' : '') + '>' +\n        (badge ? '<div class=\"label-list\"><span class=\"lux-bl__label lux-bl__label--sale\">Save ' + money(p.c - p.p) + '</span></div>' : '') +\n        media +\n        '<span class=\"lux-bl__info\">' +\n          (p.bl ? '<span class=\"lux-bl__logo\"><img src=\"' + esc(p.bl) + '\" alt=\"' + esc(brandOf(p)) + '\" loading=\"lazy\"></span>' : '<span class=\"lux-bl__slot-name\">' + esc(brandOf(p)) + '</span>') +\n          '<button type=\"button\" class=\"lux-bl__name\" data-card-open>' + esc(p.t) + '</button>' +\n          '<span class=\"lux-bl__price' + (struck ? ' is-sale' : '') + '\">' + (varies ? 'From ' : '') + price(shown.p) +\n            (struck ? ' <s>' + price(shown.c) + '</s>' : '') + '</span>' +\n          (fit.state === 'no' ? '<span class=\"lux-bl__short\">' + esc(fit.label || misfitText(fit.why, true)) + '</span>' : '') +\n          (fit.state === 'yes' && fit.label ? '<span class=\"lux-bl__fits lux-bl__fits--tag\">' + tick() + '<span>' + esc(fit.label) + '</span></span>' : '') +\n          lists +\n        '</span></div>';\n    }\n\n    // Moves a card's photo strip and keeps its dots and arrows in step.\n    function paintTrack(track, at) {\n      var wrap = track.parentNode;\n      var n = track.children.length;\n      var i = at != null ? at : Math.round(track.scrollLeft / Math.max(1, track.clientWidth));\n      wrap.querySelectorAll('.lux-tile-media__dot').forEach(function (d, k) { d.classList.toggle('is-active', k === i); });\n      var prev = wrap.querySelector('[data-slide=\"-1\"]'), next = wrap.querySelector('[data-slide=\"1\"]');\n      if (prev) prev.disabled = i <= 0;\n      if (next) next.disabled = i >= n - 1;\n    }\n\n    // ---- filters, as on the category pages\n\n    function brandOf(p) { return String(p.b || '').trim(); }\n    function disciplines(p) { return Array.isArray(p.d) ? p.d : (p.d ? [p.d] : []); }\n    // Colour groups are handles (\"colour-black\"); the category pages show\n    // them as these swatch images.\n    var COLOUR_IMG = 'https://cdn.shopify.com/s/files/1/0720/2003/3837/files/';\n    function colourName(k) {\n      var t = String(k).replace(/^colour-/, '').replace(/-/g, ' ');\n      return t.charAt(0).toUpperCase() + t.slice(1);\n    }\n    function colourMatch(v) {\n      return !opts.colours.length || (v.g || []).some(function (c) { return opts.colours.indexOf(c) !== -1; });\n    }\n    function colours(p) {\n      var out = [];\n      p.vs.forEach(function (v) { if (v.a) (v.g || []).forEach(function (c) { if (out.indexOf(c) === -1) out.push(c); }); });\n      return out;\n    }\n    // A variant the filters allow: in stock, on the shelf with Available\n    // today, in a ticked colour.\n    function sells(v) { return v.a && (!opts.luxOnly || v.l) && colourMatch(v); }\n    // One discipline is already filtered by the feed (narrowDisc).\n    function filtering() { return opts.disc.length > 1 || brandSel.length > 0 || !!opts.luxOnly || opts.colours.length > 0; }\n    function filtered(items) {\n      return items.filter(function (p) {\n        if (opts.disc.length > 1 && !disciplines(p).some(function (d) { return opts.disc.indexOf(d) !== -1; })) return false;\n        if (brandSel.length && brandSel.indexOf(brandOf(p)) === -1) return false;\n        if ((opts.luxOnly || opts.colours.length) && !p.vs.some(sells)) return false;\n        return true;\n      });\n    }\n    function chevron() {\n      return '<svg focusable=\"false\" width=\"12\" height=\"8\" viewBox=\"0 0 12 8\" fill=\"none\" aria-hidden=\"true\"><path d=\"M1 1.5l5 5 5-5\" stroke=\"currentColor\" stroke-width=\"1.5\"/></svg>';\n    }\n    // Values with counts from what's loaded; ticked values always listed.\n    function tally(items, of, ticked) {\n      var n = {};\n      items.forEach(function (p) { of(p).forEach(function (x) { if (x) n[x] = (n[x] || 0) + 1; }); });\n      ticked.forEach(function (x) { if (!(x in n)) n[x] = 0; });\n      return Object.keys(n).sort(function (a, b) { return a.localeCompare(b); }).map(function (k) { return [k, n[k]]; });\n    }\n    // The pill and its menu, built like the category pages' filter pills\n    // (snippets/filter-pills.liquid): popover choice items with the theme's\n    // checkbox. A range filter (slider) instead gets the category drawer's\n    // markup: lux-facet-slider (assets/custom.js) over checkbox rows it folds\n    // away behind \"Pick exact sizes\". Its Apply ticks those rows and fires one\n    // change, so the slider and the list are the same filter.\n    function dropdown(id, label, values, ticked, attr, fmt, locked, slider) {\n      var on = menu === id;\n      // A range counts once, as on the category pages.\n      var badge = slider ? (ticked.length ? 1 : 0) : ticked.length;\n      var list;\n      if (!values.length) list = '<p class=\"lux-bl__menu-empty\">Loading\\u2026</p>';\n      else if (slider) {\n        list = '<lux-facet-slider class=\"lux-fslider\"' + (/inch/i.test(label) ? ' data-unit=\"inch\"' : '') + '></lux-facet-slider>' +\n          values.map(function (v, i) {\n            var fid = 'lux-bl-' + esc(id.replace(/[^a-z0-9]+/gi, '-')) + '-' + i;\n            return '<div class=\"checkbox-container\"><input type=\"checkbox\" class=\"checkbox\" id=\"' + fid + '\" name=\"' + esc(slider) + '\" ' + attr + ' value=\"' + esc(v[0]) + '\"' + (ticked.indexOf(v[0]) !== -1 ? ' checked' : '') + '>' +\n              '<label for=\"' + fid + '\">' + (fmt ? fmt(v[0], true) : esc(v[0])) + '</label></div>';\n          }).join('');\n      } else {\n        list = '<div class=\"popover__choice-list\">' + values.map(function (v) {\n          return '<label class=\"popover__choice-item lux-bl__mitem\"><input type=\"checkbox\" class=\"checkbox\" ' + attr + ' value=\"' + esc(v[0]) + '\"' + (ticked.indexOf(v[0]) !== -1 ? ' checked' : '') + '>' +\n            (fmt ? fmt(v[0]) : '<span>' + esc(v[0]) + '</span>') + (v[1] !== '' ? '<span class=\"lux-bl__menu-count\">(' + v[1] + ')</span>' : '') + '</label>';\n        }).join('') + '</div>';\n      }\n      return '<div class=\"lux-bl__filter\">' +\n        '<button type=\"button\" class=\"filter-pills text--strong lux-bl__filter-btn' + (ticked.length ? ' is-active' : '') + '\" data-menu=\"' + id + '\" aria-expanded=\"' + on + '\"' + (locked ? ' disabled' : '') + '>' +\n          '<span>' + esc(label) + (badge ? ' (' + badge + ')' : '') + '</span>' + chevron() + '</button>' +\n        (on ? '<div class=\"lux-bl__menu' + (slider ? ' lux-bl__menu--range' : '') + '\" role=\"group\" aria-label=\"' + esc(label) + '\">' + list + '</div>' : '') +\n      '</div>';\n    }\n    // The part type's own Search & Discovery filters (top tube, wheel size,\n    // offset, rise...), applied by Shopify in the feed. Shopify counts\n    // variants, not products, so no counts here. A filter with one value\n    // and nothing ticked has nothing to choose between.\n    // The measurements the category pages show as a slider\n    // (lux_slider_facets in snippets/facet-filters.liquid): keep the two lists\n    // the same so a filter looks and works the same everywhere.\n    var SLIDER_FACETS = ['top tube length (inches)', 'top tube length', 'chainstay length (inches)', 'chainstay length'];\n    var seenValues = {};     // slot id -> param -> { value: label }, every value seen this visit\n    function extraFilters(locked) {\n      var mine = extraSel[open] || {};\n      return (slotFilters[open] || []).map(function (f) {\n        var ticked = mine[f.p] || [];\n        var slider = SLIDER_FACETS.indexOf(String(f.l).toLowerCase()) !== -1;\n        // A slider keeps every value seen this visit, so it doesn't shrink to\n        // the range already picked and can be widened again.\n        var seen = (seenValues[open] || (seenValues[open] = {}))[f.p] || (seenValues[open][f.p] = {});\n        f.v.forEach(function (x) { seen[x.v] = x.l; });\n        var labels = slider ? seen : {};\n        if (!slider) f.v.forEach(function (x) { labels[x.v] = x.l; });\n        var keys = slider ? Object.keys(seen) : f.v.map(function (x) { return x.v; });\n        ticked.forEach(function (v) { if (keys.indexOf(v) === -1) { keys.push(v); } });\n        if (keys.length < 2 && !ticked.length) return '';\n        var vals = keys.map(function (k) { return [k, '']; });\n        return dropdown('x:' + f.p, f.l, vals, ticked, 'data-extra=\"' + esc(f.p) + '\"', function (k, plain) {\n          return plain ? esc(labels[k] || k) : '<span>' + esc(labels[k] || k) + '</span>';\n        }, locked, slider ? f.p : '');\n      }).join('');\n    }\n    // Locked while the slot's parts are still loading, so a filter never\n    // works on half the list.\n    function filterBar(c, locked) {\n      var items = c ? c.items : [];\n      return '<div class=\"lux-bl__filters' + (locked ? ' is-locked' : '') + '\">' +\n        dropdown('disc', 'Discipline', tally(items, disciplines, opts.disc), opts.disc, 'data-disc', null, locked) +\n        dropdown('brand', 'Brand', tally(items, function (p) { return [brandOf(p)]; }, brandSel), brandSel, 'data-brand', null, locked) +\n        dropdown('colour', 'Colour', tally(items, colours, opts.colours), opts.colours, 'data-colour', function (k) {\n          return '<span class=\"lux-bl__menu-swatch\" style=\"background-image:url(' + esc(COLOUR_IMG + encodeURIComponent(k) + '.jpg') + ')\"></span><span>' + esc(colourName(k)) + '</span>';\n        }, locked) +\n        '<label class=\"filter-pills ready-toggle text--strong\"><input type=\"checkbox\" class=\"ready-toggle__input\" data-lux-only' + (opts.luxOnly ? ' checked' : '') + (locked ? ' disabled' : '') + '>' +\n          '<span>Available today</span><span class=\"ready-toggle__switch\" aria-hidden=\"true\"><span class=\"ready-toggle__knob\"></span></span></label>' +\n        extraFilters(locked) +\n      '</div>';\n    }\n\n    function renderPicker() {\n      if (!open) return;\n      var slot = slotById(open);\n      var titleId = esc(dialog.getAttribute('aria-labelledby'));\n      dialog.classList.toggle('is-detail', view === 'detail' && !!chosen);\n\n      if (view === 'detail' && chosen) {\n        var keep = focusKey();\n        picker.innerHTML = detail(slot, titleId);\n        restoreFocus(keep);\n        return;\n      }\n\n      var c = cache[cacheKey()];\n      if (c) c.drawn = true;\n      var busy = stillLoading(c, slot);\n      if (busy) menu = null;\n      var all = c ? fitFirst(sorted(filtered(c.items))) : [];\n      var limit = c ? c.limit || STEP : STEP;\n      var shown = all.slice(0, limit);\n      var body;\n      if (!c || (c.loading && !c.items.length)) body = '<p class=\"lux-bl__note\">Loading parts\\u2026</p>';\n      else if (c.error && !c.items.length) body = '<p class=\"lux-bl__note\">Parts didn\\u2019t load. <button type=\"button\" class=\"lux-bl__back\" data-retry>Try again</button></p>';\n      else if (!c.items.length) body = extraCount(open)\n        ? '<p class=\"lux-bl__note\">Nothing in stock matches those filters. <button type=\"button\" class=\"lux-bl__back\" data-clear-filters>Clear filters</button></p>'\n        : '<p class=\"lux-bl__note\">Nothing in stock matches that. Try another search.</p>';\n      else if (!all.length && !busy) body = '<p class=\"lux-bl__note\">Nothing matches those filters. <button type=\"button\" class=\"lux-bl__back\" data-clear-filters>Clear filters</button></p>';\n      else {\n        body = ((filtering() || extraCount(open)) && !busy ? '<p class=\"lux-bl__result-count\">' + (filtering() ? all.length + ' of ' + c.items.length : c.items.length) + ' ' + esc(slot.label.toLowerCase()) + ' options' +\n            ' <button type=\"button\" class=\"lux-bl__back\" data-clear-filters>Clear filters</button></p>' : '') +\n          '<div class=\"lux-bl__grid\">' + shown.map(card).join('') + '</div>' +\n          (c.error ? '<p class=\"lux-bl__note\">Some parts didn\\u2019t load. <button type=\"button\" class=\"lux-bl__back\" data-retry>Try again</button></p>' : '') +\n          (all.length > shown.length ? '<button type=\"button\" class=\"button button--secondary lux-bl__more\" data-more>Show more</button>' : '');\n      }\n      var lockNote = busy && c && c.items.length ? '<p class=\"lux-bl__load-note\" data-load-note role=\"status\">Loading every ' + esc(slot.label.toLowerCase()) + ' option\\u2026 ' + c.items.length + ' so far</p>' : '';\n\n      var refocus = focusKey();\n      var input = picker.querySelector('[data-term]');\n      var hadFocus = input && document.activeElement === input;\n      var caret = hadFocus ? input.selectionStart : null;\n      // Keep the rider's place in the list across a redraw.\n      var scroller = dialog.querySelector('.lux-bl__dialog-inner');\n      var keepTop = scroller ? scroller.scrollTop : 0;\n      var row = picker.querySelector('.lux-bl__filters');\n      var keepLeft = row ? row.scrollLeft : 0; // phones scroll the filter row sideways\n      picker.innerHTML = '<div class=\"lux-bl__list' + (busy ? ' is-loading' : '') + '\"><div class=\"lux-bl__list-head\">' +\n          '<h2 class=\"quick-view__title\" id=\"' + titleId + '\">Choose ' + (slot.req ? 'your ' : '') + esc(slot.label.toLowerCase()) + '</h2>' +\n          '<p class=\"quick-view__identity text--subdued\">' + (narrowDisc() ? 'Showing ' + esc(narrowDisc().toLowerCase()) + ' parts, most popular first.' : 'Most popular first.') + (slot.hint ? ' ' + esc(slot.hint.replace(/\\.$/, '')) + '.' : '') +\n            (narrowDisc() ? ' <button type=\"button\" class=\"lux-bl__back\" data-clear-filters>Show all</button>' : '') + '</p>' +\n          (canInclude(slot) ? '<div class=\"lux-bl__tools\"><button type=\"button\" class=\"filter-pills lux-bl__incl\" style=\"margin:0\" data-include=\"' + slot.id + '\">' + esc(slot.incl) + '</button></div>' : '') +\n          filterBar(c, busy) + lockNote +\n          '<div class=\"lux-bl__tools\">' +\n            '<input type=\"search\" data-term placeholder=\"Search ' + esc(slot.label.toLowerCase()) + ' by brand or name\" value=\"' + esc(term) + '\" aria-label=\"Search ' + esc(slot.label.toLowerCase()) + '\">' +\n            '<select data-sort aria-label=\"Sort by\"' + (busy ? ' disabled' : '') + '>' +\n              '<option value=\"popular\"' + (sort === 'popular' ? ' selected' : '') + '>' + (term.trim() ? 'Best match' : 'Best selling') + '</option>' +\n              '<option value=\"low\"' + (sort === 'low' ? ' selected' : '') + '>Price, low to high</option>' +\n              '<option value=\"high\"' + (sort === 'high' ? ' selected' : '') + '>Price, high to low</option>' +\n            '</select></div></div>' + body + '</div>';\n      if (scroller) scroller.scrollTop = keepTop;\n      row = picker.querySelector('.lux-bl__filters');\n      if (row) row.scrollLeft = keepLeft;\n      if (hadFocus) {\n        var again = picker.querySelector('[data-term]');\n        again.focus();\n        try { again.setSelectionRange(caret, caret); } catch (e) { /* search inputs in some browsers */ }\n      } else {\n        restoreFocus(refocus);\n      }\n    }\n\n    // Redraws replace the picker's HTML, which would drop focus to the page.\n    // These name the focused control by its data attributes so the redraw\n    // can put focus back on its twin (or on the heading when it's gone).\n    var FOCUS_ATTRS = ['data-card-open', 'data-extra', 'data-slide', 'data-swatch', 'data-pill', 'data-menu', 'data-value', 'data-v', 'data-pegs', 'data-thumb', 'data-include', 'data-more', 'data-retry',\n      'data-clear-filters', 'data-lux-only', 'data-disc', 'data-brand', 'data-colour', 'data-sort', 'data-lock', 'data-back'];\n    function focusKey() {\n      var a = document.activeElement;\n      if (!a || !picker.contains(a) || a === picker) return null;\n      var sel = FOCUS_ATTRS.filter(function (n) { return a.hasAttribute(n); }).map(function (n) {\n        var v = a.getAttribute(n);\n        return v ? '[' + n + '=\"' + cssEsc(v) + '\"]' : '[' + n + ']';\n      }).join('');\n      if (!sel) return '*';\n      if (a.type === 'checkbox' && a.value) sel += '[value=\"' + cssEsc(a.value) + '\"]';\n      // Controls inside a card: the same control on the same card.\n      var card = a.closest('[data-product]');\n      return (card ? '[data-product=\"' + cssEsc(card.getAttribute('data-product')) + '\"] ' : '') + sel;\n    }\n    function restoreFocus(sel) {\n      if (sel == null) return;\n      var el = null;\n      try { el = sel === '*' ? null : picker.querySelector(sel); } catch (e) { el = null; }\n      if (!el || el.disabled) el = picker.querySelector('#' + cssEsc(dialog.getAttribute('aria-labelledby')));\n      if (el) { if (!el.matches('a, button, input, select, [tabindex]')) el.setAttribute('tabindex', '-1'); el.focus({ preventScroll: true }); }\n    }\n\n    // ---- options, the buy grid way: one row per option, colour as photo\n    // swatches, everything else as pills. A value that can't make an\n    // in-stock variant with the other choices is dimmed but still clickable:\n    // clicking it moves the other options to the best match.\n\n    function hasOptions(p) { return !(p.vs.length === 1 && /^default title$/i.test(p.vs[0].t)); }\n    function valuesOf(p, i) {\n      var seen = {}, out = [];\n      p.vs.forEach(function (v) { var x = v.o[i]; if (x != null && !seen[x]) { seen[x] = true; out.push(x); } });\n      return out;\n    }\n    function current(p) {\n      for (var i = 0; i < p.vs.length; i++) {\n        var v = p.vs[i];\n        if (v.o.every(function (x, k) { return chosen.sel[k] === x; })) return v;\n      }\n      return null;\n    }\n    // Stock status per variant, as the buy grid works it out. Until it\n    // arrives, Shopify's own available flag stands in.\n    function loadStock(handle) {\n      if (stock[handle]) return;\n      stock[handle] = { loading: true, byId: {} };\n      fetch('/products/' + encodeURIComponent(handle) + '?view=build-status', { credentials: 'same-origin' })\n        .then(function (r) { return r.text(); })\n        .then(function (t) { return JSON.parse(t); })\n        .then(function (list) {\n          list.forEach(function (v) { stock[handle].byId[v.id] = v; });\n          stock[handle].loading = false;\n          if (chosen && chosen.product.h === handle) renderPicker();\n          // A part in the build: its card can now say if stock falls short.\n          if (Object.keys(picks).some(function (id) { return picks[id] && picks[id].handle === handle; })) render();\n        })\n        .catch(function () {\n          stock[handle] = { loading: false, error: true, byId: {} };\n          if (chosen && chosen.product.h === handle) renderPicker();\n        });\n    }\n    function statusOf(p, v) { return v && stock[p.h] && stock[p.h].byId[v.id]; }\n    // Every part in the build, so each card can check its stock.\n    function checkPickStock() {\n      visible().forEach(function (s) { var p = picks[s.id]; if (p && !p.included && p.handle) loadStock(p.handle); });\n    }\n    // How short of stock a part in the build is: what the build needs of the\n    // variant (both rims when they match) against the most Shopify will\n    // sell. Null when there's enough, or no limit, or it isn't known yet.\n    function shortOf(p) {\n      var st = p && p.handle && stock[p.handle] && stock[p.handle].byId[p.variantId];\n      if (!st || st.max == null) return null;\n      var need = lines().filter(function (l) { return String(l.pick.variantId) === String(p.variantId); })\n        .reduce(function (n, l) { return n + l.qty; }, 0);\n      return need > st.max ? { have: st.max, need: need } : null;\n    }\n    function buyable(p, v) {\n      var st = statusOf(p, v);\n      return st ? st.available && st.status !== 'out' : !!(v && v.a);\n    }\n    var LABELS = { lux: 'In stock at LUXBMX', supplier: 'With supplier', pre: 'Preorder', special: 'Special order', out: 'Sold out' };\n    function dot(status) {\n      var cls = { lux: 'dot--lux', supplier: 'dot--supplier', pre: 'dot--pre', special: 'dot--supplier', out: 'dot--out' }[status] || 'dot--out';\n      return '<span class=\"dot ' + cls + '\">' + (status === 'out' ? '\\u25CB' : '\\u25CF') + '</span>';\n    }\n    // The buy grid's status line (renderStatus in product-buy-grid.liquid),\n    // including the split when the build needs more than the shelf holds.\n    function statusLine(p, v, qty) {\n      if (!v) return '<div class=\"buy-grid__status text--xsmall\">Unavailable in this combination</div>';\n      var st = statusOf(p, v);\n      if (!st) return '<div class=\"buy-grid__status text--xsmall is-loading\">' + (stock[p.h] && stock[p.h].error ? '' : 'Checking stock\\u2026') + '</div>';\n      if (st.status === 'lux' && st.lux_qty > 0) {\n        var luxLine = st.lux_qty < 5 ? '<strong>' + st.lux_qty + '</strong> in stock at LUXBMX' : 'In stock at LUXBMX';\n        if (qty > st.lux_qty && st.supplier_qty > 0) {\n          var rest = qty - st.lux_qty;\n          var sup = '<strong>' + rest + '</strong> from supplier' + (st.supplier_lead ? ' - <strong>' + esc(st.supplier_lead) + '</strong>' : '');\n          return '<div class=\"buy-grid__status text--xsmall is-split\">' +\n            '<span class=\"buy-grid__status-line\">' + dot('lux') + ' <span><strong>' + st.lux_qty + '</strong> in stock at LUXBMX</span></span>' +\n            '<span class=\"buy-grid__status-line\">' + dot('supplier') + ' <span>' + sup + '</span></span></div>';\n        }\n        return '<div class=\"buy-grid__status text--xsmall\">' + dot('lux') + ' <span>' + luxLine + '</span></div>';\n      }\n      var text = LABELS[st.status] || LABELS.out;\n      if (st.lead) text += st.status === 'pre' ? ' - arrives <strong>' + esc(st.lead) + '</strong>' : ' - <strong>' + esc(st.lead) + '</strong>';\n      return '<div class=\"buy-grid__status text--xsmall\">' + dot(st.status) + ' <span>' + text + '</span></div>';\n    }\n\n    function canHave(p, i, value) {\n      return p.vs.some(function (v) {\n        return buyable(p, v) && v.o[i] === value && v.o.every(function (x, k) { return k === i || chosen.sel[k] == null || chosen.sel[k] === x; });\n      });\n    }\n    function choose(p, i, value) {\n      chosen.sel[i] = value;\n      if (current(p)) { chosen.stage = null; return; }\n      // No such combination: keep this value, take the closest in-stock variant.\n      var best = null, bestScore = -1;\n      p.vs.forEach(function (v) {\n        if (v.o[i] !== value) return;\n        var score = (v.a ? 100 : 0) + v.o.filter(function (x, k) { return chosen.sel[k] === x; }).length;\n        if (score > bestScore) { best = v; bestScore = score; }\n      });\n      if (best) chosen.sel = best.o.slice();\n      chosen.stage = null;\n    }\n\n    function detail(slot, titleId) {\n      var p = chosen.product;\n      var v = current(p);\n      // Spokes whose lengths are worked out: the build picks them, so the\n      // Length choice goes and the lengths show instead.\n      var plan = slot.id === 'spokes' && KIND === 'wheels' && v\n        ? spokePlan({ title: p.t, pack: packSize(p.t + ' ' + v.t) || packSize(p.ds), lens: lensFor(p, v) }) : null;\n      var autoLen = !!(plan && plan.ok), li = lengthIndex(p);\n      var img = chosen.stage || (v && v.img) || p.img;\n      var thumbs = [];\n      [p.img].concat(p.im || []).forEach(function (u) { if (u && thumbs.indexOf(u) === -1 && thumbs.length < 6) thumbs.push(u); });\n      var rows = '';\n      if (hasOptions(p)) {\n        rows = p.o.map(function (name, i) {\n          if (autoLen && i === li) return '';\n          var values = valuesOf(p, i);\n          var colour = /^colou?r$/i.test(name);\n          var picked = chosen.sel[i];\n          var body = values.map(function (val) {\n            var on = val === picked;\n            var dim = !canHave(p, i, val);\n            if (colour) {\n              var withImg = p.vs.filter(function (x) { return x.o[i] === val && x.img; })[0];\n              if (withImg) {\n                return '<button type=\"button\" class=\"buy-grid__swatch' + (on ? ' is-selected' : '') + (dim ? ' is-unavailable' : '') + '\" data-value=\"' + i + '\" data-v=\"' + esc(val) + '\" title=\"' + esc(val) + '\" aria-label=\"' + esc(val) + '\" aria-pressed=\"' + on + '\">' +\n                  '<img src=\"' + esc(withImg.img) + '\" alt=\"\" loading=\"lazy\"></button>';\n              }\n            }\n            return '<button type=\"button\" class=\"buy-grid__pill' + (on ? ' is-selected' : '') + (dim ? ' is-unavailable' : '') + '\" data-value=\"' + i + '\" data-v=\"' + esc(val) + '\" aria-pressed=\"' + on + '\">' + esc(val) + '</button>';\n          }).join('');\n          return '<div class=\"buy-grid__option\"><p class=\"buy-grid__label text--xsmall\"><span class=\"buy-grid__label-text\">' + esc(name) +\n            ' - <span class=\"buy-grid__label-value\">' + esc(picked || 'Select Option') + '</span></span></p>' +\n            '<div class=\"' + (colour ? 'buy-grid__swatches' : 'buy-grid__pills') + '\">' + body + '</div></div>';\n        }).join('');\n      }\n      if (slot.count === 'pegs') {\n        rows += '<div class=\"buy-grid__option\"><p class=\"buy-grid__label text--xsmall\"><span class=\"buy-grid__label-text\">How many pegs - <span class=\"buy-grid__label-value\">' + opts.pegs + '</span></span></p>' +\n          '<div class=\"buy-grid__pills\">' + [2, 3, 4].map(function (n) {\n            return '<button type=\"button\" class=\"buy-grid__pill' + (opts.pegs === n ? ' is-selected' : '') + '\" data-pegs=\"' + n + '\" aria-pressed=\"' + (opts.pegs === n) + '\">' + n + '</button>';\n          }).join('') + '</div></div>';\n      }\n\n      var probe = { title: p.t, variantTitle: v ? v.t : '' };\n      var q = qtyFor(slot, probe);\n      var note = qtyNote(slot, probe);\n      var ok = v && buyable(p, v);\n      var vName = v ? v.t : '', buildLine = '';\n      if (autoLen) {\n        // Stock for the first length the build takes; the board card checks each.\n        var first = p.vs.filter(function (x) { return x.id === plan.lines[0].v.id; })[0];\n        ok = plan.lines.every(function (l) { return l.v.a; });\n        q = plan.lines[0].qty; v = first || v;\n        vName = String(v.t).split(' / ').filter(function (x) { return !/\\d\\s*mm|cut to size/i.test(x); }).join(' / ');\n        var packs = plan.lines.reduce(function (n, l) { return n + l.qty; }, 0);\n        var cost = plan.lines.reduce(function (n, l) { return n + l.v.p * l.qty; }, 0);\n        buildLine = '<p class=\"lux-bl__qty\">' + packs + (packOf({ title: p.t, pack: packSize(p.t) || packSize(p.ds) }) ? ' pack' + (packs === 1 ? '' : 's') : ' spokes') + ': ' + price(cost) + ' in your build</p>';\n      }\n      var sale = v && v.c > v.p && (v.c - v.p) * 100 / v.c > 2; // the buy grid's rule\n      return '<div class=\"quick-view__modal\">' +\n        '<div class=\"quick-view__gallery\">' +\n          '<button type=\"button\" class=\"lux-bl__back\" data-back>\u2190 All ' + esc(slot.label.toLowerCase()) + ' options</button>' +\n          '<div class=\"quick-view__stage\">' + (img ? '<img src=\"' + esc(img) + '\" alt=\"' + esc(p.t) + '\">' : '') + '</div>' +\n          (thumbs.length > 1 ? '<div class=\"quick-view__thumbs lux-scroller\">' + thumbs.map(function (u) {\n            return '<button type=\"button\" class=\"lux-qv-thumb' + (u === img ? ' is-active' : '') + '\" data-thumb=\"' + esc(u) + '\" aria-label=\"Show this photo\"><img src=\"' + esc(u) + '\" alt=\"\" loading=\"lazy\"></button>';\n          }).join('') + '</div>' : '') +\n          '<a href=\"' + esc(p.u + (v ? '?variant=' + v.id : '')) + '\" class=\"quick-view__details-cta\" target=\"_blank\" rel=\"noopener\">View Full Details</a>' +\n        '</div>' +\n        '<div class=\"quick-view__panel\">' +\n          '<div class=\"quick-view__titles product-item-meta\">' +\n            '<a href=\"' + esc(p.u) + '\" class=\"quick-view__title\" id=\"' + titleId + '\" target=\"_blank\" rel=\"noopener\">' + esc(p.t) + '</a>' +\n            '<p class=\"quick-view__identity text--subdued\"><span class=\"quick-view__identity-item\">Brand: ' + esc(p.b) + '</span><span class=\"quick-view__identity-item\">For your ' + esc(slot.label.toLowerCase()) + '</span></p>' +\n          '</div>' +\n          rows +\n          statusLine(p, v, q) +\n          fitNote(slot, v, plan) +\n          (v && hasOptions(p) && vName ? '<p class=\"buy-grid__variant-name\">' + esc(vName) + '</p>' : '') +\n          '<div class=\"buy-grid__price-block\"><div class=\"buy-grid__price' + (sale ? ' is-sale' : '') + '\">' +\n            '<span class=\"buy-grid__price-current\">' + money(v ? v.p : p.p) + '</span><span class=\"buy-grid__price-currency\">' + esc(CUR) + '</span>' +\n            (sale ? '<span class=\"buy-grid__price-compare\">' + money(v.c) + '</span>' : '') +\n          '</div></div>' +\n          (autoLen ? buildLine : (q > 1 && v ? '<p class=\"lux-bl__qty\">' + esc(note) + ': ' + price(v.p * q) + ' in your build</p>' : '')) +\n          '<div class=\"lux-bl__lock-wrap\"><button type=\"button\" class=\"button button--primary button--full lux-bl__lock\" data-lock' + (ok ? '' : ' disabled') + '>' +\n            (ok ? (picks[slot.id] ? 'Swap into your build' : 'Add to your build') : (autoLen ? 'Not all your lengths are in stock' : (v ? 'Sold out' : 'Choose options'))) + '</button></div>' +\n        '</div></div>';\n    }\n\n    // Under the stock line: whether this variant fits the build, and for\n    // spokes, the lengths the build adds.\n    function fitNote(slot, v, plan) {\n      var html = '';\n      if (v && pairsFor(slot.id).length) {\n        var r = fitCheck(slot.id, fitOf(v));\n        if (r.state === 'no') html += '<p class=\"lux-bl__short lux-bl__fitnote\">' + esc(misfitText(r.why)) + '</p>';\n        else if (r.state === 'yes') html += '<p class=\"lux-bl__fits lux-bl__fitnote\">' + tick() + '<span>Fits the parts in your build</span></p>';\n      }\n      if (slot.id === 'spokes' && KIND === 'wheels') {\n        var w = wheelLengths();\n        if (!w) {\n          html += '<p class=\"lux-bl__fitnote\">Pick your hubs and rims first and we work out the spoke lengths for you. If you pick spokes now, choose a length and we confirm it before building.</p>';\n        } else if (w.why) {\n          html += '<p class=\"lux-bl__fitnote\">' + esc(w.why) + ', so we can\\u2019t work out the spoke lengths. Choose a length and we confirm it with you before building.</p>';\n        } else {\n          var need = w.map(function (e) {\n            return e.end + ' ' + (Math.abs(e.d - e.nd) < 0.5 ? e.d.toFixed(1) + ' mm' : e.d.toFixed(1) + ' and ' + e.nd.toFixed(1) + ' mm');\n          }).join(', ');\n          if (plan && plan.ok) {\n            html += '<p class=\"lux-bl__fits lux-bl__fitnote\">' + tick() + '<span>We add these in your lengths. ' + esc(planText(plan)) + '</span></p>' +\n              '<p class=\"lux-bl__fitnote lux-bl__fitnote--sub\">Worked out from your hubs and rims: ' + esc(need) + '.</p>';\n          } else {\n            html += '<p class=\"lux-bl__short lux-bl__fitnote\">' + esc((plan && plan.why) || 'These don\\u2019t list lengths') + ' (' + esc(need) + ', worked out from your hubs and rims). Spokes in your lengths are listed first. If you want these anyway, pick the closest length and we confirm it with you before building.</p>';\n          }\n        }\n      }\n      return html;\n    }\n\n    function firstAvailable(p) {\n      for (var i = 0; i < p.vs.length; i++) if (p.vs[i].a) return p.vs[i];\n      return p.vs[0];\n    }\n\n    // ------------------------------------------------------------ picking\n\n    function afterChange(slot, filled) {\n      checkPickStock();\n      save();\n      msg = null;\n      justFilled = filled;\n      render();\n      var pr = progress();\n      var left = pr.need - pr.done;\n      if (!left && !celebrated) {\n        celebrated = true;\n        levelClear();\n      } else if (slot.req) {\n        toast(slot.label + ' sorted. ' + (left ? left + ' to go.' : 'Build complete.'));\n      } else {\n        toast(slot.label + ' added.');\n      }\n    }\n\n    function lockIn() {\n      var slot = slotById(open);\n      var p = chosen.product;\n      var v = current(p);\n      // Spokes whose lengths the build picks: the Length choice is hidden, so\n      // take the variant of the first length the build needs.\n      if (slot.id === 'spokes' && KIND === 'wheels' && v) {\n        var plan = spokePlan({ title: p.t, pack: packSize(p.t + ' ' + v.t) || packSize(p.ds), lens: lensFor(p, v) });\n        if (plan && plan.ok) v = p.vs.filter(function (x) { return x.id === plan.lines[0].v.id; })[0] || v;\n      }\n      if (!v || !buyable(p, v)) return;\n      var pick = {\n        handle: p.h, productId: p.id, variantId: v.id, title: p.t, brand: p.b,\n        variantTitle: v.t, price: v.p, img: v.img || p.img, url: p.u, colourGroups: v.g || null, swatch: v.sw || null\n      };\n      if (p.kf) pick.kit = true;\n      var fit = KIND === 'wheels' ? fitOf(v) : null;\n      if (fit) pick.fit = fit;\n      // Spokes keep their other lengths (in the picked colour), so the build\n      // can take the lengths the wheels need.\n      if (slot.id === 'spokes' && KIND === 'wheels') {\n        var lens = lensFor(p, v);\n        if (lens) pick.lens = lens;\n      }\n      var pack = packSize(p.t + ' ' + v.t) || packSize(p.ds);\n      if (pack) pick.pack = pack;\n      var filled = [slot.id];\n      if (PAIRS[slot.id]) {\n        var other = PAIRS[slot.id];\n        var wasSet = picks[slot.id] && picks[slot.id].set;\n        if (fillsBoth(slot.id, p)) {\n          pick.set = true;\n          picks[other] = pick;\n          filled.push(other);\n        } else if (wasSet) {\n          // Swapping half of a set or pair: it no longer covers the other end.\n          delete picks[other];\n        }\n      }\n      picks[slot.id] = pick;\n      var swappedFork = false;\n      if (slot.id === 'frame') {\n        // A frame and fork kit brings its own fork: a fork picked earlier goes.\n        if (frameHasFork() && picks.fork && !picks.fork.included && !picks.fork.fromCart) { delete picks.fork; swappedFork = true; }\n        var kitFork = syncForkKit();\n        if (kitFork) filled.push(kitFork);\n      }\n      closePicker();\n      afterChange(slot, filled);\n      if (swappedFork) toast('Your frame comes with a fork, so the fork is included now.');\n      var el = board.querySelector('[data-open=\"' + slot.id + '\"]');\n      if (el && el.scrollIntoView) el.scrollIntoView({ behavior: 'smooth', block: 'nearest' });\n    }\n\n    function include(id) {\n      var slot = slotById(id);\n      if (!slot || !canInclude(slot)) return;\n      picks[id] = { included: true };\n      closePicker();\n      afterChange(slot, [id]);\n    }\n\n    // Fills a slot with the same part as its twin (rear rim from front rim).\n    function copyTwin(id) {\n      var slot = slotById(id);\n      var from = slot && slot.same && picks[slot.same];\n      if (!from || from.included) return;\n      var copy = {};\n      Object.keys(from).forEach(function (k) { copy[k] = from[k]; });\n      delete copy.fromCart;\n      picks[id] = copy;\n      afterChange(slot, [id]);\n    }\n\n    // A rim or tyre from the cart, put on the wheel the rider says: stays,\n    // moves to the other wheel, or goes on both (one more to buy).\n    function chooseEnd(id, end) {\n      var slot = slotById(id), p = picks[id];\n      if (!slot || !p || !slot.same) return;\n      p.endSet = true;\n      var here = slot.end || (/^r/.test(id) ? 'rear' : 'front');\n      if (end === 'both') return copyTwin(slot.same);\n      if (end !== here) {\n        picks[slot.same] = p;\n        delete picks[id];\n        return afterChange(slotById(slot.same), [slot.same]);\n      }\n      save();\n      render();\n    }\n\n    function removePick(id) {\n      var p = picks[id];\n      if (!p) return;\n      if (p.set && PAIRS[id]) delete picks[PAIRS[id]];\n      delete picks[id];\n      if (id === 'frame' || id === 'fork') syncForkKit();\n      afterReset();\n    }\n    function afterReset() {\n      var pr = progress();\n      if (pr.done < pr.need) celebrated = false;\n      msg = null;\n      save();\n      render();\n    }\n\n    var toastTimer;\n    function toast(text) {\n      toastEl.textContent = text;\n      toastEl.hidden = false;\n      clearTimeout(toastTimer);\n      toastTimer = setTimeout(function () { toastEl.hidden = true; }, 2600);\n    }\n\n    // Build complete: an arcade \"level clear\" screen in place of confetti.\n    // Flash, scanlines, READY TO RIDE!, BUILD slams in with a shake, COMPLETE!\n    // types out in a pixel font, the score (parts and total) counts up, pixel sparks burst,\n    // then the next moves: cart (green, as everywhere), save, or keep building. Esc, the backdrop or\n    // Keep building closes it. Reduced motion gets the same screen, still.\n    function levelClear() {\n      var still = window.matchMedia && window.matchMedia('(prefers-reduced-motion: reduce)').matches;\n      var pr = progress();\n      var sum = total() - offerSavings();\n      var word = 'COMPLETE!';\n      var el = document.createElement('div');\n      el.className = 'lux-bl__win' + (still ? ' is-still' : '');\n      el.setAttribute('role', 'dialog');\n      el.setAttribute('aria-modal', 'true');\n      el.setAttribute('aria-label', 'Build complete');\n      el.innerHTML =\n        '<div class=\"lux-bl__win-flash\" aria-hidden=\"true\"></div>' +\n        '<div class=\"lux-bl__win-sparks\" aria-hidden=\"true\"></div>' +\n        '<div class=\"lux-bl__win-box\">' +\n          '<p class=\"lux-bl__win-kicker\">' + (KIND === 'wheels' ? 'Ready to roll!' : 'Ready to ride!') + '</p>' +\n          '<p class=\"lux-bl__win-title\"><span class=\"lux-bl__win-build\">' + (KIND === 'wheels' ? 'Wheels' : 'Build') + '</span>' +\n            '<span class=\"lux-bl__win-done\">' + word.split('').map(function (ch, i) {\n              return '<span style=\"animation-delay:' + (0.75 + i * 0.07).toFixed(2) + 's\">' + esc(ch) + '</span>';\n            }).join('') + '</span></p>' +\n          '<dl class=\"lux-bl__win-score\">' +\n            '<div><dt>Parts</dt><dd>' + pr.done + '/' + pr.need + '</dd></div>' +\n            '<div><dt>Total</dt><dd data-win-total>' + (still ? money(sum) : money(0)) + '</dd></div>' +\n          '</dl>' +\n          (Number(cfg.offerPercent || 0) > 0 ? '<p class=\"lux-bl__win-unlock\">' + (offerEarned() ? esc(offerWords()) + ' unlocked' : 'Add a fork for ' + esc(offerWords())) + '</p>' : '') +\n          '<div class=\"lux-bl__win-actions\">' +\n            '<button type=\"button\" class=\"lux-bl__win-btn lux-bl__win-btn--go\" data-win=\"cart\">Add to cart</button>' +\n            (KIND === 'wheels' && cfg.bikeBuilderUrl ? '<button type=\"button\" class=\"lux-bl__win-btn\" data-win=\"cart-bike\">Add to cart and build a bike</button>' : '') +\n            '<button type=\"button\" class=\"lux-bl__win-btn\" data-win=\"wishlist\">Save to wishlist</button>' +\n            (cfg.giveawayUrl ? '<button type=\"button\" class=\"lux-bl__win-btn\" data-win=\"enter\">Save and enter the giveaway</button>' : '') +\n            '<button type=\"button\" class=\"lux-bl__win-btn lux-bl__win-btn--ghost\" data-win=\"close\">Keep building</button>' +\n          '</div>' +\n        '</div>';\n      root.appendChild(el);\n      document.documentElement.classList.add('lux-bl-win-open');\n\n      if (!still) {\n        // Pixel sparks: square bits flung out from the middle.\n        var sparks = el.querySelector('.lux-bl__win-sparks');\n        var colours = ['#95b675', '#c5dcae', '#ffffff', '#4d6b35', '#95b675'];\n        for (var i = 0; i < 64; i++) {\n          var bit = document.createElement('i');\n          var a = Math.random() * Math.PI * 2, d = 180 + Math.random() * 420, sz = [6, 8, 10, 12][i % 4];\n          bit.style.cssText = 'width:' + sz + 'px;height:' + sz + 'px;background:' + colours[i % colours.length] +\n            ';--dx:' + Math.round(Math.cos(a) * d) + 'px;--dy:' + Math.round(Math.sin(a) * d) + 'px;animation-delay:' + (0.55 + Math.random() * 0.25).toFixed(2) + 's';\n          sparks.appendChild(bit);\n        }\n        // The score counts up like an arcade tally.\n        var out = el.querySelector('[data-win-total]');\n        var t0 = null, dur = 1100, startAt = 1.3;\n        var step = function (ts) {\n          if (!el.isConnected) return;\n          if (t0 === null) t0 = ts + startAt * 1000;\n          var k = Math.max(0, Math.min(1, (ts - t0) / dur));\n          out.textContent = money(Math.round(sum * (1 - Math.pow(1 - k, 3))));\n          if (k < 1) requestAnimationFrame(step);\n        };\n        requestAnimationFrame(step);\n      }\n\n      function closeWin() {\n        if (!el.isConnected) return;\n        document.removeEventListener('keydown', onKey);\n        document.documentElement.classList.remove('lux-bl-win-open');\n        el.classList.add('is-leaving');\n        setTimeout(function () { el.remove(); }, still ? 0 : 220);\n      }\n      function onKey(e) { if (e.key === 'Escape') closeWin(); }\n      document.addEventListener('keydown', onKey);\n      el.addEventListener('click', function (e) {\n        var b = e.target.closest('[data-win]');\n        if (!b) { if (!e.target.closest('.lux-bl__win-box')) closeWin(); return; }\n        var what = b.getAttribute('data-win');\n        closeWin();\n        if (what === 'wishlist') saveToWishlist();\n        else if (what === 'enter') saveToWishlist(true);\n        else if (what === 'cart') addToCart();\n        else if (what === 'cart-bike') addToCart(bikeNext());\n      });\n      setTimeout(function () { var f = el.querySelector('[data-win=\"cart\"]'); if (f) f.focus({ preventScroll: true }); }, still ? 0 : 1900);\n    }\n\n    // ------------------------------------------------------------ save and cart\n\n    // One Swym list per save, named for the giveaway so the entry form can\n    // offer it. Swym takes at most 10 products per call and rejects brackets.\n    // With enter set, the rider goes on to the giveaway entry once the list\n    // is saved, with this build already picked there (the entry form reads\n    // the build from lux-build-lite-export, so it goes even if the wishlist\n    // can't save).\n    function goEnter() {\n      exportBuild();\n      var url = cfg.giveawayUrl;\n      window.location.href = url + (url.indexOf('?') === -1 ? '?' : '&') + 'build=builder';\n    }\n    // Saving asks for a name first: a small dialog, filled with the last name\n    // used here. Without Swym there's nothing to name, so it goes straight on\n    // to saveToWishlist, which says so.\n    var NAME_KEY = 'lux-build-list-name';\n    function cleanName(s) { return String(s || '').replace(/[^A-Za-z0-9 &'\\/.,:!?()#-]+/g, ' ').replace(/\\s+/g, ' ').trim().slice(0, 40); }\n    function askListName(enter) {\n      var swat = window._swat;\n      var last = '';\n      try { last = localStorage.getItem(NAME_KEY) || ''; } catch (e) { /* no memory, use the default */ }\n      var dflt = cleanName(last || cfg.listName || 'Dream Build') || 'Dream Build';\n      var dlg = root.querySelector('[data-name-dialog]');\n      if (!dlg) {\n        dlg = document.createElement('dialog');\n        dlg.className = 'lux-bl__namebox';\n        dlg.setAttribute('data-name-dialog', '');\n        dlg.setAttribute('aria-labelledby', 'lux-bl-name-h');\n        root.appendChild(dlg);\n      }\n      if (!swat || typeof dlg.showModal !== 'function') return saveToWishlist(enter, dflt);\n      dlg.innerHTML = '<form method=\"dialog\" class=\"lux-bl__namebox-form\">' +\n        '<h2 class=\"heading h5\" id=\"lux-bl-name-h\">Name your build</h2>' +\n        '<label class=\"lux-bl__namebox-label\" for=\"lux-bl-name\">It saves to your wishlist under this name.</label>' +\n        '<input class=\"input__field lux-bl__namebox-input\" id=\"lux-bl-name\" type=\"text\" name=\"lname\" maxlength=\"40\" required autocomplete=\"off\" value=\"' + esc(dflt) + '\">' +\n        '<div class=\"lux-bl__namebox-actions\"><button type=\"button\" class=\"lux-bl__namebox-cancel\" data-name-cancel>Cancel</button>' +\n        '<button type=\"submit\" class=\"button button--primary\">' + (enter ? 'Save and enter' : 'Save') + '</button></div></form>';\n      var form = dlg.querySelector('form'), input = form.elements.lname;\n      dlg.querySelector('[data-name-cancel]').addEventListener('click', function () { dlg.close(); });\n      // A click on the backdrop closes it too.\n      dlg.onclick = function (e) { if (e.target === dlg) dlg.close(); };\n      form.addEventListener('submit', function (e) {\n        e.preventDefault();\n        var name = cleanName(input.value);\n        if (!name) { input.value = ''; input.focus(); return; }\n        try { localStorage.setItem(NAME_KEY, name); } catch (er) { /* fine */ }\n        dlg.close();\n        saveToWishlist(enter, name);\n      });\n      dlg.showModal();\n      input.select();\n    }\n    // Swym hands back the existing list for a name it already has, so a name\n    // in use gets a number (\"Dream Build 2\"). If the lists can't be read, the\n    // date and time keep it apart instead.\n    function uniqueName(swat, base, done) {\n      var finished = false;\n      function finish(name) { if (finished) return; finished = true; clearTimeout(wait); done(name); }\n      function dated() {\n        var now = new Date();\n        finish(base + ', ' + now.toLocaleDateString('en-AU', { day: 'numeric', month: 'short' }) + ', ' +\n          now.toLocaleTimeString('en-AU', { hour: 'numeric', minute: '2-digit', second: '2-digit' }).replace(/\\s+/g, ' ').toLowerCase());\n      }\n      var wait = setTimeout(dated, 4000);\n      if (typeof swat.fetchLists !== 'function') return dated();\n      try {\n        swat.fetchLists({\n          callbackFn: function (lists) {\n            var taken = {};\n            (lists || []).forEach(function (l) { taken[String(l.lname || '').toLowerCase()] = true; });\n            var name = base, n = 2;\n            while (taken[name.toLowerCase()]) name = base + ' ' + (n++);\n            finish(name);\n          },\n          errorFn: dated\n        });\n      } catch (e) { dated(); }\n    }\n\n    function saveToWishlist(enter, listName) {\n      var swat = window._swat;\n      if (!swat || typeof swat.createList !== 'function' || typeof swat.addProductsToList !== 'function') {\n        if (enter && cfg.giveawayUrl) return goEnter();\n        msg = { ok: false, html: 'The wishlist isn\u2019t available right now. Try again in a moment.' };\n        return render();\n      }\n      // Parts only: workshop services aren't parts of the bike, and the\n      // giveaway's cap and the entry form's total count parts.\n      // Cheapest first: Swym shows a list newest first, so the frame and\n      // the other big parts lead the list and its card.\n      var items = partLines().slice().sort(function (a, b) { return a.pick.price - b.pick.price; }).map(function (l) {\n        return { epi: +l.pick.variantId, empi: +l.pick.productId, du: location.origin + l.pick.url, qty: l.qty, note: l.slot.label };\n      });\n      if (!items.length) return;\n      listBusy = true; msg = null; render();\n      var name = '';\n      var settled = false;\n      var timer = setTimeout(function () { fail('The wishlist is taking too long to answer.'); }, 15000);\n      function fail(text) {\n        if (settled) return;\n        settled = true;\n        clearTimeout(timer);\n        listBusy = false;\n        if (enter && cfg.giveawayUrl) return goEnter();\n        msg = { ok: false, html: esc(text) + ' Your build is still here.' };\n        render();\n      }\n      uniqueName(swat, cleanName(listName || cfg.listName || 'Dream Build') || 'Dream Build', function (picked) {\n      name = picked;\n      swat.createList({ lname: name }, function (made) {\n        var lid = made && (made.lid || (made.list && made.list.lid));\n        if (!lid) return fail('The wishlist didn\u2019t save.');\n        var chain = Promise.resolve();\n        for (var i = 0; i < items.length; i += 10) {\n          (function (batch) {\n            chain = chain.then(function () {\n              return new Promise(function (ok, no) { swat.addProductsToList(lid, batch, ok, no); });\n            });\n          })(items.slice(i, i + 10));\n        }\n        chain.then(function () {\n          if (settled) return;\n          settled = true;\n          clearTimeout(timer);\n          listBusy = false;\n          msg = { ok: true, html: 'Saved to your wishlist as \u201C' + esc(name) + '\u201D. <a href=\"/pages/wishlist\">View it</a>' +\n            (cfg.giveawayUrl ? ' or <a href=\"' + esc(cfg.giveawayUrl) + '\">' + esc(cfg.giveawayText || 'enter it in the giveaway') + '</a>.' : '.') };\n          try { if (typeof swat.renderWishlistCount === 'function') swat.renderWishlistCount(); } catch (e) { /* count badge only */ }\n          if (enter && cfg.giveawayUrl) return goEnter();\n          render();\n        }, function () { fail('Some parts didn\u2019t save to the wishlist.'); });\n      }, function (err) {\n        fail(err && /limit|maximum/i.test(JSON.stringify(err))\n          ? 'Your wishlist already has the most lists allowed (10). Remove one and try again.'\n          : 'The wishlist didn\u2019t save.');\n      });\n      });\n    }\n\n    // What the cart still needs: each line's quantity less what's already\n    // there (two tyres wanted, one in the cart: add one).\n    function toAdd() {\n      var held = {};\n      Object.keys(inCart).forEach(function (k) { held[k] = inCart[k]; });\n      return lines().map(function (l) {\n        var have = held[l.pick.variantId] || 0;\n        var need = Math.max(0, l.qty - have);\n        held[l.pick.variantId] = Math.max(0, have - l.qty);\n        return { line: l, need: need };\n      }).filter(function (x) { return x.need > 0; });\n    }\n\n    function cartButton(has) {\n      // Add to cart is the green button, as it is everywhere on the site.\n      if (!has) return '<button type=\"button\" class=\"button button--primary\" data-act=\"cart\" disabled>Add all to cart</button>';\n      var missing = toAdd();\n      if (!missing.length) return '<a class=\"button button--primary\" href=\"/cart\">Everything\\u2019s in your cart</a>';\n      var some = missing.length < lines().length;\n      return '<button type=\"button\" class=\"button button--primary\" data-act=\"cart\"' + (busy ? ' disabled' : '') + '>' +\n        (some ? 'Add the other ' + missing.length + ' to cart' : 'Add all to cart') + '</button>';\n    }\n\n    // The bike builder, set to custom wheels so it takes these from the cart.\n    function bikeNext() {\n      var url = cfg.bikeBuilderUrl;\n      return url + (url.indexOf('?') === -1 ? '?' : '&') + 'wheels=custom';\n    }\n    // next: where to go once it's in (the cart unless given).\n    function addToCart(next) {\n      // The workshop groups a build's lines by this. Wheel builds get their own\n      // property, so nothing reads them as a bike.\n      var id = (KIND === 'wheels' ? 'W' : 'B') + Date.now().toString(36).toUpperCase().slice(-6);\n      var tag = KIND === 'wheels' ? '_wheel_build' : '_build';\n      // Each line asks for no more than Shopify will sell (the card's stock\n      // check, less what the cart already holds), so one short part doesn't\n      // sink the whole add. What's left out is said, part by part.\n      var short = [];\n      var wants = toAdd().map(function (x) {\n        var p = x.line.pick, st = p.handle && stock[p.handle] && stock[p.handle].byId[p.variantId];\n        var q = x.need;\n        if (st && st.max != null) {\n          var room = Math.max(0, st.max - (inCart[p.variantId] || 0));\n          if (room < q) { short.push({ title: p.title, want: x.need, got: room }); q = room; }\n        }\n        var props = {}; props[tag] = id;\n        if (x.line.props) Object.keys(x.line.props).forEach(function (k) { props[k] = x.line.props[k]; });\n        return { item: { id: +p.variantId, quantity: q, properties: props }, title: p.title, want: x.need };\n      }).filter(function (w) { return w.item.quantity > 0; });\n      if (!wants.length && !short.length) { location.href = next || '/cart'; return; }\n      busy = true; msg = null; render();\n      var go = next || '/cart';\n      var done = function () {\n        if (!short.length) { location.href = go; return; }\n        busy = false;\n        msg = { ok: false, html: short.map(function (s) {\n          return s.got ? 'Only ' + s.got + ' of ' + s.want + ' ' + esc(s.title) + ' could go in.' : esc(s.title) + ' couldn\\u2019t go in' + (s.why ? ' (' + esc(s.why) + ')' : ', none left') + '.';\n        }).join(' ') + (wants.length ? ' Everything else is in your cart.' : '') + ' Swap the part here, or call us on 1300 589 269. ' +\n          '<a href=\"/cart\">View your cart</a>' + (next ? ' or <a href=\"' + esc(next) + '\">carry on to the bike builder</a>' : '') + '.' };\n        syncCart(false);\n      };\n      if (!wants.length) return done();\n      post(wants.map(function (w) { return w.item; })).then(function (res) {\n        if (res.ok) return done();\n        if (res.status !== 422) throw new Error(res.text);\n        // Still turned down (a limit the stock check didn't know): each part\n        // on its own, once, so the rest still go in.\n        return wants.reduce(function (chain, w) {\n          return chain.then(function () {\n            return post([w.item]).then(function (r) { if (!r.ok) short.push({ title: w.title, want: w.want, got: 0, why: r.text }); });\n          });\n        }, Promise.resolve()).then(done);\n      }).catch(function (e) {\n        busy = false;\n        msg = { ok: false, html: esc(String(e.message || 'The build didn\\u2019t go into your cart').replace(/\\.+$/, '')) + '. Nothing was added. Try again, or call us on 1300 589 269.' };\n        render();\n      });\n    }\n    function post(items) {\n      return fetch('/cart/add.js', {\n        method: 'POST',\n        headers: { 'Content-Type': 'application/json', Accept: 'application/json' },\n        body: JSON.stringify({ items: items })\n      }).then(function (r) {\n        return r.json().catch(function () { return {}; }).then(function (j) {\n          return { ok: r.ok, status: r.status, text: String(j.description || j.message || '').replace(/\\.+$/, '') };\n        });\n      });\n    }\n\n    // ------------------------------------------------------------ cart sync\n\n    function cartPick(it) {\n      return {\n        handle: it.handle, productId: it.product_id, variantId: it.variant_id, title: it.product_title,\n        variantTitle: it.variant_title || 'Default Title', price: it.original_price != null ? it.original_price : it.price,\n        img: (it.featured_image && it.featured_image.url) || it.image || null,\n        url: '/products/' + it.handle, fromCart: true\n      };\n    }\n\n    // Reads the cart and fills each empty slot with a part of its type that's\n    // already there. Never replaces a pick the rider made here. A wheel set\n    // fills both wheels; custom wheel parts or separate brake parts in the\n    // cart switch those options on, unless the rider has set them.\n    function syncCart(announce) {\n      return fetch('/cart.js', { credentials: 'same-origin', headers: { Accept: 'application/json' } })\n        .then(function (r) { return r.json(); })\n        .then(function (cart) {\n          inCart = {};\n          var items = cart.items || [];\n          items.forEach(function (it) { inCart[it.variant_id] = (inCart[it.variant_id] || 0) + it.quantity; });\n          var filled = [];\n          items.forEach(function (it) {\n            // Slots for this kind of bike that take the part. Brake parts share\n            // types, so the title decides between rotor, mount and so on.\n            var targets = SLOTS.filter(function (s) {\n              if (s.end && KIND === 'wheels' && opts.wheels !== 'pair' && s.end !== opts.wheels) return false;\n              return (!s.mode || s.mode === opts.mode) && s.types.indexOf(it.product_type) !== -1 && fits(s, it.product_title);\n            });\n            if (!targets.length) return;\n            if (it.product_type === 'Wheel Sets' || it.product_type === 'Hub Sets') {\n              var ends = it.product_type === 'Wheel Sets' ? ['front', 'rear'] : ['fhub', 'rhub'];\n              if (picks[ends[0]] || picks[ends[1]]) return;\n              var set = cartPick(it); set.set = true;\n              picks[ends[0]] = set; picks[ends[1]] = set;\n              filled.push(ends[0], ends[1]);\n              return;\n            }\n            // One slot per type, except rims and tyres (front then rear). A rim\n            // or tyre with quantity 2 fills both.\n            var free = targets.filter(function (s) { return !picks[s.id]; }).slice(0, Math.max(1, it.quantity));\n            free.forEach(function (slot) {\n              picks[slot.id] = cartPick(it);\n              filled.push(slot.id);\n            });\n          });\n          var cartKitFork = syncForkKit();\n          if (cartKitFork) filled.push(cartKitFork);\n          if (KIND === 'bike' && !opts.wheelsSet && ['fhub', 'rhub', 'frim', 'rrim', 'spokes'].some(function (id) { return picks[id]; }) && !picks.front && !picks.rear) {\n            opts.customWheels = true;\n            loadWheelBuild();\n          }\n          if (!opts.brakesSet && ['lever', 'cable', 'caliper'].some(function (id) { return picks[id]; }) && !picks.brakekit) {\n            opts.brakes = 'parts';\n          }\n          if (!opts.brakesSet && opts.mode !== 'race' && ['fdbrake', 'frotor', 'fdmount'].some(function (id) { return picks[id] && !picks[id].included; })) {\n            opts.brakes = 'disc';\n          }\n          if (!opts.raceBrakesSet && opts.mode === 'race' && ['vbrake', 'vlever', 'vcable'].some(function (id) { return picks[id] && !picks[id].included; }) && !picks.dbrake && !picks.rotor) {\n            opts.raceBrakes = 'v';\n          }\n          if (filled.length) {\n            checkPickStock();\n            save();\n            justFilled = filled;\n            var pr = progress();\n            if (pr.done === pr.need) celebrated = true;\n          }\n          render();\n          var parts = filled.filter(function (id) { return !(isRearOfPair(id) && picks[id] && picks[id].set && filled.indexOf(PAIRS[id]) !== -1); }).length;\n          if (announce !== false && parts) toast(parts + ' part' + (parts === 1 ? '' : 's') + ' from your cart ' + (parts === 1 ? 'is' : 'are') + ' in your build.');\n        })\n        .catch(function () { /* no cart, no fill: the builder works without it */ });\n    }\n\n    // ------------------------------------------------------------ events\n\n    root.addEventListener('click', function (e) {\n      var t = e.target;\n      var rm = t.closest('[data-remove]');\n      if (rm) return removePick(rm.getAttribute('data-remove'));\n      var sm = t.closest('[data-same]');\n      if (sm) return copyTwin(sm.getAttribute('data-same'));\n      var en = t.closest('[data-end]');\n      if (en) return chooseEnd.apply(null, en.getAttribute('data-end').split(':'));\n      var inc = t.closest('[data-include]');\n      if (inc) return include(inc.getAttribute('data-include'));\n      var op = t.closest('[data-open]');\n      if (op && board.contains(op)) return openPicker(op.getAttribute('data-open'));\n      var act = t.closest('[data-act]');\n      if (act) {\n        var a = act.getAttribute('data-act');\n        if (a === 'wishlist') askListName();\n        else if (a === 'enter') askListName(true);\n        else if (a === 'cart') addToCart();\n        else if (a === 'cart-bike') addToCart(bikeNext());\n        else if (a === 'reset' && window.confirm('Clear this build and start again? Your wishlist and cart aren\u2019t changed.')) {\n          picks = {}; afterReset();\n        }\n        return;\n      }\n      if (t.closest('[data-close]')) return closePicker();\n      var mb = t.closest('[data-menu]');\n      if (mb) { menu = menu === mb.getAttribute('data-menu') ? null : mb.getAttribute('data-menu'); return renderPicker(); }\n      if (t.closest('[data-clear-filters]')) { opts.disc = []; opts.colours = []; opts.luxOnly = false; brandSel = []; if (open) extraSel[open] = {}; menu = null; save(); return refreshPicker(); }\n      if (menu && !t.closest('.lux-bl__filter')) { menu = null; renderPicker(); }\n      if (t.closest('[data-back]')) {\n        var was = chosen && chosen.product.h;\n        view = 'list'; chosen = null; renderPicker();\n        var back = was && picker.querySelector('[data-product=\"' + cssEsc(was) + '\"] [data-card-open]');\n        if (back) back.focus();\n        return;\n      }\n      if (t.closest('[data-more]')) { var mc = cache[cacheKey()]; if (mc) mc.limit = (mc.limit || STEP) + STEP; return renderPicker(); }\n      if (t.closest('[data-retry]')) { var rc = cache[cacheKey()]; if (rc) rc.error = false; renderPicker(); return fetchMore(); }\n      var pg = t.closest('[data-pegs]');\n      if (pg) { opts.pegs = +pg.getAttribute('data-pegs'); save(); render(); return renderPicker(); }\n      var arrow = t.closest('[data-slide]');\n      if (arrow) {\n        var track = arrow.parentNode.querySelector('[data-track]');\n        var w = Math.max(1, track.clientWidth);\n        var to = Math.max(0, Math.min(track.children.length - 1, Math.round(track.scrollLeft / w) + +arrow.getAttribute('data-slide')));\n        track.scrollTo({ left: to * w, behavior: 'smooth' });\n        paintTrack(track, to);\n        return;\n      }\n      var swatch = t.closest('[data-swatch]');\n      if (swatch) {\n        // As on the category tiles: the swatch's photo takes the first slide.\n        var pc = swatch.closest('[data-product]');\n        pc.querySelectorAll('[data-swatch]').forEach(function (x) { x.classList.toggle('is-active', x === swatch); });\n        var first = pc.querySelector('[data-track] img');\n        if (first && swatch.getAttribute('data-img')) first.src = swatch.getAttribute('data-img');\n        var tr = pc.querySelector('[data-track]');\n        if (tr) { tr.scrollLeft = 0; paintTrack(tr); }\n        pc.setAttribute('data-pre-' + swatch.getAttribute('data-swatch'), swatch.getAttribute('data-v'));\n        return;\n      }\n      var pill = t.closest('[data-pill]');\n      if (pill) {\n        var pc2 = pill.closest('[data-product]');\n        pc2.setAttribute('data-pre-' + pill.getAttribute('data-pill'), pill.getAttribute('data-v'));\n        return showProduct(pc2.getAttribute('data-product'), pc2);\n      }\n      var cardEl = t.closest('[data-product]');\n      if (cardEl) return showProduct(cardEl.getAttribute('data-product'), cardEl);\n      var opt = t.closest('[data-value]');\n      if (opt && chosen) { choose(chosen.product, +opt.getAttribute('data-value'), opt.getAttribute('data-v')); return renderPicker(); }\n      var th = t.closest('[data-thumb]');\n      if (th && chosen) { chosen.stage = th.getAttribute('data-thumb'); return renderPicker(); }\n      if (t.closest('[data-lock]')) return lockIn();\n      // A click on the dim backdrop lands on the dialog itself.\n      if (t === dialog) closePicker();\n    });\n\n    // Opens a product in the quick view, on the variant already in the\n    // build if it's the same product, else the first one in stock.\n    function showProduct(handle, el) {\n      var c = cache[cacheKey()];\n      var prod = c && c.items.filter(function (p) { return p.h === handle; })[0];\n      if (!prod) return;\n      var mine = picks[open] && picks[open].handle === prod.h ? picks[open].variantId : null;\n      // A swatch or pill chosen on the card: open on the best variant with it.\n      var pre = {};\n      (prod.o || []).forEach(function (n, i) { var v = el && el.getAttribute('data-pre-' + i); if (v != null) pre[i] = v; });\n      // One value ticked in an option filter (Size: 20.75): open on it.\n      var ticked = extraSel[open] || {};\n      (prod.o || []).forEach(function (n, i) {\n        var vals = ticked['filter.v.option.' + String(n).toLowerCase().replace(/\\s+/g, '-')];\n        if (pre[i] == null && vals && vals.length === 1 && prod.vs.some(function (v) { return v.o[i] === vals[0]; })) pre[i] = vals[0];\n      });\n      var keys = Object.keys(pre);\n      var match = keys.length ? prod.vs.filter(function (v) { return keys.every(function (i) { return v.o[i] === pre[i]; }); }) : [];\n      var lastKey = keys[keys.length - 1];\n      var fitsHere = function (v) { return sells(v) && fitCheck(open, fitOf(v)).state !== 'no'; };\n      var start = match.filter(fitsHere)[0] || match.filter(sells)[0] || match.filter(function (v) { return v.a; })[0] ||\n        (!keys.length && !mine && pairsFor(open).length && prod.vs.filter(fitsHere)[0]) ||\n        (lastKey != null && prod.vs.filter(function (v) { return sells(v) && v.o[lastKey] === pre[lastKey]; })[0]) || match[0] ||\n        (mine && prod.vs.filter(function (v) { return v.id === mine; })[0]) ||\n        ((opts.colours.length || opts.luxOnly) && prod.vs.filter(sells)[0]) || firstAvailable(prod);\n      chosen = { product: prod, sel: start.o.slice(), stage: null };\n      loadStock(prod.h);\n      view = 'detail';\n      renderPicker();\n      picker.scrollTop = 0;\n      var head = picker.querySelector('#' + cssEsc(dialog.getAttribute('aria-labelledby')));\n      if (head) head.focus({ preventScroll: true });\n    }\n\n    root.addEventListener('change', function (e) {\n      if (e.target.matches('[data-brakes]')) { opts.brakes = e.target.value; opts.brakesSet = true; return afterReset(); }\n      if (e.target.matches('[data-race-brakes]')) { opts.raceBrakes = e.target.value; opts.raceBrakesSet = true; return afterReset(); }\n      if (e.target.matches('[data-mode]')) {\n        opts.mode = e.target.value === 'race' ? 'race' : 'freestyle';\n        // The picker opens on parts for this kind of bike; the Discipline\n        // filter or \"Show all\" takes that off.\n        opts.disc = opts.mode === 'race' ? ['Race'] : [];\n        // A fork ticked as coming with the frame is a race-only shortcut.\n        if (opts.mode !== 'race' && picks.fork && picks.fork.included && !picks.fork.kit) delete picks.fork;\n        applyMode();\n        afterReset();\n        syncCart(false);\n        return toast(opts.mode === 'race' ? 'Race bike: brakes are part of the build, and the lists show race parts.' : 'Freestyle bike: the lists show every part.');\n      }\n      if (e.target.matches('[data-opt=\"assembly\"]')) {\n        opts.assembly = e.target.checked;\n        save();\n        render();\n        return toast(opts.assembly ? 'Our workshop will build it.' : 'Parts only, no assembly.');\n      }\n      if (e.target.matches('[data-wheels]')) {\n        opts.wheels = e.target.value;\n        afterReset();\n        return toast(opts.wheels === 'pair' ? 'Building both wheels.' : 'Building the ' + opts.wheels + ' wheel.');\n      }\n      if (e.target.matches('[data-opt=\"customWheels\"]')) {\n        opts.customWheels = e.target.checked;\n        opts.wheelsSet = true;\n        if (opts.customWheels) loadWheelBuild();\n        afterReset();\n        toast(opts.customWheels ? 'Custom wheels: pick hubs, rims and spokes.' : 'Complete wheels it is.');\n      }\n    });\n\n    picker.addEventListener('scroll', function (e) {\n      if (e.target.matches && e.target.matches('[data-track]')) paintTrack(e.target);\n    }, true);\n\n    var searchTimer;\n    picker.addEventListener('input', function (e) {\n      if (!e.target.matches('[data-term]')) return;\n      term = e.target.value;\n      clearTimeout(searchTimer);\n      searchTimer = setTimeout(function () {\n        if (!cache[cacheKey()]) fetchMore(); else renderPicker();\n      }, 280);\n    });\n    picker.addEventListener('change', function (e) {\n      var el = e.target;\n      if (el.matches('[data-sort]')) { sort = el.value; return renderPicker(); }\n      function toggle(list, value, on) {\n        var i = list.indexOf(value);\n        if (on && i === -1) list.push(value);\n        if (!on && i !== -1) list.splice(i, 1);\n      }\n      if (el.matches('[data-disc]')) { toggle(opts.disc, el.value, el.checked); save(); return refreshPicker(); }\n      if (el.matches('[data-brand]')) { toggle(brandSel, el.value, el.checked); return renderPicker(); }\n      if (el.matches('[data-extra]') && open) {\n        // Read the whole list back: a slider's Apply ticks many rows and\n        // fires one change.\n        var mine = extraSel[open] || (extraSel[open] = {});\n        var prm = el.getAttribute('data-extra');\n        var list = [];\n        picker.querySelectorAll('[data-extra=\"' + cssEsc(prm) + '\"]').forEach(function (b) { if (b.checked) list.push(b.value); });\n        if (list.length) mine[prm] = list; else delete mine[prm];\n        return refreshPicker();\n      }\n      if (el.matches('[data-colour]')) { toggle(opts.colours, el.value, el.checked); save(); return renderPicker(); }\n      if (el.matches('[data-lux-only]')) { opts.luxOnly = el.checked; save(); return renderPicker(); }\n    });\n    // The 3D preview's info popover (a <details> in the section) closes on a\n    // click anywhere else, on Escape, and when the bigger view closes.\n    function closeInfo(e) {\n      root.querySelectorAll('.lux-bp__info[open]').forEach(function (d) {\n        var big = d.closest('.lux-bp') && d.closest('.lux-bp').classList.contains('is-large');\n        if (!e || e.type === 'keydown' || !big || !d.contains(e.target)) d.removeAttribute('open');\n      });\n    }\n    document.addEventListener('click', closeInfo);\n    document.addEventListener('keydown', function (e) { if (e.key === 'Escape') closeInfo(e); });\n\n    // The close event lands a moment after close(); if a picker has been\n    // opened again in that gap, the new one must keep its slot.\n    dialog.addEventListener('close', function () {\n      if (!dialog.open) open = null;\n      prefetchNext();\n      // The board redraws after a pick, so the tile that opened the picker\n      // is a new element: focus its twin instead of leaving it on the page.\n      var a = document.activeElement;\n      if (lastOpen && (!a || a === document.body || !document.contains(a))) {\n        var tile = board.querySelector('.lux-bl__hit[data-open=\"' + cssEsc(lastOpen) + '\"]');\n        if (tile) tile.focus({ preventScroll: true });\n      }\n    });\n\n    showPreviewStill();\n    checkPickStock();\n    loadWheelData();\n    if (customOn()) loadWheelBuild();\n    render();\n    reprice();\n    emit();\n    syncCart();\n    prefetchNext();\n    document.addEventListener('cart:updated', function () { syncCart(); });\n    document.addEventListener('cart:refresh', function () { syncCart(); });\n    window.addEventListener('pageshow', function (e) { if (e.persisted) syncCart(); });\n  }\n\n  function boot() {\n    document.querySelectorAll('[data-lux-build]').forEach(function (el) {\n      if (el.dataset.buildReady) return;\n      el.dataset.buildReady = '1';\n      try {\n        init(el);\n      } catch (e) {\n        if (window.console) console.error('Bike builder', e);\n        var board = el.querySelector('[data-build-board]');\n        if (board) board.innerHTML = '<p class=\"lux-bl__note\">The builder didn\\u2019t load. Refresh the page to try again.</p>';\n      }\n    });\n  }\n  if (document.readyState === 'loading') document.addEventListener('DOMContentLoaded', boot); else boot();\n  document.addEventListener('shopify:section:load', boot);\n})();\n"],
  "mappings": "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",
  "names": ["cross", "x", "shown", "i", "busy", "card", "colours", "list", "tile"]
}
