Thresholds are governance crystallised into a number. Render the line itself as a primitive so any chart, gauge, or sparkline can drop it in and inherit the same visual grammar.
Acceptance Criteria
[ ] Dashed horizontal rule at the threshold value
[ ] Label clamps to the right edge with the numeric value
[ ] Metric track is rendered beneath for context
[ ] Negative: does NOT carry chart semantics — pure marker
Constraints
Pure SVG, theme-aware via tokens
Self-contained — no shared imports
// threshold-line.astro
---
import type { CompendiumMeta } from '../../../data/types';
export const meta: CompendiumMeta = {
id: 561,
slug: 'threshold-line',
name: 'Threshold Line',
category: 'governance-risk',
subcategory: 'thresholds',
pillar: 'go',
description: 'A horizontal threshold marker drawn across a metric — the line where nominal becomes a breach.',
spec: `## Intent
Thresholds are governance crystallised into a number. Render the line itself as a primitive so any chart, gauge, or sparkline can drop it in and inherit the same visual grammar.
## Acceptance Criteria
- [ ] Dashed horizontal rule at the threshold value
- [ ] Label clamps to the right edge with the numeric value
- [ ] Metric track is rendered beneath for context
- [ ] Negative: does NOT carry chart semantics — pure marker
## Constraints
- Pure SVG, theme-aware via tokens
- Self-contained — no shared imports`,
tags: ['svg', 'chart', 'real-content', 'dark-mode-tested', 'responsive'],
status: 'stable',
health: { ics: 88, a11y: 'aa', themed: true, animated: false },
};
const threshold = 70;
const series = [22, 28, 35, 41, 38, 52, 47, 61, 58, 73, 69, 64];
const max = 100;
const w = 200;
const h = 80;
const stepX = w / (series.length - 1);
const ty = h - (threshold / max) * h;
const points = series.map((v, i) => `${(i * stepX).toFixed(1)},${(h - (v / max) * h).toFixed(1)}`).join(' ');
---
<div data-this-component class="w-full bg-paper text-black border-4 border-black p-4 overflow-hidden">
<div class="flex items-baseline justify-between mb-2">
<p class="font-mono text-[10px] uppercase tracking-widest opacity-60">Metric · vs threshold</p>
<span class="font-mono text-[10px] uppercase tracking-widest opacity-60">value / 100</span>
</div>
<svg viewBox={`0 0 ${w} ${h}`} class="w-full block" role="img" aria-label={`Threshold at ${threshold}`}>
<polyline
points={points}
fill="none"
stroke="var(--color-ink)"
stroke-width="2"
stroke-linecap="square"
stroke-linejoin="miter"
/>
<line
x1="0" x2={w} y1={ty} y2={ty}
stroke="var(--color-danger)"
stroke-width="2"
stroke-dasharray="6 4"
/>
</svg>
<div class="mt-2 flex items-baseline justify-between border-t-2 border-black pt-2">
<span class="font-mono text-[10px] uppercase tracking-widest opacity-60">threshold</span>
<span class="font-black text-[14px] tabular-nums">{threshold}<span class="opacity-60 text-[10px] ms-1">/100</span></span>
</div>
</div>