Live at https://ic.internetblacksmith.dev.
A digital clock displayed on seven-segment SVG displays — with the twist that each of the H / M / S components has its own toggle switch. Hide any combination and try to read what's left. Try to understand it if you dare ;)
- Seven-segment SVG displays driven entirely by CSS class state
- Independent toggle switches for hours, minutes, and seconds
- Responsive layout from mobile up to 4K
- Zero runtime dependencies — vanilla ES modules, no framework
git clone https://github.com/internetblacksmith/impossible-clock.git
cd impossible-clock
npm installRequires Node >=24.0.0 (development is pinned to 24.14.0 via .nvmrc / .node-version — current LTS).
npm run dev # Vite dev server on http://localhost:3000
npm run build # Production build into dist/
npm run preview # Serve dist/ for inspectionnpm run test:unit # Vitest — pure helpers (fast)
npm run test # Cypress E2E + visual regression
npm run test:no-visual # Cypress E2E without visual diff
npm run test:coverage # E2E with code coverage via nyc
npm run cy:open # Open Cypress interactive runnerTest layers:
- Unit (Vitest) — the pure digit/status helpers in
app/scripts/clock.js - E2E (Cypress) — clock accuracy, toggle behaviour, performance, responsive layout
- Visual regression (cypress-image-diff-js) — pixel comparison of the rendered seven-segment displays against baselines committed under
cypress-visual-screenshots/
npm run lint # ESLint
npm run format # Prettier --write
npm run format:check # Prettier --checkESLint (flat config) handles code quality, Prettier handles formatting — separated so they don't fight.
- Vite — build & dev server
- Lightning CSS — Rust-based CSS transformer + minifier (replaces the old PostCSS/autoprefixer/cssnano trio)
- SCSS — styling
- Vitest — unit tests
- Cypress — E2E and visual regression
- ESLint 9 + Prettier — code quality & formatting
- Vanilla ES modules — no framework
Modern evergreen browsers (last two versions of Chrome / Firefox / Safari / Edge) plus Firefox ESR, driven by the browserslist block in package.json. No transpilation to ES5 and no polyfills are shipped — the build target is es2020.
Deployed to Netlify on every push to main. Build config lives in netlify.toml — that's the source of truth for the build command, Node version, security headers, and cache rules. The dashboard's legacy build_settings.env API is intentionally unused.
MIT — see LICENSE.md.
Remember: the clock's behaviour is intentionally mysterious. Can you figure out how to read it? 🕐