@signal9/era-ui 10.1.0 → 12.0.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 (250) hide show
  1. package/dist/ai/actions/actions.svelte +1 -1
  2. package/dist/ai/artifact/artifact-actions.svelte +1 -1
  3. package/dist/ai/artifact/artifact-close.svelte +1 -1
  4. package/dist/ai/artifact/artifact-content.svelte +1 -1
  5. package/dist/ai/artifact/artifact-header.svelte +1 -1
  6. package/dist/ai/artifact/artifact.svelte +1 -4
  7. package/dist/ai/chain-of-thought/chain-of-thought-step.svelte +3 -3
  8. package/dist/ai/chain-of-thought/chain-of-thought.svelte +1 -1
  9. package/dist/ai/checkpoint.svelte +2 -2
  10. package/dist/ai/confirmation/confirmation-actions.svelte +1 -1
  11. package/dist/ai/confirmation/confirmation-args.svelte +4 -4
  12. package/dist/ai/confirmation/confirmation.svelte +5 -8
  13. package/dist/ai/context/context.svelte +3 -3
  14. package/dist/ai/conversation/conversation-content.svelte +1 -4
  15. package/dist/ai/conversation/conversation-empty-state.svelte +1 -1
  16. package/dist/ai/conversation/conversation-scroll-button.svelte +3 -3
  17. package/dist/ai/conversations/conversations-group.svelte +2 -2
  18. package/dist/ai/conversations/conversations-item.svelte +8 -8
  19. package/dist/ai/conversations/conversations-root.svelte +2 -2
  20. package/dist/ai/error-panel/error-panel.svelte +7 -7
  21. package/dist/ai/image.svelte +1 -1
  22. package/dist/ai/inline-citation/inline-citation.svelte +5 -5
  23. package/dist/ai/loader.svelte +1 -4
  24. package/dist/ai/message/message-branch-selector.svelte +3 -3
  25. package/dist/ai/message/message-branch.svelte +1 -1
  26. package/dist/ai/message/message-content.svelte +1 -1
  27. package/dist/ai/message/message-toolbar.svelte +1 -1
  28. package/dist/ai/message/message-usage.svelte +5 -7
  29. package/dist/ai/message/message.svelte +1 -1
  30. package/dist/ai/model-selector/model-selector.svelte +2 -2
  31. package/dist/ai/open-in-chat/open-in-chat.svelte +2 -2
  32. package/dist/ai/plan/plan-content.svelte +1 -1
  33. package/dist/ai/plan/plan-header.svelte +2 -2
  34. package/dist/ai/plan/plan.svelte +1 -4
  35. package/dist/ai/prompt-input/prompt-input-add-attachments.svelte +1 -1
  36. package/dist/ai/prompt-input/prompt-input-attachments.svelte +5 -5
  37. package/dist/ai/prompt-input/prompt-input-submit.svelte +2 -2
  38. package/dist/ai/prompt-input/prompt-input-textarea.svelte +2 -2
  39. package/dist/ai/prompt-input/prompt-input-toolbar.svelte +1 -1
  40. package/dist/ai/prompt-input/prompt-input.svelte +1 -1
  41. package/dist/ai/queue/queue-item.svelte +1 -1
  42. package/dist/ai/queue/queue.svelte +1 -1
  43. package/dist/ai/reasoning/reasoning-trigger.svelte +1 -1
  44. package/dist/ai/response/response.svelte +1 -1
  45. package/dist/ai/run-status/run-status.svelte +5 -10
  46. package/dist/ai/runtime-feed/runtime-feed-item.svelte +1 -4
  47. package/dist/ai/runtime-feed/runtime-feed-root.svelte +1 -1
  48. package/dist/ai/sources/source.svelte +2 -2
  49. package/dist/ai/sources/sources-trigger.svelte +1 -1
  50. package/dist/ai/structured-value/structured-value.svelte +4 -4
  51. package/dist/ai/suggestion/suggestion.svelte +1 -1
  52. package/dist/ai/suggestion/suggestions.svelte +1 -1
  53. package/dist/ai/swarm/swarm-agent.svelte +3 -3
  54. package/dist/ai/swarm/swarm-artifact.svelte +2 -2
  55. package/dist/ai/swarm/swarm-barrier.svelte +3 -3
  56. package/dist/ai/swarm/swarm-barriers.svelte +1 -4
  57. package/dist/ai/swarm/swarm-counts.svelte +2 -2
  58. package/dist/ai/swarm/swarm-footer.svelte +2 -2
  59. package/dist/ai/swarm/swarm-grid.svelte +2 -2
  60. package/dist/ai/swarm/swarm-header.svelte +2 -2
  61. package/dist/ai/swarm/swarm-node.svelte +7 -9
  62. package/dist/ai/swarm/swarm-role.svelte +2 -2
  63. package/dist/ai/swarm/swarm-root.svelte +1 -4
  64. package/dist/ai/swarm/swarm-sandbox.svelte +4 -7
  65. package/dist/ai/swarm/swarm-tree.svelte +2 -2
  66. package/dist/ai/task/task-content.svelte +1 -4
  67. package/dist/ai/task/task-trigger.svelte +1 -1
  68. package/dist/ai/tool/tool-chip.svelte +3 -3
  69. package/dist/ai/tool/tool-chips.svelte +3 -3
  70. package/dist/ai/tool/tool-exec.svelte +4 -4
  71. package/dist/ai/tool/tool-header.svelte +1 -1
  72. package/dist/ai/web-preview/web-preview.svelte +4 -9
  73. package/dist/ai/workflow/canvas.svelte +1 -1
  74. package/dist/ai/workflow/node.svelte +3 -3
  75. package/dist/apps/llm-shell/llm-shell.svelte +4 -4
  76. package/dist/apps/notes/notes.svelte +8 -8
  77. package/dist/dev/audit/audits/even-container-padding.js +2 -2
  78. package/dist/dev/audit/audits/single-glyph-square.js +2 -2
  79. package/dist/dev/audit-overlay.svelte +7 -7
  80. package/dist/docs/css-utilities.d.ts +31 -0
  81. package/dist/docs/css-utilities.js +141 -7
  82. package/dist/docs/quickstart.md +5 -5
  83. package/dist/era-ui.css +1 -1
  84. package/dist/generated-docs/llms-full.txt +359 -94
  85. package/dist/generated-docs/llms.txt +18 -7
  86. package/dist/generated-docs/manifest.json +355 -49
  87. package/dist/generated-docs/utilities.json +336 -41
  88. package/dist/generated-docs/utilities.md +341 -87
  89. package/dist/os/notification-center.svelte +11 -17
  90. package/dist/os/pane-manager.svelte.d.ts +1 -1
  91. package/dist/os/pane.svelte +4 -6
  92. package/dist/os/taskbar.svelte +13 -18
  93. package/dist/os/toast.svelte +6 -11
  94. package/dist/os/toaster.svelte +1 -1
  95. package/dist/styles/density.css +0 -2
  96. package/dist/styles/index.css +117 -79
  97. package/dist/styles/themes.css +49 -42
  98. package/dist/ui/accordion/accordion-content.svelte +1 -1
  99. package/dist/ui/accordion/accordion-trigger.svelte +2 -2
  100. package/dist/ui/alert-dialog/alert-dialog-content.svelte +2 -2
  101. package/dist/ui/alert-dialog/alert-dialog-overlay.svelte +1 -1
  102. package/dist/ui/aspect-ratio/aspect-ratio.svelte +1 -5
  103. package/dist/ui/avatar/avatar-fallback.svelte +1 -1
  104. package/dist/ui/avatar/avatar-root.svelte +1 -1
  105. package/dist/ui/badge/badge.svelte +1 -1
  106. package/dist/ui/badge/badge.svelte.d.ts +1 -1
  107. package/dist/ui/bar/bar.svelte +7 -7
  108. package/dist/ui/bar/bar.svelte.d.ts +15 -15
  109. package/dist/ui/button/button.svelte +1 -1
  110. package/dist/ui/button/variants.d.ts +4 -4
  111. package/dist/ui/button/variants.js +18 -18
  112. package/dist/ui/button-group/button-group.svelte +2 -2
  113. package/dist/ui/calendar/calendar-day.svelte +1 -1
  114. package/dist/ui/calendar/calendar-grid-row.svelte +1 -1
  115. package/dist/ui/calendar/calendar-grid.svelte +1 -1
  116. package/dist/ui/calendar/calendar-head-cell.svelte +1 -1
  117. package/dist/ui/calendar/calendar-header.svelte +1 -1
  118. package/dist/ui/calendar/calendar-next-button.svelte +1 -1
  119. package/dist/ui/calendar/calendar-prev-button.svelte +1 -1
  120. package/dist/ui/calendar/calendar-root.svelte +1 -1
  121. package/dist/ui/card/card.svelte +10 -10
  122. package/dist/ui/card/card.svelte.d.ts +16 -16
  123. package/dist/ui/checkbox/checkbox-group.svelte +1 -1
  124. package/dist/ui/checkbox/checkbox.svelte +1 -1
  125. package/dist/ui/chip/chip.svelte +7 -9
  126. package/dist/ui/chip/chip.svelte.d.ts +7 -7
  127. package/dist/ui/code-block/code-block.svelte +3 -9
  128. package/dist/ui/collapsible/collapsible-trigger.svelte +1 -1
  129. package/dist/ui/combobox/combobox-content.svelte +1 -1
  130. package/dist/ui/combobox/combobox-empty.svelte +1 -6
  131. package/dist/ui/combobox/combobox-group-heading.svelte +1 -4
  132. package/dist/ui/combobox/combobox-input.svelte +1 -1
  133. package/dist/ui/combobox/combobox-item.svelte +1 -1
  134. package/dist/ui/combobox/combobox-trigger.svelte +2 -2
  135. package/dist/ui/command/command-group-heading.svelte +1 -4
  136. package/dist/ui/command/command-group-items.svelte +1 -5
  137. package/dist/ui/command/command-item.svelte +1 -1
  138. package/dist/ui/command/command-link-item.svelte +1 -1
  139. package/dist/ui/command/command-root.svelte +2 -2
  140. package/dist/ui/command/command-viewport.svelte +1 -1
  141. package/dist/ui/command-bar/command-bar.svelte +9 -13
  142. package/dist/ui/context-menu/context-menu-checkbox-item.svelte +1 -1
  143. package/dist/ui/context-menu/context-menu-content.svelte +2 -2
  144. package/dist/ui/context-menu/context-menu-group-heading.svelte +1 -4
  145. package/dist/ui/context-menu/context-menu-item.svelte +1 -1
  146. package/dist/ui/context-menu/context-menu-radio-item.svelte +1 -1
  147. package/dist/ui/context-menu/context-menu-sub-content.svelte +1 -1
  148. package/dist/ui/context-menu/context-menu-sub-trigger.svelte +2 -2
  149. package/dist/ui/copy-button/copy-button.svelte +2 -2
  150. package/dist/ui/cycle/cycle.svelte +2 -2
  151. package/dist/ui/date-field/date-field-segment.svelte +1 -1
  152. package/dist/ui/date-picker/date-picker-calendar.svelte +1 -1
  153. package/dist/ui/date-picker/date-picker-content.svelte +1 -4
  154. package/dist/ui/date-picker/date-picker-day.svelte +1 -1
  155. package/dist/ui/date-picker/date-picker-grid-row.svelte +1 -1
  156. package/dist/ui/date-picker/date-picker-grid.svelte +1 -1
  157. package/dist/ui/date-picker/date-picker-head-cell.svelte +1 -1
  158. package/dist/ui/date-picker/date-picker-header.svelte +1 -1
  159. package/dist/ui/date-picker/date-picker-next-button.svelte +1 -1
  160. package/dist/ui/date-picker/date-picker-prev-button.svelte +1 -1
  161. package/dist/ui/date-picker/date-picker-segment.svelte +1 -1
  162. package/dist/ui/date-picker/date-picker-trigger.svelte +2 -2
  163. package/dist/ui/date-range-field/date-range-field-segment.svelte +1 -1
  164. package/dist/ui/date-range-picker/date-range-picker-calendar.svelte +1 -1
  165. package/dist/ui/date-range-picker/date-range-picker-content.svelte +1 -4
  166. package/dist/ui/date-range-picker/date-range-picker-day.svelte +1 -1
  167. package/dist/ui/date-range-picker/date-range-picker-grid-row.svelte +1 -1
  168. package/dist/ui/date-range-picker/date-range-picker-grid.svelte +1 -5
  169. package/dist/ui/date-range-picker/date-range-picker-head-cell.svelte +1 -1
  170. package/dist/ui/date-range-picker/date-range-picker-header.svelte +1 -1
  171. package/dist/ui/date-range-picker/date-range-picker-next-button.svelte +1 -1
  172. package/dist/ui/date-range-picker/date-range-picker-prev-button.svelte +1 -1
  173. package/dist/ui/date-range-picker/date-range-picker-segment.svelte +1 -1
  174. package/dist/ui/date-range-picker/date-range-picker-trigger.svelte +2 -2
  175. package/dist/ui/dialog/dialog-content.svelte +3 -5
  176. package/dist/ui/dialog/dialog-header.svelte +1 -6
  177. package/dist/ui/dialog/dialog-overlay.svelte +1 -5
  178. package/dist/ui/dropdown-menu/dropdown-menu-checkbox-item.svelte +1 -1
  179. package/dist/ui/dropdown-menu/dropdown-menu-content.svelte +2 -2
  180. package/dist/ui/dropdown-menu/dropdown-menu-group-heading.svelte +1 -4
  181. package/dist/ui/dropdown-menu/dropdown-menu-item.svelte +1 -1
  182. package/dist/ui/dropdown-menu/dropdown-menu-radio-item.svelte +1 -1
  183. package/dist/ui/dropdown-menu/dropdown-menu-sub-content.svelte +1 -1
  184. package/dist/ui/dropdown-menu/dropdown-menu-sub-trigger.svelte +2 -2
  185. package/dist/ui/dropdown-menu/dropdown-menu-trigger.svelte +2 -2
  186. package/dist/ui/file-upload/file-upload.svelte +2 -2
  187. package/dist/ui/input/input.svelte +2 -2
  188. package/dist/ui/input/textarea.svelte +1 -1
  189. package/dist/ui/input/variants.d.ts +18 -18
  190. package/dist/ui/input/variants.js +6 -6
  191. package/dist/ui/kv/kv.svelte +2 -3
  192. package/dist/ui/link-preview/link-preview-content.svelte +1 -1
  193. package/dist/ui/menubar/menubar-checkbox-item.svelte +1 -1
  194. package/dist/ui/menubar/menubar-content.svelte +2 -2
  195. package/dist/ui/menubar/menubar-group-heading.svelte +1 -4
  196. package/dist/ui/menubar/menubar-item.svelte +1 -1
  197. package/dist/ui/menubar/menubar-radio-item.svelte +1 -1
  198. package/dist/ui/menubar/menubar-root.svelte +1 -4
  199. package/dist/ui/menubar/menubar-sub-content.svelte +1 -1
  200. package/dist/ui/menubar/menubar-sub-trigger.svelte +2 -2
  201. package/dist/ui/menubar/menubar-trigger.svelte +1 -1
  202. package/dist/ui/meter/meter.svelte +2 -2
  203. package/dist/ui/pagination/pagination-next-button.svelte +1 -1
  204. package/dist/ui/pagination/pagination-prev-button.svelte +1 -1
  205. package/dist/ui/pagination/pagination-root.svelte +1 -1
  206. package/dist/ui/pane/pane-content.svelte +1 -1
  207. package/dist/ui/pane/pane-root.svelte +1 -1
  208. package/dist/ui/pane/pane-tab-list.svelte +1 -1
  209. package/dist/ui/pane/pane-tab-panel.svelte +1 -1
  210. package/dist/ui/pane/pane-tab.svelte +1 -1
  211. package/dist/ui/pane/pane.svelte +1 -1
  212. package/dist/ui/pin-input/pin-input-cell.svelte +1 -1
  213. package/dist/ui/popover/popover-content.svelte +1 -1
  214. package/dist/ui/popover/popover-trigger.svelte +1 -4
  215. package/dist/ui/progress/progress.svelte +2 -2
  216. package/dist/ui/radio-group/radio-group-item.svelte +2 -2
  217. package/dist/ui/radio-group/radio-group-root.svelte +1 -1
  218. package/dist/ui/rating-group/rating-group-item.svelte +1 -1
  219. package/dist/ui/rating-group/rating-group-root.svelte +1 -1
  220. package/dist/ui/scroll-area/scroll-area-scrollbar.svelte +1 -1
  221. package/dist/ui/scroll-area/scroll-area-thumb.svelte +1 -1
  222. package/dist/ui/scroll-area/scroll-area.svelte +1 -1
  223. package/dist/ui/select/select-content.svelte +7 -6
  224. package/dist/ui/select/select-group-heading.svelte +1 -4
  225. package/dist/ui/select/select-item.svelte +1 -1
  226. package/dist/ui/select/select-trigger.svelte +2 -2
  227. package/dist/ui/select/select-value.svelte +1 -1
  228. package/dist/ui/separator/separator.svelte +1 -1
  229. package/dist/ui/sheet/sheet-content.svelte +3 -3
  230. package/dist/ui/sheet/sheet-content.svelte.d.ts +4 -4
  231. package/dist/ui/skeleton/skeleton.svelte +4 -4
  232. package/dist/ui/skeleton/skeleton.svelte.d.ts +10 -10
  233. package/dist/ui/slider/slider-range.svelte +1 -1
  234. package/dist/ui/slider/slider-thumb.svelte +1 -1
  235. package/dist/ui/slider/slider-tick.svelte +1 -1
  236. package/dist/ui/step/step-content.svelte +1 -1
  237. package/dist/ui/step/step-section.svelte +1 -1
  238. package/dist/ui/step/step-summary.svelte +7 -7
  239. package/dist/ui/switch/switch.svelte +2 -2
  240. package/dist/ui/table/table-cell.svelte +1 -1
  241. package/dist/ui/table/table-head-cell.svelte +1 -1
  242. package/dist/ui/table/table-row.svelte +1 -1
  243. package/dist/ui/time-field/time-field-segment.svelte +1 -1
  244. package/dist/ui/time-range-field/time-range-field-segment.svelte +1 -1
  245. package/dist/ui/toggle-group/toggle-group-item.svelte +1 -1
  246. package/dist/ui/toggle-group/toggle-group-root.svelte +1 -1
  247. package/dist/ui/tooltip/tooltip-content.svelte +1 -1
  248. package/dist/ui/video-player/video-player.svelte +44 -47
  249. package/dist/utils/index.js +1 -1
  250. package/package.json +4 -3
