"Bento layout" KPI indicator. Asymmetric tile sizes, sparkline as a low-opacity background on each tile, big numerals layered over the chart in the lower-left corner. Hero (Monthly Revenue) spans two rows on the left; two stacked tiles on the right (top); three equal tiles below — magazine-style mixed sizes rather than a uniform grid. Card-level container query collapses the whole bento to a single-column stack when the host card narrows below 700px so the same markup works in narrow page-grid cells.

Layout modifiers on .pa-kpi-bento__grid swap the named-area template without changing markup: default (no modifier) puts the hero on the left, --hero-right mirrors it, --5-tile drops to 5 tiles (hero + 4 supporting). Row height is a CSS variable (--pa-kpi-bento-row-height, default 12rem) for taller/shorter tile rows per instance.

Key Performance Indicators

LIVE
Monthly Revenue
+12.8%
$849K
Completion Rate
+2.8%
86.5%
Server Capacity
+21.0%
85.9%
Server Temp
-2.1%
24.0°C
Error Rate
-30.9%
0.28%
Tokyo Office
+8.1%
¥12.1M

Layout variant · pa-kpi-bento__grid--hero-right

Mirror of the default layout — hero spans the right half × 2 rows, two stacked supporting tiles on the left of rows 1-2, three equal tiles below. Same 6-tile contract; source order is unchanged (1st = hero, 2nd–3rd = upper supporting, 4th–6th = bottom row). Only the named-area template flips.

Key Performance Indicators

LIVE
Monthly Revenue
+12.8%
$849K
Completion Rate
+2.8%
86.5%
Server Capacity
+21.0%
85.9%
Server Temp
-2.1%
24.0°C
Error Rate
-30.9%
0.28%
Tokyo Office
+8.1%
¥12.1M

Layout variant · pa-kpi-bento__grid--5-tile

Five-tile composition — hero spans left × 2 rows, two stacked supporting tiles on the right of rows 1-2, two equal halves on the bottom row. Use this when you have exactly 5 KPIs and don't want to force a 6th. The modifier requires exactly 5 source-order tiles; a 6th tile (if present) would be auto-placed in a new row and break the layout.

Key Performance Indicators

LIVE
Monthly Revenue
+12.8%
$849K
Completion Rate
+2.8%
86.5%
Server Capacity
+21.0%
85.9%
Server Temp
-2.1%
24.0°C
Error Rate
-30.9%
0.28%

Monthly Revenue
+12.8%
$849K
Completion
+2.8%
86.5%
Capacity
+21.0%
85.9%
Server Temp
-2.1%
24.0°C
Error Rate
-30.9%
0.28%
Tokyo
+8.1%
¥12.1M
Quarterly Bookings
+18.4%
2.4M
NPS
+4
62
CSAT
±0.0%
94.1%
DAU
+6.2%
42.7k
Churn
+0.4%
3.1%
Conversion
+1.2%
5.7%
Cloud Spend
+9.4%
$128k
Latency
-12.0%
142ms
Uptime
+0.04%
99.99%
Tickets
+22%
387
Active Users
+3.8%
128k
Build Time
-31%
3.2m

Revenue
+12.8%
$849K
Done
+2.8%
86.5%
Capacity
+21%
85.9%
Temp
-2.1%
24.0°C
Errors
-31%
0.28%
Tokyo
+8.1%
¥12.1M
Monthly Revenue
+12.8%
$849K
Completion
+2.8%
86.5%
Capacity
+21.0%
85.9%
Server Temp
-2.1%
24.0°C
Error Rate
-30.9%
0.28%
Tokyo Office
+8.1%
¥12.1M
Bookings
+18%
2.4M
NPS
+4
62
CSAT
±0.0%
94.1%
DAU
+6.2%
42.7k
Churn
+0.4%
3.1%
Convert
+1.2%
5.7%

Custom chart library · Chart.js in the chart slot

The pa-kpi-bento-tile__chart slot is a plain positioned container — the inline SVG sparkline is just the lightweight default. Each tile below swaps a <canvas data-kpi-chart> in where the <svg> was, rendering a Chart.js bar chart as the tile background instead of the area sparkline — visibly a different chart, same slot. The tile still sets color: var(--pa-kpi-accent), so the bars read currentColor for their sentiment hue and re-colour on theme change — no per-tile chart config needed.

Key Performance Indicators

LIVE
Monthly Revenue
+12.8%
$849K
Completion Rate
+2.8%
86.5%
Server Capacity
+21.0%
85.9%
Server Temp
-2.1%
24.0°C
Error Rate
-30.9%
0.28%
Tokyo Office
+8.1%
¥12.1M

Usage Guide

When to use

Magazine-cover dashboards where one headline KPI deserves disproportionate visual weight, with supporting metrics arranged around it. Sparklines sit behind the values rather than alongside them. Best for marketing pages, exec summaries, and "today at a glance" hero panels. If you want even visual weight across all KPIs, pick Editorial minimal or Numeric strip.

Layout modifiers

