Spec
Intent
Self-contained progress widget — the ring shows fraction, the centred label tells you what fraction and of what.
Acceptance Criteria
- [ ] Thin radial ring with proportional fill
- [ ] Centred two-line label: value + qualifier
- [ ] Token-driven colour
- [ ] Negative: does NOT crop label on overflow
Constraints
- Pure SVG + HTML overlay
- Theme-aware
// progress-ring-with-center-label.astro
---
import type { CompendiumMeta } from '../../../data/types';
export const meta: CompendiumMeta = {
id: 705,
slug: 'progress-ring-with-center-label',
name: 'Progress Ring With Centre Label',
category: 'metrics-telemetry',
subcategory: 'gauges',
pillar: 'de',
description: 'Progress ring with a two-line centred label — value above, qualifier below.',
spec: `## Intent
Self-contained progress widget — the ring shows fraction, the centred label tells you what fraction and of what.
## Acceptance Criteria
- [ ] Thin radial ring with proportional fill
- [ ] Centred two-line label: value + qualifier
- [ ] Token-driven colour
- [ ] Negative: does NOT crop label on overflow
## Constraints
- Pure SVG + HTML overlay
- Theme-aware`,
tags: ['svg', 'gauge', 'real-content', 'responsive'],
status: 'stable',
health: { ics: 87, a11y: 'aa', themed: true, animated: false },
};
const done = 17;
const total = 24;
const value = Math.round((done / total) * 100);
const r = 44;
const c = 2 * Math.PI * r;
const dashOffset = c * (1 - value / 100);
---
<div data-this-component class="w-full bg-paper text-black border-4 border-black p-4 flex items-center justify-center overflow-hidden">
<div class="relative">
<svg viewBox="0 0 100 100" class="w-28 h-28 block -rotate-90" aria-label={`${done} of ${total} done`}>
<circle cx="50" cy="50" r={r} fill="none" stroke="var(--color-ink)" stroke-width="8" opacity="0.12" />
<circle cx="50" cy="50" r={r} fill="none" stroke="var(--color-de)" stroke-width="8" stroke-dasharray={c} stroke-dashoffset={dashOffset} />
</svg>
<div class="absolute inset-0 flex flex-col items-center justify-center">
<span class="font-black text-xl tabular-nums leading-none">{done}<span class="opacity-60">/{total}</span></span>
<span class="font-mono text-[9px] uppercase tracking-widest opacity-60 mt-1">runbooks</span>
</div>
</div>
</div>