gridsmith-ui 0.30.1 → 0.31.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +73 -1
- package/dist/charts.d.ts +114 -1
- package/dist/charts.js +1113 -206
- package/dist/charts.js.map +1 -1
- package/dist/chat.js +24 -10
- package/dist/chat.js.map +1 -1
- package/dist/{chunk-ULCACQSA.js → chunk-2Q4HOGEI.js} +16 -51
- package/dist/chunk-2Q4HOGEI.js.map +1 -0
- package/dist/{chunk-T52LAFKG.js → chunk-3J67NISC.js} +13 -15
- package/dist/chunk-3J67NISC.js.map +1 -0
- package/dist/{chunk-L6HWACK7.js → chunk-53F7GVBQ.js} +6 -3
- package/dist/chunk-53F7GVBQ.js.map +1 -0
- package/dist/{chunk-SLRTSBCJ.js → chunk-BKYWKMUN.js} +73 -678
- package/dist/chunk-BKYWKMUN.js.map +1 -0
- package/dist/{chunk-KMKBOTFR.js → chunk-EKWXPSTI.js} +10 -12
- package/dist/chunk-EKWXPSTI.js.map +1 -0
- package/dist/{chunk-SJZWEBHL.js → chunk-GP2COVJC.js} +24 -11
- package/dist/chunk-GP2COVJC.js.map +1 -0
- package/dist/{chunk-OVHBQT3Z.js → chunk-GT6M74IZ.js} +6 -6
- package/dist/{chunk-OVHBQT3Z.js.map → chunk-GT6M74IZ.js.map} +1 -1
- package/dist/{chunk-IELIF4PJ.js → chunk-HUNEJIKV.js} +3 -3
- package/dist/{chunk-IELIF4PJ.js.map → chunk-HUNEJIKV.js.map} +1 -1
- package/dist/{chunk-NEUWZUK6.js → chunk-LE72KHIE.js} +3 -4
- package/dist/chunk-LE72KHIE.js.map +1 -0
- package/dist/{chunk-OX3NNMWG.js → chunk-OFACAHRV.js} +10 -6
- package/dist/chunk-OFACAHRV.js.map +1 -0
- package/dist/{chunk-R5QXMNW7.js → chunk-OWQ7M6R7.js} +177 -27
- package/dist/chunk-OWQ7M6R7.js.map +1 -0
- package/dist/{chunk-TYNDXMBV.js → chunk-QOMP4D6V.js} +3 -3
- package/dist/{chunk-TYNDXMBV.js.map → chunk-QOMP4D6V.js.map} +1 -1
- package/dist/chunk-U7WBI4AV.js +285 -0
- package/dist/chunk-U7WBI4AV.js.map +1 -0
- package/dist/chunk-V2ARGHJN.js +755 -0
- package/dist/chunk-V2ARGHJN.js.map +1 -0
- package/dist/chunk-V73LHNRL.js +51 -0
- package/dist/chunk-V73LHNRL.js.map +1 -0
- package/dist/{chunk-UDJOIVKQ.js → chunk-XSQD3UGY.js} +77 -7
- package/dist/chunk-XSQD3UGY.js.map +1 -0
- package/dist/{chunk-ISONVOA7.js → chunk-YFHTREH5.js} +6 -8
- package/dist/chunk-YFHTREH5.js.map +1 -0
- package/dist/data-grid.js +10 -13
- package/dist/data-grid.js.map +1 -1
- package/dist/editor-mentions.js +2 -4
- package/dist/editor-mentions.js.map +1 -1
- package/dist/editor.js +3 -7
- package/dist/editor.js.map +1 -1
- package/dist/icons.js +1 -1
- package/dist/index.d.ts +104 -16
- package/dist/index.js +1075 -654
- package/dist/index.js.map +1 -1
- package/dist/kanban.js +9 -13
- package/dist/kanban.js.map +1 -1
- package/dist/resizable.js +9 -13
- package/dist/resizable.js.map +1 -1
- package/dist/virtualized.js +10 -13
- package/dist/virtualized.js.map +1 -1
- package/package.json +1 -1
- package/dist/chunk-6C2IUMY7.js +0 -46
- package/dist/chunk-6C2IUMY7.js.map +0 -1
- package/dist/chunk-7Q46JXSK.js +0 -51
- package/dist/chunk-7Q46JXSK.js.map +0 -1
- package/dist/chunk-HTXP5BMM.js +0 -38
- package/dist/chunk-HTXP5BMM.js.map +0 -1
- package/dist/chunk-ISONVOA7.js.map +0 -1
- package/dist/chunk-KMKBOTFR.js.map +0 -1
- package/dist/chunk-L6HWACK7.js.map +0 -1
- package/dist/chunk-NEUWZUK6.js.map +0 -1
- package/dist/chunk-NKUCS67T.js +0 -13
- package/dist/chunk-NKUCS67T.js.map +0 -1
- package/dist/chunk-OX3NNMWG.js.map +0 -1
- package/dist/chunk-R5QXMNW7.js.map +0 -1
- package/dist/chunk-SJZWEBHL.js.map +0 -1
- package/dist/chunk-SLRTSBCJ.js.map +0 -1
- package/dist/chunk-T52LAFKG.js.map +0 -1
- package/dist/chunk-UDJOIVKQ.js.map +0 -1
- package/dist/chunk-ULCACQSA.js.map +0 -1
- package/dist/chunk-WIUGPZOH.js +0 -88
- package/dist/chunk-WIUGPZOH.js.map +0 -1
- package/dist/chunk-YL5KD5RC.js +0 -49
- package/dist/chunk-YL5KD5RC.js.map +0 -1
package/dist/charts.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../../showcase/src/lib/chart-utils.ts","../../../showcase/src/lib/chart-categories.ts","../../../showcase/src/components/charts/ChartWrapper.tsx","../../../showcase/src/components/charts/value-format.ts","../../../showcase/src/components/charts/ChartPrimitives.tsx","../../../showcase/src/components/charts/BarChart.tsx","../../../showcase/src/components/charts/LineChart.tsx","../../../showcase/src/components/charts/AreaChart.tsx","../../../showcase/src/components/charts/PieChart.tsx","../../../showcase/src/components/charts/CompositeChart.tsx","../../../showcase/src/components/charts/ScatterChart.tsx","../../../showcase/src/components/charts/RadarChart.tsx","../../../showcase/src/components/charts/RadialBarChart.tsx","../../../showcase/src/components/charts/FunnelChart.tsx","../../../showcase/src/lib/token-algorithms.ts","../../../showcase/src/components/charts/TreemapChart.tsx","../../../showcase/src/components/charts/SankeyChart.tsx","../../../showcase/src/components/charts/Sparkline.tsx","../../../showcase/src/components/ChartContainer.tsx"],"names":["k","ChartWrapper","categoryKind","useState","useLayoutEffect","useContext","jsxs","jsx","useMemo","useEffect","forwardRef","BarChart","useRef","RechartsBarChart","Fragment","LineChart","ResponsiveContainer","RechartsLineChart","CartesianGrid","XAxis","YAxis","Tooltip","AreaChart","RechartsAreaChart","PieChart","RechartsPieChart","CompositeChart","values","lineValues","Bar","Line","ScatterChart","RechartsScatterChart","RadarChart","RechartsRadarChart","RadialBarChart","RechartsRadialBarChart","FunnelChart","RechartsFunnelChart","TreemapChart","SankeyChart","RechartsSankey","Sparkline","useId","Area"],"mappings":"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","file":"charts.js","sourcesContent":["import { useState, useLayoutEffect, useSyncExternalStore } from \"react\";\n\nconst CHART_TOKENS = [\n \"--ds-chart-1\",\n \"--ds-chart-2\",\n \"--ds-chart-3\",\n \"--ds-chart-4\",\n \"--ds-chart-5\",\n \"--ds-chart-6\",\n] as const;\n\nconst CHART_TOKENS_SOFT = [\n \"--ds-chart-1-soft\",\n \"--ds-chart-2-soft\",\n \"--ds-chart-3-soft\",\n \"--ds-chart-4-soft\",\n \"--ds-chart-5-soft\",\n \"--ds-chart-6-soft\",\n] as const;\n\nconst FALLBACK_COLORS: Record<string, string> = {\n \"--ds-chart-1\": \"#6366f1\",\n \"--ds-chart-2\": \"#d97706\",\n \"--ds-chart-3\": \"#059669\",\n \"--ds-chart-4\": \"#dc2626\",\n \"--ds-chart-5\": \"#0891b2\",\n \"--ds-chart-6\": \"#7c3aed\",\n \"--ds-chart-1-soft\": \"rgba(99, 102, 241, 0.3)\",\n \"--ds-chart-2-soft\": \"rgba(217, 119, 6, 0.3)\",\n \"--ds-chart-3-soft\": \"rgba(5, 150, 105, 0.3)\",\n \"--ds-chart-4-soft\": \"rgba(220, 38, 38, 0.3)\",\n \"--ds-chart-5-soft\": \"rgba(8, 145, 178, 0.3)\",\n \"--ds-chart-6-soft\": \"rgba(124, 58, 237, 0.3)\",\n \"--ds-bg-surface\": \"#ffffff\",\n \"--ds-border-subtle\": \"#e5e7eb\",\n \"--ds-text-primary\": \"#111827\",\n \"--ds-text-secondary\": \"#6b7280\",\n \"--ds-text-muted\": \"#9ca3af\",\n};\n\ntype Subscriber = () => void;\n\nlet modeVersion = 0;\nconst subscribers = new Set<Subscriber>();\nlet observerAttached = false;\n\nfunction attachObserver() {\n if (observerAttached || typeof document === \"undefined\") return;\n observerAttached = true;\n\n const observer = new MutationObserver((mutations) => {\n for (const m of mutations) {\n if (m.attributeName === \"data-mode\") {\n modeVersion++;\n for (const sub of subscribers) sub();\n break;\n }\n }\n });\n\n observer.observe(document.documentElement, {\n attributes: true,\n attributeFilter: [\"data-mode\"],\n });\n}\n\nfunction subscribe(cb: Subscriber) {\n attachObserver();\n subscribers.add(cb);\n return () => { subscribers.delete(cb); };\n}\n\nfunction getSnapshot() {\n return modeVersion;\n}\n\nfunction getServerSnapshot() {\n return 0;\n}\n\nexport function resolveToken(token: string): string {\n if (typeof document === \"undefined\") return FALLBACK_COLORS[token] ?? \"#6366f1\";\n const val = getComputedStyle(document.documentElement).getPropertyValue(token).trim();\n return val || FALLBACK_COLORS[token] || \"#6366f1\";\n}\n\n/**\n * The theme's chart series colours, `count` of them in series order (repeating past the palette's length), read from the\n * live tokens so they follow the theme and its mode; `soft` gives the lighter series. Before the theme's styles are\n * committed, and on the server, it returns the fallback shades, then the theme's on the next layout.\n */\nexport function useChartColors(count: number, soft = false): string[] {\n const version = useSyncExternalStore(subscribe, getSnapshot, getServerSnapshot);\n const [colors, setColors] = useState<string[]>(() => fallbackColors(count, soft));\n\n // Reads computed CSS custom properties, which only exist after the theme's\n // style tag is committed — this has to be a post-layout effect.\n /* eslint-disable react-hooks/set-state-in-effect -- token resolution is a DOM read after commit */\n useLayoutEffect(() => {\n setColors(resolveColors(count, soft));\n }, [count, soft, version]);\n /* eslint-enable react-hooks/set-state-in-effect */\n\n return colors;\n}\n\nfunction fallbackColors(count: number, soft: boolean): string[] {\n const tokens = soft ? CHART_TOKENS_SOFT : CHART_TOKENS;\n const result: string[] = [];\n for (let i = 0; i < count; i++) {\n const token = tokens[i % tokens.length];\n result.push(FALLBACK_COLORS[token] ?? \"#6366f1\");\n }\n return result;\n}\n\nfunction resolveColors(count: number, soft: boolean): string[] {\n const tokens = soft ? CHART_TOKENS_SOFT : CHART_TOKENS;\n const result: string[] = [];\n for (let i = 0; i < count; i++) {\n const token = tokens[i % tokens.length];\n result.push(resolveToken(token));\n }\n return result;\n}\n\nexport function useResolvedToken(token: string): string {\n const version = useSyncExternalStore(subscribe, getSnapshot, getServerSnapshot);\n const [value, setValue] = useState(() => FALLBACK_COLORS[token] ?? \"#6366f1\");\n\n /* eslint-disable react-hooks/set-state-in-effect -- token resolution is a DOM read after commit */\n useLayoutEffect(() => {\n setValue(resolveToken(token));\n }, [token, version]);\n /* eslint-enable react-hooks/set-state-in-effect */\n\n return value;\n}\n\nexport function useReducedMotion(): boolean {\n const [reduced, setReduced] = useState(() => {\n if (typeof window === \"undefined\") return false;\n return window.matchMedia(\"(prefers-reduced-motion: reduce)\").matches;\n });\n\n useLayoutEffect(() => {\n const mql = window.matchMedia(\"(prefers-reduced-motion: reduce)\");\n const handler = (e: MediaQueryListEvent) => setReduced(e.matches);\n mql.addEventListener(\"change\", handler);\n return () => mql.removeEventListener(\"change\", handler);\n }, []);\n\n return reduced;\n}\n\nexport const useChartAnimation = (animated?: boolean): boolean => {\n const reduced = useReducedMotion();\n return animated !== false && !reduced;\n};\n","/**\n * Sprint 25.9, A3 — what a chart's category axis holds, and how its labels fit. No Recharts here: the charts entry and\n * the tests import it, and it never measures on its own (the measurer is handed in).\n *\n * - `categoryKind(labels)`: \"scale\" when every non-empty label is a date, a time, a period or a number, else \"names\".\n * Anchored patterns only — never `Date.parse`, which V8 lets read \"Tier 1\", \"Sprint 1\" and \"Northern Region 2\" as dates.\n * - `createAxisMeasurer(el)`: canvas text widths in the axis's resolved font, read from a probe that carries\n * `font-size: var(--ds-font-size-xs)`, so a `calc()` token (`calc(16px * .75)`, a 14 px base) measures right.\n * - `fitLabel(name, width, measure)`: one line; else two lines split at a space; else \"…\" on the second. Never drops it.\n */\n\nexport type CategoryKind = \"names\" | \"scale\";\n\n/** A text's width in px in the axis font. */\nexport type Measure = (text: string) => number;\n\nconst ENGLISH_MONTHS = [\n \"january\", \"february\", \"march\", \"april\", \"may\", \"june\", \"july\", \"august\", \"september\", \"october\", \"november\", \"december\",\n \"jan\", \"feb\", \"mar\", \"apr\", \"jun\", \"jul\", \"aug\", \"sep\", \"sept\", \"oct\", \"nov\", \"dec\",\n];\nconst ENGLISH_WEEKDAYS = [\n \"monday\", \"tuesday\", \"wednesday\", \"thursday\", \"friday\", \"saturday\", \"sunday\",\n \"mon\", \"tue\", \"tues\", \"wed\", \"thu\", \"thur\", \"thurs\", \"fri\", \"sat\", \"sun\",\n];\n\nconst escape = (s: string) => s.replace(/[.*+?^${}()|[\\]\\\\]/g, \"\\\\$&\");\nconst clean = (s: string) => s.trim().toLowerCase().replace(/\\.$/, \"\");\n\nfunction intlNames(locale: string, kind: \"month\" | \"weekday\"): string[] {\n const out: string[] = [];\n try {\n for (const width of [\"short\", \"long\"] as const) {\n const fmt = new Intl.DateTimeFormat(locale, kind === \"month\" ? { month: width, timeZone: \"UTC\" } : { weekday: width, timeZone: \"UTC\" });\n // 2026-01-05 is a Monday: seven days give the weekdays, the 15th of each month the months\n const count = kind === \"month\" ? 12 : 7;\n for (let i = 0; i < count; i++) {\n const date = kind === \"month\" ? new Date(Date.UTC(2026, i, 15)) : new Date(Date.UTC(2026, 0, 5 + i));\n out.push(clean(fmt.format(date)));\n }\n }\n } catch {\n // an unknown locale tag: English covers it\n }\n return out;\n}\n\n/**\n * The languages whose month and weekday names count: English, and the locale given (a chart's locale while a\n * server-rendered page hydrates, the same on both sides: Sprint 25.20); with none given, the runtime's, the browser's and\n * the page's, as an app's own call and a chart in the browser read them (labels in the visitor's own language count).\n */\nfunction locales(given?: string): string[] {\n const out = new Set<string>([\"en\"]);\n if (given !== undefined) {\n out.add(given);\n return [...out];\n }\n try { out.add(new Intl.DateTimeFormat().resolvedOptions().locale); } catch { /* no Intl locale */ }\n if (typeof navigator !== \"undefined\" && navigator.language) out.add(navigator.language);\n if (typeof document !== \"undefined\" && document.documentElement?.lang) out.add(document.documentElement.lang);\n return [...out];\n}\n\ninterface Patterns { key: string; list: RegExp[] }\nlet cached: Patterns | null = null;\n\nfunction patterns(given?: string): Patterns {\n const tags = locales(given);\n const key = tags.join(\"|\");\n if (cached?.key === key) return cached;\n const months = new Set(ENGLISH_MONTHS);\n const weekdays = new Set(ENGLISH_WEEKDAYS);\n for (const tag of tags) {\n for (const m of intlNames(tag, \"month\")) if (m) months.add(m);\n for (const d of intlNames(tag, \"weekday\")) if (d) weekdays.add(d);\n }\n // the longest first, so \"sept\" wins over \"sep\" and \"june\" over \"jun\"\n const alt = (set: Set<string>) => [...set].sort((a, b) => b.length - a.length).map(escape).join(\"|\");\n const M = `(?:${alt(months)})\\\\.?`;\n const D = `(?:${alt(weekdays)})\\\\.?`;\n const day = String.raw`\\d{1,2}(?:st|nd|rd|th|\\.)?`;\n const year = String.raw`'?\\d{2,4}`;\n const list = [\n // dates in digits: 2026-09-21, 21/09, 09/21/2026, 21.09.2026, an ISO date-time\n /^\\d{4}[-/.]\\d{1,2}(?:[-/.]\\d{1,2})?$/,\n /^\\d{1,2}[-/.]\\d{1,2}(?:[-/.]\\d{2,4})?$/,\n /^\\d{4}-\\d{2}-\\d{2}[T ]\\d{1,2}:\\d{2}(?::\\d{2}(?:\\.\\d+)?)?(?:Z|[+-]\\d{2}:?\\d{2})?$/,\n // a day and a month in either order, and a month alone or with its year: 16 Sep, 21. Sept., Sept 21, March 2026\n new RegExp(`^${day}\\\\s*${M}(?:,?\\\\s+${year})?$`, \"iu\"),\n new RegExp(`^${M}\\\\s*${day}(?:,?\\\\s+${year})?$`, \"iu\"),\n new RegExp(`^${M}(?:\\\\s*${year})?$`, \"iu\"),\n // CJK dates: 9月21日, 2026年9月, 9월 21일\n /^(?:\\d{4}年)?\\d{1,2}月(?:\\d{1,2}日)?$/u,\n /^\\d{4}年(?:\\d{1,2}月)?$/u,\n /^(?:\\d{4}년\\s?)?\\d{1,2}월(?:\\s?\\d{1,2}일)?$/u,\n // a quarter or a half: Q3, Q3 2026, Q3 FY26, 2026 Q3, 3Q26, H1 2026\n /^Q[1-4](?:\\s*[-/']?\\s*(?:FY\\s?)?'?\\d{2,4})?$/i,\n /^[1-4]Q\\s*'?\\d{0,4}$/i,\n /^(?:FY\\s?)?'?\\d{2,4}\\s*[-/]?\\s*Q[1-4]$/i,\n /^H[12](?:\\s*'?\\d{2,4})?$/i,\n // a year or a fiscal year: 2026, FY26, FY 2025/26, 2025/26, 2025-2026\n /^(?:19|20)\\d{2}$/,\n /^FY\\s?'?\\d{2,4}(?:\\s?[-/]\\s?'?\\d{2,4})?$/i,\n /^(?:19|20)\\d{2}\\s?[-/–]\\s?(?:(?:19|20)?\\d{2})$/,\n // a week: W12, Wk 3, Week 12, Week 12 2026, 2026-W12\n /^(?:W|Wk|Week)\\.?\\s?\\d{1,2}(?:\\s*[,/-]?\\s*\\d{4})?$/i,\n /^\\d{4}-?W\\d{1,2}(?:-?\\d)?$/i,\n // a weekday: Mon, Tuesday, and the runtime and page locales' own\n new RegExp(`^${D}$`, \"iu\"),\n // a time: 09:00, 9:30 pm, 9am, 14h\n /^\\d{1,2}:\\d{2}(?::\\d{2})?\\s?(?:[ap]\\.?m\\.?)?$/i,\n /^\\d{1,2}\\s?[ap]\\.?m\\.?$/i,\n /^\\d{1,2}h(?:\\d{2})?$/i,\n // a number, a percentage or an amount: 12, -3.5, 1,200, 12%, $5k, €1.2m, 5 €, a bin (10–20, <10, 50+)\n /^[<>≤≥~]?\\s?[+\\-−]?\\s?[$€£¥₹]?\\s?\\d[\\d,. \\u00a0\\u202f]*(?:\\s?(?:k|m|mn|bn|b|t))?\\s?(?:%|[$€£¥₹])?\\+?$/iu,\n /^[$€£¥₹]?\\d[\\d,.]*\\s?[-–]\\s?[$€£¥₹]?\\d[\\d,.]*\\s?(?:k|m|bn|%)?$/iu,\n ];\n cached = { key, list };\n return cached;\n}\n\n/**\n * Whether a category axis holds names or a scale (dates, times, periods, numbers). Every non-empty label must match an\n * anchored pattern to be \"scale\"; an all-empty set is \"scale\". LineChart and AreaChart are always \"scale\"; BarChart and\n * CompositeChart guess with this, and their `categoryKind` prop overrides the guess.\n */\nexport function categoryKind(labels: ReadonlyArray<unknown>, locale?: string): CategoryKind {\n const { list } = patterns(locale);\n for (const raw of labels) {\n if (raw == null) continue;\n if (typeof raw === \"number\") { if (Number.isFinite(raw)) continue; return \"names\"; }\n if (raw instanceof Date) continue;\n const text = String(raw).trim();\n if (!text) continue;\n if (!list.some((re) => re.test(text))) return \"names\";\n }\n return \"scale\";\n}\n\n/* ── Measuring ──────────────────────────────────────────────────────────── */\n\n/** The axis font as the page resolves it: size and family from a probe carrying the chart's tick tokens. */\nexport function resolvedAxisFont(el: Element): { font: string; px: number } {\n const doc = el.ownerDocument;\n const view = doc.defaultView;\n let probe = el.querySelector<HTMLElement>(\"[data-chart-probe]\");\n let temporary = false;\n if (!probe) {\n probe = doc.createElement(\"span\");\n probe.setAttribute(\"aria-hidden\", \"true\");\n probe.style.cssText = \"position:absolute;visibility:hidden;pointer-events:none;white-space:nowrap;font-size:var(--ds-font-size-xs);font-family:var(--ds-font-sans)\";\n el.appendChild(probe);\n temporary = true;\n }\n const cs = view?.getComputedStyle(probe);\n const px = parseFloat(cs?.fontSize ?? \"\") || 12;\n const family = (cs?.fontFamily ?? \"\").trim() || \"sans-serif\";\n const style = cs?.fontStyle && cs.fontStyle !== \"normal\" ? `${cs.fontStyle} ` : \"\";\n const weight = cs?.fontWeight && cs.fontWeight !== \"400\" && cs.fontWeight !== \"normal\" ? `${cs.fontWeight} ` : \"\";\n if (temporary) probe.remove();\n return { font: `${style}${weight}${px}px ${family}`, px };\n}\n\n/** One 2D context for every chart, kept per getContext implementation (a test may swap it for a stub). */\nlet shared: { getContext: unknown; ctx: CanvasRenderingContext2D | null } | null = null;\n\nfunction canvasContext(): CanvasRenderingContext2D | null {\n if (typeof document === \"undefined\") return null;\n const getContext = (globalThis as { HTMLCanvasElement?: { prototype: { getContext?: unknown } } }).HTMLCanvasElement?.prototype.getContext;\n if (shared && shared.getContext === getContext) return shared.ctx;\n let ctx: CanvasRenderingContext2D | null = null;\n try { ctx = document.createElement(\"canvas\").getContext?.(\"2d\") ?? null; } catch { ctx = null; }\n shared = { getContext, ctx };\n return ctx;\n}\n\n/**\n * A text measurer in the chart's own axis font, or null where there is no canvas (jsdom): the charts then show every\n * label in full on one line and leave the thinning to nobody.\n */\nexport function createAxisMeasurer(el: Element): { measure: Measure; px: number; font: string } | null {\n const ctx = canvasContext();\n if (!ctx) return null;\n const { font, px } = resolvedAxisFont(el);\n ctx.font = font;\n const widths = new Map<string, number>();\n const measure: Measure = (text) => {\n let w = widths.get(text);\n if (w === undefined) {\n // the context is shared: another chart may have set its own font since\n ctx.font = font;\n w = ctx.measureText(text).width;\n widths.set(text, w);\n }\n return w;\n };\n return { measure, px, font };\n}\n\n/* ── Fitting a name ─────────────────────────────────────────────────────── */\n\nexport const ELLIPSIS = \"…\";\n\nexport interface FittedLabel {\n /** One or two lines; the second ends with \"…\" when the name was cut. */\n lines: string[];\n cut: boolean;\n /** Characters of the name that show, spaces and the ellipsis left out. */\n shown: number;\n}\n\nconst letters = (s: string) => s.replace(/\\s+/g, \"\").replace(/…/g, \"\").length;\n\n/** The longest prefix of `text` that fits `width` (at least one character). */\nfunction prefixThatFits(text: string, width: number, measure: Measure, suffix = \"\"): number {\n let lo = 1;\n let hi = text.length;\n let best = 0;\n while (lo <= hi) {\n const mid = (lo + hi) >> 1;\n if (measure(text.slice(0, mid).trimEnd() + suffix) <= width) { best = mid; lo = mid + 1; } else hi = mid - 1;\n }\n return best;\n}\n\n/**\n * A name fitted to `width`: one line when it fits; else two lines split at a space; else the second line ends with \"…\".\n * A first word wider than the line breaks where the line ends, with a hyphen, so it reads as one word going on. The\n * name is never dropped, and without a measurer it shows in full on one line.\n */\nexport function fitLabel(name: string, width: number, measure: Measure | null): FittedLabel {\n const text = name.replace(/\\s+/g, \" \").trim();\n if (!measure || !text || width <= 0 || measure(text) <= width) return { lines: [text], cut: false, shown: letters(text) };\n const words = text.split(\" \");\n let first = \"\";\n let firstShown = \"\";\n let rest = \"\";\n for (let i = words.length - 1; i >= 1; i--) {\n const candidate = words.slice(0, i).join(\" \");\n if (measure(candidate) <= width) { first = firstShown = candidate; rest = words.slice(i).join(\" \"); break; }\n }\n if (!first) {\n // the first word alone is too wide: the first line holds what fits of it and a hyphen\n const k = Math.max(1, prefixThatFits(text, width, measure, \"-\"));\n firstShown = text.slice(0, k).trimEnd();\n rest = text.slice(k).trimStart();\n first = rest && !text.slice(k - 1, k + 1).includes(\" \") ? `${firstShown}-` : firstShown;\n }\n if (!rest) return { lines: [first], cut: false, shown: letters(firstShown) };\n if (measure(rest) <= width) return { lines: [first, rest], cut: false, shown: letters(firstShown) + letters(rest) };\n const k = prefixThatFits(rest, width, measure, ELLIPSIS);\n const kept = k > 0 ? rest.slice(0, k).trimEnd() : \"\";\n return { lines: [first, kept + ELLIPSIS], cut: true, shown: letters(firstShown) + letters(kept) };\n}\n\n/** D8: fewer visible characters than this on a cut name turns an upright chart of names sideways. */\nexport const MIN_NAME_CHARS = 6;\n\n/** Whether any name, fitted to `width`, would be cut to fewer than MIN_NAME_CHARS characters. */\nexport function namesCutShort(names: ReadonlyArray<string>, width: number, measure: Measure): boolean {\n return names.some((n) => {\n const fit = fitLabel(n, width, measure);\n return fit.cut && fit.shown < MIN_NAME_CHARS;\n });\n}\n","import {\n Children, createContext, forwardRef, isValidElement, useContext, useEffect, useLayoutEffect, useMemo, useRef, useState,\n type CSSProperties, type KeyboardEvent, type ReactNode, type Ref,\n} from \"react\";\nimport { cn } from \"../../lib/utils\";\nimport { elementType } from \"../../lib/element-type\";\nimport { mergeRefs } from \"../../lib/slot\";\n\n/* ── Heights ────────────────────────────────────────────────────────────── */\n\n/** A chart's height: \"auto\" (the default) sizes it from its type and its data; a preset or a number overrides. */\nexport type ChartHeight = \"auto\" | \"sm\" | \"md\" | \"lg\" | number;\n\nexport const CHART_HEIGHTS = {\n sm: \"var(--ds-chart-height-sm)\",\n md: \"var(--ds-chart-height-md)\",\n lg: \"var(--ds-chart-height-lg)\",\n} as const;\n\n/** One row of a row chart (a sideways bar, a funnel stage). */\nexport const CHART_ROW = \"var(--ds-chart-row, 2rem)\";\n\n/** A preset or a number as a CSS height; \"auto\" has none (the chart sizes itself). */\nexport function fixedChartHeight(height: ChartHeight | undefined): string | undefined {\n if (typeof height === \"number\") return `${height}px`;\n if (height === \"sm\" || height === \"md\" || height === \"lg\") return CHART_HEIGHTS[height];\n return undefined;\n}\n\n/**\n * How a chart sizes itself (Sprint 25.9, A2, P2):\n * - \"rows\" (a sideways BarChart, a FunnelChart): a row per item, never under sm; `units` rows, `lines` extra label lines\n * (a two-line name makes its row one line taller), `axis` the value axis and titles below or above the rows;\n * - \"ratio\" (charts over dates or numbers, Treemap, Sankey): two wide to one high, between sm and lg;\n * - \"square\" (Pie, Radar, RadialBar): as tall as wide, between sm and lg.\n */\nexport type ChartSize =\n | { model: \"ratio\" }\n | { model: \"square\" }\n | { model: \"rows\"; units: number; lines?: number; axis?: string };\n\nconst SM = CHART_HEIGHTS.sm;\nconst LG = CHART_HEIGHTS.lg;\n\n/**\n * The plot box's height and its bound in a row. `cqi` resolves against the chart's wrapper, the size container, because\n * the plot box is its child (on the wrapper itself it would read the page's container). The box is `flex: 1 0 auto`,\n * never `flex-1`: its drawing is absolute, so a zero basis would collapse it (R5). In a row it grows to the row's\n * height up to a bound: a ratio chart to square, a row chart to twice its height, a round chart not at all.\n */\nexport function plotBoxStyle(size: ChartSize, fixed: string | undefined): CSSProperties {\n if (size.model === \"square\") {\n return { height: fixed ?? `clamp(${SM}, 100cqi, ${LG})`, flex: \"0 0 auto\" };\n }\n if (size.model === \"rows\") {\n const lines = size.lines ? ` + ${size.lines} * 1.25 * var(--ds-font-size-xs)` : \"\";\n const height = fixed ?? `max(${SM}, calc(${size.units} * ${CHART_ROW}${lines} + ${size.axis ?? CHART_ROW}))`;\n return { height, maxHeight: `calc(2 * ${height})`, flex: \"1 0 auto\" };\n }\n return { height: fixed ?? `clamp(${SM}, 50cqi, ${LG})`, maxHeight: `max(${fixed ?? LG}, 100cqi)`, flex: \"1 0 auto\" };\n}\n\n/* ── The chart mark ─────────────────────────────────────────────────────── */\n\n/**\n * Marks the library's charts, so ChartContainer knows its child sizes itself and needs no minimum area of its own.\n * `Symbol.for`, as PAGE_HEADER_MARK, so a second copy of the module still matches. A hand-built chart, an EmptyState\n * or a Sparkline carries no mark and keeps the container's area.\n */\nexport const CHART_MARK: unique symbol = Symbol.for(\"gridsmith.Chart\") as never;\n\nexport function markChart<T extends object>(component: T): T {\n Object.assign(component, { [CHART_MARK]: true });\n return component;\n}\n\n/** A single library chart (not a Fragment, a wrapper of the builder's or a list of children). */\nexport function isLibraryChart(children: ReactNode): boolean {\n const kids = Children.toArray(children);\n if (kids.length !== 1) return false;\n const only = kids[0];\n if (!isValidElement(only)) return false;\n const type = elementType(only.type) as Record<symbol, unknown> | string | null;\n return !!type && typeof type !== \"string\" && type[CHART_MARK] === true;\n}\n\n/* ── Context ────────────────────────────────────────────────────────────── */\n\nexport interface ChartContainerValue {\n /** The container's own height (a preset or a number, as CSS): it beats the chart's. */\n height?: string;\n /** The container title's id: the chart's graphic is named by it. */\n titleId?: string;\n /** The chart is not the container's only child (or is wrapped): it fills the container's area instead of sizing itself. */\n fillArea?: boolean;\n}\n\nexport const ChartContainerContext = createContext<ChartContainerValue | null>(null);\n\nexport function useInsideChartContainer(): boolean {\n return useContext(ChartContainerContext) !== null;\n}\n\n/** The chart's slots outside its drawing: the legend (Recharts' Legend portals into it) and the tooltip's live region. */\nexport interface ChartFrame {\n legend: HTMLElement | null;\n live: HTMLElement | null;\n /** A value in full, with its unit, for the tooltip and what the chart says (Sprint 25.17 A27); toLocaleString without one. */\n formatValue?: (value: number, dataKey?: string) => string;\n}\n\nexport const ChartFrameContext = createContext<ChartFrame>({ legend: null, live: null });\n\n/* ── Keyboard ───────────────────────────────────────────────────────────── */\n\nconst REMAPPED = new WeakSet<Event>();\n\n/**\n * A sideways chart lists its rows top to bottom. Recharts maps only ArrowLeft and ArrowRight, and in that layout reads\n * ArrowRight as the row above. Down and Right move to the next row, Up and Left to the one before, in reading order.\n */\nfunction remapRowKeys(e: KeyboardEvent<HTMLDivElement>) {\n if (REMAPPED.has(e.nativeEvent)) return;\n const next = e.key === \"ArrowDown\" || e.key === \"ArrowRight\";\n const previous = e.key === \"ArrowUp\" || e.key === \"ArrowLeft\";\n if (!next && !previous) return;\n const target = e.target as Element;\n if (!target.closest?.(\".recharts-wrapper\")) return;\n e.preventDefault();\n e.stopPropagation();\n const View = target.ownerDocument.defaultView ?? window;\n const event = new View.KeyboardEvent(\"keydown\", { key: next ? \"ArrowLeft\" : \"ArrowRight\", bubbles: true, cancelable: true });\n REMAPPED.add(event);\n target.dispatchEvent(event);\n}\n\n/* ── The wrapper ────────────────────────────────────────────────────────── */\n\nexport interface ChartWrapperProps {\n /** The chart's own height prop. A ChartContainer's preset or number beats it. */\n height?: ChartHeight;\n /** How the chart sizes itself when no height is set. */\n size: ChartSize;\n /** The chart type, for `data-gs-chart` (the bench reads it). */\n chart: string;\n /** A cartesian category axis: its kind and its categories (`data-category-kind`, `data-categories`). */\n categoryKind?: \"names\" | \"scale\";\n categories?: number;\n /** Which axis carries the categories, for the label counts (`data-labels-shown`, `data-labels-cut`). */\n categoryAxis?: \"x\" | \"y\";\n /** The rows run top to bottom (a sideways BarChart): the arrow keys follow them. */\n sideways?: boolean;\n /** The value axis's title, drawn horizontally above the axis (the chart leaves room at the top). */\n axisTitle?: string;\n className?: string;\n children: ReactNode;\n /** The chart's values in full, for its tooltip, by series (Sprint 25.17 A27). */\n formatValue?: (value: number, dataKey?: string) => string;\n \"aria-label\"?: string;\n}\n\n/**\n * Sprint 25.9, A2: the chart's frame and its size container. It holds the plot box (the Recharts drawing sits absolutely\n * inside it), the legend's slot below and the tooltip's live region, and owns the height, with or without a\n * ChartContainer. `min-inline-size` keeps a shrink-to-fit parent from collapsing it.\n */\nexport const ChartWrapper = forwardRef<HTMLDivElement, ChartWrapperProps>(function ChartWrapper({\n height = \"auto\",\n size,\n chart,\n categoryKind,\n categories,\n categoryAxis,\n sideways = false,\n axisTitle,\n className,\n children,\n formatValue,\n \"aria-label\": ariaLabel,\n}, ref) {\n const container = useContext(ChartContainerContext);\n const rootRef = useRef<HTMLDivElement | null>(null);\n const plotRef = useRef<HTMLDivElement | null>(null);\n const [legend, setLegend] = useState<HTMLDivElement | null>(null);\n const [live, setLive] = useState<HTMLDivElement | null>(null);\n const frame = useMemo<ChartFrame>(() => ({ legend, live, formatValue }), [legend, live, formatValue]);\n // The drawing never shrinks below the plot box's last real size. A box sized with `cqi` reports a width of 0 for a\n // moment while headless Chrome takes a full-page screenshot; handed to Recharts, that cleared the drawing, so the\n // screenshot showed an empty chart or bars growing again from zero (measured). A reading of 0 is no layout: the\n // drawing keeps its size, grows at once and shrinks a frame later.\n const [drawn, setDrawn] = useState<{ width: number; height: number } | null>(null);\n useLayoutEffect(() => {\n const plot = plotRef.current;\n if (!plot || typeof ResizeObserver === \"undefined\") return;\n const observer = new ResizeObserver((entries) => {\n const box = entries[entries.length - 1]?.contentRect;\n if (!box || box.width <= 0 || box.height <= 0) return;\n setDrawn((prev) => (prev && Math.abs(prev.width - box.width) < 0.5 && Math.abs(prev.height - box.height) < 0.5 ? prev : { width: box.width, height: box.height }));\n });\n observer.observe(plot);\n return () => observer.disconnect();\n }, []);\n\n const fill = container?.fillArea === true;\n const fixed = container?.height ?? fixedChartHeight(height);\n const plotStyle: CSSProperties = fill ? { flex: \"1 1 0%\", minHeight: 0 } : plotBoxStyle(size, fixed);\n\n // The graphic is named by the chart's own label, else by its container's title (A1).\n const named = ariaLabel\n ? { role: \"img\", \"aria-label\": ariaLabel }\n : container?.titleId\n ? { role: \"img\", \"aria-labelledby\": container.titleId }\n : {};\n\n // A8: how many category labels show, and how many were shortened, counted on the rendered ticks.\n useEffect(() => {\n const root = rootRef.current;\n const plot = plotRef.current;\n if (!root || !plot || !categoryAxis || typeof MutationObserver === \"undefined\") return;\n const selector = `.recharts-${categoryAxis}Axis-tick-labels .recharts-cartesian-axis-tick-value`;\n const count = () => {\n const labels = Array.from(plot.querySelectorAll(selector)).filter((el) => (el.textContent ?? \"\").trim() !== \"\");\n const shown = String(labels.length);\n const cut = String(labels.filter((el) => el.hasAttribute(\"data-cut\")).length);\n if (root.getAttribute(\"data-labels-shown\") !== shown) root.setAttribute(\"data-labels-shown\", shown);\n if (root.getAttribute(\"data-labels-cut\") !== cut) root.setAttribute(\"data-labels-cut\", cut);\n };\n count();\n const observer = new MutationObserver(count);\n observer.observe(plot, { subtree: true, childList: true, characterData: true, attributes: true, attributeFilter: [\"data-cut\"] });\n return () => observer.disconnect();\n }, [categoryAxis]);\n\n return (\n <div\n ref={mergeRefs(ref as Ref<HTMLElement>, rootRef as Ref<HTMLElement>) as Ref<HTMLDivElement>}\n data-gs-chart={chart}\n data-category-kind={categoryKind}\n data-categories={categories}\n className={cn(\"relative flex w-full flex-col\", fill && \"h-full\", className)}\n style={{ containerType: \"inline-size\", minInlineSize: \"min(100%, 16rem)\", ...(fill ? {} : { flex: \"1 0 auto\" }) }}\n >\n <div\n ref={plotRef}\n data-chart-plot=\"\"\n className=\"relative w-full\"\n style={plotStyle}\n onKeyDownCapture={sideways ? remapRowKeys : undefined}\n {...named}\n >\n {axisTitle && (\n <span data-chart-axis-title=\"\" className=\"absolute left-0 top-0 whitespace-nowrap text-xs text-[var(--ds-text-muted)] font-[family-name:var(--ds-font-sans)] leading-normal\">\n {axisTitle}\n </span>\n )}\n <div className=\"absolute inset-0\" style={drawn ? { minWidth: drawn.width, minHeight: drawn.height } : undefined}>\n <ChartFrameContext.Provider value={frame}>{children}</ChartFrameContext.Provider>\n </div>\n </div>\n <div ref={setLegend} data-chart-legend=\"\" />\n <div ref={setLive} role=\"status\" aria-live=\"polite\" className=\"sr-only\" />\n {/* the axis font and one row, as the page resolves them (useAxisMeasure reads it) */}\n <span\n data-chart-probe=\"\"\n aria-hidden=\"true\"\n className=\"pointer-events-none invisible absolute left-0 top-0\"\n style={{ fontSize: \"var(--ds-font-size-xs)\", fontFamily: \"var(--ds-font-sans)\", height: CHART_ROW, width: 0 }}\n />\n </div>\n );\n});\n","import { getNiceTickValues } from \"recharts\";\n\n/**\n * How a chart's values read (Sprint 25.17 A27, R28-50, P21). \"number\" (the default): plain numbers, compact on the axis\n * from five digits up (1M, 750K; 1,234 as it is). \"percent\": values are percentages out of 100 (45 reads 45%; multiply a fraction by\n * 100 first). \"milliseconds\": durations in ms (120 ms, 1.5 s, 2 min). \"bytes\": sizes in bytes, in the units of 1,000 the\n * browser's own formats name (1.5 MB). A function formats both the axis and the tooltip itself. Everything is in the\n * page's language (its `lang`, in the visitor's formats where they speak it: formatLocale).\n */\nexport type ValueFormat = \"number\" | \"percent\" | \"milliseconds\" | \"bytes\" | ((value: number) => string);\n\n/** Recharts draws a value axis with five ticks on a nice scale that includes 0 (its default domain, [0, \"auto\"]). */\nconst TICK_COUNT = 5;\n\nconst TIME_UNITS: Array<[unit: string, ms: number]> = [[\"hour\", 3_600_000], [\"minute\", 60_000], [\"second\", 1_000], [\"millisecond\", 1]];\nconst BYTE_UNITS: Array<[unit: string, bytes: number]> = [[\"petabyte\", 1e15], [\"terabyte\", 1e12], [\"gigabyte\", 1e9], [\"megabyte\", 1e6], [\"kilobyte\", 1e3], [\"byte\", 1]];\n\n/** Fraction digits tried before giving up on an exact label (a value with more is shown to this many). */\nconst MAX_FRACTION = 10;\n\n/**\n * A value as `format` writes it with the fewest fraction digits that show it exactly, in the locale's own notation:\n * 2,500 is \"2.5K\" in English and 15,000 \"1.5万\" in Japanese, 0.0004 is \"0.0004\" — never a rounded \"3K\", \"2万\" or \"0\"\n * (Sprint 25.17's review: digits counted in thousands misread the locales that group by 万 or by lakh, and a cap of\n * three turned small rates into a row of zeros). Exact means more digits change nothing.\n */\nfunction exact(format: (digits: number) => string, maxDigits = MAX_FRACTION): string {\n for (let digits = 0; digits < maxDigits; digits++) {\n const label = format(digits);\n if (label === format(digits + 6)) return label;\n }\n return format(maxDigits);\n}\n\nconst unitFormat = (unit: string, value: number, locale: string | undefined) => (digits: number) =>\n new Intl.NumberFormat(locale, { style: \"unit\", unit, unitDisplay: \"short\", maximumFractionDigits: digits }).format(value);\n\nconst unitsOf = (format: \"milliseconds\" | \"bytes\") => (format === \"bytes\" ? BYTE_UNITS : TIME_UNITS);\n\n/** The largest unit a value reaches (1.5 MB, 120 ms), for a value read on its own. */\nfunction unitReached(units: Array<[string, number]>, value: number): [string, number] {\n return units.find(([, size]) => Math.abs(value) >= size) ?? units[units.length - 1];\n}\n\n/**\n * One unit for a whole axis (the review: \"0 ms, 25 sec, 1.25 min\" chose it tick by tick): the largest its biggest tick\n * reaches in which every tick reads exactly in two fraction digits or fewer, so 25 s and 75 s stay seconds where minutes\n * would read 0.417.\n */\nfunction axisUnit(units: Array<[string, number]>, ticks: number[]): [string, number] {\n const largest = Math.max(0, ...ticks.map(Math.abs));\n const exactIn = (size: number) => ticks.every((t) => Math.abs((t / size) * 100 - Math.round((t / size) * 100)) < 1e-6);\n return units.find(([, size]) => largest / size >= 1 && exactIn(size)) ?? units[units.length - 1];\n}\n\n/** The ticks Recharts draws for these values on a value axis. */\nexport function valueAxisTicks(values: number[]): number[] {\n const finite = values.filter(Number.isFinite);\n if (!finite.length) return [];\n const lo = Math.min(0, ...finite);\n const hi = Math.max(0, ...finite);\n if (lo === hi) return [lo];\n return getNiceTickValues([lo, hi], TICK_COUNT, true).map(Number);\n}\n\n/**\n * A value axis's tick labels: compact from five digits up, in the chart's locale (its useFormatLocale(), Sprint 25.20),\n * each exact (formatted as Recharts draws it, whatever ticks it picks); a duration or a size in one unit for the axis.\n */\nexport function axisTickFormatter(values: number[], format: ValueFormat | undefined, locale: string | undefined): (value: number) => string {\n if (typeof format === \"function\") return format;\n if (format === \"percent\") return (value) => exact((d) => new Intl.NumberFormat(locale, { style: \"percent\", maximumFractionDigits: d }).format(value / 100));\n if (format === \"milliseconds\" || format === \"bytes\") {\n const [unit, size] = axisUnit(unitsOf(format), valueAxisTicks(values));\n return (value) => exact(unitFormat(unit, value / size, locale));\n }\n const compact = (value: number) => exact((d) => new Intl.NumberFormat(locale, { notation: \"compact\", maximumFractionDigits: d }).format(value));\n const plain = (value: number) => exact((d) => new Intl.NumberFormat(locale, { maximumFractionDigits: d }).format(value));\n // compact where it pays, from five digits up (250k for 250,000); below, the number as people write it: 1,234, never\n // 1.234K, which is longer and reads worse (the 25.17 second review). Read from the values, so a domain of the page's own\n // (2018 to 2024) is read as Recharts draws it.\n const largest = Math.max(0, ...values.filter(Number.isFinite).map(Math.abs));\n return largest >= COMPACT_FROM ? compact : plain;\n}\n\n/** The size from which a value axis's numbers read compact (Sprint 25.17's second review). */\nconst COMPACT_FROM = 10_000;\n\n/** A value in full, as the tooltip shows it, in the chart's locale: every digit of a number (grouped); a duration's or a size's, exactly, in the largest unit it reaches. */\nexport function fullValueFormatter(format: ValueFormat | undefined, locale: string | undefined): (value: number) => string {\n if (typeof format === \"function\") return format;\n if (format === undefined || format === \"number\") return (value) => value.toLocaleString(locale);\n if (format === \"percent\") return (value) => exact((d) => new Intl.NumberFormat(locale, { style: \"percent\", maximumFractionDigits: d }).format(value / 100), 4);\n return (value) => {\n const [unit, size] = unitReached(unitsOf(format), value);\n return exact(unitFormat(unit, value / size, locale), 4);\n };\n}\n\n/** A series a value axis draws: its key, and the stack it sits in (null: on its own). */\nexport interface AxisSeries {\n dataKey: string;\n stack: string | null;\n}\n\n/**\n * The values a value axis spans: each value of a series drawn on its own, and each stack's positive values summed up from\n * 0 and its negative values down — the charts stack both ways from zero (Sprint 25.17's review: a stack of 6,500 up and\n * 2,500 down was read as one sum of 4,000). One reading for every chart.\n */\nexport function axisExtent(data: Record<string, unknown>[], series: AxisSeries[]): number[] {\n return data.flatMap((row) => {\n const own: number[] = [];\n const up = new Map<string, number>();\n const down = new Map<string, number>();\n for (const s of series) {\n const raw = row[s.dataKey];\n const v = typeof raw === \"number\" ? raw : typeof raw === \"string\" && raw.trim() !== \"\" ? Number(raw) : NaN;\n if (!Number.isFinite(v)) continue;\n if (s.stack == null) own.push(v);\n else if (v >= 0) up.set(s.stack, (up.get(s.stack) ?? 0) + v);\n else down.set(s.stack, (down.get(s.stack) ?? 0) + v);\n }\n return [...own, ...up.values(), ...down.values()];\n });\n}\n\n/** The values a value axis spans for these series: each on its own, or one stack of them all. */\nexport function seriesValues(data: Record<string, unknown>[], keys: string[], stacked = false): number[] {\n return axisExtent(data, keys.map((dataKey) => ({ dataKey, stack: stacked ? \"stack\" : null })));\n}\n","import { useContext, useEffect, useLayoutEffect, useMemo, useState, type RefObject } from \"react\";\nimport { createPortal } from \"react-dom\";\nimport { Legend, Text } from \"recharts\";\nimport { useResolvedToken } from \"../../lib/chart-utils\";\nimport { createAxisMeasurer, fitLabel, namesCutShort, type CategoryKind, type Measure } from \"../../lib/chart-categories\";\nimport { ChartFrameContext } from \"./ChartWrapper\";\nimport { valueAxisTicks } from \"./value-format\";\nimport { formatLocale } from \"../../lib/format-locale\";\nimport { useFormatLocale } from \"../../lib/locale\";\n\ninterface TooltipEntry {\n name: string;\n value: number | string;\n color: string;\n dataKey?: string;\n payload?: Record<string, unknown>;\n}\n\ninterface ChartTooltipContentProps {\n active?: boolean;\n payload?: TooltipEntry[];\n label?: string;\n}\n\nconst hasLabel = (label: unknown) => label != null && label !== \"\" && typeof label !== \"number\";\n/**\n * A series' name. A chart without a category label (a pie's slice, a funnel's stage, a treemap's tile) names the item by\n * its row's `name`; on an axis chart the row's `name` is the category, already shown as the label, so the series keeps\n * its own (a row keyed by `name` read \"Alice: Alice 20\" instead of \"Alice: Hours 20\").\n */\nconst entryName = (entry: TooltipEntry, label: unknown) =>\n (!hasLabel(label) && typeof entry.payload?.name === \"string\" && entry.payload.name) || entry.name;\n/** A value as the tooltip shows it: in full, with the chart's unit (Sprint 25.17 A27), else grouped in the locale given. */\nconst entryValue = (entry: TooltipEntry, format: ((value: number, dataKey?: string) => string) | undefined, locale: string | undefined) =>\n (typeof entry.value === \"number\" ? (format ? format(entry.value, entry.dataKey) : entry.value.toLocaleString(locale)) : entry.value);\n\n/** What the live region says for the active point: its category, then each series' name and value. */\n/** What recharts sets on a shape to draw it, which a data row may carry too (a point's x and y, a slice's fill). */\nconst DRAWING = new Set([\"x\", \"y\", \"cx\", \"cy\", \"width\", \"height\", \"r\", \"radius\", \"innerRadius\", \"outerRadius\", \"startAngle\", \"endAngle\", \"cornerRadius\", \"upperWidth\", \"lowerWidth\", \"size\", \"fill\", \"stroke\", \"strokeWidth\", \"opacity\", \"fillOpacity\", \"strokeOpacity\", \"className\"]);\n\n/**\n * A shape's props without its data row's own fields (Sprint 25.29 item 14): recharts spreads the row into each shape, so\n * a row's `role`, `aria-label` or `id` became the bar's, and a chart of people by role drew bars with role=\"Design\". The\n * row stays whole as `payload`, and what the shape draws with stays.\n */\nexport function withoutRowFields<P extends object>(props: P): P {\n const row = (props as { payload?: unknown }).payload;\n if (!row || typeof row !== \"object\") return props;\n const own: Record<string, unknown> = {};\n for (const [key, value] of Object.entries(props)) if (DRAWING.has(key) || !(key in row)) own[key] = value;\n return own as P;\n}\n\nexport function tooltipAnnouncement(label: unknown, payload: TooltipEntry[] | undefined, format?: (value: number, dataKey?: string) => string, locale: string | undefined = formatLocale()): string {\n if (!payload?.length) return \"\";\n const values = payload.map((entry) => `${entryName(entry, label)} ${entryValue(entry, format, locale)}`).join(\", \");\n return hasLabel(label) ? `${String(label)}: ${values}` : values;\n}\n\n/**\n * The chart's tooltip box. What it shows is also said in the chart's `role=\"status\"` `aria-live=\"polite\"` region, which\n * sits outside the drawing (a graphic's children are presentational) and starts empty, so the category and the values\n * are heard as the pointer or the arrow keys move (WCAG 4.1.3). Outside a library chart the region wraps the box.\n */\nexport function ChartTooltipContent({ active, payload, label }: ChartTooltipContentProps) {\n const bgSurface = useResolvedToken(\"--ds-bg-surface\");\n const borderSubtle = useResolvedToken(\"--ds-border-subtle\");\n const textPrimary = useResolvedToken(\"--ds-text-primary\");\n const textSecondary = useResolvedToken(\"--ds-text-secondary\");\n const { live, formatValue } = useContext(ChartFrameContext);\n // the values in the chart's locale (Sprint 25.20)\n const locale = useFormatLocale();\n\n const on = !!active && !!payload?.length;\n const showLabel = hasLabel(label);\n\n const box = on ? (\n <div\n className=\"rounded-[var(--ds-radius-md)] shadow-[var(--ds-shadow-popover)] font-[family-name:var(--ds-font-sans)] text-sm\"\n style={{\n backgroundColor: bgSurface,\n border: `var(--ds-border-width) solid ${borderSubtle}`,\n padding: \"var(--ds-space-2) var(--ds-space-3)\",\n }}\n >\n {showLabel && (\n <p className=\"font-medium mb-ds-1\" style={{ color: textPrimary }}>\n {label}\n </p>\n )}\n {payload!.map((entry, i) => {\n const dotColor = (entry.payload?.fill as string) || entry.color || textSecondary;\n return (\n <div key={i} className=\"flex items-center gap-ds-2\" style={{ marginTop: i > 0 ? 2 : 0 }}>\n <span\n className=\"shrink-0 rounded-[var(--ds-radius-full)]\"\n style={{ width: 8, height: 8, backgroundColor: dotColor }}\n />\n <span style={{ color: textSecondary }}>{entryName(entry, label)}:</span>\n <span className=\"tabular-nums\" style={{ color: textPrimary }}>\n {entryValue(entry, formatValue, locale)}\n </span>\n </div>\n );\n })}\n </div>\n ) : null;\n\n if (live) {\n return (\n <>\n {box}\n {createPortal(on ? tooltipAnnouncement(label, payload, formatValue, locale) : \"\", live)}\n </>\n );\n }\n return (\n <div role=\"status\" aria-live=\"polite\">\n {box}\n </div>\n );\n}\n\ninterface ChartLegendContentProps {\n payload?: Array<{\n value: string;\n color: string;\n dataKey?: string;\n }>;\n}\n\n/** A legend entry's outline: the series' stroke when it has one (a soft bar's solid edge, a line), else its colour. */\nfunction swatchEdge(entry: { color?: string; payload?: unknown }): string | undefined {\n const stroke = (entry.payload as { stroke?: unknown } | undefined)?.stroke;\n return typeof stroke === \"string\" ? stroke : entry.color;\n}\n\nexport function ChartLegendContent({ payload }: ChartLegendContentProps) {\n const textSecondary = useResolvedToken(\"--ds-text-secondary\");\n\n if (!payload?.length) return null;\n\n return (\n <div className=\"flex flex-wrap justify-center gap-y-ds-1 gap-x-ds-4 font-[family-name:var(--ds-font-sans)] text-sm\">\n {payload.map((entry, i) => (\n <div key={i} className=\"flex items-center gap-ds-1.5\">\n <span\n className=\"shrink-0 rounded-[var(--ds-radius-full)]\"\n // the series' own fill inside its outline (a soft bar's solid stroke), so a 30% tint stays visible (C4)\n style={{ width: 10, height: 10, backgroundColor: entry.color, border: `1.5px solid ${swatchEdge(entry)}` }}\n />\n <span style={{ color: textSecondary }}>{entry.value}</span>\n </div>\n ))}\n </div>\n );\n}\n\n/** Legend items in the order the chart draws its series: by dataKey (bars, lines, areas, radars) or by name (a pie's slices). */\nexport function seriesSorter(order: ReadonlyArray<string>, by: \"dataKey\" | \"value\" = \"dataKey\") {\n return (item: { dataKey?: unknown; value?: unknown }) => {\n const key = by === \"dataKey\" ? item.dataKey : item.value;\n const i = order.indexOf(String(key));\n return i < 0 ? order.length : i;\n };\n}\n\n/**\n * Sprint 25.9, A2: the chart's legend is Recharts' own Legend portalled into the slot below the drawing, so it no longer\n * takes its height from the plot. It keeps ChartLegendContent and its swatch, and follows the series' order, not the\n * alphabet (Recharts' default `itemSorter: \"value\"`). Rendered once the slot exists, so it never lands in the drawing.\n */\nexport function ChartLegend({ order, by = \"dataKey\" }: { order: ReadonlyArray<string>; by?: \"dataKey\" | \"value\" }) {\n const { legend } = useContext(ChartFrameContext);\n const orderKey = order.join(\"\\u0001\");\n // eslint-disable-next-line react-hooks/exhaustive-deps -- the order is compared by value\n const sorter = useMemo(() => seriesSorter(order, by), [orderKey, by]);\n if (!legend) return null;\n return <Legend portal={legend} content={<ChartLegendContent />} itemSorter={sorter} wrapperStyle={{ paddingTop: \"var(--ds-space-3)\" }} />;\n}\n\nexport function useGridStroke(): string {\n return useResolvedToken(\"--ds-border-subtle\");\n}\n\nexport function useAxisStyle() {\n const textMuted = useResolvedToken(\"--ds-text-muted\");\n\n return {\n tick: {\n fontSize: \"var(--ds-font-size-xs)\",\n fontFamily: \"var(--ds-font-sans)\",\n fill: textMuted,\n // Sprint 25.9: Recharts paints a default tick's text with the axis stroke (#666 unless set), not with fill, so the\n // value axes drew their numbers at about 2.6:1 on dark cards (WCAG 1.4.3 asks 4.5:1). Every axis that spreads this\n // hides its axis and tick lines, so the stroke only colours the text.\n stroke: textMuted,\n },\n };\n}\n\nexport function useRadius(): number {\n const val = useResolvedToken(\"--ds-radius-md\");\n const parsed = parseInt(val, 10);\n return isNaN(parsed) ? 6 : parsed;\n}\n/**\n * Recharts' `tick` prop as an object only passes SVG-valid properties.\n * Props like `maxLines`, `verticalAnchor` are stripped. We must use a\n * function to pass them to the internal Text component.\n */\nexport function xAxisTick(props: Record<string, unknown>) {\n // No width box (Sprint 25.3 C12): with one, Recharts measured \"20 Aug\" in a hidden span that did not carry the\n // chart's font, judged it too wide for its share of the axis and wrapped or truncated it. Without a width Text never\n // wraps or truncates; `interval` (preserveStartEnd) thins colliding ticks and keeps the first and last. Recharts' own\n // Text keeps the axis's auto height right, which a bare <text> does not (the label was clipped 8px in the pass).\n // Scale axes (dates, numbers) keep this tick; a names axis takes namesTick.\n const { x, y, payload, width: _width, visibleTicksCount: _count, ...rest } = props as {\n x: number; y: number; payload: { value: string };\n width?: number; visibleTicksCount?: number; [k: string]: unknown;\n };\n return (\n <Text {...rest} x={x} y={y} textAnchor=\"middle\" verticalAnchor=\"start\">\n {payload.value}\n </Text>\n );\n}\n\nexport function yAxisTick(props: Record<string, unknown>) {\n const { x, y, payload, ...rest } = props as { x: number; y: number; payload: { value: string };[k: string]: unknown };\n return (\n <Text {...rest} x={x} y={y} textAnchor=\"end\" verticalAnchor=\"middle\" width={200} maxLines={2}>\n {payload.value}\n </Text>\n );\n}\n\n/* ── Names on a category axis (Sprint 25.9, A3) ─────────────────────────── */\n\n/** The line height of a two-line name, in em. */\nconst LINE_EM = 1.2;\n/** The least space between two names under an upright chart. */\nexport const NAME_GAP = 8;\n/**\n * A sideways name's inset from its column: Recharts draws it tickSize + tickMargin (8 px) left of the axis edge, and\n * the chart's own margin leaves 4 px on the left.\n */\nexport const NAME_COLUMN_INSET = 12;\n\n/**\n * The tick for a names axis: each name fitted to its band — one line; else two lines split at a space; else \"…\" on\n * the second — inside one `<g className={props.className}>`, so Recharts sizes the axis for both lines (two Texts each\n * carrying the tick's class leave the axis sized for one, and the second line clipped). The full name is the label's\n * `<title>`. Upright, the band is the axis width over the ticks it draws; sideways it is the name column the chart sets.\n * Without a measurer (no canvas) every name shows in full on one line.\n */\nexport function namesTick(measure: Measure | null, orientation: \"x\" | \"y\", column?: number) {\n return function NamesTick(props: Record<string, unknown>) {\n const { x, y, payload, width, visibleTicksCount, className, fill, fontSize, fontFamily } = props as {\n x: number; y: number; payload?: { value?: unknown }; width?: number; visibleTicksCount?: number;\n className?: string; fill?: string; fontSize?: string | number; fontFamily?: string;\n };\n const name = String(payload?.value ?? \"\");\n const room = orientation === \"x\"\n ? (Number(width) || 0) / Math.max(1, Number(visibleTicksCount) || 1) - NAME_GAP\n : (column ?? (Number(width) || 0)) - NAME_COLUMN_INSET;\n const fit = fitLabel(name, room, measure);\n const text = { fill, fontSize, fontFamily, stroke: \"none\" };\n // upright: the first line's top at y (Recharts' verticalAnchor \"start\"); sideways: the lines centred on the row\n const firstDy = orientation === \"x\" ? 0.71 : 0.355 - ((fit.lines.length - 1) * LINE_EM) / 2;\n return (\n <g className={className} data-cut={fit.cut ? \"\" : undefined} data-lines={fit.lines.length}>\n <title>{name}</title>\n {fit.lines.map((line, i) => (\n <text key={i} x={x} y={y} dy={`${firstDy + i * LINE_EM}em`} textAnchor={orientation === \"x\" ? \"middle\" : \"end\"} {...text}>\n {line}\n </text>\n ))}\n </g>\n );\n };\n}\n\nexport type XAxisInterval = number | \"preserveStart\" | \"preserveEnd\" | \"preserveStartEnd\" | \"equidistantPreserveStart\";\n\nexport interface AxisMeasure {\n /** Text widths in the axis's resolved font, or null (no canvas: jsdom). */\n measure: Measure | null;\n /** The resolved axis font size, px. */\n px: number;\n /** One row of a row chart, px (--ds-chart-row as the page resolves it). */\n rowPx: number;\n /** The chart wrapper's width, px. */\n width: number;\n}\n\ntype FontSet = { ready: Promise<unknown>; addEventListener?: (t: string, f: () => void) => void; removeEventListener?: (t: string, f: () => void) => void };\n\n/**\n * The chart's measurer: the axis font read from the wrapper's probe (so `calc()` font tokens measure right), and the\n * wrapper's width. Re-read when the wrapper resizes and when web fonts land (the same font string then measures\n * differently, so the cache starts again).\n */\nexport function useAxisMeasure(ref: RefObject<HTMLDivElement | null>, enabled = true): AxisMeasure {\n const [state, setState] = useState<AxisMeasure>({ measure: null, px: 12, rowPx: 32, width: 0 });\n useLayoutEffect(() => {\n const el = ref.current;\n if (!enabled || !el) return;\n let live = true;\n let font = \"\";\n const update = (fresh = false) => {\n if (!live) return;\n const measured = el.clientWidth;\n const probe = el.querySelector<HTMLElement>(\"[data-chart-probe]\");\n const row = probe?.getBoundingClientRect().height ?? 0;\n const next = createAxisMeasurer(el);\n setState((prev) => {\n // no width is no layout (a hidden tab, or the moment headless Chrome takes a full-page screenshot): keep the last\n const width = measured > 0 ? measured : prev.width;\n const rowPx = row > 0 ? row : prev.rowPx;\n if (!next) return prev.width === width ? prev : { ...prev, width };\n if (!fresh && next.font === font && prev.measure && prev.width === width && prev.rowPx === rowPx) return prev;\n const keep = !fresh && next.font === font && prev.measure;\n font = next.font;\n return { measure: keep ? prev.measure : next.measure, px: next.px, rowPx, width };\n });\n };\n update(true);\n const ro = typeof ResizeObserver !== \"undefined\" ? new ResizeObserver(() => update()) : null;\n ro?.observe(el);\n const fonts = (typeof document !== \"undefined\" ? (document as Document & { fonts?: FontSet }).fonts : undefined);\n const landed = () => update(true);\n fonts?.ready.then(landed, () => {});\n fonts?.addEventListener?.(\"loadingdone\", landed);\n return () => {\n live = false;\n ro?.disconnect();\n fonts?.removeEventListener?.(\"loadingdone\", landed);\n };\n }, [ref, enabled]);\n return state;\n}\n\n/** The value axis's width on an upright chart: its widest tick label, as the axis formats it (Sprint 25.17 A27). */\nexport function valueAxisWidth(values: number[], measure: Measure, format: (value: number) => string = String): number {\n const ticks = valueAxisTicks(values);\n if (!ticks.length) return Math.ceil(measure(format(0))) + 8;\n return Math.ceil(Math.max(...ticks.map((t) => measure(format(t))))) + 8;\n}\n\n/** How far the switch looks back before turning an automatic sideways chart upright again (no flip at the boundary). */\nconst SWITCH_HYSTERESIS = 32;\n\n/**\n * D8: an upright chart of names turns sideways when a name would be cut to fewer than six characters at the chart's\n * width, and back when there's room: it turns upright again only once names would also fit a little narrower, so a\n * scrollbar appearing does not flip it back. The last decision is kept as state (information from the previous render).\n */\nexport function useSidewaysSwitch(enabled: boolean, names: string[], m: AxisMeasure, axisWidth: number, sideMargins: number): boolean {\n const [turned, setTurned] = useState(false);\n const key = names.join(\"\\u0001\");\n const cut = useMemo(() => {\n if (!enabled || !m.measure || m.width <= 0 || names.length === 0) return { here: false, narrower: false };\n const cutAt = (width: number) => namesCutShort(names, (width - sideMargins - axisWidth) / names.length - NAME_GAP, m.measure!);\n return { here: cutAt(m.width), narrower: cutAt(m.width - SWITCH_HYSTERESIS) };\n // names are compared by value\n }, [enabled, key, m.measure, m.width, axisWidth, sideMargins]); // eslint-disable-line react-hooks/exhaustive-deps\n // sideways as soon as names are cut short here; upright only when they fit here and a little narrower (no flip-flop)\n const decision = turned ? cut.here || cut.narrower : cut.here;\n if (decision !== turned) setTurned(decision);\n return decision;\n}\n\n/** A sideways chart's name column: its widest name, at most a third of the chart's width. */\nexport function nameColumn(names: string[], m: AxisMeasure): number | undefined {\n if (!m.measure || m.width <= 0) return undefined;\n const widest = names.reduce((w, n) => Math.max(w, m.measure!(n.replace(/\\s+/g, \" \").trim())), 0);\n return Math.max(24, Math.min(Math.ceil(widest) + NAME_COLUMN_INSET, Math.floor(m.width / 3)));\n}\n\n/** How many names take two lines in a name column (each makes its row one line taller). */\nexport function twoLineNames(names: string[], column: number | undefined, m: AxisMeasure): number {\n if (!m.measure || column === undefined) return 0;\n return names.filter((n) => fitLabel(n, column - NAME_COLUMN_INSET, m.measure).lines.length > 1).length;\n}\n\n/** The widest label in the chart's own axis font (canvas measureText), or null where there is no canvas (jsdom). */\nfunction widestLabel(el: HTMLElement, labels: string[]): number | null {\n const measurer = createAxisMeasurer(el);\n if (!measurer) return null;\n return labels.reduce((w, l) => Math.max(w, measurer.measure(l)), 0);\n}\n\nconst TICK_GAP = 12; // the least space between two labels\nconst AXIS_RESERVE = 48; // the y-axis column and the chart's side margins\n\n/**\n * Sprint 25.4 C-11 (decision 7): the category ticks a chart shows. Recharts' preserveStartEnd thins colliding ticks\n * by its own measurement (without the chart's font) and keeps the last tick, so the labels fall unevenly (round 5:\n * 14 and 15 September missing). The chart measures its widest label with the resolved axis font, picks the step\n * that fits the axis width, and labels every step from the first category — the last only when it falls on the step.\n * Re-measured when the wrapper resizes and when the web fonts land. A numeric `override` (the chart's xAxisInterval\n * prop) is every Nth category and skips the measurement; the Recharts strings are treated as \"measured\" (round 13).\n *\n * Sprint 25.9, A3: this thinning is for dates and numbers only. A names axis (`kind` \"names\") is never thinned: every\n * name from the first render (interval 0, no explicit ticks, so duplicate names keep their own bands), each fitted to\n * its band by namesTick. The font is the axis font as the page resolves it (a probe), so `calc()` tokens measure right.\n */\nexport function useCategoryTicks(\n data: ReadonlyArray<Record<string, unknown>> | undefined,\n xAxisKey: string,\n ref: RefObject<HTMLDivElement | null>,\n override?: XAxisInterval,\n kind: CategoryKind = \"scale\",\n): { ticks?: string[]; interval: XAxisInterval; endMargin: number } {\n const labels = useMemo(() => (data ?? []).map((d) => String(d[xAxisKey] ?? \"\")), [data, xAxisKey]);\n const labelsKey = labels.join(\"\\u0001\");\n const [ticks, setTicks] = useState<string[] | undefined>(undefined);\n // Half the widest label: the chart's right margin, so the last label (centred on the last point) is not clipped.\n const [endMargin, setEndMargin] = useState(4);\n // Only a number is an override (every Nth category). The Recharts strings — \"preserveStartEnd\" and friends — are the\n // thinning this hook replaced (round 13: a builder passed the old default by name and got uneven labels again), so\n // they mean \"measured\" too.\n const numeric = typeof override === \"number\" ? override : undefined;\n const names = kind === \"names\";\n useEffect(() => {\n const el = ref.current;\n if (names || numeric !== undefined || !el || labels.length === 0) return;\n let live = true;\n const compute = () => {\n if (!live) return;\n // no width is no layout (a hidden tab, or the moment headless Chrome takes a full-page screenshot): keep the last\n if (el.clientWidth <= 0) return;\n const widest = widestLabel(el, labels);\n const plot = el.clientWidth - AXIS_RESERVE;\n if (widest == null || plot <= 0) { setTicks(undefined); return; }\n setEndMargin(Math.max(4, Math.ceil(widest / 2)));\n const fits = Math.max(1, Math.floor(plot / (widest + TICK_GAP)));\n const step = Math.ceil(labels.length / fits);\n // every k-th label from the first, explicitly — an explicit list keeps Recharts from thinning on its own\n // measurement even when every label fits (round 5: \"16 Sep\" dropped at full width)\n setTicks(labels.filter((_, i) => i % step === 0));\n };\n if (typeof ResizeObserver === \"undefined\") return;\n const ro = new ResizeObserver(compute);\n ro.observe(el);\n const fonts = (document as Document & { fonts?: { ready: Promise<unknown> } }).fonts;\n fonts?.ready.then(compute, () => {});\n return () => { live = false; ro.disconnect(); };\n // labels are compared by value\n }, [labelsKey, numeric, names, ref]); // eslint-disable-line react-hooks/exhaustive-deps\n if (names) return { interval: 0, endMargin: 4 };\n if (numeric !== undefined) return { interval: numeric, endMargin: 4 };\n return ticks ? { ticks, interval: 0, endMargin } : { interval: \"preserveStartEnd\", endMargin: 4 };\n}\n","import { forwardRef, useMemo, useRef, type Ref } from \"react\";\nimport {\n BarChart as RechartsBarChart,\n Bar,\n XAxis,\n YAxis,\n CartesianGrid,\n Tooltip,\n Rectangle,\n ResponsiveContainer,\n} from \"recharts\";\nimport { useChartColors, useChartAnimation } from \"../../lib/chart-utils\";\nimport { categoryKind as guessCategoryKind } from \"../../lib/chart-categories\";\nimport {\n ChartTooltipContent, ChartLegend, useGridStroke, useAxisStyle, useRadius, xAxisTick, namesTick, useCategoryTicks,\n useAxisMeasure, useSidewaysSwitch, valueAxisWidth, nameColumn, twoLineNames, withoutRowFields, type XAxisInterval,\n} from \"./ChartPrimitives\";\nimport { mergeRefs } from \"../../lib/slot\";\nimport { axisExtent, axisTickFormatter, fullValueFormatter, type ValueFormat } from \"./value-format\";\nimport { ChartWrapper, CHART_ROW, markChart } from \"./ChartWrapper\";\nimport { useFormatLocale } from \"../../lib/locale\";\nimport { useHydrated } from \"../../lib/hydrated\";\n\nexport interface BarDef {\n dataKey: string;\n label?: string;\n soft?: boolean;\n /**\n * Bars with the same stackId stack into one column (Sprint 25.7, C4); a bar without one stands alone. BarChart's\n * `stacked` puts every bar without a stackId into one stack. The same field works in CompositeChart, where lines\n * draw over the stacks.\n */\n stackId?: string;\n}\n\n/** The stack a bar joins: its own stackId, else the one `stacked` makes for every bar. */\nexport function barStackOf(bar: BarDef, stacked: boolean): string | undefined {\n return bar.stackId ?? (stacked ? \"stack\" : undefined);\n}\n\n/** Some bar stacks. Its chart then stacks both ways from zero (stackOffset \"sign\"), so a negative series sits below it. */\nexport function anyStack(bars: BarDef[], stacked: boolean): boolean {\n return bars.some((bar) => barStackOf(bar, stacked) != null);\n}\n\n/** How many bars stand side by side in one category: one per stack, one per bar on its own. */\nexport function barGroups(bars: BarDef[], stacked: boolean): number {\n return Math.max(1, new Set(bars.map((bar, i) => barStackOf(bar, stacked) ?? `\\u0000${i}`)).size);\n}\n\n/**\n * The bar's shape: only the end segment of each stack is rounded, per column and per side of zero — the top of the\n * positive side, the bottom of the negative one — so a stack whose last series is zero in a column rounds the segment\n * that ends it there. A bar on its own rounds its end.\n */\nexport function barShape(bars: BarDef[], index: number, stacked: boolean, radius: number, horizontal = false) {\n const round: [number, number, number, number] = horizontal ? [0, radius, radius, 0] : [radius, radius, 0, 0];\n const square: [number, number, number, number] = [0, 0, 0, 0];\n const stack = barStackOf(bars[index], stacked);\n const above = stack == null ? [] : bars.filter((b, j) => j > index && barStackOf(b, stacked) === stack);\n // Recharts hands the shape the bar's geometry and its row of data; it draws a negative bar's rounded corners at its\n // far end itself\n const Shape = (props: unknown) => {\n const p = props as { payload?: Record<string, unknown> };\n const row = p.payload ?? {};\n const down = Number(row[bars[index].dataKey]) < 0;\n const onTop = above.every((b) => {\n const value = Number(row[b.dataKey]);\n return !(down ? value < 0 : value > 0);\n });\n return <Rectangle {...withoutRowFields(props as object)} radius={onTop ? round : square} />;\n };\n return Shape;\n}\n\n/** The values the value axis must reach: each bar on its own, and each stack up and down from zero (axisExtent). */\nfunction valueExtent(data: Record<string, unknown>[], bars: BarDef[], stacked: boolean): number[] {\n return axisExtent(data, bars.map((bar) => ({ dataKey: bar.dataKey, stack: barStackOf(bar, stacked) ?? null })));\n}\n\n/** A title line's height, px, in the axis font. */\nconst titleLine = (px: number) => Math.ceil(px * 1.5) + 4;\n/** The same in CSS, for a row chart's height. */\nconst TITLE_LINE_CSS = \"calc(1.5 * var(--ds-font-size-xs) + 4px)\";\n\nexport interface BarChartProps {\n /**\n * Which category ticks show on an axis of dates or numbers. Leave it out: the chart measures its widest label with\n * the chart's font and labels every k-th category from the first, the last only when it falls on the step (Sprint\n * 25.4 C-11, decision 7). A number labels every Nth category instead. The Recharts strings (\"preserveStartEnd\") are\n * accepted for compatibility and mean the same measured labelling (round 13). A names axis is never thinned.\n */\n xAxisInterval?: XAxisInterval;\n data: Record<string, unknown>[];\n bars: BarDef[];\n xAxisKey: string;\n /**\n * \"auto\" (the default): the chart sizes itself — sideways, a row per category; upright, two wide to one high. A\n * preset or a number overrides it; inside a ChartContainer, the container's own height wins.\n */\n height?: \"auto\" | \"sm\" | \"md\" | \"lg\" | number;\n /** Every bar without a stackId joins one stack. */\n stacked?: boolean;\n /**\n * Bars running sideways, one row per category. Leave it out: an upright chart of names turns itself sideways when a\n * name would be cut to fewer than six characters, and back when there's room (D8). true or false forces either.\n */\n horizontal?: boolean;\n /**\n * What the categories are. \"names\" are never skipped: each wraps onto two lines, then ends with \"…\", with the full\n * name on hover. \"scale\" (dates, times, numbers) is labelled at an even step. Leave it out: guessed from the labels.\n */\n categoryKind?: \"names\" | \"scale\";\n showGrid?: boolean;\n showTooltip?: boolean;\n showLegend?: boolean;\n /** The category axis's title, as drawn upright (below it). A sideways chart puts the category title above its names. */\n xAxisLabel?: string;\n /** The value axis's title, drawn horizontally above the axis. */\n yAxisLabel?: string;\n /**\n * How the values read: \"number\" (the default) is compact on the axis from five digits up, in the page's language (1M, 750K), and in full in\n * the tooltip; \"percent\", \"milliseconds\" or \"bytes\" add their unit; a function formats both itself (Sprint 25.17 A27).\n */\n valueFormat?: ValueFormat;\n animated?: boolean;\n \"aria-label\"?: string;\n className?: string;\n}\n\nexport const BarChart = markChart(forwardRef<HTMLDivElement, BarChartProps>(function BarChart({\n data,\n bars,\n xAxisKey,\n xAxisInterval,\n height = \"auto\",\n stacked = false,\n horizontal,\n categoryKind,\n showGrid = true,\n showTooltip = true,\n showLegend,\n xAxisLabel,\n yAxisLabel,\n valueFormat,\n animated,\n \"aria-label\": ariaLabel,\n className,\n}, ref) {\n const wrapperRef = useRef<HTMLDivElement | null>(null);\n const labels = useMemo(() => (data ?? []).map((d) => String(d[xAxisKey] ?? \"\")), [data, xAxisKey]);\n // the chart's numbers in the locale the server and the hydrating browser share (Sprint 25.20)\n const locale = useFormatLocale();\n // its labels' kind: by the server's locale while a server-rendered page hydrates (both sides alike), by the browser's\n // languages from then on, as before 0.27.0 (the review: a German browser's month names on an English page)\n const hydrated = useHydrated();\n const kind = categoryKind ?? guessCategoryKind((data ?? []).map((d) => d[xAxisKey]), hydrated ? undefined : locale);\n const names = kind === \"names\";\n const measured = useAxisMeasure(wrapperRef, (data?.length ?? 0) > 0);\n const values = useMemo(() => valueExtent(data ?? [], bars, stacked), [data, bars, stacked]);\n const tickFormat = useMemo(() => axisTickFormatter(values, valueFormat, locale), [values, valueFormat, locale]);\n const fullFormat = useMemo(() => fullValueFormatter(valueFormat, locale), [valueFormat, locale]);\n const axisWidth = useMemo(\n () => (measured.measure ? valueAxisWidth(values, measured.measure, tickFormat) : 0),\n [measured.measure, values, tickFormat],\n );\n const turned = useSidewaysSwitch(horizontal === undefined && names, labels, measured, axisWidth, 8);\n const sideways = horizontal ?? turned;\n const xTicks = useCategoryTicks(data, xAxisKey, wrapperRef, xAxisInterval, sideways || names ? \"names\" : \"scale\");\n const column = sideways ? nameColumn(labels, measured) : undefined;\n const upright = useMemo(() => namesTick(measured.measure, \"x\"), [measured.measure]);\n const rows = useMemo(() => namesTick(measured.measure, \"y\", column), [measured.measure, column]);\n const solidColors = useChartColors(bars.length, false);\n const softColors = useChartColors(bars.length, true);\n const gridStroke = useGridStroke();\n const axisStyle = useAxisStyle();\n const isAnimated = useChartAnimation(animated);\n const radius = useRadius();\n const legendVisible = showLegend ?? bars.length >= 2;\n\n // Axis titles follow their data: a chart that turned itself sideways moves the value title under the value axis and\n // the category title above the names. Every title is horizontal (Analysis Function; data_visualisation#22).\n const valueTitle = horizontal === true ? xAxisLabel : yAxisLabel;\n const categoryTitle = horizontal === true ? yAxisLabel : xAxisLabel;\n const topTitle = sideways ? categoryTitle : valueTitle;\n const bottomTitle = sideways ? valueTitle : categoryTitle;\n const axisLabelStyle = { fontSize: \"var(--ds-font-size-xs)\", fontFamily: \"var(--ds-font-sans)\", fill: axisStyle.tick.fill };\n const bottomLabel = bottomTitle ? { value: bottomTitle, position: \"insideBottom\" as const, offset: -2, style: axisLabelStyle } : undefined;\n\n const groups = barGroups(bars, stacked);\n const perCategory = 1 + 0.5 * (groups - 1);\n const titles = [topTitle, bottomTitle].filter(Boolean).length;\n const size = sideways\n ? {\n model: \"rows\" as const,\n units: labels.length * perCategory,\n lines: twoLineNames(labels, column, measured),\n axis: titles ? `calc(${CHART_ROW} + ${titles} * ${TITLE_LINE_CSS})` : CHART_ROW,\n }\n : { model: \"ratio\" as const };\n // bars keep their thickness when the chart grows in a row: the rows spread instead\n const maxBarSize = sideways ? Math.max(4, Math.round((measured.rowPx * perCategory * 0.7) / groups)) : undefined;\n\n if (!data?.length) return null;\n\n return (\n <ChartWrapper\n ref={mergeRefs(ref as Ref<HTMLElement>, wrapperRef as Ref<HTMLElement>) as Ref<HTMLDivElement>}\n height={height}\n size={size}\n chart=\"bar\"\n categoryKind={kind}\n categories={data.length}\n categoryAxis={sideways ? \"y\" : \"x\"}\n sideways={sideways}\n axisTitle={topTitle}\n formatValue={fullFormat}\n className={className}\n aria-label={ariaLabel}\n >\n <ResponsiveContainer width=\"100%\" height=\"100%\">\n <RechartsBarChart\n data={data}\n layout={sideways ? \"vertical\" : \"horizontal\"}\n stackOffset={anyStack(bars, stacked) ? \"sign\" : undefined}\n // names are fitted to their bands, so nothing hangs past the last bar: 4 px, not a margin sized from them\n margin={{ top: 4 + (topTitle ? titleLine(measured.px) : 0), right: sideways || names ? 4 : xTicks.endMargin, bottom: 4, left: 4 }}\n accessibilityLayer\n >\n {showGrid && (\n <CartesianGrid strokeDasharray=\"3 3\" stroke={gridStroke} vertical={!sideways} horizontal />\n )}\n {sideways ? (\n <>\n <XAxis type=\"number\" {...axisStyle.tick} axisLine={false} tickLine={false} height=\"auto\" label={bottomLabel} tickFormatter={tickFormat} />\n <YAxis\n dataKey={xAxisKey}\n type=\"category\"\n width={column ?? \"auto\"}\n {...axisStyle.tick}\n axisLine={false}\n tickLine={false}\n interval={0}\n tick={rows}\n />\n </>\n ) : (\n <>\n <XAxis\n dataKey={xAxisKey}\n {...axisStyle.tick}\n axisLine={false}\n tickLine={false}\n tick={names ? upright : xAxisTick}\n interval={xTicks.interval}\n ticks={xTicks.ticks}\n height=\"auto\"\n label={bottomLabel}\n />\n <YAxis width=\"auto\" {...axisStyle.tick} axisLine={false} tickLine={false} tickFormatter={tickFormat} />\n </>\n )}\n {showTooltip && <Tooltip content={<ChartTooltipContent />} cursor={{ fill: \"var(--ds-bg-muted)\", opacity: 0.5 }} />}\n {legendVisible && <ChartLegend order={bars.map((b) => b.dataKey)} />}\n {bars.map((bar, i) => (\n <Bar\n key={bar.dataKey}\n dataKey={bar.dataKey}\n name={bar.label ?? bar.dataKey}\n fill={bar.soft ? softColors[i] : solidColors[i]}\n // a soft fill is a 30% tint: the solid outline keeps the bar's edge at the colour's own contrast (WCAG 1.4.11)\n stroke={bar.soft ? solidColors[i] : undefined}\n strokeWidth={bar.soft ? 1 : undefined}\n shape={barShape(bars, i, stacked, radius, sideways)}\n stackId={barStackOf(bar, stacked)}\n maxBarSize={maxBarSize}\n isAnimationActive={isAnimated}\n />\n ))}\n </RechartsBarChart>\n </ResponsiveContainer>\n </ChartWrapper>\n );\n}));\n","import { forwardRef, useMemo, useRef, type Ref } from \"react\";\nimport {\n LineChart as RechartsLineChart,\n Line,\n XAxis,\n YAxis,\n CartesianGrid,\n Tooltip,\n ResponsiveContainer,\n} from \"recharts\";\nimport { useChartColors, useChartAnimation } from \"../../lib/chart-utils\";\nimport { ChartTooltipContent, ChartLegend, useGridStroke, useAxisStyle, xAxisTick, useCategoryTicks, useAxisMeasure, type XAxisInterval } from \"./ChartPrimitives\";\nimport { mergeRefs } from \"../../lib/slot\";\nimport { axisTickFormatter, fullValueFormatter, seriesValues, type ValueFormat } from \"./value-format\";\nimport { ChartWrapper, markChart } from \"./ChartWrapper\";\nimport { useFormatLocale } from \"../../lib/locale\";\n\nexport interface LineDef {\n dataKey: string;\n label?: string;\n dashed?: boolean;\n}\n\nexport interface LineChartProps {\n /**\n * Which category ticks show. Leave it out: the chart measures its widest label with the chart's font and labels every\n * k-th category from the first, the last only when it falls on the step (Sprint 25.4 C-11, decision 7). A number\n * labels every Nth category instead. The Recharts strings (\"preserveStartEnd\") are accepted for compatibility and\n * mean the same measured labelling — they never hand the ticks back to Recharts' thinning (round 13).\n */\n xAxisInterval?: XAxisInterval;\n data: Record<string, unknown>[];\n lines: LineDef[];\n xAxisKey: string;\n /** \"auto\" (the default): two wide to one high. A preset or a number overrides it; a ChartContainer's own height wins. */\n height?: \"auto\" | \"sm\" | \"md\" | \"lg\" | number;\n curved?: boolean;\n showDots?: boolean;\n showGrid?: boolean;\n showTooltip?: boolean;\n showLegend?: boolean;\n xAxisLabel?: string;\n /** The value axis's title, drawn horizontally above the axis. */\n yAxisLabel?: string;\n /**\n * How the values read: \"number\" (the default) is compact on the axis from five digits up, in the page's language (1M, 750K), and in full in\n * the tooltip; \"percent\", \"milliseconds\" or \"bytes\" add their unit; a function formats both itself (Sprint 25.17 A27).\n */\n valueFormat?: ValueFormat;\n animated?: boolean;\n \"aria-label\"?: string;\n className?: string;\n}\n\nexport const LineChart = markChart(forwardRef<HTMLDivElement, LineChartProps>(function LineChart({\n data,\n lines,\n xAxisKey,\n xAxisInterval,\n height = \"auto\",\n curved = true,\n showDots = false,\n showGrid = true,\n showTooltip = true,\n showLegend,\n xAxisLabel,\n yAxisLabel,\n valueFormat,\n animated,\n \"aria-label\": ariaLabel,\n className,\n}, ref) {\n const wrapperRef = useRef<HTMLDivElement | null>(null);\n const values = useMemo(() => seriesValues(data ?? [], lines.map((s) => s.dataKey), false), [data, lines]);\n // the chart's numbers in the locale the server and the hydrating browser share (Sprint 25.20)\n const locale = useFormatLocale();\n const tickFormat = useMemo(() => axisTickFormatter(values, valueFormat, locale), [values, valueFormat, locale]);\n const fullFormat = useMemo(() => fullValueFormatter(valueFormat, locale), [valueFormat, locale]);\n // a line runs over a scale (dates, times, numbers): its labels are thinned at an even step, never fitted as names\n const xTicks = useCategoryTicks(data, xAxisKey, wrapperRef, xAxisInterval, \"scale\");\n const measured = useAxisMeasure(wrapperRef, !!yAxisLabel && (data?.length ?? 0) > 0);\n const colors = useChartColors(lines.length, false);\n const gridStroke = useGridStroke();\n const axisStyle = useAxisStyle();\n const isAnimated = useChartAnimation(animated);\n const legendVisible = showLegend ?? lines.length >= 2;\n const axisLabelStyle = { fontSize: \"var(--ds-font-size-xs)\", fontFamily: \"var(--ds-font-sans)\", fill: axisStyle.tick.fill };\n const top = 4 + (yAxisLabel ? Math.ceil(measured.px * 1.5) + 4 : 0);\n\n if (!data?.length) return null;\n\n return (\n <ChartWrapper\n ref={mergeRefs(ref as Ref<HTMLElement>, wrapperRef as Ref<HTMLElement>) as Ref<HTMLDivElement>}\n height={height}\n size={{ model: \"ratio\" }}\n chart=\"line\"\n categoryKind=\"scale\"\n categories={data.length}\n categoryAxis=\"x\"\n axisTitle={yAxisLabel}\n formatValue={fullFormat}\n className={className}\n aria-label={ariaLabel}\n >\n <ResponsiveContainer width=\"100%\" height=\"100%\">\n <RechartsLineChart data={data} margin={{ top, right: xTicks.endMargin, bottom: 4, left: 4 }} accessibilityLayer>\n {showGrid && <CartesianGrid strokeDasharray=\"3 3\" stroke={gridStroke} />}\n <XAxis\n dataKey={xAxisKey}\n {...axisStyle.tick}\n axisLine={false}\n tickLine={false}\n tick={xAxisTick}\n interval={xTicks.interval}\n ticks={xTicks.ticks}\n height=\"auto\"\n label={xAxisLabel ? { value: xAxisLabel, position: \"insideBottom\", offset: -2, style: axisLabelStyle } : undefined}\n />\n <YAxis width=\"auto\" {...axisStyle.tick} axisLine={false} tickLine={false} tickFormatter={tickFormat} />\n {showTooltip && <Tooltip content={<ChartTooltipContent />} />}\n {legendVisible && <ChartLegend order={lines.map((l) => l.dataKey)} />}\n {lines.map((line, i) => (\n <Line\n key={line.dataKey}\n type={curved ? \"monotone\" : \"linear\"}\n dataKey={line.dataKey}\n name={line.label ?? line.dataKey}\n stroke={colors[i]}\n strokeWidth={2}\n strokeDasharray={line.dashed ? \"5 5\" : undefined}\n dot={showDots}\n activeDot={{ r: 5, strokeWidth: 2 }}\n isAnimationActive={isAnimated}\n />\n ))}\n </RechartsLineChart>\n </ResponsiveContainer>\n </ChartWrapper>\n );\n}));\n","import { forwardRef, useId, useMemo, useRef, type Ref } from \"react\";\nimport {\n AreaChart as RechartsAreaChart,\n Area,\n XAxis,\n YAxis,\n CartesianGrid,\n Tooltip,\n ResponsiveContainer,\n} from \"recharts\";\nimport { useChartColors, useChartAnimation } from \"../../lib/chart-utils\";\nimport { ChartTooltipContent, ChartLegend, useGridStroke, useAxisStyle, xAxisTick, useCategoryTicks, useAxisMeasure, type XAxisInterval } from \"./ChartPrimitives\";\nimport { mergeRefs } from \"../../lib/slot\";\nimport { axisTickFormatter, fullValueFormatter, seriesValues, type ValueFormat } from \"./value-format\";\nimport { ChartWrapper, markChart } from \"./ChartWrapper\";\nimport { useFormatLocale } from \"../../lib/locale\";\n\nexport interface AreaDef {\n dataKey: string;\n label?: string;\n}\n\nexport interface AreaChartProps {\n /**\n * Which category ticks show. Leave it out: the chart measures its widest label with the chart's font and labels every\n * k-th category from the first, the last only when it falls on the step (Sprint 25.4 C-11, decision 7). A number\n * labels every Nth category instead. The Recharts strings (\"preserveStartEnd\") are accepted for compatibility and\n * mean the same measured labelling — they never hand the ticks back to Recharts' thinning (round 13).\n */\n xAxisInterval?: XAxisInterval;\n data: Record<string, unknown>[];\n areas: AreaDef[];\n xAxisKey: string;\n /** \"auto\" (the default): two wide to one high. A preset or a number overrides it; a ChartContainer's own height wins. */\n height?: \"auto\" | \"sm\" | \"md\" | \"lg\" | number;\n stacked?: boolean;\n curved?: boolean;\n showGrid?: boolean;\n showTooltip?: boolean;\n showLegend?: boolean;\n gradient?: boolean;\n xAxisLabel?: string;\n /** The value axis's title, drawn horizontally above the axis. */\n yAxisLabel?: string;\n /**\n * How the values read: \"number\" (the default) is compact on the axis from five digits up, in the page's language (1M, 750K), and in full in\n * the tooltip; \"percent\", \"milliseconds\" or \"bytes\" add their unit; a function formats both itself (Sprint 25.17 A27).\n */\n valueFormat?: ValueFormat;\n animated?: boolean;\n \"aria-label\"?: string;\n className?: string;\n}\n\nexport const AreaChart = markChart(forwardRef<HTMLDivElement, AreaChartProps>(function AreaChart({\n data,\n areas,\n xAxisKey,\n xAxisInterval,\n height = \"auto\",\n stacked = false,\n curved = true,\n showGrid = true,\n showTooltip = true,\n showLegend,\n gradient = true,\n xAxisLabel,\n yAxisLabel,\n valueFormat,\n animated,\n \"aria-label\": ariaLabel,\n className,\n}, ref) {\n const wrapperRef = useRef<HTMLDivElement | null>(null);\n const values = useMemo(() => seriesValues(data ?? [], areas.map((s) => s.dataKey), stacked), [data, areas, stacked]);\n // the chart's numbers in the locale the server and the hydrating browser share (Sprint 25.20)\n const locale = useFormatLocale();\n const tickFormat = useMemo(() => axisTickFormatter(values, valueFormat, locale), [values, valueFormat, locale]);\n const fullFormat = useMemo(() => fullValueFormatter(valueFormat, locale), [valueFormat, locale]);\n // an area runs over a scale (dates, times, numbers): its labels are thinned at an even step, never fitted as names\n const xTicks = useCategoryTicks(data, xAxisKey, wrapperRef, xAxisInterval, \"scale\");\n const measured = useAxisMeasure(wrapperRef, !!yAxisLabel && (data?.length ?? 0) > 0);\n const instanceId = useId();\n const solidColors = useChartColors(areas.length, false);\n const softColors = useChartColors(areas.length, true);\n const gridStroke = useGridStroke();\n const axisStyle = useAxisStyle();\n const isAnimated = useChartAnimation(animated);\n const legendVisible = showLegend ?? areas.length >= 2;\n const axisLabelStyle = { fontSize: \"var(--ds-font-size-xs)\", fontFamily: \"var(--ds-font-sans)\", fill: axisStyle.tick.fill };\n const top = 4 + (yAxisLabel ? Math.ceil(measured.px * 1.5) + 4 : 0);\n\n if (!data?.length) return null;\n\n return (\n <ChartWrapper\n ref={mergeRefs(ref as Ref<HTMLElement>, wrapperRef as Ref<HTMLElement>) as Ref<HTMLDivElement>}\n height={height}\n size={{ model: \"ratio\" }}\n chart=\"area\"\n categoryKind=\"scale\"\n categories={data.length}\n categoryAxis=\"x\"\n axisTitle={yAxisLabel}\n formatValue={fullFormat}\n className={className}\n aria-label={ariaLabel}\n >\n <ResponsiveContainer width=\"100%\" height=\"100%\">\n <RechartsAreaChart data={data} margin={{ top, right: xTicks.endMargin, bottom: 4, left: 4 }} accessibilityLayer>\n <defs>\n {areas.map((area, i) => (\n <linearGradient key={area.dataKey} id={`gradient-${instanceId}-${area.dataKey}`} x1=\"0\" y1=\"0\" x2=\"0\" y2=\"1\">\n <stop offset=\"0%\" stopColor={softColors[i]} stopOpacity={1} />\n <stop offset=\"95%\" stopColor={softColors[i]} stopOpacity={0.1} />\n </linearGradient>\n ))}\n </defs>\n {showGrid && <CartesianGrid strokeDasharray=\"3 3\" stroke={gridStroke} />}\n <XAxis\n dataKey={xAxisKey}\n {...axisStyle.tick}\n axisLine={false}\n tickLine={false}\n tick={xAxisTick}\n interval={xTicks.interval}\n ticks={xTicks.ticks}\n height=\"auto\"\n label={xAxisLabel ? { value: xAxisLabel, position: \"insideBottom\", offset: -2, style: axisLabelStyle } : undefined}\n />\n <YAxis width=\"auto\" {...axisStyle.tick} axisLine={false} tickLine={false} tickFormatter={tickFormat} />\n {showTooltip && <Tooltip content={<ChartTooltipContent />} />}\n {legendVisible && <ChartLegend order={areas.map((a) => a.dataKey)} />}\n {areas.map((area, i) => (\n <Area\n key={area.dataKey}\n type={curved ? \"monotone\" : \"linear\"}\n dataKey={area.dataKey}\n name={area.label ?? area.dataKey}\n stroke={solidColors[i]}\n strokeWidth={2}\n fill={gradient ? `url(#gradient-${instanceId}-${area.dataKey})` : softColors[i]}\n stackId={stacked ? \"stack\" : undefined}\n isAnimationActive={isAnimated}\n />\n ))}\n </RechartsAreaChart>\n </ResponsiveContainer>\n </ChartWrapper>\n );\n}));\n","import { forwardRef } from \"react\";\nimport {\n PieChart as RechartsPieChart,\n Pie,\n Cell,\n Tooltip,\n ResponsiveContainer,\n} from \"recharts\";\nimport { useChartColors, useChartAnimation } from \"../../lib/chart-utils\";\nimport { ChartTooltipContent, ChartLegend } from \"./ChartPrimitives\";\nimport { ChartWrapper, markChart } from \"./ChartWrapper\";\n\nexport interface PieChartProps {\n data: { name: string; value: number; [key: string]: unknown }[];\n /** \"auto\" (the default): square. A preset or a number overrides it; a ChartContainer's own height wins. */\n height?: \"auto\" | \"sm\" | \"md\" | \"lg\" | number;\n donut?: boolean;\n showTooltip?: boolean;\n showLegend?: boolean;\n showLabels?: boolean;\n animated?: boolean;\n \"aria-label\"?: string;\n className?: string;\n}\n\nexport const PieChart = markChart(forwardRef<HTMLDivElement, PieChartProps>(function PieChart({\n data,\n height = \"auto\",\n donut = false,\n showTooltip = true,\n showLegend = true,\n showLabels = false,\n animated,\n \"aria-label\": ariaLabel,\n className,\n}, ref) {\n const colors = useChartColors(data.length, false);\n const isAnimated = useChartAnimation(animated);\n\n const renderLabel = showLabels\n ? ({ percent }: { percent?: number }) => `${((percent ?? 0) * 100).toFixed(0)}%`\n : false;\n\n // the chart's own fields alone: recharts draws each slice with its row's fields, so a row's `role` or `aria-label`\n // became the slice's (Sprint 25.29 item 14)\n const chartData = data.map((d) => ({ name: d.name, value: d.value }));\n\n if (!data?.length) return null;\n\n return (\n <ChartWrapper ref={ref} height={height} size={{ model: \"square\" }} chart=\"pie\" className={className} aria-label={ariaLabel}>\n <ResponsiveContainer width=\"100%\" height=\"100%\">\n <RechartsPieChart accessibilityLayer>\n <Pie\n data={chartData}\n dataKey=\"value\"\n nameKey=\"name\"\n cx=\"50%\"\n cy=\"50%\"\n outerRadius=\"75%\"\n innerRadius={donut ? \"55%\" : 0}\n label={renderLabel}\n labelLine={showLabels}\n isAnimationActive={isAnimated}\n fontSize=\"var(--ds-font-size-xs)\"\n fontFamily=\"var(--ds-font-sans)\"\n >\n {data.map((_, i) => (\n <Cell key={i} fill={colors[i % colors.length]} />\n ))}\n </Pie>\n {showTooltip && <Tooltip content={<ChartTooltipContent />} />}\n {showLegend && <ChartLegend order={data.map((d) => d.name)} by=\"value\" />}\n </RechartsPieChart>\n </ResponsiveContainer>\n </ChartWrapper>\n );\n}));\n","import { forwardRef, useMemo, useRef, type Ref } from \"react\";\nimport {\n ComposedChart,\n Bar,\n Line,\n XAxis,\n YAxis,\n CartesianGrid,\n Tooltip,\n ResponsiveContainer,\n} from \"recharts\";\nimport { useChartColors, useChartAnimation } from \"../../lib/chart-utils\";\nimport { categoryKind as guessCategoryKind } from \"../../lib/chart-categories\";\nimport {\n ChartTooltipContent, ChartLegend, useGridStroke, useAxisStyle, useRadius, xAxisTick, namesTick, useCategoryTicks,\n useAxisMeasure, useSidewaysSwitch, valueAxisWidth, nameColumn, twoLineNames, type XAxisInterval,\n} from \"./ChartPrimitives\";\nimport { mergeRefs } from \"../../lib/slot\";\nimport { axisExtent, axisTickFormatter, fullValueFormatter, type ValueFormat } from \"./value-format\";\nimport { ChartWrapper, CHART_ROW, markChart } from \"./ChartWrapper\";\nimport { anyStack, barGroups, barShape, barStackOf, type BarDef } from \"./BarChart\";\nimport type { LineDef } from \"./LineChart\";\nimport { useFormatLocale } from \"../../lib/locale\";\nimport { useHydrated } from \"../../lib/hydrated\";\n\nexport interface CompositeChartProps {\n /**\n * Which category ticks show on an axis of dates or numbers. Leave it out: the chart measures its widest label with\n * the chart's font and labels every k-th category from the first, the last only when it falls on the step (Sprint\n * 25.4 C-11, decision 7). A number labels every Nth category instead. The Recharts strings (\"preserveStartEnd\") are\n * accepted for compatibility and mean the same measured labelling (round 13). A names axis is never thinned.\n */\n xAxisInterval?: XAxisInterval;\n data: Record<string, unknown>[];\n bars: BarDef[];\n lines: LineDef[];\n xAxisKey: string;\n /**\n * \"auto\" (the default): two wide to one high; sideways, a row per category. A preset or a number overrides it; a\n * ChartContainer's own height wins.\n */\n height?: \"auto\" | \"sm\" | \"md\" | \"lg\" | number;\n /** Every bar without a stackId joins one stack; lines draw over it (Sprint 25.7, C4). A bar's stackId works too. */\n stacked?: boolean;\n /**\n * The lines on a second axis of their own, on the right, for a line whose unit differs from the bars'. Default: true\n * for bars side by side, false once the bars stack (`stacked` or a bar's stackId), so a capacity or a target line\n * reads against the stack's own scale. An explicit value wins.\n */\n dualAxis?: boolean;\n /**\n * What the categories are. \"names\" are never skipped: each wraps onto two lines, then ends with \"…\", with the full\n * name on hover. \"scale\" (dates, times, numbers) is labelled at an even step. Leave it out: guessed from the labels.\n */\n categoryKind?: \"names\" | \"scale\";\n /**\n * Bars running sideways, one row per category, with the lines crossing the rows. Leave it out: a chart of names turns\n * itself sideways when a name would be cut to fewer than six characters, and back when there's room (D8). true or\n * false forces either.\n */\n horizontal?: boolean;\n showGrid?: boolean;\n showTooltip?: boolean;\n showLegend?: boolean;\n xAxisLabel?: string;\n /** The value axis's title, drawn horizontally above the axis. */\n yAxisLabel?: string;\n /**\n * How the bars' values read (and the lines', on one axis): \"number\" (the default) is compact on the axis, in the\n * page's language (1M, 750K), and in full in the tooltip; \"percent\", \"milliseconds\" or \"bytes\" add their unit; a function\n * formats both itself (Sprint 25.17 A27).\n */\n valueFormat?: ValueFormat;\n /** How the lines' values read on their own axis (dualAxis), when their unit differs from the bars'. Default: valueFormat. */\n lineValueFormat?: ValueFormat;\n animated?: boolean;\n \"aria-label\"?: string;\n className?: string;\n}\n\nexport const CompositeChart = markChart(forwardRef<HTMLDivElement, CompositeChartProps>(function CompositeChart({\n data,\n bars,\n lines,\n xAxisKey,\n xAxisInterval,\n height = \"auto\",\n stacked = false,\n dualAxis = !anyStack(bars, stacked),\n categoryKind,\n horizontal,\n showGrid = true,\n showTooltip = true,\n showLegend = true,\n xAxisLabel,\n yAxisLabel,\n valueFormat,\n lineValueFormat = valueFormat,\n animated,\n \"aria-label\": ariaLabel,\n className,\n}, ref) {\n const wrapperRef = useRef<HTMLDivElement | null>(null);\n const labels = useMemo(() => (data ?? []).map((d) => String(d[xAxisKey] ?? \"\")), [data, xAxisKey]);\n // the chart's numbers in the locale the server and the hydrating browser share (Sprint 25.20)\n const locale = useFormatLocale();\n // its labels' kind as BarChart reads it: the server's locale while hydrating, the browser's languages from then on\n const hydrated = useHydrated();\n const kind = categoryKind ?? guessCategoryKind((data ?? []).map((d) => d[xAxisKey]), hydrated ? undefined : locale);\n const names = kind === \"names\";\n const measured = useAxisMeasure(wrapperRef, (data?.length ?? 0) > 0);\n // the bars' axis (and the lines', on one axis), and the lines' own on the right with a second axis\n const [values, lineValues] = useMemo(() => {\n // the bars' stacks up and down from zero, as BarChart reads them (axisExtent), and the lines on the same axis unless\n // they have their own\n const values = axisExtent(data ?? [], [\n ...bars.map((bar) => ({ dataKey: bar.dataKey, stack: barStackOf(bar, stacked) ?? null })),\n ...(dualAxis ? [] : lines.map((l) => ({ dataKey: l.dataKey, stack: null }))),\n ]);\n const lineValues = (data ?? []).flatMap((row) => lines.map((l) => Number(row[l.dataKey])));\n return [values, lineValues];\n }, [data, bars, lines, stacked, dualAxis]);\n const tickFormat = useMemo(() => axisTickFormatter(values, valueFormat, locale), [values, valueFormat, locale]);\n const lineTickFormat = useMemo(() => axisTickFormatter(lineValues, lineValueFormat, locale), [lineValues, lineValueFormat, locale]);\n const fullFormat = useMemo(() => {\n const bar = fullValueFormatter(valueFormat, locale);\n const line = fullValueFormatter(dualAxis ? lineValueFormat : valueFormat, locale);\n const lineKeys = new Set(lines.map((l) => l.dataKey));\n return (value: number, dataKey?: string) => (dataKey && lineKeys.has(dataKey) ? line(value) : bar(value));\n }, [valueFormat, lineValueFormat, dualAxis, lines, locale]);\n // the bars' axis sets the left column's width; with a second axis the lines' ticks take the right edge\n const axisWidth = useMemo(() => {\n if (!measured.measure) return 0;\n return valueAxisWidth(values, measured.measure, tickFormat) + (dualAxis ? valueAxisWidth(lineValues, measured.measure, lineTickFormat) : 0);\n }, [measured.measure, values, lineValues, tickFormat, lineTickFormat, dualAxis]);\n const turned = useSidewaysSwitch(horizontal === undefined && names, labels, measured, axisWidth, 8);\n const sideways = horizontal ?? turned;\n const xTicks = useCategoryTicks(data, xAxisKey, wrapperRef, xAxisInterval, sideways ? \"names\" : kind);\n const column = sideways ? nameColumn(labels, measured) : undefined;\n const tick = useMemo(() => (names ? namesTick(measured.measure, \"x\") : xAxisTick), [names, measured.measure]);\n const rows = useMemo(() => namesTick(measured.measure, \"y\", column), [measured.measure, column]);\n const barSoftColors = useChartColors(bars.length, true);\n const barSolidColors = useChartColors(bars.length, false);\n const lineColors = useChartColors(lines.length, false);\n const gridStroke = useGridStroke();\n const axisStyle = useAxisStyle();\n const isAnimated = useChartAnimation(animated);\n const radius = useRadius();\n const axisLabelStyle = { fontSize: \"var(--ds-font-size-xs)\", fontFamily: \"var(--ds-font-sans)\", fill: axisStyle.tick.fill };\n // axis titles follow their data: sideways, the value title goes under the value axis, the category title above the names\n const topTitle = sideways ? xAxisLabel : yAxisLabel;\n const bottomTitle = sideways ? yAxisLabel : xAxisLabel;\n const bottomLabel = bottomTitle ? { value: bottomTitle, position: \"insideBottom\" as const, offset: -2, style: axisLabelStyle } : undefined;\n const top = 4 + (topTitle ? Math.ceil(measured.px * 1.5) + 4 : 0);\n const groups = barGroups(bars, stacked);\n const perCategory = 1 + 0.5 * (groups - 1);\n const titles = [topTitle, bottomTitle].filter(Boolean).length + (sideways && dualAxis ? 1 : 0);\n const size = sideways\n ? {\n model: \"rows\" as const,\n units: labels.length * perCategory,\n lines: twoLineNames(labels, column, measured),\n axis: titles ? `calc(${CHART_ROW} + ${titles} * calc(1.5 * var(--ds-font-size-xs) + 4px))` : CHART_ROW,\n }\n : { model: \"ratio\" as const };\n const maxBarSize = sideways ? Math.max(4, Math.round((measured.rowPx * perCategory * 0.7) / groups)) : undefined;\n // the bars read against the left (or bottom) axis; the lines against their own when dualAxis\n const barAxis = sideways ? { xAxisId: \"left\" } : { yAxisId: \"left\" };\n const lineAxis = sideways ? { xAxisId: dualAxis ? \"right\" : \"left\" } : { yAxisId: dualAxis ? \"right\" : \"left\" };\n\n if (!data?.length) return null;\n\n return (\n <ChartWrapper\n ref={mergeRefs(ref as Ref<HTMLElement>, wrapperRef as Ref<HTMLElement>) as Ref<HTMLDivElement>}\n height={height}\n size={size}\n chart=\"composite\"\n categoryKind={kind}\n categories={data.length}\n categoryAxis={sideways ? \"y\" : \"x\"}\n sideways={sideways}\n axisTitle={topTitle}\n formatValue={fullFormat}\n className={className}\n aria-label={ariaLabel}\n >\n <ResponsiveContainer width=\"100%\" height=\"100%\">\n <ComposedChart\n data={data}\n layout={sideways ? \"vertical\" : \"horizontal\"}\n stackOffset={anyStack(bars, stacked) ? \"sign\" : undefined}\n // names are fitted to their bands, so nothing hangs past the last bar\n margin={{ top, right: sideways || names ? 4 : xTicks.endMargin, bottom: 4, left: 4 }}\n accessibilityLayer\n >\n {showGrid && <CartesianGrid strokeDasharray=\"3 3\" stroke={gridStroke} vertical={!sideways} horizontal />}\n {sideways ? (\n <>\n <XAxis xAxisId=\"left\" type=\"number\" {...axisStyle.tick} axisLine={false} tickLine={false} height=\"auto\" label={bottomLabel} tickFormatter={tickFormat} />\n {dualAxis && <XAxis xAxisId=\"right\" type=\"number\" orientation=\"top\" {...axisStyle.tick} axisLine={false} tickLine={false} height=\"auto\" tickFormatter={lineTickFormat} />}\n <YAxis\n dataKey={xAxisKey}\n type=\"category\"\n width={column ?? \"auto\"}\n {...axisStyle.tick}\n axisLine={false}\n tickLine={false}\n interval={0}\n tick={rows}\n />\n </>\n ) : (\n <>\n <XAxis\n dataKey={xAxisKey}\n {...axisStyle.tick}\n axisLine={false}\n tickLine={false}\n tick={tick}\n interval={xTicks.interval}\n ticks={xTicks.ticks}\n height=\"auto\"\n label={bottomLabel}\n />\n <YAxis yAxisId=\"left\" width=\"auto\" {...axisStyle.tick} axisLine={false} tickLine={false} tickFormatter={tickFormat} />\n {dualAxis && (\n <YAxis yAxisId=\"right\" orientation=\"right\" width=\"auto\" {...axisStyle.tick} axisLine={false} tickLine={false} tickFormatter={lineTickFormat} />\n )}\n </>\n )}\n {showTooltip && <Tooltip content={<ChartTooltipContent />} />}\n {showLegend && <ChartLegend order={[...bars.map((b) => b.dataKey), ...lines.map((l) => l.dataKey)]} />}\n {bars.map((bar, i) => (\n <Bar\n key={bar.dataKey}\n dataKey={bar.dataKey}\n name={bar.label ?? bar.dataKey}\n fill={barSoftColors[i]}\n // the soft fill is a 30% tint (1.3–1.4:1 on a dark card, Sprint 25.7 C4): the solid outline keeps the bar's\n // edge at the colour's own contrast against the card (WCAG 1.4.11), and separates stacked segments\n stroke={barSolidColors[i]}\n strokeWidth={1}\n shape={barShape(bars, i, stacked, radius, sideways)}\n stackId={barStackOf(bar, stacked)}\n maxBarSize={maxBarSize}\n {...barAxis}\n isAnimationActive={isAnimated}\n />\n ))}\n {lines.map((line, i) => (\n <Line\n key={line.dataKey}\n type=\"monotone\"\n dataKey={line.dataKey}\n name={line.label ?? line.dataKey}\n stroke={lineColors[i]}\n strokeWidth={2}\n strokeDasharray={line.dashed ? \"5 5\" : undefined}\n dot={false}\n {...lineAxis}\n isAnimationActive={isAnimated}\n />\n ))}\n </ComposedChart>\n </ResponsiveContainer>\n </ChartWrapper>\n );\n}));\n","import { forwardRef, useMemo, useRef, type Ref } from \"react\";\nimport {\n ScatterChart as RechartsScatterChart,\n Scatter,\n XAxis,\n YAxis,\n CartesianGrid,\n Tooltip,\n ResponsiveContainer,\n Symbols,\n ZAxis,\n} from \"recharts\";\nimport { useChartColors, useChartAnimation } from \"../../lib/chart-utils\";\nimport { ChartTooltipContent, ChartLegend, useGridStroke, useAxisStyle, useAxisMeasure, withoutRowFields } from \"./ChartPrimitives\";\nimport { mergeRefs } from \"../../lib/slot\";\nimport { axisTickFormatter, fullValueFormatter, type ValueFormat } from \"./value-format\";\nimport { ChartWrapper, markChart } from \"./ChartWrapper\";\nimport { useFormatLocale } from \"../../lib/locale\";\n\nexport interface ScatterSeries {\n name: string;\n points: { x: number; y: number; z?: number }[];\n}\n\nexport interface ScatterChartProps {\n data: ScatterSeries[];\n xLabel?: string;\n /** The value axis's title, drawn horizontally above the axis. */\n yLabel?: string;\n /** \"auto\" (the default): two wide to one high. A preset or a number overrides it; a ChartContainer's own height wins. */\n height?: \"auto\" | \"sm\" | \"md\" | \"lg\" | number;\n showGrid?: boolean;\n showTooltip?: boolean;\n showLegend?: boolean;\n /**\n * How the y values read: \"number\" (the default) is compact on the axis from five digits up, in the page's language (1M, 750K), and in full in\n * the tooltip; \"percent\", \"milliseconds\" or \"bytes\" add their unit; a function formats both itself (Sprint 25.17 A27).\n */\n valueFormat?: ValueFormat;\n /** How the x values read, as valueFormat. Default \"number\". */\n xValueFormat?: ValueFormat;\n animated?: boolean;\n \"aria-label\"?: string;\n className?: string;\n}\n\nexport const ScatterChart = markChart(forwardRef<HTMLDivElement, ScatterChartProps>(function ScatterChart({\n data,\n xLabel,\n yLabel,\n height = \"auto\",\n showGrid = true,\n showTooltip = true,\n showLegend,\n valueFormat,\n xValueFormat,\n animated,\n \"aria-label\": ariaLabel,\n className,\n}, ref) {\n const wrapperRef = useRef<HTMLDivElement | null>(null);\n // the chart's numbers in the locale the server and the hydrating browser share (Sprint 25.20)\n const locale = useFormatLocale();\n const [xTickFormat, yTickFormat, fullFormat] = useMemo(() => {\n const points = (data ?? []).flatMap((s) => s.points);\n const x = fullValueFormatter(xValueFormat, locale);\n const y = fullValueFormatter(valueFormat, locale);\n return [\n axisTickFormatter(points.map((p) => p.x), xValueFormat, locale),\n axisTickFormatter(points.map((p) => p.y), valueFormat, locale),\n (value: number, dataKey?: string) => (dataKey === \"x\" ? x(value) : dataKey === \"y\" ? y(value) : value.toLocaleString(locale)),\n ];\n }, [data, valueFormat, xValueFormat, locale]);\n const measured = useAxisMeasure(wrapperRef, !!yLabel && (data?.length ?? 0) > 0);\n const colors = useChartColors(data.length, false);\n const gridStroke = useGridStroke();\n const axisStyle = useAxisStyle();\n const isAnimated = useChartAnimation(animated);\n const legendVisible = showLegend ?? data.length >= 2;\n const axisLabelStyle = { fontSize: \"var(--ds-font-size-xs)\", fontFamily: \"var(--ds-font-sans)\", fill: axisStyle.tick.fill };\n\n if (!data?.length) return null;\n\n return (\n <ChartWrapper\n ref={mergeRefs(ref as Ref<HTMLElement>, wrapperRef as Ref<HTMLElement>) as Ref<HTMLDivElement>}\n height={height}\n size={{ model: \"ratio\" }}\n chart=\"scatter\"\n axisTitle={yLabel}\n formatValue={fullFormat}\n className={className}\n aria-label={ariaLabel}\n >\n <ResponsiveContainer width=\"100%\" height=\"100%\">\n <RechartsScatterChart\n margin={{ top: 8 + (yLabel ? Math.ceil(measured.px * 1.5) + 4 : 0), right: 8, bottom: xLabel ? 20 : 4, left: 4 }}\n accessibilityLayer\n >\n {showGrid && <CartesianGrid strokeDasharray=\"3 3\" stroke={gridStroke} />}\n <XAxis\n type=\"number\"\n dataKey=\"x\"\n name={xLabel ?? \"x\"}\n {...axisStyle.tick}\n axisLine={false}\n tickLine={false}\n tickFormatter={xTickFormat}\n label={xLabel ? { value: xLabel, position: \"bottom\", offset: 0, style: { ...axisLabelStyle, textAnchor: \"middle\" } } : undefined}\n />\n <YAxis\n type=\"number\"\n dataKey=\"y\"\n name={yLabel ?? \"y\"}\n width=\"auto\"\n {...axisStyle.tick}\n axisLine={false}\n tickLine={false}\n tickFormatter={yTickFormat}\n />\n <ZAxis type=\"number\" dataKey=\"z\" range={[40, 400]} />\n {showTooltip && <Tooltip content={<ChartTooltipContent />} />}\n {legendVisible && <ChartLegend order={data.map((s) => s.name)} by=\"value\" />}\n {data.map((series, i) => (\n <Scatter\n key={series.name}\n name={series.name}\n data={series.points}\n fill={colors[i]}\n isAnimationActive={isAnimated}\n // a circle, drawn from its own props, never a point's fields (Sprint 25.29 item 14)\n shape={(p: object) => <Symbols {...withoutRowFields(p)} type=\"circle\" />}\n />\n ))}\n </RechartsScatterChart>\n </ResponsiveContainer>\n </ChartWrapper>\n );\n}));\n","import { forwardRef, useMemo } from \"react\";\nimport {\n RadarChart as RechartsRadarChart,\n Radar,\n PolarGrid,\n PolarAngleAxis,\n PolarRadiusAxis,\n Tooltip,\n ResponsiveContainer,\n} from \"recharts\";\nimport { useChartColors, useChartAnimation } from \"../../lib/chart-utils\";\nimport { ChartTooltipContent, ChartLegend } from \"./ChartPrimitives\";\nimport { ChartWrapper, markChart } from \"./ChartWrapper\";\nimport { axisTickFormatter, fullValueFormatter, seriesValues, type ValueFormat } from \"./value-format\";\nimport { useFormatLocale } from \"../../lib/locale\";\n\nexport interface RadarDataKey {\n key: string;\n label?: string;\n}\n\nexport interface RadarChartProps {\n data: Record<string, unknown>[];\n dataKeys: RadarDataKey[];\n axisKey: string;\n /** \"auto\" (the default): square. A preset or a number overrides it; a ChartContainer's own height wins. */\n height?: \"auto\" | \"sm\" | \"md\" | \"lg\" | number;\n filled?: boolean;\n showDots?: boolean;\n showTooltip?: boolean;\n showLegend?: boolean;\n animated?: boolean;\n /** How the values read on the rings and in the tooltip; see ValueFormat (compact numbers by default). */\n valueFormat?: ValueFormat;\n \"aria-label\"?: string;\n className?: string;\n}\n\nexport const RadarChart = markChart(forwardRef<HTMLDivElement, RadarChartProps>(function RadarChart({\n data,\n dataKeys,\n axisKey,\n height = \"auto\",\n filled = true,\n showDots = true,\n showTooltip = true,\n showLegend,\n animated,\n valueFormat = \"number\",\n \"aria-label\": ariaLabel,\n className,\n}, ref) {\n const solidColors = useChartColors(dataKeys.length, false);\n const softColors = useChartColors(dataKeys.length, true);\n const isAnimated = useChartAnimation(animated);\n const legendVisible = showLegend ?? dataKeys.length >= 2;\n // the rings are a value axis: compact in the page's language, the tooltip in full (Sprint 25.17's review)\n const values = useMemo(() => seriesValues(data ?? [], dataKeys.map((dk) => dk.key)), [data, dataKeys]);\n // the chart's numbers in the locale the server and the hydrating browser share (Sprint 25.20)\n const locale = useFormatLocale();\n const tickFormat = useMemo(() => axisTickFormatter(values, valueFormat, locale), [values, valueFormat, locale]);\n const fullFormat = useMemo(() => fullValueFormatter(valueFormat, locale), [valueFormat, locale]);\n\n if (!data?.length) return null;\n\n return (\n <ChartWrapper ref={ref} height={height} size={{ model: \"square\" }} chart=\"radar\" className={className} aria-label={ariaLabel} formatValue={fullFormat}>\n <ResponsiveContainer width=\"100%\" height=\"100%\">\n <RechartsRadarChart data={data} cx=\"50%\" cy=\"50%\" outerRadius=\"75%\" accessibilityLayer>\n <PolarGrid stroke=\"var(--ds-border-subtle)\" />\n <PolarAngleAxis\n dataKey={axisKey}\n tick={{ fontSize: \"var(--ds-font-size-xs)\", fontFamily: \"var(--ds-font-sans)\", fill: \"var(--ds-text-muted)\" }}\n />\n <PolarRadiusAxis\n tick={{ fontSize: \"var(--ds-font-size-xs)\", fontFamily: \"var(--ds-font-sans)\", fill: \"var(--ds-text-muted)\" }}\n tickFormatter={tickFormat}\n axisLine={false}\n />\n {showTooltip && <Tooltip content={<ChartTooltipContent />} />}\n {legendVisible && <ChartLegend order={dataKeys.map((dk) => dk.key)} />}\n {dataKeys.map((dk, i) => (\n <Radar\n key={dk.key}\n name={dk.label ?? dk.key}\n dataKey={dk.key}\n stroke={solidColors[i]}\n fill={filled ? softColors[i] : \"transparent\"}\n strokeWidth={2}\n dot={showDots ? { r: 3, fill: solidColors[i] } : false}\n isAnimationActive={isAnimated}\n />\n ))}\n </RechartsRadarChart>\n </ResponsiveContainer>\n </ChartWrapper>\n );\n}));\n","import { forwardRef } from \"react\";\nimport {\n RadialBarChart as RechartsRadialBarChart,\n RadialBar,\n Tooltip,\n ResponsiveContainer,\n} from \"recharts\";\nimport { useChartColors, useChartAnimation } from \"../../lib/chart-utils\";\nimport { ChartTooltipContent, ChartLegend } from \"./ChartPrimitives\";\nimport { ChartWrapper, markChart } from \"./ChartWrapper\";\n\nexport interface RadialBarChartProps {\n data: { name: string; value: number; max?: number; [key: string]: unknown }[];\n /** \"auto\" (the default): square. A preset or a number overrides it; a ChartContainer's own height wins. */\n height?: \"auto\" | \"sm\" | \"md\" | \"lg\" | number;\n showTooltip?: boolean;\n showLegend?: boolean;\n showLabels?: boolean;\n startAngle?: number;\n endAngle?: number;\n animated?: boolean;\n \"aria-label\"?: string;\n className?: string;\n}\n\nexport const RadialBarChart = markChart(forwardRef<HTMLDivElement, RadialBarChartProps>(function RadialBarChart({\n data,\n height = \"auto\",\n showTooltip = true,\n showLegend = true,\n showLabels = false,\n startAngle = 90,\n endAngle = -270,\n animated,\n \"aria-label\": ariaLabel,\n className,\n}, ref) {\n const colors = useChartColors(data.length, false);\n const isAnimated = useChartAnimation(animated);\n\n // the chart's own fields alone: recharts draws each bar, and its background track, with its row's fields, so a row's\n // `role` or `aria-label` became theirs (Sprint 25.29 item 14)\n const chartData = data.map((d, i) => ({\n name: d.name,\n value: d.value,\n ...(d.max !== undefined ? { max: d.max } : {}),\n fill: colors[i % colors.length],\n }));\n\n if (!data?.length) return null;\n\n return (\n <ChartWrapper ref={ref} height={height} size={{ model: \"square\" }} chart=\"radial-bar\" className={className} aria-label={ariaLabel}>\n <ResponsiveContainer width=\"100%\" height=\"100%\">\n <RechartsRadialBarChart\n data={chartData}\n cx=\"50%\"\n cy=\"50%\"\n innerRadius=\"20%\"\n outerRadius=\"90%\"\n startAngle={startAngle}\n endAngle={endAngle}\n accessibilityLayer\n >\n <RadialBar\n dataKey=\"value\"\n background={{ fill: \"var(--ds-bg-muted)\" }}\n label={showLabels ? { position: \"insideStart\", fill: \"var(--ds-text-primary)\", fontSize: \"var(--ds-font-size-xs)\" } : false}\n isAnimationActive={isAnimated}\n />\n {showTooltip && <Tooltip content={<ChartTooltipContent />} />}\n {showLegend && <ChartLegend order={data.map((d) => d.name)} by=\"value\" />}\n </RechartsRadialBarChart>\n </ResponsiveContainer>\n </ChartWrapper>\n );\n}));\n","import { forwardRef } from \"react\";\nimport {\n FunnelChart as RechartsFunnelChart,\n Funnel,\n Tooltip,\n LabelList,\n ResponsiveContainer,\n} from \"recharts\";\nimport { useChartColors, useChartAnimation } from \"../../lib/chart-utils\";\nimport { ChartTooltipContent } from \"./ChartPrimitives\";\nimport { ChartWrapper, markChart } from \"./ChartWrapper\";\n\n/** A funnel stage takes a taller row than a sideways bar (Sprint 25.9, A2). */\nconst STAGE_ROWS = 1.5;\n\nexport interface FunnelChartProps {\n data: { name: string; value: number; [key: string]: unknown }[];\n /** \"auto\" (the default): a row per stage. A preset or a number overrides it; a ChartContainer's own height wins. */\n height?: \"auto\" | \"sm\" | \"md\" | \"lg\" | number;\n showTooltip?: boolean;\n /** Kept for compatibility: a funnel has no legend, its labels name the stages (Recharts gives it no legend entries). */\n showLegend?: boolean;\n showLabels?: boolean;\n animated?: boolean;\n \"aria-label\"?: string;\n className?: string;\n}\n\nexport const FunnelChart = markChart(forwardRef<HTMLDivElement, FunnelChartProps>(function FunnelChart({\n data,\n height = \"auto\",\n showTooltip = true,\n showLabels = true,\n animated,\n \"aria-label\": ariaLabel,\n className,\n}, ref) {\n const colors = useChartColors(data.length, false);\n const isAnimated = useChartAnimation(animated);\n\n // the chart's own fields alone: recharts draws each stage with its row's fields, so a row's `role` or `aria-label`\n // became the stage's (Sprint 25.29 item 14)\n const chartData = data.map((d, i) => ({\n name: d.name,\n value: d.value,\n fill: colors[i % colors.length],\n }));\n\n if (!data?.length) return null;\n\n return (\n <ChartWrapper ref={ref} height={height} size={{ model: \"rows\", units: data.length * STAGE_ROWS, axis: \"16px\" }} chart=\"funnel\" className={className} aria-label={ariaLabel}>\n <ResponsiveContainer width=\"100%\" height=\"100%\">\n <RechartsFunnelChart accessibilityLayer>\n <Funnel dataKey=\"value\" data={chartData} isAnimationActive={isAnimated}>\n {showLabels && (\n <LabelList\n dataKey=\"name\"\n position=\"right\"\n fill=\"var(--ds-text-primary)\"\n fontSize=\"var(--ds-font-size-sm)\"\n fontFamily=\"var(--ds-font-sans)\"\n />\n )}\n </Funnel>\n {showTooltip && <Tooltip content={<ChartTooltipContent />} />}\n </RechartsFunnelChart>\n </ResponsiveContainer>\n </ChartWrapper>\n );\n}));\n","// showcase/src/lib/token-algorithms.ts\n// The one source for all token generation helpers. The platform imports it through\n// platform/src/lib/token-algorithms.ts, a re-export (Sprint 25.7 review, 26 September 2026: no more synced copy).\n\nexport type HoverEffect = 'scale' | 'lift' | 'scale-lift'\n\nfunction hasScaleEffect(effect: HoverEffect): boolean {\n return effect === 'scale' || effect === 'scale-lift'\n}\n\nfunction hasLiftEffect(effect: HoverEffect): boolean {\n return effect === 'lift' || effect === 'scale-lift'\n}\n\nexport interface GradientConfig {\n accentMode: 'solid' | 'gradient'\n endHue: number\n angle: number\n hue: number\n sat: number\n endSat?: number\n endShade?: number\n}\n\nexport interface InteractiveHoverConfig {\n enabled: boolean\n effect: HoverEffect\n speed: number\n ease: string\n scale: number\n lift: number\n pressDepth: number\n}\n\nexport interface AmbientHoverConfig {\n enabled: boolean\n effect: HoverEffect\n speed: number\n ease: string\n scale: number\n lift: number\n}\n\nexport interface MotionDecisions {\n speed: number\n ease: string\n intensity?: 'none' | 'subtle' | 'moderate' | 'expressive'\n interactive?: InteractiveHoverConfig\n ambient?: AmbientHoverConfig\n}\n\n// ---------------------------------------------------------------------------\n// On-fill text (Sprint 20.10)\n// ---------------------------------------------------------------------------\n//\n// The colour of text and icons on a solid fill is decided by contrast, not by\n// preset: white when white reaches WCAG AA (4.5:1) over the fill, otherwise\n// the theme's darkest neutral. One function, `onFillText`, decides for every\n// fill the theme emits — the page accent (`--ds-text-on-primary`), the\n// independent sidebar and header accents, the three status fills and the five\n// palette bold fills — and nothing else decides on-fill colour.\n//\n// The decision uses a real conversion (OKLCH → OKLab → linear sRGB → relative\n// luminance) of the fill as the browser draws it: a colour outside sRGB has\n// each channel clipped, which is what Chrome renders (measured, Sprint 25.7\n// Part D; see oklchToLinearSrgbClamped) — not the chroma reduction CSS Color 4\n// describes, which this used until then. The status palettes are literal\n// OKLCH values at arbitrary lightness, and saturated fills near the gamut\n// edge render lighter than their mapped colour. `estimateContrastRatio` below\n// keeps its L³ proxy for the palette pair code that has always used it.\n\nexport interface Oklch { L: number; C: number; H: number }\n\n/**\n * The --ds-primary-{shade} scale from roots.css: lightness and the chroma\n * multiplier applied to --ds-sat-primary. The one table every literal accent\n * colour (gradient start and end, independent sidebar and header accents) is\n * computed from, so a flip at a given shade is the same flip everywhere.\n * A test pins it against the CSS.\n */\nexport const PRIMARY_SCALE: Record<number, { L: number; c: number }> = {\n 300: { L: 0.77, c: 0.150 },\n 400: { L: 0.66, c: 0.180 },\n 500: { L: 0.55, c: 0.200 },\n 600: { L: 0.47, c: 0.185 },\n 700: { L: 0.40, c: 0.165 },\n 800: { L: 0.33, c: 0.135 },\n 900: { L: 0.25, c: 0.100 },\n}\n\n/** Nearest step of the scale; a missing or malformed shade reads as 500 rather than throwing (stored decisions are read raw). */\nfunction scaleShade(shade: number): number {\n if (!Number.isFinite(shade)) return 500\n const s = Math.max(300, Math.min(900, shade))\n return Math.round(s / 100) * 100\n}\n\n/** The literal OKLCH of --ds-primary-{shade} at a saturation and hue. */\nexport function accentColour(shade: number, sat: number, hue: number): Oklch {\n const { L, c } = PRIMARY_SCALE[scaleShade(shade)]\n return { L, C: c * sat, H: hue }\n}\n\n/** Formats an OKLCH colour the way the emitters always have (L to 3 places, C to 4). */\nexport function oklchCss(colour: Oklch): string {\n return `oklch(${colour.L.toFixed(3)} ${colour.C.toFixed(4)} ${colour.H})`\n}\n\n/** Parses an `oklch(L C H)` literal (optional `/ alpha`). Returns null for anything else, including var() references. */\nexport function parseOklch(value: string): Oklch | null {\n const m = value.trim().match(/^oklch\\(\\s*([\\d.]+)(%?)\\s+([\\d.]+)\\s+([\\d.]+)(?:deg)?\\s*(?:\\/\\s*[\\d.%]+\\s*)?\\)$/i)\n if (!m) return null\n const L = m[2] ? parseFloat(m[1]) / 100 : parseFloat(m[1])\n return { L, C: parseFloat(m[3]), H: parseFloat(m[4]) }\n}\n\nfunction oklchToLinearSrgb({ L, C, H }: Oklch): [number, number, number] {\n const h = (H * Math.PI) / 180\n const a = C * Math.cos(h)\n const b = C * Math.sin(h)\n const l_ = L + 0.3963377774 * a + 0.2158037573 * b\n const m_ = L - 0.1055613458 * a - 0.0638541728 * b\n const s_ = L - 0.0894841775 * a - 1.2914855480 * b\n const l = l_ * l_ * l_\n const m = m_ * m_ * m_\n const s = s_ * s_ * s_\n return [\n +4.0767416621 * l - 3.3077115913 * m + 0.2309699292 * s,\n -1.2684380046 * l + 2.6097574011 * m - 0.3413193965 * s,\n -0.0041960863 * l - 0.7034186147 * m + 1.7076147010 * s,\n ]\n}\n\n/**\n * WCAG relative luminance of an OKLCH colour as the browser draws it: each\n * channel clipped to sRGB (oklchToLinearSrgbClamped) and rounded to the\n * nearest of the 256 steps an 8-bit sRGB surface has, then weighted. Contrast\n * decisions use the range Chrome's rounding can land in (luminanceRange); this\n * is its nearest value.\n */\nexport function oklchToLuminance(colour: Oklch): number {\n return srgbLuminance(oklchToSrgb(colour).map((v) => Math.round(v * 255) / 255) as [number, number, number])\n}\n\n/**\n * Linear sRGB channels as the browser renders them: an out-of-gamut colour has\n * each channel clipped to 0–1. Measured in Chrome 153 (Sprint 25.7 Part D): 211\n * of 211 oklch() colours outside sRGB came back within 1/255 of per-channel\n * clipping, from an sRGB canvas and from a screenshot alike. Reducing chroma to\n * the gamut edge, which this function did until then (CSS Color 4's intent),\n * was up to 82/255 off in a channel, and the full CSS Color 4 gamut-mapping\n * algorithm up to 73/255. Clipping is usually lighter (a negative channel\n * rises to 0), so white text decided on the chroma-reduced colour could miss\n * AA as drawn: 4.41:1 on the palette bold at hue 187.5, which it scored 4.62.\n */\nfunction oklchToLinearSrgbClamped(colour: Oklch): [number, number, number] {\n return oklchToLinearSrgb(colour).map((v) => Math.min(1, Math.max(0, v))) as [number, number, number]\n}\n\nconst gammaEncode = (v: number) => (v <= 0.0031308 ? 12.92 * v : 1.055 * Math.pow(v, 1 / 2.4) - 0.055)\nconst gammaDecode = (v: number) => (v <= 0.04045 ? v / 12.92 : Math.pow((v + 0.055) / 1.055, 2.4))\n\n/** Gamma-encoded sRGB channels (0..1) — the space `opacity` compositing and `color-mix(in srgb)` blend in. */\nfunction oklchToSrgb(colour: Oklch): [number, number, number] {\n return oklchToLinearSrgbClamped(colour).map(gammaEncode) as [number, number, number]\n}\n\nfunction srgbLuminance([r, g, b]: [number, number, number]): number {\n return 0.2126 * gammaDecode(r) + 0.7152 * gammaDecode(g) + 0.0722 * gammaDecode(b)\n}\n\n/**\n * How near a half step (of 1/255) a channel can sit and still come out of\n * Chrome one step either way. Chrome's arithmetic is not this file's: of 2,435\n * colours measured (Sprint 25.7 Part D; 7,305 channels), 39 channels came back\n * one step from the nearest, and every one sat within 0.12 of a step of the\n * half-step boundary.\n * One step is up to 0.05 of contrast near the white crossover, which is where\n * the decisions live, so a decision counts both steps inside this window.\n */\nexport const ROUNDING_WINDOW = 0.25\n\n/** A colour's WCAG luminance as Chrome can draw it: [darkest, lightest] over the 8-bit steps each channel can round to. */\nexport type LuminanceRange = readonly [number, number]\n\n/** The luminance range of gamma-encoded sRGB channels (0–1): each channel's nearest step, or both steps beside it within the window. */\nfunction srgbLuminanceRange(encoded: readonly number[]): LuminanceRange {\n let lo = 0\n let hi = 0\n encoded.forEach((v, i) => {\n const x = Math.min(1, Math.max(0, v)) * 255\n const below = Math.floor(x)\n const [a, b] = Math.abs(x - below - 0.5) <= ROUNDING_WINDOW ? [below, Math.min(255, below + 1)] : [Math.round(x), Math.round(x)]\n const weight = [0.2126, 0.7152, 0.0722][i]\n lo += weight * gammaDecode(a / 255)\n hi += weight * gammaDecode(b / 255)\n })\n return [lo, hi]\n}\n\n/** The luminance range an OKLCH colour can take as Chrome draws it: clipped to sRGB, then rounded to 8 bits. */\nexport function luminanceRange(colour: Oklch): LuminanceRange {\n return srgbLuminanceRange(oklchToSrgb(colour))\n}\n\n/** The lowest contrast two colours can show, every way either can round (1 when their ranges meet). */\nexport function worstContrastOf([t0, t1]: LuminanceRange, [f0, f1]: LuminanceRange): number {\n if (t0 <= f1 && f0 <= t1) return 1\n return t0 > f1 ? contrastRatio(t0, f1) : contrastRatio(t1, f0)\n}\n\n/** WCAG contrast ratio between two relative luminances. */\nexport function contrastRatio(lumA: number, lumB: number): number {\n const lighter = Math.max(lumA, lumB)\n const darker = Math.min(lumA, lumB)\n return (lighter + 0.05) / (darker + 0.05)\n}\n\n/**\n * Sprint 25.14 A20 (and Sprint 30's P1): colours as the browser has drawn them — 8-bit sRGB channels and an alpha, read\n * from a canvas or a screenshot — composited and compared as WCAG does. A translucent edge is judged over what it sits\n * on: each ground laid under it in gamma-encoded sRGB, the space the browser blends in.\n */\nexport type DrawnColour = readonly [r: number, g: number, b: number, alpha: number]\n\n/** `top` laid over an opaque `ground`, as the browser composites it. */\nexport function drawnOver(top: DrawnColour, ground: DrawnColour): DrawnColour {\n const a = top[3]\n return [0, 1, 2].map((i) => Math.round(top[i] * a + ground[i] * (1 - a))).concat(1) as unknown as DrawnColour\n}\n\n/** WCAG relative luminance of an opaque drawn colour. */\nexport function drawnLuminance([r, g, b]: DrawnColour): number {\n return srgbLuminance([r / 255, g / 255, b / 255])\n}\n\n/** WCAG contrast between two opaque drawn colours. */\nexport function drawnContrast(a: DrawnColour, b: DrawnColour): number {\n return contrastRatio(drawnLuminance(a), drawnLuminance(b))\n}\n\n/** The lowest contrast `edge` shows over each ground (opaque), composited where it is translucent, and the ground it is lowest on. */\nexport function edgeContrast(edge: DrawnColour, grounds: ReadonlyArray<readonly [name: string, ground: DrawnColour]>): { ratio: number; on: string } {\n let worst = { ratio: Infinity, on: \"\" }\n for (const [name, ground] of grounds) {\n const ratio = drawnContrast(drawnOver(edge, ground), ground)\n if (ratio < worst.ratio) worst = { ratio, on: name }\n }\n return worst\n}\n\nexport const WCAG_AA_TEXT = 4.5\n\n/** White text as the emitters write it. */\nexport const ON_FILL_WHITE = 'oklch(1 0 0)'\n/** Last-resort dark text: the theme's darkest neutral. Used only when no tint of the fill's own hue can pass (§ onFillDarkTint). */\nexport const ON_FILL_DARK = 'var(--ds-neutral-950)'\n/**\n * The last-resort candidate as a colour: --ds-neutral-950 is L 0.13 with a\n * chroma of 0.002 × --ds-sat-neutral, which is invisible to the luminance\n * calculation, so the hue does not matter here.\n */\nexport const DARK_TEXT_CANDIDATE: Oklch = { L: 0.13, C: 0.002, H: 0 }\n\n/** The dark tint keeps the fill's hue at this chroma (the palette's `-dark` variant uses 0.10 too); a duller fill keeps its own chroma. */\nexport const ON_FILL_TINT_CHROMA = 0.10\n/** Preferred contrast for the dark tint. Falls back to AA where no dark colour can reach it (fills just above the white crossover). */\nexport const ON_FILL_TINT_TARGET = 5\nconst TINT_L_MAX = 0.45\nconst TINT_L_MIN = 0.10\nconst TINT_L_STEP = 0.01\n\nconst WHITE_RANGE: LuminanceRange = [1, 1]\nconst DARK_RANGE = luminanceRange(DARK_TEXT_CANDIDATE)\n\n/** The worst contrast a text colour gets over one or more fills as Chrome draws them (a gradient passes every colour it paints: gradientFills). */\nfunction minContrast(text: LuminanceRange, fills: Oklch[]): number {\n let min = Infinity\n for (const f of fills) min = Math.min(min, worstContrastOf(text, luminanceRange(f)))\n return min\n}\n\n/**\n * White or dark text over one or more fills (a gradient passes every colour it\n * paints, gradientFills): whichever onFillTextValue emits, so a caller showing the choice (the\n * builder's \"text flips to dark\" note) agrees with the token.\n */\nexport function onFillText(fill: Oklch, ...moreFills: Oklch[]): 'white' | 'dark' {\n return onFillTextValue(fill, ...moreFills) === ON_FILL_WHITE ? 'white' : 'dark'\n}\n\n/**\n * The dark text colour for a fill: a deep shade of the fill's own hue rather\n * than a neutral, so an amber badge reads as amber-on-amber the way the\n * decorative palette pairs `-dark` text with `-subtle` backgrounds. The\n * lightest tint (L 0.45 → 0.10 in 0.01 steps, chroma capped at 0.10) whose\n * worst contrast across the fills reaches 5:1. Contrast comes before colour:\n * where the full-chroma tint cannot reach the target the chroma halves, then\n * quarters (a saturated green tint at L 0.10 is still luminous enough to\n * miss 5:1 over a light green); where no dark colour can reach 5:1 the\n * lightest reaching AA; null when not even AA is reachable (the caller then\n * falls back to --ds-neutral-950). For a gradient the hue is the start\n * colour's; the contrast is checked over every colour it paints (gradientFills).\n */\nexport function onFillDarkTint(fill: Oklch, ...moreFills: Oklch[]): Oklch | null {\n const fills = [fill, ...moreFills]\n const H = fill.H\n const chroma = Math.min(ON_FILL_TINT_CHROMA, fill.C)\n for (const target of [ON_FILL_TINT_TARGET, WCAG_AA_TEXT]) {\n for (const C of [chroma, chroma / 2, chroma / 4]) {\n for (let L = TINT_L_MAX; L >= TINT_L_MIN - 1e-9; L -= TINT_L_STEP) {\n const candidate = { L: +L.toFixed(2), C: +C.toFixed(4), H }\n if (minContrast(luminanceRange(candidate), fills) >= target) return candidate\n }\n }\n }\n return null\n}\n\n/**\n * The CSS value for text on a fill, the one on-fill decision: white where\n * white reaches AA over every fill as drawn; else the dark tint\n * (onFillDarkTint); else --ds-neutral-950 or white, whichever does better.\n * The tints go darker than --ds-neutral-950, so they also cover the sliver\n * around luminance 0.184 where white and the neutral both miss a single fill\n * (a fill at L 0.55 near hue 215). Only a gradient whose colours lie either\n * side of the crossover can leave every colour short of AA; the fill has to\n * change there.\n */\nexport function onFillTextValue(fill: Oklch, ...moreFills: Oklch[]): string {\n const fills = [fill, ...moreFills]\n const whiteMin = minContrast(WHITE_RANGE, fills)\n if (whiteMin >= WCAG_AA_TEXT) return ON_FILL_WHITE\n const tint = onFillDarkTint(fill, ...moreFills)\n if (tint) return oklchCss(tint)\n return minContrast(DARK_RANGE, fills) >= whiteMin ? ON_FILL_DARK : ON_FILL_WHITE\n}\n\n/** How many equal parts a gradient is sampled in, between its two ends (every 5%: a dip can sit at 95% of the way). */\nconst GRADIENT_SAMPLES = 20\n\n/**\n * The colours a gradient paints, for deciding the text over it: its two ends\n * (the start first, so a dark tint keeps the start's hue) and the points\n * between them. Chrome paints a linear-gradient of oklch() colours in Oklab\n * (CSS Color 4's default for colours that are not legacy sRGB): its pixels\n * follow Oklab interpolation to within 0.003 of luminance (measured, Sprint\n * 25.7, 26 September 2026). A point in between can be darker or lighter than\n * both ends, because two saturated ends that sRGB clips meet at a duller colour\n * that clips less: up to 5% darker than the darker end across the accent scale\n * (a violet to a red at primary-600), enough to take text below AA.\n */\nexport function gradientFills(start: Oklch, end: Oklch): [Oklch, Oklch, ...Oklch[]] {\n const lab = ({ L, C, H }: Oklch) => [L, C * Math.cos((H * Math.PI) / 180), C * Math.sin((H * Math.PI) / 180)]\n const [a, b] = [lab(start), lab(end)]\n const between: Oklch[] = []\n for (let i = 1; i < GRADIENT_SAMPLES; i++) {\n const [L, x, y] = a.map((v, k) => v + ((b[k] - v) * i) / GRADIENT_SAMPLES)\n between.push({ L, C: Math.hypot(x, y), H: ((Math.atan2(y, x) * 180) / Math.PI + 360) % 360 })\n }\n return [start, end, ...between]\n}\n\n/* ── Tinted surfaces (subtle colourful header) ──────────────────────────\n A tinted surface is the surface colour (--ds-bg-surface, so it matches the\n cards around it) washed with the accent — the gradient, or the solid accent —\n at one strength. One recipe in both accent modes, so the tint is a pure\n shade of the accent over the paper and its luminance is knowable: the muted\n ink over it is the lightest neutral step that clears AA against the worst\n wash stop. The picker measures against the default surface; a preset that\n overrides --ds-bg-surface (cream, translucent) shifts the real tint a little,\n the same limitation --ds-text-on-primary has under a --ds-gradient override. */\n\n/** Opacity of the accent wash over --ds-tint-base. Shared by the CSS (--ds-tint-strength) and the ink picker. */\nexport const TINT_STRENGTH = 0.15\n/** The default --ds-bg-surface per mode: white in light, --ds-neutral-800 in dark. @sync roots.css (tint-parity.test.ts checks). */\nexport const TINT_BASE: Record<'light' | 'dark', Oklch> = {\n light: { L: 1, C: 0, H: 0 },\n dark: { L: 0.27, C: 0.004, H: 0 },\n}\n/** The CSS for --ds-accent-wash when the accent is solid: a flat image so the overlay reads one token in both modes. */\nexport const SOLID_ACCENT_WASH = 'linear-gradient(var(--ds-accent-primary), var(--ds-accent-primary))'\n\n/** L of the neutral steps: the muted-ink candidates (200–700) and the deep steps that can serve as text on the neutral status fill (chroma ≤ 0.01 × sat, invisible to luminance). @sync roots.css --ds-neutral-* (tint-parity.test.ts checks). */\nexport const NEUTRAL_STEP_L: Record<number, number> = { 200: 0.90, 300: 0.84, 400: 0.71, 500: 0.55, 600: 0.45, 700: 0.37, 800: 0.27, 900: 0.20, 950: 0.13 }\n/** Candidate steps, lightest first: the first that clears AA wins, so hierarchy against --ds-text-secondary is kept where the tint allows. */\nconst MUTED_ON_TINT_STEPS: Record<'light' | 'dark', number[]> = { light: [400, 500, 600, 700], dark: [400, 300, 200] }\n\n/** The tinted surface for one wash colour in gamma sRGB: the base blended with the wash (clipped, as drawn) at TINT_STRENGTH, as the browser composites the overlay. */\nfunction tintSrgb(mode: 'light' | 'dark', wash: Oklch): [number, number, number] {\n const base = oklchToSrgb(TINT_BASE[mode])\n const top = oklchToSrgb(wash)\n return base.map((v, i) => v * (1 - TINT_STRENGTH) + top[i] * TINT_STRENGTH) as [number, number, number]\n}\n\n/** WCAG luminance of the tinted surface for one wash colour, at the nearest 8-bit step (the ink picker uses the range Chrome's rounding can land in). */\nexport function tintLuminance(mode: 'light' | 'dark', wash: Oklch): number {\n return srgbLuminance(tintSrgb(mode, wash).map((v) => Math.round(v * 255) / 255) as [number, number, number])\n}\n\n/**\n * The muted ink for text over a tinted surface: `var(--ds-neutral-NNN)`, the\n * lightest candidate step whose worst contrast across the wash colours (a\n * gradient passes both ends) reaches AA as Chrome draws both. The darkest\n * candidate when none does.\n */\nexport function mutedOnTint(mode: 'light' | 'dark', wash: Oklch, ...moreWashes: Oklch[]): string {\n const surfaces: Paint[] = [wash, ...moreWashes].map((w) => ({ rgb: tintSrgb(mode, w), alpha: 1 }))\n const steps = MUTED_ON_TINT_STEPS[mode]\n // the shared routine (Sprint 30's firstReadable), walking the neutral scale's steps\n const candidates = steps.map((step): ColourCandidate => ({ value: `var(--ds-neutral-${step})`, paint: { rgb: oklchToSrgb({ L: NEUTRAL_STEP_L[step], C: 0, H: 0 }), alpha: 1 } }))\n return firstReadable(candidates, surfaces, WCAG_AA_TEXT)?.value ?? `var(--ds-neutral-${steps[steps.length - 1]})`\n}\n\n/**\n * On-fill tokens for the four status fills that carry text (Badge, Button,\n * Stepper, Dock, the Gantt's bars). Takes the palette's literal values; a value\n * that is not an OKLCH literal keeps white, the roots.css default.\n */\nexport function onStatusFillTokens(sv: { success: string; warning: string; error: string; info: string }): Record<string, string> {\n const pick = (value: string) => {\n const c = parseOklch(value)\n return c ? onFillTextValue(c) : ON_FILL_WHITE\n }\n return {\n '--ds-text-on-success': pick(sv.success),\n '--ds-text-on-warning': pick(sv.warning),\n '--ds-text-on-error': pick(sv.error),\n '--ds-text-on-info': pick(sv.info),\n }\n}\n\n/**\n * The neutral status fill per mode: a mid step of the theme's neutral scale, for\n * an item with no status (\"not started\", a Gantt bar with no known status). Dark\n * mode takes the step one lighter, as every status fill does (500 → 400), so the\n * fill still shows at 3:1 on the dark surfaces (neutral-700 to -900).\n * @sync roots.css --ds-status-neutral (token-algorithms.test.ts checks).\n */\nexport const STATUS_NEUTRAL_STEP: Record<'light' | 'dark', number> = { light: 500, dark: 400 }\n\n/** The deep neutral steps that can carry text on the neutral fill, lightest first. */\nconst NEUTRAL_TEXT_STEPS = [700, 800, 900, 950]\n\n/**\n * The neutral status fill and the text on it, for one mode. The same in every\n * status palette, so roots.css declares the same pair as its defaults. The text\n * is decided as every on-fill colour is (onFillText, onFillDarkTint): white\n * where white reaches AA over the fill; else the lightest deep shade of the\n * fill's own hue reaching 5:1, then AA — for a neutral fill that is a step of\n * the neutral scale, which carries the theme's neutral hue and saturation as the\n * fill does; --ds-neutral-950 as the last resort.\n */\nexport function neutralStatusFillTokens(mode: 'light' | 'dark'): Record<string, string> {\n const step = STATUS_NEUTRAL_STEP[mode]\n const fill: Oklch = { L: NEUTRAL_STEP_L[step], C: 0, H: 0 }\n const text = (): string => {\n if (onFillText(fill) === 'white') return ON_FILL_WHITE\n for (const target of [ON_FILL_TINT_TARGET, WCAG_AA_TEXT]) {\n for (const s of NEUTRAL_TEXT_STEPS) {\n if (s > step && minContrast(luminanceRange({ L: NEUTRAL_STEP_L[s], C: 0, H: 0 }), [fill]) >= target) return `var(--ds-neutral-${s})`\n }\n }\n return ON_FILL_DARK\n }\n return {\n '--ds-status-neutral': `var(--ds-neutral-${step})`,\n '--ds-text-on-neutral': text(),\n }\n}\n\n/**\n * Computes accent tokens from shade + mode.\n * Chart tokens are now generated separately via computeChartTokens (they\n * depend on palette values that don't exist at accent-computation time).\n *\n * With a `gradient` config (which every emitter passes, solid or gradient,\n * because it carries the hue and saturation) the set also includes\n * `--ds-text-on-primary`, decided by `onFillText` over the accent — or over\n * every colour a gradient paints (gradientFills). Without one the token is\n * left to roots.css (white).\n */\nexport function getAccentTokens(\n shade: number,\n mode: 'light' | 'dark',\n gradient?: GradientConfig\n): Record<string, string> {\n const s = Math.max(300, Math.min(900, shade))\n const hover = mode === 'dark' ? Math.max(300, s - 100) : Math.min(950, s + 100)\n const active = mode === 'dark' ? Math.max(300, s - 200) : Math.min(950, s + 200)\n\n const tokens: Record<string, string> = {\n '--ds-accent-primary': `var(--ds-primary-${s})`,\n '--ds-accent-primary-hover': `var(--ds-primary-${hover})`,\n '--ds-accent-primary-active': `var(--ds-primary-${active})`,\n // The active look's soft halo (Sprint 30, D6: a field clicked into, an open trigger). The focus colour is derived\n // (readableTokens); --ds-border-focus is its alias in roots.css, and the old ring and input alias are gone (P5).\n '--ds-ring-active': 'var(--ds-accent-soft)',\n // Tinted surfaces: --ds-tint-base is var(--ds-bg-surface) in roots.css; only the strength is emitted (see mutedOnTint).\n '--ds-tint-strength': String(TINT_STRENGTH),\n }\n\n if (gradient?.accentMode === 'gradient') {\n const startHue = gradient.hue ?? gradient.endHue\n const start = accentColour(s, gradient.sat, startHue)\n const startColor = `oklch(${start.L} ${start.C.toFixed(4)} ${startHue})`\n\n const endShade = Math.max(300, Math.min(900, gradient.endShade ?? s))\n const endSat = gradient.endSat ?? gradient.sat\n const end = accentColour(endShade, endSat, gradient.endHue)\n const endColor = oklchCss(end)\n tokens['--ds-gradient'] = `linear-gradient(${gradient.angle}deg, ${startColor}, ${endColor})`\n // The two ends as their own tokens so SVG gradients (icon strokes) can follow the theme.\n tokens['--ds-gradient-start'] = startColor\n tokens['--ds-gradient-end'] = endColor\n tokens['--ds-text-on-primary'] = onFillTextValue(...gradientFills(start, end))\n // Reads the gradient token (not the literal) so a preset override of --ds-gradient washes the tint too.\n tokens['--ds-accent-wash'] = 'var(--ds-gradient)'\n tokens['--ds-text-muted-on-tint'] = mutedOnTint(mode, start, end)\n } else {\n tokens['--ds-gradient'] = 'none'\n tokens['--ds-gradient-start'] = 'var(--ds-accent-primary)'\n tokens['--ds-gradient-end'] = 'var(--ds-accent-primary)'\n tokens['--ds-accent-wash'] = SOLID_ACCENT_WASH\n if (gradient) {\n const solid = accentColour(s, gradient.sat, gradient.hue)\n tokens['--ds-text-on-primary'] = onFillTextValue(solid)\n tokens['--ds-text-muted-on-tint'] = mutedOnTint(mode, solid)\n }\n }\n\n return tokens\n}\n\nconst DEFAULT_INTERACTIVE: InteractiveHoverConfig = {\n enabled: true, effect: 'scale-lift', speed: 150, ease: 'ease-out', scale: 1.02, lift: 2, pressDepth: 1,\n}\n\nconst DEFAULT_AMBIENT: AmbientHoverConfig = {\n enabled: true, effect: 'lift', speed: 250, ease: 'cubic-bezier(0.33, 1, 0.68, 1)', scale: 1, lift: 1,\n}\n\nconst INTENSITY_PRESETS: Record<string, Record<string, string>> = {\n none: { '--ds-hover-scale': '1', '--ds-hover-lift': '0px', '--ds-press-depth': '0px', '--ds-ambient-hover-scale': '1', '--ds-ambient-hover-lift': '0px' },\n subtle: { '--ds-hover-scale': '1.02', '--ds-hover-lift': '2px', '--ds-press-depth': '1px', '--ds-ambient-hover-scale': '1', '--ds-ambient-hover-lift': '1px' },\n moderate: { '--ds-hover-scale': '1.035', '--ds-hover-lift': '3px', '--ds-press-depth': '1px', '--ds-ambient-hover-scale': '1.01', '--ds-ambient-hover-lift': '2px' },\n expressive: { '--ds-hover-scale': '1.05', '--ds-hover-lift': '6px', '--ds-press-depth': '2px', '--ds-ambient-hover-scale': '1.015', '--ds-ambient-hover-lift': '3px' },\n}\n\n/**\n * Computes hover motion tokens from structured config.\n * Handles both modern (interactive + ambient) and legacy (intensity) input shapes.\n */\nexport function computeHoverTokens(motion: MotionDecisions): Record<string, string> {\n const i = motion.interactive\n const a = motion.ambient\n\n if (i || a) {\n const interactive = i ?? DEFAULT_INTERACTIVE\n const ambient = a ?? DEFAULT_AMBIENT\n const hasScale = interactive.enabled && hasScaleEffect(interactive.effect)\n const hasILift = interactive.enabled && hasLiftEffect(interactive.effect)\n const hasAScale = ambient.enabled && hasScaleEffect(ambient.effect)\n const hasALift = ambient.enabled && hasLiftEffect(ambient.effect)\n return {\n '--ds-hover-scale': hasScale ? String(interactive.scale) : '1',\n '--ds-hover-lift': hasILift ? `${interactive.lift}px` : '0px',\n '--ds-press-depth': interactive.enabled ? `${interactive.pressDepth}px` : '0px',\n '--ds-interactive-hover-speed': `${interactive.speed}ms`,\n '--ds-interactive-hover-ease': interactive.ease,\n '--ds-ambient-hover-scale': hasAScale ? String(ambient.scale) : '1',\n '--ds-ambient-hover-lift': hasALift ? `${ambient.lift}px` : '0px',\n '--ds-ambient-hover-speed': `${ambient.speed}ms`,\n '--ds-ambient-hover-ease': ambient.ease,\n }\n }\n\n const base = INTENSITY_PRESETS[motion.intensity ?? 'subtle'] ?? INTENSITY_PRESETS['subtle']\n return {\n ...base,\n '--ds-interactive-hover-speed': `${motion.speed}ms`,\n '--ds-interactive-hover-ease': motion.ease,\n '--ds-ambient-hover-speed': `${Math.round(motion.speed * 1.5)}ms`,\n '--ds-ambient-hover-ease': 'cubic-bezier(0.33, 1, 0.68, 1)',\n }\n}\n\n/**\n * The motion tokens under prefers-reduced-motion, with their values: no hover scale, lift or press, and no transition\n * time (Sprint 25.8.7 item 1). The one list: roots.css's reduced-motion block declares exactly these, each important,\n * and the generated stylesheet ends with the same block, so a theme declared after roots.css or written on <html> can't\n * undo the visitor's preference. A writer that declares the tokens on a wrapper of its own writes these there itself\n * (the dashboard's ProjectThemeScope). The easing curves are left as they are: with no time they move nothing. A test\n * holds roots.css's block and the generator's to this list.\n */\nexport const REDUCED_MOTION_TOKENS: Record<string, string> = {\n '--ds-transition-speed': '0ms',\n '--ds-hover-scale': '1',\n '--ds-hover-lift': '0px',\n '--ds-press-depth': '0px',\n '--ds-interactive-hover-speed': '0ms',\n '--ds-ambient-hover-scale': '1',\n '--ds-ambient-hover-lift': '0px',\n '--ds-ambient-hover-speed': '0ms',\n}\n\n/**\n * Computes the accent colour of an independent-mode sidebar (or header) from\n * the target palette, as a literal because it comes from the *other* palette.\n * Since Sprint 20.10 it sits on the same --ds-primary-{shade} scale as the\n * page accent (it used to be a lighter curve, 0.597 at 500 against 0.55), so\n * the on-accent text decision flips at the same shade everywhere.\n * `onAccent` is the text colour over the accent, emitted as\n * --ds-sidebar-text-on-accent / --ds-header-text-on-accent.\n * Used by runtime DOM writers and static CSS generator.\n */\nexport function computeSidebarAccent(\n shade: number,\n satPrimary: number,\n huePrimary: number\n): { accent: string; accentSubtle: string; onAccent: string } {\n const colour = accentColour(shade, satPrimary, huePrimary)\n const accent = oklchCss(colour)\n const accentSubtle = `color-mix(in srgb, ${accent} 10%, transparent)`\n return { accent, accentSubtle, onAccent: onFillTextValue(colour) }\n}\n\n// Status hue positions (fixed, not configurable)\nconst STATUS_HUES = { success: 142, warning: 86, error: 25, info: 255 }\nconst STATUS_HUE_VALUES = Object.values(STATUS_HUES)\n\nconst GOLDEN_ANGLE = 137.508\n\n/**\n * Normalise a hue to [0, 360).\n */\nfunction normaliseHue(h: number): number {\n return ((h % 360) + 360) % 360\n}\n\n/**\n * Angular distance on the hue wheel (0–180).\n */\nfunction hueDistance(a: number, b: number): number {\n const diff = Math.abs(normaliseHue(a) - normaliseHue(b))\n return diff > 180 ? 360 - diff : diff\n}\n\n/**\n * Distributes 5 palette hues around the OKLCH hue wheel using golden-angle\n * spacing. Avoids the primary hue neighbourhood and status hue positions.\n *\n * @param primaryHue The user's primary accent hue (0–360)\n * @param exclusionRadius Minimum angular distance from primary and status hues (default 20°)\n * @returns Array of 5 hue values, each in [0, 360)\n */\nexport function computePaletteHues(\n primaryHue: number,\n exclusionRadius = 20\n): number[] {\n const hues: number[] = []\n const excluded = [normaliseHue(primaryHue), ...STATUS_HUE_VALUES]\n\n function isColliding(h: number): boolean {\n return excluded.some(ex => hueDistance(h, ex) < exclusionRadius) ||\n hues.some(existing => hueDistance(h, existing) < exclusionRadius)\n }\n\n // Start opposite the primary hue for maximum initial separation\n const cursor = normaliseHue(primaryHue + 180)\n\n for (let i = 0; i < 5; i++) {\n let candidate = normaliseHue(cursor + i * GOLDEN_ANGLE)\n\n // Nudge colliding candidates by +5° increments, up to a full rotation\n let attempts = 0\n while (isColliding(candidate) && attempts < 72) {\n candidate = normaliseHue(candidate + 5)\n attempts++\n }\n\n hues.push(candidate)\n }\n\n return hues\n}\n\n// Palette generation lightness/chroma targets\nconst PALETTE_BOLD_L = 0.55\nconst PALETTE_BOLD_C = 0.12\nconst PALETTE_SUBTLE_L = 0.92\nconst PALETTE_SUBTLE_C = 0.03\nconst PALETTE_DARK_L = 0.35\nconst PALETTE_DARK_C = 0.10\n\n/**\n * How far a palette bold may darken to keep white text (the owner's call, 26\n * September 2026). Teals and cyans near the sRGB edge (hues 170–216.5 at the\n * constants above) clip lighter than white allows at PALETTE_BOLD_L, and one\n * step of PALETTE_BOLD_STEP brings each to AA as drawn, so a row of Badges and\n * Tags keeps one text colour. A bold that no step up to this brings to AA keeps\n * its lightness and takes a tint of its hue.\n */\nexport const PALETTE_BOLD_MAX_DARKEN = 0.02\nconst PALETTE_BOLD_STEP = 0.01\n\n/**\n * A bold fill for white text: darkened by the smallest step (PALETTE_BOLD_STEP) that brings white to AA as drawn,\n * never by more than maxDarken; a fill no darkening within the cap brings there is returned as it was, and its text\n * takes a tint (onFillTextValue). getPaletteTokens passes PALETTE_BOLD_MAX_DARKEN; the cap is a parameter so a fill\n * that needs more than it can be tested (no palette hue does at today's constants).\n */\nexport function boldForWhiteText(fill: Oklch, maxDarken: number = PALETTE_BOLD_MAX_DARKEN): Oklch {\n let L = fill.L\n while (onFillText({ ...fill, L }) === 'dark' && fill.L - L < maxDarken - 1e-9) L = +(L - PALETTE_BOLD_STEP).toFixed(2)\n return onFillText({ ...fill, L }) === 'dark' ? fill : { ...fill, L }\n}\n\n/**\n * The lightness a chart series needs in dark mode to show at 3:1 against the surfaces a chart sits on (WCAG 1.4.11):\n * every hue at C 0.12 clears 3:1 on the elevated surface (neutral-700) and 4.5:1 on the card (neutral-800). It is\n * primary-400's lightness, as the light-mode series (the palette bold, 0.55, a step darker for the teals) is\n * primary-500's (Sprint 25.7).\n */\nexport const CHART_SERIES_DARK_L = 0.66\n\n/**\n * Generates the 5 palette tokens (bold/subtle/dark/bg/text) for a single hue.\n * Validates subtle/dark contrast and clamps chroma if needed.\n *\n * @param hue The palette hue value (0–360)\n * @param index Palette index (1–5) for token naming\n * @param mode 'light' | 'dark' — determines bg/text alias direction\n * @returns Record of CSS custom properties for this palette hue\n */\n/**\n * The soft pair of a hue (the supporting colours' step, Sprint 25.18's one rule for coloured text on a coloured ground,\n * the owner's D50): a pale fill and a deep text at fixed lightnesses, the gap widened until the pair reaches AA (4.5:1),\n * which these lightnesses already clear for every hue. `chroma` caps the two chromas: the supporting colours pass none\n * (their own constants); the accent passes its own chroma, so a grey accent gives a grey pair. Light mode draws the\n * pale one as the fill and the deep one as the text; dark mode swaps them.\n */\nexport function softPair(hue: number, chroma = Infinity): { subtle: string; dark: string } {\n const h = normaliseHue(hue)\n let subtleL = PALETTE_SUBTLE_L\n let darkL = PALETTE_DARK_L\n let ratio = estimateContrastRatio(subtleL, darkL)\n while (ratio < 4.5 && subtleL < 0.98 && darkL > 0.20) {\n subtleL = Math.min(0.98, subtleL + 0.02)\n darkL = Math.max(0.20, darkL - 0.02)\n ratio = estimateContrastRatio(subtleL, darkL)\n }\n const c = (constant: number) => Math.max(0, Math.min(constant, chroma)).toFixed(4)\n return {\n subtle: `oklch(${subtleL.toFixed(2)} ${c(PALETTE_SUBTLE_C)} ${h})`,\n dark: `oklch(${darkL.toFixed(2)} ${c(PALETTE_DARK_C)} ${h})`,\n }\n}\n\n/** The soft pair's lightnesses and chromas, for the stylesheet's own reading of the step (roots.css derives the accent's pair from them). */\nexport const SOFT_PAIR = { subtleL: PALETTE_SUBTLE_L, subtleC: PALETTE_SUBTLE_C, darkL: PALETTE_DARK_L, darkC: PALETTE_DARK_C } as const\n\n/**\n * The accent's soft pair (Sprint 25.18 A15, the owner's D51): the supporting colours' step applied to the accent, its\n * chroma capped by the accent's own (the primary scale's chroma at the accent's shade, times the saturation), so the\n * accent's tint and text are one more supporting colour. `--ds-accent-bg` is the fill, `--ds-accent-text` the text on it\n * (readable on the page and a card too); a Calendar event in the accent draws with them.\n */\nexport function getAccentPairTokens(shade: number, sat: number, hue: number, mode: 'light' | 'dark'): Record<string, string> {\n const { subtle, dark } = softPair(hue, accentColour(shade, sat, hue).C)\n return {\n '--ds-accent-bg': mode === 'light' ? subtle : dark,\n '--ds-accent-text': mode === 'light' ? dark : subtle,\n }\n}\n\nexport function getPaletteTokens(\n hue: number,\n index: number,\n mode: 'light' | 'dark'\n): Record<string, string> {\n const h = normaliseHue(hue)\n\n // Bold: white text as drawn, darkened within PALETTE_BOLD_MAX_DARKEN where the fill clips too light for it; past the\n // cap it keeps its lightness and its text takes a tint (below)\n const boldFill = boldForWhiteText({ L: PALETTE_BOLD_L, C: PALETTE_BOLD_C, H: h })\n const boldL = boldFill.L\n\n // Subtle/dark: the soft pair, at AA (softPair)\n const { subtle, dark } = softPair(h)\n const bold = `oklch(${boldL.toFixed(2)} ${PALETTE_BOLD_C.toFixed(4)} ${h})`\n\n const prefix = `--ds-palette-${index}`\n\n return {\n [`${prefix}-bold`]: bold,\n [`${prefix}-subtle`]: subtle,\n [`${prefix}-dark`]: dark,\n [`${prefix}-bg`]: mode === 'light' ? `var(${prefix}-subtle)` : `var(${prefix}-dark)`,\n [`${prefix}-text`]: mode === 'light' ? `var(${prefix}-dark)` : `var(${prefix}-subtle)`,\n // The chart series colour: the bold in light mode; lifted in dark, where the bold sinks into a dark card\n // (2.9:1 for reds and magentas on neutral-800). Badges and Tags keep the bold, for their white text.\n [`${prefix}-chart`]: mode === 'light' ? `var(${prefix}-bold)` : `oklch(${CHART_SERIES_DARK_L.toFixed(2)} ${PALETTE_BOLD_C.toFixed(4)} ${h})`,\n // Text on the bold fill (Badge / Tag colour variants), decided by contrast as\n // drawn: white, the teals and cyans that clip too light for it one step\n // darker (above); a deep tint of the hue only where no step within\n // PALETTE_BOLD_MAX_DARKEN brings white to AA.\n [`${prefix}-on-bold`]: onFillTextValue(boldFill),\n }\n}\n\n/**\n * The primary step chart-1 draws in: the accent's own when it shows at 3:1 on the mode's surfaces — 500 or darker on\n * a light card (PRIMARY_SCALE L 0.55 and below, the palette bold's lightness), 400 or lighter on a dark one (L 0.66\n * and above, CHART_SERIES_DARK_L) — else the nearest step that does.\n */\nexport function chartAccentShade(accentShade: number, mode: 'light' | 'dark'): number {\n const s = scaleShade(accentShade)\n return mode === 'dark' ? Math.min(s, 400) : Math.max(s, 500)\n}\n\n/**\n * Generates chart tokens that reference accent and palette values via var(). All values are CSS variable references,\n * not computed colours — the palette tokens must already exist in the same scope. chart-1 is the accent unless the\n * accent is too light (light mode) or too dark (dark mode) for a series, and then the nearest primary step that shows\n * (chartAccentShade); chart-2–6 are the palette's chart colours. Without an accent shade, chart-1 is the accent.\n *\n * @returns Record of 14 CSS custom properties (12 chart tokens + 2 backwards-compat aliases)\n */\nexport function computeChartTokens(accentShade?: number, mode: 'light' | 'dark' = 'light'): Record<string, string> {\n const series = accentShade == null ? null : chartAccentShade(accentShade, mode)\n const accent = series == null || series === scaleShade(accentShade!) ? 'var(--ds-accent-primary)' : `var(--ds-primary-${series})`\n const tokens: Record<string, string> = {\n '--ds-chart-1': accent,\n '--ds-chart-1-soft': `color-mix(in oklch, ${accent} 30%, transparent)`,\n }\n\n for (let i = 1; i <= 5; i++) {\n tokens[`--ds-chart-${i + 1}`] = `var(--ds-palette-${i}-chart)`\n tokens[`--ds-chart-${i + 1}-soft`] = `color-mix(in oklch, var(--ds-palette-${i}-chart) 30%, transparent)`\n }\n\n // Backwards-compat aliases\n tokens['--ds-chart-fill'] = `var(--ds-chart-1)`\n tokens['--ds-chart-fill-soft'] = `var(--ds-chart-1-soft)`\n\n return tokens\n}\n\n/**\n * Approximate WCAG contrast ratio between two OKLCH lightness values.\n * Uses L³ as a luminance proxy (OKLCH lightness is perceptual, L³ ≈ relative luminance).\n * Returns estimated ratio (1.0 to 21.0). Kept for the palette subtle/dark\n * pair, which only needs a ranking; on-fill text decisions use\n * `oklchToLuminance` + `contrastRatio` (Sprint 20.10), which account for hue,\n * chroma and gamut.\n */\nexport function estimateContrastRatio(L1: number, L2: number): number {\n const lum1 = Math.pow(Math.max(0, Math.min(1, L1)), 3)\n const lum2 = Math.pow(Math.max(0, Math.min(1, L2)), 3)\n const lighter = Math.max(lum1, lum2)\n const darker = Math.min(lum1, lum2)\n return (lighter + 0.05) / (darker + 0.05)\n}\n\n/**\n * Approximate WCAG contrast ratio between an oklch colour and white.\n * Delegates to estimateContrastRatio with L2 = 1.0 (white).\n */\nexport function estimateContrastVsWhite(oklchL: number): number {\n return estimateContrastRatio(oklchL, 1.0)\n}\n\n// ---------------------------------------------------------------------------\n// Navigation active styles (Sprint 20.8)\n// ---------------------------------------------------------------------------\n//\n// The *shape* of an active navigation item is a theme decision, not a per-page\n// one. Three decisions (sidebar, in-page horizontal, in-page vertical) resolve\n// to 24 CSS custom properties that SidebarNav, Tabs and TreeView read. Every\n// value is a var() of an existing mode-aware token or a plain length, so the\n// set has one body — but because var() inside a custom property is substituted\n// where it is *declared*, emitters must declare the set in every scope that\n// redeclares one of its inputs (:root, [data-mode], [data-ds-overlay]).\n//\n// The defaults reproduce today's rendering exactly (sprint §0.1). Do not\n// \"improve\" a default value here — that is a product change with its own\n// changelog entry.\n\nexport type SidebarActiveStyle = 'rail' | 'tint' | 'pill'\nexport type InPageHorizontalStyle = 'underline' | 'tint' | 'pill'\nexport type InPageVerticalStyle = 'rail' | 'tint' | 'pill'\n\nexport interface NavStyleInput {\n sidebarActiveStyle?: SidebarActiveStyle\n /** Only used to derive the default and the coercion: minimal and compact sidebars have no edge to stroke, so their default is tint and an explicit rail resolves to tint. */\n sidebarType?: 'traditional' | 'compact' | 'minimal'\n inPageHorizontal?: InPageHorizontalStyle\n inPageVertical?: InPageVerticalStyle\n}\n\nexport interface ResolvedNavStyles {\n sidebarActiveStyle: SidebarActiveStyle\n inPageHorizontal: InPageHorizontalStyle\n inPageVertical: InPageVerticalStyle\n}\n\n/**\n * The only place the missing-field defaults and the no-edge coercion (minimal\n * and compact sidebars) live. Every reader (deserialisers, Worker readers, CSS emitters, the rules\n * file) calls this — nobody writes `?? 'rail'` anywhere else.\n *\n * The coercion is render-time only: stored state keeps the user's choice so\n * switching a minimal or compact sidebar back to traditional restores the rail.\n */\nexport function resolveNavStyles(input: NavStyleInput): ResolvedNavStyles {\n const noEdge = input.sidebarType === 'minimal' || input.sidebarType === 'compact'\n let sidebarActiveStyle: SidebarActiveStyle = input.sidebarActiveStyle ?? (noEdge ? 'tint' : 'rail')\n if (noEdge && sidebarActiveStyle === 'rail') sidebarActiveStyle = 'tint'\n return {\n sidebarActiveStyle,\n inPageHorizontal: input.inPageHorizontal ?? 'underline',\n inPageVertical: input.inPageVertical ?? 'rail',\n }\n}\n\nconst ON_PRIMARY = 'var(--ds-text-on-primary)'\nconst SIDEBAR_ON_ACCENT = 'var(--ds-sidebar-text-on-accent)'\nconst ACCENT = 'var(--ds-accent-primary)'\n/** The accent as text (Sprint 30, P8): the theme's derived ink, readable on the page and on the accent's own tint; fills keep ACCENT. */\nconst ACCENT_INK = 'var(--ds-accent-ink)'\n/** The sidebar's current item as text and its marks (P8): the sidebar family's own ink. */\nconst SIDEBAR_INK = 'var(--ds-sidebar-accent-ink)'\nconst ACCENT_SUBTLE = 'var(--ds-accent-subtle)'\nconst PILL_BADGE_BG = 'color-mix(in oklab, var(--ds-bg-canvas) 20%, transparent)'\n\n/**\n * The 25 tokens of sprint §4 for the resolved styles (24, plus the sidebar\n * pill's gradient image — September 2026).\n */\nexport function getNavStyleTokens(input: NavStyleInput): Record<string, string> {\n const { sidebarActiveStyle, inPageHorizontal, inPageVertical } = resolveNavStyles(input)\n const tokens: Record<string, string> = {}\n\n // ── In-page horizontal (Tabs) ─────────────────────────────────────────\n switch (inPageHorizontal) {\n case 'underline':\n tokens['--ds-nav-h-active-bg'] = 'transparent'\n tokens['--ds-nav-h-active-text'] = 'var(--ds-text-primary)'\n tokens['--ds-nav-h-inactive-text'] = 'var(--ds-text-muted)'\n tokens['--ds-nav-h-indicator'] = 'calc(var(--ds-border-width) * 3)'\n tokens['--ds-nav-h-item-radius'] = '0px'\n tokens['--ds-nav-h-hover-bg'] = 'transparent'\n tokens['--ds-nav-h-track-border'] = 'var(--ds-border-width)'\n tokens['--ds-nav-h-track-gap'] = '0px'\n tokens['--ds-nav-h-badge-bg'] = ACCENT\n break\n case 'tint':\n tokens['--ds-nav-h-active-bg'] = ACCENT_SUBTLE\n tokens['--ds-nav-h-active-text'] = ACCENT_INK\n tokens['--ds-nav-h-inactive-text'] = 'var(--ds-text-secondary)'\n tokens['--ds-nav-h-indicator'] = '0px'\n tokens['--ds-nav-h-item-radius'] = 'var(--ds-radius-sm)'\n tokens['--ds-nav-h-hover-bg'] = 'var(--ds-tab-hover-bg)'\n tokens['--ds-nav-h-track-border'] = '0px'\n tokens['--ds-nav-h-track-gap'] = 'var(--ds-space-1)'\n tokens['--ds-nav-h-badge-bg'] = ACCENT\n break\n case 'pill':\n tokens['--ds-nav-h-active-bg'] = ACCENT\n tokens['--ds-nav-h-active-text'] = ON_PRIMARY\n tokens['--ds-nav-h-inactive-text'] = 'var(--ds-text-secondary)'\n tokens['--ds-nav-h-indicator'] = '0px'\n tokens['--ds-nav-h-item-radius'] = 'var(--ds-radius-md)'\n tokens['--ds-nav-h-hover-bg'] = 'var(--ds-tab-hover-bg)'\n tokens['--ds-nav-h-track-border'] = '0px'\n tokens['--ds-nav-h-track-gap'] = 'var(--ds-space-1)'\n tokens['--ds-nav-h-badge-bg'] = PILL_BADGE_BG\n break\n }\n\n // ── In-page vertical (Tabs rail) ──────────────────────────────────────\n switch (inPageVertical) {\n case 'rail':\n tokens['--ds-nav-v-active-bg'] = 'var(--ds-tab-active-bg)'\n tokens['--ds-nav-v-active-text'] = ACCENT_INK\n tokens['--ds-nav-v-active-rail'] = 'var(--ds-border-width-thick)'\n tokens['--ds-nav-v-item-radius'] = 'var(--ds-radius-sm)'\n tokens['--ds-nav-v-track-border'] = '0px'\n tokens['--ds-nav-v-track-padding'] = 'var(--ds-space-1)'\n // Secondary lines on the selected row (StackedList subtitle/description/meta): readable on the accent bar under pill.\n tokens['--ds-nav-v-active-muted'] = 'var(--ds-text-secondary)'\n tokens['--ds-nav-v-badge-bg'] = ACCENT\n break\n case 'tint':\n tokens['--ds-nav-v-active-bg'] = ACCENT_SUBTLE\n tokens['--ds-nav-v-active-text'] = ACCENT_INK\n tokens['--ds-nav-v-active-rail'] = '0px'\n tokens['--ds-nav-v-item-radius'] = 'var(--ds-radius-md)'\n tokens['--ds-nav-v-track-border'] = '0px'\n tokens['--ds-nav-v-track-padding'] = '0px'\n // Secondary lines on the selected row (StackedList subtitle/description/meta): readable on the accent bar under pill.\n tokens['--ds-nav-v-active-muted'] = 'var(--ds-text-secondary)'\n tokens['--ds-nav-v-badge-bg'] = ACCENT\n break\n case 'pill':\n tokens['--ds-nav-v-active-bg'] = ACCENT\n tokens['--ds-nav-v-active-text'] = ON_PRIMARY\n tokens['--ds-nav-v-active-rail'] = '0px'\n tokens['--ds-nav-v-item-radius'] = 'var(--ds-radius-sm)'\n tokens['--ds-nav-v-track-border'] = '0px'\n tokens['--ds-nav-v-track-padding'] = '0px'\n // Secondary lines on the selected row (StackedList subtitle/description/meta): readable on the accent bar under pill.\n tokens['--ds-nav-v-active-muted'] = 'color-mix(in srgb, var(--ds-text-on-primary) 80%, transparent)'\n tokens['--ds-nav-v-badge-bg'] = PILL_BADGE_BG\n break\n }\n\n // ── Tree ──────────────────────────────────────────────────────────────\n // `-muted` is the chevron on the selected row: muted grey today, on-primary\n // under pill so it stays visible on the full-width accent bar.\n switch (inPageVertical) {\n case 'rail':\n tokens['--ds-tree-active-bg'] = 'var(--ds-tab-active-bg)'\n tokens['--ds-tree-active-text'] = ACCENT_INK\n tokens['--ds-tree-active-muted'] = 'var(--ds-text-muted)'\n tokens['--ds-tree-active-rail'] = 'var(--ds-border-width-thick)'\n break\n case 'tint':\n tokens['--ds-tree-active-bg'] = ACCENT_SUBTLE\n tokens['--ds-tree-active-text'] = ACCENT_INK\n tokens['--ds-tree-active-muted'] = 'var(--ds-text-muted)'\n tokens['--ds-tree-active-rail'] = '0px'\n break\n case 'pill':\n tokens['--ds-tree-active-bg'] = ACCENT\n tokens['--ds-tree-active-text'] = ON_PRIMARY\n tokens['--ds-tree-active-muted'] = ON_PRIMARY\n tokens['--ds-tree-active-rail'] = '0px'\n break\n }\n\n // ── Sidebar ───────────────────────────────────────────────────────────\n // Decision 21: the active root label takes the sidebar accent for rail and\n // tint, matching Tabs, TreeView and NavItem (pre-20.8 it stayed neutral with\n // only the icon in accent). A deliberate default change, recorded in the\n // changelog.\n switch (sidebarActiveStyle) {\n case 'rail':\n tokens['--ds-sidebar-active-bg'] = 'var(--ds-sidebar-accent-subtle)'\n tokens['--ds-sidebar-active-text'] = SIDEBAR_INK\n tokens['--ds-sidebar-active-accent'] = SIDEBAR_INK\n tokens['--ds-sidebar-active-rail'] = 'var(--ds-border-width-thick)'\n tokens['--ds-sidebar-active-image'] = 'none'\n break\n case 'tint':\n tokens['--ds-sidebar-active-bg'] = 'var(--ds-sidebar-accent-subtle)'\n tokens['--ds-sidebar-active-text'] = SIDEBAR_INK\n tokens['--ds-sidebar-active-accent'] = SIDEBAR_INK\n tokens['--ds-sidebar-active-rail'] = '0px'\n tokens['--ds-sidebar-active-image'] = 'none'\n break\n case 'pill':\n // The sidebar accent may come from the other palette (independent mode),\n // so its on-accent text is the scoped token, which roots.css defaults to\n // --ds-text-on-primary for match mode.\n tokens['--ds-sidebar-active-bg'] = 'var(--ds-sidebar-accent)'\n tokens['--ds-sidebar-active-text'] = SIDEBAR_ON_ACCENT\n tokens['--ds-sidebar-active-accent'] = SIDEBAR_ON_ACCENT\n tokens['--ds-sidebar-active-rail'] = '0px'\n // The pill takes the accent gradient like Button does: --ds-sidebar-gradient\n // is the page gradient in match mode and the target palette's gradient in\n // an independent mode (none when the accent is solid).\n tokens['--ds-sidebar-active-image'] = 'var(--ds-sidebar-gradient)'\n break\n }\n\n return tokens\n}\n\n/**\n * Sprint 25.14 A20: the switch's off look — no fill, and the strong edge colour for its outline and its knob, as Fluent\n * 2's off switch is. Only the theme writers emit these (generateTokensCss and ThemeContext, beside the nav style set, so\n * each scope resolves them against its own edge), never roots.css: an app that upgrades the library without\n * regenerating its stylesheet keeps the switch its stylesheet draws (the Toggle falls back to the filled one without it).\n * Sprint 25.19 K2: the edge is `--ds-control-edge-strong`, the theme's 3:1 edge, since a field's resting edge\n * (`--ds-input-border`) is the soft border again; the generator writes the strong edge in every mode's block, so a\n * stylesheet made by 0.27.0 resolves it with an earlier library's roots.css too.\n *\n * The knob is the lightest shade of the edge that still reaches 3:1 on every ground (the owner, 30 September: the black\n * knob of a black-edged theme was \"very bold, unnecessarily so\"): the edge mixed toward the surface, keeping\n * `--ds-switch-knob-share` of it. A preset whose edge is far past 3:1 sets the share per mode (neo-brutalist light keeps\n * under half its black); everywhere else it is the edge itself. The knob's place is the switch's state, so it needs\n * the 3:1 an outline does. Declared with the set, the mix reads each scope's own edge and surface.\n */\nexport const SWITCH_TOKENS: Record<string, string> = {\n '--ds-switch-off-fill': 'transparent',\n '--ds-switch-off-edge': 'var(--ds-control-edge-strong)',\n '--ds-switch-off-knob': 'color-mix(in oklab, var(--ds-control-edge-strong) var(--ds-switch-knob-share, 100%), var(--ds-bg-surface))',\n}\n\n/**\n * The checked colour (a checked box, a selected radio's dot, a switch's track when on) and its mark: the accent, unless\n * the preset sets its own for the mode. roots.css declares them once, at the root (@sync, check-tokens.test.ts checks).\n * A writer redeclares them in every block that redeclares the accent for another scope (the other mode's block, a dark\n * portal, a project's theme wrapper), before that scope's preset overrides, so they follow the scope's accent, not the\n * page's (the review of 30 September: since A20 a dark sidebar's switch on a light page took the light check colour).\n * Never under NAV_STYLE_SCOPE_SELECTOR: a same-mode wrapper or an overlay would lose the page preset's own check colour,\n * which some presets set for 3:1. --ds-check-gradient is left to inherit: a scope may take the page's `none`, a look\n * without the gradient, never a weaker fill.\n */\nexport const CHECK_TOKENS: Record<string, string> = {\n '--ds-check-bg': 'var(--ds-accent-primary)',\n '--ds-check-fg': 'var(--ds-text-on-primary)',\n '--ds-check-border': 'var(--ds-accent-primary)',\n}\n\n/**\n * Selector under which every emitter declares the nav style set. One rule\n * reaching the root, every nested mode wrapper and every overlay portal, so\n * the var() aliases resolve against each scope's own inputs.\n */\nexport const NAV_STYLE_SCOPE_SELECTOR = ':root, [data-mode], [data-ds-overlay]'\n\n// ---------------------------------------------------------------------------\n// Readable colours (Sprint 30, T1)\n// ---------------------------------------------------------------------------\n//\n// The colours a theme derives so they read on what they're drawn on: the focus outline (3:1, WCAG 1.4.11), the quiet\n// greys, the accent as text and the status words (4.5:1, 1.4.3). Each is the theme's own colour wherever that reaches\n// its minimum against every ground it sits on. Otherwise it is the nearest colour that does: the same colour a little\n// darker on a light ground, a little lighter on a dark one, keeping its hue, chroma and see-through-ness, so the look\n// changes no more than the minimum asks (the owner, 2 October 2026: the look comes first).\n//\n// The grounds are read from the theme as it is written: a preset's or a saved theme's values (the presets write them\n// with calc() and var(), which parseOklch can't read), see-through surfaces laid over the page, and the glows a canvas\n// gradient paints. Colours are laid over one another in gamma-encoded sRGB, as the browser composites them, and\n// measured with the range Chrome's rounding can land in (luminanceRange, worstContrastOf). Glass's backdrop blur and\n// saturation are not modelled; T6's Chrome pass measures the drawn page.\n\n/** A colour as the browser composites it: gamma-encoded sRGB channels (0–1, clipped to the gamut) and an alpha. */\nexport interface Paint { rgb: readonly [number, number, number]; alpha: number }\n\n/** The theme variables the roots.css scales read, as one block of tokens sees them. */\nexport interface ScaleVars {\n huePrimary: number\n satPrimary: number\n hueNeutral: number\n satNeutral: number\n hueSuccess: number\n hueWarning: number\n hueDestructive: number\n}\n\ntype ScaleName = 'primary' | 'neutral' | 'destructive' | 'success' | 'warning' | 'info'\n\n/**\n * The roots.css colour scales: [lightness, chroma] per step, the chroma multiplied by the scale's saturation where it\n * has one, at the scale's hue (info's is fixed). @sync roots.css (sprint30-readable-colours.test.ts checks every step).\n */\nexport const CSS_SCALES: Record<ScaleName, { hue: keyof ScaleVars | number; sat: keyof ScaleVars | null; steps: Record<number, readonly [number, number]> }> = {\n primary: {\n hue: 'huePrimary', sat: 'satPrimary',\n steps: { 50: [0.97, 0.025], 100: [0.93, 0.050], 200: [0.87, 0.100], 300: [0.77, 0.150], 400: [0.66, 0.180], 500: [0.55, 0.200], 600: [0.47, 0.185], 700: [0.40, 0.165], 800: [0.33, 0.135], 900: [0.25, 0.100], 950: [0.17, 0.060] },\n },\n neutral: {\n hue: 'hueNeutral', sat: 'satNeutral',\n steps: { 50: [0.97, 0.007], 100: [0.94, 0.009], 200: [0.90, 0.010], 300: [0.84, 0.010], 400: [0.71, 0.009], 500: [0.55, 0.007], 600: [0.45, 0.006], 700: [0.37, 0.005], 800: [0.27, 0.004], 900: [0.20, 0.003], 950: [0.13, 0.002] },\n },\n destructive: { hue: 'hueDestructive', sat: null, steps: { 50: [0.97, 0.015], 100: [0.93, 0.040], 400: [0.66, 0.200], 500: [0.55, 0.220], 600: [0.47, 0.200], 950: [0.15, 0.050] } },\n success: { hue: 'hueSuccess', sat: null, steps: { 50: [0.97, 0.020], 100: [0.93, 0.045], 400: [0.66, 0.170], 500: [0.52, 0.160], 600: [0.45, 0.145], 950: [0.15, 0.040] } },\n warning: { hue: 'hueWarning', sat: null, steps: { 50: [0.97, 0.020], 100: [0.93, 0.060], 400: [0.78, 0.155], 500: [0.75, 0.160], 600: [0.65, 0.145], 950: [0.20, 0.040] } },\n info: { hue: 230, sat: null, steps: { 50: [0.97, 0.020], 100: [0.93, 0.045], 400: [0.66, 0.170], 500: [0.52, 0.160], 950: [0.15, 0.040] } },\n}\n\n/** The CSS variables a colour expression may read, and the scale variable each is. */\nconst SCALE_VAR_NAMES: Record<string, keyof ScaleVars> = {\n '--ds-hue-primary': 'huePrimary',\n '--ds-sat-primary': 'satPrimary',\n '--ds-hue-neutral': 'hueNeutral',\n '--ds-sat-neutral': 'satNeutral',\n '--ds-hue-success': 'hueSuccess',\n '--ds-hue-warning': 'hueWarning',\n '--ds-hue-destructive': 'hueDestructive',\n}\n\n/** The index of the parenthesis that closes the one at `open`, or -1. */\nfunction closingParen(src: string, open: number): number {\n let depth = 0\n for (let i = open; i < src.length; i++) {\n if (src[i] === '(') depth++\n else if (src[i] === ')' && --depth === 0) return i\n }\n return -1\n}\n\n/** Splits at `sep` outside parentheses (a whitespace `sep` splits at runs of whitespace). */\nfunction splitTopLevel(src: string, sep: ',' | '/' | ' '): string[] {\n const parts: string[] = []\n let depth = 0\n let start = 0\n for (let i = 0; i < src.length; i++) {\n const ch = src[i]\n if (ch === '(') depth++\n else if (ch === ')') depth--\n else if (depth === 0 && (sep === ' ' ? /\\s/.test(ch) : ch === sep)) {\n parts.push(src.slice(start, i))\n start = i + 1\n }\n }\n parts.push(src.slice(start))\n return parts.map((p) => p.trim()).filter((p) => p !== '')\n}\n\n/**\n * A number from a CSS expression: a plain number or percentage (50% is 0.5), a var() of one of the scale variables,\n * or a calc() of those with + − × ÷. NaN for anything else (an unknown variable, a unit).\n */\nexport function evalCssNumber(expr: string, vars: ScaleVars): number {\n const src = expr.trim()\n let i = 0\n const ws = () => { while (i < src.length && /\\s/.test(src[i])) i++ }\n const sum = (): number => {\n let v = product()\n for (;;) {\n ws()\n const op = src[i]\n if (op !== '+' && op !== '-') return v\n i++\n const r = product()\n v = op === '+' ? v + r : v - r\n }\n }\n const product = (): number => {\n let v = factor()\n for (;;) {\n ws()\n const op = src[i]\n if (op !== '*' && op !== '/') return v\n i++\n const r = factor()\n v = op === '*' ? v * r : v / r\n }\n }\n const factor = (): number => {\n ws()\n if (src.startsWith('calc(', i) || src[i] === '(') {\n const open = src[i] === '(' ? i : i + 4\n const close = closingParen(src, open)\n if (close < 0) return NaN\n const inner = evalCssNumber(src.slice(open + 1, close), vars)\n i = close + 1\n return inner\n }\n if (src.startsWith('var(', i)) {\n const close = closingParen(src, i + 3)\n if (close < 0) return NaN\n const name = splitTopLevel(src.slice(i + 4, close), ',')[0]\n i = close + 1\n const key = SCALE_VAR_NAMES[name]\n return key ? vars[key] : NaN\n }\n if (src[i] === '-') { i++; return -factor() }\n const m = /^(\\d*\\.?\\d+(?:e[+-]?\\d+)?)(%|deg)?/i.exec(src.slice(i))\n if (!m) return NaN\n i += m[0].length\n return m[2] === '%' ? parseFloat(m[1]) / 100 : parseFloat(m[1])\n }\n const v = sum()\n ws()\n return i === src.length ? v : NaN\n}\n\nconst WHITE_PAINT: Paint = { rgb: [1, 1, 1], alpha: 1 }\n\nfunction paintOfOklch(colour: Oklch, alpha = 1): Paint {\n return { rgb: oklchToSrgb(colour), alpha }\n}\n\n/** A scale step's colour (--ds-neutral-400 and the rest), or null when the name is not one. */\nfunction scaleColour(name: string, vars: ScaleVars): { scale: ScaleName; step: number; colour: Oklch } | null {\n const m = /^--ds-(primary|neutral|destructive|success|warning|info)-(\\d+)$/.exec(name)\n if (!m) return null\n const scale = m[1] as ScaleName\n const def = CSS_SCALES[scale]\n const step = Number(m[2])\n const entry = def.steps[step]\n if (!entry) return null\n const sat = def.sat ? vars[def.sat] : 1\n const hue = typeof def.hue === 'number' ? def.hue : vars[def.hue]\n return { scale, step, colour: { L: entry[0], C: entry[1] * sat, H: hue } }\n}\n\n/** The parts of an oklch() value: each component's text, and its numbers where they evaluate. */\ninterface OklchParts { L: number; C: number; H: number; alpha: number; cText: string; hText: string }\n\nfunction oklchParts(value: string, vars: ScaleVars): OklchParts | null {\n const v = value.trim()\n if (!/^oklch\\(/i.test(v) || closingParen(v, 5) !== v.length - 1) return null\n const inner = v.slice(6, -1)\n if (/^\\s*from\\s/i.test(inner)) return null\n const [colourPart, alphaPart] = splitTopLevel(inner, '/')\n const comps = splitTopLevel(colourPart ?? '', ' ')\n if (comps.length !== 3) return null\n const L = evalCssNumber(comps[0], vars)\n const C = evalCssNumber(comps[1], vars)\n const H = evalCssNumber(comps[2], vars)\n const alpha = alphaPart === undefined ? 1 : evalCssNumber(alphaPart, vars)\n if (![L, C, H, alpha].every(Number.isFinite)) return null\n return { L, C, H, alpha: Math.max(0, Math.min(1, alpha)), cText: comps[1], hText: comps[2] }\n}\n\n/** `color-mix(in srgb, A p%, B q%)` as CSS Color 5 mixes it: premultiplied, the percentages normalised, a sum under 100% lowering the alpha. */\nfunction mixedPaint(value: string, tokens: Record<string, string>, vars: ScaleVars, depth: number): Paint | null {\n const v = value.trim()\n if (closingParen(v, 9) !== v.length - 1) return null\n const args = splitTopLevel(v.slice(10, -1), ',')\n if (args.length !== 3 || !/^in\\s+srgb$/i.test(args[0])) return null\n const side = (arg: string) => {\n const parts = splitTopLevel(arg, ' ')\n const pct = parts.length > 1 && /%$/.test(parts[parts.length - 1]) ? parseFloat(parts.pop()!) / 100 : undefined\n return { paint: resolvePaint(parts.join(' '), tokens, vars, depth + 1), pct }\n }\n const a = side(args[1])\n const b = side(args[2])\n if (!a.paint || !b.paint) return null\n let p1 = a.pct ?? (b.pct !== undefined ? 1 - b.pct : 0.5)\n let p2 = b.pct ?? 1 - p1\n const total = p1 + p2\n if (total <= 0) return null\n const multiplier = Math.min(1, total)\n p1 /= total\n p2 /= total\n const alpha = a.paint.alpha * p1 + b.paint.alpha * p2\n if (alpha <= 0) return { rgb: [0, 0, 0], alpha: 0 }\n const rgb = [0, 1, 2].map((i) => (a.paint!.rgb[i] * a.paint!.alpha * p1 + b.paint!.rgb[i] * b.paint!.alpha * p2) / alpha) as [number, number, number]\n return { rgb, alpha: alpha * multiplier }\n}\n\n/** A #rgb, #rrggbb or #rrggbbaa colour. */\nfunction hexPaint(value: string): Paint | null {\n const m = /^#([0-9a-f]{3,8})$/i.exec(value.trim())\n if (!m || ![3, 4, 6, 8].includes(m[1].length)) return null\n const hex = m[1].length <= 4 ? m[1].split('').map((c) => c + c).join('') : m[1]\n const n = (k: number) => parseInt(hex.slice(k * 2, k * 2 + 2), 16) / 255\n return { rgb: [n(0), n(1), n(2)], alpha: hex.length === 8 ? n(3) : 1 }\n}\n\n/** An rgb()/rgba() colour with 0–255 channels. */\nfunction rgbPaint(value: string): Paint | null {\n const m = /^rgba?\\(([^)]*)\\)$/i.exec(value.trim())\n if (!m) return null\n const parts = m[1].split(/[\\s,/]+/).filter(Boolean)\n if (parts.length < 3) return null\n const ch = parts.slice(0, 3).map((p) => (p.endsWith('%') ? parseFloat(p) / 100 : parseFloat(p) / 255))\n const alpha = parts[3] === undefined ? 1 : parts[3].endsWith('%') ? parseFloat(parts[3]) / 100 : parseFloat(parts[3])\n if (![...ch, alpha].every(Number.isFinite)) return null\n return { rgb: ch.map((c) => Math.max(0, Math.min(1, c))) as [number, number, number], alpha }\n}\n\n/**\n * A token or a CSS colour value as the browser would paint it, followed through the block's own declarations\n * (`tokens`) and the roots.css scales. Null where it can't be known (an image, an unknown function or variable).\n */\nexport function resolvePaint(value: string, tokens: Record<string, string>, vars: ScaleVars, depth = 0): Paint | null {\n if (depth > 24) return null\n const v = value.trim()\n if (v === 'transparent') return { rgb: [0, 0, 0], alpha: 0 }\n if (v.startsWith('var(')) {\n if (closingParen(v, 3) !== v.length - 1) return null\n const [name, ...fallback] = splitTopLevel(v.slice(4, -1), ',')\n const own = tokens[name]\n if (own !== undefined) return resolvePaint(own, tokens, vars, depth + 1)\n const scaled = scaleColour(name, vars)\n if (scaled) return paintOfOklch(scaled.colour)\n return fallback.length ? resolvePaint(fallback.join(','), tokens, vars, depth + 1) : null\n }\n if (/^oklch\\(/i.test(v)) {\n const parts = oklchParts(v, vars)\n return parts ? paintOfOklch({ L: parts.L, C: parts.C, H: parts.H }, parts.alpha) : null\n }\n if (/^color-mix\\(/i.test(v)) return mixedPaint(v, tokens, vars, depth)\n if (v.startsWith('#')) return hexPaint(v)\n if (/^rgba?\\(/i.test(v)) return rgbPaint(v)\n if (/^color\\(\\s*srgb\\s/i.test(v)) return srgbFunctionPaint(v)\n if (/^oklab\\(/i.test(v)) return oklabPaint(v)\n return null\n}\n\n/** `color(srgb r g b / a)`, as Chrome serialises a computed colour mixed in sRGB. */\nfunction srgbFunctionPaint(value: string): Paint | null {\n const m = /^color\\(\\s*srgb\\s+([^)]*)\\)$/i.exec(value.trim())\n if (!m) return null\n const [rgbPart, alphaPart] = m[1].split('/')\n const ch = rgbPart.trim().split(/\\s+/).map((p) => (p.endsWith('%') ? parseFloat(p) / 100 : parseFloat(p)))\n const alpha = alphaPart === undefined ? 1 : alphaPart.trim().endsWith('%') ? parseFloat(alphaPart) / 100 : parseFloat(alphaPart)\n if (ch.length !== 3 || ![...ch, alpha].every(Number.isFinite)) return null\n return { rgb: ch.map((c) => Math.max(0, Math.min(1, c))) as [number, number, number], alpha }\n}\n\n/** `oklab(L a b / alpha)`, as Chrome serialises some computed colours. */\nfunction oklabPaint(value: string): Paint | null {\n const m = /^oklab\\(([^)]*)\\)$/i.exec(value.trim())\n if (!m) return null\n const [labPart, alphaPart] = m[1].split('/')\n const [L, a, b] = labPart.trim().split(/\\s+/).map((p, i) => (p.endsWith('%') ? (parseFloat(p) / 100) * (i === 0 ? 1 : 0.4) : parseFloat(p)))\n const alpha = alphaPart === undefined ? 1 : alphaPart.trim().endsWith('%') ? parseFloat(alphaPart) / 100 : parseFloat(alphaPart)\n if (![L, a, b, alpha].every(Number.isFinite)) return null\n return paintOfOklch({ L, C: Math.hypot(a, b), H: ((Math.atan2(b, a) * 180) / Math.PI + 360) % 360 }, alpha)\n}\n\n/** `top` laid over `ground` (source-over in gamma-encoded sRGB, as the browser composites). */\nexport function paintOver(top: Paint, ground: Paint): Paint {\n const alpha = top.alpha + ground.alpha * (1 - top.alpha)\n if (alpha <= 0) return { rgb: [0, 0, 0], alpha: 0 }\n const rgb = [0, 1, 2].map((i) => (top.rgb[i] * top.alpha + ground.rgb[i] * ground.alpha * (1 - top.alpha)) / alpha) as [number, number, number]\n return { rgb, alpha }\n}\n\n/** The lowest contrast `text` shows over an opaque `ground` (see-through text laid over it first), every way either can round. */\nexport function paintContrast(text: Paint, ground: Paint): number {\n const drawnGround = ground.alpha >= 1 ? ground : paintOver(ground, WHITE_PAINT)\n return worstContrastOf(srgbLuminanceRange(paintOver(text, drawnGround).rgb), srgbLuminanceRange(drawnGround.rgb))\n}\n\n/** The lowest contrast `text` shows over any of `grounds` (Infinity for none). */\nexport function worstPaintContrast(text: Paint, grounds: readonly Paint[]): number {\n let min = Infinity\n for (const g of grounds) min = Math.min(min, paintContrast(text, g))\n return min\n}\n\n/**\n * The colours a canvas gradient shows (presets.ts's `canvasGradientLight`/`Dark`, a saved theme's own): its last\n * layer's colours are the base, each laid over the canvas colour if see-through; every layer above is laid over each\n * base colour at the strongest it shows. A radial glow fades from its first colour to transparent, so where its centre\n * sits outside the page only part of it shows (an `ellipse 80% 50% at 20% -10%` peaks at 71% at the top edge, its\n * nearest point); a line pattern or a flat wash shows at full strength somewhere.\n */\nexport function gradientPaints(gradient: string, tokens: Record<string, string>, vars: ScaleVars, under: Paint): Paint[] {\n const layers = splitLayers(gradient)\n if (!layers.length) return []\n const parsed = layers.map((layer) => gradientLayer(layer, tokens, vars))\n const bases = uniquePaints(parsed[parsed.length - 1].stops.map((s) => (s.paint.alpha >= 1 ? s.paint : paintOver(s.paint, under))))\n if (!bases.length) bases.push(under)\n const out = [...bases]\n for (const layer of parsed.slice(0, -1)) {\n const lead = layer.stops.find((s) => s.paint.alpha > 0)\n if (!lead) continue\n const strength = layer.radial ? radialStrength(layer.radial, layer.stops) : 1\n const glow: Paint = { rgb: lead.paint.rgb, alpha: lead.paint.alpha * strength }\n if (glow.alpha <= 0) continue\n for (const base of bases) out.push(paintOver(glow, base))\n }\n return out\n}\n\n/** The paints, each once. */\nfunction uniquePaints(paints: Paint[]): Paint[] {\n const seen = new Set<string>()\n return paints.filter((p) => {\n const key = `${p.rgb.map((c) => c.toFixed(5)).join(',')}/${p.alpha.toFixed(5)}`\n if (seen.has(key)) return false\n seen.add(key)\n return true\n })\n}\n\n/** A gradient value's layers: each top-level `…-gradient(…)` function. */\nfunction splitLayers(gradient: string): string[] {\n const layers: string[] = []\n const re = /(?:repeating-)?(?:linear|radial|conic)-gradient\\(/gi\n let m: RegExpExecArray | null\n while ((m = re.exec(gradient))) {\n const open = m.index + m[0].length - 1\n const close = closingParen(gradient, open)\n if (close < 0) break\n layers.push(gradient.slice(m.index, close + 1))\n re.lastIndex = close + 1\n }\n return layers\n}\n\ninterface GradientStop { paint: Paint; pos?: number }\ninterface RadialShape { rx: number; ry: number; cx: number; cy: number }\n\n/** One gradient layer's colour stops (with their first position, as a fraction) and, for an ellipse, its shape. */\nfunction gradientLayer(layer: string, tokens: Record<string, string>, vars: ScaleVars): { stops: GradientStop[]; radial?: RadialShape } {\n const open = layer.indexOf('(')\n const args = splitTopLevel(layer.slice(open + 1, -1), ',')\n const stops: GradientStop[] = []\n let radial: RadialShape | undefined\n args.forEach((arg, k) => {\n const parts = splitTopLevel(arg, ' ')\n const paint = parts.length ? resolvePaint(parts[0], tokens, vars) : null\n if (paint) {\n const pos = parts[1] !== undefined ? evalCssNumber(parts[1], vars) : undefined\n stops.push({ paint, pos: Number.isFinite(pos) ? pos : undefined })\n return\n }\n if (k === 0 && /^radial/i.test(layer)) {\n const shape = /ellipse\\s+(-?[\\d.]+)%\\s+(-?[\\d.]+)%\\s+at\\s+(-?[\\d.]+)%\\s+(-?[\\d.]+)%/i.exec(arg)\n if (shape) radial = { rx: +shape[1], ry: +shape[2], cx: +shape[3], cy: +shape[4] }\n }\n })\n return { stops, radial }\n}\n\n/** How strongly a radial glow's first colour shows at its nearest point on the page (1 when its centre is on the page). */\nfunction radialStrength(shape: RadialShape, stops: GradientStop[]): number {\n const px = Math.max(0, Math.min(100, shape.cx))\n const py = Math.max(0, Math.min(100, shape.cy))\n const d = Math.hypot((px - shape.cx) / shape.rx, (py - shape.cy) / shape.ry)\n const leadIndex = stops.findIndex((s) => s.paint.alpha > 0)\n const start = stops[leadIndex]?.pos ?? 0\n const end = stops.slice(leadIndex + 1).find((s) => s.paint.alpha === 0)?.pos ?? 1\n if (d <= start) return 1\n if (d >= end) return 0\n return (end - d) / (end - start)\n}\n\n/** A candidate colour: the CSS a writer emits, and how it paints. */\nexport interface ColourCandidate { value: string; paint: Paint }\n\n/**\n * The shared routine (Sprint 30): the first candidate, in the order given, that reaches `minimum` against every ground\n * and that `accept` takes. mutedOnTint walks the neutral scale's steps with it; the readable tokens walk the theme's\n * own colour in small steps (walkCandidates).\n */\nexport function firstReadable(candidates: Iterable<ColourCandidate>, grounds: readonly Paint[], minimum: number, accept: (c: ColourCandidate) => boolean = () => true): ColourCandidate | null {\n for (const c of candidates) {\n if (worstPaintContrast(c.paint, grounds) >= minimum && accept(c)) return c\n }\n return null\n}\n\n/** A colour as written, ready to be walked: its lightness and alpha as numbers, its chroma and hue as the CSS that writes them. */\ninterface WalkableColour {\n L: number\n alpha: number\n H: number\n /** The chroma at a lightness: a scale's chroma follows the scale's curve between its steps. */\n chroma: (L: number) => number\n chromaText: (L: number) => string\n hueText: string\n}\n\n/** The chroma coefficient of a scale at a lightness, read off the line between its two nearest steps. */\nfunction scaleChromaAt(scale: ScaleName, L: number): number {\n const points = Object.values(CSS_SCALES[scale].steps).map(([l, c]) => [l, c] as const).sort((a, b) => a[0] - b[0])\n if (L <= points[0][0]) return points[0][1]\n if (L >= points[points.length - 1][0]) return points[points.length - 1][1]\n for (let k = 1; k < points.length; k++) {\n const [l1, c1] = points[k]\n const [l0, c0] = points[k - 1]\n if (L <= l1) return c0 + ((c1 - c0) * (L - l0)) / (l1 - l0)\n }\n return points[points.length - 1][1]\n}\n\nconst fixed = (n: number, places: number) => String(+n.toFixed(places))\n\n/** The colour a token's value finally writes, followed through var(), in a form the walk can step. Null for a mix or an image. */\nfunction walkableColour(value: string, tokens: Record<string, string>, vars: ScaleVars, depth = 0): WalkableColour | null {\n if (depth > 24) return null\n const v = value.trim()\n if (v.startsWith('var(')) {\n if (closingParen(v, 3) !== v.length - 1) return null\n const [name, ...fallback] = splitTopLevel(v.slice(4, -1), ',')\n const own = tokens[name]\n if (own !== undefined) return walkableColour(own, tokens, vars, depth + 1)\n const scaled = scaleColour(name, vars)\n if (scaled) {\n const def = CSS_SCALES[scaled.scale]\n const satVar = def.sat ? Object.keys(SCALE_VAR_NAMES).find((k) => SCALE_VAR_NAMES[k] === def.sat) : undefined\n const hueVar = typeof def.hue === 'number' ? undefined : Object.keys(SCALE_VAR_NAMES).find((k) => SCALE_VAR_NAMES[k] === def.hue)\n const sat = def.sat ? vars[def.sat] : 1\n return {\n L: scaled.colour.L,\n alpha: 1,\n H: scaled.colour.H,\n chroma: (L) => scaleChromaAt(scaled.scale, L) * sat,\n chromaText: (L) => (satVar ? `calc(${fixed(scaleChromaAt(scaled.scale, L), 4)} * var(${satVar}))` : fixed(scaleChromaAt(scaled.scale, L), 4)),\n hueText: hueVar ? `var(${hueVar})` : String(def.hue),\n }\n }\n return fallback.length ? walkableColour(fallback.join(','), tokens, vars, depth + 1) : null\n }\n const parts = oklchParts(v, vars)\n if (!parts) return null\n return { L: parts.L, alpha: parts.alpha, H: parts.H, chroma: () => parts.C, chromaText: () => parts.cText, hueText: parts.hText }\n}\n\n/** The CSS for a walked colour. */\nfunction walkedCss(c: WalkableColour, L: number, alpha: number): string {\n return `oklch(${fixed(L, 3)} ${c.chromaText(L)} ${c.hueText}${alpha < 1 ? ` / ${fixed(alpha, 2)}` : ''})`\n}\n\n/**\n * The colours a walk tries after the theme's own: a see-through colour first grows more opaque, 5% at a time; then the\n * lightness steps by 0.01 toward contrast (darker for `dir` −1, on a light ground; lighter for +1).\n */\nfunction* walkCandidates(c: WalkableColour, dir: 1 | -1): Generator<ColourCandidate> {\n let alpha = c.alpha\n while (alpha < 1 - 1e-9) {\n alpha = Math.min(1, +(alpha + 0.05).toFixed(2))\n yield { value: walkedCss(c, c.L, alpha), paint: paintOfOklch({ L: c.L, C: c.chroma(c.L), H: c.H }, alpha) }\n }\n for (let L = +(c.L + dir * 0.01).toFixed(3); L >= 0 && L <= 1; L = +(L + dir * 0.01).toFixed(3)) {\n yield { value: walkedCss(c, L, 1), paint: paintOfOklch({ L, C: c.chroma(L), H: c.H }, 1) }\n }\n}\n\n/**\n * The readable colour for one token: `own` (as written) where it reaches `minimum` against every ground and `accept`\n * takes it; else the nearest step of its walk that does; else `fallback`. Returns the CSS to emit and its paint.\n */\nfunction readableColour(own: string, grounds: readonly Paint[], minimum: number, dir: 1 | -1, tokens: Record<string, string>, vars: ScaleVars, fallback: string, accept: (c: ColourCandidate) => boolean = () => true): ColourCandidate {\n const ownPaint = resolvePaint(own, tokens, vars)\n const first = ownPaint ? firstReadable([{ value: own, paint: ownPaint }], grounds, minimum, accept) : null\n if (first) return first\n const walkable = walkableColour(own, tokens, vars)\n const walked = walkable ? firstReadable(walkCandidates(walkable, dir), grounds, minimum, accept) : null\n if (walked) return walked\n return { value: fallback, paint: resolvePaint(fallback, tokens, vars) ?? ownPaint ?? WHITE_PAINT }\n}\n\n/**\n * Tokens roots.css declares that the shared semantic defaults leave out: the derivations read them where a block\n * doesn't declare its own. @sync roots.css.\n */\nconst ROOTS_COLOUR_DEFAULTS: Record<string, string> = {\n '--ds-accent-subtle': 'color-mix(in srgb, var(--ds-accent-primary) 10%, transparent)',\n '--ds-accent-muted': 'color-mix(in srgb, var(--ds-accent-primary) 20%, transparent)',\n '--ds-sidebar-accent-subtle': 'color-mix(in srgb, var(--ds-sidebar-accent) 10%, transparent)',\n '--ds-header-accent-subtle': 'color-mix(in srgb, var(--ds-header-accent) 10%, transparent)',\n '--ds-tint-strength': String(TINT_STRENGTH),\n}\n\n/** The see-through layer `name` resolves to laid over each ground (the grounds unchanged where it can't be read). */\nfunction layered(name: string, grounds: readonly Paint[], tokens: Record<string, string>, vars: ScaleVars): Paint[] {\n const top = resolvePaint(`var(${name})`, tokens, vars)\n return top ? grounds.map((g) => paintOver(top, g)) : []\n}\n\nexport interface ReadableInput {\n /** The block's mode: its walks go darker on a light page, lighter on a dark one. */\n mode: 'light' | 'dark'\n /** Every declaration the block sees, in cascade order: the mode's semantic defaults, the writer's tokens, the preset's or saved theme's overrides, the status palette. */\n tokens: Record<string, string>\n vars: ScaleVars\n /** The canvas gradient painted under the page, if the theme has one for this mode. */\n canvasGradient?: string\n /** Whether to derive the sidebar family too (a mode's block; an independent sidebar derives its own with readableSidebarTokens). */\n sidebar?: boolean\n}\n\nexport interface ReadableResult {\n /** The derived tokens, to declare after the block's overrides. */\n tokens: Record<string, string>\n /** Each derived token's own colour before the derivation (the Focus page's \"before\"). */\n inputs: Record<string, string>\n}\n\n/**\n * The scale variables a theme state shows in a mode, as the preview writers' ROOT_MAP sets them on <html>: the dark\n * palette's hues and saturations in dark mode, the light ones otherwise; the status hues are shared.\n */\nexport function scaleVarsOf(s: {\n huePrimary: number; satPrimary: number; hueNeutral: number; satNeutral: number\n darkHuePrimary: number; darkSatPrimary: number; darkHueNeutral: number; darkSatNeutral: number\n hueSuccess: number; hueWarning: number; hueDestructive: number\n}, mode: 'light' | 'dark'): ScaleVars {\n const dark = mode === 'dark'\n return {\n huePrimary: dark ? s.darkHuePrimary : s.huePrimary,\n satPrimary: dark ? s.darkSatPrimary : s.satPrimary,\n hueNeutral: dark ? s.darkHueNeutral : s.hueNeutral,\n satNeutral: dark ? s.darkSatNeutral : s.satNeutral,\n hueSuccess: s.hueSuccess,\n hueWarning: s.hueWarning,\n hueDestructive: s.hueDestructive,\n }\n}\n\n/** The colours the page's canvas shows: the canvas colour (over white where see-through) and, with a gradient, every colour it paints. */\nexport function canvasPaints(tokens: Record<string, string>, vars: ScaleVars, canvasGradient?: string): Paint[] {\n const base = resolvePaint('var(--ds-bg-canvas)', tokens, vars)\n const canvasColour = base ? (base.alpha >= 1 ? base : paintOver(base, WHITE_PAINT)) : WHITE_PAINT\n return [canvasColour, ...(canvasGradient ? gradientPaints(canvasGradient, tokens, vars, canvasColour) : [])]\n}\n\n/** The page's grounds for a block: the canvas (and its gradient's colours), and the surface and the raised surface over each. */\nfunction pageGrounds(input: ReadableInput): { canvas: Paint[]; page: Paint[] } {\n const { tokens, vars } = input\n const canvas = canvasPaints(tokens, vars, input.canvasGradient)\n return { canvas, page: [...canvas, ...layered('--ds-bg-surface', canvas, tokens, vars), ...layered('--ds-bg-surface-elevated', canvas, tokens, vars)] }\n}\n\n/** The colours a fill of the accent paints: the accent, or every colour its gradient paints (gradientFills). */\nfunction accentFillPaints(tokens: Record<string, string>, vars: ScaleVars): Paint[] {\n const accent = resolvePaint('var(--ds-accent-primary)', tokens, vars)\n const gradient = (tokens['--ds-gradient'] ?? 'none').trim()\n if (gradient !== 'none' && gradient !== '') {\n const start = walkableColour(tokens['--ds-gradient-start'] ?? '', tokens, vars)\n const end = walkableColour(tokens['--ds-gradient-end'] ?? '', tokens, vars)\n if (start && end) {\n return gradientFills({ L: start.L, C: start.chroma(start.L), H: start.H }, { L: end.L, C: end.chroma(end.L), H: end.H }).map((c) => paintOfOklch(c))\n }\n }\n return accent ? [accent] : []\n}\n\n/** The text on the accent fill, quieter: the quietest of it at 60–90% that reaches 4.5:1 over every colour the fill paints. */\nfunction quietOnAccent(tokens: Record<string, string>, vars: ScaleVars): string {\n const fills = accentFillPaints(tokens, vars)\n const text = resolvePaint('var(--ds-text-on-primary)', tokens, vars)\n if (!text || !fills.length) return 'var(--ds-text-on-primary)'\n const candidates = [60, 70, 80, 90].map((pct): ColourCandidate => ({ value: `color-mix(in srgb, var(--ds-text-on-primary) ${pct}%, transparent)`, paint: { rgb: text.rgb, alpha: text.alpha * pct / 100 } }))\n return firstReadable(candidates, fills, WCAG_AA_TEXT)?.value ?? 'var(--ds-text-on-primary)'\n}\n\n/** The status words and the colour each starts from: the status colour, or warning's own text colour. */\nconst STATUS_WORDS: Array<[status: 'success' | 'warning' | 'error' | 'info', own: string]> = [\n ['success', '--ds-status-success'],\n ['warning', '--ds-status-warning-text'],\n ['error', '--ds-status-error'],\n ['info', '--ds-status-info'],\n]\n\n/** The status's words: its own colour where it reads on its soft background and on the page, else the soft pair's text at its hue (D4). */\nfunction statusWords(status: string, own: string, page: readonly Paint[], mode: 'light' | 'dark', tokens: Record<string, string>, vars: ScaleVars): ColourCandidate {\n const ownValue = tokens[own] ?? `var(${own})`\n const grounds = [...page, ...layered(`--ds-status-${status}-bg`, page, tokens, vars)]\n const ownPaint = resolvePaint(ownValue, tokens, vars)\n const walkable = walkableColour(ownValue, tokens, vars)\n const candidates: ColourCandidate[] = []\n if (ownPaint) candidates.push({ value: ownValue, paint: ownPaint })\n if (walkable) {\n const pair = softPair(walkable.H)\n const text = mode === 'light' ? pair.dark : pair.subtle\n const paint = resolvePaint(text, tokens, vars)\n if (paint) candidates.push({ value: text, paint })\n }\n return firstReadable(candidates, grounds, WCAG_AA_TEXT) ?? { value: 'var(--ds-text-primary)', paint: resolvePaint('var(--ds-text-primary)', tokens, vars) ?? WHITE_PAINT }\n}\n\n/**\n * Every token a block's readable colours set (readableTokens with the sidebar's family): what a writer declares after\n * its overrides, and what a check comparing a block with roots.css's own values leaves out.\n */\nexport const READABLE_TOKEN_NAMES: ReadonlySet<string> = new Set([\n '--ds-focus', '--ds-accent-ink', '--ds-text-muted', '--ds-text-secondary',\n '--ds-status-success-text', '--ds-status-warning-text', '--ds-status-error-text', '--ds-status-info-text',\n '--ds-text-on-primary-muted',\n '--ds-sidebar-text-muted', '--ds-sidebar-text-secondary', '--ds-sidebar-focus', '--ds-sidebar-accent-ink',\n])\n\n/** How much louder the secondary grey stays than the muted one, as a ratio of their contrasts (the hierarchy, P7). */\nexport const QUIET_HIERARCHY = 1.2\n\n/**\n * The tokens a mode's block derives so its colours read (Sprint 30: P1, P7, P8, P10, and the bold band's quiet text):\n * `--ds-focus` at 3:1, the greys, `--ds-accent-ink` and the status words at 4.5:1. With `sidebar`, the sidebar's family\n * too (readableSidebarTokens). Writers declare the result after the block's overrides.\n */\nexport function readableTokens(input: ReadableInput): ReadableResult {\n const { mode, vars } = input\n const tokens = { ...ROOTS_COLOUR_DEFAULTS, ...input.tokens }\n input = { ...input, tokens }\n const dir: 1 | -1 = mode === 'light' ? -1 : 1\n const { canvas, page } = pageGrounds(input)\n // What the colours sit on besides the page: its muted fill (a hovered row, a hint's key, a neutral trend) and the\n // accent's two tints (a selected row and a date range's days at 10%, the range's ends and a hovered accent action at 20%)\n const mutedFill = layered('--ds-bg-muted', page, tokens, vars)\n const accentTints = [...layered('--ds-accent-subtle', page, tokens, vars), ...layered('--ds-accent-muted', page, tokens, vars)]\n const out: Record<string, string> = {}\n const inputs: Record<string, string> = {}\n\n // The focus colour: on the page, its muted fill, the accent's tints, the subtle header's tint and the bold band's\n // strip (the surface, at least 60% opaque, over every colour the band paints)\n const accent = resolvePaint('var(--ds-accent-primary)', tokens, vars)\n const strength = evalCssNumber(tokens['--ds-tint-strength'] ?? String(TINT_STRENGTH), vars)\n const headerTint = accent && Number.isFinite(strength) ? layeredPaint({ rgb: accent.rgb, alpha: accent.alpha * strength }, layered('--ds-bg-surface', canvas, tokens, vars)) : []\n const surface = resolvePaint('var(--ds-bg-surface)', tokens, vars)\n const strip = surface ? accentFillPaints(tokens, vars).map((fill) => paintOver({ rgb: surface.rgb, alpha: Math.max(surface.alpha, 0.6) }, fill)) : []\n const focus = readableColour('var(--ds-accent-primary)', [...page, ...mutedFill, ...accentTints, ...headerTint, ...strip], 3, dir, tokens, vars, 'var(--ds-text-primary)')\n out['--ds-focus'] = focus.value\n inputs['--ds-focus'] = 'var(--ds-accent-primary)'\n\n // The accent as text, a mark or a state's edge: on the page, its muted fill and the accent's own tints\n out['--ds-accent-ink'] = readableColour('var(--ds-accent-primary)', [...page, ...mutedFill, ...accentTints], WCAG_AA_TEXT, dir, tokens, vars, 'var(--ds-text-primary)').value\n inputs['--ds-accent-ink'] = 'var(--ds-accent-primary)'\n\n // The greys, on the page and its muted fill: the muted one first, then the secondary one, kept louder than it\n const greyGrounds = [...page, ...mutedFill]\n const mutedOwn = tokens['--ds-text-muted'] ?? 'var(--ds-neutral-400)'\n const muted = readableColour(mutedOwn, greyGrounds, WCAG_AA_TEXT, dir, tokens, vars, 'var(--ds-text-secondary)')\n const mutedContrast = worstPaintContrast(muted.paint, greyGrounds)\n const secondaryOwn = tokens['--ds-text-secondary'] ?? 'var(--ds-neutral-600)'\n const secondary = readableColour(secondaryOwn, greyGrounds, WCAG_AA_TEXT, dir, tokens, vars, 'var(--ds-text-primary)', (c) => worstPaintContrast(c.paint, greyGrounds) >= mutedContrast * QUIET_HIERARCHY)\n out['--ds-text-muted'] = muted.value\n out['--ds-text-secondary'] = secondary.value\n inputs['--ds-text-muted'] = mutedOwn\n inputs['--ds-text-secondary'] = secondaryOwn\n\n // The status words (D4): on their soft backgrounds and on the page\n for (const [status, own] of STATUS_WORDS) {\n out[`--ds-status-${status}-text`] = statusWords(status, own, page, mode, tokens, vars).value\n inputs[`--ds-status-${status}-text`] = tokens[own] ?? `var(${own})`\n }\n\n // The bold band's quieter text\n out['--ds-text-on-primary-muted'] = quietOnAccent(tokens, vars)\n inputs['--ds-text-on-primary-muted'] = 'color-mix(in srgb, var(--ds-text-on-primary) 70%, transparent)'\n\n if (input.sidebar) {\n const sidebar = readableSidebarTokens({ mode, tokens: { ...tokens, ...out }, vars, canvas })\n Object.assign(out, sidebar.tokens)\n Object.assign(inputs, sidebar.inputs)\n }\n return { tokens: out, inputs }\n}\n\nfunction layeredPaint(top: Paint, grounds: readonly Paint[]): Paint[] {\n return grounds.map((g) => paintOver(top, g))\n}\n\n/**\n * The sidebar family's readable tokens, against the sidebar's own background (laid over the page's canvas where it is\n * see-through) and an item's hover: its quiet text, its focus colour and its current item's accent (P2, P7, P8). A\n * value that reads as it is (an alias of the page's derived token, mostly) is kept as written.\n */\nexport function readableSidebarTokens(input: { mode: 'light' | 'dark'; tokens: Record<string, string>; vars: ScaleVars; canvas?: Paint[] }): ReadableResult {\n const { mode, vars } = input\n const tokens = { ...ROOTS_COLOUR_DEFAULTS, ...input.tokens }\n const dir: 1 | -1 = mode === 'light' ? -1 : 1\n const canvas = input.canvas ?? canvasPaints(tokens, vars)\n const bg = layered('--ds-sidebar-bg', canvas, tokens, vars)\n const grounds = bg.length ? [...bg, ...layered('--ds-sidebar-item-hover', bg, tokens, vars)] : canvas\n const out: Record<string, string> = {}\n const inputs: Record<string, string> = {}\n const own = (name: string, otherwise: string) => tokens[name] ?? otherwise\n\n const mutedOwn = own('--ds-sidebar-text-muted', 'var(--ds-text-muted)')\n const muted = readableColour(mutedOwn, grounds, WCAG_AA_TEXT, dir, tokens, vars, 'var(--ds-sidebar-text)')\n const mutedContrast = worstPaintContrast(muted.paint, grounds)\n const secondaryOwn = own('--ds-sidebar-text-secondary', 'var(--ds-text-secondary)')\n const secondary = readableColour(secondaryOwn, grounds, WCAG_AA_TEXT, dir, tokens, vars, 'var(--ds-sidebar-text)', (c) => worstPaintContrast(c.paint, grounds) >= mutedContrast * QUIET_HIERARCHY)\n out['--ds-sidebar-text-muted'] = muted.value\n out['--ds-sidebar-text-secondary'] = secondary.value\n inputs['--ds-sidebar-text-muted'] = mutedOwn\n inputs['--ds-sidebar-text-secondary'] = secondaryOwn\n\n // The focus colour: the page's where it reads on the sidebar, else the sidebar accent walked\n const pageFocus = resolvePaint('var(--ds-focus)', tokens, vars)\n out['--ds-sidebar-focus'] = pageFocus && worstPaintContrast(pageFocus, grounds) >= 3\n ? 'var(--ds-focus)'\n : readableColour('var(--ds-sidebar-accent)', grounds, 3, dir, tokens, vars, 'var(--ds-sidebar-text)').value\n inputs['--ds-sidebar-focus'] = 'var(--ds-sidebar-accent)'\n\n // The current item's accent, on the sidebar and on its own tint\n const tint = layered('--ds-sidebar-accent-subtle', grounds, tokens, vars)\n out['--ds-sidebar-accent-ink'] = readableColour('var(--ds-sidebar-accent)', [...grounds, ...tint], WCAG_AA_TEXT, dir, tokens, vars, 'var(--ds-sidebar-text)').value\n inputs['--ds-sidebar-accent-ink'] = 'var(--ds-sidebar-accent)'\n return { tokens: out, inputs }\n}\n\n/**\n * The builder preview's independent header (applyHeaderOverrides; a generated app wraps its header in data-mode\n * instead, so the mode blocks cover it): the header family's focus colour, quiet text and accent ink against its own\n * background. BuilderShell's header wrapper maps the page's tokens onto them.\n */\nexport function readableHeaderTokens(input: { mode: 'light' | 'dark'; tokens: Record<string, string>; vars: ScaleVars }): ReadableResult {\n const { mode, vars } = input\n const tokens = { ...ROOTS_COLOUR_DEFAULTS, ...input.tokens }\n const dir: 1 | -1 = mode === 'light' ? -1 : 1\n const bg = resolvePaint('var(--ds-header-bg)', tokens, vars)\n const base = bg ? (bg.alpha >= 1 ? bg : paintOver(bg, WHITE_PAINT)) : WHITE_PAINT\n const grounds = [base, ...layered('--ds-header-hover', [base], tokens, vars)]\n const mutedOwn = tokens['--ds-header-text-muted'] ?? 'var(--ds-text-muted)'\n return {\n tokens: {\n '--ds-header-focus': readableColour('var(--ds-header-accent)', grounds, 3, dir, tokens, vars, 'var(--ds-header-text)').value,\n '--ds-header-text-muted': readableColour(mutedOwn, grounds, WCAG_AA_TEXT, dir, tokens, vars, 'var(--ds-header-text)').value,\n '--ds-header-accent-ink': readableColour('var(--ds-header-accent)', grounds, WCAG_AA_TEXT, dir, tokens, vars, 'var(--ds-header-text)').value,\n },\n inputs: { '--ds-header-focus': 'var(--ds-header-accent)', '--ds-header-text-muted': mutedOwn, '--ds-header-accent-ink': 'var(--ds-header-accent)' },\n }\n}\n","import { onFillTextValue, parseOklch } from \"../../lib/token-algorithms\";\nimport { forwardRef, useLayoutEffect, useRef, useState } from \"react\";\nimport {\n Treemap,\n Tooltip,\n ResponsiveContainer,\n} from \"recharts\";\nimport { useChartColors, useChartAnimation } from \"../../lib/chart-utils\";\nimport { ChartTooltipContent, useRadius } from \"./ChartPrimitives\";\nimport { ChartWrapper, markChart } from \"./ChartWrapper\";\n\nexport interface TreemapNode {\n name: string;\n value?: number;\n children?: TreemapNode[];\n [key: string]: unknown;\n}\n\nexport interface TreemapChartProps {\n data: TreemapNode[];\n /** \"auto\" (the default): two wide to one high. A preset or a number overrides it; a ChartContainer's own height wins. */\n height?: \"auto\" | \"sm\" | \"md\" | \"lg\" | number;\n showTooltip?: boolean;\n animated?: boolean;\n \"aria-label\"?: string;\n className?: string;\n}\n\ninterface TreemapContentProps {\n x?: number;\n y?: number;\n width?: number;\n height?: number;\n name?: string;\n depth?: number;\n colors: string[];\n radius: number;\n index?: number;\n /** The label's line height and font size in px, read from the page (null until read). */\n metrics: LabelMetrics | null;\n}\n\ninterface LabelMetrics { lineHeight: number; fontSize: number }\n\n/** A label's inset from its cell's edges. */\nconst LABEL_INSET = 4;\n\n/**\n * How many lines of a label a cell holds (Sprint 25.17 A25, R28-55): as many as its height takes inside the inset; none\n * when it can't hold one line, or is narrower than about three characters, since a sliver of a word reads as nothing.\n */\nexport function treemapLabelLines(width: number, height: number, metrics: LabelMetrics): number {\n if (width - 2 * LABEL_INSET < metrics.fontSize * 3) return 0;\n return Math.max(0, Math.floor((height - 2 * LABEL_INSET) / metrics.lineHeight));\n}\n\n/** Colours as the browser computes them, once each: a token's var() and calc() resolved (\"oklch(0.66 calc(0.18 * 1) 280)\"). */\nconst computedColors = new Map<string, string>();\nfunction computedColor(css: string): string {\n if (typeof document === \"undefined\") return css;\n let value = computedColors.get(css);\n if (value === undefined) {\n const probe = document.createElement(\"span\");\n probe.style.color = css;\n document.body.appendChild(probe);\n value = getComputedStyle(probe).color;\n probe.remove();\n computedColors.set(css, value);\n }\n return value;\n}\n\n/**\n * The label's colour over its cell: the library's one on-fill decision (onFillTextValue: white where it reaches AA, else\n * a deep tint of the fill), for the theme's oklch fills, read as the browser computes them (Sprint 25.17's review: read\n * as hex, every label was white, under 4.5:1 on the lighter cells of every dark preset; a fill with a calc() in it didn't\n * parse); any other colour by its brightness.\n */\nfunction labelColorOn(fill: string): string {\n const parsed = parseOklch(fill) ?? parseOklch(computedColor(fill));\n return parsed ? onFillTextValue(parsed) : contrastColor(computedColor(fill));\n}\n\n/** Dark or white text by a colour's brightness: a hex colour, or rgb() as the browser writes one. */\nfunction contrastColor(color: string): string {\n const rgb = /^rgba?\\(\\s*(\\d+)[\\s,]+(\\d+)[\\s,]+(\\d+)/.exec(color);\n const c = color.replace(\"#\", \"\");\n const [r, g, b] = rgb ? [Number(rgb[1]), Number(rgb[2]), Number(rgb[3])] : c.length >= 6 ? [parseInt(c.substring(0, 2), 16), parseInt(c.substring(2, 4), 16), parseInt(c.substring(4, 6), 16)] : [0, 0, 0];\n const luminance = (0.299 * r + 0.587 * g + 0.114 * b) / 255;\n return luminance > 0.55 ? \"#1f2937\" : \"#ffffff\";\n}\n\nfunction TreemapContent({ x = 0, y = 0, width = 0, height: h = 0, name, depth, colors, radius, index = 0, metrics }: TreemapContentProps) {\n const fill = colors[index % colors.length];\n // the label wraps onto the lines the cell holds, then ends in \"…\", and never leaves the cell (the owner: \"wrap and\n // truncate like our other items\"); SVG text doesn't wrap, so it is HTML in the cell, clamped as the library's other\n // labels are. A word too long for the cell is hyphenated where the page's language allows, else broken. The tooltip\n // keeps the full name.\n const lines = metrics && name ? treemapLabelLines(width, h, metrics) : 0;\n const labelColor = labelColorOn(fill);\n\n return (\n <g>\n <rect\n x={x}\n y={y}\n width={width}\n height={h}\n fill={fill}\n stroke=\"var(--ds-bg-surface)\"\n strokeWidth={2}\n rx={depth === 1 ? radius : 0}\n style={{ opacity: depth === 1 ? 1 : 0.85 }}\n />\n {lines > 0 && (\n <foreignObject x={x} y={y} width={width} height={h} style={{ pointerEvents: \"none\" }}>\n <div className=\"flex h-full w-full items-center justify-center overflow-hidden text-center\" style={{ padding: LABEL_INSET }}>\n <span\n data-treemap-label=\"\"\n className={LABEL_TEXT}\n style={{ color: labelColor, display: \"-webkit-box\", WebkitBoxOrient: \"vertical\", WebkitLineClamp: lines, overflow: \"hidden\", overflowWrap: \"anywhere\", hyphens: \"auto\" }}\n >\n {name}\n </span>\n </div>\n </foreignObject>\n )}\n </g>\n );\n}\n\nfunction addFillToNodes(nodes: TreemapNode[], colors: string[], counter = { i: 0 }): TreemapNode[] {\n return nodes.map((node) => {\n if (node.children) {\n return { ...node, children: addFillToNodes(node.children, colors, counter) };\n }\n const fill = colors[counter.i % colors.length];\n counter.i++;\n return { ...node, fill };\n });\n}\n\n/** The label's type: the theme's small size, its sans font, tight lines. */\nconst LABEL_TEXT = \"text-xs leading-tight font-[family-name:var(--ds-font-sans)]\";\n\n/** The label's line height and font size as the page draws them, read from a hidden sample after each render (a theme change re-renders the chart). */\nfunction useLabelMetrics(): [React.RefObject<HTMLSpanElement | null>, LabelMetrics | null] {\n const probe = useRef<HTMLSpanElement | null>(null);\n const [metrics, setMetrics] = useState<LabelMetrics | null>(null);\n // after every render: a theme's type can change with no prop of the chart's changing; the equality check below ends\n // the chain once the reading holds\n // eslint-disable-next-line react-hooks/exhaustive-deps\n useLayoutEffect(() => {\n const el = probe.current;\n if (!el) return;\n const cs = getComputedStyle(el);\n const fontSize = parseFloat(cs.fontSize);\n const lineHeight = parseFloat(cs.lineHeight) || el.getBoundingClientRect().height;\n if (!(fontSize > 0) || !(lineHeight > 0)) return;\n if (!metrics || metrics.fontSize !== fontSize || metrics.lineHeight !== lineHeight) setMetrics({ fontSize, lineHeight });\n });\n return [probe, metrics];\n}\n\nexport const TreemapChart = markChart(forwardRef<HTMLDivElement, TreemapChartProps>(function TreemapChart({\n data,\n height = \"auto\",\n showTooltip = true,\n animated,\n \"aria-label\": ariaLabel,\n className,\n}, ref) {\n const colors = useChartColors(6, false);\n const isAnimated = useChartAnimation(animated);\n const radius = useRadius();\n const [probe, metrics] = useLabelMetrics();\n\n const chartData = addFillToNodes(data, colors);\n\n if (!data?.length) return null;\n\n return (\n <ChartWrapper ref={ref} height={height} size={{ model: \"ratio\" }} chart=\"treemap\" className={className} aria-label={ariaLabel}>\n <ResponsiveContainer width=\"100%\" height=\"100%\">\n <Treemap\n data={chartData}\n dataKey=\"value\"\n nameKey=\"name\"\n aspectRatio={4 / 3}\n stroke=\"var(--ds-bg-surface)\"\n isAnimationActive={isAnimated}\n content={<TreemapContent colors={colors} radius={radius} metrics={metrics} />}\n >\n {showTooltip && <Tooltip content={<ChartTooltipContent />} />}\n </Treemap>\n </ResponsiveContainer>\n <span ref={probe} aria-hidden className={LABEL_TEXT} style={{ position: \"absolute\", visibility: \"hidden\", pointerEvents: \"none\" }}>M</span>\n </ChartWrapper>\n );\n}));\n","import { forwardRef } from \"react\";\nimport {\n Sankey as RechartsSankey,\n Tooltip,\n ResponsiveContainer,\n} from \"recharts\";\nimport { useChartColors, useResolvedToken } from \"../../lib/chart-utils\";\nimport { ChartTooltipContent } from \"./ChartPrimitives\";\nimport { ChartWrapper, markChart } from \"./ChartWrapper\";\n\nexport interface SankeyChartProps {\n data: {\n nodes: { name: string }[];\n links: { source: number; target: number; value: number }[];\n };\n /** \"auto\" (the default): two wide to one high. A preset or a number overrides it; a ChartContainer's own height wins. */\n height?: \"auto\" | \"sm\" | \"md\" | \"lg\" | number;\n showTooltip?: boolean;\n animated?: boolean;\n \"aria-label\"?: string;\n className?: string;\n}\n\nexport const SankeyChart = markChart(forwardRef<HTMLDivElement, SankeyChartProps>(function SankeyChart({\n data,\n height = \"auto\",\n showTooltip = true,\n \"aria-label\": ariaLabel,\n className,\n}, ref) {\n const colors = useChartColors(data.nodes.length, false);\n const linkStroke = useResolvedToken(\"--ds-border-subtle\");\n\n const nodesWithColor = data.nodes.map((node, i) => ({\n ...node,\n fill: colors[i % colors.length],\n }));\n\n const sankeyData = {\n nodes: nodesWithColor,\n links: data.links,\n };\n\n if (!data?.nodes?.length) return null;\n\n return (\n <ChartWrapper ref={ref} height={height} size={{ model: \"ratio\" }} chart=\"sankey\" className={className} aria-label={ariaLabel}>\n <ResponsiveContainer width=\"100%\" height=\"100%\">\n <RechartsSankey\n data={sankeyData}\n nodeWidth={10}\n nodePadding={24}\n margin={{ top: 8, right: 8, bottom: 8, left: 8 }}\n link={{ stroke: linkStroke, strokeOpacity: 0.4 }}\n >\n {showTooltip && <Tooltip content={<ChartTooltipContent />} />}\n </RechartsSankey>\n </ResponsiveContainer>\n </ChartWrapper>\n );\n}));\n","import { forwardRef, useId } from \"react\";\nimport {\n LineChart,\n Line,\n AreaChart,\n Area,\n BarChart,\n Bar,\n ResponsiveContainer,\n Tooltip,\n XAxis,\n YAxis,\n} from \"recharts\";\nimport { useResolvedToken, useChartAnimation } from \"../../lib/chart-utils\";\nimport { ChartTooltipContent } from \"./ChartPrimitives\";\nimport { useInsideChartContainer } from \"./ChartWrapper\";\n\nexport interface SparklineProps {\n data: number[];\n variant?: \"line\" | \"area\" | \"bar\";\n color?: 1 | 2 | 3 | 4 | 5 | 6;\n height?: number;\n width?: number | \"100%\";\n showTooltip?: boolean;\n curved?: boolean;\n animated?: boolean;\n \"aria-label\"?: string;\n className?: string;\n}\n\nexport const Sparkline = forwardRef<HTMLDivElement, SparklineProps>(function Sparkline({\n data,\n variant = \"line\",\n color = 1,\n height = 40,\n width = \"100%\",\n showTooltip = false,\n curved = true,\n animated,\n \"aria-label\": ariaLabel,\n className,\n}, ref) {\n const instanceId = useId();\n const isAnimated = useChartAnimation(animated);\n const insideContainer = useInsideChartContainer();\n\n const tokenName = `--ds-chart-${color}` as const;\n const softTokenName = `--ds-chart-${color}-soft` as const;\n const chartColor = useResolvedToken(tokenName);\n const softColor = useResolvedToken(softTokenName);\n const chartData = data.map((value, i) => ({ value, index: i }));\n\n const containerStyle = insideContainer\n ? { width: \"100%\", height: \"100%\" }\n : { width: typeof width === \"number\" ? `${width}px` : width, height: `${height}px` };\n\n if (!data?.length) return null;\n\n if (variant === \"bar\") {\n return (\n <div ref={ref} style={containerStyle} className={className} {...(ariaLabel ? { role: \"img\", \"aria-label\": ariaLabel } : {})}>\n <ResponsiveContainer width=\"100%\" height=\"100%\">\n <BarChart data={chartData} margin={{ top: 0, right: 0, bottom: 0, left: 0 }}>\n <XAxis dataKey=\"index\" hide />\n <YAxis hide />\n {showTooltip && <Tooltip content={<ChartTooltipContent />} cursor={false} />}\n <Bar\n dataKey=\"value\"\n fill={chartColor}\n radius={[2, 2, 0, 0]}\n isAnimationActive={isAnimated}\n />\n </BarChart>\n </ResponsiveContainer>\n </div>\n );\n }\n\n if (variant === \"area\") {\n const gradientId = `sparkline-gradient-${instanceId}-${color}`;\n return (\n <div ref={ref} style={containerStyle} className={className} {...(ariaLabel ? { role: \"img\", \"aria-label\": ariaLabel } : {})}>\n <ResponsiveContainer width=\"100%\" height=\"100%\">\n <AreaChart data={chartData} margin={{ top: 2, right: 2, bottom: 2, left: 2 }}>\n <defs>\n <linearGradient id={gradientId} x1=\"0\" y1=\"0\" x2=\"0\" y2=\"1\">\n <stop offset=\"0%\" stopColor={softColor} stopOpacity={1} />\n <stop offset=\"95%\" stopColor={softColor} stopOpacity={0.1} />\n </linearGradient>\n </defs>\n <XAxis dataKey=\"index\" hide />\n <YAxis hide domain={[\"dataMin - 1\", \"dataMax + 1\"]} />\n {showTooltip && <Tooltip content={<ChartTooltipContent />} cursor={false} />}\n <Area\n type={curved ? \"monotone\" : \"linear\"}\n dataKey=\"value\"\n stroke={chartColor}\n strokeWidth={1.5}\n fill={`url(#${gradientId})`}\n dot={false}\n activeDot={showTooltip ? { r: 3, fill: chartColor } : false}\n isAnimationActive={isAnimated}\n />\n </AreaChart>\n </ResponsiveContainer>\n </div>\n );\n }\n\n return (\n <div ref={ref} style={containerStyle} className={className} {...(ariaLabel ? { role: \"img\", \"aria-label\": ariaLabel } : {})}>\n <ResponsiveContainer width=\"100%\" height=\"100%\">\n <LineChart data={chartData} margin={{ top: 2, right: 2, bottom: 2, left: 2 }}>\n <XAxis dataKey=\"index\" hide />\n <YAxis hide domain={[\"dataMin - 1\", \"dataMax + 1\"]} />\n {showTooltip && <Tooltip content={<ChartTooltipContent />} cursor={false} />}\n <Line\n type={curved ? \"monotone\" : \"linear\"}\n dataKey=\"value\"\n stroke={chartColor}\n strokeWidth={1.5}\n dot={false}\n activeDot={showTooltip ? { r: 3, fill: chartColor } : false}\n isAnimationActive={isAnimated}\n />\n </LineChart>\n </ResponsiveContainer>\n </div>\n );\n});\n","import { useId, useMemo, type ReactNode } from \"react\";\nimport { cn, GLASS_SURFACE } from \"../lib/utils\";\nimport { TITLE_TEXT } from \"../lib/title-text\";\nimport { Skeleton } from \"./Skeleton\";\nimport { CHART_HEIGHTS, ChartContainerContext, fixedChartHeight, isLibraryChart, type ChartContainerValue } from \"./charts/ChartWrapper\";\n\n/**\n * CardTitle's classes (Card.tsx) without its line clamp: a chart's title states its insight, its message\n * (data_visualisation#3), so it is never cut. Kept equal to CardTitle's by a test.\n */\nexport const CHART_TITLE_CLASSES = TITLE_TEXT;\n\nexport interface ChartContainerProps {\n /**\n * \"auto\" (the default): the chart sizes itself from its type and its data (Sprint 25.9, A2) — a row per item for\n * sideways bars and funnels, two wide to one high for charts over dates or numbers, square for round charts — and in\n * a row its frame matches the tallest block while the chart grows only to its bound.\n * A preset (sm, md, lg) or a number of px sets this chart's height instead, and beats the chart's own.\n */\n height?: \"auto\" | \"sm\" | \"md\" | \"lg\" | number;\n /** The insight, as a heading (h3) in the card-title style, never cut. The chart's graphic is named by it. */\n title?: string;\n loading?: boolean;\n emptyState?: ReactNode;\n /** \"default\" is a card surface. \"ghost\" drops surface, border, shadow and padding for charts embedded in another container. */\n variant?: \"default\" | \"ghost\";\n children: ReactNode;\n className?: string;\n}\n\nexport function ChartContainer({\n height = \"auto\",\n title,\n loading = false,\n emptyState,\n variant = \"default\",\n children,\n className,\n}: ChartContainerProps) {\n const titleId = useId();\n const fixed = fixedChartHeight(height);\n // A library chart sizes itself (its mark). Anything else — a hand-built chart, an EmptyState, a Sparkline, several\n // children — keeps an area of the preset's height, else md, and fills it.\n const sizesItself = !loading && !!children && isLibraryChart(children);\n const area = fixed ?? CHART_HEIGHTS.md;\n const context = useMemo<ChartContainerValue>(\n () => ({ height: fixed, titleId: title ? titleId : undefined, fillArea: !sizesItself }),\n [fixed, title, titleId, sizesItself],\n );\n\n let body: ReactNode = null;\n if (loading) {\n body = (\n <div className=\"absolute inset-0 flex flex-col justify-end gap-ds-2 px-ds-2\">\n <div className=\"flex items-end h-full gap-ds-1\">\n {[65, 40, 80, 55, 72, 45, 60].map((h, i) => (\n <Skeleton key={i} variant=\"custom\" className=\"flex-1\" height={`${h}%`} />\n ))}\n </div>\n <Skeleton variant=\"text\" lines={1} className=\"w-full\" />\n </div>\n );\n } else if (children) {\n body = (\n <ChartContainerContext.Provider value={context}>\n {sizesItself ? children : (\n // the area is absolute, so a child that fills 100% has a definite height to fill\n <div className=\"absolute inset-0\">\n <div className=\"h-full w-full\">{children}</div>\n </div>\n )}\n </ChartContainerContext.Provider>\n );\n } else if (emptyState) {\n body = <div className=\"flex flex-1 items-center justify-center\">{emptyState}</div>;\n }\n\n return (\n <div\n data-card=\"\"\n data-gs=\"chart\"\n className={cn(\n \"flex flex-col\",\n variant === \"ghost\"\n ? \"bg-transparent\"\n : cn(\n // CardHeader's inset, so titles inside frames line up in a row (A1)\n \"rounded-[var(--ds-radius-md)] px-ds-5 py-ds-4\",\n \"bg-[var(--ds-bg-surface)] border-[length:var(--ds-border-width)] border-[var(--ds-border-subtle)]\",\n GLASS_SURFACE,\n ),\n className,\n )}\n >\n {title && (\n <h3 id={titleId} className={cn(CHART_TITLE_CLASSES, \"mb-ds-4\")}>\n {title}\n </h3>\n )}\n <div\n data-chart-body=\"\"\n className=\"relative flex min-w-0 flex-col\"\n style={{ flex: \"1 1 0%\", minHeight: sizesItself ? undefined : area }}\n >\n {body}\n </div>\n </div>\n );\n}\n"]}
|
|
1
|
+
{"version":3,"sources":["../../../showcase/src/lib/chart-utils.ts","../../../showcase/src/lib/chart-categories.ts","../../../showcase/src/components/charts/value-format.ts","../../../showcase/src/components/charts/chart-access.ts","../../../showcase/src/components/charts/plot-names.tsx","../../../showcase/src/components/charts/series-marks.tsx","../../../showcase/src/components/charts/chart-references.tsx","../../../showcase/src/components/charts/ChartTable.tsx","../../../showcase/src/components/charts/ChartWrapper.tsx","../../../showcase/src/components/charts/ChartPrimitives.tsx","../../../showcase/src/components/charts/BarChart.tsx","../../../showcase/src/components/charts/LineChart.tsx","../../../showcase/src/components/charts/AreaChart.tsx","../../../showcase/src/components/charts/PieChart.tsx","../../../showcase/src/components/charts/CompositeChart.tsx","../../../showcase/src/components/charts/ScatterChart.tsx","../../../showcase/src/components/charts/RadarChart.tsx","../../../showcase/src/components/charts/RadialBarChart.tsx","../../../showcase/src/components/charts/FunnelChart.tsx","../../../showcase/src/lib/token-algorithms.ts","../../../showcase/src/components/charts/TreemapChart.tsx","../../../showcase/src/components/charts/SankeyChart.tsx","../../../showcase/src/components/charts/Sparkline.tsx","../../../showcase/src/components/ChartContainer.tsx"],"names":["text","probe","measure","k","dy","useState","jsx","isNumber","useMemo","useRef","useLayoutEffect","drawn","jsxs","createContext","useContext","ChartWrapper","categoryKind","createPortal","useEffect","forwardRef","BarChart","useId","patterns","RechartsBarChart","Fragment","LineChart","ResponsiveContainer","RechartsLineChart","CartesianGrid","XAxis","YAxis","Tooltip","AreaChart","RechartsAreaChart","PieChart","percent","RechartsPieChart","CompositeChart","values","lineValues","Bar","Line","ScatterChart","RechartsScatterChart","Symbols","RadarChart","RechartsRadarChart","RadialBarChart","RechartsRadialBarChart","FunnelChart","RechartsFunnelChart","css","luminance","TreemapChart","NAME_GAP","shared","SankeyChart","RechartsSankey","Sparkline","Area","useCallback"],"mappings":"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","file":"charts.js","sourcesContent":["import { useState, useLayoutEffect, useSyncExternalStore } from \"react\";\n\nconst CHART_TOKENS = [\n \"--ds-chart-1\",\n \"--ds-chart-2\",\n \"--ds-chart-3\",\n \"--ds-chart-4\",\n \"--ds-chart-5\",\n \"--ds-chart-6\",\n] as const;\n\n/** How many colours the chart palette has: a series past it takes its colour again (useChartColors). */\nexport const CHART_COLOR_COUNT = CHART_TOKENS.length;\n\nconst CHART_TOKENS_SOFT = [\n \"--ds-chart-1-soft\",\n \"--ds-chart-2-soft\",\n \"--ds-chart-3-soft\",\n \"--ds-chart-4-soft\",\n \"--ds-chart-5-soft\",\n \"--ds-chart-6-soft\",\n] as const;\n\nconst FALLBACK_COLORS: Record<string, string> = {\n \"--ds-chart-1\": \"#6366f1\",\n \"--ds-chart-2\": \"#d97706\",\n \"--ds-chart-3\": \"#059669\",\n \"--ds-chart-4\": \"#dc2626\",\n \"--ds-chart-5\": \"#0891b2\",\n \"--ds-chart-6\": \"#7c3aed\",\n \"--ds-chart-1-soft\": \"rgba(99, 102, 241, 0.3)\",\n \"--ds-chart-2-soft\": \"rgba(217, 119, 6, 0.3)\",\n \"--ds-chart-3-soft\": \"rgba(5, 150, 105, 0.3)\",\n \"--ds-chart-4-soft\": \"rgba(220, 38, 38, 0.3)\",\n \"--ds-chart-5-soft\": \"rgba(8, 145, 178, 0.3)\",\n \"--ds-chart-6-soft\": \"rgba(124, 58, 237, 0.3)\",\n \"--ds-bg-surface\": \"#ffffff\",\n \"--ds-bg-canvas\": \"#ffffff\",\n \"--ds-border-subtle\": \"#e5e7eb\",\n \"--ds-text-primary\": \"#111827\",\n \"--ds-text-secondary\": \"#6b7280\",\n \"--ds-text-muted\": \"#9ca3af\",\n};\n\ntype Subscriber = () => void;\n\nlet modeVersion = 0;\nconst subscribers = new Set<Subscriber>();\nlet observerAttached = false;\n\nfunction attachObserver() {\n if (observerAttached || typeof document === \"undefined\") return;\n observerAttached = true;\n\n const observer = new MutationObserver((mutations) => {\n for (const m of mutations) {\n if (m.attributeName === \"data-mode\") {\n modeVersion++;\n for (const sub of subscribers) sub();\n break;\n }\n }\n });\n\n observer.observe(document.documentElement, {\n attributes: true,\n attributeFilter: [\"data-mode\"],\n });\n}\n\nfunction subscribe(cb: Subscriber) {\n attachObserver();\n subscribers.add(cb);\n return () => { subscribers.delete(cb); };\n}\n\nfunction getSnapshot() {\n return modeVersion;\n}\n\nfunction getServerSnapshot() {\n return 0;\n}\n\nexport function resolveToken(token: string): string {\n if (typeof document === \"undefined\") return FALLBACK_COLORS[token] ?? \"#6366f1\";\n const val = getComputedStyle(document.documentElement).getPropertyValue(token).trim();\n return val || FALLBACK_COLORS[token] || \"#6366f1\";\n}\n\n/**\n * The theme's chart series colours, `count` of them in series order (repeating past the palette's length), read from the\n * live tokens so they follow the theme and its mode; `soft` gives the lighter series. Before the theme's styles are\n * committed, and on the server, it returns the fallback shades, then the theme's on the next layout.\n */\nexport function useChartColors(count: number, soft = false): string[] {\n const version = useSyncExternalStore(subscribe, getSnapshot, getServerSnapshot);\n const [colors, setColors] = useState<string[]>(() => fallbackColors(count, soft));\n\n // Reads computed CSS custom properties, which only exist after the theme's\n // style tag is committed — this has to be a post-layout effect.\n /* eslint-disable react-hooks/set-state-in-effect -- token resolution is a DOM read after commit */\n useLayoutEffect(() => {\n setColors(resolveColors(count, soft));\n }, [count, soft, version]);\n /* eslint-enable react-hooks/set-state-in-effect */\n\n return colors;\n}\n\nfunction fallbackColors(count: number, soft: boolean): string[] {\n const tokens = soft ? CHART_TOKENS_SOFT : CHART_TOKENS;\n const result: string[] = [];\n for (let i = 0; i < count; i++) {\n const token = tokens[i % tokens.length];\n result.push(FALLBACK_COLORS[token] ?? \"#6366f1\");\n }\n return result;\n}\n\nfunction resolveColors(count: number, soft: boolean): string[] {\n const tokens = soft ? CHART_TOKENS_SOFT : CHART_TOKENS;\n const result: string[] = [];\n for (let i = 0; i < count; i++) {\n const token = tokens[i % tokens.length];\n result.push(resolveToken(token));\n }\n return result;\n}\n\nexport function useResolvedToken(token: string): string {\n const version = useSyncExternalStore(subscribe, getSnapshot, getServerSnapshot);\n const [value, setValue] = useState(() => FALLBACK_COLORS[token] ?? \"#6366f1\");\n\n /* eslint-disable react-hooks/set-state-in-effect -- token resolution is a DOM read after commit */\n useLayoutEffect(() => {\n setValue(resolveToken(token));\n }, [token, version]);\n /* eslint-enable react-hooks/set-state-in-effect */\n\n return value;\n}\n\nexport function useReducedMotion(): boolean {\n const [reduced, setReduced] = useState(() => {\n if (typeof window === \"undefined\") return false;\n return window.matchMedia(\"(prefers-reduced-motion: reduce)\").matches;\n });\n\n useLayoutEffect(() => {\n const mql = window.matchMedia(\"(prefers-reduced-motion: reduce)\");\n const handler = (e: MediaQueryListEvent) => setReduced(e.matches);\n mql.addEventListener(\"change\", handler);\n return () => mql.removeEventListener(\"change\", handler);\n }, []);\n\n return reduced;\n}\n\nexport const useChartAnimation = (animated?: boolean): boolean => {\n const reduced = useReducedMotion();\n return animated !== false && !reduced;\n};\n","/**\n * Sprint 25.9, A3 — what a chart's category axis holds, and how its labels fit. No Recharts here: the charts entry and\n * the tests import it, and it never measures on its own (the measurer is handed in).\n *\n * - `categoryKind(labels)`: \"scale\" when every non-empty label is a date, a time, a period or a number, else \"names\".\n * Anchored patterns only — never `Date.parse`, which V8 lets read \"Tier 1\", \"Sprint 1\" and \"Northern Region 2\" as dates.\n * - `createAxisMeasurer(el)`: canvas text widths in the axis's resolved font, read from a probe that carries\n * `font-size: var(--ds-font-size-xs)`, so a `calc()` token (`calc(16px * .75)`, a 14 px base) measures right.\n * - `fitLabel(name, width, measure)`: one line; else two lines split at a space; else \"…\" on the second. Never drops it.\n */\n\nexport type CategoryKind = \"names\" | \"scale\";\n\n/** A text's width in px in the axis font. */\nexport type Measure = (text: string) => number;\n\nconst ENGLISH_MONTHS = [\n \"january\", \"february\", \"march\", \"april\", \"may\", \"june\", \"july\", \"august\", \"september\", \"october\", \"november\", \"december\",\n \"jan\", \"feb\", \"mar\", \"apr\", \"jun\", \"jul\", \"aug\", \"sep\", \"sept\", \"oct\", \"nov\", \"dec\",\n];\nconst ENGLISH_WEEKDAYS = [\n \"monday\", \"tuesday\", \"wednesday\", \"thursday\", \"friday\", \"saturday\", \"sunday\",\n \"mon\", \"tue\", \"tues\", \"wed\", \"thu\", \"thur\", \"thurs\", \"fri\", \"sat\", \"sun\",\n];\n\nconst escape = (s: string) => s.replace(/[.*+?^${}()|[\\]\\\\]/g, \"\\\\$&\");\nconst clean = (s: string) => s.trim().toLowerCase().replace(/\\.$/, \"\");\n\nfunction intlNames(locale: string, kind: \"month\" | \"weekday\"): string[] {\n const out: string[] = [];\n try {\n for (const width of [\"short\", \"long\"] as const) {\n const fmt = new Intl.DateTimeFormat(locale, kind === \"month\" ? { month: width, timeZone: \"UTC\" } : { weekday: width, timeZone: \"UTC\" });\n // 2026-01-05 is a Monday: seven days give the weekdays, the 15th of each month the months\n const count = kind === \"month\" ? 12 : 7;\n for (let i = 0; i < count; i++) {\n const date = kind === \"month\" ? new Date(Date.UTC(2026, i, 15)) : new Date(Date.UTC(2026, 0, 5 + i));\n out.push(clean(fmt.format(date)));\n }\n }\n } catch {\n // an unknown locale tag: English covers it\n }\n return out;\n}\n\n/**\n * The languages whose month and weekday names count: English, and the locale given (a chart's locale while a\n * server-rendered page hydrates, the same on both sides: Sprint 25.20); with none given, the runtime's, the browser's and\n * the page's, as an app's own call and a chart in the browser read them (labels in the visitor's own language count).\n */\nfunction locales(given?: string): string[] {\n const out = new Set<string>([\"en\"]);\n if (given !== undefined) {\n out.add(given);\n return [...out];\n }\n try { out.add(new Intl.DateTimeFormat().resolvedOptions().locale); } catch { /* no Intl locale */ }\n if (typeof navigator !== \"undefined\" && navigator.language) out.add(navigator.language);\n if (typeof document !== \"undefined\" && document.documentElement?.lang) out.add(document.documentElement.lang);\n return [...out];\n}\n\ninterface Patterns { key: string; list: RegExp[] }\nlet cached: Patterns | null = null;\n\nfunction patterns(given?: string): Patterns {\n const tags = locales(given);\n const key = tags.join(\"|\");\n if (cached?.key === key) return cached;\n const months = new Set(ENGLISH_MONTHS);\n const weekdays = new Set(ENGLISH_WEEKDAYS);\n for (const tag of tags) {\n for (const m of intlNames(tag, \"month\")) if (m) months.add(m);\n for (const d of intlNames(tag, \"weekday\")) if (d) weekdays.add(d);\n }\n // the longest first, so \"sept\" wins over \"sep\" and \"june\" over \"jun\"\n const alt = (set: Set<string>) => [...set].sort((a, b) => b.length - a.length).map(escape).join(\"|\");\n const M = `(?:${alt(months)})\\\\.?`;\n const D = `(?:${alt(weekdays)})\\\\.?`;\n const day = String.raw`\\d{1,2}(?:st|nd|rd|th|\\.)?`;\n const year = String.raw`'?\\d{2,4}`;\n const list = [\n // dates in digits: 2026-09-21, 21/09, 09/21/2026, 21.09.2026, an ISO date-time\n /^\\d{4}[-/.]\\d{1,2}(?:[-/.]\\d{1,2})?$/,\n /^\\d{1,2}[-/.]\\d{1,2}(?:[-/.]\\d{2,4})?$/,\n /^\\d{4}-\\d{2}-\\d{2}[T ]\\d{1,2}:\\d{2}(?::\\d{2}(?:\\.\\d+)?)?(?:Z|[+-]\\d{2}:?\\d{2})?$/,\n // a day and a month in either order, and a month alone or with its year: 16 Sep, 21. Sept., Sept 21, March 2026\n new RegExp(`^${day}\\\\s*${M}(?:,?\\\\s+${year})?$`, \"iu\"),\n new RegExp(`^${M}\\\\s*${day}(?:,?\\\\s+${year})?$`, \"iu\"),\n new RegExp(`^${M}(?:\\\\s*${year})?$`, \"iu\"),\n // CJK dates: 9月21日, 2026年9月, 9월 21일\n /^(?:\\d{4}年)?\\d{1,2}月(?:\\d{1,2}日)?$/u,\n /^\\d{4}年(?:\\d{1,2}月)?$/u,\n /^(?:\\d{4}년\\s?)?\\d{1,2}월(?:\\s?\\d{1,2}일)?$/u,\n // a quarter or a half: Q3, Q3 2026, Q3 FY26, 2026 Q3, 3Q26, H1 2026\n /^Q[1-4](?:\\s*[-/']?\\s*(?:FY\\s?)?'?\\d{2,4})?$/i,\n /^[1-4]Q\\s*'?\\d{0,4}$/i,\n /^(?:FY\\s?)?'?\\d{2,4}\\s*[-/]?\\s*Q[1-4]$/i,\n /^H[12](?:\\s*'?\\d{2,4})?$/i,\n // a year or a fiscal year: 2026, FY26, FY 2025/26, 2025/26, 2025-2026\n /^(?:19|20)\\d{2}$/,\n /^FY\\s?'?\\d{2,4}(?:\\s?[-/]\\s?'?\\d{2,4})?$/i,\n /^(?:19|20)\\d{2}\\s?[-/–]\\s?(?:(?:19|20)?\\d{2})$/,\n // a week: W12, Wk 3, Week 12, Week 12 2026, 2026-W12\n /^(?:W|Wk|Week)\\.?\\s?\\d{1,2}(?:\\s*[,/-]?\\s*\\d{4})?$/i,\n /^\\d{4}-?W\\d{1,2}(?:-?\\d)?$/i,\n // a weekday: Mon, Tuesday, and the runtime and page locales' own\n new RegExp(`^${D}$`, \"iu\"),\n // a time: 09:00, 9:30 pm, 9am, 14h\n /^\\d{1,2}:\\d{2}(?::\\d{2})?\\s?(?:[ap]\\.?m\\.?)?$/i,\n /^\\d{1,2}\\s?[ap]\\.?m\\.?$/i,\n /^\\d{1,2}h(?:\\d{2})?$/i,\n // a number, a percentage or an amount: 12, -3.5, 1,200, 12%, $5k, €1.2m, 5 €, a bin (10–20, <10, 50+)\n /^[<>≤≥~]?\\s?[+\\-−]?\\s?[$€£¥₹]?\\s?\\d[\\d,. \\u00a0\\u202f]*(?:\\s?(?:k|m|mn|bn|b|t))?\\s?(?:%|[$€£¥₹])?\\+?$/iu,\n /^[$€£¥₹]?\\d[\\d,.]*\\s?[-–]\\s?[$€£¥₹]?\\d[\\d,.]*\\s?(?:k|m|bn|%)?$/iu,\n ];\n cached = { key, list };\n return cached;\n}\n\n/**\n * Whether a category axis holds names or a scale (dates, times, periods, numbers). Every non-empty label must match an\n * anchored pattern to be \"scale\"; an all-empty set is \"scale\". LineChart and AreaChart are always \"scale\"; BarChart and\n * CompositeChart guess with this, and their `categoryKind` prop overrides the guess.\n */\nexport function categoryKind(labels: ReadonlyArray<unknown>, locale?: string): CategoryKind {\n const { list } = patterns(locale);\n for (const raw of labels) {\n if (raw == null) continue;\n if (typeof raw === \"number\") { if (Number.isFinite(raw)) continue; return \"names\"; }\n if (raw instanceof Date) continue;\n const text = String(raw).trim();\n if (!text) continue;\n if (!list.some((re) => re.test(text))) return \"names\";\n }\n return \"scale\";\n}\n\n/* ── Measuring ──────────────────────────────────────────────────────────── */\n\n/** The axis font as the page resolves it: size and family from a probe carrying the chart's tick tokens. */\nexport function resolvedAxisFont(el: Element): { font: string; px: number } {\n const doc = el.ownerDocument;\n const view = doc.defaultView;\n let probe = el.querySelector<HTMLElement>(\"[data-chart-probe]\");\n let temporary = false;\n if (!probe) {\n probe = doc.createElement(\"span\");\n probe.setAttribute(\"aria-hidden\", \"true\");\n probe.style.cssText = \"position:absolute;visibility:hidden;pointer-events:none;white-space:nowrap;font-size:var(--ds-font-size-xs);font-family:var(--ds-font-sans)\";\n el.appendChild(probe);\n temporary = true;\n }\n const cs = view?.getComputedStyle(probe);\n const px = parseFloat(cs?.fontSize ?? \"\") || 12;\n const family = (cs?.fontFamily ?? \"\").trim() || \"sans-serif\";\n const style = cs?.fontStyle && cs.fontStyle !== \"normal\" ? `${cs.fontStyle} ` : \"\";\n const weight = cs?.fontWeight && cs.fontWeight !== \"400\" && cs.fontWeight !== \"normal\" ? `${cs.fontWeight} ` : \"\";\n if (temporary) probe.remove();\n return { font: `${style}${weight}${px}px ${family}`, px };\n}\n\n/** One 2D context for every chart, kept per getContext implementation (a test may swap it for a stub). */\nlet shared: { getContext: unknown; ctx: CanvasRenderingContext2D | null } | null = null;\n\nfunction canvasContext(): CanvasRenderingContext2D | null {\n if (typeof document === \"undefined\") return null;\n const getContext = (globalThis as { HTMLCanvasElement?: { prototype: { getContext?: unknown } } }).HTMLCanvasElement?.prototype.getContext;\n if (shared && shared.getContext === getContext) return shared.ctx;\n let ctx: CanvasRenderingContext2D | null = null;\n try { ctx = document.createElement(\"canvas\").getContext?.(\"2d\") ?? null; } catch { ctx = null; }\n shared = { getContext, ctx };\n return ctx;\n}\n\n/**\n * A text measurer in the chart's own axis font, or null where there is no canvas (jsdom): the charts then show every\n * label in full on one line and leave the thinning to nobody.\n */\nexport function createAxisMeasurer(el: Element): { measure: Measure; px: number; font: string } | null {\n const ctx = canvasContext();\n if (!ctx) return null;\n const { font, px } = resolvedAxisFont(el);\n ctx.font = font;\n const widths = new Map<string, number>();\n const measure: Measure = (text) => {\n let w = widths.get(text);\n if (w === undefined) {\n // the context is shared: another chart may have set its own font since\n ctx.font = font;\n w = ctx.measureText(text).width;\n widths.set(text, w);\n }\n return w;\n };\n return { measure, px, font };\n}\n\n/* ── Fitting a name ─────────────────────────────────────────────────────── */\n\nexport const ELLIPSIS = \"…\";\n\nexport interface FittedLabel {\n /** One or two lines; the second ends with \"…\" when the name was cut. */\n lines: string[];\n cut: boolean;\n /** Characters of the name that show, spaces and the ellipsis left out. */\n shown: number;\n}\n\nconst letters = (s: string) => s.replace(/\\s+/g, \"\").replace(/…/g, \"\").length;\n\n/** The longest prefix of `text` that fits `width` (at least one character). */\nfunction prefixThatFits(text: string, width: number, measure: Measure, suffix = \"\"): number {\n let lo = 1;\n let hi = text.length;\n let best = 0;\n while (lo <= hi) {\n const mid = (lo + hi) >> 1;\n if (measure(text.slice(0, mid).trimEnd() + suffix) <= width) { best = mid; lo = mid + 1; } else hi = mid - 1;\n }\n return best;\n}\n\n/**\n * A name fitted to `width`: one line when it fits; else two lines split at a space; else the second line ends with \"…\".\n * A first word wider than the line breaks where the line ends, with a hyphen, so it reads as one word going on. The\n * name is never dropped, and without a measurer it shows in full on one line.\n */\nexport function fitLabel(name: string, width: number, measure: Measure | null): FittedLabel {\n const text = name.replace(/\\s+/g, \" \").trim();\n if (!measure || !text || width <= 0 || measure(text) <= width) return { lines: [text], cut: false, shown: letters(text) };\n const words = text.split(\" \");\n let first = \"\";\n let firstShown = \"\";\n let rest = \"\";\n for (let i = words.length - 1; i >= 1; i--) {\n const candidate = words.slice(0, i).join(\" \");\n if (measure(candidate) <= width) { first = firstShown = candidate; rest = words.slice(i).join(\" \"); break; }\n }\n if (!first) {\n // the first word alone is too wide: the first line holds what fits of it and a hyphen\n const k = Math.max(1, prefixThatFits(text, width, measure, \"-\"));\n firstShown = text.slice(0, k).trimEnd();\n rest = text.slice(k).trimStart();\n first = rest && !text.slice(k - 1, k + 1).includes(\" \") ? `${firstShown}-` : firstShown;\n }\n if (!rest) return { lines: [first], cut: false, shown: letters(firstShown) };\n if (measure(rest) <= width) return { lines: [first, rest], cut: false, shown: letters(firstShown) + letters(rest) };\n const k = prefixThatFits(rest, width, measure, ELLIPSIS);\n const kept = k > 0 ? rest.slice(0, k).trimEnd() : \"\";\n return { lines: [first, kept + ELLIPSIS], cut: true, shown: letters(firstShown) + letters(kept) };\n}\n\n/** D8: fewer visible characters than this on a cut name turns an upright chart of names sideways. */\nexport const MIN_NAME_CHARS = 6;\n\n/** Whether any name, fitted to `width`, would be cut to fewer than MIN_NAME_CHARS characters. */\nexport function namesCutShort(names: ReadonlyArray<string>, width: number, measure: Measure): boolean {\n return names.some((n) => {\n const fit = fitLabel(n, width, measure);\n return fit.cut && fit.shown < MIN_NAME_CHARS;\n });\n}\n","import { getNiceTickValues } from \"recharts\";\n\n/**\n * How a chart's values read (Sprint 25.17 A27, R28-50, P21). \"number\" (the default): plain numbers, compact on the axis\n * from five digits up (1M, 750K; 1,234 as it is). \"percent\": values are percentages out of 100 (45 reads 45%; multiply a fraction by\n * 100 first). \"milliseconds\": durations in ms (120 ms, 1.5 s, 2 min). \"bytes\": sizes in bytes, in the units of 1,000 the\n * browser's own formats name (1.5 MB). A function formats both the axis and the tooltip itself. Everything is in the\n * page's language (its `lang`, in the visitor's formats where they speak it: formatLocale).\n */\nexport type ValueFormat = \"number\" | \"percent\" | \"milliseconds\" | \"bytes\" | ((value: number) => string);\n\n/** Recharts draws a value axis with five ticks on a nice scale that includes 0 (its default domain, [0, \"auto\"]). */\nconst TICK_COUNT = 5;\n\nconst TIME_UNITS: Array<[unit: string, ms: number]> = [[\"hour\", 3_600_000], [\"minute\", 60_000], [\"second\", 1_000], [\"millisecond\", 1]];\nconst BYTE_UNITS: Array<[unit: string, bytes: number]> = [[\"petabyte\", 1e15], [\"terabyte\", 1e12], [\"gigabyte\", 1e9], [\"megabyte\", 1e6], [\"kilobyte\", 1e3], [\"byte\", 1]];\n\n/** Fraction digits tried before giving up on an exact label (a value with more is shown to this many). */\nconst MAX_FRACTION = 10;\n\n/**\n * A value as `format` writes it with the fewest fraction digits that show it exactly, in the locale's own notation:\n * 2,500 is \"2.5K\" in English and 15,000 \"1.5万\" in Japanese, 0.0004 is \"0.0004\" — never a rounded \"3K\", \"2万\" or \"0\"\n * (Sprint 25.17's review: digits counted in thousands misread the locales that group by 万 or by lakh, and a cap of\n * three turned small rates into a row of zeros). Exact means more digits change nothing.\n */\nfunction exact(format: (digits: number) => string, maxDigits = MAX_FRACTION): string {\n for (let digits = 0; digits < maxDigits; digits++) {\n const label = format(digits);\n if (label === format(digits + 6)) return label;\n }\n return format(maxDigits);\n}\n\nconst unitFormat = (unit: string, value: number, locale: string | undefined) => (digits: number) =>\n new Intl.NumberFormat(locale, { style: \"unit\", unit, unitDisplay: \"short\", maximumFractionDigits: digits }).format(value);\n\nconst unitsOf = (format: \"milliseconds\" | \"bytes\") => (format === \"bytes\" ? BYTE_UNITS : TIME_UNITS);\n\n/** The largest unit a value reaches (1.5 MB, 120 ms), for a value read on its own. */\nfunction unitReached(units: Array<[string, number]>, value: number): [string, number] {\n return units.find(([, size]) => Math.abs(value) >= size) ?? units[units.length - 1];\n}\n\n/**\n * One unit for a whole axis (the review: \"0 ms, 25 sec, 1.25 min\" chose it tick by tick): the largest its biggest tick\n * reaches in which every tick reads exactly in two fraction digits or fewer, so 25 s and 75 s stay seconds where minutes\n * would read 0.417.\n */\nfunction axisUnit(units: Array<[string, number]>, ticks: number[]): [string, number] {\n const largest = Math.max(0, ...ticks.map(Math.abs));\n const exactIn = (size: number) => ticks.every((t) => Math.abs((t / size) * 100 - Math.round((t / size) * 100)) < 1e-6);\n return units.find(([, size]) => largest / size >= 1 && exactIn(size)) ?? units[units.length - 1];\n}\n\n/** The ticks Recharts draws for these values on a value axis. */\nexport function valueAxisTicks(values: number[]): number[] {\n const finite = values.filter(Number.isFinite);\n if (!finite.length) return [];\n const lo = Math.min(0, ...finite);\n const hi = Math.max(0, ...finite);\n if (lo === hi) return [lo];\n return getNiceTickValues([lo, hi], TICK_COUNT, true).map(Number);\n}\n\n/**\n * A value axis's tick labels: compact from five digits up, in the chart's locale (its useFormatLocale(), Sprint 25.20),\n * each exact (formatted as Recharts draws it, whatever ticks it picks); a duration or a size in one unit for the axis.\n */\nexport function axisTickFormatter(values: number[], format: ValueFormat | undefined, locale: string | undefined): (value: number) => string {\n if (typeof format === \"function\") return format;\n if (format === \"percent\") return (value) => exact((d) => new Intl.NumberFormat(locale, { style: \"percent\", maximumFractionDigits: d }).format(value / 100));\n if (format === \"milliseconds\" || format === \"bytes\") {\n const [unit, size] = axisUnit(unitsOf(format), valueAxisTicks(values));\n return (value) => exact(unitFormat(unit, value / size, locale));\n }\n const compact = (value: number) => exact((d) => new Intl.NumberFormat(locale, { notation: \"compact\", maximumFractionDigits: d }).format(value));\n const plain = (value: number) => exact((d) => new Intl.NumberFormat(locale, { maximumFractionDigits: d }).format(value));\n // compact where it pays, from five digits up (250k for 250,000); below, the number as people write it: 1,234, never\n // 1.234K, which is longer and reads worse (the 25.17 second review). Read from the values, so a domain of the page's own\n // (2018 to 2024) is read as Recharts draws it.\n const largest = Math.max(0, ...values.filter(Number.isFinite).map(Math.abs));\n return largest >= COMPACT_FROM ? compact : plain;\n}\n\n/** The size from which a value axis's numbers read compact (Sprint 25.17's second review). */\nconst COMPACT_FROM = 10_000;\n\n/** A value in full, as the tooltip shows it, in the chart's locale: every digit of a number (grouped); a duration's or a size's, exactly, in the largest unit it reaches. */\nexport function fullValueFormatter(format: ValueFormat | undefined, locale: string | undefined): (value: number) => string {\n if (typeof format === \"function\") return format;\n if (format === undefined || format === \"number\") return (value) => value.toLocaleString(locale);\n if (format === \"percent\") return (value) => exact((d) => new Intl.NumberFormat(locale, { style: \"percent\", maximumFractionDigits: d }).format(value / 100), 4);\n return (value) => {\n const [unit, size] = unitReached(unitsOf(format), value);\n return exact(unitFormat(unit, value / size, locale), 4);\n };\n}\n\n/** A series a value axis draws: its key, and the stack it sits in (null: on its own). */\nexport interface AxisSeries {\n dataKey: string;\n stack: string | null;\n}\n\n/**\n * A value as the charts read it: a number, or a number written as text (\"150\", as an API or a CSV gives it), which\n * Recharts draws too; else null. The axes, the table and the sentence all read values this way (Sprint 25.8.9).\n */\nexport function numberOf(raw: unknown): number | null {\n const v = typeof raw === \"number\" ? raw : typeof raw === \"string\" && raw.trim() !== \"\" ? Number(raw) : NaN;\n return Number.isFinite(v) ? v : null;\n}\n\n/**\n * The values a value axis spans: each value of a series drawn on its own, and each stack's positive values summed up from\n * 0 and its negative values down — the charts stack both ways from zero (Sprint 25.17's review: a stack of 6,500 up and\n * 2,500 down was read as one sum of 4,000). One reading for every chart.\n */\nexport function axisExtent(data: Record<string, unknown>[], series: AxisSeries[]): number[] {\n return data.flatMap((row) => {\n const own: number[] = [];\n const up = new Map<string, number>();\n const down = new Map<string, number>();\n for (const s of series) {\n const v = numberOf(row[s.dataKey]);\n if (v === null) continue;\n if (s.stack == null) own.push(v);\n else if (v >= 0) up.set(s.stack, (up.get(s.stack) ?? 0) + v);\n else down.set(s.stack, (down.get(s.stack) ?? 0) + v);\n }\n return [...own, ...up.values(), ...down.values()];\n });\n}\n\n/** The values a value axis spans for these series: each on its own, or one stack of them all. */\nexport function seriesValues(data: Record<string, unknown>[], keys: string[], stacked = false): number[] {\n return axisExtent(data, keys.map((dataKey) => ({ dataKey, stack: stacked ? \"stack\" : null })));\n}\n","/**\n * What a chart says besides its drawing (Sprint 25.8.9 items 4, 25, 26 and 27): its values as a table and a sentence of\n * what it shows, each worked out from the chart's own props, so they stay true as the data changes. The sentence is a\n * line on the page and the table one switch away, so a reader who can't see the colours, or can't see at all, gets the\n * same as one who can (charts-6, charts-7, WCAG 1.4.1 and 1.1.1).\n *\n * Pure: each chart builds its own from the page's data, read by named fields, never from the copies it draws with\n * (Sprint 25.29 item 14), so a row's own fields never reach the table's cells.\n */\n\nimport { numberOf } from \"./value-format\";\n\n/** A value a chart marks across its plot: a target or a limit as a line, or a band from `value` to `to`. */\nexport interface ChartReference {\n /** Where the line sits, or where the band starts, on the value axis. */\n value: number;\n /** What it is (\"Target\", \"Budget\"): drawn beside it, and said in the sentence and under the table. */\n label: string;\n /** A band's other end. */\n to?: number;\n}\n\n/** A chart's values as a table: its headings, which columns hold numbers, its rows as read, and what follows it. */\nexport interface ChartTableModel {\n columns: string[];\n numeric: boolean[];\n rows: string[][];\n /** Lines under the table: the reference lines and bands, and where a forecast starts. */\n notes: string[];\n /** The column that names each row, its row header (the first without one): a treemap's tile, never its group. */\n rowHeader?: number;\n}\n\nexport interface ChartAccess {\n table: ChartTableModel;\n description: string;\n}\n\n/** A value as the chart reads it in full (its unit, its locale). */\nexport type ChartFormat = (value: number, dataKey?: string) => string;\n\nconst isNumber = (v: unknown): v is number => typeof v === \"number\" && Number.isFinite(v);\nconst text = (v: unknown) => (v == null ? \"\" : String(v));\n\n/** \"A\", \"A and B\", \"A, B and C\". */\nexport function listOf(items: string[]): string {\n if (items.length <= 1) return items[0] ?? \"\";\n return `${items.slice(0, -1).join(\", \")} and ${items[items.length - 1]}`;\n}\n\n/** A share as a whole percentage, \"12%\"; never rounded to nothing or to all of it: \"under 1%\", \"over 99%\". */\nfunction percent(part: number, whole: number): string {\n if (!(whole > 0)) return \"0%\";\n const p = (part / whole) * 100;\n if (p > 0 && p < 1) return \"under 1%\";\n if (p > 99 && p < 100) return \"over 99%\";\n return `${Math.round(p)}%`;\n}\n\nfunction referenceNote(r: ChartReference, format: ChartFormat): string {\n return isNumber(r.to) ? `${r.label}: ${format(r.value)} to ${format(r.to)}` : `${r.label}: ${format(r.value)}`;\n}\n\n/** At most this many series are summed up one by one; the rest are counted. */\nconst SUMMED = 3;\n\n/**\n * One series in words (Sprint 25.8.9 item 4), saying only what holds for every value it has. Over a scale: from its\n * first value to its last, \"up\" or \"down\" only when every step goes that way, and its highest and lowest when it goes\n * both ways, so a dip or a spike is never missed. Over names: its highest and lowest. One value throughout is said once.\n * No verb, so a plural name (\"Expenses\") reads as well as a single one.\n */\nfunction seriesSentence(label: string, points: Array<{ cat: string; value: number }>, over: \"scale\" | \"names\", f: (v: number) => string): string | null {\n if (!points.length) return null;\n if (points.length === 1) return `${label}: ${f(points[0].value)} (${points[0].cat}).`;\n const high = points.reduce((a, b) => (b.value > a.value ? b : a));\n const low = points.reduce((a, b) => (b.value < a.value ? b : a));\n if (high.value === low.value) return over === \"scale\" ? `${label}: ${f(high.value)} throughout.` : `${label}: ${f(high.value)} for all ${points.length}.`;\n const extremes = `highest ${f(high.value)} (${high.cat}), lowest ${f(low.value)} (${low.cat})`;\n if (over === \"names\") return `${label}: ${extremes}.`;\n const first = points[0], end = points[points.length - 1];\n const steps = points.slice(1).map((p, i) => p.value - points[i].value);\n const up = steps.every((d) => d >= 0), down = steps.every((d) => d <= 0);\n const course = `${up ? \"up from\" : down ? \"down from\" : \"from\"} ${f(first.value)} (${first.cat}) to ${f(end.value)} (${end.cat})`;\n return up || down ? `${label}: ${course}.` : `${label}: ${course}, ${extremes}.`;\n}\n\nexport interface CartesianSeries {\n dataKey: string;\n label: string;\n}\n\n/**\n * A chart of series over categories: a line, bar, area or radar chart, or bars with lines. Over a scale (dates, times)\n * each series' sentence follows its trend; over names, its highest and lowest.\n */\nexport function cartesianAccess(o: {\n kind: string;\n data: Record<string, unknown>[];\n categoryKey: string;\n categoryHeading?: string;\n series: CartesianSeries[];\n format: ChartFormat;\n over: \"scale\" | \"names\";\n references?: ChartReference[];\n /** The first row whose values are a forecast (or a period not yet over), and what to call them. */\n forecast?: { from: number; label: string };\n}): ChartAccess {\n const { data, categoryKey, series, format } = o;\n const cats = data.map((row) => text(row[categoryKey]));\n const last = data.length - 1;\n const forecastFrom = o.forecast && o.forecast.from >= 0 && o.forecast.from < data.length ? o.forecast.from : -1;\n const rows = data.map((row, i) => [\n forecastFrom >= 0 && i >= forecastFrom ? `${cats[i]} (${o.forecast!.label})` : cats[i],\n ...series.map((s) => {\n const v = numberOf(row[s.dataKey]);\n return v === null ? \"–\" : format(v, s.dataKey);\n }),\n ]);\n // where the forecast runs, in the page's words: \"Forecast: May to Jun\", or one period not yet over, \"So far this month:\n // Jul\"; from the first category, every value is one, and the series' own sentences are told by them\n const runs = forecastFrom < last ? `${cats[forecastFrom]} to ${cats[last]}` : cats[forecastFrom];\n const forecastNote = forecastFrom >= 0 ? `${o.forecast!.label}: ${forecastFrom === 0 ? `every value (${runs})` : runs}` : null;\n const notes = [\n ...(o.references ?? []).map((r) => referenceNote(r, (v) => format(v))),\n ...(forecastNote ? [forecastNote] : []),\n ];\n\n const names = series.map((s) => s.label);\n const span = o.over === \"scale\" && cats.length > 1 ? ` from ${cats[0]} to ${cats[last]}` : cats.length === 1 ? ` for ${cats[0]}` : ` across ${cats.length} categories`;\n const sentences = [`${o.kind}: ${listOf(names)}${span}.`];\n // each series is told by its measured values; where a forecast runs is said apart, by its note (charts-2)\n const measured = forecastFrom > 0 ? forecastFrom : data.length;\n for (const s of series.slice(0, SUMMED)) {\n const points = data.slice(0, measured)\n .map((row, i) => ({ cat: cats[i], value: numberOf(row[s.dataKey]) }))\n .filter((p): p is { cat: string; value: number } => p.value !== null);\n const said = seriesSentence(s.label, points, o.over, (v) => format(v, s.dataKey));\n if (said) sentences.push(said);\n }\n if (series.length > SUMMED) sentences.push(`And ${series.length - SUMMED} more series.`);\n for (const note of notes) sentences.push(`${note}.`);\n return {\n table: { columns: [o.categoryHeading || \"Category\", ...names], numeric: [false, ...series.map(() => true)], rows, notes },\n description: sentences.join(\" \"),\n };\n}\n\n/** A whole and its parts: a pie's slices, a radial chart's bars, a funnel's stages or a treemap's tiles. */\nexport function partsAccess(o: {\n kind: \"pie\" | \"radial\" | \"funnel\" | \"treemap\";\n items: Array<{ name: string; value: number; group?: string; max?: number }>;\n format: ChartFormat;\n}): ChartAccess {\n const items = o.items\n .map((p) => ({ ...p, value: numberOf(p.value), max: numberOf(p.max) }))\n .filter((p): p is typeof p & { value: number } => p.value !== null);\n const f = (v: number) => o.format(v);\n const total = items.reduce((sum, p) => sum + Math.max(0, p.value), 0);\n const largest = items.reduce<(typeof items)[number] | null>((a, b) => (!a || b.value > a.value ? b : a), null);\n const smallest = items.reduce<(typeof items)[number] | null>((a, b) => (!a || b.value < a.value ? b : a), null);\n const grouped = o.kind === \"treemap\" && items.some((p) => p.group);\n const withMax = o.kind === \"radial\" && items.some((p) => p.max !== null);\n\n if (o.kind === \"funnel\") {\n const first = items[0], last = items[items.length - 1];\n return {\n table: {\n columns: [\"Stage\", \"Value\", \"Of the first stage\"],\n numeric: [false, true, true],\n rows: items.map((p) => [p.name, f(p.value), first && first.value > 0 ? percent(p.value, first.value) : \"–\"]),\n notes: [],\n },\n // a first stage of nothing has no share to carry through\n description: first && last && items.length > 1\n ? `Funnel of ${items.length} stages, from ${first.name} (${f(first.value)}) to ${last.name} (${f(last.value)})${first.value > 0 ? `: ${percent(last.value, first.value)} of the first stage reach the last` : \"\"}.`\n : `Funnel of ${items.length} ${items.length === 1 ? \"stage\" : \"stages\"}.`,\n };\n }\n const columns = [...(grouped ? [\"Group\"] : []), \"Name\", \"Value\", ...(withMax ? [\"Of its maximum\"] : o.kind === \"radial\" ? [] : [\"Share\"])];\n const rows = items.map((p) => [\n ...(grouped ? [p.group ?? \"\"] : []),\n p.name,\n f(p.value),\n ...(withMax ? [p.max !== null ? percent(p.value, p.max) : \"–\"] : o.kind === \"radial\" ? [] : [percent(p.value, total)]),\n ]);\n const what = o.kind === \"pie\" ? \"Pie chart\" : o.kind === \"radial\" ? \"Radial bar chart\" : \"Treemap\";\n const unit = o.kind === \"pie\" ? \"parts\" : o.kind === \"radial\" ? \"bars\" : \"items\";\n let description = `${what} of ${items.length} ${items.length === 1 ? unit.replace(/s$/, \"\") : unit}`;\n const groups = new Set(items.map((p) => p.group)).size;\n if (grouped) description += ` in ${groups} ${groups === 1 ? \"group\" : \"groups\"}`;\n if (largest && smallest && items.length > 1) {\n description += o.kind === \"radial\"\n ? `: ${largest.name} the highest (${f(largest.value)}), ${smallest.name} the lowest (${f(smallest.value)}).`\n : `: ${largest.name} the largest (${f(largest.value)}, ${percent(largest.value, total)}), ${smallest.name} the smallest (${f(smallest.value)}, ${percent(smallest.value, total)}).`;\n } else {\n description += \".\";\n }\n return {\n table: { columns, numeric: columns.map((c) => c !== \"Group\" && c !== \"Name\"), rows, notes: [], rowHeader: grouped ? 1 : 0 },\n description,\n };\n}\n\n/** Points in series over two values (a scatter chart), with a third as each point's size. */\nexport function pointsAccess(o: {\n series: Array<{ name: string; points: Array<{ x: unknown; y: unknown; z?: unknown }> }>;\n xHeading: string;\n yHeading: string;\n zHeading?: string;\n formatX: ChartFormat;\n formatY: ChartFormat;\n}): ChartAccess {\n const withZ = !!o.zHeading && o.series.some((s) => s.points.some((p) => numberOf(p.z) !== null));\n const rows: string[][] = [];\n const xs: number[] = [];\n const ys: number[] = [];\n for (const s of o.series) {\n for (const p of s.points) {\n const x = numberOf(p.x), y = numberOf(p.y), z = numberOf(p.z);\n if (x === null || y === null) continue;\n xs.push(x);\n ys.push(y);\n rows.push([s.name, o.formatX(x), o.formatY(y), ...(withZ ? [z !== null ? String(z) : \"–\"] : [])]);\n }\n }\n const range = (vs: number[], fmt: ChartFormat) => (vs.length ? `from ${fmt(Math.min(...vs))} to ${fmt(Math.max(...vs))}` : \"\");\n return {\n table: {\n columns: [\"Series\", o.xHeading, o.yHeading, ...(withZ ? [o.zHeading!] : [])],\n numeric: [false, true, true, ...(withZ ? [true] : [])],\n rows,\n notes: [],\n },\n description: `Scatter chart of ${rows.length} ${rows.length === 1 ? \"point\" : \"points\"} in ${o.series.length} ${o.series.length === 1 ? \"series\" : \"series\"}${xs.length ? `: ${o.xHeading} ${range(xs, o.formatX)}, ${o.yHeading} ${range(ys, o.formatY)}` : \"\"}.`,\n };\n}\n\n/** Flows between points (a Sankey chart). */\nexport function flowAccess(o: { nodes: Array<{ name: string }>; links: Array<{ source: number; target: number; value: number }>; undrawn?: ReadonlyArray<{ source: number; target: number; value: number }>; format: ChartFormat }): ChartAccess {\n const name = (i: number) => o.nodes[i]?.name ?? String(i);\n // a flow that runs back isn't drawn (SankeyChart's oneWayFlows): the table lists it, and says so; the sentence's largest\n // flow is one the chart draws\n const undrawn = new Set(o.undrawn ?? []);\n const links = o.links\n .map((l) => ({ ...l, value: numberOf(l.value), drawn: !undrawn.has(l) }))\n .filter((l): l is typeof l & { value: number } => l.value !== null);\n const largest = links.filter((l) => l.drawn).reduce<(typeof links)[number] | null>((a, b) => (!a || b.value > a.value ? b : a), null);\n const back = links.filter((l) => !l.drawn);\n const backSaid = back.length === 1\n ? ` The flow from ${name(back[0].source)} to ${name(back[0].target)} runs back, so it isn't drawn.`\n : back.length > 1 ? ` ${back.length} flows that run back aren't drawn.` : \"\";\n return {\n table: {\n columns: [\"From\", \"To\", \"Value\"],\n numeric: [false, false, true],\n rows: links.map((l) => [name(l.source), name(l.target), o.format(l.value)]),\n notes: back.map((l) => `Not drawn, as it runs back: ${name(l.source)} to ${name(l.target)} (${o.format(l.value)})`),\n },\n description: `Flow chart of ${links.length} ${links.length === 1 ? \"flow\" : \"flows\"} between ${o.nodes.length} ${o.nodes.length === 1 ? \"point\" : \"points\"}${largest ? `: the largest from ${name(largest.source)} to ${name(largest.target)} (${o.format(largest.value)})` : \"\"}.${backSaid}`,\n };\n}\n","import { createContext, useCallback, useMemo, useRef, useState, type ReactNode } from \"react\";\n\n/*\n * A chart's names in its plot, placed together (Sprint 25.8.9, the review of 16 October). Apart from the references'\n * drawing (chart-references.tsx), so ChartWrapper, which the core entry's ChartContainer reads, holds them without\n * Recharts, which an app without charts doesn't install.\n */\n\n/** A name drawn in the plot, as placed before any move: its box, its turn, and the way it moves to give room. */\nexport interface NameBox {\n x: number; y: number; width: number; height: number; order: number; away: 1 | -1;\n /** The plot's top and bottom: a name moves within them, the other way where its own way would leave them. */\n bounds?: { top: number; bottom: number };\n}\nconst GAP = 2;\nconst overlaps = (a: NameBox, b: NameBox) => a.x < b.x + b.width && b.x < a.x + a.width && a.y < b.y + b.height && b.y < a.y + a.height;\n\n/**\n * Where each of a plot's names goes (Sprint 25.8.9, the review of 16 October): each name is placed by its own reference,\n * so a target's at the top of the axis and a one-period forecast's printed one over the other. In turn (the references\n * as the page gave them, then the forecast's), each moves away from the edge it's set against, past any name placed\n * before it that it would cover. Returns each name's move, px.\n */\nexport function placeNames(names: ReadonlyArray<readonly [string, NameBox]>): Map<string, number> {\n const placed: NameBox[] = [];\n const moves = new Map<string, number>();\n for (const [id, box] of [...names].sort((a, b) => a[1].order - b[1].order)) {\n // past every name placed before it that it would cover, one way\n const clear = (away: 1 | -1) => {\n let dy = 0;\n for (let tries = 0; tries <= placed.length; tries++) {\n const hit = placed.find((p) => overlaps({ ...box, y: box.y + dy }, p));\n if (!hit) break;\n dy = away > 0 ? hit.y + hit.height + GAP - box.y : hit.y - GAP - box.height - box.y;\n }\n return dy;\n };\n const inside = (dy: number) => !box.bounds || (box.y + dy >= box.bounds.top - 0.5 && box.y + dy + box.height <= box.bounds.bottom + 0.5);\n let dy = clear(box.away);\n if (!inside(dy)) {\n const other = clear(box.away > 0 ? -1 : 1);\n if (inside(other)) dy = other;\n }\n moves.set(id, dy);\n placed.push({ ...box, y: box.y + dy });\n }\n return moves;\n}\n\ninterface PlotNamesValue { place(id: string, box: NameBox | null): void; moves: ReadonlyMap<string, number> }\nexport const PlotNamesContext = createContext<PlotNamesValue | null>(null);\n\n/** A chart's names in its plot, placed together (placeNames): each ChartWrapper holds one. */\nexport function PlotNames({ children }: { children: ReactNode }) {\n const boxes = useRef(new Map<string, NameBox>());\n const [moves, setMoves] = useState<ReadonlyMap<string, number>>(() => new Map());\n const place = useCallback((id: string, box: NameBox | null) => {\n if (box) boxes.current.set(id, box);\n else boxes.current.delete(id);\n const next = placeNames([...boxes.current]);\n setMoves((prev) => (prev.size === next.size && [...next].every(([k, v]) => prev.get(k) === v) ? prev : next));\n }, []);\n const value = useMemo(() => ({ place, moves }), [place, moves]);\n return <PlotNamesContext.Provider value={value}>{children}</PlotNamesContext.Provider>;\n}\n","import { Symbols } from \"recharts\";\nimport { CHART_COLOR_COUNT, useResolvedToken } from \"../../lib/chart-utils\";\n\n/**\n * How a chart's series differ besides their colour (Sprint 25.8.9 item 4, WCAG 1.4.1, charts-6). With two series or\n * more, each after the first draws with a mark of its own, which the legend and the tooltip draw too:\n * - a line, an area's outline or a radar's shape: a dash;\n * - a bar: a pattern over its colour, in the surface's colour, so it reads on any colour;\n * - a scatter series: its points' shape.\n * A chart of one series needs none: its colour names nothing.\n */\nexport type SeriesMark =\n | { kind: \"line\"; color: string; dash?: string }\n | { kind: \"fill\"; color: string; edge?: string; pattern?: string }\n | { kind: \"symbol\"; color: string; symbol: SeriesSymbol };\n\n/**\n * A series' mark, by its place among the chart's series: its place in the palette's round, moved on by one each time the\n * palette comes round, so a series past the palette's length (its colour taken again) never takes the mark of the series\n * whose colour it shares. Every series has its own colour and mark together up to 36 series.\n */\nfunction markOf(index: number, marks: number): number {\n return (index + Math.floor(index / CHART_COLOR_COUNT)) % marks;\n}\n\n/** A line's dash, by its place among the chart's series: the first solid. */\nconst DASHES = [undefined, \"6 3\", \"2 3\", \"8 3 2 3\", \"12 3 3 3\", \"1 4\"] as const;\nexport function seriesDash(index: number, count: number): string | undefined {\n return count >= 2 ? DASHES[markOf(index, DASHES.length)] : undefined;\n}\n\n/**\n * The dashes of a chart's lines (LineChart's and CompositeChart's), each line's own: by its place, as seriesDash gives\n * them, except that a line the page marks `dashed` is never solid. No two lines draw the same, their colour and dash\n * together (the palette comes round after six). A dashed line that would be solid takes a dash no other line has; else\n * it trades with a line the page didn't mark, where neither then draws the same as a line of its colour; else it takes\n * a dash no line of its colour has (with more dashed lines than dashes, two may share a dash in different colours).\n */\nexport function lineDashes(lines: ReadonlyArray<{ dashed?: boolean }>): Array<string | undefined> {\n const marks = lines.map((line, i) => (lines.length >= 2 ? markOf(i, DASHES.length) : line.dashed ? 1 : 0));\n const colour = (i: number) => i % CHART_COLOR_COUNT;\n // whether a line other than `but` draws dash `k` in line `i`'s colour\n const inColour = (i: number, k: number, ...but: number[]) => marks.some((m, j) => m === k && colour(j) === colour(i) && j !== i && !but.includes(j));\n lines.forEach((line, i) => {\n if (!line.dashed || marks[i] !== 0) return;\n const free = DASHES.findIndex((_, k) => k > 0 && !marks.includes(k));\n if (free > 0) { marks[i] = free; return; }\n const trade = lines.findIndex((other, j) => j !== i && !other.dashed && marks[j] !== 0 && !inColour(i, marks[j], j) && !inColour(j, 0, i));\n if (trade >= 0) { [marks[i], marks[trade]] = [marks[trade], 0]; return; }\n const own = DASHES.findIndex((_, k) => k > 0 && !inColour(i, k));\n marks[i] = own > 0 ? own : 1;\n });\n return marks.map((k) => DASHES[k]);\n}\n\nexport type SeriesSymbol = \"circle\" | \"square\" | \"triangle\" | \"diamond\" | \"cross\" | \"star\" | \"wye\";\nconst SYMBOLS: SeriesSymbol[] = [\"circle\", \"square\", \"triangle\", \"diamond\", \"cross\", \"star\", \"wye\"];\n// seven symbols for six colours: a series past the palette already takes a symbol its colour's first series hasn't\nexport function seriesSymbol(index: number, count: number): SeriesSymbol {\n return count >= 2 ? SYMBOLS[index % SYMBOLS.length] : \"circle\";\n}\n\n/** How many patterns there are after the first, solid, series. */\nconst PATTERNS = 5;\n/** Which of the patterns a bar series fills with (0 to 4: stripes, dots, a cross-hatch, rows, columns), else none. */\nexport function seriesPatternKind(index: number, count: number): number | undefined {\n const mark = markOf(index, PATTERNS + 1);\n return count < 2 || mark === 0 ? undefined : mark - 1;\n}\n/** A bar series' pattern id in this chart, or none: the first series is solid, as is a chart of one series. */\nexport function seriesPattern(chartId: string, index: number, count: number): string | undefined {\n if (seriesPatternKind(index, count) === undefined) return undefined;\n return `${chartId.replace(/[^a-zA-Z0-9_-]/g, \"\")}-series-${index}`;\n}\n/** The same series' pattern for its forecast's bars: the fainter fill, its marks chosen against it (aheadFill). */\nexport const aheadPattern = (id: string) => `${id}-ahead`;\n\n/** A colour as 8-bit sRGB channels, as the browser draws it. */\ntype Rgb = readonly [number, number, number];\n\n/** #rgb, #rgba, #rrggbb, #rrggbbaa, rgb() and rgba() read without a browser (the server, tests); else null. */\nfunction parseRgba(colour: string): [number, number, number, number] | null {\n const c = colour.trim();\n const hex = /^#([0-9a-f]{3,4}|[0-9a-f]{6}|[0-9a-f]{8})$/i.exec(c)?.[1];\n if (hex) {\n const full = hex.length <= 4 ? [...hex].map((h) => h + h).join(\"\") : hex;\n const n = (k: number) => parseInt(full.slice(k * 2, k * 2 + 2), 16);\n return [n(0), n(1), n(2), full.length === 8 ? n(3) / 255 : 1];\n }\n const fn = /^rgba?\\(\\s*([\\d.]+)[\\s,]+([\\d.]+)[\\s,]+([\\d.]+)(?:\\s*[,/]\\s*([\\d.]+%?))?\\s*\\)$/i.exec(c);\n if (!fn) return null;\n const alpha = fn[4] === undefined ? 1 : fn[4].endsWith(\"%\") ? parseFloat(fn[4]) / 100 : parseFloat(fn[4]);\n return [Number(fn[1]), Number(fn[2]), Number(fn[3]), alpha];\n}\n\nlet probe: CanvasRenderingContext2D | null | undefined;\nconst drawnColours = new Map<string, Rgb | null>();\n// a colour no theme writes: a canvas keeps its last fill for a colour it can't read, so a fill still this one wasn't read\nconst UNREAD = \"rgba(1, 2, 3, 0.5)\";\n/**\n * `colour` as the browser draws it over an opaque `ground`: parsed when it's hex or rgb(), else drawn on a one-pixel\n * canvas, which reads any colour the page can (a theme's oklch() or color-mix()); null where neither can read it.\n */\nfunction drawn(colour: string, ground: Rgb = [255, 255, 255]): Rgb | null {\n const key = `${colour}|${ground.join(\",\")}`;\n if (drawnColours.has(key)) return drawnColours.get(key)!;\n let out: Rgb | null = null;\n const parsed = parseRgba(colour);\n if (parsed) {\n const [r, g, b, a] = parsed;\n out = [r, g, b].map((v, i) => Math.round(v * a + ground[i] * (1 - a))) as unknown as Rgb;\n } else {\n if (probe === undefined) {\n try {\n probe = typeof document === \"undefined\" || /jsdom/i.test(navigator.userAgent) ? null : document.createElement(\"canvas\").getContext(\"2d\", { willReadFrequently: true });\n } catch {\n probe = null;\n }\n }\n if (probe) {\n probe.fillStyle = UNREAD;\n const unread = probe.fillStyle;\n probe.fillStyle = colour;\n if (probe.fillStyle !== unread) {\n probe.fillStyle = `rgb(${ground.join(\",\")})`;\n probe.fillRect(0, 0, 1, 1);\n probe.fillStyle = colour;\n probe.fillRect(0, 0, 1, 1);\n const d = probe.getImageData(0, 0, 1, 1).data;\n out = [d[0], d[1], d[2]];\n }\n }\n }\n drawnColours.set(key, out);\n return out;\n}\n\nconst channel = (c: number) => (c / 255 <= 0.04045 ? c / 255 / 12.92 : ((c / 255 + 0.055) / 1.055) ** 2.4);\nconst luminance = ([r, g, b]: Rgb) => 0.2126 * channel(r) + 0.7152 * channel(g) + 0.0722 * channel(b);\n/** WCAG's contrast between two opaque colours. */\nexport function contrast(a: Rgb, b: Rgb): number {\n const [hi, lo] = [luminance(a), luminance(b)].sort((x, y) => y - x);\n return (hi + 0.05) / (lo + 0.05);\n}\nconst css = (c: Rgb) => `rgb(${c.join(\" \")})`;\n\n/**\n * The ground a chart draws on, as one opaque colour: the surface laid over the page's canvas, the canvas over white\n * where it's see-through too, as the theme's own colours are worked out (a glass card is the page's colour showing\n * through it, never white). Null where a colour can't be read.\n */\nexport function chartGround(surface: string, canvas: string): Rgb | null {\n const page = drawn(canvas);\n return page && drawn(surface, page);\n}\n\n/** The ground as one CSS colour (chartGround), else the surface as written: a name's halo in the plot (PlotName). */\nexport function groundColour(surface: string, canvas: string): string {\n const ground = chartGround(surface, canvas);\n return ground ? css(ground) : surface;\n}\n\n/**\n * A pattern's mark colour over `fill` (Sprint 25.8.9 item 4): the ground's or the text's, whichever stands out more from\n * the fill as it's drawn on the ground, so the mark reads at 3:1 and more on any series colour, soft or solid, light or\n * dark (WCAG 1.4.11: a light mark disappears into a soft tint). Where neither reaches 3:1 (a theme whose text and\n * surface are both mid-tones), black or white, whichever stands out more: one of them always reaches 4.5:1. The surface's\n * when the colours can't be read.\n */\nexport function markInk(fill: string, surface: string, ink: string, canvas: string): string {\n const ground = chartGround(surface, canvas);\n const filled = ground && drawn(fill, ground);\n const text = ground && drawn(ink, ground);\n if (!ground || !filled || !text) return surface;\n const theme = contrast(filled, text) >= contrast(filled, ground) ? text : ground;\n if (contrast(filled, theme) >= 3) return css(theme);\n return css(contrast(filled, [0, 0, 0]) >= contrast(filled, [255, 255, 255]) ? [0, 0, 0] : [255, 255, 255]);\n}\n\n/** How strong a forecast's bar is drawn against the ground (Sprint 25.8.9 item 26). */\nexport const AHEAD_STRENGTH = 0.45;\n/**\n * A forecast bar's fill (Sprint 25.8.9 item 26): its series' colour at AHEAD_STRENGTH over the ground, as one opaque\n * colour, so a pattern's marks are chosen against the fill as drawn (markInk), and the forecast's hatch behind doesn't\n * show through as a second pattern. Null where a colour can't be read (the bar is then drawn see-through).\n */\nexport function aheadFill(colour: string, surface: string, canvas: string): string | null {\n const ground = chartGround(surface, canvas);\n const own = ground && drawn(colour, ground);\n if (!ground || !own) return null;\n return css(own.map((v, i) => Math.round(v * AHEAD_STRENGTH + ground[i] * (1 - AHEAD_STRENGTH))) as unknown as Rgb);\n}\n\n/** One pattern: `fill` with the kind's mark over it in `on`. */\nfunction Pattern({ id, kind, fill, on }: { id: string; kind: number; fill: string; on: string }) {\n const mark = { stroke: on, strokeWidth: 1.5 } as const;\n return (\n <pattern id={id} width={6} height={6} patternUnits=\"userSpaceOnUse\">\n <rect width={6} height={6} fill={fill} />\n {kind === 0 && <path d=\"M-1,1 l2,-2 M0,6 l6,-6 M5,7 l2,-2\" {...mark} />}\n {kind === 1 && <circle cx={3} cy={3} r={1.3} fill={on} />}\n {kind === 2 && <path d=\"M-1,1 l2,-2 M0,6 l6,-6 M5,7 l2,-2 M-1,5 l2,2 M0,0 l6,6 M5,-1 l2,2\" {...mark} strokeWidth={1} />}\n {kind === 3 && <path d=\"M0,3 h6\" {...mark} />}\n {kind === 4 && <path d=\"M3,0 v6\" {...mark} />}\n </pattern>\n );\n}\n\n/**\n * The patterns a chart's bar series fill with, for its `<defs>` (inside the chart's own SVG; the legend's swatches use\n * the same ids, which an SVG anywhere on the page can). Each is the series' colour with a mark over it, in the ground's\n * colour or the text's, whichever reads against that colour (markInk): stripes, dots, a cross-hatch, rows, columns. With\n * `ahead` (a chart with a forecast), each has a second, for the forecast's bars: the fainter fill (aheadFill), its mark\n * chosen against that fill, so it reads at 3:1 there too.\n */\nexport function SeriesPatterns({ chartId, colors, surface, ahead = false }: { chartId: string; colors: string[]; surface: string; ahead?: boolean }) {\n const ink = useResolvedToken(\"--ds-text-primary\");\n const canvas = useResolvedToken(\"--ds-bg-canvas\");\n if (colors.length < 2) return null;\n return (\n <defs>\n {colors.map((color, i) => {\n const id = seriesPattern(chartId, i, colors.length);\n const kind = seriesPatternKind(i, colors.length);\n if (!id || kind === undefined) return null;\n const faint = ahead ? aheadFill(color, surface, canvas) : null;\n return [\n <Pattern key={id} id={id} kind={kind} fill={color} on={markInk(color, surface, ink, canvas)} />,\n faint && <Pattern key={aheadPattern(id)} id={aheadPattern(id)} kind={kind} fill={faint} on={markInk(faint, surface, ink, canvas)} />,\n ];\n })}\n </defs>\n );\n}\n\n/** A series' swatch in the legend and the tooltip: its colour with its mark, as the chart draws it. */\nexport function SeriesSwatch({ mark, color }: { mark?: SeriesMark; color: string }) {\n if (mark?.kind === \"line\") {\n return (\n <svg width={18} height={10} aria-hidden=\"true\" className=\"shrink-0\">\n <line x1={1} y1={5} x2={17} y2={5} stroke={mark.color} strokeWidth={2.5} strokeDasharray={mark.dash} strokeLinecap=\"butt\" />\n </svg>\n );\n }\n if (mark?.kind === \"symbol\") {\n return (\n <svg width={12} height={12} aria-hidden=\"true\" className=\"shrink-0\">\n <Symbols cx={6} cy={6} size={60} type={mark.symbol} fill={mark.color} />\n </svg>\n );\n }\n const fill = mark?.kind === \"fill\" && mark.pattern ? `url(#${mark.pattern})` : (mark?.color ?? color);\n return (\n <svg width={12} height={12} aria-hidden=\"true\" className=\"shrink-0\">\n <rect x={0.75} y={0.75} width={10.5} height={10.5} rx={2.5} fill={fill} stroke={(mark?.kind === \"fill\" && mark.edge) || mark?.color || color} strokeWidth={1.5} />\n </svg>\n );\n}\n","import { useContext, useLayoutEffect, useMemo, useRef, useState, type ReactNode } from \"react\";\nimport { DefaultZIndexes, ReferenceArea, ReferenceLine, ZIndexLayer, usePlotArea } from \"recharts\";\nimport { useResolvedToken } from \"../../lib/chart-utils\";\nimport type { ChartReference } from \"./chart-access\";\nimport { PlotNamesContext } from \"./plot-names\";\nimport { groundColour } from \"./series-marks\";\n\nconst isNumber = (v: unknown): v is number => typeof v === \"number\" && Number.isFinite(v);\n\ntype Place = \"insideTopLeft\" | \"insideTopRight\" | \"insideBottomRight\";\n\n/** Recharts' label offset: how far a name sits from its line or its band's edge. */\nconst OFFSET = 5;\n\n/**\n * One name in the plot, where Recharts' label puts it (`x`, `y` from its `position`), drawn over the series, and moved\n * as PlotNames places it. Its box is measured as drawn where the browser can (getBBox), else reckoned from its words.\n * - It's drawn in a halo of the chart's ground, so it reads at 4.5:1 wherever it lands, over a bar or a line (the third\n * review of 16 October measured the secondary text on the series' colours at 1.1–2.2:1).\n * - A line's name that would leave the plot goes to the line's other side: above a line at the value axis's low end,\n * and right of a sideways line near its start, where it printed over the axis's labels.\n */\nfunction PlotName({ x = 0, y = 0, viewBox, value, id, order, place, ink }: { x?: number; y?: number; viewBox?: { x?: number; y?: number; width?: number; height?: number }; value?: ReactNode; id: string; order: number; place: Place; ink: string }) {\n const names = useContext(PlotNamesContext);\n const plot = usePlotArea();\n const surface = useResolvedToken(\"--ds-bg-surface\");\n const canvas = useResolvedToken(\"--ds-bg-canvas\");\n const halo = useMemo(() => groundColour(surface, canvas), [surface, canvas]);\n const text = useRef<SVGTextElement>(null);\n const words = String(value ?? \"\");\n // its size as drawn (its words' alone: where it's put doesn't change it)\n const [size, setSize] = useState<{ width: number; height: number } | null>(null);\n useLayoutEffect(() => {\n const drawn = text.current && typeof text.current.getBBox === \"function\" ? text.current.getBBox() : null;\n const next = drawn && drawn.width > 0 ? { width: drawn.width, height: drawn.height } : { width: words.length * 7, height: 14 };\n setSize((prev) => (prev && prev.width === next.width && prev.height === next.height ? prev : next));\n }, [words]);\n const line = { across: viewBox?.height === 0 && (viewBox?.width ?? 0) > 0, up: viewBox?.width === 0 && (viewBox?.height ?? 0) > 0 };\n const top = place !== \"insideBottomRight\";\n const flip = !!size && !!plot && (\n (line.across && top && y + size.height > plot.y + plot.height + 0.5) ||\n (line.up && x - size.width < plot.x - 0.5)\n );\n const placed = flip && line.across ? { x, y: (viewBox?.y ?? 0) - OFFSET, top: false, start: false }\n : flip && line.up ? { x: (viewBox?.x ?? 0) + OFFSET, y, top: false, start: true }\n : { x, y, top, start: place === \"insideTopLeft\" };\n // and inside the plot on both axes: a band at the axis's start or foot, narrower than its name, put the name over the\n // axis's labels (the final review of 16 October). A name wider than the plot keeps to its start.\n const inside = (from: number, length: number, edge: number, span: number) =>\n from < edge ? edge - from : from + length > edge + span ? Math.max(edge - from, edge + span - (from + length)) : 0;\n const at = size && plot\n ? {\n ...placed,\n x: placed.x + inside(placed.start ? placed.x : placed.x - size.width, size.width, plot.x, plot.width),\n y: placed.y + inside(placed.top ? placed.y : placed.y - size.height, size.height, plot.y, plot.height),\n }\n : placed;\n const register = names?.place;\n const bounds = plot ? { top: plot.y, bottom: plot.y + plot.height } : undefined;\n useLayoutEffect(() => {\n if (!register || !size) return;\n register(id, { x: at.start ? at.x : at.x - size.width, y: at.top ? at.y : at.y - size.height, ...size, order, away: at.top ? 1 : -1, ...(bounds ? { bounds } : {}) });\n return () => register(id, null);\n }, [register, id, at.x, at.y, at.top, at.start, size, order, bounds?.top, bounds?.bottom]); // eslint-disable-line react-hooks/exhaustive-deps\n const move = names?.moves.get(id) ?? 0;\n return (\n <ZIndexLayer zIndex={DefaultZIndexes.label}>\n <g transform={move ? `translate(0 ${move})` : undefined}>\n <text\n ref={text}\n className=\"recharts-label\"\n data-plot-name=\"\"\n x={at.x}\n y={at.y}\n dy={at.top ? \"0.71em\" : undefined}\n textAnchor={at.start ? \"start\" : \"end\"}\n fill={ink}\n stroke={halo}\n strokeWidth={3}\n strokeLinejoin=\"round\"\n paintOrder=\"stroke\"\n style={{ fontSize: \"var(--ds-font-size-xs)\", fontFamily: \"var(--ds-font-sans)\" }}\n >\n {words}\n </text>\n </g>\n </ZIndexLayer>\n );\n}\n\n/** A reference's or the forecast's label: its words at `position`, drawn by PlotName. */\nconst nameLabel = (value: string, position: Place, id: string, order: number, ink: string) => ({\n value,\n position,\n content: <PlotName id={id} order={order} place={position} ink={ink} />,\n});\n\ninterface Look {\n /** The value axis: \"y\" upright, \"x\" for a chart turned sideways. */\n axis: \"x\" | \"y\";\n /** The value axis's id, in a chart with two (CompositeChart's bars' \"left\"). */\n axisId?: string | number;\n /** The line's and the label's colour (the secondary text's: 3:1 and more on the surface). */\n ink: string;\n format: (value: number) => string;\n}\n\n/** The value axis's id as recharts takes it: on the y axis upright, on the x axis sideways. */\nconst onAxis = (look: Pick<Look, \"axis\" | \"axisId\">) =>\n look.axisId === undefined ? {} : look.axis === \"y\" ? { yAxisId: look.axisId } : { xAxisId: look.axisId };\n\n/**\n * A chart's reference lines and bands (Sprint 25.8.9 item 25, charts-1): a target or a limit as a dashed line, a range as\n * a band, each named beside it, and the value axis grown to show them (`extendDomain`). Recharts 3 finds them through\n * its context, so they may come from here.\n */\nexport function referenceElements(refs: ChartReference[] | undefined, look: Look) {\n return (refs ?? []).map((r, i) => {\n const axisProps = onAxis(look);\n if (isNumber(r.to)) {\n const span = look.axis === \"y\" ? { y1: Math.min(r.value, r.to), y2: Math.max(r.value, r.to) } : { x1: Math.min(r.value, r.to), x2: Math.max(r.value, r.to) };\n return (\n <ReferenceArea\n key={`reference-${i}`}\n {...span}\n {...axisProps}\n fill={look.ink}\n fillOpacity={0.1}\n stroke=\"none\"\n ifOverflow=\"extendDomain\"\n label={nameLabel(r.label, look.axis === \"y\" ? \"insideTopLeft\" : \"insideTopRight\", `reference-${i}`, i, look.ink)}\n />\n );\n }\n return (\n <ReferenceLine\n key={`reference-${i}`}\n {...(look.axis === \"y\" ? { y: r.value } : { x: r.value })}\n {...axisProps}\n stroke={look.ink}\n strokeDasharray=\"4 3\"\n strokeWidth={1.5}\n ifOverflow=\"extendDomain\"\n label={nameLabel(`${r.label}: ${look.format(r.value)}`, look.axis === \"y\" ? \"insideTopRight\" : \"insideBottomRight\", `reference-${i}`, i, look.ink)}\n />\n );\n });\n}\n\n/** The values a reference reaches, for the value axis's width (its labels are measured from the values it shows). */\nexport function referenceValues(refs: ChartReference[] | undefined): number[] {\n return (refs ?? []).flatMap((r) => (isNumber(r.to) ? [r.value, r.to] : [r.value]));\n}\n\n/**\n * Where a forecast starts (Sprint 25.8.9 item 26, charts-2): the first row whose category is `from`, else -1. A page\n * marks a period not yet over the same way, with its own words (\"So far this month\").\n */\nexport function forecastIndex(data: Record<string, unknown>[], categoryKey: string, from: unknown): number {\n if (from === undefined || from === null) return -1;\n return data.findIndex((row) => row[categoryKey] === from || String(row[categoryKey]) === String(from));\n}\n\n/** A forecast's hatch's id in this chart. */\nexport const forecastHatchId = (chartId: string) => `${chartId.replace(/[^a-zA-Z0-9_-]/g, \"\")}-forecast`;\n\n/** The hatch a forecast's band fills with, for the chart's `<defs>`: thin diagonal lines in the secondary text's colour, pale. */\nexport function ForecastHatch({ id, ink }: { id: string; ink: string }) {\n return (\n <defs>\n <pattern id={id} width={6} height={6} patternUnits=\"userSpaceOnUse\" patternTransform=\"rotate(45)\">\n <line x1={0} y1={0} x2={0} y2={6} stroke={ink} strokeWidth={1.5} strokeOpacity={0.25} />\n </pattern>\n </defs>\n );\n}\n\n/**\n * Where a forecast runs (Sprint 25.8.9 item 26, charts-2), as the rule's \"hatched band\": a pale hatched band from where it\n * starts to the chart's end, named at its top by the page's words (\"Forecast\", \"So far this month\"), after a dashed line\n * where it starts. The series keep their own colour and mark through it, so a forecast is never told by a colour or a\n * fainter line. The name sits by the line where the band starts, clear of a rising line's end; on a band too narrow for\n * it (one period at the end, \"So far this month\") at the chart's end, inside it. On a chart of points (lines, areas)\n * the band starts at the last measured point, where the line runs on into the forecast; on a chart of bands (bars) at\n * the first forecast bar's edge.\n */\nexport function forecastElements(categories: unknown[], from: number, label: string, look: { axis: \"x\" | \"y\"; axisId?: string | number; ink: string; scale: \"point\" | \"band\"; hatch: string }) {\n // a chart of one point has no width to mark: its sentence and its table say it's a forecast\n if (from < 0 || from >= categories.length || (look.scale === \"point\" && categories.length < 2)) return [];\n const start = look.scale === \"point\" ? Math.max(0, from - 1) : from;\n const first = categories[start] as string | number, last = categories[categories.length - 1] as string | number;\n // the band's share of the category axis: a quarter or more holds its name beside its start line\n const span = look.scale === \"point\" ? (categories.length - 1 - start) / Math.max(1, categories.length - 1) : (categories.length - start) / categories.length;\n const wide = span >= 0.25;\n const elements = [\n <ReferenceArea\n key=\"forecast\"\n {...(look.axis === \"y\" ? { x1: first, x2: last } : { y1: first, y2: last })}\n {...onAxis(look)}\n fill={`url(#${look.hatch})`}\n stroke=\"none\"\n label={nameLabel(label, look.axis === \"y\" ? (wide ? \"insideTopLeft\" : \"insideTopRight\") : (wide ? \"insideTopRight\" : \"insideBottomRight\"), \"forecast\", Number.MAX_SAFE_INTEGER, look.ink)}\n />,\n ];\n if (from > 0) {\n elements.push(\n <ReferenceLine\n key=\"forecast-start\"\n {...(look.axis === \"y\" ? { x: first } : { y: first })}\n {...onAxis(look)}\n position={look.scale === \"band\" ? \"start\" : undefined}\n stroke={look.ink}\n strokeDasharray=\"2 3\"\n />,\n );\n }\n return elements;\n}\n","import { useState } from \"react\";\nimport { cn, FOCUS_INSET } from \"../../lib/utils\";\nimport { useKeyboardScroll } from \"../../lib/use-keyboard-scroll\";\nimport type { ChartTableModel } from \"./chart-access\";\n\n/**\n * A chart's values as a table (Sprint 25.8.9 item 27, charts-7): a real table, its first cell in each row a row header,\n * so a screen reader moves by row and column and reads each value with its category and series. It scrolls inside its\n * own frame, a Tab stop while it scrolls, and what the chart marks across its plot (its references, a forecast) follows\n * it as lines of text. In a ChartContainer's fixed area (a chart it doesn't size) the frame takes the room left and\n * scrolls within it, so the table never spills out of its card.\n */\nexport function ChartTable({ table, name, labelledBy }: { table: ChartTableModel; name: string; labelledBy?: string }) {\n const [frame, setFrame] = useState<HTMLDivElement | null>(null);\n useKeyboardScroll(frame, name, true, false, \"both\");\n return (\n <div data-chart-table=\"\" className=\"flex min-h-0 flex-1 flex-col gap-ds-2\">\n <div\n ref={setFrame}\n className={cn(\n \"min-h-0 max-h-[var(--ds-chart-height-lg)] overflow-auto rounded-[var(--ds-radius-md)]\",\n \"border-[length:var(--ds-border-width)] border-[var(--ds-border-subtle)]\",\n FOCUS_INSET,\n )}\n >\n <table className=\"w-full border-collapse text-sm\" aria-labelledby={labelledBy} aria-label={labelledBy ? undefined : name}>\n <thead className=\"bg-[var(--ds-bg-muted)]\">\n <tr>\n {table.columns.map((column, i) => (\n <th\n key={i}\n scope=\"col\"\n className={cn(\"px-ds-3 py-ds-2 text-xs font-semibold text-[var(--ds-text-secondary)] whitespace-nowrap\", table.numeric[i] ? \"text-right\" : \"text-left\")}\n >\n {column}\n </th>\n ))}\n </tr>\n </thead>\n <tbody>\n {table.rows.map((row, r) => (\n <tr key={r} className=\"border-t-[length:var(--ds-divider-width)] border-[var(--ds-border-subtle)]\">\n {row.map((cell, i) => (i === (table.rowHeader ?? 0) ? (\n <th key={i} scope=\"row\" className=\"px-ds-3 py-ds-2 text-left font-normal text-[var(--ds-text-primary)]\">{cell}</th>\n ) : (\n <td key={i} className={cn(\"px-ds-3 py-ds-2 text-[var(--ds-text-primary)]\", table.numeric[i] && \"text-right tabular-nums whitespace-nowrap\")}>{cell}</td>\n )))}\n </tr>\n ))}\n </tbody>\n </table>\n </div>\n {table.notes.length > 0 && (\n <ul data-chart-notes=\"\" className=\"text-xs text-[var(--ds-text-secondary)]\">\n {table.notes.map((note, i) => <li key={i}>{note}</li>)}\n </ul>\n )}\n </div>\n );\n}\n","import {\n Children, createContext, forwardRef, isValidElement, useContext, useEffect, useId, useLayoutEffect, useMemo, useRef, useState,\n type CSSProperties, type KeyboardEvent, type ReactNode, type Ref,\n} from \"react\";\nimport { createPortal } from \"react-dom\";\nimport { cn } from \"../../lib/utils\";\nimport { elementType } from \"../../lib/element-type\";\nimport { mergeRefs } from \"../../lib/slot\";\nimport { FormChangeCtx } from \"../../lib/form-context\";\nimport { SegmentedControl } from \"../SegmentedControl\";\nimport { ChartTable } from \"./ChartTable\";\nimport type { ChartAccess } from \"./chart-access\";\nimport { PlotNames } from \"./plot-names\";\nimport type { SeriesMark } from \"./series-marks\";\n\n/* ── Heights ────────────────────────────────────────────────────────────── */\n\n/** A chart's height: \"auto\" (the default) sizes it from its type and its data; a preset or a number overrides. */\nexport type ChartHeight = \"auto\" | \"sm\" | \"md\" | \"lg\" | number;\n\nexport const CHART_HEIGHTS = {\n sm: \"var(--ds-chart-height-sm)\",\n md: \"var(--ds-chart-height-md)\",\n lg: \"var(--ds-chart-height-lg)\",\n} as const;\n\n/** One row of a row chart (a sideways bar, a funnel stage). */\nexport const CHART_ROW = \"var(--ds-chart-row, 2rem)\";\n\n/** A preset or a number as a CSS height; \"auto\" has none (the chart sizes itself). */\nexport function fixedChartHeight(height: ChartHeight | undefined): string | undefined {\n if (typeof height === \"number\") return `${height}px`;\n if (height === \"sm\" || height === \"md\" || height === \"lg\") return CHART_HEIGHTS[height];\n return undefined;\n}\n\n/**\n * How a chart sizes itself (Sprint 25.9, A2, P2):\n * - \"rows\" (a sideways BarChart, a FunnelChart): a row per item, never under sm; `units` rows, `lines` extra label lines\n * (a two-line name makes its row one line taller), `axis` the value axis and titles below or above the rows;\n * - \"ratio\" (charts over dates or numbers, Treemap, Sankey): two wide to one high, between sm and lg;\n * - \"square\" (Pie, Radar, RadialBar): as tall as wide, between sm and lg.\n */\nexport type ChartSize =\n | { model: \"ratio\" }\n | { model: \"square\" }\n | { model: \"rows\"; units: number; lines?: number; axis?: string };\n\nconst SM = CHART_HEIGHTS.sm;\nconst LG = CHART_HEIGHTS.lg;\n\n/**\n * The plot box's height and its bound in a row. `cqi` resolves against the chart's wrapper, the size container, because\n * the plot box is its child (on the wrapper itself it would read the page's container). The box is `flex: 1 0 auto`,\n * never `flex-1`: its drawing is absolute, so a zero basis would collapse it (R5). In a row it grows to the row's\n * height up to a bound: a ratio chart to square, a row chart to twice its height, a round chart not at all.\n */\nexport function plotBoxStyle(size: ChartSize, fixed: string | undefined): CSSProperties {\n if (size.model === \"square\") {\n return { height: fixed ?? `clamp(${SM}, 100cqi, ${LG})`, flex: \"0 0 auto\" };\n }\n if (size.model === \"rows\") {\n const lines = size.lines ? ` + ${size.lines} * 1.25 * var(--ds-font-size-xs)` : \"\";\n const height = fixed ?? `max(${SM}, calc(${size.units} * ${CHART_ROW}${lines} + ${size.axis ?? CHART_ROW}))`;\n return { height, maxHeight: `calc(2 * ${height})`, flex: \"1 0 auto\" };\n }\n return { height: fixed ?? `clamp(${SM}, 50cqi, ${LG})`, maxHeight: `max(${fixed ?? LG}, 100cqi)`, flex: \"1 0 auto\" };\n}\n\n/* ── The chart mark ─────────────────────────────────────────────────────── */\n\n/**\n * Marks the library's charts, so ChartContainer knows its child sizes itself and needs no minimum area of its own.\n * `Symbol.for`, as PAGE_HEADER_MARK, so a second copy of the module still matches. A hand-built chart, an EmptyState\n * or a Sparkline carries no mark and keeps the container's area.\n */\nexport const CHART_MARK: unique symbol = Symbol.for(\"gridsmith.Chart\") as never;\n\nexport function markChart<T extends object>(component: T): T {\n Object.assign(component, { [CHART_MARK]: true });\n return component;\n}\n\n/** A single library chart (not a Fragment, a wrapper of the builder's or a list of children). */\nexport function isLibraryChart(children: ReactNode): boolean {\n const kids = Children.toArray(children);\n if (kids.length !== 1) return false;\n const only = kids[0];\n if (!isValidElement(only)) return false;\n const type = elementType(only.type) as Record<symbol, unknown> | string | null;\n return !!type && typeof type !== \"string\" && type[CHART_MARK] === true;\n}\n\n/* ── Context ────────────────────────────────────────────────────────────── */\n\nexport interface ChartContainerValue {\n /** The container's own height (a preset or a number, as CSS): it beats the chart's. */\n height?: string;\n /** The container title's id: the chart's graphic is named by it. */\n titleId?: string;\n /** The container's title: the chart's table, scrolling, is named after it (\"Hours by month: values\"). */\n title?: string;\n /** The chart is not the container's only child (or is wrapped): it fills the container's area instead of sizing itself. */\n fillArea?: boolean;\n /** The container header's slot beside the title, where the chart's Chart / Table switch goes (Sprint 25.8.9). */\n actions?: HTMLElement | null;\n /** How many library charts the container holds: the switch goes beside the title only when its chart is the one. */\n charts?: number;\n /** A chart counts itself in while it's drawn: the cleanup counts it out. */\n register?: () => () => void;\n}\n\nexport const ChartContainerContext = createContext<ChartContainerValue | null>(null);\n\nexport function useInsideChartContainer(): boolean {\n return useContext(ChartContainerContext) !== null;\n}\n\n/** The chart's slots outside its drawing: the legend (Recharts' Legend portals into it) and the tooltip's live region. */\nexport interface ChartFrame {\n legend: HTMLElement | null;\n live: HTMLElement | null;\n /** A value in full, with its unit, for the tooltip and what the chart says (Sprint 25.17 A27); toLocaleString without one. */\n formatValue?: (value: number, dataKey?: string) => string;\n /** Each series' mark besides its colour, by its dataKey, for the legend's and tooltip's swatches (Sprint 25.8.9 item 4). */\n marks?: Record<string, SeriesMark>;\n}\n\nexport const ChartFrameContext = createContext<ChartFrame>({ legend: null, live: null });\n\n/* ── Keyboard ───────────────────────────────────────────────────────────── */\n\nconst REMAPPED = new WeakSet<Event>();\n\n/**\n * A sideways chart lists its rows top to bottom. Recharts maps only ArrowLeft and ArrowRight, and in that layout reads\n * ArrowRight as the row above. Down and Right move to the next row, Up and Left to the one before, in reading order.\n */\nfunction remapRowKeys(e: KeyboardEvent<HTMLDivElement>) {\n if (REMAPPED.has(e.nativeEvent)) return;\n const next = e.key === \"ArrowDown\" || e.key === \"ArrowRight\";\n const previous = e.key === \"ArrowUp\" || e.key === \"ArrowLeft\";\n if (!next && !previous) return;\n const target = e.target as Element;\n if (!target.closest?.(\".recharts-wrapper\")) return;\n e.preventDefault();\n e.stopPropagation();\n const View = target.ownerDocument.defaultView ?? window;\n const event = new View.KeyboardEvent(\"keydown\", { key: next ? \"ArrowLeft\" : \"ArrowRight\", bubbles: true, cancelable: true });\n REMAPPED.add(event);\n target.dispatchEvent(event);\n}\n\n/* ── The wrapper ────────────────────────────────────────────────────────── */\n\nexport interface ChartWrapperProps {\n /** The chart's own height prop. A ChartContainer's preset or number beats it. */\n height?: ChartHeight;\n /** How the chart sizes itself when no height is set. */\n size: ChartSize;\n /** The chart type, for `data-gs-chart` (the bench reads it). */\n chart: string;\n /** A cartesian category axis: its kind and its categories (`data-category-kind`, `data-categories`). */\n categoryKind?: \"names\" | \"scale\";\n categories?: number;\n /** Which axis carries the categories, for the label counts (`data-labels-shown`, `data-labels-cut`). */\n categoryAxis?: \"x\" | \"y\";\n /** The rows run top to bottom (a sideways BarChart): the arrow keys follow them. */\n sideways?: boolean;\n /** The value axis's title, drawn horizontally above the axis (the chart leaves room at the top). */\n axisTitle?: string;\n className?: string;\n children: ReactNode;\n /** The chart's values in full, for its tooltip, by series (Sprint 25.17 A27). */\n formatValue?: (value: number, dataKey?: string) => string;\n \"aria-label\"?: string;\n /**\n * The chart's values as a table and its sentence (Sprint 25.8.9 items 4 and 27), each worked out by the chart from its\n * own props: the sentence is a line above the drawing, and a Chart / Table switch shows the table in its place.\n */\n access?: ChartAccess;\n /**\n * The page's own sentence of what the chart shows, in place of the one worked out from the data. A blank one keeps the\n * worked-out sentence: the page replaces it with its own words, never with none (Sprint 25.8.9 Q2).\n */\n description?: string;\n /** Each series' mark besides its colour, by its dataKey (Sprint 25.8.9 item 4). */\n marks?: Record<string, SeriesMark>;\n}\n\n/**\n * Sprint 25.9, A2: the chart's frame and its size container. It holds the plot box (the Recharts drawing sits absolutely\n * inside it), the legend's slot below and the tooltip's live region, and owns the height, with or without a\n * ChartContainer. `min-inline-size` keeps a shrink-to-fit parent from collapsing it.\n */\nexport const ChartWrapper = forwardRef<HTMLDivElement, ChartWrapperProps>(function ChartWrapper({\n height = \"auto\",\n size,\n chart,\n categoryKind,\n categories,\n categoryAxis,\n sideways = false,\n axisTitle,\n className,\n children,\n formatValue,\n \"aria-label\": ariaLabel,\n access,\n description,\n marks,\n}, ref) {\n const container = useContext(ChartContainerContext);\n const rootRef = useRef<HTMLDivElement | null>(null);\n // the drawing's box, as an element so its watchers follow it when it's drawn again after the table (Sprint 25.8.9)\n const [plotEl, setPlotEl] = useState<HTMLDivElement | null>(null);\n const [view, setView] = useState<\"chart\" | \"table\">(\"chart\");\n const descriptionId = useId();\n const [legend, setLegend] = useState<HTMLDivElement | null>(null);\n const [live, setLive] = useState<HTMLDivElement | null>(null);\n const frame = useMemo<ChartFrame>(() => ({ legend, live, formatValue, marks }), [legend, live, formatValue, marks]);\n // The drawing never shrinks below the plot box's last real size. A box sized with `cqi` reports a width of 0 for a\n // moment while headless Chrome takes a full-page screenshot; handed to Recharts, that cleared the drawing, so the\n // screenshot showed an empty chart or bars growing again from zero (measured). A reading of 0 is no layout: the\n // drawing keeps its size, grows at once and shrinks a frame later.\n const [drawn, setDrawn] = useState<{ width: number; height: number } | null>(null);\n useLayoutEffect(() => {\n const plot = plotEl;\n if (!plot || typeof ResizeObserver === \"undefined\") return;\n const observer = new ResizeObserver((entries) => {\n const box = entries[entries.length - 1]?.contentRect;\n if (!box || box.width <= 0 || box.height <= 0) return;\n setDrawn((prev) => (prev && Math.abs(prev.width - box.width) < 0.5 && Math.abs(prev.height - box.height) < 0.5 ? prev : { width: box.width, height: box.height }));\n });\n observer.observe(plot);\n return () => observer.disconnect();\n }, [plotEl]);\n\n const fill = container?.fillArea === true;\n const fixed = container?.height ?? fixedChartHeight(height);\n const plotStyle: CSSProperties = fill ? { flex: \"1 1 0%\", minHeight: 0 } : plotBoxStyle(size, fixed);\n\n // The sentence of what the chart shows (Sprint 25.8.9 item 4): the page's own, else the one worked out from its data.\n const sentence = description?.trim() ? description : access?.description;\n // The graphic is named by the chart's own label, else by its container's title (A1), and described by the sentence.\n const describedBy = sentence ? { \"aria-describedby\": descriptionId } : {};\n const named = ariaLabel\n ? { role: \"img\", \"aria-label\": ariaLabel, ...describedBy }\n : container?.titleId\n ? { role: \"img\", \"aria-labelledby\": container.titleId, ...describedBy }\n : {};\n\n // A8: how many category labels show, and how many were shortened, counted on the rendered ticks.\n useEffect(() => {\n const root = rootRef.current;\n const plot = plotEl;\n if (!root || !plot || !categoryAxis || typeof MutationObserver === \"undefined\") return;\n const selector = `.recharts-${categoryAxis}Axis-tick-labels .recharts-cartesian-axis-tick-value`;\n const count = () => {\n const labels = Array.from(plot.querySelectorAll(selector)).filter((el) => (el.textContent ?? \"\").trim() !== \"\");\n const shown = String(labels.length);\n const cut = String(labels.filter((el) => el.hasAttribute(\"data-cut\")).length);\n if (root.getAttribute(\"data-labels-shown\") !== shown) root.setAttribute(\"data-labels-shown\", shown);\n if (root.getAttribute(\"data-labels-cut\") !== cut) root.setAttribute(\"data-labels-cut\", cut);\n };\n count();\n const observer = new MutationObserver(count);\n observer.observe(plot, { subtree: true, childList: true, characterData: true, attributes: true, attributeFilter: [\"data-cut\"] });\n return () => observer.disconnect();\n }, [categoryAxis, plotEl]);\n\n // The chart counts itself into its container, which puts the switch beside its title only for its one chart\n const register = container?.register;\n useLayoutEffect(() => register?.(), [register]);\n\n // The Chart / Table switch (Sprint 25.8.9 item 27): beside its container's title when the chart is the container's one,\n // else above the drawing; named after its chart, so several on a page are told apart. Choosing a view is never a change\n // to a form around the chart.\n const switcher = access ? (\n <FormChangeCtx value={null}>\n <SegmentedControl\n size=\"xs\"\n aria-label={`Show ${ariaLabel || container?.title || \"the chart\"} as`}\n value={view}\n onChange={(v) => setView(v === \"table\" ? \"table\" : \"chart\")}\n options={[{ value: \"chart\", label: \"Chart\" }, { value: \"table\", label: \"Table\" }]}\n />\n </FormChangeCtx>\n ) : null;\n const actions = container?.actions && container.charts === 1 ? container.actions : null;\n // In a container's fixed area the sentence would take the drawing's height (a long one leaves a sliver of plot on a\n // phone): there it's shown with the table, one switch away, and still describes the drawing to a screen reader.\n const sentenceShown = !fill || view === \"table\";\n const sentenceLine = sentence ? (\n <p id={descriptionId} data-chart-description=\"\" className={sentenceShown ? \"min-w-0 text-sm text-[var(--ds-text-secondary)]\" : \"sr-only\"}>{sentence}</p>\n ) : null;\n\n return (\n <div\n ref={mergeRefs(ref as Ref<HTMLElement>, rootRef as Ref<HTMLElement>) as Ref<HTMLDivElement>}\n data-gs-chart={chart}\n data-category-kind={categoryKind}\n data-categories={categories}\n className={cn(\"relative flex w-full flex-col\", fill && \"h-full\", className)}\n style={{ containerType: \"inline-size\", minInlineSize: \"min(100%, 16rem)\", ...(fill ? {} : { flex: \"1 0 auto\" }) }}\n >\n {((sentenceLine && sentenceShown) || (switcher && !actions)) && (\n <div data-chart-head=\"\" className=\"mb-ds-3 flex items-start justify-between gap-ds-3\">\n {sentenceShown && sentenceLine}\n {!actions && switcher && <div className=\"ml-auto shrink-0\">{switcher}</div>}\n </div>\n )}\n {!sentenceShown && sentenceLine}\n {actions && switcher && createPortal(switcher, actions)}\n {view === \"chart\" || !access ? (\n <div\n ref={setPlotEl}\n data-chart-plot=\"\"\n className=\"relative w-full\"\n style={plotStyle}\n onKeyDownCapture={sideways ? remapRowKeys : undefined}\n {...named}\n >\n {axisTitle && (\n <span data-chart-axis-title=\"\" className=\"absolute left-0 top-0 whitespace-nowrap text-xs text-[var(--ds-text-muted)] font-[family-name:var(--ds-font-sans)] leading-normal\">\n {axisTitle}\n </span>\n )}\n <div className=\"absolute inset-0\" style={drawn ? { minWidth: drawn.width, minHeight: drawn.height } : undefined}>\n <ChartFrameContext.Provider value={frame}><PlotNames>{children}</PlotNames></ChartFrameContext.Provider>\n </div>\n </div>\n ) : (\n <ChartTable table={access.table} name={`${ariaLabel || container?.title || \"The chart\"}: values`} labelledBy={ariaLabel ? undefined : container?.titleId} />\n )}\n <div ref={setLegend} data-chart-legend=\"\" />\n <div ref={setLive} role=\"status\" aria-live=\"polite\" className=\"sr-only\" />\n {/* the axis font and one row, as the page resolves them (useAxisMeasure reads it) */}\n <span\n data-chart-probe=\"\"\n aria-hidden=\"true\"\n className=\"pointer-events-none invisible absolute left-0 top-0\"\n style={{ fontSize: \"var(--ds-font-size-xs)\", fontFamily: \"var(--ds-font-sans)\", height: CHART_ROW, width: 0 }}\n />\n </div>\n );\n});\n","import { useContext, useEffect, useLayoutEffect, useMemo, useState, type RefObject } from \"react\";\nimport { createPortal } from \"react-dom\";\nimport { Legend, Text } from \"recharts\";\nimport { useResolvedToken } from \"../../lib/chart-utils\";\nimport { createAxisMeasurer, fitLabel, namesCutShort, type CategoryKind, type Measure } from \"../../lib/chart-categories\";\nimport { ChartFrameContext } from \"./ChartWrapper\";\nimport { valueAxisTicks } from \"./value-format\";\nimport { formatLocale } from \"../../lib/format-locale\";\nimport { useFormatLocale } from \"../../lib/locale\";\nimport { SeriesSwatch } from \"./series-marks\";\n\n\ninterface TooltipEntry {\n name: string;\n value: number | string;\n color: string;\n dataKey?: string;\n payload?: Record<string, unknown>;\n /** The id of the series the entry belongs to: a scatter point's entries are named after the axes, not the series. */\n graphicalItemId?: string;\n}\n\ninterface ChartTooltipContentProps {\n active?: boolean;\n payload?: TooltipEntry[];\n label?: string;\n}\n\nconst hasLabel = (label: unknown) => label != null && label !== \"\" && typeof label !== \"number\";\n/**\n * A series' name. A chart without a category label (a pie's slice, a funnel's stage, a treemap's tile) names the item by\n * its row's `name`; on an axis chart the row's `name` is the category, already shown as the label, so the series keeps\n * its own (a row keyed by `name` read \"Alice: Alice 20\" instead of \"Alice: Hours 20\").\n */\nconst entryName = (entry: TooltipEntry, label: unknown) =>\n (!hasLabel(label) && typeof entry.payload?.name === \"string\" && entry.payload.name) || entry.name;\n/** A value as the tooltip shows it: in full, with the chart's unit (Sprint 25.17 A27), else grouped in the locale given. */\nconst entryValue = (entry: TooltipEntry, format: ((value: number, dataKey?: string) => string) | undefined, locale: string | undefined) =>\n (typeof entry.value === \"number\" ? (format ? format(entry.value, entry.dataKey) : entry.value.toLocaleString(locale)) : entry.value);\n\n/** What the live region says for the active point: its category, then each series' name and value. */\n/** What recharts sets on a shape to draw it, which a data row may carry too (a point's x and y, a slice's fill). */\nconst DRAWING = new Set([\"x\", \"y\", \"cx\", \"cy\", \"width\", \"height\", \"r\", \"radius\", \"innerRadius\", \"outerRadius\", \"startAngle\", \"endAngle\", \"cornerRadius\", \"upperWidth\", \"lowerWidth\", \"size\", \"fill\", \"stroke\", \"strokeWidth\", \"opacity\", \"fillOpacity\", \"strokeOpacity\", \"className\"]);\n\n/**\n * A shape's props without its data row's own fields (Sprint 25.29 item 14): recharts spreads the row into each shape, so\n * a row's `role`, `aria-label` or `id` became the bar's, and a chart of people by role drew bars with role=\"Design\". The\n * row stays whole as `payload`, and what the shape draws with stays.\n */\nexport function withoutRowFields<P extends object>(props: P): P {\n const row = (props as { payload?: unknown }).payload;\n if (!row || typeof row !== \"object\") return props;\n const own: Record<string, unknown> = {};\n for (const [key, value] of Object.entries(props)) if (DRAWING.has(key) || !(key in row)) own[key] = value;\n return own as P;\n}\n\nexport function tooltipAnnouncement(label: unknown, payload: TooltipEntry[] | undefined, format?: (value: number, dataKey?: string) => string, locale: string | undefined = formatLocale()): string {\n if (!payload?.length) return \"\";\n const values = payload.map((entry) => `${entryName(entry, label)} ${entryValue(entry, format, locale)}`).join(\", \");\n return hasLabel(label) ? `${String(label)}: ${values}` : values;\n}\n\n/** A colour CSS can paint, or nothing: a pattern's url() is an SVG paint only. */\nfunction plainColour(value: unknown): string | undefined {\n return typeof value === \"string\" && value.trim() !== \"\" && !value.trim().startsWith(\"url(\") ? value : undefined;\n}\n\n/**\n * The chart's tooltip box. What it shows is also said in the chart's `role=\"status\"` `aria-live=\"polite\"` region, which\n * sits outside the drawing (a graphic's children are presentational) and starts empty, so the category and the values\n * are heard as the pointer or the arrow keys move (WCAG 4.1.3). Outside a library chart the region wraps the box.\n */\nexport function ChartTooltipContent({ active, payload, label }: ChartTooltipContentProps) {\n const bgSurface = useResolvedToken(\"--ds-bg-surface\");\n const borderSubtle = useResolvedToken(\"--ds-border-subtle\");\n const textPrimary = useResolvedToken(\"--ds-text-primary\");\n const textSecondary = useResolvedToken(\"--ds-text-secondary\");\n const { live, formatValue, marks } = useContext(ChartFrameContext);\n // the values in the chart's locale (Sprint 25.20)\n const locale = useFormatLocale();\n\n const on = !!active && !!payload?.length;\n const showLabel = hasLabel(label);\n\n const box = on ? (\n <div\n className=\"rounded-[var(--ds-radius-md)] shadow-[var(--ds-shadow-popover)] font-[family-name:var(--ds-font-sans)] text-sm\"\n style={{\n backgroundColor: bgSurface,\n border: `var(--ds-border-width) solid ${borderSubtle}`,\n padding: \"var(--ds-space-2) var(--ds-space-3)\",\n }}\n >\n {showLabel && (\n <p className=\"font-medium mb-ds-1\" style={{ color: textPrimary }}>\n {label}\n </p>\n )}\n {payload!.map((entry, i) => {\n // a patterned part's fill is a url() for its SVG, never a CSS colour: the dot takes the series' colour instead\n const dotColor = plainColour(entry.payload?.fill) ?? plainColour(entry.color) ?? textSecondary;\n // the series' own mark beside its colour (Sprint 25.8.9 item 4), as the legend draws it: by its series' id (a scatter\n // point's), its dataKey, else its name, as a pie's slices and a radial chart's bars are keyed\n const mark = (entry.graphicalItemId ? marks?.[entry.graphicalItemId] : undefined) ?? (entry.dataKey ? marks?.[entry.dataKey] : undefined) ?? marks?.[String(entry.name)] ?? marks?.[String(entry.payload?.name)];\n return (\n <div key={i} className=\"flex items-center gap-ds-2\" style={{ marginTop: i > 0 ? 2 : 0 }}>\n {mark ? <SeriesSwatch mark={mark} color={dotColor} /> : (\n <span\n className=\"shrink-0 rounded-[var(--ds-radius-full)]\"\n style={{ width: 8, height: 8, backgroundColor: dotColor }}\n />\n )}\n <span style={{ color: textSecondary }}>{entryName(entry, label)}:</span>\n <span className=\"tabular-nums\" style={{ color: textPrimary }}>\n {entryValue(entry, formatValue, locale)}\n </span>\n </div>\n );\n })}\n </div>\n ) : null;\n\n if (live) {\n return (\n <>\n {box}\n {createPortal(on ? tooltipAnnouncement(label, payload, formatValue, locale) : \"\", live)}\n </>\n );\n }\n return (\n <div role=\"status\" aria-live=\"polite\">\n {box}\n </div>\n );\n}\n\ninterface ChartLegendContentProps {\n payload?: Array<{\n value: string;\n color: string;\n dataKey?: string;\n /** \"none\" for a series drawn without an entry (`legendType=\"none\"`). */\n type?: string;\n }>;\n}\n\n/** A legend entry's outline: the series' stroke when it has one (a soft bar's solid edge, a line), else its colour. */\nfunction swatchEdge(entry: { color?: string; payload?: unknown }): string | undefined {\n const stroke = (entry.payload as { stroke?: unknown } | undefined)?.stroke;\n return typeof stroke === \"string\" ? stroke : entry.color;\n}\n\nexport function ChartLegendContent({ payload }: ChartLegendContentProps) {\n const textSecondary = useResolvedToken(\"--ds-text-secondary\");\n const { marks } = useContext(ChartFrameContext);\n // a series drawn with legendType \"none\" has no entry, as in Recharts' own legend\n const entries = payload?.filter((entry) => entry.type !== \"none\") ?? [];\n\n if (!entries.length) return null;\n\n return (\n <div className=\"flex flex-wrap justify-center gap-y-ds-1 gap-x-ds-4 font-[family-name:var(--ds-font-sans)] text-sm\">\n {entries.map((entry, i) => {\n // the series' own mark beside its colour, as the chart draws it (Sprint 25.8.9 item 4): by its dataKey, else by\n // its name (a scatter chart's series)\n const mark = (entry.dataKey ? marks?.[entry.dataKey] : undefined) ?? marks?.[entry.value];\n return (\n <div key={i} className=\"flex items-center gap-ds-1.5\">\n {mark ? <SeriesSwatch mark={mark} color={entry.color} /> : (\n <span\n className=\"shrink-0 rounded-[var(--ds-radius-full)]\"\n // the series' own fill inside its outline (a soft bar's solid stroke), so a 30% tint stays visible (C4)\n style={{ width: 10, height: 10, backgroundColor: entry.color, border: `1.5px solid ${swatchEdge(entry)}` }}\n />\n )}\n <span data-legend-label=\"\" style={{ color: textSecondary }}>{entry.value}</span>\n </div>\n );\n })}\n </div>\n );\n}\n\n/** Legend items in the order the chart draws its series: by dataKey (bars, lines, areas, radars) or by name (a pie's slices). */\nexport function seriesSorter(order: ReadonlyArray<string>, by: \"dataKey\" | \"value\" = \"dataKey\") {\n return (item: { dataKey?: unknown; value?: unknown }) => {\n const key = by === \"dataKey\" ? item.dataKey : item.value;\n const i = order.indexOf(String(key));\n return i < 0 ? order.length : i;\n };\n}\n\n/**\n * Sprint 25.9, A2: the chart's legend is Recharts' own Legend portalled into the slot below the drawing, so it no longer\n * takes its height from the plot. It keeps ChartLegendContent and its swatch, and follows the series' order, not the\n * alphabet (Recharts' default `itemSorter: \"value\"`). Rendered once the slot exists, so it never lands in the drawing.\n */\nexport function ChartLegend({ order, by = \"dataKey\" }: { order: ReadonlyArray<string>; by?: \"dataKey\" | \"value\" }) {\n const { legend } = useContext(ChartFrameContext);\n const orderKey = order.join(\"\\u0001\");\n // eslint-disable-next-line react-hooks/exhaustive-deps -- the order is compared by value\n const sorter = useMemo(() => seriesSorter(order, by), [orderKey, by]);\n if (!legend) return null;\n return <Legend portal={legend} content={<ChartLegendContent />} itemSorter={sorter} wrapperStyle={{ paddingTop: \"var(--ds-space-3)\" }} />;\n}\n\nexport function useGridStroke(): string {\n return useResolvedToken(\"--ds-border-subtle\");\n}\n\nexport function useAxisStyle() {\n const textMuted = useResolvedToken(\"--ds-text-muted\");\n\n return {\n tick: {\n fontSize: \"var(--ds-font-size-xs)\",\n fontFamily: \"var(--ds-font-sans)\",\n fill: textMuted,\n // Sprint 25.9: Recharts paints a default tick's text with the axis stroke (#666 unless set), not with fill, so the\n // value axes drew their numbers at about 2.6:1 on dark cards (WCAG 1.4.3 asks 4.5:1). Every axis that spreads this\n // hides its axis and tick lines, so the stroke only colours the text.\n stroke: textMuted,\n },\n };\n}\n\nexport function useRadius(): number {\n const val = useResolvedToken(\"--ds-radius-md\");\n const parsed = parseInt(val, 10);\n return isNaN(parsed) ? 6 : parsed;\n}\n/**\n * Recharts' `tick` prop as an object only passes SVG-valid properties.\n * Props like `maxLines`, `verticalAnchor` are stripped. We must use a\n * function to pass them to the internal Text component.\n */\nexport function xAxisTick(props: Record<string, unknown>) {\n // No width box (Sprint 25.3 C12): with one, Recharts measured \"20 Aug\" in a hidden span that did not carry the\n // chart's font, judged it too wide for its share of the axis and wrapped or truncated it. Without a width Text never\n // wraps or truncates; `interval` (preserveStartEnd) thins colliding ticks and keeps the first and last. Recharts' own\n // Text keeps the axis's auto height right, which a bare <text> does not (the label was clipped 8px in the pass).\n // Scale axes (dates, numbers) keep this tick; a names axis takes namesTick.\n const { x, y, payload, width: _width, visibleTicksCount: _count, ...rest } = props as {\n x: number; y: number; payload: { value: string };\n width?: number; visibleTicksCount?: number; [k: string]: unknown;\n };\n return (\n <Text {...rest} x={x} y={y} textAnchor=\"middle\" verticalAnchor=\"start\">\n {payload.value}\n </Text>\n );\n}\n\nexport function yAxisTick(props: Record<string, unknown>) {\n const { x, y, payload, ...rest } = props as { x: number; y: number; payload: { value: string };[k: string]: unknown };\n return (\n <Text {...rest} x={x} y={y} textAnchor=\"end\" verticalAnchor=\"middle\" width={200} maxLines={2}>\n {payload.value}\n </Text>\n );\n}\n\n/* ── Names on a category axis (Sprint 25.9, A3) ─────────────────────────── */\n\n/** The line height of a two-line name, in em. */\nconst LINE_EM = 1.2;\n/** The least space between two names under an upright chart. */\nexport const NAME_GAP = 8;\n/**\n * A sideways name's inset from its column: Recharts draws it tickSize + tickMargin (8 px) left of the axis edge, and\n * the chart's own margin leaves 4 px on the left.\n */\nexport const NAME_COLUMN_INSET = 12;\n\n/**\n * The tick for a names axis: each name fitted to its band — one line; else two lines split at a space; else \"…\" on\n * the second — inside one `<g className={props.className}>`, so Recharts sizes the axis for both lines (two Texts each\n * carrying the tick's class leave the axis sized for one, and the second line clipped). The full name is the label's\n * `<title>`. Upright, the band is the axis width over the ticks it draws; sideways it is the name column the chart sets.\n * Without a measurer (no canvas) every name shows in full on one line.\n */\nexport function namesTick(measure: Measure | null, orientation: \"x\" | \"y\", column?: number) {\n return function NamesTick(props: Record<string, unknown>) {\n const { x, y, payload, width, visibleTicksCount, className, fill, fontSize, fontFamily } = props as {\n x: number; y: number; payload?: { value?: unknown }; width?: number; visibleTicksCount?: number;\n className?: string; fill?: string; fontSize?: string | number; fontFamily?: string;\n };\n const name = String(payload?.value ?? \"\");\n const room = orientation === \"x\"\n ? (Number(width) || 0) / Math.max(1, Number(visibleTicksCount) || 1) - NAME_GAP\n : (column ?? (Number(width) || 0)) - NAME_COLUMN_INSET;\n const fit = fitLabel(name, room, measure);\n const text = { fill, fontSize, fontFamily, stroke: \"none\" };\n // upright: the first line's top at y (Recharts' verticalAnchor \"start\"); sideways: the lines centred on the row\n const firstDy = orientation === \"x\" ? 0.71 : 0.355 - ((fit.lines.length - 1) * LINE_EM) / 2;\n return (\n <g className={className} data-cut={fit.cut ? \"\" : undefined} data-lines={fit.lines.length}>\n <title>{name}</title>\n {fit.lines.map((line, i) => (\n <text key={i} x={x} y={y} dy={`${firstDy + i * LINE_EM}em`} textAnchor={orientation === \"x\" ? \"middle\" : \"end\"} {...text}>\n {line}\n </text>\n ))}\n </g>\n );\n };\n}\n\nexport type XAxisInterval = number | \"preserveStart\" | \"preserveEnd\" | \"preserveStartEnd\" | \"equidistantPreserveStart\";\n\nexport interface AxisMeasure {\n /** Text widths in the axis's resolved font, or null (no canvas: jsdom). */\n measure: Measure | null;\n /** The resolved axis font size, px. */\n px: number;\n /** One row of a row chart, px (--ds-chart-row as the page resolves it). */\n rowPx: number;\n /** The chart wrapper's width, px. */\n width: number;\n}\n\ntype FontSet = { ready: Promise<unknown>; addEventListener?: (t: string, f: () => void) => void; removeEventListener?: (t: string, f: () => void) => void };\n\n/**\n * The chart's measurer: the axis font read from the wrapper's probe (so `calc()` font tokens measure right), and the\n * wrapper's width. Re-read when the wrapper resizes and when web fonts land (the same font string then measures\n * differently, so the cache starts again).\n */\nexport function useAxisMeasure(ref: RefObject<HTMLDivElement | null>, enabled = true): AxisMeasure {\n const [state, setState] = useState<AxisMeasure>({ measure: null, px: 12, rowPx: 32, width: 0 });\n useLayoutEffect(() => {\n const el = ref.current;\n if (!enabled || !el) return;\n let live = true;\n let font = \"\";\n const update = (fresh = false) => {\n if (!live) return;\n const measured = el.clientWidth;\n const probe = el.querySelector<HTMLElement>(\"[data-chart-probe]\");\n const row = probe?.getBoundingClientRect().height ?? 0;\n const next = createAxisMeasurer(el);\n setState((prev) => {\n // no width is no layout (a hidden tab, or the moment headless Chrome takes a full-page screenshot): keep the last\n const width = measured > 0 ? measured : prev.width;\n const rowPx = row > 0 ? row : prev.rowPx;\n if (!next) return prev.width === width ? prev : { ...prev, width };\n if (!fresh && next.font === font && prev.measure && prev.width === width && prev.rowPx === rowPx) return prev;\n const keep = !fresh && next.font === font && prev.measure;\n font = next.font;\n return { measure: keep ? prev.measure : next.measure, px: next.px, rowPx, width };\n });\n };\n update(true);\n const ro = typeof ResizeObserver !== \"undefined\" ? new ResizeObserver(() => update()) : null;\n ro?.observe(el);\n const fonts = (typeof document !== \"undefined\" ? (document as Document & { fonts?: FontSet }).fonts : undefined);\n const landed = () => update(true);\n fonts?.ready.then(landed, () => {});\n fonts?.addEventListener?.(\"loadingdone\", landed);\n return () => {\n live = false;\n ro?.disconnect();\n fonts?.removeEventListener?.(\"loadingdone\", landed);\n };\n }, [ref, enabled]);\n return state;\n}\n\n/** The value axis's width on an upright chart: its widest tick label, as the axis formats it (Sprint 25.17 A27). */\nexport function valueAxisWidth(values: number[], measure: Measure, format: (value: number) => string = String): number {\n const ticks = valueAxisTicks(values);\n if (!ticks.length) return Math.ceil(measure(format(0))) + 8;\n return Math.ceil(Math.max(...ticks.map((t) => measure(format(t))))) + 8;\n}\n\n/** How far the switch looks back before turning an automatic sideways chart upright again (no flip at the boundary). */\nconst SWITCH_HYSTERESIS = 32;\n\n/**\n * D8: an upright chart of names turns sideways when a name would be cut to fewer than six characters at the chart's\n * width, and back when there's room: it turns upright again only once names would also fit a little narrower, so a\n * scrollbar appearing does not flip it back. The last decision is kept as state (information from the previous render).\n */\nexport function useSidewaysSwitch(enabled: boolean, names: string[], m: AxisMeasure, axisWidth: number, sideMargins: number): boolean {\n const [turned, setTurned] = useState(false);\n const key = names.join(\"\\u0001\");\n const cut = useMemo(() => {\n if (!enabled || !m.measure || m.width <= 0 || names.length === 0) return { here: false, narrower: false };\n const cutAt = (width: number) => namesCutShort(names, (width - sideMargins - axisWidth) / names.length - NAME_GAP, m.measure!);\n return { here: cutAt(m.width), narrower: cutAt(m.width - SWITCH_HYSTERESIS) };\n // names are compared by value\n }, [enabled, key, m.measure, m.width, axisWidth, sideMargins]); // eslint-disable-line react-hooks/exhaustive-deps\n // sideways as soon as names are cut short here; upright only when they fit here and a little narrower (no flip-flop)\n const decision = turned ? cut.here || cut.narrower : cut.here;\n if (decision !== turned) setTurned(decision);\n return decision;\n}\n\n/** A sideways chart's name column: its widest name, at most a third of the chart's width. */\nexport function nameColumn(names: string[], m: AxisMeasure): number | undefined {\n if (!m.measure || m.width <= 0) return undefined;\n const widest = names.reduce((w, n) => Math.max(w, m.measure!(n.replace(/\\s+/g, \" \").trim())), 0);\n return Math.max(24, Math.min(Math.ceil(widest) + NAME_COLUMN_INSET, Math.floor(m.width / 3)));\n}\n\n/** How many names take two lines in a name column (each makes its row one line taller). */\nexport function twoLineNames(names: string[], column: number | undefined, m: AxisMeasure): number {\n if (!m.measure || column === undefined) return 0;\n return names.filter((n) => fitLabel(n, column - NAME_COLUMN_INSET, m.measure).lines.length > 1).length;\n}\n\n/** The widest label in the chart's own axis font (canvas measureText), or null where there is no canvas (jsdom). */\nfunction widestLabel(el: HTMLElement, labels: string[]): number | null {\n const measurer = createAxisMeasurer(el);\n if (!measurer) return null;\n return labels.reduce((w, l) => Math.max(w, measurer.measure(l)), 0);\n}\n\nconst TICK_GAP = 12; // the least space between two labels\nconst AXIS_RESERVE = 48; // the y-axis column and the chart's side margins\n\n/**\n * Sprint 25.4 C-11 (decision 7): the category ticks a chart shows. Recharts' preserveStartEnd thins colliding ticks\n * by its own measurement (without the chart's font) and keeps the last tick, so the labels fall unevenly (round 5:\n * 14 and 15 September missing). The chart measures its widest label with the resolved axis font, picks the step\n * that fits the axis width, and labels every step from the first category — the last only when it falls on the step.\n * Re-measured when the wrapper resizes and when the web fonts land. A numeric `override` (the chart's xAxisInterval\n * prop) is every Nth category and skips the measurement; the Recharts strings are treated as \"measured\" (round 13).\n *\n * Sprint 25.9, A3: this thinning is for dates and numbers only. A names axis (`kind` \"names\") is never thinned: every\n * name from the first render (interval 0, no explicit ticks, so duplicate names keep their own bands), each fitted to\n * its band by namesTick. The font is the axis font as the page resolves it (a probe), so `calc()` tokens measure right.\n */\nexport function useCategoryTicks(\n data: ReadonlyArray<Record<string, unknown>> | undefined,\n xAxisKey: string,\n ref: RefObject<HTMLDivElement | null>,\n override?: XAxisInterval,\n kind: CategoryKind = \"scale\",\n): { ticks?: string[]; interval: XAxisInterval; endMargin: number } {\n const labels = useMemo(() => (data ?? []).map((d) => String(d[xAxisKey] ?? \"\")), [data, xAxisKey]);\n const labelsKey = labels.join(\"\\u0001\");\n const [ticks, setTicks] = useState<string[] | undefined>(undefined);\n // Half the widest label: the chart's right margin, so the last label (centred on the last point) is not clipped.\n const [endMargin, setEndMargin] = useState(4);\n // Only a number is an override (every Nth category). The Recharts strings — \"preserveStartEnd\" and friends — are the\n // thinning this hook replaced (round 13: a builder passed the old default by name and got uneven labels again), so\n // they mean \"measured\" too.\n const numeric = typeof override === \"number\" ? override : undefined;\n const names = kind === \"names\";\n useEffect(() => {\n const el = ref.current;\n if (names || numeric !== undefined || !el || labels.length === 0) return;\n let live = true;\n const compute = () => {\n if (!live) return;\n // no width is no layout (a hidden tab, or the moment headless Chrome takes a full-page screenshot): keep the last\n if (el.clientWidth <= 0) return;\n const widest = widestLabel(el, labels);\n const plot = el.clientWidth - AXIS_RESERVE;\n if (widest == null || plot <= 0) { setTicks(undefined); return; }\n setEndMargin(Math.max(4, Math.ceil(widest / 2)));\n const fits = Math.max(1, Math.floor(plot / (widest + TICK_GAP)));\n const step = Math.ceil(labels.length / fits);\n // every k-th label from the first, explicitly — an explicit list keeps Recharts from thinning on its own\n // measurement even when every label fits (round 5: \"16 Sep\" dropped at full width)\n setTicks(labels.filter((_, i) => i % step === 0));\n };\n if (typeof ResizeObserver === \"undefined\") return;\n const ro = new ResizeObserver(compute);\n ro.observe(el);\n const fonts = (document as Document & { fonts?: { ready: Promise<unknown> } }).fonts;\n fonts?.ready.then(compute, () => {});\n return () => { live = false; ro.disconnect(); };\n // labels are compared by value\n }, [labelsKey, numeric, names, ref]); // eslint-disable-line react-hooks/exhaustive-deps\n if (names) return { interval: 0, endMargin: 4 };\n if (numeric !== undefined) return { interval: numeric, endMargin: 4 };\n return ticks ? { ticks, interval: 0, endMargin } : { interval: \"preserveStartEnd\", endMargin: 4 };\n}\n","import { forwardRef, useId, useMemo, useRef, type Ref } from \"react\";\nimport {\n BarChart as RechartsBarChart,\n Bar,\n XAxis,\n YAxis,\n CartesianGrid,\n Tooltip,\n Rectangle,\n ResponsiveContainer,\n} from \"recharts\";\nimport { useChartColors, useChartAnimation, useResolvedToken } from \"../../lib/chart-utils\";\nimport { categoryKind as guessCategoryKind } from \"../../lib/chart-categories\";\nimport { cartesianAccess, type ChartReference } from \"./chart-access\";\nimport { ForecastHatch, forecastElements, forecastHatchId, forecastIndex, referenceElements, referenceValues } from \"./chart-references\";\nimport { AHEAD_STRENGTH, SeriesPatterns, aheadFill, aheadPattern, seriesPattern, type SeriesMark } from \"./series-marks\";\nimport {\n ChartTooltipContent, ChartLegend, useGridStroke, useAxisStyle, useRadius, xAxisTick, namesTick, useCategoryTicks,\n useAxisMeasure, useSidewaysSwitch, valueAxisWidth, nameColumn, twoLineNames, withoutRowFields, type XAxisInterval,\n} from \"./ChartPrimitives\";\nimport { mergeRefs } from \"../../lib/slot\";\nimport { axisExtent, axisTickFormatter, fullValueFormatter, type ValueFormat } from \"./value-format\";\nimport { ChartWrapper, CHART_ROW, markChart } from \"./ChartWrapper\";\nimport { useFormatLocale } from \"../../lib/locale\";\nimport { useHydrated } from \"../../lib/hydrated\";\n\nexport interface BarDef {\n dataKey: string;\n label?: string;\n soft?: boolean;\n /**\n * Bars with the same stackId stack into one column (Sprint 25.7, C4); a bar without one stands alone. BarChart's\n * `stacked` puts every bar without a stackId into one stack. The same field works in CompositeChart, where lines\n * draw over the stacks.\n */\n stackId?: string;\n}\n\n/** The stack a bar joins: its own stackId, else the one `stacked` makes for every bar. */\nexport function barStackOf(bar: BarDef, stacked: boolean): string | undefined {\n return bar.stackId ?? (stacked ? \"stack\" : undefined);\n}\n\n/** Some bar stacks. Its chart then stacks both ways from zero (stackOffset \"sign\"), so a negative series sits below it. */\nexport function anyStack(bars: BarDef[], stacked: boolean): boolean {\n return bars.some((bar) => barStackOf(bar, stacked) != null);\n}\n\n/** How many bars stand side by side in one category: one per stack, one per bar on its own. */\nexport function barGroups(bars: BarDef[], stacked: boolean): number {\n return Math.max(1, new Set(bars.map((bar, i) => barStackOf(bar, stacked) ?? `\\u0000${i}`)).size);\n}\n\n/**\n * The bar's shape: only the end segment of each stack is rounded, per column and per side of zero — the top of the\n * positive side, the bottom of the negative one — so a stack whose last series is zero in a column rounds the segment\n * that ends it there. A bar on its own rounds its end.\n */\nexport function barShape(bars: BarDef[], index: number, stacked: boolean, radius: number, horizontal = false, forecast?: { from: number; edge: string; fill?: string | null }) {\n const round: [number, number, number, number] = horizontal ? [0, radius, radius, 0] : [radius, radius, 0, 0];\n const square: [number, number, number, number] = [0, 0, 0, 0];\n const stack = barStackOf(bars[index], stacked);\n const above = stack == null ? [] : bars.filter((b, j) => j > index && barStackOf(b, stacked) === stack);\n // Recharts hands the shape the bar's geometry and its row of data; it draws a negative bar's rounded corners at its\n // far end itself\n const Shape = (props: unknown) => {\n const p = props as { payload?: Record<string, unknown>; index?: number };\n const row = p.payload ?? {};\n const down = Number(row[bars[index].dataKey]) < 0;\n const onTop = above.every((b) => {\n const value = Number(row[b.dataKey]);\n return !(down ? value < 0 : value > 0);\n });\n // Sprint 25.8.9 item 26: a forecast's bar draws fainter, inside a dashed outline in its series' colour: its fill the\n // fainter colour as one (a pattern's with its marks chosen against it), else see-through where it can't be worked out\n const ahead = forecast && forecast.from >= 0 && (p.index ?? -1) >= forecast.from\n ? { ...(forecast.fill ? { fill: forecast.fill } : { fillOpacity: AHEAD_STRENGTH }), stroke: forecast.edge, strokeWidth: 1.5, strokeDasharray: \"3 2\" }\n : {};\n return <Rectangle {...withoutRowFields(props as object)} {...ahead} radius={onTop ? round : square} />;\n };\n return Shape;\n}\n\n/** The values the value axis must reach: each bar on its own, and each stack up and down from zero (axisExtent). */\nfunction valueExtent(data: Record<string, unknown>[], bars: BarDef[], stacked: boolean): number[] {\n return axisExtent(data, bars.map((bar) => ({ dataKey: bar.dataKey, stack: barStackOf(bar, stacked) ?? null })));\n}\n\n/** A title line's height, px, in the axis font. */\nconst titleLine = (px: number) => Math.ceil(px * 1.5) + 4;\n/** The same in CSS, for a row chart's height. */\nconst TITLE_LINE_CSS = \"calc(1.5 * var(--ds-font-size-xs) + 4px)\";\n\nexport interface BarChartProps {\n /**\n * Which category ticks show on an axis of dates or numbers. Leave it out: the chart measures its widest label with\n * the chart's font and labels every k-th category from the first, the last only when it falls on the step (Sprint\n * 25.4 C-11, decision 7). A number labels every Nth category instead. The Recharts strings (\"preserveStartEnd\") are\n * accepted for compatibility and mean the same measured labelling (round 13). A names axis is never thinned.\n */\n xAxisInterval?: XAxisInterval;\n data: Record<string, unknown>[];\n bars: BarDef[];\n xAxisKey: string;\n /**\n * \"auto\" (the default): the chart sizes itself — sideways, a row per category; upright, two wide to one high. A\n * preset or a number overrides it; inside a ChartContainer, the container's own height wins.\n */\n height?: \"auto\" | \"sm\" | \"md\" | \"lg\" | number;\n /** Every bar without a stackId joins one stack. */\n stacked?: boolean;\n /**\n * Bars running sideways, one row per category. Leave it out: an upright chart of names turns itself sideways when a\n * name would be cut to fewer than six characters, and back when there's room (D8). true or false forces either.\n */\n horizontal?: boolean;\n /**\n * What the categories are. \"names\" are never skipped: each wraps onto two lines, then ends with \"…\", with the full\n * name on hover. \"scale\" (dates, times, numbers) is labelled at an even step. Leave it out: guessed from the labels.\n */\n categoryKind?: \"names\" | \"scale\";\n showGrid?: boolean;\n showTooltip?: boolean;\n showLegend?: boolean;\n /** The category axis's title, as drawn upright (below it). A sideways chart puts the category title above its names. */\n xAxisLabel?: string;\n /** The value axis's title, drawn horizontally above the axis. */\n yAxisLabel?: string;\n /**\n * How the values read: \"number\" (the default) is compact on the axis from five digits up, in the page's language (1M, 750K), and in full in\n * the tooltip; \"percent\", \"milliseconds\" or \"bytes\" add their unit; a function formats both itself (Sprint 25.17 A27).\n */\n valueFormat?: ValueFormat;\n animated?: boolean;\n \"aria-label\"?: string;\n className?: string;\n /**\n * What the chart shows, in the page's words: a line above the drawing, in place of the sentence the chart works out\n * from its data (each series' highest and lowest, or its trend over dates), which it shows without one.\n */\n description?: string;\n /** Targets or limits across the bars: a line at `value`, or a band from `value` to `to`, each named by its `label`. */\n references?: ChartReference[];\n /**\n * The first category whose values are a forecast (its `xAxisKey` value): from there each bar draws fainter in a dashed\n * outline of its own colour, in a pale hatched band named by `forecastLabel` (\"Forecast\" without one) that runs to the\n * chart's end, after a dashed line where it starts. A period not yet over is marked the same\n * way, with the page's own words (\"So far this month\").\n */\n forecastFrom?: string | number;\n forecastLabel?: string;\n}\n\nexport const BarChart = markChart(forwardRef<HTMLDivElement, BarChartProps>(function BarChart({\n data,\n bars,\n xAxisKey,\n xAxisInterval,\n height = \"auto\",\n stacked = false,\n horizontal,\n categoryKind,\n showGrid = true,\n showTooltip = true,\n showLegend,\n xAxisLabel,\n yAxisLabel,\n valueFormat,\n animated,\n \"aria-label\": ariaLabel,\n className,\n description,\n references,\n forecastFrom,\n forecastLabel = \"Forecast\",\n}, ref) {\n const wrapperRef = useRef<HTMLDivElement | null>(null);\n const chartId = useId();\n const labels = useMemo(() => (data ?? []).map((d) => String(d[xAxisKey] ?? \"\")), [data, xAxisKey]);\n // the chart's numbers in the locale the server and the hydrating browser share (Sprint 25.20)\n const locale = useFormatLocale();\n // its labels' kind: by the server's locale while a server-rendered page hydrates (both sides alike), by the browser's\n // languages from then on, as before 0.27.0 (the review: a German browser's month names on an English page)\n const hydrated = useHydrated();\n const kind = categoryKind ?? guessCategoryKind((data ?? []).map((d) => d[xAxisKey]), hydrated ? undefined : locale);\n const names = kind === \"names\";\n const measured = useAxisMeasure(wrapperRef, (data?.length ?? 0) > 0);\n // the axis reaches its references too (Sprint 25.8.9 item 25), so their labels' width is measured with the rest\n const values = useMemo(() => [...valueExtent(data ?? [], bars, stacked), ...referenceValues(references)], [data, bars, stacked, references]);\n const tickFormat = useMemo(() => axisTickFormatter(values, valueFormat, locale), [values, valueFormat, locale]);\n const fullFormat = useMemo(() => fullValueFormatter(valueFormat, locale), [valueFormat, locale]);\n const axisWidth = useMemo(\n () => (measured.measure ? valueAxisWidth(values, measured.measure, tickFormat) : 0),\n [measured.measure, values, tickFormat],\n );\n const turned = useSidewaysSwitch(horizontal === undefined && names, labels, measured, axisWidth, 8);\n const sideways = horizontal ?? turned;\n const xTicks = useCategoryTicks(data, xAxisKey, wrapperRef, xAxisInterval, sideways || names ? \"names\" : \"scale\");\n const column = sideways ? nameColumn(labels, measured) : undefined;\n const upright = useMemo(() => namesTick(measured.measure, \"x\"), [measured.measure]);\n const rows = useMemo(() => namesTick(measured.measure, \"y\", column), [measured.measure, column]);\n const solidColors = useChartColors(bars.length, false);\n const softColors = useChartColors(bars.length, true);\n const gridStroke = useGridStroke();\n const axisStyle = useAxisStyle();\n const isAnimated = useChartAnimation(animated);\n const radius = useRadius();\n const legendVisible = showLegend ?? bars.length >= 2;\n\n // Axis titles follow their data: a chart that turned itself sideways moves the value title under the value axis and\n // the category title above the names. Every title is horizontal (Analysis Function; data_visualisation#22).\n const valueTitle = horizontal === true ? xAxisLabel : yAxisLabel;\n const categoryTitle = horizontal === true ? yAxisLabel : xAxisLabel;\n const topTitle = sideways ? categoryTitle : valueTitle;\n const bottomTitle = sideways ? valueTitle : categoryTitle;\n const axisLabelStyle = { fontSize: \"var(--ds-font-size-xs)\", fontFamily: \"var(--ds-font-sans)\", fill: axisStyle.tick.fill };\n const bottomLabel = bottomTitle ? { value: bottomTitle, position: \"insideBottom\" as const, offset: -2, style: axisLabelStyle } : undefined;\n\n const groups = barGroups(bars, stacked);\n const perCategory = 1 + 0.5 * (groups - 1);\n const titles = [topTitle, bottomTitle].filter(Boolean).length;\n const size = sideways\n ? {\n model: \"rows\" as const,\n units: labels.length * perCategory,\n lines: twoLineNames(labels, column, measured),\n axis: titles ? `calc(${CHART_ROW} + ${titles} * ${TITLE_LINE_CSS})` : CHART_ROW,\n }\n : { model: \"ratio\" as const };\n // bars keep their thickness when the chart grows in a row: the rows spread instead\n const maxBarSize = sideways ? Math.max(4, Math.round((measured.rowPx * perCategory * 0.7) / groups)) : undefined;\n\n // Sprint 25.8.9 item 4: each bar series after the first fills with a pattern over its colour, as the legend shows it\n const surface = useResolvedToken(\"--ds-bg-surface\");\n const canvas = useResolvedToken(\"--ds-bg-canvas\");\n const ink = useResolvedToken(\"--ds-text-secondary\");\n const fills = bars.map((bar, i) => (bar.soft ? softColors[i] : solidColors[i]));\n const patterns = bars.map((_, i) => seriesPattern(chartId, i, bars.length));\n // item 26: a forecast bar's fill: its pattern's fainter twin (SeriesPatterns draws it where the fainter colour is\n // known), else the fainter colour itself; null leaves the bar see-through\n const aheadBarFill = (fill: string, pattern: string | undefined) => {\n const faint = aheadFill(fill, surface, canvas);\n return faint && pattern ? `url(#${aheadPattern(pattern)})` : faint;\n };\n const marks = useMemo<Record<string, SeriesMark>>(\n () => Object.fromEntries(bars.map((bar, i) => [bar.dataKey, { kind: \"fill\" as const, color: bar.soft ? softColors[i] : solidColors[i], edge: solidColors[i], pattern: seriesPattern(chartId, i, bars.length) }])),\n [bars, softColors, solidColors, chartId],\n );\n // item 26: from the forecast's first category, each bar draws fainter in a dashed outline\n const forecastAt = forecastIndex(data ?? [], xAxisKey, forecastFrom);\n // items 4 and 27: the chart's values as a table and its sentence, from the page's own rows\n const access = useMemo(() => cartesianAccess({\n kind: \"Bar chart\",\n data: data ?? [],\n categoryKey: xAxisKey,\n categoryHeading: categoryTitle,\n series: bars.map((b) => ({ dataKey: b.dataKey, label: b.label ?? b.dataKey })),\n format: fullFormat,\n over: names ? \"names\" : \"scale\",\n references,\n forecast: forecastAt >= 0 ? { from: forecastAt, label: forecastLabel } : undefined,\n }), [data, xAxisKey, categoryTitle, bars, fullFormat, names, references, forecastAt, forecastLabel]);\n\n if (!data?.length) return null;\n\n return (\n <ChartWrapper\n ref={mergeRefs(ref as Ref<HTMLElement>, wrapperRef as Ref<HTMLElement>) as Ref<HTMLDivElement>}\n height={height}\n size={size}\n chart=\"bar\"\n categoryKind={kind}\n categories={data.length}\n categoryAxis={sideways ? \"y\" : \"x\"}\n sideways={sideways}\n axisTitle={topTitle}\n formatValue={fullFormat}\n className={className}\n aria-label={ariaLabel}\n access={access}\n description={description}\n marks={marks}\n >\n <ResponsiveContainer width=\"100%\" height=\"100%\">\n <RechartsBarChart\n data={data}\n layout={sideways ? \"vertical\" : \"horizontal\"}\n stackOffset={anyStack(bars, stacked) ? \"sign\" : undefined}\n // names are fitted to their bands, so nothing hangs past the last bar: 4 px, not a margin sized from them\n margin={{ top: 4 + (topTitle ? titleLine(measured.px) : 0), right: sideways || names ? 4 : xTicks.endMargin, bottom: 4, left: 4 }}\n accessibilityLayer\n >\n <SeriesPatterns chartId={chartId} colors={fills} surface={surface} ahead={forecastAt >= 0} />\n {showGrid && (\n <CartesianGrid strokeDasharray=\"3 3\" stroke={gridStroke} vertical={!sideways} horizontal />\n )}\n {sideways ? (\n <>\n <XAxis type=\"number\" {...axisStyle.tick} axisLine={false} tickLine={false} height=\"auto\" label={bottomLabel} tickFormatter={tickFormat} />\n <YAxis\n dataKey={xAxisKey}\n type=\"category\"\n width={column ?? \"auto\"}\n {...axisStyle.tick}\n axisLine={false}\n tickLine={false}\n interval={0}\n tick={rows}\n />\n </>\n ) : (\n <>\n <XAxis\n dataKey={xAxisKey}\n {...axisStyle.tick}\n axisLine={false}\n tickLine={false}\n tick={names ? upright : xAxisTick}\n interval={xTicks.interval}\n ticks={xTicks.ticks}\n height=\"auto\"\n label={bottomLabel}\n />\n <YAxis width=\"auto\" {...axisStyle.tick} axisLine={false} tickLine={false} tickFormatter={tickFormat} />\n </>\n )}\n {showTooltip && <Tooltip content={<ChartTooltipContent />} cursor={{ fill: \"var(--ds-bg-muted)\", opacity: 0.5 }} />}\n {legendVisible && <ChartLegend order={bars.map((b) => b.dataKey)} />}\n {referenceElements(references, { axis: sideways ? \"x\" : \"y\", ink, format: (v) => fullFormat(v) })}\n {forecastAt >= 0 && <ForecastHatch id={forecastHatchId(chartId)} ink={ink} />}\n {forecastElements(data.map((row) => row[xAxisKey]), forecastAt, forecastLabel, { axis: sideways ? \"x\" : \"y\", ink, scale: \"band\", hatch: forecastHatchId(chartId) })}\n {bars.map((bar, i) => (\n <Bar\n key={bar.dataKey}\n dataKey={bar.dataKey}\n name={bar.label ?? bar.dataKey}\n fill={patterns[i] ? `url(#${patterns[i]})` : fills[i]}\n // a soft fill is a 30% tint: the solid outline keeps the bar's edge at the colour's own contrast (WCAG 1.4.11)\n stroke={bar.soft ? solidColors[i] : undefined}\n strokeWidth={bar.soft ? 1 : undefined}\n shape={barShape(bars, i, stacked, radius, sideways, forecastAt >= 0 ? { from: forecastAt, edge: solidColors[i], fill: aheadBarFill(fills[i], patterns[i]) } : undefined)}\n stackId={barStackOf(bar, stacked)}\n maxBarSize={maxBarSize}\n isAnimationActive={isAnimated}\n />\n ))}\n </RechartsBarChart>\n </ResponsiveContainer>\n </ChartWrapper>\n );\n}));\n","import { forwardRef, useId, useMemo, useRef, type Ref } from \"react\";\nimport {\n LineChart as RechartsLineChart,\n Line,\n XAxis,\n YAxis,\n CartesianGrid,\n Tooltip,\n ResponsiveContainer,\n} from \"recharts\";\nimport { useChartColors, useChartAnimation, useResolvedToken } from \"../../lib/chart-utils\";\nimport { ChartTooltipContent, ChartLegend, useGridStroke, useAxisStyle, xAxisTick, useCategoryTicks, useAxisMeasure, type XAxisInterval } from \"./ChartPrimitives\";\nimport { mergeRefs } from \"../../lib/slot\";\nimport { axisTickFormatter, fullValueFormatter, seriesValues, type ValueFormat } from \"./value-format\";\nimport { ChartWrapper, markChart } from \"./ChartWrapper\";\nimport { useFormatLocale } from \"../../lib/locale\";\nimport { cartesianAccess, type ChartReference } from \"./chart-access\";\nimport { ForecastHatch, forecastElements, forecastHatchId, forecastIndex, referenceElements, referenceValues } from \"./chart-references\";\nimport { lineDashes, type SeriesMark } from \"./series-marks\";\n\nexport interface LineDef {\n dataKey: string;\n label?: string;\n dashed?: boolean;\n}\n\nexport interface LineChartProps {\n /**\n * Which category ticks show. Leave it out: the chart measures its widest label with the chart's font and labels every\n * k-th category from the first, the last only when it falls on the step (Sprint 25.4 C-11, decision 7). A number\n * labels every Nth category instead. The Recharts strings (\"preserveStartEnd\") are accepted for compatibility and\n * mean the same measured labelling — they never hand the ticks back to Recharts' thinning (round 13).\n */\n xAxisInterval?: XAxisInterval;\n data: Record<string, unknown>[];\n lines: LineDef[];\n xAxisKey: string;\n /** \"auto\" (the default): two wide to one high. A preset or a number overrides it; a ChartContainer's own height wins. */\n height?: \"auto\" | \"sm\" | \"md\" | \"lg\" | number;\n curved?: boolean;\n showDots?: boolean;\n showGrid?: boolean;\n showTooltip?: boolean;\n showLegend?: boolean;\n xAxisLabel?: string;\n /** The value axis's title, drawn horizontally above the axis. */\n yAxisLabel?: string;\n /**\n * How the values read: \"number\" (the default) is compact on the axis from five digits up, in the page's language (1M, 750K), and in full in\n * the tooltip; \"percent\", \"milliseconds\" or \"bytes\" add their unit; a function formats both itself (Sprint 25.17 A27).\n */\n valueFormat?: ValueFormat;\n animated?: boolean;\n \"aria-label\"?: string;\n className?: string;\n /**\n * What the chart shows, in the page's words: a line above the drawing, in place of the sentence the chart works out\n * from its data (its series' trends and highest points), which it shows without one.\n */\n description?: string;\n /** Targets or limits across the plot: a line at `value`, or a band from `value` to `to`, each named by its `label`. */\n references?: ChartReference[];\n /**\n * The first category whose values are a forecast (its `xAxisKey` value): from there a pale hatched band, named by\n * `forecastLabel` (\"Forecast\" without one), runs to the chart's end, after a dashed line where it starts, and each line\n * keeps its own colour and mark through it. A period not yet over is marked the same\n * way, with the page's own words (\"So far this month\").\n */\n forecastFrom?: string | number;\n forecastLabel?: string;\n}\n\nexport const LineChart = markChart(forwardRef<HTMLDivElement, LineChartProps>(function LineChart({\n data,\n lines,\n xAxisKey,\n xAxisInterval,\n height = \"auto\",\n curved = true,\n showDots = false,\n showGrid = true,\n showTooltip = true,\n showLegend,\n xAxisLabel,\n yAxisLabel,\n valueFormat,\n animated,\n \"aria-label\": ariaLabel,\n className,\n description,\n references,\n forecastFrom,\n forecastLabel = \"Forecast\",\n}, ref) {\n const wrapperRef = useRef<HTMLDivElement | null>(null);\n // the axis reaches its references too (Sprint 25.8.9 item 25), so their labels' width is measured with the rest\n const values = useMemo(() => [...seriesValues(data ?? [], lines.map((s) => s.dataKey), false), ...referenceValues(references)], [data, lines, references]);\n // the chart's numbers in the locale the server and the hydrating browser share (Sprint 25.20)\n const locale = useFormatLocale();\n const tickFormat = useMemo(() => axisTickFormatter(values, valueFormat, locale), [values, valueFormat, locale]);\n const fullFormat = useMemo(() => fullValueFormatter(valueFormat, locale), [valueFormat, locale]);\n // a line runs over a scale (dates, times, numbers): its labels are thinned at an even step, never fitted as names\n const xTicks = useCategoryTicks(data, xAxisKey, wrapperRef, xAxisInterval, \"scale\");\n const measured = useAxisMeasure(wrapperRef, !!yAxisLabel && (data?.length ?? 0) > 0);\n const colors = useChartColors(lines.length, false);\n const gridStroke = useGridStroke();\n const axisStyle = useAxisStyle();\n const isAnimated = useChartAnimation(animated);\n const legendVisible = showLegend ?? lines.length >= 2;\n const axisLabelStyle = { fontSize: \"var(--ds-font-size-xs)\", fontFamily: \"var(--ds-font-sans)\", fill: axisStyle.tick.fill };\n const top = 4 + (yAxisLabel ? Math.ceil(measured.px * 1.5) + 4 : 0);\n const ink = useResolvedToken(\"--ds-text-secondary\");\n // Sprint 25.8.9 item 4: each line after the first draws with a dash of its own, which the legend and tooltip show too\n // each line's own dash, a line the page marks dashed never drawn the same as another (Sprint 25.8.9)\n const dashes = useMemo(() => lineDashes(lines), [lines]);\n const marks = useMemo<Record<string, SeriesMark>>(\n () => Object.fromEntries(lines.map((l, i) => [l.dataKey, { kind: \"line\" as const, color: colors[i], dash: dashes[i] }])),\n [lines, colors, dashes],\n );\n // item 26: from the forecast's first category, a hatched band named by its label\n const forecastAt = forecastIndex(data ?? [], xAxisKey, forecastFrom);\n const hatch = forecastHatchId(useId());\n // items 4 and 27: the chart's values as a table and its sentence, from the page's own rows\n const access = useMemo(() => cartesianAccess({\n kind: \"Line chart\",\n data: data ?? [],\n categoryKey: xAxisKey,\n categoryHeading: xAxisLabel,\n series: lines.map((l) => ({ dataKey: l.dataKey, label: l.label ?? l.dataKey })),\n format: fullFormat,\n over: \"scale\",\n references,\n forecast: forecastAt >= 0 ? { from: forecastAt, label: forecastLabel } : undefined,\n }), [data, xAxisKey, xAxisLabel, lines, fullFormat, references, forecastAt, forecastLabel]);\n\n if (!data?.length) return null;\n\n return (\n <ChartWrapper\n ref={mergeRefs(ref as Ref<HTMLElement>, wrapperRef as Ref<HTMLElement>) as Ref<HTMLDivElement>}\n height={height}\n size={{ model: \"ratio\" }}\n chart=\"line\"\n categoryKind=\"scale\"\n categories={data.length}\n categoryAxis=\"x\"\n axisTitle={yAxisLabel}\n formatValue={fullFormat}\n className={className}\n aria-label={ariaLabel}\n access={access}\n description={description}\n marks={marks}\n >\n <ResponsiveContainer width=\"100%\" height=\"100%\">\n <RechartsLineChart data={data} margin={{ top, right: xTicks.endMargin, bottom: 4, left: 4 }} accessibilityLayer>\n {showGrid && <CartesianGrid strokeDasharray=\"3 3\" stroke={gridStroke} />}\n <XAxis\n dataKey={xAxisKey}\n {...axisStyle.tick}\n axisLine={false}\n tickLine={false}\n tick={xAxisTick}\n interval={xTicks.interval}\n ticks={xTicks.ticks}\n height=\"auto\"\n label={xAxisLabel ? { value: xAxisLabel, position: \"insideBottom\", offset: -2, style: axisLabelStyle } : undefined}\n />\n <YAxis width=\"auto\" {...axisStyle.tick} axisLine={false} tickLine={false} tickFormatter={tickFormat} />\n {showTooltip && <Tooltip content={<ChartTooltipContent />} />}\n {legendVisible && <ChartLegend order={lines.map((l) => l.dataKey)} />}\n {referenceElements(references, { axis: \"y\", ink, format: (v) => fullFormat(v) })}\n {forecastAt >= 0 && <ForecastHatch id={hatch} ink={ink} />}\n {forecastElements(data.map((row) => row[xAxisKey]), forecastAt, forecastLabel, { axis: \"y\", ink, scale: \"point\", hatch })}\n {lines.map((line, i) => (\n <Line\n key={line.dataKey}\n type={curved ? \"monotone\" : \"linear\"}\n dataKey={line.dataKey}\n name={line.label ?? line.dataKey}\n stroke={colors[i]}\n strokeWidth={2}\n strokeDasharray={dashes[i]}\n dot={showDots}\n activeDot={{ r: 5, strokeWidth: 2 }}\n isAnimationActive={isAnimated}\n />\n ))}\n </RechartsLineChart>\n </ResponsiveContainer>\n </ChartWrapper>\n );\n}));\n","import { forwardRef, useId, useMemo, useRef, type Ref } from \"react\";\nimport {\n AreaChart as RechartsAreaChart,\n Area,\n XAxis,\n YAxis,\n CartesianGrid,\n Tooltip,\n ResponsiveContainer,\n} from \"recharts\";\nimport { useChartColors, useChartAnimation, useResolvedToken } from \"../../lib/chart-utils\";\nimport { ChartTooltipContent, ChartLegend, useGridStroke, useAxisStyle, xAxisTick, useCategoryTicks, useAxisMeasure, type XAxisInterval } from \"./ChartPrimitives\";\nimport { mergeRefs } from \"../../lib/slot\";\nimport { axisTickFormatter, fullValueFormatter, seriesValues, type ValueFormat } from \"./value-format\";\nimport { ChartWrapper, markChart } from \"./ChartWrapper\";\nimport { useFormatLocale } from \"../../lib/locale\";\nimport { cartesianAccess, type ChartReference } from \"./chart-access\";\nimport { ForecastHatch, forecastElements, forecastHatchId, forecastIndex, referenceElements, referenceValues } from \"./chart-references\";\nimport { seriesDash, type SeriesMark } from \"./series-marks\";\n\nexport interface AreaDef {\n dataKey: string;\n label?: string;\n}\n\nexport interface AreaChartProps {\n /**\n * Which category ticks show. Leave it out: the chart measures its widest label with the chart's font and labels every\n * k-th category from the first, the last only when it falls on the step (Sprint 25.4 C-11, decision 7). A number\n * labels every Nth category instead. The Recharts strings (\"preserveStartEnd\") are accepted for compatibility and\n * mean the same measured labelling — they never hand the ticks back to Recharts' thinning (round 13).\n */\n xAxisInterval?: XAxisInterval;\n data: Record<string, unknown>[];\n areas: AreaDef[];\n xAxisKey: string;\n /** \"auto\" (the default): two wide to one high. A preset or a number overrides it; a ChartContainer's own height wins. */\n height?: \"auto\" | \"sm\" | \"md\" | \"lg\" | number;\n stacked?: boolean;\n curved?: boolean;\n showGrid?: boolean;\n showTooltip?: boolean;\n showLegend?: boolean;\n gradient?: boolean;\n xAxisLabel?: string;\n /** The value axis's title, drawn horizontally above the axis. */\n yAxisLabel?: string;\n /**\n * How the values read: \"number\" (the default) is compact on the axis from five digits up, in the page's language (1M, 750K), and in full in\n * the tooltip; \"percent\", \"milliseconds\" or \"bytes\" add their unit; a function formats both itself (Sprint 25.17 A27).\n */\n valueFormat?: ValueFormat;\n animated?: boolean;\n \"aria-label\"?: string;\n className?: string;\n /**\n * What the chart shows, in the page's words: a line above the drawing, in place of the sentence the chart works out\n * from its data (its series' trends and highest points), which it shows without one.\n */\n description?: string;\n /** Targets or limits across the plot: a line at `value`, or a band from `value` to `to`, each named by its `label`. */\n references?: ChartReference[];\n /**\n * The first category whose values are a forecast (its `xAxisKey` value): from there a pale hatched band, named by\n * `forecastLabel` (\"Forecast\" without one), runs to the chart's end, after a dashed line where it starts, and each area\n * keeps its own colour and mark through it. A period not yet over is marked the same\n * way, with the page's own words (\"So far this month\").\n */\n forecastFrom?: string | number;\n forecastLabel?: string;\n}\n\nexport const AreaChart = markChart(forwardRef<HTMLDivElement, AreaChartProps>(function AreaChart({\n data,\n areas,\n xAxisKey,\n xAxisInterval,\n height = \"auto\",\n stacked = false,\n curved = true,\n showGrid = true,\n showTooltip = true,\n showLegend,\n gradient = true,\n xAxisLabel,\n yAxisLabel,\n valueFormat,\n animated,\n \"aria-label\": ariaLabel,\n className,\n description,\n references,\n forecastFrom,\n forecastLabel = \"Forecast\",\n}, ref) {\n const wrapperRef = useRef<HTMLDivElement | null>(null);\n // the axis reaches its references too (Sprint 25.8.9 item 25), so their labels' width is measured with the rest\n const values = useMemo(() => [...seriesValues(data ?? [], areas.map((s) => s.dataKey), stacked), ...referenceValues(references)], [data, areas, stacked, references]);\n // the chart's numbers in the locale the server and the hydrating browser share (Sprint 25.20)\n const locale = useFormatLocale();\n const tickFormat = useMemo(() => axisTickFormatter(values, valueFormat, locale), [values, valueFormat, locale]);\n const fullFormat = useMemo(() => fullValueFormatter(valueFormat, locale), [valueFormat, locale]);\n // an area runs over a scale (dates, times, numbers): its labels are thinned at an even step, never fitted as names\n const xTicks = useCategoryTicks(data, xAxisKey, wrapperRef, xAxisInterval, \"scale\");\n const measured = useAxisMeasure(wrapperRef, !!yAxisLabel && (data?.length ?? 0) > 0);\n const instanceId = useId();\n const solidColors = useChartColors(areas.length, false);\n const softColors = useChartColors(areas.length, true);\n const gridStroke = useGridStroke();\n const axisStyle = useAxisStyle();\n const isAnimated = useChartAnimation(animated);\n const legendVisible = showLegend ?? areas.length >= 2;\n const axisLabelStyle = { fontSize: \"var(--ds-font-size-xs)\", fontFamily: \"var(--ds-font-sans)\", fill: axisStyle.tick.fill };\n const top = 4 + (yAxisLabel ? Math.ceil(measured.px * 1.5) + 4 : 0);\n const ink = useResolvedToken(\"--ds-text-secondary\");\n // Sprint 25.8.9 item 4: each area after the first draws its outline with a dash of its own, as the legend shows it\n const dashes = areas.map((_, i) => seriesDash(i, areas.length));\n const marks = useMemo<Record<string, SeriesMark>>(\n () => Object.fromEntries(areas.map((a, i) => [a.dataKey, { kind: \"line\" as const, color: solidColors[i], dash: seriesDash(i, areas.length) }])),\n [areas, solidColors],\n );\n // item 26: from the forecast's first category, a hatched band named by its label\n const forecastAt = forecastIndex(data ?? [], xAxisKey, forecastFrom);\n const hatch = forecastHatchId(instanceId);\n // items 4 and 27: the chart's values as a table and its sentence, from the page's own rows\n const access = useMemo(() => cartesianAccess({\n kind: \"Area chart\",\n data: data ?? [],\n categoryKey: xAxisKey,\n categoryHeading: xAxisLabel,\n series: areas.map((a) => ({ dataKey: a.dataKey, label: a.label ?? a.dataKey })),\n format: fullFormat,\n over: \"scale\",\n references,\n forecast: forecastAt >= 0 ? { from: forecastAt, label: forecastLabel } : undefined,\n }), [data, xAxisKey, xAxisLabel, areas, fullFormat, references, forecastAt, forecastLabel]);\n\n if (!data?.length) return null;\n\n return (\n <ChartWrapper\n ref={mergeRefs(ref as Ref<HTMLElement>, wrapperRef as Ref<HTMLElement>) as Ref<HTMLDivElement>}\n height={height}\n size={{ model: \"ratio\" }}\n chart=\"area\"\n categoryKind=\"scale\"\n categories={data.length}\n categoryAxis=\"x\"\n axisTitle={yAxisLabel}\n formatValue={fullFormat}\n className={className}\n aria-label={ariaLabel}\n access={access}\n description={description}\n marks={marks}\n >\n <ResponsiveContainer width=\"100%\" height=\"100%\">\n <RechartsAreaChart data={data} margin={{ top, right: xTicks.endMargin, bottom: 4, left: 4 }} accessibilityLayer>\n <defs>\n {areas.map((area, i) => (\n <linearGradient key={area.dataKey} id={`gradient-${instanceId}-${area.dataKey}`} x1=\"0\" y1=\"0\" x2=\"0\" y2=\"1\">\n <stop offset=\"0%\" stopColor={softColors[i]} stopOpacity={1} />\n <stop offset=\"95%\" stopColor={softColors[i]} stopOpacity={0.1} />\n </linearGradient>\n ))}\n </defs>\n {showGrid && <CartesianGrid strokeDasharray=\"3 3\" stroke={gridStroke} />}\n <XAxis\n dataKey={xAxisKey}\n {...axisStyle.tick}\n axisLine={false}\n tickLine={false}\n tick={xAxisTick}\n interval={xTicks.interval}\n ticks={xTicks.ticks}\n height=\"auto\"\n label={xAxisLabel ? { value: xAxisLabel, position: \"insideBottom\", offset: -2, style: axisLabelStyle } : undefined}\n />\n <YAxis width=\"auto\" {...axisStyle.tick} axisLine={false} tickLine={false} tickFormatter={tickFormat} />\n {showTooltip && <Tooltip content={<ChartTooltipContent />} />}\n {legendVisible && <ChartLegend order={areas.map((a) => a.dataKey)} />}\n {referenceElements(references, { axis: \"y\", ink, format: (v) => fullFormat(v) })}\n {forecastAt >= 0 && <ForecastHatch id={hatch} ink={ink} />}\n {forecastElements(data.map((row) => row[xAxisKey]), forecastAt, forecastLabel, { axis: \"y\", ink, scale: \"point\", hatch })}\n {areas.map((area, i) => (\n <Area\n key={area.dataKey}\n type={curved ? \"monotone\" : \"linear\"}\n dataKey={area.dataKey}\n name={area.label ?? area.dataKey}\n stroke={solidColors[i]}\n strokeWidth={2}\n strokeDasharray={dashes[i]}\n fill={gradient ? `url(#gradient-${instanceId}-${area.dataKey})` : softColors[i]}\n stackId={stacked ? \"stack\" : undefined}\n isAnimationActive={isAnimated}\n />\n ))}\n </RechartsAreaChart>\n </ResponsiveContainer>\n </ChartWrapper>\n );\n}));\n","import { forwardRef, useId, useMemo } from \"react\";\nimport {\n PieChart as RechartsPieChart,\n Pie,\n Cell,\n Tooltip,\n ResponsiveContainer,\n} from \"recharts\";\nimport { useChartColors, useChartAnimation, useResolvedToken } from \"../../lib/chart-utils\";\nimport { ChartTooltipContent, ChartLegend } from \"./ChartPrimitives\";\nimport { ChartWrapper, markChart } from \"./ChartWrapper\";\nimport { partsAccess } from \"./chart-access\";\nimport { SeriesPatterns, seriesPattern, type SeriesMark } from \"./series-marks\";\nimport { fullValueFormatter, numberOf } from \"./value-format\";\nimport { useFormatLocale } from \"../../lib/locale\";\n\nexport interface PieChartProps {\n data: { name: string; value: number; [key: string]: unknown }[];\n /** \"auto\" (the default): square. A preset or a number overrides it; a ChartContainer's own height wins. */\n height?: \"auto\" | \"sm\" | \"md\" | \"lg\" | number;\n donut?: boolean;\n showTooltip?: boolean;\n showLegend?: boolean;\n showLabels?: boolean;\n animated?: boolean;\n \"aria-label\"?: string;\n className?: string;\n /**\n * What the chart shows, in the page's words: a line above the drawing, in place of the sentence the chart works out\n * from its parts (the largest and the smallest, with their shares), which it shows without one.\n */\n description?: string;\n}\n\nexport const PieChart = markChart(forwardRef<HTMLDivElement, PieChartProps>(function PieChart({\n data,\n height = \"auto\",\n donut = false,\n showTooltip = true,\n showLegend = true,\n showLabels = false,\n animated,\n \"aria-label\": ariaLabel,\n className,\n description,\n}, ref) {\n const colors = useChartColors(data.length, false);\n const chartId = useId();\n const surface = useResolvedToken(\"--ds-bg-surface\");\n const locale = useFormatLocale();\n const format = useMemo(() => fullValueFormatter(undefined, locale), [locale]);\n const isAnimated = useChartAnimation(animated);\n\n const renderLabel = showLabels\n ? ({ percent }: { percent?: number }) => `${((percent ?? 0) * 100).toFixed(0)}%`\n : false;\n\n // the chart's own fields alone: recharts draws each slice with its row's fields, so a row's `role` or `aria-label`\n // became the slice's (Sprint 25.29 item 14)\n // a number written as text (\"30\") is drawn as the table and the sentence read it: Recharts takes it as nothing (Sprint 25.8.9)\n const chartData = data.map((d) => ({ name: d.name, value: numberOf(d.value) ?? 0 }));\n // Sprint 25.8.9 item 4: each slice after the first fills with a pattern over its colour, as the legend shows it (by name)\n const fills = data.map((_, i) => colors[i % colors.length]);\n const marks = useMemo<Record<string, SeriesMark>>(\n () => Object.fromEntries(data.map((d, i) => [d.name, { kind: \"fill\" as const, color: colors[i % colors.length], pattern: seriesPattern(chartId, i, data.length) }])),\n [data, colors, chartId],\n );\n // items 4 and 27: the slices as a table and the chart's sentence, from the page's own rows\n const access = useMemo(() => partsAccess({ kind: \"pie\", items: data.map((d) => ({ name: d.name, value: d.value })), format }), [data, format]);\n\n if (!data?.length) return null;\n\n return (\n <ChartWrapper ref={ref} height={height} size={{ model: \"square\" }} chart=\"pie\" className={className} aria-label={ariaLabel} access={access} description={description} marks={marks}>\n <ResponsiveContainer width=\"100%\" height=\"100%\">\n <RechartsPieChart accessibilityLayer>\n <SeriesPatterns chartId={chartId} colors={fills} surface={surface} />\n <Pie\n data={chartData}\n dataKey=\"value\"\n nameKey=\"name\"\n cx=\"50%\"\n cy=\"50%\"\n outerRadius=\"75%\"\n innerRadius={donut ? \"55%\" : 0}\n label={renderLabel}\n labelLine={showLabels}\n isAnimationActive={isAnimated}\n fontSize=\"var(--ds-font-size-xs)\"\n fontFamily=\"var(--ds-font-sans)\"\n >\n {data.map((_, i) => {\n const pattern = seriesPattern(chartId, i, data.length);\n return <Cell key={i} fill={pattern ? `url(#${pattern})` : fills[i]} />;\n })}\n </Pie>\n {showTooltip && <Tooltip content={<ChartTooltipContent />} />}\n {showLegend && <ChartLegend order={data.map((d) => d.name)} by=\"value\" />}\n </RechartsPieChart>\n </ResponsiveContainer>\n </ChartWrapper>\n );\n}));\n","import { forwardRef, useId, useMemo, useRef, type Ref } from \"react\";\nimport {\n ComposedChart,\n Bar,\n Line,\n XAxis,\n YAxis,\n CartesianGrid,\n Tooltip,\n ResponsiveContainer,\n} from \"recharts\";\nimport { useChartColors, useChartAnimation, useResolvedToken } from \"../../lib/chart-utils\";\nimport { categoryKind as guessCategoryKind } from \"../../lib/chart-categories\";\nimport { cartesianAccess, type ChartReference } from \"./chart-access\";\nimport { ForecastHatch, forecastElements, forecastHatchId, forecastIndex, referenceElements, referenceValues } from \"./chart-references\";\nimport { SeriesPatterns, aheadFill, aheadPattern, lineDashes, seriesPattern, type SeriesMark } from \"./series-marks\";\nimport {\n ChartTooltipContent, ChartLegend, useGridStroke, useAxisStyle, useRadius, xAxisTick, namesTick, useCategoryTicks,\n useAxisMeasure, useSidewaysSwitch, valueAxisWidth, nameColumn, twoLineNames, type XAxisInterval,\n} from \"./ChartPrimitives\";\nimport { mergeRefs } from \"../../lib/slot\";\nimport { axisExtent, axisTickFormatter, fullValueFormatter, type ValueFormat } from \"./value-format\";\nimport { ChartWrapper, CHART_ROW, markChart } from \"./ChartWrapper\";\nimport { anyStack, barGroups, barShape, barStackOf, type BarDef } from \"./BarChart\";\nimport type { LineDef } from \"./LineChart\";\nimport { useFormatLocale } from \"../../lib/locale\";\nimport { useHydrated } from \"../../lib/hydrated\";\n\nexport interface CompositeChartProps {\n /**\n * Which category ticks show on an axis of dates or numbers. Leave it out: the chart measures its widest label with\n * the chart's font and labels every k-th category from the first, the last only when it falls on the step (Sprint\n * 25.4 C-11, decision 7). A number labels every Nth category instead. The Recharts strings (\"preserveStartEnd\") are\n * accepted for compatibility and mean the same measured labelling (round 13). A names axis is never thinned.\n */\n xAxisInterval?: XAxisInterval;\n data: Record<string, unknown>[];\n bars: BarDef[];\n lines: LineDef[];\n xAxisKey: string;\n /**\n * \"auto\" (the default): two wide to one high; sideways, a row per category. A preset or a number overrides it; a\n * ChartContainer's own height wins.\n */\n height?: \"auto\" | \"sm\" | \"md\" | \"lg\" | number;\n /** Every bar without a stackId joins one stack; lines draw over it (Sprint 25.7, C4). A bar's stackId works too. */\n stacked?: boolean;\n /**\n * The lines on a second axis of their own, on the right, for a line whose unit differs from the bars'. Default: true\n * for bars side by side, false once the bars stack (`stacked` or a bar's stackId), so a capacity or a target line\n * reads against the stack's own scale. An explicit value wins.\n */\n dualAxis?: boolean;\n /**\n * What the categories are. \"names\" are never skipped: each wraps onto two lines, then ends with \"…\", with the full\n * name on hover. \"scale\" (dates, times, numbers) is labelled at an even step. Leave it out: guessed from the labels.\n */\n categoryKind?: \"names\" | \"scale\";\n /**\n * Bars running sideways, one row per category, with the lines crossing the rows. Leave it out: a chart of names turns\n * itself sideways when a name would be cut to fewer than six characters, and back when there's room (D8). true or\n * false forces either.\n */\n horizontal?: boolean;\n showGrid?: boolean;\n showTooltip?: boolean;\n showLegend?: boolean;\n xAxisLabel?: string;\n /** The value axis's title, drawn horizontally above the axis. */\n yAxisLabel?: string;\n /**\n * How the bars' values read (and the lines', on one axis): \"number\" (the default) is compact on the axis, in the\n * page's language (1M, 750K), and in full in the tooltip; \"percent\", \"milliseconds\" or \"bytes\" add their unit; a function\n * formats both itself (Sprint 25.17 A27).\n */\n valueFormat?: ValueFormat;\n /** How the lines' values read on their own axis (dualAxis), when their unit differs from the bars'. Default: valueFormat. */\n lineValueFormat?: ValueFormat;\n animated?: boolean;\n \"aria-label\"?: string;\n className?: string;\n /**\n * What the chart shows, in the page's words: a line above the drawing, in place of the sentence the chart works out\n * from its data, which it shows without one.\n */\n description?: string;\n /** Targets or limits on the bars' axis: a line at `value`, or a band from `value` to `to`, each named by its `label`. */\n references?: ChartReference[];\n /**\n * The first category whose values are a forecast (its `xAxisKey` value): from there each bar draws fainter in a dashed\n * outline of its own colour, in a pale hatched band named by `forecastLabel` (\"Forecast\" without one) that runs to the\n * chart's end, after a dashed line where it starts; the lines keep their own colour and mark through it.\n */\n forecastFrom?: string | number;\n forecastLabel?: string;\n}\n\nexport const CompositeChart = markChart(forwardRef<HTMLDivElement, CompositeChartProps>(function CompositeChart({\n data,\n bars,\n lines,\n xAxisKey,\n xAxisInterval,\n height = \"auto\",\n stacked = false,\n dualAxis = !anyStack(bars, stacked),\n categoryKind,\n horizontal,\n showGrid = true,\n showTooltip = true,\n showLegend = true,\n xAxisLabel,\n yAxisLabel,\n valueFormat,\n lineValueFormat = valueFormat,\n animated,\n \"aria-label\": ariaLabel,\n className,\n description,\n references,\n forecastFrom,\n forecastLabel = \"Forecast\",\n}, ref) {\n const wrapperRef = useRef<HTMLDivElement | null>(null);\n const chartId = useId();\n const labels = useMemo(() => (data ?? []).map((d) => String(d[xAxisKey] ?? \"\")), [data, xAxisKey]);\n // the chart's numbers in the locale the server and the hydrating browser share (Sprint 25.20)\n const locale = useFormatLocale();\n // its labels' kind as BarChart reads it: the server's locale while hydrating, the browser's languages from then on\n const hydrated = useHydrated();\n const kind = categoryKind ?? guessCategoryKind((data ?? []).map((d) => d[xAxisKey]), hydrated ? undefined : locale);\n const names = kind === \"names\";\n const measured = useAxisMeasure(wrapperRef, (data?.length ?? 0) > 0);\n // the bars' axis (and the lines', on one axis), and the lines' own on the right with a second axis\n const [values, lineValues] = useMemo(() => {\n // the bars' stacks up and down from zero, as BarChart reads them (axisExtent), and the lines on the same axis unless\n // they have their own\n const values = axisExtent(data ?? [], [\n ...bars.map((bar) => ({ dataKey: bar.dataKey, stack: barStackOf(bar, stacked) ?? null })),\n ...(dualAxis ? [] : lines.map((l) => ({ dataKey: l.dataKey, stack: null }))),\n ]);\n const lineValues = (data ?? []).flatMap((row) => lines.map((l) => Number(row[l.dataKey])));\n // the bars' axis reaches its references too (Sprint 25.8.9 item 25), or the lines' own in a chart with no bars\n const onLines = !bars.length && dualAxis;\n return [[...values, ...(onLines ? [] : referenceValues(references))], [...lineValues, ...(onLines ? referenceValues(references) : [])]];\n }, [data, bars, lines, stacked, dualAxis, references]);\n const tickFormat = useMemo(() => axisTickFormatter(values, valueFormat, locale), [values, valueFormat, locale]);\n const lineTickFormat = useMemo(() => axisTickFormatter(lineValues, lineValueFormat, locale), [lineValues, lineValueFormat, locale]);\n const fullFormat = useMemo(() => {\n const bar = fullValueFormatter(valueFormat, locale);\n const line = fullValueFormatter(dualAxis ? lineValueFormat : valueFormat, locale);\n const lineKeys = new Set(lines.map((l) => l.dataKey));\n return (value: number, dataKey?: string) => (dataKey && lineKeys.has(dataKey) ? line(value) : bar(value));\n }, [valueFormat, lineValueFormat, dualAxis, lines, locale]);\n // the bars' axis sets the left column's width; with a second axis the lines' ticks take the right edge\n const axisWidth = useMemo(() => {\n if (!measured.measure) return 0;\n return valueAxisWidth(values, measured.measure, tickFormat) + (dualAxis ? valueAxisWidth(lineValues, measured.measure, lineTickFormat) : 0);\n }, [measured.measure, values, lineValues, tickFormat, lineTickFormat, dualAxis]);\n const turned = useSidewaysSwitch(horizontal === undefined && names, labels, measured, axisWidth, 8);\n const sideways = horizontal ?? turned;\n const xTicks = useCategoryTicks(data, xAxisKey, wrapperRef, xAxisInterval, sideways ? \"names\" : kind);\n const column = sideways ? nameColumn(labels, measured) : undefined;\n const tick = useMemo(() => (names ? namesTick(measured.measure, \"x\") : xAxisTick), [names, measured.measure]);\n const rows = useMemo(() => namesTick(measured.measure, \"y\", column), [measured.measure, column]);\n const barSoftColors = useChartColors(bars.length, true);\n const barSolidColors = useChartColors(bars.length, false);\n const lineColors = useChartColors(lines.length, false);\n const gridStroke = useGridStroke();\n const axisStyle = useAxisStyle();\n const isAnimated = useChartAnimation(animated);\n const radius = useRadius();\n const axisLabelStyle = { fontSize: \"var(--ds-font-size-xs)\", fontFamily: \"var(--ds-font-sans)\", fill: axisStyle.tick.fill };\n // axis titles follow their data: sideways, the value title goes under the value axis, the category title above the names\n const topTitle = sideways ? xAxisLabel : yAxisLabel;\n const bottomTitle = sideways ? yAxisLabel : xAxisLabel;\n const bottomLabel = bottomTitle ? { value: bottomTitle, position: \"insideBottom\" as const, offset: -2, style: axisLabelStyle } : undefined;\n const top = 4 + (topTitle ? Math.ceil(measured.px * 1.5) + 4 : 0);\n const groups = barGroups(bars, stacked);\n const perCategory = 1 + 0.5 * (groups - 1);\n const titles = [topTitle, bottomTitle].filter(Boolean).length + (sideways && dualAxis ? 1 : 0);\n const size = sideways\n ? {\n model: \"rows\" as const,\n units: labels.length * perCategory,\n lines: twoLineNames(labels, column, measured),\n axis: titles ? `calc(${CHART_ROW} + ${titles} * calc(1.5 * var(--ds-font-size-xs) + 4px))` : CHART_ROW,\n }\n : { model: \"ratio\" as const };\n const maxBarSize = sideways ? Math.max(4, Math.round((measured.rowPx * perCategory * 0.7) / groups)) : undefined;\n // the bars read against the left (or bottom) axis; the lines against their own when dualAxis\n const barAxis = sideways ? { xAxisId: \"left\" } : { yAxisId: \"left\" };\n const lineAxis = sideways ? { xAxisId: dualAxis ? \"right\" : \"left\" } : { yAxisId: dualAxis ? \"right\" : \"left\" };\n // Sprint 25.8.9 items 25 and 26: references and the forecast's band go on the bars' value axis, or the lines' in a chart\n // with no bars (an axis with nothing on it has no scale to draw them by)\n const valueAxisId = bars.length || !dualAxis ? \"left\" : \"right\";\n // (and its category axis is Recharts' point scale with no bars, its band scale with them: the forecast's band follows it)\n\n // Sprint 25.8.9 item 4: bars and lines differ by form; among the bars, each after the first fills with a pattern, and\n // among the lines, each after the first draws a dash, as the legend shows them\n const surface = useResolvedToken(\"--ds-bg-surface\");\n const canvas = useResolvedToken(\"--ds-bg-canvas\");\n const ink = useResolvedToken(\"--ds-text-secondary\");\n const patterns = bars.map((_, i) => seriesPattern(chartId, i, bars.length));\n // item 26: a forecast bar's fill, its pattern's fainter twin, else the fainter colour (BarChart's rule)\n const aheadBarFill = (fill: string, pattern: string | undefined) => {\n const faint = aheadFill(fill, surface, canvas);\n return faint && pattern ? `url(#${aheadPattern(pattern)})` : faint;\n };\n // each line's own dash, a line the page marks dashed never drawn the same as another (Sprint 25.8.9)\n const dashes = useMemo(() => lineDashes(lines), [lines]);\n const marks = useMemo<Record<string, SeriesMark>>(() => Object.fromEntries([\n ...bars.map((bar, i) => [bar.dataKey, { kind: \"fill\" as const, color: barSoftColors[i], edge: barSolidColors[i], pattern: seriesPattern(chartId, i, bars.length) }]),\n ...lines.map((line, i) => [line.dataKey, { kind: \"line\" as const, color: lineColors[i], dash: dashes[i] }]),\n ]), [bars, lines, barSoftColors, barSolidColors, lineColors, chartId, dashes]);\n // item 26: from the forecast's first category, the bars fainter in a dashed outline, in a hatched band named by its label\n const forecastAt = forecastIndex(data ?? [], xAxisKey, forecastFrom);\n // items 4 and 27: the chart's values as a table and its sentence, from the page's own rows\n const access = useMemo(() => cartesianAccess({\n kind: \"Bar and line chart\",\n data: data ?? [],\n categoryKey: xAxisKey,\n categoryHeading: xAxisLabel,\n series: [...bars, ...lines].map((s) => ({ dataKey: s.dataKey, label: s.label ?? s.dataKey })),\n format: fullFormat,\n over: names ? \"names\" : \"scale\",\n references,\n forecast: forecastAt >= 0 ? { from: forecastAt, label: forecastLabel } : undefined,\n }), [data, xAxisKey, xAxisLabel, bars, lines, fullFormat, names, references, forecastAt, forecastLabel]);\n\n if (!data?.length) return null;\n\n return (\n <ChartWrapper\n ref={mergeRefs(ref as Ref<HTMLElement>, wrapperRef as Ref<HTMLElement>) as Ref<HTMLDivElement>}\n height={height}\n size={size}\n chart=\"composite\"\n categoryKind={kind}\n categories={data.length}\n categoryAxis={sideways ? \"y\" : \"x\"}\n sideways={sideways}\n axisTitle={topTitle}\n formatValue={fullFormat}\n className={className}\n aria-label={ariaLabel}\n access={access}\n description={description}\n marks={marks}\n >\n <ResponsiveContainer width=\"100%\" height=\"100%\">\n <ComposedChart\n data={data}\n layout={sideways ? \"vertical\" : \"horizontal\"}\n stackOffset={anyStack(bars, stacked) ? \"sign\" : undefined}\n // names are fitted to their bands, so nothing hangs past the last bar\n margin={{ top, right: sideways || names ? 4 : xTicks.endMargin, bottom: 4, left: 4 }}\n accessibilityLayer\n >\n <SeriesPatterns chartId={chartId} colors={barSoftColors} surface={surface} ahead={forecastAt >= 0} />\n {showGrid && <CartesianGrid strokeDasharray=\"3 3\" stroke={gridStroke} vertical={!sideways} horizontal />}\n {sideways ? (\n <>\n <XAxis xAxisId=\"left\" type=\"number\" {...axisStyle.tick} axisLine={false} tickLine={false} height=\"auto\" label={bottomLabel} tickFormatter={tickFormat} />\n {dualAxis && <XAxis xAxisId=\"right\" type=\"number\" orientation=\"top\" {...axisStyle.tick} axisLine={false} tickLine={false} height=\"auto\" tickFormatter={lineTickFormat} />}\n <YAxis\n dataKey={xAxisKey}\n type=\"category\"\n width={column ?? \"auto\"}\n {...axisStyle.tick}\n axisLine={false}\n tickLine={false}\n interval={0}\n tick={rows}\n />\n </>\n ) : (\n <>\n <XAxis\n dataKey={xAxisKey}\n {...axisStyle.tick}\n axisLine={false}\n tickLine={false}\n tick={tick}\n interval={xTicks.interval}\n ticks={xTicks.ticks}\n height=\"auto\"\n label={bottomLabel}\n />\n <YAxis yAxisId=\"left\" width=\"auto\" {...axisStyle.tick} axisLine={false} tickLine={false} tickFormatter={tickFormat} />\n {dualAxis && (\n <YAxis yAxisId=\"right\" orientation=\"right\" width=\"auto\" {...axisStyle.tick} axisLine={false} tickLine={false} tickFormatter={lineTickFormat} />\n )}\n </>\n )}\n {showTooltip && <Tooltip content={<ChartTooltipContent />} />}\n {showLegend && <ChartLegend order={[...bars.map((b) => b.dataKey), ...lines.map((l) => l.dataKey)]} />}\n {referenceElements(references, { axis: sideways ? \"x\" : \"y\", axisId: valueAxisId, ink, format: (v) => fullFormat(v, valueAxisId === \"right\" ? lines[0]?.dataKey : undefined) })}\n {forecastAt >= 0 && <ForecastHatch id={forecastHatchId(chartId)} ink={ink} />}\n {forecastElements(data.map((row) => row[xAxisKey]), forecastAt, forecastLabel, { axis: sideways ? \"x\" : \"y\", axisId: valueAxisId, ink, scale: bars.length ? \"band\" : \"point\", hatch: forecastHatchId(chartId) })}\n {bars.map((bar, i) => (\n <Bar\n key={bar.dataKey}\n dataKey={bar.dataKey}\n name={bar.label ?? bar.dataKey}\n fill={patterns[i] ? `url(#${patterns[i]})` : barSoftColors[i]}\n // the soft fill is a 30% tint (1.3–1.4:1 on a dark card, Sprint 25.7 C4): the solid outline keeps the bar's\n // edge at the colour's own contrast against the card (WCAG 1.4.11), and separates stacked segments\n stroke={barSolidColors[i]}\n strokeWidth={1}\n shape={barShape(bars, i, stacked, radius, sideways, forecastAt >= 0 ? { from: forecastAt, edge: barSolidColors[i], fill: aheadBarFill(barSoftColors[i], patterns[i]) } : undefined)}\n stackId={barStackOf(bar, stacked)}\n maxBarSize={maxBarSize}\n {...barAxis}\n isAnimationActive={isAnimated}\n />\n ))}\n {lines.map((line, i) => (\n <Line\n key={line.dataKey}\n type=\"monotone\"\n dataKey={line.dataKey}\n name={line.label ?? line.dataKey}\n stroke={lineColors[i]}\n strokeWidth={2}\n strokeDasharray={dashes[i]}\n dot={false}\n {...lineAxis}\n isAnimationActive={isAnimated}\n />\n ))}\n </ComposedChart>\n </ResponsiveContainer>\n </ChartWrapper>\n );\n}));\n","import { useId, forwardRef, useMemo, useRef, type Ref } from \"react\";\nimport {\n ScatterChart as RechartsScatterChart,\n Scatter,\n XAxis,\n YAxis,\n CartesianGrid,\n Tooltip,\n ResponsiveContainer,\n Symbols,\n ZAxis,\n} from \"recharts\";\nimport { useChartColors, useChartAnimation } from \"../../lib/chart-utils\";\nimport { ChartTooltipContent, ChartLegend, useGridStroke, useAxisStyle, useAxisMeasure, withoutRowFields } from \"./ChartPrimitives\";\nimport { mergeRefs } from \"../../lib/slot\";\nimport { axisTickFormatter, fullValueFormatter, type ValueFormat } from \"./value-format\";\nimport { ChartWrapper, markChart } from \"./ChartWrapper\";\nimport { useFormatLocale } from \"../../lib/locale\";\nimport { pointsAccess } from \"./chart-access\";\nimport { seriesSymbol, type SeriesMark } from \"./series-marks\";\n\nexport interface ScatterSeries {\n name: string;\n points: { x: number; y: number; z?: number }[];\n}\n\nexport interface ScatterChartProps {\n data: ScatterSeries[];\n xLabel?: string;\n /** The value axis's title, drawn horizontally above the axis. */\n yLabel?: string;\n /** \"auto\" (the default): two wide to one high. A preset or a number overrides it; a ChartContainer's own height wins. */\n height?: \"auto\" | \"sm\" | \"md\" | \"lg\" | number;\n showGrid?: boolean;\n showTooltip?: boolean;\n showLegend?: boolean;\n /**\n * How the y values read: \"number\" (the default) is compact on the axis from five digits up, in the page's language (1M, 750K), and in full in\n * the tooltip; \"percent\", \"milliseconds\" or \"bytes\" add their unit; a function formats both itself (Sprint 25.17 A27).\n */\n valueFormat?: ValueFormat;\n /** How the x values read, as valueFormat. Default \"number\". */\n xValueFormat?: ValueFormat;\n animated?: boolean;\n \"aria-label\"?: string;\n className?: string;\n /**\n * What the chart shows, in the page's words: a line above the drawing, in place of the sentence the chart works out\n * from its points (how many, and the range of each value), which it shows without one.\n */\n description?: string;\n}\n\nexport const ScatterChart = markChart(forwardRef<HTMLDivElement, ScatterChartProps>(function ScatterChart({\n data,\n xLabel,\n yLabel,\n height = \"auto\",\n showGrid = true,\n showTooltip = true,\n showLegend,\n valueFormat,\n xValueFormat,\n animated,\n \"aria-label\": ariaLabel,\n className,\n description,\n}, ref) {\n const wrapperRef = useRef<HTMLDivElement | null>(null);\n // the chart's numbers in the locale the server and the hydrating browser share (Sprint 25.20)\n const locale = useFormatLocale();\n const [xTickFormat, yTickFormat, fullFormat] = useMemo(() => {\n const points = (data ?? []).flatMap((s) => s.points);\n const x = fullValueFormatter(xValueFormat, locale);\n const y = fullValueFormatter(valueFormat, locale);\n return [\n axisTickFormatter(points.map((p) => p.x), xValueFormat, locale),\n axisTickFormatter(points.map((p) => p.y), valueFormat, locale),\n (value: number, dataKey?: string) => (dataKey === \"x\" ? x(value) : dataKey === \"y\" ? y(value) : value.toLocaleString(locale)),\n ];\n }, [data, valueFormat, xValueFormat, locale]);\n const measured = useAxisMeasure(wrapperRef, !!yLabel && (data?.length ?? 0) > 0);\n const colors = useChartColors(data.length, false);\n const gridStroke = useGridStroke();\n const axisStyle = useAxisStyle();\n const isAnimated = useChartAnimation(animated);\n const legendVisible = showLegend ?? data.length >= 2;\n const axisLabelStyle = { fontSize: \"var(--ds-font-size-xs)\", fontFamily: \"var(--ds-font-sans)\", fill: axisStyle.tick.fill };\n // Sprint 25.8.9 item 4: each series draws its points in a shape of its own, as the legend shows it (by the series' name)\n // and the tooltip (by the series' own id: a point's tooltip entries are named after the axes)\n const seriesId = useId();\n const idOf = (i: number) => `${seriesId}-scatter-${i}`;\n const marks = useMemo<Record<string, SeriesMark>>(\n () => Object.fromEntries((data ?? []).flatMap((s, i) => {\n const mark = { kind: \"symbol\" as const, color: colors[i], symbol: seriesSymbol(i, data.length) };\n return [[s.name, mark], [`${seriesId}-scatter-${i}`, mark]];\n })),\n [data, colors, seriesId],\n );\n // items 4 and 27: the chart's points as a table and its sentence, from the page's own series\n const access = useMemo(() => pointsAccess({\n series: data ?? [],\n xHeading: xLabel ?? \"x\",\n yHeading: yLabel ?? \"y\",\n zHeading: \"Size\",\n formatX: (v) => fullFormat(v, \"x\"),\n formatY: (v) => fullFormat(v, \"y\"),\n }), [data, xLabel, yLabel, fullFormat]);\n\n if (!data?.length) return null;\n\n return (\n <ChartWrapper\n ref={mergeRefs(ref as Ref<HTMLElement>, wrapperRef as Ref<HTMLElement>) as Ref<HTMLDivElement>}\n height={height}\n size={{ model: \"ratio\" }}\n chart=\"scatter\"\n axisTitle={yLabel}\n formatValue={fullFormat}\n className={className}\n aria-label={ariaLabel}\n access={access}\n description={description}\n marks={marks}\n >\n <ResponsiveContainer width=\"100%\" height=\"100%\">\n <RechartsScatterChart\n margin={{ top: 8 + (yLabel ? Math.ceil(measured.px * 1.5) + 4 : 0), right: 8, bottom: xLabel ? 20 : 4, left: 4 }}\n accessibilityLayer\n >\n {showGrid && <CartesianGrid strokeDasharray=\"3 3\" stroke={gridStroke} />}\n <XAxis\n type=\"number\"\n dataKey=\"x\"\n name={xLabel ?? \"x\"}\n {...axisStyle.tick}\n axisLine={false}\n tickLine={false}\n tickFormatter={xTickFormat}\n label={xLabel ? { value: xLabel, position: \"bottom\", offset: 0, style: { ...axisLabelStyle, textAnchor: \"middle\" } } : undefined}\n />\n <YAxis\n type=\"number\"\n dataKey=\"y\"\n name={yLabel ?? \"y\"}\n width=\"auto\"\n {...axisStyle.tick}\n axisLine={false}\n tickLine={false}\n tickFormatter={yTickFormat}\n />\n <ZAxis type=\"number\" dataKey=\"z\" range={[40, 400]} />\n {showTooltip && <Tooltip content={<ChartTooltipContent />} />}\n {legendVisible && <ChartLegend order={data.map((s) => s.name)} by=\"value\" />}\n {data.map((series, i) => (\n <Scatter\n key={series.name}\n id={idOf(i)}\n name={series.name}\n data={series.points}\n fill={colors[i]}\n isAnimationActive={isAnimated}\n // the series' own shape (Sprint 25.8.9 item 4), drawn from its own props, never a point's fields (Sprint 25.29 item 14)\n shape={(p: object) => <Symbols {...withoutRowFields(p)} type={seriesSymbol(i, data.length)} />}\n />\n ))}\n </RechartsScatterChart>\n </ResponsiveContainer>\n </ChartWrapper>\n );\n}));\n","import { forwardRef, useMemo } from \"react\";\nimport {\n RadarChart as RechartsRadarChart,\n Radar,\n PolarGrid,\n PolarAngleAxis,\n PolarRadiusAxis,\n Tooltip,\n ResponsiveContainer,\n} from \"recharts\";\nimport { useChartColors, useChartAnimation } from \"../../lib/chart-utils\";\nimport { ChartTooltipContent, ChartLegend } from \"./ChartPrimitives\";\nimport { ChartWrapper, markChart } from \"./ChartWrapper\";\nimport { axisTickFormatter, fullValueFormatter, seriesValues, type ValueFormat } from \"./value-format\";\nimport { useFormatLocale } from \"../../lib/locale\";\nimport { cartesianAccess } from \"./chart-access\";\nimport { seriesDash, type SeriesMark } from \"./series-marks\";\n\nexport interface RadarDataKey {\n key: string;\n label?: string;\n}\n\nexport interface RadarChartProps {\n data: Record<string, unknown>[];\n dataKeys: RadarDataKey[];\n axisKey: string;\n /** \"auto\" (the default): square. A preset or a number overrides it; a ChartContainer's own height wins. */\n height?: \"auto\" | \"sm\" | \"md\" | \"lg\" | number;\n filled?: boolean;\n showDots?: boolean;\n showTooltip?: boolean;\n showLegend?: boolean;\n animated?: boolean;\n /** How the values read on the rings and in the tooltip; see ValueFormat (compact numbers by default). */\n valueFormat?: ValueFormat;\n \"aria-label\"?: string;\n className?: string;\n /**\n * What the chart shows, in the page's words: a line above the drawing, in place of the sentence the chart works out\n * from its data (each series' highest and lowest), which it shows without one.\n */\n description?: string;\n}\n\nexport const RadarChart = markChart(forwardRef<HTMLDivElement, RadarChartProps>(function RadarChart({\n data,\n dataKeys,\n axisKey,\n height = \"auto\",\n filled = true,\n showDots = true,\n showTooltip = true,\n showLegend,\n animated,\n valueFormat = \"number\",\n \"aria-label\": ariaLabel,\n className,\n description,\n}, ref) {\n const solidColors = useChartColors(dataKeys.length, false);\n const softColors = useChartColors(dataKeys.length, true);\n const isAnimated = useChartAnimation(animated);\n const legendVisible = showLegend ?? dataKeys.length >= 2;\n // the rings are a value axis: compact in the page's language, the tooltip in full (Sprint 25.17's review)\n const values = useMemo(() => seriesValues(data ?? [], dataKeys.map((dk) => dk.key)), [data, dataKeys]);\n // the chart's numbers in the locale the server and the hydrating browser share (Sprint 25.20)\n const locale = useFormatLocale();\n const tickFormat = useMemo(() => axisTickFormatter(values, valueFormat, locale), [values, valueFormat, locale]);\n const fullFormat = useMemo(() => fullValueFormatter(valueFormat, locale), [valueFormat, locale]);\n // Sprint 25.8.9 item 4: each shape after the first draws its outline with a dash of its own, as the legend shows it\n const dashes = dataKeys.map((_, i) => seriesDash(i, dataKeys.length));\n const marks = useMemo<Record<string, SeriesMark>>(\n () => Object.fromEntries(dataKeys.map((dk, i) => [dk.key, { kind: \"line\" as const, color: solidColors[i], dash: seriesDash(i, dataKeys.length) }])),\n [dataKeys, solidColors],\n );\n // items 4 and 27: the chart's values as a table and its sentence, from the page's own rows\n const access = useMemo(() => cartesianAccess({\n kind: \"Radar chart\",\n data: data ?? [],\n categoryKey: axisKey,\n series: dataKeys.map((dk) => ({ dataKey: dk.key, label: dk.label ?? dk.key })),\n format: fullFormat,\n over: \"names\",\n }), [data, axisKey, dataKeys, fullFormat]);\n\n if (!data?.length) return null;\n\n return (\n <ChartWrapper ref={ref} height={height} size={{ model: \"square\" }} chart=\"radar\" className={className} aria-label={ariaLabel} formatValue={fullFormat} access={access} description={description} marks={marks}>\n <ResponsiveContainer width=\"100%\" height=\"100%\">\n <RechartsRadarChart data={data} cx=\"50%\" cy=\"50%\" outerRadius=\"75%\" accessibilityLayer>\n <PolarGrid stroke=\"var(--ds-border-subtle)\" />\n <PolarAngleAxis\n dataKey={axisKey}\n tick={{ fontSize: \"var(--ds-font-size-xs)\", fontFamily: \"var(--ds-font-sans)\", fill: \"var(--ds-text-muted)\" }}\n />\n <PolarRadiusAxis\n tick={{ fontSize: \"var(--ds-font-size-xs)\", fontFamily: \"var(--ds-font-sans)\", fill: \"var(--ds-text-muted)\" }}\n tickFormatter={tickFormat}\n axisLine={false}\n />\n {showTooltip && <Tooltip content={<ChartTooltipContent />} />}\n {legendVisible && <ChartLegend order={dataKeys.map((dk) => dk.key)} />}\n {dataKeys.map((dk, i) => (\n <Radar\n key={dk.key}\n name={dk.label ?? dk.key}\n dataKey={dk.key}\n stroke={solidColors[i]}\n fill={filled ? softColors[i] : \"transparent\"}\n strokeWidth={2}\n strokeDasharray={dashes[i]}\n dot={showDots ? { r: 3, fill: solidColors[i] } : false}\n isAnimationActive={isAnimated}\n />\n ))}\n </RechartsRadarChart>\n </ResponsiveContainer>\n </ChartWrapper>\n );\n}));\n","import { forwardRef, useId, useMemo } from \"react\";\nimport {\n RadialBarChart as RechartsRadialBarChart,\n RadialBar,\n Tooltip,\n ResponsiveContainer,\n} from \"recharts\";\nimport { useChartColors, useChartAnimation, useResolvedToken } from \"../../lib/chart-utils\";\nimport { ChartTooltipContent, ChartLegend } from \"./ChartPrimitives\";\nimport { ChartWrapper, markChart } from \"./ChartWrapper\";\nimport { partsAccess } from \"./chart-access\";\nimport { SeriesPatterns, seriesPattern, type SeriesMark } from \"./series-marks\";\nimport { fullValueFormatter, numberOf } from \"./value-format\";\nimport { useFormatLocale } from \"../../lib/locale\";\n\nexport interface RadialBarChartProps {\n data: { name: string; value: number; max?: number; [key: string]: unknown }[];\n /** \"auto\" (the default): square. A preset or a number overrides it; a ChartContainer's own height wins. */\n height?: \"auto\" | \"sm\" | \"md\" | \"lg\" | number;\n showTooltip?: boolean;\n showLegend?: boolean;\n showLabels?: boolean;\n startAngle?: number;\n endAngle?: number;\n animated?: boolean;\n \"aria-label\"?: string;\n className?: string;\n /**\n * What the chart shows, in the page's words: a line above the drawing, in place of the sentence the chart works out\n * from its data, which it shows without one.\n */\n description?: string;\n}\n\nexport const RadialBarChart = markChart(forwardRef<HTMLDivElement, RadialBarChartProps>(function RadialBarChart({\n data,\n height = \"auto\",\n showTooltip = true,\n showLegend = true,\n showLabels = false,\n startAngle = 90,\n endAngle = -270,\n animated,\n \"aria-label\": ariaLabel,\n className,\n description,\n}, ref) {\n const colors = useChartColors(data.length, false);\n const chartId = useId();\n const surface = useResolvedToken(\"--ds-bg-surface\");\n const locale = useFormatLocale();\n const format = useMemo(() => fullValueFormatter(undefined, locale), [locale]);\n const isAnimated = useChartAnimation(animated);\n\n // the chart's own fields alone: recharts draws each bar, and its background track, with its row's fields, so a row's\n // `role` or `aria-label` became theirs (Sprint 25.29 item 14)\n const chartData = data.map((d, i) => ({\n name: d.name,\n // a number written as text is drawn as the table and the sentence read it (Sprint 25.8.9)\n value: numberOf(d.value) ?? 0,\n ...(d.max !== undefined ? { max: d.max } : {}),\n // Sprint 25.8.9 item 4: each bar after the first fills with a pattern over its colour, as the legend shows it\n fill: seriesPattern(chartId, i, data.length) ? `url(#${seriesPattern(chartId, i, data.length)})` : colors[i % colors.length],\n }));\n const marks = useMemo<Record<string, SeriesMark>>(\n () => Object.fromEntries(data.map((d, i) => [d.name, { kind: \"fill\" as const, color: colors[i % colors.length], pattern: seriesPattern(chartId, i, data.length) }])),\n [data, colors, chartId],\n );\n // items 4 and 27: the bars as a table and the chart's sentence, from the page's own rows\n const access = useMemo(() => partsAccess({ kind: \"radial\", items: data.map((d) => ({ name: d.name, value: d.value, ...(d.max !== undefined ? { max: d.max } : {}) })), format }), [data, format]);\n\n if (!data?.length) return null;\n\n return (\n <ChartWrapper ref={ref} height={height} size={{ model: \"square\" }} chart=\"radial-bar\" className={className} aria-label={ariaLabel} access={access} description={description} marks={marks}>\n <ResponsiveContainer width=\"100%\" height=\"100%\">\n <RechartsRadialBarChart\n data={chartData}\n cx=\"50%\"\n cy=\"50%\"\n innerRadius=\"20%\"\n outerRadius=\"90%\"\n startAngle={startAngle}\n endAngle={endAngle}\n accessibilityLayer\n >\n <SeriesPatterns chartId={chartId} colors={data.map((_, i) => colors[i % colors.length])} surface={surface} />\n <RadialBar\n dataKey=\"value\"\n background={{ fill: \"var(--ds-bg-muted)\" }}\n label={showLabels ? { position: \"insideStart\", fill: \"var(--ds-text-primary)\", fontSize: \"var(--ds-font-size-xs)\" } : false}\n isAnimationActive={isAnimated}\n />\n {showTooltip && <Tooltip content={<ChartTooltipContent />} />}\n {showLegend && <ChartLegend order={data.map((d) => d.name)} by=\"value\" />}\n </RechartsRadialBarChart>\n </ResponsiveContainer>\n </ChartWrapper>\n );\n}));\n","import { forwardRef, useMemo } from \"react\";\nimport {\n FunnelChart as RechartsFunnelChart,\n Funnel,\n Tooltip,\n LabelList,\n ResponsiveContainer,\n} from \"recharts\";\nimport { useChartColors, useChartAnimation } from \"../../lib/chart-utils\";\nimport { ChartTooltipContent } from \"./ChartPrimitives\";\nimport { ChartWrapper, markChart } from \"./ChartWrapper\";\nimport { partsAccess } from \"./chart-access\";\nimport { fullValueFormatter, numberOf } from \"./value-format\";\nimport { useFormatLocale } from \"../../lib/locale\";\n\n/** A funnel stage takes a taller row than a sideways bar (Sprint 25.9, A2). */\nconst STAGE_ROWS = 1.5;\n\nexport interface FunnelChartProps {\n data: { name: string; value: number; [key: string]: unknown }[];\n /** \"auto\" (the default): a row per stage. A preset or a number overrides it; a ChartContainer's own height wins. */\n height?: \"auto\" | \"sm\" | \"md\" | \"lg\" | number;\n showTooltip?: boolean;\n /** Kept for compatibility: a funnel has no legend, its labels name the stages (Recharts gives it no legend entries). */\n showLegend?: boolean;\n showLabels?: boolean;\n animated?: boolean;\n \"aria-label\"?: string;\n className?: string;\n /**\n * What the chart shows, in the page's words: a line above the drawing, in place of the sentence the chart works out\n * from its data, which it shows without one.\n */\n description?: string;\n}\n\nexport const FunnelChart = markChart(forwardRef<HTMLDivElement, FunnelChartProps>(function FunnelChart({\n data,\n height = \"auto\",\n showTooltip = true,\n showLabels = true,\n animated,\n \"aria-label\": ariaLabel,\n className,\n description,\n}, ref) {\n const colors = useChartColors(data.length, false);\n const locale = useFormatLocale();\n const format = useMemo(() => fullValueFormatter(undefined, locale), [locale]);\n // items 4 and 27: the stages as a table and the chart's sentence, from the page's own rows; each stage is named on it\n const access = useMemo(() => partsAccess({ kind: \"funnel\", items: data.map((d) => ({ name: d.name, value: d.value })), format }), [data, format]);\n const isAnimated = useChartAnimation(animated);\n\n // the chart's own fields alone: recharts draws each stage with its row's fields, so a row's `role` or `aria-label`\n // became the stage's (Sprint 25.29 item 14)\n // a number written as text is drawn as the table and the sentence read it (Sprint 25.8.9)\n const chartData = data.map((d, i) => ({\n name: d.name,\n value: numberOf(d.value) ?? 0,\n fill: colors[i % colors.length],\n }));\n\n if (!data?.length) return null;\n\n return (\n <ChartWrapper ref={ref} height={height} size={{ model: \"rows\", units: data.length * STAGE_ROWS, axis: \"16px\" }} chart=\"funnel\" className={className} aria-label={ariaLabel} access={access} description={description}>\n <ResponsiveContainer width=\"100%\" height=\"100%\">\n <RechartsFunnelChart accessibilityLayer>\n <Funnel dataKey=\"value\" data={chartData} isAnimationActive={isAnimated}>\n {showLabels && (\n <LabelList\n dataKey=\"name\"\n position=\"right\"\n fill=\"var(--ds-text-primary)\"\n fontSize=\"var(--ds-font-size-sm)\"\n fontFamily=\"var(--ds-font-sans)\"\n />\n )}\n </Funnel>\n {showTooltip && <Tooltip content={<ChartTooltipContent />} />}\n </RechartsFunnelChart>\n </ResponsiveContainer>\n </ChartWrapper>\n );\n}));\n","// showcase/src/lib/token-algorithms.ts\n// The one source for all token generation helpers. The platform imports it through\n// platform/src/lib/token-algorithms.ts, a re-export (Sprint 25.7 review, 26 September 2026: no more synced copy).\n\nexport type HoverEffect = 'scale' | 'lift' | 'scale-lift'\n\nfunction hasScaleEffect(effect: HoverEffect): boolean {\n return effect === 'scale' || effect === 'scale-lift'\n}\n\nfunction hasLiftEffect(effect: HoverEffect): boolean {\n return effect === 'lift' || effect === 'scale-lift'\n}\n\nexport interface GradientConfig {\n accentMode: 'solid' | 'gradient'\n endHue: number\n angle: number\n hue: number\n sat: number\n endSat?: number\n endShade?: number\n}\n\nexport interface InteractiveHoverConfig {\n enabled: boolean\n effect: HoverEffect\n speed: number\n ease: string\n scale: number\n lift: number\n pressDepth: number\n}\n\nexport interface AmbientHoverConfig {\n enabled: boolean\n effect: HoverEffect\n speed: number\n ease: string\n scale: number\n lift: number\n}\n\nexport interface MotionDecisions {\n speed: number\n ease: string\n intensity?: 'none' | 'subtle' | 'moderate' | 'expressive'\n interactive?: InteractiveHoverConfig\n ambient?: AmbientHoverConfig\n}\n\n// ---------------------------------------------------------------------------\n// On-fill text (Sprint 20.10)\n// ---------------------------------------------------------------------------\n//\n// The colour of text and icons on a solid fill is decided by contrast, not by\n// preset: white when white reaches WCAG AA (4.5:1) over the fill, otherwise\n// the theme's darkest neutral. One function, `onFillText`, decides for every\n// fill the theme emits — the page accent (`--ds-text-on-primary`), the\n// independent sidebar and header accents, the three status fills and the five\n// palette bold fills — and nothing else decides on-fill colour.\n//\n// The decision uses a real conversion (OKLCH → OKLab → linear sRGB → relative\n// luminance) of the fill as the browser draws it: a colour outside sRGB has\n// each channel clipped, which is what Chrome renders (measured, Sprint 25.7\n// Part D; see oklchToLinearSrgbClamped) — not the chroma reduction CSS Color 4\n// describes, which this used until then. The status palettes are literal\n// OKLCH values at arbitrary lightness, and saturated fills near the gamut\n// edge render lighter than their mapped colour. `estimateContrastRatio` below\n// keeps its L³ proxy for the palette pair code that has always used it.\n\nexport interface Oklch { L: number; C: number; H: number }\n\n/**\n * The --ds-primary-{shade} scale from roots.css: lightness and the chroma\n * multiplier applied to --ds-sat-primary. The one table every literal accent\n * colour (gradient start and end, independent sidebar and header accents) is\n * computed from, so a flip at a given shade is the same flip everywhere.\n * A test pins it against the CSS.\n */\nexport const PRIMARY_SCALE: Record<number, { L: number; c: number }> = {\n 300: { L: 0.77, c: 0.150 },\n 400: { L: 0.66, c: 0.180 },\n 500: { L: 0.55, c: 0.200 },\n 600: { L: 0.47, c: 0.185 },\n 700: { L: 0.40, c: 0.165 },\n 800: { L: 0.33, c: 0.135 },\n 900: { L: 0.25, c: 0.100 },\n}\n\n/** Nearest step of the scale; a missing or malformed shade reads as 500 rather than throwing (stored decisions are read raw). */\nfunction scaleShade(shade: number): number {\n if (!Number.isFinite(shade)) return 500\n const s = Math.max(300, Math.min(900, shade))\n return Math.round(s / 100) * 100\n}\n\n/** The literal OKLCH of --ds-primary-{shade} at a saturation and hue. */\nexport function accentColour(shade: number, sat: number, hue: number): Oklch {\n const { L, c } = PRIMARY_SCALE[scaleShade(shade)]\n return { L, C: c * sat, H: hue }\n}\n\n/** Formats an OKLCH colour the way the emitters always have (L to 3 places, C to 4). */\nexport function oklchCss(colour: Oklch): string {\n return `oklch(${colour.L.toFixed(3)} ${colour.C.toFixed(4)} ${colour.H})`\n}\n\n/** Parses an `oklch(L C H)` literal (optional `/ alpha`). Returns null for anything else, including var() references. */\nexport function parseOklch(value: string): Oklch | null {\n const m = value.trim().match(/^oklch\\(\\s*([\\d.]+)(%?)\\s+([\\d.]+)\\s+([\\d.]+)(?:deg)?\\s*(?:\\/\\s*[\\d.%]+\\s*)?\\)$/i)\n if (!m) return null\n const L = m[2] ? parseFloat(m[1]) / 100 : parseFloat(m[1])\n return { L, C: parseFloat(m[3]), H: parseFloat(m[4]) }\n}\n\nfunction oklchToLinearSrgb({ L, C, H }: Oklch): [number, number, number] {\n const h = (H * Math.PI) / 180\n const a = C * Math.cos(h)\n const b = C * Math.sin(h)\n const l_ = L + 0.3963377774 * a + 0.2158037573 * b\n const m_ = L - 0.1055613458 * a - 0.0638541728 * b\n const s_ = L - 0.0894841775 * a - 1.2914855480 * b\n const l = l_ * l_ * l_\n const m = m_ * m_ * m_\n const s = s_ * s_ * s_\n return [\n +4.0767416621 * l - 3.3077115913 * m + 0.2309699292 * s,\n -1.2684380046 * l + 2.6097574011 * m - 0.3413193965 * s,\n -0.0041960863 * l - 0.7034186147 * m + 1.7076147010 * s,\n ]\n}\n\n/**\n * WCAG relative luminance of an OKLCH colour as the browser draws it: each\n * channel clipped to sRGB (oklchToLinearSrgbClamped) and rounded to the\n * nearest of the 256 steps an 8-bit sRGB surface has, then weighted. Contrast\n * decisions use the range Chrome's rounding can land in (luminanceRange); this\n * is its nearest value.\n */\nexport function oklchToLuminance(colour: Oklch): number {\n return srgbLuminance(oklchToSrgb(colour).map((v) => Math.round(v * 255) / 255) as [number, number, number])\n}\n\n/**\n * Linear sRGB channels as the browser renders them: an out-of-gamut colour has\n * each channel clipped to 0–1. Measured in Chrome 153 (Sprint 25.7 Part D): 211\n * of 211 oklch() colours outside sRGB came back within 1/255 of per-channel\n * clipping, from an sRGB canvas and from a screenshot alike. Reducing chroma to\n * the gamut edge, which this function did until then (CSS Color 4's intent),\n * was up to 82/255 off in a channel, and the full CSS Color 4 gamut-mapping\n * algorithm up to 73/255. Clipping is usually lighter (a negative channel\n * rises to 0), so white text decided on the chroma-reduced colour could miss\n * AA as drawn: 4.41:1 on the palette bold at hue 187.5, which it scored 4.62.\n */\nfunction oklchToLinearSrgbClamped(colour: Oklch): [number, number, number] {\n return oklchToLinearSrgb(colour).map((v) => Math.min(1, Math.max(0, v))) as [number, number, number]\n}\n\nconst gammaEncode = (v: number) => (v <= 0.0031308 ? 12.92 * v : 1.055 * Math.pow(v, 1 / 2.4) - 0.055)\nconst gammaDecode = (v: number) => (v <= 0.04045 ? v / 12.92 : Math.pow((v + 0.055) / 1.055, 2.4))\n\n/** Gamma-encoded sRGB channels (0..1) — the space `opacity` compositing and `color-mix(in srgb)` blend in. */\nfunction oklchToSrgb(colour: Oklch): [number, number, number] {\n return oklchToLinearSrgbClamped(colour).map(gammaEncode) as [number, number, number]\n}\n\nfunction srgbLuminance([r, g, b]: [number, number, number]): number {\n return 0.2126 * gammaDecode(r) + 0.7152 * gammaDecode(g) + 0.0722 * gammaDecode(b)\n}\n\n/**\n * How near a half step (of 1/255) a channel can sit and still come out of\n * Chrome one step either way. Chrome's arithmetic is not this file's: of 2,435\n * colours measured (Sprint 25.7 Part D; 7,305 channels), 39 channels came back\n * one step from the nearest, and every one sat within 0.12 of a step of the\n * half-step boundary.\n * One step is up to 0.05 of contrast near the white crossover, which is where\n * the decisions live, so a decision counts both steps inside this window.\n */\nexport const ROUNDING_WINDOW = 0.25\n\n/** A colour's WCAG luminance as Chrome can draw it: [darkest, lightest] over the 8-bit steps each channel can round to. */\nexport type LuminanceRange = readonly [number, number]\n\n/** The luminance range of gamma-encoded sRGB channels (0–1): each channel's nearest step, or both steps beside it within the window. */\nfunction srgbLuminanceRange(encoded: readonly number[]): LuminanceRange {\n let lo = 0\n let hi = 0\n encoded.forEach((v, i) => {\n const x = Math.min(1, Math.max(0, v)) * 255\n const below = Math.floor(x)\n const [a, b] = Math.abs(x - below - 0.5) <= ROUNDING_WINDOW ? [below, Math.min(255, below + 1)] : [Math.round(x), Math.round(x)]\n const weight = [0.2126, 0.7152, 0.0722][i]\n lo += weight * gammaDecode(a / 255)\n hi += weight * gammaDecode(b / 255)\n })\n return [lo, hi]\n}\n\n/** The luminance range an OKLCH colour can take as Chrome draws it: clipped to sRGB, then rounded to 8 bits. */\nexport function luminanceRange(colour: Oklch): LuminanceRange {\n return srgbLuminanceRange(oklchToSrgb(colour))\n}\n\n/** The lowest contrast two colours can show, every way either can round (1 when their ranges meet). */\nexport function worstContrastOf([t0, t1]: LuminanceRange, [f0, f1]: LuminanceRange): number {\n if (t0 <= f1 && f0 <= t1) return 1\n return t0 > f1 ? contrastRatio(t0, f1) : contrastRatio(t1, f0)\n}\n\n/** WCAG contrast ratio between two relative luminances. */\nexport function contrastRatio(lumA: number, lumB: number): number {\n const lighter = Math.max(lumA, lumB)\n const darker = Math.min(lumA, lumB)\n return (lighter + 0.05) / (darker + 0.05)\n}\n\n/**\n * Sprint 25.14 A20 (and Sprint 30's P1): colours as the browser has drawn them — 8-bit sRGB channels and an alpha, read\n * from a canvas or a screenshot — composited and compared as WCAG does. A translucent edge is judged over what it sits\n * on: each ground laid under it in gamma-encoded sRGB, the space the browser blends in.\n */\nexport type DrawnColour = readonly [r: number, g: number, b: number, alpha: number]\n\n/** `top` laid over an opaque `ground`, as the browser composites it. */\nexport function drawnOver(top: DrawnColour, ground: DrawnColour): DrawnColour {\n const a = top[3]\n return [0, 1, 2].map((i) => Math.round(top[i] * a + ground[i] * (1 - a))).concat(1) as unknown as DrawnColour\n}\n\n/** WCAG relative luminance of an opaque drawn colour. */\nexport function drawnLuminance([r, g, b]: DrawnColour): number {\n return srgbLuminance([r / 255, g / 255, b / 255])\n}\n\n/** WCAG contrast between two opaque drawn colours. */\nexport function drawnContrast(a: DrawnColour, b: DrawnColour): number {\n return contrastRatio(drawnLuminance(a), drawnLuminance(b))\n}\n\n/** The lowest contrast `edge` shows over each ground (opaque), composited where it is translucent, and the ground it is lowest on. */\nexport function edgeContrast(edge: DrawnColour, grounds: ReadonlyArray<readonly [name: string, ground: DrawnColour]>): { ratio: number; on: string } {\n let worst = { ratio: Infinity, on: \"\" }\n for (const [name, ground] of grounds) {\n const ratio = drawnContrast(drawnOver(edge, ground), ground)\n if (ratio < worst.ratio) worst = { ratio, on: name }\n }\n return worst\n}\n\nexport const WCAG_AA_TEXT = 4.5\n\n/** White text as the emitters write it. */\nexport const ON_FILL_WHITE = 'oklch(1 0 0)'\n/** Last-resort dark text: the theme's darkest neutral. Used only when no tint of the fill's own hue can pass (§ onFillDarkTint). */\nexport const ON_FILL_DARK = 'var(--ds-neutral-950)'\n/**\n * The last-resort candidate as a colour: --ds-neutral-950 is L 0.13 with a\n * chroma of 0.002 × --ds-sat-neutral, which is invisible to the luminance\n * calculation, so the hue does not matter here.\n */\nexport const DARK_TEXT_CANDIDATE: Oklch = { L: 0.13, C: 0.002, H: 0 }\n\n/** The dark tint keeps the fill's hue at this chroma (the palette's `-dark` variant uses 0.10 too); a duller fill keeps its own chroma. */\nexport const ON_FILL_TINT_CHROMA = 0.10\n/** Preferred contrast for the dark tint. Falls back to AA where no dark colour can reach it (fills just above the white crossover). */\nexport const ON_FILL_TINT_TARGET = 5\nconst TINT_L_MAX = 0.45\nconst TINT_L_MIN = 0.10\nconst TINT_L_STEP = 0.01\n\nconst WHITE_RANGE: LuminanceRange = [1, 1]\nconst DARK_RANGE = luminanceRange(DARK_TEXT_CANDIDATE)\n\n/** The worst contrast a text colour gets over one or more fills as Chrome draws them (a gradient passes every colour it paints: gradientFills). */\nfunction minContrast(text: LuminanceRange, fills: Oklch[]): number {\n let min = Infinity\n for (const f of fills) min = Math.min(min, worstContrastOf(text, luminanceRange(f)))\n return min\n}\n\n/**\n * White or dark text over one or more fills (a gradient passes every colour it\n * paints, gradientFills): whichever onFillTextValue emits, so a caller showing the choice (the\n * builder's \"text flips to dark\" note) agrees with the token.\n */\nexport function onFillText(fill: Oklch, ...moreFills: Oklch[]): 'white' | 'dark' {\n return onFillTextValue(fill, ...moreFills) === ON_FILL_WHITE ? 'white' : 'dark'\n}\n\n/**\n * The dark text colour for a fill: a deep shade of the fill's own hue rather\n * than a neutral, so an amber badge reads as amber-on-amber the way the\n * decorative palette pairs `-dark` text with `-subtle` backgrounds. The\n * lightest tint (L 0.45 → 0.10 in 0.01 steps, chroma capped at 0.10) whose\n * worst contrast across the fills reaches 5:1. Contrast comes before colour:\n * where the full-chroma tint cannot reach the target the chroma halves, then\n * quarters (a saturated green tint at L 0.10 is still luminous enough to\n * miss 5:1 over a light green); where no dark colour can reach 5:1 the\n * lightest reaching AA; null when not even AA is reachable (the caller then\n * falls back to --ds-neutral-950). For a gradient the hue is the start\n * colour's; the contrast is checked over every colour it paints (gradientFills).\n */\nexport function onFillDarkTint(fill: Oklch, ...moreFills: Oklch[]): Oklch | null {\n const fills = [fill, ...moreFills]\n const H = fill.H\n const chroma = Math.min(ON_FILL_TINT_CHROMA, fill.C)\n for (const target of [ON_FILL_TINT_TARGET, WCAG_AA_TEXT]) {\n for (const C of [chroma, chroma / 2, chroma / 4]) {\n for (let L = TINT_L_MAX; L >= TINT_L_MIN - 1e-9; L -= TINT_L_STEP) {\n const candidate = { L: +L.toFixed(2), C: +C.toFixed(4), H }\n if (minContrast(luminanceRange(candidate), fills) >= target) return candidate\n }\n }\n }\n return null\n}\n\n/**\n * The CSS value for text on a fill, the one on-fill decision: white where\n * white reaches AA over every fill as drawn; else the dark tint\n * (onFillDarkTint); else --ds-neutral-950 or white, whichever does better.\n * The tints go darker than --ds-neutral-950, so they also cover the sliver\n * around luminance 0.184 where white and the neutral both miss a single fill\n * (a fill at L 0.55 near hue 215). Only a gradient whose colours lie either\n * side of the crossover can leave every colour short of AA; the fill has to\n * change there.\n */\nexport function onFillTextValue(fill: Oklch, ...moreFills: Oklch[]): string {\n const fills = [fill, ...moreFills]\n const whiteMin = minContrast(WHITE_RANGE, fills)\n if (whiteMin >= WCAG_AA_TEXT) return ON_FILL_WHITE\n const tint = onFillDarkTint(fill, ...moreFills)\n if (tint) return oklchCss(tint)\n return minContrast(DARK_RANGE, fills) >= whiteMin ? ON_FILL_DARK : ON_FILL_WHITE\n}\n\n/** How many equal parts a gradient is sampled in, between its two ends (every 5%: a dip can sit at 95% of the way). */\nconst GRADIENT_SAMPLES = 20\n\n/**\n * The colours a gradient paints, for deciding the text over it: its two ends\n * (the start first, so a dark tint keeps the start's hue) and the points\n * between them. Chrome paints a linear-gradient of oklch() colours in Oklab\n * (CSS Color 4's default for colours that are not legacy sRGB): its pixels\n * follow Oklab interpolation to within 0.003 of luminance (measured, Sprint\n * 25.7, 26 September 2026). A point in between can be darker or lighter than\n * both ends, because two saturated ends that sRGB clips meet at a duller colour\n * that clips less: up to 5% darker than the darker end across the accent scale\n * (a violet to a red at primary-600), enough to take text below AA.\n */\nexport function gradientFills(start: Oklch, end: Oklch): [Oklch, Oklch, ...Oklch[]] {\n const lab = ({ L, C, H }: Oklch) => [L, C * Math.cos((H * Math.PI) / 180), C * Math.sin((H * Math.PI) / 180)]\n const [a, b] = [lab(start), lab(end)]\n const between: Oklch[] = []\n for (let i = 1; i < GRADIENT_SAMPLES; i++) {\n const [L, x, y] = a.map((v, k) => v + ((b[k] - v) * i) / GRADIENT_SAMPLES)\n between.push({ L, C: Math.hypot(x, y), H: ((Math.atan2(y, x) * 180) / Math.PI + 360) % 360 })\n }\n return [start, end, ...between]\n}\n\n/* ── Tinted surfaces (subtle colourful header) ──────────────────────────\n A tinted surface is the surface colour (--ds-bg-surface, so it matches the\n cards around it) washed with the accent — the gradient, or the solid accent —\n at one strength. One recipe in both accent modes, so the tint is a pure\n shade of the accent over the paper and its luminance is knowable: the muted\n ink over it is the lightest neutral step that clears AA against the worst\n wash stop. The picker measures against the default surface; a preset that\n overrides --ds-bg-surface (cream, translucent) shifts the real tint a little,\n the same limitation --ds-text-on-primary has under a --ds-gradient override. */\n\n/** Opacity of the accent wash over --ds-tint-base. Shared by the CSS (--ds-tint-strength) and the ink picker. */\nexport const TINT_STRENGTH = 0.15\n/** The default --ds-bg-surface per mode: white in light, --ds-neutral-800 in dark. @sync roots.css (tint-parity.test.ts checks). */\nexport const TINT_BASE: Record<'light' | 'dark', Oklch> = {\n light: { L: 1, C: 0, H: 0 },\n dark: { L: 0.27, C: 0.004, H: 0 },\n}\n/** The CSS for --ds-accent-wash when the accent is solid: a flat image so the overlay reads one token in both modes. */\nexport const SOLID_ACCENT_WASH = 'linear-gradient(var(--ds-accent-primary), var(--ds-accent-primary))'\n\n/** L of the neutral steps: the muted-ink candidates (200–700) and the deep steps that can serve as text on the neutral status fill (chroma ≤ 0.01 × sat, invisible to luminance). @sync roots.css --ds-neutral-* (tint-parity.test.ts checks). */\nexport const NEUTRAL_STEP_L: Record<number, number> = { 200: 0.90, 300: 0.84, 400: 0.71, 500: 0.55, 600: 0.45, 700: 0.37, 800: 0.27, 900: 0.20, 950: 0.13 }\n/** Candidate steps, lightest first: the first that clears AA wins, so hierarchy against --ds-text-secondary is kept where the tint allows. */\nconst MUTED_ON_TINT_STEPS: Record<'light' | 'dark', number[]> = { light: [400, 500, 600, 700], dark: [400, 300, 200] }\n\n/** The tinted surface for one wash colour in gamma sRGB: the base blended with the wash (clipped, as drawn) at TINT_STRENGTH, as the browser composites the overlay. */\nfunction tintSrgb(mode: 'light' | 'dark', wash: Oklch): [number, number, number] {\n const base = oklchToSrgb(TINT_BASE[mode])\n const top = oklchToSrgb(wash)\n return base.map((v, i) => v * (1 - TINT_STRENGTH) + top[i] * TINT_STRENGTH) as [number, number, number]\n}\n\n/** WCAG luminance of the tinted surface for one wash colour, at the nearest 8-bit step (the ink picker uses the range Chrome's rounding can land in). */\nexport function tintLuminance(mode: 'light' | 'dark', wash: Oklch): number {\n return srgbLuminance(tintSrgb(mode, wash).map((v) => Math.round(v * 255) / 255) as [number, number, number])\n}\n\n/**\n * The muted ink for text over a tinted surface: `var(--ds-neutral-NNN)`, the\n * lightest candidate step whose worst contrast across the wash colours (a\n * gradient passes both ends) reaches AA as Chrome draws both. The darkest\n * candidate when none does.\n */\nexport function mutedOnTint(mode: 'light' | 'dark', wash: Oklch, ...moreWashes: Oklch[]): string {\n const surfaces: Paint[] = [wash, ...moreWashes].map((w) => ({ rgb: tintSrgb(mode, w), alpha: 1 }))\n const steps = MUTED_ON_TINT_STEPS[mode]\n // the shared routine (Sprint 30's firstReadable), walking the neutral scale's steps\n const candidates = steps.map((step): ColourCandidate => ({ value: `var(--ds-neutral-${step})`, paint: { rgb: oklchToSrgb({ L: NEUTRAL_STEP_L[step], C: 0, H: 0 }), alpha: 1 } }))\n return firstReadable(candidates, surfaces, WCAG_AA_TEXT)?.value ?? `var(--ds-neutral-${steps[steps.length - 1]})`\n}\n\n/**\n * On-fill tokens for the four status fills that carry text (Badge, Button,\n * Stepper, Dock, the Gantt's bars). Takes the palette's literal values; a value\n * that is not an OKLCH literal keeps white, the roots.css default.\n */\nexport function onStatusFillTokens(sv: { success: string; warning: string; error: string; info: string }): Record<string, string> {\n const pick = (value: string) => {\n const c = parseOklch(value)\n return c ? onFillTextValue(c) : ON_FILL_WHITE\n }\n return {\n '--ds-text-on-success': pick(sv.success),\n '--ds-text-on-warning': pick(sv.warning),\n '--ds-text-on-error': pick(sv.error),\n '--ds-text-on-info': pick(sv.info),\n }\n}\n\n/**\n * The neutral status fill per mode: a mid step of the theme's neutral scale, for\n * an item with no status (\"not started\", a Gantt bar with no known status). Dark\n * mode takes the step one lighter, as every status fill does (500 → 400), so the\n * fill still shows at 3:1 on the dark surfaces (neutral-700 to -900).\n * @sync roots.css --ds-status-neutral (token-algorithms.test.ts checks).\n */\nexport const STATUS_NEUTRAL_STEP: Record<'light' | 'dark', number> = { light: 500, dark: 400 }\n\n/** The deep neutral steps that can carry text on the neutral fill, lightest first. */\nconst NEUTRAL_TEXT_STEPS = [700, 800, 900, 950]\n\n/**\n * The neutral status fill and the text on it, for one mode. The same in every\n * status palette, so roots.css declares the same pair as its defaults. The text\n * is decided as every on-fill colour is (onFillText, onFillDarkTint): white\n * where white reaches AA over the fill; else the lightest deep shade of the\n * fill's own hue reaching 5:1, then AA — for a neutral fill that is a step of\n * the neutral scale, which carries the theme's neutral hue and saturation as the\n * fill does; --ds-neutral-950 as the last resort.\n */\nexport function neutralStatusFillTokens(mode: 'light' | 'dark'): Record<string, string> {\n const step = STATUS_NEUTRAL_STEP[mode]\n const fill: Oklch = { L: NEUTRAL_STEP_L[step], C: 0, H: 0 }\n const text = (): string => {\n if (onFillText(fill) === 'white') return ON_FILL_WHITE\n for (const target of [ON_FILL_TINT_TARGET, WCAG_AA_TEXT]) {\n for (const s of NEUTRAL_TEXT_STEPS) {\n if (s > step && minContrast(luminanceRange({ L: NEUTRAL_STEP_L[s], C: 0, H: 0 }), [fill]) >= target) return `var(--ds-neutral-${s})`\n }\n }\n return ON_FILL_DARK\n }\n return {\n '--ds-status-neutral': `var(--ds-neutral-${step})`,\n '--ds-text-on-neutral': text(),\n }\n}\n\n/**\n * Computes accent tokens from shade + mode.\n * Chart tokens are now generated separately via computeChartTokens (they\n * depend on palette values that don't exist at accent-computation time).\n *\n * With a `gradient` config (which every emitter passes, solid or gradient,\n * because it carries the hue and saturation) the set also includes\n * `--ds-text-on-primary`, decided by `onFillText` over the accent — or over\n * every colour a gradient paints (gradientFills). Without one the token is\n * left to roots.css (white).\n */\nexport function getAccentTokens(\n shade: number,\n mode: 'light' | 'dark',\n gradient?: GradientConfig\n): Record<string, string> {\n const s = Math.max(300, Math.min(900, shade))\n const hover = mode === 'dark' ? Math.max(300, s - 100) : Math.min(950, s + 100)\n const active = mode === 'dark' ? Math.max(300, s - 200) : Math.min(950, s + 200)\n\n const tokens: Record<string, string> = {\n '--ds-accent-primary': `var(--ds-primary-${s})`,\n '--ds-accent-primary-hover': `var(--ds-primary-${hover})`,\n '--ds-accent-primary-active': `var(--ds-primary-${active})`,\n // The active look's soft halo (Sprint 30, D6: a field clicked into, an open trigger). The focus colour is derived\n // (readableTokens); --ds-border-focus is its alias in roots.css, and the old ring and input alias are gone (P5).\n '--ds-ring-active': 'var(--ds-accent-soft)',\n // Tinted surfaces: --ds-tint-base is var(--ds-bg-surface) in roots.css; only the strength is emitted (see mutedOnTint).\n '--ds-tint-strength': String(TINT_STRENGTH),\n }\n\n if (gradient?.accentMode === 'gradient') {\n const startHue = gradient.hue ?? gradient.endHue\n const start = accentColour(s, gradient.sat, startHue)\n const startColor = `oklch(${start.L} ${start.C.toFixed(4)} ${startHue})`\n\n const endShade = Math.max(300, Math.min(900, gradient.endShade ?? s))\n const endSat = gradient.endSat ?? gradient.sat\n const end = accentColour(endShade, endSat, gradient.endHue)\n const endColor = oklchCss(end)\n tokens['--ds-gradient'] = `linear-gradient(${gradient.angle}deg, ${startColor}, ${endColor})`\n // The two ends as their own tokens so SVG gradients (icon strokes) can follow the theme.\n tokens['--ds-gradient-start'] = startColor\n tokens['--ds-gradient-end'] = endColor\n tokens['--ds-text-on-primary'] = onFillTextValue(...gradientFills(start, end))\n // Reads the gradient token (not the literal) so a preset override of --ds-gradient washes the tint too.\n tokens['--ds-accent-wash'] = 'var(--ds-gradient)'\n tokens['--ds-text-muted-on-tint'] = mutedOnTint(mode, start, end)\n } else {\n tokens['--ds-gradient'] = 'none'\n tokens['--ds-gradient-start'] = 'var(--ds-accent-primary)'\n tokens['--ds-gradient-end'] = 'var(--ds-accent-primary)'\n tokens['--ds-accent-wash'] = SOLID_ACCENT_WASH\n if (gradient) {\n const solid = accentColour(s, gradient.sat, gradient.hue)\n tokens['--ds-text-on-primary'] = onFillTextValue(solid)\n tokens['--ds-text-muted-on-tint'] = mutedOnTint(mode, solid)\n }\n }\n\n return tokens\n}\n\nconst DEFAULT_INTERACTIVE: InteractiveHoverConfig = {\n enabled: true, effect: 'scale-lift', speed: 150, ease: 'ease-out', scale: 1.02, lift: 2, pressDepth: 1,\n}\n\nconst DEFAULT_AMBIENT: AmbientHoverConfig = {\n enabled: true, effect: 'lift', speed: 250, ease: 'cubic-bezier(0.33, 1, 0.68, 1)', scale: 1, lift: 1,\n}\n\nconst INTENSITY_PRESETS: Record<string, Record<string, string>> = {\n none: { '--ds-hover-scale': '1', '--ds-hover-lift': '0px', '--ds-press-depth': '0px', '--ds-ambient-hover-scale': '1', '--ds-ambient-hover-lift': '0px' },\n subtle: { '--ds-hover-scale': '1.02', '--ds-hover-lift': '2px', '--ds-press-depth': '1px', '--ds-ambient-hover-scale': '1', '--ds-ambient-hover-lift': '1px' },\n moderate: { '--ds-hover-scale': '1.035', '--ds-hover-lift': '3px', '--ds-press-depth': '1px', '--ds-ambient-hover-scale': '1.01', '--ds-ambient-hover-lift': '2px' },\n expressive: { '--ds-hover-scale': '1.05', '--ds-hover-lift': '6px', '--ds-press-depth': '2px', '--ds-ambient-hover-scale': '1.015', '--ds-ambient-hover-lift': '3px' },\n}\n\n/**\n * Computes hover motion tokens from structured config.\n * Handles both modern (interactive + ambient) and legacy (intensity) input shapes.\n */\nexport function computeHoverTokens(motion: MotionDecisions): Record<string, string> {\n const i = motion.interactive\n const a = motion.ambient\n\n if (i || a) {\n const interactive = i ?? DEFAULT_INTERACTIVE\n const ambient = a ?? DEFAULT_AMBIENT\n const hasScale = interactive.enabled && hasScaleEffect(interactive.effect)\n const hasILift = interactive.enabled && hasLiftEffect(interactive.effect)\n const hasAScale = ambient.enabled && hasScaleEffect(ambient.effect)\n const hasALift = ambient.enabled && hasLiftEffect(ambient.effect)\n return {\n '--ds-hover-scale': hasScale ? String(interactive.scale) : '1',\n '--ds-hover-lift': hasILift ? `${interactive.lift}px` : '0px',\n '--ds-press-depth': interactive.enabled ? `${interactive.pressDepth}px` : '0px',\n '--ds-interactive-hover-speed': `${interactive.speed}ms`,\n '--ds-interactive-hover-ease': interactive.ease,\n '--ds-ambient-hover-scale': hasAScale ? String(ambient.scale) : '1',\n '--ds-ambient-hover-lift': hasALift ? `${ambient.lift}px` : '0px',\n '--ds-ambient-hover-speed': `${ambient.speed}ms`,\n '--ds-ambient-hover-ease': ambient.ease,\n }\n }\n\n const base = INTENSITY_PRESETS[motion.intensity ?? 'subtle'] ?? INTENSITY_PRESETS['subtle']\n return {\n ...base,\n '--ds-interactive-hover-speed': `${motion.speed}ms`,\n '--ds-interactive-hover-ease': motion.ease,\n '--ds-ambient-hover-speed': `${Math.round(motion.speed * 1.5)}ms`,\n '--ds-ambient-hover-ease': 'cubic-bezier(0.33, 1, 0.68, 1)',\n }\n}\n\n/**\n * The motion tokens under prefers-reduced-motion, with their values: no hover scale, lift or press, and no transition\n * time (Sprint 25.8.7 item 1). The one list: roots.css's reduced-motion block declares exactly these, each important,\n * and the generated stylesheet ends with the same block, so a theme declared after roots.css or written on <html> can't\n * undo the visitor's preference. A writer that declares the tokens on a wrapper of its own writes these there itself\n * (the dashboard's ProjectThemeScope). The easing curves are left as they are: with no time they move nothing. A test\n * holds roots.css's block and the generator's to this list.\n */\nexport const REDUCED_MOTION_TOKENS: Record<string, string> = {\n '--ds-transition-speed': '0ms',\n '--ds-hover-scale': '1',\n '--ds-hover-lift': '0px',\n '--ds-press-depth': '0px',\n '--ds-interactive-hover-speed': '0ms',\n '--ds-ambient-hover-scale': '1',\n '--ds-ambient-hover-lift': '0px',\n '--ds-ambient-hover-speed': '0ms',\n}\n\n/**\n * Computes the accent colour of an independent-mode sidebar (or header) from\n * the target palette, as a literal because it comes from the *other* palette.\n * Since Sprint 20.10 it sits on the same --ds-primary-{shade} scale as the\n * page accent (it used to be a lighter curve, 0.597 at 500 against 0.55), so\n * the on-accent text decision flips at the same shade everywhere.\n * `onAccent` is the text colour over the accent, emitted as\n * --ds-sidebar-text-on-accent / --ds-header-text-on-accent.\n * Used by runtime DOM writers and static CSS generator.\n */\nexport function computeSidebarAccent(\n shade: number,\n satPrimary: number,\n huePrimary: number\n): { accent: string; accentSubtle: string; onAccent: string } {\n const colour = accentColour(shade, satPrimary, huePrimary)\n const accent = oklchCss(colour)\n const accentSubtle = `color-mix(in srgb, ${accent} 10%, transparent)`\n return { accent, accentSubtle, onAccent: onFillTextValue(colour) }\n}\n\n// Status hue positions (fixed, not configurable)\nconst STATUS_HUES = { success: 142, warning: 86, error: 25, info: 255 }\nconst STATUS_HUE_VALUES = Object.values(STATUS_HUES)\n\nconst GOLDEN_ANGLE = 137.508\n\n/**\n * Normalise a hue to [0, 360).\n */\nfunction normaliseHue(h: number): number {\n return ((h % 360) + 360) % 360\n}\n\n/**\n * Angular distance on the hue wheel (0–180).\n */\nfunction hueDistance(a: number, b: number): number {\n const diff = Math.abs(normaliseHue(a) - normaliseHue(b))\n return diff > 180 ? 360 - diff : diff\n}\n\n/**\n * Distributes 5 palette hues around the OKLCH hue wheel using golden-angle\n * spacing. Avoids the primary hue neighbourhood and status hue positions.\n *\n * @param primaryHue The user's primary accent hue (0–360)\n * @param exclusionRadius Minimum angular distance from primary and status hues (default 20°)\n * @returns Array of 5 hue values, each in [0, 360)\n */\nexport function computePaletteHues(\n primaryHue: number,\n exclusionRadius = 20\n): number[] {\n const hues: number[] = []\n const excluded = [normaliseHue(primaryHue), ...STATUS_HUE_VALUES]\n\n function isColliding(h: number): boolean {\n return excluded.some(ex => hueDistance(h, ex) < exclusionRadius) ||\n hues.some(existing => hueDistance(h, existing) < exclusionRadius)\n }\n\n // Start opposite the primary hue for maximum initial separation\n const cursor = normaliseHue(primaryHue + 180)\n\n for (let i = 0; i < 5; i++) {\n let candidate = normaliseHue(cursor + i * GOLDEN_ANGLE)\n\n // Nudge colliding candidates by +5° increments, up to a full rotation\n let attempts = 0\n while (isColliding(candidate) && attempts < 72) {\n candidate = normaliseHue(candidate + 5)\n attempts++\n }\n\n hues.push(candidate)\n }\n\n return hues\n}\n\n// Palette generation lightness/chroma targets\nconst PALETTE_BOLD_L = 0.55\nconst PALETTE_BOLD_C = 0.12\nconst PALETTE_SUBTLE_L = 0.92\nconst PALETTE_SUBTLE_C = 0.03\nconst PALETTE_DARK_L = 0.35\nconst PALETTE_DARK_C = 0.10\n\n/**\n * How far a palette bold may darken to keep white text (the owner's call, 26\n * September 2026). Teals and cyans near the sRGB edge (hues 170–216.5 at the\n * constants above) clip lighter than white allows at PALETTE_BOLD_L, and one\n * step of PALETTE_BOLD_STEP brings each to AA as drawn, so a row of Badges and\n * Tags keeps one text colour. A bold that no step up to this brings to AA keeps\n * its lightness and takes a tint of its hue.\n */\nexport const PALETTE_BOLD_MAX_DARKEN = 0.02\nconst PALETTE_BOLD_STEP = 0.01\n\n/**\n * A bold fill for white text: darkened by the smallest step (PALETTE_BOLD_STEP) that brings white to AA as drawn,\n * never by more than maxDarken; a fill no darkening within the cap brings there is returned as it was, and its text\n * takes a tint (onFillTextValue). getPaletteTokens passes PALETTE_BOLD_MAX_DARKEN; the cap is a parameter so a fill\n * that needs more than it can be tested (no palette hue does at today's constants).\n */\nexport function boldForWhiteText(fill: Oklch, maxDarken: number = PALETTE_BOLD_MAX_DARKEN): Oklch {\n let L = fill.L\n while (onFillText({ ...fill, L }) === 'dark' && fill.L - L < maxDarken - 1e-9) L = +(L - PALETTE_BOLD_STEP).toFixed(2)\n return onFillText({ ...fill, L }) === 'dark' ? fill : { ...fill, L }\n}\n\n/**\n * The lightness a chart series needs in dark mode to show at 3:1 against the surfaces a chart sits on (WCAG 1.4.11):\n * every hue at C 0.12 clears 3:1 on the elevated surface (neutral-700) and 4.5:1 on the card (neutral-800). It is\n * primary-400's lightness, as the light-mode series (the palette bold, 0.55, a step darker for the teals) is\n * primary-500's (Sprint 25.7).\n */\nexport const CHART_SERIES_DARK_L = 0.66\n\n/**\n * Generates the 5 palette tokens (bold/subtle/dark/bg/text) for a single hue.\n * Validates subtle/dark contrast and clamps chroma if needed.\n *\n * @param hue The palette hue value (0–360)\n * @param index Palette index (1–5) for token naming\n * @param mode 'light' | 'dark' — determines bg/text alias direction\n * @returns Record of CSS custom properties for this palette hue\n */\n/**\n * The soft pair of a hue (the supporting colours' step, Sprint 25.18's one rule for coloured text on a coloured ground,\n * the owner's D50): a pale fill and a deep text at fixed lightnesses, the gap widened until the pair reaches AA (4.5:1),\n * which these lightnesses already clear for every hue. `chroma` caps the two chromas: the supporting colours pass none\n * (their own constants); the accent passes its own chroma, so a grey accent gives a grey pair. Light mode draws the\n * pale one as the fill and the deep one as the text; dark mode swaps them.\n */\nexport function softPair(hue: number, chroma = Infinity): { subtle: string; dark: string } {\n const h = normaliseHue(hue)\n let subtleL = PALETTE_SUBTLE_L\n let darkL = PALETTE_DARK_L\n let ratio = estimateContrastRatio(subtleL, darkL)\n while (ratio < 4.5 && subtleL < 0.98 && darkL > 0.20) {\n subtleL = Math.min(0.98, subtleL + 0.02)\n darkL = Math.max(0.20, darkL - 0.02)\n ratio = estimateContrastRatio(subtleL, darkL)\n }\n const c = (constant: number) => Math.max(0, Math.min(constant, chroma)).toFixed(4)\n return {\n subtle: `oklch(${subtleL.toFixed(2)} ${c(PALETTE_SUBTLE_C)} ${h})`,\n dark: `oklch(${darkL.toFixed(2)} ${c(PALETTE_DARK_C)} ${h})`,\n }\n}\n\n/** The soft pair's lightnesses and chromas, for the stylesheet's own reading of the step (roots.css derives the accent's pair from them). */\nexport const SOFT_PAIR = { subtleL: PALETTE_SUBTLE_L, subtleC: PALETTE_SUBTLE_C, darkL: PALETTE_DARK_L, darkC: PALETTE_DARK_C } as const\n\n/**\n * The accent's soft pair (Sprint 25.18 A15, the owner's D51): the supporting colours' step applied to the accent, its\n * chroma capped by the accent's own (the primary scale's chroma at the accent's shade, times the saturation), so the\n * accent's tint and text are one more supporting colour. `--ds-accent-bg` is the fill, `--ds-accent-text` the text on it\n * (readable on the page and a card too); a Calendar event in the accent draws with them.\n */\nexport function getAccentPairTokens(shade: number, sat: number, hue: number, mode: 'light' | 'dark'): Record<string, string> {\n const { subtle, dark } = softPair(hue, accentColour(shade, sat, hue).C)\n return {\n '--ds-accent-bg': mode === 'light' ? subtle : dark,\n '--ds-accent-text': mode === 'light' ? dark : subtle,\n }\n}\n\nexport function getPaletteTokens(\n hue: number,\n index: number,\n mode: 'light' | 'dark'\n): Record<string, string> {\n const h = normaliseHue(hue)\n\n // Bold: white text as drawn, darkened within PALETTE_BOLD_MAX_DARKEN where the fill clips too light for it; past the\n // cap it keeps its lightness and its text takes a tint (below)\n const boldFill = boldForWhiteText({ L: PALETTE_BOLD_L, C: PALETTE_BOLD_C, H: h })\n const boldL = boldFill.L\n\n // Subtle/dark: the soft pair, at AA (softPair)\n const { subtle, dark } = softPair(h)\n const bold = `oklch(${boldL.toFixed(2)} ${PALETTE_BOLD_C.toFixed(4)} ${h})`\n\n const prefix = `--ds-palette-${index}`\n\n return {\n [`${prefix}-bold`]: bold,\n [`${prefix}-subtle`]: subtle,\n [`${prefix}-dark`]: dark,\n [`${prefix}-bg`]: mode === 'light' ? `var(${prefix}-subtle)` : `var(${prefix}-dark)`,\n [`${prefix}-text`]: mode === 'light' ? `var(${prefix}-dark)` : `var(${prefix}-subtle)`,\n // The chart series colour: the bold in light mode; lifted in dark, where the bold sinks into a dark card\n // (2.9:1 for reds and magentas on neutral-800). Badges and Tags keep the bold, for their white text.\n [`${prefix}-chart`]: mode === 'light' ? `var(${prefix}-bold)` : `oklch(${CHART_SERIES_DARK_L.toFixed(2)} ${PALETTE_BOLD_C.toFixed(4)} ${h})`,\n // Text on the bold fill (Badge / Tag colour variants), decided by contrast as\n // drawn: white, the teals and cyans that clip too light for it one step\n // darker (above); a deep tint of the hue only where no step within\n // PALETTE_BOLD_MAX_DARKEN brings white to AA.\n [`${prefix}-on-bold`]: onFillTextValue(boldFill),\n }\n}\n\n/**\n * The primary step chart-1 draws in: the accent's own when it shows at 3:1 on the mode's surfaces — 500 or darker on\n * a light card (PRIMARY_SCALE L 0.55 and below, the palette bold's lightness), 400 or lighter on a dark one (L 0.66\n * and above, CHART_SERIES_DARK_L) — else the nearest step that does.\n */\nexport function chartAccentShade(accentShade: number, mode: 'light' | 'dark'): number {\n const s = scaleShade(accentShade)\n return mode === 'dark' ? Math.min(s, 400) : Math.max(s, 500)\n}\n\n/**\n * Generates chart tokens that reference accent and palette values via var(). All values are CSS variable references,\n * not computed colours — the palette tokens must already exist in the same scope. chart-1 is the accent unless the\n * accent is too light (light mode) or too dark (dark mode) for a series, and then the nearest primary step that shows\n * (chartAccentShade); chart-2–6 are the palette's chart colours. Without an accent shade, chart-1 is the accent.\n *\n * @returns Record of 14 CSS custom properties (12 chart tokens + 2 backwards-compat aliases)\n */\nexport function computeChartTokens(accentShade?: number, mode: 'light' | 'dark' = 'light'): Record<string, string> {\n const series = accentShade == null ? null : chartAccentShade(accentShade, mode)\n const accent = series == null || series === scaleShade(accentShade!) ? 'var(--ds-accent-primary)' : `var(--ds-primary-${series})`\n const tokens: Record<string, string> = {\n '--ds-chart-1': accent,\n '--ds-chart-1-soft': `color-mix(in oklch, ${accent} 30%, transparent)`,\n }\n\n for (let i = 1; i <= 5; i++) {\n tokens[`--ds-chart-${i + 1}`] = `var(--ds-palette-${i}-chart)`\n tokens[`--ds-chart-${i + 1}-soft`] = `color-mix(in oklch, var(--ds-palette-${i}-chart) 30%, transparent)`\n }\n\n // Backwards-compat aliases\n tokens['--ds-chart-fill'] = `var(--ds-chart-1)`\n tokens['--ds-chart-fill-soft'] = `var(--ds-chart-1-soft)`\n\n return tokens\n}\n\n/**\n * Approximate WCAG contrast ratio between two OKLCH lightness values.\n * Uses L³ as a luminance proxy (OKLCH lightness is perceptual, L³ ≈ relative luminance).\n * Returns estimated ratio (1.0 to 21.0). Kept for the palette subtle/dark\n * pair, which only needs a ranking; on-fill text decisions use\n * `oklchToLuminance` + `contrastRatio` (Sprint 20.10), which account for hue,\n * chroma and gamut.\n */\nexport function estimateContrastRatio(L1: number, L2: number): number {\n const lum1 = Math.pow(Math.max(0, Math.min(1, L1)), 3)\n const lum2 = Math.pow(Math.max(0, Math.min(1, L2)), 3)\n const lighter = Math.max(lum1, lum2)\n const darker = Math.min(lum1, lum2)\n return (lighter + 0.05) / (darker + 0.05)\n}\n\n/**\n * Approximate WCAG contrast ratio between an oklch colour and white.\n * Delegates to estimateContrastRatio with L2 = 1.0 (white).\n */\nexport function estimateContrastVsWhite(oklchL: number): number {\n return estimateContrastRatio(oklchL, 1.0)\n}\n\n// ---------------------------------------------------------------------------\n// Navigation active styles (Sprint 20.8)\n// ---------------------------------------------------------------------------\n//\n// The *shape* of an active navigation item is a theme decision, not a per-page\n// one. Three decisions (sidebar, in-page horizontal, in-page vertical) resolve\n// to 24 CSS custom properties that SidebarNav, Tabs and TreeView read. Every\n// value is a var() of an existing mode-aware token or a plain length, so the\n// set has one body — but because var() inside a custom property is substituted\n// where it is *declared*, emitters must declare the set in every scope that\n// redeclares one of its inputs (:root, [data-mode], [data-ds-overlay]).\n//\n// The defaults reproduce today's rendering exactly (sprint §0.1). Do not\n// \"improve\" a default value here — that is a product change with its own\n// changelog entry.\n\nexport type SidebarActiveStyle = 'rail' | 'tint' | 'pill'\nexport type InPageHorizontalStyle = 'underline' | 'tint' | 'pill'\nexport type InPageVerticalStyle = 'rail' | 'tint' | 'pill'\n\nexport interface NavStyleInput {\n sidebarActiveStyle?: SidebarActiveStyle\n /** Only used to derive the default and the coercion: minimal and compact sidebars have no edge to stroke, so their default is tint and an explicit rail resolves to tint. */\n sidebarType?: 'traditional' | 'compact' | 'minimal'\n inPageHorizontal?: InPageHorizontalStyle\n inPageVertical?: InPageVerticalStyle\n}\n\nexport interface ResolvedNavStyles {\n sidebarActiveStyle: SidebarActiveStyle\n inPageHorizontal: InPageHorizontalStyle\n inPageVertical: InPageVerticalStyle\n}\n\n/**\n * The only place the missing-field defaults and the no-edge coercion (minimal\n * and compact sidebars) live. Every reader (deserialisers, Worker readers, CSS emitters, the rules\n * file) calls this — nobody writes `?? 'rail'` anywhere else.\n *\n * The coercion is render-time only: stored state keeps the user's choice so\n * switching a minimal or compact sidebar back to traditional restores the rail.\n */\nexport function resolveNavStyles(input: NavStyleInput): ResolvedNavStyles {\n const noEdge = input.sidebarType === 'minimal' || input.sidebarType === 'compact'\n let sidebarActiveStyle: SidebarActiveStyle = input.sidebarActiveStyle ?? (noEdge ? 'tint' : 'rail')\n if (noEdge && sidebarActiveStyle === 'rail') sidebarActiveStyle = 'tint'\n return {\n sidebarActiveStyle,\n inPageHorizontal: input.inPageHorizontal ?? 'underline',\n inPageVertical: input.inPageVertical ?? 'rail',\n }\n}\n\nconst ON_PRIMARY = 'var(--ds-text-on-primary)'\nconst SIDEBAR_ON_ACCENT = 'var(--ds-sidebar-text-on-accent)'\nconst ACCENT = 'var(--ds-accent-primary)'\n/** The accent as text (Sprint 30, P8): the theme's derived ink, readable on the page and on the accent's own tint; fills keep ACCENT. */\nconst ACCENT_INK = 'var(--ds-accent-ink)'\n/** The sidebar's current item as text and its marks (P8): the sidebar family's own ink. */\nconst SIDEBAR_INK = 'var(--ds-sidebar-accent-ink)'\nconst ACCENT_SUBTLE = 'var(--ds-accent-subtle)'\nconst PILL_BADGE_BG = 'color-mix(in oklab, var(--ds-bg-canvas) 20%, transparent)'\n\n/**\n * The 25 tokens of sprint §4 for the resolved styles (24, plus the sidebar\n * pill's gradient image — September 2026).\n */\nexport function getNavStyleTokens(input: NavStyleInput): Record<string, string> {\n const { sidebarActiveStyle, inPageHorizontal, inPageVertical } = resolveNavStyles(input)\n const tokens: Record<string, string> = {}\n\n // ── In-page horizontal (Tabs) ─────────────────────────────────────────\n switch (inPageHorizontal) {\n case 'underline':\n tokens['--ds-nav-h-active-bg'] = 'transparent'\n tokens['--ds-nav-h-active-text'] = 'var(--ds-text-primary)'\n tokens['--ds-nav-h-inactive-text'] = 'var(--ds-text-muted)'\n tokens['--ds-nav-h-indicator'] = 'calc(var(--ds-border-width) * 3)'\n tokens['--ds-nav-h-item-radius'] = '0px'\n tokens['--ds-nav-h-hover-bg'] = 'transparent'\n tokens['--ds-nav-h-track-border'] = 'var(--ds-border-width)'\n tokens['--ds-nav-h-track-gap'] = '0px'\n tokens['--ds-nav-h-badge-bg'] = ACCENT\n break\n case 'tint':\n tokens['--ds-nav-h-active-bg'] = ACCENT_SUBTLE\n tokens['--ds-nav-h-active-text'] = ACCENT_INK\n tokens['--ds-nav-h-inactive-text'] = 'var(--ds-text-secondary)'\n tokens['--ds-nav-h-indicator'] = '0px'\n tokens['--ds-nav-h-item-radius'] = 'var(--ds-radius-sm)'\n tokens['--ds-nav-h-hover-bg'] = 'var(--ds-tab-hover-bg)'\n tokens['--ds-nav-h-track-border'] = '0px'\n tokens['--ds-nav-h-track-gap'] = 'var(--ds-space-1)'\n tokens['--ds-nav-h-badge-bg'] = ACCENT\n break\n case 'pill':\n tokens['--ds-nav-h-active-bg'] = ACCENT\n tokens['--ds-nav-h-active-text'] = ON_PRIMARY\n tokens['--ds-nav-h-inactive-text'] = 'var(--ds-text-secondary)'\n tokens['--ds-nav-h-indicator'] = '0px'\n tokens['--ds-nav-h-item-radius'] = 'var(--ds-radius-md)'\n tokens['--ds-nav-h-hover-bg'] = 'var(--ds-tab-hover-bg)'\n tokens['--ds-nav-h-track-border'] = '0px'\n tokens['--ds-nav-h-track-gap'] = 'var(--ds-space-1)'\n tokens['--ds-nav-h-badge-bg'] = PILL_BADGE_BG\n break\n }\n\n // ── In-page vertical (Tabs rail) ──────────────────────────────────────\n switch (inPageVertical) {\n case 'rail':\n tokens['--ds-nav-v-active-bg'] = 'var(--ds-tab-active-bg)'\n tokens['--ds-nav-v-active-text'] = ACCENT_INK\n tokens['--ds-nav-v-active-rail'] = 'var(--ds-border-width-thick)'\n tokens['--ds-nav-v-item-radius'] = 'var(--ds-radius-sm)'\n tokens['--ds-nav-v-track-border'] = '0px'\n tokens['--ds-nav-v-track-padding'] = 'var(--ds-space-1)'\n // Secondary lines on the selected row (StackedList subtitle/description/meta): readable on the accent bar under pill.\n tokens['--ds-nav-v-active-muted'] = 'var(--ds-text-secondary)'\n tokens['--ds-nav-v-badge-bg'] = ACCENT\n break\n case 'tint':\n tokens['--ds-nav-v-active-bg'] = ACCENT_SUBTLE\n tokens['--ds-nav-v-active-text'] = ACCENT_INK\n tokens['--ds-nav-v-active-rail'] = '0px'\n tokens['--ds-nav-v-item-radius'] = 'var(--ds-radius-md)'\n tokens['--ds-nav-v-track-border'] = '0px'\n tokens['--ds-nav-v-track-padding'] = '0px'\n // Secondary lines on the selected row (StackedList subtitle/description/meta): readable on the accent bar under pill.\n tokens['--ds-nav-v-active-muted'] = 'var(--ds-text-secondary)'\n tokens['--ds-nav-v-badge-bg'] = ACCENT\n break\n case 'pill':\n tokens['--ds-nav-v-active-bg'] = ACCENT\n tokens['--ds-nav-v-active-text'] = ON_PRIMARY\n tokens['--ds-nav-v-active-rail'] = '0px'\n tokens['--ds-nav-v-item-radius'] = 'var(--ds-radius-sm)'\n tokens['--ds-nav-v-track-border'] = '0px'\n tokens['--ds-nav-v-track-padding'] = '0px'\n // Secondary lines on the selected row (StackedList subtitle/description/meta): readable on the accent bar under pill.\n tokens['--ds-nav-v-active-muted'] = 'color-mix(in srgb, var(--ds-text-on-primary) 80%, transparent)'\n tokens['--ds-nav-v-badge-bg'] = PILL_BADGE_BG\n break\n }\n\n // ── Tree ──────────────────────────────────────────────────────────────\n // `-muted` is the chevron on the selected row: muted grey today, on-primary\n // under pill so it stays visible on the full-width accent bar.\n switch (inPageVertical) {\n case 'rail':\n tokens['--ds-tree-active-bg'] = 'var(--ds-tab-active-bg)'\n tokens['--ds-tree-active-text'] = ACCENT_INK\n tokens['--ds-tree-active-muted'] = 'var(--ds-text-muted)'\n tokens['--ds-tree-active-rail'] = 'var(--ds-border-width-thick)'\n break\n case 'tint':\n tokens['--ds-tree-active-bg'] = ACCENT_SUBTLE\n tokens['--ds-tree-active-text'] = ACCENT_INK\n tokens['--ds-tree-active-muted'] = 'var(--ds-text-muted)'\n tokens['--ds-tree-active-rail'] = '0px'\n break\n case 'pill':\n tokens['--ds-tree-active-bg'] = ACCENT\n tokens['--ds-tree-active-text'] = ON_PRIMARY\n tokens['--ds-tree-active-muted'] = ON_PRIMARY\n tokens['--ds-tree-active-rail'] = '0px'\n break\n }\n\n // ── Sidebar ───────────────────────────────────────────────────────────\n // Decision 21: the active root label takes the sidebar accent for rail and\n // tint, matching Tabs, TreeView and NavItem (pre-20.8 it stayed neutral with\n // only the icon in accent). A deliberate default change, recorded in the\n // changelog.\n switch (sidebarActiveStyle) {\n case 'rail':\n tokens['--ds-sidebar-active-bg'] = 'var(--ds-sidebar-accent-subtle)'\n tokens['--ds-sidebar-active-text'] = SIDEBAR_INK\n tokens['--ds-sidebar-active-accent'] = SIDEBAR_INK\n tokens['--ds-sidebar-active-rail'] = 'var(--ds-border-width-thick)'\n tokens['--ds-sidebar-active-image'] = 'none'\n break\n case 'tint':\n tokens['--ds-sidebar-active-bg'] = 'var(--ds-sidebar-accent-subtle)'\n tokens['--ds-sidebar-active-text'] = SIDEBAR_INK\n tokens['--ds-sidebar-active-accent'] = SIDEBAR_INK\n tokens['--ds-sidebar-active-rail'] = '0px'\n tokens['--ds-sidebar-active-image'] = 'none'\n break\n case 'pill':\n // The sidebar accent may come from the other palette (independent mode),\n // so its on-accent text is the scoped token, which roots.css defaults to\n // --ds-text-on-primary for match mode.\n tokens['--ds-sidebar-active-bg'] = 'var(--ds-sidebar-accent)'\n tokens['--ds-sidebar-active-text'] = SIDEBAR_ON_ACCENT\n tokens['--ds-sidebar-active-accent'] = SIDEBAR_ON_ACCENT\n tokens['--ds-sidebar-active-rail'] = '0px'\n // The pill takes the accent gradient like Button does: --ds-sidebar-gradient\n // is the page gradient in match mode and the target palette's gradient in\n // an independent mode (none when the accent is solid).\n tokens['--ds-sidebar-active-image'] = 'var(--ds-sidebar-gradient)'\n break\n }\n\n return tokens\n}\n\n/**\n * Sprint 25.14 A20: the switch's off look — no fill, and the strong edge colour for its outline and its knob, as Fluent\n * 2's off switch is. Only the theme writers emit these (generateTokensCss and ThemeContext, beside the nav style set, so\n * each scope resolves them against its own edge), never roots.css: an app that upgrades the library without\n * regenerating its stylesheet keeps the switch its stylesheet draws (the Toggle falls back to the filled one without it).\n * Sprint 25.19 K2: the edge is `--ds-control-edge-strong`, the theme's 3:1 edge, since a field's resting edge\n * (`--ds-input-border`) is the soft border again; the generator writes the strong edge in every mode's block, so a\n * stylesheet made by 0.27.0 resolves it with an earlier library's roots.css too.\n *\n * The knob is the lightest shade of the edge that still reaches 3:1 on every ground (the owner, 30 September: the black\n * knob of a black-edged theme was \"very bold, unnecessarily so\"): the edge mixed toward the surface, keeping\n * `--ds-switch-knob-share` of it. A preset whose edge is far past 3:1 sets the share per mode (neo-brutalist light keeps\n * under half its black); everywhere else it is the edge itself. The knob's place is the switch's state, so it needs\n * the 3:1 an outline does. Declared with the set, the mix reads each scope's own edge and surface.\n */\nexport const SWITCH_TOKENS: Record<string, string> = {\n '--ds-switch-off-fill': 'transparent',\n '--ds-switch-off-edge': 'var(--ds-control-edge-strong)',\n '--ds-switch-off-knob': 'color-mix(in oklab, var(--ds-control-edge-strong) var(--ds-switch-knob-share, 100%), var(--ds-bg-surface))',\n}\n\n/**\n * The checked colour (a checked box, a selected radio's dot, a switch's track when on) and its mark: the accent, unless\n * the preset sets its own for the mode. roots.css declares them once, at the root (@sync, check-tokens.test.ts checks).\n * A writer redeclares them in every block that redeclares the accent for another scope (the other mode's block, a dark\n * portal, a project's theme wrapper), before that scope's preset overrides, so they follow the scope's accent, not the\n * page's (the review of 30 September: since A20 a dark sidebar's switch on a light page took the light check colour).\n * Never under NAV_STYLE_SCOPE_SELECTOR: a same-mode wrapper or an overlay would lose the page preset's own check colour,\n * which some presets set for 3:1. --ds-check-gradient is left to inherit: a scope may take the page's `none`, a look\n * without the gradient, never a weaker fill.\n */\nexport const CHECK_TOKENS: Record<string, string> = {\n '--ds-check-bg': 'var(--ds-accent-primary)',\n '--ds-check-fg': 'var(--ds-text-on-primary)',\n '--ds-check-border': 'var(--ds-accent-primary)',\n}\n\n/**\n * Selector under which every emitter declares the nav style set. One rule\n * reaching the root, every nested mode wrapper and every overlay portal, so\n * the var() aliases resolve against each scope's own inputs.\n */\nexport const NAV_STYLE_SCOPE_SELECTOR = ':root, [data-mode], [data-ds-overlay]'\n\n// ---------------------------------------------------------------------------\n// Readable colours (Sprint 30, T1)\n// ---------------------------------------------------------------------------\n//\n// The colours a theme derives so they read on what they're drawn on: the focus outline (3:1, WCAG 1.4.11), the quiet\n// greys, the accent as text and the status words (4.5:1, 1.4.3). Each is the theme's own colour wherever that reaches\n// its minimum against every ground it sits on. Otherwise it is the nearest colour that does: the same colour a little\n// darker on a light ground, a little lighter on a dark one, keeping its hue, chroma and see-through-ness, so the look\n// changes no more than the minimum asks (the owner, 2 October 2026: the look comes first).\n//\n// The grounds are read from the theme as it is written: a preset's or a saved theme's values (the presets write them\n// with calc() and var(), which parseOklch can't read), see-through surfaces laid over the page, and the glows a canvas\n// gradient paints. Colours are laid over one another in gamma-encoded sRGB, as the browser composites them, and\n// measured with the range Chrome's rounding can land in (luminanceRange, worstContrastOf). Glass's backdrop blur and\n// saturation are not modelled; T6's Chrome pass measures the drawn page.\n\n/** A colour as the browser composites it: gamma-encoded sRGB channels (0–1, clipped to the gamut) and an alpha. */\nexport interface Paint { rgb: readonly [number, number, number]; alpha: number }\n\n/** The theme variables the roots.css scales read, as one block of tokens sees them. */\nexport interface ScaleVars {\n huePrimary: number\n satPrimary: number\n hueNeutral: number\n satNeutral: number\n hueSuccess: number\n hueWarning: number\n hueDestructive: number\n}\n\ntype ScaleName = 'primary' | 'neutral' | 'destructive' | 'success' | 'warning' | 'info'\n\n/**\n * The roots.css colour scales: [lightness, chroma] per step, the chroma multiplied by the scale's saturation where it\n * has one, at the scale's hue (info's is fixed). @sync roots.css (sprint30-readable-colours.test.ts checks every step).\n */\nexport const CSS_SCALES: Record<ScaleName, { hue: keyof ScaleVars | number; sat: keyof ScaleVars | null; steps: Record<number, readonly [number, number]> }> = {\n primary: {\n hue: 'huePrimary', sat: 'satPrimary',\n steps: { 50: [0.97, 0.025], 100: [0.93, 0.050], 200: [0.87, 0.100], 300: [0.77, 0.150], 400: [0.66, 0.180], 500: [0.55, 0.200], 600: [0.47, 0.185], 700: [0.40, 0.165], 800: [0.33, 0.135], 900: [0.25, 0.100], 950: [0.17, 0.060] },\n },\n neutral: {\n hue: 'hueNeutral', sat: 'satNeutral',\n steps: { 50: [0.97, 0.007], 100: [0.94, 0.009], 200: [0.90, 0.010], 300: [0.84, 0.010], 400: [0.71, 0.009], 500: [0.55, 0.007], 600: [0.45, 0.006], 700: [0.37, 0.005], 800: [0.27, 0.004], 900: [0.20, 0.003], 950: [0.13, 0.002] },\n },\n destructive: { hue: 'hueDestructive', sat: null, steps: { 50: [0.97, 0.015], 100: [0.93, 0.040], 400: [0.66, 0.200], 500: [0.55, 0.220], 600: [0.47, 0.200], 950: [0.15, 0.050] } },\n success: { hue: 'hueSuccess', sat: null, steps: { 50: [0.97, 0.020], 100: [0.93, 0.045], 400: [0.66, 0.170], 500: [0.52, 0.160], 600: [0.45, 0.145], 950: [0.15, 0.040] } },\n warning: { hue: 'hueWarning', sat: null, steps: { 50: [0.97, 0.020], 100: [0.93, 0.060], 400: [0.78, 0.155], 500: [0.75, 0.160], 600: [0.65, 0.145], 950: [0.20, 0.040] } },\n info: { hue: 230, sat: null, steps: { 50: [0.97, 0.020], 100: [0.93, 0.045], 400: [0.66, 0.170], 500: [0.52, 0.160], 950: [0.15, 0.040] } },\n}\n\n/** The CSS variables a colour expression may read, and the scale variable each is. */\nconst SCALE_VAR_NAMES: Record<string, keyof ScaleVars> = {\n '--ds-hue-primary': 'huePrimary',\n '--ds-sat-primary': 'satPrimary',\n '--ds-hue-neutral': 'hueNeutral',\n '--ds-sat-neutral': 'satNeutral',\n '--ds-hue-success': 'hueSuccess',\n '--ds-hue-warning': 'hueWarning',\n '--ds-hue-destructive': 'hueDestructive',\n}\n\n/** The index of the parenthesis that closes the one at `open`, or -1. */\nfunction closingParen(src: string, open: number): number {\n let depth = 0\n for (let i = open; i < src.length; i++) {\n if (src[i] === '(') depth++\n else if (src[i] === ')' && --depth === 0) return i\n }\n return -1\n}\n\n/** Splits at `sep` outside parentheses (a whitespace `sep` splits at runs of whitespace). */\nfunction splitTopLevel(src: string, sep: ',' | '/' | ' '): string[] {\n const parts: string[] = []\n let depth = 0\n let start = 0\n for (let i = 0; i < src.length; i++) {\n const ch = src[i]\n if (ch === '(') depth++\n else if (ch === ')') depth--\n else if (depth === 0 && (sep === ' ' ? /\\s/.test(ch) : ch === sep)) {\n parts.push(src.slice(start, i))\n start = i + 1\n }\n }\n parts.push(src.slice(start))\n return parts.map((p) => p.trim()).filter((p) => p !== '')\n}\n\n/**\n * A number from a CSS expression: a plain number or percentage (50% is 0.5), a var() of one of the scale variables,\n * or a calc() of those with + − × ÷. NaN for anything else (an unknown variable, a unit).\n */\nexport function evalCssNumber(expr: string, vars: ScaleVars): number {\n const src = expr.trim()\n let i = 0\n const ws = () => { while (i < src.length && /\\s/.test(src[i])) i++ }\n const sum = (): number => {\n let v = product()\n for (;;) {\n ws()\n const op = src[i]\n if (op !== '+' && op !== '-') return v\n i++\n const r = product()\n v = op === '+' ? v + r : v - r\n }\n }\n const product = (): number => {\n let v = factor()\n for (;;) {\n ws()\n const op = src[i]\n if (op !== '*' && op !== '/') return v\n i++\n const r = factor()\n v = op === '*' ? v * r : v / r\n }\n }\n const factor = (): number => {\n ws()\n if (src.startsWith('calc(', i) || src[i] === '(') {\n const open = src[i] === '(' ? i : i + 4\n const close = closingParen(src, open)\n if (close < 0) return NaN\n const inner = evalCssNumber(src.slice(open + 1, close), vars)\n i = close + 1\n return inner\n }\n if (src.startsWith('var(', i)) {\n const close = closingParen(src, i + 3)\n if (close < 0) return NaN\n const name = splitTopLevel(src.slice(i + 4, close), ',')[0]\n i = close + 1\n const key = SCALE_VAR_NAMES[name]\n return key ? vars[key] : NaN\n }\n if (src[i] === '-') { i++; return -factor() }\n const m = /^(\\d*\\.?\\d+(?:e[+-]?\\d+)?)(%|deg)?/i.exec(src.slice(i))\n if (!m) return NaN\n i += m[0].length\n return m[2] === '%' ? parseFloat(m[1]) / 100 : parseFloat(m[1])\n }\n const v = sum()\n ws()\n return i === src.length ? v : NaN\n}\n\nconst WHITE_PAINT: Paint = { rgb: [1, 1, 1], alpha: 1 }\n\nfunction paintOfOklch(colour: Oklch, alpha = 1): Paint {\n return { rgb: oklchToSrgb(colour), alpha }\n}\n\n/** A scale step's colour (--ds-neutral-400 and the rest), or null when the name is not one. */\nfunction scaleColour(name: string, vars: ScaleVars): { scale: ScaleName; step: number; colour: Oklch } | null {\n const m = /^--ds-(primary|neutral|destructive|success|warning|info)-(\\d+)$/.exec(name)\n if (!m) return null\n const scale = m[1] as ScaleName\n const def = CSS_SCALES[scale]\n const step = Number(m[2])\n const entry = def.steps[step]\n if (!entry) return null\n const sat = def.sat ? vars[def.sat] : 1\n const hue = typeof def.hue === 'number' ? def.hue : vars[def.hue]\n return { scale, step, colour: { L: entry[0], C: entry[1] * sat, H: hue } }\n}\n\n/** The parts of an oklch() value: each component's text, and its numbers where they evaluate. */\ninterface OklchParts { L: number; C: number; H: number; alpha: number; cText: string; hText: string }\n\nfunction oklchParts(value: string, vars: ScaleVars): OklchParts | null {\n const v = value.trim()\n if (!/^oklch\\(/i.test(v) || closingParen(v, 5) !== v.length - 1) return null\n const inner = v.slice(6, -1)\n if (/^\\s*from\\s/i.test(inner)) return null\n const [colourPart, alphaPart] = splitTopLevel(inner, '/')\n const comps = splitTopLevel(colourPart ?? '', ' ')\n if (comps.length !== 3) return null\n const L = evalCssNumber(comps[0], vars)\n const C = evalCssNumber(comps[1], vars)\n const H = evalCssNumber(comps[2], vars)\n const alpha = alphaPart === undefined ? 1 : evalCssNumber(alphaPart, vars)\n if (![L, C, H, alpha].every(Number.isFinite)) return null\n return { L, C, H, alpha: Math.max(0, Math.min(1, alpha)), cText: comps[1], hText: comps[2] }\n}\n\n/** `color-mix(in srgb, A p%, B q%)` as CSS Color 5 mixes it: premultiplied, the percentages normalised, a sum under 100% lowering the alpha. */\nfunction mixedPaint(value: string, tokens: Record<string, string>, vars: ScaleVars, depth: number): Paint | null {\n const v = value.trim()\n if (closingParen(v, 9) !== v.length - 1) return null\n const args = splitTopLevel(v.slice(10, -1), ',')\n if (args.length !== 3 || !/^in\\s+srgb$/i.test(args[0])) return null\n const side = (arg: string) => {\n const parts = splitTopLevel(arg, ' ')\n const pct = parts.length > 1 && /%$/.test(parts[parts.length - 1]) ? parseFloat(parts.pop()!) / 100 : undefined\n return { paint: resolvePaint(parts.join(' '), tokens, vars, depth + 1), pct }\n }\n const a = side(args[1])\n const b = side(args[2])\n if (!a.paint || !b.paint) return null\n let p1 = a.pct ?? (b.pct !== undefined ? 1 - b.pct : 0.5)\n let p2 = b.pct ?? 1 - p1\n const total = p1 + p2\n if (total <= 0) return null\n const multiplier = Math.min(1, total)\n p1 /= total\n p2 /= total\n const alpha = a.paint.alpha * p1 + b.paint.alpha * p2\n if (alpha <= 0) return { rgb: [0, 0, 0], alpha: 0 }\n const rgb = [0, 1, 2].map((i) => (a.paint!.rgb[i] * a.paint!.alpha * p1 + b.paint!.rgb[i] * b.paint!.alpha * p2) / alpha) as [number, number, number]\n return { rgb, alpha: alpha * multiplier }\n}\n\n/** A #rgb, #rrggbb or #rrggbbaa colour. */\nfunction hexPaint(value: string): Paint | null {\n const m = /^#([0-9a-f]{3,8})$/i.exec(value.trim())\n if (!m || ![3, 4, 6, 8].includes(m[1].length)) return null\n const hex = m[1].length <= 4 ? m[1].split('').map((c) => c + c).join('') : m[1]\n const n = (k: number) => parseInt(hex.slice(k * 2, k * 2 + 2), 16) / 255\n return { rgb: [n(0), n(1), n(2)], alpha: hex.length === 8 ? n(3) : 1 }\n}\n\n/** An rgb()/rgba() colour with 0–255 channels. */\nfunction rgbPaint(value: string): Paint | null {\n const m = /^rgba?\\(([^)]*)\\)$/i.exec(value.trim())\n if (!m) return null\n const parts = m[1].split(/[\\s,/]+/).filter(Boolean)\n if (parts.length < 3) return null\n const ch = parts.slice(0, 3).map((p) => (p.endsWith('%') ? parseFloat(p) / 100 : parseFloat(p) / 255))\n const alpha = parts[3] === undefined ? 1 : parts[3].endsWith('%') ? parseFloat(parts[3]) / 100 : parseFloat(parts[3])\n if (![...ch, alpha].every(Number.isFinite)) return null\n return { rgb: ch.map((c) => Math.max(0, Math.min(1, c))) as [number, number, number], alpha }\n}\n\n/**\n * A token or a CSS colour value as the browser would paint it, followed through the block's own declarations\n * (`tokens`) and the roots.css scales. Null where it can't be known (an image, an unknown function or variable).\n */\nexport function resolvePaint(value: string, tokens: Record<string, string>, vars: ScaleVars, depth = 0): Paint | null {\n if (depth > 24) return null\n const v = value.trim()\n if (v === 'transparent') return { rgb: [0, 0, 0], alpha: 0 }\n if (v.startsWith('var(')) {\n if (closingParen(v, 3) !== v.length - 1) return null\n const [name, ...fallback] = splitTopLevel(v.slice(4, -1), ',')\n const own = tokens[name]\n if (own !== undefined) return resolvePaint(own, tokens, vars, depth + 1)\n const scaled = scaleColour(name, vars)\n if (scaled) return paintOfOklch(scaled.colour)\n return fallback.length ? resolvePaint(fallback.join(','), tokens, vars, depth + 1) : null\n }\n if (/^oklch\\(/i.test(v)) {\n const parts = oklchParts(v, vars)\n return parts ? paintOfOklch({ L: parts.L, C: parts.C, H: parts.H }, parts.alpha) : null\n }\n if (/^color-mix\\(/i.test(v)) return mixedPaint(v, tokens, vars, depth)\n if (v.startsWith('#')) return hexPaint(v)\n if (/^rgba?\\(/i.test(v)) return rgbPaint(v)\n if (/^color\\(\\s*srgb\\s/i.test(v)) return srgbFunctionPaint(v)\n if (/^oklab\\(/i.test(v)) return oklabPaint(v)\n return null\n}\n\n/** `color(srgb r g b / a)`, as Chrome serialises a computed colour mixed in sRGB. */\nfunction srgbFunctionPaint(value: string): Paint | null {\n const m = /^color\\(\\s*srgb\\s+([^)]*)\\)$/i.exec(value.trim())\n if (!m) return null\n const [rgbPart, alphaPart] = m[1].split('/')\n const ch = rgbPart.trim().split(/\\s+/).map((p) => (p.endsWith('%') ? parseFloat(p) / 100 : parseFloat(p)))\n const alpha = alphaPart === undefined ? 1 : alphaPart.trim().endsWith('%') ? parseFloat(alphaPart) / 100 : parseFloat(alphaPart)\n if (ch.length !== 3 || ![...ch, alpha].every(Number.isFinite)) return null\n return { rgb: ch.map((c) => Math.max(0, Math.min(1, c))) as [number, number, number], alpha }\n}\n\n/** `oklab(L a b / alpha)`, as Chrome serialises some computed colours. */\nfunction oklabPaint(value: string): Paint | null {\n const m = /^oklab\\(([^)]*)\\)$/i.exec(value.trim())\n if (!m) return null\n const [labPart, alphaPart] = m[1].split('/')\n const [L, a, b] = labPart.trim().split(/\\s+/).map((p, i) => (p.endsWith('%') ? (parseFloat(p) / 100) * (i === 0 ? 1 : 0.4) : parseFloat(p)))\n const alpha = alphaPart === undefined ? 1 : alphaPart.trim().endsWith('%') ? parseFloat(alphaPart) / 100 : parseFloat(alphaPart)\n if (![L, a, b, alpha].every(Number.isFinite)) return null\n return paintOfOklch({ L, C: Math.hypot(a, b), H: ((Math.atan2(b, a) * 180) / Math.PI + 360) % 360 }, alpha)\n}\n\n/** `top` laid over `ground` (source-over in gamma-encoded sRGB, as the browser composites). */\nexport function paintOver(top: Paint, ground: Paint): Paint {\n const alpha = top.alpha + ground.alpha * (1 - top.alpha)\n if (alpha <= 0) return { rgb: [0, 0, 0], alpha: 0 }\n const rgb = [0, 1, 2].map((i) => (top.rgb[i] * top.alpha + ground.rgb[i] * ground.alpha * (1 - top.alpha)) / alpha) as [number, number, number]\n return { rgb, alpha }\n}\n\n/** The lowest contrast `text` shows over an opaque `ground` (see-through text laid over it first), every way either can round. */\nexport function paintContrast(text: Paint, ground: Paint): number {\n const drawnGround = ground.alpha >= 1 ? ground : paintOver(ground, WHITE_PAINT)\n return worstContrastOf(srgbLuminanceRange(paintOver(text, drawnGround).rgb), srgbLuminanceRange(drawnGround.rgb))\n}\n\n/** The lowest contrast `text` shows over any of `grounds` (Infinity for none). */\nexport function worstPaintContrast(text: Paint, grounds: readonly Paint[]): number {\n let min = Infinity\n for (const g of grounds) min = Math.min(min, paintContrast(text, g))\n return min\n}\n\n/**\n * The colours a canvas gradient shows (presets.ts's `canvasGradientLight`/`Dark`, a saved theme's own): its last\n * layer's colours are the base, each laid over the canvas colour if see-through; every layer above is laid over each\n * base colour at the strongest it shows. A radial glow fades from its first colour to transparent, so where its centre\n * sits outside the page only part of it shows (an `ellipse 80% 50% at 20% -10%` peaks at 71% at the top edge, its\n * nearest point); a line pattern or a flat wash shows at full strength somewhere.\n */\nexport function gradientPaints(gradient: string, tokens: Record<string, string>, vars: ScaleVars, under: Paint): Paint[] {\n const layers = splitLayers(gradient)\n if (!layers.length) return []\n const parsed = layers.map((layer) => gradientLayer(layer, tokens, vars))\n const bases = uniquePaints(parsed[parsed.length - 1].stops.map((s) => (s.paint.alpha >= 1 ? s.paint : paintOver(s.paint, under))))\n if (!bases.length) bases.push(under)\n const out = [...bases]\n for (const layer of parsed.slice(0, -1)) {\n const lead = layer.stops.find((s) => s.paint.alpha > 0)\n if (!lead) continue\n const strength = layer.radial ? radialStrength(layer.radial, layer.stops) : 1\n const glow: Paint = { rgb: lead.paint.rgb, alpha: lead.paint.alpha * strength }\n if (glow.alpha <= 0) continue\n for (const base of bases) out.push(paintOver(glow, base))\n }\n return out\n}\n\n/** The paints, each once. */\nfunction uniquePaints(paints: Paint[]): Paint[] {\n const seen = new Set<string>()\n return paints.filter((p) => {\n const key = `${p.rgb.map((c) => c.toFixed(5)).join(',')}/${p.alpha.toFixed(5)}`\n if (seen.has(key)) return false\n seen.add(key)\n return true\n })\n}\n\n/** A gradient value's layers: each top-level `…-gradient(…)` function. */\nfunction splitLayers(gradient: string): string[] {\n const layers: string[] = []\n const re = /(?:repeating-)?(?:linear|radial|conic)-gradient\\(/gi\n let m: RegExpExecArray | null\n while ((m = re.exec(gradient))) {\n const open = m.index + m[0].length - 1\n const close = closingParen(gradient, open)\n if (close < 0) break\n layers.push(gradient.slice(m.index, close + 1))\n re.lastIndex = close + 1\n }\n return layers\n}\n\ninterface GradientStop { paint: Paint; pos?: number }\ninterface RadialShape { rx: number; ry: number; cx: number; cy: number }\n\n/** One gradient layer's colour stops (with their first position, as a fraction) and, for an ellipse, its shape. */\nfunction gradientLayer(layer: string, tokens: Record<string, string>, vars: ScaleVars): { stops: GradientStop[]; radial?: RadialShape } {\n const open = layer.indexOf('(')\n const args = splitTopLevel(layer.slice(open + 1, -1), ',')\n const stops: GradientStop[] = []\n let radial: RadialShape | undefined\n args.forEach((arg, k) => {\n const parts = splitTopLevel(arg, ' ')\n const paint = parts.length ? resolvePaint(parts[0], tokens, vars) : null\n if (paint) {\n const pos = parts[1] !== undefined ? evalCssNumber(parts[1], vars) : undefined\n stops.push({ paint, pos: Number.isFinite(pos) ? pos : undefined })\n return\n }\n if (k === 0 && /^radial/i.test(layer)) {\n const shape = /ellipse\\s+(-?[\\d.]+)%\\s+(-?[\\d.]+)%\\s+at\\s+(-?[\\d.]+)%\\s+(-?[\\d.]+)%/i.exec(arg)\n if (shape) radial = { rx: +shape[1], ry: +shape[2], cx: +shape[3], cy: +shape[4] }\n }\n })\n return { stops, radial }\n}\n\n/** How strongly a radial glow's first colour shows at its nearest point on the page (1 when its centre is on the page). */\nfunction radialStrength(shape: RadialShape, stops: GradientStop[]): number {\n const px = Math.max(0, Math.min(100, shape.cx))\n const py = Math.max(0, Math.min(100, shape.cy))\n const d = Math.hypot((px - shape.cx) / shape.rx, (py - shape.cy) / shape.ry)\n const leadIndex = stops.findIndex((s) => s.paint.alpha > 0)\n const start = stops[leadIndex]?.pos ?? 0\n const end = stops.slice(leadIndex + 1).find((s) => s.paint.alpha === 0)?.pos ?? 1\n if (d <= start) return 1\n if (d >= end) return 0\n return (end - d) / (end - start)\n}\n\n/** A candidate colour: the CSS a writer emits, and how it paints. */\nexport interface ColourCandidate { value: string; paint: Paint }\n\n/**\n * The shared routine (Sprint 30): the first candidate, in the order given, that reaches `minimum` against every ground\n * and that `accept` takes. mutedOnTint walks the neutral scale's steps with it; the readable tokens walk the theme's\n * own colour in small steps (walkCandidates).\n */\nexport function firstReadable(candidates: Iterable<ColourCandidate>, grounds: readonly Paint[], minimum: number, accept: (c: ColourCandidate) => boolean = () => true): ColourCandidate | null {\n for (const c of candidates) {\n if (worstPaintContrast(c.paint, grounds) >= minimum && accept(c)) return c\n }\n return null\n}\n\n/** A colour as written, ready to be walked: its lightness and alpha as numbers, its chroma and hue as the CSS that writes them. */\ninterface WalkableColour {\n L: number\n alpha: number\n H: number\n /** The chroma at a lightness: a scale's chroma follows the scale's curve between its steps. */\n chroma: (L: number) => number\n chromaText: (L: number) => string\n hueText: string\n}\n\n/** The chroma coefficient of a scale at a lightness, read off the line between its two nearest steps. */\nfunction scaleChromaAt(scale: ScaleName, L: number): number {\n const points = Object.values(CSS_SCALES[scale].steps).map(([l, c]) => [l, c] as const).sort((a, b) => a[0] - b[0])\n if (L <= points[0][0]) return points[0][1]\n if (L >= points[points.length - 1][0]) return points[points.length - 1][1]\n for (let k = 1; k < points.length; k++) {\n const [l1, c1] = points[k]\n const [l0, c0] = points[k - 1]\n if (L <= l1) return c0 + ((c1 - c0) * (L - l0)) / (l1 - l0)\n }\n return points[points.length - 1][1]\n}\n\nconst fixed = (n: number, places: number) => String(+n.toFixed(places))\n\n/** The colour a token's value finally writes, followed through var(), in a form the walk can step. Null for a mix or an image. */\nfunction walkableColour(value: string, tokens: Record<string, string>, vars: ScaleVars, depth = 0): WalkableColour | null {\n if (depth > 24) return null\n const v = value.trim()\n if (v.startsWith('var(')) {\n if (closingParen(v, 3) !== v.length - 1) return null\n const [name, ...fallback] = splitTopLevel(v.slice(4, -1), ',')\n const own = tokens[name]\n if (own !== undefined) return walkableColour(own, tokens, vars, depth + 1)\n const scaled = scaleColour(name, vars)\n if (scaled) {\n const def = CSS_SCALES[scaled.scale]\n const satVar = def.sat ? Object.keys(SCALE_VAR_NAMES).find((k) => SCALE_VAR_NAMES[k] === def.sat) : undefined\n const hueVar = typeof def.hue === 'number' ? undefined : Object.keys(SCALE_VAR_NAMES).find((k) => SCALE_VAR_NAMES[k] === def.hue)\n const sat = def.sat ? vars[def.sat] : 1\n return {\n L: scaled.colour.L,\n alpha: 1,\n H: scaled.colour.H,\n chroma: (L) => scaleChromaAt(scaled.scale, L) * sat,\n chromaText: (L) => (satVar ? `calc(${fixed(scaleChromaAt(scaled.scale, L), 4)} * var(${satVar}))` : fixed(scaleChromaAt(scaled.scale, L), 4)),\n hueText: hueVar ? `var(${hueVar})` : String(def.hue),\n }\n }\n return fallback.length ? walkableColour(fallback.join(','), tokens, vars, depth + 1) : null\n }\n const parts = oklchParts(v, vars)\n if (!parts) return null\n return { L: parts.L, alpha: parts.alpha, H: parts.H, chroma: () => parts.C, chromaText: () => parts.cText, hueText: parts.hText }\n}\n\n/** The CSS for a walked colour. */\nfunction walkedCss(c: WalkableColour, L: number, alpha: number): string {\n return `oklch(${fixed(L, 3)} ${c.chromaText(L)} ${c.hueText}${alpha < 1 ? ` / ${fixed(alpha, 2)}` : ''})`\n}\n\n/**\n * The colours a walk tries after the theme's own: a see-through colour first grows more opaque, 5% at a time; then the\n * lightness steps by 0.01 toward contrast (darker for `dir` −1, on a light ground; lighter for +1).\n */\nfunction* walkCandidates(c: WalkableColour, dir: 1 | -1): Generator<ColourCandidate> {\n let alpha = c.alpha\n while (alpha < 1 - 1e-9) {\n alpha = Math.min(1, +(alpha + 0.05).toFixed(2))\n yield { value: walkedCss(c, c.L, alpha), paint: paintOfOklch({ L: c.L, C: c.chroma(c.L), H: c.H }, alpha) }\n }\n for (let L = +(c.L + dir * 0.01).toFixed(3); L >= 0 && L <= 1; L = +(L + dir * 0.01).toFixed(3)) {\n yield { value: walkedCss(c, L, 1), paint: paintOfOklch({ L, C: c.chroma(L), H: c.H }, 1) }\n }\n}\n\n/**\n * The readable colour for one token: `own` (as written) where it reaches `minimum` against every ground and `accept`\n * takes it; else the nearest step of its walk that does; else `fallback`. Returns the CSS to emit and its paint.\n */\nfunction readableColour(own: string, grounds: readonly Paint[], minimum: number, dir: 1 | -1, tokens: Record<string, string>, vars: ScaleVars, fallback: string, accept: (c: ColourCandidate) => boolean = () => true): ColourCandidate {\n const ownPaint = resolvePaint(own, tokens, vars)\n const first = ownPaint ? firstReadable([{ value: own, paint: ownPaint }], grounds, minimum, accept) : null\n if (first) return first\n const walkable = walkableColour(own, tokens, vars)\n const walked = walkable ? firstReadable(walkCandidates(walkable, dir), grounds, minimum, accept) : null\n if (walked) return walked\n return { value: fallback, paint: resolvePaint(fallback, tokens, vars) ?? ownPaint ?? WHITE_PAINT }\n}\n\n/**\n * Tokens roots.css declares that the shared semantic defaults leave out: the derivations read them where a block\n * doesn't declare its own. @sync roots.css.\n */\nconst ROOTS_COLOUR_DEFAULTS: Record<string, string> = {\n '--ds-accent-subtle': 'color-mix(in srgb, var(--ds-accent-primary) 10%, transparent)',\n '--ds-accent-muted': 'color-mix(in srgb, var(--ds-accent-primary) 20%, transparent)',\n '--ds-sidebar-accent-subtle': 'color-mix(in srgb, var(--ds-sidebar-accent) 10%, transparent)',\n '--ds-header-accent-subtle': 'color-mix(in srgb, var(--ds-header-accent) 10%, transparent)',\n '--ds-tint-strength': String(TINT_STRENGTH),\n}\n\n/** The see-through layer `name` resolves to laid over each ground (the grounds unchanged where it can't be read). */\nfunction layered(name: string, grounds: readonly Paint[], tokens: Record<string, string>, vars: ScaleVars): Paint[] {\n const top = resolvePaint(`var(${name})`, tokens, vars)\n return top ? grounds.map((g) => paintOver(top, g)) : []\n}\n\nexport interface ReadableInput {\n /** The block's mode: its walks go darker on a light page, lighter on a dark one. */\n mode: 'light' | 'dark'\n /** Every declaration the block sees, in cascade order: the mode's semantic defaults, the writer's tokens, the preset's or saved theme's overrides, the status palette. */\n tokens: Record<string, string>\n vars: ScaleVars\n /** The canvas gradient painted under the page, if the theme has one for this mode. */\n canvasGradient?: string\n /** Whether to derive the sidebar family too (a mode's block; an independent sidebar derives its own with readableSidebarTokens). */\n sidebar?: boolean\n}\n\nexport interface ReadableResult {\n /** The derived tokens, to declare after the block's overrides. */\n tokens: Record<string, string>\n /** Each derived token's own colour before the derivation (the Focus page's \"before\"). */\n inputs: Record<string, string>\n}\n\n/**\n * The scale variables a theme state shows in a mode, as the preview writers' ROOT_MAP sets them on <html>: the dark\n * palette's hues and saturations in dark mode, the light ones otherwise; the status hues are shared.\n */\nexport function scaleVarsOf(s: {\n huePrimary: number; satPrimary: number; hueNeutral: number; satNeutral: number\n darkHuePrimary: number; darkSatPrimary: number; darkHueNeutral: number; darkSatNeutral: number\n hueSuccess: number; hueWarning: number; hueDestructive: number\n}, mode: 'light' | 'dark'): ScaleVars {\n const dark = mode === 'dark'\n return {\n huePrimary: dark ? s.darkHuePrimary : s.huePrimary,\n satPrimary: dark ? s.darkSatPrimary : s.satPrimary,\n hueNeutral: dark ? s.darkHueNeutral : s.hueNeutral,\n satNeutral: dark ? s.darkSatNeutral : s.satNeutral,\n hueSuccess: s.hueSuccess,\n hueWarning: s.hueWarning,\n hueDestructive: s.hueDestructive,\n }\n}\n\n/** The colours the page's canvas shows: the canvas colour (over white where see-through) and, with a gradient, every colour it paints. */\nexport function canvasPaints(tokens: Record<string, string>, vars: ScaleVars, canvasGradient?: string): Paint[] {\n const base = resolvePaint('var(--ds-bg-canvas)', tokens, vars)\n const canvasColour = base ? (base.alpha >= 1 ? base : paintOver(base, WHITE_PAINT)) : WHITE_PAINT\n return [canvasColour, ...(canvasGradient ? gradientPaints(canvasGradient, tokens, vars, canvasColour) : [])]\n}\n\n/** The page's grounds for a block: the canvas (and its gradient's colours), and the surface and the raised surface over each. */\nfunction pageGrounds(input: ReadableInput): { canvas: Paint[]; page: Paint[] } {\n const { tokens, vars } = input\n const canvas = canvasPaints(tokens, vars, input.canvasGradient)\n return { canvas, page: [...canvas, ...layered('--ds-bg-surface', canvas, tokens, vars), ...layered('--ds-bg-surface-elevated', canvas, tokens, vars)] }\n}\n\n/** The colours a fill of the accent paints: the accent, or every colour its gradient paints (gradientFills). */\nfunction accentFillPaints(tokens: Record<string, string>, vars: ScaleVars): Paint[] {\n const accent = resolvePaint('var(--ds-accent-primary)', tokens, vars)\n const gradient = (tokens['--ds-gradient'] ?? 'none').trim()\n if (gradient !== 'none' && gradient !== '') {\n const start = walkableColour(tokens['--ds-gradient-start'] ?? '', tokens, vars)\n const end = walkableColour(tokens['--ds-gradient-end'] ?? '', tokens, vars)\n if (start && end) {\n return gradientFills({ L: start.L, C: start.chroma(start.L), H: start.H }, { L: end.L, C: end.chroma(end.L), H: end.H }).map((c) => paintOfOklch(c))\n }\n }\n return accent ? [accent] : []\n}\n\n/** The text on the accent fill, quieter: the quietest of it at 60–90% that reaches 4.5:1 over every colour the fill paints. */\nfunction quietOnAccent(tokens: Record<string, string>, vars: ScaleVars): string {\n const fills = accentFillPaints(tokens, vars)\n const text = resolvePaint('var(--ds-text-on-primary)', tokens, vars)\n if (!text || !fills.length) return 'var(--ds-text-on-primary)'\n const candidates = [60, 70, 80, 90].map((pct): ColourCandidate => ({ value: `color-mix(in srgb, var(--ds-text-on-primary) ${pct}%, transparent)`, paint: { rgb: text.rgb, alpha: text.alpha * pct / 100 } }))\n return firstReadable(candidates, fills, WCAG_AA_TEXT)?.value ?? 'var(--ds-text-on-primary)'\n}\n\n/** The status words and the colour each starts from: the status colour, or warning's own text colour. */\nconst STATUS_WORDS: Array<[status: 'success' | 'warning' | 'error' | 'info', own: string]> = [\n ['success', '--ds-status-success'],\n ['warning', '--ds-status-warning-text'],\n ['error', '--ds-status-error'],\n ['info', '--ds-status-info'],\n]\n\n/** The status's words: its own colour where it reads on its soft background and on the page, else the soft pair's text at its hue (D4). */\nfunction statusWords(status: string, own: string, page: readonly Paint[], mode: 'light' | 'dark', tokens: Record<string, string>, vars: ScaleVars): ColourCandidate {\n const ownValue = tokens[own] ?? `var(${own})`\n const grounds = [...page, ...layered(`--ds-status-${status}-bg`, page, tokens, vars)]\n const ownPaint = resolvePaint(ownValue, tokens, vars)\n const walkable = walkableColour(ownValue, tokens, vars)\n const candidates: ColourCandidate[] = []\n if (ownPaint) candidates.push({ value: ownValue, paint: ownPaint })\n if (walkable) {\n const pair = softPair(walkable.H)\n const text = mode === 'light' ? pair.dark : pair.subtle\n const paint = resolvePaint(text, tokens, vars)\n if (paint) candidates.push({ value: text, paint })\n }\n return firstReadable(candidates, grounds, WCAG_AA_TEXT) ?? { value: 'var(--ds-text-primary)', paint: resolvePaint('var(--ds-text-primary)', tokens, vars) ?? WHITE_PAINT }\n}\n\n/**\n * Every token a block's readable colours set (readableTokens with the sidebar's family): what a writer declares after\n * its overrides, and what a check comparing a block with roots.css's own values leaves out.\n */\nexport const READABLE_TOKEN_NAMES: ReadonlySet<string> = new Set([\n '--ds-focus', '--ds-accent-ink', '--ds-text-muted', '--ds-text-secondary',\n '--ds-status-success-text', '--ds-status-warning-text', '--ds-status-error-text', '--ds-status-info-text',\n '--ds-text-on-primary-muted',\n '--ds-sidebar-text-muted', '--ds-sidebar-text-secondary', '--ds-sidebar-focus', '--ds-sidebar-accent-ink',\n])\n\n/** How much louder the secondary grey stays than the muted one, as a ratio of their contrasts (the hierarchy, P7). */\nexport const QUIET_HIERARCHY = 1.2\n\n/**\n * The tokens a mode's block derives so its colours read (Sprint 30: P1, P7, P8, P10, and the bold band's quiet text):\n * `--ds-focus` at 3:1, the greys, `--ds-accent-ink` and the status words at 4.5:1. With `sidebar`, the sidebar's family\n * too (readableSidebarTokens). Writers declare the result after the block's overrides.\n */\nexport function readableTokens(input: ReadableInput): ReadableResult {\n const { mode, vars } = input\n const tokens = { ...ROOTS_COLOUR_DEFAULTS, ...input.tokens }\n input = { ...input, tokens }\n const dir: 1 | -1 = mode === 'light' ? -1 : 1\n const { canvas, page } = pageGrounds(input)\n // What the colours sit on besides the page: its muted fill (a hovered row, a hint's key, a neutral trend) and the\n // accent's two tints (a selected row and a date range's days at 10%, the range's ends and a hovered accent action at 20%)\n const mutedFill = layered('--ds-bg-muted', page, tokens, vars)\n const accentTints = [...layered('--ds-accent-subtle', page, tokens, vars), ...layered('--ds-accent-muted', page, tokens, vars)]\n const out: Record<string, string> = {}\n const inputs: Record<string, string> = {}\n\n // The focus colour: on the page, its muted fill, the accent's tints, the subtle header's tint and the bold band's\n // strip (the surface, at least 60% opaque, over every colour the band paints)\n const accent = resolvePaint('var(--ds-accent-primary)', tokens, vars)\n const strength = evalCssNumber(tokens['--ds-tint-strength'] ?? String(TINT_STRENGTH), vars)\n const headerTint = accent && Number.isFinite(strength) ? layeredPaint({ rgb: accent.rgb, alpha: accent.alpha * strength }, layered('--ds-bg-surface', canvas, tokens, vars)) : []\n const surface = resolvePaint('var(--ds-bg-surface)', tokens, vars)\n const strip = surface ? accentFillPaints(tokens, vars).map((fill) => paintOver({ rgb: surface.rgb, alpha: Math.max(surface.alpha, 0.6) }, fill)) : []\n const focus = readableColour('var(--ds-accent-primary)', [...page, ...mutedFill, ...accentTints, ...headerTint, ...strip], 3, dir, tokens, vars, 'var(--ds-text-primary)')\n out['--ds-focus'] = focus.value\n inputs['--ds-focus'] = 'var(--ds-accent-primary)'\n\n // The accent as text, a mark or a state's edge: on the page, its muted fill and the accent's own tints\n out['--ds-accent-ink'] = readableColour('var(--ds-accent-primary)', [...page, ...mutedFill, ...accentTints], WCAG_AA_TEXT, dir, tokens, vars, 'var(--ds-text-primary)').value\n inputs['--ds-accent-ink'] = 'var(--ds-accent-primary)'\n\n // The greys, on the page and its muted fill: the muted one first, then the secondary one, kept louder than it\n const greyGrounds = [...page, ...mutedFill]\n const mutedOwn = tokens['--ds-text-muted'] ?? 'var(--ds-neutral-400)'\n const muted = readableColour(mutedOwn, greyGrounds, WCAG_AA_TEXT, dir, tokens, vars, 'var(--ds-text-secondary)')\n const mutedContrast = worstPaintContrast(muted.paint, greyGrounds)\n const secondaryOwn = tokens['--ds-text-secondary'] ?? 'var(--ds-neutral-600)'\n const secondary = readableColour(secondaryOwn, greyGrounds, WCAG_AA_TEXT, dir, tokens, vars, 'var(--ds-text-primary)', (c) => worstPaintContrast(c.paint, greyGrounds) >= mutedContrast * QUIET_HIERARCHY)\n out['--ds-text-muted'] = muted.value\n out['--ds-text-secondary'] = secondary.value\n inputs['--ds-text-muted'] = mutedOwn\n inputs['--ds-text-secondary'] = secondaryOwn\n\n // The status words (D4): on their soft backgrounds and on the page\n for (const [status, own] of STATUS_WORDS) {\n out[`--ds-status-${status}-text`] = statusWords(status, own, page, mode, tokens, vars).value\n inputs[`--ds-status-${status}-text`] = tokens[own] ?? `var(${own})`\n }\n\n // The bold band's quieter text\n out['--ds-text-on-primary-muted'] = quietOnAccent(tokens, vars)\n inputs['--ds-text-on-primary-muted'] = 'color-mix(in srgb, var(--ds-text-on-primary) 70%, transparent)'\n\n if (input.sidebar) {\n const sidebar = readableSidebarTokens({ mode, tokens: { ...tokens, ...out }, vars, canvas })\n Object.assign(out, sidebar.tokens)\n Object.assign(inputs, sidebar.inputs)\n }\n return { tokens: out, inputs }\n}\n\nfunction layeredPaint(top: Paint, grounds: readonly Paint[]): Paint[] {\n return grounds.map((g) => paintOver(top, g))\n}\n\n/**\n * The sidebar family's readable tokens, against the sidebar's own background (laid over the page's canvas where it is\n * see-through) and an item's hover: its quiet text, its focus colour and its current item's accent (P2, P7, P8). A\n * value that reads as it is (an alias of the page's derived token, mostly) is kept as written.\n */\nexport function readableSidebarTokens(input: { mode: 'light' | 'dark'; tokens: Record<string, string>; vars: ScaleVars; canvas?: Paint[] }): ReadableResult {\n const { mode, vars } = input\n const tokens = { ...ROOTS_COLOUR_DEFAULTS, ...input.tokens }\n const dir: 1 | -1 = mode === 'light' ? -1 : 1\n const canvas = input.canvas ?? canvasPaints(tokens, vars)\n const bg = layered('--ds-sidebar-bg', canvas, tokens, vars)\n const grounds = bg.length ? [...bg, ...layered('--ds-sidebar-item-hover', bg, tokens, vars)] : canvas\n const out: Record<string, string> = {}\n const inputs: Record<string, string> = {}\n const own = (name: string, otherwise: string) => tokens[name] ?? otherwise\n\n const mutedOwn = own('--ds-sidebar-text-muted', 'var(--ds-text-muted)')\n const muted = readableColour(mutedOwn, grounds, WCAG_AA_TEXT, dir, tokens, vars, 'var(--ds-sidebar-text)')\n const mutedContrast = worstPaintContrast(muted.paint, grounds)\n const secondaryOwn = own('--ds-sidebar-text-secondary', 'var(--ds-text-secondary)')\n const secondary = readableColour(secondaryOwn, grounds, WCAG_AA_TEXT, dir, tokens, vars, 'var(--ds-sidebar-text)', (c) => worstPaintContrast(c.paint, grounds) >= mutedContrast * QUIET_HIERARCHY)\n out['--ds-sidebar-text-muted'] = muted.value\n out['--ds-sidebar-text-secondary'] = secondary.value\n inputs['--ds-sidebar-text-muted'] = mutedOwn\n inputs['--ds-sidebar-text-secondary'] = secondaryOwn\n\n // The focus colour: the page's where it reads on the sidebar, else the sidebar accent walked\n const pageFocus = resolvePaint('var(--ds-focus)', tokens, vars)\n out['--ds-sidebar-focus'] = pageFocus && worstPaintContrast(pageFocus, grounds) >= 3\n ? 'var(--ds-focus)'\n : readableColour('var(--ds-sidebar-accent)', grounds, 3, dir, tokens, vars, 'var(--ds-sidebar-text)').value\n inputs['--ds-sidebar-focus'] = 'var(--ds-sidebar-accent)'\n\n // The current item's accent, on the sidebar and on its own tint\n const tint = layered('--ds-sidebar-accent-subtle', grounds, tokens, vars)\n out['--ds-sidebar-accent-ink'] = readableColour('var(--ds-sidebar-accent)', [...grounds, ...tint], WCAG_AA_TEXT, dir, tokens, vars, 'var(--ds-sidebar-text)').value\n inputs['--ds-sidebar-accent-ink'] = 'var(--ds-sidebar-accent)'\n return { tokens: out, inputs }\n}\n\n/**\n * The builder preview's independent header (applyHeaderOverrides; a generated app wraps its header in data-mode\n * instead, so the mode blocks cover it): the header family's focus colour, quiet text and accent ink against its own\n * background. BuilderShell's header wrapper maps the page's tokens onto them.\n */\nexport function readableHeaderTokens(input: { mode: 'light' | 'dark'; tokens: Record<string, string>; vars: ScaleVars }): ReadableResult {\n const { mode, vars } = input\n const tokens = { ...ROOTS_COLOUR_DEFAULTS, ...input.tokens }\n const dir: 1 | -1 = mode === 'light' ? -1 : 1\n const bg = resolvePaint('var(--ds-header-bg)', tokens, vars)\n const base = bg ? (bg.alpha >= 1 ? bg : paintOver(bg, WHITE_PAINT)) : WHITE_PAINT\n const grounds = [base, ...layered('--ds-header-hover', [base], tokens, vars)]\n const mutedOwn = tokens['--ds-header-text-muted'] ?? 'var(--ds-text-muted)'\n return {\n tokens: {\n '--ds-header-focus': readableColour('var(--ds-header-accent)', grounds, 3, dir, tokens, vars, 'var(--ds-header-text)').value,\n '--ds-header-text-muted': readableColour(mutedOwn, grounds, WCAG_AA_TEXT, dir, tokens, vars, 'var(--ds-header-text)').value,\n '--ds-header-accent-ink': readableColour('var(--ds-header-accent)', grounds, WCAG_AA_TEXT, dir, tokens, vars, 'var(--ds-header-text)').value,\n },\n inputs: { '--ds-header-focus': 'var(--ds-header-accent)', '--ds-header-text-muted': mutedOwn, '--ds-header-accent-ink': 'var(--ds-header-accent)' },\n }\n}\n","import { onFillTextValue, parseOklch } from \"../../lib/token-algorithms\";\nimport { forwardRef, useLayoutEffect, useMemo, useRef, useState } from \"react\";\nimport {\n Treemap,\n Tooltip,\n ResponsiveContainer,\n} from \"recharts\";\nimport { useChartColors, useChartAnimation } from \"../../lib/chart-utils\";\nimport { ChartTooltipContent, useRadius } from \"./ChartPrimitives\";\nimport { ChartWrapper, markChart } from \"./ChartWrapper\";\nimport { partsAccess } from \"./chart-access\";\nimport { numberOf, fullValueFormatter } from \"./value-format\";\nimport { useFormatLocale } from \"../../lib/locale\";\n\nexport interface TreemapNode {\n name: string;\n value?: number;\n children?: TreemapNode[];\n [key: string]: unknown;\n}\n\nexport interface TreemapChartProps {\n data: TreemapNode[];\n /** \"auto\" (the default): two wide to one high. A preset or a number overrides it; a ChartContainer's own height wins. */\n height?: \"auto\" | \"sm\" | \"md\" | \"lg\" | number;\n showTooltip?: boolean;\n animated?: boolean;\n \"aria-label\"?: string;\n className?: string;\n /**\n * What the chart shows, in the page's words: a line above the drawing, in place of the sentence the chart works out\n * from its data, which it shows without one.\n */\n description?: string;\n}\n\n/** Each tile the treemap draws, with the groups it sits in (\"Engineering › Platform\"), read from the page's own nodes. */\nfunction treemapLeaves(nodes: TreemapNode[], path: string[] = []): Array<{ name: string; value: number; group?: string }> {\n return nodes.flatMap((node) => (node.children?.length\n ? treemapLeaves(node.children, [...path, node.name])\n : [{ name: node.name, value: numberOf(node.value) ?? 0, ...(path.length ? { group: path.join(\" › \") } : {}) }]));\n}\n\ninterface TreemapContentProps {\n x?: number;\n y?: number;\n width?: number;\n height?: number;\n name?: string;\n depth?: number;\n colors: string[];\n radius: number;\n index?: number;\n /** The label's line height and font size in px, read from the page (null until read). */\n metrics: LabelMetrics | null;\n}\n\ninterface LabelMetrics { lineHeight: number; fontSize: number }\n\n/** A label's inset from its cell's edges. */\nconst LABEL_INSET = 4;\n\n/**\n * How many lines of a label a cell holds (Sprint 25.17 A25, R28-55): as many as its height takes inside the inset; none\n * when it can't hold one line, or is narrower than about three characters, since a sliver of a word reads as nothing.\n */\nexport function treemapLabelLines(width: number, height: number, metrics: LabelMetrics): number {\n if (width - 2 * LABEL_INSET < metrics.fontSize * 3) return 0;\n return Math.max(0, Math.floor((height - 2 * LABEL_INSET) / metrics.lineHeight));\n}\n\n/** Colours as the browser computes them, once each: a token's var() and calc() resolved (\"oklch(0.66 calc(0.18 * 1) 280)\"). */\nconst computedColors = new Map<string, string>();\nfunction computedColor(css: string): string {\n if (typeof document === \"undefined\") return css;\n let value = computedColors.get(css);\n if (value === undefined) {\n const probe = document.createElement(\"span\");\n probe.style.color = css;\n document.body.appendChild(probe);\n value = getComputedStyle(probe).color;\n probe.remove();\n computedColors.set(css, value);\n }\n return value;\n}\n\n/**\n * The label's colour over its cell: the library's one on-fill decision (onFillTextValue: white where it reaches AA, else\n * a deep tint of the fill), for the theme's oklch fills, read as the browser computes them (Sprint 25.17's review: read\n * as hex, every label was white, under 4.5:1 on the lighter cells of every dark preset; a fill with a calc() in it didn't\n * parse); any other colour by its brightness.\n */\nfunction labelColorOn(fill: string): string {\n const parsed = parseOklch(fill) ?? parseOklch(computedColor(fill));\n return parsed ? onFillTextValue(parsed) : contrastColor(computedColor(fill));\n}\n\n/** Dark or white text by a colour's brightness: a hex colour, or rgb() as the browser writes one. */\nfunction contrastColor(color: string): string {\n const rgb = /^rgba?\\(\\s*(\\d+)[\\s,]+(\\d+)[\\s,]+(\\d+)/.exec(color);\n const c = color.replace(\"#\", \"\");\n const [r, g, b] = rgb ? [Number(rgb[1]), Number(rgb[2]), Number(rgb[3])] : c.length >= 6 ? [parseInt(c.substring(0, 2), 16), parseInt(c.substring(2, 4), 16), parseInt(c.substring(4, 6), 16)] : [0, 0, 0];\n const luminance = (0.299 * r + 0.587 * g + 0.114 * b) / 255;\n return luminance > 0.55 ? \"#1f2937\" : \"#ffffff\";\n}\n\nfunction TreemapContent({ x = 0, y = 0, width = 0, height: h = 0, name, depth, colors, radius, index = 0, metrics }: TreemapContentProps) {\n const fill = colors[index % colors.length];\n // the label wraps onto the lines the cell holds, then ends in \"…\", and never leaves the cell (the owner: \"wrap and\n // truncate like our other items\"); SVG text doesn't wrap, so it is HTML in the cell, clamped as the library's other\n // labels are. A word too long for the cell is hyphenated where the page's language allows, else broken. The tooltip\n // keeps the full name.\n const lines = metrics && name ? treemapLabelLines(width, h, metrics) : 0;\n const labelColor = labelColorOn(fill);\n\n return (\n <g>\n <rect\n x={x}\n y={y}\n width={width}\n height={h}\n fill={fill}\n stroke=\"var(--ds-bg-surface)\"\n strokeWidth={2}\n rx={depth === 1 ? radius : 0}\n style={{ opacity: depth === 1 ? 1 : 0.85 }}\n />\n {lines > 0 && (\n <foreignObject x={x} y={y} width={width} height={h} style={{ pointerEvents: \"none\" }}>\n <div className=\"flex h-full w-full items-center justify-center overflow-hidden text-center\" style={{ padding: LABEL_INSET }}>\n <span\n data-treemap-label=\"\"\n className={LABEL_TEXT}\n style={{ color: labelColor, display: \"-webkit-box\", WebkitBoxOrient: \"vertical\", WebkitLineClamp: lines, overflow: \"hidden\", overflowWrap: \"anywhere\", hyphens: \"auto\" }}\n >\n {name}\n </span>\n </div>\n </foreignObject>\n )}\n </g>\n );\n}\n\nfunction addFillToNodes(nodes: TreemapNode[], colors: string[], counter = { i: 0 }): TreemapNode[] {\n return nodes.map((node) => {\n if (node.children) {\n return { ...node, children: addFillToNodes(node.children, colors, counter) };\n }\n const fill = colors[counter.i % colors.length];\n counter.i++;\n // a number written as text is drawn as the table and the sentence read it (Sprint 25.8.9)\n return { ...node, value: numberOf(node.value) ?? 0, fill };\n });\n}\n\n/** The label's type: the theme's small size, its sans font, tight lines. */\nconst LABEL_TEXT = \"text-xs leading-tight font-[family-name:var(--ds-font-sans)]\";\n\n/** The label's line height and font size as the page draws them, read from a hidden sample after each render (a theme change re-renders the chart). */\nfunction useLabelMetrics(): [React.RefObject<HTMLSpanElement | null>, LabelMetrics | null] {\n const probe = useRef<HTMLSpanElement | null>(null);\n const [metrics, setMetrics] = useState<LabelMetrics | null>(null);\n // after every render: a theme's type can change with no prop of the chart's changing; the equality check below ends\n // the chain once the reading holds\n // eslint-disable-next-line react-hooks/exhaustive-deps\n useLayoutEffect(() => {\n const el = probe.current;\n if (!el) return;\n const cs = getComputedStyle(el);\n const fontSize = parseFloat(cs.fontSize);\n const lineHeight = parseFloat(cs.lineHeight) || el.getBoundingClientRect().height;\n if (!(fontSize > 0) || !(lineHeight > 0)) return;\n if (!metrics || metrics.fontSize !== fontSize || metrics.lineHeight !== lineHeight) setMetrics({ fontSize, lineHeight });\n });\n return [probe, metrics];\n}\n\nexport const TreemapChart = markChart(forwardRef<HTMLDivElement, TreemapChartProps>(function TreemapChart({\n data,\n height = \"auto\",\n showTooltip = true,\n animated,\n \"aria-label\": ariaLabel,\n className,\n description,\n}, ref) {\n const colors = useChartColors(6, false);\n const locale = useFormatLocale();\n const format = useMemo(() => fullValueFormatter(undefined, locale), [locale]);\n // Sprint 25.8.9 items 4 and 27: the tiles as a table and the chart's sentence, from the page's own nodes; each tile is\n // named on it where there's room\n const access = useMemo(() => partsAccess({ kind: \"treemap\", items: treemapLeaves(data ?? []), format }), [data, format]);\n const isAnimated = useChartAnimation(animated);\n const radius = useRadius();\n const [probe, metrics] = useLabelMetrics();\n\n const chartData = addFillToNodes(data, colors);\n\n if (!data?.length) return null;\n\n return (\n <ChartWrapper ref={ref} height={height} size={{ model: \"ratio\" }} chart=\"treemap\" className={className} aria-label={ariaLabel} access={access} description={description}>\n <ResponsiveContainer width=\"100%\" height=\"100%\">\n <Treemap\n data={chartData}\n dataKey=\"value\"\n nameKey=\"name\"\n aspectRatio={4 / 3}\n stroke=\"var(--ds-bg-surface)\"\n isAnimationActive={isAnimated}\n content={<TreemapContent colors={colors} radius={radius} metrics={metrics} />}\n >\n {showTooltip && <Tooltip content={<ChartTooltipContent />} />}\n </Treemap>\n </ResponsiveContainer>\n <span ref={probe} aria-hidden className={LABEL_TEXT} style={{ position: \"absolute\", visibility: \"hidden\", pointerEvents: \"none\" }}>M</span>\n </ChartWrapper>\n );\n}));\n","import { forwardRef, useEffect, useLayoutEffect, useMemo, useRef, useState } from \"react\";\nimport {\n Sankey as RechartsSankey,\n Tooltip,\n ResponsiveContainer,\n} from \"recharts\";\nimport { useChartColors, useResolvedToken } from \"../../lib/chart-utils\";\nimport { ChartTooltipContent } from \"./ChartPrimitives\";\nimport { ChartWrapper, markChart } from \"./ChartWrapper\";\nimport { flowAccess } from \"./chart-access\";\nimport { fullValueFormatter, numberOf } from \"./value-format\";\nimport { useFormatLocale } from \"../../lib/locale\";\nimport { warnOnce } from \"../../lib/dev-warn\";\n\nexport interface SankeyChartProps {\n data: {\n nodes: { name: string }[];\n links: { source: number; target: number; value: number }[];\n };\n /** \"auto\" (the default): two wide to one high. A preset or a number overrides it; a ChartContainer's own height wins. */\n height?: \"auto\" | \"sm\" | \"md\" | \"lg\" | number;\n showTooltip?: boolean;\n animated?: boolean;\n \"aria-label\"?: string;\n className?: string;\n /**\n * What the chart shows, in the page's words: a line above the drawing, in place of the sentence the chart works out\n * from its data, which it shows without one.\n */\n description?: string;\n}\n\ntype Flow = { source: number; target: number; value: number };\n\n/**\n * The flows a Sankey chart can draw: each in the page's order, less any that would close a loop (a flow back to a point it\n * came from, or from a point to itself). Recharts follows every path to its end, so a loop never ends and takes the page\n * down; a Sankey chart's flows run one way. The larger flows are taken first, so a loop gives up its smallest and the main\n * direction is drawn, whatever order the page lists them in (an analytics export lists them in none). The table still\n * lists every flow the page gave.\n */\nexport function oneWayFlows(links: readonly Flow[]): { flows: Flow[]; loops: Flow[] } {\n const next = new Map<number, number[]>();\n const reaches = (from: number, to: number) => {\n const seen = new Set<number>();\n const stack = [from];\n while (stack.length) {\n const at = stack.pop()!;\n if (at === to) return true;\n if (seen.has(at)) continue;\n seen.add(at);\n stack.push(...(next.get(at) ?? []));\n }\n return false;\n };\n const kept = new Set<number>();\n const loops: Flow[] = [];\n const largestFirst = links.map((link, i) => ({ link, i })).sort((a, b) => (numberOf(b.link.value) ?? 0) - (numberOf(a.link.value) ?? 0) || a.i - b.i);\n for (const { link, i } of largestFirst) {\n if (reaches(link.target, link.source)) { loops.push(link); continue; }\n kept.add(i);\n next.set(link.source, [...(next.get(link.source) ?? []), link.target]);\n }\n return { flows: links.filter((_, i) => kept.has(i)), loops };\n}\n\n/** How many steps the flows take from the first column to the last, as Recharts lays the points out (the longest path). */\nexport function stepsOf(count: number, flows: readonly Flow[]): number {\n const depth = new Array<number>(count).fill(0);\n const valid = flows.filter((f) => f.source >= 0 && f.source < count && f.target >= 0 && f.target < count);\n for (let pass = 0; pass < count; pass++) {\n let moved = false;\n for (const f of valid) if (depth[f.target] < depth[f.source] + 1) { depth[f.target] = depth[f.source] + 1; moved = true; }\n if (!moved) break;\n }\n return Math.max(0, ...depth);\n}\n\nlet measure: CanvasRenderingContext2D | null | undefined;\n/** How wide `text` draws in `el`'s font: measured on a canvas where the browser has one, else reckoned from its size. */\nfunction textWidth(text: string, el: SVGTextElement): number {\n const style = getComputedStyle(el);\n const size = parseFloat(style.fontSize) || 12;\n if (measure === undefined) {\n try {\n measure = /jsdom/i.test(navigator.userAgent) ? null : document.createElement(\"canvas\").getContext(\"2d\");\n } catch {\n measure = null;\n }\n }\n if (!measure) return text.length * size * 0.6;\n measure.font = `${style.fontWeight || \"400\"} ${size}px ${style.fontFamily || \"sans-serif\"}`;\n return measure.measureText(text).width;\n}\n\nconst NAME_GAP = 6;\n/** The drawing's margin on every side. */\nconst INSET = 8;\n\n/**\n * A point of the flow, drawn in its colour with its name beside it (Sprint 25.8.9 item 4): to its left where the flow\n * ends there (no flows out: Recharts sets every such point in the last column), else to its right, so each name reads\n * into the drawing. Each point is named on the drawing, never told by its colour alone; Recharts' own node drew every\n * point in one colour, with no name. (Recharts calls a point's flows in its `sourceLinks`, and its flows out\n * `targetLinks`.)\n *\n * A name keeps to its own room, and is cut short with \"…\" where it's longer (the table and the tooltip give it whole;\n * the review of 16 October found a middle column's long name running off a phone's drawing, over the next column's):\n * the gap to the next column, which before the last column is the name's own, and the last gap is shared, half each, by\n * the names either side of it. Where a drawing of many columns is too narrow for even a letter, the name is left to the\n * tooltip, the table and the sentence.\n */\nfunction SankeyNode({ x, y, width, height, payload, ink, steps, inset, drawn }: { x: number; y: number; width: number; height: number; payload: { name?: unknown; fill?: string; targetLinks?: unknown[]; depth?: number }; ink: string; steps: number; inset: number; drawn: number }) {\n const end = steps > 0 && !payload.targetLinks?.length;\n const name = String(payload.name ?? \"\");\n const text = useRef<SVGTextElement>(null);\n const [shown, setShown] = useState(name);\n // fitted again whenever the drawing's width changes (`drawn`, as its container last gave it): a point's own place may\n // not move with it, and a first column's never does\n useLayoutEffect(() => {\n const el = text.current;\n // the width its container last gave it, else the drawing's own (Recharts sets the drawing's on a later render)\n const drawing = drawn > 0 ? drawn : Number(el?.ownerSVGElement?.getAttribute(\"width\")) || 0;\n if (!el || drawing <= 0) { setShown(name); return; }\n const step = steps > 0 ? (drawing - 2 * inset - width) / steps : drawing - 2 * inset;\n const gap = step - width;\n const shared = end || (payload.depth ?? 0) === steps - 1;\n const room = Math.max(0, (shared ? gap / 2 : gap) - 2 * NAME_GAP);\n if (textWidth(name, el) <= room) { setShown(name); return; }\n let fits = 0;\n for (let lo = 1, hi = name.length - 1; lo <= hi; ) {\n const mid = Math.floor((lo + hi) / 2);\n if (textWidth(`${name.slice(0, mid).trimEnd()}…`, el) <= room) { fits = mid; lo = mid + 1; } else hi = mid - 1;\n }\n setShown(fits > 0 ? `${name.slice(0, fits).trimEnd()}…` : \"\");\n }, [name, steps, inset, width, end, payload.depth, drawn]);\n return (\n <g>\n <rect x={x} y={y} width={width} height={height} fill={payload.fill} />\n <text\n ref={text}\n data-sankey-name=\"\"\n x={end ? x - NAME_GAP : x + width + NAME_GAP}\n y={y + height / 2}\n textAnchor={end ? \"end\" : \"start\"}\n dominantBaseline=\"middle\"\n fill={ink}\n style={{ fontSize: \"var(--ds-font-size-xs)\", fontFamily: \"var(--ds-font-sans)\" }}\n >\n {shown}\n </text>\n </g>\n );\n}\n\nexport const SankeyChart = markChart(forwardRef<HTMLDivElement, SankeyChartProps>(function SankeyChart({\n data,\n height = \"auto\",\n showTooltip = true,\n \"aria-label\": ariaLabel,\n className,\n description,\n}, ref) {\n const colors = useChartColors(data.nodes.length, false);\n const locale = useFormatLocale();\n const format = useMemo(() => fullValueFormatter(undefined, locale), [locale]);\n const { flows, loops } = useMemo(() => oneWayFlows(data?.links ?? []), [data]);\n const [drawn, setDrawn] = useState(0);\n const steps = useMemo(() => stepsOf(data?.nodes?.length ?? 0, flows), [data, flows]);\n // Sprint 25.8.9 items 4 and 27: the flows as a table and the chart's sentence, from the page's own nodes and links\n const access = useMemo(() => flowAccess({ nodes: data?.nodes ?? [], links: data?.links ?? [], undrawn: loops, format }), [data, loops, format]);\n const linkStroke = useResolvedToken(\"--ds-border-subtle\");\n const nameInk = useResolvedToken(\"--ds-text-secondary\");\n\n const nodesWithColor = data.nodes.map((node, i) => ({\n ...node,\n fill: colors[i % colors.length],\n }));\n\n useEffect(() => {\n const loop = loops[0];\n if (loop) warnOnce(\"SankeyChart\", `the flow from \"${data.nodes[loop.source]?.name ?? loop.source}\" to \"${data.nodes[loop.target]?.name ?? loop.target}\" closes a loop, so it isn't drawn: a Sankey chart's flows run one way. Its table still lists it.`);\n }, [loops, data]);\n\n // a value written as text is drawn as the number the table and the sentence read (Recharts adds text as text)\n const sankeyData = {\n nodes: nodesWithColor,\n links: flows.map((flow) => ({ ...flow, value: numberOf(flow.value) ?? 0 })),\n };\n\n if (!data?.nodes?.length) return null;\n\n return (\n <ChartWrapper ref={ref} height={height} size={{ model: \"ratio\" }} chart=\"sankey\" className={className} aria-label={ariaLabel} access={access} description={description}>\n <ResponsiveContainer width=\"100%\" height=\"100%\" onResize={(w) => setDrawn(w)}>\n <RechartsSankey\n data={sankeyData}\n nodeWidth={10}\n nodePadding={24}\n margin={{ top: INSET, right: INSET, bottom: INSET, left: INSET }}\n link={{ stroke: linkStroke, strokeOpacity: 0.4 }}\n node={(n) => <SankeyNode x={n.x} y={n.y} width={n.width} height={n.height} payload={n.payload as Parameters<typeof SankeyNode>[0][\"payload\"]} ink={nameInk} steps={steps} inset={INSET} drawn={drawn} />}\n >\n {showTooltip && <Tooltip content={<ChartTooltipContent />} />}\n </RechartsSankey>\n </ResponsiveContainer>\n </ChartWrapper>\n );\n}));\n","import { forwardRef, useId } from \"react\";\nimport {\n LineChart,\n Line,\n AreaChart,\n Area,\n BarChart,\n Bar,\n ResponsiveContainer,\n Tooltip,\n XAxis,\n YAxis,\n} from \"recharts\";\nimport { useResolvedToken, useChartAnimation } from \"../../lib/chart-utils\";\nimport { ChartTooltipContent } from \"./ChartPrimitives\";\nimport { useInsideChartContainer } from \"./ChartWrapper\";\n\nexport interface SparklineProps {\n data: number[];\n variant?: \"line\" | \"area\" | \"bar\";\n color?: 1 | 2 | 3 | 4 | 5 | 6;\n height?: number;\n width?: number | \"100%\";\n showTooltip?: boolean;\n curved?: boolean;\n animated?: boolean;\n \"aria-label\"?: string;\n className?: string;\n}\n\nexport const Sparkline = forwardRef<HTMLDivElement, SparklineProps>(function Sparkline({\n data,\n variant = \"line\",\n color = 1,\n height = 40,\n width = \"100%\",\n showTooltip = false,\n curved = true,\n animated,\n \"aria-label\": ariaLabel,\n className,\n}, ref) {\n const instanceId = useId();\n const isAnimated = useChartAnimation(animated);\n const insideContainer = useInsideChartContainer();\n\n const tokenName = `--ds-chart-${color}` as const;\n const softTokenName = `--ds-chart-${color}-soft` as const;\n const chartColor = useResolvedToken(tokenName);\n const softColor = useResolvedToken(softTokenName);\n const chartData = data.map((value, i) => ({ value, index: i }));\n\n const containerStyle = insideContainer\n ? { width: \"100%\", height: \"100%\" }\n : { width: typeof width === \"number\" ? `${width}px` : width, height: `${height}px` };\n\n if (!data?.length) return null;\n\n if (variant === \"bar\") {\n return (\n <div ref={ref} style={containerStyle} className={className} {...(ariaLabel ? { role: \"img\", \"aria-label\": ariaLabel } : {})}>\n <ResponsiveContainer width=\"100%\" height=\"100%\">\n <BarChart data={chartData} margin={{ top: 0, right: 0, bottom: 0, left: 0 }}>\n <XAxis dataKey=\"index\" hide />\n <YAxis hide />\n {showTooltip && <Tooltip content={<ChartTooltipContent />} cursor={false} />}\n <Bar\n dataKey=\"value\"\n fill={chartColor}\n radius={[2, 2, 0, 0]}\n isAnimationActive={isAnimated}\n />\n </BarChart>\n </ResponsiveContainer>\n </div>\n );\n }\n\n if (variant === \"area\") {\n const gradientId = `sparkline-gradient-${instanceId}-${color}`;\n return (\n <div ref={ref} style={containerStyle} className={className} {...(ariaLabel ? { role: \"img\", \"aria-label\": ariaLabel } : {})}>\n <ResponsiveContainer width=\"100%\" height=\"100%\">\n <AreaChart data={chartData} margin={{ top: 2, right: 2, bottom: 2, left: 2 }}>\n <defs>\n <linearGradient id={gradientId} x1=\"0\" y1=\"0\" x2=\"0\" y2=\"1\">\n <stop offset=\"0%\" stopColor={softColor} stopOpacity={1} />\n <stop offset=\"95%\" stopColor={softColor} stopOpacity={0.1} />\n </linearGradient>\n </defs>\n <XAxis dataKey=\"index\" hide />\n <YAxis hide domain={[\"dataMin - 1\", \"dataMax + 1\"]} />\n {showTooltip && <Tooltip content={<ChartTooltipContent />} cursor={false} />}\n <Area\n type={curved ? \"monotone\" : \"linear\"}\n dataKey=\"value\"\n stroke={chartColor}\n strokeWidth={1.5}\n fill={`url(#${gradientId})`}\n dot={false}\n activeDot={showTooltip ? { r: 3, fill: chartColor } : false}\n isAnimationActive={isAnimated}\n />\n </AreaChart>\n </ResponsiveContainer>\n </div>\n );\n }\n\n return (\n <div ref={ref} style={containerStyle} className={className} {...(ariaLabel ? { role: \"img\", \"aria-label\": ariaLabel } : {})}>\n <ResponsiveContainer width=\"100%\" height=\"100%\">\n <LineChart data={chartData} margin={{ top: 2, right: 2, bottom: 2, left: 2 }}>\n <XAxis dataKey=\"index\" hide />\n <YAxis hide domain={[\"dataMin - 1\", \"dataMax + 1\"]} />\n {showTooltip && <Tooltip content={<ChartTooltipContent />} cursor={false} />}\n <Line\n type={curved ? \"monotone\" : \"linear\"}\n dataKey=\"value\"\n stroke={chartColor}\n strokeWidth={1.5}\n dot={false}\n activeDot={showTooltip ? { r: 3, fill: chartColor } : false}\n isAnimationActive={isAnimated}\n />\n </LineChart>\n </ResponsiveContainer>\n </div>\n );\n});\n","import { useCallback, useId, useMemo, useState, type ReactNode } from \"react\";\nimport { cn, GLASS_SURFACE } from \"../lib/utils\";\nimport { TITLE_TEXT } from \"../lib/title-text\";\nimport { Skeleton } from \"./Skeleton\";\nimport { CHART_HEIGHTS, ChartContainerContext, fixedChartHeight, isLibraryChart, type ChartContainerValue } from \"./charts/ChartWrapper\";\n\n/**\n * CardTitle's classes (Card.tsx) without its line clamp: a chart's title states its insight, its message\n * (data_visualisation#3), so it is never cut. Kept equal to CardTitle's by a test.\n */\nexport const CHART_TITLE_CLASSES = TITLE_TEXT;\n\nexport interface ChartContainerProps {\n /**\n * \"auto\" (the default): the chart sizes itself from its type and its data (Sprint 25.9, A2) — a row per item for\n * sideways bars and funnels, two wide to one high for charts over dates or numbers, square for round charts — and in\n * a row its frame matches the tallest block while the chart grows only to its bound.\n * A preset (sm, md, lg) or a number of px sets this chart's height instead, and beats the chart's own.\n */\n height?: \"auto\" | \"sm\" | \"md\" | \"lg\" | number;\n /** The insight, as a heading (h3) in the card-title style, never cut. The chart's graphic is named by it. */\n title?: string;\n loading?: boolean;\n emptyState?: ReactNode;\n /** \"default\" is a card surface. \"ghost\" drops surface, border, shadow and padding for charts embedded in another container. */\n variant?: \"default\" | \"ghost\";\n children: ReactNode;\n className?: string;\n}\n\nexport function ChartContainer({\n height = \"auto\",\n title,\n loading = false,\n emptyState,\n variant = \"default\",\n children,\n className,\n}: ChartContainerProps) {\n const titleId = useId();\n const fixed = fixedChartHeight(height);\n // A library chart sizes itself (its mark). Anything else — a hand-built chart, an EmptyState, a Sparkline, several\n // children — keeps an area of the preset's height, else md, and fills it.\n const sizesItself = !loading && !!children && isLibraryChart(children);\n const area = fixed ?? CHART_HEIGHTS.md;\n // the slot beside the title for the chart's Chart / Table switch (Sprint 25.8.9 item 27), used while the container holds\n // one library chart: the charts count themselves in\n const [actions, setActions] = useState<HTMLDivElement | null>(null);\n const [charts, setCharts] = useState(0);\n const register = useCallback(() => {\n setCharts((n) => n + 1);\n return () => setCharts((n) => n - 1);\n }, []);\n const context = useMemo<ChartContainerValue>(\n () => ({ height: fixed, titleId: title ? titleId : undefined, title: title || undefined, fillArea: !sizesItself, actions, charts, register }),\n [fixed, title, titleId, sizesItself, actions, charts, register],\n );\n\n let body: ReactNode = null;\n if (loading) {\n body = (\n <div className=\"absolute inset-0 flex flex-col justify-end gap-ds-2 px-ds-2\">\n <div className=\"flex items-end h-full gap-ds-1\">\n {[65, 40, 80, 55, 72, 45, 60].map((h, i) => (\n <Skeleton key={i} variant=\"custom\" className=\"flex-1\" height={`${h}%`} />\n ))}\n </div>\n <Skeleton variant=\"text\" lines={1} className=\"w-full\" />\n </div>\n );\n } else if (children) {\n body = (\n <ChartContainerContext.Provider value={context}>\n {sizesItself ? children : (\n // the area is absolute, so a child that fills 100% has a definite height to fill\n <div className=\"absolute inset-0\">\n <div className=\"h-full w-full\">{children}</div>\n </div>\n )}\n </ChartContainerContext.Provider>\n );\n } else if (emptyState) {\n body = <div className=\"flex flex-1 items-center justify-center\">{emptyState}</div>;\n }\n\n return (\n <div\n data-card=\"\"\n data-gs=\"chart\"\n className={cn(\n \"flex flex-col\",\n variant === \"ghost\"\n ? \"bg-transparent\"\n : cn(\n // CardHeader's inset, so titles inside frames line up in a row (A1)\n \"rounded-[var(--ds-radius-md)] px-ds-5 py-ds-4\",\n \"bg-[var(--ds-bg-surface)] border-[length:var(--ds-border-width)] border-[var(--ds-border-subtle)]\",\n GLASS_SURFACE,\n ),\n className,\n )}\n >\n {title && (\n <div data-chart-header=\"\" className=\"mb-ds-4 flex items-start justify-between gap-ds-3\">\n <h3 id={titleId} className={cn(CHART_TITLE_CLASSES, \"min-w-0 flex-1\")}>\n {title}\n </h3>\n <div ref={setActions} data-chart-actions=\"\" className=\"shrink-0 empty:hidden\" />\n </div>\n )}\n <div\n data-chart-body=\"\"\n className=\"relative flex min-w-0 flex-col\"\n style={{ flex: \"1 1 0%\", minHeight: sizesItself ? undefined : area }}\n >\n {body}\n </div>\n </div>\n );\n}\n"]}
|