NEON DJ is built entirely inside a singleDocumentation Index
Fetch the complete documentation index at: https://mintlify.com/kepabilbao67-bot/musicplayer2/llms.txt
Use this file to discover all available pages before exploring further.
index.html file of approximately 75 KB. There are no build tools, no npm packages, no bundler, and no external JavaScript dependencies loaded at startup — you can open the file directly in any modern browser and the full DJ mixer is immediately available. This document explains how the file is structured internally and how its three logical sections work together.
File Structure Overview
The file is divided into three distinct sections that map directly to HTML’s natural layers:<style> block comes first and contains all visual design tokens, layout rules, and component styles. The <body> defines the static HTML skeleton — header, the three-column .console grid, both deck panels, the central mixer, and the FX bar at the bottom. The <script> block at the end of <body> contains every piece of application logic.
CSS Design Tokens
All colours and surface values are declared as CSS custom properties on:root, making the entire visual theme easy to adjust from a single location:
getComputedStyle.
Layout: Three-Column CSS Grid
The main.console element uses a three-column CSS Grid to place Deck A, the central mixer, and Deck B side by side:
Key Global Objects
The JavaScript section is built around a small set of global objects and instances:audioCtx
The singleton
AudioContext (or webkitAudioContext) created lazily on the first user gesture via the AC() helper function. Never instantiated at script parse time.masterGain
A
GainNode that receives both deck outputs. Its gain value is set by the master volume slider (default 0.85).masterLimiter
A
DynamicsCompressorNode connected after masterGain. Prevents clipping when multiple elements play simultaneously (threshold −3 dB, ratio 20:1).masterFlangerWet / masterEchoWet
GainNodes that control the wet level of the master flanger and echo send effects. Both start at gain 0 and are ramped up momentarily by flangerThrow() and echoThrow().deckA / deckB
Instances of the
Deck class. Each encapsulates its own Web Audio graph, UI element references, playback state, EQ nodes, filter, delay send, and reverb send.FX object
A plain object mapping effect names (
riser, airhorn, impact, zap, flanger, brake, echo) to their trigger functions. Used by the FX pad buttons and keyboard shortcuts.The Deck Class
The Deck class is the core abstraction. Each instance is constructed with a reference to its root DOM element, a colour string ("a" or "b"), and a getter for the other deck (used for SYNC). The constructor:
- Stores playback state (
buffer,offset,rate,isPlaying,loopActive, hot cue positions). - Queries and caches all relevant DOM elements by
data-roleattribute. - Calls
buildGraph()to create and connect all Web Audio nodes for that deck. - Calls
bind()to attach all event listeners (transport buttons, knobs, vinyl jog, waveform click).
The FX Object
Effect trigger functions are collected into a single FX map:
btn.dataset.fx and look up the function: FX[btn.dataset.fx](). The keyboard handler maps number keys 1–7 to the same functions.
Initialization Flow
Page Load
The browser parses and executes the
<script> block. No audio is created yet — AudioContext is not instantiated.Track Generation
init() is called immediately. It iterates over all genre definitions in TRACKS and calls generateTrack(def) for each, rendering every track offline using OfflineAudioContext. A progress bar is shown during this phase.Deck Construction
After all buffers are ready,
deckA and deckB are instantiated. Both call AC() for the first time, which creates the shared AudioContext and the master node chain.Default Tracks Loaded
House is loaded into Deck A and Techno into Deck B. Previously saved settings are restored from
localStorage.The single-file architecture makes NEON DJ trivially easy to share — send one file, open in a browser, done. The trade-off is maintainability at scale: all CSS, markup, and logic live in one 1,500-line document with no module boundaries, no type checking, and no hot-module reload. For a personal tool or creative demo this is an excellent choice; for a production app maintained by a team, splitting into modules would be preferable.