@sckyzo/cosmos-theme 0.0.2 → 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/CHANGELOG.md +21 -0
- package/README.md +81 -11
- package/css/css-vars.css +392 -4
- package/css/fonts/inter.css +2 -0
- package/css/fonts/montserrat.css +2 -0
- package/css/fonts/open-sans.css +2 -0
- package/css/fonts/plex.css +2 -0
- package/css/fonts.css +3 -2
- package/css/tailwind-tokens.css +15 -9
- package/package.json +12 -4
package/CHANGELOG.md
CHANGED
|
@@ -5,6 +5,27 @@ 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.2.0](https://github.com/SckyzO/cosmos/compare/@sckyzo/cosmos-theme@0.1.0...@sckyzo/cosmos-theme@0.2.0) (2026-10-21)
|
|
9
|
+
|
|
10
|
+
|
|
11
|
+
### Features
|
|
12
|
+
|
|
13
|
+
* **theme:** add a data-font setting with five more fonts ([6135b66](https://github.com/SckyzO/cosmos/commit/6135b6681f669bdcd178b113fb7b0cbf82aef5d0)), closes [#157](https://github.com/SckyzO/cosmos/issues/157)
|
|
14
|
+
* **theme:** add a data-text-size setting ([cd6ed5c](https://github.com/SckyzO/cosmos/commit/cd6ed5c07b15a9df12b56a3638ff0ca477cf1392)), closes [#157](https://github.com/SckyzO/cosmos/issues/157)
|
|
15
|
+
* **theme:** add syntax highlighting tokens ([8589ef1](https://github.com/SckyzO/cosmos/commit/8589ef1434fafdd20e7ae042372ff89a534a30f3))
|
|
16
|
+
* **theme:** add the text-2xs and text-3xs sizes ([57decb3](https://github.com/SckyzO/cosmos/commit/57decb3bc301ec65ce9966c84b8412cd9791b32a)), closes [#157](https://github.com/SckyzO/cosmos/issues/157)
|
|
17
|
+
|
|
18
|
+
## [0.1.0](https://github.com/SckyzO/cosmos/compare/@sckyzo/cosmos-theme@0.0.2...@sckyzo/cosmos-theme@0.1.0) (2026-10-20)
|
|
19
|
+
|
|
20
|
+
|
|
21
|
+
### ⚠ BREAKING CHANGES
|
|
22
|
+
|
|
23
|
+
* **theme:** .dark is now the neutral black/gray theme. Use .deep-blue for the previous navy dark theme.
|
|
24
|
+
|
|
25
|
+
### Features
|
|
26
|
+
|
|
27
|
+
* **theme:** add sand, neutral dark, deep-blue themes and 12 accents ([2ab8ebb](https://github.com/SckyzO/cosmos/commit/2ab8ebb61ee2ca3eeaafb588eb93ab481b156cab))
|
|
28
|
+
|
|
8
29
|
## [0.0.2] - 2026-05-21
|
|
9
30
|
|
|
10
31
|
Packaging/metadata only — no token, no CSS changes.
|
package/README.md
CHANGED
|
@@ -1,27 +1,37 @@
|
|
|
1
1
|
# @sckyzo/cosmos-theme
|
|
2
2
|
|
|
3
|
+
[](https://www.npmjs.com/package/@sckyzo/cosmos-theme)
|
|
4
|
+
|
|
3
5
|
Cosmos design tokens — CSS only.
|
|
4
6
|
|
|
5
|
-
Provides
|
|
7
|
+
Provides CSS files consumable by any framework:
|
|
6
8
|
|
|
7
|
-
| Import
|
|
8
|
-
|
|
|
9
|
-
| `@sckyzo/cosmos-theme/tailwind`
|
|
10
|
-
| `@sckyzo/cosmos-theme/vars`
|
|
11
|
-
| `@sckyzo/cosmos-theme/fonts`
|
|
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) |
|
|
14
|
+
| `@sckyzo/cosmos-theme/fonts/<name>` | One variable font for `data-font`: `inter`, `plex`, `montserrat`, `open-sans` |
|
|
12
15
|
|
|
13
16
|
## Usage
|
|
14
17
|
|
|
15
18
|
### With Tailwind 4 (recommended for React apps)
|
|
16
19
|
|
|
20
|
+
Import order matters: `tailwindcss` comes first, then the Cosmos tokens, then
|
|
21
|
+
the vars.
|
|
22
|
+
|
|
17
23
|
```css
|
|
18
24
|
/* src/index.css */
|
|
19
|
-
@import '@sckyzo/cosmos-theme/fonts';
|
|
20
|
-
@import '@sckyzo/cosmos-theme/tailwind';
|
|
21
25
|
@import 'tailwindcss';
|
|
26
|
+
@import '@sckyzo/cosmos-theme/tailwind';
|
|
22
27
|
@import '@sckyzo/cosmos-theme/vars';
|
|
28
|
+
@import '@sckyzo/cosmos-theme/fonts';
|
|
23
29
|
```
|
|
24
30
|
|
|
31
|
+
Pairing this with `@sckyzo/cosmos-react`? You also need an `@source` line so
|
|
32
|
+
Tailwind scans the components — see the
|
|
33
|
+
[cosmos-react README](../react#set-up-the-styles).
|
|
34
|
+
|
|
25
35
|
### Without Tailwind (e.g. Docusaurus)
|
|
26
36
|
|
|
27
37
|
```css
|
|
@@ -30,6 +40,65 @@ Provides three CSS files consumable by any framework:
|
|
|
30
40
|
/* Then reference vars: var(--color-brand-500), var(--color-bg-base), etc. */
|
|
31
41
|
```
|
|
32
42
|
|
|
43
|
+
## Themes & accents
|
|
44
|
+
|
|
45
|
+
Two independent settings, both on the `<html>` element:
|
|
46
|
+
|
|
47
|
+
- **Theme**: one class, and only one at a time.
|
|
48
|
+
|
|
49
|
+
| Theme | Class | Look |
|
|
50
|
+
| ----------- | ------------ | -------------------------------------------- |
|
|
51
|
+
| `light` | _(none)_ | Cool gray, the default |
|
|
52
|
+
| `sand` | `.sand` | Warm beige light theme |
|
|
53
|
+
| `dark` | `.dark` | Neutral black/gray, softened (no pure black) |
|
|
54
|
+
| `deep-blue` | `.deep-blue` | Navy dark theme |
|
|
55
|
+
|
|
56
|
+
`.dark` and `.deep-blue` both enable Tailwind's `dark:` variant.
|
|
57
|
+
|
|
58
|
+
- **Accent**: a `data-accent` attribute that swaps the whole `--color-brand-*`
|
|
59
|
+
scale (and with it `--color-accent` and the focus ring). Leave it off for
|
|
60
|
+
`blue`. The others are `indigo`, `violet`, `purple`, `rose`, `teal`, `cyan`,
|
|
61
|
+
`graphite`, `red`, `orange`, `amber`, `green`.
|
|
62
|
+
|
|
63
|
+
```html
|
|
64
|
+
<html class="sand" data-accent="teal"></html>
|
|
65
|
+
```
|
|
66
|
+
|
|
67
|
+
`red`, `orange`, `amber` and `green` look like the status colors (error,
|
|
68
|
+
warning, success): a red primary button reads as a destructive action. Offer
|
|
69
|
+
them last in any picker, after the others.
|
|
70
|
+
|
|
71
|
+
Every theme × accent pair meets WCAG AA for body text, links and white text on
|
|
72
|
+
the accent. `pnpm --filter @sckyzo/cosmos-theme test` runs the contrast check
|
|
73
|
+
(`scripts/check-contrast.mjs`) against the CSS files.
|
|
74
|
+
|
|
75
|
+
## Fonts & text size
|
|
76
|
+
|
|
77
|
+
Two more settings on `<html>`, both optional:
|
|
78
|
+
|
|
79
|
+
- **Font**: a `data-font` attribute that swaps `--font-sans`. Leave it off for
|
|
80
|
+
Outfit. The others are `inter`, `plex` (IBM Plex Sans), `montserrat`,
|
|
81
|
+
`open-sans`, and `system`, the platform's UI font. Each one loads from its own
|
|
82
|
+
subpath, so import only the fonts you offer; `system` loads nothing. The mono
|
|
83
|
+
font stays JetBrains Mono.
|
|
84
|
+
|
|
85
|
+
```css
|
|
86
|
+
@import '@sckyzo/cosmos-theme/fonts'; /* Outfit + JetBrains Mono */
|
|
87
|
+
@import '@sckyzo/cosmos-theme/fonts/inter';
|
|
88
|
+
```
|
|
89
|
+
|
|
90
|
+
- **Text size**: a `data-text-size` attribute, `sm`, `lg` or `xl`, that scales
|
|
91
|
+
every `text-*` size to 93.75%, 112.5% or 125%. Leave it off for 100%. Only the
|
|
92
|
+
text grows: spacing keeps its `rem` values, so layouts keep their density.
|
|
93
|
+
Sizes written in pixels, such as `text-[13px]`, don't scale; the `text-*`
|
|
94
|
+
scale includes `text-2xs` (11px) and `text-3xs` (10px) for small labels.
|
|
95
|
+
|
|
96
|
+
```html
|
|
97
|
+
<html class="sand" data-accent="teal" data-font="inter" data-text-size="lg"></html>
|
|
98
|
+
```
|
|
99
|
+
|
|
100
|
+
Both attributes also work on an element below `<html>`, for one part of a page.
|
|
101
|
+
|
|
33
102
|
## Tokens
|
|
34
103
|
|
|
35
104
|
See [`css/tailwind-tokens.css`](css/tailwind-tokens.css) for the full source.
|
|
@@ -37,11 +106,12 @@ See [`css/tailwind-tokens.css`](css/tailwind-tokens.css) for the full source.
|
|
|
37
106
|
Categories:
|
|
38
107
|
|
|
39
108
|
- **Brand palette** : `--color-brand-25` to `--color-brand-950`
|
|
40
|
-
- **Semantic colors** : `--color-success-*`, `--color-error-*`, `--color-
|
|
109
|
+
- **Semantic colors** : `--color-success-*`, `--color-error-*`, `--color-warning-*`
|
|
41
110
|
- **Status** : `--color-status-{ok,warn,crit,unknown}`
|
|
42
|
-
- **Typography** : `--font-sans` (Outfit), `--font-mono` (JetBrains Mono)
|
|
111
|
+
- **Typography** : `--font-sans` (Outfit), `--font-mono` (JetBrains Mono), `--text-2xs` (11px), `--text-3xs` (10px)
|
|
43
112
|
- **Shadows** : `--shadow-card`, `--shadow-card-hover`
|
|
44
|
-
- **Layout vars** (
|
|
113
|
+
- **Layout vars** (theme-aware): `--color-bg-{base,panel,elevated}`, `--color-text-{base,primary,secondary,muted}`, `--color-border`, `--color-accent`
|
|
114
|
+
- **Code highlighting** (theme-aware): `--color-code-foreground` and `--color-code-token-*` (keyword, string, comment, constant, function, parameter, string-expression, punctuation, link, inserted, deleted, changed). The names match Shiki's CSS variables theme with `variablePrefix: '--color-code-'`. Each one keeps 4.5:1 on CodeBlock's background in all four themes (checked by `pnpm test`).
|
|
45
115
|
|
|
46
116
|
## License
|
|
47
117
|
|
package/css/css-vars.css
CHANGED
|
@@ -1,7 +1,24 @@
|
|
|
1
1
|
/* Cosmos CSS variables — universal (work with or without Tailwind).
|
|
2
2
|
*
|
|
3
|
-
*
|
|
4
|
-
*
|
|
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
|
+
* font → data-font="inter" etc. — no attribute means Outfit
|
|
13
|
+
* text → data-text-size="sm" | "lg" | "xl" — no attribute means normal
|
|
14
|
+
*
|
|
15
|
+
* <html class="sand" data-accent="teal" data-font="inter" data-text-size="lg">
|
|
16
|
+
*
|
|
17
|
+
* Themes and accents redefine Tailwind's palette variables (--color-white,
|
|
18
|
+
* --color-gray-*, --color-brand-*), so components styled with bg-white /
|
|
19
|
+
* text-gray-500 / dark:bg-gray-900 / bg-brand-500 follow them without
|
|
20
|
+
* per-theme classes. These rules stay outside any @layer so they win over
|
|
21
|
+
* the @theme block, which Tailwind emits in @layer theme.
|
|
5
22
|
*
|
|
6
23
|
* Consumers reference these via var(--color-bg-base), var(--color-text-primary), etc.
|
|
7
24
|
* Tailwind 4 utilities (bg-accent-primary, etc.) are bridged via tailwind-tokens.css.
|
|
@@ -22,13 +39,113 @@
|
|
|
22
39
|
--color-text-secondary: #667085;
|
|
23
40
|
--color-text-muted: #98a2b3;
|
|
24
41
|
|
|
42
|
+
/* ── Code ──────────────────────────────────────────────────────────────── */
|
|
43
|
+
/* Syntax highlighting on CodeBlock (gray-50 / gray-900), read by Shiki's
|
|
44
|
+
* CSS variables theme with variablePrefix '--color-code-'. */
|
|
45
|
+
--color-code-foreground: oklch(27.8% 0.033 256.848);
|
|
46
|
+
--color-code-token-keyword: #6d28d9;
|
|
47
|
+
--color-code-token-string: #15803d;
|
|
48
|
+
--color-code-token-comment: #5b6472;
|
|
49
|
+
--color-code-token-constant: #b45309;
|
|
50
|
+
--color-code-token-function: #1d4ed8;
|
|
51
|
+
--color-code-token-parameter: #c2410c;
|
|
52
|
+
--color-code-token-string-expression: #0f766e;
|
|
53
|
+
--color-code-token-punctuation: #4b5563;
|
|
54
|
+
--color-code-token-link: #1d4ed8;
|
|
55
|
+
--color-code-token-inserted: #15803d;
|
|
56
|
+
--color-code-token-deleted: #b91c1c;
|
|
57
|
+
--color-code-token-changed: #b45309;
|
|
58
|
+
|
|
25
59
|
/* ── Accent ────────────────────────────────────────────────────────────── */
|
|
26
|
-
--color-accent:
|
|
60
|
+
--color-accent: var(--color-brand-500);
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
/* ── Themes ────────────────────────────────────────────────────────────── */
|
|
64
|
+
|
|
65
|
+
.sand {
|
|
66
|
+
--color-bg-base: #f9f5eb;
|
|
67
|
+
--color-bg-panel: #fffcf7;
|
|
68
|
+
--color-bg-elevated: #fffcf7;
|
|
69
|
+
|
|
70
|
+
--color-border: #d5cbba;
|
|
71
|
+
|
|
72
|
+
--color-text-base: #1e1711;
|
|
73
|
+
--color-text-primary: #1e1711;
|
|
74
|
+
--color-text-secondary: #746656;
|
|
75
|
+
--color-text-muted: #a39684;
|
|
76
|
+
|
|
77
|
+
/* ── Code ──────────────────────────────────────────────────────────────── */
|
|
78
|
+
/* Syntax highlighting on CodeBlock (gray-50 / gray-900), read by Shiki's
|
|
79
|
+
* CSS variables theme with variablePrefix '--color-code-'. */
|
|
80
|
+
--color-code-foreground: oklch(27.5% 0.02 60);
|
|
81
|
+
--color-code-token-comment: #6e5f4f;
|
|
82
|
+
--color-code-token-punctuation: #57493c;
|
|
83
|
+
|
|
84
|
+
/* Warm gray scale — same lightness steps as Tailwind gray, beige hue. */
|
|
85
|
+
--color-white: oklch(99.3% 0.008 85);
|
|
86
|
+
--color-gray-50: oklch(97% 0.014 85);
|
|
87
|
+
--color-gray-100: oklch(94.8% 0.018 84);
|
|
88
|
+
--color-gray-200: oklch(90.5% 0.022 82);
|
|
89
|
+
--color-gray-300: oklch(84.5% 0.026 80);
|
|
90
|
+
--color-gray-400: oklch(68% 0.03 75);
|
|
91
|
+
--color-gray-500: oklch(52% 0.03 70);
|
|
92
|
+
--color-gray-600: oklch(43% 0.028 65);
|
|
93
|
+
--color-gray-700: oklch(36% 0.025 60);
|
|
94
|
+
--color-gray-800: oklch(27.5% 0.02 60);
|
|
95
|
+
--color-gray-900: oklch(21% 0.016 60);
|
|
96
|
+
--color-gray-950: oklch(13% 0.012 60);
|
|
27
97
|
}
|
|
28
98
|
|
|
29
99
|
.dark {
|
|
30
100
|
color-scheme: dark;
|
|
31
101
|
|
|
102
|
+
--color-bg-base: #0a0a0a;
|
|
103
|
+
--color-bg-panel: #141414;
|
|
104
|
+
--color-bg-elevated: #242424;
|
|
105
|
+
|
|
106
|
+
--color-border: #3d3d3d;
|
|
107
|
+
|
|
108
|
+
--color-text-base: #e5e5e5;
|
|
109
|
+
--color-text-primary: #fff;
|
|
110
|
+
--color-text-secondary: #a3a3a3;
|
|
111
|
+
--color-text-muted: #8f8f8f;
|
|
112
|
+
|
|
113
|
+
/* ── Code ──────────────────────────────────────────────────────────────── */
|
|
114
|
+
/* Syntax highlighting on CodeBlock (gray-50 / gray-900), read by Shiki's
|
|
115
|
+
* CSS variables theme with variablePrefix '--color-code-'. */
|
|
116
|
+
--color-code-foreground: #e5e5e5;
|
|
117
|
+
--color-code-token-comment: #8f8f8f;
|
|
118
|
+
--color-code-token-punctuation: #a3a3a3;
|
|
119
|
+
--color-code-token-keyword: #c4b5fd;
|
|
120
|
+
--color-code-token-string: #86efac;
|
|
121
|
+
--color-code-token-constant: #fcd34d;
|
|
122
|
+
--color-code-token-function: #93c5fd;
|
|
123
|
+
--color-code-token-parameter: #fdba74;
|
|
124
|
+
--color-code-token-string-expression: #5eead4;
|
|
125
|
+
--color-code-token-link: #93c5fd;
|
|
126
|
+
--color-code-token-inserted: #86efac;
|
|
127
|
+
--color-code-token-deleted: #fca5a5;
|
|
128
|
+
--color-code-token-changed: #fcd34d;
|
|
129
|
+
|
|
130
|
+
/* Neutral gray scale, softened near-black (no pure #000). */
|
|
131
|
+
--color-gray-50: #fafafa;
|
|
132
|
+
--color-gray-100: #f5f5f5;
|
|
133
|
+
--color-gray-200: #e5e5e5;
|
|
134
|
+
--color-gray-300: #d4d4d4;
|
|
135
|
+
--color-gray-400: #a3a3a3;
|
|
136
|
+
--color-gray-500: #8f8f8f;
|
|
137
|
+
--color-gray-600: #5c5c5c;
|
|
138
|
+
--color-gray-700: #3d3d3d;
|
|
139
|
+
--color-gray-800: #242424;
|
|
140
|
+
--color-gray-900: #141414;
|
|
141
|
+
--color-gray-950: #0a0a0a;
|
|
142
|
+
--color-gray-dark: #141414;
|
|
143
|
+
}
|
|
144
|
+
|
|
145
|
+
/* Uses Tailwind's default gray scale. */
|
|
146
|
+
.deep-blue {
|
|
147
|
+
color-scheme: dark;
|
|
148
|
+
|
|
32
149
|
--color-bg-base: #0c111d;
|
|
33
150
|
--color-bg-panel: #1a2231;
|
|
34
151
|
--color-bg-elevated: #1d2939;
|
|
@@ -40,7 +157,278 @@
|
|
|
40
157
|
--color-text-secondary: #98a2b3;
|
|
41
158
|
--color-text-muted: #667085;
|
|
42
159
|
|
|
43
|
-
|
|
160
|
+
/* ── Code ──────────────────────────────────────────────────────────────── */
|
|
161
|
+
/* Syntax highlighting on CodeBlock (gray-50 / gray-900), read by Shiki's
|
|
162
|
+
* CSS variables theme with variablePrefix '--color-code-'. */
|
|
163
|
+
--color-code-foreground: oklch(92.8% 0.006 264.531);
|
|
164
|
+
--color-code-token-comment: #98a2b3;
|
|
165
|
+
--color-code-token-punctuation: #b8c0cc;
|
|
166
|
+
--color-code-token-keyword: #c4b5fd;
|
|
167
|
+
--color-code-token-string: #86efac;
|
|
168
|
+
--color-code-token-constant: #fcd34d;
|
|
169
|
+
--color-code-token-function: #93c5fd;
|
|
170
|
+
--color-code-token-parameter: #fdba74;
|
|
171
|
+
--color-code-token-string-expression: #5eead4;
|
|
172
|
+
--color-code-token-link: #93c5fd;
|
|
173
|
+
--color-code-token-inserted: #86efac;
|
|
174
|
+
--color-code-token-deleted: #fca5a5;
|
|
175
|
+
--color-code-token-changed: #fcd34d;
|
|
176
|
+
}
|
|
177
|
+
|
|
178
|
+
/* ── Accents ───────────────────────────────────────────────────────────────
|
|
179
|
+
Blue is the @theme default and has no rule. Red, orange, amber and green
|
|
180
|
+
look like the status colors (error / warning / success): list them last. */
|
|
181
|
+
|
|
182
|
+
[data-accent='indigo'] {
|
|
183
|
+
--color-brand-25: #f4f6fe;
|
|
184
|
+
--color-brand-50: #eff2fe;
|
|
185
|
+
--color-brand-100: #e2e7ff;
|
|
186
|
+
--color-brand-200: #c9d3ff;
|
|
187
|
+
--color-brand-300: #a7b5ff;
|
|
188
|
+
--color-brand-400: #7f8fff;
|
|
189
|
+
--color-brand-500: #5963e9;
|
|
190
|
+
--color-brand-600: #4a4fd3;
|
|
191
|
+
--color-brand-700: #3c3bbf;
|
|
192
|
+
--color-brand-800: #2f25ab;
|
|
193
|
+
--color-brand-900: #24257a;
|
|
194
|
+
--color-brand-950: #160b63;
|
|
195
|
+
}
|
|
196
|
+
|
|
197
|
+
[data-accent='violet'] {
|
|
198
|
+
--color-brand-25: #f7f5ff;
|
|
199
|
+
--color-brand-50: #f3f0fe;
|
|
200
|
+
--color-brand-100: #eae4ff;
|
|
201
|
+
--color-brand-200: #d8ceff;
|
|
202
|
+
--color-brand-300: #c0abff;
|
|
203
|
+
--color-brand-400: #a57eff;
|
|
204
|
+
--color-brand-500: #8745f1;
|
|
205
|
+
--color-brand-600: #752cdb;
|
|
206
|
+
--color-brand-700: #6508c6;
|
|
207
|
+
--color-brand-800: #5200a4;
|
|
208
|
+
--color-brand-900: #3f097e;
|
|
209
|
+
--color-brand-950: #2b005b;
|
|
210
|
+
}
|
|
211
|
+
|
|
212
|
+
[data-accent='purple'] {
|
|
213
|
+
--color-brand-25: #fcf3ff;
|
|
214
|
+
--color-brand-50: #fbedff;
|
|
215
|
+
--color-brand-100: #f7dfff;
|
|
216
|
+
--color-brand-200: #f0c2ff;
|
|
217
|
+
--color-brand-300: #e696ff;
|
|
218
|
+
--color-brand-400: #d55bf8;
|
|
219
|
+
--color-brand-500: #ad2ecf;
|
|
220
|
+
--color-brand-600: #990aba;
|
|
221
|
+
--color-brand-700: #81019e;
|
|
222
|
+
--color-brand-800: #690181;
|
|
223
|
+
--color-brand-900: #520066;
|
|
224
|
+
--color-brand-950: #380046;
|
|
225
|
+
}
|
|
226
|
+
|
|
227
|
+
[data-accent='rose'] {
|
|
228
|
+
--color-brand-25: #fff3f6;
|
|
229
|
+
--color-brand-50: #ffeef1;
|
|
230
|
+
--color-brand-100: #ffdfe6;
|
|
231
|
+
--color-brand-200: #ffc3d2;
|
|
232
|
+
--color-brand-300: #ff96b4;
|
|
233
|
+
--color-brand-400: #ff4e90;
|
|
234
|
+
--color-brand-500: #d4166d;
|
|
235
|
+
--color-brand-600: #b8005c;
|
|
236
|
+
--color-brand-700: #9b004c;
|
|
237
|
+
--color-brand-800: #7f013d;
|
|
238
|
+
--color-brand-900: #64002f;
|
|
239
|
+
--color-brand-950: #45001e;
|
|
240
|
+
}
|
|
241
|
+
|
|
242
|
+
[data-accent='teal'] {
|
|
243
|
+
--color-brand-25: #defffa;
|
|
244
|
+
--color-brand-50: #d2fdf6;
|
|
245
|
+
--color-brand-100: #c8f3ec;
|
|
246
|
+
--color-brand-200: #99e7dc;
|
|
247
|
+
--color-brand-300: #31d5c6;
|
|
248
|
+
--color-brand-400: #02b3a5;
|
|
249
|
+
--color-brand-500: #038378;
|
|
250
|
+
--color-brand-600: #006f66;
|
|
251
|
+
--color-brand-700: #015c54;
|
|
252
|
+
--color-brand-800: #024a43;
|
|
253
|
+
--color-brand-900: #003833;
|
|
254
|
+
--color-brand-950: #002723;
|
|
255
|
+
}
|
|
256
|
+
|
|
257
|
+
[data-accent='cyan'] {
|
|
258
|
+
--color-brand-25: #ecf9ff;
|
|
259
|
+
--color-brand-50: #e1f7ff;
|
|
260
|
+
--color-brand-100: #c8f0ff;
|
|
261
|
+
--color-brand-200: #96e3fe;
|
|
262
|
+
--color-brand-300: #25cefb;
|
|
263
|
+
--color-brand-400: #01abd3;
|
|
264
|
+
--color-brand-500: #017f9d;
|
|
265
|
+
--color-brand-600: #016b84;
|
|
266
|
+
--color-brand-700: #01596e;
|
|
267
|
+
--color-brand-800: #014759;
|
|
268
|
+
--color-brand-900: #003645;
|
|
269
|
+
--color-brand-950: #002631;
|
|
270
|
+
}
|
|
271
|
+
|
|
272
|
+
[data-accent='graphite'] {
|
|
273
|
+
--color-brand-25: #f5f7fb;
|
|
274
|
+
--color-brand-50: #f0f3f7;
|
|
275
|
+
--color-brand-100: #e6e8ec;
|
|
276
|
+
--color-brand-200: #d0d6e2;
|
|
277
|
+
--color-brand-300: #b5bbc7;
|
|
278
|
+
--color-brand-400: #959ba6;
|
|
279
|
+
--color-brand-500: #707580;
|
|
280
|
+
--color-brand-600: #5d626d;
|
|
281
|
+
--color-brand-700: #4c515c;
|
|
282
|
+
--color-brand-800: #3c414b;
|
|
283
|
+
--color-brand-900: #2e3138;
|
|
284
|
+
--color-brand-950: #1f2228;
|
|
285
|
+
}
|
|
286
|
+
|
|
287
|
+
[data-accent='red'] {
|
|
288
|
+
--color-brand-25: #fff4f3;
|
|
289
|
+
--color-brand-50: #ffeeec;
|
|
290
|
+
--color-brand-100: #ffe0dd;
|
|
291
|
+
--color-brand-200: #ffc6c0;
|
|
292
|
+
--color-brand-300: #ff9b94;
|
|
293
|
+
--color-brand-400: #ff5a57;
|
|
294
|
+
--color-brand-500: #db192a;
|
|
295
|
+
--color-brand-600: #be021e;
|
|
296
|
+
--color-brand-700: #a00118;
|
|
297
|
+
--color-brand-800: #830011;
|
|
298
|
+
--color-brand-900: #67000b;
|
|
299
|
+
--color-brand-950: #470005;
|
|
300
|
+
}
|
|
301
|
+
|
|
302
|
+
[data-accent='orange'] {
|
|
303
|
+
--color-brand-25: #fff4f0;
|
|
304
|
+
--color-brand-50: #ffefe8;
|
|
305
|
+
--color-brand-100: #ffe1d5;
|
|
306
|
+
--color-brand-200: #ffc8b0;
|
|
307
|
+
--color-brand-300: #ff9f73;
|
|
308
|
+
--color-brand-400: #f66a15;
|
|
309
|
+
--color-brand-500: #c04f01;
|
|
310
|
+
--color-brand-600: #a44201;
|
|
311
|
+
--color-brand-700: #8a3600;
|
|
312
|
+
--color-brand-800: #712b00;
|
|
313
|
+
--color-brand-900: #592000;
|
|
314
|
+
--color-brand-950: #3d1300;
|
|
315
|
+
}
|
|
316
|
+
|
|
317
|
+
[data-accent='amber'] {
|
|
318
|
+
--color-brand-25: #fff5ea;
|
|
319
|
+
--color-brand-50: #fff0e0;
|
|
320
|
+
--color-brand-100: #ffe3c5;
|
|
321
|
+
--color-brand-200: #ffcb8f;
|
|
322
|
+
--color-brand-300: #ffa408;
|
|
323
|
+
--color-brand-400: #d48700;
|
|
324
|
+
--color-brand-500: #a46800;
|
|
325
|
+
--color-brand-600: #8a5601;
|
|
326
|
+
--color-brand-700: #734701;
|
|
327
|
+
--color-brand-800: #5d3900;
|
|
328
|
+
--color-brand-900: #482b00;
|
|
329
|
+
--color-brand-950: #321c00;
|
|
330
|
+
}
|
|
331
|
+
|
|
332
|
+
[data-accent='green'] {
|
|
333
|
+
--color-brand-25: #e5ffe9;
|
|
334
|
+
--color-brand-50: #d7ffde;
|
|
335
|
+
--color-brand-100: #cdf4d4;
|
|
336
|
+
--color-brand-200: #a5e9b2;
|
|
337
|
+
--color-brand-300: #5ad87e;
|
|
338
|
+
--color-brand-400: #32b75e;
|
|
339
|
+
--color-brand-500: #02863c;
|
|
340
|
+
--color-brand-600: #027232;
|
|
341
|
+
--color-brand-700: #015e28;
|
|
342
|
+
--color-brand-800: #014b1f;
|
|
343
|
+
--color-brand-900: #003915;
|
|
344
|
+
--color-brand-950: #00280d;
|
|
345
|
+
}
|
|
346
|
+
|
|
347
|
+
/* ── Fonts ─────────────────────────────────────────────────────────────────
|
|
348
|
+
* data-font swaps the sans-serif family; no attribute keeps Outfit. Each
|
|
349
|
+
* font loads from its own subpath (@sckyzo/cosmos-theme/fonts/inter, …), so
|
|
350
|
+
* an app only ships the ones it offers; `system` uses the platform's UI font
|
|
351
|
+
* and loads nothing. The mono font stays JetBrains Mono.
|
|
352
|
+
*
|
|
353
|
+
* font-family is set here too: plain text inherits the family <html>
|
|
354
|
+
* computed, so an element below <html> with data-font needs its own
|
|
355
|
+
* font-family to switch. In the base layer, so font-mono on the same element
|
|
356
|
+
* still wins. */
|
|
357
|
+
@layer base {
|
|
358
|
+
[data-font] {
|
|
359
|
+
font-family: var(--font-sans);
|
|
360
|
+
}
|
|
361
|
+
}
|
|
362
|
+
|
|
363
|
+
[data-font='inter'] {
|
|
364
|
+
--font-sans: 'Inter Variable', system-ui, sans-serif;
|
|
365
|
+
}
|
|
366
|
+
|
|
367
|
+
[data-font='plex'] {
|
|
368
|
+
--font-sans: 'IBM Plex Sans Variable', system-ui, sans-serif;
|
|
369
|
+
}
|
|
370
|
+
|
|
371
|
+
[data-font='montserrat'] {
|
|
372
|
+
--font-sans: 'Montserrat Variable', system-ui, sans-serif;
|
|
373
|
+
}
|
|
374
|
+
|
|
375
|
+
[data-font='open-sans'] {
|
|
376
|
+
--font-sans: 'Open Sans Variable', system-ui, sans-serif;
|
|
377
|
+
}
|
|
378
|
+
|
|
379
|
+
[data-font='system'] {
|
|
380
|
+
--font-sans: system-ui, -apple-system, 'Segoe UI', Roboto, sans-serif;
|
|
381
|
+
}
|
|
382
|
+
|
|
383
|
+
/* ── Text size ─────────────────────────────────────────────────────────────
|
|
384
|
+
* data-text-size scales every text-* size: sm 93.75%, lg 112.5%, xl 125%;
|
|
385
|
+
* no attribute keeps 100%. Spacing stays the same, so layouts keep their
|
|
386
|
+
* density, and line heights follow (they are ratios). Sizes written in
|
|
387
|
+
* pixels, such as text-[9px], don't scale.
|
|
388
|
+
*
|
|
389
|
+
* The sizes are declared again here, not scaled in the @theme block: a
|
|
390
|
+
* custom property resolves var() on the element that declares it, so a
|
|
391
|
+
* --text-sm declared on :root would ignore an attribute set below <html>.
|
|
392
|
+
* Same values as Tailwind's, plus text-2xs and text-3xs. */
|
|
393
|
+
[data-text-size] {
|
|
394
|
+
--text-3xs: calc(0.625rem * var(--cosmos-text-scale, 1));
|
|
395
|
+
--text-2xs: calc(0.6875rem * var(--cosmos-text-scale, 1));
|
|
396
|
+
--text-xs: calc(0.75rem * var(--cosmos-text-scale, 1));
|
|
397
|
+
--text-sm: calc(0.875rem * var(--cosmos-text-scale, 1));
|
|
398
|
+
--text-base: calc(1rem * var(--cosmos-text-scale, 1));
|
|
399
|
+
--text-lg: calc(1.125rem * var(--cosmos-text-scale, 1));
|
|
400
|
+
--text-xl: calc(1.25rem * var(--cosmos-text-scale, 1));
|
|
401
|
+
--text-2xl: calc(1.5rem * var(--cosmos-text-scale, 1));
|
|
402
|
+
--text-3xl: calc(1.875rem * var(--cosmos-text-scale, 1));
|
|
403
|
+
--text-4xl: calc(2.25rem * var(--cosmos-text-scale, 1));
|
|
404
|
+
--text-5xl: calc(3rem * var(--cosmos-text-scale, 1));
|
|
405
|
+
--text-6xl: calc(3.75rem * var(--cosmos-text-scale, 1));
|
|
406
|
+
--text-7xl: calc(4.5rem * var(--cosmos-text-scale, 1));
|
|
407
|
+
--text-8xl: calc(6rem * var(--cosmos-text-scale, 1));
|
|
408
|
+
--text-9xl: calc(8rem * var(--cosmos-text-scale, 1));
|
|
409
|
+
}
|
|
410
|
+
|
|
411
|
+
[data-text-size='sm'] {
|
|
412
|
+
--cosmos-text-scale: 0.9375;
|
|
413
|
+
}
|
|
414
|
+
|
|
415
|
+
[data-text-size='lg'] {
|
|
416
|
+
--cosmos-text-scale: 1.125;
|
|
417
|
+
}
|
|
418
|
+
|
|
419
|
+
[data-text-size='xl'] {
|
|
420
|
+
--cosmos-text-scale: 1.25;
|
|
421
|
+
}
|
|
422
|
+
|
|
423
|
+
/* Text without a text-* class: body under <html data-text-size>, or the
|
|
424
|
+
element carrying the attribute below <html>. Not <html> itself, whose
|
|
425
|
+
font size sets rem and would scale the spacing too. In the base layer, so
|
|
426
|
+
a text-* class on the same element still wins. */
|
|
427
|
+
@layer base {
|
|
428
|
+
[data-text-size] body,
|
|
429
|
+
[data-text-size]:not(:root) {
|
|
430
|
+
font-size: var(--text-base);
|
|
431
|
+
}
|
|
44
432
|
}
|
|
45
433
|
|
|
46
434
|
/* Smooth theme switching transition — opt-in via .cosmos-bg-transition class
|
package/css/fonts.css
CHANGED
|
@@ -1,5 +1,6 @@
|
|
|
1
|
-
/* Cosmos fonts
|
|
2
|
-
|
|
1
|
+
/* Cosmos default fonts, Outfit and JetBrains Mono, self-hosted via @fontsource
|
|
2
|
+
(no network needed at runtime). The @fontsource packages are dependencies of
|
|
3
|
+
this package. The other data-font choices load from fonts/<name>.css. */
|
|
3
4
|
|
|
4
5
|
@import '@fontsource/outfit/300.css';
|
|
5
6
|
@import '@fontsource/outfit/400.css';
|
package/css/tailwind-tokens.css
CHANGED
|
@@ -1,23 +1,29 @@
|
|
|
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
|
|
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 ─────────────────────────────────────────────────────────── */
|
|
18
18
|
--font-sans: 'Outfit', system-ui, sans-serif;
|
|
19
19
|
--font-mono: 'JetBrains Mono', monospace;
|
|
20
20
|
|
|
21
|
+
/* Sizes under text-xs (12px) for dense labels: 11px and 10px. Without a
|
|
22
|
+
--line-height they set only font-size, like text-[11px] would, and the
|
|
23
|
+
text size setting in css-vars.css can scale them. */
|
|
24
|
+
--text-2xs: 0.6875rem;
|
|
25
|
+
--text-3xs: 0.625rem;
|
|
26
|
+
|
|
21
27
|
/* ── Status colors — health indicators, badges, alerts ─────────────────── */
|
|
22
28
|
--color-status-ok: #10b981;
|
|
23
29
|
--color-status-warn: #f59e0b;
|
|
@@ -34,9 +40,9 @@
|
|
|
34
40
|
--shadow-theme-md: 0px 4px 8px -2px rgb(16 24 40 / 10%), 0px 2px 4px -2px rgb(16 24 40 / 6%);
|
|
35
41
|
--shadow-theme-lg: 0px 12px 16px -4px rgb(16 24 40 / 8%), 0px 4px 6px -2px rgb(16 24 40 / 3%);
|
|
36
42
|
--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
|
|
43
|
+
--shadow-focus-ring: 0px 0px 0px 4px color-mix(in srgb, var(--color-brand-500) 12%, transparent);
|
|
38
44
|
|
|
39
|
-
/* ── Brand palette (TailAdmin blue)
|
|
45
|
+
/* ── Brand palette (TailAdmin blue) — [data-accent] in css-vars.css swaps it ── */
|
|
40
46
|
--color-brand-25: #f2f7ff;
|
|
41
47
|
--color-brand-50: #ecf3ff;
|
|
42
48
|
--color-brand-100: #dde9ff;
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@sckyzo/cosmos-theme",
|
|
3
|
-
"version": "0.0
|
|
3
|
+
"version": "0.2.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",
|
|
@@ -18,6 +18,10 @@
|
|
|
18
18
|
"./tailwind": "./css/tailwind-tokens.css",
|
|
19
19
|
"./vars": "./css/css-vars.css",
|
|
20
20
|
"./fonts": "./css/fonts.css",
|
|
21
|
+
"./fonts/inter": "./css/fonts/inter.css",
|
|
22
|
+
"./fonts/plex": "./css/fonts/plex.css",
|
|
23
|
+
"./fonts/montserrat": "./css/fonts/montserrat.css",
|
|
24
|
+
"./fonts/open-sans": "./css/fonts/open-sans.css",
|
|
21
25
|
"./package.json": "./package.json"
|
|
22
26
|
},
|
|
23
27
|
"files": [
|
|
@@ -30,12 +34,16 @@
|
|
|
30
34
|
"lint": "echo 'CSS-only package, no JS lint needed'",
|
|
31
35
|
"lint:fix": "echo 'CSS-only package, no JS lint needed'",
|
|
32
36
|
"typecheck": "echo 'CSS-only package, no TS check needed'",
|
|
33
|
-
"test": "
|
|
37
|
+
"test": "node scripts/check-contrast.mjs",
|
|
34
38
|
"build": "echo 'CSS-only package, no build step needed'"
|
|
35
39
|
},
|
|
36
40
|
"dependencies": {
|
|
37
|
-
"@fontsource/
|
|
38
|
-
"@fontsource/
|
|
41
|
+
"@fontsource-variable/ibm-plex-sans": "^5.3.0",
|
|
42
|
+
"@fontsource-variable/inter": "^5.3.0",
|
|
43
|
+
"@fontsource-variable/montserrat": "^5.3.0",
|
|
44
|
+
"@fontsource-variable/open-sans": "^5.3.0",
|
|
45
|
+
"@fontsource/jetbrains-mono": "^5.3.0",
|
|
46
|
+
"@fontsource/outfit": "^5.3.0"
|
|
39
47
|
},
|
|
40
48
|
"publishConfig": {
|
|
41
49
|
"access": "public"
|