@cloudgrid-io/ui 0.28.0 → 0.29.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/README.md +8 -1
- package/dist/console.css +65 -0
- package/dist/lib/cloudgrid-cn.d.ts +1 -1
- package/dist/lib/cloudgrid-cn.d.ts.map +1 -1
- package/dist/lib/cloudgrid-cn.js +10 -0
- package/dist/lib/cloudgrid-cn.js.map +1 -1
- package/dist/theme.css +44 -0
- package/dist/tokens/base.json +101 -2
- package/dist/tokens.css +212 -2
- package/dist/tokens.json +10 -0
- package/package.json +2 -1
package/README.md
CHANGED
|
@@ -35,6 +35,7 @@ component tree.
|
|
|
35
35
|
|
|
36
36
|
@import "@cloudgrid-io/ui/fonts.css";
|
|
37
37
|
@import "@cloudgrid-io/ui/tokens.css";
|
|
38
|
+
@import "@cloudgrid-io/ui/console.css"; /* optional, see below */
|
|
38
39
|
@import "@cloudgrid-io/ui/theme.css";
|
|
39
40
|
@import "@cloudgrid-io/ui/shadcn.css";
|
|
40
41
|
```
|
|
@@ -44,10 +45,15 @@ The order matters, and getting it wrong fails quietly rather than loudly.
|
|
|
44
45
|
- `theme.css` maps Tailwind utilities onto the tokens. Before `tokens.css` has run there is
|
|
45
46
|
nothing to map, so every utility resolves to nothing and the page renders unstyled
|
|
46
47
|
instead of erroring.
|
|
48
|
+
- `console.css` is a **product preset**, not part of the base. It re-declares the body and
|
|
49
|
+
display faces as the UI face, Manrope. The CloudGrid Console imports it; so should any
|
|
50
|
+
product whose type is the UI face rather than the display face. Everyone else leaves the
|
|
51
|
+
line out and keeps the default. It has to sit after `tokens.css`, which is what it
|
|
52
|
+
re-declares, and before `theme.css`, which maps the utilities onto the result.
|
|
47
53
|
- `shadcn.css` must come after whatever `:root` your own `shadcn init` wrote, because it
|
|
48
54
|
overrides those values. Put it earlier and the stock grey palette wins.
|
|
49
55
|
|
|
50
|
-
Not using shadcn: skip the last line. Not using Tailwind: `tokens.css` alone gives you every
|
|
56
|
+
Not using the Console's face: skip the `console.css` line. Not using shadcn: skip the last line. Not using Tailwind: `tokens.css` alone gives you every
|
|
51
57
|
value as a custom property.
|
|
52
58
|
|
|
53
59
|
## Point Tailwind at the package
|
|
@@ -92,6 +98,7 @@ property of a container, never a page-level theme.
|
|
|
92
98
|
| | |
|
|
93
99
|
|---|---|
|
|
94
100
|
| `@cloudgrid-io/ui/tokens.css` | every value as a CSS custom property |
|
|
101
|
+
| `@cloudgrid-io/ui/console.css` | product preset: body and display type set to Manrope |
|
|
95
102
|
| `@cloudgrid-io/ui/theme.css` | maps Tailwind utilities onto the tokens |
|
|
96
103
|
| `@cloudgrid-io/ui/shadcn.css` | maps shadcn's variables onto the tokens |
|
|
97
104
|
| `@cloudgrid-io/ui/fonts.css` | the three self-hosted families |
|
package/dist/console.css
ADDED
|
@@ -0,0 +1,65 @@
|
|
|
1
|
+
/*
|
|
2
|
+
A PRODUCT PRESET, not a theme and not a second brand.
|
|
3
|
+
|
|
4
|
+
The Console's type is the UI face, Manrope, for body and for display. This
|
|
5
|
+
file states that in the library, so the Console does not carry a font stack of
|
|
6
|
+
its own. ui#250, 2026-09-20.
|
|
7
|
+
|
|
8
|
+
Two declarations, and deliberately nothing else: no colour, no spacing, no
|
|
9
|
+
size, no component. A preset that grew a second concern would become a theme,
|
|
10
|
+
and this package has one brand.
|
|
11
|
+
|
|
12
|
+
WHY IT EXISTS. #243 moved --cg-font-body to Space Grotesk and --cg-font-display
|
|
13
|
+
to Tanker, measured against the six canonical marketing frames, and that is
|
|
14
|
+
correct for the marketing site. The Console deleted its own @theme font
|
|
15
|
+
forwards (console#652) and inherits every family from here, so installing
|
|
16
|
+
0.28.0 changed every face in it at once. The marketing default is untouched by
|
|
17
|
+
this file; the Console imports it and gets back exactly the two values both
|
|
18
|
+
tokens held before ef8dc00.
|
|
19
|
+
|
|
20
|
+
WHY var(--cg-font-ui) RATHER THAN THE STACK. --cg-font-ui is already the
|
|
21
|
+
Manrope stack, and its docblock in tokens.css records that its value is
|
|
22
|
+
--cg-font-body's previous value byte for byte. Aliasing keeps one copy of the
|
|
23
|
+
fallback chain in the package. A consumer that spelled the stack out instead
|
|
24
|
+
went stale the moment the library's fallbacks moved — cloudgrid-landing PR
|
|
25
|
+
#132 did exactly that with the display stack — and a copy one repo further
|
|
26
|
+
away goes stale the same way.
|
|
27
|
+
|
|
28
|
+
IMPORT ORDER. After tokens.css, which is what it re-declares, and before
|
|
29
|
+
theme.css, which maps the Tailwind utilities onto the result:
|
|
30
|
+
|
|
31
|
+
@import "tailwindcss";
|
|
32
|
+
@import "@cloudgrid-io/ui/fonts.css";
|
|
33
|
+
@import "@cloudgrid-io/ui/tokens.css";
|
|
34
|
+
@import "@cloudgrid-io/ui/console.css"; <- here
|
|
35
|
+
@import "@cloudgrid-io/ui/theme.css";
|
|
36
|
+
@import "@cloudgrid-io/ui/shadcn.css";
|
|
37
|
+
|
|
38
|
+
Import it before tokens.css and tokens.css wins: same specificity, later
|
|
39
|
+
declaration, and the page renders Space Grotesk with no error anywhere.
|
|
40
|
+
|
|
41
|
+
THE SELECTOR LIST IS LOAD-BEARING, for the reason shadcn.css states at length.
|
|
42
|
+
A custom property that references another is substituted where it is DECLARED,
|
|
43
|
+
and descendants inherit the already-resolved value. tokens.css declares the
|
|
44
|
+
font families only at :root today, because a family has no on-purple value, so
|
|
45
|
+
a :root-only preset would render correctly as things stand. It is repeated on
|
|
46
|
+
both surface selectors anyway: the day --cg-font-ui gains a per-surface value,
|
|
47
|
+
a :root-only alias freezes to the root stack and silently stops following it.
|
|
48
|
+
Three selectors is a cheaper price than that failure, and
|
|
49
|
+
test/console-preset.test.mjs pins it.
|
|
50
|
+
|
|
51
|
+
WHO IMPORTS IT. The Console first. Any product whose type is the UI face
|
|
52
|
+
rather than the display face imports the same file; nothing here is named for
|
|
53
|
+
the Console except this sentence.
|
|
54
|
+
|
|
55
|
+
SIDE EFFECT WORTH KNOWING. StatTile values read as typed again. Tanker is an
|
|
56
|
+
all-caps face, so `15s` and `Coming soon` rendered as `15S` and `COMING SOON`
|
|
57
|
+
under the marketing display token. No component changed to fix that.
|
|
58
|
+
*/
|
|
59
|
+
|
|
60
|
+
:root,
|
|
61
|
+
[data-cg-surface='panel'],
|
|
62
|
+
[data-cg-surface='ink'] {
|
|
63
|
+
--cg-font-body: var(--cg-font-ui);
|
|
64
|
+
--cg-font-display: var(--cg-font-ui);
|
|
65
|
+
}
|
|
@@ -60,6 +60,6 @@ import { type ClassValue } from "clsx";
|
|
|
60
60
|
* to write `font-regular` rediscovers this.
|
|
61
61
|
*/
|
|
62
62
|
export declare const BRAND_FONT_WEIGHTS: readonly ["heavy", "regular"];
|
|
63
|
-
export declare const BRAND_FONT_SIZES: readonly ["display-3xl", "display-2xl", "display-xl", "display-lg", "display-md", "display-sm", "title-lg", "title-md", "title-sm", "heading-lg", "heading-md", "heading-sm", "body-xl", "body-lg", "body-md", "body-sm", "caption", "mono", "label", "eyebrow"];
|
|
63
|
+
export declare const BRAND_FONT_SIZES: readonly ["display-3xl", "display-2xl", "display-xl", "display-48", "display-lg", "display-md", "display-sm", "title-lg", "title-36", "title-32", "title-md", "title-24", "title-sm", "heading-lg", "heading-md", "heading-sm", "body-xl", "body-lg", "body-18", "body-md", "body-sm", "caption", "mono", "label", "eyebrow", "stat"];
|
|
64
64
|
export declare function cn(...inputs: ClassValue[]): string;
|
|
65
65
|
//# sourceMappingURL=cloudgrid-cn.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"cloudgrid-cn.d.ts","sourceRoot":"","sources":["../../src/lib/cloudgrid-cn.ts"],"names":[],"mappings":"AAAA,OAAO,EAAQ,KAAK,UAAU,EAAE,MAAM,MAAM,CAAA;AAG5C;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAsCG;AACH;;;;;;;;;;;;;;;;;;;;GAoBG;AACH,eAAO,MAAM,kBAAkB,+BAAgC,CAAA;AAE/D,eAAO,MAAM,gBAAgB,
|
|
1
|
+
{"version":3,"file":"cloudgrid-cn.d.ts","sourceRoot":"","sources":["../../src/lib/cloudgrid-cn.ts"],"names":[],"mappings":"AAAA,OAAO,EAAQ,KAAK,UAAU,EAAE,MAAM,MAAM,CAAA;AAG5C;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAsCG;AACH;;;;;;;;;;;;;;;;;;;;GAoBG;AACH,eAAO,MAAM,kBAAkB,+BAAgC,CAAA;AAE/D,eAAO,MAAM,gBAAgB,uUA+BnB,CAAA;AAWV,wBAAgB,EAAE,CAAC,GAAG,MAAM,EAAE,UAAU,EAAE,UAEzC"}
|
package/dist/lib/cloudgrid-cn.js
CHANGED
|
@@ -65,23 +65,33 @@ export const BRAND_FONT_SIZES = [
|
|
|
65
65
|
"display-3xl",
|
|
66
66
|
"display-2xl",
|
|
67
67
|
"display-xl",
|
|
68
|
+
// Px-named rungs (#248). They do not match tailwind-merge's t-shirt size
|
|
69
|
+
// regex either -- `^(\d+(\.\d+)?)?(xs|sm|md|lg|xl)$` anchors on a t-shirt
|
|
70
|
+
// word, and "48" has none -- so they fall through to text-color exactly the
|
|
71
|
+
// way the role names do, and belong here for the same reason.
|
|
72
|
+
"display-48",
|
|
68
73
|
"display-lg",
|
|
69
74
|
"display-md",
|
|
70
75
|
"display-sm",
|
|
71
76
|
"title-lg",
|
|
77
|
+
"title-36",
|
|
78
|
+
"title-32",
|
|
72
79
|
"title-md",
|
|
80
|
+
"title-24",
|
|
73
81
|
"title-sm",
|
|
74
82
|
"heading-lg",
|
|
75
83
|
"heading-md",
|
|
76
84
|
"heading-sm",
|
|
77
85
|
"body-xl",
|
|
78
86
|
"body-lg",
|
|
87
|
+
"body-18",
|
|
79
88
|
"body-md",
|
|
80
89
|
"body-sm",
|
|
81
90
|
"caption",
|
|
82
91
|
"mono",
|
|
83
92
|
"label",
|
|
84
93
|
"eyebrow",
|
|
94
|
+
"stat",
|
|
85
95
|
];
|
|
86
96
|
const twMerge = extendTailwindMerge({
|
|
87
97
|
extend: {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"cloudgrid-cn.js","sourceRoot":"","sources":["../../src/lib/cloudgrid-cn.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,IAAI,EAAmB,MAAM,MAAM,CAAA;AAC5C,OAAO,EAAE,mBAAmB,EAAE,MAAM,gBAAgB,CAAA;AAEpD;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAsCG;AACH;;;;;;;;;;;;;;;;;;;;GAoBG;AACH,MAAM,CAAC,MAAM,kBAAkB,GAAG,CAAC,OAAO,EAAE,SAAS,CAAU,CAAA;AAE/D,MAAM,CAAC,MAAM,gBAAgB,GAAG;IAC9B,aAAa;IACb,aAAa;IACb,YAAY;IACZ,YAAY;IACZ,YAAY;IACZ,YAAY;IACZ,UAAU;IACV,UAAU;IACV,UAAU;IACV,YAAY;IACZ,YAAY;IACZ,YAAY;IACZ,SAAS;IACT,SAAS;IACT,SAAS;IACT,SAAS;IACT,SAAS;IACT,MAAM;IACN,OAAO;IACP,SAAS;
|
|
1
|
+
{"version":3,"file":"cloudgrid-cn.js","sourceRoot":"","sources":["../../src/lib/cloudgrid-cn.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,IAAI,EAAmB,MAAM,MAAM,CAAA;AAC5C,OAAO,EAAE,mBAAmB,EAAE,MAAM,gBAAgB,CAAA;AAEpD;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAsCG;AACH;;;;;;;;;;;;;;;;;;;;GAoBG;AACH,MAAM,CAAC,MAAM,kBAAkB,GAAG,CAAC,OAAO,EAAE,SAAS,CAAU,CAAA;AAE/D,MAAM,CAAC,MAAM,gBAAgB,GAAG;IAC9B,aAAa;IACb,aAAa;IACb,YAAY;IACZ,yEAAyE;IACzE,0EAA0E;IAC1E,4EAA4E;IAC5E,8DAA8D;IAC9D,YAAY;IACZ,YAAY;IACZ,YAAY;IACZ,YAAY;IACZ,UAAU;IACV,UAAU;IACV,UAAU;IACV,UAAU;IACV,UAAU;IACV,UAAU;IACV,YAAY;IACZ,YAAY;IACZ,YAAY;IACZ,SAAS;IACT,SAAS;IACT,SAAS;IACT,SAAS;IACT,SAAS;IACT,SAAS;IACT,MAAM;IACN,OAAO;IACP,SAAS;IACT,MAAM;CACE,CAAA;AAEV,MAAM,OAAO,GAAG,mBAAmB,CAAC;IAClC,MAAM,EAAE;QACN,WAAW,EAAE;YACX,WAAW,EAAE,CAAC,EAAE,IAAI,EAAE,CAAC,GAAG,gBAAgB,CAAC,EAAE,CAAC;YAC9C,aAAa,EAAE,CAAC,EAAE,IAAI,EAAE,CAAC,GAAG,kBAAkB,CAAC,EAAE,CAAC;SACnD;KACF;CACF,CAAC,CAAA;AAEF,MAAM,UAAU,EAAE,CAAC,GAAG,MAAoB;IACxC,OAAO,OAAO,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC,CAAA;AAC9B,CAAC"}
|
package/dist/theme.css
CHANGED
|
@@ -289,6 +289,20 @@
|
|
|
289
289
|
--text-display-xl: var(--cg-display-xl);
|
|
290
290
|
--text-display-xl--line-height: var(--cg-display-line);
|
|
291
291
|
--text-display-xl--letter-spacing: var(--cg-display-tracking);
|
|
292
|
+
/* Like 2xl and 3xl, and unlike the four rungs below it, this one is
|
|
293
|
+
leading-none with no tracking because its node is (#248). The legacy
|
|
294
|
+
--cg-display-line 1.06 and --cg-display-tracking 0.012em were tuned for a
|
|
295
|
+
condensed face this package no longer ships and are kept only for the rungs
|
|
296
|
+
that already rendered with them. */
|
|
297
|
+
--text-display-48: var(--cg-display-48);
|
|
298
|
+
--text-display-48--line-height: var(--cg-display-line-tight);
|
|
299
|
+
--text-display-48--letter-spacing: var(--cg-title-tracking);
|
|
300
|
+
/* --cg-display-64 has NO utility here, deliberately. Its two nodes disagree on
|
|
301
|
+
a leading -- thegrid sets 70px, home leaves Figma's Auto -- and a --text-*
|
|
302
|
+
entry cannot exist without a --line-height companion, so the utility could
|
|
303
|
+
only be built by inventing one. Same reasoning as --cg-body-14, and the same
|
|
304
|
+
reasoning that keeps 96px out of the ramp entirely. Spell it as
|
|
305
|
+
`[font-size:var(--cg-display-64)]` with the leading the page wants. */
|
|
292
306
|
--text-display-lg: var(--cg-display-lg);
|
|
293
307
|
--text-display-lg--line-height: var(--cg-display-line);
|
|
294
308
|
--text-display-lg--letter-spacing: var(--cg-display-tracking);
|
|
@@ -306,9 +320,21 @@
|
|
|
306
320
|
--text-title-lg: var(--cg-title-lg);
|
|
307
321
|
--text-title-lg--line-height: var(--cg-title-line);
|
|
308
322
|
--text-title-lg--letter-spacing: var(--cg-title-tracking);
|
|
323
|
+
/* Three rungs named by pixel value (#248): every size this round falls
|
|
324
|
+
strictly between two shipped ones, so there is no free t-shirt name in the
|
|
325
|
+
right place. tokens.css's --cg-display-64 note has the reasoning. */
|
|
326
|
+
--text-title-36: var(--cg-title-36);
|
|
327
|
+
--text-title-36--line-height: var(--cg-title-line);
|
|
328
|
+
--text-title-36--letter-spacing: var(--cg-title-tracking);
|
|
329
|
+
--text-title-32: var(--cg-title-32);
|
|
330
|
+
--text-title-32--line-height: var(--cg-title-line);
|
|
331
|
+
--text-title-32--letter-spacing: var(--cg-title-tracking);
|
|
309
332
|
--text-title-md: var(--cg-title-md);
|
|
310
333
|
--text-title-md--line-height: var(--cg-title-line);
|
|
311
334
|
--text-title-md--letter-spacing: var(--cg-title-tracking);
|
|
335
|
+
--text-title-24: var(--cg-title-24);
|
|
336
|
+
--text-title-24--line-height: var(--cg-title-line);
|
|
337
|
+
--text-title-24--letter-spacing: var(--cg-title-tracking);
|
|
312
338
|
--text-title-sm: var(--cg-title-sm);
|
|
313
339
|
--text-title-sm--line-height: var(--cg-title-line);
|
|
314
340
|
--text-title-sm--letter-spacing: var(--cg-title-tracking);
|
|
@@ -324,10 +350,20 @@
|
|
|
324
350
|
--text-body-xl--line-height: var(--cg-body-line);
|
|
325
351
|
--text-body-lg: var(--cg-body-lg);
|
|
326
352
|
--text-body-lg--line-height: var(--cg-body-line);
|
|
353
|
+
/* pricing's three plan names, at --cg-body-line exactly. A body rung and not a
|
|
354
|
+
heading one: nothing at 18 in six frames is near --cg-heading-line's 1.2
|
|
355
|
+
(#248). */
|
|
356
|
+
--text-body-18: var(--cg-body-18);
|
|
357
|
+
--text-body-18--line-height: var(--cg-body-line);
|
|
327
358
|
--text-body-md: var(--cg-body-md);
|
|
328
359
|
--text-body-md--line-height: var(--cg-body-line);
|
|
329
360
|
--text-body-sm: var(--cg-body-sm);
|
|
330
361
|
--text-body-sm--line-height: var(--cg-body-line);
|
|
362
|
+
/* --cg-body-14 has NO utility, for the same reason as --cg-display-64: its
|
|
363
|
+
three non-eyebrow runs read 1.295 and 1.55 and there is no leading to ship.
|
|
364
|
+
Sixteen of the nineteen 14px runs in the frames are the eyebrow, which is
|
|
365
|
+
--text-eyebrow below and already carries its own leading, tracking and
|
|
366
|
+
weight. */
|
|
331
367
|
--text-caption: var(--cg-caption);
|
|
332
368
|
--text-caption--line-height: var(--cg-body-line);
|
|
333
369
|
--text-mono: var(--cg-mono-size);
|
|
@@ -344,6 +380,14 @@
|
|
|
344
380
|
--text-eyebrow--line-height: var(--cg-eyebrow-line);
|
|
345
381
|
--text-eyebrow--letter-spacing: var(--cg-eyebrow-tracking);
|
|
346
382
|
--text-eyebrow--font-weight: var(--cg-eyebrow-weight);
|
|
383
|
+
/* The big figure in a stat block: the UI face at leading-none, which no other
|
|
384
|
+
rung on this ramp is (heading is 1.2, body is 1.46). Ten nodes on home and
|
|
385
|
+
enterprise, all Manrope Medium 32 (#248). A role set rather than a bare
|
|
386
|
+
size, on the eyebrow's pattern, so the leading and the weight cannot drift
|
|
387
|
+
into a component inline. */
|
|
388
|
+
--text-stat: var(--cg-stat-size);
|
|
389
|
+
--text-stat--line-height: var(--cg-stat-line);
|
|
390
|
+
--text-stat--font-weight: var(--cg-stat-weight);
|
|
347
391
|
|
|
348
392
|
/* ---- weights ----
|
|
349
393
|
`--font-weight-display` is unreachable and kept only for completeness. Both
|
package/dist/tokens/base.json
CHANGED
|
@@ -926,7 +926,7 @@
|
|
|
926
926
|
}
|
|
927
927
|
},
|
|
928
928
|
"h1-display-ramp": {
|
|
929
|
-
"$description": "H1 display ramp: uppercase, condensed, Primary or white\n\nStepped down one notch 2026-08-06 (operator: main headings read too\ndominant). The SOURCE values were xl 64 / lg 48 / md 42 / sm 32.",
|
|
929
|
+
"$description": "H1 display ramp: uppercase, condensed, Primary or white\n\nStepped down one notch 2026-08-06 (operator: main headings read too\ndominant). The SOURCE values were xl 64 / lg 48 / md 42 / sm 32.\n\n2026-09-19 (#248): display-64 and display-48 added, named by pixel value — see\ndisplay-64's note. With the eight \"SET FONT TO TANKER\" placeholder nodes\nexcluded, ALL 68 remaining runs at 56 across all six frames are explicit\nleading-none with zero tracking, as are all of 48, 36 and 32. #248's comment\nreports 56 carrying two ratios and two trackings; that was one un-converted Anton\nnode (home 8216:1762) and three of its runs. This does NOT reopen the proposal to\nmove --cg-display-line and --cg-display-tracking: 26 (77 runs) genuinely carries\n1.0, 1.1 and Auto, so no single library default is right for it, and\n--cg-display-line-tight already covers the cases that want 1. Both shipped values\nstay exactly as they are.",
|
|
930
930
|
"display-3xl": {
|
|
931
931
|
"$value": "120px",
|
|
932
932
|
"$type": "dimension",
|
|
@@ -947,6 +947,16 @@
|
|
|
947
947
|
}
|
|
948
948
|
}
|
|
949
949
|
},
|
|
950
|
+
"display-64": {
|
|
951
|
+
"$value": "64px",
|
|
952
|
+
"$type": "dimension",
|
|
953
|
+
"$description": "SOURCE: home 8204:3110 (\"WHERE DOES IT LIVE?\"), thegrid 8364:4363 (\"Say what it\nneeds\"). Two nodes, two frames, Tanker, no tracking. The widest hole in the ramp:\n36px separate --cg-display-xl 56 from --cg-display-2xl 92, and both consumers\nwere clamping their own value into it.\n\nNAMED BY PIXEL VALUE, 2026-09-19 (#248). Every size added in this round falls\nSTRICTLY BETWEEN two shipped rungs, which is the second consecutive census to\nhit that wall — the tanker-title-ramp note records the first. A t-shirt suffix\nencodes ORDER, and order is what an insertion breaks; renaming a shipped rung is\nbreaking for two published consumers, and a third Tanker ramp would carry the\nsame face, leading and roles as the two that exist and therefore no information.\nSo the ramp prefix still means (face, leading, role) and the suffix becomes the\nsize. A px-named rung cannot be made wrong by a later insertion.\n\nSIZE ONLY, AND DELIBERATELY.\n\nA rung gets a --text-* utility only where the frames settled on a leading. Where\nthey did not, it ships as a custom property alone: theme.css's own rule is that\n\"a companion that invents a value is worse than an absent one\", and\ntokens.test.mjs requires every --text-* to carry a --line-height, so a utility\nhere could only exist by inventing one.\n\nThe two nodes do not agree on a leading and only one of them expresses an\nopinion: thegrid sets 70px (ratio 1.094) and home leaves lineHeightUnit at\nINTRINSIC_%, i.e. Figma's Auto, which is Tanker's own 1.35 default and not a\ndesign decision at all. A leading shipped here would be wrong for one of its two\nusers. The same reasoning is why 96px (thegrid 8364:3957, lh 56 — a ratio of\n0.583, 96px type in a 56px line box) is recorded and still has no rung.",
|
|
954
|
+
"$extensions": {
|
|
955
|
+
"io.cloudgrid": {
|
|
956
|
+
"css": "--cg-display-64"
|
|
957
|
+
}
|
|
958
|
+
}
|
|
959
|
+
},
|
|
950
960
|
"display-xl": {
|
|
951
961
|
"$value": "56px",
|
|
952
962
|
"$type": "dimension",
|
|
@@ -956,6 +966,16 @@
|
|
|
956
966
|
}
|
|
957
967
|
}
|
|
958
968
|
},
|
|
969
|
+
"display-48": {
|
|
970
|
+
"$value": "48px",
|
|
971
|
+
"$type": "dimension",
|
|
972
|
+
"$description": "SOURCE: home 8216:1868, the \"Copy this command INTO your aI tool to Plug in\"\nstatement. Tanker, explicit leading-none (lineHeightUnit FONT_SIZE_% at 100), no\ntracking.\n\nONE NODE ON ONE FRAME, stated plainly because the count in #248 reads as four:\nthe node carries four per-character colour runs and a run census counts each of\nthem. One node is not disqualifying here — --cg-display-3xl 120 is also a single\nnode on a single frame and 0.28.0 shipped it — but the evidence is one headline,\nnot four.\n\nNamed by pixel value; --cg-display-64's note has the reasoning (#248).\n\nIt carries display-line-tight and title-tracking rather than --cg-display-line\nand --cg-display-tracking, the same as --cg-display-2xl and --cg-display-3xl:\nthe node is explicitly 1.0 / 0, and the two legacy values were tuned for a\ncondensed face this package no longer ships (#240).",
|
|
973
|
+
"$extensions": {
|
|
974
|
+
"io.cloudgrid": {
|
|
975
|
+
"css": "--cg-display-48"
|
|
976
|
+
}
|
|
977
|
+
}
|
|
978
|
+
},
|
|
959
979
|
"display-lg": {
|
|
960
980
|
"$value": "44px",
|
|
961
981
|
"$type": "dimension",
|
|
@@ -1013,7 +1033,7 @@
|
|
|
1013
1033
|
}
|
|
1014
1034
|
},
|
|
1015
1035
|
"tanker-title-ramp": {
|
|
1016
|
-
"$description": "The display face at CARD scale, 2026-09-18.\n\nFour rungs the canonical frames use constantly and this package could spell\nnone of. They are separated from h1-display-ramp rather than wedged into it\nbecause the two ramps disagree everywhere they overlap, and the disagreement is\nnot resolvable by addition:\n\n frames 120 96 92 64 56 40 38 32 30 26 20\n package 56 44 38 30\n\n56, 38 and 30 coincide. 44 is used by nothing in any of the six frames. Every\nother size the frames ask for falls BETWEEN two shipped rungs — 40 between 44\nand 38, 26 between 30 and heading-lg's 22 — so there is no name left on the\nt-shirt ramp that is both free and in the right place, and renaming a shipped\nrung is a breaking change for two published consumers.\n\nThey are also not headings. --cg-heading-* is the Manrope ramp at 1.2 leading;\nthis is the display FACE at leading-none, and --cg-title-sm and\n--cg-heading-md are both 20px precisely because a face and a leading are what\nseparate them, not a size.\n\nSIZES, with where they were read:\n 40 home 8204:2589, enterprise 7038:1244, pricing 7785:9809, thegrid 8364:4382\n 26 teams 7297:8606, builders 6916:8648, enterprise 7038:1192,\n pricing 7788:10264, thegrid 8364:3882\n 20 teams 7172:7760, builders 6919:8783, thegrid petal labels\n\npricing 7785:10059 draws one 32px Tanker number and thegrid draws 15px Tanker\neyebrows. Single-frame, so recorded and not given a rung.",
|
|
1036
|
+
"$description": "The display face at CARD scale, 2026-09-18.\n\nFour rungs the canonical frames use constantly and this package could spell\nnone of. They are separated from h1-display-ramp rather than wedged into it\nbecause the two ramps disagree everywhere they overlap, and the disagreement is\nnot resolvable by addition:\n\n frames 120 96 92 64 56 40 38 32 30 26 20\n package 56 44 38 30\n\n56, 38 and 30 coincide. 44 is used by nothing in any of the six frames. Every\nother size the frames ask for falls BETWEEN two shipped rungs — 40 between 44\nand 38, 26 between 30 and heading-lg's 22 — so there is no name left on the\nt-shirt ramp that is both free and in the right place, and renaming a shipped\nrung is a breaking change for two published consumers.\n\nThey are also not headings. --cg-heading-* is the Manrope ramp at 1.2 leading;\nthis is the display FACE at leading-none, and --cg-title-sm and\n--cg-heading-md are both 20px precisely because a face and a leading are what\nseparate them, not a size.\n\nSIZES, with where they were read:\n 40 home 8204:2589, enterprise 7038:1244, pricing 7785:9809, thegrid 8364:4382\n 26 teams 7297:8606, builders 6916:8648, enterprise 7038:1192,\n pricing 7788:10264, thegrid 8364:3882\n 20 teams 7172:7760, builders 6919:8783, thegrid petal labels\n\npricing 7785:10059 draws one 32px Tanker number and thegrid draws 15px Tanker\neyebrows. Single-frame, so recorded and not given a rung.\n\n---\n\n2026-09-19 (#248). Three more rungs — title-36, title-32, title-24 — and the\nt-shirt suffix stops here. See --cg-display-64's note for why they are named by\npixel value and the group note above for why this ramp is separate from\nh1-display-ramp in the first place.\n\nRECORDED AND DELIBERATELY NOT GIVEN A RUNG:\n\n 28px. #248 proposes it on two home nodes. Both are placeholders the designer\n has not converted: 8204:3066 \"lead - SET FONT TO TANKER\" (lineHeight 92.6%,\n letterSpacing 0.24) and 8216:1784 \"txt:RIGHT HERE - SET FONT TO TANKER\"\n (106%, 0.42). They keep the previous face's metrics — a third node in the same\n set, 8216:1762, is still literally set in Anton — so there is no settled 28px\n anything in the six frames. Six home nodes and two thegrid nodes carry that\n \"SET FONT TO TANKER\" marker; every Tanker node in the frames that emits a\n letter-spacing is one of them.\n\n 32px on Inter (builders 7172:8458, the \"$ grid plug\" pill). Off-system in the\n design itself; #243 recorded it.\n\nON AUTO LEADING. Figma's lineHeightUnit distinguishes a decision from an\nabsence: FONT_SIZE_% and PIXELS mean the designer set a leading, INTRINSIC_%\nmeans Auto and the number in the file is the FACE's default, which for Tanker is\n1.35. Every 1.35 in a Tanker census is INTRINSIC_%. A rung built on one would\nencode Tanker's metrics as a brand decision.",
|
|
1017
1037
|
"title-lg": {
|
|
1018
1038
|
"$value": "40px",
|
|
1019
1039
|
"$type": "dimension",
|
|
@@ -1024,6 +1044,26 @@
|
|
|
1024
1044
|
}
|
|
1025
1045
|
}
|
|
1026
1046
|
},
|
|
1047
|
+
"title-36": {
|
|
1048
|
+
"$value": "36px",
|
|
1049
|
+
"$type": "dimension",
|
|
1050
|
+
"$description": "SOURCE: enterprise 7039:5124, 7039:5119, 7039:5129 — the three audience column\nheadings (\"Platform and security teams\", \"Innovation Leaders\", \"Business\nfunctions\"). Three nodes, one frame, all explicit leading-none, no tracking.\n\nOne frame, and 2px from --cg-display-md 38. It is a rung rather than an\napproximation of 38 because it is the card/column role, not the section-heading\nrole, and because rounding a measured 36 onto 38 is the kind of \"close enough\"\nthat #243 had to unpick when ui#239's table called this ramp's 26 a \"24px card\ntitle\".\n\nNamed by pixel value; --cg-display-64's note has the reasoning (#248).",
|
|
1051
|
+
"$extensions": {
|
|
1052
|
+
"io.cloudgrid": {
|
|
1053
|
+
"css": "--cg-title-36"
|
|
1054
|
+
}
|
|
1055
|
+
}
|
|
1056
|
+
},
|
|
1057
|
+
"title-32": {
|
|
1058
|
+
"$value": "32px",
|
|
1059
|
+
"$type": "dimension",
|
|
1060
|
+
"$description": "SOURCE: home 8204:2590 (\"Learn how the grid can help you\"), pricing 7785:10059 /\n10068 / 10073 / 10076 / 10081 / 10084 (the six plan prices). Seven nodes, two\nframes, all explicit leading-none, no tracking.\n\nTHE DISPLAY FACE HALF OF 32. The frames also draw 32 on the UI face, ten times,\nand that is --cg-stat-size on the Manrope ramp, not this. Two rungs at one size\nis the ramp rule working as intended, exactly as --cg-title-sm and\n--cg-heading-md are both 20px: a rung is a face, a leading and a role, not a\nnumber.\n\n#243 recorded pricing's 32 as \"one 32px Tanker number, single-frame, so recorded\nand not given a rung\". The rebuilt extract finds seven nodes on two frames.\n\nNamed by pixel value; --cg-display-64's note has the reasoning (#248).",
|
|
1061
|
+
"$extensions": {
|
|
1062
|
+
"io.cloudgrid": {
|
|
1063
|
+
"css": "--cg-title-32"
|
|
1064
|
+
}
|
|
1065
|
+
}
|
|
1066
|
+
},
|
|
1027
1067
|
"title-md": {
|
|
1028
1068
|
"$value": "26px",
|
|
1029
1069
|
"$type": "dimension",
|
|
@@ -1034,6 +1074,16 @@
|
|
|
1034
1074
|
}
|
|
1035
1075
|
}
|
|
1036
1076
|
},
|
|
1077
|
+
"title-24": {
|
|
1078
|
+
"$value": "24px",
|
|
1079
|
+
"$type": "dimension",
|
|
1080
|
+
"$description": "SOURCE: home 8204:2813, 8204:2753 / 2758 / 2763; enterprise 7039:5084, 7039:5088,\n7039:5093, 7039:5097, 7395:666. Twelve nodes, two frames. Nine set an explicit\nleading-none; two leave lineHeightUnit at INTRINSIC_% (Figma's Auto, no\ndecision); one, home 8216:1908, sets 30px. No node carries tracking.\n\nTWO PIXELS FROM --cg-title-md 26, AND BOTH ARE REAL. 26 is 77 runs on six frames\nand 24 is 12 on two; they coexist in the same design and in some cases in the\nsame section. Note that #239's type table called the 26 rung \"24px card title\"\nfrom a consumer's approximation — this rung is the actual 24, measured, and does\nnot retroactively make that table right.\n\nNamed by pixel value; --cg-display-64's note has the reasoning (#248).",
|
|
1081
|
+
"$extensions": {
|
|
1082
|
+
"io.cloudgrid": {
|
|
1083
|
+
"css": "--cg-title-24"
|
|
1084
|
+
}
|
|
1085
|
+
}
|
|
1086
|
+
},
|
|
1037
1087
|
"title-sm": {
|
|
1038
1088
|
"$value": "20px",
|
|
1039
1089
|
"$type": "dimension",
|
|
@@ -1124,6 +1174,16 @@
|
|
|
1124
1174
|
}
|
|
1125
1175
|
}
|
|
1126
1176
|
},
|
|
1177
|
+
"body-18": {
|
|
1178
|
+
"$value": "18px",
|
|
1179
|
+
"$type": "dimension",
|
|
1180
|
+
"$description": "SOURCE: pricing 7785:9832 / 9858 / 9872, the three plan names — Space Grotesk\nBold 18 at line-height 1.46, which is --cg-body-line exactly. Also thegrid\n8364:4352 / 4355 / 4358 and 8364:4385, Manrope 18 at 1.5.\n\nA BODY RUNG, NOT A HEADING ONE. #248 asks which ramp 18 belongs on, since it\nsits between --cg-heading-sm 17 and --cg-heading-md 20. Every node at 18 that\nexpresses a leading at all reads 1.46 or 1.5; nothing is near\n--cg-heading-line's 1.2. home 8204:3090 and 8204:3105 draw Tanker at 18 and both\nare INTRINSIC_% (Auto), so they express no opinion and do not make this a\ndisplay rung either.\n\n#243 recorded pricing's 18 as \"one 18px bold plan name. Single node, one frame,\n1px off --cg-body-lg\". It is three nodes, and the 1px is the point: a consumer\notherwise rounds it onto --cg-body-lg 19 and the plan-name row drifts by a pixel\nagainst the Figma it is being checked against.\n\nNamed by pixel value; --cg-display-64's note has the reasoning (#248).",
|
|
1181
|
+
"$extensions": {
|
|
1182
|
+
"io.cloudgrid": {
|
|
1183
|
+
"css": "--cg-body-18"
|
|
1184
|
+
}
|
|
1185
|
+
}
|
|
1186
|
+
},
|
|
1127
1187
|
"body-md": {
|
|
1128
1188
|
"$value": "16px",
|
|
1129
1189
|
"$type": "dimension",
|
|
@@ -1144,6 +1204,16 @@
|
|
|
1144
1204
|
}
|
|
1145
1205
|
}
|
|
1146
1206
|
},
|
|
1207
|
+
"body-14": {
|
|
1208
|
+
"$value": "14px",
|
|
1209
|
+
"$type": "dimension",
|
|
1210
|
+
"$description": "SOURCE: home 8216:1768, 8216:1769, 8216:1771 — the three lines of the prompt-and-\nreply mock. Manrope Regular 14. Three runs, one frame.\n\nREAD THIS BEFORE TREATING 14 AS A GAP. #248 counts nineteen 14px runs on four\nframes and calls it one of its two strongest cases. SIXTEEN OF THE NINETEEN ARE\nTHE EYEBROW — Manrope 600, leading 1.2, tracking 1.4px, uppercase — which 0.28.0\nalready ships whole as --cg-eyebrow-size / -line / -tracking / -weight, and\nthree of the nodes the issue cites (teams 7172:8463, builders 6916:8053,\nenterprise 7038:1184) are the very nodes in that token's own docblock. 14 was\nalready closed; the four frames are the eyebrow's four frames.\n\nSo this rung exists for the residue, and the residue is thin. It ships anyway\nbecause without it the only 14 in the package is --cg-eyebrow-size, and a\nconsumer who wants plain 14px text will reach for it and sooner or later reach\nfor text-eyebrow with it, inheriting a weight and a tracking nobody asked for.\n--cg-mono-size is also 14 and is the mono face.\n\nSIZE ONLY.\n\nA rung gets a --text-* utility only where the frames settled on a leading. Where\nthey did not, it ships as a custom property alone: theme.css's own rule is that\n\"a companion that invents a value is worse than an absent one\", and\ntokens.test.mjs requires every --text-* to carry a --line-height, so a utility\nhere could only exist by inventing one. The three runs read 1.295 and 1.55; there is nothing\nto ship.",
|
|
1211
|
+
"$extensions": {
|
|
1212
|
+
"io.cloudgrid": {
|
|
1213
|
+
"css": "--cg-body-14"
|
|
1214
|
+
}
|
|
1215
|
+
}
|
|
1216
|
+
},
|
|
1147
1217
|
"caption": {
|
|
1148
1218
|
"$value": "13px",
|
|
1149
1219
|
"$type": "dimension",
|
|
@@ -1244,6 +1314,35 @@
|
|
|
1244
1314
|
"css": "--cg-eyebrow-weight"
|
|
1245
1315
|
}
|
|
1246
1316
|
}
|
|
1317
|
+
},
|
|
1318
|
+
"stat-size": {
|
|
1319
|
+
"$value": "32px",
|
|
1320
|
+
"$type": "dimension",
|
|
1321
|
+
"$description": "The big figure in a stat block: the UI face at leading-none.\n\nSOURCE: home 8204:2769 / 2774 / 2779 / 2784 / 2789 and enterprise 7038:4564 /\n4569 / 4574 / 4579 / 4584 — \"2\", \"184\", \"4\", \"8\", \"$0\". Ten nodes, two frames,\nManrope Medium 32, every one of them explicit leading-none with no tracking.\n\nTHE UI-FACE HALF OF 32; --cg-title-32 is the display-face half. This is a role\nthe Manrope ramp could not spell at all: --cg-heading-* is 1.2 and --cg-body-* is\n1.46, and nothing on this face was at 1.\n\nIt is a role set rather than a bare size, on the --cg-eyebrow-* pattern, for the\nreason that block gives: the figure carries a leading and a weight as well as a\nsize, and spelling two of the three inline is how a component drifts.\n\nKNOWN DIVERGENCE, not fixed here: StatTile renders its value as\n`font-display text-display-sm` — Tanker 30 at --cg-display-line. The frames say\nManrope Medium 32 at leading-none. Repointing it changes what every StatTile\nrenders today, so it is a separate change with its own changeset.\n\nThe same five figures appear again at 18.149px inside scaled product mocks on\nhome, thegrid and enterprise. That is the per-mock scale factor #248 documents,\nnot a second rung.",
|
|
1322
|
+
"$extensions": {
|
|
1323
|
+
"io.cloudgrid": {
|
|
1324
|
+
"css": "--cg-stat-size"
|
|
1325
|
+
}
|
|
1326
|
+
}
|
|
1327
|
+
},
|
|
1328
|
+
"stat-line": {
|
|
1329
|
+
"$value": "1",
|
|
1330
|
+
"$type": "number",
|
|
1331
|
+
"$description": "leading-none, from all ten nodes. Spelled as a number rather than aliased onto\n--cg-display-line-tight: that alias exists so a retune of the DISPLAY leading\nreaches the title ramp too, and the stat figure is on the UI face and must not\nmove with it.",
|
|
1332
|
+
"$extensions": {
|
|
1333
|
+
"io.cloudgrid": {
|
|
1334
|
+
"css": "--cg-stat-line"
|
|
1335
|
+
}
|
|
1336
|
+
}
|
|
1337
|
+
},
|
|
1338
|
+
"stat-weight": {
|
|
1339
|
+
"$value": "{weights.weight-medium}",
|
|
1340
|
+
"$description": "500, from all ten nodes. Manrope Medium, not the eyebrow's 600 and not\n--cg-label-weight's 500 by coincidence — aliased onto the weight rung so it\ntracks the brand's Medium.",
|
|
1341
|
+
"$extensions": {
|
|
1342
|
+
"io.cloudgrid": {
|
|
1343
|
+
"css": "--cg-stat-weight"
|
|
1344
|
+
}
|
|
1345
|
+
}
|
|
1247
1346
|
}
|
|
1248
1347
|
},
|
|
1249
1348
|
"spacing": {
|
package/dist/tokens.css
CHANGED
|
@@ -889,7 +889,18 @@
|
|
|
889
889
|
H1 display ramp: uppercase, condensed, Primary or white
|
|
890
890
|
|
|
891
891
|
Stepped down one notch 2026-08-06 (operator: main headings read too
|
|
892
|
-
dominant). The SOURCE values were xl 64 / lg 48 / md 42 / sm 32.
|
|
892
|
+
dominant). The SOURCE values were xl 64 / lg 48 / md 42 / sm 32.
|
|
893
|
+
|
|
894
|
+
2026-09-19 (#248): display-64 and display-48 added, named by pixel value — see
|
|
895
|
+
display-64's note. With the eight "SET FONT TO TANKER" placeholder nodes
|
|
896
|
+
excluded, ALL 68 remaining runs at 56 across all six frames are explicit
|
|
897
|
+
leading-none with zero tracking, as are all of 48, 36 and 32. #248's comment
|
|
898
|
+
reports 56 carrying two ratios and two trackings; that was one un-converted Anton
|
|
899
|
+
node (home 8216:1762) and three of its runs. This does NOT reopen the proposal to
|
|
900
|
+
move --cg-display-line and --cg-display-tracking: 26 (77 runs) genuinely carries
|
|
901
|
+
1.0, 1.1 and Auto, so no single library default is right for it, and
|
|
902
|
+
--cg-display-line-tight already covers the cases that want 1. Both shipped values
|
|
903
|
+
stay exactly as they are. */
|
|
893
904
|
/*
|
|
894
905
|
SOURCE: home 8204:2556, the hero headline, Tanker at leading-none.
|
|
895
906
|
|
|
@@ -909,7 +920,55 @@
|
|
|
909
920
|
not rungs. A value invented to complete a grid is the thing this file keeps
|
|
910
921
|
refusing to add. */
|
|
911
922
|
--cg-display-2xl: 92px;
|
|
923
|
+
/*
|
|
924
|
+
SOURCE: home 8204:3110 ("WHERE DOES IT LIVE?"), thegrid 8364:4363 ("Say what it
|
|
925
|
+
needs"). Two nodes, two frames, Tanker, no tracking. The widest hole in the ramp:
|
|
926
|
+
36px separate --cg-display-xl 56 from --cg-display-2xl 92, and both consumers
|
|
927
|
+
were clamping their own value into it.
|
|
928
|
+
|
|
929
|
+
NAMED BY PIXEL VALUE, 2026-09-19 (#248). Every size added in this round falls
|
|
930
|
+
STRICTLY BETWEEN two shipped rungs, which is the second consecutive census to
|
|
931
|
+
hit that wall — the tanker-title-ramp note records the first. A t-shirt suffix
|
|
932
|
+
encodes ORDER, and order is what an insertion breaks; renaming a shipped rung is
|
|
933
|
+
breaking for two published consumers, and a third Tanker ramp would carry the
|
|
934
|
+
same face, leading and roles as the two that exist and therefore no information.
|
|
935
|
+
So the ramp prefix still means (face, leading, role) and the suffix becomes the
|
|
936
|
+
size. A px-named rung cannot be made wrong by a later insertion.
|
|
937
|
+
|
|
938
|
+
SIZE ONLY, AND DELIBERATELY.
|
|
939
|
+
|
|
940
|
+
A rung gets a --text-* utility only where the frames settled on a leading. Where
|
|
941
|
+
they did not, it ships as a custom property alone: theme.css's own rule is that
|
|
942
|
+
"a companion that invents a value is worse than an absent one", and
|
|
943
|
+
tokens.test.mjs requires every --text-* to carry a --line-height, so a utility
|
|
944
|
+
here could only exist by inventing one.
|
|
945
|
+
|
|
946
|
+
The two nodes do not agree on a leading and only one of them expresses an
|
|
947
|
+
opinion: thegrid sets 70px (ratio 1.094) and home leaves lineHeightUnit at
|
|
948
|
+
INTRINSIC_%, i.e. Figma's Auto, which is Tanker's own 1.35 default and not a
|
|
949
|
+
design decision at all. A leading shipped here would be wrong for one of its two
|
|
950
|
+
users. The same reasoning is why 96px (thegrid 8364:3957, lh 56 — a ratio of
|
|
951
|
+
0.583, 96px type in a 56px line box) is recorded and still has no rung. */
|
|
952
|
+
--cg-display-64: 64px;
|
|
912
953
|
--cg-display-xl: 56px;
|
|
954
|
+
/*
|
|
955
|
+
SOURCE: home 8216:1868, the "Copy this command INTO your aI tool to Plug in"
|
|
956
|
+
statement. Tanker, explicit leading-none (lineHeightUnit FONT_SIZE_% at 100), no
|
|
957
|
+
tracking.
|
|
958
|
+
|
|
959
|
+
ONE NODE ON ONE FRAME, stated plainly because the count in #248 reads as four:
|
|
960
|
+
the node carries four per-character colour runs and a run census counts each of
|
|
961
|
+
them. One node is not disqualifying here — --cg-display-3xl 120 is also a single
|
|
962
|
+
node on a single frame and 0.28.0 shipped it — but the evidence is one headline,
|
|
963
|
+
not four.
|
|
964
|
+
|
|
965
|
+
Named by pixel value; --cg-display-64's note has the reasoning (#248).
|
|
966
|
+
|
|
967
|
+
It carries display-line-tight and title-tracking rather than --cg-display-line
|
|
968
|
+
and --cg-display-tracking, the same as --cg-display-2xl and --cg-display-3xl:
|
|
969
|
+
the node is explicitly 1.0 / 0, and the two legacy values were tuned for a
|
|
970
|
+
condensed face this package no longer ships (#240). */
|
|
971
|
+
--cg-display-48: 48px;
|
|
913
972
|
--cg-display-lg: 44px;
|
|
914
973
|
/* SOURCE: onboarding H1 (was 42px) */
|
|
915
974
|
--cg-display-md: 38px;
|
|
@@ -957,15 +1016,85 @@
|
|
|
957
1016
|
20 teams 7172:7760, builders 6919:8783, thegrid petal labels
|
|
958
1017
|
|
|
959
1018
|
pricing 7785:10059 draws one 32px Tanker number and thegrid draws 15px Tanker
|
|
960
|
-
eyebrows. Single-frame, so recorded and not given a rung.
|
|
1019
|
+
eyebrows. Single-frame, so recorded and not given a rung.
|
|
1020
|
+
|
|
1021
|
+
---
|
|
1022
|
+
|
|
1023
|
+
2026-09-19 (#248). Three more rungs — title-36, title-32, title-24 — and the
|
|
1024
|
+
t-shirt suffix stops here. See --cg-display-64's note for why they are named by
|
|
1025
|
+
pixel value and the group note above for why this ramp is separate from
|
|
1026
|
+
h1-display-ramp in the first place.
|
|
1027
|
+
|
|
1028
|
+
RECORDED AND DELIBERATELY NOT GIVEN A RUNG:
|
|
1029
|
+
|
|
1030
|
+
28px. #248 proposes it on two home nodes. Both are placeholders the designer
|
|
1031
|
+
has not converted: 8204:3066 "lead - SET FONT TO TANKER" (lineHeight 92.6%,
|
|
1032
|
+
letterSpacing 0.24) and 8216:1784 "txt:RIGHT HERE - SET FONT TO TANKER"
|
|
1033
|
+
(106%, 0.42). They keep the previous face's metrics — a third node in the same
|
|
1034
|
+
set, 8216:1762, is still literally set in Anton — so there is no settled 28px
|
|
1035
|
+
anything in the six frames. Six home nodes and two thegrid nodes carry that
|
|
1036
|
+
"SET FONT TO TANKER" marker; every Tanker node in the frames that emits a
|
|
1037
|
+
letter-spacing is one of them.
|
|
1038
|
+
|
|
1039
|
+
32px on Inter (builders 7172:8458, the "$ grid plug" pill). Off-system in the
|
|
1040
|
+
design itself; #243 recorded it.
|
|
1041
|
+
|
|
1042
|
+
ON AUTO LEADING. Figma's lineHeightUnit distinguishes a decision from an
|
|
1043
|
+
absence: FONT_SIZE_% and PIXELS mean the designer set a leading, INTRINSIC_%
|
|
1044
|
+
means Auto and the number in the file is the FACE's default, which for Tanker is
|
|
1045
|
+
1.35. Every 1.35 in a Tanker census is INTRINSIC_%. A rung built on one would
|
|
1046
|
+
encode Tanker's metrics as a brand decision. */
|
|
961
1047
|
/*
|
|
962
1048
|
Four frames. The governance card title, the plan price, the sub-heading under a section statement. */
|
|
963
1049
|
--cg-title-lg: 40px;
|
|
1050
|
+
/*
|
|
1051
|
+
SOURCE: enterprise 7039:5124, 7039:5119, 7039:5129 — the three audience column
|
|
1052
|
+
headings ("Platform and security teams", "Innovation Leaders", "Business
|
|
1053
|
+
functions"). Three nodes, one frame, all explicit leading-none, no tracking.
|
|
1054
|
+
|
|
1055
|
+
One frame, and 2px from --cg-display-md 38. It is a rung rather than an
|
|
1056
|
+
approximation of 38 because it is the card/column role, not the section-heading
|
|
1057
|
+
role, and because rounding a measured 36 onto 38 is the kind of "close enough"
|
|
1058
|
+
that #243 had to unpick when ui#239's table called this ramp's 26 a "24px card
|
|
1059
|
+
title".
|
|
1060
|
+
|
|
1061
|
+
Named by pixel value; --cg-display-64's note has the reasoning (#248). */
|
|
1062
|
+
--cg-title-36: 36px;
|
|
1063
|
+
/*
|
|
1064
|
+
SOURCE: home 8204:2590 ("Learn how the grid can help you"), pricing 7785:10059 /
|
|
1065
|
+
10068 / 10073 / 10076 / 10081 / 10084 (the six plan prices). Seven nodes, two
|
|
1066
|
+
frames, all explicit leading-none, no tracking.
|
|
1067
|
+
|
|
1068
|
+
THE DISPLAY FACE HALF OF 32. The frames also draw 32 on the UI face, ten times,
|
|
1069
|
+
and that is --cg-stat-size on the Manrope ramp, not this. Two rungs at one size
|
|
1070
|
+
is the ramp rule working as intended, exactly as --cg-title-sm and
|
|
1071
|
+
--cg-heading-md are both 20px: a rung is a face, a leading and a role, not a
|
|
1072
|
+
number.
|
|
1073
|
+
|
|
1074
|
+
#243 recorded pricing's 32 as "one 32px Tanker number, single-frame, so recorded
|
|
1075
|
+
and not given a rung". The rebuilt extract finds seven nodes on two frames.
|
|
1076
|
+
|
|
1077
|
+
Named by pixel value; --cg-display-64's note has the reasoning (#248). */
|
|
1078
|
+
--cg-title-32: 32px;
|
|
964
1079
|
/*
|
|
965
1080
|
Five frames. The card title and the FAQ question — the most common display size in the design after the section heading.
|
|
966
1081
|
|
|
967
1082
|
ui#239's type table calls this rung "24px card title". Measured on five frames it is 26, not 24, and nothing in any frame is 24. The table was written from a consumer's approximation rather than from the node. */
|
|
968
1083
|
--cg-title-md: 26px;
|
|
1084
|
+
/*
|
|
1085
|
+
SOURCE: home 8204:2813, 8204:2753 / 2758 / 2763; enterprise 7039:5084, 7039:5088,
|
|
1086
|
+
7039:5093, 7039:5097, 7395:666. Twelve nodes, two frames. Nine set an explicit
|
|
1087
|
+
leading-none; two leave lineHeightUnit at INTRINSIC_% (Figma's Auto, no
|
|
1088
|
+
decision); one, home 8216:1908, sets 30px. No node carries tracking.
|
|
1089
|
+
|
|
1090
|
+
TWO PIXELS FROM --cg-title-md 26, AND BOTH ARE REAL. 26 is 77 runs on six frames
|
|
1091
|
+
and 24 is 12 on two; they coexist in the same design and in some cases in the
|
|
1092
|
+
same section. Note that #239's type table called the 26 rung "24px card title"
|
|
1093
|
+
from a consumer's approximation — this rung is the actual 24, measured, and does
|
|
1094
|
+
not retroactively make that table right.
|
|
1095
|
+
|
|
1096
|
+
Named by pixel value; --cg-display-64's note has the reasoning (#248). */
|
|
1097
|
+
--cg-title-24: 24px;
|
|
969
1098
|
/*
|
|
970
1099
|
Three frames. The label inside a step circle or a diagram petal. Same size as --cg-heading-md and a different face and leading; see the group note. */
|
|
971
1100
|
--cg-title-sm: 20px;
|
|
@@ -1014,10 +1143,56 @@
|
|
|
1014
1143
|
--cg-body-xl: 20px;
|
|
1015
1144
|
/* SOURCE: H1 subline */
|
|
1016
1145
|
--cg-body-lg: 19px;
|
|
1146
|
+
/*
|
|
1147
|
+
SOURCE: pricing 7785:9832 / 9858 / 9872, the three plan names — Space Grotesk
|
|
1148
|
+
Bold 18 at line-height 1.46, which is --cg-body-line exactly. Also thegrid
|
|
1149
|
+
8364:4352 / 4355 / 4358 and 8364:4385, Manrope 18 at 1.5.
|
|
1150
|
+
|
|
1151
|
+
A BODY RUNG, NOT A HEADING ONE. #248 asks which ramp 18 belongs on, since it
|
|
1152
|
+
sits between --cg-heading-sm 17 and --cg-heading-md 20. Every node at 18 that
|
|
1153
|
+
expresses a leading at all reads 1.46 or 1.5; nothing is near
|
|
1154
|
+
--cg-heading-line's 1.2. home 8204:3090 and 8204:3105 draw Tanker at 18 and both
|
|
1155
|
+
are INTRINSIC_% (Auto), so they express no opinion and do not make this a
|
|
1156
|
+
display rung either.
|
|
1157
|
+
|
|
1158
|
+
#243 recorded pricing's 18 as "one 18px bold plan name. Single node, one frame,
|
|
1159
|
+
1px off --cg-body-lg". It is three nodes, and the 1px is the point: a consumer
|
|
1160
|
+
otherwise rounds it onto --cg-body-lg 19 and the plan-name row drifts by a pixel
|
|
1161
|
+
against the Figma it is being checked against.
|
|
1162
|
+
|
|
1163
|
+
Named by pixel value; --cg-display-64's note has the reasoning (#248). */
|
|
1164
|
+
--cg-body-18: 18px;
|
|
1017
1165
|
/* SOURCE: default UI text */
|
|
1018
1166
|
--cg-body-md: 16px;
|
|
1019
1167
|
/* SOURCE: card body, legal */
|
|
1020
1168
|
--cg-body-sm: 15px;
|
|
1169
|
+
/*
|
|
1170
|
+
SOURCE: home 8216:1768, 8216:1769, 8216:1771 — the three lines of the prompt-and-
|
|
1171
|
+
reply mock. Manrope Regular 14. Three runs, one frame.
|
|
1172
|
+
|
|
1173
|
+
READ THIS BEFORE TREATING 14 AS A GAP. #248 counts nineteen 14px runs on four
|
|
1174
|
+
frames and calls it one of its two strongest cases. SIXTEEN OF THE NINETEEN ARE
|
|
1175
|
+
THE EYEBROW — Manrope 600, leading 1.2, tracking 1.4px, uppercase — which 0.28.0
|
|
1176
|
+
already ships whole as --cg-eyebrow-size / -line / -tracking / -weight, and
|
|
1177
|
+
three of the nodes the issue cites (teams 7172:8463, builders 6916:8053,
|
|
1178
|
+
enterprise 7038:1184) are the very nodes in that token's own docblock. 14 was
|
|
1179
|
+
already closed; the four frames are the eyebrow's four frames.
|
|
1180
|
+
|
|
1181
|
+
So this rung exists for the residue, and the residue is thin. It ships anyway
|
|
1182
|
+
because without it the only 14 in the package is --cg-eyebrow-size, and a
|
|
1183
|
+
consumer who wants plain 14px text will reach for it and sooner or later reach
|
|
1184
|
+
for text-eyebrow with it, inheriting a weight and a tracking nobody asked for.
|
|
1185
|
+
--cg-mono-size is also 14 and is the mono face.
|
|
1186
|
+
|
|
1187
|
+
SIZE ONLY.
|
|
1188
|
+
|
|
1189
|
+
A rung gets a --text-* utility only where the frames settled on a leading. Where
|
|
1190
|
+
they did not, it ships as a custom property alone: theme.css's own rule is that
|
|
1191
|
+
"a companion that invents a value is worse than an absent one", and
|
|
1192
|
+
tokens.test.mjs requires every --text-* to carry a --line-height, so a utility
|
|
1193
|
+
here could only exist by inventing one. The three runs read 1.295 and 1.55; there is nothing
|
|
1194
|
+
to ship. */
|
|
1195
|
+
--cg-body-14: 14px;
|
|
1021
1196
|
/* SOURCE: footer, helper */
|
|
1022
1197
|
--cg-caption: 13px;
|
|
1023
1198
|
/*
|
|
@@ -1069,6 +1244,41 @@
|
|
|
1069
1244
|
Note this is NOT --cg-label-weight, which is 500. The eyebrow and the label are
|
|
1070
1245
|
different rungs; see the group note. */
|
|
1071
1246
|
--cg-eyebrow-weight: var(--cg-weight-bold);
|
|
1247
|
+
/*
|
|
1248
|
+
The big figure in a stat block: the UI face at leading-none.
|
|
1249
|
+
|
|
1250
|
+
SOURCE: home 8204:2769 / 2774 / 2779 / 2784 / 2789 and enterprise 7038:4564 /
|
|
1251
|
+
4569 / 4574 / 4579 / 4584 — "2", "184", "4", "8", "$0". Ten nodes, two frames,
|
|
1252
|
+
Manrope Medium 32, every one of them explicit leading-none with no tracking.
|
|
1253
|
+
|
|
1254
|
+
THE UI-FACE HALF OF 32; --cg-title-32 is the display-face half. This is a role
|
|
1255
|
+
the Manrope ramp could not spell at all: --cg-heading-* is 1.2 and --cg-body-* is
|
|
1256
|
+
1.46, and nothing on this face was at 1.
|
|
1257
|
+
|
|
1258
|
+
It is a role set rather than a bare size, on the --cg-eyebrow-* pattern, for the
|
|
1259
|
+
reason that block gives: the figure carries a leading and a weight as well as a
|
|
1260
|
+
size, and spelling two of the three inline is how a component drifts.
|
|
1261
|
+
|
|
1262
|
+
KNOWN DIVERGENCE, not fixed here: StatTile renders its value as
|
|
1263
|
+
`font-display text-display-sm` — Tanker 30 at --cg-display-line. The frames say
|
|
1264
|
+
Manrope Medium 32 at leading-none. Repointing it changes what every StatTile
|
|
1265
|
+
renders today, so it is a separate change with its own changeset.
|
|
1266
|
+
|
|
1267
|
+
The same five figures appear again at 18.149px inside scaled product mocks on
|
|
1268
|
+
home, thegrid and enterprise. That is the per-mock scale factor #248 documents,
|
|
1269
|
+
not a second rung. */
|
|
1270
|
+
--cg-stat-size: 32px;
|
|
1271
|
+
/*
|
|
1272
|
+
leading-none, from all ten nodes. Spelled as a number rather than aliased onto
|
|
1273
|
+
--cg-display-line-tight: that alias exists so a retune of the DISPLAY leading
|
|
1274
|
+
reaches the title ramp too, and the stat figure is on the UI face and must not
|
|
1275
|
+
move with it. */
|
|
1276
|
+
--cg-stat-line: 1;
|
|
1277
|
+
/*
|
|
1278
|
+
500, from all ten nodes. Manrope Medium, not the eyebrow's 600 and not
|
|
1279
|
+
--cg-label-weight's 500 by coincidence — aliased onto the weight rung so it
|
|
1280
|
+
tracks the brand's Medium. */
|
|
1281
|
+
--cg-stat-weight: var(--cg-weight-medium);
|
|
1072
1282
|
|
|
1073
1283
|
/* ---- spacing ----
|
|
1074
1284
|
spacing: 4px base */
|
package/dist/tokens.json
CHANGED
|
@@ -101,7 +101,9 @@
|
|
|
101
101
|
"--cg-weight-display": "700",
|
|
102
102
|
"--cg-display-3xl": "120px",
|
|
103
103
|
"--cg-display-2xl": "92px",
|
|
104
|
+
"--cg-display-64": "64px",
|
|
104
105
|
"--cg-display-xl": "56px",
|
|
106
|
+
"--cg-display-48": "48px",
|
|
105
107
|
"--cg-display-lg": "44px",
|
|
106
108
|
"--cg-display-md": "38px",
|
|
107
109
|
"--cg-display-sm": "30px",
|
|
@@ -109,7 +111,10 @@
|
|
|
109
111
|
"--cg-display-tracking": "0.012em",
|
|
110
112
|
"--cg-display-line-tight": "1",
|
|
111
113
|
"--cg-title-lg": "40px",
|
|
114
|
+
"--cg-title-36": "36px",
|
|
115
|
+
"--cg-title-32": "32px",
|
|
112
116
|
"--cg-title-md": "26px",
|
|
117
|
+
"--cg-title-24": "24px",
|
|
113
118
|
"--cg-title-sm": "20px",
|
|
114
119
|
"--cg-title-line": "var(--cg-display-line-tight)",
|
|
115
120
|
"--cg-title-tracking": "0em",
|
|
@@ -119,8 +124,10 @@
|
|
|
119
124
|
"--cg-heading-line": "1.2",
|
|
120
125
|
"--cg-body-xl": "20px",
|
|
121
126
|
"--cg-body-lg": "19px",
|
|
127
|
+
"--cg-body-18": "18px",
|
|
122
128
|
"--cg-body-md": "16px",
|
|
123
129
|
"--cg-body-sm": "15px",
|
|
130
|
+
"--cg-body-14": "14px",
|
|
124
131
|
"--cg-caption": "13px",
|
|
125
132
|
"--cg-body-line": "1.46",
|
|
126
133
|
"--cg-body-tracking": "0em",
|
|
@@ -132,6 +139,9 @@
|
|
|
132
139
|
"--cg-eyebrow-line": "1.2",
|
|
133
140
|
"--cg-eyebrow-tracking": "0.1em",
|
|
134
141
|
"--cg-eyebrow-weight": "var(--cg-weight-bold)",
|
|
142
|
+
"--cg-stat-size": "32px",
|
|
143
|
+
"--cg-stat-line": "1",
|
|
144
|
+
"--cg-stat-weight": "var(--cg-weight-medium)",
|
|
135
145
|
"--cg-space-1": "4px",
|
|
136
146
|
"--cg-space-2": "8px",
|
|
137
147
|
"--cg-space-3": "12px",
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@cloudgrid-io/ui",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.29.0",
|
|
4
4
|
"description": "CloudGrid design system: React components, brand design tokens, Tailwind theme, self-hosted fonts.",
|
|
5
5
|
"publishConfig": {
|
|
6
6
|
"registry": "https://registry.npmjs.org/",
|
|
@@ -21,6 +21,7 @@
|
|
|
21
21
|
"default": "./dist/index.js"
|
|
22
22
|
},
|
|
23
23
|
"./tokens.css": "./dist/tokens.css",
|
|
24
|
+
"./console.css": "./dist/console.css",
|
|
24
25
|
"./theme.css": "./dist/theme.css",
|
|
25
26
|
"./shadcn.css": "./dist/shadcn.css",
|
|
26
27
|
"./fonts.css": "./dist/fonts.css",
|