/* bits.jsx — atomic UI bits: icons, sparkline, etc. */
const Icon = ({ name, size=16, color, style, className, fill }) => {
const s = { width:size, height:size, color:color||'currentColor', flex:'none', ...style };
const P = (paths) => ;
switch(name){
case 'home': return P(<>>);
case 'bolt': return P(<>>);
case 'sun': return P(<>>);
case 'cloudy': return P(<>>);
case 'cloud': return P(<>>);
/* fill 0–1 = laddnivå (Lennie 14/9). Utan fill: gamla fasta fyllningen. Inre
spannet är 4…18 (14 bred); minst 0,6 så en tom cell ändå syns som en strimma. */
case 'battery': {
/* Fyllfärg efter nivå (Lennie 14/9): röd vid tomt, orange runt 40 %, grönt
däröver; mjuk övergång via hue 0 → 30 → 140. Konturen behåller nodens
färg (currentColor). Utan fill: gamla fasta fyllningen. */
const lv = fill == null ? null : Math.max(0, Math.min(1, fill));
const hue = lv == null ? null : lv <= 0.25 ? 30*(lv/0.25) : 30 + 110*Math.min(1, (lv-0.25)/0.25); /* v607: röd 0, orange 25 %, grön från 50 % (André 26/9) */
const fc = lv == null ? 'currentColor' : `hsl(${hue.toFixed(0)} 85% 55%)`;
return P(<>>);
}
case 'car': return P(<>>);
case 'plug': return P(<>>);
case 'flash': return P(<>>);
case 'grid': return P(<>>);
case 'chart': return P(<>>);
case 'gear': return P(<>>);
case 'bell': return P(<>>);
case 'search': return P(<>>);
case 'lightning': return P(<>>);
case 'leaf': return P(<>>);
case 'wallet': return P(<>>);
case 'chevron': return P(<>>);
case 'expand': return P(<>>);
case 'wifi': return P(<>>);
case 'arrowup': return P(<>>);
case 'arrowdown': return P(<>>);
case 'arrowr': return P(<>>);
case 'wind': return P(<>>);
case 'snow': return P(<>>);
case 'eye': return P(<>>);
case 'pause': return P(<>>);
case 'play': return P(<>>);
case 'thermo': return P(<>>);
default: return null;
}
};
/* ---- small sparkline ---- */
const Sparkline = ({ data, width=80, height=24, color="currentColor", area=true, stroke=1.4 }) => {
if (!data || data.length<2) return null;
const min = Math.min(...data), max = Math.max(...data);
const range = (max-min) || 1;
const pts = data.map((v,i)=>{
const x = (i/(data.length-1)) * (width-2) + 1;
const y = height - 2 - ((v-min)/range) * (height-4);
return [x,y];
});
const d = pts.map((p,i)=> (i?'L':'M') + p[0].toFixed(1) + ' ' + p[1].toFixed(1)).join(' ');
const dArea = d + ` L ${(width-1).toFixed(1)} ${(height-1).toFixed(1)} L 1 ${(height-1).toFixed(1)} Z`;
return (
);
};
/* ---- diagonal stripe pattern as inline svg url ---- */
const stripePattern = (color, opacity=1) =>
`url("data:image/svg+xml;utf8,${encodeURIComponent(
``
)}")`;
Object.assign(window, { Icon, Sparkline, stripePattern });