@lindaui/tokens 0.0.3 → 0.1.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 +45 -0
- package/dist/index.css +3 -0
- package/llms.txt +48 -4
- package/package.json +5 -3
- package/theme-template.css +126 -0
package/README.md
CHANGED
|
@@ -21,6 +21,51 @@ Toggle a `.dark` class on an ancestor (e.g. `<html class="dark">`). The dark
|
|
|
21
21
|
palette redefines the canonical tokens; HeroUI's variables reference them, so
|
|
22
22
|
components re-skin for free.
|
|
23
23
|
|
|
24
|
+
## Custom theme (per project)
|
|
25
|
+
|
|
26
|
+
Every consumer can ship its own brand without rebuilding this package or touching
|
|
27
|
+
any component. The whole design system is driven by CSS custom properties read at
|
|
28
|
+
runtime, so theming = overriding a small set of **canonical** variables.
|
|
29
|
+
|
|
30
|
+
Copy the template, fill it with your brand, and import it **after** the base:
|
|
31
|
+
|
|
32
|
+
```tsx
|
|
33
|
+
import "@lindaui/tokens/css"; // HeroUI + utilities + default (teal) theme
|
|
34
|
+
import "./theme.css"; // your brand — overrides the canonical vars
|
|
35
|
+
```
|
|
36
|
+
|
|
37
|
+
The template lists every overridable variable (for `:root` and `.dark`) with the
|
|
38
|
+
defaults as a starting point:
|
|
39
|
+
|
|
40
|
+
```bash
|
|
41
|
+
# the template ships in the package:
|
|
42
|
+
node -e "console.log(require.resolve('@lindaui/tokens/theme-template.css'))"
|
|
43
|
+
```
|
|
44
|
+
|
|
45
|
+
Only override the **canonical** vars (`--primary`, `--card`, `--secondary`,
|
|
46
|
+
`--destructive`, `--ring`, `--radius`, `--chart-1..5`, ...). Do NOT touch the
|
|
47
|
+
HeroUI vars (`--accent`/`--surface`/`--default`/`--danger`/...) or the utility
|
|
48
|
+
vars (`--color-*`) — they reference the canonical ones and update automatically.
|
|
49
|
+
Soft variants (`--accent-soft`, `--danger-soft`, ...) are derived from `--primary`
|
|
50
|
+
/`--destructive` via `color-mix`, so they follow your brand for free.
|
|
51
|
+
|
|
52
|
+
### Runtime-switchable themes
|
|
53
|
+
|
|
54
|
+
For multiple themes in one app, switchable without reload (on top of dark/light),
|
|
55
|
+
scope each theme under a selector instead of `:root` — the matrix is theme × mode:
|
|
56
|
+
|
|
57
|
+
```css
|
|
58
|
+
[data-theme="ocean"] { --primary: oklch(0.55 0.13 240); --ring: oklch(0.55 0.13 240); /* ... */ }
|
|
59
|
+
[data-theme="ocean"].dark { --primary: oklch(0.78 0.12 240); /* ... */ }
|
|
60
|
+
```
|
|
61
|
+
|
|
62
|
+
```js
|
|
63
|
+
document.documentElement.dataset.theme = "ocean"; // switch theme
|
|
64
|
+
document.documentElement.classList.toggle("dark"); // switch mode
|
|
65
|
+
```
|
|
66
|
+
|
|
67
|
+
The template's bottom section documents this pattern in full.
|
|
68
|
+
|
|
24
69
|
## Local build
|
|
25
70
|
|
|
26
71
|
```bash
|
package/dist/index.css
CHANGED
package/llms.txt
CHANGED
|
@@ -33,8 +33,52 @@ That single import brings:
|
|
|
33
33
|
Toggle a `.dark` class on any ancestor element. Only the canonical tokens are
|
|
34
34
|
redefined in `.dark`; the HeroUI vars are references, so everything follows.
|
|
35
35
|
|
|
36
|
-
##
|
|
36
|
+
## Custom theme (per consuming project)
|
|
37
37
|
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
38
|
+
Theming = overriding the **canonical** CSS vars; everything reads them at runtime, so
|
|
39
|
+
no rebuild and no component changes. Override AFTER the base import:
|
|
40
|
+
|
|
41
|
+
```tsx
|
|
42
|
+
import "@lindaui/tokens/css"; // default (teal) theme
|
|
43
|
+
import "./theme.css"; // your brand — wins by source order
|
|
44
|
+
```
|
|
45
|
+
|
|
46
|
+
```css
|
|
47
|
+
/* theme.css — override ONLY canonical vars */
|
|
48
|
+
:root { --primary: oklch(0.55 0.2 264); --primary-foreground: oklch(.98 0 0); --ring: oklch(0.55 0.2 264); --radius: 0.5rem; --chart-1: oklch(0.6 0.2 264); }
|
|
49
|
+
.dark { --primary: oklch(0.72 0.16 264); --primary-foreground: oklch(.2 0 0); --ring: oklch(0.72 0.16 264); }
|
|
50
|
+
```
|
|
51
|
+
|
|
52
|
+
There are THREE var systems — override only (A):
|
|
53
|
+
- **(A) canonical** (source of truth, override these): `--background`, `--foreground`,
|
|
54
|
+
`--card(-foreground)`, `--popover(-foreground)`, `--secondary(-foreground)`,
|
|
55
|
+
`--muted-foreground`, `--primary(-foreground)`, `--destructive`, `--success(-foreground)`,
|
|
56
|
+
`--warning(-foreground)`, `--border`, `--input`, `--ring`, `--radius`,
|
|
57
|
+
`--chart-1..5`, `--viewer-*`.
|
|
58
|
+
- **(B) HeroUI** (`--accent`/`--surface`/`--default`/`--danger`/`--focus`/...) — refs to (A),
|
|
59
|
+
DO NOT override.
|
|
60
|
+
- **(C) utilities** (`--color-*` from `@theme inline`) — refs to (A), DO NOT override.
|
|
61
|
+
Soft variants (`--accent-soft`/`--danger-soft`/...) are `color-mix` of (A), follow for free.
|
|
62
|
+
|
|
63
|
+
A ready, commented starting point ships as `@lindaui/tokens/theme-template.css` — copy it
|
|
64
|
+
into your project and fill in your brand. Resolve its path with
|
|
65
|
+
`require.resolve('@lindaui/tokens/theme-template.css')`.
|
|
66
|
+
|
|
67
|
+
### Runtime-switchable themes
|
|
68
|
+
|
|
69
|
+
For multiple themes in one app (beyond dark/light), scope each theme under a selector
|
|
70
|
+
instead of `:root` (matrix = theme × mode):
|
|
71
|
+
|
|
72
|
+
```css
|
|
73
|
+
[data-theme="ocean"] { --primary: oklch(0.55 0.13 240); --ring: oklch(0.55 0.13 240); }
|
|
74
|
+
[data-theme="ocean"].dark { --primary: oklch(0.78 0.12 240); }
|
|
75
|
+
```
|
|
76
|
+
|
|
77
|
+
Toggle with `document.documentElement.dataset.theme = "ocean"` + the `.dark` class.
|
|
78
|
+
|
|
79
|
+
## Exports & notes for agents
|
|
80
|
+
|
|
81
|
+
- `@lindaui/tokens/css` → the compiled stylesheet (the only thing you import for runtime).
|
|
82
|
+
- `@lindaui/tokens/theme-template.css` → commented theme template to copy (not imported).
|
|
83
|
+
- No JS entry point. `@lindaui/ui` and `@lindaui/blocks` declare this as a peer.
|
|
84
|
+
- If a layout looks unstyled ("just text"), the consumer usually forgot the `/css` import.
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@lindaui/tokens",
|
|
3
|
-
"version": "0.0
|
|
3
|
+
"version": "0.1.0",
|
|
4
4
|
"description": "Brand design tokens (OKLCH light/dark) + HeroUI v3 + Tailwind v4 compiled into a single CSS bundle.",
|
|
5
5
|
"author": "Franco Carballar <francocarballar@gmail.com>",
|
|
6
6
|
"license": "MIT",
|
|
@@ -14,13 +14,15 @@
|
|
|
14
14
|
},
|
|
15
15
|
"type": "module",
|
|
16
16
|
"exports": {
|
|
17
|
-
"./css": "./dist/index.css"
|
|
17
|
+
"./css": "./dist/index.css",
|
|
18
|
+
"./theme-template.css": "./theme-template.css"
|
|
18
19
|
},
|
|
19
20
|
"files": [
|
|
20
21
|
"dist",
|
|
21
22
|
"LICENSE",
|
|
22
23
|
"README.md",
|
|
23
|
-
"llms.txt"
|
|
24
|
+
"llms.txt",
|
|
25
|
+
"theme-template.css"
|
|
24
26
|
],
|
|
25
27
|
"devDependencies": {
|
|
26
28
|
"tailwindcss": "^4.0.0",
|
|
@@ -0,0 +1,126 @@
|
|
|
1
|
+
/* ============================================================
|
|
2
|
+
@lindaui — THEME TEMPLATE (copiá este archivo a tu proyecto)
|
|
3
|
+
|
|
4
|
+
Cada proyecto consumidor define su marca pisando las variables
|
|
5
|
+
CANÓNICAS de abajo. NO necesitás rebuildear @lindaui/tokens ni tocar
|
|
6
|
+
componentes: HeroUI v3, los bespoke, las utilities (bg-primary, ...) y
|
|
7
|
+
los charts leen estas vars en runtime, así que re-skinean solos.
|
|
8
|
+
|
|
9
|
+
USO (orden importa — el tema va DESPUÉS de la base):
|
|
10
|
+
import "@lindaui/tokens/css"; // HeroUI + utilities + tema default
|
|
11
|
+
import "./theme.css"; // este archivo, con TUS valores
|
|
12
|
+
|
|
13
|
+
REGLA DE ORO: pisá SOLO las variables de este archivo (las "canónicas").
|
|
14
|
+
NO toques las de HeroUI (--accent/--surface/--default/--danger/--focus/...)
|
|
15
|
+
ni las utilities (--color-*): son referencias a estas y se actualizan solas.
|
|
16
|
+
Las variantes soft (--accent-soft, --danger-soft, ...) salen por color-mix
|
|
17
|
+
desde --primary/--destructive → cambian con tu marca automáticamente.
|
|
18
|
+
|
|
19
|
+
Los valores de acá son los DEFAULT (teal). Cambialos por los tuyos.
|
|
20
|
+
Color en OKLCH: oklch(L C H) — L 0..1 (luz), C croma, H 0..360 (matiz).
|
|
21
|
+
============================================================ */
|
|
22
|
+
|
|
23
|
+
:root {
|
|
24
|
+
/* ── Superficies + texto base ── */
|
|
25
|
+
--background: oklch(1 0 0);
|
|
26
|
+
--foreground: oklch(0.145 0 0);
|
|
27
|
+
--card: oklch(1 0 0);
|
|
28
|
+
--card-foreground: oklch(0.145 0 0);
|
|
29
|
+
--popover: oklch(1 0 0);
|
|
30
|
+
--popover-foreground: oklch(0.145 0 0);
|
|
31
|
+
--secondary: oklch(0.97 0 0); /* superficie neutra (bg-secondary) */
|
|
32
|
+
--secondary-foreground: oklch(0.205 0 0);
|
|
33
|
+
--muted-foreground: oklch(0.556 0 0); /* texto atenuado (text-muted-foreground) */
|
|
34
|
+
|
|
35
|
+
/* ── Marca (lo más importante) ── */
|
|
36
|
+
--primary: oklch(0.47 0.097 183); /* <- TU color de marca */
|
|
37
|
+
--primary-foreground: oklch(0.985 0 0); /* texto sobre la marca */
|
|
38
|
+
|
|
39
|
+
/* ── Estado ── */
|
|
40
|
+
--destructive: oklch(0.577 0.245 27.325);
|
|
41
|
+
--success: oklch(0.59 0.163 148);
|
|
42
|
+
--success-foreground: oklch(1 0 0);
|
|
43
|
+
--warning: oklch(0.56 0.14 58);
|
|
44
|
+
--warning-foreground: oklch(1 0 0);
|
|
45
|
+
|
|
46
|
+
/* ── Bordes / input / foco / radio ── */
|
|
47
|
+
--border: oklch(0.922 0 0);
|
|
48
|
+
--input: oklch(0.922 0 0);
|
|
49
|
+
--ring: oklch(0.47 0.097 183); /* normalmente == --primary */
|
|
50
|
+
--radius: 0.625rem; /* escala sm/md/lg/xl... deriva de esto */
|
|
51
|
+
|
|
52
|
+
/* ── Paleta categórica de charts ── */
|
|
53
|
+
--chart-1: oklch(0.55 0.12 183);
|
|
54
|
+
--chart-2: oklch(0.6 0.12 220);
|
|
55
|
+
--chart-3: oklch(0.65 0.14 150);
|
|
56
|
+
--chart-4: oklch(0.72 0.15 80);
|
|
57
|
+
--chart-5: oklch(0.62 0.19 25);
|
|
58
|
+
|
|
59
|
+
/* ── Visor media (oscuro SIEMPRE; opcional, borralo si no usás image-viewer) ── */
|
|
60
|
+
--viewer-bg: oklch(0.22 0.027 214);
|
|
61
|
+
--viewer-foreground: oklch(0.88 0.012 220);
|
|
62
|
+
--viewer-border: oklch(0.3 0.025 214);
|
|
63
|
+
|
|
64
|
+
/* Tipografía: inyectá tus fuentes vía --font-sans / --font-mono / --font-heading
|
|
65
|
+
(ej. next/font expone --font-xxx). Si no, quedan los fallbacks del default. */
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
/* ── Dark mode: redefiní SOLO lo que cambia en oscuro (toggleás la clase .dark) ── */
|
|
69
|
+
.dark {
|
|
70
|
+
--background: oklch(0.145 0 0);
|
|
71
|
+
--foreground: oklch(0.985 0 0);
|
|
72
|
+
--card: oklch(0.205 0 0);
|
|
73
|
+
--card-foreground: oklch(0.985 0 0);
|
|
74
|
+
--popover: oklch(0.205 0 0);
|
|
75
|
+
--popover-foreground: oklch(0.985 0 0);
|
|
76
|
+
--secondary: oklch(0.269 0 0);
|
|
77
|
+
--secondary-foreground: oklch(0.985 0 0);
|
|
78
|
+
--muted-foreground: oklch(0.708 0 0);
|
|
79
|
+
--primary: oklch(0.79 0.12 181); /* marca más brillante en dark */
|
|
80
|
+
--primary-foreground: oklch(0.205 0 0);
|
|
81
|
+
--destructive: oklch(0.704 0.191 22.216);
|
|
82
|
+
--success: oklch(0.7 0.16 150);
|
|
83
|
+
--success-foreground: oklch(0.205 0 0);
|
|
84
|
+
--warning: oklch(0.75 0.14 70);
|
|
85
|
+
--warning-foreground: oklch(0.205 0 0);
|
|
86
|
+
--border: oklch(1 0 0 / 10%);
|
|
87
|
+
--input: oklch(1 0 0 / 15%);
|
|
88
|
+
--ring: oklch(0.79 0.12 181);
|
|
89
|
+
--chart-1: oklch(0.7 0.13 183);
|
|
90
|
+
--chart-2: oklch(0.7 0.13 220);
|
|
91
|
+
--chart-3: oklch(0.72 0.15 150);
|
|
92
|
+
--chart-4: oklch(0.78 0.15 80);
|
|
93
|
+
--chart-5: oklch(0.7 0.18 25);
|
|
94
|
+
}
|
|
95
|
+
|
|
96
|
+
/* ============================================================
|
|
97
|
+
TEMAS CONMUTABLES EN RUNTIME (opcional)
|
|
98
|
+
|
|
99
|
+
Si querés varios temas en el MISMO proyecto, conmutables sin reload
|
|
100
|
+
(además de dark/light), scopeá cada tema bajo un selector en vez de
|
|
101
|
+
:root. La matriz es tema × modo. Toggleás el atributo data-theme en
|
|
102
|
+
<html> (o cualquier ancestro) y la clase .dark como siempre.
|
|
103
|
+
|
|
104
|
+
<html data-theme="ocean" class="dark">
|
|
105
|
+
|
|
106
|
+
Default (sin data-theme) = el bloque :root/.dark de arriba.
|
|
107
|
+
Cada tema extra define su light bajo [data-theme="x"] y su dark bajo
|
|
108
|
+
[data-theme="x"].dark. Solo necesitás repetir las vars que cambian.
|
|
109
|
+
|
|
110
|
+
[data-theme="ocean"] {
|
|
111
|
+
--primary: oklch(0.55 0.13 240);
|
|
112
|
+
--primary-foreground: oklch(0.985 0 0);
|
|
113
|
+
--ring: oklch(0.55 0.13 240);
|
|
114
|
+
--chart-1: oklch(0.6 0.14 240);
|
|
115
|
+
...
|
|
116
|
+
}
|
|
117
|
+
[data-theme="ocean"].dark {
|
|
118
|
+
--primary: oklch(0.78 0.12 240);
|
|
119
|
+
--primary-foreground: oklch(0.205 0 0);
|
|
120
|
+
--ring: oklch(0.78 0.12 240);
|
|
121
|
+
...
|
|
122
|
+
}
|
|
123
|
+
|
|
124
|
+
En JS: document.documentElement.dataset.theme = "ocean"; // cambiar
|
|
125
|
+
document.documentElement.classList.toggle("dark"); // modo
|
|
126
|
+
============================================================ */
|