Skip to content

style: design system polish (cards, radius, controls, type, surfaces, charts) - #458

Merged
samcm merged 43 commits into
masterfrom
samcm/design-system-polish
Oct 22, 2026
Merged

samcm merged 43 commits into
masterfrom
samcm/design-system-polish

Conversation

@samcm

@samcm samcm commented Oct 21, 2026 •

Copy link
Copy Markdown
Member

Reworks the shared design system so every page picks up a tidier, more consistent look. All changes are made centrally in tokens and core components, not per page; .interface-design/system.md is updated to match.

What changes

Structure

  • Card anatomy — Card takes title / subtitle / actions and renders one header row. Header py-5 → py-3; header, body and footer share one inset so content lines up under the title. PopoutCard and hand-built card titles use it.
  • Radius — two tokens: rounded-xs (4px) for inline marks, rounded-sm (6px) for every container and control. md–3xl alias to sm. Card, Button, ButtonGroup, SelectMenu, Toggle and Checkbox are rounded by default (the rounded prop now opts out).
  • Controls — new SegmentedControl replaces seven copy-pasted time-window pill rows; selects and filter inputs are h-8 text-sm; chart legend chips lose their borders.
  • Tables — ~40px rows, muted text-xs headers, tabular numerals; nested tables run flush inside cards and align with the card title.
  • Stats — headline numbers render as one KPI strip (a panel split by hairlines) instead of a card per number, with one icon style.

