@cloudgrid-io/ui 0.32.4 → 0.34.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (129) hide show
  1. package/README.md +25 -0
  2. package/dist/badge/css-live.d.ts +7 -4
  3. package/dist/badge/css-live.d.ts.map +1 -1
  4. package/dist/badge/css-live.js +9 -6
  5. package/dist/badge/css-live.js.map +1 -1
  6. package/dist/badge/css-owner.d.ts.map +1 -1
  7. package/dist/badge/css-owner.js +11 -2
  8. package/dist/badge/css-owner.js.map +1 -1
  9. package/dist/badge/live.d.ts +4 -3
  10. package/dist/badge/live.d.ts.map +1 -1
  11. package/dist/badge/live.js +4 -3
  12. package/dist/badge/live.js.map +1 -1
  13. package/dist/badge/palette.d.ts +1 -1
  14. package/dist/badge/palette.d.ts.map +1 -1
  15. package/dist/badge/palette.js +2 -1
  16. package/dist/badge/palette.js.map +1 -1
  17. package/dist/blocks/bar-chart.d.ts +97 -0
  18. package/dist/blocks/bar-chart.d.ts.map +1 -0
  19. package/dist/blocks/bar-chart.js +25 -0
  20. package/dist/blocks/bar-chart.js.map +1 -0
  21. package/dist/blocks/chart-parts.d.ts +101 -0
  22. package/dist/blocks/chart-parts.d.ts.map +1 -0
  23. package/dist/blocks/chart-parts.js +96 -0
  24. package/dist/blocks/chart-parts.js.map +1 -0
  25. package/dist/blocks/coming-soon-tag.d.ts +34 -0
  26. package/dist/blocks/coming-soon-tag.d.ts.map +1 -0
  27. package/dist/blocks/coming-soon-tag.js +37 -0
  28. package/dist/blocks/coming-soon-tag.js.map +1 -0
  29. package/dist/blocks/disabled-button.d.ts +43 -0
  30. package/dist/blocks/disabled-button.d.ts.map +1 -0
  31. package/dist/blocks/disabled-button.js +50 -0
  32. package/dist/blocks/disabled-button.js.map +1 -0
  33. package/dist/blocks/entity-card.d.ts.map +1 -1
  34. package/dist/blocks/entity-card.js +3 -1
  35. package/dist/blocks/entity-card.js.map +1 -1
  36. package/dist/blocks/full-screen-button.d.ts +9 -0
  37. package/dist/blocks/full-screen-button.d.ts.map +1 -0
  38. package/dist/blocks/full-screen-button.js +51 -0
  39. package/dist/blocks/full-screen-button.js.map +1 -0
  40. package/dist/blocks/icons.d.ts +30 -0
  41. package/dist/blocks/icons.d.ts.map +1 -1
  42. package/dist/blocks/icons.js +30 -0
  43. package/dist/blocks/icons.js.map +1 -1
  44. package/dist/blocks/meter.d.ts +57 -0
  45. package/dist/blocks/meter.d.ts.map +1 -0
  46. package/dist/blocks/meter.js +19 -0
  47. package/dist/blocks/meter.js.map +1 -0
  48. package/dist/blocks/notice.d.ts +87 -0
  49. package/dist/blocks/notice.d.ts.map +1 -0
  50. package/dist/blocks/notice.js +26 -0
  51. package/dist/blocks/notice.js.map +1 -0
  52. package/dist/blocks/pager.d.ts +76 -0
  53. package/dist/blocks/pager.d.ts.map +1 -0
  54. package/dist/blocks/pager.js +86 -0
  55. package/dist/blocks/pager.js.map +1 -0
  56. package/dist/blocks/phosphor-marks.d.ts +20 -0
  57. package/dist/blocks/phosphor-marks.d.ts.map +1 -1
  58. package/dist/blocks/phosphor-marks.js +30 -0
  59. package/dist/blocks/phosphor-marks.js.map +1 -1
  60. package/dist/blocks/ranked-list.d.ts +67 -0
  61. package/dist/blocks/ranked-list.d.ts.map +1 -0
  62. package/dist/blocks/ranked-list.js +32 -0
  63. package/dist/blocks/ranked-list.js.map +1 -0
  64. package/dist/blocks/side-nav.d.ts.map +1 -1
  65. package/dist/blocks/side-nav.js +3 -1
  66. package/dist/blocks/side-nav.js.map +1 -1
  67. package/dist/blocks/sign-in-options.d.ts.map +1 -1
  68. package/dist/blocks/sign-in-options.js +3 -1
  69. package/dist/blocks/sign-in-options.js.map +1 -1
  70. package/dist/blocks/stacked-bar.d.ts +64 -0
  71. package/dist/blocks/stacked-bar.d.ts.map +1 -0
  72. package/dist/blocks/stacked-bar.js +18 -0
  73. package/dist/blocks/stacked-bar.js.map +1 -0
  74. package/dist/blocks/stat-tile.d.ts +42 -1
  75. package/dist/blocks/stat-tile.d.ts.map +1 -1
  76. package/dist/blocks/stat-tile.js +23 -4
  77. package/dist/blocks/stat-tile.js.map +1 -1
  78. package/dist/blocks/tab-bar.d.ts.map +1 -1
  79. package/dist/blocks/tab-bar.js +3 -1
  80. package/dist/blocks/tab-bar.js.map +1 -1
  81. package/dist/blocks/timeline.d.ts +53 -0
  82. package/dist/blocks/timeline.d.ts.map +1 -0
  83. package/dist/blocks/timeline.js +18 -0
  84. package/dist/blocks/timeline.js.map +1 -0
  85. package/dist/blocks/tool-setup.d.ts.map +1 -1
  86. package/dist/blocks/tool-setup.js +3 -1
  87. package/dist/blocks/tool-setup.js.map +1 -1
  88. package/dist/blocks/trend.d.ts +33 -0
  89. package/dist/blocks/trend.d.ts.map +1 -0
  90. package/dist/blocks/trend.js +13 -0
  91. package/dist/blocks/trend.js.map +1 -0
  92. package/dist/claim-banner/css.d.ts +39 -0
  93. package/dist/claim-banner/css.d.ts.map +1 -0
  94. package/dist/claim-banner/css.js +87 -0
  95. package/dist/claim-banner/css.js.map +1 -0
  96. package/dist/claim-banner/index.d.ts +122 -0
  97. package/dist/claim-banner/index.d.ts.map +1 -0
  98. package/dist/claim-banner/index.js +135 -0
  99. package/dist/claim-banner/index.js.map +1 -0
  100. package/dist/docs.css +466 -0
  101. package/dist/expressive-code-palette.d.ts +5 -0
  102. package/dist/expressive-code-palette.d.ts.map +1 -0
  103. package/dist/expressive-code-palette.js +10 -0
  104. package/dist/expressive-code-palette.js.map +1 -0
  105. package/dist/expressive-code.d.ts +57 -0
  106. package/dist/expressive-code.d.ts.map +1 -0
  107. package/dist/expressive-code.js +101 -0
  108. package/dist/expressive-code.js.map +1 -0
  109. package/dist/index.d.ts +12 -0
  110. package/dist/index.d.ts.map +1 -1
  111. package/dist/index.js +12 -0
  112. package/dist/index.js.map +1 -1
  113. package/dist/tokens/base.json +13 -0
  114. package/dist/tokens/surface-ink.json +13 -0
  115. package/dist/tokens/surface-panel.json +13 -0
  116. package/dist/tokens.css +36 -0
  117. package/dist/tokens.json +6 -3
  118. package/dist/ui/card.d.ts +23 -2
  119. package/dist/ui/card.d.ts.map +1 -1
  120. package/dist/ui/card.js +16 -5
  121. package/dist/ui/card.js.map +1 -1
  122. package/dist/ui/drawer.d.ts +37 -6
  123. package/dist/ui/drawer.d.ts.map +1 -1
  124. package/dist/ui/drawer.js +31 -7
  125. package/dist/ui/drawer.js.map +1 -1
  126. package/dist/ui/input-group.d.ts.map +1 -1
  127. package/dist/ui/input-group.js +3 -1
  128. package/dist/ui/input-group.js.map +1 -1
  129. package/package.json +18 -3
package/dist/docs.css ADDED
@@ -0,0 +1,466 @@
1
+ /*
2
+ A PRODUCT PRESET for the docs site (docs.cloudgrid.io, Astro Starlight). ui#341.
3
+
4
+ It styles Starlight entirely from this package's tokens, so the docs repo
5
+ keeps an import and its config and nothing else: no hex, no font stack, no
6
+ second copy of the brand.
7
+
8
+ HOW. Starlight paints almost everything from about sixty `--sl-*` custom
9
+ properties. Part one of this file maps them onto `--cg-*` tokens. Part two is
10
+ a short list of targeted rules, only where Starlight hard-wires a pairing the
11
+ brand does not want or has no variable at all. Every value is a token; a test
12
+ (test/docs-preset.test.mjs) holds the file to that.
13
+
14
+ LIGHT ONLY (founder, 2026-10-19). This package has no dark mode: dark is a
15
+ container concern (`data-cg-surface='ink'`), never a page mode. So the dark
16
+ scope is not styled here at all. The consumer forces `data-theme='light'` and
17
+ removes the theme picker; without that, a dark-OS reader would get this
18
+ palette's light values under Starlight's own dark logo and code theme.
19
+
20
+ IMPORT ORDER. After tokens.css, which is what every var() below reads:
21
+
22
+ customCss: [
23
+ '@cloudgrid-io/ui/fonts.css',
24
+ '@cloudgrid-io/ui/tokens.css',
25
+ '@cloudgrid-io/ui/docs.css',
26
+ ]
27
+
28
+ UNLAYERED ON PURPOSE. Starlight puts its own rules in `@layer starlight.*`,
29
+ and an unlayered rule beats any layered one whatever the specificity or the
30
+ order. That is why the targeted rules below can be plain class selectors.
31
+
32
+ SAME ELEMENT, SAME RESOLUTION. Rule 2 of this library: a custom property that
33
+ references another resolves where it is declared. Starlight declares its
34
+ derived variables (`--sl-color-text: var(--sl-color-gray-2)`) on :root, and
35
+ this file remaps the ramp on :root too, so both resolve on the same element.
36
+ Do not flip tokens per container inside the docs; it would not follow.
37
+
38
+ PROSE PARITY. prose.css cannot be applied to Starlight's markup (it is scoped
39
+ to `.prose`, and adding that class means overriding MarkdownContent and then
40
+ fighting `.prose pre` on Expressive Code). The few element rules are mirrored
41
+ here against `.sl-markdown-content`, with the same tokens, and
42
+ test/docs-preset.test.mjs fails if the two drift.
43
+
44
+ STARLIGHT COUPLING. Measured against @astrojs/starlight 0.42.6. Part one uses
45
+ the documented `--sl-*` contract. Part two depends on a handful of internal
46
+ selectors (`#_top`, `.sidebar-content`, `.sl-link-button`, `.card`,
47
+ `.sl-link-card`, `.pagination-links`, `button[data-open-modal] > kbd`,
48
+ `#starlight__search`). A Starlight upgrade can rename one silently; take
49
+ upgrades with a screenshot check.
50
+
51
+ NOT IN THIS FILE. Icons stay Starlight's own until the Phosphor follow-up.
52
+ Code blocks are styled by the Expressive Code export,
53
+ `@cloudgrid-io/ui/expressive-code`, plus the one rule below that Expressive
54
+ Code has no setting for.
55
+ */
56
+
57
+ /* ---- part one: Starlight's variables, onto the tokens ---------------------- */
58
+
59
+ /* `::backdrop` because Starlight declares its colours there too: the search
60
+ dialog's backdrop reads --sl-color-backdrop-overlay from it. */
61
+ :root,
62
+ ::backdrop {
63
+ /* The neutral ramp. Starlight's `white` is its highest-contrast ink and its
64
+ `black` is the page, so the ramp runs from text-primary to the ground. */
65
+ --sl-color-white: var(--cg-text-primary);
66
+ --sl-color-gray-1: var(--cg-text-primary);
67
+ /* Body text. prose.css sets `p, li` in text-secondary and `strong` in
68
+ text-primary, and so does this. */
69
+ --sl-color-gray-2: var(--cg-text-secondary);
70
+ --sl-color-gray-3: var(--cg-text-muted-strong);
71
+ --sl-color-gray-4: var(--cg-text-muted);
72
+ /* Structural borders: the search control, table rules, cards. */
73
+ --sl-color-gray-5: var(--cg-border-control);
74
+ --sl-color-gray-6: var(--cg-border-hairline);
75
+ --sl-color-gray-7: var(--cg-surface-subtle);
76
+ /* The library's page ground, with white cards on it (founder, 2026-10-19). */
77
+ --sl-color-black: var(--cg-surface-page);
78
+
79
+ /* The accent triplet: selection tint, focus and active marks. */
80
+ --sl-color-accent-low: var(--cg-primary-tint);
81
+ --sl-color-accent: var(--cg-primary);
82
+ --sl-color-accent-high: var(--cg-primary-press);
83
+
84
+ /* The hue triplets, `-low` fill, base, `-high` text. Each is a library tone.
85
+ Caution borrows the expired state's amber: an editorial role on a state
86
+ tone, stated here rather than minted as a new token. The note (blue) has no
87
+ tinted rung in the library, so its fill is the neutral raised surface. */
88
+ --sl-color-purple-low: var(--cg-primary-tint);
89
+ --sl-color-purple: var(--cg-primary);
90
+ --sl-color-purple-high: var(--cg-primary-press);
91
+ --sl-color-orange-low: var(--cg-expired-fill);
92
+ --sl-color-orange: var(--cg-expired);
93
+ --sl-color-orange-high: var(--cg-expired-strong);
94
+ --sl-color-red-low: var(--cg-danger-fill);
95
+ --sl-color-red: var(--cg-danger);
96
+ --sl-color-red-high: var(--cg-danger-strong);
97
+ --sl-color-green-low: var(--cg-online-fill);
98
+ --sl-color-green: var(--cg-online);
99
+ --sl-color-green-high: var(--cg-online-strong);
100
+ --sl-color-blue-low: var(--cg-surface-raised);
101
+ --sl-color-blue: var(--cg-accent);
102
+ --sl-color-blue-high: var(--cg-accent-press);
103
+
104
+ /* The semantic slots Starlight derives, set explicitly so none of them
105
+ falls back to Starlight's own light values. */
106
+ --sl-color-text: var(--cg-text-secondary);
107
+ --sl-color-text-accent: var(--cg-primary);
108
+ --sl-color-text-invert: var(--cg-text-on-primary);
109
+ --sl-color-bg: var(--cg-surface-page);
110
+ --sl-color-bg-nav: var(--cg-surface-card);
111
+ --sl-color-bg-sidebar: var(--cg-surface-page);
112
+ --sl-color-bg-inline-code: var(--cg-surface-page-alt);
113
+ --sl-color-bg-accent: var(--cg-primary);
114
+ --sl-color-hairline-light: var(--cg-border-hairline);
115
+ --sl-color-hairline: var(--cg-border-hairline);
116
+ --sl-color-hairline-shade: var(--cg-border-hairline);
117
+ --sl-color-backdrop-overlay: var(--cg-scrim);
118
+
119
+ /* The brand is flat and contains by hairlines; the card shadow is the one it
120
+ uses under a white card on the ground. */
121
+ --sl-shadow-sm: var(--cg-shadow-card);
122
+ --sl-shadow-md: var(--cg-shadow-card);
123
+ --sl-shadow-lg: var(--cg-shadow-raised);
124
+
125
+ /* Type. Space Grotesk for everything a reader reads, headings included, and
126
+ no Tanker anywhere (founder, 2026-10-19). */
127
+ --sl-font: var(--cg-font-body);
128
+ --sl-font-mono: var(--cg-font-mono);
129
+
130
+ /* The size scale. Nothing under 13px: Starlight's 12px rung (the search
131
+ shortcut) lands on the caption, the brand's floor. */
132
+ --sl-text-2xs: var(--cg-caption);
133
+ --sl-text-xs: var(--cg-caption);
134
+ --sl-text-sm: var(--cg-body-14);
135
+ --sl-text-base: var(--cg-body-md);
136
+ --sl-text-lg: var(--cg-body-18);
137
+ --sl-text-xl: var(--cg-body-xl);
138
+ --sl-text-2xl: var(--cg-title-24);
139
+ --sl-text-3xl: var(--cg-display-sm);
140
+ --sl-text-4xl: var(--cg-title-36);
141
+ --sl-text-5xl: var(--cg-display-lg);
142
+ --sl-text-6xl: var(--cg-display-64);
143
+ --sl-text-body: var(--cg-body-md);
144
+ --sl-text-body-sm: var(--cg-caption);
145
+ --sl-text-code: var(--cg-mono-size);
146
+ --sl-text-code-sm: var(--cg-caption);
147
+
148
+ /* Headings follow prose.css: h1 is its clamp, h2 and h3 its two rungs, and
149
+ h4 and h5 continue down the heading ramp. Starlight re-declares h1 to h4
150
+ above 50em inside its layer; this unlayered block wins at every width. */
151
+ --sl-text-h1: clamp(var(--cg-display-sm), 5vw, var(--cg-display-lg));
152
+ --sl-text-h2: var(--cg-heading-lg);
153
+ --sl-text-h3: var(--cg-heading-md);
154
+ --sl-text-h4: var(--cg-heading-sm);
155
+ --sl-text-h5: var(--cg-body-md);
156
+
157
+ --sl-line-height: var(--cg-body-line);
158
+ --sl-line-height-headings: var(--cg-heading-line);
159
+ }
160
+
161
+ /* Starlight's reset sets `color-scheme: dark` under a dark theme. Light only,
162
+ so scrollbars and form controls stay light whatever the OS says. */
163
+ :root {
164
+ color-scheme: light;
165
+ }
166
+
167
+ /* ---- part two: targeted rules -------------------------------------------- */
168
+
169
+ /* Headings: the body face at medium, as the library sets a heading. `#_top` is
170
+ Starlight's page title (PAGE_TITLE_ID); it defaults to 600. */
171
+ .sl-markdown-content :is(h1, h2, h3, h4, h5, h6):not(:where(.not-content *)),
172
+ #_top,
173
+ .hero h1 {
174
+ font-weight: var(--cg-weight-medium);
175
+ }
176
+
177
+ /* The heading anchor glyph, quiet until hovered. */
178
+ .sl-markdown-content .sl-anchor-link {
179
+ color: var(--cg-text-muted);
180
+ }
181
+
182
+ /* prose.css: strong is the ink. */
183
+ .sl-markdown-content strong:not(:where(.not-content *)) {
184
+ color: var(--cg-text-primary);
185
+ font-weight: var(--cg-weight-bold);
186
+ }
187
+
188
+ /* prose.css links: --cg-link, the accent blue since #197, one link colour
189
+ across the brand (founder, 2026-10-19). Inside an aside too: no per-callout
190
+ link colour. */
191
+ .sl-markdown-content a:not(:where(.not-content *)) {
192
+ color: var(--cg-link);
193
+ text-decoration-thickness: 1px;
194
+ text-underline-offset: 3px;
195
+ }
196
+
197
+ .sl-markdown-content a:hover:not(:where(.not-content *)) {
198
+ color: var(--cg-link-hover);
199
+ }
200
+
201
+ /* prose.css inline code. `:not(pre) >` keeps it off code inside a block. */
202
+ .sl-markdown-content :not(pre) > code:not(:where(.not-content *)) {
203
+ background: var(--cg-surface-page-alt);
204
+ border: var(--cg-border-width) solid var(--cg-border-hairline);
205
+ border-radius: var(--cg-radius-xs);
206
+ padding: 0.1em 0.35em;
207
+ font-size: 0.9em;
208
+ overflow-wrap: anywhere;
209
+ }
210
+
211
+ /* No chip inside a heading: the mono face only (founder, 2026-10-19). Every CLI
212
+ h2 is a command, and a chip at heading size reads as a button. */
213
+ .sl-markdown-content :is(h1, h2, h3, h4, h5, h6) code:not(:where(.not-content *)) {
214
+ background: none;
215
+ border: 0;
216
+ padding: 0;
217
+ }
218
+
219
+ /* Inside a tinted callout the chip is the white card, so it reads as a chip
220
+ on every tone instead of a mix of the tone. */
221
+ .sl-markdown-content .starlight-aside :not(pre) > code:not(:where(.not-content *)) {
222
+ background: var(--cg-surface-card);
223
+ }
224
+
225
+ /* prose.css blockquote. Unused in the content today, kept so a first one does
226
+ not arrive in Starlight's grey. */
227
+ .sl-markdown-content blockquote:not(:where(.not-content *)) {
228
+ border-inline-start: var(--cg-border-width-strong) solid var(--cg-border-accent);
229
+ color: var(--cg-text-primary);
230
+ }
231
+
232
+ /* prose.css tables: hairline cells, a tinted header row. The cells are white
233
+ so a table reads as a card on the ground.
234
+
235
+ THE TABLE IS ITS OWN SCROLL CONTAINER. Starlight renders a bare <table> with
236
+ no wrapper, so the scroll goes on the table itself: `display: block` with
237
+ `overflow-x: auto`, exactly prose.css's recipe. A table wider than the column
238
+ scrolls inside itself and the page never scrolls sideways. */
239
+ .sl-markdown-content table:not(:where(.not-content *)) {
240
+ border-collapse: collapse;
241
+ font-size: var(--cg-body-sm);
242
+ display: block;
243
+ width: 100%;
244
+ max-width: max-content;
245
+ overflow-x: auto;
246
+ }
247
+
248
+ /* Code in a cell never breaks inside a word. prose.css's `overflow-wrap:
249
+ anywhere` on inline code also lowers a cell's minimum width, so on a phone
250
+ the table squeezed `inside` into `insid` / `e` rather than scrolling
251
+ (founder, 2026-10-19). `nowrap` keeps a flag such as `--require-signin` whole
252
+ too, which `overflow-wrap: normal` alone would still break after a hyphen;
253
+ the table scrolls instead. */
254
+ .sl-markdown-content :is(th, td) code:not(:where(.not-content *)) {
255
+ white-space: nowrap;
256
+ overflow-wrap: normal;
257
+ }
258
+
259
+ .sl-markdown-content :is(th, td):not(:where(.not-content *)) {
260
+ border: var(--cg-border-width) solid var(--cg-border-hairline);
261
+ padding: var(--cg-space-2) var(--cg-space-3);
262
+ background: var(--cg-surface-card);
263
+ }
264
+
265
+ .sl-markdown-content th:not(:where(.not-content *)) {
266
+ background: var(--cg-surface-page-alt);
267
+ font-weight: var(--cg-weight-bold);
268
+ }
269
+
270
+ /* Asides: a hairline box with the library's corner, in place of Starlight's
271
+ 4px bar. Each type takes its tone's own border rung. */
272
+ .starlight-aside {
273
+ border: var(--cg-border-width) solid var(--sl-color-asides-border);
274
+ border-radius: var(--cg-radius-md);
275
+ }
276
+
277
+ .starlight-aside--note {
278
+ --sl-color-asides-border: var(--cg-border-control);
279
+ --sl-color-asides-text-accent: var(--cg-text-primary);
280
+ }
281
+
282
+ .starlight-aside--tip {
283
+ --sl-color-asides-border: var(--cg-primary-tint);
284
+ }
285
+
286
+ .starlight-aside--caution {
287
+ --sl-color-asides-border: var(--cg-expired-border);
288
+ }
289
+
290
+ .starlight-aside--danger {
291
+ --sl-color-asides-border: var(--cg-danger-border);
292
+ }
293
+
294
+ /* Sidebar, as the library SideNav draws it: a group header and its rows in
295
+ the body size, rounded rows, the hover wash, and the current page as the
296
+ brand-tint chip rather than Starlight's solid purple bar. */
297
+ .sidebar-content .large {
298
+ font-size: var(--cg-body-sm);
299
+ font-weight: var(--cg-weight-medium);
300
+ color: var(--cg-text-primary);
301
+ }
302
+
303
+ .sidebar-content summary {
304
+ border-radius: var(--cg-radius-lg);
305
+ }
306
+
307
+ .sidebar-content summary:hover {
308
+ background: var(--cg-hover);
309
+ }
310
+
311
+ .sidebar-content a {
312
+ font-size: var(--cg-body-sm);
313
+ color: var(--cg-text-secondary);
314
+ border-radius: var(--cg-radius-lg);
315
+ }
316
+
317
+ .sidebar-content a:hover,
318
+ .sidebar-content a:focus {
319
+ background: var(--cg-hover);
320
+ color: var(--cg-text-primary);
321
+ }
322
+
323
+ .sidebar-content a[aria-current='page'],
324
+ .sidebar-content a[aria-current='page']:hover,
325
+ .sidebar-content a[aria-current='page']:focus {
326
+ background: var(--cg-primary-tint);
327
+ color: var(--cg-primary);
328
+ font-weight: var(--cg-weight-medium);
329
+ }
330
+
331
+ /* The header's social link, quiet ink rather than the accent. */
332
+ .social-icons a {
333
+ color: var(--cg-text-secondary);
334
+ }
335
+
336
+ .social-icons a:hover {
337
+ color: var(--cg-text-primary);
338
+ }
339
+
340
+ /* The search control: a white control with the library's control corner. */
341
+ @media (min-width: 50rem) {
342
+ button[data-open-modal] {
343
+ background-color: var(--cg-surface-card);
344
+ border-radius: var(--cg-radius-sm);
345
+ }
346
+ }
347
+
348
+ /* The search shortcut, a key cap at the caption size, the brand's floor. */
349
+ button[data-open-modal] > kbd {
350
+ font-size: var(--cg-caption);
351
+ background-color: var(--cg-surface-control);
352
+ border-radius: var(--cg-radius-2xs);
353
+ }
354
+
355
+ /* Pagefind sets its own scale to 0.8, which puts result text at 11 to 13px.
356
+ At 1 it is 14, 16 and 21px. */
357
+ #starlight__search {
358
+ --pagefind-ui-scale: 1;
359
+ --pagefind-ui-font: var(--cg-font-body);
360
+ --pagefind-ui-border-radius: var(--cg-radius-sm);
361
+ }
362
+
363
+ /* Hero buttons as the library's primary Button: the brand fill with its own
364
+ on-primary text. Starlight paints that text in --sl-color-black, which is
365
+ now the page ground, not white. */
366
+ .sl-link-button {
367
+ font-family: var(--cg-font-ui);
368
+ font-weight: var(--cg-label-weight);
369
+ }
370
+
371
+ .sl-link-button.primary,
372
+ .sl-link-button.primary:hover {
373
+ background: var(--cg-primary);
374
+ border-color: var(--cg-primary);
375
+ color: var(--cg-text-on-primary);
376
+ }
377
+
378
+ .sl-link-button.primary:hover {
379
+ background: var(--cg-primary-press);
380
+ border-color: var(--cg-primary-press);
381
+ }
382
+
383
+ /* Cards on the ground, as the library Card: white, a hairline ring, the card
384
+ corner. One brand tone for every icon tile instead of Starlight's rotation
385
+ through five hues; unlayered, this beats its :nth-child rules outright. */
386
+ .card,
387
+ .sl-link-card,
388
+ .pagination-links a {
389
+ background-color: var(--cg-surface-card);
390
+ border-color: var(--cg-border-hairline);
391
+ border-radius: var(--cg-radius-xl);
392
+ }
393
+
394
+ .card {
395
+ --sl-card-border: var(--cg-primary-tint);
396
+ --sl-card-bg: var(--cg-primary-tint);
397
+ }
398
+
399
+ .card .icon {
400
+ color: var(--cg-primary);
401
+ border-radius: var(--cg-radius-2xs);
402
+ }
403
+
404
+ .card .title {
405
+ font-weight: var(--cg-weight-medium);
406
+ }
407
+
408
+ /* The Card body at the library Card's size. Starlight's clamp bottoms out at
409
+ 14px on a phone, where inline code at prose's 0.9em measured 12.6px. */
410
+ .card .body {
411
+ font-size: var(--cg-body-sm);
412
+ }
413
+
414
+ .sl-link-card:hover,
415
+ .pagination-links a:hover {
416
+ background-color: var(--cg-surface-card);
417
+ border-color: var(--cg-border-control);
418
+ }
419
+
420
+ /* Expressive Code draws its copy button at a fixed 0.2rem corner and has no
421
+ setting for it. The library's copy control is a pill. */
422
+ .expressive-code .copy button,
423
+ .expressive-code .copy button div {
424
+ border-radius: var(--cg-radius-pill);
425
+ }
426
+
427
+ /* NO WINDOW DOTS (founder, 2026-10-19: "the icons are not relevant").
428
+ Expressive Code draws a terminal frame for every sh/bash block: a title bar
429
+ with three window dots and nothing else in it. The dots go, and so does the
430
+ empty bar they sat in, so a terminal block is the same ink box as every other
431
+ block, the way CodeBlock draws one.
432
+
433
+ The bar is collapsed, never `display: none`. It holds the screen-reader label
434
+ "Terminal window", and hiding the bar would remove that text from the page.
435
+ A titled terminal frame keeps its bar for the title, without the dots. */
436
+ .expressive-code .frame.is-terminal .header::before {
437
+ content: none;
438
+ }
439
+
440
+ .expressive-code .frame.is-terminal:not(.has-title) {
441
+ /* The copy button's offset from the top: the bar is gone, so it sits where
442
+ an untitled code frame's does. */
443
+ --button-spacing: var(--cg-space-2);
444
+ }
445
+
446
+ .expressive-code .frame.is-terminal:not(.has-title) .header {
447
+ padding: 0;
448
+ border: 0;
449
+ }
450
+
451
+ .expressive-code .frame.is-terminal:not(.has-title) .header .title,
452
+ .expressive-code .frame.is-terminal:not(.has-title) .header::after {
453
+ display: none;
454
+ }
455
+
456
+ /* With the bar gone the code box carries the top edge and corners again,
457
+ which Expressive Code removes from any terminal frame. */
458
+ .expressive-code .frame.is-terminal:not(.has-title) pre {
459
+ border-top: var(--cg-border-width) solid var(--cg-surface-code);
460
+ border-top-left-radius: var(--header-border-radius);
461
+ border-top-right-radius: var(--header-border-radius);
462
+ }
463
+
464
+ .expressive-code .frame:not(.has-title):not(.is-terminal) {
465
+ --button-spacing: var(--cg-space-2);
466
+ }
@@ -0,0 +1,5 @@
1
+ export declare const CODE_PALETTE: {
2
+ readonly background: "#222222";
3
+ readonly foreground: "#e7e7e7";
4
+ };
5
+ //# sourceMappingURL=expressive-code-palette.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"expressive-code-palette.d.ts","sourceRoot":"","sources":["../src/expressive-code-palette.ts"],"names":[],"mappings":"AAMA,eAAO,MAAM,YAAY;;;CAGf,CAAA"}
@@ -0,0 +1,10 @@
1
+ // GENERATED by scripts/build-expressive-code.mjs from src/tokens.css. Do not edit.
2
+ //
3
+ // Expressive Code does colour arithmetic on its theme at build time and cannot
4
+ // read a CSS custom property there, so these two are the resolved values of the
5
+ // tokens named beside them, at :root. Retune the token and rebuild.
6
+ export const CODE_PALETTE = {
7
+ background: "#222222", // --cg-surface-code
8
+ foreground: "#e7e7e7", // --cg-text-on-code
9
+ };
10
+ //# sourceMappingURL=expressive-code-palette.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"expressive-code-palette.js","sourceRoot":"","sources":["../src/expressive-code-palette.ts"],"names":[],"mappings":"AAAA,mFAAmF;AACnF,EAAE;AACF,+EAA+E;AAC/E,gFAAgF;AAChF,oEAAoE;AAEpE,MAAM,CAAC,MAAM,YAAY,GAAG;IAC1B,UAAU,EAAE,SAAS,EAAE,oBAAoB;IAC3C,UAAU,EAAE,SAAS,EAAE,oBAAoB;CACnC,CAAA"}
@@ -0,0 +1,57 @@
1
+ /**
2
+ * The code blocks of the docs site, as the library CodeBlock draws them. ui#341.
3
+ *
4
+ * Expressive Code renders every fenced block in the Starlight docs. This is its
5
+ * configuration, so the docs repo takes it in one line:
6
+ *
7
+ * import { cloudgridExpressiveCode } from "@cloudgrid-io/ui/expressive-code"
8
+ * starlight({ expressiveCode: cloudgridExpressiveCode, ... })
9
+ *
10
+ * MONOCHROME (founder, 2026-10-19), like CodeBlock: ink ground, every token in
11
+ * the on-code text, no syntax palette. The theme has no token rules at all, so
12
+ * Shiki gives every token the default foreground.
13
+ *
14
+ * TWO KINDS OF VALUE. Expressive Code paints through CSS, and every value it
15
+ * paints with here is a `var(--cg-*)` (`styleOverrides`), so a retune lands
16
+ * without touching this file. It also does colour arithmetic on its theme at
17
+ * build time (contrast, derived scrollbar and selection colours, the colour
18
+ * baked into each highlighted span), and that cannot read a custom property.
19
+ * Those values come from CODE_PALETTE, which scripts/build-expressive-code.mjs
20
+ * generates from tokens.css. Nothing here is a typed literal colour, and
21
+ * test/docs-preset.test.mjs holds it to that.
22
+ *
23
+ * PLAIN DATA. No functions, no class instances, no import from Expressive Code:
24
+ * Starlight serialises this config into a virtual module, and a theme object is
25
+ * accepted as-is (Expressive Code wraps it in ExpressiveCodeTheme itself).
26
+ *
27
+ * LIGHT ONLY. One theme, so Expressive Code emits no per-theme switch, and code
28
+ * is dark on a light page the way CodeBlock is everywhere.
29
+ *
30
+ * Measured against Expressive Code 0.44 (astro-expressive-code, via
31
+ * @astrojs/starlight 0.42.6).
32
+ */
33
+ /** A VS Code-style theme, the shape Expressive Code accepts as a theme object. */
34
+ export interface CodeTheme {
35
+ name: string;
36
+ type: "dark" | "light";
37
+ fg: string;
38
+ bg: string;
39
+ colors: Record<string, string>;
40
+ settings: Array<{
41
+ scope?: string[];
42
+ settings: Record<string, string>;
43
+ }>;
44
+ }
45
+ /** The subset of Expressive Code's options this export sets. */
46
+ export interface CloudgridExpressiveCodeOptions {
47
+ themes: CodeTheme[];
48
+ styleOverrides: Record<string, string | Record<string, string>>;
49
+ }
50
+ /** The monochrome code theme: one ground, one foreground, no token rules. */
51
+ export declare const cloudgridCodeTheme: CodeTheme;
52
+ /** Every value Expressive Code paints through CSS, as a library token. */
53
+ export declare const cloudgridCodeStyleOverrides: CloudgridExpressiveCodeOptions["styleOverrides"];
54
+ /** The whole configuration: `starlight({ expressiveCode: cloudgridExpressiveCode })`. */
55
+ export declare const cloudgridExpressiveCode: CloudgridExpressiveCodeOptions;
56
+ export default cloudgridExpressiveCode;
57
+ //# sourceMappingURL=expressive-code.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"expressive-code.d.ts","sourceRoot":"","sources":["../src/expressive-code.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA+BG;AAIH,kFAAkF;AAClF,MAAM,WAAW,SAAS;IACxB,IAAI,EAAE,MAAM,CAAA;IACZ,IAAI,EAAE,MAAM,GAAG,OAAO,CAAA;IACtB,EAAE,EAAE,MAAM,CAAA;IACV,EAAE,EAAE,MAAM,CAAA;IACV,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAA;IAC9B,QAAQ,EAAE,KAAK,CAAC;QAAE,KAAK,CAAC,EAAE,MAAM,EAAE,CAAC;QAAC,QAAQ,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAA;KAAE,CAAC,CAAA;CACxE;AAED,gEAAgE;AAChE,MAAM,WAAW,8BAA8B;IAC7C,MAAM,EAAE,SAAS,EAAE,CAAA;IACnB,cAAc,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,GAAG,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC,CAAA;CAChE;AAED,6EAA6E;AAC7E,eAAO,MAAM,kBAAkB,EAAE,SAahC,CAAA;AAED,0EAA0E;AAC1E,eAAO,MAAM,2BAA2B,EAAE,8BAA8B,CAAC,gBAAgB,CA4CxF,CAAA;AAED,yFAAyF;AACzF,eAAO,MAAM,uBAAuB,EAAE,8BAGrC,CAAA;AAED,eAAe,uBAAuB,CAAA"}
@@ -0,0 +1,101 @@
1
+ /**
2
+ * The code blocks of the docs site, as the library CodeBlock draws them. ui#341.
3
+ *
4
+ * Expressive Code renders every fenced block in the Starlight docs. This is its
5
+ * configuration, so the docs repo takes it in one line:
6
+ *
7
+ * import { cloudgridExpressiveCode } from "@cloudgrid-io/ui/expressive-code"
8
+ * starlight({ expressiveCode: cloudgridExpressiveCode, ... })
9
+ *
10
+ * MONOCHROME (founder, 2026-10-19), like CodeBlock: ink ground, every token in
11
+ * the on-code text, no syntax palette. The theme has no token rules at all, so
12
+ * Shiki gives every token the default foreground.
13
+ *
14
+ * TWO KINDS OF VALUE. Expressive Code paints through CSS, and every value it
15
+ * paints with here is a `var(--cg-*)` (`styleOverrides`), so a retune lands
16
+ * without touching this file. It also does colour arithmetic on its theme at
17
+ * build time (contrast, derived scrollbar and selection colours, the colour
18
+ * baked into each highlighted span), and that cannot read a custom property.
19
+ * Those values come from CODE_PALETTE, which scripts/build-expressive-code.mjs
20
+ * generates from tokens.css. Nothing here is a typed literal colour, and
21
+ * test/docs-preset.test.mjs holds it to that.
22
+ *
23
+ * PLAIN DATA. No functions, no class instances, no import from Expressive Code:
24
+ * Starlight serialises this config into a virtual module, and a theme object is
25
+ * accepted as-is (Expressive Code wraps it in ExpressiveCodeTheme itself).
26
+ *
27
+ * LIGHT ONLY. One theme, so Expressive Code emits no per-theme switch, and code
28
+ * is dark on a light page the way CodeBlock is everywhere.
29
+ *
30
+ * Measured against Expressive Code 0.44 (astro-expressive-code, via
31
+ * @astrojs/starlight 0.42.6).
32
+ */
33
+ import { CODE_PALETTE } from "./expressive-code-palette.js";
34
+ /** The monochrome code theme: one ground, one foreground, no token rules. */
35
+ export const cloudgridCodeTheme = {
36
+ name: "cloudgrid",
37
+ type: "dark",
38
+ fg: CODE_PALETTE.foreground,
39
+ bg: CODE_PALETTE.background,
40
+ colors: {
41
+ "editor.background": CODE_PALETTE.background,
42
+ "editor.foreground": CODE_PALETTE.foreground,
43
+ "terminal.background": CODE_PALETTE.background,
44
+ "terminal.foreground": CODE_PALETTE.foreground,
45
+ },
46
+ // The default entry only. No scoped rules is what makes it monochrome.
47
+ settings: [{ settings: { foreground: CODE_PALETTE.foreground, background: CODE_PALETTE.background } }],
48
+ };
49
+ /** Every value Expressive Code paints through CSS, as a library token. */
50
+ export const cloudgridCodeStyleOverrides = {
51
+ // The frame: CodeBlock's corner on the ink ground, and no ring around it.
52
+ borderRadius: "var(--cg-radius-md)",
53
+ borderWidth: "var(--cg-border-width)",
54
+ borderColor: "var(--cg-surface-code)",
55
+ codeBackground: "var(--cg-surface-code)",
56
+ codeForeground: "var(--cg-text-on-code)",
57
+ codeFontFamily: "var(--cg-font-mono)",
58
+ codeFontSize: "var(--cg-mono-size)",
59
+ codeLineHeight: "var(--cg-mono-line)",
60
+ // CodeBlock's padding: py-5, px-6.
61
+ codePaddingBlock: "var(--cg-space-5)",
62
+ codePaddingInline: "var(--cg-space-6)",
63
+ uiFontFamily: "var(--cg-font-ui)",
64
+ uiFontSize: "var(--cg-body-14)",
65
+ // On ink the library's focus colour is the lime (`[data-cg-surface='ink']`
66
+ // sets --cg-border-accent to --cg-secondary); the purple measures about 2:1.
67
+ focusBorder: "var(--cg-secondary)",
68
+ frames: {
69
+ frameBoxShadowCssValue: "var(--cg-shadow-none)",
70
+ editorBackground: "var(--cg-surface-code)",
71
+ terminalBackground: "var(--cg-surface-code)",
72
+ // A titled frame and a terminal both keep their bar, on the same ink, so the
73
+ // block reads as one surface.
74
+ editorTabBarBackground: "var(--cg-surface-code)",
75
+ editorTabBarBorderColor: "var(--cg-surface-code)",
76
+ editorTabBarBorderBottomColor: "var(--cg-surface-code)",
77
+ editorActiveTabBackground: "var(--cg-surface-code)",
78
+ editorActiveTabForeground: "var(--cg-text-muted)",
79
+ editorActiveTabIndicatorTopColor: "var(--cg-surface-code)",
80
+ editorActiveTabIndicatorBottomColor: "var(--cg-surface-code)",
81
+ terminalTitlebarBackground: "var(--cg-surface-code)",
82
+ terminalTitlebarForeground: "var(--cg-text-muted)",
83
+ terminalTitlebarBorderBottomColor: "var(--cg-surface-code)",
84
+ // No dots colour: docs.css removes the window dots and the empty bar they
85
+ // sit in (founder, 2026-10-19), which Expressive Code has no setting for.
86
+ // The copy control, in the on-code text like everything else on ink.
87
+ inlineButtonForeground: "var(--cg-text-on-code)",
88
+ inlineButtonBackground: "var(--cg-text-on-code)",
89
+ inlineButtonBorder: "var(--cg-text-on-code)",
90
+ // The copy confirmation: the online state's text on its fill.
91
+ tooltipSuccessBackground: "var(--cg-online-fill)",
92
+ tooltipSuccessForeground: "var(--cg-online-strong)",
93
+ },
94
+ };
95
+ /** The whole configuration: `starlight({ expressiveCode: cloudgridExpressiveCode })`. */
96
+ export const cloudgridExpressiveCode = {
97
+ themes: [cloudgridCodeTheme],
98
+ styleOverrides: cloudgridCodeStyleOverrides,
99
+ };
100
+ export default cloudgridExpressiveCode;
101
+ //# sourceMappingURL=expressive-code.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"expressive-code.js","sourceRoot":"","sources":["../src/expressive-code.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA+BG;AAEH,OAAO,EAAE,YAAY,EAAE,MAAM,8BAA8B,CAAA;AAkB3D,6EAA6E;AAC7E,MAAM,CAAC,MAAM,kBAAkB,GAAc;IAC3C,IAAI,EAAE,WAAW;IACjB,IAAI,EAAE,MAAM;IACZ,EAAE,EAAE,YAAY,CAAC,UAAU;IAC3B,EAAE,EAAE,YAAY,CAAC,UAAU;IAC3B,MAAM,EAAE;QACN,mBAAmB,EAAE,YAAY,CAAC,UAAU;QAC5C,mBAAmB,EAAE,YAAY,CAAC,UAAU;QAC5C,qBAAqB,EAAE,YAAY,CAAC,UAAU;QAC9C,qBAAqB,EAAE,YAAY,CAAC,UAAU;KAC/C;IACD,uEAAuE;IACvE,QAAQ,EAAE,CAAC,EAAE,QAAQ,EAAE,EAAE,UAAU,EAAE,YAAY,CAAC,UAAU,EAAE,UAAU,EAAE,YAAY,CAAC,UAAU,EAAE,EAAE,CAAC;CACvG,CAAA;AAED,0EAA0E;AAC1E,MAAM,CAAC,MAAM,2BAA2B,GAAqD;IAC3F,0EAA0E;IAC1E,YAAY,EAAE,qBAAqB;IACnC,WAAW,EAAE,wBAAwB;IACrC,WAAW,EAAE,wBAAwB;IACrC,cAAc,EAAE,wBAAwB;IACxC,cAAc,EAAE,wBAAwB;IACxC,cAAc,EAAE,qBAAqB;IACrC,YAAY,EAAE,qBAAqB;IACnC,cAAc,EAAE,qBAAqB;IACrC,mCAAmC;IACnC,gBAAgB,EAAE,mBAAmB;IACrC,iBAAiB,EAAE,mBAAmB;IACtC,YAAY,EAAE,mBAAmB;IACjC,UAAU,EAAE,mBAAmB;IAC/B,2EAA2E;IAC3E,6EAA6E;IAC7E,WAAW,EAAE,qBAAqB;IAClC,MAAM,EAAE;QACN,sBAAsB,EAAE,uBAAuB;QAC/C,gBAAgB,EAAE,wBAAwB;QAC1C,kBAAkB,EAAE,wBAAwB;QAC5C,6EAA6E;QAC7E,8BAA8B;QAC9B,sBAAsB,EAAE,wBAAwB;QAChD,uBAAuB,EAAE,wBAAwB;QACjD,6BAA6B,EAAE,wBAAwB;QACvD,yBAAyB,EAAE,wBAAwB;QACnD,yBAAyB,EAAE,sBAAsB;QACjD,gCAAgC,EAAE,wBAAwB;QAC1D,mCAAmC,EAAE,wBAAwB;QAC7D,0BAA0B,EAAE,wBAAwB;QACpD,0BAA0B,EAAE,sBAAsB;QAClD,iCAAiC,EAAE,wBAAwB;QAC3D,0EAA0E;QAC1E,0EAA0E;QAC1E,qEAAqE;QACrE,sBAAsB,EAAE,wBAAwB;QAChD,sBAAsB,EAAE,wBAAwB;QAChD,kBAAkB,EAAE,wBAAwB;QAC5C,8DAA8D;QAC9D,wBAAwB,EAAE,uBAAuB;QACjD,wBAAwB,EAAE,yBAAyB;KACpD;CACF,CAAA;AAED,yFAAyF;AACzF,MAAM,CAAC,MAAM,uBAAuB,GAAmC;IACrE,MAAM,EAAE,CAAC,kBAAkB,CAAC;IAC5B,cAAc,EAAE,2BAA2B;CAC5C,CAAA;AAED,eAAe,uBAAuB,CAAA"}