@@ -14,7 +14,7 @@
14
14
  </script>
15
15
 
16
16
  <Step.Summary>
17
- <Wrench class="size-(--era-h-icon) shrink-0" aria-hidden="true" />
17
+ <Wrench class="size-icon shrink-0" aria-hidden="true" />
18
18
  <span class="truncate text-fg">{type}</span>
19
19
  {@render children?.()}
20
20
  </Step.Summary>
@@ -15,19 +15,14 @@
15
15
  let nonce = $state(0);
16
16
  </script>
17
17
 
18
- <div
19
- class={cn(
20
- 'flex min-h-0 flex-col overflow-hidden rounded-(--era-rd-bar) bg-(--era-surface-bg) shadow-(--era-shadow-lg)',
21
- className
22
- )}
23
- >
24
- <Bar size="control" class="shrink-0 gap-(--era-gap) rounded-none">
18
+ <div class={cn('flex min-h-0 flex-col overflow-hidden rounded-bar bg-well shadow-lg', className)}>
19
+ <Bar size="control" class="shrink-0 gap-gutter rounded-none">
25
20
  <Button icon size="chip" aria-label="Reload" onclick={() => (nonce += 1)}>
26
- <RotateCw class="size-(--era-h-icon)" />
21
+ <RotateCw class="size-icon" />
27
22
  </Button>
