@cueplusplus/ui 0.17.0 → 0.18.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 (203) hide show
  1. package/CHANGELOG.md +76 -0
  2. package/dist/chrome/empty-state.js +8 -4
  3. package/dist/chrome/navigation-menu.js +3 -2
  4. package/dist/chrome/panel.js +2 -1
  5. package/dist/chrome/row.js +4 -3
  6. package/dist/chrome/scroll-area.js +4 -3
  7. package/dist/chrome/segmented-control.js +2 -1
  8. package/dist/chrome/tabs.js +5 -2
  9. package/dist/chrome/toolbar.js +5 -3
  10. package/dist/date/_trigger.js +4 -1
  11. package/dist/date/calendar.js +15 -9
  12. package/dist/forms/_chassis.d.ts +10 -2
  13. package/dist/forms/_chassis.js +15 -5
  14. package/dist/forms/_listbox.js +18 -13
  15. package/dist/forms/checkbox.js +9 -6
  16. package/dist/forms/field.js +5 -5
  17. package/dist/forms/input-group.js +11 -2
  18. package/dist/forms/multi-select.js +4 -3
  19. package/dist/forms/number-field.js +6 -3
  20. package/dist/forms/otp-field.js +15 -6
  21. package/dist/forms/radio-group.js +7 -5
  22. package/dist/forms/select.js +8 -5
  23. package/dist/forms/slider.js +5 -3
  24. package/dist/forms/switch.js +6 -4
  25. package/dist/forms/tags-input.js +4 -3
  26. package/dist/forms/textarea.js +2 -1
  27. package/dist/forms/toggle-group.js +2 -1
  28. package/dist/forms/toggle.js +3 -1
  29. package/dist/instruments/meter.js +2 -1
  30. package/dist/instruments/progress.js +6 -3
  31. package/dist/instruments/stat.js +5 -3
  32. package/dist/instruments/table.js +3 -2
  33. package/dist/layout/_collapse.js +24 -8
  34. package/dist/layout/accordion.js +2 -1
  35. package/dist/layout/breadcrumb.js +8 -7
  36. package/dist/layout/card.js +2 -1
  37. package/dist/layout/collapsible.js +2 -1
  38. package/dist/layout/link.d.ts +14 -0
  39. package/dist/layout/link.js +4 -4
  40. package/dist/layout/pagination.js +7 -8
  41. package/dist/overlays/_surface.d.ts +4 -4
  42. package/dist/overlays/_surface.js +8 -7
  43. package/dist/overlays/alert-dialog.js +1 -1
  44. package/dist/overlays/command-palette.js +23 -8
  45. package/dist/overlays/dialog.js +1 -1
  46. package/dist/overlays/drawer.js +8 -1
  47. package/dist/overlays/hover-card.js +3 -1
  48. package/dist/overlays/popover.js +2 -1
  49. package/dist/overlays/toast.js +8 -4
  50. package/dist/overlays/tooltip.js +3 -4
  51. package/dist/primitives/avatar.js +6 -2
  52. package/dist/primitives/button.d.ts +1 -1
  53. package/dist/primitives/button.js +10 -7
  54. package/dist/primitives/chip.d.ts +0 -36
  55. package/dist/primitives/chip.js +14 -46
  56. package/dist/primitives/icon-button.d.ts +1 -1
  57. package/dist/primitives/kbd.js +2 -2
  58. package/dist/primitives/skeleton.js +2 -1
  59. package/dist/system/_style-accordion-rule.js +32 -0
  60. package/dist/system/_style-avatar.js +20 -0
  61. package/dist/system/_style-body-leading.js +1 -3
  62. package/dist/system/_style-body.js +7 -2
  63. package/dist/system/_style-caption-ink.js +17 -0
  64. package/dist/system/_style-caption-size.js +19 -0
  65. package/dist/system/_style-caption-weight.js +18 -0
  66. package/dist/system/_style-card-gap.js +14 -0
  67. package/dist/system/_style-cell.js +18 -0
  68. package/dist/system/_style-check-glyph.js +14 -0
  69. package/dist/system/_style-check.js +8 -1
  70. package/dist/system/_style-chip.js +41 -1
  71. package/dist/system/_style-choice-gap.js +15 -0
  72. package/dist/system/_style-collapse.js +81 -1
  73. package/dist/system/_style-control-gap.js +14 -0
  74. package/dist/system/_style-control-label.js +8 -1
  75. package/dist/system/_style-crumb.js +44 -0
  76. package/dist/system/_style-day.js +25 -0
  77. package/dist/system/_style-disabled.js +70 -0
  78. package/dist/system/_style-disclosure.js +21 -0
  79. package/dist/system/_style-empty-state.js +42 -0
  80. package/dist/system/_style-field-chassis.js +38 -0
  81. package/dist/system/_style-field-gap.js +12 -0
  82. package/dist/system/_style-glyph-ink.js +20 -0
  83. package/dist/system/_style-glyph-opacity.js +20 -0
  84. package/dist/system/_style-glyph-size.js +21 -0
  85. package/dist/system/_style-group-gap.js +15 -0
  86. package/dist/system/_style-group-label-pad.js +14 -0
  87. package/dist/system/_style-group-label.js +24 -0
  88. package/dist/system/_style-help.js +10 -1
  89. package/dist/system/_style-hover-card-width.js +15 -0
  90. package/dist/system/_style-kbd.js +13 -1
  91. package/dist/system/_style-link.js +15 -3
  92. package/dist/system/_style-menu.js +14 -1
  93. package/dist/system/_style-meter.js +15 -0
  94. package/dist/system/_style-nav-menu.js +48 -0
  95. package/dist/system/_style-option.js +61 -4
  96. package/dist/system/_style-otp.js +15 -0
  97. package/dist/system/_style-outline-hover.js +18 -0
  98. package/dist/system/_style-page.js +17 -0
  99. package/dist/system/_style-palette.js +18 -0
  100. package/dist/system/_style-panel.js +21 -0
  101. package/dist/system/_style-popover-width.js +15 -0
  102. package/dist/system/_style-radio.js +19 -0
  103. package/dist/system/_style-row-disabled.js +17 -0
  104. package/dist/system/_style-row.js +30 -0
  105. package/dist/system/_style-scrollbar.js +19 -0
  106. package/dist/system/_style-segment-pad.js +15 -0
  107. package/dist/system/_style-skeleton.js +15 -0
  108. package/dist/system/_style-slider.js +26 -0
  109. package/dist/system/_style-stat.js +31 -0
  110. package/dist/system/_style-stepper.js +16 -0
  111. package/dist/system/_style-switch.js +26 -0
  112. package/dist/system/_style-tab-hover.js +15 -0
  113. package/dist/system/_style-text-focus.js +26 -0
  114. package/dist/system/_style-toast.js +22 -0
  115. package/dist/system/_style-toggle.js +50 -0
  116. package/dist/system/_style-toolbar.js +23 -0
  117. package/dist/system/_style-tooltip.js +30 -1
  118. package/manifest/components/accordion.json +22 -1
  119. package/manifest/components/alert-dialog.json +7 -0
  120. package/manifest/components/app-bar.json +42 -0
  121. package/manifest/components/autocomplete.json +48 -1
  122. package/manifest/components/avatar-group.json +7 -0
  123. package/manifest/components/avatar.json +7 -0
  124. package/manifest/components/breadcrumb.json +7 -2
  125. package/manifest/components/button.json +16 -1
  126. package/manifest/components/calendar.json +6 -0
  127. package/manifest/components/card.json +1 -0
  128. package/manifest/components/channel-matrix.json +6 -0
  129. package/manifest/components/chart-tooltip-content.json +6 -0
  130. package/manifest/components/checkbox-group.json +22 -1
  131. package/manifest/components/checkbox.json +22 -1
  132. package/manifest/components/chip.json +6 -0
  133. package/manifest/components/collapsible.json +22 -0
  134. package/manifest/components/color-field.json +19 -0
  135. package/manifest/components/color-picker.json +19 -0
  136. package/manifest/components/combobox.json +48 -1
  137. package/manifest/components/command-palette.json +11 -0
  138. package/manifest/components/composer.json +19 -0
  139. package/manifest/components/context-menu.json +6 -0
  140. package/manifest/components/date-field.json +18 -0
  141. package/manifest/components/date-picker.json +22 -0
  142. package/manifest/components/date-range-picker.json +22 -0
  143. package/manifest/components/dialog.json +7 -0
  144. package/manifest/components/disclosure.json +22 -0
  145. package/manifest/components/dmx-bar.json +6 -0
  146. package/manifest/components/dmx-strip.json +6 -0
  147. package/manifest/components/drawer.json +7 -0
  148. package/manifest/components/dropdown-menu.json +6 -0
  149. package/manifest/components/empty-state.json +13 -0
  150. package/manifest/components/env-var-input.json +19 -0
  151. package/manifest/components/field-description.json +2 -1
  152. package/manifest/components/field-error.json +2 -1
  153. package/manifest/components/field-label.json +2 -1
  154. package/manifest/components/field.json +2 -1
  155. package/manifest/components/hover-card.json +8 -0
  156. package/manifest/components/input-group.json +21 -0
  157. package/manifest/components/input.json +19 -0
  158. package/manifest/components/kbd.json +2 -0
  159. package/manifest/components/link.json +23 -0
  160. package/manifest/components/menubar.json +6 -0
  161. package/manifest/components/meter.json +1 -0
  162. package/manifest/components/multi-select.json +49 -1
  163. package/manifest/components/musical-time-input.json +19 -0
  164. package/manifest/components/navigation-menu.json +16 -0
  165. package/manifest/components/number-field.json +21 -0
  166. package/manifest/components/otp-field.json +20 -0
  167. package/manifest/components/pagination.json +19 -0
  168. package/manifest/components/panel-header.json +3 -0
  169. package/manifest/components/panel.json +3 -0
  170. package/manifest/components/password-input.json +19 -0
  171. package/manifest/components/popover.json +7 -0
  172. package/manifest/components/progress.json +4 -0
  173. package/manifest/components/radio-group.json +6 -0
  174. package/manifest/components/radio.json +6 -0
  175. package/manifest/components/row.json +3 -0
  176. package/manifest/components/scroll-area.json +3 -1
  177. package/manifest/components/scrollable-tabs-list.json +3 -0
  178. package/manifest/components/scrub-input.json +19 -0
  179. package/manifest/components/seam-list.json +3 -0
  180. package/manifest/components/search-input.json +19 -0
  181. package/manifest/components/segmented-control.json +1 -0
  182. package/manifest/components/select.json +25 -0
  183. package/manifest/components/sheet.json +6 -0
  184. package/manifest/components/skeleton.json +2 -0
  185. package/manifest/components/slider.json +8 -0
  186. package/manifest/components/stat.json +8 -0
  187. package/manifest/components/switch.json +22 -0
  188. package/manifest/components/table-scroll-region.json +2 -0
  189. package/manifest/components/table.json +2 -0
  190. package/manifest/components/tabs.json +3 -0
  191. package/manifest/components/tags-input.json +49 -1
  192. package/manifest/components/textarea.json +19 -0
  193. package/manifest/components/theme-configurator.json +6 -0
  194. package/manifest/components/time-field.json +18 -0
  195. package/manifest/components/toast.json +9 -0
  196. package/manifest/components/toggle-group.json +2 -1
  197. package/manifest/components/toggle.json +28 -0
  198. package/manifest/components/toolbar.json +19 -0
  199. package/manifest/components/tooltip.json +11 -0
  200. package/manifest/fixtures.json +15 -0
  201. package/manifest/manifest.json +84 -84
  202. package/manifest/tokens.json +155 -1
  203. package/package.json +6 -6
