@nebutra/tokens 0.1.3 → 3.0.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.
Files changed (41) hide show
  1. package/CHANGELOG.md +16 -0
  2. package/brands/README.md +66 -0
  3. package/brands/cosmos/DESIGN.md +356 -0
  4. package/brands/cosmos/brand.json +209 -0
  5. package/brands/cosmos/refero-tokens.json +312 -0
  6. package/brands/gsap/brand.json +1 -27
  7. package/brands/linear/DESIGN.md +478 -0
  8. package/brands/linear/brand.json +2 -19
  9. package/brands/notion/brand.json +2 -28
  10. package/brands/raycast/brand.json +2 -17
  11. package/brands/stripe/brand.json +1 -16
  12. package/brands/vanta/brand.json +1 -38
  13. package/brands/vercel/brand.json +1 -18
  14. package/dist/brand-package/index.d.ts +13 -7
  15. package/dist/brand-package/index.js +2290 -34
  16. package/dist/brand-package/index.js.map +1 -1
  17. package/dist/brand-package/use-brand.d.ts +1 -1
  18. package/dist/brand-package/use-brand.js +957 -5
  19. package/dist/brand-package/use-brand.js.map +1 -1
  20. package/dist/index.d.ts +1 -1
  21. package/dist/index.js +2417 -22
  22. package/dist/index.js.map +1 -1
  23. package/dist/{use-brand-C8d4DPqE.d.ts → use-brand-ClmvK_lC.d.ts} +19 -3
  24. package/dist/values.d.ts +1192 -0
  25. package/dist/values.js +518 -0
  26. package/dist/values.js.map +1 -0
  27. package/package.json +16 -4
  28. package/recipe.css +36 -2
  29. package/skins/cosmos.css +239 -0
  30. package/skins/gsap.css +32 -20
  31. package/skins/linear.css +54 -17
  32. package/skins/notion.css +36 -25
  33. package/skins/raycast.css +37 -19
  34. package/skins/stripe.css +34 -15
  35. package/skins/vanta.css +34 -30
  36. package/skins/vercel.css +55 -19
  37. package/styles.css +492 -149
  38. package/dist/chunk-ALJTP5HL.js +0 -881
  39. package/dist/chunk-ALJTP5HL.js.map +0 -1
  40. package/dist/chunk-RGUJQOLH.js +0 -1582
  41. package/dist/chunk-RGUJQOLH.js.map +0 -1
package/package.json CHANGED
@@ -1,8 +1,13 @@
1
1
  {
2
2
  "name": "@nebutra/tokens",
3
- "version": "0.1.3",
3
+ "version": "3.0.0",
4
4
  "description": "Unified theme tokens and theme-provider entry for Nebutra apps",
5
5
  "private": false,
6
+ "nebutra": {
7
+ "status": "foundation",
8
+ "graph": "core",
9
+ "productionReady": false
10
+ },
6
11
  "license": "MIT",
7
12
  "type": "module",
8
13
  "sideEffects": [
@@ -31,10 +36,16 @@
31
36
  "types": "./dist/brand-package/use-brand.d.ts",
32
37
  "import": "./dist/brand-package/use-brand.js",
33
38
  "default": "./dist/brand-package/use-brand.js"
39
+ },
40
+ "./values": {
41
+ "types": "./dist/values.d.ts",
42
+ "import": "./dist/values.js",
43
+ "default": "./dist/values.js"
34
44
  }
35
45
  },
36
46
  "dependencies": {
37
- "@nebutra/design-tokens": "0.1.2"
47
+ "@nebutra/design-tokens": "3.0.0",
48
+ "@nebutra/fonts": "3.0.0"
38
49
  },
39
50
  "peerDependencies": {
40
51
  "react": "^19"
@@ -69,11 +80,12 @@
69
80
  "CHANGELOG.md"
70
81
  ],
71
82
  "scripts": {
72
- "build": "node scripts/sync-styles.mjs && node scripts/emit-skins.mjs && tsup",
83
+ "build": "node scripts/sync-styles.mjs && node scripts/emit-values.mjs && node scripts/emit-skins.mjs && tsup",
73
84
  "sync": "node scripts/sync-styles.mjs",
74
85
  "emit-skins": "node scripts/emit-skins.mjs",
75
86
  "compile-brand": "node scripts/compile-brand.mjs",
76
87
  "typecheck": "tsc --noEmit",
77
- "test": "tsx --test src/brand-package/__tests__/*.test.ts"
88
+ "test": "tsx --test src/brand-package/__tests__/*.test.ts src/__tests__/*.test.ts",
89
+ "emit-values": "node scripts/emit-values.mjs"
78
90
  }
79
91
  }
package/recipe.css CHANGED
@@ -11,6 +11,14 @@
11
11
  * Tailwind utilities: bg-brand-mark / text-brand-mark (see @theme below).
12
12
  */
13
13
 
