Skip to main content
Compendium / Metrics & Telemetry / Badges & Deltas / Score Delta
#062

Score Delta

A "Δ +3.2" chip with directional arrow and reference period — week-over-week change at a glance.

STABLE DE
#badge #list #real-content
Live
ICS 82 Δ +3.2 WoW
Coverage 67 Δ -1.4 WoW
Drift 12 Δ 0.0 WoW
Spec

Intent

Show period-over-period change of a metric — direction and magnitude — in a single chip that fits inline next to a headline number.

Acceptance Criteria

  • [ ] Sign-aware arrow (up/down) and colour (success/danger)
  • [ ] Magnitude shown to 1 decimal place
  • [ ] Reference label ("WoW", "vs last sprint", etc.)
  • [ ] Negative: does NOT use red/green dichotomy when delta is zero

Constraints

  • Pure markup, no JS
  • Theme-aware
// score-delta.astro
---
import type { CompendiumMeta } from '../../../data/types';

export const meta: CompendiumMeta = {
  id: 62,
  slug: 'score-delta',
  name: 'Score Delta',
  category: 'metrics-telemetry',
  subcategory: 'badges-and-deltas',
  pillar: 'de',
  description: 'A "Δ +3.2" chip with directional arrow and reference period — week-over-week change at a glance.',
  spec: `## Intent
Show period-over-period change of a metric — direction and magnitude — in a single chip that fits inline next to a headline number.

## Acceptance Criteria
- [ ] Sign-aware arrow (up/down) and colour (success/danger)
- [ ] Magnitude shown to 1 decimal place
- [ ] Reference label ("WoW", "vs last sprint", etc.)
- [ ] Negative: does NOT use red/green dichotomy when delta is zero

## Constraints
- Pure markup, no JS
- Theme-aware`,
  tags: ['badge', 'list', 'real-content'],
  status: 'stable',
  health: { ics: 86, a11y: 'aa', themed: true, animated: false },
};

const items = [
  { label: 'ICS',      value: 82, delta: 3.2,  ref: 'WoW' },
  { label: 'Coverage', value: 67, delta: -1.4, ref: 'WoW' },
  { label: 'Drift',    value: 12, delta: 0,    ref: 'WoW' },
];
const colorFor = (d: number) => d > 0 ? 'bg-success text-black' : d < 0 ? 'bg-danger text-white' : 'bg-paper text-black';
const arrowFor = (d: number) => d > 0 ? '↑' : d < 0 ? '↓' : '→';
const fmt = (d: number) => (d > 0 ? '+' : '') + d.toFixed(1);
---

<div class="w-full bg-paper text-black border-4 border-black divide-y-2 divide-black">
  {items.map((it) => (
    <div class="flex items-center gap-3 px-3 py-2.5">
      <span class="font-mono text-[10px] uppercase tracking-widest opacity-60 w-16">{it.label}</span>
      <span class="font-black text-2xl tabular-nums leading-none">{it.value}</span>
      <span class={`ms-auto inline-flex items-center gap-1 border-2 border-black px-2 py-0.5 font-black text-[11px] tabular-nums ${colorFor(it.delta)}`}>
        <span class="text-sm leading-none">{arrowFor(it.delta)}</span>
        <span>Δ&nbsp;{fmt(it.delta)}</span>
      </span>
      <span class="font-mono text-[9px] uppercase tracking-widest opacity-60 w-8 text-end">{it.ref}</span>
    </div>
  ))}
</div>