Make the crowding strip readable: level columns, one lollipop mark, a colour per meaning - #37
Merged
Merged
Conversation
Two rendering defects left the two-column strip reading as two different charts. The legend, drawn as traces inside the first figure, was laid out by Plotly as two vertically stacked groups; the stack outgrew the margin arithmetic that tried to predict its height, and Plotly silently pushed that one figure's top margin out, so the left column's axis and rows sat ~40px below the right's. And Bootstrap's default column stretch, combined with responsive figures, inflated the shorter column to the taller one's height, spreading its rows on a ~23px pitch beside the other's 19px. The legend is page chrome now — strip_traces.legend_items says what the entries are, the page renders them as one line of coloured text above both columns — so every figure carries the same constant top margin, and align="start" lets each column keep its natural height. Tests hold the new invariants: no figure draws a legend of its own, and every column figure gets the same top margin whatever the model or mark. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Measured on screen rather than reasoned about: at 19px a row's four marks blurred into one lane, and the 0.035 alternating band — chosen to be 'faint enough to group without reading as shading' — was simply imperceptible over the near-black background, so nothing grouped a row's marks or parted it from its neighbours. ROW_PX goes to 22 (the pitch the stretch bug accidentally demonstrated was more readable), the row band to 0.06, and the gate-zone bands to 0.09 so the shading that carries meaning stays the strongest on the page. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
The Dot/Bar toggle existed because neither form had won, and read side by side neither deserved to: the bar's fill was a half-row of colour saying one number, and the bare diamond scattered over an empty row and did not scan. The lollipop is the working part of each — a hairline stem from neutral carries the bar's at-a-glance 'how far, which way' on a twentieth of the ink, and a full-strength head carries the diamond's precise position and the hover. With one form there is nothing left to toggle, so the Mark control goes too. Quiet rows draw in the app's Commercial series colour rather than the old grey, which read as disabled rather than as quiet: the mark is Commercial positioning whatever the gate thinks of it, and every other panel names that series by this colour. 'No setup' stays a legend entry precisely because it is now a colour a reader could mistake for a verdict. The blocked-extreme pin (Orange Juice at 96 with a leg blocking) updates with the scheme: its lollipop sits deep in the bull band in the plain Commercial colour, position saying the level and colour withholding the verdict, same rule as before in the new clothes. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
0.06 was calibrated against the old marks and overshot the new ones: beside a hairline stem, a white band at 0.06 is the brightest thing on the row, and the page read as stripes with data in the gaps. 0.045 sits between that and the invisible 0.035 this started from — visible as association, beaten for attention by any actual mark. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
The palette's Commercial slot is #F87171-family red and grid_colors builds the bear verdicts from the same family — #FF4D4D full, the same at 0.5 for near — so a quiet row at full strength completed a line-up of three nearly identical reds, and a board of mostly-quiet markets read as a board of almost-bear-setups. Colour cannot fix this without giving up the series identity the quiet tier exists to state, so the separation comes from the channels colour does not own: quiet heads shrink from 9px to 5px and fade to 0.45, below even the near tier's 0.5, with stems at 0.22. Full setup > near > quiet, in size and intensity, whatever the hues. The legend's comm-coloured keys (No setup, 6w ago) fade to match the marks they stand for — a full-strength swatch would promise a red the plot never draws, and promise it in the bear family. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
The quiet tier's colour completes the loop. Grey slabs read as disabled, so it took the Commercial series red; the red sat in the bear verdict's own hue family, so it shrank and faded; and even faded, forty quiet rows still whispered bearish, because hue is the loudest channel and theirs said the wrong thing. If green means setup-long and red means setup-short, neutral cannot wear either. Quiet rows now draw in the app's own neutral — colors.dim, the same DIM_TEXT the Heatmap uses for 'no verdict' — whose 0.35 sits below the near tier's 0.5 by the ordering viz_constants already documents. The prior-position ring and the legend's neutral keys go with it. 'Disabled' was the slabs' failure, not the colour's: a 5px dim dot is texture, and whose series it is needs no colour to say — every lollipop on this chart is Commercials, and the legend and caption both say so. The smaller head stays, keeping full > near > quiet legible where hue is weak. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
The leg ticks carried their own gate state as opacity — bright when the leg sat through its extreme opposite Commercials, 0.4 otherwise. That spent the channel on something the axis already says (a gating leg is by definition at its own extreme, which is where its tick is drawn; the hover names it besides), and 0.4 had sunk the legs to the background tier where the quiet lollipops live. The legs are data — where the other side of the trade sits — not chrome. Opacity now follows the ROW's tier, the same rule every other mark on the row obeys: rows with a verdict light whole — lollipop, name, and every leg on them, ready to be inspected — and quiet rows knock their ticks back to 0.55, dimmed but solidly readable. One prominence system for the whole row instead of three. Co-Authored-By: Claude Fable 5 <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.
Seven visual fixes to /strip, each driven by looking at the rendered page and each pinned by tests (224 pass).
Layout
legend_items+ HTML), every figure carries one constant top margin, and the graph row usesalign="start".The mark
Colour, one meaning each
dim: the Commercial red is the bear verdict's own hue family, and forty quiet rows whispered bearish. Neutral is now a small faint grey dot; the only colour on the board is a verdict.Verified in the browser at each step (columns level to the pixel, one shared row pitch, tier ordering full > near > quiet on hue, size and intensity).
🤖 Generated with Claude Code