@squadbase/vantage 0.6.2-dev1.48b34e1 → 0.6.2-dev1.56da87f

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.
Files changed (71) hide show
  1. package/dist/{chunk-57GHR5LN.js → chunk-3RJEOP3J.js} +29 -18
  2. package/dist/chunk-3RJEOP3J.js.map +1 -0
  3. package/dist/{chunk-QOXXOFGL.js → chunk-77CISBMG.js} +994 -464
  4. package/dist/chunk-77CISBMG.js.map +1 -0
  5. package/dist/{chunk-JXFCSF3K.js → chunk-EG4PX726.js} +12 -7
  6. package/dist/chunk-EG4PX726.js.map +1 -0
  7. package/dist/{chunk-2N72FKLB.js → chunk-NZ5QIIG4.js} +33 -11
  8. package/dist/chunk-NZ5QIIG4.js.map +1 -0
  9. package/dist/{chunk-7S52M2SL.js → chunk-QNOX7WLZ.js} +3 -3
  10. package/dist/{chunk-7S52M2SL.js.map → chunk-QNOX7WLZ.js.map} +1 -1
  11. package/dist/{chunk-PDOBHMUQ.js → chunk-ROHNXP7J.js} +72 -3
  12. package/dist/chunk-ROHNXP7J.js.map +1 -0
  13. package/dist/{chunk-6OTTGAPO.js → chunk-TRMHNMMZ.js} +24 -7
  14. package/dist/chunk-TRMHNMMZ.js.map +1 -0
  15. package/dist/components/index.d.ts +49 -29
  16. package/dist/components/index.js +5 -5
  17. package/dist/{delta-text-CvwBGJ95.d.ts → delta-text-CbrOaW83.d.ts} +4 -2
  18. package/dist/doc/index.d.ts +14 -14
  19. package/dist/doc/index.js +198 -84
  20. package/dist/doc/index.js.map +1 -1
  21. package/dist/{format-U0cQl069.d.ts → format-DihQkL1N.d.ts} +17 -11
  22. package/dist/slide/index.d.ts +2 -2
  23. package/dist/slide/index.js +95 -44
  24. package/dist/slide/index.js.map +1 -1
  25. package/dist/table/index.js +6 -6
  26. package/dist/ui/index.d.ts +1 -1
  27. package/dist/ui/index.js +5 -5
  28. package/package.json +2 -2
  29. package/registry/ui/app-shell.tsx +138 -1
  30. package/registry/ui/area-chart.tsx +344 -85
  31. package/registry/ui/attention-list.tsx +177 -15
  32. package/registry/ui/bar-chart.tsx +341 -85
  33. package/registry/ui/bar-list.tsx +332 -77
  34. package/registry/ui/box-plot-chart.tsx +405 -97
  35. package/registry/ui/category-bar.tsx +248 -40
  36. package/registry/ui/chart-frame.tsx +257 -46
  37. package/registry/ui/data-table.tsx +229 -37
  38. package/registry/ui/date-range-picker.tsx +190 -36
  39. package/registry/ui/delta.tsx +171 -12
  40. package/registry/ui/donut-chart.tsx +339 -84
  41. package/registry/ui/echart.tsx +142 -4
  42. package/registry/ui/filter-bar.tsx +179 -20
  43. package/registry/ui/funnel-steps.tsx +354 -80
  44. package/registry/ui/heatmap.tsx +293 -52
  45. package/registry/ui/histogram-chart.tsx +395 -97
  46. package/registry/ui/kpi-card.tsx +245 -44
  47. package/registry/ui/legend.tsx +330 -76
  48. package/registry/ui/line-chart.tsx +344 -85
  49. package/registry/ui/multi-select.tsx +159 -9
  50. package/registry/ui/page-shell.tsx +141 -3
  51. package/registry/ui/paired-chart.tsx +349 -90
  52. package/registry/ui/progress-circle.tsx +205 -39
  53. package/registry/ui/sample-data.tsx +153 -9
  54. package/registry/ui/scatter-chart.tsx +391 -100
  55. package/registry/ui/searchable-select.tsx +145 -7
  56. package/registry/ui/states.tsx +170 -13
  57. package/registry/ui/status-badge.tsx +193 -28
  58. package/registry/ui/tracker.tsx +205 -39
  59. package/registry/ui/trend-indicator.tsx +149 -6
  60. package/registry/ui/updated-at.tsx +170 -16
  61. package/registry/ui/waterfall-chart.tsx +415 -102
  62. package/skills/vantage-add-feature/SKILL.md +5 -0
  63. package/templates/AGENTS.md +3 -2
  64. package/templates/agents/api.md +7 -0
  65. package/templates/agents/page.md +36 -0
  66. package/dist/chunk-2N72FKLB.js.map +0 -1
  67. package/dist/chunk-57GHR5LN.js.map +0 -1
  68. package/dist/chunk-6OTTGAPO.js.map +0 -1
  69. package/dist/chunk-JXFCSF3K.js.map +0 -1
  70. package/dist/chunk-PDOBHMUQ.js.map +0 -1
  71. package/dist/chunk-QOXXOFGL.js.map +0 -1
package/dist/doc/index.js CHANGED
@@ -1,8 +1,8 @@
1
- import { DeltaText } from '../chunk-6OTTGAPO.js';
2
- export { DeltaText } from '../chunk-6OTTGAPO.js';
1
+ import { DeltaText } from '../chunk-TRMHNMMZ.js';
2
+ export { DeltaText } from '../chunk-TRMHNMMZ.js';
3
3
  import { Sparkline } from '../chunk-2IAPIOPS.js';
