30×20 cells with per-cell simplex delay and HSL hue drift.
<!doctype html>
<!-- Example: melt-pixelate — 30×20 grid · simplex delay · HSL drift · scanline scroll -->
<html data-duration="4" data-aspect="16:9"><head><style>
:root {
--cream:#f6f5f1; --cream-2:#efece4; --ink:#0a0a0a; --mute:#6b6862;
--line:#e3dfd3; --signal:#ff3b1f; --signal-2:#ff6a4a; --frame:#ffb800;
--green:#1f8a5b; --blue:#2b66ff;
}
* { box-sizing: border-box; }
body { margin:0; }
body { background: #0a0a0a; height: 100vh; overflow: hidden;
display: grid; place-items: center; position: relative; }
.grid { width: 720px; height: 460px; display: grid;
grid-template-columns: repeat(30, 1fr); grid-template-rows: repeat(20, 1fr); gap: 1px;
position: relative; }
.grid > i { display: block; transform-origin: center;
will-change: transform, opacity, filter; }
.scan { position: absolute; inset: 0; pointer-events: none;
background: repeating-linear-gradient(0deg, rgba(255,255,255,.04) 0 1px, transparent 1px 4px);
mix-blend-mode: overlay; will-change: background-position; }
.label { position: absolute; top: 36px; left: 0; right: 0; text-align: center;
color: rgba(255,255,255,.55); font-family: ui-monospace, monospace;
font-size: 11px; letter-spacing: .25em; }
</style></head><body>
<div class="label">● MELT · PIXEL · 30×20</div>
<div class="grid" id="g"></div>
<div class="scan" id="sc"></div>
<script>
var g = document.getElementById('g');
var sc = document.getElementById('sc');
var COLS = 30, ROWS = 20;
var cells = [];
for (var r = 0; r < ROWS; r++) {
for (var c = 0; c < COLS; c++) {
var i = document.createElement('i');
var dx = (c - COLS / 2) / COLS, dy = (r - ROWS / 2) / ROWS;
var d = Math.sqrt(dx * dx + dy * dy);
// Smiley-like initial colorization to give the melt something to chew on.
var hue = d < 0.28 ? 38 : (d < 0.42 ? 14 : 6);
i.style.background = 'hsl(' + hue + ', 95%, 55%)';
g.appendChild(i);
cells.push({ el: i, c: c, r: r, d: d, hue: hue });
}
}
var t = 0;
var reduced = matchMedia('(prefers-reduced-motion: reduce)').matches;
// Pseudo-simplex noise: stacked sines over a hashed cell coordinate.
function snoise(c, r) {
var k = (c * 374.761) + (r * 271.337);
return 0.5 + 0.5 * (Math.sin(k * 0.013) * 0.6 + Math.sin(k * 0.029 + 1.7) * 0.4);
}
function render() {
var tt = reduced ? 4 : t;
cells.forEach(function(o) {
var delay = snoise(o.c, o.r) * 1.5;
var u = Math.max(0, Math.min(1, (tt - 1 - delay) / 2.2));
o.el.style.transform = 'translateY(' + (u * 760).toFixed(1) + 'px) scale(' + (1 - u * 0.5).toFixed(2) + ')';
o.el.style.opacity = (1 - u).toString();
// HSL hue drift during the melt phase.
var hue = o.hue + (1 - Math.abs(u - 0.5) * 2) * 40;
o.el.style.background = 'hsl(' + hue.toFixed(0) + ', 95%, ' + (55 - u * 20).toFixed(0) + '%)';
});
sc.style.backgroundPosition = '0 ' + (tt * 80).toFixed(0) + 'px';
}
addEventListener('hf-seek', function(e) { t = e.detail.time; render(); });
render();
</script>
</body></html>