Rate monitor: call embers rise off the bars in proportion to real traffic
1-3 tiny accent sparks per socket update drift up from each bar's fill tip, scaled by the real (unclamped) rate — motion strictly means API calls are happening right now. Self-removing DOM nodes with a per-bar live cap of 6, suppressed during cooldown and under reduced-effects mode. The taste-risk one of the set: revert this commit alone if it reads as noise.
This commit is contained in:
parent
7efb5da893
commit
1ad3dac222
2 changed files with 45 additions and 0 deletions
|
|
@ -383,6 +383,14 @@ function _renderEqualizerBars(grid, data) {
|
||||||
}
|
}
|
||||||
bar.classList.toggle('cooldown', cooling);
|
bar.classList.toggle('cooldown', cooling);
|
||||||
|
|
||||||
|
// Call embers: tiny accent sparks rise off the fill tip, spawned per
|
||||||
|
// socket update in proportion to REAL traffic — motion strictly means
|
||||||
|
// API calls are happening right now. Suppressed during cooldown and
|
||||||
|
// under reduced-effects.
|
||||||
|
if (!window._reduceEffectsActive && !cooling && realPct > 0.03) {
|
||||||
|
_spawnEmbers(bar, pct, realPct > 0.6 ? 3 : realPct > 0.25 ? 2 : 1);
|
||||||
|
}
|
||||||
|
|
||||||
// Daily-budget ring (Spotify is the only service with a real daily
|
// Daily-budget ring (Spotify is the only service with a real daily
|
||||||
// cap): a conic rim inside the avatar disc fills as the budget is
|
// cap): a conic rim inside the avatar disc fills as the budget is
|
||||||
// spent — green → amber → red, purple once the worker has bridged
|
// spent — green → amber → red, purple once the worker has bridged
|
||||||
|
|
@ -409,6 +417,23 @@ function _renderEqualizerBars(grid, data) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Spawn ember particles at a bar's fill tip. Self-removing DOM sparks with
|
||||||
|
// a per-bar live cap so a busy hour can't accumulate nodes.
|
||||||
|
function _spawnEmbers(bar, pct, count) {
|
||||||
|
const track = bar.querySelector('.rate-eq-track');
|
||||||
|
if (!track || track.querySelectorAll('.rate-eq-ember').length > 6) return;
|
||||||
|
for (let i = 0; i < count; i++) {
|
||||||
|
const e = document.createElement('span');
|
||||||
|
e.className = 'rate-eq-ember';
|
||||||
|
e.style.left = `${20 + Math.random() * 60}%`;
|
||||||
|
e.style.bottom = `${Math.min(96, pct * 100)}%`;
|
||||||
|
e.style.setProperty('--ember-drift', `${(Math.random() - 0.5) * 14}px`);
|
||||||
|
e.style.animationDuration = `${1.1 + Math.random() * 0.7}s`;
|
||||||
|
e.addEventListener('animationend', () => e.remove());
|
||||||
|
track.appendChild(e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// Animate a single integer counter from `from` to `to` with an
|
// Animate a single integer counter from `from` to `to` with an
|
||||||
// easeOutCubic curve. Used by the equalizer bars so the live count
|
// easeOutCubic curve. Used by the equalizer bars so the live count
|
||||||
// digit-rolls instead of snapping when sockets push a new value.
|
// digit-rolls instead of snapping when sockets push a new value.
|
||||||
|
|
|
||||||
|
|
@ -63340,6 +63340,26 @@ body.reduce-effects .dash-card::after {
|
||||||
text-shadow: 0 0 8px rgba(239, 68, 68, 0.8);
|
text-shadow: 0 0 8px rgba(239, 68, 68, 0.8);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Call embers — tiny accent sparks rising off the fill tip, spawned per
|
||||||
|
* socket update in proportion to real traffic. Motion == actual API calls. */
|
||||||
|
.rate-eq-ember {
|
||||||
|
position: absolute;
|
||||||
|
width: 3px;
|
||||||
|
height: 3px;
|
||||||
|
border-radius: 50%;
|
||||||
|
background: color-mix(in srgb, var(--eq-accent) 60%, white 40%);
|
||||||
|
box-shadow: 0 0 6px var(--eq-accent);
|
||||||
|
pointer-events: none;
|
||||||
|
animation: rate-eq-ember-rise 1.4s ease-out forwards;
|
||||||
|
z-index: 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
@keyframes rate-eq-ember-rise {
|
||||||
|
0% { opacity: 0; transform: translate(0, 0) scale(1); }
|
||||||
|
15% { opacity: 0.9; }
|
||||||
|
100% { opacity: 0; transform: translate(var(--ember-drift, 0px), -26px) scale(0.4); }
|
||||||
|
}
|
||||||
|
|
||||||
/* Recovery flash — the moment a ban expires the track blinks back alive */
|
/* Recovery flash — the moment a ban expires the track blinks back alive */
|
||||||
.rate-eq.recovered .rate-eq-track {
|
.rate-eq.recovered .rate-eq-track {
|
||||||
animation: rate-eq-recovered 1.2s ease-out;
|
animation: rate-eq-recovered 1.2s ease-out;
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue