onlyn00bs-badge

OnlyN00bs: a DEF CON 34 friend-finder badge. ESP32 firmware, Web Bluetooth setup app, printable case
git clone https://git.virtualshack.io/onlyn00bs-badge.git
Log | Files | Refs | README | LICENSE

commit 757547a3974dce760c35e1d3fdfcd22925196677
parent f78abc520b3178e44d1b384128d722385f844be8
Author: virtualtack <[email protected]>
Date:   Sat, 26 Sep 2026 12:46:46 -0700

Snapshot of v1.10-dc34-90-gce26904

Diffstat:
MSNAPSHOT.md | 2+-
Mweb/src/assets/badge.css | 24++++++++++++++++--------
Mweb/src/gallery/index.html | 2+-
Mweb/src/index.html | 2+-
Mweb/src/sw.js | 2+-
5 files changed, 20 insertions(+), 12 deletions(-)

diff --git a/SNAPSHOT.md b/SNAPSHOT.md @@ -1,7 +1,7 @@ # About this snapshot This repository is the public release of the OnlyN00bs badge, taken from its private -development repo at `v1.10-dc34-89-ge894278` on 2026-09-26. It holds what describes the **production unit +development repo at `v1.10-dc34-90-gce26904` on 2026-09-26. It holds what describes the **production unit as it is**: the firmware, the Web Bluetooth setup app, the site, the parts list, and the case. diff --git a/web/src/assets/badge.css b/web/src/assets/badge.css @@ -12,7 +12,9 @@ :root { --bg: #212121; /* virtualshack.io dark bg */ --fg: #dadada; - --link: #42a5f5; /* parent accent */ + --link: #22d3ee; /* virtualshack accents (STYLE.md): cyan links, */ + --hover: #ff79c6; /* pink hover/focus, */ + --focus: #9b8cff; /* blue-purple focus ring */ --accent: #3ddc97; /* badge sub-brand mint */ --panel: #2b2b2b; --rule: #424242; @@ -26,8 +28,10 @@ :root { --bg: #fafafa; --fg: #212121; - --link: #1565c0; - --accent: #0f9d63; /* mint darkened for contrast on white */ + --link: #0e7490; + --hover: #c2185b; + --focus: #5b4fe0; + --accent: #0a7f50; /* mint for white: 4.8:1 (#0f9d63 was 3.3:1, failed AA) */ --panel: #efefef; --rule: #d5d5d5; --code-bg: #e4e4e4; @@ -49,8 +53,11 @@ body { .wrapper { max-width: 780px; margin: 0 auto; padding: 32px 20px 64px; } -a { color: var(--link); text-decoration: none; } -a:hover, a:focus { text-decoration: underline; } +/* Links are never underlined (STYLE.md): hover/focus is the colour change, keyboard focus + also gets the ring. */ +a { color: var(--link); text-decoration: none; transition: color .15s ease; } +a:hover, a:focus { color: var(--hover); text-decoration: none; } +a:focus-visible { outline: 2px solid var(--focus); outline-offset: 2px; border-radius: 2px; } h1, h2, h3 { line-height: 1.3; font-weight: 700; } h1 { font-size: 26px; margin: 0 0 6px; color: var(--accent); letter-spacing: .5px; } @@ -107,12 +114,13 @@ hr { border: 0; border-top: 1px solid var(--rule); margin: 36px 0; } display: inline-block; margin: 8px 0 4px; padding: 12px 20px; - background: var(--accent); + background: #3ddc97; /* bright mint in BOTH themes: the dark label is 10.8:1 on it, + but only 3.8:1 on the light-mode TEXT mint (#0a7f50) */ color: #08110b; font-weight: 700; border-radius: 8px; } -.cta:hover, .cta:focus { text-decoration: none; opacity: .9; } +.cta:hover, .cta:focus { color: #08110b; text-decoration: none; opacity: .9; } /* keep the dark label: a:hover would turn it pink */ /* Non-link CTA while the setup app isn't hosted yet: same shape, but muted and inert. */ .cta.disabled { @@ -282,7 +290,7 @@ dialog.lightbox figcaption { font-size: 13px; color: #bdbdbd; text-align: center color: #dadada; background: rgba(43, 43, 43, .85); border: 1px solid #424242; border-radius: 8px; cursor: pointer; } -.lightbox button:hover, .lightbox button:focus-visible { border-color: #3ddc97; color: #3ddc97; outline: none; } +.lightbox button:hover, .lightbox button:focus-visible { border-color: #ff79c6; color: #ff79c6; outline: none; } .lightbox .close { top: 8px; right: 12px; } .lightbox .prev { left: 12px; top: 50%; transform: translateY(-50%); } .lightbox .next { right: 12px; top: 50%; transform: translateY(-50%); } diff --git a/web/src/gallery/index.html b/web/src/gallery/index.html @@ -17,7 +17,7 @@ <meta name="twitter:card" content="summary_large_image"> <meta name="twitter:image" content="https://badge.virtualshack.io/assets/img/og-badge.jpg"> <!-- ?v= must match CACHE in ../sw.js — same rule as index.html --> -<link rel="stylesheet" href="../assets/badge.css?v=36"> +<link rel="stylesheet" href="../assets/badge.css?v=37"> <link rel="icon" type="image/svg+xml" href="../assets/icon.svg"> <link rel="manifest" href="../manifest.webmanifest"> <meta name="theme-color" content="#212121"> diff --git a/web/src/index.html b/web/src/index.html @@ -32,7 +32,7 @@ invisible to visitors for hours after a deploy. A new query = a new edge cache key = it lands immediately. Safe for offline: sw.js matches with ignoreSearch, so this still resolves to the precached bare URL. --> -<link rel="stylesheet" href="assets/badge.css?v=36"> +<link rel="stylesheet" href="assets/badge.css?v=37"> <link rel="icon" type="image/svg+xml" href="assets/icon.svg"> <link rel="manifest" href="manifest.webmanifest"> <meta name="theme-color" content="#212121"> diff --git a/web/src/sw.js b/web/src/sw.js @@ -17,7 +17,7 @@ * there is one version to remember, not two. */ -const CACHE = "onlyn00bs-v36"; +const CACHE = "onlyn00bs-v37"; // Resolved against the worker's own location, so it's right whether the site is served at // / (production) or under a path (a local preview).