@squadbase/vantage 0.6.1 → 0.6.2-dev1.0017a4d

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 (319) hide show
  1. package/dist/add-4GHF2TX2.js +6 -0
  2. package/dist/add-4GHF2TX2.js.map +1 -0
  3. package/dist/{build-O5TVNH4E.js → build-X5NVCQKT.js} +9 -9
  4. package/dist/{build-O5TVNH4E.js.map → build-X5NVCQKT.js.map} +1 -1
  5. package/dist/{check-WFBEDHDR.js → check-ZBIH422T.js} +7 -7
  6. package/dist/{check-WFBEDHDR.js.map → check-ZBIH422T.js.map} +1 -1
  7. package/dist/chunk-2IAPIOPS.js +152 -0
  8. package/dist/chunk-2IAPIOPS.js.map +1 -0
  9. package/dist/chunk-2ICNHUG6.js +1820 -0
  10. package/dist/chunk-2ICNHUG6.js.map +1 -0
  11. package/dist/{chunk-5ZOP4SQR.js → chunk-2N72FKLB.js} +12 -7
  12. package/dist/chunk-2N72FKLB.js.map +1 -0
  13. package/dist/chunk-57GHR5LN.js +163 -0
  14. package/dist/chunk-57GHR5LN.js.map +1 -0
  15. package/dist/{chunk-BCE22JSM.js → chunk-7DZGJQ3P.js} +33 -14
  16. package/dist/chunk-7DZGJQ3P.js.map +1 -0
  17. package/dist/{chunk-MXI3PZFT.js → chunk-7S52M2SL.js} +257 -210
  18. package/dist/chunk-7S52M2SL.js.map +1 -0
  19. package/dist/{chunk-QDZA5JSL.js → chunk-AABMKHEU.js} +4 -4
  20. package/dist/{chunk-QDZA5JSL.js.map → chunk-AABMKHEU.js.map} +1 -1
  21. package/dist/{chunk-KLEIVDUV.js → chunk-CEXAQQ5W.js} +150 -11
  22. package/dist/chunk-CEXAQQ5W.js.map +1 -0
  23. package/dist/{chunk-3G43C6OL.js → chunk-GNXCX4WE.js} +46 -3
  24. package/dist/chunk-GNXCX4WE.js.map +1 -0
  25. package/dist/{chunk-JGRMRXXZ.js → chunk-JKLLFVEU.js} +3 -3
  26. package/dist/{chunk-JGRMRXXZ.js.map → chunk-JKLLFVEU.js.map} +1 -1
  27. package/dist/chunk-JXFCSF3K.js +673 -0
  28. package/dist/chunk-JXFCSF3K.js.map +1 -0
  29. package/dist/chunk-PDOBHMUQ.js +54 -0
  30. package/dist/chunk-PDOBHMUQ.js.map +1 -0
  31. package/dist/{chunk-ZVANIULZ.js → chunk-RNTDBX6S.js} +4 -4
  32. package/dist/{chunk-ZVANIULZ.js.map → chunk-RNTDBX6S.js.map} +1 -1
  33. package/dist/chunk-RU6WKEOG.js +7048 -0
  34. package/dist/chunk-RU6WKEOG.js.map +1 -0
  35. package/dist/{chunk-A2UUGASH.js → chunk-U736PVHY.js} +2 -2
  36. package/dist/chunk-U736PVHY.js.map +1 -0
  37. package/dist/{chunk-PVTHHV7X.js → chunk-V3LF7BE7.js} +27 -5
  38. package/dist/chunk-V3LF7BE7.js.map +1 -0
  39. package/dist/{chunk-EP6JHXSR.js → chunk-WAMZWZJB.js} +54 -9
  40. package/dist/chunk-WAMZWZJB.js.map +1 -0
  41. package/dist/{chunk-DTDVSFRY.js → chunk-XQUSGIDG.js} +17 -3
  42. package/dist/chunk-XQUSGIDG.js.map +1 -0
  43. package/dist/cli.js +15 -11
  44. package/dist/cli.js.map +1 -1
  45. package/dist/client/index.d.ts +32 -3
  46. package/dist/client/index.js +205 -12
  47. package/dist/client/index.js.map +1 -1
  48. package/dist/components/index.d.ts +1743 -29
  49. package/dist/components/index.js +7 -3
  50. package/dist/{dev-NZRLOQCL.js → dev-4XEDTELV.js} +24 -13
  51. package/dist/dev-4XEDTELV.js.map +1 -0
  52. package/dist/doc/index.d.ts +198 -2
  53. package/dist/doc/index.js +438 -11
  54. package/dist/doc/index.js.map +1 -1
  55. package/dist/{docs-ZGDJUHJI.js → docs-JVP4RPKT.js} +3 -3
  56. package/dist/{docs-ZGDJUHJI.js.map → docs-JVP4RPKT.js.map} +1 -1
  57. package/dist/{doctor-VFKEMR54.js → doctor-5E2VEZPK.js} +8 -8
  58. package/dist/doctor-5E2VEZPK.js.map +1 -0
  59. package/dist/format-U0cQl069.d.ts +243 -0
  60. package/dist/markdown/index.js +1 -1
  61. package/dist/markdown/index.js.map +1 -1
  62. package/dist/{preview-QDCIVVSR.js → preview-T6CLSQVX.js} +12 -4
  63. package/dist/preview-T6CLSQVX.js.map +1 -0
  64. package/dist/query/index.d.ts +0 -11
  65. package/dist/query/index.js +2 -2
  66. package/dist/{routes-RHP5FVGD.js → routes-3SGAFDMC.js} +6 -6
  67. package/dist/{routes-RHP5FVGD.js.map → routes-3SGAFDMC.js.map} +1 -1
  68. package/dist/{search-RFBELGY7.js → search-5LC4XPB5.js} +3 -3
  69. package/dist/{search-RFBELGY7.js.map → search-5LC4XPB5.js.map} +1 -1
  70. package/dist/slide/index.d.ts +177 -1
  71. package/dist/slide/index.js +917 -18
  72. package/dist/slide/index.js.map +1 -1
  73. package/dist/table/index.js +14 -9
  74. package/dist/table/index.js.map +1 -1
  75. package/dist/ui/index.d.ts +148 -12
  76. package/dist/ui/index.js +1340 -87
  77. package/dist/ui/index.js.map +1 -1
  78. package/dist/{upgrade-GF2P67M6.js → upgrade-JHXZBGQS.js} +7 -7
  79. package/dist/{upgrade-GF2P67M6.js.map → upgrade-JHXZBGQS.js.map} +1 -1
  80. package/dist/vite/index.d.ts +10 -0
  81. package/dist/vite/index.js +4 -4
  82. package/docs/en/changelog.md +24 -0
  83. package/docs/en/cli-reference.md +30 -0
  84. package/docs/en/components.md +40 -17
  85. package/docs/en/doc/doc-action-items.md +49 -0
  86. package/docs/en/doc/doc-callout.md +38 -0
  87. package/docs/en/doc/doc-data-table.md +60 -0
  88. package/docs/en/doc/doc-executive-summary.md +64 -0
  89. package/docs/en/doc/doc-figure.md +56 -0
  90. package/docs/en/doc/doc-key-findings.md +61 -0
  91. package/docs/en/doc/doc-kpi-scorecard.md +80 -0
  92. package/docs/en/doc/doc-report-header.md +46 -0
  93. package/docs/en/parts/area-chart.md +99 -0
  94. package/docs/en/parts/bar-chart.md +91 -0
  95. package/docs/en/parts/bar-list.md +50 -0
  96. package/docs/en/parts/category-bar.md +37 -0
  97. package/docs/en/parts/chart-frame.md +39 -0
  98. package/docs/en/parts/data-table.md +22 -0
  99. package/docs/en/parts/delta.md +50 -0
  100. package/docs/en/parts/donut-chart.md +72 -0
  101. package/docs/en/parts/format.md +43 -0
  102. package/docs/en/parts/funnel-steps.md +2 -1
  103. package/docs/en/parts/heatmap.md +53 -0
  104. package/docs/en/parts/kpi-card.md +57 -0
  105. package/docs/en/parts/legend.md +35 -0
  106. package/docs/en/parts/line-chart.md +94 -0
  107. package/docs/en/parts/metric-value.md +3 -2
  108. package/docs/en/parts/page-shell.md +1 -1
  109. package/docs/en/parts/progress-circle.md +33 -0
  110. package/docs/en/parts/sample-data.md +39 -0
  111. package/docs/en/parts/scatter-chart.md +56 -0
  112. package/docs/en/parts/sparkline.md +1 -1
  113. package/docs/en/parts/tracker.md +36 -0
  114. package/docs/en/parts/trend-indicator.md +17 -1
  115. package/docs/en/parts/updated-at.md +30 -0
  116. package/docs/en/parts/waterfall-chart.md +56 -0
  117. package/docs/en/routing.md +4 -2
  118. package/docs/en/slide/slide-chart-insight.md +52 -0
  119. package/docs/en/slide/slide-cover.md +39 -0
  120. package/docs/en/slide/slide-exec-summary.md +47 -0
  121. package/docs/en/slide/slide-kpi-grid.md +55 -0
  122. package/docs/en/slide/slide-kpi-hero.md +58 -0
  123. package/docs/en/slide/slide-next-actions.md +49 -0
  124. package/docs/en/slide/slide-scorecard-table.md +54 -0
  125. package/docs/en/ui/alert-dialog.md +42 -0
  126. package/docs/en/ui/avatar.md +31 -0
  127. package/docs/en/ui/combobox.md +74 -0
  128. package/docs/en/ui/drawer.md +41 -0
  129. package/docs/en/ui/empty.md +1 -1
  130. package/docs/en/ui/error-state.md +4 -3
  131. package/docs/en/ui/field.md +42 -0
  132. package/docs/en/ui/hover-card.md +21 -0
  133. package/docs/en/ui/kbd.md +17 -0
  134. package/docs/en/ui/loading.md +1 -1
  135. package/docs/en/ui/pagination.md +36 -0
  136. package/docs/en/ui/radio-group.md +21 -0
  137. package/docs/en/ui/toast.md +44 -0
  138. package/docs/en/ui/toggle-group.md +4 -3
  139. package/docs/en/ui-and-theming.md +1 -1
  140. package/docs/index.json +1024 -114
  141. package/docs/ja/changelog.md +55 -0
  142. package/docs/ja/cli-reference.md +29 -0
  143. package/docs/ja/components.md +66 -101
  144. package/docs/ja/doc/doc-action-items.md +49 -0
  145. package/docs/ja/doc/doc-callout.md +38 -0
  146. package/docs/ja/doc/doc-data-table.md +60 -0
  147. package/docs/ja/doc/doc-executive-summary.md +64 -0
  148. package/docs/ja/doc/doc-figure.md +56 -0
  149. package/docs/ja/doc/doc-key-findings.md +61 -0
  150. package/docs/ja/doc/doc-kpi-scorecard.md +80 -0
  151. package/docs/ja/doc/doc-report-header.md +46 -0
  152. package/docs/ja/page-types/csv.md +83 -0
  153. package/docs/ja/page-types/doc.md +83 -0
  154. package/docs/ja/page-types/excel.md +82 -0
  155. package/docs/ja/page-types/slide.md +132 -0
  156. package/docs/ja/page-types.md +47 -0
  157. package/docs/ja/parts/area-chart.md +85 -0
  158. package/docs/ja/parts/bar-chart.md +95 -0
  159. package/docs/ja/parts/bar-list.md +58 -0
  160. package/docs/ja/parts/category-bar.md +36 -0
  161. package/docs/ja/parts/chart-frame.md +36 -0
  162. package/docs/ja/parts/data-table.md +22 -0
  163. package/docs/ja/parts/delta.md +50 -0
  164. package/docs/ja/parts/donut-chart.md +66 -0
  165. package/docs/ja/parts/echart.md +3 -0
  166. package/docs/ja/parts/format.md +44 -0
  167. package/docs/ja/parts/funnel-steps.md +27 -8
  168. package/docs/ja/parts/heatmap.md +45 -0
  169. package/docs/ja/parts/kpi-card.md +55 -0
  170. package/docs/ja/parts/legend.md +36 -0
  171. package/docs/ja/parts/line-chart.md +84 -0
  172. package/docs/ja/parts/metric-value.md +3 -2
  173. package/docs/ja/parts/page-shell.md +1 -1
  174. package/docs/ja/parts/progress-circle.md +34 -0
  175. package/docs/ja/parts/sample-data.md +61 -0
  176. package/docs/ja/parts/scatter-chart.md +69 -0
  177. package/docs/ja/parts/sparkline.md +2 -2
  178. package/docs/ja/parts/tracker.md +32 -0
  179. package/docs/ja/parts/trend-indicator.md +17 -1
  180. package/docs/ja/parts/updated-at.md +27 -0
  181. package/docs/ja/parts/waterfall-chart.md +61 -0
  182. package/docs/ja/routing.md +8 -84
  183. package/docs/ja/slide/slide-chart-insight.md +52 -0
  184. package/docs/ja/slide/slide-cover.md +39 -0
  185. package/docs/ja/slide/slide-exec-summary.md +47 -0
  186. package/docs/ja/slide/slide-kpi-grid.md +55 -0
  187. package/docs/ja/slide/slide-kpi-hero.md +58 -0
  188. package/docs/ja/slide/slide-next-actions.md +49 -0
  189. package/docs/ja/slide/slide-scorecard-table.md +54 -0
  190. package/docs/ja/ui/alert-dialog.md +41 -0
  191. package/docs/ja/ui/avatar.md +31 -0
  192. package/docs/ja/ui/combobox.md +74 -0
  193. package/docs/ja/ui/drawer.md +41 -0
  194. package/docs/ja/ui/empty.md +1 -1
  195. package/docs/ja/ui/error-state.md +4 -3
  196. package/docs/ja/ui/field.md +42 -0
  197. package/docs/ja/ui/hover-card.md +21 -0
  198. package/docs/ja/ui/kbd.md +16 -0
  199. package/docs/ja/ui/loading.md +1 -1
  200. package/docs/ja/ui/pagination.md +36 -0
  201. package/docs/ja/ui/radio-group.md +21 -0
  202. package/docs/ja/ui/toast.md +46 -0
  203. package/docs/ja/ui/toggle-group.md +4 -3
  204. package/docs/ja/ui-and-theming.md +14 -7
  205. package/package.json +43 -29
  206. package/registry/ui/accordion.tsx +76 -0
  207. package/registry/ui/alert-dialog.tsx +189 -0
  208. package/registry/ui/alert.tsx +80 -0
  209. package/registry/ui/app-shell.tsx +287 -0
  210. package/registry/ui/area-chart.tsx +3701 -0
  211. package/registry/ui/attention-list.tsx +303 -0
  212. package/registry/ui/avatar.tsx +110 -0
  213. package/registry/ui/badge.tsx +56 -0
  214. package/registry/ui/bar-chart.tsx +3698 -0
  215. package/registry/ui/bar-list.tsx +3743 -0
  216. package/registry/ui/box-plot-chart.tsx +3906 -0
  217. package/registry/ui/breadcrumb.tsx +128 -0
  218. package/registry/ui/button.tsx +62 -0
  219. package/registry/ui/calendar.tsx +223 -0
  220. package/registry/ui/card.tsx +107 -0
  221. package/registry/ui/category-bar.tsx +1290 -0
  222. package/registry/ui/chart-frame.tsx +1393 -0
  223. package/registry/ui/checkbox.tsx +30 -0
  224. package/registry/ui/collapsible.tsx +23 -0
  225. package/registry/ui/combobox.tsx +310 -0
  226. package/registry/ui/command.tsx +198 -0
  227. package/registry/ui/dashboard-card.tsx +217 -0
  228. package/registry/ui/data-table.tsx +693 -146
  229. package/registry/ui/date-range-picker.tsx +390 -0
  230. package/registry/ui/delta.tsx +188 -0
  231. package/registry/ui/dialog.tsx +161 -0
  232. package/registry/ui/donut-chart.tsx +3751 -0
  233. package/registry/ui/drawer.tsx +229 -0
  234. package/registry/ui/dropdown-menu.tsx +274 -0
  235. package/registry/ui/echart.tsx +1040 -0
  236. package/registry/ui/field.tsx +240 -0
  237. package/registry/ui/filter-bar.tsx +392 -0
  238. package/registry/ui/funnel-steps.tsx +3569 -0
  239. package/registry/ui/heatmap.tsx +1786 -0
  240. package/registry/ui/histogram-chart.tsx +3986 -0
  241. package/registry/ui/hover-card.tsx +52 -0
  242. package/registry/ui/input-group.tsx +160 -0
  243. package/registry/ui/input.tsx +24 -0
  244. package/registry/ui/kbd.tsx +30 -0
  245. package/registry/ui/kpi-card.tsx +699 -0
  246. package/registry/ui/label.tsx +22 -0
  247. package/registry/ui/legend.tsx +3563 -0
  248. package/registry/ui/line-chart.tsx +3699 -0
  249. package/registry/ui/metric-value.tsx +62 -0
  250. package/registry/ui/multi-select.tsx +232 -0
  251. package/registry/ui/page-shell.tsx +282 -0
  252. package/registry/ui/pagination.tsx +140 -0
  253. package/registry/ui/paired-chart.tsx +3827 -0
  254. package/registry/ui/placeholder.tsx +36 -0
  255. package/registry/ui/popover.tsx +92 -0
  256. package/registry/ui/progress-circle.tsx +867 -0
  257. package/registry/ui/progress.tsx +85 -0
  258. package/registry/ui/radio-group.tsx +39 -0
  259. package/registry/ui/sample-data.tsx +86 -0
  260. package/registry/ui/scatter-chart.tsx +4212 -0
  261. package/registry/ui/scroll-area.tsx +56 -0
  262. package/registry/ui/searchable-select.tsx +214 -0
  263. package/registry/ui/section-header.tsx +43 -0
  264. package/registry/ui/segmented-control.tsx +76 -0
  265. package/registry/ui/select.tsx +255 -0
  266. package/registry/ui/separator.tsx +27 -0
  267. package/registry/ui/sheet.tsx +139 -0
  268. package/registry/ui/sidebar.tsx +725 -0
  269. package/registry/ui/skeleton.tsx +17 -0
  270. package/registry/ui/slider.tsx +56 -0
  271. package/registry/ui/sparkline.tsx +230 -0
  272. package/registry/ui/spinner.tsx +14 -0
  273. package/registry/ui/states.tsx +90 -0
  274. package/registry/ui/status-badge.tsx +121 -0
  275. package/registry/ui/switch.tsx +34 -0
  276. package/registry/ui/table.tsx +118 -0
  277. package/registry/ui/tabs.tsx +84 -0
  278. package/registry/ui/textarea.tsx +22 -0
  279. package/registry/ui/toast.tsx +250 -0
  280. package/registry/ui/toggle-group.tsx +91 -0
  281. package/registry/ui/toggle.tsx +47 -0
  282. package/registry/ui/tooltip.tsx +72 -0
  283. package/registry/ui/tracker.tsx +849 -0
  284. package/registry/ui/trend-indicator.tsx +74 -0
  285. package/registry/ui/updated-at.tsx +122 -0
  286. package/registry/ui/waterfall-chart.tsx +4248 -0
  287. package/skills/vantage-add-feature/SKILL.md +9 -7
  288. package/skills/vantage-design/SKILL.md +36 -24
  289. package/skills/vantage-design/references/extract.md +16 -14
  290. package/skills/vantage-design/references/format.md +6 -5
  291. package/skills/vantage-design/references/presets.md +60 -110
  292. package/skills/vantage-pitfalls/SKILL.md +5 -1
  293. package/skills/vantage-slide/SKILL.md +71 -36
  294. package/templates/AGENTS.md +24 -3
  295. package/templates/agents/api.md +29 -0
  296. package/templates/agents/csv.md +2 -1
  297. package/templates/agents/doc.md +51 -3
  298. package/templates/agents/page.md +54 -9
  299. package/templates/agents/slide.md +68 -3
  300. package/templates/agents/xlsx.md +2 -1
  301. package/theme.css +284 -128
  302. package/dist/add-EISGSZAH.js +0 -6
  303. package/dist/add-EISGSZAH.js.map +0 -1
  304. package/dist/chunk-3G43C6OL.js.map +0 -1
  305. package/dist/chunk-5ZOP4SQR.js.map +0 -1
  306. package/dist/chunk-A2UUGASH.js.map +0 -1
  307. package/dist/chunk-BCE22JSM.js.map +0 -1
  308. package/dist/chunk-DTDVSFRY.js.map +0 -1
  309. package/dist/chunk-EP6JHXSR.js.map +0 -1
  310. package/dist/chunk-KLEIVDUV.js.map +0 -1
  311. package/dist/chunk-MXI3PZFT.js.map +0 -1
  312. package/dist/chunk-PLST5Q7T.js +0 -2221
  313. package/dist/chunk-PLST5Q7T.js.map +0 -1
  314. package/dist/chunk-PVTHHV7X.js.map +0 -1
  315. package/dist/chunk-T3FLAGI6.js +0 -316
  316. package/dist/chunk-T3FLAGI6.js.map +0 -1
  317. package/dist/dev-NZRLOQCL.js.map +0 -1
  318. package/dist/doctor-VFKEMR54.js.map +0 -1
  319. package/dist/preview-QDCIVVSR.js.map +0 -1
