Monorepo for Aesthetic.Computer aesthetic.computer
4
fork

Configure Feed

Select the types of activity you want to include in your feed.

notepat-remote: true full-fill + 2px gray divider

Grid now fills H precisely — vertical remainder is absorbed row-by-row
(rowHeights array) instead of leaving a few dead pixels at the bottom.
Octave divider drops to 2px of flat gray between the base and +1
octave blocks — subtle seam rather than a chunky bar.

+22 -25
+22 -25
system/public/aesthetic.computer/disks/notepat-remote.mjs
··· 481 481 // BAR_BORDER so it reads as a seam, not a void. 482 482 const cols = 4; 483 483 const rows = 6; 484 - const octaveGap = 4; 485 - // Per-axis cell size (no longer forced square — "no margins" wins 486 - // over "perfect squares" at this aspect ratio). 487 - const cellW = floor(W / cols); 488 - const cellH = floor((H - octaveGap) / rows); 489 - // colEdges distributed so the 4 columns exactly span W (last cell 490 - // absorbs any rounding remainder). 484 + const octaveGap = 2; 485 + // colEdges span W exactly (last cell absorbs any horizontal 486 + // rounding remainder). 491 487 const colEdges = []; 492 488 for (let c = 0; c <= cols; c += 1) colEdges.push(floor((c * W) / cols)); 493 - // rowEdges[r] is the top of row r; the octave gap sits between rows 494 - // 2 and 3, adding octaveGap px before row 3's top. 495 - const rowEdges = []; 496 - for (let r = 0; r <= rows; r += 1) { 497 - const gapBefore = r >= 3 ? octaveGap : 0; 498 - rowEdges.push(r * cellH + gapBefore); 489 + // rowHeights distribute the available vertical space evenly and 490 + // absorb the leftover px into the first few rows so the grid ends 491 + // flush with H — otherwise we'd leave a few dead pixels at the 492 + // bottom edge. Octave gap is inserted between row 2 and row 3. 493 + const avail = H - octaveGap; 494 + const rowBase = floor(avail / rows); 495 + const rowRem = avail - rowBase * rows; 496 + const rowHeights = []; 497 + for (let r = 0; r < rows; r += 1) rowHeights.push(rowBase + (r < rowRem ? 1 : 0)); 498 + const rowEdges = [0]; 499 + for (let r = 0; r < rows; r += 1) { 500 + const gap = r === 3 ? octaveGap : 0; 501 + rowEdges.push(rowEdges[r] + rowHeights[r] + gap); 499 502 } 500 503 501 504 buttons = []; ··· 516 519 const x0 = colEdges[globalCol]; 517 520 const x1 = colEdges[globalCol + 1]; 518 521 const y0 = rowEdges[globalRow]; 519 - // Pads are cellH tall regardless of the octave-gap between rows 520 - // 2 and 3; using rowEdges[r+1] would swell row 2 to include the 521 - // divider strip. 522 - const b = { x: x0, y: y0, w: x1 - x0, h: cellH, key, pitch }; 522 + // rowHeights absorbs the vertical rounding remainder so the 523 + // grid fills H precisely without dead pixels at the bottom. 524 + const b = { x: x0, y: y0, w: x1 - x0, h: rowHeights[globalRow], key, pitch }; 523 525 buttons.push(b); 524 526 525 527 const held = ··· 644 646 } 645 647 } 646 648 647 - // ── Octave divider bar ────────────────────────────────────────── 648 - // Full-width horizontal strip between the base octave block 649 - // (rows 0-2) and the +1 octave block (rows 3-5). Uses BAR_BG fill + 650 - // BAR_BORDER edges so it reads as a hard seam across the device. 649 + // ── Octave divider: 2px gray horizontal bar between blocks ─────── 651 650 if (focused) { 652 - const barY = 3 * cellH; 653 - ink(...BAR_BG).box(0, barY, W, octaveGap, "fill"); 654 - ink(...BAR_BORDER).line(0, barY, W - 1, barY); 655 - ink(...BAR_BORDER).line(0, barY + octaveGap - 1, W - 1, barY + octaveGap - 1); 651 + const barY = rowEdges[3] - octaveGap; 652 + ink(100, 100, 110).box(0, barY, W, octaveGap, "fill"); 656 653 } 657 654 658 655 // ── Unfocused overlay: big red X spanning the device ─────────────────
system/public/m4l/notepat.com.amxd

This is a binary file and will not be displayed.