14
+ @custom-variant hover {
15
+ @media (hover: hover) and (pointer: fine) {
16
+ &:hover {
17
+ @slot;
18
+ }
19
+ }
20
+ }
21
+
14
22
  :root {
15
23
  /* ── Color roles (overridden by brand skins) ──────────────────── */
16
24
  --role-action: var(--primary);
@@ -53,12 +61,33 @@
53
61
  --control-font-size-md: 0.875rem; /* 14 */
54
62
  --control-font-size-lg: 1rem; /* 16 */
55
63
  --font-weight-medium: 500;
56
- --font-weight-heading: 600;
64
+ /* 500, not 600: headings in DM Sans read confident at 500 and the measured
65
+ consensus caps heading weight at 400–510 (Linear 510, Vercel 400). */
66
+ --font-weight-heading: 500;
67
+
68
+ /*
69
+ * The boundary of an unchecked checkbox / radio. WCAG 1.4.11 wants 3:1 against
70
+ * the surface for a control's edge; --input and --border are hairlines at
71
+ * ~1.2:1 and left an empty checkbox all but invisible. Derived from each
72
+ * language's own foreground and background — the perceptual midpoint — rather
73
+ * than a scale step, because a skin's --neutral-8 can be a pale mix (Stripe's
74
+ * is): measured 3.4:1 light / 5.5:1 dark on House, and it holds per brand.
75
+ */
76
+ --control-border: color-mix(in oklab, hsl(var(--foreground)) 50%, hsl(var(--background)));
57
77
 
58
78
  /* ── Elevation (free CSS; brand package replaces these) ───────── */
59
- --elevation-card: var(--shadow-sm, 0 1px 2px 0 rgb(0 0 0 / 0.05));
79
+ /* House: a card is a hairline (--edge-soft), not a lifted object. Measured
80
+ consensus — Vercel, OpenAI, Resend, Ramp ban card shadows outright; the
81
+ one float shadow is for overlays (--elevation-overlay). Seventeen call
82
+ sites were flattening Card by hand; a Brand Package can lift it again. */
83
+ --elevation-card: 0 0 #0000;
60
84
  --elevation-control: var(--shadow-xs, 0 1px 2px 0 rgb(0 0 0 / 0.04));
61
85
  --elevation-raised: var(--shadow-md, 0 4px 6px -1px rgb(0 0 0 / 0.1));
86
+ --elevation-overlay: var(
87
+ --shadow-xl,
88
+ 0 20px 25px -5px rgb(0 0 0 / 0.1),
89
+ 0 8px 10px -6px rgb(0 0 0 / 0.1)
90
+ );
62
91
 
63
92
  /* ── Badge default = brand mark (AI / identity chips; not CTA) ─── */
64
93
  --badge-default-bg: hsl(var(--brand-mark));
@@ -352,6 +381,11 @@
352
381
  inherits: true;
353
382
  }
354
383
 
