body{display:block}
.viz{display:flex;flex-direction:column;width:100%;height:100%}
svg{flex:1;min-height:0;display:block;width:100%;overflow:visible}
.scale{flex:none;display:flex;align-items:center;justify-content:center;gap:6px;padding:2px 4px 4px;font:600 9px/1 system-ui,sans-serif;color:var(--muted)}
.scale i{width:56px;height:7px;border-radius:4px;background:linear-gradient(90deg, color-mix(in srgb, var(--accent) 10%, var(--surface)), var(--accent))}
.hex{transition:fill .6s ease}
var svg = document.getElementById('svg');
var NS = 'http://www.w3.org/2000/svg';
function se(t){ return document.createElementNS(NS,t); }
function sa(e,o){ for (var k in o) e.setAttribute(k,o[k]); }
function R(a,b){ return a + Math.random()*(b-a); }
var COLS=8, ROWS=5;
var cells = [];
for (var r=0;r<ROWS;r++) for (var c=0;c<COLS;c++) cells.push({ r:r, c:c, v:R(10,90) });
var W=300, H=200;
var polys = [];
function measure(){
var rc = svg.getBoundingClientRect();
W = Math.max(rc.width,10); H = Math.max(rc.height,10);
sa(svg,{ viewBox: '0 0 ' + W + ' ' + H });
}
function hexPoints(cx,cy,r){
var pts = [];
for (var i=0;i<6;i++){ var a = Math.PI/180*(60*i); pts.push((cx+r*Math.cos(a)).toFixed(1)+','+(cy+r*Math.sin(a)).toFixed(1)); }
return pts.join(' ');
}
function build(){
svg.innerHTML = '';
polys = [];
var padL=10, padR=10, padT=8, padB=8;
var pw=W-padL-padR, ph=H-padT-padB;
var hrW = pw/(1.5*COLS+0.5);
var hrH = ph/(Math.sqrt(3)*(ROWS+0.5));
var hr = Math.max(4, Math.min(hrW,hrH));
var gridW = hr*(1.5*COLS+0.5);
var gridH = Math.sqrt(3)*hr*(ROWS+0.5);
var offX = padL+(pw-gridW)/2+hr;
var offY = padT+(ph-gridH)/2+hr*Math.sqrt(3)/2;
cells.forEach(function(cell){
var cx = offX+cell.c*1.5*hr;
var cy = offY+cell.r*Math.sqrt(3)*hr + (cell.c%2 ? Math.sqrt(3)*hr/2 : 0);
var poly = se('polygon');
sa(poly,{ points: hexPoints(cx,cy,hr*0.92), class:'hex' });
svg.appendChild(poly);
polys.push({ el:poly, cell:cell });
});
paint();
}
function paint(){
polys.forEach(function(p){
var pct = Math.max(6, Math.min(96, p.cell.v));
p.el.setAttribute('fill', 'color-mix(in srgb, var(--accent) ' + pct + '%, var(--surface))');
});
}
new ResizeObserver(function(){ measure(); build(); }).observe(svg);
measure();
build();
setInterval(function(){
cells.forEach(function(cell){ cell.v = R(8,92); });
paint();
}, 2900);