"Comparison gauges" KPI indicator. Each KPI is a goal-oriented progress bar — label · value on top, bar with a target tick in the middle, 0 · tgt scale below. Bar fill is value/target, capped at 100% (overshoots are signalled by colour, not by overflowing the bar). Colours: --pa-positive for "on track", --pa-warning for "off-target / approaching limit", --pa-neutral for "no strong sentiment".
Layout is a cell-min-driven auto-fit grid: cells stay at least --pa-kpi-gauge-cell-min wide (default 20rem), the grid fits as many columns as the container allows, and the responsive cascade is intrinsic. --max-2…--max-6 modifiers cap the column count while still collapsing on narrow containers. The canonical card below uses --max-3 for a deterministic 2-row layout.
Key Performance Indicators
LIVE- Current
- 88.1%
- Target
- 90.0%
- Δ to target
- −1.9pp
- % of target
- 97.9%
- Current
- $859K
- Target
- $900K
- Δ to target
- −$41K
- % of target
- 95.4%
- Current
- 23.8°C
- Target (max)
- 25.0°C
- Δ to target
- −1.2°C
- % of target
- 95.2%
- Current
- 84.5%
- Target (max)
- 80.0%
- Δ to target
- +4.5pp
- % of target
- 105.6%
- Scale
- 0 → 100%
- Current
- 0.27%
- Target (max)
- 0.50%
- Δ to target
- −0.23pp
- % of target
- 54.0%
- Current
- ¥11.7M
- Target
- ¥13.0M
- Δ to target
- −¥1.3M
- % of target
- 90.0%
1×3 · .pa-col-1-3 columns
Three smaller cards side-by-side. Each card uses the default pa-kpi-gauge-list__grid (no cap modifier) — at ~400px wide the cell-min threshold forces a single column, so each card stacks its 2 gauges vertically.
- Current
- 88.1%
- Target
- 90.0%
- % of target
- 97.9%
- Current
- $859K
- Target
- $900K
- % of target
- 95.4%
- Current
- 23.8°C
- Target
- 25.0°C
- % of target
- 95.2%
- Current
- 84.5%
- Target
- 80.0%
- % of target
- 105.6%
- Current
- 0.27%
- Target
- 0.50%
- % of target
- 54.0%
- Current
- ¥11.7M
- Target
- ¥13.0M
- % of target
- 90.0%
2×3 stack · .pa-col-25 + .pa-col-45 (asymmetric, 30% empty)
Two page-grid columns: 25% wide on the left (narrow stress test — each gauge gets ~280–320px), 45% on the right. Each holds three gauges with the default pa-kpi-gauge-list__grid. Both cards sit below the cell-min × 2 threshold, so the grid collapses to a single column inside both.
- Current
- 88.1%
- Target
- 90.0%
- % of target
- 97.9%
- Current
- 23.8°C
- Target
- 25.0°C
- % of target
- 95.2%
- Current
- 0.27%
- Target
- 0.50%
- % of target
- 54.0%
- Current
- $859K
- Target
- $900K
- % of target
- 95.4%
- Current
- 84.5%
- Target
- 80.0%
- % of target
- 105.6%
- Current
- ¥11.7M
- Target
- ¥13.0M
- % of target
- 90.0%
Usage Guide
When to use
Goal-oriented dashboards — each KPI is shown as a progress bar against a target. Best when the operator's mental model is "are we on track?" rather than "what's the trend?". For trend-first reads, see Sparkline list or Terminal grid; for purely textual scanning, see Numeric strip.
Bar semantics — two modes
Default mode (0 → target scale): the bar's full width represents the target. Fill width = value / target, capped at 100%. Tick sits at the right edge marking target. Overshoots are signalled by the warning colour rather than by overflowing the bar. Best for metrics where "how close to target" is the only question.
0 → max scale (override --pa-kpi-gauge-tick-pos): the bar's full width represents some wider scale (e.g. 0–100% capacity). Fill width = the raw value; tick slides inside the bar to mark the target position. Overshoots become visible as fill extending past the tick. See "Server Capacity" in the canonical card for an example. Best for metrics with a natural upper bound (capacity, threshold-style targets, percentages).
Sentiment colours
- positive (green) — on track / approaching target.
- warning (orange) — off-target or approaching a limit. New to this showcase, sits alongside the green/red sentiment scale on a different axis (proximity-to-limit, not direction-of-change).
- negative (red) — actively bad / failing target.
- neutral (grey) — informational, no strong sentiment.
The bar fill colour is set per-tile via --pa-kpi-bar-color; the four .pa-kpi-gauge--* modifiers each set this custom property, so adding a new sentiment is just one rule. The fill element reads from the property.
Layout
Cell-min-driven auto-fit grid. The default .pa-kpi-gauge-list__grid packs as many columns as fit while keeping each cell at least --pa-kpi-gauge-cell-min wide (default 20rem). No @container queries — the responsive cascade is intrinsic to the grid template. Override the cell-min per instance to change density: style="--pa-kpi-gauge-cell-min: 24rem" for fewer, wider columns; 16rem for more, narrower ones.
Cap-at-N modifiers. --max-2, --max-3, --max-4, --max-5, --max-6 each cap the column count at N while still collapsing below the cell-min × N threshold (a ceiling, not a force). Pick the cap so your item count divides into clean rows. --2col is a separate deterministic modifier — exactly 2 columns regardless of cell-min or container width.
Hairline dividers. The inter-tile dividers are gap: 1px on the grid over background: var(--pa-border-color), with each tile painting background: var(--pa-card-bg) on top. Only the gap shows through, giving single-pixel hairlines on every interior boundary regardless of column count. Replaces the previous per-tile border-right + border-bottom + nth-child suppression, which only worked for the hardcoded 2-col layout. The card's outer border supplies the perimeter; the body still uses padding: 0 so the dividers go edge-to-edge.
Hover detail popover
Cursor-anchored via Floating UI's computePosition + a virtual reference element built from e.clientX/clientY. Same recipe as the other KPI showcases: position: fixed, pointer-events: none, popover moved to <body> on init to escape ancestor overflow: hidden.
CSS Classes Reference
Card structure
pa-kpi-gauge-list— page-namespace class on.pa-card.pa-kpi-header— flex header with title + LIVE indicator.pa-kpi-live/pa-kpi-live__dot— LIVE pill + animated dot.pa-kpi-gauge-list__body— appliespadding: 0so the inter-tile hairlines go edge-to-edge.pa-kpi-gauge-list__grid— cell-min-drivenauto-fitgrid (default cell-min20rem). Hairlines come fromgap: 1pxover the grid's border-coloured background.pa-kpi-footer— flex footer caption.
Grid layout modifiers
pa-kpi-gauge-list__grid--2col— force exactly 2 columns regardless of cell-min or container width.pa-kpi-gauge-list__grid--max-2/--max-3/--max-4/--max-5/--max-6— cap the column count at N while still collapsing below the cell-min × N threshold. The canonical card uses--max-3for a clean 3-column layout.
Layout CSS variables
--pa-kpi-gauge-cell-min— minimum cell width for theauto-fitgrid (default20rem). Smaller → more columns at the same container width; larger → fewer. Override per instance viastyle="--pa-kpi-gauge-cell-min: 24rem".
Gauge tile
pa-kpi-gauge— single gauge cell. Carries--pa-kpi-bar-color(set by sentiment modifiers below).pa-kpi-gauge--positive— green fill (on track).pa-kpi-gauge--warning— orange fill (off-target / approaching limit).pa-kpi-gauge--negative— red fill (actively bad).pa-kpi-gauge--neutral— grey fill (no sentiment).
Tile content
pa-kpi-gauge__head— flex row with label + value.pa-kpi-gauge__label— uppercase mono caption.pa-kpi-gauge__value— focal number + unit.pa-kpi-gauge__num/pa-kpi-gauge__unit— numeric + unit spans.pa-kpi-gauge__scale— flex row with "0" left and "tgt {value}" right (mono, dim).
Bar + target tick
pa-kpi-gauge__bar— track. Reads--pa-kpi-gauge-tick-posfor tick position (default100%).pa-kpi-gauge__fill— coloured fill. Width set inline per tile viastyle="width: X%".--pa-kpi-gauge-tick-pos— custom property on.pa-kpi-gauge__barsetting the target tick's position. Default100%(right edge, matching 0→target scale). Override per-tile viastyle="--pa-kpi-gauge-tick-pos: 80%"when the bar represents a wider scale (e.g. 0→100% capacity, target at 80%).--pa-kpi-gauge-tick-color— custom property on.pa-kpi-gauge__barsetting the target tick's colour. Defaultvar(--pa-text-color-1)(full opacity body text, so the tick stays readable against any sentiment fill colour). Override globally or per-tile for a quieter mark.
Hover detail popover
pa-kpi-detail— popover root (moved to<body>on init;position: fixed, hidden untildata-show).pa-kpi-detail__title— uppercase mono header.pa-kpi-detail .pos / .neg / .warn— sentiment-coloured<dd>text.
Framework tokens used by this showcase
--pa-very-positive/--pa-positive/--pa-neutral/--pa-negative/--pa-very-negative— 5-step semantic sentiment scale.--pa-warning— orange "off-target / approaching limit" signal.--pa-detail-bg/--pa-detail-text/--pa-detail-row-label/--pa-detail-title/--pa-detail-shadow— popover chrome.