@cloudgrid-io/ui 0.5.0 → 0.7.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/entity-status.d.ts +13 -5
- package/dist/blocks/entity-status.d.ts.map +1 -1
- package/dist/blocks/entity-status.js +18 -2
- package/dist/blocks/entity-status.js.map +1 -1
- package/dist/theme.css +12 -2
- package/dist/tokens/base.json +74 -1
- package/dist/tokens/surface-ink.json +34 -1
- package/dist/tokens/surface-panel.json +34 -1
- package/dist/tokens.css +123 -3
- package/dist/tokens.json +16 -3
- package/package.json +1 -1
|
@@ -8,7 +8,7 @@
|
|
|
8
8
|
*
|
|
9
9
|
* ## The mapping is a table, and the table is the thing a designer edits
|
|
10
10
|
*
|
|
11
|
-
*
|
|
11
|
+
* Ten statuses, six tones. `ENTITY_STATUS_TONE` is the whole mapping and
|
|
12
12
|
* nothing else in this file branches on a status, so retuning what colour
|
|
13
13
|
* `paused` is means editing one line. `ENTITY_STATUS_LABEL` is the same
|
|
14
14
|
* arrangement for the words.
|
|
@@ -41,7 +41,7 @@
|
|
|
41
41
|
*
|
|
42
42
|
* ## Grounds
|
|
43
43
|
*
|
|
44
|
-
*
|
|
44
|
+
* Five tones sit on their own fill. `offline` sits on the card ground with a
|
|
45
45
|
* control border instead, which is #111's decision rather than this component's:
|
|
46
46
|
* the muted neutral on a neutral tint measures 2.90:1, under the bar, so absence
|
|
47
47
|
* of state deliberately has no fill of its own.
|
|
@@ -55,10 +55,10 @@
|
|
|
55
55
|
* both tables below and typecheck says so, which is the only arrangement where
|
|
56
56
|
* a half-added status cannot ship.
|
|
57
57
|
*/
|
|
58
|
-
export declare const ENTITY_STATUS_ORDER: readonly ["live", "building", "charged", "draft", "paused", "stopped", "archived", "expired", "error"];
|
|
58
|
+
export declare const ENTITY_STATUS_ORDER: readonly ["live", "unhealthy", "building", "charged", "draft", "paused", "stopped", "archived", "expired", "error"];
|
|
59
59
|
export type EntityStatusName = (typeof ENTITY_STATUS_ORDER)[number];
|
|
60
|
-
/** The
|
|
61
|
-
export type EntityStatusTone = "online" | "pending" | "offline" | "expired" | "danger";
|
|
60
|
+
/** The six families of the state palette. One token pair each. */
|
|
61
|
+
export type EntityStatusTone = "online" | "unhealthy" | "pending" | "offline" | "expired" | "danger";
|
|
62
62
|
/**
|
|
63
63
|
* THE MAPPING. Edit this to change what a status looks like.
|
|
64
64
|
*
|
|
@@ -80,6 +80,14 @@ export type EntityStatusTone = "online" | "pending" | "offline" | "expired" | "d
|
|
|
80
80
|
* `live` is the library's green, explicitly not the console's lime: the brand
|
|
81
81
|
* has already spent lime on decoration, so a lime "live" would not read as a
|
|
82
82
|
* signal.
|
|
83
|
+
*
|
|
84
|
+
* `unhealthy` is its OWN tone, added 2026-08-25 (#122). Before it existed the
|
|
85
|
+
* console had nowhere to put `live_unhealthy` and folded it onto `live`, so a
|
|
86
|
+
* degraded entity rendered green and a broken app looked healthy unless you
|
|
87
|
+
* read the word. It is deliberately not `expired` and not `danger`: expired is
|
|
88
|
+
* terminal, danger is failed, and this one is still serving and still fixable.
|
|
89
|
+
* `--cg-unhealthy` is a real value rather than an alias, so retuning it cannot
|
|
90
|
+
* move either of them.
|
|
83
91
|
*/
|
|
84
92
|
export declare const ENTITY_STATUS_TONE: Record<EntityStatusName, EntityStatusTone>;
|
|
85
93
|
/**
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"entity-status.d.ts","sourceRoot":"","sources":["../../src/blocks/entity-status.tsx"],"names":[],"mappings":"AAEA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA+CG;AAEH;;;;;;;;GAQG;AACH,eAAO,MAAM,mBAAmB,
|
|
1
|
+
{"version":3,"file":"entity-status.d.ts","sourceRoot":"","sources":["../../src/blocks/entity-status.tsx"],"names":[],"mappings":"AAEA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA+CG;AAEH;;;;;;;;GAQG;AACH,eAAO,MAAM,mBAAmB,qHAWtB,CAAA;AAEV,MAAM,MAAM,gBAAgB,GAAG,CAAC,OAAO,mBAAmB,CAAC,CAAC,MAAM,CAAC,CAAA;AAEnE,kEAAkE;AAClE,MAAM,MAAM,gBAAgB,GACxB,QAAQ,GACR,WAAW,GACX,SAAS,GACT,SAAS,GACT,SAAS,GACT,QAAQ,CAAA;AAEZ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA6BG;AACH,eAAO,MAAM,kBAAkB,EAAE,MAAM,CAAC,gBAAgB,EAAE,gBAAgB,CAWzE,CAAA;AAED;;;;GAIG;AACH,eAAO,MAAM,mBAAmB,EAAE,MAAM,CAAC,gBAAgB,EAAE,MAAM,CAehE,CAAA;AAmBD,iBAAS,YAAY,CAAC,EACpB,MAAM,EACN,KAAK,EACL,SAAS,EACT,GAAG,KAAK,EACT,EAAE,IAAI,CAAC,KAAK,CAAC,cAAc,CAAC,MAAM,CAAC,EAAE,UAAU,CAAC,GAAG;IAClD,MAAM,EAAE,gBAAgB,CAAA;IACxB,sFAAsF;IACtF,KAAK,CAAC,EAAE,KAAK,CAAC,SAAS,CAAA;CACxB,+BAqCA;AAED,OAAO,EAAE,YAAY,EAAE,CAAA"}
|
|
@@ -10,7 +10,7 @@ import { cn } from "../lib/cloudgrid-cn.js";
|
|
|
10
10
|
*
|
|
11
11
|
* ## The mapping is a table, and the table is the thing a designer edits
|
|
12
12
|
*
|
|
13
|
-
*
|
|
13
|
+
* Ten statuses, six tones. `ENTITY_STATUS_TONE` is the whole mapping and
|
|
14
14
|
* nothing else in this file branches on a status, so retuning what colour
|
|
15
15
|
* `paused` is means editing one line. `ENTITY_STATUS_LABEL` is the same
|
|
16
16
|
* arrangement for the words.
|
|
@@ -43,7 +43,7 @@ import { cn } from "../lib/cloudgrid-cn.js";
|
|
|
43
43
|
*
|
|
44
44
|
* ## Grounds
|
|
45
45
|
*
|
|
46
|
-
*
|
|
46
|
+
* Five tones sit on their own fill. `offline` sits on the card ground with a
|
|
47
47
|
* control border instead, which is #111's decision rather than this component's:
|
|
48
48
|
* the muted neutral on a neutral tint measures 2.90:1, under the bar, so absence
|
|
49
49
|
* of state deliberately has no fill of its own.
|
|
@@ -59,6 +59,7 @@ import { cn } from "../lib/cloudgrid-cn.js";
|
|
|
59
59
|
*/
|
|
60
60
|
export const ENTITY_STATUS_ORDER = [
|
|
61
61
|
"live",
|
|
62
|
+
"unhealthy",
|
|
62
63
|
"building",
|
|
63
64
|
"charged",
|
|
64
65
|
"draft",
|
|
@@ -89,9 +90,18 @@ export const ENTITY_STATUS_ORDER = [
|
|
|
89
90
|
* `live` is the library's green, explicitly not the console's lime: the brand
|
|
90
91
|
* has already spent lime on decoration, so a lime "live" would not read as a
|
|
91
92
|
* signal.
|
|
93
|
+
*
|
|
94
|
+
* `unhealthy` is its OWN tone, added 2026-08-25 (#122). Before it existed the
|
|
95
|
+
* console had nowhere to put `live_unhealthy` and folded it onto `live`, so a
|
|
96
|
+
* degraded entity rendered green and a broken app looked healthy unless you
|
|
97
|
+
* read the word. It is deliberately not `expired` and not `danger`: expired is
|
|
98
|
+
* terminal, danger is failed, and this one is still serving and still fixable.
|
|
99
|
+
* `--cg-unhealthy` is a real value rather than an alias, so retuning it cannot
|
|
100
|
+
* move either of them.
|
|
92
101
|
*/
|
|
93
102
|
export const ENTITY_STATUS_TONE = {
|
|
94
103
|
live: "online",
|
|
104
|
+
unhealthy: "unhealthy",
|
|
95
105
|
building: "pending",
|
|
96
106
|
charged: "offline",
|
|
97
107
|
draft: "offline",
|
|
@@ -108,6 +118,11 @@ export const ENTITY_STATUS_TONE = {
|
|
|
108
118
|
*/
|
|
109
119
|
export const ENTITY_STATUS_LABEL = {
|
|
110
120
|
live: "Live",
|
|
121
|
+
// Not "Live, degraded". The word is the whole meaning when the colour is
|
|
122
|
+
// unfamiliar, and a comma makes it read as a variant of Live rather than as
|
|
123
|
+
// its own state. A surface that knows more passes `label`, e.g. "Failing
|
|
124
|
+
// health checks".
|
|
125
|
+
unhealthy: "Unhealthy",
|
|
111
126
|
building: "Building",
|
|
112
127
|
charged: "Charged",
|
|
113
128
|
draft: "Draft",
|
|
@@ -126,6 +141,7 @@ export const ENTITY_STATUS_LABEL = {
|
|
|
126
141
|
*/
|
|
127
142
|
const TONE_STYLE = {
|
|
128
143
|
online: { chip: "border-transparent bg-online-fill", dot: "bg-online" },
|
|
144
|
+
unhealthy: { chip: "border-transparent bg-unhealthy-fill", dot: "bg-unhealthy" },
|
|
129
145
|
pending: { chip: "border-transparent bg-pending-fill", dot: "bg-pending" },
|
|
130
146
|
expired: { chip: "border-transparent bg-expired-fill", dot: "bg-expired" },
|
|
131
147
|
danger: { chip: "border-transparent bg-danger-fill", dot: "bg-danger" },
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"entity-status.js","sourceRoot":"","sources":["../../src/blocks/entity-status.tsx"],"names":[],"mappings":";AAAA,OAAO,EAAE,EAAE,EAAE,MAAM,oBAAoB,CAAA;AAEvC;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA+CG;AAEH;;;;;;;;GAQG;AACH,MAAM,CAAC,MAAM,mBAAmB,GAAG;IACjC,MAAM;IACN,UAAU;IACV,SAAS;IACT,OAAO;IACP,QAAQ;IACR,SAAS;IACT,UAAU;IACV,SAAS;IACT,OAAO;CACC,CAAA;
|
|
1
|
+
{"version":3,"file":"entity-status.js","sourceRoot":"","sources":["../../src/blocks/entity-status.tsx"],"names":[],"mappings":";AAAA,OAAO,EAAE,EAAE,EAAE,MAAM,oBAAoB,CAAA;AAEvC;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA+CG;AAEH;;;;;;;;GAQG;AACH,MAAM,CAAC,MAAM,mBAAmB,GAAG;IACjC,MAAM;IACN,WAAW;IACX,UAAU;IACV,SAAS;IACT,OAAO;IACP,QAAQ;IACR,SAAS;IACT,UAAU;IACV,SAAS;IACT,OAAO;CACC,CAAA;AAaV;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA6BG;AACH,MAAM,CAAC,MAAM,kBAAkB,GAA+C;IAC5E,IAAI,EAAE,QAAQ;IACd,SAAS,EAAE,WAAW;IACtB,QAAQ,EAAE,SAAS;IACnB,OAAO,EAAE,SAAS;IAClB,KAAK,EAAE,SAAS;IAChB,MAAM,EAAE,SAAS;IACjB,OAAO,EAAE,SAAS;IAClB,QAAQ,EAAE,SAAS;IACnB,OAAO,EAAE,SAAS;IAClB,KAAK,EAAE,QAAQ;CAChB,CAAA;AAED;;;;GAIG;AACH,MAAM,CAAC,MAAM,mBAAmB,GAAqC;IACnE,IAAI,EAAE,MAAM;IACZ,yEAAyE;IACzE,4EAA4E;IAC5E,yEAAyE;IACzE,kBAAkB;IAClB,SAAS,EAAE,WAAW;IACtB,QAAQ,EAAE,UAAU;IACpB,OAAO,EAAE,SAAS;IAClB,KAAK,EAAE,OAAO;IACd,MAAM,EAAE,QAAQ;IAChB,OAAO,EAAE,SAAS;IAClB,QAAQ,EAAE,UAAU;IACpB,OAAO,EAAE,SAAS;IAClB,KAAK,EAAE,OAAO;CACf,CAAA;AAED;;;;;;GAMG;AACH,MAAM,UAAU,GAA4D;IAC1E,MAAM,EAAE,EAAE,IAAI,EAAE,mCAAmC,EAAE,GAAG,EAAE,WAAW,EAAE;IACvE,SAAS,EAAE,EAAE,IAAI,EAAE,sCAAsC,EAAE,GAAG,EAAE,cAAc,EAAE;IAChF,OAAO,EAAE,EAAE,IAAI,EAAE,oCAAoC,EAAE,GAAG,EAAE,YAAY,EAAE;IAC1E,OAAO,EAAE,EAAE,IAAI,EAAE,oCAAoC,EAAE,GAAG,EAAE,YAAY,EAAE;IAC1E,MAAM,EAAE,EAAE,IAAI,EAAE,mCAAmC,EAAE,GAAG,EAAE,WAAW,EAAE;IACvE,8DAA8D;IAC9D,OAAO,EAAE,EAAE,IAAI,EAAE,qBAAqB,EAAE,GAAG,EAAE,YAAY,EAAE;CAC5D,CAAA;AAED,SAAS,YAAY,CAAC,EACpB,MAAM,EACN,KAAK,EACL,SAAS,EACT,GAAG,KAAK,EAKT;IACC,MAAM,IAAI,GAAG,kBAAkB,CAAC,MAAM,CAAC,CAAA;IACvC,MAAM,KAAK,GAAG,UAAU,CAAC,IAAI,CAAC,CAAA;IAE9B,OAAO,CACL,6BACY,eAAe,iBAIZ,MAAM,eACR,IAAI,EACf,SAAS,EAAE,EAAE,CACX,uIAAuI,EACvI,KAAK,CAAC,IAAI,EACV,SAAS,CACV,KACG,KAAK,aAET,8BAGc,MAAM,eACR,mBAAmB,EAC7B,SAAS,EAAE,EAAE,CACX,gCAAgC,EAChC,KAAK,CAAC,GAAG;gBACT,uEAAuE;gBACvE,uEAAuE;gBACvE,qEAAqE;gBACrE,8CAA8C;gBAC9C,MAAM,KAAK,UAAU,IAAI,2BAA2B,CACrD,GACD,EACD,KAAK,IAAI,mBAAmB,CAAC,MAAM,CAAC,IAChC,CACR,CAAA;AACH,CAAC;AAED,OAAO,EAAE,YAAY,EAAE,CAAA"}
|
package/dist/theme.css
CHANGED
|
@@ -98,7 +98,8 @@
|
|
|
98
98
|
--color-danger: var(--cg-danger);
|
|
99
99
|
|
|
100
100
|
/* ---- state ----
|
|
101
|
-
What an entity IS: online, offline, pending, expired, and danger
|
|
101
|
+
What an entity IS: online, offline, pending, unhealthy, expired, and danger
|
|
102
|
+
above.
|
|
102
103
|
|
|
103
104
|
#111 added the tokens and stopped there, so for one release the state
|
|
104
105
|
palette was reachable only as raw var(--cg-online). That is the shape #30
|
|
@@ -117,12 +118,21 @@
|
|
|
117
118
|
#111's note explains why, and it is a design decision rather than an
|
|
118
119
|
omission: the muted neutral on a neutral tint measures 2.90:1, under the
|
|
119
120
|
3:1 bar, so an unplugged chip uses the card ground and border-control
|
|
120
|
-
instead. A utility here would have to invent the value it maps.
|
|
121
|
+
instead. A utility here would have to invent the value it maps.
|
|
122
|
+
|
|
123
|
+
unhealthy (#122) arrives with its token rather than a release later, which
|
|
124
|
+
is the whole point of the guard that walks this block. #113 shipped the
|
|
125
|
+
`indicator` group with no bridge at all and nothing went red, because that
|
|
126
|
+
guard walks the `state` group and only that one. A token whose utility
|
|
127
|
+
lands in a later version is a token the first consumer reaches for and
|
|
128
|
+
does not find. */
|
|
121
129
|
--color-online: var(--cg-online);
|
|
122
130
|
--color-online-fill: var(--cg-online-fill);
|
|
123
131
|
--color-offline: var(--cg-offline);
|
|
124
132
|
--color-pending: var(--cg-pending);
|
|
125
133
|
--color-pending-fill: var(--cg-pending-fill);
|
|
134
|
+
--color-unhealthy: var(--cg-unhealthy);
|
|
135
|
+
--color-unhealthy-fill: var(--cg-unhealthy-fill);
|
|
126
136
|
--color-expired: var(--cg-expired);
|
|
127
137
|
--color-expired-fill: var(--cg-expired-fill);
|
|
128
138
|
--color-danger-fill: var(--cg-danger-fill);
|
package/dist/tokens/base.json
CHANGED
|
@@ -52,7 +52,7 @@
|
|
|
52
52
|
}
|
|
53
53
|
},
|
|
54
54
|
"state": {
|
|
55
|
-
"$description": "state: what an entity IS, not what it means editorially.\n\nAdopted from the Console rather than invented, 2026-08-24 (#96). The Console\nhad already chosen and contrast-tested these — --color-live and\n--color-attention — while the brand carried no state colour at all beyond the\ndanger placeholder. Taking its values means the Console's appearance does not\nchange when it starts consuming this package, and the two stop disagreeing\nabout what 'live' looks like.\n\nEach carries per-surface values in surface-panel and surface-ink, for the same\nreason danger does: measured against all three grounds, no single value works.\nThe live green is 1.72:1 on the purple panel, and the brand's own lime is\n1.54:1 on white. A flat value would be invisible somewhere.\n\nNo --cg-offline-fill, deliberately. Measured, the pair does not work: the\nmuted neutral on a neutral tint is 2.90:1, under the 3:1 bar for a dot or a\nborder. Rather than invent a value to satisfy the ratio, an unplugged chip\nuses the existing surface-card ground with border-control, and --cg-offline\nis the dot on that ground, where it measures 3.28:1. Absence of state should\nnot need a colour of its own.\n\npending joined them on 2026-08-24 (#114) as an ALIAS of expired rather than a\nnew value. Same amber today, separate name, so the two can diverge later with\na one-line edit here and no change in any consumer. Aliases compile to var(),\nso the flip survives.",
|
|
55
|
+
"$description": "state: what an entity IS, not what it means editorially.\n\nAdopted from the Console rather than invented, 2026-08-24 (#96). The Console\nhad already chosen and contrast-tested these — --color-live and\n--color-attention — while the brand carried no state colour at all beyond the\ndanger placeholder. Taking its values means the Console's appearance does not\nchange when it starts consuming this package, and the two stop disagreeing\nabout what 'live' looks like.\n\nEach carries per-surface values in surface-panel and surface-ink, for the same\nreason danger does: measured against all three grounds, no single value works.\nThe live green is 1.72:1 on the purple panel, and the brand's own lime is\n1.54:1 on white. A flat value would be invisible somewhere.\n\nNo --cg-offline-fill, deliberately. Measured, the pair does not work: the\nmuted neutral on a neutral tint is 2.90:1, under the 3:1 bar for a dot or a\nborder. Rather than invent a value to satisfy the ratio, an unplugged chip\nuses the existing surface-card ground with border-control, and --cg-offline\nis the dot on that ground, where it measures 3.28:1. Absence of state should\nnot need a colour of its own.\n\npending joined them on 2026-08-24 (#114) as an ALIAS of expired rather than a\nnew value. Same amber today, separate name, so the two can diverge later with\na one-line edit here and no change in any consumer. Aliases compile to var(),\nso the flip survives.\n\nunhealthy joined them on 2026-08-25 (#122) as a REAL value, not an alias, and\nit is the one tone here that was searched for rather than adopted. Founder\ndecision: expired is terminal, unhealthy is live-and-fixable, and sharing a\ntoken would mean retuning one silently retunes the other. It is a warmer,\nbrighter gold on the same ramp as the amber rather than a new hue family,\nbecause green/amber/red is the traffic light an operator already reads and\n'serving but degraded' is its middle rung. Its own note carries the numbers\nand the three families that were measured and rejected.",
|
|
56
56
|
"online": {
|
|
57
57
|
"$value": "#00a05c",
|
|
58
58
|
"$type": "color",
|
|
@@ -91,6 +91,16 @@
|
|
|
91
91
|
}
|
|
92
92
|
}
|
|
93
93
|
},
|
|
94
|
+
"unhealthy": {
|
|
95
|
+
"$value": "#7F7301",
|
|
96
|
+
"$type": "color",
|
|
97
|
+
"$description": "Serving, and degraded. The entity is up and answering; its health checks are not. 4.82:1 on white and 4.46:1 on its own fill — an indicator, like every tone here, never body text.\n\nA REAL value rather than an alias, which is the whole decision. Founder, 2026-08-25, issue #122: expired is terminal, unhealthy is live-and-fixable, and one token for both would mean a designer retuning one silently retunes the other. That is the same reasoning that gave pending its own NAME in #114 — this one also needs its own VALUE, because it must not read as either of the states it sits between.\n\nWHY A GOLD, measured rather than asserted. Green/amber/red is the traffic light an operator already reads, and this palette's amber is spent on two states that are both benign: pending is transitional, expired is terminal. Unhealthy is the warning rung, so it takes the warmer, brighter, more saturated seat on the same ramp rather than a different hue family.\n\nThe alternatives were searched, not guessed, over every hue at 5-degree steps against all four existing tones on all three surfaces:\n\n magenta h339 13.7 from danger on the panel, where danger is a pale pink.\n The one confusion that matters most, and a new palette worst.\n azure h235 the best normal-vision numbers of anything measured (21.5),\n and 1.2 from panel offline for a deuteranope — a degraded\n entity would be indistinguishable from a stopped one.\n chartreuse 10-14 from --cg-secondary and --cg-volt. It IS the brand lime,\n and #114 already ruled a lime cannot signal state.\n\ndE2000 on white: online 28.4, offline 26.6, expired/pending 22.3, danger 43.1. The tightest pair is expired, as expected for the neighbouring rung, and 22.3 is wider than the tightest pair this palette already ships on white (19.4, expired/danger).\n\nKNOWN, and recorded rather than tuned away: on ink the pair is 18.3, which is a new worst for that surface (was 25.3). It stays above the palette's global floor of 16.5, and buying more would mean walking into --cg-secondary (16.5 away) or --cg-volt (17.8). A light amber and a light gold have the least room on a dark ground; that is the cost of putting them on one ramp deliberately.",
|
|
98
|
+
"$extensions": {
|
|
99
|
+
"io.cloudgrid": {
|
|
100
|
+
"css": "--cg-unhealthy"
|
|
101
|
+
}
|
|
102
|
+
}
|
|
103
|
+
},
|
|
94
104
|
"online-fill": {
|
|
95
105
|
"$value": "#e6f7ef",
|
|
96
106
|
"$type": "color",
|
|
@@ -120,6 +130,16 @@
|
|
|
120
130
|
}
|
|
121
131
|
}
|
|
122
132
|
},
|
|
133
|
+
"unhealthy-fill": {
|
|
134
|
+
"$value": "#fdf6df",
|
|
135
|
+
"$type": "color",
|
|
136
|
+
"$description": "The chip ground for unhealthy. --cg-unhealthy measures 4.46:1 on it.\n\nA pale tint of its own foreground, in the same family as online-fill and expired-fill, so the five chips read as one set rather than as four tints and an exception. It is deliberately NOT expired-fill: a shared ground would put the two warm states on the same card and undo half of what the separate foreground buys.",
|
|
137
|
+
"$extensions": {
|
|
138
|
+
"io.cloudgrid": {
|
|
139
|
+
"css": "--cg-unhealthy-fill"
|
|
140
|
+
}
|
|
141
|
+
}
|
|
142
|
+
},
|
|
123
143
|
"danger-fill": {
|
|
124
144
|
"$value": "#fceded",
|
|
125
145
|
"$type": "color",
|
|
@@ -1138,5 +1158,58 @@
|
|
|
1138
1158
|
}
|
|
1139
1159
|
}
|
|
1140
1160
|
}
|
|
1161
|
+
},
|
|
1162
|
+
"indicator": {
|
|
1163
|
+
"$description": "indicator + chrome: taken from the Console so the system holds every value in\none place, 2026-08-24 (#96).\n\nPENDING A DESIGNER. These are adopted as-is, not designed. They are here so the\nConsole can stop carrying private copies and so there is a single thing to edit;\nthe values themselves are the Console's current ones and are expected to change.\nMeasurements are recorded beside each so the decision is informed rather than\ninherited.",
|
|
1164
|
+
"volt": {
|
|
1165
|
+
"$value": "#b6ff2e",
|
|
1166
|
+
"$type": "color",
|
|
1167
|
+
"$description": "The live/current INDICATOR — the dot in its halo, and the brand mark. Never\ndecorative, never a fill.\n\nMEASURED 1.21:1 on white, which is below every bar there is. It works on the\npanel (4.82:1) and on ink (13.13:1); on the page ground it reads only because\nit is paired with the ring and, in a pill, with volt-ink. Recorded rather than\nsilently corrected: darkening it would change the Console's appearance, which\nis a design decision and not a contrast fix.\n\nNote it is a SECOND lime beside --cg-secondary (#b6de68), 36 dE away. Which one\nthe brand owns is the open question here.\n\nIt is also a second LIVE. state.online (#00a05c) is the same idea in the state\nscale, and EntityStatus (#116) already paints the live dot with it. They are not\ninterchangeable at any bar — online is 3.40:1 on white, volt is 1.21:1 — so a\nsurface must not swap one for the other on the assumption that both mean\n'serving'. Which name the brand keeps for live belongs to the same open question,\nand until it is answered volt is the Console's brand mark and online is the\nentity's state.",
|
|
1168
|
+
"$extensions": {
|
|
1169
|
+
"io.cloudgrid": {
|
|
1170
|
+
"css": "--cg-volt"
|
|
1171
|
+
}
|
|
1172
|
+
}
|
|
1173
|
+
},
|
|
1174
|
+
"volt-ring": {
|
|
1175
|
+
"$value": "rgba(182, 255, 46, 0.32)",
|
|
1176
|
+
"$type": "color",
|
|
1177
|
+
"$description": "The halo behind a volt dot. Its job is to make the dot findable on a light ground, which is what carries the 1.21:1 above.",
|
|
1178
|
+
"$extensions": {
|
|
1179
|
+
"io.cloudgrid": {
|
|
1180
|
+
"css": "--cg-volt-ring"
|
|
1181
|
+
}
|
|
1182
|
+
}
|
|
1183
|
+
},
|
|
1184
|
+
"volt-ink": {
|
|
1185
|
+
"$value": "#243d00",
|
|
1186
|
+
"$type": "color",
|
|
1187
|
+
"$description": "Text and glyphs ON volt. 9.95:1 against it — the one part of the volt family that\nis comfortably legible.\n\nThis is NOT the state -ink that EntityStatus (#116) says the library lacks. That\nnote wants a foreground for the WORD on a state chip, and the arrangement it\nshipped instead — dot carries the colour, word is text-ink — already measures\n14.33:1 on online-fill, against 10.86:1 for this olive. volt-ink is tuned to volt\nand belongs to volt. Adding a state -ink is still a brand decision and still\nopen.",
|
|
1188
|
+
"$extensions": {
|
|
1189
|
+
"io.cloudgrid": {
|
|
1190
|
+
"css": "--cg-volt-ink"
|
|
1191
|
+
}
|
|
1192
|
+
}
|
|
1193
|
+
},
|
|
1194
|
+
"scrim": {
|
|
1195
|
+
"$value": "rgba(34, 34, 34, 0.4)",
|
|
1196
|
+
"$type": "color",
|
|
1197
|
+
"$description": "The wash behind a modal or overlay. Uses the BRAND ink (#222222) rather than the\nConsole's (#16181d) — a scrim sits above content and belongs to the system, not\nto one surface's ink scale.\n\nDoes NOT flip per surface, deliberately: it composites over whatever is beneath\nit, so a panel-scoped override would darken a scrim that is already dark.",
|
|
1198
|
+
"$extensions": {
|
|
1199
|
+
"io.cloudgrid": {
|
|
1200
|
+
"css": "--cg-scrim"
|
|
1201
|
+
}
|
|
1202
|
+
}
|
|
1203
|
+
},
|
|
1204
|
+
"hover": {
|
|
1205
|
+
"$value": "rgba(34, 34, 34, 0.045)",
|
|
1206
|
+
"$type": "color",
|
|
1207
|
+
"$description": "The wash under a hovered row or control. The system had no hover token; components were each inventing one.",
|
|
1208
|
+
"$extensions": {
|
|
1209
|
+
"io.cloudgrid": {
|
|
1210
|
+
"css": "--cg-hover"
|
|
1211
|
+
}
|
|
1212
|
+
}
|
|
1213
|
+
}
|
|
1141
1214
|
}
|
|
1142
1215
|
}
|
|
@@ -134,7 +134,7 @@
|
|
|
134
134
|
}
|
|
135
135
|
},
|
|
136
136
|
"state": {
|
|
137
|
-
"$description": "state: the per-surface values for online/offline/expired. Same necessity as danger — measured, not assumed. pending is an alias of expired (#114), declared here so it flips rather than freezing to the base scope.",
|
|
137
|
+
"$description": "state: the per-surface values for online/offline/expired. Same necessity as danger — measured, not assumed. pending is an alias of expired (#114), declared here so it flips rather than freezing to the base scope. unhealthy (#122) is a real value rather than an alias, and needs the same per-surface treatment for the same reason every other tone here does: its base gold is unreadable on this ground.",
|
|
138
138
|
"online": {
|
|
139
139
|
"$value": "#5FD99A",
|
|
140
140
|
"$type": "color",
|
|
@@ -174,6 +174,16 @@
|
|
|
174
174
|
}
|
|
175
175
|
}
|
|
176
176
|
},
|
|
177
|
+
"unhealthy": {
|
|
178
|
+
"$value": "#F1DC03",
|
|
179
|
+
"$type": "color",
|
|
180
|
+
"$description": "11.35:1 on #222, 8.88:1 on its own fill. Ink has headroom, so the gold stays a gold instead of washing to cream.\n\nThis is the tightest the tone gets anywhere: 18.3 from expired, which is a new worst pair for this surface (was 25.3, offline/danger) while staying above the palette's global floor of 16.5. Recorded rather than tuned away — a light amber and a light gold have the least room on a dark ground, and the next 2 points of separation would walk into --cg-secondary (16.5 away) or --cg-volt (17.8). The pair that matters most is unaffected: 31.3 from online.",
|
|
181
|
+
"$extensions": {
|
|
182
|
+
"io.cloudgrid": {
|
|
183
|
+
"css": "--cg-unhealthy"
|
|
184
|
+
}
|
|
185
|
+
}
|
|
186
|
+
},
|
|
177
187
|
"online-fill": {
|
|
178
188
|
"$value": "rgba(255, 255, 255, 0.08)",
|
|
179
189
|
"$type": "color",
|
|
@@ -203,6 +213,16 @@
|
|
|
203
213
|
}
|
|
204
214
|
}
|
|
205
215
|
},
|
|
216
|
+
"unhealthy-fill": {
|
|
217
|
+
"$value": "rgba(255, 255, 255, 0.08)",
|
|
218
|
+
"$type": "color",
|
|
219
|
+
"$description": "Translucent white; the ink foreground measures 11.42:1 on it.",
|
|
220
|
+
"$extensions": {
|
|
221
|
+
"io.cloudgrid": {
|
|
222
|
+
"css": "--cg-unhealthy-fill"
|
|
223
|
+
}
|
|
224
|
+
}
|
|
225
|
+
},
|
|
206
226
|
"danger-fill": {
|
|
207
227
|
"$value": "rgba(255, 255, 255, 0.08)",
|
|
208
228
|
"$type": "color",
|
|
@@ -213,5 +233,18 @@
|
|
|
213
233
|
}
|
|
214
234
|
}
|
|
215
235
|
}
|
|
236
|
+
},
|
|
237
|
+
"indicator": {
|
|
238
|
+
"$description": "indicator + chrome: only hover flips. A dark wash is invisible on a dark ground.",
|
|
239
|
+
"hover": {
|
|
240
|
+
"$value": "rgba(255, 255, 255, 0.06)",
|
|
241
|
+
"$type": "color",
|
|
242
|
+
"$description": "Translucent white — the base wash is a dark ink and would not register on the ink ground.",
|
|
243
|
+
"$extensions": {
|
|
244
|
+
"io.cloudgrid": {
|
|
245
|
+
"css": "--cg-hover"
|
|
246
|
+
}
|
|
247
|
+
}
|
|
248
|
+
}
|
|
216
249
|
}
|
|
217
250
|
}
|
|
@@ -118,7 +118,7 @@
|
|
|
118
118
|
}
|
|
119
119
|
},
|
|
120
120
|
"state": {
|
|
121
|
-
"$description": "state: the per-surface values for online/offline/expired. Same necessity as danger — measured, not assumed. pending is an alias of expired (#114), declared here so it flips rather than freezing to the base scope.",
|
|
121
|
+
"$description": "state: the per-surface values for online/offline/expired. Same necessity as danger — measured, not assumed. pending is an alias of expired (#114), declared here so it flips rather than freezing to the base scope. unhealthy (#122) is a real value rather than an alias, and needs the same per-surface treatment for the same reason every other tone here does: its base gold is unreadable on this ground.",
|
|
122
122
|
"online": {
|
|
123
123
|
"$value": "#C8F5DC",
|
|
124
124
|
"$type": "color",
|
|
@@ -158,6 +158,16 @@
|
|
|
158
158
|
}
|
|
159
159
|
}
|
|
160
160
|
},
|
|
161
|
+
"unhealthy": {
|
|
162
|
+
"$value": "#F7E20C",
|
|
163
|
+
"$type": "color",
|
|
164
|
+
"$description": "4.41:1 on the purple, 3.27:1 on its own fill. The source gold is 1.09:1 on this ground — invisible, same class as the danger override.\n\nThis is the surface that DECIDED the value. A dot on a panel chip has to clear 3:1 against rgba(255,255,255,0.16) over #5a47f0, whose relative luminance is 0.192; that forces the dot's own luminance above 0.677, i.e. Lab L >= 86, which is why every state value here is a near-white tint. Four already occupy that sliver at hues 29, 81, 159 and 297, and a fifth has to fit between them. The gold sits at hue 97, 20.0 from expired and 29.5 from online.\n\nIt is louder than its four siblings, deliberately: a warning that recedes is not doing its job, and chroma is the only axis left once lightness is pinned by the contrast floor.",
|
|
165
|
+
"$extensions": {
|
|
166
|
+
"io.cloudgrid": {
|
|
167
|
+
"css": "--cg-unhealthy"
|
|
168
|
+
}
|
|
169
|
+
}
|
|
170
|
+
},
|
|
161
171
|
"online-fill": {
|
|
162
172
|
"$value": "rgba(255, 255, 255, 0.16)",
|
|
163
173
|
"$type": "color",
|
|
@@ -187,6 +197,16 @@
|
|
|
187
197
|
}
|
|
188
198
|
}
|
|
189
199
|
},
|
|
200
|
+
"unhealthy-fill": {
|
|
201
|
+
"$value": "rgba(255, 255, 255, 0.16)",
|
|
202
|
+
"$type": "color",
|
|
203
|
+
"$description": "Translucent white rather than a tint, like every other chip ground here; the panel foreground measures 4.33:1 on it. Written out rather than aliased to online-fill for the same reason the others are: four tokens that happen to share a value are not one token.",
|
|
204
|
+
"$extensions": {
|
|
205
|
+
"io.cloudgrid": {
|
|
206
|
+
"css": "--cg-unhealthy-fill"
|
|
207
|
+
}
|
|
208
|
+
}
|
|
209
|
+
},
|
|
190
210
|
"danger-fill": {
|
|
191
211
|
"$value": "rgba(255, 255, 255, 0.16)",
|
|
192
212
|
"$type": "color",
|
|
@@ -197,5 +217,18 @@
|
|
|
197
217
|
}
|
|
198
218
|
}
|
|
199
219
|
}
|
|
220
|
+
},
|
|
221
|
+
"indicator": {
|
|
222
|
+
"$description": "indicator + chrome: only hover flips. A dark wash is invisible on a dark ground.",
|
|
223
|
+
"hover": {
|
|
224
|
+
"$value": "rgba(255, 255, 255, 0.10)",
|
|
225
|
+
"$type": "color",
|
|
226
|
+
"$description": "Translucent white — the base wash is a dark ink and would not register on the panel ground.",
|
|
227
|
+
"$extensions": {
|
|
228
|
+
"io.cloudgrid": {
|
|
229
|
+
"css": "--cg-hover"
|
|
230
|
+
}
|
|
231
|
+
}
|
|
232
|
+
}
|
|
200
233
|
}
|
|
201
234
|
}
|
package/dist/tokens.css
CHANGED
|
@@ -98,7 +98,16 @@
|
|
|
98
98
|
pending joined them on 2026-08-24 (#114) as an ALIAS of expired rather than a
|
|
99
99
|
new value. Same amber today, separate name, so the two can diverge later with
|
|
100
100
|
a one-line edit here and no change in any consumer. Aliases compile to var(),
|
|
101
|
-
so the flip survives.
|
|
101
|
+
so the flip survives.
|
|
102
|
+
|
|
103
|
+
unhealthy joined them on 2026-08-25 (#122) as a REAL value, not an alias, and
|
|
104
|
+
it is the one tone here that was searched for rather than adopted. Founder
|
|
105
|
+
decision: expired is terminal, unhealthy is live-and-fixable, and sharing a
|
|
106
|
+
token would mean retuning one silently retunes the other. It is a warmer,
|
|
107
|
+
brighter gold on the same ramp as the amber rather than a new hue family,
|
|
108
|
+
because green/amber/red is the traffic light an operator already reads and
|
|
109
|
+
'serving but degraded' is its middle rung. Its own note carries the numbers
|
|
110
|
+
and the three families that were measured and rejected. */
|
|
102
111
|
/*
|
|
103
112
|
Serving. From the Console's --color-live. 3.40:1 on white — clears the 3:1 bar for an indicator, which is all this is ever used as. Never body text on white. */
|
|
104
113
|
--cg-online: #00a05c;
|
|
@@ -115,6 +124,27 @@
|
|
|
115
124
|
|
|
116
125
|
Founder decision 2026-08-24, issue #114: "building is like something in progress, something in between amber and yellow and orange." */
|
|
117
126
|
--cg-pending: var(--cg-expired);
|
|
127
|
+
/*
|
|
128
|
+
Serving, and degraded. The entity is up and answering; its health checks are not. 4.82:1 on white and 4.46:1 on its own fill — an indicator, like every tone here, never body text.
|
|
129
|
+
|
|
130
|
+
A REAL value rather than an alias, which is the whole decision. Founder, 2026-08-25, issue #122: expired is terminal, unhealthy is live-and-fixable, and one token for both would mean a designer retuning one silently retunes the other. That is the same reasoning that gave pending its own NAME in #114 — this one also needs its own VALUE, because it must not read as either of the states it sits between.
|
|
131
|
+
|
|
132
|
+
WHY A GOLD, measured rather than asserted. Green/amber/red is the traffic light an operator already reads, and this palette's amber is spent on two states that are both benign: pending is transitional, expired is terminal. Unhealthy is the warning rung, so it takes the warmer, brighter, more saturated seat on the same ramp rather than a different hue family.
|
|
133
|
+
|
|
134
|
+
The alternatives were searched, not guessed, over every hue at 5-degree steps against all four existing tones on all three surfaces:
|
|
135
|
+
|
|
136
|
+
magenta h339 13.7 from danger on the panel, where danger is a pale pink.
|
|
137
|
+
The one confusion that matters most, and a new palette worst.
|
|
138
|
+
azure h235 the best normal-vision numbers of anything measured (21.5),
|
|
139
|
+
and 1.2 from panel offline for a deuteranope — a degraded
|
|
140
|
+
entity would be indistinguishable from a stopped one.
|
|
141
|
+
chartreuse 10-14 from --cg-secondary and --cg-volt. It IS the brand lime,
|
|
142
|
+
and #114 already ruled a lime cannot signal state.
|
|
143
|
+
|
|
144
|
+
dE2000 on white: online 28.4, offline 26.6, expired/pending 22.3, danger 43.1. The tightest pair is expired, as expected for the neighbouring rung, and 22.3 is wider than the tightest pair this palette already ships on white (19.4, expired/danger).
|
|
145
|
+
|
|
146
|
+
KNOWN, and recorded rather than tuned away: on ink the pair is 18.3, which is a new worst for that surface (was 25.3). It stays above the palette's global floor of 16.5, and buying more would mean walking into --cg-secondary (16.5 away) or --cg-volt (17.8). A light amber and a light gold have the least room on a dark ground; that is the cost of putting them on one ramp deliberately. */
|
|
147
|
+
--cg-unhealthy: #7F7301;
|
|
118
148
|
/*
|
|
119
149
|
From the Console's --color-live-fill. --cg-online measures 3.06:1 on it. */
|
|
120
150
|
--cg-online-fill: #e6f7ef;
|
|
@@ -124,6 +154,11 @@
|
|
|
124
154
|
/*
|
|
125
155
|
The chip ground for pending, aliased to expired's for the same reason the foreground is. Splitting pending from expired later means editing these two entries and nothing else. */
|
|
126
156
|
--cg-pending-fill: var(--cg-expired-fill);
|
|
157
|
+
/*
|
|
158
|
+
The chip ground for unhealthy. --cg-unhealthy measures 4.46:1 on it.
|
|
159
|
+
|
|
160
|
+
A pale tint of its own foreground, in the same family as online-fill and expired-fill, so the five chips read as one set rather than as four tints and an exception. It is deliberately NOT expired-fill: a shared ground would put the two warm states on the same card and undo half of what the separate foreground buys. */
|
|
161
|
+
--cg-unhealthy-fill: #fdf6df;
|
|
127
162
|
/*
|
|
128
163
|
From the Console's --color-error-fill. --cg-danger measures 3.72:1 on it. danger had no fill before; a chip needs one. */
|
|
129
164
|
--cg-danger-fill: #fceded;
|
|
@@ -302,6 +337,62 @@
|
|
|
302
337
|
--cg-transition-control: background-color var(--cg-duration) var(--cg-ease-out), border-color var(--cg-duration) var(--cg-ease-out), color var(--cg-duration) var(--cg-ease-out), box-shadow var(--cg-duration) var(--cg-ease-out);
|
|
303
338
|
--cg-lift-hover: translateY(-1px);
|
|
304
339
|
--cg-press-scale: 0.985;
|
|
340
|
+
|
|
341
|
+
/* ---- indicator ----
|
|
342
|
+
indicator + chrome: taken from the Console so the system holds every value in
|
|
343
|
+
one place, 2026-08-24 (#96).
|
|
344
|
+
|
|
345
|
+
PENDING A DESIGNER. These are adopted as-is, not designed. They are here so the
|
|
346
|
+
Console can stop carrying private copies and so there is a single thing to edit;
|
|
347
|
+
the values themselves are the Console's current ones and are expected to change.
|
|
348
|
+
Measurements are recorded beside each so the decision is informed rather than
|
|
349
|
+
inherited. */
|
|
350
|
+
/*
|
|
351
|
+
The live/current INDICATOR — the dot in its halo, and the brand mark. Never
|
|
352
|
+
decorative, never a fill.
|
|
353
|
+
|
|
354
|
+
MEASURED 1.21:1 on white, which is below every bar there is. It works on the
|
|
355
|
+
panel (4.82:1) and on ink (13.13:1); on the page ground it reads only because
|
|
356
|
+
it is paired with the ring and, in a pill, with volt-ink. Recorded rather than
|
|
357
|
+
silently corrected: darkening it would change the Console's appearance, which
|
|
358
|
+
is a design decision and not a contrast fix.
|
|
359
|
+
|
|
360
|
+
Note it is a SECOND lime beside --cg-secondary (#b6de68), 36 dE away. Which one
|
|
361
|
+
the brand owns is the open question here.
|
|
362
|
+
|
|
363
|
+
It is also a second LIVE. state.online (#00a05c) is the same idea in the state
|
|
364
|
+
scale, and EntityStatus (#116) already paints the live dot with it. They are not
|
|
365
|
+
interchangeable at any bar — online is 3.40:1 on white, volt is 1.21:1 — so a
|
|
366
|
+
surface must not swap one for the other on the assumption that both mean
|
|
367
|
+
'serving'. Which name the brand keeps for live belongs to the same open question,
|
|
368
|
+
and until it is answered volt is the Console's brand mark and online is the
|
|
369
|
+
entity's state. */
|
|
370
|
+
--cg-volt: #b6ff2e;
|
|
371
|
+
/*
|
|
372
|
+
The halo behind a volt dot. Its job is to make the dot findable on a light ground, which is what carries the 1.21:1 above. */
|
|
373
|
+
--cg-volt-ring: rgba(182, 255, 46, 0.32);
|
|
374
|
+
/*
|
|
375
|
+
Text and glyphs ON volt. 9.95:1 against it — the one part of the volt family that
|
|
376
|
+
is comfortably legible.
|
|
377
|
+
|
|
378
|
+
This is NOT the state -ink that EntityStatus (#116) says the library lacks. That
|
|
379
|
+
note wants a foreground for the WORD on a state chip, and the arrangement it
|
|
380
|
+
shipped instead — dot carries the colour, word is text-ink — already measures
|
|
381
|
+
14.33:1 on online-fill, against 10.86:1 for this olive. volt-ink is tuned to volt
|
|
382
|
+
and belongs to volt. Adding a state -ink is still a brand decision and still
|
|
383
|
+
open. */
|
|
384
|
+
--cg-volt-ink: #243d00;
|
|
385
|
+
/*
|
|
386
|
+
The wash behind a modal or overlay. Uses the BRAND ink (#222222) rather than the
|
|
387
|
+
Console's (#16181d) — a scrim sits above content and belongs to the system, not
|
|
388
|
+
to one surface's ink scale.
|
|
389
|
+
|
|
390
|
+
Does NOT flip per surface, deliberately: it composites over whatever is beneath
|
|
391
|
+
it, so a panel-scoped override would darken a scrim that is already dark. */
|
|
392
|
+
--cg-scrim: rgba(34, 34, 34, 0.4);
|
|
393
|
+
/*
|
|
394
|
+
The wash under a hovered row or control. The system had no hover token; components were each inventing one. */
|
|
395
|
+
--cg-hover: rgba(34, 34, 34, 0.045);
|
|
305
396
|
}
|
|
306
397
|
|
|
307
398
|
[data-cg-surface='panel'] {
|
|
@@ -332,7 +423,7 @@
|
|
|
332
423
|
--cg-danger: #FFDAD6;
|
|
333
424
|
|
|
334
425
|
/* ---- state ----
|
|
335
|
-
state: the per-surface values for online/offline/expired. Same necessity as danger — measured, not assumed. pending is an alias of expired (#114), declared here so it flips rather than freezing to the base scope. */
|
|
426
|
+
state: the per-surface values for online/offline/expired. Same necessity as danger — measured, not assumed. pending is an alias of expired (#114), declared here so it flips rather than freezing to the base scope. unhealthy (#122) is a real value rather than an alias, and needs the same per-surface treatment for the same reason every other tone here does: its base gold is unreadable on this ground. */
|
|
336
427
|
/*
|
|
337
428
|
4.88:1 on the purple. The source green is 1.72:1 here — invisible, same class as the danger override. */
|
|
338
429
|
--cg-online: #C8F5DC;
|
|
@@ -345,6 +436,13 @@
|
|
|
345
436
|
/*
|
|
346
437
|
Aliased to expired, which is 4.68:1 on the purple. Declared here as well as at :root because an alias is substituted where it is DECLARED — a :root-only pending would freeze to the white-surface amber and stop flipping, with no error. */
|
|
347
438
|
--cg-pending: var(--cg-expired);
|
|
439
|
+
/*
|
|
440
|
+
4.41:1 on the purple, 3.27:1 on its own fill. The source gold is 1.09:1 on this ground — invisible, same class as the danger override.
|
|
441
|
+
|
|
442
|
+
This is the surface that DECIDED the value. A dot on a panel chip has to clear 3:1 against rgba(255,255,255,0.16) over #5a47f0, whose relative luminance is 0.192; that forces the dot's own luminance above 0.677, i.e. Lab L >= 86, which is why every state value here is a near-white tint. Four already occupy that sliver at hues 29, 81, 159 and 297, and a fifth has to fit between them. The gold sits at hue 97, 20.0 from expired and 29.5 from online.
|
|
443
|
+
|
|
444
|
+
It is louder than its four siblings, deliberately: a warning that recedes is not doing its job, and chroma is the only axis left once lightness is pinned by the contrast floor. */
|
|
445
|
+
--cg-unhealthy: #F7E20C;
|
|
348
446
|
/*
|
|
349
447
|
Translucent white rather than a tint; the panel foreground measures 3.62:1 on it. */
|
|
350
448
|
--cg-online-fill: rgba(255, 255, 255, 0.16);
|
|
@@ -354,9 +452,18 @@
|
|
|
354
452
|
/*
|
|
355
453
|
Aliased to expired-fill. Declared per scope for the same reason the foreground is. */
|
|
356
454
|
--cg-pending-fill: var(--cg-expired-fill);
|
|
455
|
+
/*
|
|
456
|
+
Translucent white rather than a tint, like every other chip ground here; the panel foreground measures 4.33:1 on it. Written out rather than aliased to online-fill for the same reason the others are: four tokens that happen to share a value are not one token. */
|
|
457
|
+
--cg-unhealthy-fill: rgba(255, 255, 255, 0.16);
|
|
357
458
|
/*
|
|
358
459
|
Translucent white rather than a tint; the panel foreground measures 3.35:1 on it. */
|
|
359
460
|
--cg-danger-fill: rgba(255, 255, 255, 0.16);
|
|
461
|
+
|
|
462
|
+
/* ---- indicator ----
|
|
463
|
+
indicator + chrome: only hover flips. A dark wash is invisible on a dark ground. */
|
|
464
|
+
/*
|
|
465
|
+
Translucent white — the base wash is a dark ink and would not register on the panel ground. */
|
|
466
|
+
--cg-hover: rgba(255, 255, 255, 0.10);
|
|
360
467
|
}
|
|
361
468
|
|
|
362
469
|
[data-cg-surface='ink'] {
|
|
@@ -389,7 +496,7 @@
|
|
|
389
496
|
--cg-danger: #FF8A80;
|
|
390
497
|
|
|
391
498
|
/* ---- state ----
|
|
392
|
-
state: the per-surface values for online/offline/expired. Same necessity as danger — measured, not assumed. pending is an alias of expired (#114), declared here so it flips rather than freezing to the base scope. */
|
|
499
|
+
state: the per-surface values for online/offline/expired. Same necessity as danger — measured, not assumed. pending is an alias of expired (#114), declared here so it flips rather than freezing to the base scope. unhealthy (#122) is a real value rather than an alias, and needs the same per-surface treatment for the same reason every other tone here does: its base gold is unreadable on this ground. */
|
|
393
500
|
/*
|
|
394
501
|
9.00:1 on #222. Ink has headroom, so this stays a recognisable green rather than washing to mint. */
|
|
395
502
|
--cg-online: #5FD99A;
|
|
@@ -400,6 +507,11 @@
|
|
|
400
507
|
/*
|
|
401
508
|
Aliased to expired, which is 8.63:1 on #222. Declared here as well as at :root because an alias is substituted where it is DECLARED — a :root-only pending would freeze to the white-surface amber and stop flipping, with no error. */
|
|
402
509
|
--cg-pending: var(--cg-expired);
|
|
510
|
+
/*
|
|
511
|
+
11.35:1 on #222, 8.88:1 on its own fill. Ink has headroom, so the gold stays a gold instead of washing to cream.
|
|
512
|
+
|
|
513
|
+
This is the tightest the tone gets anywhere: 18.3 from expired, which is a new worst pair for this surface (was 25.3, offline/danger) while staying above the palette's global floor of 16.5. Recorded rather than tuned away — a light amber and a light gold have the least room on a dark ground, and the next 2 points of separation would walk into --cg-secondary (16.5 away) or --cg-volt (17.8). The pair that matters most is unaffected: 31.3 from online. */
|
|
514
|
+
--cg-unhealthy: #F1DC03;
|
|
403
515
|
/* Translucent white; the ink foreground measures 7.04:1 on it. */
|
|
404
516
|
--cg-online-fill: rgba(255, 255, 255, 0.08);
|
|
405
517
|
/* Translucent white; the ink foreground measures 6.76:1 on it. */
|
|
@@ -407,6 +519,14 @@
|
|
|
407
519
|
/*
|
|
408
520
|
Aliased to expired-fill. Declared per scope for the same reason the foreground is. */
|
|
409
521
|
--cg-pending-fill: var(--cg-expired-fill);
|
|
522
|
+
/* Translucent white; the ink foreground measures 11.42:1 on it. */
|
|
523
|
+
--cg-unhealthy-fill: rgba(255, 255, 255, 0.08);
|
|
410
524
|
/* Translucent white; the ink foreground measures 5.45:1 on it. */
|
|
411
525
|
--cg-danger-fill: rgba(255, 255, 255, 0.08);
|
|
526
|
+
|
|
527
|
+
/* ---- indicator ----
|
|
528
|
+
indicator + chrome: only hover flips. A dark wash is invisible on a dark ground. */
|
|
529
|
+
/*
|
|
530
|
+
Translucent white — the base wash is a dark ink and would not register on the ink ground. */
|
|
531
|
+
--cg-hover: rgba(255, 255, 255, 0.06);
|
|
412
532
|
}
|
package/dist/tokens.json
CHANGED
|
@@ -12,9 +12,11 @@
|
|
|
12
12
|
"--cg-offline": "var(--cg-neutral-500)",
|
|
13
13
|
"--cg-expired": "#b0662a",
|
|
14
14
|
"--cg-pending": "var(--cg-expired)",
|
|
15
|
+
"--cg-unhealthy": "#7F7301",
|
|
15
16
|
"--cg-online-fill": "#e6f7ef",
|
|
16
17
|
"--cg-expired-fill": "#fdf3e0",
|
|
17
18
|
"--cg-pending-fill": "var(--cg-expired-fill)",
|
|
19
|
+
"--cg-unhealthy-fill": "#fdf6df",
|
|
18
20
|
"--cg-danger-fill": "#fceded",
|
|
19
21
|
"--cg-primary-press": "#4b39db",
|
|
20
22
|
"--cg-primary-tint": "#eeecfe",
|
|
@@ -123,7 +125,12 @@
|
|
|
123
125
|
"--cg-ease-in-out": "cubic-bezier(0.4, 0, 0.2, 1)",
|
|
124
126
|
"--cg-transition-control": "background-color var(--cg-duration) var(--cg-ease-out), border-color var(--cg-duration) var(--cg-ease-out), color var(--cg-duration) var(--cg-ease-out), box-shadow var(--cg-duration) var(--cg-ease-out)",
|
|
125
127
|
"--cg-lift-hover": "translateY(-1px)",
|
|
126
|
-
"--cg-press-scale": "0.985"
|
|
128
|
+
"--cg-press-scale": "0.985",
|
|
129
|
+
"--cg-volt": "#b6ff2e",
|
|
130
|
+
"--cg-volt-ring": "rgba(182, 255, 46, 0.32)",
|
|
131
|
+
"--cg-volt-ink": "#243d00",
|
|
132
|
+
"--cg-scrim": "rgba(34, 34, 34, 0.4)",
|
|
133
|
+
"--cg-hover": "rgba(34, 34, 34, 0.045)"
|
|
127
134
|
},
|
|
128
135
|
"panel": {
|
|
129
136
|
"--cg-text-primary": "#ffffff",
|
|
@@ -142,10 +149,13 @@
|
|
|
142
149
|
"--cg-offline": "#D9D4FB",
|
|
143
150
|
"--cg-expired": "#FFE2B8",
|
|
144
151
|
"--cg-pending": "var(--cg-expired)",
|
|
152
|
+
"--cg-unhealthy": "#F7E20C",
|
|
145
153
|
"--cg-online-fill": "rgba(255, 255, 255, 0.16)",
|
|
146
154
|
"--cg-expired-fill": "rgba(255, 255, 255, 0.16)",
|
|
147
155
|
"--cg-pending-fill": "var(--cg-expired-fill)",
|
|
148
|
-
"--cg-
|
|
156
|
+
"--cg-unhealthy-fill": "rgba(255, 255, 255, 0.16)",
|
|
157
|
+
"--cg-danger-fill": "rgba(255, 255, 255, 0.16)",
|
|
158
|
+
"--cg-hover": "rgba(255, 255, 255, 0.10)"
|
|
149
159
|
},
|
|
150
160
|
"ink": {
|
|
151
161
|
"--cg-text-primary": "#ffffff",
|
|
@@ -166,10 +176,13 @@
|
|
|
166
176
|
"--cg-offline": "#9A9A9A",
|
|
167
177
|
"--cg-expired": "#F0B45E",
|
|
168
178
|
"--cg-pending": "var(--cg-expired)",
|
|
179
|
+
"--cg-unhealthy": "#F1DC03",
|
|
169
180
|
"--cg-online-fill": "rgba(255, 255, 255, 0.08)",
|
|
170
181
|
"--cg-expired-fill": "rgba(255, 255, 255, 0.08)",
|
|
171
182
|
"--cg-pending-fill": "var(--cg-expired-fill)",
|
|
172
|
-
"--cg-
|
|
183
|
+
"--cg-unhealthy-fill": "rgba(255, 255, 255, 0.08)",
|
|
184
|
+
"--cg-danger-fill": "rgba(255, 255, 255, 0.08)",
|
|
185
|
+
"--cg-hover": "rgba(255, 255, 255, 0.06)"
|
|
173
186
|
}
|
|
174
187
|
}
|
|
175
188
|
}
|
package/package.json
CHANGED