Pages
Teams & Users — Strip Metrics

Source: qdash /teams — c67 strip metric exploration, 2026-08-15

The v7 Teams strip only speaks spend. This page brainstorms every per-team metric the data already supports, picks five for a lens switcher, and works out the visual grammar — because the thin bar means something different per metric family, and it must not lie. Everything here derives from /api/costs.by_team plus a client rollup of userRollups() — no backend work.

Catalog

Every metric the strip could speak

Grouped by family, mapped to the page's ranked jobs. Per-team trends are off the table — the daily series is fleet-wide only. Identity is mostly degenerate per team (members are mapped by definition): the amber Unassigned chip, not a metric, carries J3.

FamilyMetricQuestion it answersJobIn the select?
SpendCost /30dWhere does the money go?J2yes
Spend$ / personWho burns hottest per head? (raw spend just ranks team size)J2 J4yes
SpendTokens /30dSame, token-denominatedJ2Cost Center owns the $/Tokens unit toggle — a metric × unit matrix answers nothing new
SpendCalls /30dRaw request volumeJ2weak story; correlates with tokens
AdoptionActive nowIs anyone on right now? The only near-real-time signalJ4 J1yes
AdoptionAgents / person"Tried it once" vs "runs a stack"J4yes
AdoptionPeopleHow big is the observed team?J3 J4permanent sub-line anchor instead — the denominator of half the metrics
AdoptionSessions /30dUsage intensityJ4correlates with spend, weaker story
AdoptionLast active / new this weekDormant teams, growth edgeJ4tooltip + roster material, not a lens
AdoptionModels breadthExploration vs standardizationJ4 J2niche; tooltip material
RiskAt-risk peopleWhich team needs me now?J1yes
RiskCrit / Elev countsHow bad, exactly?J1folded into the Risk lens sub-line
RiskFindings · DLP opensOpen review debt, data exposureJ1tooltip; roster columns own the detail
RiskΣ riskScoreSortable compositeJ1sort-only — a heuristic ordering signal, never displayed
IdentityAlias countAttribution debt inside a mapped teamJ3tooltip; the amber chip carries J3
Live

The strip with a lens switcher

UxTabGroup (the c66 Cost Center idiom — a lens is a mode, exactly one always selected). Sort follows the metric, descending; the amber Unassigned chip always pins last, so the row's one landmark stays put through reorders. Switch to Risk and watch the bars disappear — severity is never a length.

Teams

Meridian — 14 people · 4 teams
click filters the roster · estimated · same /api/costs rollup Cost Center reads

Teams

at scale — 214 people · 26 teams · top 5 by the selected lens
the cap re-ranks with the lens — which five teams you see depends on the question you asked
at scale the top-5 cap re-ranks per lens — Research surfaces under $/person, Support-Ops under Active, Core-Banking under Risk; none of them are top-5 spenders · the chip's geometry never changes, only what the number, bar, and sub-line mean
Encodings

Four semantics, one chip

The bar is the danger zone: it must not imply "share of a whole" when the metric isn't one. One rule per family, and the Unassigned chip's participation decided per metric.

Share of totalSpend

Today's grammar, kept: grey fill, widths sum to 100% across chips, "% · people" sub-line. The bar answers "how is the whole divided."

Unassigned: participates fully — its share of spend is the amber chip's whole point.

Per-person, scaled to max$/person · Agents

Bars no longer sum — the hottest team is full-width, others relative. Two guards against misreading as share: the % leaves the sub-line, and the fill stays the same magnitude grey (one hue, still a quantity).

Unassigned: denominates by identity ("$67 per identity") — a genuinely useful which-pool-to-map-first signal.

Fraction of self — a meterActive

Own denominator per chip (2 of 4), so it's a meter, not a share bar: success-hue fill on a success-tinted track. The hue switch is deliberate — it announces the semantic switch at a glance. Value is "2/4" mono.

Unassigned: kept — running state exists for unmapped identities too, and "3 of 61 running right now" is the best catch-them-in-the-act mapping prompt on the page.

Counts with severity — no barRisk

A magnitude bar invites "3 Elevated > 1 Critical," which is backwards — and status colors never encode length. The track slot stays empty (chip height never changes); the value is the at-risk count toned by worst level; the sub-line spells "1 Crit · 2 Elev" in words. Clear teams say "clear," quietly — calm chips make hot ones pop.

Unassigned: participates fully — risk among unmapped identities is the sharpest J1×J3 intersection on the page.

Notes

Decisions & ship notes

UxTabGroup, not FilterGroup, not a dropdown

A lens is a mode: exactly one always selected — TabGroup's contract. FilterGroup deselects to null (a "no metric" strip) and its styling reads as scoping the data. A dropdown hides the option space; five flat labels invite lens-flipping at one click each. Precedent: c66's $/Tokens toggle — the page teaches one switching idiom.

Sort follows the lens; Unassigned pins last

Re-ranking is the payoff of switching — at scale the top-5 cap changes membership (Research under $/person, Support-Ops under Active, Core-Banking under Risk; none are top-5 spenders). The amber chip stays last before the Cost Center tail, so the row's landmark survives every reorder. The tail card never changes with the lens.

URL, tooltip, estimated

Ship with ?teamsBy= riding useUrlState (a Slack link lands someone in the triage view). Hover = the full stat sheet — all five numbers + people, so the lens picks what's comparable and the tooltip answers the follow-up. by_team rows carry an estimated bool — an asterisk on the $ value per estimated team beats the blanket caption.

Ship track: teamRollups() + the data seam

$ comes from /api/costs.by_team (server-attributed); people/active/agents/risk come from a client teamRollups() — the natural sibling of userRollups() in fleet-rollups.ts, unit-tested the same way. The two "unassigned" sets can disagree at the margin (by_team's unknown bucket vs the rollup's NO_IDENTITY + unmapped) — build the chip list as the union keyed by team name, same accepted seam as the page's stat tiles. Optional, flagged: Risk-lens chip click could pre-apply the "risk: any open" roster filter.

Qpoint Brand Style Guide