384
+ @property --elevation-overlay {
385
+ syntax: "*";
386
+ inherits: true;
387
+ }
388
+
355
389
  /* ── Genuinely untypeable: bare HSL channel triplets ──────────────────────────
356
390
  * These carry channels ("222 47% 11%"), not colours — they exist to be wrapped
357
391
  * as `hsl(var(--brand-mark))` / `hsl(var(--brand-mark) / 0.08)`, which is what
@@ -0,0 +1,239 @@
1
+ /**
2
+ * Brand carrier skin: Cosmos (cosmos) v2.0.0
3
+ * darkDefault=false dualMode=true button=solid
4
+ * fonts=0 mode=global
5
+ * Contract: roles.action → --primary; roles.brand → --brand-mark (never default CTA)
6
+ */
7
+
8
+ :root,
9
+ html[data-brand="cosmos"] {
10
+ /* ── Color roles (carrier) ── */
11
+ --role-canvas: 30 20% 96%;
12
+ --role-canvas-fg: 0 0% 5%;
13
+ --role-surface: 0 0% 100%;
14
+ --role-surface-fg: 0 0% 5%;
15
+ --role-action: 0 0% 5%;
16
+ --role-action-fg: 30 20% 96%;
17
+ --role-quiet: 0 0% 100%;
18
+ --role-quiet-fg: 0 0% 5%;
19
+ --role-muted: 30 20% 96%;
20
+ --role-muted-fg: 12 2% 42%;
21
+ --role-border: 30 5% 85%;
22
+ --role-input: 30 5% 85%;
23
+ --role-ring: 0 0% 5%;
24
+ --role-brand: 0 0% 5%;
25
+ --role-brand-fg: 30 20% 96%;
26
+ --brand-mark: 0 0% 5%;
27
+ --brand-mark-foreground: 30 20% 96%;
28
+
29
+ /* ── shadcn bridge (primary = action CTA) ── */
30
+ --background: 30 20% 96%;
31
+ --foreground: 0 0% 5%;
32
+ --card: 0 0% 100%;
33
+ --card-foreground: 0 0% 5%;
34
+ --popover: 0 0% 100%;
35
+ --popover-foreground: 0 0% 5%;
36
+ --primary: 0 0% 5%;
37
+ --primary-foreground: 30 20% 96%;
38
+ --secondary: 0 0% 100%;
39
+ --secondary-foreground: 0 0% 5%;
40
+ --muted: 30 20% 96%;
41
+ --muted-foreground: 12 2% 42%;
42
+ --accent: 0 0% 5%;
43
+ --accent-foreground: 30 20% 96%;
44
+ --destructive: 4 76% 40%;
45
+ --destructive-foreground: 0 0% 100%;
46
+ --border: 30 5% 85%;
47
+ --input: 30 5% 85%;
48
+ --ring: 0 0% 5%;
49
+ --success: 134 62% 40%;
50
+ --success-foreground: 0 0% 100%;
51
+ --info: 12 2% 42%;
52
+ --info-foreground: 0 0% 100%;
53
+ --sidebar: 0 0% 100%;
54
+ --sidebar-foreground: 0 0% 5%;
55
+ --sidebar-primary: 0 0% 5%;
56
+ --sidebar-primary-foreground: 30 20% 96%;
57
+ --sidebar-accent: 0 0% 5%;
58
+ --sidebar-accent-foreground: 30 20% 96%;
59
+ --sidebar-border: 30 5% 85%;
60
+ --sidebar-ring: 0 0% 5%;
61
+ --brand-primary: hsl(0 0% 5%);
62
+ --brand-accent: hsl(0 0% 5%);
63
+ --brand-accent-foreground: hsl(30 20% 96%);
64
+ --brand-tertiary: hsl(0 0% 5%);
65
+ --brand-gradient: hsl(var(--primary));
66
+ --brand-gradient-reverse: hsl(var(--primary));
67
+ --brand-gradient-vertical: hsl(var(--primary));
68
+ --brand-gradient-radial: hsl(var(--primary));
69
+
70
+ /* ── Neutral ramp, anchored on this language's roles ── */
71
+ --neutral-1: hsl(30 20% 96%);
72
+ --neutral-2: hsl(0 0% 100%);
73
+ --neutral-3: color-mix(in oklab, hsl(30 5% 85%) 20%, hsl(0 0% 100%));
74
+ --neutral-4: color-mix(in oklab, hsl(30 5% 85%) 40%, hsl(0 0% 100%));
75
+ --neutral-5: color-mix(in oklab, hsl(30 5% 85%) 60%, hsl(0 0% 100%));
76
+ --neutral-6: color-mix(in oklab, hsl(30 5% 85%) 80%, hsl(0 0% 100%));
77
+ --neutral-7: hsl(30 5% 85%);
78
+ --neutral-8: color-mix(in oklab, hsl(12 2% 42%) 25%, hsl(30 5% 85%));
79
+ --neutral-9: color-mix(in oklab, hsl(12 2% 42%) 50%, hsl(30 5% 85%));
80
+ --neutral-10: color-mix(in oklab, hsl(12 2% 42%) 75%, hsl(30 5% 85%));
81
+ --neutral-11: hsl(12 2% 42%);
82
+ --neutral-12: hsl(0 0% 5%);
83
+
84
+ /* Recipe (action language + free elev/radii) */
85
+ /* Shape slots */
86
+ --btn-default-radius: 16px;
87
+ --radius-button: 16px;
88
+ --radius-buttons: 16px;
89
+ --radius-md: min(16px, 16px);
90
+ --radius-card: 16px;
91
+ --radius-lg: 16px;
92
+ --radius-badge: 16px;
93
+ --badge-default-radius: 16px;
94
+ --radius-inputs: 16px;
95
+ --input-radius: 16px;
96
+ --radius-pill: 9999px;
97
+
98
+ /* Free elevation (carrier-provided CSS shadows) */
99
+ --elevation-card: 0 0 #0000;
100
+ --elevation-control: 0 0 #0000;
101
+ --elevation-raised: 0 0 #0000;
102
+ --elevation-xs: 0 0 #0000;
103
+ --elevation-sm: 0 0 #0000;
104
+ --elevation-md: 0 0 #0000;
105
+ --elevation-lg: 0 0 #0000;
106
+ --btn-default-shadow: 0 0 #0000;
107
+ --btn-default-bg: hsl(var(--primary));
108
+ --btn-default-fg: hsl(var(--primary-foreground));
109
+ --btn-default-border-width: 0px;
110
+ --btn-default-border: transparent;
111
+ --btn-default-stroke-gradient: linear-gradient(transparent, transparent);
112
+ --btn-default-hover-bg: color-mix(in srgb, hsl(var(--primary)) 90%, transparent);
113
+ --badge-default-bg: hsl(var(--secondary));
114
+ --badge-default-fg: hsl(var(--secondary-foreground));
115
+ --badge-default-border: transparent;
116
+ --badge-default-hover-bg: color-mix(in srgb, hsl(var(--secondary)) 90%, white);
117
+
118
+ /* Typography */
119
+ --font-sans:
120
+ var(--font-reg-fraunces), "Fraunces", "GT Super", Georgia, var(--font-misans, "MiSans"),
121
+ "PingFang SC", ui-serif, serif;
122
+ --font-cn:
123
+ var(--font-reg-fraunces), "Fraunces", "GT Super", Georgia, var(--font-misans, "MiSans"),
124
+ "PingFang SC", ui-serif, serif;
125
+ --font-heading:
126
+ var(--font-reg-fraunces), "Fraunces", "GT Super", Georgia, var(--font-misans, "MiSans"),
127
+ "PingFang SC", ui-serif, serif;
128
+ --font-display:
129
+ var(--font-reg-fraunces), "Fraunces", "GT Super", Georgia, var(--font-misans, "MiSans"),
130
+ "PingFang SC", ui-serif, serif;
131
+ --font-mono: var(--font-jetbrains-mono), "JetBrains Mono", ui-monospace, monospace;
132
+ --font-weight-heading: 350;
133
+
134
+ /* Motion */
135
+ --ease-out: cubic-bezier(0.16, 1, 0.3, 1);
136
+ --motion-ease-out: cubic-bezier(0.16, 1, 0.3, 1);
137
+ --ease-in-out: cubic-bezier(0.4, 0, 0.2, 1);
138
+ --motion-ease-in-out: cubic-bezier(0.4, 0, 0.2, 1);
139
+ --duration-micro: 80ms;
140
+ --motion-duration-micro: 80ms;
141
+ --duration-flow: 180ms;
142
+ --motion-duration-flow: 180ms;
143
+ --duration-reveal: 180ms;
144
+ --motion-duration-reveal: 180ms;
145
+ --duration-cinematic: 320ms;
146
+ --motion-duration-cinematic: 320ms;
147
+
148
+ /* Spacing */
149
+ --space-source-xs: 0.5rem;
150
+ --space-source-sm: 1rem;
151
+ --space-source-md: 1.25rem;
152
+ --space-source-lg: 1.5rem;
153
+ --space-source-xl: 2rem;
154
+ --space-source-2xl: 3rem;
155
+
156
+ /* Taxonomy / decorative (not product CTA) */
157
+ --brand-category-linen-canvas: #f7f5f3;
158
+ --brand-category-ink-black: #0d0d0d;
159
+ --brand-category-paper-white: #ffffff;
160
+ --brand-category-stone: #6e6a69;
161
+ --brand-category-pebble: #9a9796;
162
+ }
163
+
164
+ .dark,
165
+ html.dark[data-brand="cosmos"] {
166
+ /* ── Color roles (carrier) ── */
167
+ --role-canvas: 0 0% 5%;
168
+ --role-canvas-fg: 30 20% 96%;
169
+ --role-surface: 0 0% 11%;
170
+ --role-surface-fg: 30 20% 96%;
171
+ --role-action: 30 20% 96%;
172
+ --role-action-fg: 0 0% 5%;
173
+ --role-quiet: 0 0% 14%;
174
+ --role-quiet-fg: 30 20% 96%;
175
+ --role-muted: 0 0% 11%;
176
+ --role-muted-fg: 15 2% 60%;
177
+ --role-border: 0 1% 18%;
178
+ --role-input: 0 1% 18%;
179
+ --role-ring: 30 20% 96%;
180
+ --role-brand: 30 20% 96%;
181
+ --role-brand-fg: 0 0% 5%;
182
+ --brand-mark: 30 20% 96%;
183
+ --brand-mark-foreground: 0 0% 5%;
184
+
185
+ /* ── shadcn bridge (primary = action CTA) ── */
186
+ --background: 0 0% 5%;
187
+ --foreground: 30 20% 96%;
188
+ --card: 0 0% 11%;
189
+ --card-foreground: 30 20% 96%;
190
+ --popover: 0 0% 11%;
191
+ --popover-foreground: 30 20% 96%;
192
+ --primary: 30 20% 96%;
193
+ --primary-foreground: 0 0% 5%;
194
+ --secondary: 0 0% 14%;
195
+ --secondary-foreground: 30 20% 96%;
196
+ --muted: 0 0% 11%;
197
+ --muted-foreground: 15 2% 60%;
198
+ --accent: 30 20% 96%;
199
+ --accent-foreground: 0 0% 5%;
200
+ --destructive: 4 76% 40%;
201
+ --destructive-foreground: 0 0% 100%;
202
+ --border: 0 1% 18%;
203
+ --input: 0 1% 18%;
204
+ --ring: 30 20% 96%;
205
+ --success: 134 62% 40%;
206
+ --success-foreground: 0 0% 100%;
207
+ --info: 12 2% 42%;
208
+ --info-foreground: 0 0% 100%;
209
+ --sidebar: 0 0% 11%;
210
+ --sidebar-foreground: 30 20% 96%;
211
+ --sidebar-primary: 30 20% 96%;
212
+ --sidebar-primary-foreground: 0 0% 5%;
213
+ --sidebar-accent: 30 20% 96%;
214
+ --sidebar-accent-foreground: 0 0% 5%;
215
+ --sidebar-border: 0 1% 18%;
216
+ --sidebar-ring: 30 20% 96%;
217
+ --brand-primary: hsl(30 20% 96%);
218
+ --brand-accent: hsl(30 20% 96%);
219
+ --brand-accent-foreground: hsl(0 0% 5%);
220
+ --brand-tertiary: hsl(30 20% 96%);
221
+ --brand-gradient: hsl(var(--primary));
222
+ --brand-gradient-reverse: hsl(var(--primary));
223
+ --brand-gradient-vertical: hsl(var(--primary));
224
+ --brand-gradient-radial: hsl(var(--primary));
225
+
226
+ /* ── Neutral ramp, anchored on this language's roles ── */
227
+ --neutral-1: hsl(0 0% 5%);
228
+ --neutral-2: hsl(0 0% 11%);
229
+ --neutral-3: color-mix(in oklab, hsl(0 1% 18%) 20%, hsl(0 0% 11%));
230
+ --neutral-4: color-mix(in oklab, hsl(0 1% 18%) 40%, hsl(0 0% 11%));
231
+ --neutral-5: color-mix(in oklab, hsl(0 1% 18%) 60%, hsl(0 0% 11%));
232
+ --neutral-6: color-mix(in oklab, hsl(0 1% 18%) 80%, hsl(0 0% 11%));
233
+ --neutral-7: hsl(0 1% 18%);
234
+ --neutral-8: color-mix(in oklab, hsl(15 2% 60%) 25%, hsl(0 1% 18%));
235
+ --neutral-9: color-mix(in oklab, hsl(15 2% 60%) 50%, hsl(0 1% 18%));
236
+ --neutral-10: color-mix(in oklab, hsl(15 2% 60%) 75%, hsl(0 1% 18%));
237
+ --neutral-11: hsl(15 2% 60%);
238
+ --neutral-12: hsl(30 20% 96%);
239
+ }
package/skins/gsap.css CHANGED
@@ -1,25 +1,10 @@
1
1
  /**
2
2
  * Brand carrier skin: GSAP (gsap) v1.0.0
3
3
  * darkDefault=true dualMode=false button=gradient-stroke
4
- * fonts=2 mode=global
4
+ * fonts=0 mode=global
5
5
  * Contract: roles.action → --primary; roles.brand → --brand-mark (never default CTA)
6
6
  */
