@sckyzo/cosmos-theme 0.0.2 → 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/CHANGELOG.md CHANGED
@@ -5,6 +5,17 @@ All notable changes to `@sckyzo/cosmos-theme` are documented in this file.
5
5
  The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.1.0/),
6
6
  and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
7
7
 
8
+ ## [0.1.0](https://github.com/SckyzO/cosmos/compare/@sckyzo/cosmos-theme@0.0.2...@sckyzo/cosmos-theme@0.1.0) (2026-10-20)
9
+
10
+
11
+ ### ⚠ BREAKING CHANGES
12
+
13
+ * **theme:** .dark is now the neutral black/gray theme. Use .deep-blue for the previous navy dark theme.
14
+
15
+ ### Features
16
+
17
+ * **theme:** add sand, neutral dark, deep-blue themes and 12 accents ([2ab8ebb](https://github.com/SckyzO/cosmos/commit/2ab8ebb61ee2ca3eeaafb588eb93ab481b156cab))
18
+
8
19
  ## [0.0.2] - 2026-05-21
9
20
 
10
21
  Packaging/metadata only — no token, no CSS changes.
package/README.md CHANGED
@@ -1,27 +1,36 @@
1
1
  # @sckyzo/cosmos-theme
2
2
 
3
+ [![npm](https://img.shields.io/npm/v/@sckyzo/cosmos-theme)](https://www.npmjs.com/package/@sckyzo/cosmos-theme)
4
+
3
5
  Cosmos design tokens — CSS only.
4
6
 
5
7
  Provides three CSS files consumable by any framework:
6
8
 
7
- | Import | Purpose |
8
- | ------------------------------- | ---------------------------------------------------------------------- |
9
- | `@sckyzo/cosmos-theme/tailwind` | Tailwind 4 `@theme` block (palette, fonts, shadows, brand colors) |
10
- | `@sckyzo/cosmos-theme/vars` | Universal CSS custom properties (bg, text, border, accent + dark mode) |
11
- | `@sckyzo/cosmos-theme/fonts` | `@fontsource` font imports (Outfit + JetBrains Mono) |
9
+ | Import | Purpose |
10
+ | ------------------------------- | ------------------------------------------------------------------------------ |
11
+ | `@sckyzo/cosmos-theme/tailwind` | Tailwind 4 `@theme` block (palette, fonts, shadows, brand colors) |
12
+ | `@sckyzo/cosmos-theme/vars` | Universal CSS custom properties (bg, text, border, accent), themes and accents |
13
+ | `@sckyzo/cosmos-theme/fonts` | `@fontsource` font imports (Outfit + JetBrains Mono) |
12
14
 
13
15
  ## Usage
14
16
 
15
17
  ### With Tailwind 4 (recommended for React apps)
16
18
 
19
+ Import order matters: `tailwindcss` comes first, then the Cosmos tokens, then
20
+ the vars.
21
+
17
22
  ```css
18
23
  /* src/index.css */
19
- @import '@sckyzo/cosmos-theme/fonts';
20
- @import '@sckyzo/cosmos-theme/tailwind';
21
24
  @import 'tailwindcss';
25
+ @import '@sckyzo/cosmos-theme/tailwind';
22
26
  @import '@sckyzo/cosmos-theme/vars';
27
+ @import '@sckyzo/cosmos-theme/fonts';
23
28
  ```
24
29
 
30
+ Pairing this with `@sckyzo/cosmos-react`? You also need an `@source` line so
31
+ Tailwind scans the components — see the
32
+ [cosmos-react README](../react#set-up-the-styles).
33
+
25
34
  ### Without Tailwind (e.g. Docusaurus)
26
35
 
27
36
  ```css
@@ -30,6 +39,38 @@ Provides three CSS files consumable by any framework:
30
39
  /* Then reference vars: var(--color-brand-500), var(--color-bg-base), etc. */
31
40
  ```
32
41
 
42
+ ## Themes & accents
43
+
44
+ Two independent settings, both on the `<html>` element:
45
+
46
+ - **Theme**: one class, and only one at a time.
47
+
48
+ | Theme | Class | Look |
49
+ | ----------- | ------------ | -------------------------------------------- |
50
+ | `light` | _(none)_ | Cool gray, the default |
51
+ | `sand` | `.sand` | Warm beige light theme |
52
+ | `dark` | `.dark` | Neutral black/gray, softened (no pure black) |
53
+ | `deep-blue` | `.deep-blue` | Navy dark theme |
54
+
55
+ `.dark` and `.deep-blue` both enable Tailwind's `dark:` variant.
56
+
57
+ - **Accent**: a `data-accent` attribute that swaps the whole `--color-brand-*`
58
+ scale (and with it `--color-accent` and the focus ring). Leave it off for
59
+ `blue`. The others are `indigo`, `violet`, `purple`, `rose`, `teal`, `cyan`,
60
+ `graphite`, `red`, `orange`, `amber`, `green`.
61
+
62
+ ```html
63
+ <html class="sand" data-accent="teal"></html>
64
+ ```
65
+
66
+ `red`, `orange`, `amber` and `green` look like the status colors (error,
67
+ warning, success): a red primary button reads as a destructive action. Offer
68
+ them last in any picker, after the others.
69
+
70
+ Every theme × accent pair meets WCAG AA for body text, links and white text on
71
+ the accent. `pnpm --filter @sckyzo/cosmos-theme test` runs the contrast check
72
+ (`scripts/check-contrast.mjs`) against the CSS files.
73
+
33
74
  ## Tokens
34
75
 
35
76
  See [`css/tailwind-tokens.css`](css/tailwind-tokens.css) for the full source.
@@ -37,11 +78,11 @@ See [`css/tailwind-tokens.css`](css/tailwind-tokens.css) for the full source.
37
78
  Categories:
38
79
 
39
80
  - **Brand palette** : `--color-brand-25` to `--color-brand-950`
40
- - **Semantic colors** : `--color-success-*`, `--color-error-*`, `--color-warn-*`
81
+ - **Semantic colors** : `--color-success-*`, `--color-error-*`, `--color-warning-*`
41
82
  - **Status** : `--color-status-{ok,warn,crit,unknown}`
42
83
  - **Typography** : `--font-sans` (Outfit), `--font-mono` (JetBrains Mono)
43
84
  - **Shadows** : `--shadow-card`, `--shadow-card-hover`
44
- - **Layout vars** (dark-mode aware): `--color-bg-{base,panel,elevated}`, `--color-text-{base,primary,secondary,muted}`, `--color-border`, `--color-accent`
85
+ - **Layout vars** (theme-aware): `--color-bg-{base,panel,elevated}`, `--color-text-{base,primary,secondary,muted}`, `--color-border`, `--color-accent`
45
86
 
46
87
  ## License
47
88
 
package/css/css-vars.css CHANGED
@@ -1,7 +1,22 @@
1
1
  /* Cosmos CSS variables — universal (work with or without Tailwind).
2
2
  *
3
- * Light mode is :root (default). Dark mode is .dark — applied by the
4
- * consumer's theme switcher (ThemeContext, etc.) on the <html> element.
3
+ * Two independent settings on the <html> element, set by the consumer's
4
+ * theme switcher (ThemeContext, etc.):
5
+ *
6
+ * theme → one class, at most one at a time:
7
+ * light no class (:root default) — cool gray
8
+ * sand .sand — warm beige light theme
9
+ * dark .dark — neutral black/gray dark theme
10
+ * deep-blue .deep-blue — navy dark theme
11
+ * accent → data-accent="indigo" etc. — no attribute means blue
12
+ *
13
+ * <html class="sand" data-accent="teal">
14
+ *
15
+ * Themes and accents redefine Tailwind's palette variables (--color-white,
16
+ * --color-gray-*, --color-brand-*), so components styled with bg-white /
17
+ * text-gray-500 / dark:bg-gray-900 / bg-brand-500 follow them without
18
+ * per-theme classes. These rules stay outside any @layer so they win over
19
+ * the @theme block, which Tailwind emits in @layer theme.
5
20
  *
6
21
  * Consumers reference these via var(--color-bg-base), var(--color-text-primary), etc.
7
22
  * Tailwind 4 utilities (bg-accent-primary, etc.) are bridged via tailwind-tokens.css.
@@ -23,12 +38,71 @@
23
38
  --color-text-muted: #98a2b3;
24
39
 
25
40
  /* ── Accent ────────────────────────────────────────────────────────────── */
26
- --color-accent: #465fff;
41
+ --color-accent: var(--color-brand-500);
42
+ }
43
+
44
+ /* ── Themes ────────────────────────────────────────────────────────────── */
45
+
46
+ .sand {
47
+ --color-bg-base: #f9f5eb;
48
+ --color-bg-panel: #fffcf7;
49
+ --color-bg-elevated: #fffcf7;
50
+
51
+ --color-border: #d5cbba;
52
+
53
+ --color-text-base: #1e1711;
54
+ --color-text-primary: #1e1711;
55
+ --color-text-secondary: #746656;
56
+ --color-text-muted: #a39684;
57
+
58
+ /* Warm gray scale — same lightness steps as Tailwind gray, beige hue. */
59
+ --color-white: oklch(99.3% 0.008 85);
60
+ --color-gray-50: oklch(97% 0.014 85);
61
+ --color-gray-100: oklch(94.8% 0.018 84);
62
+ --color-gray-200: oklch(90.5% 0.022 82);
63
+ --color-gray-300: oklch(84.5% 0.026 80);
64
+ --color-gray-400: oklch(68% 0.03 75);
65
+ --color-gray-500: oklch(52% 0.03 70);
66
+ --color-gray-600: oklch(43% 0.028 65);
67
+ --color-gray-700: oklch(36% 0.025 60);
68
+ --color-gray-800: oklch(27.5% 0.02 60);
69
+ --color-gray-900: oklch(21% 0.016 60);
70
+ --color-gray-950: oklch(13% 0.012 60);
27
71
  }
28
72
 
29
73
  .dark {
30
74
  color-scheme: dark;
31
75
 
76
+ --color-bg-base: #0a0a0a;
77
+ --color-bg-panel: #141414;
78
+ --color-bg-elevated: #242424;
79
+
80
+ --color-border: #3d3d3d;
81
+
82
+ --color-text-base: #e5e5e5;
83
+ --color-text-primary: #fff;
84
+ --color-text-secondary: #a3a3a3;
85
+ --color-text-muted: #8f8f8f;
86
+
87
+ /* Neutral gray scale, softened near-black (no pure #000). */
88
+ --color-gray-50: #fafafa;
89
+ --color-gray-100: #f5f5f5;
90
+ --color-gray-200: #e5e5e5;
91
+ --color-gray-300: #d4d4d4;
92
+ --color-gray-400: #a3a3a3;
93
+ --color-gray-500: #8f8f8f;
94
+ --color-gray-600: #5c5c5c;
95
+ --color-gray-700: #3d3d3d;
96
+ --color-gray-800: #242424;
97
+ --color-gray-900: #141414;
98
+ --color-gray-950: #0a0a0a;
99
+ --color-gray-dark: #141414;
100
+ }
101
+
102
+ /* Uses Tailwind's default gray scale. */
103
+ .deep-blue {
104
+ color-scheme: dark;
105
+
32
106
  --color-bg-base: #0c111d;
33
107
  --color-bg-panel: #1a2231;
34
108
  --color-bg-elevated: #1d2939;
@@ -39,8 +113,175 @@
39
113
  --color-text-primary: #fff;
40
114
  --color-text-secondary: #98a2b3;
41
115
  --color-text-muted: #667085;
116
+ }
117
+
118
+ /* ── Accents ───────────────────────────────────────────────────────────────
119
+ Blue is the @theme default and has no rule. Red, orange, amber and green
120
+ look like the status colors (error / warning / success): list them last. */
121
+
122
+ [data-accent='indigo'] {
123
+ --color-brand-25: #f4f6fe;
124
+ --color-brand-50: #eff2fe;
125
+ --color-brand-100: #e2e7ff;
126
+ --color-brand-200: #c9d3ff;
127
+ --color-brand-300: #a7b5ff;
128
+ --color-brand-400: #7f8fff;
129
+ --color-brand-500: #5963e9;
130
+ --color-brand-600: #4a4fd3;
131
+ --color-brand-700: #3c3bbf;
132
+ --color-brand-800: #2f25ab;
133
+ --color-brand-900: #24257a;
134
+ --color-brand-950: #160b63;
135
+ }
136
+
137
+ [data-accent='violet'] {
138
+ --color-brand-25: #f7f5ff;
139
+ --color-brand-50: #f3f0fe;
140
+ --color-brand-100: #eae4ff;
141
+ --color-brand-200: #d8ceff;
142
+ --color-brand-300: #c0abff;
143
+ --color-brand-400: #a57eff;
144
+ --color-brand-500: #8745f1;
145
+ --color-brand-600: #752cdb;
146
+ --color-brand-700: #6508c6;
147
+ --color-brand-800: #5200a4;
148
+ --color-brand-900: #3f097e;
149
+ --color-brand-950: #2b005b;
150
+ }
151
+
152
+ [data-accent='purple'] {
153
+ --color-brand-25: #fcf3ff;
154
+ --color-brand-50: #fbedff;
155
+ --color-brand-100: #f7dfff;
156
+ --color-brand-200: #f0c2ff;
157
+ --color-brand-300: #e696ff;
158
+ --color-brand-400: #d55bf8;
159
+ --color-brand-500: #ad2ecf;
160
+ --color-brand-600: #990aba;
161
+ --color-brand-700: #81019e;
162
+ --color-brand-800: #690181;
163
+ --color-brand-900: #520066;
164
+ --color-brand-950: #380046;
165
+ }
166
+
167
+ [data-accent='rose'] {
168
+ --color-brand-25: #fff3f6;
169
+ --color-brand-50: #ffeef1;
170
+ --color-brand-100: #ffdfe6;
171
+ --color-brand-200: #ffc3d2;
172
+ --color-brand-300: #ff96b4;
173
+ --color-brand-400: #ff4e90;
174
+ --color-brand-500: #d4166d;
175
+ --color-brand-600: #b8005c;
176
+ --color-brand-700: #9b004c;
177
+ --color-brand-800: #7f013d;
178
+ --color-brand-900: #64002f;
179
+ --color-brand-950: #45001e;
180
+ }
181
+
182
+ [data-accent='teal'] {
183
+ --color-brand-25: #defffa;
184
+ --color-brand-50: #d2fdf6;
185
+ --color-brand-100: #c8f3ec;
186
+ --color-brand-200: #99e7dc;
187
+ --color-brand-300: #31d5c6;
188
+ --color-brand-400: #02b3a5;
189
+ --color-brand-500: #038378;
190
+ --color-brand-600: #006f66;
191
+ --color-brand-700: #015c54;
192
+ --color-brand-800: #024a43;
193
+ --color-brand-900: #003833;
194
+ --color-brand-950: #002723;
195
+ }
196
+
197
+ [data-accent='cyan'] {
198
+ --color-brand-25: #ecf9ff;
199
+ --color-brand-50: #e1f7ff;
200
+ --color-brand-100: #c8f0ff;
201
+ --color-brand-200: #96e3fe;
202
+ --color-brand-300: #25cefb;
203
+ --color-brand-400: #01abd3;
204
+ --color-brand-500: #017f9d;
205
+ --color-brand-600: #016b84;
206
+ --color-brand-700: #01596e;
207
+ --color-brand-800: #014759;
208
+ --color-brand-900: #003645;
209
+ --color-brand-950: #002631;
210
+ }
211
+
212
+ [data-accent='graphite'] {
213
+ --color-brand-25: #f5f7fb;
214
+ --color-brand-50: #f0f3f7;
215
+ --color-brand-100: #e6e8ec;
216
+ --color-brand-200: #d0d6e2;
217
+ --color-brand-300: #b5bbc7;
218
+ --color-brand-400: #959ba6;
219
+ --color-brand-500: #707580;
220
+ --color-brand-600: #5d626d;
221
+ --color-brand-700: #4c515c;
222
+ --color-brand-800: #3c414b;
223
+ --color-brand-900: #2e3138;
224
+ --color-brand-950: #1f2228;
225
+ }
226
+
227
+ [data-accent='red'] {
228
+ --color-brand-25: #fff4f3;
229
+ --color-brand-50: #ffeeec;
230
+ --color-brand-100: #ffe0dd;
231
+ --color-brand-200: #ffc6c0;
232
+ --color-brand-300: #ff9b94;
233
+ --color-brand-400: #ff5a57;
234
+ --color-brand-500: #db192a;
235
+ --color-brand-600: #be021e;
236
+ --color-brand-700: #a00118;
237
+ --color-brand-800: #830011;
238
+ --color-brand-900: #67000b;
239
+ --color-brand-950: #470005;
240
+ }
241
+
242
+ [data-accent='orange'] {
243
+ --color-brand-25: #fff4f0;
244
+ --color-brand-50: #ffefe8;
245
+ --color-brand-100: #ffe1d5;
246
+ --color-brand-200: #ffc8b0;
247
+ --color-brand-300: #ff9f73;
248
+ --color-brand-400: #f66a15;
249
+ --color-brand-500: #c04f01;
250
+ --color-brand-600: #a44201;
251
+ --color-brand-700: #8a3600;
252
+ --color-brand-800: #712b00;
253
+ --color-brand-900: #592000;
254
+ --color-brand-950: #3d1300;
255
+ }
256
+
257
+ [data-accent='amber'] {
258
+ --color-brand-25: #fff5ea;
259
+ --color-brand-50: #fff0e0;
260
+ --color-brand-100: #ffe3c5;
261
+ --color-brand-200: #ffcb8f;
262
+ --color-brand-300: #ffa408;
263
+ --color-brand-400: #d48700;
264
+ --color-brand-500: #a46800;
265
+ --color-brand-600: #8a5601;
266
+ --color-brand-700: #734701;
267
+ --color-brand-800: #5d3900;
268
+ --color-brand-900: #482b00;
269
+ --color-brand-950: #321c00;
270
+ }
42
271
 
43
- --color-accent: #465fff;
272
+ [data-accent='green'] {
273
+ --color-brand-25: #e5ffe9;
274
+ --color-brand-50: #d7ffde;
275
+ --color-brand-100: #cdf4d4;
276
+ --color-brand-200: #a5e9b2;
277
+ --color-brand-300: #5ad87e;
278
+ --color-brand-400: #32b75e;
279
+ --color-brand-500: #02863c;
280
+ --color-brand-600: #027232;
281
+ --color-brand-700: #015e28;
282
+ --color-brand-800: #014b1f;
283
+ --color-brand-900: #003915;
284
+ --color-brand-950: #00280d;
44
285
  }
45
286
 
46
287
  /* Smooth theme switching transition — opt-in via .cosmos-bg-transition class
@@ -1,17 +1,17 @@
1
1
  /* Cosmos Tailwind 4 theme — @theme block (generates Tailwind utility classes).
2
2
  *
3
- * Usage:
4
- * @import '@sckyzo/cosmos-theme/fonts';
5
- * @import '@sckyzo/cosmos-theme/tailwind';
3
+ * Usage (import order matters — tailwindcss first):
6
4
  * @import 'tailwindcss';
5
+ * @import '@sckyzo/cosmos-theme/tailwind';
7
6
  * @import '@sckyzo/cosmos-theme/vars';
7
+ * @import '@sckyzo/cosmos-theme/fonts';
8
8
  *
9
- * The dark variant is class-based (.dark) — applied by the consumer's theme switcher.
9
+ * The dark variant is class-based (.dark or .deep-blue) — applied by the consumer's theme switcher.
10
10
  */
11
11
 
12
- /* Tailwind dark variant: respond to the .dark class set by the consumer's ThemeContext,
13
- instead of (or in addition to) prefers-color-scheme. */
14
- @custom-variant dark (&:is(.dark, .dark *));
12
+ /* Tailwind dark variant: respond to the .dark / .deep-blue class set by the consumer's
13
+ ThemeContext, instead of (or in addition to) prefers-color-scheme. */
14
+ @custom-variant dark (&:is(.dark, .dark *, .deep-blue, .deep-blue *));
15
15
 
16
16
  @theme {
17
17
  /* ── Typography ─────────────────────────────────────────────────────────── */
@@ -34,9 +34,9 @@
34
34
  --shadow-theme-md: 0px 4px 8px -2px rgb(16 24 40 / 10%), 0px 2px 4px -2px rgb(16 24 40 / 6%);
35
35
  --shadow-theme-lg: 0px 12px 16px -4px rgb(16 24 40 / 8%), 0px 4px 6px -2px rgb(16 24 40 / 3%);
36
36
  --shadow-theme-xl: 0px 20px 24px -4px rgb(16 24 40 / 8%), 0px 8px 8px -4px rgb(16 24 40 / 3%);
37
- --shadow-focus-ring: 0px 0px 0px 4px rgb(70 95 255 / 12%);
37
+ --shadow-focus-ring: 0px 0px 0px 4px color-mix(in srgb, var(--color-brand-500) 12%, transparent);
38
38
 
39
- /* ── Brand palette (TailAdmin blue) ────────────────────────────────────── */
39
+ /* ── Brand palette (TailAdmin blue) — [data-accent] in css-vars.css swaps it ── */
40
40
  --color-brand-25: #f2f7ff;
41
41
  --color-brand-50: #ecf3ff;
42
42
  --color-brand-100: #dde9ff;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@sckyzo/cosmos-theme",
3
- "version": "0.0.2",
3
+ "version": "0.1.0",
4
4
  "description": "Tailwind 4 theme and design tokens for the Cosmos design system — palette, typography, radii and light/dark CSS variables.",
5
5
  "license": "MIT",
6
6
  "author": "SckyzO",
@@ -30,12 +30,12 @@
30
30
  "lint": "echo 'CSS-only package, no JS lint needed'",
31
31
  "lint:fix": "echo 'CSS-only package, no JS lint needed'",
32
32
  "typecheck": "echo 'CSS-only package, no TS check needed'",
33
- "test": "echo 'CSS-only package, no tests yet'",
33
+ "test": "node scripts/check-contrast.mjs",
34
34
  "build": "echo 'CSS-only package, no build step needed'"
35
35
  },
36
36
  "dependencies": {
37
- "@fontsource/jetbrains-mono": "^5.2.8",
38
- "@fontsource/outfit": "^5.2.8"
37
+ "@fontsource/jetbrains-mono": "^5.3.0",
38
+ "@fontsource/outfit": "^5.3.0"
39
39
  },
40
40
  "publishConfig": {
41
41
  "access": "public"