@squadbase/vantage-template 0.1.1 → 0.2.0-stg.3618932
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.
- package/README.md +19 -9
- package/base-template/.squadbase/skills/vantage-add-feature/SKILL.md +14 -7
- package/base-template/.squadbase/skills/vantage-app/SKILL.md +4 -0
- package/base-template/.squadbase/skills/vantage-design/SKILL.md +62 -52
- package/base-template/.squadbase/skills/vantage-design/references/extract.md +26 -27
- package/base-template/.squadbase/skills/vantage-design/references/format.md +12 -172
- package/base-template/.squadbase/skills/vantage-design/references/presets.md +50 -110
- package/base-template/.squadbase/skills/vantage-pitfalls/SKILL.md +50 -1
- package/base-template/.squadbase/skills/vantage-slide/SKILL.md +299 -0
- package/base-template/.squadbase/skills/vantage-slide/references/morph.md +102 -0
- package/base-template/.squadbase/skills/vantage-slide/references/steps.md +57 -0
- package/base-template/.squadbase/skills/vantage-slide/references/tokens.md +87 -0
- package/base-template/.squadbase/skills/vantage-slide/references/transitions.md +196 -0
- package/base-template/AGENTS.md +224 -17
- package/base-template/agents/api.md +36 -0
- package/base-template/agents/csv.md +2 -1
- package/base-template/agents/doc.md +52 -3
- package/base-template/agents/page.md +91 -10
- package/base-template/agents/slide.md +90 -4
- package/base-template/agents/xlsx.md +2 -1
- package/base-template/bun.lock +917 -0
- package/base-template/bunfig.toml +5 -0
- package/base-template/package.json +6 -6
- package/base-template/squadbase.yml +1 -0
- package/base-template/src/_layout.tsx +16 -7
- package/base-template/src/components/build-recovery.tsx +37 -1
- package/base-template/src/components/user-card.tsx +11 -11
- package/base-template/src/index.tsx +8 -3
- package/base-template/src/styles.css +108 -12
- package/dist/index.js +971 -6
- package/package.json +20 -17
- package/ui-templates/CLAUDE.md +2 -0
- package/ui-templates/kpi-chart-simple/pages/index.tsx +48 -48
- package/ui-templates/kpi-chart-simple-ja/pages/index.tsx +48 -48
- package/base-template/DESIGN.md +0 -108
- package/base-template/package-lock.json +0 -5841
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@squadbase/vantage-template",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.2.0-stg.3618932",
|
|
4
4
|
"description": "CLI tool for initializing and customizing Squadbase Vantage projects.",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"squadbase",
|
|
@@ -36,29 +36,32 @@
|
|
|
36
36
|
"access": "public",
|
|
37
37
|
"registry": "https://registry.npmjs.org"
|
|
38
38
|
},
|
|
39
|
-
"scripts": {
|
|
40
|
-
"sync-base": "rsync -a --delete --exclude='node_modules' --exclude='dist' --exclude='.vantage' --exclude='*.tsbuildinfo' --exclude='*.log' template/ base-template/ && mv base-template/.gitignore base-template/_gitignore",
|
|
41
|
-
"build": "npm run sync-base && tsup",
|
|
42
|
-
"type-check": "tsc",
|
|
43
|
-
"agents": "node scripts/build-agents.cjs",
|
|
44
|
-
"agents:check": "node scripts/build-agents.cjs --check",
|
|
45
|
-
"template:install": "npm --prefix template ci",
|
|
46
|
-
"template:build": "npm --prefix template run build",
|
|
47
|
-
"prepublishOnly": "npm run agents:check && npm run build",
|
|
48
|
-
"release": "npm publish --@squadbase:registry=https://registry.npmjs.org",
|
|
49
|
-
"dev": "node scripts/dev.mjs",
|
|
50
|
-
"screenshot": "node scripts/screenshot.mjs"
|
|
51
|
-
},
|
|
52
39
|
"devDependencies": {
|
|
53
40
|
"@types/node": "^22.15.0",
|
|
54
41
|
"playwright": "^1.49.0",
|
|
55
42
|
"tsup": "^8.4.0",
|
|
56
|
-
"typescript": "~5.7.0"
|
|
43
|
+
"typescript": "~5.7.0",
|
|
44
|
+
"vitest": "^5.0.5",
|
|
45
|
+
"@squadbase/squadkit": "0.0.0"
|
|
57
46
|
},
|
|
58
47
|
"optionalDependencies": {
|
|
59
48
|
"@ai-sdk/anthropic": "^2.0.0",
|
|
60
49
|
"@ai-sdk/google": "^2.0.0",
|
|
61
|
-
"@ai-sdk/openai": "
|
|
50
|
+
"@ai-sdk/openai": "2.0.122",
|
|
62
51
|
"ai": "^5.0.52"
|
|
52
|
+
},
|
|
53
|
+
"gitHead": "3618932d3decca096c0eb3a505149570cc6cddbd",
|
|
54
|
+
"scripts": {
|
|
55
|
+
"sync-base": "rsync -a --delete --exclude='node_modules' --exclude='dist' --exclude='.vantage' --exclude='*.tsbuildinfo' --exclude='*.log' template/ base-template/ && mv base-template/.gitignore base-template/_gitignore",
|
|
56
|
+
"build": "pnpm run sync-base && tsup",
|
|
57
|
+
"type-check": "tsc",
|
|
58
|
+
"test": "vitest run",
|
|
59
|
+
"agents": "node scripts/build-agents.cjs",
|
|
60
|
+
"agents:check": "node scripts/build-agents.cjs --check",
|
|
61
|
+
"template:install": "bun install --cwd template --frozen-lockfile",
|
|
62
|
+
"template:build": "bun run --cwd template build",
|
|
63
|
+
"release": "pnpm publish --@squadbase:registry=https://registry.npmjs.org",
|
|
64
|
+
"dev": "node scripts/dev.mjs",
|
|
65
|
+
"screenshot": "node scripts/screenshot.mjs"
|
|
63
66
|
}
|
|
64
|
-
}
|
|
67
|
+
}
|
package/ui-templates/CLAUDE.md
CHANGED
|
@@ -96,6 +96,8 @@ server/api/<endpoint>.ts # ★ サンプルデータ + GET ハ
|
|
|
96
96
|
| --- | --- |
|
|
97
97
|
| `PageShell*` / `DashboardCard*` / `EChart` / `EChartsOption` / `DataTable*` / `ColumnDef` / `DateRangePicker` / `FilterBar*` / `FunnelSteps` / `MetricValue` / `TrendIndicator` / `StatusBadge` / `SegmentedControl` / `MultiSelect` / `SearchableSelect` / `SectionHeader` / `AppShell` / `Placeholder` / `Sparkline` | `@squadbase/vantage/components` |
|
|
98
98
|
| `Button` / `Input` / `Badge` / `Tabs*` / `ToggleGroup*` / `Table*` / `Select*` / `Dialog*` / `cn` ほか shadcn プリミティブ | `@squadbase/vantage/ui` |
|
|
99
|
+
|
|
100
|
+
型付きチャート(`LineChart` / `AreaChart` / `BarChart` / `DonutChart` / `BarList` / `CategoryBar` / `ProgressCircle` / `Tracker`、`@squadbase/vantage/components`)と `Avatar` / `Pagination` / `RadioGroup` / `AlertDialog` / `Drawer` / `Toaster` / `Field` / `Combobox` / `HoverCard` / `Kbd`(`@squadbase/vantage/ui`)は 0.6.3 で入った。雛形の依存が `^0.5.3` の間は使わない(上の EChart の書き方のまま)。
|
|
99
101
|
| `definePage` | `@squadbase/vantage` |
|
|
100
102
|
| `Link` / `Outlet` / `useParams` / `useSearch` / `useNavigate` / `useRoutes` / `useCurrentRoute` / `useSearchParam` / `useSearchState` | `@squadbase/vantage/router` |
|
|
101
103
|
| `useApiQuery` / `useApiMutation` / `useQuery` / `useMutation` / `apiFetch` | `@squadbase/vantage/query` |
|
|
@@ -104,54 +104,6 @@ const RANGE_OPTIONS: SegmentOption[] = [
|
|
|
104
104
|
{ label: "90 days", value: "90d" },
|
|
105
105
|
]
|
|
106
106
|
|
|
107
|
-
function DashboardBody({ data }: { data: KpiSummary }) {
|
|
108
|
-
return (
|
|
109
|
-
<>
|
|
110
|
-
<div className="grid gap-4 sm:grid-cols-2 lg:grid-cols-4">
|
|
111
|
-
{data.kpis.map((kpi) => {
|
|
112
|
-
const { label, icon: Icon, format } = KPI_META[kpi.id]
|
|
113
|
-
return (
|
|
114
|
-
<DashboardCard key={kpi.id}>
|
|
115
|
-
<DashboardCardHeader>
|
|
116
|
-
<DashboardCardTitle className="text-muted-foreground">
|
|
117
|
-
{label}
|
|
118
|
-
</DashboardCardTitle>
|
|
119
|
-
<DashboardCardAction>
|
|
120
|
-
<Icon className="size-4 text-muted-foreground" />
|
|
121
|
-
</DashboardCardAction>
|
|
122
|
-
</DashboardCardHeader>
|
|
123
|
-
<DashboardCardContent>
|
|
124
|
-
<Placeholder className="text-2xl font-bold">
|
|
125
|
-
{format(kpi.value)}
|
|
126
|
-
</Placeholder>
|
|
127
|
-
<div className="mt-2">
|
|
128
|
-
<Placeholder className="text-sm font-medium">
|
|
129
|
-
{kpi.change >= 0 ? `+${kpi.change}%` : `${kpi.change}%`}
|
|
130
|
-
</Placeholder>
|
|
131
|
-
</div>
|
|
132
|
-
<Sparkline
|
|
133
|
-
data={kpi.sparklineData.map((v) => ({ value: v }))}
|
|
134
|
-
height={32}
|
|
135
|
-
area
|
|
136
|
-
className="mt-3"
|
|
137
|
-
/>
|
|
138
|
-
</DashboardCardContent>
|
|
139
|
-
</DashboardCard>
|
|
140
|
-
)
|
|
141
|
-
})}
|
|
142
|
-
</div>
|
|
143
|
-
|
|
144
|
-
<DashboardCardPreset title="Trend" description="Values over the selected period">
|
|
145
|
-
<EChart option={trendOption(data.trend)} height="320px" />
|
|
146
|
-
</DashboardCardPreset>
|
|
147
|
-
|
|
148
|
-
<DashboardCardPreset title="Top items" description="Ranked by value">
|
|
149
|
-
<TopItemsTable data={data.topItems} />
|
|
150
|
-
</DashboardCardPreset>
|
|
151
|
-
</>
|
|
152
|
-
)
|
|
153
|
-
}
|
|
154
|
-
|
|
155
107
|
export default function HomePage() {
|
|
156
108
|
// Filter state belongs in the URL rather than `useState`: it survives a
|
|
157
109
|
// reload, and a pasted link reproduces exactly what you were looking at.
|
|
@@ -198,3 +150,51 @@ export default function HomePage() {
|
|
|
198
150
|
</PageShell>
|
|
199
151
|
)
|
|
200
152
|
}
|
|
153
|
+
|
|
154
|
+
function DashboardBody({ data }: { data: KpiSummary }) {
|
|
155
|
+
return (
|
|
156
|
+
<>
|
|
157
|
+
<div className="grid gap-4 sm:grid-cols-2 lg:grid-cols-4">
|
|
158
|
+
{data.kpis.map((kpi) => {
|
|
159
|
+
const { label, icon: Icon, format } = KPI_META[kpi.id]
|
|
160
|
+
return (
|
|
161
|
+
<DashboardCard key={kpi.id} data-sq-ref={kpi.id}>
|
|
162
|
+
<DashboardCardHeader>
|
|
163
|
+
<DashboardCardTitle className="text-muted-foreground">
|
|
164
|
+
{label}
|
|
165
|
+
</DashboardCardTitle>
|
|
166
|
+
<DashboardCardAction>
|
|
167
|
+
<Icon className="size-4 text-muted-foreground" />
|
|
168
|
+
</DashboardCardAction>
|
|
169
|
+
</DashboardCardHeader>
|
|
170
|
+
<DashboardCardContent>
|
|
171
|
+
<Placeholder className="text-2xl font-bold">
|
|
172
|
+
{format(kpi.value)}
|
|
173
|
+
</Placeholder>
|
|
174
|
+
<div className="mt-2">
|
|
175
|
+
<Placeholder className="text-sm font-medium">
|
|
176
|
+
{kpi.change >= 0 ? `+${kpi.change}%` : `${kpi.change}%`}
|
|
177
|
+
</Placeholder>
|
|
178
|
+
</div>
|
|
179
|
+
<Sparkline
|
|
180
|
+
data={kpi.sparklineData.map((v) => ({ value: v }))}
|
|
181
|
+
height={32}
|
|
182
|
+
area
|
|
183
|
+
className="mt-3"
|
|
184
|
+
/>
|
|
185
|
+
</DashboardCardContent>
|
|
186
|
+
</DashboardCard>
|
|
187
|
+
)
|
|
188
|
+
})}
|
|
189
|
+
</div>
|
|
190
|
+
|
|
191
|
+
<DashboardCardPreset data-sq-ref="trend" title="Trend" description="Values over the selected period">
|
|
192
|
+
<EChart option={trendOption(data.trend)} height="320px" />
|
|
193
|
+
</DashboardCardPreset>
|
|
194
|
+
|
|
195
|
+
<DashboardCardPreset data-sq-ref="top-items" title="Top items" description="Ranked by value">
|
|
196
|
+
<TopItemsTable data={data.topItems} />
|
|
197
|
+
</DashboardCardPreset>
|
|
198
|
+
</>
|
|
199
|
+
)
|
|
200
|
+
}
|
|
@@ -104,54 +104,6 @@ const RANGE_OPTIONS: SegmentOption[] = [
|
|
|
104
104
|
{ label: "90日", value: "90d" },
|
|
105
105
|
]
|
|
106
106
|
|
|
107
|
-
function DashboardBody({ data }: { data: KpiSummary }) {
|
|
108
|
-
return (
|
|
109
|
-
<>
|
|
110
|
-
<div className="grid gap-4 sm:grid-cols-2 lg:grid-cols-4">
|
|
111
|
-
{data.kpis.map((kpi) => {
|
|
112
|
-
const { label, icon: Icon, format } = KPI_META[kpi.id]
|
|
113
|
-
return (
|
|
114
|
-
<DashboardCard key={kpi.id}>
|
|
115
|
-
<DashboardCardHeader>
|
|
116
|
-
<DashboardCardTitle className="text-muted-foreground">
|
|
117
|
-
{label}
|
|
118
|
-
</DashboardCardTitle>
|
|
119
|
-
<DashboardCardAction>
|
|
120
|
-
<Icon className="size-4 text-muted-foreground" />
|
|
121
|
-
</DashboardCardAction>
|
|
122
|
-
</DashboardCardHeader>
|
|
123
|
-
<DashboardCardContent>
|
|
124
|
-
<Placeholder className="text-2xl font-bold">
|
|
125
|
-
{format(kpi.value)}
|
|
126
|
-
</Placeholder>
|
|
127
|
-
<div className="mt-2">
|
|
128
|
-
<Placeholder className="text-sm font-medium">
|
|
129
|
-
{kpi.change >= 0 ? `+${kpi.change}%` : `${kpi.change}%`}
|
|
130
|
-
</Placeholder>
|
|
131
|
-
</div>
|
|
132
|
-
<Sparkline
|
|
133
|
-
data={kpi.sparklineData.map((v) => ({ value: v }))}
|
|
134
|
-
height={32}
|
|
135
|
-
area
|
|
136
|
-
className="mt-3"
|
|
137
|
-
/>
|
|
138
|
-
</DashboardCardContent>
|
|
139
|
-
</DashboardCard>
|
|
140
|
-
)
|
|
141
|
-
})}
|
|
142
|
-
</div>
|
|
143
|
-
|
|
144
|
-
<DashboardCardPreset title="トレンド" description="選択期間の値">
|
|
145
|
-
<EChart option={trendOption(data.trend)} height="320px" />
|
|
146
|
-
</DashboardCardPreset>
|
|
147
|
-
|
|
148
|
-
<DashboardCardPreset title="上位項目" description="値で並べ替え">
|
|
149
|
-
<TopItemsTable data={data.topItems} />
|
|
150
|
-
</DashboardCardPreset>
|
|
151
|
-
</>
|
|
152
|
-
)
|
|
153
|
-
}
|
|
154
|
-
|
|
155
107
|
export default function HomePage() {
|
|
156
108
|
// 絞り込み状態は useState ではなく URL に置く。リロードで消えず、URL を
|
|
157
109
|
// そのまま共有すれば相手も同じ画面を見られる。
|
|
@@ -198,3 +150,51 @@ export default function HomePage() {
|
|
|
198
150
|
</PageShell>
|
|
199
151
|
)
|
|
200
152
|
}
|
|
153
|
+
|
|
154
|
+
function DashboardBody({ data }: { data: KpiSummary }) {
|
|
155
|
+
return (
|
|
156
|
+
<>
|
|
157
|
+
<div className="grid gap-4 sm:grid-cols-2 lg:grid-cols-4">
|
|
158
|
+
{data.kpis.map((kpi) => {
|
|
159
|
+
const { label, icon: Icon, format } = KPI_META[kpi.id]
|
|
160
|
+
return (
|
|
161
|
+
<DashboardCard key={kpi.id} data-sq-ref={kpi.id}>
|
|
162
|
+
<DashboardCardHeader>
|
|
163
|
+
<DashboardCardTitle className="text-muted-foreground">
|
|
164
|
+
{label}
|
|
165
|
+
</DashboardCardTitle>
|
|
166
|
+
<DashboardCardAction>
|
|
167
|
+
<Icon className="size-4 text-muted-foreground" />
|
|
168
|
+
</DashboardCardAction>
|
|
169
|
+
</DashboardCardHeader>
|
|
170
|
+
<DashboardCardContent>
|
|
171
|
+
<Placeholder className="text-2xl font-bold">
|
|
172
|
+
{format(kpi.value)}
|
|
173
|
+
</Placeholder>
|
|
174
|
+
<div className="mt-2">
|
|
175
|
+
<Placeholder className="text-sm font-medium">
|
|
176
|
+
{kpi.change >= 0 ? `+${kpi.change}%` : `${kpi.change}%`}
|
|
177
|
+
</Placeholder>
|
|
178
|
+
</div>
|
|
179
|
+
<Sparkline
|
|
180
|
+
data={kpi.sparklineData.map((v) => ({ value: v }))}
|
|
181
|
+
height={32}
|
|
182
|
+
area
|
|
183
|
+
className="mt-3"
|
|
184
|
+
/>
|
|
185
|
+
</DashboardCardContent>
|
|
186
|
+
</DashboardCard>
|
|
187
|
+
)
|
|
188
|
+
})}
|
|
189
|
+
</div>
|
|
190
|
+
|
|
191
|
+
<DashboardCardPreset data-sq-ref="trend" title="トレンド" description="選択期間の値">
|
|
192
|
+
<EChart option={trendOption(data.trend)} height="320px" />
|
|
193
|
+
</DashboardCardPreset>
|
|
194
|
+
|
|
195
|
+
<DashboardCardPreset data-sq-ref="top-items" title="上位項目" description="値で並べ替え">
|
|
196
|
+
<TopItemsTable data={data.topItems} />
|
|
197
|
+
</DashboardCardPreset>
|
|
198
|
+
</>
|
|
199
|
+
)
|
|
200
|
+
}
|
package/base-template/DESIGN.md
DELETED
|
@@ -1,108 +0,0 @@
|
|
|
1
|
-
<!--
|
|
2
|
-
DESIGN.md — このアプリの「見た目の意図」を書くファイルです。
|
|
3
|
-
|
|
4
|
-
- 実際の色・角丸・書体の値は src/styles.css にあります。ここにはトークン名(--primary など)と
|
|
5
|
-
使い分けのルールだけを書き、色コードは書きません。
|
|
6
|
-
- エージェントはページ・スライド・コンポーネントを書く前にこのファイルを読みます。
|
|
7
|
-
会話の中での指示はこのファイルより優先されます。
|
|
8
|
-
- 「このサイトに合わせて」「色を落ち着いた感じに」と頼めば、このファイルと styles.css を
|
|
9
|
-
まとめて更新します。
|
|
10
|
-
- このファイルはあなたのものです。`vantage upgrade` が書き換えることはありません。
|
|
11
|
-
-->
|
|
12
|
-
|
|
13
|
-
# デザイン
|
|
14
|
-
|
|
15
|
-
## 全体のトーン (Overview)
|
|
16
|
-
|
|
17
|
-
- 落ち着いた無彩色のベースに、データだけが色を持つ業務ダッシュボード。
|
|
18
|
-
- 装飾より読みやすさを優先する。影・グラデーション・アニメーションは最小限。
|
|
19
|
-
- 数字が主役。1 画面で伝えたいことを 1 つに絞り、補足は小さく添える。
|
|
20
|
-
- ブランド素材: なし(ロゴを使う場合は `public/brand/logo.svg` のように `public/` 配下のパスで書く)
|
|
21
|
-
|
|
22
|
-
## 色 (Colors)
|
|
23
|
-
|
|
24
|
-
色は必ずトークン(Tailwind のセマンティッククラス)で指定する。素のパレット(`bg-blue-600` など)や
|
|
25
|
-
色コードを直接書かない。
|
|
26
|
-
|
|
27
|
-
| 役割 | トークン | 使う場所 |
|
|
28
|
-
| --- | --- | --- |
|
|
29
|
-
| 主色 (Primary) | `--primary` / `--primary-foreground` | 主要ボタン、選択中の状態。既定は無彩色 |
|
|
30
|
-
| 強調 (Accent) | `--chart-1` | 1 つだけ目立たせたい数値・系列・リンク的な強調 |
|
|
31
|
-
| 良い (Positive) | `--chart-2` | 前期比のプラスなど、良い変化の小さな印 |
|
|
32
|
-
| 悪い (Negative) | `--destructive` | 前期比のマイナス、エラー、削除操作 |
|
|
33
|
-
| 注意 (Warning) | 専用トークンなし | 文言とアイコンで示し、色は `--muted-foreground` |
|
|
34
|
-
| 背景の段階 | `--background` → `--card` → `--muted` | ページ → カード → カード内の区画・ホバー |
|
|
35
|
-
| 境界 | `--border` / `--input` / `--ring` | 罫線、入力欄、フォーカス |
|
|
36
|
-
| 文字 | `--foreground` / `--muted-foreground` | 本文 / 補足・ラベル・単位 |
|
|
37
|
-
|
|
38
|
-
- `--muted`・`--accent`・`--secondary`・`--border` は背景・境界用。文字色に使わない。
|
|
39
|
-
- 増減(▲▼・前期比)は向きで色を分ける: 増加・プラスは `--chart-2`(または `--primary`)、
|
|
40
|
-
減少・マイナスは `--destructive`。下向きの矢印やマイナスを `--primary` で塗らない。
|
|
41
|
-
- ライトとダークの両方がトークンで決まるので `dark:` を並べない。
|
|
42
|
-
|
|
43
|
-
## チャート (Charts)
|
|
44
|
-
|
|
45
|
-
- 系列の順番は `--chart-1` → `--chart-2` → `--chart-3` → `--chart-4` → `--chart-5`
|
|
46
|
-
(現在はプリセット `blue`: 青 → ティール → フクシア → バイオレット → グレー)。
|
|
47
|
-
- 1 系列だけを目立たせるときは、その系列を `--chart-1`、残りをすべて `--chart-5`(グレー)にする。
|
|
48
|
-
- 良い / 悪いを色で塗り分けるときは `--chart-2` / `--destructive`。色だけに頼らず ▲▼ や符号も添える。
|
|
49
|
-
- 系列は 5 つまで。それ以上はグループ化するか「その他」にまとめる。
|
|
50
|
-
- 禁止: 同じチャートで `--destructive` を普通の系列色として使う(悪い値に見える)。
|
|
51
|
-
- 禁止: 隣り合う系列に `--chart-3` と `--chart-4` を並べて細い線で描く(見分けにくい)。
|
|
52
|
-
- 配色を丸ごと変えるときは `npx @squadbase/vantage-template chart <preset>` を使う
|
|
53
|
-
(`blue` / `ocean` / `sunset` / `forest` / `berry` / `mono`)。
|
|
54
|
-
|
|
55
|
-
## 書体 (Typography)
|
|
56
|
-
|
|
57
|
-
| 用途 | 指定 | 備考 |
|
|
58
|
-
| --- | --- | --- |
|
|
59
|
-
| 見出し・本文 | システムフォント(`body` の `font-family`) | Web フォントは使わない |
|
|
60
|
-
| 数字 | 同上 + `tabular-nums` | 桁がそろうように必ず付ける |
|
|
61
|
-
| スライドの見出し | `--slide-font-display` | 既定は日本語を含むシステムフォント |
|
|
62
|
-
| スライドの本文 | `--slide-font-body` | 既定は見出しと同じ |
|
|
63
|
-
|
|
64
|
-
サイズの段階(ダッシュボード):
|
|
65
|
-
|
|
66
|
-
- ページ見出し: `text-2xl font-bold`
|
|
67
|
-
- カード見出し・ラベル: `text-sm font-medium text-muted-foreground`
|
|
68
|
-
- KPI の数値: `text-3xl font-semibold tabular-nums`
|
|
69
|
-
- 本文・表: `text-sm`
|
|
70
|
-
- 注釈・出典: `text-xs text-muted-foreground`
|
|
71
|
-
|
|
72
|
-
スライドのサイズは `--slide-size-hero`(表紙・大きな数字)と `--slide-size-body`(本文)を基準にする。
|
|
73
|
-
|
|
74
|
-
## レイアウトと密度 (Layout)
|
|
75
|
-
|
|
76
|
-
- 情報はカード(`bg-card` + `border-border`)で区切る。角丸は `--radius` に従う(個別に変えない)。
|
|
77
|
-
- グリッドの間隔は `gap-4`。セクション間は `gap-6` 程度。
|
|
78
|
-
- KPI は 1 行に 2〜4 枚。その下にチャート、最後に明細の表。
|
|
79
|
-
- 密度は「中」。余白を削って詰め込むより、ページを分ける。
|
|
80
|
-
|
|
81
|
-
## 成果物の種類ごとの規則 (Per-artifact)
|
|
82
|
-
|
|
83
|
-
### ダッシュボード
|
|
84
|
-
|
|
85
|
-
- 先頭に KPI カード、次にトレンドのチャート、最後に明細の表。
|
|
86
|
-
- 各 KPI には比較対象(前月比・目標比など)を 1 つ添える。
|
|
87
|
-
- チャートのタイトルは結論を書く(「売上推移」より「売上は 3 か月連続で増加」)。
|
|
88
|
-
|
|
89
|
-
### スライド
|
|
90
|
-
|
|
91
|
-
- 1 枚に 1 メッセージ。見出しに結論を書く。
|
|
92
|
-
- 色は `--slide-bg` / `--slide-fg` / `--slide-accent` / `--slide-muted` を使う
|
|
93
|
-
(既定では `--background` / `--foreground` / `--primary` / `--muted-foreground` に連動)。
|
|
94
|
-
- 強調色は 1 枚につき 1 か所まで。
|
|
95
|
-
|
|
96
|
-
## Do / Don't
|
|
97
|
-
|
|
98
|
-
Do:
|
|
99
|
-
|
|
100
|
-
- トークンと Tailwind のセマンティッククラスで色を指定する。
|
|
101
|
-
- 数値には単位と比較対象を付ける。
|
|
102
|
-
- 色の意味(良い / 悪い / 強調)をアプリ全体でそろえる。
|
|
103
|
-
|
|
104
|
-
Don't:
|
|
105
|
-
|
|
106
|
-
- 色コードや素のパレットクラスを直接書く。
|
|
107
|
-
- 1 画面で強調色を何か所にも使う。
|
|
108
|
-
- 3D チャート・円グラフの多用・装飾目的のグラデーション。
|