diff --git a/assets/versions.js b/assets/versions.js
index a441e76..60dbc4b 100644
--- a/assets/versions.js
+++ b/assets/versions.js
@@ -1,8 +1,15 @@
// Generated by tools/make_builder_data.py from tools/changelog.json and the mods' versions.
window.CDJ_VERSIONS = {
- "site": "1.4.0",
+ "site": "1.4.1",
"date": "2026-10-20",
"log": [
+ {
+ "version": "1.4.1",
+ "date": "2026-10-20",
+ "changes": [
+ "Open the builder carries a PLAY/PAUSE key that blinks green like the player's."
+ ]
+ },
{
"version": "1.4.0",
"date": "2026-10-20",
diff --git a/builder.html b/builder.html
index 4a10b2b..68dfda2 100644
--- a/builder.html
+++ b/builder.html
@@ -8,12 +8,12 @@
-
-
-
-
-
-
+
+
+
+
+
+
diff --git a/docs.html b/docs.html
index ab0ade5..42ab15e 100644
--- a/docs.html
+++ b/docs.html
@@ -8,9 +8,9 @@
-
-
-
+
+
+
diff --git a/index.html b/index.html
index 828921f..8fd3b95 100644
--- a/index.html
+++ b/index.html
@@ -8,9 +8,9 @@
-
-
-
+
+
+
@@ -35,7 +35,7 @@
Firmware mods for the Pioneer CDJ-900NXS. We took the player's firmware apart in an emulator and added what newer Pioneer players have: hot cues on the deck, beat jump, colour and 3-band waveforms, keys in Camelot colours and more.
Pick the mods you want in the builder. It patches the official 1.31 update in your browser and gives you a normal C900NXS.UPD to install like any update. The boot loader is never touched, so you can always go back to stock.
@@ -278,7 +278,7 @@
Build it in your browser
The builder takes the official 1.31 update and adds the mods you tick, on your computer. Only the main application changes; the boot loader and recovery are copied byte for byte and checked.
-
+
Prefer the command line? The Python patcher builds the same file, byte for byte:
# pick the mods in a list
$ python cdj900nxs_patcher.py C900NXS.UPD
diff --git a/style.css b/style.css
index 277dea1..5daff37 100644
--- a/style.css
+++ b/style.css
@@ -492,6 +492,26 @@ h2.section-title { text-transform: uppercase; letter-spacing: .02em; }
@media (max-width: 560px) {
.tabs a { padding: 10px 7px 8px; letter-spacing: .06em; font-size: .72rem; }
}
+/* PLAY/PAUSE key inside the builder button: a round key with a green ring
+ that blinks like the player's when it waits; steady green on hover */
+.btn.play { padding: 7px 20px 7px 7px; gap: 12px; }
+.play-key {
+ width: 34px; height: 34px; border-radius: 50%; flex: none; display: grid; place-items: center;
+ background: radial-gradient(circle at 50% 35%, #2a2d33, #121418 70%);
+ box-shadow: inset 0 1px 0 rgba(255,255,255,.12), 0 1px 2px rgba(0,0,0,.5);
+ position: relative;
+}
+.play-key::before {
+ content: ""; position: absolute; inset: 2px; border-radius: 50%;
+ border: 2px solid var(--lcd-green); box-shadow: 0 0 8px var(--lcd-green), inset 0 0 6px color-mix(in srgb, var(--lcd-green) 50%, transparent);
+ animation: play-blink 1s steps(1, end) infinite;
+}
+.play-key svg { width: 17px; height: 10px; fill: #e8eaee; }
+.btn.play:hover .play-key::before { animation: none; opacity: 1; }
+@keyframes play-blink { 0% { opacity: 1; } 50% { opacity: .12; } }
+:root[data-theme="light"] .play-key::before { border-color: #8dffb4; box-shadow: 0 0 8px #8dffb4; }
+
@media (prefers-reduced-motion: reduce) {
.brand .disc { animation: none; }
+ .play-key::before { animation: none; }
}
diff --git a/tools/changelog.json b/tools/changelog.json
index f926e82..1c19086 100644
--- a/tools/changelog.json
+++ b/tools/changelog.json
@@ -1,6 +1,13 @@
{
"_about": "The site's changelog, newest first. Versions follow Semantic Versioning (MAJOR.MINOR.PATCH), dates ISO 8601 (DIN EN 28601). make_builder_data.py adds every mod's current version from its module and writes assets/versions.js.",
"site": [
+ {
+ "version": "1.4.1",
+ "date": "2026-10-20",
+ "changes": [
+ "Open the builder carries a PLAY/PAUSE key that blinks green like the player's."
+ ]
+ },
{
"version": "1.4.0",
"date": "2026-10-20",
diff --git a/upcoming.html b/upcoming.html
index ce90ae6..dca877b 100644
--- a/upcoming.html
+++ b/upcoming.html
@@ -8,9 +8,9 @@
-
-
-
+
+
+