4
- import { formatValue } from '../chunk-57GHR5LN.js';
5
- import { Button } from '../chunk-PDOBHMUQ.js';
4
+ import { formatValue } from '../chunk-3RJEOP3J.js';
5
+ import { Button, uiLanguage, useLocale } from '../chunk-ROHNXP7J.js';
6
6
  import '../chunk-U736PVHY.js';
7
7
  import { forwardRef, useEffect, useId } from 'react';
8
8
  import { PrinterIcon } from 'lucide-react';
@@ -139,51 +139,68 @@ var Document = forwardRef(function Document2({ theme, style, ...props }, ref) {
139
139
  ] });
140
140
  });
141
141
  Document.displayName = "Document";
142
- var PRIORITY = { high: "\u9AD8", medium: "\u4E2D", low: "\u4F4E" };
142
+ var TEXT = {
143
+ ja: {
144
+ title: "\u63A8\u5968\u3059\u308B\u5BFE\u5FDC",
145
+ priority: { high: "\u9AD8", medium: "\u4E2D", low: "\u4F4E" },
146
+ due: (due) => `${due} \u307E\u3067`,
147
+ asks: (parts) => `\uFF08${parts.join("\u30FB")}\uFF09`,
148
+ head: { action: "\u5BFE\u5FDC", owner: "\u62C5\u5F53", due: "\u671F\u9650", impact: "\u671F\u5F85\u3059\u308B\u52B9\u679C", priority: "\u512A\u5148\u5EA6" }
149
+ },
150
+ en: {
151
+ title: "Recommended actions",
152
+ priority: { high: "High", medium: "Medium", low: "Low" },
153
+ due: (due) => `by ${due}`,
154
+ asks: (parts) => ` (${parts.join(", ")})`,
155
+ head: { action: "Action", owner: "Owner", due: "Due", impact: "Expected impact", priority: "Priority" }
156
+ }
157
+ };
143
158
  var MUTED = { color: "var(--doc-muted)" };
