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 GROUPS = ['var(--accent)','var(--viz-4)','var(--viz-5)'];
var N = 11;
var nodes = [];
for (var i=0;i<N;i++) nodes.push({ x:R(0.25,0.75), y:R(0.25,0.75), vx:0, vy:0, g:i%3 });
var EDGES = [[0,1],[0,2],[1,2],[1,3],[3,4],[4,5],[3,5],[5,6],[6,7],[6,8],[7,8],[8,9],[9,10],[2,4],[0,5]];
var restLen = 0.22;
var W=300, H=200;
function measure(){
var r = svg.getBoundingClientRect();
W = Math.max(r.width,10); H = Math.max(r.height,10);
sa(svg,{ viewBox: '0 0 ' + W + ' ' + H });
}
function physics(){
for (var i=0;i<N;i++){
for (var j=i+1;j<N;j++){
var dx=nodes[j].x-nodes[i].x, dy=nodes[j].y-nodes[i].y;
var d2=dx*dx+dy*dy+0.0006;
var d=Math.sqrt(d2);
var f=0.00028/d2;
var fx=dx/d*f, fy=dy/d*f;
nodes[i].vx-=fx; nodes[i].vy-=fy;
nodes[j].vx+=fx; nodes[j].vy+=fy;
}
}
EDGES.forEach(function(e){
var a=nodes[e[0]], b=nodes[e[1]];
var dx=b.x-a.x, dy=b.y-a.y;
var d=Math.sqrt(dx*dx+dy*dy)+0.0006;
var diff=(d-restLen)*0.02;
var fx=dx/d*diff, fy=dy/d*diff;
a.vx+=fx; a.vy+=fy;
b.vx-=fx; b.vy-=fy;
});
nodes.forEach(function(n){
n.vx += (0.5-n.x)*0.004;
n.vy += (0.5-n.y)*0.004;
n.vx*=0.82; n.vy*=0.82;
n.x += n.vx; n.y += n.vy;
n.x = Math.max(0.05,Math.min(0.95,n.x));
n.y = Math.max(0.05,Math.min(0.95,n.y));
});
}
function draw(){
svg.innerHTML = '';
var padL=12, padR=12, padT=12, padB=12;
var pw=W-padL-padR, ph=H-padT-padB;
function X(n){ return padL+n.x*pw; }
function Y(n){ return padT+n.y*ph; }
EDGES.forEach(function(e){
var a=nodes[e[0]], b=nodes[e[1]];
var line = se('line');
sa(line,{x1:X(a),y1:Y(a),x2:X(b),y2:Y(b),class:'edge'});
svg.appendChild(line);
});
nodes.forEach(function(n){
var ring = se('circle');
sa(ring,{cx:X(n),cy:Y(n),r:6.4,class:'ring'});
svg.appendChild(ring);
var dot = se('circle');
sa(dot,{cx:X(n),cy:Y(n),r:4.6,fill:GROUPS[n.g]});
svg.appendChild(dot);
});
}
function loop(){
physics();
draw();
requestAnimationFrame(loop);
}
new ResizeObserver(function(){ measure(); }).observe(svg);
measure();
loop();
setInterval(function(){ restLen = R(0.15,0.3); }, 4200);