Humuhumu33 commited on
Commit ·
77b0c39
1
Parent(s): 5283e29
hologram hardened (WebGL smoke test + CSS holographic fallback + click pulse + inner shell), 27B background warm-up at landing, scrollbar chrome removed
Browse files- index.html +55 -4
index.html
CHANGED
|
@@ -44,7 +44,9 @@
|
|
| 44 |
#hello h2 { display:inline; font-family:var(--serif); font-weight:500; font-size:clamp(30px,4.4vw,44px); letter-spacing:-.01em; }
|
| 45 |
.col.started #hello { display:none; }
|
| 46 |
#log { display:none; }
|
| 47 |
-
.col.started #log { display:block; flex:1; overflow-y:auto; padding:30px 4px 16px;
|
|
|
|
|
|
|
| 48 |
.msg { margin:0 0 20px; }
|
| 49 |
.msg .who { font-size:15px; color:var(--faint); margin-bottom:4px; }
|
| 50 |
.msg.user .who { color:var(--muted); }
|
|
@@ -70,11 +72,29 @@
|
|
| 70 |
#err { color:#f87171; font-size:15px; padding:0 0 18px; text-align:center; white-space:pre-wrap; }
|
| 71 |
.spn { display:inline-block; width:1.1ch; font-family:ui-monospace,SFMono-Regular,Menlo,Consolas,monospace;
|
| 72 |
color:var(--coral-hi); margin-right:7px; }
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 73 |
</style>
|
| 74 |
<body>
|
| 75 |
|
| 76 |
<div class="stage on" id="arrive">
|
| 77 |
<canvas id="holo"></canvas>
|
|
|
|
| 78 |
<div class="copy">
|
| 79 |
<h1>An AI<br>that’s yours.</h1>
|
| 80 |
<p class="sub">Bonsai streams into your browser like a film. Every piece is checked before it runs. After one visit it answers on your device, even offline.</p>
|
|
@@ -119,6 +139,7 @@ try {
|
|
| 119 |
if (!document.getElementById("arrive").classList.contains("on")) throw new Error("past landing");
|
| 120 |
const THREE = await import("./vendor/three.module.min.js");
|
| 121 |
const renderer = new THREE.WebGLRenderer({ canvas: cv, antialias: true, alpha: true, powerPreference: "high-performance" });
|
|
|
|
| 122 |
renderer.setPixelRatio(Math.min(devicePixelRatio || 1, 2));
|
| 123 |
const scene = new THREE.Scene();
|
| 124 |
const cam = new THREE.PerspectiveCamera(45, 1, 0.1, 30); cam.position.z = 5;
|
|
@@ -158,9 +179,12 @@ try {
|
|
| 158 |
}`,
|
| 159 |
});
|
| 160 |
const mesh = new THREE.Mesh(new THREE.IcosahedronGeometry(1.35, 12), mat);
|
|
|
|
|
|
|
| 161 |
scene.add(mesh);
|
|
|
|
| 162 |
// pointer parallax: mesh tilts toward the cursor (eased); stripes speed up when the cursor is near.
|
| 163 |
-
let tx = 0, ty = 0, rx = 0, ry = 0, boost = 0, tBoost = 0;
|
| 164 |
if (!reduced) addEventListener("pointermove", (e) => {
|
| 165 |
const nx = e.clientX / innerWidth * 2 - 1, ny = e.clientY / innerHeight * 2 - 1;
|
| 166 |
tx = nx * 0.45; ty = ny * 0.35;
|
|
@@ -180,7 +204,9 @@ try {
|
|
| 180 |
const t = performance.now() / 1000;
|
| 181 |
uni.uTime.value = t;
|
| 182 |
boost += (tBoost - boost) * 0.06;
|
| 183 |
-
|
|
|
|
|
|
|
| 184 |
rx += (ty - rx) * 0.05; ry += (tx - ry) * 0.05; // eased parallax
|
| 185 |
mesh.rotation.x = rx * 0.6; mesh.rotation.y = t * 0.12 + ry; // + constant slow spin
|
| 186 |
renderer.render(scene, cam);
|
|
@@ -200,7 +226,12 @@ try {
|
|
| 200 |
try { renderer.getContext().getExtension("WEBGL_lose_context").loseContext(); } catch {}
|
| 201 |
cv.remove();
|
| 202 |
};
|
| 203 |
-
} catch {
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 204 |
</script>
|
| 205 |
|
| 206 |
<script type="module">
|
|
@@ -399,6 +430,26 @@ $("go").addEventListener("click", () => {
|
|
| 399 |
if (!streamStarted) { streamStarted = true; stream(); }
|
| 400 |
});
|
| 401 |
$("send").disabled = true; // until the mind is resident (early questions queue)
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 402 |
(async () => { // returning visitor: the mind wakes BEHIND the welcome screen
|
| 403 |
try { const c = await caches.open("holo-kappa-v1"); if (await c.match(BASE + "/manifest.json")) { streamStarted = true; stream(); } } catch {}
|
| 404 |
})();
|
|
|
|
| 44 |
#hello h2 { display:inline; font-family:var(--serif); font-weight:500; font-size:clamp(30px,4.4vw,44px); letter-spacing:-.01em; }
|
| 45 |
.col.started #hello { display:none; }
|
| 46 |
#log { display:none; }
|
| 47 |
+
.col.started #log { display:block; flex:1; overflow-y:auto; padding:30px 4px 16px;
|
| 48 |
+
scrollbar-width:none; -ms-overflow-style:none; } /* the content scrolls; no chrome */
|
| 49 |
+
#log::-webkit-scrollbar { width:0; height:0; }
|
| 50 |
.msg { margin:0 0 20px; }
|
| 51 |
.msg .who { font-size:15px; color:var(--faint); margin-bottom:4px; }
|
| 52 |
.msg.user .who { color:var(--muted); }
|
|
|
|
| 72 |
#err { color:#f87171; font-size:15px; padding:0 0 18px; text-align:center; white-space:pre-wrap; }
|
| 73 |
.spn { display:inline-block; width:1.1ch; font-family:ui-monospace,SFMono-Regular,Menlo,Consolas,monospace;
|
| 74 |
color:var(--coral-hi); margin-right:7px; }
|
| 75 |
+
/* CSS hologram (fallback when WebGL is unavailable/blocked): layered orb + scanlines + drift */
|
| 76 |
+
#holofb { position:absolute; width:min(46vw,520px); aspect-ratio:1; right:4vw; top:50%;
|
| 77 |
+
transform:translateY(-50%); border-radius:50%; pointer-events:none;
|
| 78 |
+
background:radial-gradient(circle at 38% 34%, rgba(232,152,122,.55), rgba(217,119,87,.28) 42%, rgba(196,181,253,.16) 72%, transparent 76%);
|
| 79 |
+
box-shadow:0 0 90px rgba(217,119,87,.25), inset 0 0 60px rgba(196,181,253,.18);
|
| 80 |
+
animation:holofloat 7s ease-in-out infinite; }
|
| 81 |
+
#holofb::before { content:""; position:absolute; inset:0; border-radius:50%;
|
| 82 |
+
background:repeating-linear-gradient(to bottom, rgba(255,255,255,.09) 0 2px, transparent 2px 7px);
|
| 83 |
+
mix-blend-mode:screen; animation:holoscan 2.6s linear infinite;
|
| 84 |
+
-webkit-mask:radial-gradient(circle, #000 70%, transparent 74%); mask:radial-gradient(circle, #000 70%, transparent 74%); }
|
| 85 |
+
#holofb::after { content:""; position:absolute; inset:-2%; border-radius:50%;
|
| 86 |
+
border:1px solid rgba(196,181,253,.30); filter:blur(.4px); }
|
| 87 |
+
@keyframes holofloat { 50% { transform:translateY(calc(-50% - 14px)); } }
|
| 88 |
+
@keyframes holoscan { to { background-position:0 7px; } }
|
| 89 |
+
@media (max-width:760px){ #holofb { right:50%; top:26%; transform:translate(50%,-50%); width:min(62vw,300px); }
|
| 90 |
+
@keyframes holofloat { 50% { transform:translate(50%,calc(-50% - 10px)); } } }
|
| 91 |
+
@media (prefers-reduced-motion: reduce){ #holofb, #holofb::before { animation:none; } }
|
| 92 |
</style>
|
| 93 |
<body>
|
| 94 |
|
| 95 |
<div class="stage on" id="arrive">
|
| 96 |
<canvas id="holo"></canvas>
|
| 97 |
+
<div id="holofb" hidden></div>
|
| 98 |
<div class="copy">
|
| 99 |
<h1>An AI<br>that’s yours.</h1>
|
| 100 |
<p class="sub">Bonsai streams into your browser like a film. Every piece is checked before it runs. After one visit it answers on your device, even offline.</p>
|
|
|
|
| 139 |
if (!document.getElementById("arrive").classList.contains("on")) throw new Error("past landing");
|
| 140 |
const THREE = await import("./vendor/three.module.min.js");
|
| 141 |
const renderer = new THREE.WebGLRenderer({ canvas: cv, antialias: true, alpha: true, powerPreference: "high-performance" });
|
| 142 |
+
if (!renderer.getContext() || renderer.getContext().isContextLost()) throw new Error("webgl unavailable");
|
| 143 |
renderer.setPixelRatio(Math.min(devicePixelRatio || 1, 2));
|
| 144 |
const scene = new THREE.Scene();
|
| 145 |
const cam = new THREE.PerspectiveCamera(45, 1, 0.1, 30); cam.position.z = 5;
|
|
|
|
| 179 |
}`,
|
| 180 |
});
|
| 181 |
const mesh = new THREE.Mesh(new THREE.IcosahedronGeometry(1.35, 12), mat);
|
| 182 |
+
const core = new THREE.Mesh(new THREE.IcosahedronGeometry(0.92, 8), mat); // inner shell: same material, real depth
|
| 183 |
+
mesh.add(core);
|
| 184 |
scene.add(mesh);
|
| 185 |
+
addEventListener("pointerdown", () => { tPulse = performance.now(); }, { passive: true }); // click: the hologram answers back
|
| 186 |
// pointer parallax: mesh tilts toward the cursor (eased); stripes speed up when the cursor is near.
|
| 187 |
+
let tx = 0, ty = 0, rx = 0, ry = 0, boost = 0, tBoost = 0, tPulse = -9e9;
|
| 188 |
if (!reduced) addEventListener("pointermove", (e) => {
|
| 189 |
const nx = e.clientX / innerWidth * 2 - 1, ny = e.clientY / innerHeight * 2 - 1;
|
| 190 |
tx = nx * 0.45; ty = ny * 0.35;
|
|
|
|
| 204 |
const t = performance.now() / 1000;
|
| 205 |
uni.uTime.value = t;
|
| 206 |
boost += (tBoost - boost) * 0.06;
|
| 207 |
+
const pulse = Math.max(0, 1 - (performance.now() - tPulse) / 700); // click pulse decays over 0.7s
|
| 208 |
+
uni.uSpeed.value = 0.35 + boost * 1.1 + pulse * 2.4;
|
| 209 |
+
uni.uGlitch.value = reduced ? 0 : 1 + pulse * 2.0;
|
| 210 |
rx += (ty - rx) * 0.05; ry += (tx - ry) * 0.05; // eased parallax
|
| 211 |
mesh.rotation.x = rx * 0.6; mesh.rotation.y = t * 0.12 + ry; // + constant slow spin
|
| 212 |
renderer.render(scene, cam);
|
|
|
|
| 226 |
try { renderer.getContext().getExtension("WEBGL_lose_context").loseContext(); } catch {}
|
| 227 |
cv.remove();
|
| 228 |
};
|
| 229 |
+
} catch (e) { // no WebGL (Brave shields, GPU-less) / past landing
|
| 230 |
+
if (document.getElementById("arrive").classList.contains("on")) {
|
| 231 |
+
try { cv.remove(); } catch {}
|
| 232 |
+
const fb = document.getElementById("holofb"); if (fb) fb.hidden = false; // the CSS hologram stands in
|
| 233 |
+
}
|
| 234 |
+
}
|
| 235 |
</script>
|
| 236 |
|
| 237 |
<script type="module">
|
|
|
|
| 430 |
if (!streamStarted) { streamStarted = true; stream(); }
|
| 431 |
});
|
| 432 |
$("send").disabled = true; // until the mind is resident (early questions queue)
|
| 433 |
+
(async () => {
|
| 434 |
+
try {
|
| 435 |
+
if (navigator.connection && navigator.connection.saveData) return; // respect data saver
|
| 436 |
+
if (SRC) return; // dev override: no background pulls
|
| 437 |
+
const B27 = "https://huggingface.co/HOLOGRAMTECH/q-bonsai-27b/resolve/main";
|
| 438 |
+
const cache = await caches.open("holo-kappa-v1");
|
| 439 |
+
const man = await (await fetch(B27 + "/manifest.json")).json();
|
| 440 |
+
const urls = Object.values(man.tensors || {}).map((r) => B27 + "/b/" + String(r.kappa).replace(":", "_") + ".gz");
|
| 441 |
+
let i = 0;
|
| 442 |
+
const worker = async () => {
|
| 443 |
+
while (i < urls.length) {
|
| 444 |
+
const u = urls[i++];
|
| 445 |
+
if (await cache.match(u)) continue;
|
| 446 |
+
while (streamStarted && !ready) await new Promise((r) => setTimeout(r, 1500)); // the live stream owns the wire
|
| 447 |
+
try { const b = await (await fetch(u, { cache: "no-store" })).arrayBuffer(); await cache.put(u, new Response(b, { headers: { "Content-Type": "application/octet-stream" } })); } catch {}
|
| 448 |
+
}
|
| 449 |
+
};
|
| 450 |
+
Promise.all(Array.from({ length: 3 }, worker)).catch(() => {});
|
| 451 |
+
} catch {}
|
| 452 |
+
})();
|
| 453 |
(async () => { // returning visitor: the mind wakes BEHIND the welcome screen
|
| 454 |
try { const c = await caches.open("holo-kappa-v1"); if (await c.match(BASE + "/manifest.json")) { streamStarted = true; stream(); } } catch {}
|
| 455 |
})();
|