28
23
  <Input
29
24
  bind:value={draft}
30
- class="h-(--era-h-chip) flex-1"
25
+ class="h-chip flex-1"
31
26
  placeholder="https://…"
32
27
  onkeydown={(e: KeyboardEvent) => {
33
28
  if (e.key === 'Enter') {
@@ -12,7 +12,7 @@
12
12
 
13
13
  <!-- Thin era skin over Svelte Flow — the graph engine is xyflow's. This file
14
14
  lives on its own subpath so the dependency stays opt-in. -->
15
- <SvelteFlow bind:nodes bind:edges fitView class="rounded-(--era-rd-bar) shadow-(--era-shadow)">
15
+ <SvelteFlow bind:nodes bind:edges fitView class="rounded-bar shadow-sm">
16
16
  <Background bgColor="var(--color-1)" />
17
17
  <Controls />
18
18
  {@render children?.()}
@@ -12,18 +12,18 @@
12
12
 
13
13
  <div
14
14
  class={cn(
15
- 'flex w-56 flex-col overflow-hidden rounded-(--era-rd-control) bg-(--era-surface-bg-elevated) text-body shadow-(--era-shadow-lg)',
15
+ 'flex w-56 flex-col overflow-hidden rounded-control bg-elevated text-body shadow-lg',
16
16
  className
17
17
  )}
18
18
  >
19
19
  <Handle type="target" position={Position.Left} />
20
20
  {#if title}
21
21
  <div
22
- class="flex h-(--era-h-control) items-center border-b border-divider-faded px-(--era-inset-control) font-medium text-bright"
22
+ class="flex h-control items-center border-b border-divider-faded px-inset-control font-medium text-bright"
23
23
  >
24
24
  {title}
25
25
  </div>
26
26
  {/if}
27
- <div class="p-(--era-inset-control) text-fg">{@render children?.()}</div>
27
+ <div class="p-inset-control text-fg">{@render children?.()}</div>
28
28
  <Handle type="source" position={Position.Right} />
29
29
  </div>
@@ -143,7 +143,7 @@
143
143
  <!-- Thread -->
144
144
  <div class="flex min-w-0 flex-1 flex-col">
145
145
  {#if runStatus !== 'idle'}
146
- <div class="shrink-0 border-b border-divider px-(--era-pad-card) py-gutter">
146
+ <div class="shrink-0 border-b border-divider px-card py-gutter">
147
147
  <AI.RunStatus.Root
148
148
  status={runStatus}
149
149
  tools={{
@@ -187,9 +187,9 @@
187
187
  <AI.Conversation.ScrollButton />
188
188
  </AI.Conversation.Root>
189
189
 
190
- <div class="mx-auto w-full max-w-2xl shrink-0 p-(--era-pad-card) pt-0">
190
+ <div class="mx-auto w-full max-w-2xl shrink-0 p-card pt-0">
191
191
  {#if active && active.messages.length === 0 && suggestions.length > 0}
192
- <div class="pb-(--era-gap)">
192
+ <div class="pb-gutter">
193
193
  <AI.Suggestions.Root>
194
194
  {#each suggestions as s (s)}
195
195
  <AI.Suggestions.Suggestion suggestion={s} onSelect={(t) => onSend?.(t)} />
@@ -265,7 +265,7 @@
265
265
  {#snippet expanded()}
266
266
  {@const tool = block.tools.find((t) => t.id === openChip)}
267
267
  {#if tool}
268
- <Card tone="well" class="flex min-w-0 flex-col gap-(--era-pad-panel) p-(--era-pad-panel)">
268
+ <Card tone="well" class="flex min-w-0 flex-col gap-panel p-panel">
269
269
  <AI.Tool.Input input={tool.input} />
270
270
  <AI.Tool.Output output={tool.output} />
271
271
  </Card>
@@ -239,13 +239,13 @@
239
239
 
240
240
  {#snippet paneHeader()}
241
241
  {#if selected}
242
- <div class="relative flex min-w-0 items-center gap-(--era-gap)" data-pane-control>
242
+ <div class="relative flex min-w-0 items-center gap-gutter" data-pane-control>
243
243
  {@render iconPicker(selected)}
244
244
  {@render titleField(selected, 'field-sizing-content max-w-56 min-w-0 text-center')}
245
245
  <!-- Absolutely positioned, so the badge appearing never nudges the
246
246
  centred title; empty when the status is quiet, which costs
247
247
  nothing off-flow. -->
248
- <span class="absolute top-1/2 left-full ml-(--era-gap) -translate-y-1/2">
248
+ <span class="absolute top-1/2 left-full ml-gutter -translate-y-1/2">
249
249
  {@render statusBadge()}
250
250
  </span>
251
251
  </div>
@@ -303,7 +303,7 @@
303
303
  one, and the bar's + is always within reach. Two competing CTAs for
304
304
  an empty list reads as indecision. -->
305
305
  <div
306
- class="flex flex-1 flex-col items-center justify-center gap-gutter p-content text-center"
306
+ class="flex flex-1 flex-col items-center justify-center gap-gutter p-section text-center"
307
307
  >
308
308
  <p class="text-muted">{query ? 'No matches' : 'No notes yet'}</p>
309
309
  </div>
@@ -331,8 +331,8 @@
331
331
  {#snippet child({ props })}
332
332
  <div
333
333
  {...props}
334
- class="group/row flex h-control cursor-pointer items-center gap-(--era-pill-inset-control) rounded-control px-(--era-pill-inset-control) leading-none {current
335
- ? 'bg-hover text-bright shadow-(--era-shadow-pressed)'
334
+ class="group/row flex h-control cursor-pointer items-center gap-pill-inset-control rounded-control px-pill-inset-control leading-none {current
335
+ ? 'bg-hover text-bright shadow-pressed'
336
336
  : 'hover:bg-highlight hover:shadow-highlight'}"
337
337
  role="option"
338
338
  aria-selected={current}
@@ -351,7 +351,7 @@
351
351
  {#if note.icon}
352
352
  {note.icon}
353
353
  {:else}
354
- <FileText class="size-(--era-glyph-pill) text-muted" />
354
+ <FileText class="size-glyph-pill text-muted" />
355
355
  {/if}
356
356
  </span>
357
357
 
@@ -370,7 +370,7 @@
370
370
  {formatAge(note.updatedAt)}
371
371
  </span>
372
372
  <span
373
- class="hidden shrink-0 items-center gap-(--era-pill-inset-control) group-hover/row:flex"
373
+ class="hidden shrink-0 items-center gap-pill-inset-control group-hover/row:flex"
374
374
  >
375
375
  <Button
376
376
  icon
@@ -467,7 +467,7 @@
467
467
  {/key}
468
468
  </div>
469
469
  {:else}
470
- <div class="flex flex-1 flex-col items-center justify-center gap-gutter p-content">
470
+ <div class="flex flex-1 flex-col items-center justify-center gap-gutter p-section">
471
471
  <p class="text-muted">
472
472
  {store.notes.length === 0 ? 'Create a note to get started' : 'Select a note'}
473
473
  </p>
@@ -16,7 +16,7 @@
16
16
  * its copy button — so flagging it would be noise. Nothing has a reason to sit
17
17
  * closer to its top edge than its bottom.
18
18
  *
19
- * `p-content` is the one earned exception and is exempt by construction rather
19
+ * `p-section` is the one earned exception and is exempt by construction rather
20
20
  * than by name: it subtracts the heading ROW's own slack from its top padding,
21
21
  * so it only ever appears on a full-bleed section with no radius, and this
22
22
  * audit looks only at rounded boxes — the ones that read as a container.
@@ -34,7 +34,7 @@ export const evenContainerPadding = {
34
34
  const s = getComputedStyle(el);
35
35
  // Rounded boxes only: a radius is what makes a box read as a container
36
36
  // with edges, and it also excludes the full-bleed page sections whose
37
- // top padding is legitimately reduced (see p-content).
37
+ // top padding is legitimately reduced (see p-section).
38
38
  if (parseFloat(s.borderTopLeftRadius) <= 0)
39
39
  return null;
40
40
  const top = parseFloat(s.paddingTop) || 0;
@@ -5,8 +5,8 @@ import { BOUNDED_TIER_MAX } from '../../measure.js';
5
5
  *
6
6
  * Rule 5: every element that can hold a single glyph carries a min-width equal to
7
7
  * its tier height, so one character renders as a perfect square (or circle, once
8
- * rounded) instead of a skinny vertical pill. Icon buttons take min-w-(--era-h-control);
9
- * Badge, Chip and the KV value cell take min-w-(--era-h-pill).
8
+ * rounded) instead of a skinny vertical pill. Icon buttons take min-w-control;
9
+ * Badge, Chip and the KV value cell take min-w-pill.
10
10
  *
11
11
  * Drop the min-width and nothing looks wrong until content happens to BE one
12
12
  * character — a badge showing "1", a count that ticks from 10 down to 9 — and the
@@ -59,10 +59,10 @@
59
59
 
60
60
  {#if dev && open}
61
61
  <div
62
- class="fixed right-4 bottom-4 z-50 flex max-h-[70vh] w-96 flex-col overflow-hidden rounded-(--era-rd-control) bg-surface font-mono text-body shadow-[inset_0_0_0_0.5px_var(--color-border),var(--era-shadow)]"
62
+ class="fixed right-4 bottom-4 z-50 flex max-h-[70vh] w-96 flex-col overflow-hidden rounded-control bg-surface font-mono text-body shadow-[inset_0_0_0_0.5px_var(--color-border),var(--era-shadow)]"
63
63
  >
64
64
  <header
65
- class="flex items-center gap-(--era-icon-inset-chip) px-(--era-inset-chip) py-(--era-gap) shadow-[inset_0_-0.5px_0_0_var(--color-border)]"
65
+ class="flex items-center gap-icon-inset-chip px-inset-chip py-gutter shadow-[inset_0_-0.5px_0_0_var(--color-border)]"
66
66
  >
67
67
  <strong class="text-bright">audits</strong>
68
68
  <span class="text-muted">
@@ -81,7 +81,7 @@
81
81
  {@const enabled = registry.isEnabled(r.audit.id)}
82
82
  <details open={r.issues.length > 0}>
83
83
  <summary
84
- class="flex cursor-pointer items-center gap-(--era-icon-inset-chip) px-(--era-inset-chip) py-(--era-gap) hover:bg-(--era-highlight)"
84
+ class="flex cursor-pointer items-center gap-icon-inset-chip px-inset-chip py-gutter hover:bg-highlight"
85
85
  >
86
86
  <input
87
87
  type="checkbox"
@@ -95,13 +95,13 @@
95
95
  </span>
96
96
  </summary>
97
97
  {#if r.issues.length === 0}
98
- <p class="px-(--era-inset-chip) py-(--era-gap) text-muted">
98
+ <p class="px-inset-chip py-gutter text-muted">
99
99
  {r.audit.description}
100
100
  </p>
101
101
  {:else}
102
102
  {#each r.issues as issue, i (i)}
103
103
  <button
104
- class="flex w-full items-start gap-(--era-icon-inset-chip) px-(--era-inset-chip) py-(--era-gap) text-left hover:bg-(--era-highlight)"
104
+ class="flex w-full items-start gap-icon-inset-chip px-inset-chip py-gutter text-left hover:bg-highlight"
105
105
  onclick={() => highlight(issue.element)}
106
106
  >
107
107
  <span class="text-destructive">●</span>
@@ -114,9 +114,9 @@
114
114
  </div>
115
115
 
116
116
  <footer
117
- class="flex items-center gap-(--era-gap) px-(--era-inset-chip) py-(--era-gap) text-muted shadow-[inset_0_0.5px_0_0_var(--color-border)]"
117
+ class="flex items-center gap-gutter px-inset-chip py-gutter text-muted shadow-[inset_0_0.5px_0_0_var(--color-border)]"
118
118
  >
119
- <kbd class="rounded-(--era-rd-icon) bg-hover px-(--era-inset-chip) text-fg">
119
+ <kbd class="rounded-icon bg-hover px-inset-chip text-fg">
120
120
  {isMac ? '⌘' : 'ctrl'}⇧{key.toUpperCase()}
121
121
  </kbd>
122
122
  <span>toggle</span>
@@ -16,6 +16,37 @@ export interface CssUtility {
16
16
  /** The `@utility` block verbatim, as authored. */
17
17
  css: string;
18
18
  }
19
+ /**
20
+ * `@theme` namespace → the utility prefixes it generates.
21
+ *
22
+ * Half of era's public class API is registered this way rather than as
23
+ * `@utility` blocks — `rounded-control` from `--radius-control`, `shadow-lg`,
24
+ * `bg-highlight`, `text-body`, and the whole spacing scale. They are classes a
25
+ * consumer writes exactly like the others, and until this table existed the
26
+ * doc pipeline could not see any of them: `@utility` was the only thing it
27
+ * parsed, so era's most-used names were also its least-documented.
28
+ *
29
+ * The list per namespace is the SPELLINGS WORTH DOCUMENTING, not everything
30
+ * Tailwind derives — a spacing token really does generate `mt-`, `gap-x-`,
31
+ * `inset-`, `translate-` and a dozen more, and printing all of them per name
32
+ * would bury the point. The prose says the rest.
33
+ */
34
+ export declare const THEME_CLASS_PREFIXES: Record<string, string[]>;
35
+ /** Every prefix a namespace really generates — the map the codemod needs. */
36
+ export declare const THEME_ALL_PREFIXES: Record<string, string[]>;
37
+ /**
38
+ * The classes one `@theme` key generates, each with the utility PREFIX that
39
+ * generated it — `--spacing-inset-control` → `{ prefix: 'px', name:
40
+ * 'px-inset-control' }`. The prefix cannot be recovered from the name (both
41
+ * `px` and `px-inset` are hyphen-splits of `px-inset-control`), and the codemod
42
+ * matches on it, so it is returned rather than re-derived.
43
+ */
44
+ export declare function themeKeyClassEntries(themeKey: string, prefixes?: Record<string, string[]>): {
45
+ prefix: string;
46
+ name: string;
47
+ }[];
48
+ /** The class names one `@theme` key generates, e.g. `--radius-control` → `rounded-control`. */
49
+ export declare function themeKeyClasses(themeKey: string, prefixes?: Record<string, string[]>): string[];
19
50
  /**
20
51
  * @param sources stylesheet text keyed by path relative to src/lib/styles
21
52
  * (e.g. `index.css`, `surfaces/glass.css`).
@@ -19,6 +19,64 @@
19
19
  */
20
20
  /** Files whose utilities are library API. Order fixes the doc's order. */
21
21
  const FILE_ORDER = ['index.css', 'surfaces/glass.css'];
22
+ /**
23
+ * `@theme` namespace → the utility prefixes it generates.
24
+ *
25
+ * Half of era's public class API is registered this way rather than as
26
+ * `@utility` blocks — `rounded-control` from `--radius-control`, `shadow-lg`,
27
+ * `bg-highlight`, `text-body`, and the whole spacing scale. They are classes a
28
+ * consumer writes exactly like the others, and until this table existed the
29
+ * doc pipeline could not see any of them: `@utility` was the only thing it
30
+ * parsed, so era's most-used names were also its least-documented.
31
+ *
32
+ * The list per namespace is the SPELLINGS WORTH DOCUMENTING, not everything
33
+ * Tailwind derives — a spacing token really does generate `mt-`, `gap-x-`,
34
+ * `inset-`, `translate-` and a dozen more, and printing all of them per name
35
+ * would bury the point. The prose says the rest.
36
+ */
37
+ export const THEME_CLASS_PREFIXES = {
38
+ radius: ['rounded'],
39
+ shadow: ['shadow'],
40
+ text: ['text'],
41
+ leading: ['leading'],
42
+ ease: ['ease'],
43
+ color: ['bg', 'text', 'border'],
44
+ spacing: ['p', 'px', 'py', 'gap']
45
+ };
46
+ /** Every prefix a namespace really generates — the map the codemod needs. */
47
+ export const THEME_ALL_PREFIXES = {
48
+ ...THEME_CLASS_PREFIXES,
49
+ radius: [
50
+ 'rounded',
51
+ ...'t,r,b,l,tl,tr,bl,br,s,e,ss,se,es,ee'.split(',').map((s) => `rounded-${s}`)
52
+ ],
53
+ color: [
54
+ 'bg',
55
+ 'text',
56
+ 'border',
57
+ 'fill',
58
+ 'stroke',
59
+ 'ring',
60
+ 'outline',
61
+ 'divide',
62
+ 'decoration',
63
+ 'caret',
64
+ 'accent',
65
+ 'from',
66
+ 'via',
67
+ 'to'
68
+ ],
69
+ spacing: [
70
+ 'p,px,py,pt,pr,pb,pl,ps,pe',
71
+ 'm,mx,my,mt,mr,mb,ml,ms,me',
72
+ 'gap,gap-x,gap-y',
73
+ 'w,h,size,min-w,min-h,max-w,max-h',
74
+ 'inset,inset-x,inset-y,top,right,bottom,left,start,end',
75
+ 'translate,translate-x,translate-y,scroll-m,scroll-p,basis,indent'
76
+ ]
77
+ .join(',')
78
+ .split(',')
79
+ };
22
80
  function cleanComment(raw) {
23
81
  return raw
24
82
  .split('\n')
@@ -86,6 +144,62 @@ function parseFile(file, source) {
86
144
  }
87
145
  return out;
88
146
  }
147
+ /**
148
+ * The classes one `@theme` key generates, each with the utility PREFIX that
149
+ * generated it — `--spacing-inset-control` → `{ prefix: 'px', name:
150
+ * 'px-inset-control' }`. The prefix cannot be recovered from the name (both
151
+ * `px` and `px-inset` are hyphen-splits of `px-inset-control`), and the codemod
152
+ * matches on it, so it is returned rather than re-derived.
153
+ */
154
+ export function themeKeyClassEntries(themeKey, prefixes = THEME_CLASS_PREFIXES) {
155
+ const bare = themeKey.replace(/^--/, '');
156
+ // `--shadow: …` IS the bare `shadow` class — a namespace with no suffix.
157
+ if (prefixes[bare])
158
+ return [{ prefix: bare, name: bare }];
159
+ const cut = bare.indexOf('-');
160
+ if (cut === -1)
161
+ return [];
162
+ const namespace = bare.slice(0, cut);
163
+ const suffix = bare.slice(cut + 1);
164
+ return (prefixes[namespace] ?? []).map((p) => ({ prefix: p, name: `${p}-${suffix}` }));
165
+ }
166
+ /** The class names one `@theme` key generates, e.g. `--radius-control` → `rounded-control`. */
167
+ export function themeKeyClasses(themeKey, prefixes = THEME_CLASS_PREFIXES) {
168
+ return themeKeyClassEntries(themeKey, prefixes).map((e) => e.name);
169
+ }
170
+ /**
171
+ * Named theme scales — the other half of the public class API.
172
+ *
173
+ * Shape parsed: a doc comment followed by a RUN of `--key: var(…)` lines inside
174
+ * `@theme`, exactly like the `@utility` ladder rule above. One comment governs
175
+ * the whole run, so the radius ladder or the spacing scale documents once.
176
+ */
177
+ function parseTheme(file, source) {
178
+ const theme = source.match(/@theme[^{]*\{([\s\S]*?)\n\}/);
179
+ if (!theme)
180
+ return [];
181
+ const body = theme[1];
182
+ const out = [];
183
+ const pattern = /\/\*((?:(?!\*\/)[\s\S])*)\*\/\s*((?:\s*--[\w-]+\s*:[^;]+;\n?)+)/g;
184
+ for (const match of body.matchAll(pattern)) {
185
+ const decls = [...match[2].matchAll(/--[\w-]+\s*:[^;]+;/g)].map((m) => m[0]);
186
+ const names = decls.flatMap((d) => themeKeyClasses(d.slice(0, d.indexOf(':')).trim()));
187
+ // A comment governing only non-class keys (--default-transition-*) has
188
+ // nothing to document — it is internal wiring, not API.
189
+ if (!names.length)
190
+ continue;
191
+ const { useCase, description } = splitUseCase(cleanComment(match[1]));
192
+ out.push({
193
+ name: names[0],
194
+ names,
195
+ file,
196
+ useCase,
197
+ description,
198
+ css: `@theme inline {\n${decls.map((d) => `\t${d}`).join('\n')}\n}`
199
+ });
200
+ }
201
+ return out;
202
+ }
89
203
  /**
90
204
  * @param sources stylesheet text keyed by path relative to src/lib/styles
91
205
  * (e.g. `index.css`, `surfaces/glass.css`).
@@ -97,7 +211,7 @@ export function parseUtilities(sources) {
97
211
  };
98
212
  return Object.entries(sources)
99
213
  .sort(([a], [b]) => rank(a) - rank(b) || a.localeCompare(b))
100
- .flatMap(([file, source]) => parseFile(file, source));
214
+ .flatMap(([file, source]) => [...parseFile(file, source), ...parseTheme(file, source)]);
101
215
  }
102
216
  const INTRO = [
103
217
  "era's styling API is pure class names — write `h-control rounded-control px-gutter shadow`,",
@@ -119,7 +233,7 @@ const INTRO = [
119
233
  '',
120
234
  '| Stock-looking class | What it resolves to |',
121
235
  '|---|---|',
122
- '| `rounded-icon/xxs/sm/md/lg` | the concentric radius ladder (collapses on `data-corners="square"`) |',
236
+ '| `rounded-icon/pill/chip/control/bar` | the concentric radius ladder (collapses on `data-corners="square"`) |',
123
237
  '| `rounded-menu-item` | menu-row radius, concentric inside a `rounded-control` panel |',
124
238
  '| `shadow` / `shadow-lg` | resting control edge / floating panel chrome, per surface |',
125
239
  '| `shadow-well` / `shadow-pressed` / `shadow-highlight` | recessed, pressed/latched, hover-material chrome |',
@@ -127,13 +241,33 @@ const INTRO = [
127
241
  '| `transition-*` (bare) | duration + easing default to the motion axis |',
128
242
  '| `ease-base` / `duration-base` | the motion axis, named explicitly |',
129
243
  '| `text-body` | density-derived body/control text size |',
244
+ '| `p-gutter` / `gap-gutter` / `mt-gutter` / … | the spacing scale — EVERY spacing prefix works |',
245
+ '',
246
+ 'The spacing names (`gutter`, `card`, `panel`, `content`, `menu`, `field`, the',
247
+ '`inset-*` and concentric `*-inset-*` insets, `glyph-*`) are registered as a',
248
+ 'Tailwind spacing scale, so every prefix derives automatically: `p-`, `px-`,',
249
+ '`pt-`, `mt-`, `gap-`, `gap-x-`, `inset-`, `translate-`, and the rest. The TIER',
250
+ 'names (`icon`, `pill`, `chip`, `control`, `bar`) are heights, not spacing, so',
251
+ 'they are registered per prefix instead — `h-`, `w-`, `min-h-`, `min-w-` and',
252
+ '`size-` — and the two vocabularies deliberately share no word. Putting a tier',
253
+ 'in the spacing scale would silently make `px-control` mean 24px of padding.',
130
254
  '',
131
- "Deliberate gaps: `w-*`/`min-w-*` tier names would shadow Tailwind's container",
132
- 'scale (`min-w-md` stays 28rem), and the concentric-inset tokens are advanced',
133
- 'enough to stay var-form `min-w-(--era-h-control)` etc. remain the escape hatch.'
255
+ 'The var form (`h-(--era-h-control)`) still works and is the escape hatch for a',
256
+ 'token with no registered name — `--era-sp`, the press-sink offsets, anything',
257
+ 'a component reaches for once. `scripts/check-canonical.ts` fails the build if',
258
+ 'source uses it where a name exists.'
134
259
  ].join('\n');
135
- /** `h-icon` for a single class, `h-icon · h-pill · … · h-bar` for a ladder. */
136
- const label = (u) => u.names.join(' · ');
260
+ /**
261
+ * `h-icon` for a single class, `h-icon · h-pill · … · h-bar` for a ladder.
262
+ *
263
+ * Capped, because a theme scale can govern a LOT of spellings: the colour block
264
+ * generates bg-/text-/border- for every token, which is ~60 names and reads as
265
+ * noise in a heading. The prose under each entry states the full rule.
266
+ */
267
+ const LABEL_CAP = 8;
268
+ const label = (u) => u.names.length > LABEL_CAP
269
+ ? `${u.names.slice(0, LABEL_CAP).join(' · ')} · … (${u.names.length} in all)`
270
+ : u.names.join(' · ');
137
271
  /** Renders the utilities reference — the generated `utilities.md` body. */
138
272
  export function buildUtilitiesDoc(utilities) {
139
273
  const lines = ['## Overview', '', INTRO, '', '| Utility | Use it for |', '|---|---|'];
@@ -7,7 +7,7 @@ Use a single, pure component import from `$lib/ui` for a clean docs-friendly sta
7
7
  import { Badge, Bar, Button, ButtonGroup, Card, Separator } from '$lib/ui';
8
8
  </script>
9
9
 
10
- <section class="mx-auto flex w-full max-w-4xl flex-col gap-(--era-content-p) p-(--era-content-p)">
10
+ <section class="mx-auto flex w-full max-w-4xl flex-col gap-content p-content">
11
11
  <Badge tone="accent">Now shipping v0.8</Badge>
12
12
 
13
13
  <div class="space-y-(--era-gap)">
@@ -28,10 +28,10 @@ Use a single, pure component import from `$lib/ui` for a clean docs-friendly sta
28
28
 
29
29
  <Separator />
30
30
 
31
- <div class="grid gap-(--era-gap) md:grid-cols-3">
32
- <Card class="p-(--era-gap)">Dense-ready</Card>
33
- <Card class="p-(--era-gap)">Balanced defaults</Card>
34
- <Card class="p-(--era-gap)">Spacious polish</Card>
31
+ <div class="grid gap-gutter md:grid-cols-3">
32
+ <Card class="p-gutter">Dense-ready</Card>
33
+ <Card class="p-gutter">Balanced defaults</Card>
34
+ <Card class="p-gutter">Spacious polish</Card>
35
35
  </div>
36
36
  </section>
37
37
  ```