mirror of
https://github.com/hanzoai/templates.git
synced 2026-10-30 18:20:05 +00:00
Replaces the old lorem-ipsum e-commerce demo with a best-in-class human gallery over the REAL 1,030-app catalog (meta.json), sharing templates.hanzo.ai's machine-readable contract (meta.json + blueprints/ UNTOUCHED — only the human UI changed). - Educational: hero + live app count + a 'How it works' Pick→Deploy→Manage strip + a 'Why Hanzo' (managed / scalable / pay-as-you-go / your own org) section. - Discoverable: fast debounced client-side search (name/desc/id/tags) + 16 data-driven category chips + Load-more, with #q=&tag= URL sync for shareable views + keyboard (/ , Esc). - Quick-launcher: each card's Deploy CTA deep-links the REAL PaaS deploy flow platform.hanzo.ai/templates?deploy=<id> (verified against platform source + a live 200). - Removed the public 'earn 20% compute revenue' claims; fixed a latent CSP bug (inline onerror → DOM-attached). 100% self-contained/CSP-safe (inline SVG icons, data-URI favicon, NO external CDN/font/style), theme-aware (light/dark), responsive (390 mobile → 1680 desktop, no horizontal scroll). Purged the old demo cruft (18 CSS + 11 JS + 30 img + fonts + stubs). Verified headless under the exact prod CSP: cards render (0 violations/0 JS errors), search/ filter/load-more/96-of-96-logos/theme-toggle all work, 390px no-h-scroll. Catalog contract untouched (UI only READS meta.json/blueprints).
37 lines
1.2 KiB
JavaScript
37 lines
1.2 KiB
JavaScript
// Theme bootstrap — applied before first paint (loaded blocking in <head>) so
|
|
// an explicit choice never flashes. With no saved choice the CSS follows the OS
|
|
// via prefers-color-scheme. CSP-safe: same-origin external script, no inline.
|
|
'use strict';
|
|
(function () {
|
|
var KEY = 'hz-theme';
|
|
try {
|
|
var saved = localStorage.getItem(KEY);
|
|
if (saved === 'light' || saved === 'dark') {
|
|
document.documentElement.setAttribute('data-theme', saved);
|
|
}
|
|
} catch (e) { /* private mode / storage blocked — fall back to OS */ }
|
|
|
|
function effective() {
|
|
var set = document.documentElement.getAttribute('data-theme');
|
|
if (set) return set;
|
|
return window.matchMedia && window.matchMedia('(prefers-color-scheme: dark)').matches
|
|
? 'dark' : 'light';
|
|
}
|
|
|
|
function wire() {
|
|
var btn = document.getElementById('theme-toggle');
|
|
if (!btn) return;
|
|
btn.addEventListener('click', function () {
|
|
var next = effective() === 'dark' ? 'light' : 'dark';
|
|
document.documentElement.setAttribute('data-theme', next);
|
|
try { localStorage.setItem(KEY, next); } catch (e) { /* ignore */ }
|
|
});
|
|
}
|
|
|
|
if (document.readyState === 'loading') {
|
|
document.addEventListener('DOMContentLoaded', wire);
|
|
} else {
|
|
wire();
|
|
}
|
|
})();
|