Panel rebuilt as the heat matrix: verdict header (ring + newest fault named with its age, cable cell top right), one row per check with NOW / last-90s-at-5s-a-cell / since-reset columns, noise as a blue context lane; history.go keeps the 18-slot wall-time ring (per-class fault deltas, SNR minima, rate verdicts, measuring gray) plus since-reset aggregates and fault ages that clear on reset; noise cycle grid-locked to the shared slot clock so cells never straddle a phase and flicker, presence granted at boot until the first up-phase verdict; check/cross stroked as capsule marks (font has neither), line rate is a pure verdict everywhere, footer is a three-line stat stack beside hold-to-reset; old panel/chip/stat-grid machinery deleted; mockups/ gitignored

This commit is contained in:
flamingcow
2026-08-17 12:22:55 -07:00
parent e3c3f945c5
commit fb4b4596e9
8 changed files with 641 additions and 337 deletions
+26
View File
@@ -432,6 +432,32 @@ func (fb *framebuffer) roundRect(x0, y0, w, h, r int, c rgb) {
fb.rect(x0+w-r, y0+r, r-1, h-2*r, c)
}
// A round-capped stroke between two points, drawn as a capsule: coverage from
// distance to the segment, so marks the font lacks (check, cross) match its
// antialiasing.
func (fb *framebuffer) stroke(x0, y0, x1, y1, t float64, c rgb) {
r := t / 2
minx, maxx := int(math.Floor(math.Min(x0, x1)-r))-1, int(math.Ceil(math.Max(x0, x1)+r))+1
miny, maxy := int(math.Floor(math.Min(y0, y1)-r))-1, int(math.Ceil(math.Max(y0, y1)+r))+1
dx, dy := x1-x0, y1-y0
len2 := dx*dx + dy*dy
for y := miny; y <= maxy; y++ {
for x := minx; x <= maxx; x++ {
px, py := float64(x)-x0, float64(y)-y0
u := 0.0
if len2 > 0 {
u = math.Max(0, math.Min(1, (px*dx+py*dy)/len2))
}
ex, ey := px-u*dx, py-u*dy
cov := r - math.Sqrt(ex*ex+ey*ey) + 0.5
if cov <= 0 {
continue
}
fb.blend(x, y, c, uint8(math.Min(cov, 1)*255))
}
}
}
// Blends src over the existing pixel, with cov as 0-255 coverage.
func (fb *framebuffer) blend(x, y int, c rgb, cov uint8) {
if x < 0 || y < 0 || x >= fb.w || y >= fb.h || cov == 0 {