feat(site): original device art + amazing polish pass

Adds original OpenScribe illustrations and elevates the whole site from a plain
scaffold to a polished, animated product site.

What changed:
- assets/img/: original SVG artwork (CC-BY-SA, no third-party photos):
  - openscribe-wearable.svg - the wearable recorder with a breathing status LED (SMIL
    animation that plays even when embedded via <img>).
  - openscribe-kit.svg - the dev/kit build: ESP32-S3 board + I2S mic + microSD + LiPo,
    with amber trace connectors.
  - favicon.svg - the "12" studio mark; wired as the site icon and header logo.
- index.html: two-column hero with the floating device, a trust strip, a featured
  showcase (device image + sync diagram), project cards with device thumbnails, and a
  new "why open beats a locked box" comparison table (our own words, no competitor art).
- projects/openscribe.html: device hero, the AI picker in a proper panel, and a new
  "two ways to build it" section with product figures (wearable + kit) and descriptions.
- assets/styles.css: full theme refresh - atmospheric background, gradient headings,
  hero float, hover lift + shadows, product/figure styles, comparison table, and
  scroll-reveal transitions (honours prefers-reduced-motion).
- assets/app.js: IntersectionObserver scroll reveals alongside the provider picker.
- README: documents the artwork and that it is original/publishable.

Why:
- The user asked for product images with descriptions, then to "make it amazing" - this
  delivers IP-safe original device imagery and a genuinely polished, animated site.

Notes:
- Still zero dependencies and no build step. Validated: app.js passes node --check, all
  SVGs are valid XML, HTML section tags balanced, every local link/asset resolves.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
Laurence 2026-07-03 19:17:35 +01:00
parent e1bf5a2d7a
commit 71217ce3e1
8 changed files with 448 additions and 107 deletions

View file

@ -81,6 +81,23 @@
render(Object.keys(PROVIDERS)[0]);
}
if (document.readyState !== "loading") init();
else document.addEventListener("DOMContentLoaded", init);
// Reveal sections as they scroll into view (graceful if unsupported).
function reveals() {
var els = document.querySelectorAll(".reveal");
if (!("IntersectionObserver" in window) || !els.length) {
els.forEach(function (el) { el.classList.add("in"); });
return;
}
var io = new IntersectionObserver(function (entries) {
entries.forEach(function (e) {
if (e.isIntersecting) { e.target.classList.add("in"); io.unobserve(e.target); }
});
}, { threshold: 0.12, rootMargin: "0px 0px -8% 0px" });
els.forEach(function (el) { io.observe(el); });
}
function boot() { init(); reveals(); }
if (document.readyState !== "loading") boot();
else document.addEventListener("DOMContentLoaded", boot);
})();