Character

  • Type — Geist for UI text, numbers and charts; Geist Mono for identifiers; Space Grotesk kept for the wordmark and landing hero. Charts get the font through a registered lab ECharts theme. Page titles drop to text-2xl semibold; the gradient accent bar and showAccent are removed; a text-2xs token replaces 121 arbitrary text-[8–11px] sizes.
  • Surfaces — hairline panels with no shadows in both themes; the dark palette gets three distinct steps (page #0f0f0e, panel #181817, hairline #2c2b29).
  • App frame — breadcrumb moves into a sticky 48px top bar aligned with the sidebar header; navigation states are neutral (primary marks only the active icon).
  • Charts (MultiLine) — hairline grid lines, 11px labels, horizontal y-axis unit above the axis, no redundant "Date" axis name, slim neutral zoom slider, rounded tooltips.

Subtraction

  • No decorative motion, blur or gradients — page-entry fade-ins, staggered row animations, backdrop blur on menus/overlays/bars, the home hero glow and dot grid, gradient washes on error/loading screens, and CardChain's glow/3D/animated line are removed.
  • Consensus Overview — one full-width stack of synced charts with attestation participation leading, instead of a grid of ten equal cards; only the expanded view shows a range slider (MultiLine showDataZoomSlider). Hourly axes label each day once.
  • Copy — subtitles that restated the title or selected window, or were phrased as questions, are removed. InfoBox gains summary, collapsing method notes behind "How this is measured".

Long lists page through full history

  • New RangePager + getRangePage (Latest / Newer / Older / go to a number, ?from= URLs, clamped to the earliest indexed row from /bounds).
  • Slots: 50-slot pages back to the start of proposer data, replacing "Load older slots" (which kept at most 100 rows).
  • Epochs: 10-epoch pages instead of only the latest 10. Offline validators follow the page: the chart shows the worst 10 entities, and a new table lists every entity with total and per-epoch counts, worst first, filterable.
  • Entity Blocks tab: every proposal, 25 per page, instead of the 10 most recent within 12h.
  • Locally built blocks: 6-slot pages through the indexed prepared-block history instead of only the latest 6.

Fixes

  • Live: the data-column status waits for the 4s deadline before calling a slot unavailable, and says "No blobs" for blobless blocks.
  • buttonClassName gives router links the exact Button styles; Stats accepts rich labels and values (gas profiler block stats now use it, tooltip kept).

Colour, charts and layout

  • Colour only exceptions: normal and good values render neutral; warning/danger states, live indicators and categorical data colours are unchanged. Each client has one colour (getClientColor) across charts.
  • MultiLine labels lines at their ends (2–8 plain lines; off for narrow charts, secondary-axis charts and lines that end too close together); legends still toggle series.
  • MultiLine axes and marks:
    • Date axes tick on calendar boundaries (years, quarters, months, weeks, days) instead of every Nth point; value axes use compact numbers (40M, 1.2B) on every chart type; dataMin/dataMax bounds round to the tick interval.
    • Lines default to 1.5px; series over 600 points are LTTB-sampled; share stacks render as opaque bands, confidence bands stay translucent.
    • Fork marks: half-strength rules with title-case names that start below the plot's top edge, sit above the data, truncate inside the plot, and merge when crowded ("Istanbul · Muir Glacier", "Fusaka +2").
    • The legend is one wrapping row with swatches that match the mark; the zoom track appears only once zoomed; at height="100%" legend and chart share the container instead of pushing the x axis out.
  • Execution Overview Min/Max bands start hidden.
  • Attestation Arrivals by Block Vote: votes for this block in neutral ink, votes for older blocks in warning/danger at the chunks where they arrived, seconds axis synced with the other slot-time charts, 4s deadline marked.
  • Execution Overview and Partial Columns become synced stacks with a lead chart, like Consensus Overview; overview skeletons match.
  • Home becomes a start page: each network's fork, head slot/epoch and indexing lag, then a live feed of the latest blocks (slot, proposer, relays or local, MEV value, txs, blobs, gas, age), refreshed every slot.
  • Overview pages default to the all time range.
  • Validators: PerformanceSummary is a Stats strip; fork status badges share one treatment.

App-wide pass

  • Shared components: no shadows on menus/dialogs/popovers/tooltips, one radius scale, one focus style, Alert on semantic tokens, gate/error screens without glows.
  • Charts: Bar, Line, ScatterAndLine, BoxPlot, Heatmap, StackedBar and Donut share MultiLine's chrome via chartChrome.
  • Pages: hand-built panels and headers → Card title/subtitle/actions, stat grids → Stats, pills → Badge, toggles → SegmentedControl; decorative pings, gradients, medal emoji and tracked uppercase labels removed. Live page titles, HUD labels and status marks follow the same rules.

CI

  • The Test job runs on ubuntu-24.04: ubuntu-latest moved to 26.04, where Playwright 1.58 can't install Chromium.

Worth checking

  • The rounded default flips from opt-in to opt-out on several core components.
  • The old design doc said "never add grid lines"; MultiLine now has horizontal hairlines.
  • Category/date x-axes on MultiLine no longer show their axis name.
  • Bar, StackedBar, Line, ScatterAndLine and BoxPlot get the new font but keep their old axis styling.
  • Consensus Overview chart order is a judgment call (participation, missed slots, head votes, reorgs, proposals, inclusion delay, blobs, payload delivery, MEV reward).
  • New dependencies: @fontsource-variable/geist, @fontsource-variable/geist-mono.

Verification

  • tsc, eslint (no new warnings), 702 unit tests, Storybook play tests for core components; CI green.
  • Before/after screenshots in dark and light mode against the production backend are in the Amp thread.

ampagent and others added 18 commits October 21, 2026 02:14
Card gains title/subtitle/actions props that render a single header recipe
(text-sm/6 title, text-xs/5 subtitle, right-aligned actions). Header, body
and footer share one horizontal inset (px-4 sm:px-5) so content lines up
with the title, and the header drops from py-5 to py-3. PopoutCard and
cards that hand-built their titles now use the shared header.

Amp-Thread-ID: https://ampcode.com/threads/T-01a15c1f-9849-716a-a407-e518ae211996
Co-authored-by: Sam Calder-Mason <samcaldermason@gmail.com>
rounded-xs (4px) for inline marks and rounded-sm (6px) for every container
and control; md..3xl alias to rounded-sm in the theme so legacy classes stay
on the scale. Card, Button, ButtonGroup, SelectMenu, Toggle and Checkbox
are rounded by default instead of square, and hand-rolled pill buttons and
square selects move onto rounded-sm.

Amp-Thread-ID: https://ampcode.com/threads/T-01a15c1f-9849-716a-a407-e518ae211996
Co-authored-by: Sam Calder-Mason <samcaldermason@gmail.com>
Add SegmentedControl and replace seven hand-rolled time-window pill rows
with it. SelectMenu and the clients entity filter drop to h-8 text-sm with
a plain surface (no blur or shadow) so filter rows line up. Chart legend
chips lose their borders and the rule above the chart.

Amp-Thread-ID: https://ampcode.com/threads/T-01a15c1f-9849-716a-a407-e518ae211996
Co-authored-by: Sam Calder-Mason <samcaldermason@gmail.com>
Page titles drop from text-4xl bold to text-2xl semibold with a text-sm
description, and the gradient accent bar under every title is removed
along with the showAccent prop. A text-2xs (10px) theme token replaces
121 arbitrary text-[8px]..text-[11px] sizes. InfoBox loses its corner
fold and gradient strip.

Amp-Thread-ID: https://ampcode.com/threads/T-01a15c1f-9849-716a-a407-e518ae211996
Co-authored-by: Sam Calder-Mason <samcaldermason@gmail.com>
Rows drop from py-4 to py-2.5, column labels become muted text-xs, cells
default to foreground text with tabular numerals, and the table loses its
own background. Nested tables inside a Card body bleed to the card edges
and take the card's inset (via --card-inset) so rules span the card and
the first column lines up with the card title.

Co-authored-by: Sam Calder-Mason <samcaldermason@gmail.com>
Amp-Thread-ID: https://ampcode.com/threads/T-01a15c1f-9849-716a-a407-e518ae211996
Amp-Thread-ID: https://ampcode.com/threads/T-01a15c1f-9849-716a-a407-e518ae211996

# Conflicts:
#	src/components/Forms/SelectMenu/SelectMenu.tsx
#	src/pages/ethereum/clients/IndexPage.tsx
#	src/pages/ethereum/clients/components/EntityFilter/EntityFilter.tsx
#	src/pages/ethereum/consensus/overview/IndexPage.tsx
#	src/pages/ethereum/data-availability/partial-columns/IndexPage.tsx
#	src/pages/ethereum/entities/DetailPage.tsx
#	src/pages/ethereum/execution/gas-profiler/HomePage.tsx
#	src/pages/ethereum/execution/overview/IndexPage.tsx
#	src/pages/ethereum/execution/timings/IndexPage.tsx
Amp-Thread-ID: https://ampcode.com/threads/T-01a15c1f-9849-716a-a407-e518ae211996

# Conflicts:
#	src/components/Layout/Card/Card.tsx
#	src/components/Layout/PopoutCard/PopoutCard.tsx
Amp-Thread-ID: https://ampcode.com/threads/T-01a15c1f-9849-716a-a407-e518ae211996
Co-authored-by: Sam Calder-Mason <samcaldermason@gmail.com>
…for brand only

Body text, numbers and charts move from Space Grotesk to Geist; font-mono
becomes Geist Mono instead of the system monospace. Space Grotesk becomes
a font-display token used by the wordmark and landing hero. Charts get the
font through a registered 'lab' ECharts theme passed to every instance,
since canvas text cannot inherit CSS fonts.

Amp-Thread-ID: https://ampcode.com/threads/T-01a15c1f-9849-716a-a407-e518ae211996
Co-authored-by: Sam Calder-Mason <samcaldermason@gmail.com>
Cards and page-level tables use one depth strategy in both themes: a
hairline outline, no shadows, no hover lift. The dark palette gets three
distinct steps (page #0f0f0e, panel #181817, hairline #2c2b29) where the
old surface and border were nearly identical; light panels become near
white with a hairline and muted text darkens to sand-700. The sidebar
sits on the page background instead of a blurred surface.

Amp-Thread-ID: https://ampcode.com/threads/T-01a15c1f-9849-716a-a407-e518ae211996
Co-authored-by: Sam Calder-Mason <samcaldermason@gmail.com>
The breadcrumb moves into a sticky h-12 top bar whose rule continues the
sidebar header's, with muted ancestors instead of accent-colored links.
Sidebar hover and active states become neutral (primary marks only the
active icon), the network select shrinks to h-10 text-sm, and the mobile
header drops its blur-and-shadow surface.

Amp-Thread-ID: https://ampcode.com/threads/T-01a15c1f-9849-716a-a407-e518ae211996
Co-authored-by: Sam Calder-Mason <samcaldermason@gmail.com>
Stats renders a single hairline panel divided by internal rules instead
of a card per number. Label, icon, value and delta follow one recipe, the
three icon treatments (solid primary square, tinted square, none) become
one inline 14px icon, and values use tabular numerals.

Amp-Thread-ID: https://ampcode.com/threads/T-01a15c1f-9849-716a-a407-e518ae211996
Co-authored-by: Sam Calder-Mason <samcaldermason@gmail.com>
Value axes get hairline grid lines and lose their axis line; labels drop
to 11px; the y-axis unit reads horizontally above the axis instead of
rotated beside it; date and category x-axes drop their redundant name
("Date"). The dataZoom slider becomes a slim neutral track without the
orange data preview, tooltips become rounded panels, and legend group
labels no longer wrap.

Amp-Thread-ID: https://ampcode.com/threads/T-01a15c1f-9849-716a-a407-e518ae211996
Co-authored-by: Sam Calder-Mason <samcaldermason@gmail.com>
Amp-Thread-ID: https://ampcode.com/threads/T-01a15c1f-9849-716a-a407-e518ae211996
Co-authored-by: Sam Calder-Mason <samcaldermason@gmail.com>
@samcm
samcm requested a review from Savid as a code owner October 21, 2026 04:26

@redpandabot redpandabot Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

A central design-system refresh: Card gains title/subtitle/actions anatomy, radius and text-size tokens are consolidated, SegmentedControl replaces seven copy-pasted pill rows, Stats becomes a KPI strip, tables get one density, and charts pick up a registered ECharts theme. I verified the Tailwind v4 mechanics it depends on (in-data-[slot=card-body] variant, --spacing() in arbitrary properties, --font-sans emission), the OSV status of the two new font packages, all removed-prop call sites, and the MultiLine memo deps; nothing is broken. The intentional flips listed in the PR description are documented in system.md, so I have no findings.


Reviewed 111 changed file(s) @ 0d62b223 — no blocking issues found.
"A camel is a horse designed by committee."

ampagent and others added 9 commits October 21, 2026 05:19
Pages no longer fade in on entry (fade-in tokens, the opacity-0 start
state and the staggered slot-row animation are gone). Menus, popovers,
overlays, the dialog scrim and the sticky bars use solid surfaces instead
of backdrop blur. The home hero loses its glow and dot grid, the error
and loading screens lose their gradient washes, and CardChain drops its
grid pattern, pulsing glow, fake 3D top face and animated gradient line.

Amp-Thread-ID: https://ampcode.com/threads/T-01a15c1f-9849-716a-a407-e518ae211996
Co-authored-by: Sam Calder-Mason <samcaldermason@gmail.com>
Consensus Overview drops the two-column grid of ten equal cards for one
full-width stack sharing a crosshair and zoom: attestation participation
leads at 320px, the rest follow at 200px in order of importance, and only
the expanded view shows a range slider. Subtitles that restated the title
and the selected window are removed.

MultiLine gains showDataZoomSlider, and hourly category axes label only the
first point of each day instead of repeating the date.

Amp-Thread-ID: https://ampcode.com/threads/T-01a15c1f-9849-716a-a407-e518ae211996
Co-authored-by: Sam Calder-Mason <samcaldermason@gmail.com>
… method notes

Chart subtitles that repeated the card title or the selected time window
are removed (execution overview, gas profiler), as are subtitles phrased
as questions. InfoBox gains a summary prop that collapses the note behind
one line; the clients and partial-columns method paragraphs use it with
"How this is measured" instead of sitting above the data.

Amp-Thread-ID: https://ampcode.com/threads/T-01a15c1f-9849-716a-a407-e518ae211996
Co-authored-by: Sam Calder-Mason <samcaldermason@gmail.com>
Add a shared RangePager (range on screen, Latest / Newer / Older, jump to
a number) and getRangePage, which pages a newest-first sequence by its top
number and clamps to the earliest indexed row from /bounds. Pages are
addressed by ?from=, so every page has a URL.

Slots: replace the infinite "Load older slots" list (capped at 100 rows
in memory) with 50-slot pages back to the start of proposer data, pager
above and below the table. Epochs: 10-epoch pages instead of only the
latest 10. Offline validators follow the page; the chart shows the worst
10 entities and a new table lists every entity with a total and exact
per-epoch counts, worst first, filterable by name.

TopEntitiesChart's default subtitle counted only the plotted entities;
it now reports all of them and notes how many are shown. Its x labels
no longer locale-format slot and epoch numbers.

Amp-Thread-ID: https://ampcode.com/threads/T-01a15c1f-9849-716a-a407-e518ae211996
Co-authored-by: Sam Calder-Mason <samcaldermason@gmail.com>
The Blocks tab showed only the 10 most recent proposals within 12 hours.
It now pages every proposal by the entity, 25 at a time, with the same
columns (proposer index, status, blobs, attestation votes), the shared
RangePager and a jump to any slot (?blocksFrom=). Because proposals are
sparse, Newer looks up the page above on demand (RangePager onNewer).

useEntityDetailData no longer runs the recent-10 and four supplemental
queries that fed the old table.

Amp-Thread-ID: https://ampcode.com/threads/T-01a15c1f-9849-716a-a407-e518ae211996
Co-authored-by: Sam Calder-Mason <samcaldermason@gmail.com>
A chartChrome helper supplies the axis, grid-line, tooltip and title
styling, so Bar, Line, ScatterAndLine, BoxPlot, Heatmap, StackedBar and
Donut match MultiLine: muted 11px labels, hairline value grid lines with
no value-axis line, y-axis names above the axis, surface tooltips with a
hairline and no shadow, 14px titles. Donut loses its hover glow. Axis
names, legends, series and zoom are unchanged.

Amp-Thread-ID: https://ampcode.com/threads/T-01a15c1f-9849-716a-a407-e518ae211996
Co-authored-by: Sam Calder-Mason <samcaldermason@gmail.com>
Overlays, menus, popovers, dialogs, notifications and tooltips use hairline
surfaces with no shadow; error and gate screens lose their glows and
gradient bar; buttons, badges, toggles, tabs and inputs use rounded-sm or
rounded-xs and one outline focus style (Tab gains a visible one). Alert
is rebuilt on semantic tokens; its links use foreground text so the
warning tone stays readable. Stats and Card titles nest cleanly: a Stats
strip inside a Card body runs flush to the card edges.

Live page: panel titles share the card title style, HUD labels and status
marks drop the tracked uppercase, client names are capitalised, the time
readout uses tabular numerals so it no longer jitters, the data-column
status says "Data not available" instead of a red "✗ Data available",
and the Aggregations phase label no longer truncates.

Amp-Thread-ID: https://ampcode.com/threads/T-01a15c1f-9849-716a-a407-e518ae211996
Co-authored-by: Sam Calder-Mason <samcaldermason@gmail.com>
Slot, epoch, entity, fork, validator and contract pages replace hand-built
panels and headers with Card title/subtitle/actions, stat-box grids with
Stats, pills with Badge and tab buttons with SegmentedControl. Forks drops
its rings, glows and xl radii and shares one countdown, status badge,
quick-links and external-resources component instead of duplicated JSX.
Every value, link, count and unit is kept; copy changes are limited to
loading descriptions and two page descriptions.

Amp-Thread-ID: https://ampcode.com/threads/T-01a15c1f-9849-716a-a407-e518ae211996
Co-authored-by: Sam Calder-Mason <samcaldermason@gmail.com>
…omponents

Gas profiler, timings, payloads, state growth/expiry, custody, probes,
partial columns, locally built blocks, contributors, geo checklist, home
and experiments replace hand-built panels and headers with Card
title/subtitle/actions, toggles with SegmentedControl, pills with Badge
and ad hoc buttons with Button; explorer links share one component. Drop
shadows, pings, decorative pulses and gradients, medal emoji (rank numbers
instead), tracked uppercase labels and raw palette colours for status.
Categorical colours (call types, policies, heatmap ramps) are kept.
Method notes move behind InfoBox summaries with their text unchanged.

SegmentedControl options can be disabled (zero-count filters), Card hides
an empty body, and the design doc covers paged long lists.

Amp-Thread-ID: https://ampcode.com/threads/T-01a15c1f-9849-716a-a407-e518ae211996
Co-authored-by: Sam Calder-Mason <samcaldermason@gmail.com>
@redpandabot

This comment has been minimized.

ampagent and others added 13 commits October 21, 2026 08:42
… rich labels

buttonClassName (Button.styles.ts) gives router links the exact Button
styles, replacing the class strings the fork and custody pages copied.
Stats name, value and subtitle accept nodes, so the gas profiler block
page's five stat cards become one Stats strip with the Receipt Payload
tooltip and the failed-transaction count kept.

Amp-Thread-ID: https://ampcode.com/threads/T-01a15c1f-9849-716a-a407-e518ae211996
Co-authored-by: Sam Calder-Mason <samcaldermason@gmail.com>
The data-column header said "Data not available" in red for every slot
until 64 columns arrived, including the first seconds of each replay and
slots whose block carried no blobs. It now shows "Waiting for columns"
until the 4s deadline passes in the replay (or the block's blob count is
still loading), "No blobs" when the block has none, and the red verdict
only after the deadline with fewer than 64 columns. The block's blob
count is passed through as null until known instead of defaulting to 0.

Amp-Thread-ID: https://ampcode.com/threads/T-01a15c1f-9849-716a-a407-e518ae211996
Co-authored-by: Sam Calder-Mason <samcaldermason@gmail.com>
The timeline showed only the latest 6 slots. It now uses RangePager over
the fct_prepared_block bounds: Latest / Newer / Older and go to a slot,
6 slots per page, addressed by ?from=. The latest page still follows new
data as the bounds refresh.

Amp-Thread-ID: https://ampcode.com/threads/T-01a15c1f-9849-716a-a407-e518ae211996
Co-authored-by: Sam Calder-Mason <samcaldermason@gmail.com>
Execution Overview follows Consensus Overview: one full-width stack
sharing a crosshair and zoom, TPS first at 320px, then gas, transactions
and gas-limit signalling at 240px, the range slider only in the expanded
view, and the shared Header instead of a hand-built 4xl title. Partial
Columns keeps adoption beside adoption-by-version and stacks the six
synced completion charts led by Completion Paths. The gas profiler's
receipt-size chart no longer sits alone at half width. Both overview
skeletons now match the stacked layout.

Amp-Thread-ID: https://ampcode.com/threads/T-01a15c1f-9849-716a-a407-e518ae211996
Co-authored-by: Sam Calder-Mason <samcaldermason@gmail.com>
…ours

MultiLine labels each plain line with its series name at its right end
when 2-8 lines are shown, shifting labels apart when they collide and
widening the right margin only when labels render. Stacked, area, bar,
band and helper series are never labelled; legends still toggle series.
endLabels={false} opts out.

Node resource charts keyed by client name now take getClientColor, like
the clients, timings and partial-columns charts, so a client has one
colour across the app.

Amp-Thread-ID: https://ampcode.com/threads/T-01a15c1f-9849-716a-a407-e518ae211996
Co-authored-by: Sam Calder-Mason <samcaldermason@gmail.com>
Normal and good values (participation, rates, Ready/Delivered/Canonical,
MEV values, pass marks, savings, shrinking state) render in foreground or
muted text instead of green; warning and danger states, live indicators,
transient feedback and categorical data colours are unchanged. Thresholds
keep their bad-side colours.

Validators: PerformanceSummary becomes one Stats strip with every value,
suffix, breakdown and fail colour kept, and the threshold panel's whole
title row toggles it again. Fork Current/Active badges share one neutral
treatment instead of mixing blue and green.

Amp-Thread-ID: https://ampcode.com/threads/T-01a15c1f-9849-716a-a407-e518ae211996
Co-authored-by: Sam Calder-Mason <samcaldermason@gmail.com>
The full-screen hero (giant wordmark, flip-digit slot counters, network
tiles) becomes a plain start page: one table per network group with the
active fork, head slot and epoch, and the newest indexed block with how
far behind the head it is (flagged after 10 minutes), then the main pages
by section. Rows open the network's live view as before. useNetworksBounds
fetches /bounds for several networks through the shared bounds cache.

Amp-Thread-ID: https://ampcode.com/threads/T-01a15c1f-9849-716a-a407-e518ae211996
Co-authored-by: Sam Calder-Mason <samcaldermason@gmail.com>
…ur rules

MultiLine skips end labels on charts narrower than 480px and on charts
with a secondary y-axis, whose numbers occupy the right edge. The
RangePager jump box spans the row on mobile. The design doc describes the
colour-only-exceptions rule, client colours and end labels.

Amp-Thread-ID: https://ampcode.com/threads/T-01a15c1f-9849-716a-a407-e518ae211996
Co-authored-by: Sam Calder-Mason <samcaldermason@gmail.com>
…inting

'dataMin'/'dataMax' value-axis bounds started the axis on the raw data
value, so the first tick read 1.333 or 0.002192. MultiLine now maps them to
scale: true, letting ECharts round the extent to whole intervals while
still leaving out zero; this covers every chart that uses them.

End labels are skipped when two lines end within ~18px of each other on
the plot (Average/Median/Moving Avg on the overview pages). Fork mark-line
labels that would overprint are merged into their neighbour ("Fusaka ·
BPO1 · BPO2") so every fork stays named. Execution Overview's Min/Max
bands start hidden like Consensus Overview's, so all-time TPS reads on a
0-250 axis instead of 0-3000. Both overview pages default to All time.

Amp-Thread-ID: https://ampcode.com/threads/T-01a15c1f-9849-716a-a407-e518ae211996
Co-authored-by: Sam Calder-Mason <samcaldermason@gmail.com>
The start page's static list of links becomes the newest blocks on the
selected network, refreshed every slot: slot, proposer entity, relays and
MEV value (or Local), transactions, blobs, gas used against the limit,
and age. Rows open the slot. Slots newer than the MEV table's newest row
show a dash rather than claiming a local build. On mobile the row folds
to slot, proposer and a line of figures.

Co-authored-by: Sam Calder-Mason <samcaldermason@gmail.com>
Mark-line labels draw above data series with a surface-coloured halo, and
long merged labels truncate at the plot bottom instead of crossing the
x-axis. Hovering a mark line shows the full name.

Amp-Thread-ID: https://ampcode.com/threads/T-01a15c1f-9849-716a-a407-e518ae211996
Co-authored-by: Sam Calder-Mason <samcaldermason@gmail.com>
…tations, solid stacked bands

- Date category axes tick on year/quarter/month/week boundaries instead of every Nth point
- Value axes default to compact numbers (40M, 1.2B)
- Lines default to 1.5px; dense series are LTTB-sampled to the plot's resolution
- Fork mark lines draw at half strength with title-case names
- Stacked areas fill with opaque blends, so grid lines and neighbouring bands never show through
- The zoom track only appears once the chart is zoomed

Amp-Thread-ID: https://ampcode.com/threads/T-01a15c1f-9849-716a-a407-e518ae211996
Co-authored-by: Sam Calder-Mason <samcaldermason@gmail.com>
…labels, compact numbers on every value axis

- The MultiLine legend lays its groups out in one wrapping row; swatches are a line, dashed line or
  block matching the mark, and both legend positions share one renderer
- Three or more fork marks in one spot read "Fusaka +2" instead of a full list
- Confidence bands keep their translucent fill; only share stacks render as opaque bands
- Bar, ScatterAndLine and BoxPlot value axes use the shared compact number formatter
- charts.md describes the current axis, grid, mark and legend defaults

Amp-Thread-ID: https://ampcode.com/threads/T-01a15c1f-9849-716a-a407-e518ae211996
Co-authored-by: Sam Calder-Mason <samcaldermason@gmail.com>
@redpandabot

This comment has been minimized.

@redpandabot

This comment has been minimized.

ampagent and others added 3 commits October 22, 2026 02:54
ubuntu-latest moved to 26.04, which Playwright 1.58 has no Chromium build for, so
`playwright install` fails before any test runs.

Amp-Thread-ID: https://ampcode.com/threads/T-01a15c1f-9849-716a-a407-e518ae211996
Co-authored-by: Sam Calder-Mason <samcaldermason@gmail.com>
Labels began on the top grid line, where series near their maximum (participation,
head votes) ran straight through the first letters.

Amp-Thread-ID: https://ampcode.com/threads/T-01a15c1f-9849-716a-a407-e518ae211996
Co-authored-by: Sam Calder-Mason <samcaldermason@gmail.com>
- Votes for this block are neutral ink; votes for an older block (missed head) carry warning and
  danger colour, plotted only where they arrived instead of as flat lines along the baseline
- Time axis is seconds (0-12) like the other slot-time charts, so its crosshair syncs with them
- The 4s attestation deadline is marked, with the time after it lightly shaded
- HTML legend instead of the native diamond legend; y axis names its unit (per 50 ms)
- MultiLine at height 100% lays out legend and chart as a flex column, so the x axis is no longer
  pushed out of the card

Amp-Thread-ID: https://ampcode.com/threads/T-01a15c1f-9849-716a-a407-e518ae211996
Co-authored-by: Sam Calder-Mason <samcaldermason@gmail.com>
@samcm
samcm merged commit a1819fb into master Oct 22, 2026
3 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants