@archetypeai/ds-lib-tokens 0.8.0 → 0.8.1

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 (4) hide show
  1. package/README.md +14 -1
  2. package/fonts.css +198 -16
  3. package/package.json +1 -1
  4. package/theme.css +8 -2
package/README.md CHANGED
@@ -53,4 +53,17 @@ Brand tokens are defined in `tokens.css` and loaded automatically via `theme.css
53
53
 
54
54
  ## Fonts
55
55
 
56
- `fonts.css` is included in this package with `@font-face` declarations (15 faces of PP Neue Montreal Sans + Mono, `font-display: swap`) pointing to `/fonts/`. The font binaries themselves are **not** part of the npm package - the CLI (`ds create` / `ds init` / `ds add --fonts <path>`) copies them into your project's `static/fonts/`. Without fonts, the theme falls back to system fonts (`system-ui`, `Courier New`).
56
+ `fonts.css` is included in this package with two kinds of `@font-face` declarations: **15 binary faces** of PP Neue Montreal Sans + Mono (`font-display: swap`) pointing to `/fonts/`, plus **15 metric-matched fallback faces** (per-OS base × per weight). The font binaries themselves are **not** part of the npm package - the CLI (`ds create` / `ds init` / `ds add --fonts <path>`) copies them into your project's `static/fonts/`.
57
+
58
+ **When the binaries are absent**, the fallback faces take over: each re-shapes a *local* system font to PP Neue Montreal's own metrics — x-height, average character width, and line box — via `size-adjust` + `ascent`/`descent`/`line-gap-override`, so an un-provisioned project still renders at the brand font's proportions and lays out identically. **When the binaries are present**, the same faces make the fallback→brand-font swap shift-free (no layout shift / CLS).
59
+
60
+ The fallback bases are chosen **per operating system** (the stacks in `theme.css` order them so each platform resolves its closest native font, all confirmed `local()`-reachable):
61
+
62
+ | | Apple | Windows | Android |
63
+ |---|---|---|---|
64
+ | **Sans** | Helvetica Neue | Arial | Roboto |
65
+ | **Mono** | Menlo | Consolas / Cascadia Mono | Roboto Mono |
66
+
67
+ SF Mono is intentionally not used — it is not reachable via `local()`. Override numbers are generated with `@capsizecss` from the Regular weights (regenerate if the brand font's metrics change).
68
+
69
+ Weights are declared **per instance**: `local('Helvetica Neue')` always resolves to the *Regular* cut regardless of the `font-weight` descriptor, so a single face would silently render Medium as Regular and *faux-bold* 700. Each weight therefore names its real cut (`local('HelveticaNeue-Medium')` / `-Bold`, etc.). Bases without a true Medium (Arial, Menlo, Cascadia) omit 500, so it matches down to Regular.
package/fonts.css CHANGED
@@ -1,3 +1,5 @@
1
+ /* OFFICIAL BRAND FONTS */
2
+
1
3
  /* PP Neue Montreal Sans*/
2
4
 
3
5
  @font-face {
@@ -40,14 +42,6 @@
40
42
  font-display: swap;
41
43
  }
42
44
 
43
- @font-face {
44
- font-family: 'PP Neue Montreal';
45
- src: url('/fonts/PPNeueMontreal-Book.ttf') format('truetype');
46
- font-weight: 400;
47
- font-style: normal;
48
- font-display: swap;
49
- }
50
-
51
45
  @font-face {
52
46
  font-family: 'PP Neue Montreal';
53
47
  src: url('/fonts/PPNeueMontreal-Medium.ttf') format('truetype');
@@ -98,14 +92,6 @@
98
92
  font-display: swap;
99
93
  }
100
94
 
101
- @font-face {
102
- font-family: 'PP Neue Montreal Mono';
103
- src: url('/fonts/PPNeueMontrealMono-Book.otf') format('opentype');
104
- font-weight: 400;
105
- font-style: normal;
106
- font-display: swap;
107
- }
108
-
109
95
  @font-face {
110
96
  font-family: 'PP Neue Montreal Mono';
111
97
  src: url('/fonts/PPNeueMontrealMono-Medium.otf') format('opentype');
@@ -121,3 +107,199 @@
121
107
  font-style: normal;
122
108
  font-display: swap;
123
109
  }
110
+
111
+ /* METRIC-MATCHED FALLBACKS */
112
+
113
+ /* sans — Helvetica Neue (MacOS) */
114
+ @font-face {
115
+ font-family: 'PP Neue Montreal Fallback Helvetica';
116
+ src: local('HelveticaNeue-UltraLight'), local('Helvetica Neue UltraLight');
117
+ font-weight: 100;
118
+ ascent-override: 101.4353%;
119
+ descent-override: 25.6235%;
120
+ line-gap-override: 0%;
121
+ size-adjust: 94.4444%;
122
+ }
123
+ @font-face {
124
+ font-family: 'PP Neue Montreal Fallback Helvetica';
125
+ src: local('HelveticaNeue-Light'), local('Helvetica Neue Light');
126
+ font-weight: 300;
127
+ ascent-override: 101.4353%;
128
+ descent-override: 25.6235%;
129
+ line-gap-override: 0%;
130
+ size-adjust: 94.4444%;
131
+ }
132
+ @font-face {
133
+ font-family: 'PP Neue Montreal Fallback Helvetica';
134
+ src: local('Helvetica Neue'), local('HelveticaNeue');
135
+ font-weight: 400;
136
+ ascent-override: 101.4353%;
137
+ descent-override: 25.6235%;
138
+ line-gap-override: 0%;
139
+ size-adjust: 94.4444%;
140
+ }
141
+ @font-face {
142
+ font-family: 'PP Neue Montreal Fallback Helvetica';
143
+ src: local('HelveticaNeue-Medium'), local('Helvetica Neue Medium');
144
+ font-weight: 500;
145
+ ascent-override: 101.4353%;
146
+ descent-override: 25.6235%;
147
+ line-gap-override: 0%;
148
+ size-adjust: 94.4444%;
149
+ }
150
+ @font-face {
151
+ font-family: 'PP Neue Montreal Fallback Helvetica';
152
+ src: local('HelveticaNeue-Bold'), local('Helvetica Neue Bold');
153
+ font-weight: 700;
154
+ ascent-override: 101.4353%;
155
+ descent-override: 25.6235%;
156
+ line-gap-override: 0%;
157
+ size-adjust: 94.4444%;
158
+ }
159
+
160
+ /* sans — Roboto (Android) */
161
+ @font-face {
162
+ font-family: 'PP Neue Montreal Fallback Roboto';
163
+ src: local('Roboto Thin'), local('Roboto-Thin');
164
+ font-weight: 100;
165
+ ascent-override: 100.2686%;
166
+ descent-override: 25.3288%;
167
+ line-gap-override: 0%;
168
+ size-adjust: 95.5434%;
169
+ }
170
+ @font-face {
171
+ font-family: 'PP Neue Montreal Fallback Roboto';
172
+ src: local('Roboto Light'), local('Roboto-Light');
173
+ font-weight: 300;
174
+ ascent-override: 100.2686%;
175
+ descent-override: 25.3288%;
176
+ line-gap-override: 0%;
177
+ size-adjust: 95.5434%;
178
+ }
179
+ @font-face {
180
+ font-family: 'PP Neue Montreal Fallback Roboto';
181
+ src: local('Roboto'), local('Roboto-Regular');
182
+ font-weight: 400;
183
+ ascent-override: 100.2686%;
184
+ descent-override: 25.3288%;
185
+ line-gap-override: 0%;
186
+ size-adjust: 95.5434%;
187
+ }
188
+ @font-face {
189
+ font-family: 'PP Neue Montreal Fallback Roboto';
190
+ src: local('Roboto Medium'), local('Roboto-Medium');
191
+ font-weight: 500;
192
+ ascent-override: 100.2686%;
193
+ descent-override: 25.3288%;
194
+ line-gap-override: 0%;
195
+ size-adjust: 95.5434%;
196
+ }
197
+ @font-face {
198
+ font-family: 'PP Neue Montreal Fallback Roboto';
199
+ src: local('Roboto Bold'), local('Roboto-Bold');
200
+ font-weight: 700;
201
+ ascent-override: 100.2686%;
202
+ descent-override: 25.3288%;
203
+ line-gap-override: 0%;
204
+ size-adjust: 95.5434%;
205
+ }
206
+
207
+ /* sans — Arial (Windows + universal); ships only Regular + Bold → 100/300/500 match to Regular */
208
+ @font-face {
209
+ font-family: 'PP Neue Montreal Fallback Arial';
210
+ src: local('Arial'), local('ArialMT');
211
+ font-weight: 400;
212
+ ascent-override: 100.4887%;
213
+ descent-override: 25.3844%;
214
+ line-gap-override: 0%;
215
+ size-adjust: 95.3341%;
216
+ }
217
+ @font-face {
218
+ font-family: 'PP Neue Montreal Fallback Arial';
219
+ src: local('Arial Bold'), local('Arial-BoldMT');
220
+ font-weight: 700;
221
+ ascent-override: 100.4887%;
222
+ descent-override: 25.3844%;
223
+ line-gap-override: 0%;
224
+ size-adjust: 95.3341%;
225
+ }
226
+
227
+ /* mono — Menlo (Apple); ships only Regular + Bold → 100/500 match to Regular */
228
+ @font-face {
229
+ font-family: 'PP Neue Montreal Mono Fallback Menlo';
230
+ src: local('Menlo'), local('Menlo-Regular');
231
+ font-weight: 400;
232
+ ascent-override: 96.1274%;
233
+ descent-override: 24.2827%;
234
+ line-gap-override: 0%;
235
+ size-adjust: 99.6594%;
236
+ }
237
+ @font-face {
238
+ font-family: 'PP Neue Montreal Mono Fallback Menlo';
239
+ src: local('Menlo Bold'), local('Menlo-Bold');
240
+ font-weight: 700;
241
+ ascent-override: 96.1274%;
242
+ descent-override: 24.2827%;
243
+ line-gap-override: 0%;
244
+ size-adjust: 99.6594%;
245
+ }
246
+
247
+ /* mono — Consolas / Cascadia (Windows); Consolas ships only Regular + Bold → 100/500 match to Regular */
248
+ @font-face {
249
+ font-family: 'PP Neue Montreal Mono Fallback Cascadia';
250
+ src: local('Cascadia Mono'), local('Cascadia Code'), local('Consolas');
251
+ font-weight: 400;
252
+ ascent-override: 93.5547%;
253
+ descent-override: 23.6328%;
254
+ line-gap-override: 0%;
255
+ size-adjust: 102.4%;
256
+ }
257
+ @font-face {
258
+ font-family: 'PP Neue Montreal Mono Fallback Cascadia';
259
+ src:
260
+ local('Cascadia Mono Bold'), local('CascadiaMono-Bold'), local('Consolas Bold'),
261
+ local('Consolas-Bold');
262
+ font-weight: 700;
263
+ ascent-override: 93.5547%;
264
+ descent-override: 23.6328%;
265
+ line-gap-override: 0%;
266
+ size-adjust: 102.4%;
267
+ }
268
+
269
+ /* mono — Roboto Mono (Android) */
270
+ @font-face {
271
+ font-family: 'PP Neue Montreal Mono Fallback Roboto';
272
+ src: local('Roboto Mono Thin'), local('RobotoMono-Thin');
273
+ font-weight: 100;
274
+ ascent-override: 95.8156%;
275
+ descent-override: 24.2039%;
276
+ line-gap-override: 0%;
277
+ size-adjust: 99.9837%;
278
+ }
279
+ @font-face {
280
+ font-family: 'PP Neue Montreal Mono Fallback Roboto';
281
+ src: local('Roboto Mono'), local('RobotoMono-Regular');
282
+ font-weight: 400;
283
+ ascent-override: 95.8156%;
284
+ descent-override: 24.2039%;
285
+ line-gap-override: 0%;
286
+ size-adjust: 99.9837%;
287
+ }
288
+ @font-face {
289
+ font-family: 'PP Neue Montreal Mono Fallback Roboto';
290
+ src: local('Roboto Mono Medium'), local('RobotoMono-Medium');
291
+ font-weight: 500;
292
+ ascent-override: 95.8156%;
293
+ descent-override: 24.2039%;
294
+ line-gap-override: 0%;
295
+ size-adjust: 99.9837%;
296
+ }
297
+ @font-face {
298
+ font-family: 'PP Neue Montreal Mono Fallback Roboto';
299
+ src: local('Roboto Mono Bold'), local('RobotoMono-Bold');
300
+ font-weight: 700;
301
+ ascent-override: 95.8156%;
302
+ descent-override: 24.2039%;
303
+ line-gap-override: 0%;
304
+ size-adjust: 99.9837%;
305
+ }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@archetypeai/ds-lib-tokens",
3
- "version": "0.8.0",
3
+ "version": "0.8.1",
4
4
  "description": "Archetype AI Design System Tokens",
5
5
  "type": "module",
6
6
  "exports": {
package/theme.css CHANGED
@@ -112,8 +112,14 @@
112
112
 
113
113
  /* Tailwind Theme */
114
114
  @theme {
115
- --font-sans: 'PP Neue Montreal', system-ui, -apple-system, sans-serif;
116
- --font-mono: 'PP Neue Montreal Mono', 'Courier New', monospace;
115
+ /* ' Fallback ' faces (metric-matched, per-OS bases) are defined in fonts.css */
116
+ --font-sans:
117
+ 'PP Neue Montreal', 'PP Neue Montreal Fallback Helvetica', 'PP Neue Montreal Fallback Roboto',
118
+ 'PP Neue Montreal Fallback Arial', ui-sans-serif, system-ui, -apple-system, sans-serif;
119
+ --font-mono:
120
+ 'PP Neue Montreal Mono', 'PP Neue Montreal Mono Fallback Menlo',
121
+ 'PP Neue Montreal Mono Fallback Cascadia', 'PP Neue Montreal Mono Fallback Roboto',
122
+ ui-monospace, monospace;
117
123
  --radius-xs: 0.125rem;
118
124
  --radius-sm: 0.25rem;
119
125
  --radius-md: var(--radius);