@squadbase/vantage 0.6.2-dev1.ac99e02 → 0.6.2-dev1.d7c0911

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 (141) hide show
  1. package/dist/{build-MFWRPYKW.js → build-X5NVCQKT.js} +4 -4
  2. package/dist/{build-MFWRPYKW.js.map → build-X5NVCQKT.js.map} +1 -1
  3. package/dist/{chunk-IBGOCWJB.js → chunk-2ICNHUG6.js} +186 -82
  4. package/dist/chunk-2ICNHUG6.js.map +1 -0
  5. package/dist/{chunk-5ZOP4SQR.js → chunk-2N72FKLB.js} +12 -7
  6. package/dist/chunk-2N72FKLB.js.map +1 -0
  7. package/dist/{chunk-PXRX5PEC.js → chunk-PDOBHMUQ.js} +3 -3
  8. package/dist/chunk-PDOBHMUQ.js.map +1 -0
  9. package/dist/{chunk-A2UUGASH.js → chunk-U736PVHY.js} +2 -2
  10. package/dist/chunk-U736PVHY.js.map +1 -0
  11. package/dist/{chunk-QEWCYW3I.js → chunk-WAMZWZJB.js} +13 -3
  12. package/dist/chunk-WAMZWZJB.js.map +1 -0
  13. package/dist/chunk-WRSX2MDK.js +7866 -0
  14. package/dist/chunk-WRSX2MDK.js.map +1 -0
  15. package/dist/{chunk-OB6UBJXF.js → chunk-XPQSTZUU.js} +125 -35
  16. package/dist/chunk-XPQSTZUU.js.map +1 -0
  17. package/dist/cli.js +3 -3
  18. package/dist/components/index.d.ts +1831 -99
  19. package/dist/components/index.js +4 -4
  20. package/dist/{dev-DCTOHQ6W.js → dev-4XEDTELV.js} +4 -4
  21. package/dist/{dev-DCTOHQ6W.js.map → dev-4XEDTELV.js.map} +1 -1
  22. package/dist/doc/index.js +2 -2
  23. package/dist/doc/index.js.map +1 -1
  24. package/dist/markdown/index.js +1 -1
  25. package/dist/markdown/index.js.map +1 -1
  26. package/dist/table/index.js +5 -5
  27. package/dist/table/index.js.map +1 -1
  28. package/dist/ui/index.d.ts +4 -1
  29. package/dist/ui/index.js +21 -111
  30. package/dist/ui/index.js.map +1 -1
  31. package/dist/{upgrade-DBBE6GIR.js → upgrade-JHXZBGQS.js} +3 -3
  32. package/dist/{upgrade-DBBE6GIR.js.map → upgrade-JHXZBGQS.js.map} +1 -1
  33. package/dist/vite/index.js +2 -2
  34. package/docs/en/components.md +29 -15
  35. package/docs/en/parts/data-table.md +22 -0
  36. package/docs/en/parts/delta.md +50 -0
  37. package/docs/en/parts/format.md +43 -0
  38. package/docs/en/parts/kpi-card.md +57 -0
  39. package/docs/en/parts/metric-value.md +3 -2
  40. package/docs/en/parts/sparkline.md +1 -1
  41. package/docs/en/parts/trend-indicator.md +17 -1
  42. package/docs/en/ui-and-theming.md +1 -1
  43. package/docs/index.json +92 -32
  44. package/docs/ja/changelog.md +5 -0
  45. package/docs/ja/components.md +27 -15
  46. package/docs/ja/parts/data-table.md +22 -0
  47. package/docs/ja/parts/delta.md +50 -0
  48. package/docs/ja/parts/format.md +44 -0
  49. package/docs/ja/parts/kpi-card.md +55 -0
  50. package/docs/ja/parts/metric-value.md +3 -2
  51. package/docs/ja/parts/sparkline.md +1 -1
  52. package/docs/ja/parts/trend-indicator.md +17 -1
  53. package/docs/ja/ui-and-theming.md +2 -2
  54. package/package.json +2 -1
  55. package/registry/ui/accordion.tsx +4 -2
  56. package/registry/ui/alert-dialog.tsx +3 -3
  57. package/registry/ui/alert.tsx +3 -1
  58. package/registry/ui/app-shell.tsx +7 -1
  59. package/registry/ui/area-chart.tsx +2781 -157
  60. package/registry/ui/avatar.tsx +1 -1
  61. package/registry/ui/badge.tsx +3 -1
  62. package/registry/ui/bar-chart.tsx +2780 -157
  63. package/registry/ui/bar-list.tsx +3471 -93
  64. package/registry/ui/breadcrumb.tsx +3 -1
  65. package/registry/ui/button.tsx +3 -1
  66. package/registry/ui/calendar.tsx +3 -1
  67. package/registry/ui/card.tsx +4 -2
  68. package/registry/ui/category-bar.tsx +990 -16
  69. package/registry/ui/chart-frame.tsx +1358 -0
  70. package/registry/ui/checkbox.tsx +3 -1
  71. package/registry/ui/collapsible.tsx +3 -1
  72. package/registry/ui/combobox.tsx +2 -2
  73. package/registry/ui/command.tsx +3 -1
  74. package/registry/ui/dashboard-card.tsx +69 -26
  75. package/registry/ui/data-table.tsx +678 -56
  76. package/registry/ui/date-range-picker.tsx +245 -64
  77. package/registry/ui/delta.tsx +188 -0
  78. package/registry/ui/dialog.tsx +5 -3
  79. package/registry/ui/donut-chart.tsx +2857 -173
  80. package/registry/ui/drawer.tsx +1 -1
  81. package/registry/ui/dropdown-menu.tsx +5 -3
  82. package/registry/ui/echart.tsx +448 -44
  83. package/registry/ui/field.tsx +1 -1
  84. package/registry/ui/filter-bar.tsx +33 -6
  85. package/registry/ui/funnel-steps.tsx +3316 -49
  86. package/registry/ui/heatmap.tsx +1752 -0
  87. package/registry/ui/hover-card.tsx +2 -2
  88. package/registry/ui/input-group.tsx +3 -1
  89. package/registry/ui/input.tsx +3 -1
  90. package/registry/ui/kbd.tsx +3 -1
  91. package/registry/ui/kpi-card.tsx +677 -0
  92. package/registry/ui/label.tsx +3 -1
  93. package/registry/ui/legend.tsx +3500 -0
  94. package/registry/ui/line-chart.tsx +2781 -151
  95. package/registry/ui/metric-value.tsx +9 -1
  96. package/registry/ui/multi-select.tsx +11 -5
  97. package/registry/ui/page-shell.tsx +104 -49
  98. package/registry/ui/pagination.tsx +3 -1
  99. package/registry/ui/placeholder.tsx +8 -2
  100. package/registry/ui/popover.tsx +4 -2
  101. package/registry/ui/progress-circle.tsx +607 -12
  102. package/registry/ui/progress.tsx +3 -1
  103. package/registry/ui/radio-group.tsx +1 -1
  104. package/registry/ui/sample-data.tsx +86 -0
  105. package/registry/ui/scatter-chart.tsx +4150 -0
  106. package/registry/ui/scroll-area.tsx +3 -2
  107. package/registry/ui/searchable-select.tsx +8 -3
  108. package/registry/ui/section-header.tsx +4 -2
  109. package/registry/ui/segmented-control.tsx +7 -2
  110. package/registry/ui/select.tsx +4 -2
  111. package/registry/ui/separator.tsx +3 -1
  112. package/registry/ui/sheet.tsx +4 -2
  113. package/registry/ui/sidebar.tsx +4 -2
  114. package/registry/ui/skeleton.tsx +4 -2
  115. package/registry/ui/slider.tsx +3 -1
  116. package/registry/ui/sparkline.tsx +84 -9
  117. package/registry/ui/spinner.tsx +3 -1
  118. package/registry/ui/states.tsx +34 -5
  119. package/registry/ui/status-badge.tsx +81 -39
  120. package/registry/ui/switch.tsx +3 -1
  121. package/registry/ui/table.tsx +4 -2
  122. package/registry/ui/tabs.tsx +5 -3
  123. package/registry/ui/textarea.tsx +3 -1
  124. package/registry/ui/toast.tsx +2 -2
  125. package/registry/ui/toggle-group.tsx +3 -1
  126. package/registry/ui/toggle.tsx +3 -1
  127. package/registry/ui/tooltip.tsx +4 -2
  128. package/registry/ui/tracker.tsx +624 -17
  129. package/registry/ui/trend-indicator.tsx +13 -1
  130. package/registry/ui/updated-at.tsx +122 -0
  131. package/registry/ui/waterfall-chart.tsx +4186 -0
  132. package/templates/AGENTS.md +13 -1
  133. package/theme.css +237 -136
  134. package/dist/chunk-5ZOP4SQR.js.map +0 -1
  135. package/dist/chunk-A2UUGASH.js.map +0 -1
  136. package/dist/chunk-AG6RZ2RR.js +0 -3208
  137. package/dist/chunk-AG6RZ2RR.js.map +0 -1
  138. package/dist/chunk-IBGOCWJB.js.map +0 -1
  139. package/dist/chunk-OB6UBJXF.js.map +0 -1
  140. package/dist/chunk-PXRX5PEC.js.map +0 -1
  141. package/dist/chunk-QEWCYW3I.js.map +0 -1
