adop.tools · reports

Component showcase

Every core data-visualisation primitive with hardcoded sample data, so presentation and consistency can be refined independently of live API data. Each section names the primitive and the widget file(s) it maps to. Not linked from navigation; noindex.

window.Scorecards · core/scorecards.js · scorecard.js · *-overview.js

GA4 headline row (5 cards, weighted-average ratio total)

Search Console row (4 cards, position is lower-is-better)

Delta & state coverage (positive · negative · flat · new metric · clickable drill · position)

With sparkline (hover to read a datapoint) · shown at 4 cards/row, the recommended density

See the section note below on why interactive sparklines stop at 5 cards/row.

With a target / goal (progress bar) · the last card is a lower-is-better metric, where a fall is positive

Fill and the % label follow the metric's good direction: below a lower-is-better goal still reads as ahead (brand), above it flips to the loss token.

sc-trend.js · area-chart.js · monthly-trend.js (Chart.js, Catmull-Rom)

Sessions, last 30 days (normal range)

Conversions, sparse range (7 days, 2 data points)

Sessions & revenue (dual Y-axis, secondary dashed)

Clicks with a zero-value day

breakdown-table.js · core/table-menu.js (real TableMenu)

Three-dot menu switches Numbers / Heatmap / Bars. Totals row uses weighted averages for ratio columns.

Sessions by channel

Drill-down version · click a row to expand its child dimension (Channel → Source / Medium). The menu's Drill-down section toggles it.

Sessions by channel, drill to source / medium

Empty state (0 rows)

Sessions by campaign

No rows match the current filters and date range.
funnel-chart.js · conversion-funnel.js · meta-funnel.js

Four steps, step values and step-to-step conversion %. One large drop-off (checkout abandonment).

Vertical

Horizontal (matches production funnel-chart.js orientation)

heatmap.js · channel-heatmap.js

Channel × device sessions. Each cell tinted against its column maximum (Brand & Direct dominate desktop; a zero cell included).

window.Scorecards.delta · core/scorecards.js

Every state, directionally correct. Cost falling is good (green); clicks falling is bad (red).

app.widgetUtil.loading / empty / error · core/widget-registry.js

All three occupy the same card footprint a filled widget would.

Loading

Loading data…

Empty

No data for this metric in the selected period.

Error

Couldn't load this widget Google Ads query failed: incompatible metric combination (400).
breakdown-switcher.js · sc-breakdown-hub.js · ads-campaigns-hub.js · scz-tabbar

In-page tabs that swap the primary dimension or metric while the surrounding structure stays put. Bottom-border style only (2px brand underline), per DATA-DESIGN.

Table · same columns, switch the dimension

Chart · same channel breakdown, switch the metric

proposed standard · scz-head · heatmap-head · core/table-menu.js · core/chart-menu.js

Proposed standard header anatomy

One row: title (+ optional subtitle) on the left, then a right cluster of inline filter pills (component-specific, e.g. Device / Segment) followed by a single three-dot settings menu (TableMenu for tables, ChartMenu for charts). The three-dot menu is the only settings entry point, no separate gear or CSV button. Sub-navigation, when present, sits on a second row directly under the header as bottom-border tabs. Filters change the data shown; settings change how it's shown.

A · Data-widget header (filter pill + ChartMenu settings)

Sessions over time
Last 30 days, compared to previous period

Click the Device pill and the three-dot menu to see the standard controls.

B · Header with a sub-navigation row + TableMenu

Campaign performance
Google Ads · search campaigns

Sub-nav tabs render on their own row, flush under the title.

C · Minimal header (title only + settings)

Top landing pages