Apply QA: brand-blue buttons, no DNA, theme-aware fireworks and footer
- Buttons return to the brand accent colors (primary fill, accent outline) - Current Ventures shows only the copy beside the portfolio dashboard; the DNA helix and its library are removed - The journey fireworks stage, pins and particles switch to a light palette in light mode - The footer follows the theme instead of staying black Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
+10
-23
@@ -60,20 +60,10 @@
|
||||
sizeCluster();
|
||||
addEventListener('resize', sizeCluster);
|
||||
|
||||
/* ---------- scroll-linked: "still building" rows + playbook word ---------- */
|
||||
const bst = $('#bstack'), rows = bst ? $$('.r', bst) : [], pbSec = $('#playbook'), pbWord = $('#pbword');
|
||||
/* ---------- scroll-linked playbook word ---------- */
|
||||
const pbSec = $('#playbook'), pbWord = $('#pbword');
|
||||
let ticking = false;
|
||||
function onScroll() {
|
||||
if (bst) {
|
||||
const r = bst.getBoundingClientRect();
|
||||
const k = clamp((innerHeight - r.top) / (innerHeight + r.height), 0, 1) - .5;
|
||||
rows.forEach((el, i) => {
|
||||
const dir = i % 2 ? 1 : -1;
|
||||
const op = 1 - Math.abs(i - 2.5) / 3.2;
|
||||
el.style.opacity = clamp(op, .18, 1).toFixed(2);
|
||||
el.style.transform = reduce ? '' : 'translate3d(' + (k * dir * (120 + i * 14)).toFixed(1) + 'px,0,0)';
|
||||
});
|
||||
}
|
||||
if (pbSec && pbWord) {
|
||||
const rp = pbSec.getBoundingClientRect();
|
||||
const kp = clamp((innerHeight - rp.top) / (innerHeight + rp.height), 0, 1);
|
||||
@@ -111,7 +101,9 @@
|
||||
const pinEls = $$('.pn'), jx = $$('.jx'), jfinal = $('#jfinal'), jreplay = $('#jreplay');
|
||||
const cEx = $('#cEx'), cInd = $('#cInd'), cYr = $('#cYr');
|
||||
const PINX = [.12, .31, .5, .69, .88], PINF = [.22, .34, .46, .58, .72], LAUNCH = [200, 950, 1700, 2450, 3300];
|
||||
const COLORS = ['#ffffff', '#9fe6ff', '#1fb7ff', '#3d8bff', '#d6ecff'];
|
||||
const COLORS_DARK = ['#ffffff', '#9fe6ff', '#1fb7ff', '#3d8bff', '#d6ecff'];
|
||||
const COLORS_LIGHT = ['#1a7fff', '#0b5fd0', '#1fb7ff', '#5b6cff', '#0870c4'];
|
||||
const isLight = () => document.documentElement.getAttribute('data-theme') === 'light';
|
||||
let FW = { w: 0, h: 0, floor: 0 }, PH = [0, 0, 0, 0, 0], rockets = [], parts = [], extra = [];
|
||||
let fwState = 'idle', fwStart = 0, fwVis = false, cleared = true, fwLaunched = [false, false, false, false, false], fwPlayed = false;
|
||||
const countUp = (el, to, suf) => {
|
||||
@@ -133,6 +125,7 @@
|
||||
pinEls.forEach((p, i) => { PH[i] = Math.round(FW.h * PINF[i] * .88); p.style.left = (PINX[i] * 100) + '%'; p.style.setProperty('--ph', PH[i] + 'px'); });
|
||||
}
|
||||
function burst(x, y, n, spread) {
|
||||
const COLORS = isLight() ? COLORS_LIGHT : COLORS_DARK;
|
||||
const base = COLORS[(Math.random() * COLORS.length) | 0], sp = spread || 1;
|
||||
for (let i = 0; i < n; i++) {
|
||||
const a = Math.random() * Math.PI * 2, v = (50 + Math.random() * 190) * sp;
|
||||
@@ -188,12 +181,13 @@
|
||||
cleared = false;
|
||||
if (fwState === 'play') { const el = now - fwStart; LAUNCH.forEach((t, i) => { if (!fwLaunched[i] && el >= t) { fwLaunched[i] = true; launch(i); } }); }
|
||||
if (extra.length) { extra.forEach((e) => { e.t -= dt; }); extra = extra.filter((e) => { if (e.t <= 0) { burst(e.x * FW.w, e.y * FW.h, 70, 1.1); return false; } return true; }); }
|
||||
fx.clearRect(0, 0, FW.w, FW.h); fx.globalCompositeOperation = 'lighter'; fx.lineCap = 'round';
|
||||
const light = isLight();
|
||||
fx.clearRect(0, 0, FW.w, FW.h); fx.globalCompositeOperation = light ? 'source-over' : 'lighter'; fx.lineCap = 'round';
|
||||
rockets = rockets.filter((r) => {
|
||||
r.t += dt; const k = Math.min(1, r.t / r.dur), e = 1 - Math.pow(1 - k, 3); r.y = lerp(FW.floor, r.ty, e);
|
||||
r.trail.push({ x: r.x + (Math.random() - .5) * 1.5, y: r.y }); if (r.trail.length > 14) r.trail.shift();
|
||||
for (let j = 1; j < r.trail.length; j++) { const a = j / r.trail.length; fx.strokeStyle = 'rgba(159,230,255,' + (a * .8) + ')'; fx.lineWidth = 2.4 * a; fx.beginPath(); fx.moveTo(r.trail[j - 1].x, r.trail[j - 1].y); fx.lineTo(r.trail[j].x, r.trail[j].y); fx.stroke(); }
|
||||
fx.fillStyle = '#fff'; fx.beginPath(); fx.arc(r.x, r.y, 2.6, 0, 6.283); fx.fill();
|
||||
for (let j = 1; j < r.trail.length; j++) { const a = j / r.trail.length; fx.strokeStyle = (light ? 'rgba(26,127,255,' : 'rgba(159,230,255,') + (a * .8) + ')'; fx.lineWidth = 2.4 * a; fx.beginPath(); fx.moveTo(r.trail[j - 1].x, r.trail[j - 1].y); fx.lineTo(r.trail[j].x, r.trail[j].y); fx.stroke(); }
|
||||
fx.fillStyle = light ? '#0b5fd0' : '#fff'; fx.beginPath(); fx.arc(r.x, r.y, 2.6, 0, 6.283); fx.fill();
|
||||
if (k >= 1) { arrive(r.i); return false; } return true;
|
||||
});
|
||||
parts = parts.filter((p) => {
|
||||
@@ -207,13 +201,6 @@
|
||||
fx.globalAlpha = 1; fx.globalCompositeOperation = 'source-over';
|
||||
}
|
||||
|
||||
/* ---------- 3D DNA: fall back to the still image without WebGL ---------- */
|
||||
setTimeout(() => {
|
||||
const dna = $('#dna'), fb = $('#dnaFallback');
|
||||
const ok = dna && dna.shadowRoot && dna.shadowRoot.querySelector('canvas');
|
||||
if (!ok && fb) { if (dna) dna.hidden = true; fb.hidden = false; }
|
||||
}, 1500);
|
||||
|
||||
/* ---------- main loop ---------- */
|
||||
let last = performance.now();
|
||||
(function loop(now) {
|
||||
|
||||
Reference in New Issue
Block a user