@kolkrabbi/kol-theme 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 +26 -0
- package/kol-base-tokens.css +74 -0
- package/kol-color.css +280 -0
- package/kol-components-atoms.css +709 -0
- package/kol-components-molecules.css +255 -0
- package/kol-components-organisms.css +220 -0
- package/kol-opacity.css +369 -0
- package/kol-opaque.css +203 -0
- package/kol-theme.css +110 -0
- package/kol-type-mono-classes.css +115 -0
- package/kol-typography-mono.css +64 -0
- package/kol-typography.css +1090 -0
- package/kol-utilities.css +92 -0
- package/package.json +34 -0
package/README.md
ADDED
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
# @kolkrabbi/kol-theme
|
|
2
|
+
|
|
3
|
+
Brand-neutral tokens + base CSS for the KOL (Kolkrabbi) design system. The cascade layer every other KOL package and consumer builds on — design tokens, color/opacity scales, typography, and the canonical `kol-*` component classes.
|
|
4
|
+
|
|
5
|
+
## Install
|
|
6
|
+
|
|
7
|
+
```sh
|
|
8
|
+
npm i @kolkrabbi/kol-theme
|
|
9
|
+
```
|
|
10
|
+
|
|
11
|
+
## Use
|
|
12
|
+
|
|
13
|
+
In a Vite + Tailwind v4 app, import the barrel after Tailwind:
|
|
14
|
+
|
|
15
|
+
```css
|
|
16
|
+
@import "tailwindcss";
|
|
17
|
+
@import "@kolkrabbi/kol-theme";
|
|
18
|
+
```
|
|
19
|
+
|
|
20
|
+
Cascade order is load-bearing — `kol-theme` must come after Tailwind so its component classes and tokens resolve correctly. Individual files are also reachable (`@kolkrabbi/kol-theme/kol-color.css`, etc.) if you need finer control.
|
|
21
|
+
|
|
22
|
+
## Fonts
|
|
23
|
+
|
|
24
|
+
The typography CSS references the brand fonts at absolute paths (`/fonts/Right-Grotesk/…`, `/fonts/jetbrains-mono/…`). **The package does not ship the font files** — your app must serve them from `/fonts/` (e.g. drop them in your `public/` dir). The showcase in this repo does exactly that. Without them, type falls back to system fonts.
|
|
25
|
+
|
|
26
|
+
Pure CSS — no JS, no dependencies.
|
|
@@ -0,0 +1,74 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @kol/theme — Canonical neutral surface base (shared)
|
|
3
|
+
*
|
|
4
|
+
* The brand-NEUTRAL tokens that are identical across apps/web and apps/brand:
|
|
5
|
+
* the surface elevation tiers and theme-invariant absolutes. These are the real
|
|
6
|
+
* drift surface (page bg/fg colors) and they carry no brand identity, so they
|
|
7
|
+
* are safe to share as the single canonical source — kolkrabbi and any
|
|
8
|
+
* scaffolded client render on the same surface base.
|
|
9
|
+
*
|
|
10
|
+
* Deliberately NOT here: accent (kolkrabbi yellow in web; neutral-ink default +
|
|
11
|
+
* brand-layer rebind in brand), fonts, and brand color primitives — those are
|
|
12
|
+
* brand-specific and stay with each app's own theme layer.
|
|
13
|
+
*
|
|
14
|
+
* Plain :root (not @theme): these tokens aren't in Tailwind's --color-*
|
|
15
|
+
* namespace, so they generate no utilities either way — consumed as
|
|
16
|
+
* var(--kol-surface-*) by hand-written utilities + components in both apps.
|
|
17
|
+
* Dark selector matches brand's mechanism: [data-theme="dark"], .dark.
|
|
18
|
+
*/
|
|
19
|
+
|
|
20
|
+
:root {
|
|
21
|
+
/* Absolutes (theme-invariant) */
|
|
22
|
+
--kol-color-absolute-white: #ffffff;
|
|
23
|
+
--kol-color-absolute-black: #000000;
|
|
24
|
+
|
|
25
|
+
/* Surface tiers (page-level) — Light Mode (default) */
|
|
26
|
+
--kol-surface-primary: #fafafa;
|
|
27
|
+
--kol-surface-on-primary: #121215;
|
|
28
|
+
|
|
29
|
+
--kol-surface-secondary: #f2f2f2;
|
|
30
|
+
--kol-surface-on-secondary: #19191d;
|
|
31
|
+
|
|
32
|
+
--kol-surface-tertiary: #ffffff;
|
|
33
|
+
--kol-surface-on-tertiary: #0e0e11;
|
|
34
|
+
|
|
35
|
+
--kol-surface-inverse: #0e0e11;
|
|
36
|
+
--kol-surface-on-inverse: #fcfbf8;
|
|
37
|
+
|
|
38
|
+
--kol-surface-secondary-inverse: #212121;
|
|
39
|
+
--kol-surface-tertiary-inverse: #424242;
|
|
40
|
+
|
|
41
|
+
--kol-surface-contrast: #f2f2f2;
|
|
42
|
+
|
|
43
|
+
/* Surface split tokens */
|
|
44
|
+
--kol-surface-support-split: #eeeeee;
|
|
45
|
+
--kol-surface-support-split-inverse: #202026;
|
|
46
|
+
--kol-surface-absolute-split: #ffffff;
|
|
47
|
+
--kol-surface-absolute-split-inverse: #000000;
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
/* Dark Mode — surface overrides */
|
|
51
|
+
:is([data-theme="dark"], .dark) {
|
|
52
|
+
--kol-surface-primary: #121215;
|
|
53
|
+
--kol-surface-on-primary: #fafafa;
|
|
54
|
+
|
|
55
|
+
--kol-surface-secondary: #19191d;
|
|
56
|
+
--kol-surface-on-secondary: #f8f8f8;
|
|
57
|
+
|
|
58
|
+
--kol-surface-tertiary: #0e0e11;
|
|
59
|
+
--kol-surface-on-tertiary: #ffffff;
|
|
60
|
+
|
|
61
|
+
--kol-surface-inverse: #fcfbf8;
|
|
62
|
+
--kol-surface-on-inverse: #0e0e11;
|
|
63
|
+
|
|
64
|
+
--kol-surface-secondary-inverse: #e0e0e0;
|
|
65
|
+
--kol-surface-tertiary-inverse: #d4d4d8;
|
|
66
|
+
|
|
67
|
+
--kol-surface-contrast: #0b0b0c;
|
|
68
|
+
|
|
69
|
+
/* Surface split tokens - Dark Mode */
|
|
70
|
+
--kol-surface-support-split: #202026;
|
|
71
|
+
--kol-surface-support-split-inverse: #eeeeee;
|
|
72
|
+
--kol-surface-absolute-split: #000000;
|
|
73
|
+
--kol-surface-absolute-split-inverse: #ffffff;
|
|
74
|
+
}
|
package/kol-color.css
ADDED
|
@@ -0,0 +1,280 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* KOL Color System — DS theme layer (brand-neutral).
|
|
3
|
+
*
|
|
4
|
+
* Surface tiers, ink-based accent default, ui-state, borders, opacity ramp
|
|
5
|
+
* re-declarations for surface-inverse contexts. Brand identity (hue ramps,
|
|
6
|
+
* cream ramp, brand-primary/secondary roles, accent rebind) lives in the
|
|
7
|
+
* sibling `kol-brand-color.css` and mirrors the `kol-brand` package — loaded
|
|
8
|
+
* explicitly by `index.css` for this repo (the brand showcase). A scaffolded
|
|
9
|
+
* project that does NOT pull `kol-brand` skips the brand import and renders
|
|
10
|
+
* brand-neutral with `--kol-accent-*` defaulting to surface ink.
|
|
11
|
+
*
|
|
12
|
+
* Dark mode toggle:
|
|
13
|
+
* document.documentElement.setAttribute('data-theme', 'dark')
|
|
14
|
+
*/
|
|
15
|
+
|
|
16
|
+
/* =============================================================================
|
|
17
|
+
* LIGHT MODE (Default)
|
|
18
|
+
* ============================================================================= */
|
|
19
|
+
|
|
20
|
+
:root {
|
|
21
|
+
/* Absolutes + surface elevation tiers now come from
|
|
22
|
+
* @kol/theme/kol-base-tokens.css (imported first by kol-theme.css) — the
|
|
23
|
+
* shared canonical neutral base, identical to apps/web. */
|
|
24
|
+
|
|
25
|
+
/* ---------------------------------------------------------------------------
|
|
26
|
+
* ACCENT (interactive role — buttons, toggles, focus rings)
|
|
27
|
+
*
|
|
28
|
+
* Brand-neutral default: points at the surface ink color so the DS works
|
|
29
|
+
* without a brand layer. kol-brand-color.css overrides these to point at
|
|
30
|
+
* --brand-primary / --brand-on-primary / a brand-strong stop.
|
|
31
|
+
* --------------------------------------------------------------------------- */
|
|
32
|
+
|
|
33
|
+
--kol-accent-primary: var(--kol-surface-on-primary);
|
|
34
|
+
--kol-accent-on-primary: var(--kol-surface-primary);
|
|
35
|
+
--kol-accent-primary-strong: color-mix(in srgb, var(--kol-surface-on-primary) 80%, transparent);
|
|
36
|
+
|
|
37
|
+
/* ---------------------------------------------------------------------------
|
|
38
|
+
* UI STATE — error / warning / info / success.
|
|
39
|
+
* Direct hex (not ramp-dependent). Intentionally not part of the brand layer
|
|
40
|
+
* so consumers get sensible defaults out of the box.
|
|
41
|
+
* --------------------------------------------------------------------------- */
|
|
42
|
+
|
|
43
|
+
--ui-error: #B91C1C;
|
|
44
|
+
--ui-warning: #EAB308;
|
|
45
|
+
--ui-info: #1D4ED8;
|
|
46
|
+
--ui-success: #15803D;
|
|
47
|
+
|
|
48
|
+
/* ---------------------------------------------------------------------------
|
|
49
|
+
* BORDER
|
|
50
|
+
* --------------------------------------------------------------------------- */
|
|
51
|
+
|
|
52
|
+
--kol-border-default: color-mix(in srgb, var(--kol-surface-on-primary) 8%, transparent);
|
|
53
|
+
--kol-border-focus: color-mix(in srgb, var(--kol-accent-primary) 70%, var(--kol-surface-on-primary));
|
|
54
|
+
--kol-focus-ring: var(--kol-accent-primary);
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
:root[data-theme="light"] {
|
|
58
|
+
--ui-error: #DC2626;
|
|
59
|
+
--ui-warning: #CA8A04;
|
|
60
|
+
--ui-info: #2563EB;
|
|
61
|
+
--ui-success: #16A34A;
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
/* =============================================================================
|
|
65
|
+
* DARK MODE
|
|
66
|
+
* Explicit dark-mode surface overrides ([data-theme="dark"], .dark) now come
|
|
67
|
+
* from @kol/theme/kol-base-tokens.css (shared with apps/web). The system-
|
|
68
|
+
* preference auto-dark block below stays brand-local — web has no equivalent.
|
|
69
|
+
* ============================================================================= */
|
|
70
|
+
|
|
71
|
+
/* =============================================================================
|
|
72
|
+
* SYSTEM PREFERENCE (Automatic Dark Mode)
|
|
73
|
+
* ============================================================================= */
|
|
74
|
+
|
|
75
|
+
@media (prefers-color-scheme: dark) {
|
|
76
|
+
:root:not([data-theme="light"]) {
|
|
77
|
+
--kol-surface-primary: #121215;
|
|
78
|
+
--kol-surface-on-primary: #FAFAFA;
|
|
79
|
+
|
|
80
|
+
--kol-surface-secondary: #19191D;
|
|
81
|
+
--kol-surface-on-secondary: #F8F8F8;
|
|
82
|
+
|
|
83
|
+
--kol-surface-tertiary: #0E0E11;
|
|
84
|
+
--kol-surface-on-tertiary: #FFFFFF;
|
|
85
|
+
|
|
86
|
+
--kol-surface-inverse: #FCFBF8;
|
|
87
|
+
--kol-surface-on-inverse: #0E0E11;
|
|
88
|
+
}
|
|
89
|
+
}
|
|
90
|
+
|
|
91
|
+
/* =============================================================================
|
|
92
|
+
* CONTEXT-AWARE SURFACE INVERSE
|
|
93
|
+
* ============================================================================= */
|
|
94
|
+
|
|
95
|
+
.bg-surface-inverse {
|
|
96
|
+
background-color: var(--kol-surface-inverse);
|
|
97
|
+
color: var(--kol-surface-on-inverse);
|
|
98
|
+
|
|
99
|
+
--kol-surface-primary: var(--kol-surface-inverse);
|
|
100
|
+
--kol-surface-on-primary: var(--kol-surface-on-inverse);
|
|
101
|
+
--kol-surface-secondary: var(--kol-surface-secondary);
|
|
102
|
+
--kol-surface-on-secondary: var(--kol-surface-on-inverse);
|
|
103
|
+
--kol-surface-tertiary: var(--kol-surface-tertiary);
|
|
104
|
+
--kol-surface-on-tertiary: var(--kol-surface-on-inverse);
|
|
105
|
+
--kol-border-default: color-mix(in srgb, var(--kol-surface-on-inverse) 8%, transparent);
|
|
106
|
+
|
|
107
|
+
/* Re-declare fg-ramp against on-inverse so opacity tokens flip with surface.
|
|
108
|
+
* CSS substitutes inner var() at the declaration site, so the :root declarations
|
|
109
|
+
* bake the on-primary color and don't re-resolve here. Redeclaring here lets every
|
|
110
|
+
* --kol-fg-* consumer (borders, dividers, dimmed text) automatically contrast-flip. */
|
|
111
|
+
--kol-fg-01: color-mix(in srgb, var(--kol-surface-on-inverse) 1%, transparent);
|
|
112
|
+
--kol-fg-02: color-mix(in srgb, var(--kol-surface-on-inverse) 2%, transparent);
|
|
113
|
+
--kol-fg-04: color-mix(in srgb, var(--kol-surface-on-inverse) 4%, transparent);
|
|
114
|
+
--kol-fg-08: color-mix(in srgb, var(--kol-surface-on-inverse) 8%, transparent);
|
|
115
|
+
--kol-fg-12: color-mix(in srgb, var(--kol-surface-on-inverse) 12%, transparent);
|
|
116
|
+
--kol-fg-16: color-mix(in srgb, var(--kol-surface-on-inverse) 16%, transparent);
|
|
117
|
+
--kol-fg-24: color-mix(in srgb, var(--kol-surface-on-inverse) 24%, transparent);
|
|
118
|
+
--kol-fg-32: color-mix(in srgb, var(--kol-surface-on-inverse) 32%, transparent);
|
|
119
|
+
--kol-fg-40: color-mix(in srgb, var(--kol-surface-on-inverse) 40%, transparent);
|
|
120
|
+
--kol-fg-48: color-mix(in srgb, var(--kol-surface-on-inverse) 48%, transparent);
|
|
121
|
+
--kol-fg-64: color-mix(in srgb, var(--kol-surface-on-inverse) 64%, transparent);
|
|
122
|
+
--kol-fg-80: color-mix(in srgb, var(--kol-surface-on-inverse) 80%, transparent);
|
|
123
|
+
--kol-fg-88: color-mix(in srgb, var(--kol-surface-on-inverse) 88%, transparent);
|
|
124
|
+
--kol-fg-96: color-mix(in srgb, var(--kol-surface-on-inverse) 96%, transparent);
|
|
125
|
+
}
|
|
126
|
+
|
|
127
|
+
/* =============================================================================
|
|
128
|
+
* UTILITY CLASSES (HEAVILY USED — Based on usage audit)
|
|
129
|
+
*
|
|
130
|
+
* - .text-fg-* (594 references) live in kol-opacity.css
|
|
131
|
+
* - .border-fg-* / .bg-fg-* live in kol-opacity.css
|
|
132
|
+
*
|
|
133
|
+
* Below: surface + elevation + basic + state classes that consume the surface
|
|
134
|
+
* tier directly (not through opacity ramps).
|
|
135
|
+
* ============================================================================= */
|
|
136
|
+
|
|
137
|
+
/* ---------------------------------------------------------------------------
|
|
138
|
+
* Surface Utilities
|
|
139
|
+
* --------------------------------------------------------------------------- */
|
|
140
|
+
|
|
141
|
+
.bg-surface-primary {
|
|
142
|
+
background-color: var(--kol-surface-primary);
|
|
143
|
+
color: var(--kol-surface-on-primary);
|
|
144
|
+
}
|
|
145
|
+
|
|
146
|
+
.bg-surface-secondary {
|
|
147
|
+
background-color: var(--kol-surface-secondary);
|
|
148
|
+
color: var(--kol-surface-on-secondary);
|
|
149
|
+
}
|
|
150
|
+
|
|
151
|
+
.bg-surface-tertiary {
|
|
152
|
+
background-color: var(--kol-surface-tertiary);
|
|
153
|
+
color: var(--kol-surface-on-tertiary);
|
|
154
|
+
}
|
|
155
|
+
|
|
156
|
+
.bg-surface-inverse {
|
|
157
|
+
background-color: var(--kol-surface-inverse);
|
|
158
|
+
color: var(--kol-surface-on-inverse);
|
|
159
|
+
}
|
|
160
|
+
|
|
161
|
+
/* ---------------------------------------------------------------------------
|
|
162
|
+
* Elevation Utilities
|
|
163
|
+
* --------------------------------------------------------------------------- */
|
|
164
|
+
|
|
165
|
+
.elevation-base {
|
|
166
|
+
background-color: var(--kol-surface-primary);
|
|
167
|
+
color: var(--kol-surface-on-primary);
|
|
168
|
+
}
|
|
169
|
+
|
|
170
|
+
.elevation-raised {
|
|
171
|
+
background-color: var(--kol-surface-secondary);
|
|
172
|
+
color: var(--kol-surface-on-secondary);
|
|
173
|
+
}
|
|
174
|
+
|
|
175
|
+
.elevation-elevated {
|
|
176
|
+
background-color: var(--kol-surface-tertiary);
|
|
177
|
+
color: var(--kol-surface-on-tertiary);
|
|
178
|
+
}
|
|
179
|
+
|
|
180
|
+
/* ---------------------------------------------------------------------------
|
|
181
|
+
* Basic Utilities
|
|
182
|
+
* --------------------------------------------------------------------------- */
|
|
183
|
+
|
|
184
|
+
.text-auto {
|
|
185
|
+
color: var(--kol-surface-on-primary);
|
|
186
|
+
}
|
|
187
|
+
|
|
188
|
+
.text-inverse {
|
|
189
|
+
color: var(--kol-surface-on-inverse);
|
|
190
|
+
}
|
|
191
|
+
|
|
192
|
+
.bg-auto {
|
|
193
|
+
background-color: var(--kol-surface-primary);
|
|
194
|
+
}
|
|
195
|
+
|
|
196
|
+
.bg-fg {
|
|
197
|
+
background-color: var(--kol-surface-on-primary);
|
|
198
|
+
}
|
|
199
|
+
|
|
200
|
+
.border-auto {
|
|
201
|
+
border-color: var(--kol-border-default);
|
|
202
|
+
}
|
|
203
|
+
|
|
204
|
+
.divider-auto {
|
|
205
|
+
border-color: var(--kol-border-default);
|
|
206
|
+
border-width: 1px;
|
|
207
|
+
}
|
|
208
|
+
|
|
209
|
+
/* ---------------------------------------------------------------------------
|
|
210
|
+
* Surface-based Borders (for contrast on bg-fg fills)
|
|
211
|
+
* --------------------------------------------------------------------------- */
|
|
212
|
+
|
|
213
|
+
.border-surface {
|
|
214
|
+
border-color: var(--kol-surface-primary);
|
|
215
|
+
}
|
|
216
|
+
|
|
217
|
+
.border-surface-08 {
|
|
218
|
+
border-color: color-mix(in srgb, var(--kol-surface-primary) 8%, transparent);
|
|
219
|
+
}
|
|
220
|
+
|
|
221
|
+
.border-surface-16 {
|
|
222
|
+
border-color: color-mix(in srgb, var(--kol-surface-primary) 16%, transparent);
|
|
223
|
+
}
|
|
224
|
+
|
|
225
|
+
/* ---------------------------------------------------------------------------
|
|
226
|
+
* State Utilities
|
|
227
|
+
* --------------------------------------------------------------------------- */
|
|
228
|
+
|
|
229
|
+
.hover\:border-hover:hover {
|
|
230
|
+
border-color: var(--kol-border-default);
|
|
231
|
+
}
|
|
232
|
+
|
|
233
|
+
.focus\:border-focus:focus {
|
|
234
|
+
border-color: var(--kol-border-focus);
|
|
235
|
+
}
|
|
236
|
+
|
|
237
|
+
.focus-visible\:border-focus:focus-visible {
|
|
238
|
+
border-color: var(--kol-border-focus);
|
|
239
|
+
}
|
|
240
|
+
|
|
241
|
+
.focus-visible\:ring-focus:focus-visible {
|
|
242
|
+
outline: 2px solid var(--kol-focus-ring);
|
|
243
|
+
outline-offset: 2px;
|
|
244
|
+
}
|
|
245
|
+
|
|
246
|
+
/* ---------------------------------------------------------------------------
|
|
247
|
+
* Absolute Colors
|
|
248
|
+
* --------------------------------------------------------------------------- */
|
|
249
|
+
|
|
250
|
+
.bg-absolute-white {
|
|
251
|
+
background-color: var(--kol-color-absolute-white);
|
|
252
|
+
}
|
|
253
|
+
|
|
254
|
+
.bg-absolute-black {
|
|
255
|
+
background-color: var(--kol-color-absolute-black);
|
|
256
|
+
}
|
|
257
|
+
|
|
258
|
+
.text-absolute-white {
|
|
259
|
+
color: var(--kol-color-absolute-white);
|
|
260
|
+
}
|
|
261
|
+
|
|
262
|
+
.text-absolute-black {
|
|
263
|
+
color: var(--kol-color-absolute-black);
|
|
264
|
+
}
|
|
265
|
+
|
|
266
|
+
/* =============================================================================
|
|
267
|
+
* TAILWIND CONTRACT — color exposures (DS layer)
|
|
268
|
+
*
|
|
269
|
+
* Tailwind v4 generates utilities from --color-* tokens. UI state lives here
|
|
270
|
+
* (DS-level). Brand role + brand ramps + cream are registered in
|
|
271
|
+
* kol-brand-color.css (loaded after this file when client branding is desired).
|
|
272
|
+
* ============================================================================= */
|
|
273
|
+
|
|
274
|
+
@theme {
|
|
275
|
+
/* UI state — conventional Tailwind hexes, disconnected from brand ramps. */
|
|
276
|
+
--color-ui-error: var(--ui-error);
|
|
277
|
+
--color-ui-warning: var(--ui-warning);
|
|
278
|
+
--color-ui-info: var(--ui-info);
|
|
279
|
+
--color-ui-success: var(--ui-success);
|
|
280
|
+
}
|