@darthcharles/greda 0.2.0 → 1.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/dist/tokens.css CHANGED
@@ -1,28 +1,22 @@
1
- /* Colors are space-separated HSL channels. All other tokens use CSS values.
2
- Low-specificity defaults let consumer :root rules win in either import order. */
3
- :where(:root) {
4
- color-scheme: light;
5
- --background: 0 0% 100%;
6
- --foreground: 222 47% 11%;
7
- --card: 0 0% 100%;
8
- --card-foreground: 222 47% 11%;
9
- --popover: 0 0% 100%;
10
- --popover-foreground: 222 47% 11%;
11
- --accent: 220 20% 94%;
12
- --accent-foreground: 222 35% 20%;
13
- --primary: 220 80% 45%;
14
- --primary-foreground: 0 0% 100%;
15
- --primary-hover: 220 80% 38%;
16
- --secondary: 220 20% 94%;
17
- --secondary-foreground: 222 35% 20%;
18
- --muted: 220 15% 96%;
19
- --muted-foreground: 220 10% 42%;
20
- --border: 220 15% 82%;
21
- --input: 220 15% 82%;
22
- --ring: 220 80% 45%;
23
- --destructive: 0 72% 43%;
24
- --destructive-foreground: 0 0% 100%;
25
- --overlay: 222 47% 11% / 0.4;
1
+ /* Consumers customize only the generic --base-* colors. All color values are
2
+ space-separated HSL channels. Role assignments are owned by Greda. */
3
+ :where(:root, [data-color-scheme="light"]) {
4
+ --base-white: 0 0% 100%;
5
+ --base-black: 222 47% 11%;
6
+ --base-gray-50: 220 15% 96%;
7
+ --base-gray-100: 220 20% 94%;
8
+ --base-gray-200: 220 15% 82%;
9
+ --base-gray-300: 220 15% 72%;
10
+ --base-gray-500: 220 10% 42%;
11
+ --base-gray-600: 220 15% 36%;
12
+ --base-gray-800: 222 20% 18%;
13
+ --base-gray-900: 222 30% 9%;
14
+ --base-primary: 220 80% 45%;
15
+ --base-primary-hover: 220 80% 38%;
16
+ --base-secondary: 220 20% 94%;
17
+ --base-tertiary: 214 100% 96.863%;
18
+ --base-accent: 220 20% 94%;
19
+ --base-destructive: 0 72% 43%;
26
20
  --font-sans: system-ui, -apple-system, BlinkMacSystemFont, "Segoe UI",
27
21
  sans-serif;
28
22
  --font-heading: var(--font-sans);
@@ -61,9 +55,6 @@
61
55
  --dialog-width: 32.5rem;
62
56
  --tooltip-width: 20rem;
63
57
  --toast-width: 24rem;
64
- --shadow-sm: 0 1px 2px hsl(222 47% 11% / 0.08);
65
- --shadow: 0 8px 24px hsl(222 47% 11% / 0.12);
66
- --shadow-dialog: 0 24px 70px hsl(222 47% 11% / 0.24);
67
58
  --focus-width: 2px;
68
59
  --focus-offset: 2px;
69
60
  --disabled-opacity: 0.5;
@@ -72,33 +63,111 @@
72
63
  --z-popover: 60;
73
64
  --z-toast: 70;
74
65
  }
75
- :where([data-color-scheme="light"]) {
66
+
67
+ /* Complete typography roles. Rebind font and scale aliases at theme boundaries
68
+ so scoped font overrides resolve locally. Colors and casing stay independent. */
69
+ :where(:root, [data-theme], [data-color-scheme]) {
70
+ --type-display-family: var(--font-heading);
71
+ --type-display-size: clamp(2.25rem, 4.8vw, 3.5rem);
72
+ --type-display-weight: 500;
73
+ --type-display-leading: 1.1;
74
+ --type-display-tracking: -0.04em;
75
+ --type-title-family: var(--font-heading);
76
+ --type-title-size: clamp(1.75rem, 3vw, 2.25rem);
77
+ --type-title-weight: 500;
78
+ --type-title-leading: 1.2;
79
+ --type-title-tracking: normal;
80
+ --type-body-family: var(--font-sans);
81
+ --type-body-size: 1rem;
82
+ --type-body-weight: 400;
83
+ --type-body-leading: 1.5;
84
+ --type-body-tracking: normal;
85
+ --type-label-family: var(--font-sans);
86
+ --type-label-size: var(--font-size-sm);
87
+ --type-label-weight: var(--font-weight-medium);
88
+ --type-label-leading: var(--line-height);
89
+ --type-label-tracking: normal;
90
+ --type-caption-family: var(--font-sans);
91
+ --type-caption-size: var(--font-size-xs);
92
+ --type-caption-weight: 400;
93
+ --type-caption-leading: var(--line-height);
94
+ --type-caption-tracking: normal;
95
+ --type-eyebrow-family: var(--font-sans);
96
+ --type-eyebrow-size: var(--font-size-xs);
97
+ --type-eyebrow-weight: var(--font-weight-bold);
98
+ --type-eyebrow-leading: var(--line-height);
99
+ --type-eyebrow-tracking: 0.1em;
100
+ }
101
+
102
+ /* Rebind roles at theme boundaries so scoped base overrides update every role.
103
+ Low specificity lets consumers supply base colors in either import order. */
104
+ :where(:root, [data-theme], [data-color-scheme]) {
76
105
  color-scheme: light;
106
+ --surface-primary: var(--base-white);
107
+ --surface-secondary: var(--base-gray-100);
108
+ --surface-tertiary: var(--base-tertiary);
109
+ --surface-raised: var(--base-gray-50);
110
+ --surface-inverse: var(--base-black);
111
+ --text-primary: var(--base-black);
112
+ --text-secondary: var(--base-gray-600);
113
+ --text-muted: var(--base-gray-500);
114
+ --text-inverse: var(--base-white);
115
+ --text-action: var(--base-primary);
116
+ --border-primary: var(--base-gray-200);
117
+ --border-secondary: var(--base-gray-100);
118
+ --border-inverse: var(--base-gray-600);
119
+ --border-action: var(--base-primary);
120
+
121
+ /* Existing component tokens derive from the same generic base palette. */
122
+ --background: var(--surface-primary);
123
+ --foreground: var(--text-primary);
124
+ --card: var(--surface-raised);
125
+ --card-foreground: var(--text-primary);
126
+ --popover: var(--surface-raised);
127
+ --popover-foreground: var(--text-primary);
128
+ --accent: var(--base-accent);
129
+ --accent-foreground: var(--text-primary);
130
+ --primary: var(--base-primary);
131
+ --primary-foreground: var(--base-white);
132
+ --primary-hover: var(--base-primary-hover);
133
+ --secondary: var(--base-secondary);
134
+ --secondary-foreground: var(--text-primary);
135
+ --muted: var(--surface-secondary);
136
+ --muted-foreground: var(--text-muted);
137
+ --border: var(--border-primary);
138
+ --input: var(--border-primary);
139
+ --ring: var(--base-primary);
140
+ --destructive: var(--base-destructive);
141
+ --destructive-foreground: var(--base-white);
142
+ --overlay: var(--base-black) / 0.4;
143
+ --shadow-sm: 0 1px 2px hsl(var(--base-black) / 0.08);
144
+ --shadow: 0 8px 24px hsl(var(--base-black) / 0.12);
145
+ --shadow-dialog: 0 24px 70px hsl(var(--base-black) / 0.24);
77
146
  }
147
+
78
148
  /* Opt in independently of the consumer's brand theme. */
79
149
  :where([data-color-scheme="dark"]) {
80
150
  color-scheme: dark;
81
- --background: 222 30% 9%;
82
- --foreground: 220 20% 96%;
83
- --card: 222 25% 13%;
84
- --card-foreground: 220 20% 96%;
85
- --popover: 222 25% 13%;
86
- --popover-foreground: 220 20% 96%;
87
- --accent: 222 20% 22%;
88
- --accent-foreground: 220 20% 96%;
89
- --primary: 217 90% 70%;
90
- --primary-foreground: 222 47% 11%;
91
- --primary-hover: 217 90% 78%;
92
- --secondary: 222 20% 22%;
93
- --secondary-foreground: 220 20% 96%;
94
- --muted: 222 20% 18%;
95
- --muted-foreground: 220 15% 72%;
96
- --border: 220 15% 36%;
97
- --input: 220 15% 36%;
98
- --ring: 217 90% 70%;
99
- --destructive: 0 80% 72%;
100
- --destructive-foreground: 222 47% 11%;
101
- --overlay: 222 47% 3% / 0.7;
151
+ --base-primary: 217 90% 70%;
152
+ --base-primary-hover: 217 90% 78%;
153
+ --base-secondary: 222 20% 22%;
154
+ --base-tertiary: 218 40% 18%;
155
+ --base-accent: 222 20% 22%;
156
+ --base-destructive: 0 80% 72%;
157
+ --surface-primary: var(--base-gray-900);
158
+ --surface-secondary: var(--base-gray-800);
159
+ --surface-raised: var(--base-gray-800);
160
+ --surface-inverse: var(--base-white);
161
+ --text-primary: var(--base-white);
162
+ --text-secondary: var(--base-gray-300);
163
+ --text-muted: var(--base-gray-300);
164
+ --text-inverse: var(--base-black);
165
+ --border-primary: var(--base-gray-600);
166
+ --border-secondary: var(--base-gray-800);
167
+ --border-inverse: var(--base-gray-200);
168
+ --primary-foreground: var(--base-black);
169
+ --destructive-foreground: var(--base-black);
170
+ --overlay: var(--base-black) / 0.7;
102
171
  }
103
172
 
104
173
 
@@ -113,12 +182,18 @@
113
182
  --color-popover-foreground: hsl(var(--popover-foreground));
114
183
  --color-accent: hsl(var(--accent));
115
184
  --color-accent-foreground: hsl(var(--accent-foreground));
116
- --color-primary: hsl(var(--primary));
185
+ --greda-bg-primary: var(--primary);
186
+ --greda-text-primary: var(--text-primary);
187
+ --greda-border-primary: var(--border-primary);
117
188
  --color-primary-foreground: hsl(var(--primary-foreground));
118
189
  --color-primary-hover: hsl(var(--primary-hover));
119
- --color-secondary: hsl(var(--secondary));
190
+ --greda-bg-secondary: var(--secondary);
191
+ --greda-text-secondary: var(--text-secondary);
192
+ --greda-border-secondary: var(--border-secondary);
120
193
  --color-secondary-foreground: hsl(var(--secondary-foreground));
121
- --color-muted: hsl(var(--muted));
194
+ --greda-bg-muted: var(--muted);
195
+ --greda-text-muted: var(--text-muted);
196
+ --greda-border-muted: var(--muted);
122
197
  --color-muted-foreground: hsl(var(--muted-foreground));
123
198
  --color-border: hsl(var(--border));
124
199
  --color-input: hsl(var(--input));
@@ -126,6 +201,15 @@
126
201
  --color-destructive: hsl(var(--destructive));
127
202
  --color-destructive-foreground: hsl(var(--destructive-foreground));
128
203
  --color-overlay: hsl(var(--overlay));
204
+ --greda-surface-primary: var(--surface-primary);
205
+ --greda-surface-secondary: var(--surface-secondary);
206
+ --greda-surface-tertiary: var(--surface-tertiary);
207
+ --greda-surface-raised: var(--surface-raised);
208
+ --greda-surface-inverse: var(--surface-inverse);
209
+ --greda-text-inverse: var(--text-inverse);
210
+ --greda-text-action: var(--text-action);
211
+ --greda-border-inverse: var(--border-inverse);
212
+ --greda-border-action: var(--border-action);
129
213
  --spacing: var(--spacing-unit);
130
214
  --spacing-0: var(--space-0);
131
215
  --spacing-0\.5: var(--space-0-5);
@@ -178,6 +262,78 @@
178
262
 
179
263
  @custom-variant dark (&:where([data-color-scheme="dark"], [data-color-scheme="dark"] *));
180
264
 
265
+ @utility text-display {
266
+ font-family: var(--type-display-family);
267
+ font-size: var(--type-display-size);
268
+ font-weight: var(--type-display-weight);
269
+ line-height: var(--type-display-leading);
270
+ letter-spacing: var(--type-display-tracking);
271
+ }
272
+
273
+ @utility text-title {
274
+ font-family: var(--type-title-family);
275
+ font-size: var(--type-title-size);
276
+ font-weight: var(--type-title-weight);
277
+ line-height: var(--type-title-leading);
278
+ letter-spacing: var(--type-title-tracking);
279
+ }
280
+
281
+ @utility text-body {
282
+ font-family: var(--type-body-family);
283
+ font-size: var(--type-body-size);
284
+ font-weight: var(--type-body-weight);
285
+ line-height: var(--type-body-leading);
286
+ letter-spacing: var(--type-body-tracking);
287
+ }
288
+
289
+ @utility text-label {
290
+ font-family: var(--type-label-family);
291
+ font-size: var(--type-label-size);
292
+ font-weight: var(--type-label-weight);
293
+ line-height: var(--type-label-leading);
294
+ letter-spacing: var(--type-label-tracking);
295
+ }
296
+
297
+ @utility text-caption {
298
+ font-family: var(--type-caption-family);
299
+ font-size: var(--type-caption-size);
300
+ font-weight: var(--type-caption-weight);
301
+ line-height: var(--type-caption-leading);
302
+ letter-spacing: var(--type-caption-tracking);
303
+ }
304
+
305
+ @utility text-eyebrow {
306
+ font-family: var(--type-eyebrow-family);
307
+ font-size: var(--type-eyebrow-size);
308
+ font-weight: var(--type-eyebrow-weight);
309
+ line-height: var(--type-eyebrow-leading);
310
+ letter-spacing: var(--type-eyebrow-tracking);
311
+ }
312
+
313
+ @utility bg-* {
314
+ background-color: hsl(--value(--greda-bg-*));
315
+ background-color: hsl(--value(--greda-bg-*) / calc(--modifier(integer) * 1%));
316
+ background-color: hsl(--value(--greda-bg-*) / --modifier([number], [percentage]));
317
+ }
318
+
319
+ @utility surface-* {
320
+ background-color: hsl(--value(--greda-surface-*));
321
+ background-color: hsl(--value(--greda-surface-*) / calc(--modifier(integer) * 1%));
322
+ background-color: hsl(--value(--greda-surface-*) / --modifier([number], [percentage]));
323
+ }
324
+
325
+ @utility text-* {
326
+ color: hsl(--value(--greda-text-*));
327
+ color: hsl(--value(--greda-text-*) / calc(--modifier(integer) * 1%));
328
+ color: hsl(--value(--greda-text-*) / --modifier([number], [percentage]));
329
+ }
330
+
331
+ @utility border-* {
332
+ border-color: hsl(--value(--greda-border-*));
333
+ border-color: hsl(--value(--greda-border-*) / calc(--modifier(integer) * 1%));
334
+ border-color: hsl(--value(--greda-border-*) / --modifier([number], [percentage]));
335
+ }
336
+
181
337
  @utility z-overlay {
182
338
  z-index: var(--z-overlay);
183
339
  }
package/dist/utils.js CHANGED
@@ -1,9 +1,22 @@
1
- import { clsx as o } from "clsx";
2
- import { twMerge as t } from "tailwind-merge";
3
- function n(...r) {
4
- return t(o(r));
1
+ import { clsx as r } from "clsx";
2
+ import { extendTailwindMerge as t } from "tailwind-merge";
3
+ const o = t({
4
+ extend: {
5
+ classGroups: {
6
+ "bg-color": [{ surface: ["primary", "secondary", "tertiary", "raised", "inverse"] }],
7
+ typography: [{ text: ["display", "title", "body", "label", "caption", "eyebrow"] }]
8
+ },
9
+ // A later complete role replaces earlier typography axes. A later single
10
+ // axis keeps the role so its other properties still apply.
11
+ conflictingClassGroups: {
12
+ typography: ["font-family", "font-size", "font-weight", "leading", "tracking"]
13
+ }
14
+ }
15
+ });
16
+ function a(...e) {
17
+ return o(r(e));
5
18
  }
6
19
  export {
7
- n as cn
20
+ a as cn
8
21
  };
9
22
  //# sourceMappingURL=utils.js.map
package/dist/utils.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"utils.js","sources":["../src/lib/utils.ts"],"sourcesContent":["import { clsx, type ClassValue } from \"clsx\";\nimport { twMerge } from \"tailwind-merge\";\n\n/** Combine conditional classes and resolve conflicting Tailwind utilities. */\nexport function cn(...inputs: ClassValue[]) {\n return twMerge(clsx(inputs));\n}\n"],"names":["cn","inputs","twMerge","clsx"],"mappings":";;AAIO,SAASA,KAAMC,GAAsB;AAC1C,SAAOC,EAAQC,EAAKF,CAAM,CAAC;AAC7B;"}
1
+ {"version":3,"file":"utils.js","sources":["../src/lib/utils.ts"],"sourcesContent":["import { clsx, type ClassValue } from \"clsx\";\nimport { extendTailwindMerge } from \"tailwind-merge\";\n\nconst twMerge = extendTailwindMerge<\"typography\">({\n extend: {\n classGroups: {\n \"bg-color\": [{ surface: [\"primary\", \"secondary\", \"tertiary\", \"raised\", \"inverse\"] }],\n typography: [{ text: [\"display\", \"title\", \"body\", \"label\", \"caption\", \"eyebrow\"] }],\n },\n // A later complete role replaces earlier typography axes. A later single\n // axis keeps the role so its other properties still apply.\n conflictingClassGroups: {\n typography: [\"font-family\", \"font-size\", \"font-weight\", \"leading\", \"tracking\"],\n },\n },\n});\n\n/** Combine conditional classes and resolve conflicting Tailwind utilities. */\nexport function cn(...inputs: ClassValue[]) {\n return twMerge(clsx(inputs));\n}\n"],"names":["twMerge","extendTailwindMerge","cn","inputs","clsx"],"mappings":";;AAGA,MAAMA,IAAUC,EAAkC;AAAA,EAChD,QAAQ;AAAA,IACN,aAAa;AAAA,MACX,YAAY,CAAC,EAAE,SAAS,CAAC,WAAW,aAAa,YAAY,UAAU,SAAS,GAAG;AAAA,MACnF,YAAY,CAAC,EAAE,MAAM,CAAC,WAAW,SAAS,QAAQ,SAAS,WAAW,SAAS,EAAA,CAAG;AAAA,IAAA;AAAA;AAAA;AAAA,IAIpF,wBAAwB;AAAA,MACtB,YAAY,CAAC,eAAe,aAAa,eAAe,WAAW,UAAU;AAAA,IAAA;AAAA,EAC/E;AAEJ,CAAC;AAGM,SAASC,KAAMC,GAAsB;AAC1C,SAAOH,EAAQI,EAAKD,CAAM,CAAC;AAC7B;"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@darthcharles/greda",
3
- "version": "0.2.0",
3
+ "version": "1.1.0",
4
4
  "description": "Generic React components with a complete, overridable base theme.",
5
5
  "type": "module",
6
6
  "license": "MIT",
@@ -24,7 +24,9 @@
24
24
  "import": "./dist/utils.js"
25
25
  },
26
26
  "./styles.css": "./dist/styles.css",
27
- "./tokens.css": "./dist/tokens.css"
27
+ "./tokens.css": "./dist/tokens.css",
28
+ "./themes/cobalto.css": "./dist/themes/cobalto.css",
29
+ "./themes/comal.css": "./dist/themes/comal.css"
28
30
  },
29
31
  "sideEffects": [
30
32
  "**/*.css"