feat: masonry board and fact grids, full-bleed width, contradicted hidden by default - #7
Merged
Merged
Conversation
…default The fixed 1320px column wasted horizontal space on wide displays and the auto-fit grid stretched every card in a row to the tallest one, leaving ragged whitespace under short events. - main goes full-bleed with fluid gutters instead of a capped column - feed becomes true masonry: 1px auto-rows plus a per-card row span, so cards pack by their own height. Row spacing is the child margin, not row-gap, because a row-gap is charged per 1px row and would coarsen the quantization. - every #feed mutation now goes through setFeed(), which assigns the row span. A node added without one collapses to 1px and paints over the footer, so the chokepoint is load-bearing, not tidiness. - contradicted events drop off the board unless their pill is selected. The pill still carries the true count, so hidden never reads as gone. Card minimum drops 440px to 360px to give masonry more columns to work with. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Two fixes found while verifying the board layout in a browser. The fact grids inside each card had the same problem the board just lost: every row stretched to its tallest box, so a one-line price sat in a box padded out to match a three-line yield note next to it. They now pack by their own height using the same row-span technique, so a short fact rises into the gap beside a tall one. The packing maths is now shared as packGrid() rather than duplicated. Fact grids pack before the cards are measured, because reclaiming their dead space shortens the card, and measuring first would bake in the taller pre-pack height and leave a gap under the content. Separately, scroll-margin-top was a hardcoded 164px while the header measures 169px, so clicking a ticker headline landed the card five pixels behind the header. A constant cannot be right here: the operator telemetry rows are hidden from public visitors, so the header is a different height per viewer, and it wraps taller as the viewport narrows — 319px at mobile width, where the old constant would have hidden the card by 155px. The offset now derives from the measured header, republished on resize and after each render. Verified in a browser over 100 real events: no card or fact overlaps and no horizontal overflow at either 1920px (4 columns) or 492px (1 column), fact boxes no longer stretch, targeted cards clear the header by 14px at both widths, and contradicted events stay off the board while their pill keeps the true count. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
What
The Edge Board moves from a capped 1320px column with an equal-height auto-fit grid to a full-bleed masonry layout — at both levels, the board and the fact grids inside each card. Contradicted events come off the board by default. Plus one real bug found during verification.
Why
Three problems on the live board:
auto-fitstretched every card in a row to the tallest one, so a row containing one long event left ragged whitespace under its short neighbours. The fact grids inside each card had the identical problem — a one-line price sat in a box padded out to match a three-line yield note beside it.How
mainis full-bleed with fluid gutters (clamp(18px,4vw,60px)) instead of a fixed column.grid-auto-rows:1pxplus a per-child row span. Row spacing is the childmargin-bottom, notrow-gap— a row-gap is charged per 1px row and would coarsen the span quantization.packGrid()rather than duplicated. Fact grids pack before cards are measured, because reclaiming their dead space shortens the card; measuring first would bake in the taller pre-pack height.#feedmutations go throughsetFeed(), which assigns the row span. A node inserted without one collapses to 1px and paints over the footer, so this is load-bearing rather than tidiness.DEFAULT_HIDDENkeepscontradictedoff the board unless its pill is selected.statusCountstill counts the full item list, so the pill shows the true number — hidden never means gone.Bug found while verifying
scroll-margin-topwas a hardcoded 164px against a 169px header, so clicking a ticker headline landed the target card 5px behind the header. A constant can't be correct here — the operator telemetry rows are hidden from public visitors, so the header height differs per viewer, and it wraps taller as the viewport narrows (319px at mobile width, where the old constant would have hidden the card by 155px). The offset now derives from the measured header via a--header-hcustom property, republished on resize and after each render.Testing
Verified in a browser against 100 real events, at 1920px (4 columns) and 492px (1 column):
:targetactive.2), board and ticker both exclude them, selecting the pill reveals exactly those 2, deselecting restores.test_service_setup, systemd-dependent; 1 dashboard concurrency test) reproduce identically onmainwith these changes stashed — macOS-local. CI is the gate.🤖 Generated with Claude Code