@cloudgrid-io/ui 0.27.1 → 0.28.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/blocks/avatar.d.ts +10 -4
- package/dist/blocks/avatar.d.ts.map +1 -1
- package/dist/blocks/avatar.js +8 -2
- package/dist/blocks/avatar.js.map +1 -1
- package/dist/blocks/icons.d.ts +1 -1
- package/dist/blocks/icons.d.ts.map +1 -1
- package/dist/blocks/icons.js +13 -1
- package/dist/blocks/icons.js.map +1 -1
- package/dist/blocks/side-nav.d.ts +49 -0
- package/dist/blocks/side-nav.d.ts.map +1 -0
- package/dist/blocks/side-nav.js +217 -0
- package/dist/blocks/side-nav.js.map +1 -0
- package/dist/blocks/stat-tile.d.ts +69 -0
- package/dist/blocks/stat-tile.d.ts.map +1 -0
- package/dist/blocks/stat-tile.js +54 -0
- package/dist/blocks/stat-tile.js.map +1 -0
- package/dist/blocks/tool-setup.d.ts +105 -4
- package/dist/blocks/tool-setup.d.ts.map +1 -1
- package/dist/blocks/tool-setup.js +238 -13
- package/dist/blocks/tool-setup.js.map +1 -1
- package/dist/fonts.css +38 -9
- package/dist/index.d.ts +5 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +5 -0
- package/dist/index.js.map +1 -1
- 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 +7 -0
- package/dist/lib/cloudgrid-cn.js.map +1 -1
- package/dist/theme.css +95 -0
- package/dist/tokens/base.json +389 -3
- package/dist/tokens/surface-ink.json +10 -0
- package/dist/tokens/surface-panel.json +10 -0
- package/dist/tokens.css +520 -10
- package/dist/tokens.json +43 -2
- package/dist/ui/button.d.ts +1 -1
- package/dist/ui/button.d.ts.map +1 -1
- package/dist/ui/button.js +28 -0
- package/dist/ui/button.js.map +1 -1
- package/dist/ui/dialog.d.ts +17 -1
- package/dist/ui/dialog.d.ts.map +1 -1
- package/dist/ui/dialog.js +18 -2
- package/dist/ui/dialog.js.map +1 -1
- package/dist/ui/drawer.d.ts +208 -0
- package/dist/ui/drawer.d.ts.map +1 -0
- package/dist/ui/drawer.js +265 -0
- package/dist/ui/drawer.js.map +1 -0
- package/dist/ui/popover.d.ts +83 -0
- package/dist/ui/popover.d.ts.map +1 -0
- package/dist/ui/popover.js +102 -0
- package/dist/ui/popover.js.map +1 -0
- package/dist/ui/radio-group.d.ts +21 -0
- package/dist/ui/radio-group.d.ts.map +1 -0
- package/dist/ui/radio-group.js +101 -0
- package/dist/ui/radio-group.js.map +1 -0
- package/package.json +2 -1
package/dist/tokens.css
CHANGED
|
@@ -443,10 +443,230 @@
|
|
|
443
443
|
value held on white, so the ground moved and the dot kept its contrast. The
|
|
444
444
|
muted text rung comes with it, 3.27:1 -> 3.69:1 on white. */
|
|
445
445
|
--cg-neutral-500: #858585;
|
|
446
|
+
/*
|
|
447
|
+
SOURCE: derived, 2026-09-18 (#232). The missing rung between neutral-500 and
|
|
448
|
+
neutral-700, and the only reason it exists is that --cg-text-muted has no value
|
|
449
|
+
on this ramp that clears the 4.5:1 body-text floor.
|
|
450
|
+
|
|
451
|
+
neutral-500 measures 3.69:1 on the card, 3.28:1 on the page ground and 3.29:1 on
|
|
452
|
+
the lavender wash. All three clear 3:1 for large text and none clears 4.5:1, so
|
|
453
|
+
every caption, every eyebrow and every tile hint in this library is under AA for
|
|
454
|
+
body copy. neutral-700 clears it everywhere (7.00:1 on the card) but it IS
|
|
455
|
+
--cg-text-secondary, so aliasing a "strong muted" onto it would not add a rung,
|
|
456
|
+
it would rename one.
|
|
457
|
+
|
|
458
|
+
Derived, with the sweep, so the next person does not repeat it:
|
|
459
|
+
|
|
460
|
+
#6e6e6e on the page ground : 4.53:1 clears by 0.03 — a margin a later
|
|
461
|
+
ground retune would erase in silence
|
|
462
|
+
#6c6c6c : 4.66:1
|
|
463
|
+
#6a6a6a : 4.80:1 <-- this
|
|
464
|
+
#686868 : 4.95:1
|
|
465
|
+
|
|
466
|
+
#6a6a6a on the card #ffffff : 5.41:1
|
|
467
|
+
on the page #f1f1f6 : 4.80:1
|
|
468
|
+
on raised #f4f6f8 : 4.99:1
|
|
469
|
+
on subtle #f2f1f7 : 4.82:1
|
|
470
|
+
|
|
471
|
+
The extra step past the first passing value is --cg-accent's practice, and for
|
|
472
|
+
its reason: 4.53:1 is a number that a page-ground retune turns into a failure
|
|
473
|
+
with nothing going red.
|
|
474
|
+
|
|
475
|
+
KNOWN, and not fixed here: on the violet-200 wash the frames draw (#d9d4fb) this
|
|
476
|
+
measures 3.80:1, still under the body floor. Nothing on a neutral ramp clears
|
|
477
|
+
4.5:1 on that ground and stays muted; see --cg-violet-200's own note. */
|
|
478
|
+
--cg-neutral-600: #6a6a6a;
|
|
446
479
|
/* SOURCE: legal / secondary text */
|
|
447
480
|
--cg-neutral-700: #595959;
|
|
448
481
|
/* SOURCE: ink */
|
|
449
482
|
--cg-neutral-900: #222222;
|
|
483
|
+
/*
|
|
484
|
+
SOURCE: Figma variable color/neutral/300, read first-hand on the thegrid frame
|
|
485
|
+
(8364:4396, "On the grid & to the world" on the ink band).
|
|
486
|
+
|
|
487
|
+
THE NAME IS NOT AN ACCIDENT. Figma calls this family color/neutral/300 / 500 /
|
|
488
|
+
600. This package's neutral ramp is already occupied at every one of those
|
|
489
|
+
numbers by a PURE grey (#acacac, #858585, #595959) that two published consumers
|
|
490
|
+
ship today, and these three are blue-greys: #828c98 is B152 against R130, which
|
|
491
|
+
is not a grey at all. Taking the Figma numbers would mean either changing three
|
|
492
|
+
shipped values (breaking) or having one ramp hold two hue families under one
|
|
493
|
+
name (silent). So the cool family takes its own root and the greys keep theirs.
|
|
494
|
+
|
|
495
|
+
1.45:1 on the card and 1.29:1 on the page ground: this is a value for text on a
|
|
496
|
+
dark ground, never on a light one. */
|
|
497
|
+
--cg-slate-300: #d2d7de;
|
|
498
|
+
/*
|
|
499
|
+
SOURCE: Figma variable color/neutral/500, also carried under the legacy name
|
|
500
|
+
"N3 new". Read first-hand on four of the six canonical frames — thegrid
|
|
501
|
+
(8364:3966, footer links), teams (7172:7607), pricing (7779:9284), builders
|
|
502
|
+
(6916:8104, the terminal's "$"). It is the design's quiet-text tone and the most
|
|
503
|
+
frequently missing value in this package (ui#239).
|
|
504
|
+
|
|
505
|
+
WHAT IT MEASURES, because the frames spend it on words:
|
|
506
|
+
|
|
507
|
+
on the card #ffffff : 3.41:1
|
|
508
|
+
on the page ground #f1f1f6 : 3.03:1
|
|
509
|
+
on raised #f4f6f8 : 3.15:1
|
|
510
|
+
on the violet wash #d9d4fb : 2.40:1 <-- under even the 3:1 indicator bar
|
|
511
|
+
on ink #222222 : 4.66:1
|
|
512
|
+
on the purple panel #5a47f0 : 1.71:1 invisible
|
|
513
|
+
|
|
514
|
+
So it clears 3:1 for large text on the three light grounds, clears 4.5:1 on ink
|
|
515
|
+
alone, and fails everywhere the frames actually use it for 15px footer links.
|
|
516
|
+
It is shipped because the frames use it and this package is meant to be able to
|
|
517
|
+
draw them; it is deliberately NOT wired to a --cg-text-* semantic, because those
|
|
518
|
+
carry a contrast contract and this value cannot meet it. --cg-slate-600 is the
|
|
519
|
+
companion that can. See ui#232 for the same shape of problem on --cg-text-muted.
|
|
520
|
+
|
|
521
|
+
DECLARED AT :root ONLY. A brand ramp rung is not a semantic and does not flip. */
|
|
522
|
+
--cg-slate-500: #828c98;
|
|
523
|
+
/*
|
|
524
|
+
SOURCE: Figma variable color/neutral/600, read first-hand on thegrid
|
|
525
|
+
(8364:4327, the stats rows; 8364:4255, "your CREATIONS").
|
|
526
|
+
|
|
527
|
+
This is the accessible companion to --cg-slate-500 and the design supplied it
|
|
528
|
+
itself, which is why nothing had to be invented:
|
|
529
|
+
|
|
530
|
+
on the card #ffffff : 5.65:1
|
|
531
|
+
on the page ground #f1f1f6 : 5.02:1
|
|
532
|
+
on raised #f4f6f8 : 5.21:1
|
|
533
|
+
on subtle #f2f1f7 : 5.03:1
|
|
534
|
+
on the cyan tint #dffbfc : 5.20:1
|
|
535
|
+
on the violet wash #d9d4fb : 3.97:1 large text only
|
|
536
|
+
on the lime #b6de68 : 3.67:1 large text only
|
|
537
|
+
on ink #222222 : 2.82:1 do not
|
|
538
|
+
on the purple panel #5a47f0 : 1.03:1 invisible
|
|
539
|
+
|
|
540
|
+
So: safe for body copy on any of the light page and card grounds, and on the
|
|
541
|
+
cyan tint. NOT safe on the violet wash, on the lime, or on either dark surface.
|
|
542
|
+
Where the frames put slate-500 on a light ground and mean it as running text,
|
|
543
|
+
this is the value that keeps the design and passes. */
|
|
544
|
+
--cg-slate-600: #5f6874;
|
|
545
|
+
/*
|
|
546
|
+
SOURCE: Figma variable "stone", declared on the home frame (8204:2397). ui#239
|
|
547
|
+
asks for it by name.
|
|
548
|
+
|
|
549
|
+
HONEST PROVENANCE, because this is the one value here that is weaker than the
|
|
550
|
+
rest: it is a DECLARATION. The home frame declares it as a variable, and the
|
|
551
|
+
Figma quota ran out before the audit could read the ~90 nodes of that frame that
|
|
552
|
+
might paint with it. No node on any of the other five frames uses it. So its
|
|
553
|
+
role is recorded as unknown rather than guessed, and nothing in this package
|
|
554
|
+
consumes it yet.
|
|
555
|
+
|
|
556
|
+
It is a warm near-black, not a grey: R52 G51 B48 against --cg-ink's flat #222222.
|
|
557
|
+
12.63:1 on the card and 11.22:1 on the page ground, so wherever it lands it is a
|
|
558
|
+
text-or-ink value and not a surface tint.
|
|
559
|
+
|
|
560
|
+
The rung number is by lightness against this package's own ramp, which ends at
|
|
561
|
+
neutral-900 #222222. Figma gives it no number. */
|
|
562
|
+
--cg-stone-800: #343330;
|
|
563
|
+
|
|
564
|
+
/* ---- hue-ramps ----
|
|
565
|
+
The three brand hues as RAMPS, not as single values (#239, 2026-09-18).
|
|
566
|
+
|
|
567
|
+
Until now this package carried one violet, one lime and one cyan, plus a single
|
|
568
|
+
--cg-primary-tint. The six canonical Figma frames carry a full scale of each,
|
|
569
|
+
declared as Figma variables under color/violet/*, color/lime/* and color/cyan/*,
|
|
570
|
+
and they spend those rungs on real surfaces: chips, role badges, avatar strokes,
|
|
571
|
+
step diagrams, the enterprise button. With no rung to reach for, a consumer
|
|
572
|
+
either hardcodes the hex, which CLAUDE.md forbids, or approximates with
|
|
573
|
+
color-mix(). cloudgrid-landing is doing the second right now — #133 renders
|
|
574
|
+
`color-mix(in srgb, var(--cg-primary) 22%, var(--cg-neutral-0))` to get within
|
|
575
|
+
2/255 of --cg-violet-200 — and that is the drift this group removes.
|
|
576
|
+
|
|
577
|
+
RUNG NUMBERS ARE FIGMA'S, not this package's, wherever Figma names them. Two
|
|
578
|
+
rungs (violet-150, violet-400, cyan-400) are values observed applied on a node
|
|
579
|
+
with NO Figma variable behind them; each says so in its own note and is placed
|
|
580
|
+
by lightness between the bound rungs either side. Nothing here was invented.
|
|
581
|
+
|
|
582
|
+
WHY THE UTILITY NAMES DIVERGE FROM THE TOKEN NAMES. The violet ramp maps onto
|
|
583
|
+
--color-brand-100..900, because "brand" is this package's own name for the hue
|
|
584
|
+
(theme.css, rule 4) and Tailwind ships no `brand` scale to collide with. The
|
|
585
|
+
cyan and lime rungs map onto SUFFIXED names (cyan-tint, lime-edge) rather than
|
|
586
|
+
cyan-200 / lime-700, because Tailwind DOES ship those exact numbered names and
|
|
587
|
+
claiming them would silently repaint every `bg-cyan-200` in a consumer's own
|
|
588
|
+
markup. That is rule 4's failure aimed at Tailwind instead of shadcn, and it is
|
|
589
|
+
worse, because the consumer never opted in.
|
|
590
|
+
|
|
591
|
+
DECLARED AT :root ONLY, like every brand source. A ramp rung is not a semantic
|
|
592
|
+
and does not flip; the semantics that spend it do. */
|
|
593
|
+
/*
|
|
594
|
+
SOURCE: Figma color/violet/100. Applied on thegrid at 8364:4136 (the private-status chip), 8364:4158 (the Owner role badge) and the Add-people button. 1.20:1 on the card, so a ground and never a foreground. */
|
|
595
|
+
--cg-violet-100: #ebe8fd;
|
|
596
|
+
/*
|
|
597
|
+
SOURCE: observed applied, UNBOUND. teams 7172:7759 (the first flow circle) and builders 6919:8782 (the first step circle, "Detect"). No Figma variable carries it.
|
|
598
|
+
|
|
599
|
+
It is the value ui#239 asks for and the one cloudgrid-landing currently reaches with a color-mix of --cg-primary. Placed at 150 because it sits between the two bound rungs either side: violet-100 #ebe8fd and violet-200 #d9d4fb. A half-rung is not new here; the neutral ramp already carries neutral-25 between 0 and 50.
|
|
600
|
+
|
|
601
|
+
Measured as a ground: --cg-text-primary is 12.38:1 on it, --cg-slate-600 4.25:1, --cg-slate-500 2.56:1. */
|
|
602
|
+
--cg-violet-150: #e3e0fd;
|
|
603
|
+
/*
|
|
604
|
+
SOURCE: Figma color/violet/200, declared on the home and thegrid frames.
|
|
605
|
+
|
|
606
|
+
READ ui#239'S CORRECTION BEFORE USING --cg-offline FOR THIS. That issue's first table maps #D9D4FB onto --cg-offline, and the mapping only holds inside [data-cg-surface='panel']. At :root --cg-offline is var(--cg-neutral-500), a mid grey, so a consumer taking that token at face value on the page ground gets #858585 and nothing goes red. This rung is the value; --cg-offline is a status tone that happens to reach it on one surface.
|
|
607
|
+
|
|
608
|
+
The pairing the frames draw on it is a documented AA failure and the reason --cg-slate-600 exists: --cg-slate-500 on this ground measures 2.40:1, under even the 3:1 indicator bar. --cg-text-primary is 11.18:1, --cg-slate-600 3.97:1 (large text only), --cg-neutral-600 3.80:1. */
|
|
609
|
+
--cg-violet-200: #d9d4fb;
|
|
610
|
+
/*
|
|
611
|
+
SOURCE: Figma color/violet/300, declared on thegrid. Rendered there only inside flattened SVG illustration, so it is a declared rung with no CSS-reachable node behind it yet. Carried so the ramp a designer edits in Figma is the ramp this package ships. */
|
|
612
|
+
--cg-violet-300: #c8c2fa;
|
|
613
|
+
/*
|
|
614
|
+
SOURCE: observed applied, UNBOUND. builders 6919:8785, the second step circle.
|
|
615
|
+
|
|
616
|
+
Placed at 400 because it is the only observed violet with no bound rung within reach: it sits between color/violet/300 #c8c2fa and color/violet/500 #a69bf7.
|
|
617
|
+
|
|
618
|
+
Worth knowing before retuning: the four builders step circles are #E3E0FD / #BCB4F9 / #A49AF7 / #8072F3, which are --cg-primary composited on white at 17 / 40 / 55 / 77 percent. The last two land within 2 and 4 of bound rungs 500 and 700 and are taken as those; this one does not. */
|
|
619
|
+
--cg-violet-400: #bcb4f9;
|
|
620
|
+
/*
|
|
621
|
+
SOURCE: Figma color/violet/500, declared on thegrid. builders 6919:8788 paints #A49AF7, which is this value within 2/255 per channel and is treated as this rung rather than as a ninth violet. */
|
|
622
|
+
--cg-violet-500: #a69bf7;
|
|
623
|
+
/*
|
|
624
|
+
SOURCE: Figma color/violet/600, declared on thegrid; rendered only inside flattened SVG illustration. Carried for the same reason as violet-300. */
|
|
625
|
+
--cg-violet-600: #9488f5;
|
|
626
|
+
/*
|
|
627
|
+
SOURCE: Figma color/violet/700. Applied on thegrid 8364:4388, the stroke around an avatar chip in the Plug section. builders 6919:8791 paints #8072F3, within 4/255 per channel, and is taken as this rung.
|
|
628
|
+
|
|
629
|
+
3.57:1 on the card: an indicator or a border, never a word. */
|
|
630
|
+
--cg-violet-700: #8476f4;
|
|
631
|
+
/*
|
|
632
|
+
Figma names --cg-primary color/violet/900. Deliberately an ALIAS rather than the hex written a second time: the brand hue has one home, at the top of this file, and a designer retuning it must not have to find two. */
|
|
633
|
+
--cg-violet-900: var(--cg-primary);
|
|
634
|
+
/*
|
|
635
|
+
SOURCE: Figma color/cyan/200, also carried under the legacy name "Teriary 20" (the typo is Figma's). Applied on three frames: thegrid 8364:4166 (the Editor role badge), teams 7172:7643 and pricing 7779:9320 (the footer's secondary buttons, with a --cg-tertiary hairline around them).
|
|
636
|
+
|
|
637
|
+
It IS a tint of the tertiary, and exactly: #60e9f0 composited on white at 20% is #dffbfc to the byte. Shipped as a value anyway rather than as a color-mix, because a consumer should not have to know the recipe to draw a button.
|
|
638
|
+
|
|
639
|
+
--cg-slate-600 measures 5.20:1 on it and --cg-text-primary 14.65:1. */
|
|
640
|
+
--cg-cyan-200: #dffbfc;
|
|
641
|
+
/*
|
|
642
|
+
SOURCE: Figma color/cyan/300, declared on thegrid; rendered only inside flattened SVG illustration. Carried so the ramp is whole. */
|
|
643
|
+
--cg-cyan-300: #cff8fa;
|
|
644
|
+
/*
|
|
645
|
+
SOURCE: observed applied, UNBOUND. thegrid 8364:4002 and 8364:4056 — the footer and enterprise buttons, drawn as this fill with a --cg-tertiary hairline. ui#239's second comment asks for it.
|
|
646
|
+
|
|
647
|
+
IT IS NOT A TINT OF --cg-tertiary, and that is worth the arithmetic, because every other rung in this family is. #60E9F0 has G 233, so reaching G 252 needs 86% white, and that mix gives R 233 — this value has R 177. Solving the same mix from the blue channel gives 0%. No single alpha produces it. So the color-mix() workaround available for the violet wash is not available here, which is precisely why the token is.
|
|
648
|
+
|
|
649
|
+
Placed at 400 by lightness, between bound rungs cyan-300 and cyan-900.
|
|
650
|
+
|
|
651
|
+
5.07:1 on the purple panel and 13.82:1 on ink: as a fill it carries text on both dark surfaces. 1.15:1 on the card, so never a foreground on white. */
|
|
652
|
+
--cg-cyan-400: #b1fcff;
|
|
653
|
+
/*
|
|
654
|
+
Figma names --cg-tertiary color/cyan/900. An alias, for the reason violet-900 is one. */
|
|
655
|
+
--cg-cyan-900: var(--cg-tertiary);
|
|
656
|
+
/*
|
|
657
|
+
SOURCE: Figma color/lime/200, declared on thegrid; rendered only inside flattened SVG illustration. Carried so the ramp is whole. */
|
|
658
|
+
--cg-lime-200: #eef7dc;
|
|
659
|
+
/*
|
|
660
|
+
SOURCE: Figma color/lime/600, declared on thegrid; rendered only inside flattened SVG illustration. */
|
|
661
|
+
--cg-lime-600: #d0ea9e;
|
|
662
|
+
/*
|
|
663
|
+
SOURCE: Figma color/lime/700. Applied on thegrid 8364:4387, the stroke around the audience avatars in the Plug section.
|
|
664
|
+
|
|
665
|
+
1.38:1 on the card and 4.22:1 on the purple panel: a border on a dark ground, not a line on a light one. */
|
|
666
|
+
--cg-lime-700: #c8e68e;
|
|
667
|
+
/*
|
|
668
|
+
Figma names --cg-secondary color/lime/900. An alias, for the reason violet-900 is one. */
|
|
669
|
+
--cg-lime-900: var(--cg-secondary);
|
|
450
670
|
|
|
451
671
|
/* ---- semantic-surfaces ---- */
|
|
452
672
|
--cg-surface-page: var(--cg-neutral-25);
|
|
@@ -476,6 +696,37 @@
|
|
|
476
696
|
--cg-text-primary: var(--cg-neutral-900);
|
|
477
697
|
--cg-text-secondary: var(--cg-neutral-700);
|
|
478
698
|
--cg-text-muted: var(--cg-neutral-500);
|
|
699
|
+
/*
|
|
700
|
+
The muted tone for text that is real content: a tile hint, an eyebrow that
|
|
701
|
+
carries meaning, a caption a reader has to read. ui#232, 2026-09-18.
|
|
702
|
+
|
|
703
|
+
--cg-text-muted is under the 4.5:1 body-text floor on three of the four grounds
|
|
704
|
+
(3.69:1 card, 3.28:1 page, 3.44:1 panel, 5.92:1 ink), which means every caption
|
|
705
|
+
in this library is AA-legal as large text and illegal as body copy. #232 asked
|
|
706
|
+
for a stronger rung rather than a retune, on the reasoning #149 used for
|
|
707
|
+
state's -strong: a tone tuned to recede and a tone tuned to be read are two
|
|
708
|
+
jobs, and collapsing them retunes both.
|
|
709
|
+
|
|
710
|
+
It is NOT --cg-text-secondary under a second name. Secondary is neutral-700
|
|
711
|
+
(7.00:1 on the card) and reads as a second voice; this is neutral-600, a new
|
|
712
|
+
rung derived for the floor and nothing else. Its note carries the sweep.
|
|
713
|
+
|
|
714
|
+
base #6a6a6a card 5.41:1 page 4.80:1 raised 4.99:1 subtle 4.82:1
|
|
715
|
+
panel rgba(255,255,255,0.86) on #5a47f0 : 4.75:1
|
|
716
|
+
ink rgba(255,255,255,0.68) on #222222 : 8.02:1
|
|
717
|
+
|
|
718
|
+
ON THE PANEL THIS RUNG IS BRIGHTER THAN --cg-text-secondary, and that is not a
|
|
719
|
+
mistake. Measured, the panel's own secondary (0.82 white) is 4.47:1, which is
|
|
720
|
+
under the floor by 0.03. Nothing dimmer than 0.84 white clears 4.5:1 on that
|
|
721
|
+
ground, so the panel cannot deliver a "muted that reads as body copy" below its
|
|
722
|
+
own secondary. Same shape as the note further up about a panel chip's word:
|
|
723
|
+
where the surface cannot deliver the ratio, the surface has to move, not the
|
|
724
|
+
foreground. A designer who dislikes the inversion changes --cg-surface-panel,
|
|
725
|
+
not this.
|
|
726
|
+
|
|
727
|
+
DECORATIVE CAPTIONS MAY KEEP --cg-text-muted. This rung does not deprecate it;
|
|
728
|
+
#232's own done-when says so. */
|
|
729
|
+
--cg-text-muted-strong: var(--cg-neutral-600);
|
|
479
730
|
--cg-text-placeholder: var(--cg-neutral-400);
|
|
480
731
|
--cg-text-accent: var(--cg-primary);
|
|
481
732
|
--cg-text-inverse: var(--cg-neutral-0);
|
|
@@ -523,16 +774,94 @@
|
|
|
523
774
|
The mono face is untouched: it is used only inside prompt and terminal surfaces
|
|
524
775
|
and the draft says nothing about it. */
|
|
525
776
|
/*
|
|
526
|
-
The display
|
|
527
|
-
|
|
528
|
-
|
|
529
|
-
|
|
530
|
-
|
|
531
|
-
|
|
532
|
-
|
|
533
|
-
|
|
534
|
-
|
|
535
|
-
|
|
777
|
+
The display face, and the one token in this file that names a font this package
|
|
778
|
+
does NOT ship. ui#240, 2026-09-18.
|
|
779
|
+
|
|
780
|
+
All six canonical Figma frames set every headline in TANKER: the hero (92px on
|
|
781
|
+
five frames, 120px on home), every section heading (56px), every card title.
|
|
782
|
+
Nothing else in the design uses it and it is used for nothing else.
|
|
783
|
+
|
|
784
|
+
THE BINARY CANNOT SHIP HERE, and the reason is a licence, not an oversight.
|
|
785
|
+
Tanker is under the ITF Free Font License v2.0, whose section 02 forbids making
|
|
786
|
+
the Font Software available "through another font website, font library,
|
|
787
|
+
marketplace, repository, download service, application or platform". This
|
|
788
|
+
package is public on registry.npmjs.org, installable by anyone with no
|
|
789
|
+
credentials, which is exactly what that clause names. Section 03 states the
|
|
790
|
+
remedy: "Any third party wishing to use the Font Software must obtain their own
|
|
791
|
+
copy directly from Fontshare and be independently bound by this License."
|
|
792
|
+
|
|
793
|
+
That is why Manrope is fine and Tanker is not. Manrope arrives as
|
|
794
|
+
@fontsource-variable/manrope under the Open Font License, which permits
|
|
795
|
+
redistribution. Fontshare publishes no fontsource package.
|
|
796
|
+
|
|
797
|
+
So the package owns the STACK and the consumer owns the FILE. Adding 'Tanker' at
|
|
798
|
+
the front is strictly additive in effect: a consumer that has not self-hosted it
|
|
799
|
+
falls straight through to Manrope and renders exactly what 0.27.2 rendered.
|
|
800
|
+
Before this, a consumer wanting the display face had to copy this whole fallback
|
|
801
|
+
chain verbatim into its own :root (cloudgrid-landing PR #132 did), and that copy
|
|
802
|
+
went stale the moment this package retired the condensed rung.
|
|
803
|
+
|
|
804
|
+
PENDING, and stated so rather than assumed: the 2026-09-10 re-skin (#197)
|
|
805
|
+
deliberately removed the display rung and set the whole system in Manrope.
|
|
806
|
+
Whether naming Tanker here reverses that decision is the founder's call, and it
|
|
807
|
+
is the open question at the end of #240. This change is written to be reversible
|
|
808
|
+
in one line if the answer is no.
|
|
809
|
+
|
|
810
|
+
NOT RETUNED, deliberately: --cg-display-line (1.06) and --cg-display-tracking
|
|
811
|
+
(0.012em) were tuned against Saira Semi Condensed 800. Every Tanker node in
|
|
812
|
+
every frame is leading-none with no tracking. See --cg-display-line-tight. */
|
|
813
|
+
--cg-font-display: 'Tanker', 'Manrope Variable', 'Manrope', -apple-system, BlinkMacSystemFont, 'Segoe UI', sans-serif;
|
|
814
|
+
/*
|
|
815
|
+
The body face. cloudgrid-landing#145, 2026-09-18.
|
|
816
|
+
|
|
817
|
+
Every body string in the canonical frames is SPACE GROTESK, and it was checked
|
|
818
|
+
on five of the six independently before it was believed: home 8204:2561 and
|
|
819
|
+
8204:2563, thegrid 8364:4213, builders 6913:7654, teams 7172:7571, enterprise
|
|
820
|
+
7037:779, pricing 7779:9261 — all 20px / 1.46, all the lede under a headline,
|
|
821
|
+
all in unrelated sections. The nav links and the card copy are the same face at
|
|
822
|
+
15px. This is the design's text face, not a stray on one frame.
|
|
823
|
+
|
|
824
|
+
IT SHIPS HERE, unlike Tanker. @fontsource-variable/space-grotesk is OFL-1.1,
|
|
825
|
+
which permits redistribution, so it arrives as a dependency and an @import in
|
|
826
|
+
fonts.css exactly the way Manrope does. See fonts.css.
|
|
827
|
+
|
|
828
|
+
THIS IS A VALUE CHANGE, not an addition, and it is the only one in this release.
|
|
829
|
+
Manrope is kept in the chain immediately behind it, so a consumer whose pipeline
|
|
830
|
+
somehow does not resolve the new dependency renders precisely what it rendered
|
|
831
|
+
before. Blast radius: every string in every consumer that has not overridden
|
|
832
|
+
this token changes face. Metrics differ — Space Grotesk is wider at the same
|
|
833
|
+
size — so a consumer with a tightly measured layout should look at it before
|
|
834
|
+
taking the release. cloudgrid-landing is the consumer that asked for it.
|
|
835
|
+
|
|
836
|
+
MANROPE DID NOT LEAVE. The frames keep it, and only for two jobs: the eyebrow
|
|
837
|
+
and the button label. Those now read --cg-font-ui, which is this token's
|
|
838
|
+
previous value unchanged, so neither of them moves. */
|
|
839
|
+
--cg-font-body: 'Space Grotesk Variable', 'Space Grotesk', 'Manrope Variable', 'Manrope', -apple-system, BlinkMacSystemFont, 'Segoe UI', sans-serif;
|
|
840
|
+
/*
|
|
841
|
+
The face for the small fixed chrome of a page: the eyebrow above a heading, and
|
|
842
|
+
the label inside a button. 2026-09-18.
|
|
843
|
+
|
|
844
|
+
A third family stack is not a flourish. The canonical frames use exactly three
|
|
845
|
+
faces in three jobs — Tanker for display, Space Grotesk for everything a reader
|
|
846
|
+
reads, and MANROPE for the eyebrow and the button label — and they are
|
|
847
|
+
consistent about it. Every button label on all six frames is Manrope Bold 15
|
|
848
|
+
leading-none (home I8204:2580;732:46, thegrid I8364:4215;732:46, builders
|
|
849
|
+
I6913:7656;732:46, teams I7172:7573;732:46, enterprise I7037:781;732:46,
|
|
850
|
+
pricing I7779:9336;732:46). Every applied eyebrow is Manrope SemiBold 14, and
|
|
851
|
+
Figma binds it as a named text variable, "Eyebrow".
|
|
852
|
+
|
|
853
|
+
Its VALUE is --cg-font-body's previous value, byte for byte. That is what makes
|
|
854
|
+
the body-face change safe to read: the eyebrow and the button did not move, they
|
|
855
|
+
just stopped being spelled with the body token.
|
|
856
|
+
|
|
857
|
+
KNOWN INCONSISTENCY IN THE SOURCE, recorded so nobody "fixes" it from the wrong
|
|
858
|
+
end: on the home frame the four nav links (8204:2573) are Manrope Medium 15 and
|
|
859
|
+
"Sign In" beside them (8204:2579) is Space Grotesk Medium 15 — same slot, same
|
|
860
|
+
size, same weight, two faces. On thegrid the same split appears at 8364:4053
|
|
861
|
+
against 8364:4052/4054/4055. Five frames agree the nav is Space Grotesk, so the
|
|
862
|
+
Manrope instances read as a migration caught mid-flight rather than as intent,
|
|
863
|
+
and this token is NOT the nav's face. */
|
|
864
|
+
--cg-font-ui: 'Manrope Variable', 'Manrope', -apple-system, BlinkMacSystemFont, 'Segoe UI', sans-serif;
|
|
536
865
|
--cg-font-mono: 'JetBrains Mono Variable', 'JetBrains Mono', ui-monospace, SFMono-Regular, Menlo, monospace;
|
|
537
866
|
|
|
538
867
|
/* ---- weights ----
|
|
@@ -561,6 +890,25 @@
|
|
|
561
890
|
|
|
562
891
|
Stepped down one notch 2026-08-06 (operator: main headings read too
|
|
563
892
|
dominant). The SOURCE values were xl 64 / lg 48 / md 42 / sm 32. */
|
|
893
|
+
/*
|
|
894
|
+
SOURCE: home 8204:2556, the hero headline, Tanker at leading-none.
|
|
895
|
+
|
|
896
|
+
The largest rung in the system and the only node that asks for it. It is kept
|
|
897
|
+
separate from display-2xl rather than collapsed onto it because the two are 28px
|
|
898
|
+
apart and both are heroes: home is 120 and the other five frames are 92. */
|
|
899
|
+
--cg-display-3xl: 120px;
|
|
900
|
+
/*
|
|
901
|
+
SOURCE: the hero headline on five of the six canonical frames — thegrid
|
|
902
|
+
8364:4211, builders 6913:7652, teams 7172:7569, enterprise 7037:777, pricing
|
|
903
|
+
7779:9259. Tanker, leading-none, no tracking.
|
|
904
|
+
|
|
905
|
+
This is the ramp's real top. Before it, --cg-display-xl (56px) was the largest
|
|
906
|
+
value in the package and every hero in the design was 36px above it, so each
|
|
907
|
+
consumer clamped its own. thegrid also draws a 96px closing CTA (8364:3957) and
|
|
908
|
+
a 64px section heading (8364:4363); both are single nodes and are deliberately
|
|
909
|
+
not rungs. A value invented to complete a grid is the thing this file keeps
|
|
910
|
+
refusing to add. */
|
|
911
|
+
--cg-display-2xl: 92px;
|
|
564
912
|
--cg-display-xl: 56px;
|
|
565
913
|
--cg-display-lg: 44px;
|
|
566
914
|
/* SOURCE: onboarding H1 (was 42px) */
|
|
@@ -568,6 +916,65 @@
|
|
|
568
916
|
--cg-display-sm: 30px;
|
|
569
917
|
--cg-display-line: 1.06;
|
|
570
918
|
--cg-display-tracking: 0.012em;
|
|
919
|
+
/*
|
|
920
|
+
The leading every Tanker node in every canonical frame actually uses: 1, i.e.
|
|
921
|
+
leading-none. Not one display node in six frames emits a letter-spacing either.
|
|
922
|
+
|
|
923
|
+
--cg-display-line stays 1.06 and --cg-display-tracking stays 0.012em. Both were
|
|
924
|
+
tuned against Saira Semi Condensed 800 (ui#240 records this), neither has been
|
|
925
|
+
retuned for Tanker, and both are shipped values that four display rungs and
|
|
926
|
+
every consumer's display utility already read. Retuning them is a one-line edit
|
|
927
|
+
and a visible change to text that exists today, so it is proposed rather than
|
|
928
|
+
made. This rung is what the new sizes are built on in the meantime. */
|
|
929
|
+
--cg-display-line-tight: 1;
|
|
930
|
+
|
|
931
|
+
/* ---- tanker-title-ramp ----
|
|
932
|
+
The display face at CARD scale, 2026-09-18.
|
|
933
|
+
|
|
934
|
+
Four rungs the canonical frames use constantly and this package could spell
|
|
935
|
+
none of. They are separated from h1-display-ramp rather than wedged into it
|
|
936
|
+
because the two ramps disagree everywhere they overlap, and the disagreement is
|
|
937
|
+
not resolvable by addition:
|
|
938
|
+
|
|
939
|
+
frames 120 96 92 64 56 40 38 32 30 26 20
|
|
940
|
+
package 56 44 38 30
|
|
941
|
+
|
|
942
|
+
56, 38 and 30 coincide. 44 is used by nothing in any of the six frames. Every
|
|
943
|
+
other size the frames ask for falls BETWEEN two shipped rungs — 40 between 44
|
|
944
|
+
and 38, 26 between 30 and heading-lg's 22 — so there is no name left on the
|
|
945
|
+
t-shirt ramp that is both free and in the right place, and renaming a shipped
|
|
946
|
+
rung is a breaking change for two published consumers.
|
|
947
|
+
|
|
948
|
+
They are also not headings. --cg-heading-* is the Manrope ramp at 1.2 leading;
|
|
949
|
+
this is the display FACE at leading-none, and --cg-title-sm and
|
|
950
|
+
--cg-heading-md are both 20px precisely because a face and a leading are what
|
|
951
|
+
separate them, not a size.
|
|
952
|
+
|
|
953
|
+
SIZES, with where they were read:
|
|
954
|
+
40 home 8204:2589, enterprise 7038:1244, pricing 7785:9809, thegrid 8364:4382
|
|
955
|
+
26 teams 7297:8606, builders 6916:8648, enterprise 7038:1192,
|
|
956
|
+
pricing 7788:10264, thegrid 8364:3882
|
|
957
|
+
20 teams 7172:7760, builders 6919:8783, thegrid petal labels
|
|
958
|
+
|
|
959
|
+
pricing 7785:10059 draws one 32px Tanker number and thegrid draws 15px Tanker
|
|
960
|
+
eyebrows. Single-frame, so recorded and not given a rung. */
|
|
961
|
+
/*
|
|
962
|
+
Four frames. The governance card title, the plan price, the sub-heading under a section statement. */
|
|
963
|
+
--cg-title-lg: 40px;
|
|
964
|
+
/*
|
|
965
|
+
Five frames. The card title and the FAQ question — the most common display size in the design after the section heading.
|
|
966
|
+
|
|
967
|
+
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
|
+
--cg-title-md: 26px;
|
|
969
|
+
/*
|
|
970
|
+
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
|
+
--cg-title-sm: 20px;
|
|
972
|
+
/*
|
|
973
|
+
leading-none, aliased rather than repeated so a retune of the display leading reaches both ramps. An alias compiles to var(), so it survives a scope flip. */
|
|
974
|
+
--cg-title-line: var(--cg-display-line-tight);
|
|
975
|
+
/*
|
|
976
|
+
No Tanker node in any of the six frames emits a letter-spacing. Spelled out rather than omitted so a utility built on this ramp cannot inherit --cg-display-tracking's 0.012em by accident. */
|
|
977
|
+
--cg-title-tracking: 0em;
|
|
571
978
|
|
|
572
979
|
/* ---- manrope-ramp ---- */
|
|
573
980
|
/*
|
|
@@ -589,6 +996,22 @@
|
|
|
589
996
|
extrapolation, and a heading is short enough that 1.2 does not cost a line its
|
|
590
997
|
descenders. */
|
|
591
998
|
--cg-heading-line: 1.2;
|
|
999
|
+
/*
|
|
1000
|
+
SOURCE: the lede paragraph on all six canonical frames — home 8204:2561,
|
|
1001
|
+
thegrid 8364:4213, builders 6913:7654, teams 7172:7571, enterprise 7037:779,
|
|
1002
|
+
pricing 7779:9261. Space Grotesk regular, line-height 1.46, no tracking.
|
|
1003
|
+
|
|
1004
|
+
The single most-used text size in the whole design and the one this package
|
|
1005
|
+
could not spell. --cg-body-lg is 19px and --cg-heading-md is 20px, so a
|
|
1006
|
+
consumer building a lede had to pick between a body token one pixel short and a
|
|
1007
|
+
heading token that is the right size with the wrong role and the wrong leading
|
|
1008
|
+
(1.2 against 1.46). cloudgrid-landing#145 records sections doing the first.
|
|
1009
|
+
|
|
1010
|
+
It reads --cg-body-line, so it is a body rung and not a fifth display rung.
|
|
1011
|
+
|
|
1012
|
+
pricing 7785:9832 draws one 18px bold plan name. Single node, one frame, 1px
|
|
1013
|
+
off --cg-body-lg: recorded, not given a rung. */
|
|
1014
|
+
--cg-body-xl: 20px;
|
|
592
1015
|
/* SOURCE: H1 subline */
|
|
593
1016
|
--cg-body-lg: 19px;
|
|
594
1017
|
/* SOURCE: default UI text */
|
|
@@ -609,6 +1032,43 @@
|
|
|
609
1032
|
--cg-mono-line: 1.7;
|
|
610
1033
|
--cg-label-size: 15px;
|
|
611
1034
|
--cg-label-weight: var(--cg-weight-medium);
|
|
1035
|
+
/*
|
|
1036
|
+
SOURCE: Figma's own bound text variable, "Eyebrow" —
|
|
1037
|
+
Font(family: "Manrope", style: SemiBold, size: 14, weight: 600, lineHeight: 1.2,
|
|
1038
|
+
letterSpacing: 10). Applied first-hand on teams 7172:8463, builders 6916:8053
|
|
1039
|
+
and enterprise 7038:1184, each rendering tracking-[1.4px] uppercase.
|
|
1040
|
+
|
|
1041
|
+
The only rung in this package derived from a Figma TEXT variable rather than
|
|
1042
|
+
from a measured node, and it agrees with the nodes, which is why it is trusted.
|
|
1043
|
+
|
|
1044
|
+
It is equidistant from the two tokens a consumer would otherwise reach for:
|
|
1045
|
+
--cg-caption is 13px and --cg-label-size is 15px, and Eyebrow currently builds
|
|
1046
|
+
on the second. One pixel is not the point — the eyebrow also carries a weight,
|
|
1047
|
+
a leading and a tracking that neither of those tokens has, and spelling three
|
|
1048
|
+
of the four inline is how a component drifts.
|
|
1049
|
+
|
|
1050
|
+
KNOWN: thegrid draws its eyebrows differently — Tanker regular 15px, leading
|
|
1051
|
+
16px, tracking 1.1px (8364:3905, 8364:4409) — and both of pricing's eyebrows are
|
|
1052
|
+
switched off in the file. So this is the eyebrow of three frames, not six, and
|
|
1053
|
+
thegrid's is an open question for the designer rather than a second rung here. */
|
|
1054
|
+
--cg-eyebrow-size: 14px;
|
|
1055
|
+
/*
|
|
1056
|
+
From the Eyebrow variable. The same number as --cg-heading-line, spelled out rather than aliased: an eyebrow is not a heading, and a heading retune must not silently move it. */
|
|
1057
|
+
--cg-eyebrow-line: 1.2;
|
|
1058
|
+
/*
|
|
1059
|
+
From the Eyebrow variable, whose letterSpacing is 10 — Figma's percent, not pixels. At 14px that is 1.4px, which is what all three frames render. Stored in em so the ratio survives a size change. */
|
|
1060
|
+
--cg-eyebrow-tracking: 0.1em;
|
|
1061
|
+
/*
|
|
1062
|
+
600, from the Eyebrow variable's weight: 600.
|
|
1063
|
+
|
|
1064
|
+
Aliased onto --cg-weight-bold rather than written as a number, because 600 is
|
|
1065
|
+
already this package's "bold" (the weights group's own note explains why that
|
|
1066
|
+
name and not "semibold"). Two spellings of one weight is how a ramp starts
|
|
1067
|
+
disagreeing with itself.
|
|
1068
|
+
|
|
1069
|
+
Note this is NOT --cg-label-weight, which is 500. The eyebrow and the label are
|
|
1070
|
+
different rungs; see the group note. */
|
|
1071
|
+
--cg-eyebrow-weight: var(--cg-weight-bold);
|
|
612
1072
|
|
|
613
1073
|
/* ---- spacing ----
|
|
614
1074
|
spacing: 4px base */
|
|
@@ -657,8 +1117,44 @@
|
|
|
657
1117
|
--cg-radius-lg: 14px;
|
|
658
1118
|
/* SOURCE: option card */
|
|
659
1119
|
--cg-radius-xl: 16px;
|
|
1120
|
+
/*
|
|
1121
|
+
SOURCE: the corner of every section slab and every card in the design, read on
|
|
1122
|
+
all six canonical frames — home 8204:2440, thegrid 8364:3928, builders
|
|
1123
|
+
6913:8019, teams 7172:7567, enterprise 7037:775, pricing 7785:10051.
|
|
1124
|
+
|
|
1125
|
+
It is the most-used radius in the whole design and the ramp had no name for it.
|
|
1126
|
+
--cg-radius-xl is 16 and --cg-radius-2xl is 24, and both are shipped, so 20 has
|
|
1127
|
+
no free t-shirt name in the right place. Renaming a rung two published
|
|
1128
|
+
consumers already read is a breaking change for a corner.
|
|
1129
|
+
|
|
1130
|
+
So it takes a ROLE name, which the corners group already does once for
|
|
1131
|
+
--cg-radius-pill. The role is exact and worth stating: in these frames 16 is
|
|
1132
|
+
what a CONTROL is rounded to (every button on every frame is 16) and 20 is what
|
|
1133
|
+
a CONTAINER is rounded to. The design draws that distinction consistently, which
|
|
1134
|
+
is more information than a number between two numbers.
|
|
1135
|
+
|
|
1136
|
+
NOT --cg-radius-panel, deliberately: "panel" in this package is the purple
|
|
1137
|
+
surface (--cg-surface-panel, data-cg-surface="panel"), and a radius named after
|
|
1138
|
+
it would read as that surface's corner rather than as every container's. */
|
|
1139
|
+
--cg-radius-container: 20px;
|
|
660
1140
|
/* SOURCE: full-bleed purple panel */
|
|
661
1141
|
--cg-radius-2xl: 24px;
|
|
1142
|
+
/*
|
|
1143
|
+
SOURCE: home 8204:2557 and 8204:2569, the two 92px lime image cards in the hero.
|
|
1144
|
+
|
|
1145
|
+
One frame, two nodes, and it is here rather than recorded-and-skipped for one
|
|
1146
|
+
reason: it extends the t-shirt ramp at the TOP, where there is a free name and
|
|
1147
|
+
no ambiguity, instead of asking for one between two shipped rungs.
|
|
1148
|
+
|
|
1149
|
+
WHAT IS NOT HERE. The brief this work came from expected a rung between
|
|
1150
|
+
--cg-radius-2xl and --cg-radius-pill for a frame nesting 108 / 93 / 80px
|
|
1151
|
+
corners. No radius above 60 and below the pill appears on any of the six frames
|
|
1152
|
+
first-hand. builders draws 60px on three decorative glow rectangles
|
|
1153
|
+
(7172:8460-8462) and thegrid draws 22 / 18 / 15 / 11 / 9 inside a flattened
|
|
1154
|
+
product-UI mock. None of those is a rung; all are recorded here so the next
|
|
1155
|
+
audit does not re-find them. The home frame is only ~10% audited (the Figma
|
|
1156
|
+
quota ran out), so if that expectation has a node behind it, it is there. */
|
|
1157
|
+
--cg-radius-3xl: 32px;
|
|
662
1158
|
--cg-radius-pill: 999px;
|
|
663
1159
|
--cg-border-width: 1px;
|
|
664
1160
|
--cg-border-width-strong: 1.5px;
|
|
@@ -844,6 +1340,12 @@
|
|
|
844
1340
|
--cg-text-primary: #ffffff;
|
|
845
1341
|
--cg-text-secondary: rgba(255, 255, 255, 0.82);
|
|
846
1342
|
--cg-text-muted: rgba(255, 255, 255, 0.66);
|
|
1343
|
+
/*
|
|
1344
|
+
4.75:1 on --cg-surface-panel. See the base note: on this ground nothing dimmer
|
|
1345
|
+
than 0.84 white clears the 4.5:1 floor, so this rung is necessarily brighter
|
|
1346
|
+
than the panel's own --cg-text-secondary (0.82, 4.47:1). The surface is what
|
|
1347
|
+
would have to move to change that, not this value. */
|
|
1348
|
+
--cg-text-muted-strong: rgba(255, 255, 255, 0.86);
|
|
847
1349
|
--cg-text-accent: #ffffff;
|
|
848
1350
|
|
|
849
1351
|
/* ---- semantic-lines ---- */
|
|
@@ -945,6 +1447,14 @@
|
|
|
945
1447
|
--cg-text-primary: #ffffff;
|
|
946
1448
|
--cg-text-secondary: rgba(255, 255, 255, 0.78);
|
|
947
1449
|
--cg-text-muted: rgba(255, 255, 255, 0.56);
|
|
1450
|
+
/*
|
|
1451
|
+
8.02:1 on --cg-surface-code. Ink is the one ground where --cg-text-muted
|
|
1452
|
+
already clears the body floor (5.92:1), so this rung exists there for
|
|
1453
|
+
consistency of meaning rather than to fix a ratio: a component that reaches for
|
|
1454
|
+
text-faint-strong must resolve to something on all three surfaces, and
|
|
1455
|
+
resolving to the base #6a6a6a inside a dark scope would be the CLAUDE.md rule-3
|
|
1456
|
+
failure. It sits between the ink scope's muted (0.56) and its secondary (0.78). */
|
|
1457
|
+
--cg-text-muted-strong: rgba(255, 255, 255, 0.68);
|
|
948
1458
|
--cg-text-accent: var(--cg-secondary);
|
|
949
1459
|
|
|
950
1460
|
/* ---- semantic-surfaces ---- */
|