@@ -1,5 +1,6 @@
1
1
  "use client";
2
2
  import { cn } from "../lib/cn.js";
3
+ import { ACCORDION_RULE_INK, ACCORDION_RULE_STYLE } from "../system/_style-accordion-rule.js";
3
4
  import { accordionPanelClasses, collapseCaretClasses, collapseLabelClasses, collapsePanelBodyClasses, collapseTriggerClasses } from "./_collapse.js";
4
5
  import { ChevronRightGlyph } from "./_glyphs.js";
5
6
  import * as React from "react";
@@ -36,7 +37,7 @@ const Accordion$1 = {
36
37
  return /* @__PURE__ */ jsx(Accordion.Item, {
37
38
  ref,
38
39
  "data-slot": "accordion-item",
39
- className: cn("border-t border-border first:border-t-0", className),
40
+ className: cn("border-t first:border-t-0", ACCORDION_RULE_INK, ACCORDION_RULE_STYLE, className),
40
41
  ...elementProps
41
42
  });
42
43
  }),
@@ -1,16 +1,17 @@
1
1
  import { cn } from "../lib/cn.js";
2
2
  import { FOCUS_RING_OFFSET_2 } from "../system/_focus-ring.js";
3
- import { CONTROL_FACE } from "../system/_style-control-face.js";
4
- import { BODY_SIZE_LABEL } from "../system/_style-body-size.js";
5
3
  import { HELP_INK } from "../system/_style-help-ink.js";
4
+ import { CRUMB_CURRENT_INK, CRUMB_FACE, CRUMB_GAP, CRUMB_HOVER_INK, CRUMB_INK, CRUMB_SEPARATOR_OPACITY, CRUMB_SIZE } from "../system/_style-crumb.js";
6
5
  import * as React from "react";
7
6
  import { jsx, jsxs } from "react/jsx-runtime";
8
7
  //#region src/layout/breadcrumb.tsx
9
8
  /**
10
9
  * A crumb that goes somewhere. Muted until hovered, never underlined — the
11
- * trail is navigation furniture and should not read as body-copy links.
10
+ * trail is navigation furniture and should not read as body-copy links. Its
11
+ * face, hover ink and the trail's gap read the style set (round 6, spec §11,
12
+ * lane R6.Z: `_style-crumb.ts`), each falling back to what it drew.
12
13
  */