144
- function Priority({ value }) {
159
+ function Priority({ value, words }) {
145
160
  if (!value) return /* @__PURE__ */ jsx(Fragment, { children: "\u2014" });
146
- return /* @__PURE__ */ jsx("span", { className: value === "high" ? "font-semibold" : void 0, children: PRIORITY[value] });
161
+ return /* @__PURE__ */ jsx("span", { className: value === "high" ? "font-semibold" : void 0, children: words[value] });
147
162
  }
148
- function DocActionItems({ title = "\u63A8\u5968\u3059\u308B\u5BFE\u5FDC", headingLevel = 2, items, variant = "table" }) {
163
+ function DocActionItems({ title, headingLevel = 2, items, variant = "table" }) {
164
+ const t = TEXT[uiLanguage(useLocale())];
149
165
  const Heading = headingLevel === 3 ? "h3" : "h2";
150
166
  return /* @__PURE__ */ jsxs("section", { "data-slot": "doc-action-items", children: [
151
- /* @__PURE__ */ jsx(Heading, { children: title }),
167
+ /* @__PURE__ */ jsx(Heading, { children: title ?? t.title }),
152
168
  variant === "asks" ? /* @__PURE__ */ jsx("ul", { children: items.map((item, i) => /* @__PURE__ */ jsxs("li", { className: "break-inside-avoid", children: [
153
169
  item.action,
154
- item.owner || item.due ? /* @__PURE__ */ jsxs("span", { style: MUTED, children: [
155
- "\uFF08",
156
- [item.owner, item.due ? `${item.due} \u307E\u3067` : void 0].filter(Boolean).join("\u30FB"),
157
- "\uFF09"
158
- ] }) : null
170
+ item.owner || item.due ? /* @__PURE__ */ jsx("span", { style: MUTED, children: t.asks([item.owner, item.due ? t.due(item.due) : void 0].filter((p) => Boolean(p))) }) : null
159
171
  ] }, i)) }) : /* @__PURE__ */ jsx("div", { className: "w-full overflow-x-auto", children: /* @__PURE__ */ jsxs("table", { className: "table w-full", children: [
160
172
  /* @__PURE__ */ jsx("thead", { children: /* @__PURE__ */ jsxs("tr", { children: [
161
- /* @__PURE__ */ jsx("th", { scope: "col", children: "\u5BFE\u5FDC" }),
162
- /* @__PURE__ */ jsx("th", { scope: "col", children: "\u62C5\u5F53" }),
163
- /* @__PURE__ */ jsx("th", { scope: "col", children: "\u671F\u9650" }),
164
- /* @__PURE__ */ jsx("th", { scope: "col", children: "\u671F\u5F85\u3059\u308B\u52B9\u679C" }),
165
- /* @__PURE__ */ jsx("th", { scope: "col", children: "\u512A\u5148\u5EA6" })
173
+ /* @__PURE__ */ jsx("th", { scope: "col", children: t.head.action }),
174
+ /* @__PURE__ */ jsx("th", { scope: "col", children: t.head.owner }),
175
+ /* @__PURE__ */ jsx("th", { scope: "col", children: t.head.due }),
176
+ /* @__PURE__ */ jsx("th", { scope: "col", children: t.head.impact }),
177
+ /* @__PURE__ */ jsx("th", { scope: "col", children: t.head.priority })
166
178
  ] }) }),
167
179
  /* @__PURE__ */ jsx("tbody", { children: items.map((item, i) => /* @__PURE__ */ jsxs("tr", { children: [
168
180
  /* @__PURE__ */ jsx("td", { children: item.action }),
169
181
  /* @__PURE__ */ jsx("td", { children: item.owner ?? "\u2014" }),
170
182
  /* @__PURE__ */ jsx("td", { className: "whitespace-nowrap tabular-nums", children: item.due ?? "\u2014" }),
171
183
  /* @__PURE__ */ jsx("td", { children: item.impact ?? "\u2014" }),
172
- /* @__PURE__ */ jsx("td", { children: /* @__PURE__ */ jsx(Priority, { value: item.priority }) })
184
+ /* @__PURE__ */ jsx("td", { children: /* @__PURE__ */ jsx(Priority, { value: item.priority, words: t.priority }) })
173
185
  ] }, i)) })
174
186
  ] }) })
175
187
  ] });
176
188
  }
177
189
  var KINDS = {
178
- note: { word: "\u88DC\u8DB3", rule: "border-info", tint: "bg-info-subtle", text: "text-info" },
179
- insight: { word: "\u793A\u5506", rule: "border-positive", tint: "bg-positive-subtle", text: "text-positive" },
180
- warning: { word: "\u6CE8\u610F", rule: "border-warning", tint: "bg-warning-subtle", text: "text-warning" },
181
- decision: { word: "\u6C7A\u5B9A\u4E8B\u9805", rule: "border-foreground", tint: "bg-muted", text: "text-foreground" }
190
+ note: { rule: "border-info", tint: "bg-info-subtle", text: "text-info" },
191
+ insight: { rule: "border-positive", tint: "bg-positive-subtle", text: "text-positive" },
192
+ warning: { rule: "border-warning", tint: "bg-warning-subtle", text: "text-warning" },
193
+ decision: { rule: "border-foreground", tint: "bg-muted", text: "text-foreground" }
194
+ };
195
+ var WORDS = {
196
+ ja: { note: "\u88DC\u8DB3", insight: "\u793A\u5506", warning: "\u6CE8\u610F", decision: "\u6C7A\u5B9A\u4E8B\u9805" },
197
+ en: { note: "Note", insight: "Insight", warning: "Caution", decision: "Decision" }
182
198
  };
183
199
  function DocCallout({ kind = "note", title, children }) {
184
200
  const k = KINDS[kind];
201
+ const word = WORDS[uiLanguage(useLocale())][kind];
185
202
  const titleId = useId();
186
- const heading = title && title !== k.word ? `${k.word}: ${title}` : k.word;
203
+ const heading = title && title !== word ? `${word}: ${title}` : word;
187
204
  return /* @__PURE__ */ jsxs(
188
205
  "div",
189
206
  {
@@ -200,20 +217,36 @@ function DocCallout({ kind = "note", title, children }) {
200
217
  );
201
218
  }
202
219
  var ALIGN = { left: "text-left", right: "text-right", center: "text-center" };
220
+ var TEXT2 = {
221
+ ja: {
222
+ source: (source) => `\u51FA\u5178: ${source}`,
223
+ asOf: (asOf) => `\u30C7\u30FC\u30BF\u6642\u70B9 ${asOf}`,
224
+ separator: " \uFF0F ",
225
+ unit: (unit) => `\uFF08${unit}\uFF09`
226
+ },
227
+ en: {
228
+ source: (source) => `Source: ${source}`,
229
+ asOf: (asOf) => `Data as of ${asOf}`,
230
+ separator: " / ",
231
+ unit: (unit) => ` (${unit})`
232
+ }
233
+ };
203
234
  function DocDataTable({ title, unit, columns, rows, total, highlightRows, footnotes, source, asOf }) {
235
+ const locale = useLocale();
236
+ const t = TEXT2[uiLanguage(locale)];
204
237
  const isNumeric = (col) => rows.some((r) => typeof r[col.key] === "number");
205
238
  const cls = (col) => {
206
239
  const numeric = isNumeric(col);
207
240
  return `${ALIGN[col.align ?? (numeric ? "right" : "left")]}${numeric ? " tabular-nums" : ""}`;
208
241
  };
209
- const text = (col, v) => typeof v === "number" ? formatValue(v, col.format ?? "number") : v === null || v === void 0 || v === "" ? "\u2014" : v;
210
- const origin = [source ? `\u51FA\u5178: ${source}` : void 0, asOf ? `\u30C7\u30FC\u30BF\u6642\u70B9 ${asOf}` : void 0].filter(Boolean).join(" \uFF0F ");
242
+ const text = (col, v) => typeof v === "number" ? formatValue(v, col.format ?? "number", locale) : v === null || v === void 0 || v === "" ? "\u2014" : v;
243
+ const origin = [source ? t.source(source) : void 0, asOf ? t.asOf(asOf) : void 0].filter(Boolean).join(t.separator);
211
244
  const highlighted = new Set(highlightRows);
212
245
  return /* @__PURE__ */ jsxs("figure", { "data-slot": "doc-data-table", className: "m-0 w-full break-inside-auto", children: [
213
246
  /* @__PURE__ */ jsx("div", { className: "w-full overflow-x-auto", children: /* @__PURE__ */ jsxs("table", { className: "table w-full", children: [
214
247
  title || unit ? /* @__PURE__ */ jsxs("caption", { className: "text-left", children: [
215
248
  title ? /* @__PURE__ */ jsx("span", { className: "font-semibold", children: title }) : null,
216
- unit ? /* @__PURE__ */ jsx("span", { style: { color: "var(--doc-muted)" }, children: title ? `\uFF08${unit}\uFF09` : unit }) : null
249
+ unit ? /* @__PURE__ */ jsx("span", { style: { color: "var(--doc-muted)" }, children: title ? t.unit(unit) : unit }) : null
217
250
  ] }) : null,
218
251
  /* @__PURE__ */ jsx("thead", { children: /* @__PURE__ */ jsx("tr", { children: columns.map((col) => /* @__PURE__ */ jsx("th", { scope: "col", className: cls(col), children: col.label }, col.key)) }) }),
219
252
  /* @__PURE__ */ jsx("tbody", { children: rows.map((row, i) => /* @__PURE__ */ jsx("tr", { className: highlighted.has(i) ? "font-semibold" : void 0, children: columns.map((col) => /* @__PURE__ */ jsx("td", { className: cls(col), children: text(col, row[col.key]) }, col.key)) }, i)) }),
@@ -229,17 +262,23 @@ function DocDataTable({ title, unit, columns, rows, total, highlightRows, footno
229
262
  ] }) : null
230
263
  ] });
231
264
  }
265
+ var TEXT3 = {
266
+ ja: { title: "\u8981\u65E8", comparison: "\u524D\u671F\u6BD4" },
267
+ en: { title: "Executive summary", comparison: "vs. prior period" }
268
+ };
232
269
  function DocExecutiveSummary({
233
- title = "\u8981\u65E8",
270
+ title,
234
271
  headingLevel = 2,
235
272
  conclusion,
236
273
  points,
237
274
  metrics
238
275
  }) {
276
+ const locale = useLocale();
277
+ const t = TEXT3[uiLanguage(locale)];
239
278
  const Heading = headingLevel === 3 ? "h3" : "h2";
240
279
  const shown2 = (metrics ?? []).slice(0, 3);
241
280
  return /* @__PURE__ */ jsxs("section", { "data-slot": "doc-executive-summary", children: [
242
- /* @__PURE__ */ jsx(Heading, { children: title }),
281
+ /* @__PURE__ */ jsx(Heading, { children: title ?? t.title }),
243
282
  /* @__PURE__ */ jsx("p", { className: "font-semibold", children: conclusion }),
244
283
  /* @__PURE__ */ jsx("ol", { children: points.map((point, i) => /* @__PURE__ */ jsx("li", { className: "break-inside-avoid", children: point }, i)) }),
245
284
  shown2.length > 0 ? /* @__PURE__ */ jsx("dl", { className: "grid grid-cols-1 gap-4 sm:grid-cols-3 print:grid-cols-3", children: shown2.map((m) => /* @__PURE__ */ jsxs(
@@ -249,13 +288,13 @@ function DocExecutiveSummary({
249
288
  style: { borderColor: "var(--doc-border)" },
250
289
  children: [
251
290
  /* @__PURE__ */ jsx("dt", { style: { color: "var(--doc-muted)" }, children: m.label }),
252
- /* @__PURE__ */ jsx("dd", { className: "m-0 font-semibold tabular-nums", children: m.display ?? formatValue(m.value, m.format) }),
291
+ /* @__PURE__ */ jsx("dd", { className: "m-0 font-semibold tabular-nums", children: m.display ?? formatValue(m.value, m.format, locale) }),
253
292
  m.delta ? /* @__PURE__ */ jsxs("dd", { className: "m-0", children: [
254
293
  /* @__PURE__ */ jsxs("span", { style: { color: "var(--doc-muted)" }, children: [
255
- m.comparisonLabel ?? "\u524D\u671F\u6BD4",
294
+ m.comparisonLabel ?? t.comparison,
256
295
  " "
257
296
  ] }),
258
- /* @__PURE__ */ jsx(DeltaText, { value: m.delta.value, format: m.delta.format ?? m.format, betterWhen: m.betterWhen })
297
+ /* @__PURE__ */ jsx(DeltaText, { value: m.delta.value, format: m.delta.format ?? m.format, betterWhen: m.betterWhen, locale })
259
298
  ] }) : null
260
299
  ]
261
300
  },
@@ -263,29 +302,47 @@ function DocExecutiveSummary({
263
302
  )) }) : null
264
303
  ] });
265
304
  }
305
+ var TEXT4 = {
306
+ ja: {
307
+ source: (source) => `\u51FA\u5178: ${source}`,
308
+ asOf: (asOf) => `\u30C7\u30FC\u30BF\u6642\u70B9 ${asOf}`,
309
+ separator: " \uFF0F ",
310
+ figure: (n) => `\u56F3 ${n}`
311
+ },
312
+ en: {
313
+ source: (source) => `Source: ${source}`,
314
+ asOf: (asOf) => `Data as of ${asOf}`,
315
+ separator: " / ",
316
+ figure: (n) => `Figure ${n}`
317
+ }
318
+ };
266
319
  function DocFigure({ title, unit, number, source, asOf, notes, children }) {
320
+ const t = TEXT4[uiLanguage(useLocale())];
267
321
  const titleId = useId();
268
- const origin = [source ? `\u51FA\u5178: ${source}` : void 0, asOf ? `\u30C7\u30FC\u30BF\u6642\u70B9 ${asOf}` : void 0].filter(Boolean).join(" \uFF0F ");
322
+ const origin = [source ? t.source(source) : void 0, asOf ? t.asOf(asOf) : void 0].filter(Boolean).join(t.separator);
269
323
  const hasCaption = number !== void 0 || origin || notes && notes.length > 0;
270
324
  return /* @__PURE__ */ jsxs("figure", { "data-slot": "doc-figure", "aria-labelledby": titleId, className: "w-full break-inside-avoid", children: [
271
325
  /* @__PURE__ */ jsx("p", { id: titleId, className: "m-0 font-semibold", children: title }),
272
326
  unit ? /* @__PURE__ */ jsx("p", { className: "m-0", style: { color: "var(--doc-muted)" }, children: unit }) : null,
273
327
  /* @__PURE__ */ jsx("div", { className: "w-full", children }),
274
328
  hasCaption ? /* @__PURE__ */ jsxs("figcaption", { className: "flex flex-col gap-0.5 text-left", children: [
275
- number !== void 0 ? /* @__PURE__ */ jsxs("span", { className: "font-medium", children: [
276
- "\u56F3 ",
277
- number
278
- ] }) : null,
329
+ number !== void 0 ? /* @__PURE__ */ jsx("span", { className: "font-medium", children: t.figure(number) }) : null,
279
330
  origin ? /* @__PURE__ */ jsx("span", { children: origin }) : null,
280
331
  notes?.map((note, i) => /* @__PURE__ */ jsx("span", { children: note }, i))
281
332
  ] }) : null
282
333
  ] });
283
334
  }
284
- function DocKeyFindings({ title = "\u4E3B\u8981\u306A\u767A\u898B", headingLevel = 2, findings }) {
335
+ var TEXT5 = {
336
+ ja: { title: "\u4E3B\u8981\u306A\u767A\u898B", comparison: "\u524D\u671F\u6BD4" },
337
+ en: { title: "Key findings", comparison: "vs. prior period" }
338
+ };
339
+ function DocKeyFindings({ title, headingLevel = 2, findings }) {
340
+ const locale = useLocale();
341
+ const t = TEXT5[uiLanguage(locale)];
285
342
  const Heading = headingLevel === 3 ? "h3" : "h2";
286
343
  const Item = headingLevel === 3 ? "h4" : "h3";
287
344
  return /* @__PURE__ */ jsxs("section", { "data-slot": "doc-key-findings", children: [
288
- /* @__PURE__ */ jsx(Heading, { children: title }),
345
+ /* @__PURE__ */ jsx(Heading, { children: title ?? t.title }),
289
346
  findings.map((f, i) => /* @__PURE__ */ jsxs("article", { className: "break-inside-avoid", children: [
290
347
  /* @__PURE__ */ jsxs(Item, { children: [
291
348
  i + 1,
@@ -296,13 +353,21 @@ function DocKeyFindings({ title = "\u4E3B\u8981\u306A\u767A\u898B", headingLevel
296
353
  /* @__PURE__ */ jsx("div", { children: typeof f.evidence === "string" ? /* @__PURE__ */ jsx("p", { className: "m-0", children: f.evidence }) : f.evidence }),
297
354
  f.metric ? /* @__PURE__ */ jsxs("dl", { className: "m-0 shrink-0 sm:text-right print:text-right", children: [
298
355
  /* @__PURE__ */ jsx("dt", { style: { color: "var(--doc-muted)" }, children: f.metric.label }),
299
- /* @__PURE__ */ jsx("dd", { className: "m-0 font-semibold tabular-nums", children: f.metric.display ?? formatValue(f.metric.value, f.metric.format) }),
356
+ /* @__PURE__ */ jsx("dd", { className: "m-0 font-semibold tabular-nums", children: f.metric.display ?? formatValue(f.metric.value, f.metric.format, locale) }),
300
357
  f.metric.delta ? /* @__PURE__ */ jsxs("dd", { className: "m-0", children: [
301
358
  /* @__PURE__ */ jsxs("span", { style: { color: "var(--doc-muted)" }, children: [
302
- f.metric.comparisonLabel ?? "\u524D\u671F\u6BD4",
359
+ f.metric.comparisonLabel ?? t.comparison,
303
360
  " "
304
361
  ] }),
305
- /* @__PURE__ */ jsx(DeltaText, { value: f.metric.delta.value, format: f.metric.delta.format ?? f.metric.format, betterWhen: f.metric.betterWhen })
362
+ /* @__PURE__ */ jsx(
363
+ DeltaText,
364
+ {
365
+ value: f.metric.delta.value,
366
+ format: f.metric.delta.format ?? f.metric.format,
367
+ betterWhen: f.metric.betterWhen,
368
+ locale
369
+ }
370
+ )
306
371
  ] }) : null
307
372
  ] }) : null
308
373
  ] })
@@ -311,23 +376,55 @@ function DocKeyFindings({ title = "\u4E3B\u8981\u306A\u767A\u898B", headingLevel
311
376
  }
312
377
  var MUTED2 = { color: "var(--doc-muted)" };
313
378
  var ACHIEVEMENT = { type: "percent", digits: 1 };
314
- var shown = (m) => m.display ?? formatValue(m.value, m.format);
315
- var achievement = (m) => m.target === void 0 || m.target === 0 || m.value === null ? "\u2014" : formatValue(m.value / m.target, ACHIEVEMENT);
316
- var change = (m) => m.delta ? /* @__PURE__ */ jsx(DeltaText, { value: m.delta.value, format: m.delta.format ?? m.format, betterWhen: m.betterWhen }) : "\u2014";
379
+ var TEXT6 = {
380
+ ja: {
381
+ title: "\u4E3B\u8981\u6307\u6A19",
382
+ comparison: "\u524D\u671F\u6BD4",
383
+ source: (source) => `\u51FA\u5178: ${source}`,
384
+ asOf: (asOf) => `\u30C7\u30FC\u30BF\u6642\u70B9 ${asOf}`,
385
+ separator: " \uFF0F ",
386
+ attainment: "\u9054\u6210\u7387",
387
+ target: (target) => `\uFF08\u76EE\u6A19 ${target}\uFF09`,
388
+ trendLabel: (label) => `${label}\u306E\u63A8\u79FB`,
389
+ metric: "\u6307\u6A19",
390
+ actual: "\u5B9F\u7E3E",
391
+ targetHead: "\u76EE\u6A19",
392
+ trend: "\u63A8\u79FB"
393
+ },
394
+ en: {
395
+ title: "Key metrics",
396
+ comparison: "vs. prior period",
397
+ source: (source) => `Source: ${source}`,
398
+ asOf: (asOf) => `Data as of ${asOf}`,
399
+ separator: " / ",
400
+ attainment: "Attainment",
401
+ target: (target) => ` (target ${target})`,
402
+ trendLabel: (label) => `${label} trend`,
403
+ metric: "Metric",
404
+ actual: "Actual",
405
+ targetHead: "Target",
406
+ trend: "Trend"
407
+ }
408
+ };
409
+ var shown = (m, locale) => m.display ?? formatValue(m.value, m.format, locale);
410
+ var achievement = (m, locale) => m.target === void 0 || m.target === 0 || m.value === null ? "\u2014" : formatValue(m.value / m.target, ACHIEVEMENT, locale);
411
+ var change = (m, locale) => m.delta ? /* @__PURE__ */ jsx(DeltaText, { value: m.delta.value, format: m.delta.format ?? m.format, betterWhen: m.betterWhen, locale }) : "\u2014";
317
412
  var trendOf = (m) => (m.trend ?? []).map(({ y }) => ({ value: y }));
318
413
  function DocKpiScorecard({
319
- title = "\u4E3B\u8981\u6307\u6A19",
414
+ title,
320
415
  headingLevel = 2,
321
416
  metrics,
322
417
  variant = "table",
323
418
  asOf,
324
419
  source
325
420
  }) {
421
+ const locale = useLocale();
422
+ const t = TEXT6[uiLanguage(locale)];
326
423
  const Heading = headingLevel === 3 ? "h3" : "h2";
327
- const caption = [source ? `\u51FA\u5178: ${source}` : void 0, asOf ? `\u30C7\u30FC\u30BF\u6642\u70B9 ${asOf}` : void 0].filter(Boolean).join(" \uFF0F ");
328
- const columnLabel = metrics.find((m) => m.comparisonLabel)?.comparisonLabel ?? "\u524D\u671F\u6BD4";
424
+ const caption = [source ? t.source(source) : void 0, asOf ? t.asOf(asOf) : void 0].filter(Boolean).join(t.separator);
425
+ const columnLabel = metrics.find((m) => m.comparisonLabel)?.comparisonLabel ?? t.comparison;
329
426
  return /* @__PURE__ */ jsxs("section", { "data-slot": "doc-kpi-scorecard", children: [
330
- /* @__PURE__ */ jsx(Heading, { children: title }),
427
+ /* @__PURE__ */ jsx(Heading, { children: title ?? t.title }),
331
428
  variant === "grid" ? /* @__PURE__ */ jsx("dl", { className: "m-0 grid grid-cols-1 gap-4 sm:grid-cols-3 print:grid-cols-3", children: metrics.map((m) => /* @__PURE__ */ jsxs(
332
429
  "div",
333
430
  {
@@ -335,56 +432,60 @@ function DocKpiScorecard({
335
432
  style: { borderColor: "var(--doc-border)", background: "var(--doc-subtle)" },
336
433
  children: [
337
434
  /* @__PURE__ */ jsx("dt", { style: MUTED2, children: m.label }),
338
- /* @__PURE__ */ jsx("dd", { className: "m-0 font-semibold tabular-nums", children: shown(m) }),
435
+ /* @__PURE__ */ jsx("dd", { className: "m-0 font-semibold tabular-nums", children: shown(m, locale) }),
339
436
  /* @__PURE__ */ jsxs("dd", { className: "m-0 flex flex-col gap-0.5", children: [
340
437
  m.delta ? /* @__PURE__ */ jsxs("span", { children: [
341
438
  /* @__PURE__ */ jsxs("span", { style: MUTED2, children: [
342
- m.comparisonLabel ?? "\u524D\u671F\u6BD4",
439
+ m.comparisonLabel ?? t.comparison,
343
440
  " "
344
441
  ] }),
345
- change(m)
442
+ change(m, locale)
346
443
  ] }) : null,
347
444
  m.target !== void 0 ? /* @__PURE__ */ jsxs("span", { children: [
348
- /* @__PURE__ */ jsx("span", { style: MUTED2, children: "\u9054\u6210\u7387 " }),
349
- achievement(m),
350
445
  /* @__PURE__ */ jsxs("span", { style: MUTED2, children: [
351
- "\uFF08\u76EE\u6A19 ",
352
- formatValue(m.target, m.format),
353
- "\uFF09"
354
- ] })
446
+ t.attainment,
447
+ " "
448
+ ] }),
449
+ achievement(m, locale),
450
+ /* @__PURE__ */ jsx("span", { style: MUTED2, children: t.target(formatValue(m.target, m.format, locale)) })
355
451
  ] }) : null
356
452
  ] }),
357
- m.trend && m.trend.length > 1 ? /* @__PURE__ */ jsx("dd", { className: "m-0", children: /* @__PURE__ */ jsx(Sparkline, { data: trendOf(m), height: 28, "aria-label": `${m.label}\u306E\u63A8\u79FB` }) }) : null
453
+ m.trend && m.trend.length > 1 ? /* @__PURE__ */ jsx("dd", { className: "m-0", children: /* @__PURE__ */ jsx(Sparkline, { data: trendOf(m), height: 28, "aria-label": t.trendLabel(m.label) }) }) : null
358
454
  ]
359
455
  },
360
456
  m.label
361
457
  )) }) : /* @__PURE__ */ jsx("div", { className: "w-full overflow-x-auto", children: /* @__PURE__ */ jsxs("table", { className: "table w-full", children: [
362
458
  /* @__PURE__ */ jsx("thead", { children: /* @__PURE__ */ jsxs("tr", { children: [
363
- /* @__PURE__ */ jsx("th", { scope: "col", children: "\u6307\u6A19" }),
364
- /* @__PURE__ */ jsx("th", { scope: "col", className: "text-right", children: "\u5B9F\u7E3E" }),
459
+ /* @__PURE__ */ jsx("th", { scope: "col", children: t.metric }),
460
+ /* @__PURE__ */ jsx("th", { scope: "col", className: "text-right", children: t.actual }),
365
461
  /* @__PURE__ */ jsx("th", { scope: "col", className: "text-right", children: columnLabel }),
366
- /* @__PURE__ */ jsx("th", { scope: "col", className: "text-right", children: "\u76EE\u6A19" }),
367
- /* @__PURE__ */ jsx("th", { scope: "col", className: "text-right", children: "\u9054\u6210\u7387" }),
368
- /* @__PURE__ */ jsx("th", { scope: "col", children: "\u63A8\u79FB" })
462
+ /* @__PURE__ */ jsx("th", { scope: "col", className: "text-right", children: t.targetHead }),
463
+ /* @__PURE__ */ jsx("th", { scope: "col", className: "text-right", children: t.attainment }),
464
+ /* @__PURE__ */ jsx("th", { scope: "col", children: t.trend })
369
465
  ] }) }),
370
466
  /* @__PURE__ */ jsx("tbody", { children: metrics.map((m) => /* @__PURE__ */ jsxs("tr", { children: [
371
467
  /* @__PURE__ */ jsx("th", { scope: "row", className: "font-medium", children: m.label }),
372
- /* @__PURE__ */ jsx("td", { className: "text-right font-semibold tabular-nums", children: shown(m) }),
373
- /* @__PURE__ */ jsx("td", { className: "text-right whitespace-nowrap", children: change(m) }),
374
- /* @__PURE__ */ jsx("td", { className: "text-right tabular-nums", children: m.target === void 0 ? "\u2014" : formatValue(m.target, m.format) }),
375
- /* @__PURE__ */ jsx("td", { className: "text-right tabular-nums", children: achievement(m) }),
376
- /* @__PURE__ */ jsx("td", { children: m.trend && m.trend.length > 1 ? /* @__PURE__ */ jsx(Sparkline, { data: trendOf(m), height: 24, "aria-label": `${m.label}\u306E\u63A8\u79FB` }) : "\u2014" })
468
+ /* @__PURE__ */ jsx("td", { className: "text-right font-semibold tabular-nums", children: shown(m, locale) }),
469
+ /* @__PURE__ */ jsx("td", { className: "text-right whitespace-nowrap", children: change(m, locale) }),
470
+ /* @__PURE__ */ jsx("td", { className: "text-right tabular-nums", children: m.target === void 0 ? "\u2014" : formatValue(m.target, m.format, locale) }),
471
+ /* @__PURE__ */ jsx("td", { className: "text-right tabular-nums", children: achievement(m, locale) }),
472
+ /* @__PURE__ */ jsx("td", { children: m.trend && m.trend.length > 1 ? /* @__PURE__ */ jsx(Sparkline, { data: trendOf(m), height: 24, "aria-label": t.trendLabel(m.label) }) : "\u2014" })
377
473
  ] }, m.label)) })
378
474
  ] }) }),
379
475
  caption ? /* @__PURE__ */ jsx("p", { style: MUTED2, children: caption }) : null
380
476
  ] });
381
477
  }
478
+ var TEXT7 = {
479
+ ja: { period: "\u5BFE\u8C61\u671F\u9593", asOf: "\u30C7\u30FC\u30BF\u6642\u70B9", author: "\u4F5C\u6210\u8005", source: "\u51FA\u5178" },
480
+ en: { period: "Period", asOf: "Data as of", author: "Author", source: "Source" }
481
+ };
382
482
  function DocReportHeader({ title, subtitle, period, asOf, author, source }) {
483
+ const t = TEXT7[uiLanguage(useLocale())];
383
484
  const facts = [
384
- ...period ? [{ label: "\u5BFE\u8C61\u671F\u9593", value: period }] : [],
385
- ...asOf ? [{ label: "\u30C7\u30FC\u30BF\u6642\u70B9", value: asOf }] : [],
386
- ...author ? [{ label: "\u4F5C\u6210\u8005", value: author }] : [],
387
- ...source ? [{ label: "\u51FA\u5178", value: source }] : []
485
+ ...period ? [{ label: t.period, value: period }] : [],
486
+ ...asOf ? [{ label: t.asOf, value: asOf }] : [],
487
+ ...author ? [{ label: t.author, value: author }] : [],
488
+ ...source ? [{ label: t.source, value: source }] : []
388
489
  ];
389
490
  return /* @__PURE__ */ jsxs("header", { "data-slot": "doc-report-header", className: "break-inside-avoid", children: [
390
491
  /* @__PURE__ */ jsx("h1", { children: title }),
@@ -402,32 +503,45 @@ function DocReportHeader({ title, subtitle, period, asOf, author, source }) {
402
503
  ) : null
403
504
  ] });
404
505
  }
405
- function DocNotesAndSources({ title = "\u6CE8\u8A18\u30FB\u51FA\u5178", headingLevel = 2, notes = [], definitions = [], sources = [] }) {
506
+ var TEXT8 = {
507
+ ja: {
508
+ title: "\u6CE8\u8A18\u30FB\u51FA\u5178",
509
+ notes: "\u6CE8\u8A18",
510
+ definitions: "\u7528\u8A9E\u306E\u5B9A\u7FA9",
511
+ sources: "\u51FA\u5178",
512
+ asOf: (asOf) => `\uFF08\u30C7\u30FC\u30BF\u6642\u70B9 ${asOf}\uFF09`
513
+ },
514
+ en: {
515
+ title: "Notes and sources",
516
+ notes: "Notes",
517
+ definitions: "Definitions",
518
+ sources: "Sources",
519
+ asOf: (asOf) => ` (data as of ${asOf})`
520
+ }
521
+ };
522
+ function DocNotesAndSources({ title, headingLevel = 2, notes = [], definitions = [], sources = [] }) {
523
+ const t = TEXT8[uiLanguage(useLocale())];
406
524
  if (notes.length === 0 && definitions.length === 0 && sources.length === 0) return null;
407
525
  const Heading = headingLevel === 3 ? "h3" : "h2";
408
526
  const Sub = headingLevel === 3 ? "h4" : "h3";
409
527
  return /* @__PURE__ */ jsxs("section", { "data-slot": "doc-notes-and-sources", children: [
410
- /* @__PURE__ */ jsx(Heading, { children: title }),
528
+ /* @__PURE__ */ jsx(Heading, { children: title ?? t.title }),
411
529
  notes.length > 0 ? /* @__PURE__ */ jsxs("div", { className: "break-inside-avoid", children: [
412
- /* @__PURE__ */ jsx(Sub, { children: "\u6CE8\u8A18" }),
530
+ /* @__PURE__ */ jsx(Sub, { children: t.notes }),
413
531
  /* @__PURE__ */ jsx("ol", { children: notes.map((n, i) => /* @__PURE__ */ jsx("li", { children: n }, i)) })
414
532
  ] }) : null,
415
533
  definitions.length > 0 ? /* @__PURE__ */ jsxs("div", { className: "break-inside-avoid", children: [
416
- /* @__PURE__ */ jsx(Sub, { children: "\u7528\u8A9E\u306E\u5B9A\u7FA9" }),
534
+ /* @__PURE__ */ jsx(Sub, { children: t.definitions }),
417
535
  /* @__PURE__ */ jsx("dl", { className: "m-0", children: definitions.map((d, i) => /* @__PURE__ */ jsxs("div", { className: "break-inside-avoid", children: [
418
536
  /* @__PURE__ */ jsx("dt", { className: "font-semibold", children: d.term }),
419
537
  /* @__PURE__ */ jsx("dd", { className: "m-0", children: d.description })
420
538
  ] }, i)) })
421
539
  ] }) : null,
422
540
  sources.length > 0 ? /* @__PURE__ */ jsxs("div", { className: "break-inside-avoid", children: [
423
- /* @__PURE__ */ jsx(Sub, { children: "\u51FA\u5178" }),
541
+ /* @__PURE__ */ jsx(Sub, { children: t.sources }),
424
542
  /* @__PURE__ */ jsx("ul", { children: sources.map((s, i) => /* @__PURE__ */ jsxs("li", { children: [
425
543
  s.name,
426
- s.asOf ? /* @__PURE__ */ jsxs("span", { style: { color: "var(--doc-muted)" }, children: [
427
- "\uFF08\u30C7\u30FC\u30BF\u6642\u70B9 ",
428
- s.asOf,
429
- "\uFF09"
430
- ] }) : null
544
+ s.asOf ? /* @__PURE__ */ jsx("span", { style: { color: "var(--doc-muted)" }, children: t.asOf(s.asOf) }) : null
431
545
  ] }, i)) })
432
546
  ] }) : null
433
547
  ] });