@@ -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`、型付きチャート `LineChart`・`BarChart`・`AreaChart`・`DonutChart`・`BarList` ほか、`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
98
  | `@squadbase/vantage/slide` | `SlideDeck`・`Slide`・`Steps`・`Step`・`MorphElement`・`useSlideNumber`・`useIsActiveSlide`(スライド専用。1920×1080 の固定キャンバス) |
99
99
  | `@squadbase/vantage/doc` | `Document`(ドキュメント専用。中の素の 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` の
package/theme.css CHANGED
@@ -1,3 +1,7 @@
1
+ /* GENERATED by scripts/gen-theme.mjs — do not edit. Sources:
2
+ * packages/squadkit/registry/theme/theme.css (UI part tokens)
3
+ * packages/vantage/src/theme/framework.css (slide / document styles) */
4
+
1
5
  /**
2
6
  * Vantage design tokens. Imported after `@import "tailwindcss"` by the
3
7
  * generated runtime.css. Defines CSS variables (light + dark), maps them to
@@ -18,123 +22,149 @@
18
22
  `<select>` popup. */
19
23
  color-scheme: light;
20
24
 
21
- --background: oklch(1 0 0);
22
- --foreground: oklch(0.145 0 0);
25
+ --background: oklch(0.975 0.004 255);
26
+ --foreground: oklch(0.21 0.02 260);
23
27
  --card: oklch(1 0 0);
24
- --card-foreground: oklch(0.145 0 0);
28
+ --card-foreground: oklch(0.21 0.02 260);
25
29
  --popover: oklch(1 0 0);
26
- --popover-foreground: oklch(0.145 0 0);
27
- --primary: oklch(0.205 0 0);
30
+ --popover-foreground: oklch(0.21 0.02 260);
31
+ --primary: oklch(0.55 0.2 262);
28
32
  --primary-foreground: oklch(0.985 0 0);
29
- --secondary: oklch(0.97 0 0);
30
- --secondary-foreground: oklch(0.205 0 0);
31
- --muted: oklch(0.97 0 0);
32
- --muted-foreground: oklch(0.556 0 0);
33
- --accent: oklch(0.97 0 0);
34
- --accent-foreground: oklch(0.205 0 0);
35
- --destructive: oklch(0.577 0.245 27.325);
33
+ --secondary: oklch(0.965 0.005 255);
34
+ --secondary-foreground: oklch(0.25 0.02 260);
35
+ --muted: oklch(0.965 0.005 255);
36
+ --muted-foreground: oklch(0.5 0.02 258);
37
+ --accent: oklch(0.955 0.01 255);
38
+ --accent-foreground: oklch(0.25 0.02 260);
39
+ --destructive: oklch(0.53 0.21 27.325);
36
40
  --destructive-foreground: oklch(0.985 0 0);
37
- --border: oklch(0.922 0 0);
38
- --input: oklch(0.922 0 0);
39
- --ring: oklch(0.708 0 0);
40
- --radius: 0.625rem;
41
-
42
- --chart-1: hsl(221 83% 53%);
43
- --chart-2: hsl(160 60% 45%);
44
- --chart-3: hsl(31 90% 55%);
45
- --chart-4: hsl(280 65% 60%);
46
- --chart-5: hsl(340 75% 55%);
47
-
48
- --sidebar: oklch(0.985 0 0);
49
- --sidebar-foreground: oklch(0.145 0 0);
50
- --sidebar-primary: oklch(0.205 0 0);
51
- --sidebar-primary-foreground: oklch(0.985 0 0);
52
- --sidebar-accent: oklch(0.97 0 0);
53
- --sidebar-accent-foreground: oklch(0.205 0 0);
54
- --sidebar-border: oklch(0.922 0 0);
55
- --sidebar-ring: oklch(0.708 0 0);
56
-
57
- /* Slides (@squadbase/vantage/slide).
58
- These are aliases, not values. Custom properties resolve lazily, so
59
- pointing them at the tokens above is enough for a deck to follow `.dark`
60
- and `[data-theme="dark"]` on its own — restating them in the dark block
61
- below would create two places to keep in step for no gain. A deck
62
- overrides any of them inline through `<SlideDeck theme>`. */
63
- --slide-bg: var(--background);
64
- --slide-fg: var(--foreground);
65
- --slide-accent: var(--primary);
66
- --slide-muted: var(--muted-foreground);
67
- --slide-radius: var(--radius);
68
- /* A system stack that includes Japanese. The pptx export rasterises through
69
- an SVG `foreignObject`, where locally installed families resolve by name
70
- but webfonts must be inlined — so a system default is what makes the
71
- common path export correctly with nothing embedded. */
72
- --slide-font-display:
73
- system-ui, -apple-system, "Hiragino Kaku Gothic ProN", "Hiragino Sans", "Yu Gothic", Meiryo,
41
+ --border: oklch(0.915 0.008 255);
42
+ --input: oklch(0.9 0.01 255);
43
+ --ring: oklch(0.7 0.12 262);
44
+ --radius: 0.5rem;
45
+
46
+ /* Card elevation: a hairline-soft shadow in light, none in dark (the border does the work there). */
47
+ --shadow-card: 0 1px 2px 0 oklch(0.2 0.02 260 / 0.06);
48
+
49
+ /* Body typeface: a system stack only (no web font is shipped). Presets may swap
50
+ it; `@theme inline` below points `font-sans` at this variable, so overriding
51
+ the variable also moves the utility (and the `html` rule in `@layer base`).
52
+ Latin system faces carry no kana/kanji, so without Japanese families here the
53
+ browser picks a per-locale fallback (lang="en" -> e.g. thin "Yu Gothic" Regular
54
+ on Windows, or a face without a 500 weight on macOS) and kana render thin.
55
+ List the Japanese system faces explicitly, after the Latin ones. */
56
+ --font-sans:
57
+ ui-sans-serif, system-ui, -apple-system, "Segoe UI", Roboto, "Hiragino Sans", "Hiragino Kaku Gothic ProN", "Noto Sans JP", "Yu Gothic UI", Meiryo,
74
58
  sans-serif;
75
- --slide-font-body: var(--slide-font-display);
76
- /* Canvas pixels, on the 1920x1080 canvas — not rem: a slide is scaled as a
77
- whole, so its type must not also follow the browser's root font size. */
78
- --slide-size-hero: 168px;
79
- --slide-size-body: 36px;
80
59
 
81
- /* Documents (@squadbase/vantage/doc). Aliases, like --slide-*: they follow
82
- `.dark` through the tokens they point at, so they are not restated in the
83
- dark block. A document overrides any of them inline through
84
- `<Document theme>`, an app through its styles.css. */
85
- --doc-fg: var(--foreground);
86
- --doc-muted: var(--muted-foreground);
87
- --doc-accent: var(--primary);
88
- --doc-border: var(--border);
89
- --doc-subtle: var(--muted);
90
- --doc-font-body: inherit;
91
- --doc-font-heading: var(--doc-font-body);
92
- --doc-font-mono: ui-monospace, SFMono-Regular, Menlo, Consolas, monospace;
93
- --doc-size-body: 1rem;
94
- --doc-line-height: 1.8;
95
- --doc-max-width: 48rem;
60
+ --chart-1: oklch(0.55 0.2 262);
61
+ --chart-2: oklch(0.7 0.14 215);
62
+ --chart-3: oklch(0.6 0.23 295);
63
+ --chart-4: oklch(0.63 0.24 330);
64
+ --chart-5: oklch(0.78 0.19 125);
65
+
66
+ /* Semantic status tokens — see the contract above the `@theme inline` block. */
67
+ --positive: oklch(0.52 0.14 150);
68
+ --positive-subtle: oklch(0.96 0.04 150);
69
+ --negative: oklch(0.53 0.19 25);
70
+ --negative-subtle: oklch(0.96 0.03 25);
71
+ --warning: oklch(0.53 0.12 70);
72
+ --warning-subtle: oklch(0.96 0.05 85);
73
+ --info: oklch(0.52 0.16 255);
74
+ --info-subtle: oklch(0.96 0.03 250);
75
+ --positive-fill: oklch(0.62 0.15 150);
76
+ --negative-fill: oklch(0.62 0.17 25);
77
+ --warning-fill: oklch(0.79 0.16 82);
78
+ --info-fill: oklch(0.62 0.15 250);
79
+ --neutral-fill: oklch(0.62 0 0);
80
+ --neutral: oklch(0.52 0 0);
81
+ --neutral-subtle: oklch(0.96 0 0);
82
+
83
+ --sidebar: oklch(0.985 0.003 255);
84
+ --sidebar-foreground: oklch(0.21 0.02 260);
85
+ --sidebar-primary: oklch(0.55 0.2 262);
86
+ --sidebar-primary-foreground: oklch(0.985 0 0);
87
+ --sidebar-accent: oklch(0.955 0.01 255);
88
+ --sidebar-accent-foreground: oklch(0.25 0.02 260);
89
+ --sidebar-border: oklch(0.915 0.008 255);
90
+ --sidebar-ring: oklch(0.7 0.12 262);
96
91
  }
97
92
 
98
93
  .dark,
99
94
  [data-theme="dark"] {
100
95
  color-scheme: dark;
101
96
 
102
- --background: oklch(0.145 0 0);
103
- --foreground: oklch(0.985 0 0);
104
- --card: oklch(0.205 0 0);
105
- --card-foreground: oklch(0.985 0 0);
106
- --popover: oklch(0.205 0 0);
107
- --popover-foreground: oklch(0.985 0 0);
108
- --primary: oklch(0.922 0 0);
109
- --primary-foreground: oklch(0.205 0 0);
110
- --secondary: oklch(0.269 0 0);
111
- --secondary-foreground: oklch(0.985 0 0);
112
- --muted: oklch(0.269 0 0);
113
- --muted-foreground: oklch(0.708 0 0);
114
- --accent: oklch(0.269 0 0);
115
- --accent-foreground: oklch(0.985 0 0);
97
+ --shadow-card: none;
98
+
99
+ --background: oklch(0.16 0.012 262);
100
+ --foreground: oklch(0.96 0.005 255);
101
+ --card: oklch(0.215 0.015 262);
102
+ --card-foreground: oklch(0.96 0.005 255);
103
+ --popover: oklch(0.235 0.016 262);
104
+ --popover-foreground: oklch(0.96 0.005 255);
105
+ --primary: oklch(0.68 0.19 262);
106
+ --primary-foreground: oklch(0.145 0.02 262);
107
+ --secondary: oklch(0.27 0.016 262);
108
+ --secondary-foreground: oklch(0.96 0.005 255);
109
+ --muted: oklch(0.27 0.016 262);
110
+ --muted-foreground: oklch(0.72 0.02 258);
111
+ --accent: oklch(0.3 0.02 262);
112
+ --accent-foreground: oklch(0.96 0.005 255);
116
113
  --destructive: oklch(0.704 0.191 22.216);
117
114
  --destructive-foreground: oklch(0.985 0 0);
118
115
  --border: oklch(1 0 0 / 10%);
119
116
  --input: oklch(1 0 0 / 15%);
120
- --ring: oklch(0.556 0 0);
121
-
122
- --chart-1: hsl(217 91% 60%);
123
- --chart-2: hsl(160 60% 45%);
124
- --chart-3: hsl(31 90% 55%);
125
- --chart-4: hsl(280 65% 65%);
126
- --chart-5: hsl(340 75% 60%);
127
-
128
- --sidebar: oklch(0.205 0 0);
129
- --sidebar-foreground: oklch(0.985 0 0);
130
- --sidebar-primary: oklch(0.488 0.243 264.376);
117
+ --ring: oklch(0.6 0.15 262);
118
+
119
+ --chart-1: oklch(0.55 0.2 262);
120
+ --chart-2: oklch(0.76 0.14 215);
121
+ --chart-3: oklch(0.68 0.2 295);
122
+ --chart-4: oklch(0.7 0.22 330);
123
+ --chart-5: oklch(0.82 0.18 125);
124
+
125
+ --positive: oklch(0.76 0.15 150);
126
+ --positive-subtle: oklch(0.27 0.05 150);
127
+ --negative: oklch(0.74 0.15 22);
128
+ --negative-subtle: oklch(0.27 0.06 25);
129
+ --warning: oklch(0.8 0.14 80);
130
+ --warning-subtle: oklch(0.27 0.05 75);
131
+ --info: oklch(0.75 0.12 250);
132
+ --info-subtle: oklch(0.27 0.06 255);
133
+ --positive-fill: oklch(0.56 0.13 150);
134
+ --negative-fill: oklch(0.56 0.15 22);
135
+ --warning-fill: oklch(0.73 0.145 78);
136
+ --info-fill: oklch(0.56 0.13 250);
137
+ --neutral-fill: oklch(0.56 0 0);
138
+ --neutral: oklch(0.85 0 0);
139
+ --neutral-subtle: oklch(0.27 0 0);
140
+
141
+ --sidebar: oklch(0.2 0.014 262);
142
+ --sidebar-foreground: oklch(0.96 0.005 255);
143
+ --sidebar-primary: oklch(0.68 0.19 262);
131
144
  --sidebar-primary-foreground: oklch(0.985 0 0);
132
- --sidebar-accent: oklch(0.269 0 0);
133
- --sidebar-accent-foreground: oklch(0.985 0 0);
145
+ --sidebar-accent: oklch(0.3 0.02 262);
146
+ --sidebar-accent-foreground: oklch(0.96 0.005 255);
134
147
  --sidebar-border: oklch(1 0 0 / 10%);
135
- --sidebar-ring: oklch(0.556 0 0);
148
+ --sidebar-ring: oklch(0.6 0.15 262);
136
149
  }
137
150
 
151
+ /* Semantic status tokens (increase/decrease/status). Every increase, decrease
152
+ and status colour in registry/ comes from these — never a Tailwind palette
153
+ colour like `green-500` (tests/raw-colors.test.ts enforces it).
154
+ --<tone> text colour on --background, --card and --<tone>-subtle
155
+ (>= 4.5:1), and dot / line / icon colour (>= 3:1).
156
+ --<tone>-subtle tinted background behind --<tone> text (badges, callouts).
157
+ --<tone>-fill (incl. --neutral-fill, the grey area) FILL colour for areas (bars, heatmap cells, tracker blocks). Not for
158
+ text or icons — use --<tone>. Same lightness step from the page in both
159
+ modes (light 0.62 / dark 0.56: ~0.36-0.40 OKLCH L away from --background,
160
+ >= 3:1 against --background and --card), so a fill is never strong in one
161
+ mode and faint in the other. Presets do not override it.
162
+ --warning-fill is the exception: amber (light 0.79 / dark 0.73, ~#f5b324 / ~#d99a1e) is
163
+ a light colour by nature, so it is ~2:1 on the light page (still >= 0.18 L away)
164
+ and ~7-8:1 on the dark one; dark text (--foreground in light, --background in dark) sits on it at >= 4.5:1.
165
+ Tones: positive (green), negative (red), warning (amber), info (blue),
166
+ neutral (grey). Colour never carries the meaning alone — pair it with an
167
+ arrow or sign. `npm run contrast` prints the measured ratios. */
138
168
  @theme inline {
139
169
  --color-background: var(--background);
140
170
  --color-foreground: var(--foreground);
@@ -155,6 +185,21 @@
155
185
  --color-border: var(--border);
156
186
  --color-input: var(--input);
157
187
  --color-ring: var(--ring);
188
+ --color-positive: var(--positive);
189
+ --color-positive-subtle: var(--positive-subtle);
190
+ --color-negative: var(--negative);
191
+ --color-negative-subtle: var(--negative-subtle);
192
+ --color-warning: var(--warning);
193
+ --color-warning-subtle: var(--warning-subtle);
194
+ --color-info: var(--info);
195
+ --color-info-subtle: var(--info-subtle);
196
+ --color-positive-fill: var(--positive-fill);
197
+ --color-negative-fill: var(--negative-fill);
198
+ --color-warning-fill: var(--warning-fill);
199
+ --color-info-fill: var(--info-fill);
200
+ --color-neutral-fill: var(--neutral-fill);
201
+ --color-neutral: var(--neutral);
202
+ --color-neutral-subtle: var(--neutral-subtle);
158
203
  --color-chart-1: var(--chart-1);
159
204
  --color-chart-2: var(--chart-2);
160
205
  --color-chart-3: var(--chart-3);
@@ -168,10 +213,7 @@
168
213
  --color-sidebar-accent-foreground: var(--sidebar-accent-foreground);
169
214
  --color-sidebar-border: var(--sidebar-border);
170
215
  --color-sidebar-ring: var(--sidebar-ring);
171
- --color-slide-bg: var(--slide-bg);
172
- --color-slide-fg: var(--slide-fg);
173
- --color-slide-accent: var(--slide-accent);
174
- --color-slide-muted: var(--slide-muted);
216
+ --font-sans: var(--font-sans);
175
217
  --radius-sm: calc(var(--radius) - 4px);
176
218
  --radius-md: calc(var(--radius) - 2px);
177
219
  --radius-lg: var(--radius);
@@ -272,6 +314,100 @@
272
314
  }
273
315
  }
274
316
 
317
+ /* ------------------------------------------------------------ utilities */
318
+
319
+ @utility no-scrollbar {
320
+ -ms-overflow-style: none;
321
+ scrollbar-width: none;
322
+
323
+ &::-webkit-scrollbar {
324
+ display: none;
325
+ }
326
+ }
327
+
328
+ /* Icons that must point the other way when the document is right-to-left. */
329
+ .cn-rtl-flip {
330
+ &:where([dir="rtl"], [dir="rtl"] *) {
331
+ transform: scaleX(-1);
332
+ }
333
+ }
334
+
335
+ /* Page defaults live in `@layer base`, like shadcn's own init, so a project's
336
+ `html { @apply font-sans }`, its `next/font` setup and its own border rules
337
+ (all unlayered or later in the layer) win over them instead of losing to an
338
+ unlayered rule here. */
339
+ @layer base {
340
+ html {
341
+ font-family: var(--font-sans);
342
+ }
343
+
344
+ body {
345
+ background-color: var(--background);
346
+ color: var(--foreground);
347
+ -webkit-font-smoothing: antialiased;
348
+ }
349
+
350
+ * {
351
+ border-color: var(--border);
352
+ }
353
+ }
354
+
355
+ /**
356
+ * Vantage framework styles: the slide / document tokens and the document
357
+ * typesetting. The UI parts' tokens live in SquadKit
358
+ * (packages/squadkit/registry/theme/theme.css); scripts/gen-theme.mjs appends
359
+ * this file to them to produce packages/vantage/theme.css.
360
+ */
361
+
362
+ :root {
363
+ /* Slides (@squadbase/vantage/slide).
364
+ These are aliases, not values. Custom properties resolve lazily, so
365
+ pointing them at the tokens above is enough for a deck to follow `.dark`
366
+ and `[data-theme="dark"]` on its own — restating them in the dark block
367
+ below would create two places to keep in step for no gain. A deck
368
+ overrides any of them inline through `<SlideDeck theme>`. */
369
+ --slide-bg: var(--background);
370
+ --slide-fg: var(--foreground);
371
+ --slide-accent: var(--primary);
372
+ --slide-muted: var(--muted-foreground);
373
+ --slide-radius: var(--radius);
374
+ /* A system stack that includes Japanese. The pptx export rasterises through
375
+ an SVG `foreignObject`, where locally installed families resolve by name
376
+ but webfonts must be inlined — so a system default is what makes the
377
+ common path export correctly with nothing embedded. */
378
+ --slide-font-display:
379
+ system-ui, -apple-system, "Hiragino Kaku Gothic ProN", "Hiragino Sans", "Yu Gothic", Meiryo,
380
+ sans-serif;
381
+ --slide-font-body: var(--slide-font-display);
382
+ /* Canvas pixels, on the 1920x1080 canvas — not rem: a slide is scaled as a
383
+ whole, so its type must not also follow the browser's root font size. */
384
+ --slide-size-hero: 168px;
385
+ --slide-size-body: 36px;
386
+
387
+ /* Documents (@squadbase/vantage/doc). Aliases, like --slide-*: they follow
388
+ `.dark` through the tokens they point at, so they are not restated in the
389
+ dark block. A document overrides any of them inline through
390
+ `<Document theme>`, an app through its styles.css. */
391
+ --doc-fg: var(--foreground);
392
+ --doc-muted: var(--muted-foreground);
393
+ --doc-accent: var(--primary);
394
+ --doc-border: var(--border);
395
+ --doc-subtle: var(--muted);
396
+ --doc-font-body: inherit;
397
+ --doc-font-heading: var(--doc-font-body);
398
+ --doc-font-mono: ui-monospace, SFMono-Regular, Menlo, Consolas, monospace;
399
+ --doc-size-body: 1rem;
400
+ --doc-line-height: 1.8;
401
+ --doc-max-width: 48rem;
402
+ }
403
+
404
+ @theme inline {
405
+ --color-slide-bg: var(--slide-bg);
406
+ --color-slide-fg: var(--slide-fg);
407
+ --color-slide-accent: var(--slide-accent);
408
+ --color-slide-muted: var(--slide-muted);
409
+ }
410
+
275
411
  /* ------------------------------------------------------------ documents */
276
412
 
277
413
  /* Typesetting for `<Document>`. Plain elements inside it need no classes.
@@ -440,38 +576,3 @@
440
576
  overflow: visible;
441
577
  }
442
578
  }
443
-
444
- /* ------------------------------------------------------------ utilities */
445
-
446
- @utility no-scrollbar {
447
- -ms-overflow-style: none;
448
- scrollbar-width: none;
449
-
450
- &::-webkit-scrollbar {
451
- display: none;
452
- }
453
- }
454
-
455
- /* Icons that must point the other way when the document is right-to-left. */
456
- .cn-rtl-flip {
457
- &:where([dir="rtl"], [dir="rtl"] *) {
458
- transform: scaleX(-1);
459
- }
460
- }
461
-
462
- body {
463
- background-color: var(--background);
464
- color: var(--foreground);
465
- /* Latin system faces carry no kana/kanji, so without Japanese families here the
466
- browser picks a per-locale fallback (lang="en" → e.g. thin "Yu Gothic" Regular
467
- on Windows, or a face without a 500 weight on macOS) and kana render thin.
468
- List the Japanese system faces explicitly, after the Latin ones. */
469
- font-family:
470
- ui-sans-serif, system-ui, -apple-system, "Segoe UI", Roboto, "Hiragino Sans", "Hiragino Kaku Gothic ProN", "Noto Sans JP", "Yu Gothic UI", Meiryo,
471
- sans-serif;
472
- -webkit-font-smoothing: antialiased;
473
- }
474
-
475
- * {
476
- border-color: var(--border);
477
- }
@@ -1 +0,0 @@
1
- {"version":3,"sources":["../src/ui/states.tsx"],"names":[],"mappings":";;;;AAGO,SAAS,OAAA,CAAQ,EAAE,KAAA,GAAQ,eAAA,EAAY,WAAU,EAA2C;AACjG,EAAA,uBACE,GAAA,CAAC,KAAA,EAAA,EAAI,SAAA,EAAW,EAAA,CAAG,iDAAiD,SAAS,CAAA,EAAG,IAAA,EAAK,QAAA,EAAS,WAAA,EAAU,QAAA,EACtG,QAAA,kBAAA,IAAA,CAAC,KAAA,EAAA,EAAI,WAAU,uDAAA,EACb,QAAA,EAAA;AAAA,oBAAA,GAAA,CAAC,MAAA,EAAA,EAAK,WAAU,gFAAA,EAAiF,CAAA;AAAA,IAChG;AAAA,GAAA,EACH,CAAA,EACF,CAAA;AAEJ;AAEO,SAAS,KAAA,CAAM;AAAA,EACpB,KAAA,GAAQ,kBAAA;AAAA,EACR,WAAA;AAAA,EACA,IAAA;AAAA,EACA,MAAA;AAAA,EACA;AACF,CAAA,EAMG;AACD,EAAA,4BACG,KAAA,EAAA,EAAI,SAAA,EAAW,EAAA,CAAG,kEAAA,EAAoE,SAAS,CAAA,EAC7F,QAAA,EAAA;AAAA,IAAA,IAAA,mBAAO,GAAA,CAAC,KAAA,EAAA,EAAI,SAAA,EAAU,gCAAA,EAAkC,gBAAK,CAAA,GAAS,IAAA;AAAA,oBACvE,GAAA,CAAC,GAAA,EAAA,EAAE,SAAA,EAAU,aAAA,EAAe,QAAA,EAAA,KAAA,EAAM,CAAA;AAAA,IACjC,8BAAc,GAAA,CAAC,GAAA,EAAA,EAAE,SAAA,EAAU,wCAAA,EAA0C,uBAAY,CAAA,GAAO,IAAA;AAAA,IACxF,yBAAS,GAAA,CAAC,KAAA,EAAA,EAAI,SAAA,EAAU,MAAA,EAAQ,kBAAO,CAAA,GAAS;AAAA,GAAA,EACnD,CAAA;AAEJ;AAEO,SAAS,UAAA,CAAW;AAAA,EACzB,KAAA,GAAQ,sBAAA;AAAA,EACR,OAAA;AAAA,EACA,MAAA;AAAA,EACA;AACF,CAAA,EAKG;AACD,EAAA,uBACE,IAAA;AAAA,IAAC,KAAA;AAAA,IAAA;AAAA,MACC,SAAA,EAAW,EAAA,CAAG,8DAAA,EAAgE,SAAS,CAAA;AAAA,MACvF,IAAA,EAAK,OAAA;AAAA,MAEL,QAAA,EAAA;AAAA,wBAAA,GAAA,CAAC,GAAA,EAAA,EAAE,SAAA,EAAU,gCAAA,EAAkC,QAAA,EAAA,KAAA,EAAM,CAAA;AAAA,QACpD,0BAAU,GAAA,CAAC,GAAA,EAAA,EAAE,SAAA,EAAU,oCAAA,EAAsC,mBAAQ,CAAA,GAAO,IAAA;AAAA,QAC5E,yBAAS,GAAA,CAAC,KAAA,EAAA,EAAI,SAAA,EAAU,MAAA,EAAQ,kBAAO,CAAA,GAAS;AAAA;AAAA;AAAA,GACnD;AAEJ","file":"chunk-5ZOP4SQR.js","sourcesContent":["import type { ReactNode } from \"react\"\nimport { cn } from \"./cn\"\n\nexport function Loading({ label = \"Loading…\", className }: { label?: string; className?: string }) {\n return (\n <div className={cn(\"flex min-h-[30vh] items-center justify-center\", className)} role=\"status\" aria-live=\"polite\">\n <div className=\"flex items-center gap-3 text-sm text-muted-foreground\">\n <span className=\"h-4 w-4 animate-spin rounded-full border-2 border-current border-t-transparent\" />\n {label}\n </div>\n </div>\n )\n}\n\nexport function Empty({\n title = \"Nothing here yet\",\n description,\n icon,\n action,\n className,\n}: {\n title?: string\n description?: string\n icon?: ReactNode\n action?: ReactNode\n className?: string\n}) {\n return (\n <div className={cn(\"flex flex-col items-center justify-center gap-2 p-10 text-center\", className)}>\n {icon ? <div className=\"text-3xl text-muted-foreground\">{icon}</div> : null}\n <p className=\"font-medium\">{title}</p>\n {description ? <p className=\"max-w-sm text-sm text-muted-foreground\">{description}</p> : null}\n {action ? <div className=\"mt-2\">{action}</div> : null}\n </div>\n )\n}\n\nexport function ErrorState({\n title = \"Something went wrong\",\n message,\n action,\n className,\n}: {\n title?: string\n message?: ReactNode\n action?: ReactNode\n className?: string\n}) {\n return (\n <div\n className={cn(\"rounded-xl border border-destructive/30 bg-destructive/5 p-6\", className)}\n role=\"alert\"\n >\n <p className=\"font-semibold text-destructive\">{title}</p>\n {message ? <p className=\"mt-1 text-sm text-muted-foreground\">{message}</p> : null}\n {action ? <div className=\"mt-3\">{action}</div> : null}\n </div>\n )\n}\n"]}
@@ -1 +0,0 @@
1
- {"version":3,"sources":["../src/ui/cn.ts"],"names":[],"mappings":";;;;;AAUO,SAAS,MAAM,MAAA,EAA8B;AAClD,EAAA,OAAO,OAAA,CAAQ,IAAA,CAAK,MAAM,CAAC,CAAA;AAC7B","file":"chunk-A2UUGASH.js","sourcesContent":["/**\n * Class merger used by every component in the kit. `clsx` resolves conditional\n * class values, `tailwind-merge` drops the earlier of two conflicting Tailwind\n * utilities so a caller's `className` always wins over a component default.\n */\nimport { clsx, type ClassValue } from \"clsx\"\nimport { twMerge } from \"tailwind-merge\"\n\nexport type { ClassValue }\n\nexport function cn(...inputs: ClassValue[]): string {\n return twMerge(clsx(inputs))\n}\n"]}