@trading-game/design-system-playground 0.2.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.
- package/README.md +433 -0
- package/dist/index.cjs +6666 -0
- package/dist/index.cjs.map +1 -0
- package/dist/index.d.cts +592 -0
- package/dist/index.d.ts +592 -0
- package/dist/index.js +6344 -0
- package/dist/index.js.map +1 -0
- package/package.json +84 -0
- package/rules/design-system-consuming-project.mdc +126 -0
- package/src/styles.css +276 -0
package/package.json
ADDED
|
@@ -0,0 +1,84 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@trading-game/design-system-playground",
|
|
3
|
+
"version": "0.2.0",
|
|
4
|
+
"description": "Trading Game Design System — shadcn/ui components with Tailwind CSS v4",
|
|
5
|
+
"type": "module",
|
|
6
|
+
"main": "./dist/index.cjs",
|
|
7
|
+
"module": "./dist/index.js",
|
|
8
|
+
"types": "./dist/index.d.ts",
|
|
9
|
+
"exports": {
|
|
10
|
+
".": {
|
|
11
|
+
"import": {
|
|
12
|
+
"types": "./dist/index.d.ts",
|
|
13
|
+
"default": "./dist/index.js"
|
|
14
|
+
},
|
|
15
|
+
"require": {
|
|
16
|
+
"types": "./dist/index.d.cts",
|
|
17
|
+
"default": "./dist/index.cjs"
|
|
18
|
+
}
|
|
19
|
+
},
|
|
20
|
+
"./styles": "./src/styles.css"
|
|
21
|
+
},
|
|
22
|
+
"sideEffects": [
|
|
23
|
+
"**/*.css"
|
|
24
|
+
],
|
|
25
|
+
"scripts": {
|
|
26
|
+
"dev": "next dev",
|
|
27
|
+
"generate:registry": "node scripts/generate-component-registry.mjs",
|
|
28
|
+
"build": "tsup",
|
|
29
|
+
"build:next": "next build",
|
|
30
|
+
"start": "next start",
|
|
31
|
+
"lint": "eslint",
|
|
32
|
+
"prepublishOnly": "npm run build"
|
|
33
|
+
},
|
|
34
|
+
"files": [
|
|
35
|
+
"dist/",
|
|
36
|
+
"src/styles.css",
|
|
37
|
+
"rules/"
|
|
38
|
+
],
|
|
39
|
+
"publishConfig": {
|
|
40
|
+
"access": "public"
|
|
41
|
+
},
|
|
42
|
+
"peerDependencies": {
|
|
43
|
+
"react": ">=18",
|
|
44
|
+
"react-dom": ">=18",
|
|
45
|
+
"tailwindcss": ">=4"
|
|
46
|
+
},
|
|
47
|
+
"dependencies": {
|
|
48
|
+
"@base-ui/react": "^1.2.0",
|
|
49
|
+
"@hookform/resolvers": "^5.2.2",
|
|
50
|
+
"class-variance-authority": "^0.7.1",
|
|
51
|
+
"clsx": "^2.1.1",
|
|
52
|
+
"cmdk": "^1.1.1",
|
|
53
|
+
"date-fns": "^4.1.0",
|
|
54
|
+
"embla-carousel-react": "^8.6.0",
|
|
55
|
+
"input-otp": "^1.4.2",
|
|
56
|
+
"lucide-react": "^0.577.0",
|
|
57
|
+
"radix-ui": "^1.4.3",
|
|
58
|
+
"react-day-picker": "^9.14.0",
|
|
59
|
+
"react-hook-form": "^7.71.2",
|
|
60
|
+
"react-resizable-panels": "^4.7.1",
|
|
61
|
+
"recharts": "^2.15.4",
|
|
62
|
+
"sonner": "^2.0.7",
|
|
63
|
+
"tailwind-merge": "^3.5.0",
|
|
64
|
+
"vaul": "^1.1.2",
|
|
65
|
+
"zod": "^4.3.6"
|
|
66
|
+
},
|
|
67
|
+
"devDependencies": {
|
|
68
|
+
"@tailwindcss/postcss": "^4",
|
|
69
|
+
"@types/node": "^20",
|
|
70
|
+
"@types/react": "^19",
|
|
71
|
+
"@types/react-dom": "^19",
|
|
72
|
+
"eslint": "^9",
|
|
73
|
+
"eslint-config-next": "16.1.6",
|
|
74
|
+
"next": "16.1.6",
|
|
75
|
+
"next-themes": "^0.4.6",
|
|
76
|
+
"react": "19.2.3",
|
|
77
|
+
"react-dom": "19.2.3",
|
|
78
|
+
"shadcn": "^3.8.5",
|
|
79
|
+
"tailwindcss": "^4",
|
|
80
|
+
"tsup": "^8.5.1",
|
|
81
|
+
"tw-animate-css": "^1.4.0",
|
|
82
|
+
"typescript": "^5"
|
|
83
|
+
}
|
|
84
|
+
}
|
|
@@ -0,0 +1,126 @@
|
|
|
1
|
+
---
|
|
2
|
+
description: Enforce correct usage of the @trading-game/design-system-playground npm package. Apply whenever building UI in a project that has the package installed — before writing any component, layout, or styled element.
|
|
3
|
+
globs: ["**/*.tsx", "**/*.jsx", "**/*.ts", "**/*.css"]
|
|
4
|
+
alwaysApply: true
|
|
5
|
+
---
|
|
6
|
+
|
|
7
|
+
# @trading-game/design-system-playground — AI Agent Usage Rules
|
|
8
|
+
|
|
9
|
+
## Rule 1 — Check the package before writing any custom UI
|
|
10
|
+
|
|
11
|
+
**BEFORE** writing any `<div>`, `<button>`, `<span>`, or other element styled with Tailwind classes, you MUST check if a component already exists in `@trading-game/design-system-playground`.
|
|
12
|
+
|
|
13
|
+
### Available components (check this list first)
|
|
14
|
+
|
|
15
|
+
Accordion, Alert, AlertDialog, Avatar, AvatarGroup, Badge, Breadcrumb, Button, Calendar, Card, Carousel, Chart, Checkbox, Collapsible, Combobox, Command, ContextMenu, Dialog, Drawer, DropdownMenu, EmptyState, Field, Form, HoverCard, Input, InputGroup, InputOTP, Item, Kbd, Label, Menubar, NativeSelect, NavigationMenu, Pagination, Popover, Progress, RadioGroup, Resizable, ScrollArea, Select, Separator, Sheet, Sidebar, Skeleton, Slider, Spinner, Switch, Table, Tabs, Textarea, Toast/Toaster, Toggle, ToggleGroup, Tooltip
|
|
16
|
+
|
|
17
|
+
### Decision flow
|
|
18
|
+
|
|
19
|
+
```
|
|
20
|
+
Does a component exist in the list above?
|
|
21
|
+
YES → Import it from @trading-game/design-system-playground. Do NOT re-implement it.
|
|
22
|
+
NO → STOP. Tell the user:
|
|
23
|
+
"The [ComponentName] component does not exist in @trading-game/design-system-playground.
|
|
24
|
+
Options:
|
|
25
|
+
(a) Build a custom one using design system tokens only
|
|
26
|
+
(b) Use a different existing component
|
|
27
|
+
(c) Skip this component"
|
|
28
|
+
Wait for user to choose. Do NOT proceed without confirmation.
|
|
29
|
+
```
|
|
30
|
+
|
|
31
|
+
### Correct import pattern
|
|
32
|
+
|
|
33
|
+
```tsx
|
|
34
|
+
import { Button, Card, Badge } from "@trading-game/design-system-playground"
|
|
35
|
+
```
|
|
36
|
+
|
|
37
|
+
---
|
|
38
|
+
|
|
39
|
+
## Rule 2 — Token-only rule (applies to ALL code, including approved custom builds)
|
|
40
|
+
|
|
41
|
+
### Never use
|
|
42
|
+
|
|
43
|
+
```
|
|
44
|
+
❌ Hardcoded hex: #2323FF, #020B0A, rgba(0,0,0,0.5)
|
|
45
|
+
❌ Raw Tailwind palette: bg-gray-900, text-zinc-500, text-slate-400, bg-black, bg-white
|
|
46
|
+
❌ Arbitrary color: bg-[#FF6600], text-[rgba(35,35,255,0.1)]
|
|
47
|
+
❌ Raw CSS var: bg-[var(--semantic-warning)] ← NEVER do this
|
|
48
|
+
❌ hsl(var()) syntax: hsl(var(--primary)) ← this is Tailwind v3, not v4
|
|
49
|
+
❌ Raw opacity on non-tokens: bg-black/50
|
|
50
|
+
```
|
|
51
|
+
|
|
52
|
+
### Always use semantic token classes
|
|
53
|
+
|
|
54
|
+
```
|
|
55
|
+
✅ bg-background, bg-card, bg-popover, bg-muted, bg-overlay
|
|
56
|
+
✅ text-on-prominent, text-on-subtle, text-on-muted, text-on-decorative
|
|
57
|
+
✅ text-primary-foreground
|
|
58
|
+
✅ bg-primary, bg-primary-hover, bg-secondary, bg-secondary-hover
|
|
59
|
+
✅ border-border, ring-ring
|
|
60
|
+
✅ text-semantic-win, text-semantic-loss, text-semantic-warning
|
|
61
|
+
✅ bg-semantic-win, bg-semantic-loss, bg-semantic-warning
|
|
62
|
+
✅ bg-destructive
|
|
63
|
+
✅ bg-hover (cyan 10% tint — for hover states)
|
|
64
|
+
✅ bg-overlay (black 50% — for modal/dialog/drawer backdrops only)
|
|
65
|
+
|
|
66
|
+
✅ Opacity on a token is fine: bg-primary/20, border-border/50, ring-primary/10
|
|
67
|
+
```
|
|
68
|
+
|
|
69
|
+
---
|
|
70
|
+
|
|
71
|
+
## Rule 3 — Layout utilities are exempt
|
|
72
|
+
|
|
73
|
+
Structural Tailwind utilities are freely usable without token rules:
|
|
74
|
+
|
|
75
|
+
```
|
|
76
|
+
✅ flex, grid, gap-4, p-6, m-2, w-full, h-screen, max-w-lg
|
|
77
|
+
✅ z-50, overflow-hidden, opacity-50, transition-all
|
|
78
|
+
✅ col-span-2, items-center, justify-between
|
|
79
|
+
```
|
|
80
|
+
|
|
81
|
+
Token rules apply **only** to: color (bg, text, border, ring, shadow color), border radius, and font family.
|
|
82
|
+
|
|
83
|
+
---
|
|
84
|
+
|
|
85
|
+
## Rule 4 — Do NOT install or configure these separately
|
|
86
|
+
|
|
87
|
+
```
|
|
88
|
+
❌ Do NOT install lucide-react — it is already bundled in the package
|
|
89
|
+
❌ Do NOT install tailwindcss separately — the package ships its own Tailwind v4 setup
|
|
90
|
+
❌ Do NOT add a tailwind.config.js — configuration is handled by the package
|
|
91
|
+
❌ Do NOT use @apply with hsl(var(--token)) — Tailwind v4 uses CSS variables directly
|
|
92
|
+
❌ Do NOT override font-family manually in CSS — use font-display and font-body utility classes
|
|
93
|
+
```
|
|
94
|
+
|
|
95
|
+
### Correct CSS setup in the consuming project
|
|
96
|
+
|
|
97
|
+
```css
|
|
98
|
+
@import "@trading-game/design-system-playground/styles";
|
|
99
|
+
@import "tailwindcss";
|
|
100
|
+
@source "../node_modules/@trading-game/design-system-playground/dist";
|
|
101
|
+
```
|
|
102
|
+
|
|
103
|
+
### Vite projects — required plugin
|
|
104
|
+
|
|
105
|
+
If the project uses Vite, `@tailwindcss/vite` MUST be in `vite.config.js`:
|
|
106
|
+
|
|
107
|
+
```js
|
|
108
|
+
import tailwindcss from '@tailwindcss/vite'
|
|
109
|
+
// plugins: [react(), tailwindcss()]
|
|
110
|
+
```
|
|
111
|
+
|
|
112
|
+
Without this, Tailwind CSS will not process any styles. Next.js projects do NOT need this.
|
|
113
|
+
|
|
114
|
+
---
|
|
115
|
+
|
|
116
|
+
## Rule 5 — If in doubt, stop and ask
|
|
117
|
+
|
|
118
|
+
If you cannot find a token for a value you need, do NOT fall back to a hardcoded value.
|
|
119
|
+
|
|
120
|
+
Stop and tell the user:
|
|
121
|
+
```
|
|
122
|
+
"I need [value] for [element]. No design token exists for this.
|
|
123
|
+
Should I: (a) use a hardcoded value, or (b) skip this styling?"
|
|
124
|
+
```
|
|
125
|
+
|
|
126
|
+
Wait for confirmation before proceeding.
|
package/src/styles.css
ADDED
|
@@ -0,0 +1,276 @@
|
|
|
1
|
+
/*
|
|
2
|
+
* Trading Game Design System — Design Tokens
|
|
3
|
+
*
|
|
4
|
+
* Usage in consumer apps:
|
|
5
|
+
* import "@trading-game/design-system-playground/styles"
|
|
6
|
+
*
|
|
7
|
+
* Requires Tailwind CSS v4 in your project.
|
|
8
|
+
* Add `@import "@trading-game/design-system-playground/styles"` in your CSS
|
|
9
|
+
* or import it in your JS entry point.
|
|
10
|
+
*/
|
|
11
|
+
|
|
12
|
+
/* Fonts — Barlow (body) + Orbitron (display/headings) */
|
|
13
|
+
@import url("https://fonts.googleapis.com/css2?family=Barlow:wght@300;400;500;600;700&family=Orbitron:wght@400;500;600;700;800;900&display=swap");
|
|
14
|
+
|
|
15
|
+
@custom-variant dark (&:is(.dark *));
|
|
16
|
+
|
|
17
|
+
@theme inline {
|
|
18
|
+
--color-background: var(--background);
|
|
19
|
+
--color-on-prominent: var(--on-prominent);
|
|
20
|
+
--font-sans: var(--font-barlow);
|
|
21
|
+
--font-body: var(--font-barlow);
|
|
22
|
+
--font-display: var(--font-orbitron);
|
|
23
|
+
--color-sidebar-ring: var(--sidebar-ring);
|
|
24
|
+
--color-sidebar-border: var(--sidebar-border);
|
|
25
|
+
--color-sidebar-accent-foreground: var(--sidebar-accent-foreground);
|
|
26
|
+
--color-sidebar-accent: var(--sidebar-accent);
|
|
27
|
+
--color-sidebar-primary-foreground: var(--sidebar-primary-foreground);
|
|
28
|
+
--color-sidebar-primary: var(--sidebar-primary);
|
|
29
|
+
--color-sidebar-foreground: var(--sidebar-foreground);
|
|
30
|
+
--color-sidebar: var(--sidebar);
|
|
31
|
+
--color-badge-rank: var(--badge-rank);
|
|
32
|
+
--color-ring: var(--ring);
|
|
33
|
+
--color-input: var(--input);
|
|
34
|
+
--color-border: var(--border);
|
|
35
|
+
--color-destructive: var(--destructive);
|
|
36
|
+
--color-accent-foreground: var(--accent-foreground);
|
|
37
|
+
--color-accent: var(--accent);
|
|
38
|
+
--color-accent-hover: var(--accent-hover);
|
|
39
|
+
--color-hover: var(--hover);
|
|
40
|
+
--color-brand-accent: var(--brand-accent);
|
|
41
|
+
--color-brand-accent-hover: var(--brand-accent-hover);
|
|
42
|
+
--color-on-subtle: var(--on-subtle);
|
|
43
|
+
--color-muted: var(--muted);
|
|
44
|
+
--color-secondary-foreground: var(--secondary-foreground);
|
|
45
|
+
--color-secondary: var(--secondary);
|
|
46
|
+
--color-primary-foreground: var(--primary-foreground);
|
|
47
|
+
--color-primary: var(--primary);
|
|
48
|
+
--color-primary-hover: var(--primary-hover);
|
|
49
|
+
--color-secondary-hover: var(--secondary-hover);
|
|
50
|
+
--color-popover-foreground: var(--popover-foreground);
|
|
51
|
+
--color-popover: var(--popover);
|
|
52
|
+
--color-card-foreground: var(--card-foreground);
|
|
53
|
+
--color-card: var(--card);
|
|
54
|
+
--color-semantic-win: var(--semantic-win);
|
|
55
|
+
--color-semantic-loss: var(--semantic-loss);
|
|
56
|
+
--color-semantic-warning: var(--semantic-warning);
|
|
57
|
+
--color-on-muted: var(--on-muted);
|
|
58
|
+
--color-on-decorative: var(--on-decorative);
|
|
59
|
+
--color-overlay: var(--overlay);
|
|
60
|
+
--color-alert-info-bg: var(--alert-info-bg);
|
|
61
|
+
/* #53B9FF — value in theme so text/border utilities apply reliably */
|
|
62
|
+
--color-alert-info-text: oklch(0.72 0.14 240);
|
|
63
|
+
--color-alert-info-border: oklch(0.72 0.14 240);
|
|
64
|
+
--color-alert-error-bg: var(--alert-error-bg);
|
|
65
|
+
--color-alert-error-text: var(--alert-error-text);
|
|
66
|
+
--color-alert-error-border: var(--alert-error-border);
|
|
67
|
+
--color-slider-range: var(--slider-range);
|
|
68
|
+
--radius-2xs: calc(var(--radius) - 8px);
|
|
69
|
+
--radius-xs: calc(var(--radius) - 6px);
|
|
70
|
+
--radius-sm: calc(var(--radius) - 4px);
|
|
71
|
+
--radius-md: calc(var(--radius) - 2px);
|
|
72
|
+
--radius-lg: var(--radius);
|
|
73
|
+
--radius-xl: calc(var(--radius) + 4px);
|
|
74
|
+
--radius-2xl: calc(var(--radius) + 8px);
|
|
75
|
+
--radius-3xl: calc(var(--radius) + 12px);
|
|
76
|
+
--radius-4xl: calc(var(--radius) + 16px);
|
|
77
|
+
}
|
|
78
|
+
|
|
79
|
+
:root {
|
|
80
|
+
--font-barlow: "Barlow", ui-sans-serif, system-ui, sans-serif;
|
|
81
|
+
--font-orbitron: "Orbitron", ui-sans-serif, system-ui, sans-serif;
|
|
82
|
+
--radius: 0.625rem;
|
|
83
|
+
/* Dark theme background */
|
|
84
|
+
--background: oklch(0.199 0.137 264.8); /* #010052 page bg */
|
|
85
|
+
--on-prominent: oklch(0.929 0.027 179.8); /* #D5EEE8 primary text */
|
|
86
|
+
--card: oklch(0.097 0.050 305.8); /* #06000F card/panel bg */
|
|
87
|
+
--card-foreground: var(--on-prominent);
|
|
88
|
+
--popover: oklch(0.206 0.023 215.8); /* #0A1A1E elevated surfaces */
|
|
89
|
+
--popover-foreground: var(--on-prominent);
|
|
90
|
+
--primary: oklch(0.476 0.297 267.4); /* #2323FF */
|
|
91
|
+
--primary-foreground: oklch(0.138 0.018 188.4); /* #020B0A */
|
|
92
|
+
--primary-hover: oklch(0.403 0.251 267.5); /* #1A1ACC */
|
|
93
|
+
--secondary: oklch(0.827 0.171 80.5 / 4%); /* #FFB800 @ 4% */
|
|
94
|
+
--secondary-hover: oklch(0.827 0.171 80.5); /* #FFB800 amber */
|
|
95
|
+
--secondary-foreground: var(--on-prominent);
|
|
96
|
+
--muted: oklch(0.206 0.023 215.8);
|
|
97
|
+
--on-subtle: oklch(0.701 0.050 206.2); /* #7AA8AE paragraph, descriptions, labels */
|
|
98
|
+
/* shadcn accent = UI interaction surface */
|
|
99
|
+
--accent: oklch(0.206 0.023 215.8);
|
|
100
|
+
--accent-foreground: var(--on-prominent);
|
|
101
|
+
--accent-hover: oklch(0.261 0.034 221.5);
|
|
102
|
+
--destructive: oklch(0.653 0.234 18.5); /* #FF3355 */
|
|
103
|
+
--border: oklch(0.226 0.042 215.0); /* #0F2830 border-dividers */
|
|
104
|
+
--input: oklch(0.226 0.042 215.0); /* #0F2830 border-dividers */
|
|
105
|
+
--ring: oklch(0.476 0.297 267.4); /* primary — focus ring */
|
|
106
|
+
--hover: oklch(0.476 0.297 267.4 / 12%); /* primary 12% — hover bg */
|
|
107
|
+
--brand-accent: oklch(0.62 0.185 38); /* #FF6600 accent orange */
|
|
108
|
+
--brand-accent-hover: oklch(0.52 0.168 38); /* #D45200 accent hover */
|
|
109
|
+
--badge-rank: oklch(0.601 0.263 301.6); /* #A040FF violet — badge/rank accent */
|
|
110
|
+
--semantic-win: oklch(0.880 0.208 157.4); /* #00FF9F */
|
|
111
|
+
--semantic-loss: oklch(0.653 0.234 18.5); /* #FF3355 */
|
|
112
|
+
--semantic-warning: oklch(0.751 0.179 58.3); /* #FF8C00 */
|
|
113
|
+
--on-muted: oklch(0.439 0.054 204.1); /* #295B60 headers, labels */
|
|
114
|
+
--on-decorative: oklch(0.226 0.024 230.9); /* #101E25 decorative */
|
|
115
|
+
--overlay: oklch(0 0 0 / 50%); /* rgba(0,0,0,0.50) modal scrim */
|
|
116
|
+
--slider-range: oklch(0.476 0.297 267.4 / 40%); /* primary 40% — slider range */
|
|
117
|
+
--sidebar-foreground: var(--on-prominent);
|
|
118
|
+
--sidebar-primary: oklch(0.476 0.297 267.4);
|
|
119
|
+
--sidebar-primary-foreground: oklch(0.138 0.018 188.4);
|
|
120
|
+
--sidebar-accent: oklch(0.206 0.023 215.8);
|
|
121
|
+
--sidebar-accent-foreground: var(--on-prominent);
|
|
122
|
+
--sidebar-border: oklch(0.226 0.042 215.0); /* #0F2830 */
|
|
123
|
+
--sidebar-ring: oklch(0.476 0.297 267.4);
|
|
124
|
+
/* Alert — Info (blue) */
|
|
125
|
+
--alert-info-bg: oklch(0.95 0.02 250); /* #e3f2fd */
|
|
126
|
+
--alert-info-text: oklch(0.72 0.14 240); /* #53B9FF */
|
|
127
|
+
--alert-info-border: oklch(0.72 0.14 240); /* #53B9FF */
|
|
128
|
+
/* Alert — Error (red) */
|
|
129
|
+
--alert-error-bg: oklch(0.96 0.02 15); /* #ffebee */
|
|
130
|
+
--alert-error-text: oklch(0.63 0.23 26); /* #FF4D4D */
|
|
131
|
+
--alert-error-border: oklch(0.63 0.23 26); /* #FF4D4D */
|
|
132
|
+
}
|
|
133
|
+
|
|
134
|
+
.dark {
|
|
135
|
+
/* Dark theme background */
|
|
136
|
+
--background: oklch(0.199 0.137 264.8); /* #010052 page bg */
|
|
137
|
+
--on-prominent: oklch(0.929 0.027 179.8); /* #D5EEE8 primary text */
|
|
138
|
+
--card: oklch(0.097 0.050 305.8); /* #06000F card/panel bg */
|
|
139
|
+
--card-foreground: var(--on-prominent);
|
|
140
|
+
--popover: oklch(0.206 0.023 215.8); /* #0A1A1E elevated surfaces */
|
|
141
|
+
--popover-foreground: var(--on-prominent);
|
|
142
|
+
/* Primary blue */
|
|
143
|
+
--primary: oklch(0.476 0.297 267.4); /* #2323FF */
|
|
144
|
+
--primary-foreground: oklch(0.138 0.018 188.4); /* #020B0A */
|
|
145
|
+
--primary-hover: oklch(0.403 0.251 267.5); /* #1A1ACC */
|
|
146
|
+
/* Supporting — amber */
|
|
147
|
+
--secondary: oklch(0.827 0.171 80.5 / 4%); /* #FFB800 @ 4% */
|
|
148
|
+
--secondary-hover: oklch(0.827 0.171 80.5); /* #FFB800 */
|
|
149
|
+
--secondary-foreground: var(--on-prominent);
|
|
150
|
+
/* Surfaces */
|
|
151
|
+
--muted: oklch(0.206 0.023 215.8);
|
|
152
|
+
--on-subtle: oklch(0.701 0.050 206.2); /* #7AA8AE */
|
|
153
|
+
/* shadcn accent = UI interaction surface (NOT the brand orange) */
|
|
154
|
+
--accent: oklch(0.206 0.023 215.8);
|
|
155
|
+
--accent-foreground: var(--on-prominent);
|
|
156
|
+
--accent-hover: oklch(0.261 0.034 221.5);
|
|
157
|
+
--destructive: oklch(0.653 0.234 18.5); /* #FF3355 */
|
|
158
|
+
--border: oklch(0.226 0.042 215.0); /* #0F2830 border-dividers */
|
|
159
|
+
--input: oklch(0.226 0.042 215.0); /* #0F2830 border-dividers */
|
|
160
|
+
--ring: oklch(0.476 0.297 267.4); /* primary — focus ring */
|
|
161
|
+
--hover: oklch(0.476 0.297 267.4 / 12%); /* primary 12% — hover bg */
|
|
162
|
+
--brand-accent: oklch(0.62 0.185 38); /* #FF6600 accent orange */
|
|
163
|
+
--brand-accent-hover: oklch(0.52 0.168 38); /* #D45200 accent hover */
|
|
164
|
+
/* Badge/rank accent */
|
|
165
|
+
--badge-rank: oklch(0.601 0.263 301.6); /* #A040FF violet */
|
|
166
|
+
/* Semantic trading colors */
|
|
167
|
+
--semantic-win: oklch(0.880 0.208 157.4); /* #00FF9F */
|
|
168
|
+
--semantic-loss: oklch(0.653 0.234 18.5); /* #FF3355 */
|
|
169
|
+
--semantic-warning: oklch(0.751 0.179 58.3); /* #FF8C00 */
|
|
170
|
+
/* Text scale */
|
|
171
|
+
--on-muted: oklch(0.439 0.054 204.1); /* #295B60 */
|
|
172
|
+
--on-decorative: oklch(0.226 0.024 230.9); /* #101E25 */
|
|
173
|
+
--overlay: oklch(0 0 0 / 50%); /* rgba(0,0,0,0.50) modal scrim */
|
|
174
|
+
--slider-range: oklch(0.476 0.297 267.4 / 40%); /* primary 40% — slider range */
|
|
175
|
+
/* Sidebar */
|
|
176
|
+
--sidebar: oklch(0.097 0.050 305.8);
|
|
177
|
+
--sidebar-foreground: var(--on-prominent);
|
|
178
|
+
--sidebar-primary: oklch(0.476 0.297 267.4);
|
|
179
|
+
--sidebar-primary-foreground: oklch(0.138 0.018 188.4);
|
|
180
|
+
--sidebar-accent: oklch(0.206 0.023 215.8);
|
|
181
|
+
--sidebar-accent-foreground: var(--on-prominent);
|
|
182
|
+
--sidebar-border: oklch(0.226 0.042 215.0); /* #0F2830 */
|
|
183
|
+
--sidebar-ring: oklch(0.476 0.297 267.4);
|
|
184
|
+
/* Alert — Info (blue) */
|
|
185
|
+
--alert-info-bg: oklch(0.95 0.02 250); /* #e3f2fd */
|
|
186
|
+
--alert-info-text: oklch(0.72 0.14 240); /* #53B9FF */
|
|
187
|
+
--alert-info-border: oklch(0.72 0.14 240); /* #53B9FF */
|
|
188
|
+
/* Alert — Error (red) */
|
|
189
|
+
--alert-error-bg: oklch(0.96 0.02 15); /* #ffebee */
|
|
190
|
+
--alert-error-text: oklch(0.63 0.23 26); /* #FF4D4D */
|
|
191
|
+
--alert-error-border: oklch(0.63 0.23 26); /* #FF4D4D */
|
|
192
|
+
}
|
|
193
|
+
|
|
194
|
+
@layer base {
|
|
195
|
+
* {
|
|
196
|
+
border-color: var(--color-border);
|
|
197
|
+
outline-color: color-mix(in oklch, var(--color-ring) 50%, transparent);
|
|
198
|
+
}
|
|
199
|
+
body {
|
|
200
|
+
@apply bg-background text-on-prominent font-sans antialiased;
|
|
201
|
+
}
|
|
202
|
+
}
|
|
203
|
+
|
|
204
|
+
/* Spinner — pill-style activity indicator */
|
|
205
|
+
@keyframes spinner-fade {
|
|
206
|
+
0% { opacity: 1; }
|
|
207
|
+
100% { opacity: 0.2; }
|
|
208
|
+
}
|
|
209
|
+
|
|
210
|
+
/* Typography — Heading scale (Orbitron · Semibold 600 · LS 1.5px) */
|
|
211
|
+
.heading-h1 {
|
|
212
|
+
font-family: var(--font-orbitron);
|
|
213
|
+
font-weight: 600;
|
|
214
|
+
font-size: 72px;
|
|
215
|
+
line-height: 72px;
|
|
216
|
+
letter-spacing: 1.5px;
|
|
217
|
+
text-transform: uppercase;
|
|
218
|
+
}
|
|
219
|
+
.heading-h2 {
|
|
220
|
+
font-family: var(--font-orbitron);
|
|
221
|
+
font-weight: 600;
|
|
222
|
+
font-size: 64px;
|
|
223
|
+
line-height: 64px;
|
|
224
|
+
letter-spacing: 1.5px;
|
|
225
|
+
text-transform: uppercase;
|
|
226
|
+
}
|
|
227
|
+
.heading-h3 {
|
|
228
|
+
font-family: var(--font-orbitron);
|
|
229
|
+
font-weight: 600;
|
|
230
|
+
font-size: 48px;
|
|
231
|
+
line-height: 48px;
|
|
232
|
+
letter-spacing: 1.5px;
|
|
233
|
+
text-transform: uppercase;
|
|
234
|
+
}
|
|
235
|
+
.heading-h4 {
|
|
236
|
+
font-family: var(--font-orbitron);
|
|
237
|
+
font-weight: 600;
|
|
238
|
+
font-size: 40px;
|
|
239
|
+
line-height: 40px;
|
|
240
|
+
letter-spacing: 1.5px;
|
|
241
|
+
text-transform: uppercase;
|
|
242
|
+
}
|
|
243
|
+
.heading-xs {
|
|
244
|
+
font-family: var(--font-orbitron);
|
|
245
|
+
font-weight: 600;
|
|
246
|
+
font-size: 24px;
|
|
247
|
+
line-height: 24px;
|
|
248
|
+
letter-spacing: 1.5px;
|
|
249
|
+
text-transform: uppercase;
|
|
250
|
+
}
|
|
251
|
+
|
|
252
|
+
/* Typography — Body scale (Barlow · Semibold 600) */
|
|
253
|
+
.body-lg {
|
|
254
|
+
font-family: var(--font-barlow);
|
|
255
|
+
font-weight: 600;
|
|
256
|
+
font-size: 18px;
|
|
257
|
+
line-height: 28px;
|
|
258
|
+
}
|
|
259
|
+
.body-md {
|
|
260
|
+
font-family: var(--font-barlow);
|
|
261
|
+
font-weight: 600;
|
|
262
|
+
font-size: 16px;
|
|
263
|
+
line-height: 24px;
|
|
264
|
+
}
|
|
265
|
+
.body-sm {
|
|
266
|
+
font-family: var(--font-barlow);
|
|
267
|
+
font-weight: 600;
|
|
268
|
+
font-size: 12px;
|
|
269
|
+
line-height: 16px;
|
|
270
|
+
}
|
|
271
|
+
.body-xs {
|
|
272
|
+
font-family: var(--font-barlow);
|
|
273
|
+
font-weight: 600;
|
|
274
|
+
font-size: 8px;
|
|
275
|
+
line-height: 12px;
|
|
276
|
+
}
|