The grid uses CSS grid-template-areas on a 6-col × 3-row layout. Tile placement is by source order via :nth-child rules, so the markup stays identical across layout modifiers — authors only list tiles in reading order and pick a modifier. Three layouts ship today:

  • Default (no modifier): 6 tiles — hero spans the left half × 2 rows, two stacked tiles on the right of rows 1-2, three equal tiles on the bottom row.
  • --hero-right: mirror of default — hero on the right half, two stacked tiles on the left of rows 1-2, three equal tiles below. Same 6-tile contract.
  • --5-tile: hero + 4 supporting — hero spans the left half × 2 rows, two stacked tiles on the right of rows 1-2, two equal halves on the bottom row. Requires exactly 5 source-order tiles; a 6th would auto-place into a new row.

To add a new layout, declare a sibling modifier with a different grid-template-areas using the same area names (hero, a, b, c, d, e) and the existing nth-child assignments map source order to those areas automatically.

Row height as a CSS variable

The grid's row height is exposed as --pa-kpi-bento-row-height (default 12rem) on .pa-kpi-bento. Override per instance for taller or shorter tiles: style="--pa-kpi-bento-row-height: 14rem". The three rows of the default layout share the same height (= total grid height is 3× the row variable), so the variable controls both the per-row tile height and the overall card body height.

Sparkline-behind-value layering

Each tile is an internal 2-row grid ("label delta" / "value value"). The value sits at the bottom-left layered over an absolutely-positioned chart underneath it (z-index: 1 on the value, z-index: 0 on the chart). The sparkline reads through behind the digits rather than living in its own column. Polygon fill is opacity: 0.10 and polyline is stroke-opacity: 0.55 so the chart doesn't compete with the headline number.

Container-relative typography

Hero value: clamp(3.6rem, 22cqi, 7rem). Non-hero: clamp(2rem, 14cqi, 3.2rem). cqi resolves against the tile's width (each tile is its own container via container-type: inline-size), not the card's. So at narrow page-grid widths the digits scale down without manual breakpoints, and at wide canonical widths the hero number gets dramatic without overflowing.

Narrow-width collapse

Card-level container query at max-width: 700px collapses the whole bento to a single-column stack and resets grid-area: auto on every tile so the same markup works inside narrow page-grid cells (1×3 widths, 25% asymmetric placements).

Hover detail popover

Cursor-anchored via Floating UI's computePosition + virtual reference element built from e.clientX/clientY. Same recipe as the other KPI showcases. Sparkline trailing dots use the SVG <circle> → HTML <span> conversion to stay circular at non-square chart aspect ratios (the chart's preserveAspectRatio="none" would otherwise stretch the dot into an oval).


CSS Classes Reference

Card structure

  • pa-kpi-bento — page-namespace class on .pa-card. Declares --pa-kpi-bento-row-height (default 12rem).
  • pa-kpi-header — flex header with title + LIVE indicator.
  • pa-kpi-live / pa-kpi-live__dot — LIVE pill + animated dot.
  • pa-kpi-bento__body — card body with internal padding (the bento's outer breathing room).
  • pa-kpi-bento__grid — 6×3 named-area grid; :nth-child rules assign each tile to its area. Default layout puts the hero on the left.
  • pa-kpi-footer — flex footer caption.

Layout modifiers

  • pa-kpi-bento__grid--hero-right — mirror of default; hero on the right half. Same 6-tile contract.
  • pa-kpi-bento__grid--5-tile — 5-tile variant (hero + 4 supporting; two equal halves on bottom row). Requires exactly 5 tiles.

Layout CSS variables

  • --pa-kpi-bento-row-height — row height for all three rows of the grid (default 12rem). Override per instance via style="--pa-kpi-bento-row-height: 14rem".

Tiles

  • pa-kpi-bento-tile — single tile (declares its own container-type: inline-size for cqi-relative typography). Carries --pa-kpi-accent.
  • pa-kpi-bento-tile--hero — hero modifier: bigger value (22cqi), bigger min-height in collapsed mode.
  • pa-kpi-bento-tile--positive / --negative / --neutral / --up-strong / --down-strong — sentiment modifiers setting --pa-kpi-accent on the tile.

Tile content

  • pa-kpi-bento-tile__label — uppercase mono caption (top-left of the internal 2-row grid).
  • pa-kpi-bento-tile__delta — coloured Δ% (top-right; reads --pa-kpi-accent).
  • pa-kpi-bento-tile__value — focal number row (bottom span of the tile, layered over the chart at z-index: 1).
  • pa-kpi-bento-tile__num / pa-kpi-bento-tile__unit — numeric + unit spans inside __value.
  • pa-kpi-bento-tile__chart — absolutely-positioned chart wrapper (z-index: 0, sits behind the value).
  • pa-kpi-bento-tile__chart-svg — fixed-height pinned-to-bottom span containing the SVG (so vertical stretch doesn't distort the line).

Hover detail popover

  • pa-kpi-detail — popover root (moved to <body> on init; position: fixed, hidden until data-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.
Type / for commands, : to search a category, or just start typing

Settings

Body text size. All elements scale proportionally.
👤

John Doe

Administrator
  • 📊 Dashboard
  • 📝 Forms
  • 📋 Tables
  • 📊 Data Grid