7
7
 
8
- /* Brand font faces */
9
- @font-face {
10
- font-family: "Mori";
11
- src: url("/brand-assets/mori-regular.woff2") format("woff2");
12
- font-weight: 400;
13
- font-display: swap;
14
- }
15
-
16
- @font-face {
17
- font-family: "Mori";
18
- src: url("/brand-assets/mori-semibold.woff2") format("woff2");
19
- font-weight: 600;
20
- font-display: swap;
21
- }
22
-
23
8
  :root,
24
9
  .dark,
25
10
  html[data-brand="gsap"] {
@@ -70,17 +55,35 @@ html[data-brand="gsap"] {
70
55
  --sidebar-accent-foreground: 54 100% 94%;
71
56
  --sidebar-border: 70 5% 25%;
72
57
  --sidebar-ring: 137 92% 47%;
58
+ --brand-primary: hsl(137 92% 47%);
59
+ --brand-accent: hsl(137 92% 47%);
60
+ --brand-accent-foreground: hsl(150 7% 6%);
61
+ --brand-tertiary: hsl(137 92% 47%);
73
62
  --brand-gradient: hsl(var(--primary));
74
63
  --brand-gradient-reverse: hsl(var(--primary));
75
64
  --brand-gradient-vertical: hsl(var(--primary));
76
65
  --brand-gradient-radial: hsl(var(--primary));
77
66
 
67
+ /* ── Neutral ramp, anchored on this language's roles ── */
68
+ --neutral-1: hsl(150 7% 6%);
69
+ --neutral-2: hsl(0 0% 10%);
70
+ --neutral-3: color-mix(in oklab, hsl(70 5% 25%) 20%, hsl(0 0% 10%));
71
+ --neutral-4: color-mix(in oklab, hsl(70 5% 25%) 40%, hsl(0 0% 10%));
72
+ --neutral-5: color-mix(in oklab, hsl(70 5% 25%) 60%, hsl(0 0% 10%));
73
+ --neutral-6: color-mix(in oklab, hsl(70 5% 25%) 80%, hsl(0 0% 10%));
74
+ --neutral-7: hsl(70 5% 25%);
75
+ --neutral-8: color-mix(in oklab, hsl(60 6% 46%) 25%, hsl(70 5% 25%));
76
+ --neutral-9: color-mix(in oklab, hsl(60 6% 46%) 50%, hsl(70 5% 25%));
77
+ --neutral-10: color-mix(in oklab, hsl(60 6% 46%) 75%, hsl(70 5% 25%));
78
+ --neutral-11: hsl(60 6% 46%);
79
+ --neutral-12: hsl(54 100% 94%);
80
+
78
81
  /* Recipe (action language + free elev/radii) */
79
82
  /* Shape slots */
80
83
  --btn-default-radius: 100px;
81
84
  --radius-button: 100px;
82
85
  --radius-buttons: 100px;
83
- --radius-md: 100px;
86
+ --radius-md: min(100px, 8px);
84
87
  --radius-card: 8px;
85
88
  --radius-lg: 8px;
86
89
  --radius-badge: 9999px;
@@ -120,9 +123,18 @@ html[data-brand="gsap"] {
120
123
  --control-font-size-md: 0.8125rem;
121
124
 
122
125
  /* Typography */
123
- --font-sans: "Mori", "Inter Tight", "DM Sans", ui-sans-serif, system-ui, sans-serif;
124
- --font-heading: "Mori", "Inter Tight", ui-sans-serif, system-ui, sans-serif;
125
- --font-display: "Mori", "Inter Tight", ui-sans-serif, system-ui, sans-serif;
126
+ --font-sans:
127
+ var(--font-reg-inter-tight), "Mori", "Inter Tight", "DM Sans", var(--font-misans, "MiSans"),
128
+ "PingFang SC", ui-sans-serif, system-ui, sans-serif;
129
+ --font-cn:
130
+ var(--font-reg-inter-tight), "Mori", "Inter Tight", "DM Sans", var(--font-misans, "MiSans"),
131
+ "PingFang SC", ui-sans-serif, system-ui, sans-serif;
132
+ --font-heading:
133
+ var(--font-reg-inter-tight), "Mori", "Inter Tight", var(--font-misans, "MiSans"), "PingFang SC",
134
+ ui-sans-serif, system-ui, sans-serif;
135
+ --font-display:
136
+ var(--font-reg-inter-tight), "Mori", "Inter Tight", var(--font-misans, "MiSans"), "PingFang SC",
137
+ ui-sans-serif, system-ui, sans-serif;
126
138
  --font-weight-heading: 600;
127
139
 
128
140
  /* Motion */
package/skins/linear.css CHANGED
@@ -1,19 +1,10 @@
1
1
  /**
2
2
  * Brand carrier skin: Linear (linear) v1.0.0
3
3
  * darkDefault=true dualMode=true button=solid
4
- * fonts=1 mode=global
4
+ * fonts=0 mode=global
5
5
  * Contract: roles.action → --primary; roles.brand → --brand-mark (never default CTA)
6
6
  */
7
7
 
8
- /* Brand font faces */
9
- @font-face {
10
- font-family: "Inter Variable";
11
- src: url("https://cdn.jsdelivr.net/fontsource/fonts/inter:vf@latest/latin-wght-normal.woff2")
12
- format("woff2");
13
- font-weight: 100 900;
14
- font-display: swap;
15
- }
16
-
17
8
  :root,
18
9
  html[data-brand="linear"] {
19
10
  /* ── Color roles (carrier) ── */
@@ -28,7 +19,7 @@ html[data-brand="linear"] {
28
19
  --role-muted: 220 14% 96%;
29
20
  --role-muted-fg: 218 5% 41%;
30
21
  --role-border: 220 13% 91%;
31
- --role-input: 0 0% 100%;
22
+ --role-input: 220 13% 91%;
32
23
  --role-ring: 64 89% 54%;
33
24
 
34
25
  /* ── shadcn bridge (primary = action CTA) ── */
@@ -49,7 +40,7 @@ html[data-brand="linear"] {
49
40
  --destructive: 0 79% 63%;
50
41
  --destructive-foreground: 0 0% 100%;
51
42
  --border: 220 13% 91%;
52
- --input: 0 0% 100%;
43
+ --input: 220 13% 91%;
53
44
  --ring: 64 89% 54%;
54
45
  --success: 134 62% 40%;
55
46
  --success-foreground: 0 0% 100%;
@@ -63,17 +54,35 @@ html[data-brand="linear"] {
63
54
  --sidebar-accent-foreground: 210 11% 4%;
64
55
  --sidebar-border: 220 13% 91%;
65
56
  --sidebar-ring: 64 89% 54%;
57
+ --brand-primary: hsl(64 89% 54%);
58
+ --brand-accent: hsl(64 89% 54%);
59
+ --brand-accent-foreground: hsl(210 11% 4%);
60
+ --brand-tertiary: hsl(64 89% 54%);
66
61
  --brand-gradient: hsl(var(--primary));
67
62
  --brand-gradient-reverse: hsl(var(--primary));
68
63
  --brand-gradient-vertical: hsl(var(--primary));
69
64
  --brand-gradient-radial: hsl(var(--primary));
70
65
 
66
+ /* ── Neutral ramp, anchored on this language's roles ── */
67
+ --neutral-1: hsl(0 0% 100%);
68
+ --neutral-2: hsl(0 0% 98%);
69
+ --neutral-3: color-mix(in oklab, hsl(220 13% 91%) 20%, hsl(0 0% 98%));
70
+ --neutral-4: color-mix(in oklab, hsl(220 13% 91%) 40%, hsl(0 0% 98%));
71
+ --neutral-5: color-mix(in oklab, hsl(220 13% 91%) 60%, hsl(0 0% 98%));
72
+ --neutral-6: color-mix(in oklab, hsl(220 13% 91%) 80%, hsl(0 0% 98%));
73
+ --neutral-7: hsl(220 13% 91%);
74
+ --neutral-8: color-mix(in oklab, hsl(218 5% 41%) 25%, hsl(220 13% 91%));
75
+ --neutral-9: color-mix(in oklab, hsl(218 5% 41%) 50%, hsl(220 13% 91%));
76
+ --neutral-10: color-mix(in oklab, hsl(218 5% 41%) 75%, hsl(220 13% 91%));
77
+ --neutral-11: hsl(218 5% 41%);
78
+ --neutral-12: hsl(210 11% 4%);
79
+
71
80
  /* Recipe (action language + free elev/radii) */
72
81
  /* Shape slots */
73
82
  --btn-default-radius: 6px;
74
83
  --radius-button: 6px;
75
84
  --radius-buttons: 6px;
76
- --radius-md: 6px;
85
+ --radius-md: min(6px, 12px);
77
86
  --radius-card: 12px;
78
87
  --radius-lg: 12px;
79
88
  --radius-badge: 9999px;
@@ -113,10 +122,20 @@ html[data-brand="linear"] {
113
122
  --control-font-size-md: 0.8125rem;
114
123
 
115
124
  /* Typography */
116
- --font-sans: "Inter Variable", "Inter", ui-sans-serif, system-ui, sans-serif;
117
- --font-heading: "Inter Variable", "Inter", ui-sans-serif, system-ui, sans-serif;
118
- --font-display: "Inter Variable", "Inter", ui-sans-serif, system-ui, sans-serif;
119
- --font-mono: "Berkeley Mono", "JetBrains Mono", ui-monospace, monospace;
125
+ --font-sans:
126
+ var(--font-inter), "Inter Variable", "Inter", var(--font-misans, "MiSans"), "PingFang SC",
127
+ ui-sans-serif, system-ui, sans-serif;
128
+ --font-cn:
129
+ var(--font-inter), "Inter Variable", "Inter", var(--font-misans, "MiSans"), "PingFang SC",
130
+ ui-sans-serif, system-ui, sans-serif;
131
+ --font-heading:
132
+ var(--font-inter), "Inter Variable", "Inter", var(--font-misans, "MiSans"), "PingFang SC",
133
+ ui-sans-serif, system-ui, sans-serif;
134
+ --font-display:
135
+ var(--font-inter), "Inter Variable", "Inter", var(--font-misans, "MiSans"), "PingFang SC",
136
+ ui-sans-serif, system-ui, sans-serif;
137
+ --font-mono:
138
+ var(--font-jetbrains-mono), "Berkeley Mono", "JetBrains Mono", ui-monospace, monospace;
120
139
  --font-weight-heading: 510;
121
140
 
122
141
  /* Motion */
@@ -191,8 +210,26 @@ html.dark[data-brand="linear"] {
191
210
  --sidebar-accent-foreground: 218 21% 85%;
192
211
  --sidebar-border: 223 9% 15%;
193
212
  --sidebar-ring: 64 89% 54%;
213
+ --brand-primary: hsl(64 89% 54%);
214
+ --brand-accent: hsl(64 89% 54%);
215
+ --brand-accent-foreground: hsl(210 11% 4%);
216
+ --brand-tertiary: hsl(64 89% 54%);
194
217
  --brand-gradient: hsl(var(--primary));
195
218
  --brand-gradient-reverse: hsl(var(--primary));
196
219
  --brand-gradient-vertical: hsl(var(--primary));
197
220
  --brand-gradient-radial: hsl(var(--primary));
221
+
222
+ /* ── Neutral ramp, anchored on this language's roles ── */
223
+ --neutral-1: hsl(210 11% 4%);
224
+ --neutral-2: hsl(210 6% 6%);
225
+ --neutral-3: color-mix(in oklab, hsl(223 9% 15%) 20%, hsl(210 6% 6%));
226
+ --neutral-4: color-mix(in oklab, hsl(223 9% 15%) 40%, hsl(210 6% 6%));
227
+ --neutral-5: color-mix(in oklab, hsl(223 9% 15%) 60%, hsl(210 6% 6%));
228
+ --neutral-6: color-mix(in oklab, hsl(223 9% 15%) 80%, hsl(210 6% 6%));
229
+ --neutral-7: hsl(223 9% 15%);
230
+ --neutral-8: color-mix(in oklab, hsl(218 5% 41%) 25%, hsl(223 9% 15%));
231
+ --neutral-9: color-mix(in oklab, hsl(218 5% 41%) 50%, hsl(223 9% 15%));
232
+ --neutral-10: color-mix(in oklab, hsl(218 5% 41%) 75%, hsl(223 9% 15%));
233
+ --neutral-11: hsl(218 5% 41%);
234
+ --neutral-12: hsl(0 0% 100%);
198
235
  }
package/skins/notion.css CHANGED
@@ -1,26 +1,10 @@
1
1
  /**
2
2
  * Brand carrier skin: Notion (notion) v1.0.0
3
3
  * darkDefault=false dualMode=false button=solid
4
- * fonts=2 mode=global
4
+ * fonts=0 mode=global
5
5
  * Contract: roles.action → --primary; roles.brand → --brand-mark (never default CTA)
6
6
  */
7
7
 
8
- /* Brand font faces */
9
- @font-face {
10
- font-family: "NotionInter";
11
- src: url("https://cdn.jsdelivr.net/fontsource/fonts/inter:vf@latest/latin-wght-normal.woff2")
12
- format("woff2");
13
- font-weight: 100 900;
14
- font-display: swap;
15
- }
16
-
17
- @font-face {
18
- font-family: "Lyon Text";
19
- src: url("/brand-assets/lyon-text-regular.woff2") format("woff2");
20
- font-weight: 400;
21
- font-display: swap;
22
- }
23
-
24
8
  :root,
25
9
  html[data-brand="notion"] {
26
10
  /* ── Color roles (carrier) ── */
@@ -33,9 +17,9 @@ html[data-brand="notion"] {
33
17
  --role-quiet: 208 92% 95%;
34
18
  --role-quiet-fg: 208 100% 44%;
35
19
  --role-muted: 208 92% 95%;
36
- --role-muted-fg: 0 0% 46%;
20
+ --role-muted-fg: 0 0% 43%;
37
21
  --role-border: 30 5% 88%;
38
- --role-input: 0 0% 100%;
22
+ --role-input: 30 5% 88%;
39
23
  --role-ring: 208 100% 44%;
40
24
  --role-brand: 0 0% 0%;
41
25
  --role-brand-fg: 0 0% 100%;
@@ -54,13 +38,13 @@ html[data-brand="notion"] {
54
38
  --secondary: 208 92% 95%;
55
39
  --secondary-foreground: 208 100% 44%;
56
40
  --muted: 208 92% 95%;
57
- --muted-foreground: 0 0% 46%;
41
+ --muted-foreground: 0 0% 43%;
58
42
  --accent: 0 0% 0%;
59
43
  --accent-foreground: 0 0% 100%;
60
44
  --destructive: 7 92% 58%;
61
45
  --destructive-foreground: 0 0% 100%;
62
46
  --border: 30 5% 88%;
63
- --input: 0 0% 100%;
47
+ --input: 30 5% 88%;
64
48
  --ring: 208 100% 44%;
65
49
  --warning: 40 100% 53%;
66
50
  --warning-foreground: 0 0% 0%;
@@ -74,17 +58,35 @@ html[data-brand="notion"] {
74
58
  --sidebar-accent-foreground: 0 0% 100%;
75
59
  --sidebar-border: 30 5% 88%;
76
60
  --sidebar-ring: 208 100% 44%;
61
+ --brand-primary: hsl(0 0% 0%);
62
+ --brand-accent: hsl(208 100% 44%);
63
+ --brand-accent-foreground: hsl(0 0% 100%);
64
+ --brand-tertiary: hsl(208 100% 44%);
77
65
  --brand-gradient: hsl(var(--primary));
78
66
  --brand-gradient-reverse: hsl(var(--primary));
79
67
  --brand-gradient-vertical: hsl(var(--primary));
80
68
  --brand-gradient-radial: hsl(var(--primary));
81
69
 
70
+ /* ── Neutral ramp, anchored on this language's roles ── */
71
+ --neutral-1: hsl(30 10% 96%);
72
+ --neutral-2: hsl(0 0% 100%);
73
+ --neutral-3: color-mix(in oklab, hsl(30 5% 88%) 20%, hsl(0 0% 100%));
74
+ --neutral-4: color-mix(in oklab, hsl(30 5% 88%) 40%, hsl(0 0% 100%));
75
+ --neutral-5: color-mix(in oklab, hsl(30 5% 88%) 60%, hsl(0 0% 100%));
76
+ --neutral-6: color-mix(in oklab, hsl(30 5% 88%) 80%, hsl(0 0% 100%));
77
+ --neutral-7: hsl(30 5% 88%);
78
+ --neutral-8: color-mix(in oklab, hsl(0 0% 43%) 25%, hsl(30 5% 88%));
79
+ --neutral-9: color-mix(in oklab, hsl(0 0% 43%) 50%, hsl(30 5% 88%));
80
+ --neutral-10: color-mix(in oklab, hsl(0 0% 43%) 75%, hsl(30 5% 88%));
81
+ --neutral-11: hsl(0 0% 43%);
82
+ --neutral-12: hsl(0 0% 0%);
83
+
82
84
  /* Recipe (action language + free elev/radii) */
83
85
  /* Shape slots */
84
86
  --btn-default-radius: 8px;
85
87
  --radius-button: 8px;
86
88
  --radius-buttons: 8px;
87
- --radius-md: 8px;
89
+ --radius-md: min(8px, 12px);
88
90
  --radius-card: 12px;
89
91
  --radius-lg: 12px;
90
92
  --radius-badge: 9999px;
@@ -114,9 +116,18 @@ html[data-brand="notion"] {
114
116
  --badge-default-hover-bg: color-mix(in srgb, hsl(var(--secondary)) 90%, white);
115
117
 
116
118
  /* Typography */
117
- --font-sans: "NotionInter", "Inter", ui-sans-serif, system-ui, sans-serif;
118
- --font-heading: "NotionInter", "Inter", ui-sans-serif, system-ui, sans-serif;
119
- --font-display: "NotionInter", "Inter", ui-sans-serif, system-ui, sans-serif;
119
+ --font-sans:
120
+ var(--font-inter), "NotionInter", "Inter", var(--font-misans, "MiSans"), "PingFang SC",
121
+ ui-sans-serif, system-ui, sans-serif;
122
+ --font-cn:
123
+ var(--font-inter), "NotionInter", "Inter", var(--font-misans, "MiSans"), "PingFang SC",
124
+ ui-sans-serif, system-ui, sans-serif;
125
+ --font-heading:
126
+ var(--font-inter), "NotionInter", "Inter", var(--font-misans, "MiSans"), "PingFang SC",
127
+ ui-sans-serif, system-ui, sans-serif;
128
+ --font-display:
129
+ var(--font-inter), "NotionInter", "Inter", var(--font-misans, "MiSans"), "PingFang SC",
130
+ ui-sans-serif, system-ui, sans-serif;
120
131
  --font-weight-heading: 700;
121
132
 
122
133
  /* Motion */