@uncinq/design-tokens 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/LICENSE +21 -0
- package/README.md +220 -0
- package/package.json +36 -0
- package/tokens/index.css +10 -0
- package/tokens/primitive/color.css +128 -0
- package/tokens/primitive/font.css +30 -0
- package/tokens/primitive/opacity.css +12 -0
- package/tokens/primitive/shadow.css +16 -0
- package/tokens/primitive/size.css +57 -0
- package/tokens/primitive.css +8 -0
- package/tokens/semantic/border.css +15 -0
- package/tokens/semantic/color.css +88 -0
- package/tokens/semantic/fluid.css +30 -0
- package/tokens/semantic/focus.css +9 -0
- package/tokens/semantic/form.css +93 -0
- package/tokens/semantic/grid.css +53 -0
- package/tokens/semantic/motion.css +43 -0
- package/tokens/semantic/opacity.css +8 -0
- package/tokens/semantic/radius.css +19 -0
- package/tokens/semantic/ratio.css +13 -0
- package/tokens/semantic/size.css +19 -0
- package/tokens/semantic/spacing.css +21 -0
- package/tokens/semantic/typography.css +66 -0
- package/tokens/semantic/z-index.css +14 -0
- package/tokens/semantic.css +17 -0
package/LICENSE
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2026 Un Cinq
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
package/README.md
ADDED
|
@@ -0,0 +1,220 @@
|
|
|
1
|
+
# @uncinq/design-tokens
|
|
2
|
+
|
|
3
|
+
> Framework-agnostic design tokens for Un Cinq projects — Hugo, Symfony, Shopify, or any CSS environment.
|
|
4
|
+
|
|
5
|
+
<img width="1280" height="640" alt="share-design-tokens" src="https://github.com/user-attachments/assets/66b8ce73-b07d-4cd0-bcb7-f8e0f7a5bb98" />
|
|
6
|
+
|
|
7
|
+
## What are design tokens?
|
|
8
|
+
|
|
9
|
+
Design tokens are the atomic decisions of a design system: colors, spacing, typography, motion. Instead of hardcoding `#ae003f` or `1rem` throughout your codebase, you name the decision — `--color-brand`, `--spacing-md` — and reference that name everywhere.
|
|
10
|
+
|
|
11
|
+
## Token architecture
|
|
12
|
+
|
|
13
|
+
This package follows the [DTCG](docs/dtcg.md) three-layer model — primitive → semantic → component:
|
|
14
|
+
|
|
15
|
+
```
|
|
16
|
+
primitive → semantic → component
|
|
17
|
+
(raw values) (purpose) (component-scoped, not in this package)
|
|
18
|
+
```
|
|
19
|
+
|
|
20
|
+
### Layer 1 — Primitive
|
|
21
|
+
|
|
22
|
+
Raw, context-free values. No opinions about where they're used.
|
|
23
|
+
|
|
24
|
+
```css
|
|
25
|
+
--color-indigo-600: #4338ca;
|
|
26
|
+
--size-16: 1rem;
|
|
27
|
+
--font-weight-bold: 700;
|
|
28
|
+
```
|
|
29
|
+
|
|
30
|
+
A primitive token answers: **"what is the value?"**
|
|
31
|
+
|
|
32
|
+
### Layer 2 — Semantic
|
|
33
|
+
|
|
34
|
+
Named by purpose, not by appearance. References primitives via CSS `var()`.
|
|
35
|
+
|
|
36
|
+
```css
|
|
37
|
+
--color-brand: var(--color-indigo-600);
|
|
38
|
+
--spacing-md: var(--size-30);
|
|
39
|
+
--font-weight-heading: var(--font-weight-bold);
|
|
40
|
+
```
|
|
41
|
+
|
|
42
|
+
A semantic token answers: **"what is this value for?"**
|
|
43
|
+
|
|
44
|
+
This is the layer that gives portability: all projects consuming `@uncinq/design-tokens` share the same semantic API. When the brand color changes, you update one primitive — all semantic tokens that reference it update automatically.
|
|
45
|
+
|
|
46
|
+
### Layer 3 — Component
|
|
47
|
+
|
|
48
|
+
Scoped to a specific component. Generic component tokens are provided by [@uncinq/component-tokens](https://github.com/uncinq/component-tokens); project-specific ones live in each project's own design system.
|
|
49
|
+
|
|
50
|
+
```css
|
|
51
|
+
--alert-border-radius: var(--radius-none);
|
|
52
|
+
--btn-padding: var(--spacing-control);
|
|
53
|
+
```
|
|
54
|
+
|
|
55
|
+
---
|
|
56
|
+
|
|
57
|
+
## Naming convention
|
|
58
|
+
|
|
59
|
+
All tokens follow the pattern: `--{category}-{subcategory?}-{variant}-{state?}`
|
|
60
|
+
|
|
61
|
+
```
|
|
62
|
+
--{category} --color
|
|
63
|
+
-{subcategory} --color-text
|
|
64
|
+
-{variant} --color-text-muted
|
|
65
|
+
-{state} --color-text-disabled
|
|
66
|
+
```
|
|
67
|
+
|
|
68
|
+
### Rules
|
|
69
|
+
|
|
70
|
+
- **Lowercase kebab-case** — always
|
|
71
|
+
- **No component names** in primitive or semantic tokens (`--button-*` belongs in component tokens, not here)
|
|
72
|
+
- **Semantic tokens are named by intent** — they may reference a primitive via `var()` or carry a raw value when the value itself has design intent (e.g. `--z-index-modal: 400`, `--radius-pill: 9999px`)
|
|
73
|
+
- **States at the end** — `-hover`, `-focus`, `-active`, `-disabled`, `-checked`
|
|
74
|
+
- **`color-*` prefix for all color values** — even when the CSS property is `background-color`, `border-color`, etc.
|
|
75
|
+
- **Alphabetical order** — tokens within a file are sorted alphabetically; group related tokens with a comment when the file has many entries:
|
|
76
|
+
|
|
77
|
+
```css
|
|
78
|
+
/* Brand */
|
|
79
|
+
--color-brand: var(--color-indigo-600);
|
|
80
|
+
--color-brand-hover: var(--color-indigo-700);
|
|
81
|
+
|
|
82
|
+
/* Text */
|
|
83
|
+
--color-text: var(--color-gray-900);
|
|
84
|
+
--color-text-muted: var(--color-gray-500);
|
|
85
|
+
```
|
|
86
|
+
|
|
87
|
+
### Scales
|
|
88
|
+
|
|
89
|
+
| Use case | Scale | Example |
|
|
90
|
+
| --- | --- | --- |
|
|
91
|
+
| Color palettes | Numeric `100–900` | `--color-gray-500` |
|
|
92
|
+
| Heading levels | Zero-padded `01–06` | `--font-size-heading-01` |
|
|
93
|
+
| Layout / spacing | T-shirt `2xs xs sm md lg xl 2xl` | `--spacing-md` |
|
|
94
|
+
| Radius, shadow, size | T-shirt `2xs xs sm md lg xl 2xl` | `--radius-sm` |
|
|
95
|
+
| Purposeful aliases | Named | `--radius-control`, `--radius-pill` |
|
|
96
|
+
|
|
97
|
+
### Category reference
|
|
98
|
+
|
|
99
|
+
| Category | Covers | Example tokens |
|
|
100
|
+
| --- | --- | --- |
|
|
101
|
+
| `color` | All color values | `--color-brand`, `--color-bg-muted`, `--color-text-on-dark` |
|
|
102
|
+
| `font-family` | Typefaces | `--font-family-sans`, `--font-family-heading` |
|
|
103
|
+
| `font-size` | Text sizes | `--font-size-sm`, `--font-size-heading-01` |
|
|
104
|
+
| `font-weight` | Weight values | `--font-weight-bold`, `--font-weight-heading` |
|
|
105
|
+
| `line-height` | Line heights | `--line-height-tight`, `--line-height-heading` |
|
|
106
|
+
| `letter-spacing` | Tracking | `--letter-spacing-large` |
|
|
107
|
+
| `text-decoration` | Decoration props | `--text-decoration-underline`, `--text-decoration-offset` |
|
|
108
|
+
| `spacing` | Margin / padding | `--spacing-md`, `--spacing-section` |
|
|
109
|
+
| `size` | Width / height | `--size-16`, `--size-tablet` |
|
|
110
|
+
| `radius` | Border radius | `--radius-md`, `--radius-pill` |
|
|
111
|
+
| `border` | Border style/width | `--border-width-normal`, `--border-style-solid` |
|
|
112
|
+
| `shadow` | Box shadows | `--shadow-md`, `--shadow-center-sm` |
|
|
113
|
+
| `duration` | Animation timing | `--duration-fast` |
|
|
114
|
+
| `easing` | Timing functions | `--easing-bounce` |
|
|
115
|
+
| `transition` | Shorthand transitions | `--transition-normal`, `--transition-color` |
|
|
116
|
+
| `ratio` | Aspect ratios | `--ratio-16-9` |
|
|
117
|
+
| `flex` | Flex-basis fractions | `--flex-half`, `--flex-third` |
|
|
118
|
+
| `fluid-text` | Responsive fluid type scale (Utopia) | `--fluid-text-sm`, `--fluid-text-xl` |
|
|
119
|
+
| `fluid-spacing` | Responsive fluid spacing scale (Utopia) | `--fluid-spacing-sm`, `--fluid-spacing-lg` |
|
|
120
|
+
| `focus` | Focus ring tokens | `--focus-color`, `--focus-outline-width` |
|
|
121
|
+
| `opacity` | Opacity values | `--opacity-disabled`, `--opacity-overlay` |
|
|
122
|
+
| `span` | Grid column spans | `--span-6`, `--span-4` |
|
|
123
|
+
| `z-index` | Stacking order | `--z-index-modal`, `--z-index-dropdown` |
|
|
124
|
+
| `max-width` | Readability caps | `--max-width-paragraph` |
|
|
125
|
+
|
|
126
|
+
---
|
|
127
|
+
|
|
128
|
+
## CSS cascade layers
|
|
129
|
+
|
|
130
|
+
All tokens are declared inside `@layer config`, the lowest-priority layer in the stack:
|
|
131
|
+
|
|
132
|
+
```css
|
|
133
|
+
@layer config, base, layouts, vendors, components;
|
|
134
|
+
```
|
|
135
|
+
|
|
136
|
+
This means any project can **override any token** in its own `@layer config` block, simply by importing after this package:
|
|
137
|
+
|
|
138
|
+
```css
|
|
139
|
+
@import '@uncinq/design-tokens/tokens/index.css'; /* package defaults */
|
|
140
|
+
|
|
141
|
+
/* your project overrides — same layer, wins by order */
|
|
142
|
+
@layer config {
|
|
143
|
+
:root {
|
|
144
|
+
--color-brand: #0070f3;
|
|
145
|
+
--font-family-sans: 'Inter', system-ui, sans-serif;
|
|
146
|
+
}
|
|
147
|
+
}
|
|
148
|
+
```
|
|
149
|
+
|
|
150
|
+
→ MDN: [Using CSS cascade layers](https://developer.mozilla.org/en-US/docs/Learn_web_development/Core/Styling_basics/Cascade_layers)
|
|
151
|
+
|
|
152
|
+
---
|
|
153
|
+
|
|
154
|
+
## Installation
|
|
155
|
+
|
|
156
|
+
```bash
|
|
157
|
+
npm install @uncinq/design-tokens
|
|
158
|
+
# or
|
|
159
|
+
yarn add @uncinq/design-tokens
|
|
160
|
+
```
|
|
161
|
+
|
|
162
|
+
### Usage — CSS import
|
|
163
|
+
|
|
164
|
+
```css
|
|
165
|
+
/* everything */
|
|
166
|
+
@import '@uncinq/design-tokens';
|
|
167
|
+
|
|
168
|
+
/* or by layer */
|
|
169
|
+
@import '@uncinq/design-tokens/tokens/primitive.css';
|
|
170
|
+
@import '@uncinq/design-tokens/tokens/semantic.css';
|
|
171
|
+
|
|
172
|
+
/* or file by file */
|
|
173
|
+
@import '@uncinq/design-tokens/tokens/primitive/color.css';
|
|
174
|
+
@import '@uncinq/design-tokens/tokens/semantic/color.css';
|
|
175
|
+
```
|
|
176
|
+
|
|
177
|
+
### Usage — CDN (no build step)
|
|
178
|
+
|
|
179
|
+
```html
|
|
180
|
+
<link rel="stylesheet" href="https://unpkg.com/@uncinq/design-tokens/tokens/index.css">
|
|
181
|
+
```
|
|
182
|
+
|
|
183
|
+
---
|
|
184
|
+
|
|
185
|
+
## File structure
|
|
186
|
+
|
|
187
|
+
```
|
|
188
|
+
tokens/
|
|
189
|
+
index.css ← imports all layers in order
|
|
190
|
+
primitive/
|
|
191
|
+
color.css ← color palette (Tailwind v3 — amber, blue, gray, green…)
|
|
192
|
+
font.css ← font families, weights, line-heights, text-decoration
|
|
193
|
+
opacity.css ← opacity scale (0 → 1)
|
|
194
|
+
shadow.css ← box-shadow scale
|
|
195
|
+
size.css ← rem scale (--size-1 → --size-1920)
|
|
196
|
+
semantic/
|
|
197
|
+
border.css ← border styles and widths
|
|
198
|
+
color.css ← purposeful color aliases (--color-brand, --color-bg…)
|
|
199
|
+
fluid.css ← responsive clamp() scales (--fluid-text-*, --fluid-spacing-*)
|
|
200
|
+
focus.css ← focus ring tokens (color, style, width, offset)
|
|
201
|
+
form.css ← form control tokens (input, label, checkbox, switch…)
|
|
202
|
+
grid.css ← columns, gap, flex fractions, integer spans (--span-1 → --span-24)
|
|
203
|
+
motion.css ← duration, easing (standard + expressive + spring), transitions
|
|
204
|
+
opacity.css ← purposeful opacity aliases (disabled, overlay)
|
|
205
|
+
radius.css ← border-radius scale + purposeful aliases
|
|
206
|
+
ratio.css ← aspect-ratio values (16/9, 4/3…)
|
|
207
|
+
size.css ← T-shirt scale + breakpoint aliases
|
|
208
|
+
spacing.css ← spacing scale + purposeful aliases
|
|
209
|
+
typography.css ← font-size scale (fixed + fluid), heading sizes, max-widths
|
|
210
|
+
z-index.css ← stacking order (below → tooltip)
|
|
211
|
+
```
|
|
212
|
+
|
|
213
|
+
---
|
|
214
|
+
|
|
215
|
+
## References
|
|
216
|
+
|
|
217
|
+
- [DTCG — format and concepts](docs/dtcg.md)
|
|
218
|
+
- [DTCG specification](https://tr.designtokens.org/format/) — W3C Community Group draft
|
|
219
|
+
- [Style Dictionary](https://amzn.github.io/style-dictionary/) — token build pipeline (JSON → CSS/SCSS/JS)
|
|
220
|
+
- [MDN: CSS cascade layers](https://developer.mozilla.org/en-US/docs/Learn_web_development/Core/Styling_basics/Cascade_layers)
|
package/package.json
ADDED
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@uncinq/design-tokens",
|
|
3
|
+
"version": "0.1.0",
|
|
4
|
+
"description": "Framework-agnostic CSS design tokens — primitive and semantic layers.",
|
|
5
|
+
"license": "MIT",
|
|
6
|
+
"repository": {
|
|
7
|
+
"type": "git",
|
|
8
|
+
"url": "https://github.com/uncinq/design-tokens.git"
|
|
9
|
+
},
|
|
10
|
+
"homepage": "https://github.com/uncinq/design-tokens#readme",
|
|
11
|
+
"author": {
|
|
12
|
+
"name": "Un Cinq",
|
|
13
|
+
"url": "https://uncinq.dev/"
|
|
14
|
+
},
|
|
15
|
+
"keywords": [
|
|
16
|
+
"design-tokens",
|
|
17
|
+
"css",
|
|
18
|
+
"custom-properties",
|
|
19
|
+
"design-system"
|
|
20
|
+
],
|
|
21
|
+
"files": [
|
|
22
|
+
"tokens/"
|
|
23
|
+
],
|
|
24
|
+
"exports": {
|
|
25
|
+
".": "./tokens/index.css",
|
|
26
|
+
"./tokens/index.css": "./tokens/index.css",
|
|
27
|
+
"./tokens/primitive.css": "./tokens/primitive.css",
|
|
28
|
+
"./tokens/semantic.css": "./tokens/semantic.css",
|
|
29
|
+
"./tokens/primitive/*": "./tokens/primitive/*",
|
|
30
|
+
"./tokens/semantic/*": "./tokens/semantic/*"
|
|
31
|
+
},
|
|
32
|
+
"style": "./tokens/index.css",
|
|
33
|
+
"publishConfig": {
|
|
34
|
+
"access": "public"
|
|
35
|
+
}
|
|
36
|
+
}
|
package/tokens/index.css
ADDED
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
/* @uncinq/design-tokens — index.css */
|
|
2
|
+
/*
|
|
3
|
+
* Imports all layers in order: primitives first, then semantic.
|
|
4
|
+
* Use this file to get everything, or import primitive.css / semantic.css individually.
|
|
5
|
+
*
|
|
6
|
+
* Usage:
|
|
7
|
+
* @import '@uncinq/design-tokens/tokens/index.css';
|
|
8
|
+
*/
|
|
9
|
+
@import 'primitive.css';
|
|
10
|
+
@import 'semantic.css';
|
|
@@ -0,0 +1,128 @@
|
|
|
1
|
+
/* primitive/color.css */
|
|
2
|
+
@layer config {
|
|
3
|
+
:root {
|
|
4
|
+
--color-black: #000000;
|
|
5
|
+
|
|
6
|
+
--color-amber-100: #fef3c7;
|
|
7
|
+
--color-amber-200: #fde68a;
|
|
8
|
+
--color-amber-300: #fcd34d;
|
|
9
|
+
--color-amber-400: #fbbf24;
|
|
10
|
+
--color-amber-500: #f59e0b;
|
|
11
|
+
--color-amber-600: #d97706;
|
|
12
|
+
--color-amber-700: #b45309;
|
|
13
|
+
--color-amber-800: #92400e;
|
|
14
|
+
--color-amber-900: #78350f;
|
|
15
|
+
|
|
16
|
+
--color-blue-100: #dbeafe;
|
|
17
|
+
--color-blue-200: #bfdbfe;
|
|
18
|
+
--color-blue-300: #93c5fd;
|
|
19
|
+
--color-blue-400: #60a5fa;
|
|
20
|
+
--color-blue-500: #3b82f6;
|
|
21
|
+
--color-blue-600: #2563eb;
|
|
22
|
+
--color-blue-700: #1d4ed8;
|
|
23
|
+
--color-blue-800: #1e40af;
|
|
24
|
+
--color-blue-900: #1e3a8a;
|
|
25
|
+
|
|
26
|
+
--color-gray-100: #f3f4f6;
|
|
27
|
+
--color-gray-200: #e5e7eb;
|
|
28
|
+
--color-gray-300: #d1d5db;
|
|
29
|
+
--color-gray-400: #9ca3af;
|
|
30
|
+
--color-gray-500: #6b7280;
|
|
31
|
+
--color-gray-600: #4b5563;
|
|
32
|
+
--color-gray-700: #374151;
|
|
33
|
+
--color-gray-800: #1f2937;
|
|
34
|
+
--color-gray-900: #111827;
|
|
35
|
+
|
|
36
|
+
--color-green-100: #dcfce7;
|
|
37
|
+
--color-green-200: #bbf7d0;
|
|
38
|
+
--color-green-300: #86efac;
|
|
39
|
+
--color-green-400: #4ade80;
|
|
40
|
+
--color-green-500: #22c55e;
|
|
41
|
+
--color-green-600: #16a34a;
|
|
42
|
+
--color-green-700: #15803d;
|
|
43
|
+
--color-green-800: #166534;
|
|
44
|
+
--color-green-900: #14532d;
|
|
45
|
+
|
|
46
|
+
--color-cyan-100: #cffafe;
|
|
47
|
+
--color-cyan-200: #a5f3fc;
|
|
48
|
+
--color-cyan-300: #67e8f9;
|
|
49
|
+
--color-cyan-400: #22d3ee;
|
|
50
|
+
--color-cyan-500: #06b6d4;
|
|
51
|
+
--color-cyan-600: #0891b2;
|
|
52
|
+
--color-cyan-700: #0e7490;
|
|
53
|
+
--color-cyan-800: #155e75;
|
|
54
|
+
--color-cyan-900: #164e63;
|
|
55
|
+
|
|
56
|
+
--color-indigo-100: #e0e7ff;
|
|
57
|
+
--color-indigo-200: #c7d2fe;
|
|
58
|
+
--color-indigo-300: #a5b4fc;
|
|
59
|
+
--color-indigo-400: #818cf8;
|
|
60
|
+
--color-indigo-500: #4f46e5;
|
|
61
|
+
--color-indigo-600: #4338ca;
|
|
62
|
+
--color-indigo-700: #3730a3;
|
|
63
|
+
--color-indigo-800: #312e81;
|
|
64
|
+
--color-indigo-900: #2e1065;
|
|
65
|
+
|
|
66
|
+
--color-orange-100: #ffedd5;
|
|
67
|
+
--color-orange-200: #fed7aa;
|
|
68
|
+
--color-orange-300: #fdba74;
|
|
69
|
+
--color-orange-400: #fb923c;
|
|
70
|
+
--color-orange-500: #f97316;
|
|
71
|
+
--color-orange-600: #ea580c;
|
|
72
|
+
--color-orange-700: #c2410c;
|
|
73
|
+
--color-orange-800: #9a3412;
|
|
74
|
+
--color-orange-900: #431407;
|
|
75
|
+
|
|
76
|
+
--color-pink-100: #fce7f3;
|
|
77
|
+
--color-pink-200: #fbcfe8;
|
|
78
|
+
--color-pink-300: #f9a8d4;
|
|
79
|
+
--color-pink-400: #f472b6;
|
|
80
|
+
--color-pink-500: #ec4899;
|
|
81
|
+
--color-pink-600: #db2777;
|
|
82
|
+
--color-pink-700: #be185d;
|
|
83
|
+
--color-pink-800: #9d174d;
|
|
84
|
+
--color-pink-900: #831843;
|
|
85
|
+
|
|
86
|
+
--color-purple-100: #f3e8ff;
|
|
87
|
+
--color-purple-200: #e9d5ff;
|
|
88
|
+
--color-purple-300: #d8b4fe;
|
|
89
|
+
--color-purple-400: #c084fc;
|
|
90
|
+
--color-purple-500: #a855f7;
|
|
91
|
+
--color-purple-600: #9333ea;
|
|
92
|
+
--color-purple-700: #7e22ce;
|
|
93
|
+
--color-purple-800: #6b21a8;
|
|
94
|
+
--color-purple-900: #581c87;
|
|
95
|
+
|
|
96
|
+
--color-red-100: #fee2e2;
|
|
97
|
+
--color-red-200: #fecaca;
|
|
98
|
+
--color-red-300: #fca5a5;
|
|
99
|
+
--color-red-400: #f87171;
|
|
100
|
+
--color-red-500: #ef4444;
|
|
101
|
+
--color-red-600: #dc2626;
|
|
102
|
+
--color-red-700: #b91c1c;
|
|
103
|
+
--color-red-800: #991b1b;
|
|
104
|
+
--color-red-900: #7f1d1d;
|
|
105
|
+
|
|
106
|
+
--color-teal-100: #ccfbf1;
|
|
107
|
+
--color-teal-200: #99f6e4;
|
|
108
|
+
--color-teal-300: #5eead4;
|
|
109
|
+
--color-teal-400: #2dd4bf;
|
|
110
|
+
--color-teal-500: #14b8a6;
|
|
111
|
+
--color-teal-600: #0d9488;
|
|
112
|
+
--color-teal-700: #0f766e;
|
|
113
|
+
--color-teal-800: #115e59;
|
|
114
|
+
--color-teal-900: #134e4a;
|
|
115
|
+
|
|
116
|
+
--color-white: #ffffff;
|
|
117
|
+
|
|
118
|
+
--color-yellow-100: #fef9c3;
|
|
119
|
+
--color-yellow-200: #fef08a;
|
|
120
|
+
--color-yellow-300: #fde047;
|
|
121
|
+
--color-yellow-400: #facc15;
|
|
122
|
+
--color-yellow-500: #eab308;
|
|
123
|
+
--color-yellow-600: #ca8a04;
|
|
124
|
+
--color-yellow-700: #a16207;
|
|
125
|
+
--color-yellow-800: #854d0e;
|
|
126
|
+
--color-yellow-900: #713f12;
|
|
127
|
+
}
|
|
128
|
+
}
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
/* primitive/font.css */
|
|
2
|
+
@layer config {
|
|
3
|
+
:root {
|
|
4
|
+
/* Families */
|
|
5
|
+
--font-family-mono: ui-monospace, monospace;
|
|
6
|
+
--font-family-sans: system-ui, sans-serif;
|
|
7
|
+
--font-family-serif: Georgia, serif;
|
|
8
|
+
|
|
9
|
+
/* Weights */
|
|
10
|
+
--font-weight-thin: 100;
|
|
11
|
+
--font-weight-light: 300;
|
|
12
|
+
--font-weight-normal: 400;
|
|
13
|
+
--font-weight-medium: 500;
|
|
14
|
+
--font-weight-semibold: 600;
|
|
15
|
+
--font-weight-bold: 700;
|
|
16
|
+
--font-weight-black: 900;
|
|
17
|
+
|
|
18
|
+
/* Line heights */
|
|
19
|
+
--line-height-tight: 1.1;
|
|
20
|
+
--line-height-snug: 1.25;
|
|
21
|
+
--line-height-normal: 1.5;
|
|
22
|
+
--line-height-relaxed: 1.75;
|
|
23
|
+
|
|
24
|
+
/* Text decoration */
|
|
25
|
+
--text-decoration-none: none;
|
|
26
|
+
--text-decoration-underline: underline;
|
|
27
|
+
--text-decoration-offset: 0.25rem;
|
|
28
|
+
--text-decoration-thickness: 1px;
|
|
29
|
+
}
|
|
30
|
+
}
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
/* primitive/shadow.css */
|
|
2
|
+
@layer config {
|
|
3
|
+
:root {
|
|
4
|
+
--shadow-none: none;
|
|
5
|
+
|
|
6
|
+
/* Directional (top-left light source) */
|
|
7
|
+
--shadow-sm: 0 1px 2px 0 rgb(0 0 0 / 0.05);
|
|
8
|
+
--shadow-md: 0 4px 6px -1px rgb(0 0 0 / 0.1), 0 2px 4px -2px rgb(0 0 0 / 0.1);
|
|
9
|
+
--shadow-lg: 0 10px 15px -3px rgb(0 0 0 / 0.1), 0 4px 6px -4px rgb(0 0 0 / 0.1);
|
|
10
|
+
|
|
11
|
+
/* Centered (ambient glow) */
|
|
12
|
+
--shadow-center-sm: 0 0 2px 2px rgb(0 0 0 / 0.05);
|
|
13
|
+
--shadow-center-md: 0 0 5px 5px rgb(0 0 0 / 0.05);
|
|
14
|
+
--shadow-center-lg: 0 0 10px 10px rgb(0 0 0 / 0.05);
|
|
15
|
+
}
|
|
16
|
+
}
|
|
@@ -0,0 +1,57 @@
|
|
|
1
|
+
/* primitive/size.css */
|
|
2
|
+
/*
|
|
3
|
+
* Pixel-named rem scale.
|
|
4
|
+
* Name = equivalent px value at 16px base, value = rem equivalent.
|
|
5
|
+
* e.g. --size-16 = 1rem = 16px
|
|
6
|
+
*/
|
|
7
|
+
@layer config {
|
|
8
|
+
:root {
|
|
9
|
+
--size-1: 0.0625rem;
|
|
10
|
+
--size-2: 0.125rem;
|
|
11
|
+
--size-3: 0.1875rem;
|
|
12
|
+
--size-4: 0.25rem;
|
|
13
|
+
--size-5: 0.3125rem;
|
|
14
|
+
--size-6: 0.375rem;
|
|
15
|
+
--size-7: 0.4375rem;
|
|
16
|
+
--size-8: 0.5rem;
|
|
17
|
+
--size-9: 0.5625rem;
|
|
18
|
+
--size-10: 0.625rem;
|
|
19
|
+
--size-11: 0.6875rem;
|
|
20
|
+
--size-12: 0.75rem;
|
|
21
|
+
--size-13: 0.8125rem;
|
|
22
|
+
--size-14: 0.875rem;
|
|
23
|
+
--size-15: 0.9375rem;
|
|
24
|
+
--size-16: 1rem;
|
|
25
|
+
--size-17: 1.0625rem;
|
|
26
|
+
--size-18: 1.125rem;
|
|
27
|
+
--size-19: 1.1875rem;
|
|
28
|
+
--size-20: 1.25rem;
|
|
29
|
+
--size-22: 1.375rem;
|
|
30
|
+
--size-24: 1.5rem;
|
|
31
|
+
--size-25: 1.5625rem;
|
|
32
|
+
--size-26: 1.625rem;
|
|
33
|
+
--size-28: 1.75rem;
|
|
34
|
+
--size-30: 1.875rem;
|
|
35
|
+
--size-32: 2rem;
|
|
36
|
+
--size-40: 2.5rem;
|
|
37
|
+
--size-48: 3rem;
|
|
38
|
+
--size-50: 3.125rem;
|
|
39
|
+
--size-52: 3.25rem;
|
|
40
|
+
--size-56: 3.5rem;
|
|
41
|
+
--size-60: 3.75rem;
|
|
42
|
+
--size-64: 4rem;
|
|
43
|
+
--size-68: 4.25rem;
|
|
44
|
+
--size-72: 4.5rem;
|
|
45
|
+
--size-80: 5rem;
|
|
46
|
+
--size-88: 5.5rem;
|
|
47
|
+
--size-96: 6rem;
|
|
48
|
+
--size-100: 6.25rem;
|
|
49
|
+
--size-150: 9.375rem;
|
|
50
|
+
|
|
51
|
+
/* Screen widths */
|
|
52
|
+
--size-768: 48rem;
|
|
53
|
+
--size-1024: 64rem;
|
|
54
|
+
--size-1440: 90rem;
|
|
55
|
+
--size-1920: 120rem;
|
|
56
|
+
}
|
|
57
|
+
}
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
/* semantic/border.css */
|
|
2
|
+
@layer config {
|
|
3
|
+
:root {
|
|
4
|
+
/* Styles */
|
|
5
|
+
--border-style-dotted: dotted;
|
|
6
|
+
--border-style-dashed: dashed;
|
|
7
|
+
--border-style-solid: solid;
|
|
8
|
+
|
|
9
|
+
/* Widths */
|
|
10
|
+
--border-width-none: 0px;
|
|
11
|
+
--border-width-normal: 1px;
|
|
12
|
+
--border-width-large: 2px;
|
|
13
|
+
--border-width-xl: 4px;
|
|
14
|
+
}
|
|
15
|
+
}
|
|
@@ -0,0 +1,88 @@
|
|
|
1
|
+
/* semantic/color.css */
|
|
2
|
+
/*
|
|
3
|
+
* Purposeful color aliases — reference primitives, never raw values.
|
|
4
|
+
* Override --color-brand (and optionally --color-*) in your project to rebrand.
|
|
5
|
+
*
|
|
6
|
+
* Default brand: claret (deep red).
|
|
7
|
+
*/
|
|
8
|
+
@layer config {
|
|
9
|
+
:root {
|
|
10
|
+
/* ── Brand ─────────────────────────────────────────────────────────── */
|
|
11
|
+
--color-brand: var(--color-indigo-600);
|
|
12
|
+
--color-brand-muted: var(--color-indigo-100);
|
|
13
|
+
--color-brand-hover: var(--color-indigo-700);
|
|
14
|
+
--color-brand-strong: var(--color-indigo-900);
|
|
15
|
+
|
|
16
|
+
/* ── Backgrounds ───────────────────────────────────────────────────── */
|
|
17
|
+
--color-bg: var(--color-white);
|
|
18
|
+
--color-bg-accent: var(--color-brand);
|
|
19
|
+
--color-bg-media: var(--color-gray-200);
|
|
20
|
+
--color-bg-muted: var(--color-gray-100);
|
|
21
|
+
|
|
22
|
+
/* ── Borders & focus ───────────────────────────────────────────────── */
|
|
23
|
+
--color-border: var(--color-gray-200);
|
|
24
|
+
--color-focus: var(--color-brand);
|
|
25
|
+
|
|
26
|
+
/* ── Text ──────────────────────────────────────────────────────────── */
|
|
27
|
+
--color-active: var(--color-brand);
|
|
28
|
+
--color-credit: var(--color-text-muted);
|
|
29
|
+
--color-heading: var(--color-black);
|
|
30
|
+
--color-link: var(--color-black);
|
|
31
|
+
--color-text: var(--color-gray-900);
|
|
32
|
+
--color-text-muted: var(--color-gray-500);
|
|
33
|
+
--color-text-disabled: var(--color-gray-300);
|
|
34
|
+
--color-text-on-accent: var(--color-white);
|
|
35
|
+
--color-text-on-brand: var(--color-white);
|
|
36
|
+
--color-text-on-danger: var(--color-white);
|
|
37
|
+
--color-text-on-dark: var(--color-white);
|
|
38
|
+
--color-text-on-info: var(--color-white);
|
|
39
|
+
--color-text-on-light: var(--color-gray-900);
|
|
40
|
+
--color-text-on-primary: var(--color-white);
|
|
41
|
+
--color-text-on-secondary: var(--color-white);
|
|
42
|
+
--color-text-on-success: var(--color-white);
|
|
43
|
+
--color-text-on-warning: var(--color-gray-900);
|
|
44
|
+
|
|
45
|
+
/* ── Semantic variants ─────────────────────────────────────────────── */
|
|
46
|
+
|
|
47
|
+
/* Primary (alias of brand) */
|
|
48
|
+
--color-primary: var(--color-brand);
|
|
49
|
+
--color-primary-muted: var(--color-brand-muted);
|
|
50
|
+
--color-primary-hover: var(--color-brand-hover);
|
|
51
|
+
--color-primary-strong: var(--color-brand-strong);
|
|
52
|
+
|
|
53
|
+
/* Secondary */
|
|
54
|
+
--color-secondary: var(--color-gray-500);
|
|
55
|
+
--color-secondary-muted: var(--color-gray-100);
|
|
56
|
+
--color-secondary-strong: var(--color-gray-800);
|
|
57
|
+
|
|
58
|
+
/* Danger */
|
|
59
|
+
--color-danger: var(--color-red-500);
|
|
60
|
+
--color-danger-muted: var(--color-red-100);
|
|
61
|
+
--color-danger-strong: var(--color-red-900);
|
|
62
|
+
|
|
63
|
+
/* Dark */
|
|
64
|
+
--color-dark: var(--color-gray-900);
|
|
65
|
+
--color-dark-muted: var(--color-gray-100);
|
|
66
|
+
--color-dark-strong: var(--color-black);
|
|
67
|
+
|
|
68
|
+
/* Info */
|
|
69
|
+
--color-info: var(--color-blue-500);
|
|
70
|
+
--color-info-muted: var(--color-blue-100);
|
|
71
|
+
--color-info-strong: var(--color-blue-900);
|
|
72
|
+
|
|
73
|
+
/* Light */
|
|
74
|
+
--color-light: var(--color-gray-200);
|
|
75
|
+
--color-light-muted: var(--color-gray-100);
|
|
76
|
+
--color-light-strong: var(--color-gray-700);
|
|
77
|
+
|
|
78
|
+
/* Success */
|
|
79
|
+
--color-success: var(--color-green-500);
|
|
80
|
+
--color-success-muted: var(--color-green-100);
|
|
81
|
+
--color-success-strong: var(--color-green-900);
|
|
82
|
+
|
|
83
|
+
/* Warning */
|
|
84
|
+
--color-warning: var(--color-yellow-500);
|
|
85
|
+
--color-warning-muted: var(--color-yellow-100);
|
|
86
|
+
--color-warning-strong: var(--color-yellow-900);
|
|
87
|
+
}
|
|
88
|
+
}
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
/* semantic/fluid.css */
|
|
2
|
+
/*
|
|
3
|
+
* Responsive fluid scales using clamp().
|
|
4
|
+
* Viewport range: 360px → 1440px (1080px range).
|
|
5
|
+
* preferred = intercept + slope×vw (exact linear interpolation, no approximation)
|
|
6
|
+
* $type: dimension
|
|
7
|
+
*
|
|
8
|
+
* https://utopia.fyi/clamp/calculator/
|
|
9
|
+
*/
|
|
10
|
+
@layer config {
|
|
11
|
+
:root {
|
|
12
|
+
|
|
13
|
+
/* ── Fluid text scale ───────────────────────────────────────────────── */
|
|
14
|
+
--fluid-text-2xs: clamp(0.5625rem, 0.5rem + 0.2778vw, 0.75rem); /* 9 → 12px */
|
|
15
|
+
--fluid-text-xs: clamp(0.75rem, 0.625rem + 0.5556vw, 1.125rem); /* 12 → 18px */
|
|
16
|
+
--fluid-text-sm: clamp(1.125rem, 1rem + 0.5556vw, 1.5rem); /* 18 → 24px */
|
|
17
|
+
--fluid-text-md: clamp(1.5rem, 1.25rem + 1.1111vw, 2.25rem); /* 24 → 36px */
|
|
18
|
+
--fluid-text-lg: clamp(2.25rem, 2rem + 1.1111vw, 3rem); /* 36 → 48px */
|
|
19
|
+
--fluid-text-xl: clamp(3rem, 2.5rem + 2.2222vw, 4.5rem); /* 48 → 72px */
|
|
20
|
+
--fluid-text-2xl: clamp(4.5rem, 4rem + 2.2222vw, 6rem); /* 72 → 96px */
|
|
21
|
+
|
|
22
|
+
/* ── Fluid spacing scale ────────────────────────────────────────────── */
|
|
23
|
+
--fluid-spacing-xs: clamp(0.625rem, 0.4167rem + 0.9259vw, 1.25rem); /* 10 → 20px */
|
|
24
|
+
--fluid-spacing-sm: clamp(1.25rem, 0.8333rem + 1.8519vw, 2.5rem); /* 20 → 40px */
|
|
25
|
+
--fluid-spacing-md: clamp(1.875rem, 1.25rem + 2.7778vw, 3.75rem); /* 30 → 60px */
|
|
26
|
+
--fluid-spacing-lg: clamp(2.5rem, 1.6667rem + 3.7037vw, 5rem); /* 40 → 80px */
|
|
27
|
+
--fluid-spacing-xl: clamp(3.125rem, 2.0833rem + 4.6296vw, 6.25rem); /* 50 → 100px */
|
|
28
|
+
|
|
29
|
+
}
|
|
30
|
+
}
|
|
@@ -0,0 +1,93 @@
|
|
|
1
|
+
/* semantic/form.css */
|
|
2
|
+
@layer config {
|
|
3
|
+
:root {
|
|
4
|
+
/* ── Base form ─────────────────────────────────────────────────────── */
|
|
5
|
+
--form-color-accent: var(--color-black);
|
|
6
|
+
--form-color-background: var(--color-white);
|
|
7
|
+
--form-color-border: var(--color-border);
|
|
8
|
+
--form-color-text: var(--color-text);
|
|
9
|
+
--form-border-radius: var(--radius-xs);
|
|
10
|
+
--form-border-width: var(--border-width-normal);
|
|
11
|
+
|
|
12
|
+
/* ── Input ─────────────────────────────────────────────────────────── */
|
|
13
|
+
--input-color-background: var(--form-color-background);
|
|
14
|
+
--input-color-border: var(--form-color-border);
|
|
15
|
+
--input-color-border-hover: var(--form-color-accent);
|
|
16
|
+
--input-color-placeholder: var(--color-text-muted);
|
|
17
|
+
--input-color-text: var(--form-color-text);
|
|
18
|
+
--input-border-radius: var(--form-border-radius);
|
|
19
|
+
--input-border-width: var(--form-border-width);
|
|
20
|
+
--input-padding: var(--spacing-control);
|
|
21
|
+
|
|
22
|
+
/* ── Textarea ──────────────────────────────────────────────────────── */
|
|
23
|
+
--textarea-color-background: var(--form-color-background);
|
|
24
|
+
--textarea-color-border: var(--form-color-border);
|
|
25
|
+
--textarea-color-border-hover: var(--textarea-color-border);
|
|
26
|
+
--textarea-color-placeholder: var(--color-text-muted);
|
|
27
|
+
--textarea-color-text: var(--form-color-text);
|
|
28
|
+
--textarea-border-radius: var(--form-border-radius);
|
|
29
|
+
--textarea-border-width: var(--form-border-width);
|
|
30
|
+
|
|
31
|
+
/* ── Select ────────────────────────────────────────────────────────── */
|
|
32
|
+
--select-color-background: var(--form-color-background);
|
|
33
|
+
--select-color-border: var(--form-color-border);
|
|
34
|
+
--select-color-border-hover: var(--select-color-border);
|
|
35
|
+
--select-color-optgroup: var(--color-text-muted);
|
|
36
|
+
--select-color-text: var(--form-color-text);
|
|
37
|
+
--select-border-radius: var(--form-border-radius);
|
|
38
|
+
--select-border-width: var(--form-border-width);
|
|
39
|
+
|
|
40
|
+
/* ── Label ─────────────────────────────────────────────────────────── */
|
|
41
|
+
--label-color-text: var(--form-color-text);
|
|
42
|
+
--label-font-size: var(--font-size-xs);
|
|
43
|
+
--label-font-weight: var(--font-weight-medium);
|
|
44
|
+
--label-padding: var(--spacing-2xs) 0;
|
|
45
|
+
--label-text-transform: uppercase;
|
|
46
|
+
|
|
47
|
+
/* ── Help text ─────────────────────────────────────────────────────── */
|
|
48
|
+
--help-color-text: var(--color-text-muted);
|
|
49
|
+
--help-font-size: var(--font-size-xs);
|
|
50
|
+
--help-font-weight: var(--font-weight-normal);
|
|
51
|
+
--help-margin: 0;
|
|
52
|
+
|
|
53
|
+
/* ── Checkables (checkbox + radio shared) ──────────────────────────── */
|
|
54
|
+
--checkable-color-border: var(--form-color-border);
|
|
55
|
+
--checkable-color-border-checked: transparent;
|
|
56
|
+
|
|
57
|
+
/* ── Checkbox ──────────────────────────────────────────────────────── */
|
|
58
|
+
--checkbox-color-background: var(--form-color-background);
|
|
59
|
+
--checkbox-color-background-checked: transparent;
|
|
60
|
+
--checkbox-color-border: var(--checkable-color-border);
|
|
61
|
+
--checkbox-color-border-hover: var(--checkbox-color-border);
|
|
62
|
+
--checkbox-color-checked: var(--form-color-accent);
|
|
63
|
+
--checkbox-border-radius: 0;
|
|
64
|
+
--checkbox-border-width: var(--form-border-width);
|
|
65
|
+
|
|
66
|
+
/* ── Radio ─────────────────────────────────────────────────────────── */
|
|
67
|
+
--radio-color-background: var(--form-color-background);
|
|
68
|
+
--radio-color-border: var(--checkable-color-border);
|
|
69
|
+
--radio-color-border-checked: var(--checkable-color-border-checked);
|
|
70
|
+
--radio-color-border-hover: var(--radio-color-border);
|
|
71
|
+
--radio-color-checked: var(--form-color-accent);
|
|
72
|
+
--radio-border-radius: var(--radius-pill);
|
|
73
|
+
--radio-border-width: var(--form-border-width);
|
|
74
|
+
|
|
75
|
+
/* ── Switch ────────────────────────────────────────────────────────── */
|
|
76
|
+
--switch-color-border: var(--checkable-color-border);
|
|
77
|
+
--switch-color-thumb: var(--color-white);
|
|
78
|
+
--switch-color-track: var(--form-color-background);
|
|
79
|
+
--switch-color-track-checked: var(--form-color-accent);
|
|
80
|
+
--switch-border-radius: var(--radius-pill);
|
|
81
|
+
--switch-border-width: var(--border-width-normal);
|
|
82
|
+
--switch-height: var(--size-24);
|
|
83
|
+
--switch-width: var(--size-40);
|
|
84
|
+
|
|
85
|
+
/* ── Range ─────────────────────────────────────────────────────────── */
|
|
86
|
+
--range-color-accent: var(--form-color-accent);
|
|
87
|
+
--range-color-track: var(--form-color-border);
|
|
88
|
+
--range-thumb-color-border: var(--color-white);
|
|
89
|
+
--range-thumb-border-width: var(--size-4);
|
|
90
|
+
--range-thumb-size: var(--size-24);
|
|
91
|
+
--range-track-height: calc(var(--border-width-normal) + 2px);
|
|
92
|
+
}
|
|
93
|
+
}
|
|
@@ -0,0 +1,53 @@
|
|
|
1
|
+
/* semantic/grid.css */
|
|
2
|
+
@layer config {
|
|
3
|
+
:root {
|
|
4
|
+
/* ── Grid base ──────────────────────────────────────────────────────── */
|
|
5
|
+
--columns: 12;
|
|
6
|
+
--gap: var(--spacing-md);
|
|
7
|
+
|
|
8
|
+
/* ── Flex fractions ─────────────────────────────────────────────────── */
|
|
9
|
+
--flex-full: 100%;
|
|
10
|
+
--flex-eleven-twelfths: 91.6666666667%;
|
|
11
|
+
--flex-five-sixths: 83.3333333333%;
|
|
12
|
+
--flex-four-fifths: 80%;
|
|
13
|
+
--flex-three-quarters: 75%;
|
|
14
|
+
--flex-two-thirds: 66.6666666667%;
|
|
15
|
+
--flex-half: 50%;
|
|
16
|
+
--flex-third: 33.3333333333%;
|
|
17
|
+
--flex-quarter: 25%;
|
|
18
|
+
--flex-fifth: 20%;
|
|
19
|
+
--flex-sixth: 16.6666666667%;
|
|
20
|
+
--flex-twelfth: 8.3333333333%;
|
|
21
|
+
|
|
22
|
+
/* ── Grid column spans ──────────────────────────────────────────────── */
|
|
23
|
+
/* Integer spans — grid-agnostic. Comments show col-12 / col-24 fractions. */
|
|
24
|
+
--span-full: span var(--columns);
|
|
25
|
+
--span-half: span calc(var(--columns) / 2);
|
|
26
|
+
--span-quarter: span calc(var(--columns) / 4);
|
|
27
|
+
--span-third: span calc(var(--columns) / 3);
|
|
28
|
+
--span-24: span 24;
|
|
29
|
+
--span-23: span 23;
|
|
30
|
+
--span-22: span 22;
|
|
31
|
+
--span-21: span 21;
|
|
32
|
+
--span-20: span 20;
|
|
33
|
+
--span-19: span 19;
|
|
34
|
+
--span-18: span 18;
|
|
35
|
+
--span-17: span 17;
|
|
36
|
+
--span-16: span 16;
|
|
37
|
+
--span-15: span 15;
|
|
38
|
+
--span-14: span 14;
|
|
39
|
+
--span-13: span 13;
|
|
40
|
+
--span-12: span 12;
|
|
41
|
+
--span-11: span 11;
|
|
42
|
+
--span-10: span 10;
|
|
43
|
+
--span-9: span 9;
|
|
44
|
+
--span-8: span 8;
|
|
45
|
+
--span-7: span 7;
|
|
46
|
+
--span-6: span 6;
|
|
47
|
+
--span-5: span 5;
|
|
48
|
+
--span-4: span 4;
|
|
49
|
+
--span-3: span 3;
|
|
50
|
+
--span-2: span 2;
|
|
51
|
+
--span-1: span 1;
|
|
52
|
+
}
|
|
53
|
+
}
|
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
/* semantic/motion.css */
|
|
2
|
+
@layer config {
|
|
3
|
+
:root {
|
|
4
|
+
/* ── Duration ───────────────────────────────────────────────────────── */
|
|
5
|
+
--duration-fast: 150ms;
|
|
6
|
+
--duration-normal: 300ms;
|
|
7
|
+
--duration-slow: 600ms;
|
|
8
|
+
|
|
9
|
+
/* ── Easing — standard ──────────────────────────────────────────────── */
|
|
10
|
+
--easing-linear: linear;
|
|
11
|
+
--easing-default: ease-in-out;
|
|
12
|
+
--easing-in: ease-in;
|
|
13
|
+
--easing-out: ease-out;
|
|
14
|
+
|
|
15
|
+
/* ── Easing — expressive ─────────────────────────────────────────────── */
|
|
16
|
+
/* Fast deceleration, natural feel — good for elements entering the screen */
|
|
17
|
+
--easing-out-circ: cubic-bezier(0, 0.55, 0.45, 1);
|
|
18
|
+
/* Dramatic deceleration — good for modals, drawers */
|
|
19
|
+
--easing-out-expo: cubic-bezier(0.16, 1, 0.3, 1);
|
|
20
|
+
/* Slight overshoot then settle — good for confirmations, badges */
|
|
21
|
+
--easing-out-back: cubic-bezier(0.34, 1.56, 0.64, 1);
|
|
22
|
+
/* Bounce — ease-out-quart curve */
|
|
23
|
+
--easing-bounce: cubic-bezier(0.165, 0.84, 0.44, 1);
|
|
24
|
+
|
|
25
|
+
/* ── Easing — physics (requires modern browser linear() support) ─────── */
|
|
26
|
+
/* Spring — overshoots slightly, settles naturally */
|
|
27
|
+
--easing-spring: linear(
|
|
28
|
+
0, 0.006, 0.025 2.8%, 0.101, 0.197, 0.325, 0.474, 0.638, 0.806,
|
|
29
|
+
0.962, 1.065, 1.12, 1.14, 1.12 30.9%, 1.034, 0.997, 0.986, 0.998, 1
|
|
30
|
+
);
|
|
31
|
+
|
|
32
|
+
/* ── Transition shorthands ──────────────────────────────────────────── */
|
|
33
|
+
--transition-fast: all var(--duration-fast) var(--easing-default);
|
|
34
|
+
--transition-normal: all var(--duration-normal) var(--easing-default);
|
|
35
|
+
--transition-slow: all var(--duration-slow) var(--easing-default);
|
|
36
|
+
/* Targeted transitions — prefer over `all` for performance */
|
|
37
|
+
--transition-opacity: opacity var(--duration-normal) var(--easing-default);
|
|
38
|
+
--transition-transform: transform var(--duration-normal) var(--easing-default);
|
|
39
|
+
/* Targeted color transitions */
|
|
40
|
+
--transition-property-color: color, background-color, border-color, outline-color, fill, stroke;
|
|
41
|
+
--transition-color: var(--transition-property-color) var(--duration-normal) var(--easing-default);
|
|
42
|
+
}
|
|
43
|
+
}
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
/* semantic/radius.css */
|
|
2
|
+
@layer config {
|
|
3
|
+
:root {
|
|
4
|
+
/* ── T-shirt scale ──────────────────────────────────────────────────── */
|
|
5
|
+
--radius-2xs: var(--size-2);
|
|
6
|
+
--radius-xs: var(--size-4);
|
|
7
|
+
--radius-sm: var(--size-8);
|
|
8
|
+
--radius-md: var(--size-12);
|
|
9
|
+
--radius-lg: var(--size-16);
|
|
10
|
+
--radius-xl: var(--size-24);
|
|
11
|
+
--radius-2xl: var(--size-32);
|
|
12
|
+
|
|
13
|
+
/* ── Purposeful aliases ─────────────────────────────────────────────── */
|
|
14
|
+
--radius-none: 0; /* no rounding — sharp edges */
|
|
15
|
+
--radius-control: var(--radius-sm); /* button, input, select */
|
|
16
|
+
--radius-surface: var(--radius-md); /* card, modal, panel */
|
|
17
|
+
--radius-pill: 9999px; /* badge, tag, avatar */
|
|
18
|
+
}
|
|
19
|
+
}
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
/* semantic/size.css */
|
|
2
|
+
@layer config {
|
|
3
|
+
:root {
|
|
4
|
+
/* ── Breakpoints ────────────────────────────────────────────────────── */
|
|
5
|
+
--size-tablet: var(--size-768); /* 48rem — 768px */
|
|
6
|
+
--size-tablet-wide: var(--size-1024); /* 64rem — 1024px */
|
|
7
|
+
--size-laptop: var(--size-1440); /* 90rem — 1440px */
|
|
8
|
+
--size-desktop: var(--size-1920); /* 120rem — 1920px */
|
|
9
|
+
|
|
10
|
+
/* ── T-shirt scale ──────────────────────────────────────────────────── */
|
|
11
|
+
--size-2xs: var(--size-5);
|
|
12
|
+
--size-xs: var(--size-10);
|
|
13
|
+
--size-sm: var(--size-20);
|
|
14
|
+
--size-md: var(--size-40);
|
|
15
|
+
--size-lg: var(--size-60);
|
|
16
|
+
--size-xl: var(--size-80);
|
|
17
|
+
--size-2xl: var(--size-100);
|
|
18
|
+
}
|
|
19
|
+
}
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
/* semantic/spacing.css */
|
|
2
|
+
@layer config {
|
|
3
|
+
:root {
|
|
4
|
+
/* ── T-shirt scale ──────────────────────────────────────────────────── */
|
|
5
|
+
--spacing-2xs: var(--size-5);
|
|
6
|
+
--spacing-xs: var(--size-10);
|
|
7
|
+
--spacing-sm: var(--size-20);
|
|
8
|
+
--spacing-md: var(--size-30);
|
|
9
|
+
--spacing-lg: var(--size-40);
|
|
10
|
+
--spacing-xl: var(--size-60);
|
|
11
|
+
--spacing-2xl: var(--size-100);
|
|
12
|
+
--spacing-3xl: var(--size-150);
|
|
13
|
+
|
|
14
|
+
/* ── Purposeful aliases ─────────────────────────────────────────────── */
|
|
15
|
+
--spacing-control: var(--spacing-xs); /* padding inside interactive controls */
|
|
16
|
+
--spacing-heading: var(--spacing-sm); /* gap below headings */
|
|
17
|
+
--spacing-section: var(--spacing-2xl); /* vertical rhythm between sections */
|
|
18
|
+
--spacing-surface: var(--spacing-sm); /* padding inside surfaces (card, panel) */
|
|
19
|
+
--spacing-typography: var(--spacing-xs); /* gap between typographic elements */
|
|
20
|
+
}
|
|
21
|
+
}
|
|
@@ -0,0 +1,66 @@
|
|
|
1
|
+
/* semantic/typography.css */
|
|
2
|
+
@layer config {
|
|
3
|
+
:root {
|
|
4
|
+
/* ── Font families ──────────────────────────────────────────────────── */
|
|
5
|
+
--font-family-code: var(--font-family-mono);
|
|
6
|
+
--font-family-heading: var(--font-family-sans);
|
|
7
|
+
--font-family-text: var(--font-family-sans);
|
|
8
|
+
|
|
9
|
+
/* ── Font weights ───────────────────────────────────────────────────── */
|
|
10
|
+
--font-weight-control: var(--font-weight-medium);
|
|
11
|
+
--font-weight-heading: var(--font-weight-bold);
|
|
12
|
+
--font-weight-text: var(--font-weight-normal);
|
|
13
|
+
|
|
14
|
+
/* ── Letter spacing ─────────────────────────────────────────────────── */
|
|
15
|
+
--letter-spacing-normal: 0;
|
|
16
|
+
--letter-spacing-medium: 0.025em;
|
|
17
|
+
--letter-spacing-large: 0.05em;
|
|
18
|
+
|
|
19
|
+
/* ── Line heights ───────────────────────────────────────────────────── */
|
|
20
|
+
--line-height-heading: var(--line-height-tight);
|
|
21
|
+
--line-height-text: var(--line-height-normal);
|
|
22
|
+
|
|
23
|
+
/* ── Font size scale (T-shirt) ──────────────────────────────────────── */
|
|
24
|
+
--font-size-2xs: var(--size-12);
|
|
25
|
+
--font-size-xs: var(--size-14);
|
|
26
|
+
--font-size-sm: var(--size-16);
|
|
27
|
+
--font-size-md: var(--size-18);
|
|
28
|
+
--font-size-lg: var(--size-24);
|
|
29
|
+
--font-size-xl: var(--size-40);
|
|
30
|
+
--font-size-2xl: var(--size-64);
|
|
31
|
+
--font-size-display: var(--size-96); /* hero / marketing */
|
|
32
|
+
|
|
33
|
+
/* ── Body ───────────────────────────────────────────────────────────── */
|
|
34
|
+
--font-size-text: var(--font-size-sm);
|
|
35
|
+
|
|
36
|
+
/* ── Headings ───────────────────────────────────────────────────────── */
|
|
37
|
+
--font-size-heading-01: var(--font-size-xl);
|
|
38
|
+
--font-size-heading-02: var(--font-size-lg);
|
|
39
|
+
--font-size-heading-03: var(--font-size-md);
|
|
40
|
+
--font-size-heading-04: var(--font-size-sm);
|
|
41
|
+
--font-size-heading-05: var(--font-size-sm);
|
|
42
|
+
--font-size-heading-06: var(--font-size-sm);
|
|
43
|
+
|
|
44
|
+
/* ── Fluid font sizes ───────────────────────────────────────────────── */
|
|
45
|
+
/*
|
|
46
|
+
* clamp(min, preferred, max) — scales between ~320px and ~1440px viewport.
|
|
47
|
+
* Use these instead of fixed sizes for responsive typography without breakpoints.
|
|
48
|
+
* $type: dimension
|
|
49
|
+
*/
|
|
50
|
+
--font-size-fluid-xs: clamp(0.875rem, 1.5vw, 1rem); /* 14 → 16px */
|
|
51
|
+
--font-size-fluid-sm: clamp(1rem, 2vw, 1.125rem); /* 16 → 18px */
|
|
52
|
+
--font-size-fluid-md: clamp(1.125rem, 2.5vw, 1.5rem); /* 18 → 24px */
|
|
53
|
+
--font-size-fluid-lg: clamp(1.5rem, 4vw, 2.5rem); /* 24 → 40px */
|
|
54
|
+
--font-size-fluid-xl: clamp(2.5rem, 6vw, 4rem); /* 40 → 64px */
|
|
55
|
+
--font-size-fluid-display: clamp(4rem, 8vw, 6rem); /* 64 → 96px */
|
|
56
|
+
|
|
57
|
+
/* ── Readability ────────────────────────────────────────────────────── */
|
|
58
|
+
/*
|
|
59
|
+
* Max line length in ch units (width of "0" character).
|
|
60
|
+
* Prevents overly long lines causing reading fatigue (WCAG 1.4.8).
|
|
61
|
+
* Headings use a shorter value: larger font = physically wider chars.
|
|
62
|
+
*/
|
|
63
|
+
--max-width-heading: 40ch;
|
|
64
|
+
--max-width-paragraph: 70ch;
|
|
65
|
+
}
|
|
66
|
+
}
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
/* semantic/z-index.css */
|
|
2
|
+
@layer config {
|
|
3
|
+
:root {
|
|
4
|
+
--z-index-below: -1; /* background decorative elements */
|
|
5
|
+
--z-index-base: 0;
|
|
6
|
+
--z-index-raised: 10; /* cards, sticky elements within flow */
|
|
7
|
+
--z-index-dropdown: 100; /* dropdowns, popovers */
|
|
8
|
+
--z-index-sticky: 200; /* sticky header/sidebar */
|
|
9
|
+
--z-index-offcanvas: 300; /* drawer, side panel */
|
|
10
|
+
--z-index-modal: 400; /* modal dialogs */
|
|
11
|
+
--z-index-toast: 500; /* notifications, toasts */
|
|
12
|
+
--z-index-tooltip: 600; /* tooltips (always on top) */
|
|
13
|
+
}
|
|
14
|
+
}
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
/* @uncinq/design-tokens — semantic.css */
|
|
2
|
+
@layer config;
|
|
3
|
+
|
|
4
|
+
@import 'semantic/border.css';
|
|
5
|
+
@import 'semantic/color.css';
|
|
6
|
+
@import 'semantic/fluid.css';
|
|
7
|
+
@import 'semantic/focus.css';
|
|
8
|
+
@import 'semantic/form.css';
|
|
9
|
+
@import 'semantic/grid.css';
|
|
10
|
+
@import 'semantic/motion.css';
|
|
11
|
+
@import 'semantic/opacity.css';
|
|
12
|
+
@import 'semantic/radius.css';
|
|
13
|
+
@import 'semantic/ratio.css';
|
|
14
|
+
@import 'semantic/size.css';
|
|
15
|
+
@import 'semantic/spacing.css';
|
|
16
|
+
@import 'semantic/typography.css';
|
|
17
|
+
@import 'semantic/z-index.css';
|