08e80d9f9f
The face of learn.bztmon.com is now a chapter index: 01 The Exploded Cluster (moved to /cluster) and 02 The Mirror (/mirror), with a forming-chapter ghost slot. The Mirror ships rev 3 of the dossier - six curated plates fingerprinted under /assets/, its scroll engine as an external fingerprinted script (CSP script-src self holds), diagrams as inline SVG, replay panes from real receipts. Assembler grows a shared document shell + per-page preflight gates; build.sh inline-script check now covers every page.
40 lines
1.8 KiB
JavaScript
40 lines
1.8 KiB
JavaScript
(function(){
|
|
var rm = matchMedia('(prefers-reduced-motion: reduce)').matches;
|
|
var bar = document.getElementById('bar');
|
|
var s20 = document.querySelector('#s20 img');
|
|
var ring = document.getElementById('ring');
|
|
var glows = [].slice.call(document.querySelectorAll('.s22-glow'));
|
|
var s24 = document.querySelector('#s24 img');
|
|
function prog(el){
|
|
var r = el.getBoundingClientRect(), vh = innerHeight;
|
|
return Math.max(0, Math.min(1, (vh - r.top) / (vh + r.height)));
|
|
}
|
|
function onScroll(){
|
|
var d = document.documentElement;
|
|
bar.style.width = (100 * d.scrollTop / (d.scrollHeight - innerHeight)) + '%';
|
|
if (rm) return;
|
|
var p20 = prog(s20); /* dock-and-stow: assembles inward */
|
|
s20.style.transform = 'scale(' + (1.07 - 0.07 * Math.min(1, p20 * 1.6)) + ') translateY(' + (26 - 26 * Math.min(1, p20 * 1.6)) + 'px)';
|
|
var p21 = prog(ring); /* ring-walk: the cycle turns */
|
|
ring.style.transform = 'rotate(' + (p21 * 300) + 'deg)';
|
|
glows.forEach(function(g, i){ /* checkpoint procession: three beats */
|
|
var p = prog(g.parentElement);
|
|
var band = 0.18 + i * 0.22;
|
|
g.style.opacity = Math.max(0, Math.min(0.85, (p - band) * 6));
|
|
});
|
|
var p24 = prog(s24); /* two-plane parallax */
|
|
s24.style.transform = 'translateY(' + ((p24 - 0.5) * -26) + 'px) scale(1.03)';
|
|
}
|
|
addEventListener('scroll', onScroll, {passive: true});
|
|
addEventListener('resize', onScroll);
|
|
onScroll();
|
|
if (!rm){ /* the jam breathes; nothing else does */
|
|
var pulse = document.getElementById('pulse'), t0 = null;
|
|
requestAnimationFrame(function breathe(t){
|
|
if (t0 === null) t0 = t;
|
|
pulse.style.opacity = 0.18 + 0.2 * (0.5 + 0.5 * Math.sin((t - t0) / 520));
|
|
requestAnimationFrame(breathe);
|
|
});
|
|
}
|
|
})();
|