kaze-design-system 0.6.0 → 0.7.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (74) hide show
  1. package/README.md +54 -9
  2. package/components.css +476 -0
  3. package/dist/components/Alert/Alert.js +7 -16
  4. package/dist/components/Badge/Badge.js +1 -6
  5. package/dist/components/BarChart/BarChart.js +19 -15
  6. package/dist/components/BarList/BarList.js +2 -16
  7. package/dist/components/Card/Card.js +5 -3
  8. package/dist/components/CategoryBar/CategoryBar.js +88 -0
  9. package/dist/components/ChartLegend/ChartLegend.js +43 -0
  10. package/dist/components/Checkbox/Checkbox.js +1 -10
  11. package/dist/components/ColumnChart/ColumnChart.js +290 -0
  12. package/dist/components/CommandPalette/CommandPalette.js +3 -9
  13. package/dist/components/DescriptionList/DescriptionList.js +11 -14
  14. package/dist/components/Dialog/Dialog.js +1 -10
  15. package/dist/components/Disclosure/Disclosure.js +1 -4
  16. package/dist/components/DonutChart/DonutChart.js +54 -50
  17. package/dist/components/Dropdown/Dropdown.js +2 -11
  18. package/dist/components/FAQ/FAQ.js +36 -46
  19. package/dist/components/FeatureGrid/FeatureGrid.js +1 -5
  20. package/dist/components/FilterPill/FilterPill.js +1 -5
  21. package/dist/components/FormField/FormField.js +2 -15
  22. package/dist/components/Grid/Grid.js +1 -9
  23. package/dist/components/Heatmap/Heatmap.js +255 -0
  24. package/dist/components/HelpButton/HelpButton.js +1 -9
  25. package/dist/components/LPFooter/LPFooter.js +1 -10
  26. package/dist/components/LineChart/LineChart.js +314 -0
  27. package/dist/components/List/List.js +2 -15
  28. package/dist/components/Logo/Logo.js +1 -10
  29. package/dist/components/Meter/Meter.js +1 -4
  30. package/dist/components/Metric/Metric.js +2 -17
  31. package/dist/components/Navbar/Navbar.js +2 -10
  32. package/dist/components/NumberField/NumberField.js +30 -7
  33. package/dist/components/Pagination/Pagination.js +37 -46
  34. package/dist/components/Pricing/Pricing.js +2 -17
  35. package/dist/components/Progress/Progress.js +3 -18
  36. package/dist/components/Radio/Radio.js +2 -14
  37. package/dist/components/Search/Search.js +10 -1
  38. package/dist/components/Section/Section.js +4 -12
  39. package/dist/components/SegmentedControl/SegmentedControl.js +120 -0
  40. package/dist/components/Sidebar/Sidebar.js +7 -31
  41. package/dist/components/SplitSection/SplitSection.js +1 -5
  42. package/dist/components/StatusBadge/StatusBadge.js +1 -11
  43. package/dist/components/Stepper/Stepper.js +29 -27
  44. package/dist/components/Table/Table.js +5 -3
  45. package/dist/components/Tabs/Tabs.js +29 -36
  46. package/dist/components/Testimonial/Testimonial.js +19 -23
  47. package/dist/components/Text/Text.js +1 -11
  48. package/dist/components/Toast/Toast.js +103 -116
  49. package/dist/components/Tooltip/Tooltip.js +89 -92
  50. package/dist/components/TopBar/TopBar.js +4 -12
  51. package/dist/hooks/useLegendToggle.js +1 -4
  52. package/dist/hooks/useTheme.js +1 -4
  53. package/dist/index.js +12 -0
  54. package/dist/lib/chartScale.js +38 -0
  55. package/dist/types/components/CategoryBar/CategoryBar.d.ts +28 -0
  56. package/dist/types/components/CategoryBar/index.d.ts +2 -0
  57. package/dist/types/components/ChartLegend/ChartLegend.d.ts +17 -0
  58. package/dist/types/components/ChartLegend/index.d.ts +2 -0
  59. package/dist/types/components/ColumnChart/ColumnChart.d.ts +33 -0
  60. package/dist/types/components/ColumnChart/index.d.ts +2 -0
  61. package/dist/types/components/Dropdown/Dropdown.d.ts +2 -3
  62. package/dist/types/components/Heatmap/Heatmap.d.ts +49 -0
  63. package/dist/types/components/Heatmap/index.d.ts +2 -0
  64. package/dist/types/components/LineChart/LineChart.d.ts +40 -0
  65. package/dist/types/components/LineChart/index.d.ts +2 -0
  66. package/dist/types/components/SegmentedControl/SegmentedControl.d.ts +21 -0
  67. package/dist/types/components/SegmentedControl/index.d.ts +2 -0
  68. package/dist/types/components/Sidebar/index.d.ts +1 -1
  69. package/dist/types/components/Toast/Toast.d.ts +1 -1
  70. package/dist/types/components/index.d.ts +13 -1
  71. package/dist/types/hooks/useTheme.d.ts +1 -1
  72. package/dist/types/lib/chartScale.d.ts +19 -0
  73. package/dist/types/lib/utils.d.ts +1 -1
  74. package/package.json +7 -3
