Spec
Intent
A simple ring that fills as work progresses. No centre label — pair with adjacent text. Pure visual indicator.
Acceptance Criteria
- [ ] 360-degree thin ring with proportional fill
- [ ] No centre label (paired externally)
- [ ] Theme-aware tokens
- [ ] Negative: does NOT depend on JS
Constraints
- Pure SVG
- Smaller stroke than radial-percent-gauge
// progress-ring.astro
---
import type { CompendiumMeta } from '../../../data/types';
export const meta: CompendiumMeta = {
id: 704,
slug: 'progress-ring',
name: 'Progress Ring',
category: 'metrics-telemetry',
subcategory: 'gauges',
pillar: 'de',
description: 'Thin progress ring — minimal radial fill for inline progress indication.',
spec: `## Intent
A simple ring that fills as work progresses. No centre label — pair with adjacent text. Pure visual indicator.
## Acceptance Criteria
- [ ] 360-degree thin ring with proportional fill
- [ ] No centre label (paired externally)
- [ ] Theme-aware tokens
- [ ] Negative: does NOT depend on JS
## Constraints
- Pure SVG
- Smaller stroke than radial-percent-gauge`,
tags: ['svg', 'gauge', 'real-content', 'responsive'],
status: 'stable',
health: { ics: 85, a11y: 'aa', themed: true, animated: false },
};
const value = 38;
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 gap-4 overflow-hidden">
<svg viewBox="0 0 100 100" class="w-20 h-20 block -rotate-90 shrink-0" aria-label={`Progress ${value} percent`}>
<circle cx="50" cy="50" r={r} fill="none" stroke="var(--color-ink)" stroke-width="6" opacity="0.12" />
<circle cx="50" cy="50" r={r} fill="none" stroke="var(--color-de)" stroke-width="6" stroke-dasharray={c} stroke-dashoffset={dashOffset} />
</svg>
<div class="flex flex-col">
<span class="font-mono text-[10px] uppercase tracking-widest opacity-60">spec build</span>
<span class="font-black text-xl tabular-nums leading-tight">{value}%</span>
<span class="font-mono text-[9px] uppercase tracking-widest opacity-60">in progress</span>
</div>
</div>