@squadbase/vantage 0.6.1 → 0.6.2-dev1.0010f67

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 (346) 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-U7GO26HR.js} +9 -9
  4. package/dist/{build-O5TVNH4E.js.map → build-U7GO26HR.js.map} +1 -1
  5. package/dist/{check-WFBEDHDR.js → check-MRVAIHG5.js} +7 -7
  6. package/dist/{check-WFBEDHDR.js.map → check-MRVAIHG5.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-3RJEOP3J.js +174 -0
  10. package/dist/chunk-3RJEOP3J.js.map +1 -0
  11. package/dist/chunk-77CISBMG.js +7581 -0
  12. package/dist/chunk-77CISBMG.js.map +1 -0
  13. package/dist/{chunk-QDZA5JSL.js → chunk-AABMKHEU.js} +4 -4
  14. package/dist/{chunk-QDZA5JSL.js.map → chunk-AABMKHEU.js.map} +1 -1
  15. package/dist/{chunk-PVTHHV7X.js → chunk-ANZLVSEP.js} +28 -7
  16. package/dist/chunk-ANZLVSEP.js.map +1 -0
  17. package/dist/chunk-CKWPK4RO.js +50 -0
  18. package/dist/chunk-CKWPK4RO.js.map +1 -0
  19. package/dist/chunk-EG4PX726.js +678 -0
  20. package/dist/chunk-EG4PX726.js.map +1 -0
  21. package/dist/{chunk-3G43C6OL.js → chunk-GNXCX4WE.js} +46 -3
  22. package/dist/chunk-GNXCX4WE.js.map +1 -0
  23. package/dist/chunk-NZ5QIIG4.js +74 -0
  24. package/dist/chunk-NZ5QIIG4.js.map +1 -0
  25. package/dist/{chunk-BCE22JSM.js → chunk-PJ4SPXHS.js} +52 -16
  26. package/dist/chunk-PJ4SPXHS.js.map +1 -0
  27. package/dist/{chunk-MXI3PZFT.js → chunk-QNOX7WLZ.js} +257 -210
  28. package/dist/chunk-QNOX7WLZ.js.map +1 -0
  29. package/dist/{chunk-ZVANIULZ.js → chunk-RNTDBX6S.js} +4 -4
  30. package/dist/{chunk-ZVANIULZ.js.map → chunk-RNTDBX6S.js.map} +1 -1
  31. package/dist/chunk-ROHNXP7J.js +123 -0
  32. package/dist/chunk-ROHNXP7J.js.map +1 -0
  33. package/dist/chunk-S5MDTHH7.js +466 -0
  34. package/dist/chunk-S5MDTHH7.js.map +1 -0
  35. package/dist/chunk-SDJTTMLK.js +1877 -0
  36. package/dist/chunk-SDJTTMLK.js.map +1 -0
  37. package/dist/{chunk-EP6JHXSR.js → chunk-SHZM3EXB.js} +68 -12
  38. package/dist/chunk-SHZM3EXB.js.map +1 -0
  39. package/dist/chunk-TRMHNMMZ.js +61 -0
  40. package/dist/chunk-TRMHNMMZ.js.map +1 -0
  41. package/dist/{chunk-A2UUGASH.js → chunk-U736PVHY.js} +2 -2
  42. package/dist/chunk-U736PVHY.js.map +1 -0
  43. package/dist/{chunk-JGRMRXXZ.js → chunk-UWSQUHX6.js} +4 -99
  44. package/dist/chunk-UWSQUHX6.js.map +1 -0
  45. package/dist/cli.js +15 -11
  46. package/dist/cli.js.map +1 -1
  47. package/dist/client/index.d.ts +34 -3
  48. package/dist/client/index.js +211 -12
  49. package/dist/client/index.js.map +1 -1
  50. package/dist/components/index.d.ts +1768 -30
  51. package/dist/components/index.js +7 -3
  52. package/dist/delta-text-CbrOaW83.d.ts +17 -0
  53. package/dist/{dev-NZRLOQCL.js → dev-O42JFQ64.js} +24 -13
  54. package/dist/dev-O42JFQ64.js.map +1 -0
  55. package/dist/doc/index.d.ts +219 -2
  56. package/dist/doc/index.js +525 -11
  57. package/dist/doc/index.js.map +1 -1
  58. package/dist/{docs-ZGDJUHJI.js → docs-JVP4RPKT.js} +3 -3
  59. package/dist/{docs-ZGDJUHJI.js.map → docs-JVP4RPKT.js.map} +1 -1
  60. package/dist/{doctor-VFKEMR54.js → doctor-YD3XAAOT.js} +8 -8
  61. package/dist/doctor-YD3XAAOT.js.map +1 -0
  62. package/dist/format-DihQkL1N.d.ts +249 -0
  63. package/dist/markdown/index.js +1 -1
  64. package/dist/markdown/index.js.map +1 -1
  65. package/dist/{preview-QDCIVVSR.js → preview-T6CLSQVX.js} +12 -4
  66. package/dist/preview-T6CLSQVX.js.map +1 -0
  67. package/dist/query/index.d.ts +0 -11
  68. package/dist/query/index.js +2 -2
  69. package/dist/{routes-RHP5FVGD.js → routes-PVKNT777.js} +6 -6
  70. package/dist/{routes-RHP5FVGD.js.map → routes-PVKNT777.js.map} +1 -1
  71. package/dist/{search-RFBELGY7.js → search-5LC4XPB5.js} +3 -3
  72. package/dist/{search-RFBELGY7.js.map → search-5LC4XPB5.js.map} +1 -1
  73. package/dist/slide/index.d.ts +272 -1
  74. package/dist/slide/index.js +1086 -19
  75. package/dist/slide/index.js.map +1 -1
  76. package/dist/table/index.js +14 -9
  77. package/dist/table/index.js.map +1 -1
  78. package/dist/ui/index.d.ts +148 -12
  79. package/dist/ui/index.js +1340 -87
  80. package/dist/ui/index.js.map +1 -1
  81. package/dist/{upgrade-GF2P67M6.js → upgrade-6DT7ADRP.js} +7 -7
  82. package/dist/{upgrade-GF2P67M6.js.map → upgrade-6DT7ADRP.js.map} +1 -1
  83. package/dist/vite/index.d.ts +10 -0
  84. package/dist/vite/index.js +4 -4
  85. package/docs/en/agent-skills.md +1 -1
  86. package/docs/en/changelog.md +26 -0
  87. package/docs/en/cli-reference.md +30 -0
  88. package/docs/en/components.md +42 -17
  89. package/docs/en/doc/delta-text.md +40 -0
  90. package/docs/en/doc/doc-action-items.md +49 -0
  91. package/docs/en/doc/doc-callout.md +38 -0
  92. package/docs/en/doc/doc-data-table.md +60 -0
  93. package/docs/en/doc/doc-executive-summary.md +64 -0
  94. package/docs/en/doc/doc-figure.md +56 -0
  95. package/docs/en/doc/doc-key-findings.md +61 -0
  96. package/docs/en/doc/doc-kpi-scorecard.md +80 -0
  97. package/docs/en/doc/doc-notes-and-sources.md +43 -0
  98. package/docs/en/doc/doc-report-header.md +46 -0
  99. package/docs/en/pages-and-metadata.md +15 -0
  100. package/docs/en/parts/area-chart.md +99 -0
  101. package/docs/en/parts/bar-chart.md +91 -0
  102. package/docs/en/parts/bar-list.md +50 -0
  103. package/docs/en/parts/category-bar.md +37 -0
  104. package/docs/en/parts/chart-frame.md +39 -0
  105. package/docs/en/parts/data-table.md +22 -0
  106. package/docs/en/parts/delta.md +51 -0
  107. package/docs/en/parts/donut-chart.md +72 -0
  108. package/docs/en/parts/format.md +43 -0
  109. package/docs/en/parts/funnel-steps.md +2 -1
  110. package/docs/en/parts/heatmap.md +53 -0
  111. package/docs/en/parts/kpi-card.md +58 -0
  112. package/docs/en/parts/legend.md +35 -0
  113. package/docs/en/parts/line-chart.md +94 -0
  114. package/docs/en/parts/metric-value.md +3 -2
  115. package/docs/en/parts/page-shell.md +1 -1
  116. package/docs/en/parts/progress-circle.md +33 -0
  117. package/docs/en/parts/sample-data.md +39 -0
  118. package/docs/en/parts/scatter-chart.md +56 -0
  119. package/docs/en/parts/sparkline.md +1 -1
  120. package/docs/en/parts/tracker.md +36 -0
  121. package/docs/en/parts/trend-indicator.md +17 -1
  122. package/docs/en/parts/updated-at.md +30 -0
  123. package/docs/en/parts/waterfall-chart.md +56 -0
  124. package/docs/en/routing.md +4 -2
  125. package/docs/en/slide/slide-chart-full.md +48 -0
  126. package/docs/en/slide/slide-chart-insight.md +52 -0
  127. package/docs/en/slide/slide-columns.md +46 -0
  128. package/docs/en/slide/slide-comparison.md +68 -0
  129. package/docs/en/slide/slide-cover.md +39 -0
  130. package/docs/en/slide/slide-exec-summary.md +47 -0
  131. package/docs/en/slide/slide-heading.md +38 -0
  132. package/docs/en/slide/slide-kpi-grid.md +55 -0
  133. package/docs/en/slide/slide-kpi-hero.md +58 -0
  134. package/docs/en/slide/slide-next-actions.md +49 -0
  135. package/docs/en/slide/slide-scorecard-table.md +54 -0
  136. package/docs/en/slide/slide-section.md +44 -0
  137. package/docs/en/slide/slide-source-line.md +34 -0
  138. package/docs/en/ui/alert-dialog.md +42 -0
  139. package/docs/en/ui/avatar.md +31 -0
  140. package/docs/en/ui/combobox.md +74 -0
  141. package/docs/en/ui/drawer.md +41 -0
  142. package/docs/en/ui/empty.md +1 -1
  143. package/docs/en/ui/error-state.md +4 -3
  144. package/docs/en/ui/field.md +42 -0
  145. package/docs/en/ui/hover-card.md +21 -0
  146. package/docs/en/ui/kbd.md +17 -0
  147. package/docs/en/ui/loading.md +1 -1
  148. package/docs/en/ui/pagination.md +36 -0
  149. package/docs/en/ui/radio-group.md +21 -0
  150. package/docs/en/ui/toast.md +44 -0
  151. package/docs/en/ui/toggle-group.md +4 -3
  152. package/docs/en/ui-and-theming.md +1 -1
  153. package/docs/index.json +1184 -114
  154. package/docs/ja/agent-skills.md +1 -1
  155. package/docs/ja/changelog.md +57 -0
  156. package/docs/ja/cli-reference.md +29 -0
  157. package/docs/ja/components.md +68 -101
  158. package/docs/ja/doc/delta-text.md +40 -0
  159. package/docs/ja/doc/doc-action-items.md +49 -0
  160. package/docs/ja/doc/doc-callout.md +38 -0
  161. package/docs/ja/doc/doc-data-table.md +60 -0
  162. package/docs/ja/doc/doc-executive-summary.md +64 -0
  163. package/docs/ja/doc/doc-figure.md +56 -0
  164. package/docs/ja/doc/doc-key-findings.md +61 -0
  165. package/docs/ja/doc/doc-kpi-scorecard.md +80 -0
  166. package/docs/ja/doc/doc-notes-and-sources.md +43 -0
  167. package/docs/ja/doc/doc-report-header.md +46 -0
  168. package/docs/ja/page-types/csv.md +83 -0
  169. package/docs/ja/page-types/doc.md +83 -0
  170. package/docs/ja/page-types/excel.md +82 -0
  171. package/docs/ja/page-types/slide.md +133 -0
  172. package/docs/ja/page-types.md +47 -0
  173. package/docs/ja/pages-and-metadata.md +15 -0
  174. package/docs/ja/parts/area-chart.md +85 -0
  175. package/docs/ja/parts/bar-chart.md +95 -0
  176. package/docs/ja/parts/bar-list.md +58 -0
  177. package/docs/ja/parts/category-bar.md +36 -0
  178. package/docs/ja/parts/chart-frame.md +36 -0
  179. package/docs/ja/parts/data-table.md +22 -0
  180. package/docs/ja/parts/delta.md +51 -0
  181. package/docs/ja/parts/donut-chart.md +66 -0
  182. package/docs/ja/parts/echart.md +3 -0
  183. package/docs/ja/parts/format.md +44 -0
  184. package/docs/ja/parts/funnel-steps.md +27 -8
  185. package/docs/ja/parts/heatmap.md +45 -0
  186. package/docs/ja/parts/kpi-card.md +56 -0
  187. package/docs/ja/parts/legend.md +36 -0
  188. package/docs/ja/parts/line-chart.md +84 -0
  189. package/docs/ja/parts/metric-value.md +3 -2
  190. package/docs/ja/parts/page-shell.md +1 -1
  191. package/docs/ja/parts/progress-circle.md +34 -0
  192. package/docs/ja/parts/sample-data.md +61 -0
  193. package/docs/ja/parts/scatter-chart.md +69 -0
  194. package/docs/ja/parts/sparkline.md +2 -2
  195. package/docs/ja/parts/tracker.md +32 -0
  196. package/docs/ja/parts/trend-indicator.md +17 -1
  197. package/docs/ja/parts/updated-at.md +27 -0
  198. package/docs/ja/parts/waterfall-chart.md +61 -0
  199. package/docs/ja/routing.md +8 -84
  200. package/docs/ja/slide/slide-chart-full.md +48 -0
  201. package/docs/ja/slide/slide-chart-insight.md +52 -0
  202. package/docs/ja/slide/slide-columns.md +46 -0
  203. package/docs/ja/slide/slide-comparison.md +68 -0
  204. package/docs/ja/slide/slide-cover.md +39 -0
  205. package/docs/ja/slide/slide-exec-summary.md +47 -0
  206. package/docs/ja/slide/slide-heading.md +38 -0
  207. package/docs/ja/slide/slide-kpi-grid.md +55 -0
  208. package/docs/ja/slide/slide-kpi-hero.md +58 -0
  209. package/docs/ja/slide/slide-next-actions.md +49 -0
  210. package/docs/ja/slide/slide-scorecard-table.md +54 -0
  211. package/docs/ja/slide/slide-section.md +44 -0
  212. package/docs/ja/slide/slide-source-line.md +34 -0
  213. package/docs/ja/ui/alert-dialog.md +41 -0
  214. package/docs/ja/ui/avatar.md +31 -0
  215. package/docs/ja/ui/combobox.md +74 -0
  216. package/docs/ja/ui/drawer.md +41 -0
  217. package/docs/ja/ui/empty.md +1 -1
  218. package/docs/ja/ui/error-state.md +4 -3
  219. package/docs/ja/ui/field.md +42 -0
  220. package/docs/ja/ui/hover-card.md +21 -0
  221. package/docs/ja/ui/kbd.md +16 -0
  222. package/docs/ja/ui/loading.md +1 -1
  223. package/docs/ja/ui/pagination.md +36 -0
  224. package/docs/ja/ui/radio-group.md +21 -0
  225. package/docs/ja/ui/toast.md +46 -0
  226. package/docs/ja/ui/toggle-group.md +4 -3
  227. package/docs/ja/ui-and-theming.md +14 -7
  228. package/package.json +43 -29
  229. package/registry/ui/accordion.tsx +76 -0
  230. package/registry/ui/alert-dialog.tsx +189 -0
  231. package/registry/ui/alert.tsx +80 -0
  232. package/registry/ui/app-shell.tsx +424 -0
  233. package/registry/ui/area-chart.tsx +3960 -0
  234. package/registry/ui/attention-list.tsx +465 -0
  235. package/registry/ui/avatar.tsx +110 -0
  236. package/registry/ui/badge.tsx +56 -0
  237. package/registry/ui/bar-chart.tsx +3954 -0
  238. package/registry/ui/bar-list.tsx +3998 -0
  239. package/registry/ui/box-plot-chart.tsx +4214 -0
  240. package/registry/ui/breadcrumb.tsx +128 -0
  241. package/registry/ui/button.tsx +62 -0
  242. package/registry/ui/calendar.tsx +223 -0
  243. package/registry/ui/card.tsx +107 -0
  244. package/registry/ui/category-bar.tsx +1498 -0
  245. package/registry/ui/chart-frame.tsx +1604 -0
  246. package/registry/ui/checkbox.tsx +30 -0
  247. package/registry/ui/collapsible.tsx +23 -0
  248. package/registry/ui/combobox.tsx +310 -0
  249. package/registry/ui/command.tsx +198 -0
  250. package/registry/ui/dashboard-card.tsx +217 -0
  251. package/registry/ui/data-table.tsx +896 -157
  252. package/registry/ui/date-range-picker.tsx +544 -0
  253. package/registry/ui/delta.tsx +350 -0
  254. package/registry/ui/dialog.tsx +161 -0
  255. package/registry/ui/donut-chart.tsx +4006 -0
  256. package/registry/ui/drawer.tsx +229 -0
  257. package/registry/ui/dropdown-menu.tsx +274 -0
  258. package/registry/ui/echart.tsx +1178 -0
  259. package/registry/ui/field.tsx +240 -0
  260. package/registry/ui/filter-bar.tsx +551 -0
  261. package/registry/ui/funnel-steps.tsx +3843 -0
  262. package/registry/ui/heatmap.tsx +2027 -0
  263. package/registry/ui/histogram-chart.tsx +4284 -0
  264. package/registry/ui/hover-card.tsx +52 -0
  265. package/registry/ui/input-group.tsx +160 -0
  266. package/registry/ui/input.tsx +24 -0
  267. package/registry/ui/kbd.tsx +30 -0
  268. package/registry/ui/kpi-card.tsx +905 -0
  269. package/registry/ui/label.tsx +22 -0
  270. package/registry/ui/legend.tsx +3817 -0
  271. package/registry/ui/line-chart.tsx +3958 -0
  272. package/registry/ui/metric-value.tsx +62 -0
  273. package/registry/ui/multi-select.tsx +382 -0
  274. package/registry/ui/page-shell.tsx +420 -0
  275. package/registry/ui/pagination.tsx +140 -0
  276. package/registry/ui/paired-chart.tsx +4086 -0
  277. package/registry/ui/placeholder.tsx +36 -0
  278. package/registry/ui/popover.tsx +92 -0
  279. package/registry/ui/progress-circle.tsx +1033 -0
  280. package/registry/ui/progress.tsx +85 -0
  281. package/registry/ui/radio-group.tsx +39 -0
  282. package/registry/ui/sample-data.tsx +230 -0
  283. package/registry/ui/scatter-chart.tsx +4503 -0
  284. package/registry/ui/scroll-area.tsx +56 -0
  285. package/registry/ui/searchable-select.tsx +352 -0
  286. package/registry/ui/section-header.tsx +43 -0
  287. package/registry/ui/segmented-control.tsx +76 -0
  288. package/registry/ui/select.tsx +255 -0
  289. package/registry/ui/separator.tsx +27 -0
  290. package/registry/ui/sheet.tsx +139 -0
  291. package/registry/ui/sidebar.tsx +725 -0
  292. package/registry/ui/skeleton.tsx +17 -0
  293. package/registry/ui/slider.tsx +56 -0
  294. package/registry/ui/sparkline.tsx +230 -0
  295. package/registry/ui/spinner.tsx +14 -0
  296. package/registry/ui/states.tsx +247 -0
  297. package/registry/ui/status-badge.tsx +286 -0
  298. package/registry/ui/switch.tsx +34 -0
  299. package/registry/ui/table.tsx +118 -0
  300. package/registry/ui/tabs.tsx +84 -0
  301. package/registry/ui/textarea.tsx +22 -0
  302. package/registry/ui/toast.tsx +250 -0
  303. package/registry/ui/toggle-group.tsx +91 -0
  304. package/registry/ui/toggle.tsx +47 -0
  305. package/registry/ui/tooltip.tsx +72 -0
  306. package/registry/ui/tracker.tsx +1015 -0
  307. package/registry/ui/trend-indicator.tsx +217 -0
  308. package/registry/ui/updated-at.tsx +276 -0
  309. package/registry/ui/waterfall-chart.tsx +4561 -0
  310. package/skills/vantage-add-feature/SKILL.md +9 -7
  311. package/skills/vantage-design/SKILL.md +62 -52
  312. package/skills/vantage-design/references/extract.md +26 -27
  313. package/skills/vantage-design/references/format.md +12 -172
  314. package/skills/vantage-design/references/presets.md +50 -110
  315. package/skills/vantage-pitfalls/SKILL.md +10 -1
  316. package/skills/vantage-slide/SKILL.md +71 -36
  317. package/templates/AGENTS.md +53 -16
  318. package/templates/agents/api.md +29 -0
  319. package/templates/agents/csv.md +2 -1
  320. package/templates/agents/doc.md +54 -3
  321. package/templates/agents/page.md +55 -10
  322. package/templates/agents/slide.md +90 -4
  323. package/templates/agents/xlsx.md +2 -1
  324. package/theme.css +287 -128
  325. package/dist/add-EISGSZAH.js +0 -6
  326. package/dist/add-EISGSZAH.js.map +0 -1
  327. package/dist/chunk-3G43C6OL.js.map +0 -1
  328. package/dist/chunk-5ZOP4SQR.js +0 -47
  329. package/dist/chunk-5ZOP4SQR.js.map +0 -1
  330. package/dist/chunk-A2UUGASH.js.map +0 -1
  331. package/dist/chunk-BCE22JSM.js.map +0 -1
  332. package/dist/chunk-DTDVSFRY.js +0 -29
  333. package/dist/chunk-DTDVSFRY.js.map +0 -1
  334. package/dist/chunk-EP6JHXSR.js.map +0 -1
  335. package/dist/chunk-JGRMRXXZ.js.map +0 -1
  336. package/dist/chunk-KLEIVDUV.js +0 -165
  337. package/dist/chunk-KLEIVDUV.js.map +0 -1
  338. package/dist/chunk-MXI3PZFT.js.map +0 -1
  339. package/dist/chunk-PLST5Q7T.js +0 -2221
  340. package/dist/chunk-PLST5Q7T.js.map +0 -1
  341. package/dist/chunk-PVTHHV7X.js.map +0 -1
  342. package/dist/chunk-T3FLAGI6.js +0 -316
  343. package/dist/chunk-T3FLAGI6.js.map +0 -1
  344. package/dist/dev-NZRLOQCL.js.map +0 -1
  345. package/dist/doctor-VFKEMR54.js.map +0 -1
  346. package/dist/preview-QDCIVVSR.js.map +0 -1
@@ -1,5 +1,11 @@
1
+ import { DeltaText } from '../chunk-TRMHNMMZ.js';
2
+ export { DeltaText } from '../chunk-TRMHNMMZ.js';
1
3
  import { useSearchState } from '../chunk-ZO62C6T4.js';
2
4
  import '../chunk-6S4BAIGV.js';
5
+ import { EChart } from '../chunk-EG4PX726.js';
6
+ import { formatValue, EMPTY_VALUE } from '../chunk-3RJEOP3J.js';
7
+ import { uiLanguage, useLocale } from '../chunk-ROHNXP7J.js';
8
+ import '../chunk-U736PVHY.js';
3
9
  import { createContext, useRef, useState, useLayoutEffect, useContext, createElement, Children, isValidElement, useCallback, cloneElement, useMemo, useEffect } from 'react';
4
10
  import { jsx, Fragment, jsxs } from 'react/jsx-runtime';
5
11
  import { createRoot } from 'react-dom/client';
@@ -58,6 +64,11 @@ function SlideCanvas({ children, scale, themeVars }) {
58
64
  transformOrigin: "top left",
59
65
  fontFamily: "var(--slide-font-body)",
60
66
  fontSize: "var(--slide-size-body)",
67
+ // Phrase-aware Japanese line breaks for every block. Browsers without
68
+ // `auto-phrase` drop the declaration and keep the strict line-break rules.
69
+ wordBreak: "auto-phrase",
70
+ lineBreak: "strict",
71
+ overflowWrap: "break-word",
61
72
  ...themeVars
62
73
  },
63
74
  children
@@ -217,8 +228,13 @@ async function exportDeckAsPptx({
217
228
  background: "var(--slide-bg)",
218
229
  color: "var(--slide-fg)",
219
230
  fontFamily: "var(--slide-font-body)",
220
- fontSize: "var(--slide-size-body)"
231
+ fontSize: "var(--slide-size-body)",
232
+ // Same phrase-aware line breaking as the on-screen canvas (see canvas.tsx).
233
+ wordBreak: "auto-phrase",
234
+ lineBreak: "strict",
235
+ overflowWrap: "break-word"
221
236
  });
237
+ if (document.documentElement.lang) host.lang = document.documentElement.lang;
222
238
  if (themeVars) {
223
239
  for (const [key, value] of Object.entries(themeVars)) {
224
240
  host.style.setProperty(key, String(value));
@@ -380,6 +396,41 @@ function isForwardKey(e) {
380
396
  function isBackwardKey(e) {
381
397
  return e.key === "ArrowLeft" || e.key === "ArrowUp" || e.key === "PageUp";
382
398
  }
399
+
400
+ // src/slide/messages.ts
401
+ var MESSAGES_JA = {
402
+ previousSlide: "\u524D\u306E\u30B9\u30E9\u30A4\u30C9",
403
+ nextSlide: "\u6B21\u306E\u30B9\u30E9\u30A4\u30C9",
404
+ slideList: "\u30B9\u30E9\u30A4\u30C9\u4E00\u89A7",
405
+ closeSlideList: "\u30B9\u30E9\u30A4\u30C9\u4E00\u89A7\u3092\u9589\u3058\u308B (L)",
406
+ openSlideList: "\u30B9\u30E9\u30A4\u30C9\u4E00\u89A7\u3092\u958B\u304F (L)",
407
+ fullscreen: "\u5168\u753B\u9762\u8868\u793A (F)",
408
+ exitFullscreen: "\u5168\u753B\u9762\u8868\u793A\u3092\u7D42\u4E86 (F)",
409
+ exportToPowerPoint: "PowerPoint \u3068\u3057\u3066\u66F8\u304D\u51FA\u3059",
410
+ slideNumber: (n) => `\u30B9\u30E9\u30A4\u30C9 ${n}`
411
+ };
412
+ var MESSAGES_EN = {
413
+ previousSlide: "Previous slide",
414
+ nextSlide: "Next slide",
415
+ slideList: "Slide list",
416
+ closeSlideList: "Close slide list (L)",
417
+ openSlideList: "Open slide list (L)",
418
+ fullscreen: "Fullscreen (F)",
419
+ exitFullscreen: "Exit fullscreen (F)",
420
+ exportToPowerPoint: "Export to PowerPoint",
421
+ slideNumber: (n) => `Slide ${n}`
422
+ };
423
+ function detectLanguage() {
424
+ if (typeof document === "undefined") return "ja";
425
+ const lang = document.documentElement.lang;
426
+ if (!lang) return "ja";
427
+ if (lang.toLowerCase().startsWith("en")) return "en";
428
+ return "ja";
429
+ }
430
+ function getSlideMessages() {
431
+ const lang = detectLanguage();
432
+ return lang === "en" ? MESSAGES_EN : MESSAGES_JA;
433
+ }
383
434
  var THUMB_WIDTH = 176;
384
435
  var THUMB_HEIGHT = Math.round(THUMB_WIDTH * CANVAS_HEIGHT / CANVAS_WIDTH);
385
436
  var NUMBER_COLUMN = 20;
@@ -400,6 +451,7 @@ var ITEM_BUTTON = {
400
451
  };
401
452
  function SlideRail({ slides, index, onSelect, themeVars }) {
402
453
  const listRef = useRef(null);
454
+ const messages = useMemo(() => getSlideMessages(), []);
403
455
  useEffect(() => {
404
456
  const item = listRef.current?.children[index];
405
457
  item?.scrollIntoView({ block: "nearest" });
@@ -408,7 +460,7 @@ function SlideRail({ slides, index, onSelect, themeVars }) {
408
460
  "div",
409
461
  {
410
462
  "data-slide-chrome": "",
411
- "aria-label": "\u30B9\u30E9\u30A4\u30C9\u4E00\u89A7",
463
+ "aria-label": messages.slideList,
412
464
  style: {
413
465
  flex: "0 0 auto",
414
466
  width: RAIL_WIDTH,
@@ -418,7 +470,7 @@ function SlideRail({ slides, index, onSelect, themeVars }) {
418
470
  background: "color-mix(in oklab, var(--slide-fg) 6%, var(--slide-bg))",
419
471
  color: "var(--slide-fg)",
420
472
  borderRight: "1px solid color-mix(in oklab, var(--slide-fg) 14%, transparent)",
421
- fontFamily: 'system-ui, -apple-system, "Hiragino Kaku Gothic ProN", "Yu Gothic", Meiryo, sans-serif',
473
+ fontFamily: '-apple-system, BlinkMacSystemFont, "Segoe UI", "Hiragino Kaku Gothic ProN", "Yu Gothic", Meiryo, system-ui, sans-serif',
422
474
  userSelect: "none",
423
475
  // An embedded deck does not put the theme on its root, so the rail
424
476
  // carries it too rather than reading whatever cascaded in.
@@ -452,7 +504,7 @@ function SlideRail({ slides, index, onSelect, themeVars }) {
452
504
  style: ITEM_BUTTON,
453
505
  onClick: () => onSelect(i),
454
506
  "aria-current": active ? "true" : void 0,
455
- "aria-label": `\u30B9\u30E9\u30A4\u30C9 ${i + 1}`,
507
+ "aria-label": messages.slideNumber(i + 1),
456
508
  children: [
457
509
  /* @__PURE__ */ jsx(
458
510
  "span",
@@ -523,6 +575,7 @@ function SlideToolbar({
523
575
  onPrev,
524
576
  onNext,
525
577
  onFullscreen,
578
+ canFullscreen,
526
579
  onExport,
527
580
  exportProgress,
528
581
  railOpen,
@@ -531,6 +584,7 @@ function SlideToolbar({
531
584
  }) {
532
585
  const [hovered, setHovered] = useState(false);
533
586
  const busy = exportProgress !== null && exportProgress.phase !== "done";
587
+ const messages = useMemo(() => getSlideMessages(), []);
534
588
  return /* @__PURE__ */ jsxs(
535
589
  "div",
536
590
  {
@@ -552,40 +606,40 @@ function SlideToolbar({
552
606
  backdropFilter: "blur(8px)",
553
607
  opacity: hovered || busy ? 1 : 0.25,
554
608
  transition: "opacity 150ms ease",
555
- fontFamily: 'system-ui, -apple-system, "Hiragino Kaku Gothic ProN", "Yu Gothic", Meiryo, sans-serif',
609
+ fontFamily: '-apple-system, BlinkMacSystemFont, "Segoe UI", "Hiragino Kaku Gothic ProN", "Yu Gothic", Meiryo, system-ui, sans-serif',
556
610
  userSelect: "none"
557
611
  },
558
612
  children: [
559
- /* @__PURE__ */ jsx("button", { type: "button", style: BUTTON, onClick: onPrev, "aria-label": "\u524D\u306E\u30B9\u30E9\u30A4\u30C9", children: /* @__PURE__ */ jsx(ChevronLeftIcon, { size: 16, "aria-hidden": "true" }) }),
613
+ /* @__PURE__ */ jsx("button", { type: "button", style: BUTTON, onClick: onPrev, "aria-label": messages.previousSlide, children: /* @__PURE__ */ jsx(ChevronLeftIcon, { size: 16, "aria-hidden": "true" }) }),
560
614
  /* @__PURE__ */ jsxs("span", { style: { padding: "0 8px", fontSize: 13, fontVariantNumeric: "tabular-nums" }, children: [
561
615
  current,
562
616
  " / ",
563
617
  total
564
618
  ] }),
565
- /* @__PURE__ */ jsx("button", { type: "button", style: BUTTON, onClick: onNext, "aria-label": "\u6B21\u306E\u30B9\u30E9\u30A4\u30C9", children: /* @__PURE__ */ jsx(ChevronRightIcon, { size: 16, "aria-hidden": "true" }) }),
619
+ /* @__PURE__ */ jsx("button", { type: "button", style: BUTTON, onClick: onNext, "aria-label": messages.nextSlide, children: /* @__PURE__ */ jsx(ChevronRightIcon, { size: 16, "aria-hidden": "true" }) }),
566
620
  isFullscreen ? null : /* @__PURE__ */ jsx(
567
621
  "button",
568
622
  {
569
623
  type: "button",
570
624
  style: BUTTON,
571
625
  onClick: onToggleRail,
572
- "aria-label": railOpen ? "\u30B9\u30E9\u30A4\u30C9\u4E00\u89A7\u3092\u9589\u3058\u308B (L)" : "\u30B9\u30E9\u30A4\u30C9\u4E00\u89A7\u3092\u958B\u304F (L)",
573
- title: railOpen ? "\u30B9\u30E9\u30A4\u30C9\u4E00\u89A7\u3092\u9589\u3058\u308B (L)" : "\u30B9\u30E9\u30A4\u30C9\u4E00\u89A7\u3092\u958B\u304F (L)",
626
+ "aria-label": railOpen ? messages.closeSlideList : messages.openSlideList,
627
+ title: railOpen ? messages.closeSlideList : messages.openSlideList,
574
628
  "aria-pressed": railOpen,
575
629
  children: railOpen ? /* @__PURE__ */ jsx(PanelLeftCloseIcon, { size: 16, "aria-hidden": "true" }) : /* @__PURE__ */ jsx(PanelLeftOpenIcon, { size: 16, "aria-hidden": "true" })
576
630
  }
577
631
  ),
578
- /* @__PURE__ */ jsx(
632
+ canFullscreen ? /* @__PURE__ */ jsx(
579
633
  "button",
580
634
  {
581
635
  type: "button",
582
636
  style: BUTTON,
583
637
  onClick: onFullscreen,
584
- "aria-label": isFullscreen ? "\u5168\u753B\u9762\u8868\u793A\u3092\u7D42\u4E86 (F)" : "\u5168\u753B\u9762\u8868\u793A (F)",
585
- title: isFullscreen ? "\u5168\u753B\u9762\u8868\u793A\u3092\u7D42\u4E86 (F)" : "\u5168\u753B\u9762\u8868\u793A (F)",
638
+ "aria-label": isFullscreen ? messages.exitFullscreen : messages.fullscreen,
639
+ title: isFullscreen ? messages.exitFullscreen : messages.fullscreen,
586
640
  children: isFullscreen ? /* @__PURE__ */ jsx(MinimizeIcon, { size: 16, "aria-hidden": "true" }) : /* @__PURE__ */ jsx(MaximizeIcon, { size: 16, "aria-hidden": "true" })
587
641
  }
588
- ),
642
+ ) : null,
589
643
  /* @__PURE__ */ jsxs(
590
644
  "button",
591
645
  {
@@ -593,8 +647,8 @@ function SlideToolbar({
593
647
  style: { ...BUTTON, opacity: busy ? 0.6 : 1, cursor: busy ? "progress" : "pointer" },
594
648
  onClick: onExport,
595
649
  disabled: busy,
596
- "aria-label": "PowerPoint \u3068\u3057\u3066\u66F8\u304D\u51FA\u3059",
597
- title: "PowerPoint \u3068\u3057\u3066\u66F8\u304D\u51FA\u3059",
650
+ "aria-label": messages.exportToPowerPoint,
651
+ title: messages.exportToPowerPoint,
598
652
  children: [
599
653
  /* @__PURE__ */ jsx(DownloadIcon, { size: 16, "aria-hidden": "true" }),
600
654
  busy ? /* @__PURE__ */ jsxs("span", { children: [
@@ -1376,6 +1430,10 @@ function collectSlides(children) {
1376
1430
  }
1377
1431
  return { slides, transitions };
1378
1432
  }
1433
+ function fullscreenEnabled() {
1434
+ if (typeof document === "undefined") return false;
1435
+ return document.fullscreenEnabled === true;
1436
+ }
1379
1437
  function defaultExportName() {
1380
1438
  if (typeof window === "undefined") return "slides";
1381
1439
  const parts = window.location.pathname.split("/").filter(Boolean);
@@ -1396,6 +1454,7 @@ function SlideDeck({
1396
1454
  const index = Math.min(Math.max(Math.floor(page) - 1, 0), Math.max(total - 1, 0));
1397
1455
  const [railOpen, setRailOpen] = useSearchState("rail", rail);
1398
1456
  const [isFullscreen, setIsFullscreen] = useState(false);
1457
+ const [canFullscreen] = useState(fullscreenEnabled);
1399
1458
  const [entryDirection, setEntryDirection] = useState("jump");
1400
1459
  const [exporting, setExporting] = useState(null);
1401
1460
  const stepControllerRef = useRef(null);
@@ -1421,9 +1480,11 @@ function SlideDeck({
1421
1480
  const toggleRail = useCallback(() => setRailOpen((open) => !open), [setRailOpen]);
1422
1481
  const toggleFullscreen = useCallback(() => {
1423
1482
  const el = viewportRef.current;
1424
- if (!el) return;
1425
- if (document.fullscreenElement) void document.exitFullscreen();
1426
- else void el.requestFullscreen?.();
1483
+ if (!el || !fullscreenEnabled()) return;
1484
+ if (document.fullscreenElement) document.exitFullscreen().catch(() => {
1485
+ });
1486
+ else el.requestFullscreen?.().catch(() => {
1487
+ });
1427
1488
  }, []);
1428
1489
  useEffect(() => {
1429
1490
  const onChange = () => setIsFullscreen(document.fullscreenElement === viewportRef.current);
@@ -1541,6 +1602,7 @@ function SlideDeck({
1541
1602
  onPrev: goPrev,
1542
1603
  onNext: goNext,
1543
1604
  onFullscreen: toggleFullscreen,
1605
+ canFullscreen,
1544
1606
  onExport,
1545
1607
  exportProgress: exporting,
1546
1608
  railOpen,
@@ -1565,7 +1627,1012 @@ function MorphElement({ id, children, className, style }) {
1565
1627
  }
1566
1628
  return /* @__PURE__ */ jsx("div", { className, style, "data-slide-morph": id, children });
1567
1629
  }
1630
+ var SAFE_X = 160;
1631
+ var SAFE_Y = 120;
1632
+ var COLUMNS = 12;
1633
+ var GUTTER2 = 32;
1634
+ var COLUMN_WIDTH = 104;
1635
+ var SLIDE_SPEC = {
1636
+ /** Keep content inside this margin; backgrounds may bleed past it. */
1637
+ safeArea: { x: SAFE_X, y: SAFE_Y },
1638
+ /** Spans the content width: 12 columns + 11 gutters = 1600. */
1639
+ grid: { columns: COLUMNS, gutter: GUTTER2, columnWidth: COLUMN_WIDTH },
1640
+ /** Font sizes in canvas px, strictly increasing. */
1641
+ fontSize: { caption: 24, page: 64, section: 88},
1642
+ lineHeight: { heading: 1.2, body: 1.6 },
1643
+ /** Gaps between elements, in canvas px. */
1644
+ space: { sm: 32, md: 48, lg: 64 }
1645
+ };
1646
+ function SlideColumns({ children, align = "stretch" }) {
1647
+ return /* @__PURE__ */ jsx(
1648
+ "div",
1649
+ {
1650
+ style: {
1651
+ gridColumn: "1 / -1",
1652
+ minHeight: 0,
1653
+ display: "grid",
1654
+ gridTemplateColumns: `repeat(${SLIDE_SPEC.grid.columns}, 1fr)`,
1655
+ gridTemplateRows: "minmax(0, 1fr)",
1656
+ columnGap: SLIDE_SPEC.grid.gutter,
1657
+ alignItems: align
1658
+ },
1659
+ children
1660
+ }
1661
+ );
1662
+ }
1663
+ function SlideColumn({ span, children }) {
1664
+ return /* @__PURE__ */ jsx("div", { style: { gridColumn: `span ${span}`, minWidth: 0, minHeight: 0 }, children });
1665
+ }
1666
+ function SlideHeading({ title, eyebrow }) {
1667
+ const heading = /* @__PURE__ */ jsx(
1668
+ "h2",
1669
+ {
1670
+ style: {
1671
+ ...eyebrow ? {} : { gridColumn: "1 / -1" },
1672
+ margin: 0,
1673
+ fontFamily: "var(--slide-font-display)",
1674
+ fontSize: SLIDE_SPEC.fontSize.page,
1675
+ lineHeight: SLIDE_SPEC.lineHeight.heading,
1676
+ fontWeight: 700,
1677
+ display: "-webkit-box",
1678
+ WebkitBoxOrient: "vertical",
1679
+ WebkitLineClamp: 2,
1680
+ overflow: "hidden"
1681
+ },
1682
+ children: title
1683
+ }
1684
+ );
1685
+ if (!eyebrow) return heading;
1686
+ return /* @__PURE__ */ jsxs("div", { style: { gridColumn: "1 / -1", display: "flex", flexDirection: "column", gap: SLIDE_SPEC.space.sm }, children: [
1687
+ /* @__PURE__ */ jsx(
1688
+ "p",
1689
+ {
1690
+ style: {
1691
+ margin: 0,
1692
+ fontSize: SLIDE_SPEC.fontSize.caption,
1693
+ lineHeight: SLIDE_SPEC.lineHeight.body,
1694
+ fontWeight: 700,
1695
+ color: "var(--slide-accent)"
1696
+ },
1697
+ children: eyebrow
1698
+ }
1699
+ ),
1700
+ heading
1701
+ ] });
1702
+ }
1703
+ var TEXT = {
1704
+ ja: { asOf: (asOf) => `${asOf} \u6642\u70B9`, source: (source) => `\u51FA\u5178: ${source}` },
1705
+ en: { asOf: (asOf) => `As of ${asOf}`, source: (source) => `Source: ${source}` }
1706
+ };
1707
+ function SlideSourceLine({ asOf, source, page }) {
1708
+ const t = TEXT[uiLanguage(useLocale())];
1709
+ const text = [asOf ? t.asOf(asOf) : null, source ? t.source(source) : null].filter(Boolean).join(" / ");
1710
+ if (!text && !page) return null;
1711
+ return /* @__PURE__ */ jsx(
1712
+ "p",
1713
+ {
1714
+ style: {
1715
+ gridColumn: "1 / -1",
1716
+ margin: 0,
1717
+ fontSize: SLIDE_SPEC.fontSize.caption,
1718
+ lineHeight: SLIDE_SPEC.lineHeight.body,
1719
+ color: "var(--slide-muted)",
1720
+ ...page ? { display: "flex", justifyContent: "space-between", gap: SLIDE_SPEC.space.md } : {}
1721
+ },
1722
+ children: page ? /* @__PURE__ */ jsxs(Fragment, { children: [
1723
+ /* @__PURE__ */ jsx("span", { children: text }),
1724
+ /* @__PURE__ */ jsx("span", { style: { fontVariantNumeric: "tabular-nums" }, children: `${page.current} / ${page.total}` })
1725
+ ] }) : text
1726
+ }
1727
+ );
1728
+ }
1729
+ var MAX_INSIGHTS = 3;
1730
+ var MAX_INSIGHT_CHARS = 40;
1731
+ var LINE_TYPES = ["solid", "dashed", "dotted"];
1732
+ var SYMBOLS = ["circle", "rect", "triangle", "diamond"];
1733
+ function buildSlideChartOption(chart, locale) {
1734
+ return {
1735
+ animation: false,
1736
+ textStyle: { fontSize: SLIDE_SPEC.fontSize.caption },
1737
+ grid: {
1738
+ left: 0,
1739
+ right: SLIDE_SPEC.space.sm,
1740
+ top: chart.series.length > 1 ? SLIDE_SPEC.space.lg : SLIDE_SPEC.space.sm,
1741
+ bottom: 0,
1742
+ containLabel: true
1743
+ },
1744
+ legend: chart.series.length > 1 ? {
1745
+ top: 0,
1746
+ left: 0,
1747
+ textStyle: { fontSize: SLIDE_SPEC.fontSize.caption }
1748
+ } : { show: false },
1749
+ // The first x label and the lowest y label meet at the corner: the margin keeps the x labels clear of the axis, and
1750
+ // `hideOverlap` drops whichever still collides.
1751
+ xAxis: {
1752
+ type: "category",
1753
+ data: chart.categories,
1754
+ // Half a category of room on both sides keeps the first point off the y-axis labels (a line from the axis touches them).
1755
+ boundaryGap: true,
1756
+ axisLabel: {
1757
+ fontSize: SLIDE_SPEC.fontSize.caption,
1758
+ margin: SLIDE_SPEC.space.sm,
1759
+ hideOverlap: true
1760
+ }
1761
+ },
1762
+ yAxis: {
1763
+ type: "value",
1764
+ // A line from 0 hugs the top when the values sit in a narrow band; bars must keep their zero baseline.
1765
+ scale: chart.type !== "bar",
1766
+ axisLabel: {
1767
+ fontSize: SLIDE_SPEC.fontSize.caption,
1768
+ hideOverlap: true,
1769
+ formatter: (v) => formatValue(v, "compact", locale)
1770
+ }
1771
+ },
1772
+ ...chart.type === "bar" && chart.series.length > 1 ? { aria: { enabled: true, decal: { show: true } } } : {},
1773
+ series: chart.series.map((s, i) => ({
1774
+ name: s.name,
1775
+ type: chart.type === "bar" ? "bar" : "line",
1776
+ data: s.data,
1777
+ ...chart.type === "bar" ? {} : {
1778
+ symbol: SYMBOLS[i % SYMBOLS.length],
1779
+ symbolSize: SLIDE_SPEC.space.sm / 2,
1780
+ lineStyle: { width: 6, type: LINE_TYPES[i % LINE_TYPES.length] }
1781
+ },
1782
+ ...chart.type === "area" ? { areaStyle: { opacity: 0.16 } } : {}
1783
+ }))
1784
+ };
1785
+ }
1786
+ function SlideChartInsight({ title, chart, insights, chartSide = "left", asOf, source }) {
1787
+ const hasSource = Boolean(asOf || source);
1788
+ if (insights.some((t) => t.length > MAX_INSIGHT_CHARS)) console.warn(`SlideChartInsight: an insight is over ${MAX_INSIGHT_CHARS} characters; the column is narrow. Shorten it.`);
1789
+ if (insights.length > MAX_INSIGHTS) console.warn(`SlideChartInsight: ${insights.length} insights; ${MAX_INSIGHTS} fit beside the chart. Split the slide.`);
1790
+ const locale = useLocale();
1791
+ const option = useMemo(() => buildSlideChartOption(chart, locale), [chart, locale]);
1792
+ const chartFirst = chartSide === "left";
1793
+ const chartColumn = /* @__PURE__ */ jsx(SlideColumn, { span: 7, children: /* @__PURE__ */ jsx("div", { "data-waitfor": "canvas", style: { minHeight: 0, height: "100%" }, children: /* @__PURE__ */ jsx(EChart, { option, height: "100%", ariaLabel: title }) }) });
1794
+ const insightsColumn = /* @__PURE__ */ jsx(SlideColumn, { span: 5, children: /* @__PURE__ */ jsx(
1795
+ "ul",
1796
+ {
1797
+ style: {
1798
+ height: "100%",
1799
+ boxSizing: "border-box",
1800
+ margin: 0,
1801
+ padding: 0,
1802
+ listStyle: "none",
1803
+ minHeight: 0,
1804
+ display: "flex",
1805
+ flexDirection: "column",
1806
+ justifyContent: "center",
1807
+ gap: SLIDE_SPEC.space.md
1808
+ },
1809
+ children: insights.map((text, i) => /* @__PURE__ */ jsx(
1810
+ "li",
1811
+ {
1812
+ style: {
1813
+ paddingLeft: SLIDE_SPEC.space.sm,
1814
+ borderLeft: "4px solid var(--slide-accent)",
1815
+ fontSize: "var(--slide-size-body)",
1816
+ lineHeight: SLIDE_SPEC.lineHeight.body
1817
+ },
1818
+ children: text
1819
+ },
1820
+ i
1821
+ ))
1822
+ }
1823
+ ) });
1824
+ return /* @__PURE__ */ jsxs(
1825
+ "section",
1826
+ {
1827
+ "data-slot": "slide-chart-insight",
1828
+ style: {
1829
+ width: "100%",
1830
+ height: "100%",
1831
+ boxSizing: "border-box",
1832
+ display: "grid",
1833
+ gridTemplateColumns: `repeat(${SLIDE_SPEC.grid.columns}, 1fr)`,
1834
+ gridTemplateRows: hasSource ? "auto 1fr auto" : "auto 1fr",
1835
+ columnGap: SLIDE_SPEC.grid.gutter,
1836
+ rowGap: SLIDE_SPEC.space.lg,
1837
+ padding: `${SLIDE_SPEC.safeArea.y}px ${SLIDE_SPEC.safeArea.x}px`,
1838
+ color: "var(--slide-fg)",
1839
+ fontFamily: "var(--slide-font-body)"
1840
+ },
1841
+ children: [
1842
+ /* @__PURE__ */ jsx(SlideHeading, { title }),
1843
+ /* @__PURE__ */ jsxs(SlideColumns, { children: [
1844
+ chartFirst ? chartColumn : insightsColumn,
1845
+ chartFirst ? insightsColumn : chartColumn
1846
+ ] }),
1847
+ hasSource && /* @__PURE__ */ jsx(SlideSourceLine, { asOf, source })
1848
+ ]
1849
+ }
1850
+ );
1851
+ }
1852
+ var TEXT2 = {
1853
+ ja: { asOf: (asOf) => `${asOf} \u6642\u70B9`, source: (source) => `\u51FA\u5178: ${source}`, separator: "\u3000|\u3000" },
1854
+ en: { asOf: (asOf) => `As of ${asOf}`, source: (source) => `Source: ${source}`, separator: " | " }
1855
+ };
1856
+ function SlideCover({ title, subtitle, period, author, asOf, source }) {
1857
+ const t = TEXT2[uiLanguage(useLocale())];
1858
+ const meta = [
1859
+ period,
1860
+ author,
1861
+ [asOf ? t.asOf(asOf) : null, source ? t.source(source) : null].filter(Boolean).join(" / ") || void 0
1862
+ ].filter(Boolean);
1863
+ return /* @__PURE__ */ jsxs(
1864
+ "section",
1865
+ {
1866
+ "data-slot": "slide-cover",
1867
+ style: {
1868
+ width: "100%",
1869
+ height: "100%",
1870
+ boxSizing: "border-box",
1871
+ display: "grid",
1872
+ gridTemplateColumns: `repeat(${SLIDE_SPEC.grid.columns}, 1fr)`,
1873
+ gridTemplateRows: "1fr auto",
1874
+ columnGap: SLIDE_SPEC.grid.gutter,
1875
+ rowGap: SLIDE_SPEC.space.lg,
1876
+ padding: `${SLIDE_SPEC.safeArea.y}px ${SLIDE_SPEC.safeArea.x}px`,
1877
+ color: "var(--slide-fg)",
1878
+ fontFamily: "var(--slide-font-body)"
1879
+ },
1880
+ children: [
1881
+ /* @__PURE__ */ jsx(SlideColumns, { children: /* @__PURE__ */ jsx(SlideColumn, { span: 8, children: /* @__PURE__ */ jsxs(
1882
+ "div",
1883
+ {
1884
+ style: {
1885
+ height: "100%",
1886
+ boxSizing: "border-box",
1887
+ display: "flex",
1888
+ flexDirection: "column",
1889
+ justifyContent: "center",
1890
+ gap: SLIDE_SPEC.space.md,
1891
+ minHeight: 0
1892
+ },
1893
+ children: [
1894
+ /* @__PURE__ */ jsx("div", { style: { width: SLIDE_SPEC.grid.columnWidth, height: 8, background: "var(--slide-accent)" } }),
1895
+ /* @__PURE__ */ jsx(
1896
+ "h1",
1897
+ {
1898
+ style: {
1899
+ margin: 0,
1900
+ fontFamily: "var(--slide-font-display)",
1901
+ fontSize: SLIDE_SPEC.fontSize.section,
1902
+ lineHeight: SLIDE_SPEC.lineHeight.heading,
1903
+ fontWeight: 700,
1904
+ textWrap: "balance"
1905
+ },
1906
+ children: title
1907
+ }
1908
+ ),
1909
+ subtitle && /* @__PURE__ */ jsx("p", { style: { margin: 0, fontSize: "var(--slide-size-body)", lineHeight: SLIDE_SPEC.lineHeight.body, color: "var(--slide-muted)" }, children: subtitle })
1910
+ ]
1911
+ }
1912
+ ) }) }),
1913
+ meta.length > 0 && /* @__PURE__ */ jsx(
1914
+ "p",
1915
+ {
1916
+ style: {
1917
+ gridColumn: "1 / -1",
1918
+ margin: 0,
1919
+ fontSize: SLIDE_SPEC.fontSize.caption,
1920
+ lineHeight: SLIDE_SPEC.lineHeight.body,
1921
+ color: "var(--slide-muted)"
1922
+ },
1923
+ children: meta.join(t.separator)
1924
+ }
1925
+ )
1926
+ ]
1927
+ }
1928
+ );
1929
+ }
1930
+ var MAX_POINTS = 5;
1931
+ function SlideExecSummary({ title, points, layout = "rows", asOf, source }) {
1932
+ const hasSource = Boolean(asOf || source);
1933
+ if (points.length > MAX_POINTS) console.warn(`SlideExecSummary: ${points.length} points; ${MAX_POINTS} fit the canvas. Split the slide.`);
1934
+ const number = (i) => String(i + 1).padStart(2, "0");
1935
+ return /* @__PURE__ */ jsxs(
1936
+ "section",
1937
+ {
1938
+ "data-slot": "slide-exec-summary",
1939
+ style: {
1940
+ width: "100%",
1941
+ height: "100%",
1942
+ boxSizing: "border-box",
1943
+ display: "grid",
1944
+ gridTemplateColumns: `repeat(${SLIDE_SPEC.grid.columns}, 1fr)`,
1945
+ gridTemplateRows: hasSource ? "auto 1fr auto" : "auto 1fr",
1946
+ columnGap: SLIDE_SPEC.grid.gutter,
1947
+ rowGap: SLIDE_SPEC.space.lg,
1948
+ padding: `${SLIDE_SPEC.safeArea.y}px ${SLIDE_SPEC.safeArea.x}px`,
1949
+ color: "var(--slide-fg)",
1950
+ fontFamily: "var(--slide-font-body)"
1951
+ },
1952
+ children: [
1953
+ /* @__PURE__ */ jsx(SlideHeading, { title }),
1954
+ layout === "columns" ? /* @__PURE__ */ jsx(
1955
+ "ol",
1956
+ {
1957
+ style: {
1958
+ gridColumn: "1 / -1",
1959
+ margin: 0,
1960
+ padding: 0,
1961
+ listStyle: "none",
1962
+ minHeight: 0,
1963
+ display: "grid",
1964
+ gridTemplateColumns: `repeat(${Math.max(points.length, 1)}, 1fr)`,
1965
+ columnGap: SLIDE_SPEC.grid.gutter
1966
+ },
1967
+ children: points.map((p, i) => /* @__PURE__ */ jsxs(
1968
+ "li",
1969
+ {
1970
+ style: {
1971
+ display: "flex",
1972
+ flexDirection: "column",
1973
+ gap: SLIDE_SPEC.space.sm,
1974
+ paddingTop: SLIDE_SPEC.space.md,
1975
+ borderTop: "4px solid var(--slide-accent)"
1976
+ },
1977
+ children: [
1978
+ /* @__PURE__ */ jsx("span", { style: { fontSize: SLIDE_SPEC.fontSize.page, lineHeight: SLIDE_SPEC.lineHeight.heading, fontWeight: 700, color: "var(--slide-accent)" }, children: number(i) }),
1979
+ /* @__PURE__ */ jsx("span", { style: { fontSize: "var(--slide-size-body)", lineHeight: SLIDE_SPEC.lineHeight.heading, fontWeight: 700 }, children: p.headline }),
1980
+ p.detail && /* @__PURE__ */ jsx("span", { style: { fontSize: SLIDE_SPEC.fontSize.caption, lineHeight: SLIDE_SPEC.lineHeight.body, color: "var(--slide-muted)" }, children: p.detail })
1981
+ ]
1982
+ },
1983
+ i
1984
+ ))
1985
+ }
1986
+ ) : /* @__PURE__ */ jsx(
1987
+ "ol",
1988
+ {
1989
+ style: {
1990
+ gridColumn: "1 / -1",
1991
+ margin: 0,
1992
+ padding: 0,
1993
+ listStyle: "none",
1994
+ minHeight: 0,
1995
+ display: "flex",
1996
+ flexDirection: "column",
1997
+ justifyContent: "center",
1998
+ gap: SLIDE_SPEC.space.sm
1999
+ },
2000
+ children: points.map((p, i) => /* @__PURE__ */ jsxs(
2001
+ "li",
2002
+ {
2003
+ style: {
2004
+ display: "grid",
2005
+ gridTemplateColumns: `${SLIDE_SPEC.grid.columnWidth}px 1fr`,
2006
+ columnGap: SLIDE_SPEC.space.md,
2007
+ alignItems: "baseline"
2008
+ },
2009
+ children: [
2010
+ /* @__PURE__ */ jsx("span", { style: { fontSize: SLIDE_SPEC.fontSize.page, lineHeight: SLIDE_SPEC.lineHeight.heading, fontWeight: 700, color: "var(--slide-accent)" }, children: number(i) }),
2011
+ /* @__PURE__ */ jsxs("div", { style: { display: "flex", flexDirection: "column" }, children: [
2012
+ /* @__PURE__ */ jsx("span", { style: { fontSize: "var(--slide-size-body)", lineHeight: SLIDE_SPEC.lineHeight.heading, fontWeight: 700 }, children: p.headline }),
2013
+ p.detail && /* @__PURE__ */ jsx("span", { style: { fontSize: SLIDE_SPEC.fontSize.caption, lineHeight: SLIDE_SPEC.lineHeight.body, color: "var(--slide-muted)" }, children: p.detail })
2014
+ ] })
2015
+ ]
2016
+ },
2017
+ i
2018
+ ))
2019
+ }
2020
+ ),
2021
+ hasSource && /* @__PURE__ */ jsx(SlideSourceLine, { asOf, source })
2022
+ ]
2023
+ }
2024
+ );
2025
+ }
2026
+ var MAX_ITEMS = 4;
2027
+ var ARROW = { up: "\u25B2", down: "\u25BC", flat: "\u25AC" };
2028
+ var TEXT3 = {
2029
+ ja: {
2030
+ up: "\u5897",
2031
+ down: "\u6E1B",
2032
+ flat: "\u6A2A\u3070\u3044",
2033
+ target: (target) => `\u76EE\u6A19 ${target}`,
2034
+ attainment: (shown, rate) => `${shown}(\u9054\u6210\u7387 ${rate})`
2035
+ },
2036
+ en: {
2037
+ up: "Up",
2038
+ down: "Down",
2039
+ flat: "Flat",
2040
+ target: (target) => `Target ${target}`,
2041
+ attainment: (shown, rate) => `${shown} (${rate} attained)`
2042
+ }
2043
+ };
2044
+ function deltaView(delta, betterWhen, locale) {
2045
+ const direction = delta.value > 0 ? "up" : delta.value < 0 ? "down" : "flat";
2046
+ const color = direction === "flat" ? "var(--slide-muted)" : direction === betterWhen ? "var(--positive)" : "var(--negative)";
2047
+ const amount = formatValue(delta.value, delta.format, locale, { signDisplay: "exceptZero" });
2048
+ return { color, text: `${ARROW[direction]} ${TEXT3[uiLanguage(locale)][direction]} ${amount}` };
2049
+ }
2050
+ function targetText(item, locale) {
2051
+ if (item.target === void 0) return void 0;
2052
+ const t = TEXT3[uiLanguage(locale)];
2053
+ const { value, target, betterWhen = "up" } = item;
2054
+ const rate = value === null ? void 0 : betterWhen === "down" ? target / value : value / target;
2055
+ const shown = t.target(formatValue(target, item.format, locale));
2056
+ return rate === void 0 || !Number.isFinite(rate) ? shown : t.attainment(shown, formatValue(rate, { type: "percent", digits: 0 }, locale));
2057
+ }
2058
+ function SlideKpiGrid({ title, items, asOf, source }) {
2059
+ const locale = useLocale();
2060
+ const hasSource = Boolean(asOf || source);
2061
+ if (items.length > MAX_ITEMS) console.warn(`SlideKpiGrid: ${items.length} items; ${MAX_ITEMS} fit the canvas. Split the slide.`);
2062
+ return /* @__PURE__ */ jsxs(
2063
+ "section",
2064
+ {
2065
+ "data-slot": "slide-kpi-grid",
2066
+ style: {
2067
+ width: "100%",
2068
+ height: "100%",
2069
+ boxSizing: "border-box",
2070
+ display: "grid",
2071
+ gridTemplateColumns: `repeat(${SLIDE_SPEC.grid.columns}, 1fr)`,
2072
+ gridTemplateRows: hasSource ? "auto 1fr auto" : "auto 1fr",
2073
+ columnGap: SLIDE_SPEC.grid.gutter,
2074
+ rowGap: SLIDE_SPEC.space.lg,
2075
+ padding: `${SLIDE_SPEC.safeArea.y}px ${SLIDE_SPEC.safeArea.x}px`,
2076
+ color: "var(--slide-fg)",
2077
+ fontFamily: "var(--slide-font-body)"
2078
+ },
2079
+ children: [
2080
+ /* @__PURE__ */ jsx(SlideHeading, { title }),
2081
+ /* @__PURE__ */ jsx(
2082
+ "div",
2083
+ {
2084
+ style: {
2085
+ gridColumn: "1 / -1",
2086
+ minHeight: 0,
2087
+ display: "grid",
2088
+ gridTemplateColumns: `repeat(${Math.max(items.length, 1)}, 1fr)`,
2089
+ columnGap: SLIDE_SPEC.grid.gutter,
2090
+ alignItems: "center"
2091
+ },
2092
+ children: items.map((item, i) => {
2093
+ const delta = item.delta ? deltaView({ value: item.delta.value, format: item.delta.format ?? item.format }, item.betterWhen ?? "up", locale) : void 0;
2094
+ const target = targetText(item, locale);
2095
+ return /* @__PURE__ */ jsxs(
2096
+ "div",
2097
+ {
2098
+ style: {
2099
+ display: "flex",
2100
+ flexDirection: "column",
2101
+ gap: SLIDE_SPEC.space.sm,
2102
+ padding: SLIDE_SPEC.space.md,
2103
+ border: "2px solid var(--border)",
2104
+ borderRadius: "var(--slide-radius)",
2105
+ minWidth: 0
2106
+ },
2107
+ children: [
2108
+ /* @__PURE__ */ jsx("span", { style: { fontSize: SLIDE_SPEC.fontSize.caption, lineHeight: SLIDE_SPEC.lineHeight.body, fontWeight: 700, color: "var(--slide-muted)" }, children: item.label }),
2109
+ /* @__PURE__ */ jsx(
2110
+ "span",
2111
+ {
2112
+ "data-raw": item.value ?? void 0,
2113
+ style: {
2114
+ fontFamily: "var(--slide-font-display)",
2115
+ fontSize: SLIDE_SPEC.fontSize.page,
2116
+ lineHeight: SLIDE_SPEC.lineHeight.heading,
2117
+ fontWeight: 700,
2118
+ fontVariantNumeric: "tabular-nums"
2119
+ },
2120
+ children: item.display ?? formatValue(item.value, item.format, locale)
2121
+ }
2122
+ ),
2123
+ delta && /* @__PURE__ */ jsxs("span", { style: { fontSize: "var(--slide-size-body)", lineHeight: SLIDE_SPEC.lineHeight.heading, fontWeight: 700, color: delta.color }, children: [
2124
+ delta.text,
2125
+ item.comparisonLabel && /* @__PURE__ */ jsxs("span", { style: { fontSize: SLIDE_SPEC.fontSize.caption, fontWeight: 400, color: "var(--slide-muted)" }, children: [
2126
+ " ",
2127
+ item.comparisonLabel
2128
+ ] })
2129
+ ] }),
2130
+ target && /* @__PURE__ */ jsx("span", { style: { fontSize: SLIDE_SPEC.fontSize.caption, lineHeight: SLIDE_SPEC.lineHeight.body, color: "var(--slide-muted)" }, children: target })
2131
+ ]
2132
+ },
2133
+ i
2134
+ );
2135
+ })
2136
+ }
2137
+ ),
2138
+ hasSource && /* @__PURE__ */ jsx(SlideSourceLine, { asOf, source })
2139
+ ]
2140
+ }
2141
+ );
2142
+ }
2143
+ var ARROW2 = { up: "\u25B2", down: "\u25BC", flat: "\u25AC" };
2144
+ var TEXT4 = {
2145
+ ja: { up: "\u5897", down: "\u6E1B", flat: "\u6A2A\u3070\u3044", trend: (label) => `${label}\u306E\u63A8\u79FB` },
2146
+ en: { up: "Up", down: "Down", flat: "Flat", trend: (label) => `${label} trend` }
2147
+ };
2148
+ function deltaView2(delta, betterWhen, locale) {
2149
+ const direction = delta.value > 0 ? "up" : delta.value < 0 ? "down" : "flat";
2150
+ const color = direction === "flat" ? "var(--slide-muted)" : direction === betterWhen ? "var(--positive)" : "var(--negative)";
2151
+ const amount = formatValue(delta.value, delta.format, locale, { signDisplay: "exceptZero" });
2152
+ return { color, text: `${ARROW2[direction]} ${TEXT4[uiLanguage(locale)][direction]} ${amount}` };
2153
+ }
2154
+ function SlideKpiHero({ title, label, value, format, display, delta, betterWhen = "up", comparisonLabel, trend, asOf, source }) {
2155
+ const locale = useLocale();
2156
+ const t = TEXT4[uiLanguage(locale)];
2157
+ const hasSource = Boolean(asOf || source);
2158
+ const deltaShown = delta ? deltaView2({ value: delta.value, format: delta.format ?? format }, betterWhen, locale) : void 0;
2159
+ const option = useMemo(() => {
2160
+ if (!trend || trend.length === 0) return void 0;
2161
+ return {
2162
+ animation: false,
2163
+ textStyle: { fontSize: SLIDE_SPEC.fontSize.caption },
2164
+ grid: { left: 0, right: SLIDE_SPEC.space.sm, top: SLIDE_SPEC.space.sm, bottom: 0, containLabel: true },
2165
+ // The first x label and the lowest y label meet at the corner: the margin keeps the x labels clear of the axis, and
2166
+ // `hideOverlap` drops whichever still collides.
2167
+ xAxis: {
2168
+ type: "category",
2169
+ data: trend.map((p) => p.x),
2170
+ boundaryGap: false,
2171
+ axisLabel: { fontSize: SLIDE_SPEC.fontSize.caption, margin: SLIDE_SPEC.space.sm, hideOverlap: true }
2172
+ },
2173
+ yAxis: {
2174
+ type: "value",
2175
+ scale: true,
2176
+ axisLabel: { fontSize: SLIDE_SPEC.fontSize.caption, hideOverlap: true, formatter: (v) => formatValue(v, "compact", locale) }
2177
+ },
2178
+ series: [
2179
+ {
2180
+ type: "line",
2181
+ data: trend.map((p) => p.y),
2182
+ symbol: "circle",
2183
+ symbolSize: SLIDE_SPEC.space.sm / 2,
2184
+ lineStyle: { width: 6 },
2185
+ areaStyle: { opacity: 0.12 }
2186
+ }
2187
+ ]
2188
+ };
2189
+ }, [trend, locale]);
2190
+ return /* @__PURE__ */ jsxs(
2191
+ "section",
2192
+ {
2193
+ "data-slot": "slide-kpi-hero",
2194
+ style: {
2195
+ width: "100%",
2196
+ height: "100%",
2197
+ boxSizing: "border-box",
2198
+ display: "grid",
2199
+ gridTemplateColumns: `repeat(${SLIDE_SPEC.grid.columns}, 1fr)`,
2200
+ gridTemplateRows: hasSource ? "auto 1fr auto" : "auto 1fr",
2201
+ columnGap: SLIDE_SPEC.grid.gutter,
2202
+ rowGap: SLIDE_SPEC.space.lg,
2203
+ padding: `${SLIDE_SPEC.safeArea.y}px ${SLIDE_SPEC.safeArea.x}px`,
2204
+ color: "var(--slide-fg)",
2205
+ fontFamily: "var(--slide-font-body)"
2206
+ },
2207
+ children: [
2208
+ /* @__PURE__ */ jsx(SlideHeading, { title }),
2209
+ /* @__PURE__ */ jsxs(SlideColumns, { children: [
2210
+ /* @__PURE__ */ jsx(SlideColumn, { span: option ? 6 : 12, children: /* @__PURE__ */ jsxs(
2211
+ "div",
2212
+ {
2213
+ style: {
2214
+ height: "100%",
2215
+ boxSizing: "border-box",
2216
+ display: "flex",
2217
+ flexDirection: "column",
2218
+ justifyContent: "center",
2219
+ gap: SLIDE_SPEC.space.sm
2220
+ },
2221
+ children: [
2222
+ /* @__PURE__ */ jsx("span", { style: { fontSize: "var(--slide-size-body)", lineHeight: SLIDE_SPEC.lineHeight.heading, color: "var(--slide-muted)" }, children: label }),
2223
+ /* @__PURE__ */ jsx(
2224
+ "span",
2225
+ {
2226
+ "data-raw": value ?? void 0,
2227
+ style: {
2228
+ fontFamily: "var(--slide-font-display)",
2229
+ fontSize: "var(--slide-size-hero)",
2230
+ lineHeight: SLIDE_SPEC.lineHeight.heading,
2231
+ fontWeight: 700,
2232
+ fontVariantNumeric: "tabular-nums"
2233
+ },
2234
+ children: display ?? formatValue(value, format, locale)
2235
+ }
2236
+ ),
2237
+ (deltaShown || comparisonLabel) && /* @__PURE__ */ jsxs("span", { style: { display: "flex", flexWrap: "wrap", alignItems: "baseline", gap: SLIDE_SPEC.space.sm, fontSize: "var(--slide-size-body)", lineHeight: SLIDE_SPEC.lineHeight.heading }, children: [
2238
+ deltaShown && /* @__PURE__ */ jsx("span", { style: { color: deltaShown.color, fontWeight: 700 }, children: deltaShown.text }),
2239
+ comparisonLabel && /* @__PURE__ */ jsx("span", { style: { fontSize: SLIDE_SPEC.fontSize.caption, color: "var(--slide-muted)" }, children: comparisonLabel })
2240
+ ] })
2241
+ ]
2242
+ }
2243
+ ) }),
2244
+ option && /* @__PURE__ */ jsx(SlideColumn, { span: 6, children: /* @__PURE__ */ jsx("div", { "data-waitfor": "canvas", style: { minHeight: 0, height: "100%" }, children: /* @__PURE__ */ jsx(EChart, { option, height: "100%", ariaLabel: t.trend(label) }) }) })
2245
+ ] }),
2246
+ hasSource && /* @__PURE__ */ jsx(SlideSourceLine, { asOf, source })
2247
+ ]
2248
+ }
2249
+ );
2250
+ }
2251
+ var MAX_ITEMS2 = 5;
2252
+ var MAX_DUE_CHARS = 10;
2253
+ var HEADS = {
2254
+ ja: { owner: "\u62C5\u5F53", due: "\u671F\u9650", metric: "\u78BA\u8A8D\u3059\u308B\u6307\u6A19" },
2255
+ en: { owner: "Owner", due: "Due", metric: "Metric to watch" }
2256
+ };
2257
+ function SlideNextActions({ title, items, asOf, source }) {
2258
+ const head = HEADS[uiLanguage(useLocale())];
2259
+ const hasSource = Boolean(asOf || source);
2260
+ if (items.length > MAX_ITEMS2) console.warn(`SlideNextActions: ${items.length} items; ${MAX_ITEMS2} fit the canvas. Split the slide.`);
2261
+ if (items.some((it) => (it.due?.length ?? 0) > MAX_DUE_CHARS)) console.warn(`SlideNextActions: a due date is over ${MAX_DUE_CHARS} characters; the column is one line wide. Shorten it.`);
2262
+ const cols = [
2263
+ { key: "owner", head: head.owner, fr: 2 },
2264
+ { key: "due", head: head.due, fr: 2 },
2265
+ { key: "metric", head: head.metric, fr: 3 }
2266
+ ];
2267
+ const shown = cols.filter((c) => items.some((it) => it[c.key]));
2268
+ const template = [`${SLIDE_SPEC.grid.columnWidth}px`, "minmax(0, 6fr)", ...shown.map((c) => `minmax(0, ${c.fr}fr)`)].join(" ");
2269
+ const row = { display: "grid", gridTemplateColumns: template, columnGap: SLIDE_SPEC.space.md, alignItems: "baseline" };
2270
+ return /* @__PURE__ */ jsxs(
2271
+ "section",
2272
+ {
2273
+ "data-slot": "slide-next-actions",
2274
+ style: {
2275
+ width: "100%",
2276
+ height: "100%",
2277
+ boxSizing: "border-box",
2278
+ display: "grid",
2279
+ gridTemplateColumns: `repeat(${SLIDE_SPEC.grid.columns}, 1fr)`,
2280
+ gridTemplateRows: hasSource ? "auto 1fr auto" : "auto 1fr",
2281
+ columnGap: SLIDE_SPEC.grid.gutter,
2282
+ rowGap: SLIDE_SPEC.space.lg,
2283
+ padding: `${SLIDE_SPEC.safeArea.y}px ${SLIDE_SPEC.safeArea.x}px`,
2284
+ color: "var(--slide-fg)",
2285
+ fontFamily: "var(--slide-font-body)"
2286
+ },
2287
+ children: [
2288
+ /* @__PURE__ */ jsx(SlideHeading, { title }),
2289
+ /* @__PURE__ */ jsxs("div", { style: { gridColumn: "1 / -1", minHeight: 0, display: "flex", flexDirection: "column", justifyContent: "center" }, children: [
2290
+ shown.length > 0 && /* @__PURE__ */ jsxs(
2291
+ "div",
2292
+ {
2293
+ "aria-hidden": true,
2294
+ style: {
2295
+ ...row,
2296
+ paddingBottom: SLIDE_SPEC.space.sm,
2297
+ fontSize: SLIDE_SPEC.fontSize.caption,
2298
+ lineHeight: SLIDE_SPEC.lineHeight.body,
2299
+ fontWeight: 700,
2300
+ color: "var(--slide-muted)"
2301
+ },
2302
+ children: [
2303
+ /* @__PURE__ */ jsx("span", {}),
2304
+ /* @__PURE__ */ jsx("span", {}),
2305
+ shown.map((c) => /* @__PURE__ */ jsx("span", { children: c.head }, c.key))
2306
+ ]
2307
+ }
2308
+ ),
2309
+ /* @__PURE__ */ jsx("ol", { style: { margin: 0, padding: 0, listStyle: "none" }, children: items.map((it, i) => /* @__PURE__ */ jsxs(
2310
+ "li",
2311
+ {
2312
+ style: {
2313
+ ...row,
2314
+ paddingTop: SLIDE_SPEC.space.sm,
2315
+ paddingBottom: SLIDE_SPEC.space.sm,
2316
+ borderTop: "2px solid var(--border)"
2317
+ },
2318
+ children: [
2319
+ /* @__PURE__ */ jsx("span", { style: { fontSize: SLIDE_SPEC.fontSize.page, lineHeight: SLIDE_SPEC.lineHeight.heading, fontWeight: 700, color: "var(--slide-accent)" }, children: String(i + 1).padStart(2, "0") }),
2320
+ /* @__PURE__ */ jsx("span", { style: { fontSize: "var(--slide-size-body)", lineHeight: SLIDE_SPEC.lineHeight.heading, fontWeight: 700 }, children: it.action }),
2321
+ shown.map((c) => /* @__PURE__ */ jsx(
2322
+ "span",
2323
+ {
2324
+ style: { fontSize: SLIDE_SPEC.fontSize.caption, lineHeight: SLIDE_SPEC.lineHeight.body, ...c.key === "due" ? { whiteSpace: "nowrap" } : {} },
2325
+ children: it[c.key]
2326
+ },
2327
+ c.key
2328
+ ))
2329
+ ]
2330
+ },
2331
+ i
2332
+ )) })
2333
+ ] }),
2334
+ hasSource && /* @__PURE__ */ jsx(SlideSourceLine, { asOf, source })
2335
+ ]
2336
+ }
2337
+ );
2338
+ }
2339
+ var MAX_ROWS = 8;
2340
+ var DENSE_ROWS = 6;
2341
+ var STATUS_COLOR = {
2342
+ on: "var(--positive)",
2343
+ risk: "var(--warning)",
2344
+ off: "var(--negative)"
2345
+ };
2346
+ var TEXT5 = {
2347
+ ja: {
2348
+ status: { on: "\u9806\u8ABF", risk: "\u8981\u6CE8\u610F", off: "\u9045\u5EF6" },
2349
+ head: { metric: "\u6307\u6A19", target: "\u76EE\u6A19", actual: "\u5B9F\u7E3E", attainment: "\u9054\u6210\u7387", status: "\u72B6\u614B" }
2350
+ },
2351
+ en: {
2352
+ status: { on: "On track", risk: "At risk", off: "Off track" },
2353
+ head: { metric: "Metric", target: "Target", actual: "Actual", attainment: "Attainment", status: "Status" }
2354
+ }
2355
+ };
2356
+ function attainment(row) {
2357
+ if (row.value === null || row.target === void 0) return void 0;
2358
+ const rate = row.betterWhen === "down" ? row.target / row.value : row.value / row.target;
2359
+ return Number.isFinite(rate) ? rate : void 0;
2360
+ }
2361
+ function SlideScorecardTable({ title, rows, columns, asOf, source }) {
2362
+ const locale = useLocale();
2363
+ const t = TEXT5[uiLanguage(locale)];
2364
+ const hasSource = Boolean(asOf || source);
2365
+ if (rows.length > MAX_ROWS) console.warn(`SlideScorecardTable: ${rows.length} rows; ${MAX_ROWS} fit the canvas. Split the slide.`);
2366
+ const head = { ...t.head, ...columns };
2367
+ const showAttainment = rows.some((r) => attainment(r) !== void 0);
2368
+ const cellSize = rows.length > DENSE_ROWS ? SLIDE_SPEC.fontSize.caption : "var(--slide-size-body)";
2369
+ const cell = {
2370
+ paddingLeft: SLIDE_SPEC.space.sm,
2371
+ paddingRight: SLIDE_SPEC.space.sm,
2372
+ borderBottom: "2px solid var(--border)",
2373
+ textAlign: "left",
2374
+ verticalAlign: "middle"
2375
+ };
2376
+ const num = { ...cell, textAlign: "right", fontVariantNumeric: "tabular-nums" };
2377
+ return /* @__PURE__ */ jsxs(
2378
+ "section",
2379
+ {
2380
+ "data-slot": "slide-scorecard-table",
2381
+ style: {
2382
+ width: "100%",
2383
+ height: "100%",
2384
+ boxSizing: "border-box",
2385
+ display: "grid",
2386
+ gridTemplateColumns: `repeat(${SLIDE_SPEC.grid.columns}, 1fr)`,
2387
+ gridTemplateRows: hasSource ? "auto 1fr auto" : "auto 1fr",
2388
+ columnGap: SLIDE_SPEC.grid.gutter,
2389
+ rowGap: SLIDE_SPEC.space.lg,
2390
+ padding: `${SLIDE_SPEC.safeArea.y}px ${SLIDE_SPEC.safeArea.x}px`,
2391
+ color: "var(--slide-fg)",
2392
+ fontFamily: "var(--slide-font-body)"
2393
+ },
2394
+ children: [
2395
+ /* @__PURE__ */ jsx(SlideHeading, { title }),
2396
+ /* @__PURE__ */ jsx("div", { style: { gridColumn: "1 / -1", minHeight: 0 }, children: /* @__PURE__ */ jsxs("table", { style: { width: "100%", borderCollapse: "collapse", fontSize: cellSize, lineHeight: SLIDE_SPEC.lineHeight.body }, children: [
2397
+ /* @__PURE__ */ jsx("thead", { children: /* @__PURE__ */ jsxs("tr", { style: { color: "var(--slide-muted)", fontSize: SLIDE_SPEC.fontSize.caption }, children: [
2398
+ /* @__PURE__ */ jsx("th", { style: { ...cell, fontWeight: 700 }, children: head.metric }),
2399
+ /* @__PURE__ */ jsx("th", { style: { ...num, fontWeight: 700 }, children: head.target }),
2400
+ /* @__PURE__ */ jsx("th", { style: { ...num, fontWeight: 700 }, children: head.actual }),
2401
+ showAttainment && /* @__PURE__ */ jsx("th", { style: { ...num, fontWeight: 700 }, children: head.attainment }),
2402
+ /* @__PURE__ */ jsx("th", { style: { ...cell, fontWeight: 700 }, children: head.status })
2403
+ ] }) }),
2404
+ /* @__PURE__ */ jsx("tbody", { children: rows.map((r, i) => /* @__PURE__ */ jsxs("tr", { children: [
2405
+ /* @__PURE__ */ jsx("th", { scope: "row", style: { ...cell, fontWeight: 700 }, children: r.metric }),
2406
+ /* @__PURE__ */ jsx("td", { style: num, children: r.target === void 0 ? EMPTY_VALUE : formatValue(r.target, r.format, locale) }),
2407
+ /* @__PURE__ */ jsx("td", { style: { ...num, fontWeight: 700 }, children: r.display ?? formatValue(r.value, r.format, locale) }),
2408
+ showAttainment && /* @__PURE__ */ jsx("td", { style: num, children: attainment(r) === void 0 ? EMPTY_VALUE : formatValue(attainment(r), { type: "percent", digits: 0 }, locale) }),
2409
+ /* @__PURE__ */ jsxs("td", { style: cell, children: [
2410
+ /* @__PURE__ */ jsx("span", { "aria-hidden": true, style: { color: STATUS_COLOR[r.status] }, children: "\u25CF" }),
2411
+ " ",
2412
+ t.status[r.status]
2413
+ ] })
2414
+ ] }, i)) })
2415
+ ] }) }),
2416
+ hasSource && /* @__PURE__ */ jsx(SlideSourceLine, { asOf, source })
2417
+ ]
2418
+ }
2419
+ );
2420
+ }
2421
+ function SlideChartFull({ title, chart, note, asOf, source }) {
2422
+ const hasSource = Boolean(asOf || source);
2423
+ const option = useMemo(() => buildSlideChartOption(chart), [chart]);
2424
+ return /* @__PURE__ */ jsxs(
2425
+ "section",
2426
+ {
2427
+ "data-slot": "slide-chart-full",
2428
+ style: {
2429
+ width: "100%",
2430
+ height: "100%",
2431
+ boxSizing: "border-box",
2432
+ display: "grid",
2433
+ gridTemplateColumns: `repeat(${SLIDE_SPEC.grid.columns}, 1fr)`,
2434
+ gridTemplateRows: ["auto", "1fr", note ? "auto" : null, hasSource ? "auto" : null].filter(Boolean).join(" "),
2435
+ columnGap: SLIDE_SPEC.grid.gutter,
2436
+ rowGap: SLIDE_SPEC.space.lg,
2437
+ padding: `${SLIDE_SPEC.safeArea.y}px ${SLIDE_SPEC.safeArea.x}px`,
2438
+ color: "var(--slide-fg)",
2439
+ fontFamily: "var(--slide-font-body)"
2440
+ },
2441
+ children: [
2442
+ /* @__PURE__ */ jsx(SlideHeading, { title }),
2443
+ /* @__PURE__ */ jsx(SlideColumns, { children: /* @__PURE__ */ jsx(SlideColumn, { span: 12, children: /* @__PURE__ */ jsx("div", { "data-waitfor": "canvas", style: { minHeight: 0, height: "100%" }, children: /* @__PURE__ */ jsx(EChart, { option, height: "100%", ariaLabel: title }) }) }) }),
2444
+ note && /* @__PURE__ */ jsx("p", { style: { gridColumn: "1 / -1", margin: 0, fontSize: "var(--slide-size-body)", lineHeight: SLIDE_SPEC.lineHeight.body }, children: note }),
2445
+ hasSource && /* @__PURE__ */ jsx(SlideSourceLine, { asOf, source })
2446
+ ]
2447
+ }
2448
+ );
2449
+ }
2450
+ var MAX_POINTS2 = 3;
2451
+ var MAX_POINT_CHARS = 24;
2452
+ function SlideComparison({ title, columns, verdict, asOf, source }) {
2453
+ const locale = useLocale();
2454
+ const hasSource = Boolean(asOf || source);
2455
+ if (columns.length < 2 || columns.length > 3) console.warn(`SlideComparison: ${columns.length} columns; 2\u20133 fit. Split the slide.`);
2456
+ if (columns.some((c) => c.points.length > MAX_POINTS2 || c.points.some((t) => t.length > MAX_POINT_CHARS)))
2457
+ console.warn(`SlideComparison: a column has over ${MAX_POINTS2} points or a point over ${MAX_POINT_CHARS} characters. Shorten it.`);
2458
+ const span = Math.floor(SLIDE_SPEC.grid.columns / Math.max(columns.length, 1));
2459
+ return /* @__PURE__ */ jsxs(
2460
+ "section",
2461
+ {
2462
+ "data-slot": "slide-comparison",
2463
+ style: {
2464
+ width: "100%",
2465
+ height: "100%",
2466
+ boxSizing: "border-box",
2467
+ display: "grid",
2468
+ gridTemplateColumns: `repeat(${SLIDE_SPEC.grid.columns}, 1fr)`,
2469
+ gridTemplateRows: ["auto", "1fr", verdict ? "auto" : null, hasSource ? "auto" : null].filter(Boolean).join(" "),
2470
+ columnGap: SLIDE_SPEC.grid.gutter,
2471
+ rowGap: SLIDE_SPEC.space.lg,
2472
+ padding: `${SLIDE_SPEC.safeArea.y}px ${SLIDE_SPEC.safeArea.x}px`,
2473
+ color: "var(--slide-fg)",
2474
+ fontFamily: "var(--slide-font-body)"
2475
+ },
2476
+ children: [
2477
+ /* @__PURE__ */ jsx(SlideHeading, { title }),
2478
+ /* @__PURE__ */ jsx(SlideColumns, { children: columns.map((col, i) => {
2479
+ const main = col.display ?? (col.value === void 0 ? void 0 : col.value === null ? "\u2014" : formatValue(col.value, col.format, locale));
2480
+ return /* @__PURE__ */ jsx(SlideColumn, { span, children: /* @__PURE__ */ jsxs(
2481
+ "div",
2482
+ {
2483
+ style: {
2484
+ height: "100%",
2485
+ boxSizing: "border-box",
2486
+ display: "flex",
2487
+ flexDirection: "column",
2488
+ gap: SLIDE_SPEC.space.md,
2489
+ paddingTop: SLIDE_SPEC.space.sm,
2490
+ borderTop: "4px solid var(--slide-accent)"
2491
+ },
2492
+ children: [
2493
+ /* @__PURE__ */ jsx(
2494
+ "h3",
2495
+ {
2496
+ style: {
2497
+ margin: 0,
2498
+ fontSize: "var(--slide-size-body)",
2499
+ lineHeight: SLIDE_SPEC.lineHeight.heading,
2500
+ fontWeight: 700
2501
+ },
2502
+ children: col.heading
2503
+ }
2504
+ ),
2505
+ main !== void 0 && /* @__PURE__ */ jsxs("p", { style: { margin: 0, display: "flex", flexDirection: "column", gap: SLIDE_SPEC.space.sm }, children: [
2506
+ /* @__PURE__ */ jsx(
2507
+ "span",
2508
+ {
2509
+ style: {
2510
+ fontFamily: "var(--slide-font-display)",
2511
+ fontSize: SLIDE_SPEC.fontSize.section,
2512
+ lineHeight: SLIDE_SPEC.lineHeight.heading,
2513
+ fontWeight: 700,
2514
+ fontVariantNumeric: "tabular-nums"
2515
+ },
2516
+ children: main
2517
+ }
2518
+ ),
2519
+ col.delta && /* @__PURE__ */ jsx("span", { style: { fontSize: "var(--slide-size-body)", lineHeight: SLIDE_SPEC.lineHeight.body }, children: /* @__PURE__ */ jsx(DeltaText, { value: col.delta.value, format: col.delta.format ?? col.format, betterWhen: col.betterWhen, comparisonLabel: col.comparisonLabel }) })
2520
+ ] }),
2521
+ col.points.length > 0 && /* @__PURE__ */ jsx(
2522
+ "ul",
2523
+ {
2524
+ style: {
2525
+ margin: 0,
2526
+ padding: 0,
2527
+ listStyle: "none",
2528
+ display: "flex",
2529
+ flexDirection: "column",
2530
+ gap: SLIDE_SPEC.space.sm
2531
+ },
2532
+ children: col.points.map((text, j) => /* @__PURE__ */ jsx("li", { style: { fontSize: "var(--slide-size-body)", lineHeight: SLIDE_SPEC.lineHeight.body }, children: text }, j))
2533
+ }
2534
+ )
2535
+ ]
2536
+ }
2537
+ ) }, i);
2538
+ }) }),
2539
+ verdict && /* @__PURE__ */ jsx(
2540
+ "p",
2541
+ {
2542
+ style: {
2543
+ gridColumn: "1 / -1",
2544
+ margin: 0,
2545
+ paddingLeft: SLIDE_SPEC.space.sm,
2546
+ borderLeft: "4px solid var(--slide-accent)",
2547
+ fontSize: "var(--slide-size-body)",
2548
+ lineHeight: SLIDE_SPEC.lineHeight.body,
2549
+ fontWeight: 700
2550
+ },
2551
+ children: verdict
2552
+ }
2553
+ ),
2554
+ hasSource && /* @__PURE__ */ jsx(SlideSourceLine, { asOf, source })
2555
+ ]
2556
+ }
2557
+ );
2558
+ }
2559
+ function SlideSection({ index, title, lead, items, current }) {
2560
+ const hasItems = Boolean(items && items.length > 0);
2561
+ return /* @__PURE__ */ jsx(
2562
+ "section",
2563
+ {
2564
+ "data-slot": "slide-section",
2565
+ style: {
2566
+ width: "100%",
2567
+ height: "100%",
2568
+ boxSizing: "border-box",
2569
+ display: "grid",
2570
+ gridTemplateColumns: `repeat(${SLIDE_SPEC.grid.columns}, 1fr)`,
2571
+ gridTemplateRows: "minmax(0, 1fr)",
2572
+ columnGap: SLIDE_SPEC.grid.gutter,
2573
+ padding: `${SLIDE_SPEC.safeArea.y}px ${SLIDE_SPEC.safeArea.x}px`,
2574
+ color: "var(--slide-fg)",
2575
+ fontFamily: "var(--slide-font-body)"
2576
+ },
2577
+ children: /* @__PURE__ */ jsxs(SlideColumns, { align: "center", children: [
2578
+ /* @__PURE__ */ jsx(SlideColumn, { span: hasItems ? 7 : 12, children: /* @__PURE__ */ jsxs("div", { style: { display: "flex", flexDirection: "column", gap: SLIDE_SPEC.space.md }, children: [
2579
+ /* @__PURE__ */ jsx("div", { style: { width: SLIDE_SPEC.grid.columnWidth, height: 8, background: "var(--slide-accent)" } }),
2580
+ index !== void 0 && /* @__PURE__ */ jsx(
2581
+ "p",
2582
+ {
2583
+ style: {
2584
+ margin: 0,
2585
+ fontSize: SLIDE_SPEC.fontSize.page,
2586
+ lineHeight: SLIDE_SPEC.lineHeight.heading,
2587
+ fontWeight: 700,
2588
+ color: "var(--slide-accent)",
2589
+ fontVariantNumeric: "tabular-nums"
2590
+ },
2591
+ children: String(index).padStart(2, "0")
2592
+ }
2593
+ ),
2594
+ /* @__PURE__ */ jsx(
2595
+ "h1",
2596
+ {
2597
+ style: {
2598
+ margin: 0,
2599
+ fontFamily: "var(--slide-font-display)",
2600
+ fontSize: SLIDE_SPEC.fontSize.section,
2601
+ lineHeight: SLIDE_SPEC.lineHeight.heading,
2602
+ fontWeight: 700
2603
+ },
2604
+ children: title
2605
+ }
2606
+ ),
2607
+ lead && /* @__PURE__ */ jsx("p", { style: { margin: 0, fontSize: "var(--slide-size-body)", lineHeight: SLIDE_SPEC.lineHeight.body, color: "var(--slide-muted)" }, children: lead })
2608
+ ] }) }),
2609
+ hasItems && /* @__PURE__ */ jsx(SlideColumn, { span: 5, children: /* @__PURE__ */ jsx("ol", { style: { margin: 0, padding: 0, listStyle: "none", display: "flex", flexDirection: "column", gap: SLIDE_SPEC.space.sm }, children: items.map((text, i) => {
2610
+ const active = current === i + 1;
2611
+ return /* @__PURE__ */ jsxs(
2612
+ "li",
2613
+ {
2614
+ "aria-current": active ? "step" : void 0,
2615
+ style: {
2616
+ display: "flex",
2617
+ gap: SLIDE_SPEC.space.sm,
2618
+ fontSize: "var(--slide-size-body)",
2619
+ lineHeight: SLIDE_SPEC.lineHeight.body,
2620
+ fontWeight: active ? 700 : 400,
2621
+ color: active ? "var(--slide-accent)" : "var(--slide-muted)"
2622
+ },
2623
+ children: [
2624
+ /* @__PURE__ */ jsx("span", { style: { fontVariantNumeric: "tabular-nums" }, children: String(i + 1).padStart(2, "0") }),
2625
+ /* @__PURE__ */ jsx("span", { children: text })
2626
+ ]
2627
+ },
2628
+ i
2629
+ );
2630
+ }) }) })
2631
+ ] })
2632
+ }
2633
+ );
2634
+ }
1568
2635
 
1569
- export { CANVAS_HEIGHT, CANVAS_WIDTH, MorphElement, Slide, SlideCanvas, SlideDeck, Step, Steps, exportDeckAsPptx, useIsActiveSlide, useSlideNumber };
2636
+ export { CANVAS_HEIGHT, CANVAS_WIDTH, MorphElement, Slide, SlideCanvas, SlideChartFull, SlideChartInsight, SlideColumn, SlideColumns, SlideComparison, SlideCover, SlideDeck, SlideExecSummary, SlideHeading, SlideKpiGrid, SlideKpiHero, SlideNextActions, SlideScorecardTable, SlideSection, SlideSourceLine, Step, Steps, exportDeckAsPptx, useIsActiveSlide, useSlideNumber };
1570
2637
  //# sourceMappingURL=index.js.map
1571
2638
  //# sourceMappingURL=index.js.map