package/README.md CHANGED
@@ -3,9 +3,9 @@
3
3
  [![npm version](https://img.shields.io/npm/v/kaze-design-system)](https://www.npmjs.com/package/kaze-design-system)
4
4
  [![GitHub](https://img.shields.io/github/license/yuki930/kaze-design-system)](https://github.com/yuki930/kaze-design-system/blob/main/LICENSE)
5
5
 
6
- **Kaze (風)** は、管理画面・ダッシュボード・金融系アプリのための React デザインシステムです。**白と温かみのあるグレーを基調にした静かな配色**と、日本語組版への丁寧な最適化(PALT・和欧混植・読みやすい行間)、そしてコピペで完結する 63 のコンポーネントを 1 パッケージにまとめています。派手な色や装飾ではなく「読みやすさ」「情報密度」「長時間見続けても疲れないこと」を設計の中心に置いています。
6
+ **Kaze (風)** は、管理画面・ダッシュボード・金融系アプリのための React デザインシステムです。**白と温かみのあるグレーを基調にした静かな配色**と、日本語組版への丁寧な最適化(PALT・和欧混植・読みやすい行間)、そしてコピペで完結する 69 のコンポーネントを 1 パッケージにまとめています。派手な色や装飾ではなく「読みやすさ」「情報密度」「長時間見続けても疲れないこと」を設計の中心に置いています。
7
7
 
8
- - **63 コンポーネント**: フォーム、テーブル、チャート、ダッシュボード UI、ランディングページ、マーケティングパーツまで
8
+ - **69 コンポーネント**: フォーム、テーブル、依存ゼロの SVG チャート(折れ線・縦棒・ヒートマップ等)、ダッシュボード UI、ランディングページ、マーケティングパーツまで
9
9
  - **日本語組版に最適化**: PALT グローバル適用、和欧混植、括弧ツメ、適切な line-height
10
10
  - **ライト / ダーク両対応**: `data-theme` 属性で切替、`prefers-color-scheme` 連動
11
11
  - **素の CSS + カスケードレイヤー**: `@layer tokens, reset, components, utilities` でカスケード管理、Tailwind/CSS-in-JS 不要
@@ -57,7 +57,7 @@ AI コーディングアシスタントは以下のファイルからライブ
57
57
  - **Short index**: https://kaze-design-system.vercel.app/llms.txt
58
58
  - **Full API reference**: https://kaze-design-system.vercel.app/llms-full.txt
59
59
 
60
- `llms-full.txt` には 63 コンポーネントの `Props` / `Usage` / カテゴリが機械可読形式で含まれており、Storybook を参照しなくても正確なコード提案が可能です。[llmstxt.org](https://llmstxt.org) 準拠。
60
+ `llms-full.txt` には 69 コンポーネントの `Props` / `Usage` / カテゴリが機械可読形式で含まれており、Storybook を参照しなくても正確なコード提案が可能です。[llmstxt.org](https://llmstxt.org) 準拠。
61
61
 
62
62
  ## インストール
63
63
 
@@ -122,7 +122,7 @@ function App() {
122
122
  kaze は1パッケージ・3レイヤーで構成されています。
123
123
 
124
124
  - **Foundation**: デザイントークン(カラー・タイポグラフィ・スペーシング)と CSS。両レイヤー共通の土台
125
- - **Application UI**: 管理画面・アプリ向けの52コンポーネント。`kaze-design-system` から import
125
+ - **Application UI**: 管理画面・アプリ向けの58コンポーネント。`kaze-design-system` から import
126
126
  - **Marketing**: LP・キャンペーンページ向けの11コンポーネント。`kaze-design-system/marketing` から import
127
127
 
128
128
  ```tsx
@@ -133,15 +133,15 @@ import { Table, Sidebar, CommandPalette } from "kaze-design-system";
133
133
  import { Hero, PricingGrid, CTABanner } from "kaze-design-system/marketing";
134
134
  ```
135
135
 
136
- ## コンポーネント一覧(63 コンポーネント)
136
+ ## コンポーネント一覧(69 コンポーネント)
137
137
 
138
- ### Application UI(52)
138
+ ### Application UI(58)
139
139
 
140
140
  | カテゴリ | コンポーネント |
141
141
  |---|---|
142
- | **フォーム** | Button, FAB, Input, NumberField, Select, Checkbox, Radio, Textarea, Switch, FormField, FilterPill |
142
+ | **フォーム** | Button, FAB, Input, NumberField, Select, Checkbox, Radio, Textarea, Switch, FormField, FilterPill, SegmentedControl |
143
143
  | **データ表示** | Card, Badge, StatusBadge, Table, Metric, Avatar, BarList, Tracker, Watermark |
144
- | **チャート** | BarChart, DonutChart, Sparkline |
144
+ | **チャート** | BarChart, DonutChart, Sparkline, LineChart, ColumnChart, Heatmap, CategoryBar, ChartLegend |
145
145
  | **フィードバック** | Alert, Progress, Meter, Skeleton, EmptyState, Toast |
146
146
  | **ナビゲーション** | Tabs, Sidebar, TopBar, Breadcrumb, Pagination, Stepper, Disclosure |
147
147
  | **オーバーレイ** | Dialog, Tooltip, HelpButton, Dropdown, CommandPalette |
@@ -156,6 +156,51 @@ import { Hero, PricingGrid, CTABanner } from "kaze-design-system/marketing";
156
156
 
157
157
  詳細は [kaze-design-system.vercel.app/docs/components](https://kaze-design-system.vercel.app/docs/components) を参照してください。
158
158
 
159
+ ## チャート
160
+
161
+ チャートはすべて SVG の手書き実装で、追加の依存はありません(recharts 等は不要)。色は `--chart-*` トークンを使うので、ダークモードとパレット切り替えに自動で追従します。
162
+
163
+ | コンポーネント | 用途 |
164
+ |---|---|
165
+ | `LineChart` | 時系列の折れ線 / 面グラフ。複数系列、欠損値、ホバーとキーボードのツールチップ |
166
+ | `ColumnChart` | 縦棒グラフ。グループ / 積み上げ、負の値 |
167
+ | `BarChart` | 横棒のランキング |
168
+ | `DonutChart` | 構成比のドーナツ |
169
+ | `CategoryBar` | 構成比を 1 本の帯で。目標線マーカー付き |
170
+ | `Heatmap` | 曜日×時間などの行列、日別カレンダー |
171
+ | `Sparkline` | 表やカードに埋め込む小さな推移 |
172
+ | `ChartLegend` | 系列の表示 / 非表示を切り替える凡例 |
173
+ | `SegmentedControl` | 期間(1W / 1M / 1Y)や表示の切り替え |
174
+
175
+ ```tsx
176
+ import { LineChart, SegmentedControl } from "kaze-design-system";
177
+
178
+ <SegmentedControl
179
+ aria-label="期間"
180
+ options={[
181
+ { value: "1m", label: "1M" },
182
+ { value: "3m", label: "3M" },
183
+ { value: "1y", label: "1Y" },
184
+ ]}
185
+ defaultValue="3m"
186
+ />
187
+ <LineChart
188
+ aria-label="月別の売上と利用者数"
189
+ index="month"
190
+ data={[
191
+ { month: "4月", sales: 320, users: 210 },
192
+ { month: "5月", sales: 340, users: 230 },
193
+ { month: "6月", sales: 310, users: 245 },
194
+ ]}
195
+ series={[
196
+ { key: "sales", label: "売上(万円)" },
197
+ { key: "users", label: "利用者数(人)" },
198
+ ]}
199
+ curve="monotone"
200
+ area
201
+ />
202
+ ```
203
+
159
204
  ## Hooks
160
205
 
161
206
  ```tsx
@@ -169,7 +214,7 @@ import { useFocusTrap, useLegendToggle } from "kaze-design-system/hooks";
169
214
 
170
215
  ## バンドルサイズ
171
216
 
172
- 63 コンポーネント全部込みで **JS 38 kB gzip + CSS 23 kB gzip ≒ 61 kB gz**。ただし、個別 import すれば使った分だけが bundle に入ります。
217
+ 63 コンポーネント時点の計測で **JS 38 kB gzip + CSS 23 kB gzip ≒ 61 kB gz**。ただし、個別 import すれば使った分だけが bundle に入ります。
173
218
 
174
219
  | 区分 | 生サイズ | gzip |
175
220
  |---|---:|---:|
package/components.css CHANGED
@@ -2891,6 +2891,482 @@
2891
2891
  font-variant-numeric: tabular-nums;
2892
2892
  }
2893
2893
 
2894
+ /* ── ChartLegend ─────────────────────────────────────────── */
2895
+ .chart-legend {
2896
+ display: flex;
2897
+ flex-wrap: wrap;
2898
+ gap: var(--space-1) var(--space-4);
2899
+ font-size: var(--font-size-xs);
2900
+ }
2901
+
2902
+ .chart-legend__item {
2903
+ display: inline-flex;
2904
+ align-items: center;
2905
+ gap: var(--space-1-5);
2906
+ padding: 0;
2907
+ background: none;
2908
+ border: none;
2909
+ color: var(--color-fg-secondary);
2910
+ font: inherit;
2911
+ transition: opacity var(--duration-normal) var(--ease-default);
2912
+ }
2913
+
2914
+ button.chart-legend__item {
2915
+ cursor: pointer;
2916
+ border-radius: var(--radius-sm);
2917
+ }
2918
+
2919
+ button.chart-legend__item:hover {
2920
+ color: var(--color-fg);
2921
+ }
2922
+
2923
+ button.chart-legend__item:focus-visible {
2924
+ outline: none;
2925
+ box-shadow: 0 0 0 var(--ring-width) var(--ring-color);
2926
+ }
2927
+
2928
+ .chart-legend__item--hidden {
2929
+ opacity: 0.4;
2930
+ }
2931
+
2932
+ .chart-legend__swatch {
2933
+ width: 8px;
2934
+ height: 8px;
2935
+ border-radius: var(--radius-full);
2936
+ flex-shrink: 0;
2937
+ }
2938
+
2939
+ /* ── Chart primitives (shared by LineChart / ColumnChart / Heatmap) ── */
2940
+ .chart {
2941
+ position: relative;
2942
+ width: 100%;
2943
+ }
2944
+
2945
+ .chart__svg {
2946
+ display: block;
2947
+ width: 100%;
2948
+ overflow: visible;
2949
+ }
2950
+
2951
+ .chart-grid line {
2952
+ stroke: var(--color-border-subtle);
2953
+ stroke-width: 1;
2954
+ shape-rendering: crispEdges;
2955
+ }
2956
+
2957
+ .chart-axis text {
2958
+ fill: var(--color-fg-tertiary);
2959
+ font-size: var(--font-size-xs);
2960
+ font-variant-numeric: tabular-nums;
2961
+ }
2962
+
2963
+ .chart-axis line {
2964
+ stroke: var(--color-border);
2965
+ shape-rendering: crispEdges;
2966
+ }
2967
+
2968
+ .chart-crosshair {
2969
+ stroke: var(--color-border-strong);
2970
+ stroke-width: 1;
2971
+ stroke-dasharray: 3 3;
2972
+ pointer-events: none;
2973
+ }
2974
+
2975
+ .chart-tooltip {
2976
+ position: absolute;
2977
+ z-index: var(--z-tooltip);
2978
+ min-width: 8rem;
2979
+ padding: var(--space-2) var(--space-3);
2980
+ background: var(--color-surface);
2981
+ color: var(--color-fg);
2982
+ border: 1px solid var(--color-border);
2983
+ border-radius: var(--radius-md);
2984
+ box-shadow: var(--shadow-md);
2985
+ font-size: var(--font-size-xs);
2986
+ pointer-events: none;
2987
+ white-space: nowrap;
2988
+ }
2989
+
2990
+ .chart-tooltip__title {
2991
+ margin-bottom: var(--space-1);
2992
+ font-weight: var(--font-weight-medium);
2993
+ color: var(--color-fg-secondary);
2994
+ }
2995
+
2996
+ .chart-tooltip__row {
2997
+ display: flex;
2998
+ align-items: center;
2999
+ gap: var(--space-2);
3000
+ }
3001
+
3002
+ .chart-tooltip__swatch {
3003
+ width: 8px;
3004
+ height: 8px;
3005
+ border-radius: var(--radius-full);
3006
+ flex-shrink: 0;
3007
+ }
3008
+
3009
+ .chart-tooltip__label {
3010
+ flex: 1;
3011
+ color: var(--color-fg-secondary);
3012
+ }
3013
+
3014
+ .chart-tooltip__value {
3015
+ font-weight: var(--font-weight-medium);
3016
+ font-variant-numeric: tabular-nums;
3017
+ }
3018
+
3019
+ /* ================================================================
3020
+ Chart: LineChart
3021
+ Uses the shared "Chart primitives" (.chart, .chart-grid, .chart-axis,
3022
+ .chart-crosshair, .chart-tooltip). Series color is set via `color`
3023
+ on .line-chart__series and consumed with currentColor.
3024
+ ================================================================ */
3025
+
3026
+ .line-chart {
3027
+ display: flex;
3028
+ flex-direction: column;
3029
+ gap: var(--space-3);
3030
+ width: 100%;
3031
+ }
3032
+
3033
+ .line-chart__svg {
3034
+ touch-action: pan-y;
3035
+ }
3036
+
3037
+ .line-chart__svg:focus-visible {
3038
+ outline: var(--ring-width) solid var(--ring-color);
3039
+ outline-offset: var(--ring-offset);
3040
+ border-radius: var(--radius-sm);
3041
+ }
3042
+
3043
+ .line-chart__line {
3044
+ fill: none;
3045
+ stroke: currentColor;
3046
+ stroke-width: 2;
3047
+ stroke-linecap: round;
3048
+ stroke-linejoin: round;
3049
+ }
3050
+
3051
+ .line-chart__area {
3052
+ fill: currentColor;
3053
+ fill-opacity: 0.12;
3054
+ stroke: none;
3055
+ }
3056
+
3057
+ .line-chart__dot {
3058
+ fill: var(--color-surface);
3059
+ stroke: currentColor;
3060
+ stroke-width: 2;
3061
+ }
3062
+
3063
+ .line-chart__dot--active {
3064
+ fill: currentColor;
3065
+ stroke: var(--color-surface);
3066
+ }
3067
+
3068
+ .line-chart__tooltip {
3069
+ /* position / transform are set inline from the active point */
3070
+ pointer-events: none;
3071
+ }
3072
+
3073
+ /* ── ColumnChart ─────────────────────────────────────────── */
3074
+ .column-chart {
3075
+ display: flex;
3076
+ flex-direction: column;
3077
+ gap: var(--space-3);
3078
+ border-radius: var(--radius-sm);
3079
+ }
3080
+
3081
+ .column-chart__figure:focus-visible {
3082
+ outline: none;
3083
+ box-shadow: 0 0 0 var(--ring-width) var(--ring-color);
3084
+ }
3085
+
3086
+ .column-chart__plot {
3087
+ position: relative;
3088
+ width: 100%;
3089
+ }
3090
+
3091
+ .column-chart__hit {
3092
+ fill: transparent;
3093
+ }
3094
+
3095
+ .column-chart__band {
3096
+ fill: var(--color-surface-active);
3097
+ opacity: 0.5;
3098
+ pointer-events: none;
3099
+ }
3100
+
3101
+ .column-chart__bar {
3102
+ transition: opacity var(--duration-normal) var(--ease-default);
3103
+ }
3104
+
3105
+ .column-chart__total {
3106
+ margin-top: var(--space-1);
3107
+ padding-top: var(--space-1);
3108
+ border-top: 1px solid var(--color-border-subtle);
3109
+ font-weight: var(--font-weight-medium);
3110
+ }
3111
+
3112
+ /* ── Heatmap ── */
3113
+ .heatmap {
3114
+ --heatmap-color: var(--chart-1);
3115
+ --heatmap-cell: 16px;
3116
+ --heatmap-gap: 3px;
3117
+ width: fit-content;
3118
+ max-width: 100%;
3119
+ }
3120
+
3121
+ .heatmap__scroll {
3122
+ overflow-x: auto;
3123
+ padding-block: var(--space-1);
3124
+ }
3125
+
3126
+ .heatmap__grid {
3127
+ display: inline-grid;
3128
+ gap: var(--heatmap-gap);
3129
+ align-items: center;
3130
+ }
3131
+
3132
+ .heatmap__label {
3133
+ font-size: var(--font-size-xs);
3134
+ color: var(--color-fg-tertiary);
3135
+ font-variant-numeric: tabular-nums;
3136
+ line-height: 1;
3137
+ white-space: nowrap;
3138
+ }
3139
+
3140
+ .heatmap__label--row {
3141
+ padding-right: var(--space-2);
3142
+ text-align: right;
3143
+ }
3144
+
3145
+ .heatmap__label--column {
3146
+ text-align: center;
3147
+ overflow: visible;
3148
+ }
3149
+
3150
+ .heatmap__label[hidden] {
3151
+ display: block;
3152
+ visibility: hidden;
3153
+ }
3154
+
3155
+ /* Spans several week columns so "10月" is not clipped by one narrow cell. */
3156
+ .heatmap__label--month {
3157
+ text-align: left;
3158
+ }
3159
+
3160
+ .heatmap__cell {
3161
+ width: var(--heatmap-cell);
3162
+ height: var(--heatmap-cell);
3163
+ border-radius: calc(var(--heatmap-cell) * 0.2);
3164
+ background: var(--color-bg-tertiary);
3165
+ outline: 1px solid transparent;
3166
+ outline-offset: 1px;
3167
+ }
3168
+
3169
+ .heatmap__cell:hover {
3170
+ outline-color: var(--color-fg-secondary);
3171
+ }
3172
+
3173
+ .heatmap__legend {
3174
+ display: flex;
3175
+ align-items: center;
3176
+ justify-content: flex-end;
3177
+ gap: var(--space-1);
3178
+ margin-top: var(--space-2);
3179
+ font-size: var(--font-size-xs);
3180
+ color: var(--color-fg-tertiary);
3181
+ }
3182
+
3183
+ .heatmap__legend > span:first-child {
3184
+ margin-right: var(--space-1);
3185
+ }
3186
+
3187
+ .heatmap__legend > span:last-child {
3188
+ margin-left: var(--space-1);
3189
+ }
3190
+
3191
+ .heatmap__swatch {
3192
+ width: 12px;
3193
+ height: 12px;
3194
+ border-radius: calc(12px * 0.2);
3195
+ }
3196
+
3197
+ .heatmap__tooltip {
3198
+ transform: translate(-50%, calc(-100% - 6px));
3199
+ }
3200
+
3201
+ /* ── CategoryBar ─────────────────────────────────────────── */
3202
+ .category-bar {
3203
+ display: flex;
3204
+ flex-direction: column;
3205
+ gap: var(--space-2);
3206
+ width: 100%;
3207
+ }
3208
+
3209
+ .category-bar__track {
3210
+ position: relative;
3211
+ display: flex;
3212
+ gap: 2px;
3213
+ align-items: center;
3214
+ width: 100%;
3215
+ background: var(--color-bg-tertiary);
3216
+ border-radius: var(--radius-full);
3217
+ }
3218
+
3219
+ .category-bar__segment {
3220
+ flex-basis: 0;
3221
+ min-width: 2px;
3222
+ height: 100%;
3223
+ }
3224
+
3225
+ .category-bar__segment:first-child {
3226
+ border-radius: var(--radius-full) 0 0 var(--radius-full);
3227
+ }
3228
+
3229
+ .category-bar__segment:last-of-type {
3230
+ border-radius: 0 var(--radius-full) var(--radius-full) 0;
3231
+ }
3232
+
3233
+ .category-bar__segment:only-of-type {
3234
+ border-radius: var(--radius-full);
3235
+ }
3236
+
3237
+ .category-bar__marker {
3238
+ position: absolute;
3239
+ top: 50%;
3240
+ width: 2px;
3241
+ background: var(--color-fg);
3242
+ border-radius: var(--radius-full);
3243
+ box-shadow: 0 0 0 1px var(--color-surface);
3244
+ transform: translate(-50%, -50%);
3245
+ }
3246
+
3247
+ .category-bar__legend {
3248
+ display: flex;
3249
+ flex-wrap: wrap;
3250
+ gap: var(--space-1) var(--space-4);
3251
+ margin: 0;
3252
+ padding: 0;
3253
+ list-style: none;
3254
+ font-size: var(--font-size-xs);
3255
+ }
3256
+
3257
+ .category-bar__legend-item {
3258
+ display: inline-flex;
3259
+ align-items: center;
3260
+ gap: var(--space-2);
3261
+ }
3262
+
3263
+ .category-bar__swatch {
3264
+ flex: none;
3265
+ width: 8px;
3266
+ height: 8px;
3267
+ border-radius: var(--radius-full);
3268
+ }
3269
+
3270
+ .category-bar__swatch--marker {
3271
+ width: 2px;
3272
+ height: 12px;
3273
+ background: var(--color-fg);
3274
+ }
3275
+
3276
+ .category-bar__label {
3277
+ color: var(--color-fg-secondary);
3278
+ }
3279
+
3280
+ .category-bar__value {
3281
+ font-weight: var(--font-weight-medium);
3282
+ color: var(--color-fg);
3283
+ font-variant-numeric: tabular-nums;
3284
+ }
3285
+
3286
+ .category-bar__percent {
3287
+ font-weight: var(--font-weight-normal);
3288
+ color: var(--color-fg-secondary);
3289
+ }
3290
+
3291
+ /* ── SegmentedControl ────────────────────────────────────── */
3292
+ .segmented-control {
3293
+ --segmented-control-padding: 2px;
3294
+ position: relative;
3295
+ display: inline-grid;
3296
+ grid-auto-flow: column;
3297
+ grid-auto-columns: 1fr;
3298
+ padding: var(--segmented-control-padding);
3299
+ background: var(--color-bg-tertiary);
3300
+ border-radius: var(--radius-field);
3301
+ }
3302
+
3303
+ .segmented-control--full {
3304
+ display: grid;
3305
+ width: 100%;
3306
+ }
3307
+
3308
+ .segmented-control__indicator {
3309
+ position: absolute;
3310
+ top: var(--segmented-control-padding);
3311
+ bottom: var(--segmented-control-padding);
3312
+ left: var(--segmented-control-padding);
3313
+ background: var(--color-surface);
3314
+ border-radius: calc(var(--radius-field) - 2px);
3315
+ box-shadow: var(--shadow-xs);
3316
+ transition: transform var(--duration-normal) var(--ease-out);
3317
+ }
3318
+
3319
+ .segmented-control__option {
3320
+ position: relative;
3321
+ z-index: 1;
3322
+ display: inline-flex;
3323
+ align-items: center;
3324
+ justify-content: center;
3325
+ height: calc(var(--density-control-height) - var(--segmented-control-padding) * 2);
3326
+ padding: 0 var(--space-3);
3327
+ font: inherit;
3328
+ font-size: var(--density-font-size-ui);
3329
+ font-weight: var(--font-weight-medium);
3330
+ color: var(--color-fg-secondary);
3331
+ white-space: nowrap;
3332
+ background: transparent;
3333
+ border: 0;
3334
+ border-radius: calc(var(--radius-field) - 2px);
3335
+ cursor: pointer;
3336
+ transition: color var(--duration-normal) var(--ease-out);
3337
+ }
3338
+
3339
+ .segmented-control__option:hover:not(:disabled) {
3340
+ color: var(--color-fg);
3341
+ }
3342
+
3343
+ .segmented-control__option[aria-checked="true"] {
3344
+ color: var(--color-fg);
3345
+ }
3346
+
3347
+ .segmented-control__option:focus-visible {
3348
+ outline: var(--ring-width) solid var(--ring-color);
3349
+ outline-offset: var(--ring-offset);
3350
+ }
3351
+
3352
+ .segmented-control__option:disabled {
3353
+ opacity: 0.5;
3354
+ cursor: not-allowed;
3355
+ }
3356
+
3357
+ .segmented-control--sm .segmented-control__option {
3358
+ height: calc(var(--density-control-height) - 0.5rem - var(--segmented-control-padding) * 2);
3359
+ padding: 0 var(--space-2);
3360
+ font-size: var(--font-size-xs);
3361
+ }
3362
+
3363
+ @media (prefers-reduced-motion: reduce) {
3364
+ .segmented-control__indicator,
3365
+ .segmented-control__option {
3366
+ transition: none;
3367
+ }
3368
+ }
3369
+
2894
3370
  /* ================================================================
2895
3371
  Chart — DonutChart
2896
3372
  ================================================================ */
@@ -2,22 +2,13 @@ import { jsxs, jsx } from "react/jsx-runtime";
2
2
  import { forwardRef } from "react";
3
3
  import { cn } from "../../lib/utils.js";
4
4
  const Alert = forwardRef(
5
- ({ variant = "info", icon, title, className, children, ...rest }, ref) => /* @__PURE__ */ jsxs(
6
- "div",
7
- {
8
- ref,
9
- role: "alert",
10
- className: cn("alert", `alert--${variant}`, className),
11
- ...rest,
12
- children: [
13
- icon && /* @__PURE__ */ jsx("span", { className: "alert__icon", children: icon }),
14
- /* @__PURE__ */ jsxs("div", { className: "alert__content", children: [
15
- title && /* @__PURE__ */ jsx("p", { className: "alert__title", children: title }),
16
- /* @__PURE__ */ jsx("div", { className: "alert__description", children })
17
- ] })
18
- ]
19
- }
20
- )
5
+ ({ variant = "info", icon, title, className, children, ...rest }, ref) => /* @__PURE__ */ jsxs("div", { ref, role: "alert", className: cn("alert", `alert--${variant}`, className), ...rest, children: [
6
+ icon && /* @__PURE__ */ jsx("span", { className: "alert__icon", children: icon }),
7
+ /* @__PURE__ */ jsxs("div", { className: "alert__content", children: [
8
+ title && /* @__PURE__ */ jsx("p", { className: "alert__title", children: title }),
9
+ /* @__PURE__ */ jsx("div", { className: "alert__description", children })
10
+ ] })
11
+ ] })
21
12
  );
22
13
  Alert.displayName = "Alert";
23
14
  export {
@@ -8,12 +8,7 @@ const Badge = forwardRef(
8
8
  {
9
9
  ref,
10
10
  ...live ? { role: "status" } : {},
11
- className: cn(
12
- "badge",
13
- `badge--${variant}`,
14
- solid && "badge--solid",
15
- className
16
- ),
11
+ className: cn("badge", `badge--${variant}`, solid && "badge--solid", className),
17
12
  ...rest,
18
13
  children: [
19
14
  dot && /* @__PURE__ */ jsx("span", { className: "badge__dot", "aria-hidden": "true" }),
@@ -6,21 +6,25 @@ const BarChart = forwardRef(
6
6
  ({ data, max, formatValue, "aria-label": ariaLabel, className, ...rest }, ref) => {
7
7
  const maxVal = max ?? Math.max(...data.map((d) => d.value));
8
8
  const fmt = formatValue ?? ((v) => String(v));
9
- return /* @__PURE__ */ jsx("div", { ref, role: "img", "aria-label": ariaLabel, className: cn("bar-chart", className), ...rest, children: data.map((item, i) => {
10
- const pct = maxVal > 0 ? item.value / maxVal * 100 : 0;
11
- const color = item.color ?? CHART_COLORS[i % CHART_COLORS.length];
12
- return /* @__PURE__ */ jsxs("div", { className: "bar-chart__item", children: [
13
- /* @__PURE__ */ jsx("span", { className: "bar-chart__label", children: item.label }),
14
- /* @__PURE__ */ jsx("span", { className: "bar-chart__track", children: /* @__PURE__ */ jsx(
15
- "span",
16
- {
17
- className: "bar-chart__fill",
18
- style: { width: `${pct}%`, background: color }
19
- }
20
- ) }),
21
- /* @__PURE__ */ jsx("span", { className: "bar-chart__value", children: fmt(item.value) })
22
- ] }, item.label);
23
- }) });
9
+ return /* @__PURE__ */ jsx(
10
+ "div",
11
+ {
12
+ ref,
13
+ role: "img",
14
+ "aria-label": ariaLabel,
15
+ className: cn("bar-chart", className),
16
+ ...rest,
17
+ children: data.map((item, i) => {
18
+ const pct = maxVal > 0 ? item.value / maxVal * 100 : 0;
19
+ const color = item.color ?? CHART_COLORS[i % CHART_COLORS.length];
20
+ return /* @__PURE__ */ jsxs("div", { className: "bar-chart__item", children: [
21
+ /* @__PURE__ */ jsx("span", { className: "bar-chart__label", children: item.label }),
22
+ /* @__PURE__ */ jsx("span", { className: "bar-chart__track", children: /* @__PURE__ */ jsx("span", { className: "bar-chart__fill", style: { width: `${pct}%`, background: color } }) }),
23
+ /* @__PURE__ */ jsx("span", { className: "bar-chart__value", children: fmt(item.value) })
24
+ ] }, item.label);
25
+ })
26
+ }
27
+ );
24
28
  }
25
29
  );
26
30
  BarChart.displayName = "BarChart";