13
- const CRUMB_LINK_CLASSES = `cursor-pointer rounded-control border-0 bg-transparent p-0 ${CONTROL_FACE} ${BODY_SIZE_LABEL} text-fg-muted no-underline transition-colors duration-150 outline-none hover:text-accent ${FOCUS_RING_OFFSET_2}`;
14
+ const CRUMB_LINK_CLASSES = `cursor-pointer rounded-control border-0 bg-transparent p-0 ${CRUMB_FACE} ${CRUMB_SIZE} ${CRUMB_INK} no-underline transition-colors duration-150 outline-none ${CRUMB_HOVER_INK} ${FOCUS_RING_OFFSET_2}`;
14
15
  /**
15
16
  * Where you are, and how to get back.
16
17
  *
@@ -32,13 +33,13 @@ const Breadcrumb = React.forwardRef(function Breadcrumb({ className, items, sepa
32
33
  className: cn("min-w-0", className),
33
34
  ...elementProps,
34
35
  children: /* @__PURE__ */ jsx("ol", {
35
- className: cn(`m-0 flex list-none flex-wrap items-center gap-(--cue-space-2) p-0 ${BODY_SIZE_LABEL} text-fg-muted`, CONTROL_FACE),
36
+ className: cn(`m-0 flex list-none flex-wrap items-center ${CRUMB_GAP} p-0 ${CRUMB_SIZE} ${CRUMB_INK}`, CRUMB_FACE),
36
37
  children: items.map((item, index) => {
37
38
  const last = index === items.length - 1;
38
39
  return /* @__PURE__ */ jsxs(React.Fragment, { children: [index === 0 ? null : /* @__PURE__ */ jsx("li", {
39
40
  "data-slot": "breadcrumb-separator",
40
41
  "aria-hidden": "true",
41
- className: `${HELP_INK} select-none`,
42
+ className: `${HELP_INK} ${CRUMB_SEPARATOR_OPACITY} select-none`,
42
43
  children: separator
43
44
  }), /* @__PURE__ */ jsx("li", {
44
45
  "data-slot": "breadcrumb-item",
@@ -46,7 +47,7 @@ const Breadcrumb = React.forwardRef(function Breadcrumb({ className, items, sepa
46
47
  children: last ? /* @__PURE__ */ jsx("span", {
47
48
  "data-slot": "breadcrumb-current",
48
49
  "aria-current": "page",
49
- className: "truncate text-fg",
50
+ className: `truncate ${CRUMB_CURRENT_INK}`,
50
51
  children: item.label
51
52
  }) : item.href !== void 0 ? /* @__PURE__ */ jsx("a", {
52
53
  href: item.href,
@@ -5,6 +5,7 @@ import { RIM_INSET } from "../system/_paint-rim.js";
5
5
  import { TITLE_VOICE } from "../system/_style-title.js";
6
6
  import { SEAM_INK, SEAM_RIM } from "../system/_style-seam.js";
7
7
  import { STROKE_SURFACE_1 } from "../system/_paint-stroke-surface-1.js";
8
+ import { CARD_GAP } from "../system/_style-card-gap.js";
8
9
  import { CARD_PAD, CARD_PAD_BOTTOM, CARD_PAD_SEAM_BOTTOM, CARD_PAD_SEAM_TOP, CARD_PAD_TOP, CARD_PAD_X } from "../system/_style-card-pad.js";
9
10
  import { DESCRIPTION_LEADING, DESCRIPTION_TRACKING } from "../system/_style-description.js";
10
11
  import * as React from "react";
@@ -38,7 +39,7 @@ const Card = {
38
39
  className: cn(`flex items-start justify-between gap-(--cue-space-4) bg-surface-1 ${CARD_PAD_X} ${CARD_PAD_TOP} pb-0 ${CARD_PAD_SEAM_BOTTOM}`, className),
39
40
  ...elementProps,
40
41
  children: [/* @__PURE__ */ jsx("div", {
41
- className: "flex min-w-0 flex-col gap-(--cue-space-1)",
42
+ className: `flex min-w-0 flex-col ${CARD_GAP}`,
42
43
  children
43
44
  }), actions === void 0 ? null : /* @__PURE__ */ jsx("div", {
44
45
  "data-slot": "card-header-actions",
@@ -6,6 +6,7 @@ import { LABEL_CASE } from "../system/_style-label-case.js";
6
6
  import { LABEL_TRACKING } from "../system/_style-label-tracking.js";
7
7
  import { collapseCaretClasses, collapseLabelClasses, collapsePanelBodyClasses, collapseTriggerClasses, collapsiblePanelClasses } from "./_collapse.js";
8
8
  import { ChevronRightGlyph } from "./_glyphs.js";
9
+ import { DISCLOSURE_HOVER_INK, DISCLOSURE_INK, DISCLOSURE_WEIGHT } from "../system/_style-disclosure.js";
9
10
  import * as React from "react";
10
11
  import { jsx, jsxs } from "react/jsx-runtime";
11
12
  import { Collapsible } from "@base-ui/react/collapsible";
@@ -98,7 +99,7 @@ const Disclosure = React.forwardRef(function Disclosure({ className, label = "ad
98
99
  children: [/* @__PURE__ */ jsxs(Collapsible.Trigger, {
99
100
  ref,
100
101
  "data-slot": "disclosure-trigger",
101
- className: cn(`group/disclosure inline-flex cursor-pointer items-center gap-(--cue-space-2) self-start border-0 bg-transparent p-0 py-(--cue-space-2) text-(length:--cue-text-label) text-fg-subtle transition-colors duration-150 outline-none select-none hover:text-fg-muted ${FOCUS_RING_OFFSET_2}`, LABEL_FACE, LABEL_TRACKING, LABEL_CASE, className),
102
+ className: cn(`group/disclosure inline-flex cursor-pointer items-center gap-(--cue-space-2) self-start border-0 bg-transparent p-0 py-(--cue-space-2) text-(length:--cue-text-label) ${DISCLOSURE_INK} ${DISCLOSURE_WEIGHT} transition-colors duration-150 outline-none select-none ${DISCLOSURE_HOVER_INK} ${FOCUS_RING_OFFSET_2}`, LABEL_FACE, LABEL_TRACKING, LABEL_CASE, className),
102
103
  ...elementProps,
103
104
  children: [
104
105
  /* @__PURE__ */ jsx("span", {
@@ -48,6 +48,20 @@ interface LinkProps extends React.ComponentPropsWithoutRef<"a">, VariantProps<ty
48
48
  * how the design system composes with a router without depending on one.
49
49
  */
50
50
  render?: useRender.RenderProp;
51
+ /**
52
+ * Where the link goes. Restated from the anchor's own attributes, as
53
+ * `children` is below: docgen documents a prop only where the library
54
+ * declares it, and an anchor without an `href` is not a link to the
55
+ * keyboard or to a screen reader.
56
+ */
57
+ href?: string;
58
+ /**
59
+ * The link's text. Restated for the same reason: without it the props table
60
+ * omitted it and no propSet could name it, so the docs' Link tile drew an
61
+ * empty anchor (round 6 of the Looks' fidelity plan found it, measuring
62
+ * Kiln's plain link, K161).
63
+ */
64
+ children?: React.ReactNode;
51
65
  }
52
66
  /**
53
67
  * A text link: accent on hover, no rule unless you ask for one.
@@ -1,9 +1,9 @@
1
1
  "use client";
2
2
  import { cn } from "../lib/cn.js";
3
- import { FOCUS_RING_OFFSET_2 } from "../system/_focus-ring.js";
4
3
  import { CONTROL_FACE } from "../system/_style-control-face.js";
5
4
  import { cva } from "../lib/cva.js";
6
- import { HOVER_INK, INLINE_LINK_INK, LINK_INK, LINK_OFFSET, LINK_RULE, LINK_WEIGHT } from "../system/_style-link.js";
5
+ import { HOVER_INK, HOVER_RULE, INLINE_LINK_INK, LINK_INK, LINK_OFFSET, LINK_RULE, LINK_WEIGHT } from "../system/_style-link.js";
6
+ import { LINK_FOCUS_RING } from "../system/_style-text-focus.js";
7
7
  import * as React from "react";
8
8
  import { Fragment, jsx, jsxs } from "react/jsx-runtime";
9
9
  import { useRender } from "@base-ui/react/use-render";
@@ -38,10 +38,10 @@ import { useRender } from "@base-ui/react/use-render";
38
38
  * @example
39
39
  * <a className={linkVariants({ variant: "underline" })} href="/docs">Docs</a>
40
40
  */
41
- const linkVariants = cva(`cursor-pointer rounded-control ${CONTROL_FACE} ${LINK_WEIGHT} transition-colors duration-150 outline-none ${HOVER_INK} ${FOCUS_RING_OFFSET_2}`, {
41
+ const linkVariants = cva(`cursor-pointer rounded-control ${CONTROL_FACE} ${LINK_WEIGHT} transition-colors duration-150 outline-none ${HOVER_INK} ${LINK_FOCUS_RING}`, {
42
42
  variants: { variant: {
43
43
  plain: `no-underline ${LINK_INK}`,
44
- underline: `underline ${INLINE_LINK_INK} ${LINK_RULE} ${LINK_OFFSET} hover:decoration-[color:var(--cue-style-hover-ink,var(--cue-accent))]`
44
+ underline: `underline ${INLINE_LINK_INK} ${LINK_RULE} ${LINK_OFFSET} ${HOVER_RULE}`
45
45
  } },
46
46
  defaultVariants: { variant: "plain" }
47
47
  });
@@ -1,8 +1,12 @@
1
1
  "use client";
2
2
  import { cn } from "../lib/cn.js";
3
3
  import { FOCUS_RING_INSET } from "../system/_focus-ring.js";
4
+ import { CONTROL_FACE } from "../system/_style-control-face.js";
5
+ import { GLYPH_INK_SUBTLE } from "../system/_style-glyph-ink.js";
6
+ import { GHOST_INK } from "../system/_style-control.js";
4
7
  import { IconButton } from "../primitives/icon-button.js";
5
8
  import { ChevronLeftGlyph, ChevronRightGlyph } from "./_glyphs.js";
9
+ import { PAGE_CURRENT } from "../system/_style-page.js";
6
10
  import * as React from "react";
7
11
  import { jsx, jsxs } from "react/jsx-runtime";
8
12
  //#region src/layout/pagination.tsx
@@ -58,12 +62,7 @@ function paginationRange(page, pageCount, siblingCount = 1) {
58
62
  return typeof before === "number" && typeof after === "number" && after - before === 2 ? before + 1 : entry;
59
63
  });
60
64
  }
61
- /**
62
- * One page button: a square on the short rung of the control ladder, tinted
63
- * with `accent-soft` when it is the page you are on — never a solid accent
64
- * fill, which at console density reads as a second, louder button.
65
- */
66
- const PAGE_BUTTON_CLASSES = `inline-flex h-control-sm min-w-control-sm cursor-pointer items-center justify-center rounded-control border-0 bg-transparent px-(--cue-space-2) font-mono text-(length:--cue-text-ui) tabular-nums text-fg-muted transition-colors duration-150 outline-none select-none hover:bg-surface-2 hover:text-fg ${FOCUS_RING_INSET}`;
65
+ const PAGE_BUTTON_CLASSES = `inline-flex h-control-sm min-w-control-sm cursor-pointer items-center justify-center rounded-control border-0 bg-transparent px-(--cue-space-2) ${CONTROL_FACE} font-[number:var(--cue-style-control-weight,inherit)] text-(length:--cue-text-ui) tabular-nums ${GHOST_INK} transition-colors duration-150 outline-none select-none hover:bg-surface-2 hover:text-fg ${FOCUS_RING_INSET}`;
67
66
  /**
68
67
  * The pager: previous, a window of page numbers, next.
69
68
  *
@@ -97,7 +96,7 @@ const Pagination = React.forwardRef(function Pagination({ className, page, pageC
97
96
  entries.map((entry, index) => entry === "gap" ? /* @__PURE__ */ jsx("span", {
98
97
  "data-slot": "pagination-gap",
99
98
  "aria-hidden": "true",
100
- className: "inline-flex h-control-sm items-center justify-center px-(--cue-space-1) font-mono text-(length:--cue-text-ui) text-fg-subtle select-none",
99
+ className: `inline-flex h-control-sm items-center justify-center px-(--cue-space-1) font-mono text-(length:--cue-text-ui) ${GLYPH_INK_SUBTLE} select-none`,
101
100
  children: "…"
102
101
  }, `gap-${index}`) : /* @__PURE__ */ jsx("button", {
103
102
  type: "button",
@@ -105,7 +104,7 @@ const Pagination = React.forwardRef(function Pagination({ className, page, pageC
105
104
  "aria-label": `Page ${entry}`,
106
105
  "aria-current": entry === page ? "page" : void 0,
107
106
  onClick: () => onPageChange(entry),
108
- className: cn(PAGE_BUTTON_CLASSES, entry === page ? "bg-accent-soft text-accent" : null),
107
+ className: cn(PAGE_BUTTON_CLASSES, entry === page ? PAGE_CURRENT : null),
109
108
  children: entry
110
109
  }, entry)),
111
110
  /* @__PURE__ */ jsx(IconButton, {
@@ -117,13 +117,13 @@ declare const overlayFooterClasses = "flex items-center justify-end gap-(--cue-s
117
117
  * and the highlight are the style set's, with those as their defaults
118
118
  * (`_style-menu.ts`).
119
119
  */
120
- declare const menuItemClasses = "flex h-control-sm cursor-default items-center gap-(--cue-space-2) rounded-[var(--cue-style-menu-item-radius,calc(var(--cue-radius-control)*var(--cue-radius-scale)))] px-(--cue-space-3) font-[family-name:var(--cue-style-control-face,var(--cue-font-mono))] text-(length:--cue-text-ui) text-[color:var(--cue-style-quiet-ink,var(--cue-fg-muted))] data-[highlighted]:bg-[color:var(--cue-style-menu-highlight,var(--cue-accent-soft))] outline-none select-none data-[highlighted]:text-fg data-[disabled]:pointer-events-none data-[disabled]:opacity-40";
120
+ declare const menuItemClasses = "flex h-control-sm cursor-default items-center gap-(--cue-space-2) rounded-[var(--cue-style-menu-item-radius,calc(var(--cue-radius-control)*var(--cue-radius-scale)))] px-(--cue-space-3) font-[family-name:var(--cue-style-control-face,var(--cue-font-mono))] text-(length:--cue-text-ui) text-[color:var(--cue-style-quiet-ink,var(--cue-fg-muted))] data-[highlighted]:bg-[color:var(--cue-style-menu-highlight,var(--cue-accent-soft))] outline-none select-none data-[highlighted]:text-fg data-[disabled]:pointer-events-none data-[disabled]:opacity-[var(--cue-style-row-disabled-opacity,0.4)]";
121
121
  /** The uppercase mono caption over a group of menu rows — by default. */
122
- declare const menuLabelClasses = "flex h-control-sm items-center px-(--cue-space-3) font-[family-name:var(--cue-style-label-face,var(--cue-font-mono))] text-[length:var(--cue-style-label-size,var(--cue-text-label))] tracking-[var(--cue-style-label-tracking,var(--cue-tracking-caps))] text-[color:var(--cue-style-label-ink,var(--cue-fg-subtle))] font-[number:var(--cue-style-label-weight,inherit)] [text-transform:var(--cue-style-label-case,uppercase)] select-none";
122
+ declare const menuLabelClasses = "flex h-control-sm items-center px-(--cue-space-3) py-[var(--cue-style-group-label-pad,0px)] font-[family-name:var(--cue-style-label-face,var(--cue-font-mono))] text-[length:var(--cue-style-group-label-size,var(--cue-style-label-size,var(--cue-text-label)))] tracking-[var(--cue-style-label-tracking,var(--cue-tracking-caps))] text-[color:var(--cue-style-group-label-ink,var(--cue-style-label-ink,var(--cue-fg-subtle)))] font-[number:var(--cue-style-label-weight,inherit)] [text-transform:var(--cue-style-label-case,uppercase)] select-none";
123
123
  /** The hairline between menu groups. */
124
- declare const menuSeparatorClasses = "my-(--cue-space-1) h-px bg-border";
124
+ declare const menuSeparatorClasses = "my-(--cue-space-1) mx-[var(--cue-style-menu-separator-inset,0px)] h-px bg-border";
125
125
  /** Padding of a menu popup — a single space unit so rows reach the rim. */
126
- declare const menuPopupClasses = "min-w-[10rem] p-(--cue-space-1)";
126
+ declare const menuPopupClasses = "min-w-[var(--cue-style-menu-min-width,10rem)] p-(--cue-space-1)";
127
127
  /** Default gap in px between an anchored popup and its trigger. */
128
128
  declare const OVERLAY_SIDE_OFFSET = 4;
129
129
  //#endregion
@@ -1,14 +1,15 @@
1
1
  import { CONTROL_FACE } from "../system/_style-control-face.js";
2
- import { LABEL_INK_SUBTLE } from "../system/_style-label-ink.js";
3
2
  import { LABEL_FACE } from "../system/_style-label-face.js";
4
3
  import { LABEL_WEIGHT } from "../system/_style-label-weight.js";
5
4
  import { LABEL_CASE } from "../system/_style-label-case.js";
6
5
  import { LABEL_TRACKING } from "../system/_style-label-tracking.js";
7
6
  import { ELEVATION_2 } from "../system/_paint-elevation.js";
8
- import { LABEL_SIZE } from "../system/_style-label-size.js";
9
7
  import { STROKE_SURFACE_2 } from "../system/_paint-stroke-surface-2.js";
10
8
  import { BODY_VOICE } from "../system/_style-body.js";
11
- import { MENU_ITEM_INK, MENU_ITEM_RADIUS } from "../system/_style-menu.js";
9
+ import { GROUP_LABEL_INK, GROUP_LABEL_SIZE } from "../system/_style-group-label.js";
10
+ import { GROUP_LABEL_PAD } from "../system/_style-group-label-pad.js";
11
+ import { MENU_ITEM_INK, MENU_ITEM_RADIUS, MENU_MIN_WIDTH, MENU_SEPARATOR_INSET } from "../system/_style-menu.js";
12
+ import { ROW_DISABLED_OPACITY } from "../system/_style-row-disabled.js";
12
13
  import { OVERLAY_TITLE_VOICE } from "../system/_style-overlay-title.js";
13
14
  import { BODY_LEADING } from "../system/_style-body-leading.js";
14
15
  import { BODY_SIZE } from "../system/_style-body-size.js";
@@ -131,13 +132,13 @@ const overlayFooterClasses = "flex items-center justify-end gap-(--cue-space-3)
131
132
  * and the highlight are the style set's, with those as their defaults
132
133
  * (`_style-menu.ts`).
133
134
  */
134
- const menuItemClasses = `flex h-control-sm cursor-default items-center gap-(--cue-space-2) ${MENU_ITEM_RADIUS} px-(--cue-space-3) ${CONTROL_FACE} text-(length:--cue-text-ui) ${MENU_ITEM_INK} outline-none select-none data-[highlighted]:text-fg data-[disabled]:pointer-events-none data-[disabled]:opacity-40`;
135
+ const menuItemClasses = `flex h-control-sm cursor-default items-center gap-(--cue-space-2) ${MENU_ITEM_RADIUS} px-(--cue-space-3) ${CONTROL_FACE} text-(length:--cue-text-ui) ${MENU_ITEM_INK} outline-none select-none data-[highlighted]:text-fg data-[disabled]:pointer-events-none ${ROW_DISABLED_OPACITY}`;
135
136
  /** The uppercase mono caption over a group of menu rows — by default. */
136
- const menuLabelClasses = `flex h-control-sm items-center px-(--cue-space-3) ${LABEL_FACE} ${LABEL_SIZE} ${LABEL_TRACKING} ${LABEL_INK_SUBTLE} ${LABEL_WEIGHT} ${LABEL_CASE} select-none`;
137
+ const menuLabelClasses = `flex h-control-sm items-center px-(--cue-space-3) ${GROUP_LABEL_PAD} ${LABEL_FACE} ${GROUP_LABEL_SIZE} ${LABEL_TRACKING} ${GROUP_LABEL_INK} ${LABEL_WEIGHT} ${LABEL_CASE} select-none`;
137
138
  /** The hairline between menu groups. */
138
- const menuSeparatorClasses = "my-(--cue-space-1) h-px bg-border";
139
+ const menuSeparatorClasses = `my-(--cue-space-1) ${MENU_SEPARATOR_INSET} h-px bg-border`;
139
140
  /** Padding of a menu popup — a single space unit so rows reach the rim. */
140
- const menuPopupClasses = "min-w-[10rem] p-(--cue-space-1)";
141
+ const menuPopupClasses = `${MENU_MIN_WIDTH} p-(--cue-space-1)`;
141
142
  /** Default gap in px between an anchored popup and its trigger. */
142
143
  const OVERLAY_SIDE_OFFSET = 4;
143
144
  //#endregion
@@ -9,7 +9,7 @@ import { jsx, jsxs } from "react/jsx-runtime";
9
9
  import { AlertDialog } from "@base-ui/react/alert-dialog";
10
10
  //#region src/overlays/alert-dialog.tsx
11
11
  /** Same geometry as a dialog; an alert is simply a narrower default. */
12
- const alertDialogPopupVariants = cva(`${overlaySurfaceClasses} ${overlayModalTransitionClasses} fixed top-1/2 left-1/2 z-50 flex max-h-[85vh] w-[calc(100vw-2rem)] -translate-x-1/2 -translate-y-1/2 flex-col gap-(--cue-space-4) overflow-y-auto p-(--cue-space-6) outline-none`, {
12
+ const alertDialogPopupVariants = cva(`${overlaySurfaceClasses} rounded-[calc(var(--cue-style-dialog-radius,var(--cue-radius-overlay))*var(--cue-radius-scale))] ${overlayModalTransitionClasses} fixed top-1/2 left-1/2 z-50 flex max-h-[85vh] w-[calc(100vw-2rem)] -translate-x-1/2 -translate-y-1/2 flex-col gap-(--cue-space-4) overflow-y-auto p-(--cue-space-6) outline-none`, {
13
13
  variants: { width: {
14
14
  sm: "max-w-[20rem]",
15
15
  md: "max-w-[26rem]",
@@ -1,12 +1,17 @@
1
1
  "use client";
2
2
  import { cn } from "../lib/cn.js";
3
3
  import { CONTROL_FACE } from "../system/_style-control-face.js";
4
+ import { CONTROL_STEP_SIZE_BODY } from "../system/_style-control-step.js";
4
5
  import { LABEL_FACE } from "../system/_style-label-face.js";
5
6
  import { LABEL_CASE } from "../system/_style-label-case.js";
6
7
  import { LABEL_TRACKING } from "../system/_style-label-tracking.js";
7
8
  import { SearchGlyph } from "./_glyphs.js";
8
9
  import { useCuePortalProps } from "../system/portal.js";
10
+ import { GROUP_LABEL_INK_SUBTLE, GROUP_LABEL_SIZE_MICRO } from "../system/_style-group-label.js";
11
+ import { MENU_ITEM_INK, MENU_ITEM_RADIUS } from "../system/_style-menu.js";
12
+ import { ROW_DISABLED_OPACITY } from "../system/_style-row-disabled.js";
9
13
  import { overlayModalTransitionClasses, overlaySurfaceClasses, scrimClasses } from "./_surface.js";
14
+ import { PALETTE_FOOTER_PAD, PALETTE_RULE } from "../system/_style-palette.js";
10
15
  import { useDebouncedValue } from "./_debounce.js";
11
16
  import * as React from "react";
12
17
  import { Fragment, jsx, jsxs } from "react/jsx-runtime";
@@ -51,8 +56,18 @@ function groupCommands(items) {
51
56
  }
52
57
  return groups;
53
58
  }
54
- /** The row: same rhythm as a menu row, with a reserved gutter for the icon. */
55
- const commandItemClasses = `flex h-control-md cursor-default items-center gap-(--cue-space-3) rounded-control px-(--cue-space-3) ${CONTROL_FACE} text-(length:--cue-text-ui) text-fg-muted outline-none select-none data-[highlighted]:bg-accent-soft data-[highlighted]:text-fg data-[disabled]:pointer-events-none data-[disabled]:opacity-40`;
59
+ /**
60
+ * The palette's corner is a dialog's (round 6, spec §11, P152): coss's command
61
+ * palette is a dialog, rounded at its 16px surface rung. The same class as
62
+ * `dialog.tsx`'s `DIALOG_RADIUS`, kept in this file for that file's reason.
63
+ */
64
+ const PALETTE_RADIUS = "rounded-[calc(var(--cue-style-dialog-radius,var(--cue-radius-overlay))*var(--cue-radius-scale))]";
65
+ /**
66
+ * The row: same rhythm as a menu row, with a reserved gutter for the icon. Its
67
+ * ink, highlight and corner are a menu row's (round 6, spec §11, P152): coss's
68
+ * command rows draw like its menu rows, in `fg` on 0.6 of the control corner.
69
+ */
70
+ const commandItemClasses = `flex h-control-md cursor-default items-center gap-(--cue-space-3) ${MENU_ITEM_RADIUS} px-(--cue-space-3) ${CONTROL_FACE} text-(length:--cue-text-ui) ${MENU_ITEM_INK} outline-none select-none data-[highlighted]:text-fg data-[disabled]:pointer-events-none ${ROW_DISABLED_OPACITY}`;
56
71
  /**
57
72
  * The ⌘K surface: type a few letters, run a command.
58
73
  *
@@ -118,7 +133,7 @@ function CommandPalette({ items, onSelect, open: openProp, defaultOpen = false,
118
133
  }), /* @__PURE__ */ jsxs(Dialog.Popup, {
119
134
  "aria-label": label,
120
135
  "data-slot": "command-palette-popup",
121
- className: cn(overlaySurfaceClasses, overlayModalTransitionClasses, "fixed top-[14vh] left-1/2 z-50 flex max-h-[72vh] w-[min(35rem,92vw)] -translate-x-1/2 flex-col overflow-hidden outline-none", className),
136
+ className: cn(overlaySurfaceClasses, PALETTE_RADIUS, overlayModalTransitionClasses, "fixed top-[14vh] left-1/2 z-50 flex max-h-[72vh] w-[min(35rem,92vw)] -translate-x-1/2 flex-col overflow-hidden outline-none", className),
122
137
  children: [/* @__PURE__ */ jsxs(Combobox.Root, {
123
138
  items: groups,
124
139
  filteredItems: filteredGroups,
@@ -136,7 +151,7 @@ function CommandPalette({ items, onSelect, open: openProp, defaultOpen = false,
136
151
  children: [
137
152
  /* @__PURE__ */ jsxs("div", {
138
153
  "data-slot": "command-palette-field",
139
- className: "flex h-control-lg shrink-0 items-center gap-(--cue-space-3) border-b border-border bg-sunken px-(--cue-space-4)",
154
+ className: `flex h-control-lg shrink-0 items-center gap-(--cue-space-3) border-b ${PALETTE_RULE} bg-sunken px-(--cue-space-4)`,
140
155
  children: [/* @__PURE__ */ jsx(SearchGlyph, {
141
156
  "aria-hidden": "true",
142
157
  className: "size-icon-md shrink-0 text-fg-subtle"
@@ -144,7 +159,7 @@ function CommandPalette({ items, onSelect, open: openProp, defaultOpen = false,
144
159
  "aria-label": label,
145
160
  placeholder,
146
161
  "data-slot": "command-palette-input",
147
- className: cn("h-full w-full min-w-0 border-0 bg-transparent p-0 text-(length:--cue-text-body) text-fg outline-none placeholder:text-fg-subtle", CONTROL_FACE)
162
+ className: cn(`h-full w-full min-w-0 border-0 bg-transparent p-0 ${CONTROL_STEP_SIZE_BODY} text-fg outline-none placeholder:text-fg-subtle`, CONTROL_FACE)
148
163
  })]
149
164
  }),
150
165
  /* @__PURE__ */ jsx(Combobox.Empty, {
@@ -154,12 +169,12 @@ function CommandPalette({ items, onSelect, open: openProp, defaultOpen = false,
154
169
  }),
155
170
  /* @__PURE__ */ jsx(Combobox.List, {
156
171
  "data-slot": "command-palette-list",
157
- className: "min-h-0 flex-1 overflow-y-auto overscroll-contain p-(--cue-space-1) outline-none",
172
+ className: "min-h-0 flex-1 overflow-y-auto overscroll-contain p-[var(--cue-style-listbox-pad,var(--cue-space-1))] outline-none",
158
173
  children: (group) => /* @__PURE__ */ jsxs(Combobox.Group, {
159
174
  items: group.items,
160
175
  className: "block",
161
176
  children: [group.value === "" ? null : /* @__PURE__ */ jsx(Combobox.GroupLabel, {
162
- className: cn("flex h-control-sm items-center px-(--cue-space-3) text-(length:--cue-text-micro) text-fg-subtle select-none", LABEL_FACE, LABEL_TRACKING, LABEL_CASE),
177
+ className: cn(`flex h-control-sm items-center px-(--cue-space-3) ${GROUP_LABEL_SIZE_MICRO} ${GROUP_LABEL_INK_SUBTLE} select-none`, LABEL_FACE, LABEL_TRACKING, LABEL_CASE),
163
178
  children: group.value
164
179
  }), /* @__PURE__ */ jsx(Combobox.Collection, { children: (item) => /* @__PURE__ */ jsxs(Combobox.Item, {
165
180
  value: item,
@@ -186,7 +201,7 @@ function CommandPalette({ items, onSelect, open: openProp, defaultOpen = false,
186
201
  ]
187
202
  }), footer === null ? null : /* @__PURE__ */ jsx("div", {
188
203
  "data-slot": "command-palette-footer",
189
- className: cn("flex shrink-0 items-center gap-(--cue-space-4) border-t border-border bg-surface-1 px-(--cue-space-4) py-(--cue-space-2) text-(length:--cue-text-micro) text-fg-subtle select-none", CONTROL_FACE),
204
+ className: cn(`flex shrink-0 items-center gap-(--cue-space-4) border-t border-border bg-surface-1 px-(--cue-space-4) ${PALETTE_FOOTER_PAD} text-(length:--cue-text-micro) text-fg-subtle select-none`, CONTROL_FACE),
190
205
  children: footer
191
206
  })]
192
207
  })]
@@ -21,7 +21,7 @@ import { Dialog } from "@base-ui/react/dialog";
21
21
  * own `cn` drops the shared `rounded-overlay`: only the dialog reads the name,
22
22
  * and every other overlay keeps the rung.
23
23
  */
24
- const dialogPopupVariants = cva(`${overlaySurfaceClasses} rounded-[calc(var(--cue-style-dialog-radius,var(--cue-radius-overlay))*var(--cue-radius-scale))] ${overlayModalTransitionClasses} fixed top-1/2 left-1/2 z-50 flex max-h-[85vh] w-[calc(100vw-2rem)] -translate-x-1/2 -translate-y-1/2 flex-col gap-(--cue-space-4) overflow-y-auto p-(--cue-space-6) outline-none`, {
24
+ const dialogPopupVariants = cva(`${overlaySurfaceClasses} rounded-[calc(var(--cue-style-dialog-radius,var(--cue-radius-overlay))*var(--cue-radius-scale))] ${overlayModalTransitionClasses} fixed top-1/2 left-1/2 z-50 flex max-h-[85vh] w-[calc(100vw-2rem)] -translate-x-1/2 -translate-y-1/2 flex-col gap-(--cue-space-4) overflow-y-auto p-[calc(var(--cue-space-6)*var(--cue-style-dialog-pad,1))] outline-none`, {
25
25
  variants: { width: {
26
26
  sm: "max-w-[20rem]",
27
27
  md: "max-w-[28rem]",
@@ -27,6 +27,13 @@ const VIEWPORT_ALIGNMENT = {
27
27
  * sheet track the finger and then settle, rather than snapping when the gesture
28
28
  * ends.
29
29
  */
30
+ /**
31
+ * A drawer's corners are a dialog's (round 6, spec §11, P155.radius): coss.com/ui
32
+ * rounds its drawer's open edge at its 16px surface rung, as it rounds a dialog.
33
+ * The same class as `dialog.tsx`'s `DIALOG_RADIUS`, kept in this file for that
34
+ * file's reason; the attached edge's `rounded-*-none` still squares that side.
35
+ */
36
+ const DRAWER_RADIUS = "rounded-[calc(var(--cue-style-dialog-radius,var(--cue-radius-overlay))*var(--cue-radius-scale))]";
30
37
  const POPUP_GEOMETRY = {
31
38
  down: "max-h-[85vh] w-full max-w-[42rem] translate-y-(--drawer-swipe-movement-y) rounded-b-none border-x-0 border-b-0 data-[starting-style]:translate-y-full data-[ending-style]:translate-y-full",
32
39
  up: "max-h-[85vh] w-full max-w-[42rem] translate-y-(--drawer-swipe-movement-y) rounded-t-none border-x-0 border-t-0 data-[starting-style]:-translate-y-full data-[ending-style]:-translate-y-full",
@@ -99,7 +106,7 @@ const Drawer$1 = {
99
106
  children: /* @__PURE__ */ jsxs(Drawer.Popup, {
100
107
  ref,
101
108
  "data-slot": "drawer-popup",
102
- className: cn(overlaySurfaceClasses, "flex flex-col overflow-y-auto overscroll-contain outline-none transition-transform duration-200 ease-out data-[swiping]:duration-0 motion-reduce:transition-none", POPUP_GEOMETRY[direction], className),
109
+ className: cn(overlaySurfaceClasses, DRAWER_RADIUS, "flex flex-col overflow-y-auto overscroll-contain outline-none transition-transform duration-200 ease-out data-[swiping]:duration-0 motion-reduce:transition-none", POPUP_GEOMETRY[direction], className),
103
110
  ...popupProps,
104
111
  children: [grabHandle ? /* @__PURE__ */ jsx("div", {
105
112
  "data-slot": "drawer-grab-handle",
@@ -4,6 +4,8 @@ import { useComposedRefs } from "../lib/compose.js";
4
4
  import { useCuePortalProps } from "../system/portal.js";
5
5
  import { overlayPopupTransitionClasses, overlayPositionerClasses, overlaySurfaceClasses } from "./_surface.js";
6
6
  import { useCloseOnWheel } from "./_wheel.js";
7
+ import { HOVER_CARD_WIDTH } from "../system/_style-hover-card-width.js";
8
+ import { POPOVER_PAD } from "../system/_style-popover-pad.js";
7
9
  import * as React from "react";
8
10
  import { jsx } from "react/jsx-runtime";
9
11
  import { PreviewCard } from "@base-ui/react/preview-card";
@@ -79,7 +81,7 @@ const HoverCard = {
79
81
  children: /* @__PURE__ */ jsx(PreviewCard.Popup, {
80
82
  ref: composedRef,
81
83
  "data-slot": "hover-card-popup",
82
- className: cn(overlaySurfaceClasses, overlayPopupTransitionClasses, "flex w-[min(20rem,calc(100vw-2rem))] flex-col gap-(--cue-space-2) p-(--cue-space-4) font-mono text-(length:--cue-text-ui) text-fg-muted outline-none", className),
84
+ className: cn(overlaySurfaceClasses, overlayPopupTransitionClasses, `flex ${HOVER_CARD_WIDTH} flex-col gap-(--cue-space-2) ${POPOVER_PAD} font-mono text-(length:--cue-text-ui) text-fg-muted outline-none`, className),
83
85
  ...popupProps,
84
86
  children
85
87
  })
@@ -5,6 +5,7 @@ import { useCuePortalProps } from "../system/portal.js";
5
5
  import { overlayDescriptionClasses, overlayPopupTransitionClasses, overlayPositionerClasses, overlaySurfaceClasses, overlayTitleClasses } from "./_surface.js";
6
6
  import { useCloseOnWheel } from "./_wheel.js";
7
7
  import { POPOVER_PAD } from "../system/_style-popover-pad.js";
8
+ import { POPOVER_WIDTH } from "../system/_style-popover-width.js";
8
9
  import * as React from "react";
9
10
  import { jsx } from "react/jsx-runtime";
10
11
  import { Popover } from "@base-ui/react/popover";
@@ -79,7 +80,7 @@ const Popover$1 = {
79
80
  children: /* @__PURE__ */ jsx(Popover.Popup, {
80
81
  ref: composedRef,
81
82
  "data-slot": "popover-popup",
82
- className: cn(overlaySurfaceClasses, overlayPopupTransitionClasses, `flex max-w-[calc(100vw-2rem)] flex-col gap-(--cue-space-3) ${POPOVER_PAD} outline-none`, className),
83
+ className: cn(overlaySurfaceClasses, overlayPopupTransitionClasses, `flex ${POPOVER_WIDTH} max-w-[calc(100vw-2rem)] flex-col gap-(--cue-space-3) ${POPOVER_PAD} outline-none`, className),
83
84
  ...popupProps,
84
85
  children
85
86
  })
@@ -6,7 +6,11 @@ import { LABEL_CASE } from "../system/_style-label-case.js";
6
6
  import { LABEL_TRACKING_TIGHT } from "../system/_style-label-tracking.js";
7
7
  import { CrossGlyph } from "./_glyphs.js";
8
8
  import { useCuePortalProps } from "../system/portal.js";
9
+ import { BODY_FACE, BODY_VOICE } from "../system/_style-body.js";
10
+ import { BODY_LEADING } from "../system/_style-body-leading.js";
11
+ import { BODY_SIZE, BODY_SIZE_LABEL } from "../system/_style-body-size.js";
9
12
  import { overlaySurfaceClasses } from "./_surface.js";
13
+ import { TOAST_PAD_X, TOAST_PAD_Y, TOAST_WIDTH } from "../system/_style-toast.js";
10
14
  import * as React from "react";
11
15
  import { jsx, jsxs } from "react/jsx-runtime";
12
16
  import { Toast } from "@base-ui/react/toast";
@@ -79,15 +83,15 @@ function ToastItem({ toast, className, closeLabel }) {
79
83
  return /* @__PURE__ */ jsxs(Toast.Root, {
80
84
  toast,
81
85
  "data-slot": "toast-root",
82
- className: cn(overlaySurfaceClasses, "relative flex flex-col gap-(--cue-space-1) border-l-2 py-(--cue-space-3) pr-(--cue-space-6) pl-(--cue-space-4) outline-none", "transition-[opacity,translate] duration-150 ease-out motion-reduce:transition-none", "data-[starting-style]:translate-x-2 data-[starting-style]:opacity-0", "data-[ending-style]:translate-x-2 data-[ending-style]:opacity-0", "data-[limited]:hidden", TOAST_TONE_RAIL[toToastTone(toast.type)], className),
86
+ className: cn(overlaySurfaceClasses, `relative flex flex-col gap-(--cue-space-1) border-l-2 ${TOAST_PAD_Y} pr-(--cue-space-6) ${TOAST_PAD_X} outline-none`, "transition-[opacity,translate] duration-150 ease-out motion-reduce:transition-none", "data-[starting-style]:translate-x-2 data-[starting-style]:opacity-0", "data-[ending-style]:translate-x-2 data-[ending-style]:opacity-0", "data-[limited]:hidden", TOAST_TONE_RAIL[toToastTone(toast.type)], className),
83
87
  children: [
84
88
  /* @__PURE__ */ jsx(Toast.Title, {
85
89
  "data-slot": "toast-title",
86
- className: "font-mono text-(length:--cue-text-ui) font-medium text-fg"
90
+ className: `${BODY_FACE} ${BODY_SIZE} font-medium text-fg`
87
91
  }),
88
92
  /* @__PURE__ */ jsx(Toast.Description, {
89
93
  "data-slot": "toast-description",
90
- className: "font-mono text-(length:--cue-text-label) leading-(--cue-leading-ui) text-fg-muted"
94
+ className: `${BODY_VOICE} ${BODY_SIZE_LABEL} ${BODY_LEADING} text-fg-muted`
91
95
  }),
92
96
  /* @__PURE__ */ jsx(Toast.Action, {
93
97
  "data-slot": "toast-action",
@@ -119,7 +123,7 @@ function ToastViewport({ className, toastClassName, closeLabel = "Dismiss" }) {
119
123
  ...portalProps,
120
124
  children: /* @__PURE__ */ jsx(Toast.Viewport, {
121
125
  "data-slot": "toast-viewport",
122
- className: cn("fixed right-(--cue-space-6) bottom-(--cue-space-6) z-50 flex w-[20rem] max-w-[calc(100vw-2rem)] flex-col-reverse gap-(--cue-space-3) outline-none", className),
126
+ className: cn(`fixed right-(--cue-space-6) bottom-(--cue-space-6) z-50 flex ${TOAST_WIDTH} max-w-[calc(100vw-2rem)] flex-col-reverse gap-(--cue-space-3) outline-none`, className),
123
127
  children: toasts.map((toast) => /* @__PURE__ */ jsx(ToastItem, {
124
128
  toast,
125
129
  className: toastClassName,
@@ -1,10 +1,9 @@
1
1
  "use client";
2
2
  import { cn } from "../lib/cn.js";
3
- import { CONTROL_FACE } from "../system/_style-control-face.js";
3
+ import { BODY_WEIGHT } from "../system/_style-body-weight.js";
4
4
  import { useCuePortalProps } from "../system/portal.js";
5
- import { BODY_LEADING } from "../system/_style-body-leading.js";
6
5
  import { overlayPopupTransitionClasses, overlayPositionerClasses, overlaySurfaceClasses } from "./_surface.js";
7
- import { TOOLTIP_PAD, TOOLTIP_SIZE } from "../system/_style-tooltip.js";
6
+ import { TOOLTIP_FACE, TOOLTIP_INK, TOOLTIP_LEADING, TOOLTIP_PAD, TOOLTIP_RADIUS, TOOLTIP_SIZE, TOOLTIP_TRACKING } from "../system/_style-tooltip.js";
8
7
  import * as React from "react";
9
8
  import { jsx } from "react/jsx-runtime";
10
9
  import { Tooltip } from "@base-ui/react/tooltip";
@@ -86,7 +85,7 @@ const Tooltip$1 = {
86
85
  id,
87
86
  role: "tooltip",
88
87
  "data-slot": "tooltip-popup",
89
- className: cn(overlaySurfaceClasses, overlayPopupTransitionClasses, `max-w-[16rem] ${TOOLTIP_PAD} ${TOOLTIP_SIZE} ${BODY_LEADING} text-fg`, CONTROL_FACE, className),
88
+ className: cn(overlaySurfaceClasses, overlayPopupTransitionClasses, `max-w-[16rem] ${TOOLTIP_RADIUS} ${TOOLTIP_PAD} ${TOOLTIP_SIZE} ${TOOLTIP_LEADING} ${BODY_WEIGHT} ${TOOLTIP_TRACKING} ${TOOLTIP_INK}`, TOOLTIP_FACE, className),
90
89
  ...popupProps,
91
90
  children
92
91
  })
@@ -1,14 +1,18 @@
1
1
  "use client";
2
2
  import { cn } from "../lib/cn.js";
3
3
  import { cva } from "../lib/cva.js";
4
+ import { CAPTION_SIZE_LABEL } from "../system/_style-caption-size.js";
5
+ import { CAPTION_INK_MUTED } from "../system/_style-caption-ink.js";
6
+ import { CAPTION_WEIGHT } from "../system/_style-caption-weight.js";
7
+ import { AVATAR_EDGE, AVATAR_RADIUS } from "../system/_style-avatar.js";
4
8
  import * as React from "react";
5
9
  import { jsx, jsxs } from "react/jsx-runtime";
6
10
  import { Avatar } from "@base-ui/react/avatar";
7
11
  //#region src/primitives/avatar.tsx
8
- const avatarVariants = cva("relative inline-flex shrink-0 select-none items-center justify-center overflow-hidden rounded-full border border-border bg-surface-2 font-mono leading-none tracking-normal text-fg-muted uppercase", {
12
+ const avatarVariants = cva(`relative inline-flex shrink-0 select-none items-center justify-center overflow-hidden ${AVATAR_RADIUS} border ${AVATAR_EDGE} bg-surface-2 font-mono leading-none tracking-normal ${CAPTION_INK_MUTED} ${CAPTION_WEIGHT} uppercase`, {
9
13
  variants: { size: {
10
14
  sm: "size-control-sm text-(length:--cue-text-micro)",
11
- md: "size-control-md text-(length:--cue-text-label)",
15
+ md: `size-control-md ${CAPTION_SIZE_LABEL}`,
12
16
  lg: "size-control-lg text-(length:--cue-text-ui)"
13
17
  } },
14
18
  defaultVariants: { size: "md" }
@@ -20,7 +20,7 @@ import { useRender } from "@base-ui/react/use-render";
20
20
  * <a className={buttonVariants({ variant: "primary", size: "sm" })} href="/go">Go</a>
21
21
  */
22
22
  declare const buttonVariants: (props?: ({
23
- variant?: "ghost" | "primary" | "secondary" | "outline" | "danger" | "danger-outline" | null | undefined;
23
+ variant?: "danger-outline" | "ghost" | "primary" | "secondary" | "outline" | "danger" | null | undefined;
24
24
  size?: "sm" | "md" | "lg" | null | undefined;
25
25
  } & ClassProp) | undefined) => string;
26
26
  interface ButtonProps extends React.ComponentPropsWithoutRef<"button">, VariantProps<typeof buttonVariants> {
@@ -3,10 +3,13 @@ import { cn } from "../lib/cn.js";
3
3
  import { FOCUS_RING_PAINT } from "../system/_focus-ring.js";
4
4
  import { CONTROL_FACE } from "../system/_style-control-face.js";
5
5
  import { REST_SHADE_CLASS } from "../system/_paint-rest-shade.js";
6
+ import { DISABLED_OPACITY, DISABLED_TONES } from "../system/_style-disabled.js";
6
7
  import { cva } from "../lib/cva.js";
7
8
  import { CONTROL_STEP_SIZE_LG } from "../system/_style-control-step.js";
8
9
  import { GLOW_CLASSES, GLOW_DANGER_CLASSES } from "../system/_paint-glow.js";
9
10
  import { CONTROL_CASE, CONTROL_PAD_LG, CONTROL_PAD_MD, CONTROL_PAD_SM, CONTROL_TRACKING, CONTROL_TRIM, CONTROL_WEIGHT, GHOST_INK, OUTLINE_EDGE, OUTLINE_INK, SECONDARY_EDGE, SECONDARY_GROUND, SECONDARY_INK } from "../system/_style-control.js";
11
+ import { CONTROL_GAP } from "../system/_style-control-gap.js";
12
+ import { OUTLINE_HOVER_EDGE, OUTLINE_HOVER_GROUND } from "../system/_style-outline-hover.js";
10
13
  import * as React from "react";
11
14
  import { Fragment, jsx, jsxs } from "react/jsx-runtime";
12
15
  import { useRender } from "@base-ui/react/use-render";
@@ -35,7 +38,7 @@ import { useRender } from "@base-ui/react/use-render";
35
38
  *
36
39
  * @internal Not part of the public API; imported by `icon-button.tsx`.
37
40
  */
38
- const buttonChassis = `inline-flex select-none items-center justify-center gap-[0.4em] whitespace-nowrap rounded-control ${CONTROL_FACE} ${CONTROL_WEIGHT} ${CONTROL_TRACKING} ${CONTROL_TRIM} ${CONTROL_CASE} transition-colors duration-150 outline-none ${FOCUS_RING_PAINT} focus-visible:outline-offset-[var(--cue-style-focus-offset,1px)] disabled:pointer-events-none disabled:opacity-40`;
41
+ const buttonChassis = `inline-flex select-none items-center justify-center ${CONTROL_GAP} whitespace-nowrap rounded-control ${CONTROL_FACE} ${CONTROL_WEIGHT} ${CONTROL_TRACKING} ${CONTROL_TRIM} ${CONTROL_CASE} transition-colors duration-150 outline-none ${FOCUS_RING_PAINT} focus-visible:outline-offset-[var(--cue-style-focus-offset,1px)] disabled:pointer-events-none ${DISABLED_OPACITY}`;
39
42
  /**
40
43
  * The shared colour vocabulary. `accent` is theme-controlled, so `primary`
41
44
  * reads as white-on-black in `cue` and cyan-on-near-black in `terminal` with no
@@ -54,12 +57,12 @@ const buttonChassis = `inline-flex select-none items-center justify-center gap-[
54
57
  * @internal Not part of the public API; imported by `icon-button.tsx`.
55
58
  */
56
59
  const buttonTones = {
57
- primary: `bg-accent-fill text-accent-fill-fg hover:bg-accent-fill-hover border border-transparent ${GLOW_CLASSES}`,
58
- secondary: `border ${SECONDARY_EDGE} ${SECONDARY_INK} hover:text-[color:var(--cue-style-secondary-hover-ink,var(--cue-fg))] hover:border-[color:var(--cue-style-secondary-hover-edge,var(--cue-border-strong))] ${SECONDARY_GROUND}`,
59
- ghost: `${GHOST_INK} hover:text-fg hover:bg-surface-2 border border-transparent`,
60
- outline: `border ${OUTLINE_EDGE} ${OUTLINE_INK} hover:border-accent hover:text-accent bg-transparent ${REST_SHADE_CLASS}`,
61
- danger: `bg-danger text-danger-fg hover:opacity-90 border border-transparent ${GLOW_DANGER_CLASSES}`,
62
- "danger-outline": "border text-danger bg-transparent hover:bg-danger/10 border-danger/40"
60
+ primary: `bg-accent-fill text-accent-fill-fg hover:bg-accent-fill-hover border border-transparent ${GLOW_CLASSES} ${DISABLED_TONES.primary}`,
61
+ secondary: `border ${SECONDARY_EDGE} ${SECONDARY_INK} hover:text-[color:var(--cue-style-secondary-hover-ink,var(--cue-fg))] hover:border-[color:var(--cue-style-secondary-hover-edge,var(--cue-border-strong))] ${SECONDARY_GROUND} hover:bg-[color:var(--cue-style-secondary-hover-ground,var(--cue-style-secondary-ground,var(--cue-surface-2)))] ${DISABLED_TONES.secondary}`,
62
+ ghost: `${GHOST_INK} hover:text-fg hover:bg-surface-2 border border-transparent ${DISABLED_TONES.ghost}`,
63
+ outline: `border ${OUTLINE_EDGE} ${OUTLINE_INK} ${OUTLINE_HOVER_EDGE} hover:text-accent bg-transparent ${OUTLINE_HOVER_GROUND} ${REST_SHADE_CLASS} ${DISABLED_TONES.outline}`,
64
+ danger: `bg-danger text-danger-fg hover:opacity-90 border border-transparent ${GLOW_DANGER_CLASSES} ${DISABLED_TONES.danger}`,
65
+ "danger-outline": `border text-danger bg-transparent hover:bg-danger/10 border-danger/40 ${DISABLED_TONES["danger-outline"]}`
63
66
  };
64
67
  /**
65
68
  * The `Button` class recipe, exported so other surfaces (a link that must look
@@ -1,42 +1,6 @@
1
1
  import { ClassProp, VariantProps } from "../lib/cva.js";
2
2
  import * as React from "react";
3
3
  //#region src/primitives/chip.d.ts
4
- /**
5
- * The tinted-chip recipe: `bg-<tone>/10 border-<tone>/35 text-<tone>`, and the
6
- * two quieter readings of it — `outline`, which drops the fill, and `tag`,
7
- * which drops the fill and the voice with it.
8
- *
9
- * Every property that varies is emitted from exactly one place: one rim, one
10
- * ink, one fill, one gutter, one type size, always. Emitting `bg-<tone>/10`
11
- * from the tone map and then cancelling it with `bg-transparent` would leave
12
- * two competing utilities in the class string, and `chipVariants` is exported —
13
- * a caller who uses it without `cn` gets a raw string where the winner is
14
- * decided by stylesheet order rather than by which utility was written last.
15
- * `h-chip h-4` proves the point at the other end: `tailwind-merge` cannot even
16
- * see that as a conflict, because `chip` is a token name and not a scale step.
17
- * So nothing here cancels anything. What varies moves into `variants` or
18
- * `compoundVariants` until only one of it is ever emitted.
19
- *
20
- * That is why `neutral` carries no rim of its own. The other six tones rim
21
- * themselves at `/35` in all three variants, but the neutral line has two
22
- * weights in this system: `--cue-border` is a box edge, and a chip is a box;
23
- * `--cue-hair-strong` is the rule between things, and a tag is a mark on the
24
- * page rather than a container. The rim is therefore a compound of tone and
25
- * variant, exactly as the fill is.
26
- *
27
- * **The recipe reads the style set** (spec 2026-09-26-looks-fidelity §3.6,
28
- * `system/_style-chip.ts`): the six tones' fill and rim are
29
- * `color-mix(in oklab, var(--cue-<tone>) var(--cue-style-chip-fill, 10%), transparent)`
30
- * and the same with `--cue-style-chip-edge` at `35%` — exactly `bg-<tone>/10`
31
- * and `border-<tone>/35` under no set, and a set's own shares inside one. The
32
- * case, tracking, radius, size and weight read `--cue-style-chip-case`,
33
- * `-tracking`, `-radius`, `-size` and `--cue-style-label-weight` the same way.
34
- *
35
- * @example
36
- * <span className={chipVariants({ tone: "danger", variant: "outline" })}>fault</span>
37
- * @example
38
- * <span className={chipVariants({ variant: "tag" })}>mcp</span>
39
- */
40
4
  declare const chipVariants: (props?: ({
41
5
  tone?: "danger" | "info" | "warn" | "accent" | "ok" | "busy" | "neutral" | null | undefined;
42
6
  variant?: "outline" | "tinted" | "tag" | null | undefined;