@@ -43,20 +43,36 @@ export default function JuneDeck() {
43
43
 
44
44
  - **1 ファイル = 1 デッキ = 1 ルート。** `export default` は `<SlideDeck>` を返す React コンポーネント
45
45
  (通常のページと同じ契約なので、`vantage check` も `vantage routes` も特別扱いをしません)。
46
- - **スライドは `<SlideDeck>` の直下の `<Slide>`。** 深くネストした `<Slide>` は拾われません。
47
- - `definePage` の `title` / `navLabel` はビルド時に静的抽出されるので**リテラルで書く**(変数・
48
- テンプレート補間は不可)。ナビの表示名はこれで決まります。
46
+ - **ファイル形式の MUST / SHOULD(`<Slide>` は `<SlideDeck>` の直下、`<Step>` は `<Steps>` の直下、
47
+ `definePage` はリテラル など)は `agents/slide.md` と `agents/page.md` が正本**です。ここでは繰り返しません。
49
48
  - **`.slide` を付けられるのはルートになるページモジュールだけ。** `_layout.slide.tsx` や
50
49
  `deck.slide.ts` は `INVALID_PAGE_VARIANT` エラーになります。
51
50
  - **`june.slide.tsx` と `june.tsx` は同じ URL** になるので `ROUTE_CONFLICT` です。どちらかを消すこと。
51
+ - **ルート `/` がすでに他のページ(`index.tsx` など)で使われている場合、スライドは `index.slide.tsx` ではなく、タイトルから作った slug でファイル名を付ける。** `index.slide.tsx` と `index.tsx` は同じ `/` に解決して `ROUTE_CONFLICT` になる。
52
+ - 例: "Label check" → `src/label-check.slide.tsx` → `/label-check`
53
+ - 例: "Monthly Report" → `src/monthly-report.slide.tsx` → `/monthly-report`
52
54
  - **デッキファイル以外を作らない。** ヘルパーコンポーネントも定数も同じ `.slide.tsx` の中に書く。
53
55
  スライド専用のコンポーネントを `components/` に切り出すと、デッキ 1 本を読むのに 2 ファイル
54
56
  追わせることになります。
55
57
 
58
+ ## まず block を探す
59
+
60
+ 1 枚分の中身は、手で組む前に `@squadbase/vantage/slide` の block(`SlideCover` `SlideExecSummary`
61
+ `SlideKpiHero` `SlideKpiGrid` `SlideChartInsight` `SlideScorecardTable` `SlideNextActions`)に
62
+ 合うものがないか探します。`<Slide>` の**中**に置き、props は `vantage docs <name>`(例:
63
+ `vantage docs slide-cover`)で引く。一覧は `agents/slide.md` が正本です。
64
+ - props は block 間で共通: `value: number | null` + `format`(上書きだけ `display`)、`delta: { value, format? }` + `betterWhen` + `comparisonLabel`、`target: number`、`source` は文字列、`asOf` は日付だけ(「時点」は block が付ける)。
65
+
66
+ - block は `@squadbase/vantage/slide` から import する。**新しい import 元は増えない**(下の
67
+ 「import してよいもの」と矛盾しない)。`vantage add` でコピーするものでもない。
68
+ - block が合わない**1 枚だけ**を、この下の規約で手書きする。デッキ全体を手書きに切り替えない。
69
+ - デッキ以外のファイルは作らない。block を使っても、デッキは 1 ファイルのままで、独自の
70
+ ヘルパーコンポーネントは同じ `.slide.tsx` に書く。
71
+
56
72
  ## import してよいもの
57
73
 
58
74
  - `@squadbase/vantage/slide` — `SlideDeck` `Slide` `Steps` `Step` `MorphElement` `useSlideNumber`
59
- `useIsActiveSlide` `SlideCanvas` と、その型
75
+ `useIsActiveSlide` `SlideCanvas`、1 枚分の block(`SlideCover` ほか上の 7 つ)と、その型
60
76
  - `@squadbase/vantage` — `definePage`
61
77
  - `@squadbase/vantage/components` の `EChart` — **チャートを載せるときはこれ**(→「チャート」)
62
78
  - `lucide-react` のアイコン
@@ -74,21 +90,25 @@ export default function JuneDeck() {
74
90
  - 各スライドのルート要素はキャンバスを埋める(`width: "100%"; height: "100%"`)
75
91
  - インライン `style={{ … }}` を使う。読み込んだ CSS はグローバルです
76
92
 
77
- ### タイプスケール(ここから始めて調整する)
93
+ 以下の値がスライドの規約です。ヒーローと本文は `var(--slide-size-hero)` /
94
+ `var(--slide-size-body)` としても読めます(→ `references/tokens.md`)。
95
+
96
+ ### タイプスケール
78
97
 
79
98
  | 要素 | サイズ |
80
99
  | --- | --- |
81
- | ヒーロータイトル | 140–200px |
82
- | セクション見出し | 80–120px |
83
- | ページ見出し | 56–80px |
84
- | 本文 | 32–44px |
85
- | キャプション / ラベル | 22–28px |
100
+ | ヒーロータイトル | 168px |
101
+ | セクション見出し | 88px |
102
+ | ページ見出し | 64px |
103
+ | 本文 | 36px |
104
+ | キャプション / ラベル | 24px |
86
105
 
87
- ### 余白
106
+ ### 余白とグリッド
88
107
 
89
- - コンテンツの padding: キャンバス端から **100–160px**。文字を端に触れさせない
90
- - line-height: 見出し 1.2、本文 1.5–1.7
91
- - 要素間: 32–64px
108
+ - セーフエリア: キャンバス端から **左右 160px・上下 120px**。中身はこの内側の **1600 × 840px** に置き、文字を端に触れさせない
109
+ - グリッド: 内容幅 1600px を **12 列**(列幅 104px・溝 32px)に割る
110
+ - line-height: 見出し 1.2、本文 1.6
111
+ - 要素間: 32 / 48 / 64px のどれか
92
112
 
93
113
  ### 縦方向の予算 — 中身は 1080px に収まらなければならない
94
114
 
@@ -96,33 +116,32 @@ export default function JuneDeck() {
96
116
  計算して収まることを確かめること。**これがスライドが壊れる原因の第 1 位**で、確かめない限り
97
117
  溢れていると思ってください。
98
118
 
99
- **使える高さ** = `1080 − 上 padding − 下 padding`。上下 120px なら **840px**、160px なら **760px**。
100
- 先に padding を決めて、その予算の中で設計します。
119
+ **使える高さ** = `1080 − 上下のセーフエリア(120px × 2)` = **840px**。この予算の中で設計します。
101
120
 
102
121
  **要素の高さ** = `文字サイズ × line-height × 行数`。2 行に折り返す箇条書きは 2 行と数えます。
103
- 次の要素を足す前に、その下の gap(32–64px)を加算してください。
122
+ 次の要素を足す前に、その下の gap(32 / 48 / 64px)を加算してください。
104
123
 
105
- **計算例 — 本文 1 枚、padding 120px(予算 840px):**
124
+ **計算例 — 本文 1 枚(予算 840px):**
106
125
 
107
126
  | 要素 | 高さ |
108
127
  | --- | --- |
109
- | 見出し: 80px × 1.2 × 1 行 | 96px |
128
+ | ページ見出し: 64px × 1.2 × 1 行 | 76.8px |
110
129
  | gap | 64px |
111
- | 本文: 40px × 1.6 × 3 行 | 192px |
130
+ | 本文: 36px × 1.6 × 3 行 | 172.8px |
112
131
  | gap | 48px |
113
- | 箇条書き 5 行: 40px × 1.6 × 1 行 | 320px(5 × 64px) |
114
- | 箇条書き間の gap 4 つ: 24px | 96px |
115
- | **合計** | **816px ✅ 840 に収まる** |
132
+ | 箇条書き 5 行: 36px × 1.6 × 1 行 | 288px(5 × 57.6px) |
133
+ | 箇条書き間の gap 4 つ: 32px | 128px |
134
+ | **合計** | **777.6px ✅ 840 に収まる** |
116
135
 
117
- 見出しを 120px にするか箇条書きを 6 つにすると溢れます。**書く前に毎ページこの検算をすること。**
136
+ 箇条書きを 6 つにすると 867.2px で溢れます。**書く前に毎ページこの検算をすること。**
118
137
 
119
138
  **ページ単位の規則:**
120
139
 
121
140
  - 「見出し + 本文」か「見出し + 5 つ以内の短い箇条書き」のどちらか。両方は載せない
122
141
  - 箇条書きは選んだ文字サイズで 1 行に収まること。折り返すなら短くするか別ページに割る
123
- - ヒーロータイトル(140–200px)はタイトル + サブタイトル 1 行 + アイブロウまで。それ以外は載せない
124
- - セクション見出し(80–120px)のページにはほとんど何も足さない
125
- - 収めるために padding を上げる・スケールの下限より小さい文字にする・本文の line-height を 1.4 未満に
142
+ - ヒーロータイトル(168px)はタイトル + サブタイトル 1 行 + アイブロウまで。それ以外は載せない
143
+ - セクション見出し(88px)のページにはほとんど何も足さない
144
+ - 収めるためにセーフエリアを削る・タイプスケールより小さい文字にする・本文の line-height を 1.6 未満に
126
145
  詰める、をやりたくなったら**ページを 2 枚に割る**。予算が厳しいときは分割が常に正解
127
146
 
128
147
  **`overflow: auto/scroll`・負のマージン・transform で溢れを隠さないこと。** キャンバスは固定で、
@@ -136,7 +155,7 @@ export default function JuneDeck() {
136
155
  それ以外はプレーンな const にする(→ `references/tokens.md`)
137
156
  - **書体** — ディスプレイ 1 + 本文 1。指定がなければシステムスタック。見出しは太く(800–900)、
138
157
  本文は通常(400–500)
139
- - **レイアウトグリッド** — padding を 1 つ決めて(例: 120px)貫く。左揃えは編集的、中央揃えは儀礼的
158
+ - **レイアウトグリッド** — セーフエリアと 12 列グリッド(→「余白とグリッド」)を全ページで貫く。左揃えは編集的、中央揃えは儀礼的
140
159
  - **美学のコミットメント** — 1 つ選ぶ: ミニマル / マキシマル / エディトリアル / レトロ /
141
160
  ブルータリスト / ソフト・パステル / ネオン / 紙・印刷。混ぜない
142
161
 
@@ -149,12 +168,12 @@ export default function JuneDeck() {
149
168
  // ✅ 各カードが独自の JSX ノードを持つ
150
169
  const Card = ({ label, value }: { label: string; value: string }) => (
151
170
  <div style={{ flex: 1 }}>
152
- <div style={{ fontSize: 28, opacity: 0.6 }}>{label}</div>
153
- <div style={{ fontSize: 120, fontWeight: 800 }}>{value}</div>
171
+ <div style={{ fontSize: 24, opacity: 0.6 }}>{label}</div>
172
+ <div style={{ fontSize: 88, fontWeight: 800 }}>{value}</div>
154
173
  </div>
155
174
  )
156
175
 
157
- <div style={{ display: "flex", gap: 96 }}>
176
+ <div style={{ display: "flex", gap: 64 }}>
158
177
  <Card label="売上" value="¥5.2億" />
159
178
  <Card label="解約率" value="1.4%" />
160
179
  </div>
@@ -166,6 +185,8 @@ const Card = ({ label, value }: { label: string; value: string }) => (
166
185
 
167
186
  これは**視覚要素が繰り返すとき**の話で、データが繰り返すときの話ではありません。純粋な
168
187
  テキストの箇条書き(`<ul><li>`)は各 `<li>` が既に独立した JSX ノードなので、そのままで正しい。
188
+ `<SlideDeck>` の直下に `<Slide>` を配列で渡すこと自体はファイル形式として可能です(`agents/slide.md`)が、
189
+ 1 枚ごとの文言・図を変えるスライドは 1 枚ずつ書きます。
169
190
 
170
191
  ## ページ番号
171
192
 
@@ -194,6 +215,17 @@ pptx 書き出しのために描き終わりを待たせる必要があります
194
215
  チャートに色をハードコードしないこと(`option.color` / `itemStyle.color` / `theme`)。
195
216
  `EChart` はテーマトークンに追従します。
196
217
 
218
+ ## 説明と図表を同じデータ時点へ揃える
219
+
220
+ 分析を共有するデッキでは、本文・数値・図表が**同じ対象期間と同じ取得時点の結果**を参照していることを
221
+ 確かめます。
222
+
223
+ - 対象期間とデータ取得時点を、該当ページかフッターに短く表示する(例: 「2026年6月 / 7月1日 9:00 取得」)
224
+ - **固定した説明文に対して図表だけが最新値へ変わる構成を避ける。** ライブ更新を意図するなら、本文の
225
+ 数値・結論も同じ取得結果から導いて、図表と一緒に変わる構成にする
226
+ - 同一時点の結果を保持・参照できない場合は、スナップショットとして保存できたとは報告しない。
227
+ 必要な保持の仕組みと、現在保証できない範囲(例: 再表示すると図表だけ最新値になる)を伝える
228
+
197
229
  ## 実行時に無料で付いてくるもの
198
230
 
199
231
  - `src/june.slide.tsx` → `/june`。ナビ(`useRoutes()`)に通常のページと同格で並ぶ
@@ -236,14 +268,15 @@ pptx 書き出しのために描き終わりを待たせる必要があります
236
268
  - [ ] `export default` が `<SlideDeck>` を返している
237
269
  - [ ] `<Slide>` が `<SlideDeck>` の直下にある
238
270
  - [ ] 各スライドのルート要素が `100% × 100%` を埋めている
239
- - [ ] 文字が padding の内側にある(端に触れていない)
240
- - [ ] **全ページで(文字サイズ × line-height × 行数)+ gap + padding×2 ≤ 1080px。** 際どいなら分割
271
+ - [ ] 文字がセーフエリア(左右 160px・上下 120px)の内側にある
272
+ - [ ] **全ページで(文字サイズ × line-height × 行数)+ gap ≤ 840px。** 際どいなら分割
241
273
  - [ ] 箇条書きが 2 行目に折り返していない
242
274
  - [ ] 配色とタイプスケールが全ページで一貫している
243
275
  - [ ] 1 ページ 1 メッセージ
244
276
  - [ ] 繰り返す視覚要素が `array.map` ではなく明示的な `<Component />` になっている
245
277
  - [ ] ページ番号が `useSlideNumber()` から来ている(ハードコードしていない)
246
278
  - [ ] チャートが `data-waitfor="canvas"` で包まれている
279
+ - [ ] 本文・数値・図表が同じ対象期間と取得時点の結果を参照し、その期間と時点が表示されている
247
280
  - [ ] `<Steps>` を使ったページが、`?p=` で直接開いても完成した絵として読める
248
281
  - [ ] トランジションを宣言したなら、全ページが 1 つの family に収まっている(→ `references/transitions.md`)
249
282
  - [ ] `definePage` の値がリテラルである
@@ -252,13 +285,15 @@ pptx 書き出しのために描き終わりを待たせる必要があります
252
285
  ## アンチパターン
253
286
 
254
287
  - ❌ 文字の壁。1 ページ 40 語を超えたら分割する
255
- - ❌ キャンバス全面を本文で使う。padding 100–160px を守る
288
+ - ❌ キャンバス全面を本文で使う。セーフエリア(左右 160px・上下 120px)を守る
256
289
  - ❌ 縦に 1080px を溢れさせる。切れた中身は見えない — 分割する
257
290
  - ❌ `overflow: auto` / `scroll` / `hidden` で溢れを「隠す」。バグを隠しただけ
258
- - ❌ 詰め込むためにスケールの下限より小さい文字にする・padding を 100px 未満にする
259
- - ❌ 本文 28px 未満。プロジェクタで読めない
291
+ - ❌ 詰め込むためにタイプスケールより小さい文字にする・セーフエリアを削る
292
+ - ❌ 本文を 36px 未満にする。プロジェクタで読めない
260
293
  - ❌ `@squadbase/vantage/ui` のプリミティブをスライドに置く(縮小されて読めなくなる)
261
294
  - ❌ 依存を追加する。使えるのは `@squadbase/vantage/*` と `lucide-react` と標準 Web API だけ
262
295
  - ❌ スライド用のコンポーネントを別ファイルに切り出す
263
296
  - ❌ チャートに `data-waitfor="canvas"` を付け忘れる(pptx が白紙になる)
264
297
  - ❌ プリミティブを `references/*.md` を読まずに使う
298
+ - ❌ 説明文を固定したまま図表だけライブデータで描く(再表示すると本文と図表の時点がずれる)
299
+ - ❌ 同一時点の結果を保持できていないのに「スナップショットとして保存した」と報告する
@@ -93,13 +93,25 @@ root/
93
93
  | `@squadbase/vantage/router` | `Link`・`Outlet`・`useParams`・`useSearch`・`useNavigate`・`redirect`・`notFound`・`useRoutes`・`useCurrentRoute`・`useSearchParam`・`useSearchState` |
94
94
  | `@squadbase/vantage/query` | `useApiQuery`・`useApiMutation`・`apiJson`・`apiFetch`・`apiUrl`・`ApiError`、ほか `useQuery`/`useMutation` など TanStack Query の再エクスポート |
95
95
  | `@squadbase/vantage/ui` | shadcn/ui(Base UI バリアント)プリミティブ(`Button`・`Loading`・`ErrorState`・`Empty` ほか) |
96
- | `@squadbase/vantage/components` | 複合パーツ(`PageShell`・`DashboardCardPreset`・`DataTablePreset`・`EChart` ほか) |
96
+ | `@squadbase/vantage/components` | 複合パーツ(`PageShell`・`DashboardCardPreset`・`DataTablePreset`、KPI の `KpiCard`・`Delta`、型付きチャート `LineChart`・`BarChart`・`AreaChart`・`DonutChart`・`BarList` ほか、`EChart`、書式の `formatValue`) |
97
97
  | `@squadbase/vantage/table` | `FilePageView`・`TableViewer`(データファイルページの表ビューア) |
98
- | `@squadbase/vantage/slide` | `SlideDeck`・`Slide`・`Steps`・`Step`・`MorphElement`・`useSlideNumber`・`useIsActiveSlide`(スライド専用。1920×1080 の固定キャンバス) |
99
- | `@squadbase/vantage/doc` | `Document`(ドキュメント専用。中の素の HTML 要素に見出し・表などのスタイルが当たる) |
98
+ | `@squadbase/vantage/slide` | `SlideDeck`・`Slide`・`Steps`・`Step`・`MorphElement`・`useSlideNumber`・`useIsActiveSlide`、1 枚分の block `SlideCover`・`SlideExecSummary`・`SlideKpiHero`・`SlideKpiGrid`・`SlideChartInsight`・`SlideScorecardTable`・`SlideNextActions`(スライド専用。1920×1080 の固定キャンバス) |
99
+ | `@squadbase/vantage/doc` | `Document`、ドキュメント用の block `DocReportHeader`・`DocExecutiveSummary`・`DocKpiScorecard`・`DocFigure`・`DocDataTable`・`DocCallout`・`DocKeyFindings`・`DocActionItems`(ドキュメント専用。中の素の HTML 要素に見出し・表などのスタイルが当たる) |
100
100
  | `@squadbase/vantage/markdown` | `MarkdownRenderer`(Shiki を隔離するための専用サブパス) |
101
101
  | `@squadbase/vantage/server` | `ApiContext`・`ApiHandler`・`HttpError`・`isHttpError`・`json`(server/ 側でのみ使う) |
102
102
 
103
+ **KPI は `KpiCard`、増減は `Delta`(`comparison` と `polarity` を渡す)。** 向き・率・色は値から計算
104
+ されるので手で渡さない。`TrendIndicator` は非推奨(`direction` を手で渡すので値と食い違いうる)。props は
105
+ `vantage docs kpi-card` / `vantage docs delta` を引く。
106
+
107
+ ```tsx
108
+ import { KpiCard, Delta } from "@squadbase/vantage/components";
109
+
110
+ <KpiCard label="売上" value={48_200_000} format="currency"
111
+ comparison={{ previous: 42_900_000, vs: "prior-period" }} />
112
+ <Delta value={0.021} comparison={{ previous: 0.026, vs: "prior-period" }} polarity="lower-is-better" />
113
+ ```
114
+
103
115
  ## モードは 2 つ、切り替えるのは `server/` の有無だけ
104
116
 
105
117
  `server/` ディレクトリがあれば **fullstack**、無ければ **SPA**。`vantage-manifest.json` の
@@ -137,6 +149,15 @@ root/
137
149
  | `.xlsx` ページ | `agents/xlsx.md` |
138
150
  | `.csv` ページ | `agents/csv.md` |
139
151
 
152
+ **ページになるのは `.tsx` / `.jsx`(`.slide.tsx`・`.doc.tsx` を含む)・`.csv`・`.xlsx` だけ。**
153
+
154
+ - `.xls`・`.xlsm`・`.xlsb`・`.ods`・`.tsv`・`.numbers`・`.parquet` はルートにならず、404 にもならない。
155
+ `vantage check` の `UNSUPPORTED_PAGE_FILE` 警告だけが知らせる。`.xlsx` / `.csv` に変換して置く
156
+ - `.md`・`.json`・`.txt` は何も言わずに無視される。Markdown を見せたいときは `.tsx` のページで
157
+ `MarkdownRenderer`(`@squadbase/vantage/markdown`)に渡す
158
+ - `.csv` / `.xlsx` はブラウザでパースする。25MB を超えるとそのページにエラーが出る
159
+ (`FILE_PAGE_TOO_LARGE` 警告)。20 万行を超えるシートは先頭 20 万行だけが表示される
160
+
140
161
  ## 環境変数
141
162
 
142
163
  - **クライアントで読めるのは `import.meta.env.PUBLIC_*` と `MODE`/`DEV`/`PROD`/`SSR`/`BASE_URL`
@@ -25,6 +25,11 @@ export async function GET({ params, env }: ApiContext) {
25
25
  エクスポートする。それ以外の名前は `INVALID_API_EXPORT` エラー。
26
26
  - 動的 API も `[id].ts` 記法: `server/api/customers/[id].ts` → `GET /api/customers/:id`。
27
27
  `params.id` で取り出す(`noUncheckedIndexedAccess` が効くので narrowing が要る)。
28
+ - **`noUncheckedIndexedAccess` は配列・レコードの添字すべてに効く。** `arr[0]` も `obj[key]` も
29
+ `T | undefined` になる。最初に書く前に、添字アクセスと `useApiQuery` の `data` が
30
+ undefined を扱っているかを頭の中で型検査してから書く。上流の生の応答の値は
31
+ `Number(row.metricValues?.[0]?.value ?? "0")` のように `?.` と `??` で取り出す
32
+ (`!` で黙らせない)。
28
33
  - **クライアントに見せたいエラーは `HttpError(status, msg)` を throw する。** それ以外の throw は
29
34
  ログに記録され汎用の 500 に丸められる。
30
35
  - **シークレットは `ApiContext.env` にだけ届く**(クライアントには決して届かない)。
@@ -34,9 +39,12 @@ export async function GET({ params, env }: ApiContext) {
34
39
 
35
40
  ```tsx
36
41
  import { useApiQuery, useApiMutation } from "@squadbase/vantage/query"
42
+ import { Loading, ErrorState } from "@squadbase/vantage/ui"
37
43
 
38
44
  const q = useApiQuery<Customer>(`/api/customers/${customerId}`)
45
+ if (q.isPending) return <Loading />
39
46
  if (q.isError) return <ErrorState message={q.error.message} /> // HttpError のメッセージ
47
+ q.data // ここで初めて Customer(undefined ではない)
40
48
 
41
49
  // クエリ文字列は search で。undefined の項目は落ちる
42
50
  const rows = useApiQuery<Row[]>("/api/customers", { search: { segment } })
@@ -45,5 +53,26 @@ const rows = useApiQuery<Row[]>("/api/customers", { search: { segment } })
45
53
  const save = useApiMutation<Customer, Payload>("/api/customers", { method: "POST" })
46
54
  ```
47
55
 
56
+ **`data` は、同じ結果オブジェクトで `isPending` と `isError` を判定したあとでしか
57
+ narrowing されない。** 判定前や、配列の `.find` などでまとめた判定のあとでは `T | undefined` のまま。
58
+ 複数のクエリは 1 本ずつ判定してから `data` を使う(`data!` で黙らせない):
59
+
60
+ ```tsx
61
+ const sessions = useApiQuery<SessionsDaily[]>("/api/sessions-daily")
62
+ const metrics = useApiQuery<MetricsDaily[]>("/api/metrics-daily")
63
+
64
+ if (sessions.isPending || metrics.isPending) return <Loading />
65
+ if (sessions.isError) return <ErrorState message={sessions.error.message} />
66
+ if (metrics.isError) return <ErrorState message={metrics.error.message} />
67
+ // ここから sessions.data: SessionsDaily[] / metrics.data: MetricsDaily[]
68
+ return <Chart sessions={sessions.data} metrics={metrics.data} />
69
+
70
+ // NG: const failed = [sessions, metrics].find((q) => q.isError) のように配列でまとめて判定すると
71
+ // 各 q.data は narrowing されず、`T[] | undefined` を T[] の props に渡して型エラーになる
72
+ ```
73
+
74
+ カードごとに別々に読み込み中・エラーを出すなら、`data` を渡す側で `q.data ?? []` にするか、
75
+ カードのコンポーネントの中で上と同じ判定をする。
76
+
48
77
  `ApiError` は `message`・`status`・`body`・`requestId` を持つ。hook が使えない場所では
49
78
  `apiJson(path, init)`、生の `Response` が要るときは `apiFetch`。
@@ -27,6 +27,7 @@
27
27
  ```
28
28
  - 数式・グラフ・セル書式といった概念は csv には無いので、値がそのまま読めます。ブラウザで
29
29
  パースするので 25MB を超えるファイルはそのページにエラーが出ます —— 大きいデータは
30
- `server/api/` から配って `DataTable` で描いてください
30
+ `server/api/` から配って `DataTable` で描いてください。20 万行を超えると先頭
31
+ 20 万行だけが表示されます(残りはダウンロードして見る)
31
32
  - **ビューアの無い拡張子(`.tsv` など)はルートになりません。** `vantage check` の
32
33
  `UNSUPPORTED_PAGE_FILE` 警告が知らせます
@@ -12,9 +12,16 @@
12
12
 
13
13
  ```tsx
14
14
  import { definePage } from "@squadbase/vantage"
15
- import { EChart } from "@squadbase/vantage/components"
15
+ import { BarChart } from "@squadbase/vantage/components"
16
16
  import { Document } from "@squadbase/vantage/doc"
17
17
 
18
+ const weekly = [
19
+ { week: "第1週", 売上: 1180 },
20
+ { week: "第2週", 売上: 1240 },
21
+ { week: "第3週", 売上: 1210 },
22
+ { week: "第4週", 売上: 1620 },
23
+ ]
24
+
18
25
  export const page = definePage({ title: "6月度サマリー", navLabel: "6月度サマリー" })
19
26
  export default function JuneSummary() {
20
27
  return (
@@ -23,7 +30,7 @@ export default function JuneSummary() {
23
30
  <p>6月の売上は <strong>5,250 万円</strong>で、目標を 5% 上回りました。</p>
24
31
  <h2>週次の売上</h2>
25
32
  <figure>
26
- <EChart option={option} height={280} ariaLabel="6月の週次売上" />
33
+ <BarChart data={weekly} index="week" categories={["売上"]} height={280} ariaLabel="6月の週次売上" />
27
34
  <figcaption>第4週はキャンペーン初週</figcaption>
28
35
  </figure>
29
36
  <table>…</table>
@@ -42,11 +49,35 @@ export default function JuneSummary() {
42
49
  見た目を変えたいときはユーティリティを並べず、下の `--doc-*` を変えます。
43
50
  - **数値はコードに直接書く。** ドキュメントは書いた時点の内容を残すページです。
44
51
  `useApiQuery` などで読み込むと、開くたびに値が変わります。
45
- - **チャートは `EChart`(`@squadbase/vantage/components`)を文中に置く。** `figure` で囲めば
52
+ - **チャートは型付きチャート(`BarChart`・`LineChart` など。`@squadbase/vantage/components`)を
53
+ 文中に置く**(選び方は `agents/page.md` の「グラフはまず型付きチャートで描く」)。`figure` で囲めば
46
54
  `figcaption` がキャプションになります。
55
+ - **PDF の保存ボタンは作らない。** `<Document>` が右下に PDF 保存のボタンを出し、印刷時は
56
+ 本文だけをライトの配色で出します。
47
57
  - **ページ全体を包むのは `<Document>` だけ。** `PageShell` などのダッシュボード用の枠で包まない
48
58
  (本文の幅と余白は `<Document>` が決めます)。
49
59
 
60
+ ## まず block を探す
61
+
62
+ 1 節分の中身は、手で組む前に `@squadbase/vantage/doc` の block から探します(`<Document>` の直下に
63
+ 並べる。多くは 1 block = 1 節。`DocCallout`・`DocFigure`・`DocDataTable` は節ではなく、節の中(本文の間)に置く部品)。props は `vantage docs <name>`(例: `vantage docs doc-kpi-scorecard`)で引く。
64
+
65
+ | block | 用途 |
66
+ | --- | --- |
67
+ | `DocReportHeader` | レポートの冒頭(タイトル・サブタイトル・対象期間・データ時点・作成者・出典) |
68
+ | `DocExecutiveSummary` | 結論を先に述べる要約の節 |
69
+ | `DocKpiScorecard` | 主要指標をまとめたスコアカード |
70
+ | `DocFigure` | 図表 1 つとキャプション(チャートは children で渡す) |
71
+ | `DocDataTable` | 素の `table` による表 |
72
+ | `DocCallout` | 補足・示唆・注意・決定の囲み(`kind`: `note` / `insight` / `warning` / `decision`) |
73
+ | `DocKeyFindings` | 主要な発見の箇条 |
74
+ | `DocActionItems` | 次のアクション(担当・期限つき) |
75
+
76
+ **props の渡し方は block 間で共通。** 数値は `value: number | null` と `format`(整形は block がする。表示を上書きするときだけ `display`。`null` は「—」)。前期比などは `delta: { value, format? }` と `comparisonLabel`(例 `"前年同期比"`)、良し悪しは指標ごとの `betterWhen`(`"up"` が既定、コストなど下がるほど良いものは `"down"`。向きは block が符号から出す)。目標は `target: number`。出典は `source`、時点は `asOf` に**日付だけ**(例 `"2026-09-30"`。「データ時点」は block が付けるので「時点」を書かない)。時系列は、単一系列なら `{ x, y }[]`(`trend`)。
77
+
78
+ block が合わない**1 節だけ**を素の HTML 要素で手で書く。import 元は `@squadbase/vantage/doc` のままで、
79
+ block のための新しい import 元はありません。本文は文字列か ReactNode で渡し、Markdown 文字列は渡さない。
80
+
50
81
  ## 見た目を変える
51
82
 
52
83
  配色・書体・本文の幅は `--doc-*` の CSS 変数です。既定値はアプリのトークンへの別名なので、
@@ -71,3 +102,20 @@ export default function JuneSummary() {
71
102
  `.doc` を付けられるのはルートになるページモジュールだけで、`_layout.doc.tsx` などは
72
103
  `INVALID_PAGE_VARIANT` エラーになります。`june.doc.tsx` と `june.tsx` は同じ URL に解決するので
73
104
  `ROUTE_CONFLICT` です。
105
+
106
+ ## ファイル形式の規約
107
+
108
+ 置き場所・URL・default export・`definePage` の書き方は全ページ共通(`agents/page.md` の
109
+ 「ページファイルの規約」)。ここではドキュメント固有のものだけを挙げます。
110
+
111
+ **MUST**
112
+
113
+ - ファイル名は `<name>.doc.tsx`(`.jsx` も可)。サフィックスは小文字で 1 つだけ。`.doc.mdx` は
114
+ `INVALID_PAGE_VARIANT`、`.DOC.tsx`・二重サフィックスは黙って通常ページになる
115
+ - default export は `<Document>` をルートに返す。フレームワークは包まない
116
+ - ドキュメントの部品は `@squadbase/vantage/doc` から import する
117
+
118
+ **SHOULD**
119
+
120
+ - `PageShell` で包まない・PDF の保存ボタンを自作しない(上の「書き方」)
121
+ - 数値はコードに直接書き、いつ時点の値かを本文に書く
@@ -26,8 +26,8 @@
26
26
  },
27
27
  "dependencies": {
28
28
  "@squadbase/vantage": "^0.5.0",
29
- "react": "^19.2.7",
30
- "react-dom": "^19.2.7"
29
+ "react": "^19.3.1",
30
+ "react-dom": "^19.3.1"
31
31
  }
32
32
  }
33
33
  ```
@@ -71,6 +71,7 @@ URL になる。各ページは**デフォルトエクスポートの React コ
71
71
  | `_404.tsx` | Not Found ページ |
72
72
  | `_error.tsx` | ルートが throw したときのエラーページ |
73
73
  | `monthly-report.slide.tsx` | `/monthly-report`(スライドデッキ。詳しくは `agents/slide.md`) |
74
+ | `june-summary.doc.tsx` | `/june-summary`(ドキュメント。詳しくは `agents/doc.md`) |
74
75
  | `sales-export.csv` | `/sales-export`(詳しくは `agents/csv.md`) |
75
76
  | `data/june.xlsx` | `/data/june`(詳しくは `agents/xlsx.md`) |
76
77
 
@@ -89,6 +90,26 @@ export default function MonthlyAnalysis() {
89
90
  }
90
91
  ```
91
92
 
93
+ ### ページファイルの規約(`.tsx` / `.slide.tsx` / `.doc.tsx` 共通)
94
+
95
+ **MUST**
96
+
97
+ - ページルートの配下に置く。`components/` などの走査対象外のディレクトリに置いたファイルはページに
98
+ ならず、エラーも出ない。`_` 始まりの名前は予約名(`_layout` / `_404` / `_error`)にだけ使う
99
+ (それ以外の `_` 始まりはページにならない。予約名にサフィックスを付けると `INVALID_PAGE_VARIANT`)
100
+ - URL はサフィックスと拡張子を除いたパスで決まる。同じ URL になる別ファイル(`june.tsx` /
101
+ `june.slide.tsx` / `june.doc.tsx` / `june.csv`)を並べない(`ROUTE_CONFLICT`)。テンプレートの
102
+ 未編集の `index.tsx` だけは例外で、`index.slide.tsx` / `index.doc.tsx` が `/` を取れる
103
+ - default export は React の関数コンポーネント(無いと `MISSING_DEFAULT_EXPORT`。関数かどうかは
104
+ 検査されない)
105
+ - `definePage({ ... })` にはオブジェクトリテラルを直接渡し、`title` / `description` / `navLabel` は
106
+ 文字列リテラルで書く。ビルド時に静的抽出されるので、変数・関数呼び出し・spread・shorthand・
107
+ `${}` を含むテンプレート文字列は**エラーにならず黙ってメタなし**になる
108
+
109
+ **SHOULD**
110
+
111
+ - `definePage` に `title` と `navLabel` を書く(ナビの表示名とブラウザのタブ名になる)
112
+
92
113
  ### ナビはルート一覧から組む
93
114
 
94
115
  `useRoutes()` がページルート一覧(スキャン順)を返すので、リンク配列を手で持たない。
@@ -109,7 +130,7 @@ routes.map((r) => (
109
130
  ```
110
131
 
111
132
  `RouteInfo`: `path`(`/sales/:id`)・`to`(`/sales/$id`)・`params`・`dynamic`・`index`・`label`・
112
- `title`・`description`・`navLabel`・`kind`(`"module"` | `"file"`)・`variant`(`"slide"`)。
133
+ `title`・`description`・`navLabel`・`kind`(`"module"` | `"file"`)・`variant`(`"slide"` | `"doc"`)。
113
134
  後ろの 2 つで、ナビをダッシュボード / スライド / データに分けたりアイコンを変えたりできます。
114
135
 
115
136
  ### フィルタ状態は URL に置く
@@ -164,17 +185,41 @@ refetchOnWindowFocus false・networkMode "always")。挙動を変えたいとき
164
185
  ## 組み込み UI / コンポーネントの入口
165
186
 
166
187
  - **プリミティブ**は `@squadbase/vantage/ui` から import する(`Button`・`Loading`・
167
- `ErrorState`・`Empty`・`Select`・`Checkbox` ほか)。
188
+ `ErrorState`・`Empty`・`Select`・`Checkbox`・`RadioGroup`・`Field`・`Combobox`・`Pagination`・
189
+ `Avatar`・`Kbd`・`HoverCard`・`AlertDialog`・`Drawer`・`Toaster` + `toast.add()` ほか)。
168
190
  - **複合パーツ**は `@squadbase/vantage/components` から(`PageShell`・`DashboardCardPreset`・
169
- `DataTablePreset`・`EChart` ほか)。
191
+ `DataTablePreset`・型付きチャート(下の「グラフ」)・`EChart` ほか)。
170
192
  - **どの名前が import 可能か / props の詳細は `vantage docs` で引く。** ガイドとコンポーネント
171
193
  リファレンスはパッケージに同梱されていて、オフラインでも読める(→ `AGENTS.md` の
172
194
  「ドキュメントを引く」)。**名前が分からないとき**はやりたいことで `vantage search` する
173
195
  (→ 同節)。
174
- - **UI は import して使うのが既定。取り出す(eject)必要はない。** `vantage add ui|block` は
175
- ソースを手元にコピーして**改造したいとき専用**のコマンドで、取り出せるのは
176
- `ui: data-table` と `block: sales-overview` の 2 つだけ。それ以外の名前は import 専用で
177
- `add` の対象ではない(未知名で実行すると候補が一覧表示される)。
196
+ - **UI は import して使うのが既定。取り出す(eject)必要はない。** `vantage add ui <name>` は
197
+ ソースを手元にコピーして**改造したいとき専用**のコマンド。`/ui` のプリミティブも
198
+ `/components` の複合パーツも全部取り出せる(名前は kebab-case: `add ui bar-chart`。
199
+ ブロックは `add block sales-overview`。未知名で実行すると候補が一覧表示される)。
200
+
201
+ ### 長い表はページングする(縦スクロール箱を作らない)
202
+
203
+ - 行が多い表は `DataTablePreset`(または `DataTable`)に `enablePagination` を付けて**ページング**する
204
+ (既定は 10 行 / ページ。ページングは既定で無効なので、付け忘れると全行が並ぶ)。素の `<table>` を
205
+ 手書きして全行を流し込まない。
206
+ - カードの中に `max-h-*` + `overflow-y-auto` の**縦スクロール領域を作らない**。ホイールやキー
207
+ (End / Space)がその箱に吸われ、ページ全体がスクロールしなくなる。高さは内容に任せる。
208
+ - 横に広い表の `overflow-x-auto` は構わない。`SheetGrid`(`.csv` / `.xlsx` のビューア)は
209
+ グリッドとして意図した入れ子スクロールなので対象外。
210
+
211
+ ### グラフはまず型付きチャートで描く
212
+
213
+ - 推移は `LineChart` / `AreaChart`、比較は `BarChart`、構成比は `DonutChart`。`data`(行の配列)・
214
+ `index`(x 軸の列)・`categories`(系列の列)を渡すだけで、option は書かない
215
+ (`DonutChart` は `category` / `value`)。
216
+ - 上位 N 件は `BarList`、判定帯や予算消化は `CategoryBar`、達成率は `ProgressCircle`、
217
+ 日ごとの状態は `Tracker`。
218
+ - `EChart` + `EChartsOption` は、二軸・散布図・ヒートマップ・注釈線など型付きチャートの props で
219
+ 表せないときだけ使う。
220
+ - 色は省略してテーマトークンに任せる。指定するなら `"chart-1"`〜`"chart-5"` か
221
+ `"var(--destructive)"` などの CSS 色。hex の直書きや Tailwind クラスは使わない。
222
+ - 数値の書式(`¥`・`%`・桁区切り)は `valueFormatter` に渡す。
178
223
 
179
224
  ### ダークモードは opt-in
180
225
 
@@ -11,7 +11,15 @@
11
11
  `src/monthly-report.slide.tsx` → `/monthly-report`。中身は `<SlideDeck>` を返す普通の React
12
12
  コンポーネントで、`definePage` もナビも通常のページと同じように効きます。
13
13
 
14
+ **ファイル名の決め方:**
15
+
16
+ - **ルート `/` がすでに他のページ(`index.tsx`など)で使われている場合は、スライドのタイトルから slug を作ってファイル名にする。** `index.slide.tsx` は `index.tsx` と同じ `/` に解決するので `ROUTE_CONFLICT` になる。
17
+ - 例: "Label check" というスライド → `src/label-check.slide.tsx` → `/label-check`
18
+ - 例: "Monthly Report" というスライド → `src/monthly-report.slide.tsx` → `/monthly-report`
19
+ - 新規プロジェクトでまだ `/` が空いている場合のみ、`index.slide.tsx` を使ってよい。
20
+
14
21
  ```tsx
22
+ import { definePage } from "@squadbase/vantage"
15
23
  import { Slide, SlideDeck } from "@squadbase/vantage/slide"
16
24
 
17
25
  export const page = definePage({ title: "6月度レビュー", navLabel: "6月度" })
@@ -27,15 +35,72 @@ export default function Deck() {
27
35
 
28
36
  **`<Slide>` は `<SlideDeck>` の直接の子に書く。** `SlideDeck` は直下の `<Slide>` 要素だけを数えるので、
29
37
  `<Slide>` を自作コンポーネント(`<Slide1 />` など)や Fragment で包むと 1 枚も数えられず「1 / 0」に
30
- なります(`{items.map((x) => <Slide key={x.id}>…</Slide>)}` のような配列は可)。共通の部品は
31
- `<Slide>` の**中**に置くコンポーネントとして切り出します(`<Slide><CoverPage /></Slide>`)。
38
+ なります(`{items.map((x) => <Slide key={x.id}>…</Slide>)}` のような配列はファイル形式としては可。
39
+ 1 枚の中で視覚要素を `map` で量産しない方針は `vantage-slide` skill の「繰り返す要素は `map` ではなく
40
+ コンポーネント」)。共通の部品は `<Slide>` の**中**に置くコンポーネントとして切り出します
41
+ (`<Slide><CoverPage /></Slide>`)。
32
42
 
33
43
  1920×1080 の固定キャンバスに絶対 px で書き、画面サイズに合わせて縮小されます。キー / クリックで
34
44
  送れ、左のスライド一覧(サムネイル列)は `L` で開閉、`F` で全画面、ツールバーから pptx を
35
45
  書き出せます。**書き方の作法は同梱 Skill の
36
46
  `vantage-slide`** にあります(キャンバスの縦方向の予算、段階表示、トランジション、モーフ、
37
- pptx が壊れる条件)。
47
+ pptx が壊れる条件、説明と図表のデータ時点の揃え方)。
48
+
49
+ **分析を共有するデッキでは、本文・数値・図表を同じ対象期間と同じ取得時点の結果に揃え、その期間と
50
+ 時点を短く表示する。** 説明文を固定したまま図表だけが最新値へ変わる構成にしない(ライブ更新を
51
+ 意図するなら本文も同じ取得結果から導く)。同一時点の結果を保持できない場合は、スナップショットとして
52
+ 保存できたとは報告せず、必要な保持の仕組みと保証できない範囲を伝える。
38
53
 
39
54
  `.slide` を付けられるのはルートになるページモジュールだけで、`_layout.slide.tsx` などは
40
55
  `INVALID_PAGE_VARIANT` エラーになります。`june.slide.tsx` と `june.tsx` は同じ URL に解決するので
41
56
  `ROUTE_CONFLICT` です。
57
+
58
+ ## まず block を探す
59
+
60
+ 1 枚分の中身は、手で組む前に `@squadbase/vantage/slide` の block から探します(`<Slide>` の**中**に
61
+ 置く。ルートは 100% で、`<Slide>` 自体は持たない)。props は `vantage docs <name>`(例:
62
+ `vantage docs slide-kpi-hero`)で引く。
63
+
64
+ | block | 用途 |
65
+ | --- | --- |
66
+ | `SlideCover` | 表紙(タイトル・サブタイトル・期間) |
67
+ | `SlideExecSummary` | 結論を先に述べるエグゼクティブサマリー |
68
+ | `SlideKpiHero` | 主要な KPI 1 つを大きく見せる |
69
+ | `SlideKpiGrid` | 複数の KPI を並べる |
70
+ | `SlideChartInsight` | チャート 1 つと、そこから読み取れること |
71
+ | `SlideScorecardTable` | 指標と目標・達成度を表にしたスコアカード |
72
+ | `SlideNextActions` | 次のアクション(担当・期限つき) |
73
+
74
+ ```tsx
75
+ import { Slide, SlideDeck, SlideCover, SlideExecSummary } from "@squadbase/vantage/slide"
76
+ // <SlideDeck><Slide><SlideCover … /></Slide><Slide><SlideExecSummary … /></Slide></SlideDeck>
77
+ ```
78
+
79
+ **props の渡し方は block 間で共通。** 数値は `value: number | null` と `format`(整形は block がする。表示を上書きするときだけ `display`。`null` は「—」)。前期比などは `delta: { value, format? }` と `comparisonLabel`(例 `"前年同期比"`)、良し悪しは指標ごとの `betterWhen`(`"up"` が既定、コストなど下がるほど良いものは `"down"`。向きは block が符号から出す)。目標は `target: number`。出典は `source`(文字列)、時点は `asOf` に**日付だけ**(例 `"2026-09-30"`。「時点」は block が付けるので書かない)。時系列は、単一系列なら `{ x, y }[]`(kpi-hero・scorecard の `trend`)、複数系列なら `{ categories, series }`(chart-insight の `chart`)。
80
+
81
+ block が合わない**1 枚だけ**を手で書く(デッキ全体を手書きに切り替えない)。import 元は
82
+ `@squadbase/vantage/slide` のままで、block のための新しい import 元はありません。
83
+
84
+ ## ファイル形式の規約
85
+
86
+ 置き場所・URL・default export・`definePage` の書き方は全ページ共通(`agents/page.md` の
87
+ 「ページファイルの規約」)。ここではスライド固有のものだけを挙げます。**中身の値(キャンバス・
88
+ セーフエリア・グリッド・文字サイズ・余白)は `vantage-slide` skill を参照。**
89
+
90
+ **MUST**(破ると黙って壊れるものが多い。`vantage check` が拾うのは名前の誤りだけ)
91
+
92
+ - ファイル名は `<name>.slide.tsx`(`.jsx` も可)。サフィックスは小文字で 1 つだけ。`.slide.ts` は
93
+ `INVALID_PAGE_VARIANT`、`.SLIDE.tsx`・二重サフィックス・`.slide.test.tsx` は黙って通常ページになる
94
+ - default export は `<SlideDeck>` をルートに返す。フレームワークは包まない
95
+ - `<Slide>` は `<SlideDeck>` の直接の子(配列は可。Fragment・自作コンポーネントで包まない)
96
+ - `<Step>` は `<Steps>` の直接の子(包むと常に表示される)
97
+ - スライドの部品は `@squadbase/vantage/slide` から import する
98
+
99
+ **SHOULD**
100
+
101
+ - 1 ファイル = 1 デッキ。ヘルパーコンポーネント・定数も同じ `.slide.tsx` に書く
102
+ - 各 `<Slide>` のルート要素は `width: "100%"; height: "100%"` でキャンバスを埋める
103
+ - canvas に描くチャート(`EChart`)は `data-waitfor="canvas"` で包む(無いと pptx でそのスライドが白紙になりうる)
104
+ - pptx に出る中身をアプリの Context(router / query / テーマ)に依存させない
105
+ - `MorphElement` の `id` はページ内で一意にし、入れ子にしない。遷移先の `<Slide>` で `transition.morph` を有効にする
106
+ - pptx 用などの依存を追加しない(html-to-image / fflate は自動で入る)
@@ -28,6 +28,7 @@
28
28
  - **複数シートに対応**しています。シートのタブは下端に並び、切り替えて閲覧できます。
29
29
  - 数式・グラフ・セル書式は再現されません(値として読めれば十分、という設計)。ブラウザでパースするので
30
30
  25MB を超えるファイルはそのページにエラーが出ます —— 大きいデータは `server/api/` から配って
31
- `DataTable` で描いてください
31
+ `DataTable` で描いてください。20 万行を超えると先頭
32
+ 20 万行だけが表示されます(残りはダウンロードして見る)
32
33
  - **ビューアの無い拡張子(`.xls`・`.ods` など)はルートになりません。** `vantage check` の
33
34
  `UNSUPPORTED_PAGE_FILE` 警告が知らせます