pixelize-design-library 2.4.2-beta.2 → 2.4.2-beta.20

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 (192) hide show
  1. package/dist/Components/Accordion/Accordion.js +2 -2
  2. package/dist/Components/Button/Button.d.ts +2 -2
  3. package/dist/Components/Button/Button.js +3 -3
  4. package/dist/Components/Button/Button.styles.js +4 -3
  5. package/dist/Components/Button/ButtonProps.d.ts +6 -1
  6. package/dist/Components/ButtonGroupIcon/ButtonGroupIcon.js +6 -6
  7. package/dist/Components/Card/Card.d.ts +1 -1
  8. package/dist/Components/Card/Card.js +2 -2
  9. package/dist/Components/Card/CardProps.d.ts +0 -1
  10. package/dist/Components/Checkbox/Checkbox.js +1 -1
  11. package/dist/Components/Checkbox/Checkbox.styles.js +2 -0
  12. package/dist/Components/Common/fieldStyles.js +1 -1
  13. package/dist/Components/CopyButton/CopyButton.js +1 -1
  14. package/dist/Components/CustomModulesTable/EditModuleModal.js +1 -1
  15. package/dist/Components/DatePicker/CalendarPanel.js +1 -1
  16. package/dist/Components/DatePicker/RangeDatePicker.js +2 -2
  17. package/dist/Components/DatePicker/SingleDatePicker.js +2 -2
  18. package/dist/Components/DatePicker/TimeOnlyPicker.js +1 -1
  19. package/dist/Components/Dropdown/DropDown.js +3 -13
  20. package/dist/Components/EmailCards/VerifyEmailOtp/VerifyEmailOtp.js +1 -1
  21. package/dist/Components/FilePreview/FilePreview.js +1 -1
  22. package/dist/Components/FileUpload/FileUpload.js +3 -2
  23. package/dist/Components/FileUpload/FileUploadProps.d.ts +2 -1
  24. package/dist/Components/FileUpload/constants.js +1 -0
  25. package/dist/Components/FilterSidebar/FilterSidebar.js +4 -4
  26. package/dist/Components/Form/FormWrapper.js +1 -1
  27. package/dist/Components/Input/TextInput.styles.js +6 -4
  28. package/dist/Components/InputTextArea/InputTextArea.style.js +5 -4
  29. package/dist/Components/KanbanBoard/KanbanBoard.js +5 -45
  30. package/dist/Components/LimitReachedModal/LimitReachedModal.js +4 -5
  31. package/dist/Components/MultiSelect/MultiSelect.js +1 -1
  32. package/dist/Components/NavigationBar/NavigationBar.js +3 -3
  33. package/dist/Components/NoteTextArea/NoteTextArea.js +5 -3
  34. package/dist/Components/NumberInput/NumberInput.styles.js +5 -4
  35. package/dist/Components/OrgSwitcher/OrgSwitcher.js +2 -2
  36. package/dist/Components/PinInput/PinInput.js +1 -1
  37. package/dist/Components/PlanPill/PlanPill.js +5 -5
  38. package/dist/Components/PlanPill/planPillGradient.d.ts +2 -14
  39. package/dist/Components/PlanPill/planPillGradient.js +3 -15
  40. package/dist/Components/ProductCard/ProductPrice.js +1 -1
  41. package/dist/Components/ProfileCard/ProfileCard.js +1 -1
  42. package/dist/Components/ProfilePhotoViewer/ProfilePhotoViewer.js +1 -1
  43. package/dist/Components/RadioButton/RadioButton.js +1 -1
  44. package/dist/Components/Reorder/Reorder.js +1 -1
  45. package/dist/Components/ScrollbarBox/ScrollbarBox.d.ts +13 -0
  46. package/dist/Components/ScrollbarBox/ScrollbarBox.js +11 -0
  47. package/dist/Components/SearchSelect/SearchSelect.js +5 -4
  48. package/dist/Components/Select/Select.styles.js +3 -2
  49. package/dist/Components/SelectSearch/SelectSearch.js +3 -3
  50. package/dist/Components/SelectV2/SelectV2.js +5 -11
  51. package/dist/Components/SideBar/SecondaryBar.js +1 -1
  52. package/dist/Components/StageProgress/StageProgress.js +2 -9
  53. package/dist/Components/Table/Table.d.ts +1 -1
  54. package/dist/Components/Table/Table.js +17 -24
  55. package/dist/Components/Table/TableProps.d.ts +4 -0
  56. package/dist/Components/Table/components/TableActions.js +2 -2
  57. package/dist/Components/Table/components/TableBody.js +41 -12
  58. package/dist/Components/Table/components/TableGroupRow.js +1 -1
  59. package/dist/Components/Table/components/TableHeader.js +21 -8
  60. package/dist/Components/Table/components/TableSearch.js +1 -1
  61. package/dist/Components/Table/filters/ActiveFilters.js +2 -18
  62. package/dist/Components/Table/settings/ManageColumns.js +3 -17
  63. package/dist/Components/Table/settings/TableSettings.js +5 -11
  64. package/dist/Components/Table/variants/TableVariantContext.d.ts +4 -0
  65. package/dist/Components/Table/variants/TableVariantContext.js +17 -0
  66. package/dist/Components/Table/variants/classic.d.ts +6 -0
  67. package/dist/Components/Table/variants/classic.js +47 -0
  68. package/dist/Components/Table/variants/index.d.ts +7 -0
  69. package/dist/Components/Table/variants/index.js +27 -0
  70. package/dist/Components/Table/variants/pillInk.d.ts +6 -0
  71. package/dist/Components/Table/variants/pillInk.js +21 -0
  72. package/dist/Components/Table/variants/studio.d.ts +6 -0
  73. package/dist/Components/Table/variants/studio.js +50 -0
  74. package/dist/Components/Table/variants/tokens.d.ts +49 -0
  75. package/dist/Components/Table/variants/tokens.js +2 -0
  76. package/dist/Components/Timeline/Timeline.js +2 -2
  77. package/dist/Components/Toaster/Toaster.js +1 -1
  78. package/dist/Components/Trail/TrailWorks.js +1 -1
  79. package/dist/Components/UpgradeButton/UpgradeButton.js +3 -3
  80. package/dist/Constants/Sidebar.js +3 -2
  81. package/dist/Theme/chakra/Menu.styles.d.ts +9 -6
  82. package/dist/Theme/chakra/Menu.styles.js +11 -5
  83. package/dist/Theme/chakra/Popover.styles.d.ts +6 -3
  84. package/dist/Theme/chakra/Popover.styles.js +11 -6
  85. package/dist/Theme/chakra/Switch.styles.d.ts +1 -1
  86. package/dist/Theme/chakra/Switch.styles.js +7 -9
  87. package/dist/Theme/chakra/componentStyles.d.ts +15 -9
  88. package/dist/Theme/chakra/createBrandTheme.js +3 -16
  89. package/dist/Theme/provider/PixelizeThemeProvider.js +18 -20
  90. package/dist/Theme/provider/ThemeSwitcher.js +13 -20
  91. package/dist/Theme/tokens/brands/lavender/palette.light.js +2 -6
  92. package/dist/Theme/tokens/brands/slate/palette.light.js +1 -5
  93. package/dist/Theme/tokens/builders/chartColorsFromTheme.js +1 -1
  94. package/dist/Theme/tokens/builders/gradientInk.d.ts +22 -0
  95. package/dist/Theme/tokens/builders/gradientInk.js +28 -0
  96. package/dist/Theme/tokens/builders/index.d.ts +3 -0
  97. package/dist/Theme/tokens/builders/index.js +3 -0
  98. package/dist/Theme/tokens/builders/outlineRung.d.ts +32 -3
  99. package/dist/Theme/tokens/builders/outlineRung.js +74 -5
  100. package/dist/Theme/tokens/builders/placeholderInk.d.ts +19 -0
  101. package/dist/Theme/tokens/builders/placeholderInk.js +35 -0
  102. package/dist/Theme/tokens/builders/resolvedRungs.d.ts +5 -1
  103. package/dist/Theme/tokens/builders/resolvedRungs.js +7 -2
  104. package/dist/Theme/tokens/builders/scrollbar.d.ts +12 -0
  105. package/dist/Theme/tokens/builders/scrollbar.js +57 -0
  106. package/dist/Theme/tokens/builders/surfaceRungs.d.ts +5 -0
  107. package/dist/Theme/tokens/builders/surfaceRungs.js +20 -5
  108. package/dist/esm/Components/Accordion/Accordion.js +2 -2
  109. package/dist/esm/Components/Button/Button.js +4 -4
  110. package/dist/esm/Components/Button/Button.styles.js +5 -4
  111. package/dist/esm/Components/ButtonGroupIcon/ButtonGroupIcon.js +6 -6
  112. package/dist/esm/Components/Card/Card.js +2 -2
  113. package/dist/esm/Components/Checkbox/Checkbox.js +1 -1
  114. package/dist/esm/Components/Checkbox/Checkbox.styles.js +2 -0
  115. package/dist/esm/Components/Common/fieldStyles.js +1 -1
  116. package/dist/esm/Components/CopyButton/CopyButton.js +1 -1
  117. package/dist/esm/Components/CustomModulesTable/EditModuleModal.js +1 -1
  118. package/dist/esm/Components/DatePicker/CalendarPanel.js +1 -1
  119. package/dist/esm/Components/DatePicker/RangeDatePicker.js +2 -2
  120. package/dist/esm/Components/DatePicker/SingleDatePicker.js +2 -2
  121. package/dist/esm/Components/DatePicker/TimeOnlyPicker.js +1 -1
  122. package/dist/esm/Components/Dropdown/DropDown.js +3 -13
  123. package/dist/esm/Components/EmailCards/VerifyEmailOtp/VerifyEmailOtp.js +1 -1
  124. package/dist/esm/Components/FilePreview/FilePreview.js +1 -1
  125. package/dist/esm/Components/FileUpload/FileUpload.js +4 -3
  126. package/dist/esm/Components/FileUpload/constants.js +1 -0
  127. package/dist/esm/Components/FilterSidebar/FilterSidebar.js +4 -4
  128. package/dist/esm/Components/Form/FormWrapper.js +1 -1
  129. package/dist/esm/Components/Input/TextInput.styles.js +6 -4
  130. package/dist/esm/Components/InputTextArea/InputTextArea.style.js +5 -4
  131. package/dist/esm/Components/KanbanBoard/KanbanBoard.js +5 -45
  132. package/dist/esm/Components/LimitReachedModal/LimitReachedModal.js +4 -5
  133. package/dist/esm/Components/MultiSelect/MultiSelect.js +1 -1
  134. package/dist/esm/Components/NavigationBar/NavigationBar.js +3 -3
  135. package/dist/esm/Components/NoteTextArea/NoteTextArea.js +5 -3
  136. package/dist/esm/Components/NumberInput/NumberInput.styles.js +5 -4
  137. package/dist/esm/Components/OrgSwitcher/OrgSwitcher.js +2 -2
  138. package/dist/esm/Components/PinInput/PinInput.js +1 -1
  139. package/dist/esm/Components/PlanPill/PlanPill.js +6 -6
  140. package/dist/esm/Components/PlanPill/planPillGradient.js +3 -15
  141. package/dist/esm/Components/ProductCard/ProductPrice.js +1 -1
  142. package/dist/esm/Components/ProfileCard/ProfileCard.js +1 -1
  143. package/dist/esm/Components/ProfilePhotoViewer/ProfilePhotoViewer.js +1 -1
  144. package/dist/esm/Components/RadioButton/RadioButton.js +1 -1
  145. package/dist/esm/Components/Reorder/Reorder.js +1 -1
  146. package/dist/esm/Components/ScrollbarBox/ScrollbarBox.js +9 -0
  147. package/dist/esm/Components/SearchSelect/SearchSelect.js +5 -4
  148. package/dist/esm/Components/Select/Select.styles.js +3 -2
  149. package/dist/esm/Components/SelectSearch/SelectSearch.js +3 -3
  150. package/dist/esm/Components/SelectV2/SelectV2.js +5 -11
  151. package/dist/esm/Components/SideBar/SecondaryBar.js +1 -1
  152. package/dist/esm/Components/StageProgress/StageProgress.js +2 -9
  153. package/dist/esm/Components/Table/Table.js +17 -24
  154. package/dist/esm/Components/Table/components/TableActions.js +2 -2
  155. package/dist/esm/Components/Table/components/TableBody.js +42 -13
  156. package/dist/esm/Components/Table/components/TableGroupRow.js +1 -1
  157. package/dist/esm/Components/Table/components/TableHeader.js +21 -8
  158. package/dist/esm/Components/Table/components/TableSearch.js +1 -1
  159. package/dist/esm/Components/Table/filters/ActiveFilters.js +2 -18
  160. package/dist/esm/Components/Table/settings/ManageColumns.js +3 -17
  161. package/dist/esm/Components/Table/settings/TableSettings.js +5 -11
  162. package/dist/esm/Components/Table/variants/TableVariantContext.js +13 -0
  163. package/dist/esm/Components/Table/variants/classic.js +43 -0
  164. package/dist/esm/Components/Table/variants/index.js +9 -0
  165. package/dist/esm/Components/Table/variants/pillInk.js +18 -0
  166. package/dist/esm/Components/Table/variants/studio.js +46 -0
  167. package/dist/esm/Components/Table/variants/tokens.js +1 -0
  168. package/dist/esm/Components/Timeline/Timeline.js +2 -2
  169. package/dist/esm/Components/Toaster/Toaster.js +1 -1
  170. package/dist/esm/Components/Trail/TrailWorks.js +1 -1
  171. package/dist/esm/Components/UpgradeButton/UpgradeButton.js +3 -3
  172. package/dist/esm/Constants/Sidebar.js +3 -2
  173. package/dist/esm/Theme/chakra/Menu.styles.js +11 -5
  174. package/dist/esm/Theme/chakra/Popover.styles.js +11 -6
  175. package/dist/esm/Theme/chakra/Switch.styles.js +7 -9
  176. package/dist/esm/Theme/chakra/createBrandTheme.js +3 -16
  177. package/dist/esm/Theme/provider/PixelizeThemeProvider.js +18 -20
  178. package/dist/esm/Theme/provider/ThemeSwitcher.js +13 -20
  179. package/dist/esm/Theme/tokens/brands/lavender/palette.light.js +2 -6
  180. package/dist/esm/Theme/tokens/brands/slate/palette.light.js +1 -5
  181. package/dist/esm/Theme/tokens/builders/chartColorsFromTheme.js +1 -1
  182. package/dist/esm/Theme/tokens/builders/gradientInk.js +22 -0
  183. package/dist/esm/Theme/tokens/builders/index.js +3 -0
  184. package/dist/esm/Theme/tokens/builders/outlineRung.js +70 -4
  185. package/dist/esm/Theme/tokens/builders/placeholderInk.js +29 -0
  186. package/dist/esm/Theme/tokens/builders/resolvedRungs.js +7 -2
  187. package/dist/esm/Theme/tokens/builders/scrollbar.js +52 -0
  188. package/dist/esm/Theme/tokens/builders/surfaceRungs.js +20 -5
  189. package/dist/esm/index.js +5 -1
  190. package/dist/index.d.ts +10 -2
  191. package/dist/index.js +17 -3
  192. package/package.json +4 -2
@@ -0,0 +1,13 @@
1
+ import { createContext, useContext, useMemo } from "react";
2
+ import { useCustomTheme } from "../../../Theme/useCustomTheme.js";
3
+ import { isDarkCanvas } from "../../../Theme/tokens/builders/accentText.js";
4
+ import { classicPreset } from "./classic.js";
5
+ const TableVariantContext = createContext(null);
6
+ export const TableVariantProvider = TableVariantContext.Provider;
7
+ /** No provider means the table as it always was — the default is a variant, not a gap. */
8
+ export function useTableVariant() {
9
+ const provided = useContext(TableVariantContext);
10
+ const theme = useCustomTheme();
11
+ const isDark = isDarkCanvas(theme.colors.backgroundColor.main);
12
+ return useMemo(() => provided !== null && provided !== void 0 ? provided : classicPreset(theme.colors, isDark), [provided, theme.colors, isDark]);
13
+ }
@@ -0,0 +1,43 @@
1
+ import { accentTextOnCanvas } from "../../../Theme/tokens/builders/accentText.js";
2
+ import { getTableRowHoverStyle } from "../components/tableRowHoverStyle.js";
3
+ /**
4
+ * The table as it shipped. Pinned by snapshot: every value here is read off the
5
+ * live component, so adding a variant cannot move it.
6
+ */
7
+ export const classicPreset = (colors, isDark) => {
8
+ const headerBg = colors.table.hover[200];
9
+ return {
10
+ header: {
11
+ bg: headerBg,
12
+ ink: accentTextOnCanvas(colors.secondary, headerBg),
13
+ fontSize: 13,
14
+ fontWeight: 600,
15
+ textTransform: "capitalize",
16
+ letterSpacing: "normal",
17
+ height: "45px",
18
+ ruleColor: colors.boxborder[200],
19
+ showColumnRule: true,
20
+ actions: "always",
21
+ },
22
+ row: {
23
+ hoverBg: getTableRowHoverStyle(colors, isDark).backgroundColor,
24
+ hoverScope: "cell",
25
+ ruleColor: colors.boxborder[200],
26
+ frozenRuleColor: colors.boxborder[300],
27
+ selectedBg: colors.primary.opacity[16],
28
+ selectedBarColor: colors.primary[500],
29
+ showSelectedBar: false,
30
+ },
31
+ slot: {
32
+ width: "6",
33
+ rest: "checkbox",
34
+ indexInk: colors.textMuted,
35
+ centered: false,
36
+ },
37
+ cells: {
38
+ ink: colors.text[500],
39
+ statusFill: "bleed",
40
+ pillRadius: "0",
41
+ },
42
+ };
43
+ };
@@ -0,0 +1,9 @@
1
+ import { classicPreset } from "./classic.js";
2
+ import { studioPreset } from "./studio.js";
3
+ /** Adding a variant is one file and one union member — no component changes. */
4
+ export const TABLE_VARIANTS = {
5
+ classic: classicPreset,
6
+ studio: studioPreset,
7
+ };
8
+ export * from "./tokens.js";
9
+ export { classicPreset, studioPreset };
@@ -0,0 +1,18 @@
1
+ import { AA_NORMAL_TEXT } from "../../../Theme/tokens/builders/accentText.js";
2
+ import { compositeOver } from "../../../Theme/tokens/builders/color.js";
3
+ import { liftToContrast } from "../../../Theme/tokens/builders/outlineRung.js";
4
+ const cache = new Map();
5
+ /**
6
+ * A consumer `statusColors` hex is a FILL, and `pickTableColor` hands it straight back as ink
7
+ * over a 13%-alpha tint of itself — legible reversed out of a solid cell, ~1.9:1 on a pill.
8
+ * The palette path is already resolved by `resolveStatusTone`; this rescues the override path.
9
+ */
10
+ export function resolvePillInk(ink, soft, surface) {
11
+ const key = `${ink}|${soft}|${surface}`;
12
+ const hit = cache.get(key);
13
+ if (hit !== undefined)
14
+ return hit;
15
+ const resolved = liftToContrast(ink, compositeOver(soft, surface), AA_NORMAL_TEXT);
16
+ cache.set(key, resolved);
17
+ return resolved;
18
+ }
@@ -0,0 +1,46 @@
1
+ import { CHROME_RULE, MIN_PERCEPTIBLE_STEP, liftToContrast, } from "../../../Theme/tokens/builders/outlineRung.js";
2
+ import { getTableRowHoverStyle } from "../components/tableRowHoverStyle.js";
3
+ /**
4
+ * Quieter chrome, one rule instead of a grid, and a slot that rests on the row
5
+ * number. Every colour is lifted against the surface it actually sits on.
6
+ */
7
+ export const studioPreset = (colors, isDark) => {
8
+ const surface = colors.background[50];
9
+ // Studio drops the per-column rule, so the one line left has to be visible on
10
+ // every brand — `boxborder[200]` measures as low as 1.09:1 on some of them.
11
+ const rule = liftToContrast(colors.boxborder[200], surface, CHROME_RULE);
12
+ return {
13
+ header: {
14
+ bg: surface,
15
+ ink: colors.text[500],
16
+ fontSize: 11,
17
+ fontWeight: 600,
18
+ textTransform: "uppercase",
19
+ letterSpacing: "0.06em",
20
+ height: "40px",
21
+ ruleColor: rule,
22
+ showColumnRule: false,
23
+ actions: "hover",
24
+ },
25
+ row: {
26
+ hoverBg: getTableRowHoverStyle(colors, isDark).backgroundColor,
27
+ hoverScope: "row",
28
+ ruleColor: rule,
29
+ frozenRuleColor: rule,
30
+ selectedBg: liftToContrast(colors.primary[50], surface, MIN_PERCEPTIBLE_STEP),
31
+ selectedBarColor: colors.primary[500],
32
+ showSelectedBar: true,
33
+ },
34
+ slot: {
35
+ width: "3.5rem",
36
+ rest: "index",
37
+ indexInk: colors.textMuted,
38
+ centered: true,
39
+ },
40
+ cells: {
41
+ ink: colors.text[500],
42
+ statusFill: "pill",
43
+ pillRadius: "0.375rem",
44
+ },
45
+ };
46
+ };
@@ -0,0 +1 @@
1
+ export {};
@@ -163,7 +163,7 @@ const EventCard = React.memo(function EventCard({ event, index, accent, colors,
163
163
  const scale = getEventScale(colors, event.title);
164
164
  const changes = useMemo(() => parseChanges(event.changes), [event.changes]);
165
165
  const clickable = typeof onEventClick === "function";
166
- return (_jsxs(Box, { _hover: { ".timeline-add-note": { opacity: 1 } }, _focusWithin: { ".timeline-add-note": { opacity: 1 } }, children: [_jsxs(Box, { as: clickable ? "button" : undefined, type: clickable ? "button" : undefined, display: clickable ? "block" : undefined, w: clickable ? "100%" : undefined, textAlign: clickable ? "start" : undefined, position: "relative", zIndex: 1, bg: colors.background[50], border: `0.063rem solid ${colors.boxborder[300]}`, borderInlineStartWidth: accent === "left" ? "0.1875rem" : undefined, borderInlineEndWidth: accent === "right" ? "0.1875rem" : undefined, borderInlineStartColor: accent === "left" ? scale[400] : undefined, borderInlineEndColor: accent === "right" ? scale[400] : undefined, borderRadius: "xl", px: 3.5, py: 2.5, transition: "all 0.15s ease", cursor: clickable ? "pointer" : "default", onClick: clickable ? () => onEventClick(event, index) : undefined, _hover: {
166
+ return (_jsxs(Box, { _hover: { ".timeline-add-note": { opacity: 1 } }, _focusWithin: { ".timeline-add-note": { opacity: 1 } }, children: [_jsxs(Box, { as: clickable ? "button" : undefined, type: clickable ? "button" : undefined, display: clickable ? "block" : undefined, w: clickable ? "100%" : undefined, textAlign: clickable ? "start" : undefined, position: "relative", zIndex: 1, bg: colors.background[50], border: `0.063rem solid ${colors.boxborder[200]}`, borderInlineStartWidth: accent === "left" ? "0.1875rem" : undefined, borderInlineEndWidth: accent === "right" ? "0.1875rem" : undefined, borderInlineStartColor: accent === "left" ? scale[400] : undefined, borderInlineEndColor: accent === "right" ? scale[400] : undefined, borderRadius: "xl", px: 3.5, py: 2.5, transition: "all 0.15s ease", cursor: clickable ? "pointer" : "default", onClick: clickable ? () => onEventClick(event, index) : undefined, _hover: {
167
167
  borderColor: scale[300],
168
168
  boxShadow: (_a = theme.shadows) === null || _a === void 0 ? void 0 : _a.md,
169
169
  transform: clickable ? "translateY(-1px)" : undefined,
@@ -224,7 +224,7 @@ const Timeline = ({ timelineEvents, onEventClick, onAddNote, onEditNote, onDelet
224
224
  // -------------------------------------------------------------------------
225
225
  return (_jsxs(Box, { position: "relative", maxW: "60rem", mx: "auto", px: 4, py: 2, children: [_jsx(Box, { position: "absolute", left: "50%", top: "0.5rem", bottom: "0.5rem", w: "0.015rem", borderRadius: "full", bg: colors.gray[300], transform: "translateX(-50%)" }), Object.keys(groupedEvents).map((date) => {
226
226
  var _a;
227
- return (_jsxs(Box, { mb: 2, children: [_jsx(Flex, { justify: "center", mb: 5, mt: 3, position: "relative", zIndex: 2, children: _jsx(Text, { fontSize: "0.75rem", fontWeight: 600, textTransform: "uppercase", letterSpacing: "0.02em", color: colors.textMuted, bg: colors.background[50], border: `0.063rem solid ${colors.boxborder[300]}`, boxShadow: (_a = theme.shadows) === null || _a === void 0 ? void 0 : _a.xs, borderRadius: "full", px: 4, py: 1.5, whiteSpace: "nowrap", children: date }) }), groupedEvents[date].map(({ event, globalIndex }, index) => {
227
+ return (_jsxs(Box, { mb: 2, children: [_jsx(Flex, { justify: "center", mb: 5, mt: 3, position: "relative", zIndex: 2, children: _jsx(Text, { fontSize: "0.75rem", fontWeight: 600, textTransform: "uppercase", letterSpacing: "0.02em", color: colors.textMuted, bg: colors.background[50], border: `0.063rem solid ${colors.boxborder[200]}`, boxShadow: (_a = theme.shadows) === null || _a === void 0 ? void 0 : _a.xs, borderRadius: "full", px: 4, py: 1.5, whiteSpace: "nowrap", children: date }) }), groupedEvents[date].map(({ event, globalIndex }, index) => {
228
228
  var _a;
229
229
  const isLeft = index % 2 === 0;
230
230
  const scale = getEventScale(colors, event.title);
@@ -46,7 +46,7 @@ function ToastCard({ onClose, title, description, actions, isClosable, duration,
46
46
  initial: { opacity: 0, x: 24 }, animate: { opacity: 1, x: 0 }, exit: { opacity: 0, x: 24 }, transition: { duration: 0.24, ease: [0.22, 1, 0.36, 1] }, onHoverStart: () => setPaused(true), onHoverEnd: () => setPaused(false), position: "relative",
47
47
  // Surface token, not `colors.white`: `white` is a foreground token and stays
48
48
  // white in dark mode. `background[50]` is #ffffff in light, near-black in dark.
49
- bg: c.background[50], border: `0.063rem solid ${c.boxborder[300]}`, boxShadow: shadowLg !== null && shadowLg !== void 0 ? shadowLg : "lg", borderRadius: "2xl", overflow: "hidden", minW: "22.5rem", maxW: "26rem", willChange: "transform, opacity", sx: {
49
+ bg: c.background[50], border: `0.063rem solid ${c.boxborder[200]}`, boxShadow: shadowLg !== null && shadowLg !== void 0 ? shadowLg : "lg", borderRadius: "2xl", overflow: "hidden", minW: "22.5rem", maxW: "26rem", willChange: "transform, opacity", sx: {
50
50
  transition: "box-shadow 0.18s ease",
51
51
  _hover: { boxShadow: "xl" },
52
52
  }, children: [_jsxs(Flex, { p: 3.5, gap: 3, align: actions ? "flex-start" : "center", children: [_jsx(Flex, { align: "center", justify: "center", boxSize: "2rem", minW: "2rem", borderRadius: "full", bg: tone.bg, color: tone.fg, sx: {
@@ -3,7 +3,7 @@ import { Box, Thead, Table, Tr, Th, Tbody, Td, Checkbox, } from "@chakra-ui/reac
3
3
  import { useCustomTheme } from "../../Theme/useCustomTheme.js";
4
4
  const TrailWorks = () => {
5
5
  const { colors } = useCustomTheme();
6
- const cellBorder = colors.border[500];
6
+ const cellBorder = colors.boxborder[200];
7
7
  const data = [
8
8
  {
9
9
  contact: "John Doe",
@@ -2,7 +2,7 @@ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
2
2
  import { Box, Flex, Spinner, Text } from "@chakra-ui/react";
3
3
  import { Sparkles } from "lucide-react";
4
4
  import { useCustomTheme } from "../../Theme/useCustomTheme.js";
5
- import { onGradient } from "../../Theme/tokens/builders/accentText.js";
5
+ import { resolveGradient } from "../../Theme/tokens/builders/gradientInk.js";
6
6
  import { contrastRatio } from "../../Theme/tokens/builders/color.js";
7
7
  import { AA_NON_TEXT } from "../../Theme/tokens/builders/outlineRung.js";
8
8
  /** The brand's gold sparkle accent, kept only where it clears 3:1 on the button's own fill. */
@@ -33,10 +33,10 @@ const UpgradeButton = ({ label, mobileLabel, subtitle, icon = Sparkles, iconColo
33
33
  danger: { from: c.semantic.error[400], to: c.semantic.error[600] },
34
34
  info: { from: c.semantic.info[400], to: c.semantic.info[600] },
35
35
  };
36
- const resolved = gradient !== null && gradient !== void 0 ? gradient : variantGradient[variant];
37
36
  // `iconColor`'s gold default fails AA as body text against this gradient (measured ~1.4-3.3
38
37
  // across brands) — the label/subtitle share this computed ink instead.
39
- const ink = onGradient(resolved.from, resolved.to, c.white, c.black);
38
+ const resolved = resolveGradient(gradient !== null && gradient !== void 0 ? gradient : variantGradient[variant], c.white, c.black);
39
+ const ink = resolved.ink;
40
40
  // The gold only clears 1.4.11's 3:1 on a DARK gradient. zinc dark inverts `primary` to a
41
41
  // near-white fill, where gold-on-near-white measures ~1.3:1 and the icon vanishes, so fall
42
42
  // back to the label's ink whenever the gold misses either stop.
@@ -1,7 +1,8 @@
1
+ import { SCROLLBAR_WIDTH } from "../Theme/tokens/builders/scrollbar.js";
1
2
  export const HEADER_HEIGHT = "4.3rem";
2
3
  export const FlexCss = {
3
4
  "&::-webkit-scrollbar": {
4
- width: "0.188rem",
5
+ width: SCROLLBAR_WIDTH,
5
6
  },
6
7
  "&::-webkit-scrollbar-track": {
7
8
  background: "transparent",
@@ -16,7 +17,7 @@ export const FlexCss = {
16
17
  };
17
18
  export const cssForScrollBar = (theme) => ({
18
19
  "&::-webkit-scrollbar": {
19
- width: "0.125rem",
20
+ width: SCROLLBAR_WIDTH,
20
21
  },
21
22
  "&::-webkit-scrollbar-track": {
22
23
  background: theme.colors.sidebar.background[500],
@@ -1,5 +1,6 @@
1
1
  import { createMultiStyleConfigHelpers, cssVar } from "@chakra-ui/react";
2
2
  import { menuAnatomy } from "@chakra-ui/anatomy";
3
+ import { paletteOf } from "./paletteFromTheme.js";
3
4
  const { defineMultiStyleConfig, definePartsStyle } = createMultiStyleConfigHelpers(menuAnatomy.keys);
4
5
  const $bg = cssVar("menu-bg");
5
6
  /**
@@ -19,14 +20,19 @@ const $bg = cssVar("menu-bg");
19
20
  */
20
21
  const $itemBg = cssVar("menu-item-bg");
21
22
  const baseStyle = definePartsStyle(({ theme }) => {
22
- var _a, _b, _c, _d, _e, _f, _g, _h, _j, _k, _l, _m, _o, _p, _q, _r, _s, _t, _u, _v, _w, _x, _y;
23
- const hoverBg = (_g = (_d = (_c = (_b = (_a = theme.colors) === null || _a === void 0 ? void 0 : _a.primary) === null || _b === void 0 ? void 0 : _b.opacity) === null || _c === void 0 ? void 0 : _c[8]) !== null && _d !== void 0 ? _d : (_f = (_e = theme.colors) === null || _e === void 0 ? void 0 : _e.gray) === null || _f === void 0 ? void 0 : _f[100]) !== null && _g !== void 0 ? _g : "#f7fafc";
24
- const activeBg = (_p = (_l = (_k = (_j = (_h = theme.colors) === null || _h === void 0 ? void 0 : _h.primary) === null || _j === void 0 ? void 0 : _j.opacity) === null || _k === void 0 ? void 0 : _k[16]) !== null && _l !== void 0 ? _l : (_o = (_m = theme.colors) === null || _m === void 0 ? void 0 : _m.gray) === null || _o === void 0 ? void 0 : _o[200]) !== null && _p !== void 0 ? _p : "#edf2f7";
23
+ const colors = paletteOf(theme);
24
+ const hoverBg = colors.primary.opacity[8];
25
+ const activeBg = colors.primary.opacity[16];
25
26
  return {
26
27
  list: {
27
- [$bg.variable]: (_v = (_s = (_r = (_q = theme.colors) === null || _q === void 0 ? void 0 : _q.backgroundColor) === null || _r === void 0 ? void 0 : _r.light) !== null && _s !== void 0 ? _s : (_u = (_t = theme.colors) === null || _t === void 0 ? void 0 : _t.background) === null || _u === void 0 ? void 0 : _u[50]) !== null && _v !== void 0 ? _v : "#fff",
28
+ [$bg.variable]: colors.backgroundColor.light,
28
29
  bg: $bg.reference,
29
- color: (_y = (_x = (_w = theme.colors) === null || _w === void 0 ? void 0 : _w.text) === null || _x === void 0 ? void 0 : _x[900]) !== null && _y !== void 0 ? _y : "inherit",
30
+ color: colors.text[900],
31
+ // A rule at CHROME_RULE weight, not Chakra's gray.200: that default read as a hard edge,
32
+ // which is why this shipped borderless. At 1.31:1 the edge defines the surface instead.
33
+ borderWidth: "1px",
34
+ borderStyle: "solid",
35
+ borderColor: colors.boxborder[200],
30
36
  },
31
37
  // Own CSS var (`--menu-item-bg`), NOT the list's `--menu-bg` — Chakra's stock item
32
38
  // baseStyle rewrites `--menu-bg` itself on hover/focus, so reusing that same var name
@@ -1,5 +1,6 @@
1
1
  import { createMultiStyleConfigHelpers, cssVar } from "@chakra-ui/react";
2
2
  import { popoverAnatomy } from "@chakra-ui/anatomy";
3
+ import { paletteOf } from "./paletteFromTheme.js";
3
4
  const { defineMultiStyleConfig, definePartsStyle } = createMultiStyleConfigHelpers(popoverAnatomy.keys);
4
5
  const $popperBg = cssVar("popper-bg");
5
6
  const $arrowShadowColor = cssVar("popper-arrow-shadow-color");
@@ -12,15 +13,19 @@ const $arrowShadowColor = cssVar("popper-arrow-shadow-color");
12
13
  * fixing `$popperBg` here fixes the arrow fill too.
13
14
  */
14
15
  const baseStyle = definePartsStyle(({ theme }) => {
15
- var _a, _b, _c, _d, _e, _f, _g, _h, _j, _k, _l, _m, _o, _p, _q;
16
- return ({
16
+ const colors = paletteOf(theme);
17
+ return {
17
18
  content: {
18
- [$popperBg.variable]: (_f = (_c = (_b = (_a = theme.colors) === null || _a === void 0 ? void 0 : _a.backgroundColor) === null || _b === void 0 ? void 0 : _b.light) !== null && _c !== void 0 ? _c : (_e = (_d = theme.colors) === null || _d === void 0 ? void 0 : _d.background) === null || _e === void 0 ? void 0 : _e[50]) !== null && _f !== void 0 ? _f : "#fff",
19
+ [$popperBg.variable]: colors.backgroundColor.light,
19
20
  bg: $popperBg.reference,
20
- [$arrowShadowColor.variable]: (_m = (_j = (_h = (_g = theme.colors) === null || _g === void 0 ? void 0 : _g.border) === null || _h === void 0 ? void 0 : _h[200]) !== null && _j !== void 0 ? _j : (_l = (_k = theme.colors) === null || _k === void 0 ? void 0 : _k.gray) === null || _l === void 0 ? void 0 : _l[200]) !== null && _m !== void 0 ? _m : "#e2e8f0",
21
- color: (_q = (_p = (_o = theme.colors) === null || _o === void 0 ? void 0 : _o.text) === null || _p === void 0 ? void 0 : _p[900]) !== null && _q !== void 0 ? _q : "inherit",
21
+ [$arrowShadowColor.variable]: colors.boxborder[200],
22
+ color: colors.text[900],
23
+ // Matches Menu: a CHROME_RULE-weight edge, not Chakra's gray.200 hard edge.
24
+ borderWidth: "1px",
25
+ borderStyle: "solid",
26
+ borderColor: colors.boxborder[200],
22
27
  },
23
- });
28
+ };
24
29
  });
25
30
  export const Popover = defineMultiStyleConfig({
26
31
  baseStyle,
@@ -1,5 +1,6 @@
1
1
  import { createMultiStyleConfigHelpers, cssVar } from "@chakra-ui/react";
2
2
  import { switchAnatomy } from "@chakra-ui/anatomy";
3
+ import { paletteOf } from "./paletteFromTheme.js";
3
4
  const { defineMultiStyleConfig, definePartsStyle } = createMultiStyleConfigHelpers(switchAnatomy.keys);
4
5
  const $thumbBg = cssVar("switch-thumb-bg");
5
6
  /**
@@ -7,15 +8,12 @@ const $thumbBg = cssVar("switch-thumb-bg");
7
8
  * `_dark` gate at all, so every bare `<Switch>` renders a literal white knob on the dark canvas
8
9
  * regardless of mode.
9
10
  */
10
- const baseStyle = definePartsStyle(({ theme }) => {
11
- var _a, _b, _c, _d, _e, _f;
12
- return ({
13
- thumb: {
14
- [$thumbBg.variable]: (_f = (_c = (_b = (_a = theme.colors) === null || _a === void 0 ? void 0 : _a.backgroundColor) === null || _b === void 0 ? void 0 : _b.light) !== null && _c !== void 0 ? _c : (_e = (_d = theme.colors) === null || _d === void 0 ? void 0 : _d.background) === null || _e === void 0 ? void 0 : _e[50]) !== null && _f !== void 0 ? _f : "#fff",
15
- bg: $thumbBg.reference,
16
- },
17
- });
18
- });
11
+ const baseStyle = definePartsStyle(({ theme }) => ({
12
+ thumb: {
13
+ [$thumbBg.variable]: paletteOf(theme).backgroundColor.light,
14
+ bg: $thumbBg.reference,
15
+ },
16
+ }));
19
17
  export const Switch = defineMultiStyleConfig({
20
18
  baseStyle,
21
19
  });
@@ -3,6 +3,7 @@ import common from "./common.web.js";
3
3
  import fonts from "./fonts.web.js";
4
4
  import { componentStyles } from "./componentStyles.js";
5
5
  import { onFilled } from "../tokens/builders/accentText.js";
6
+ import { globalScrollbarStyles } from "../tokens/builders/scrollbar.js";
6
7
  /**
7
8
  * Builds a Chakra theme from a pure brand palette.
8
9
  *
@@ -83,22 +84,8 @@ export const createBrandTheme = (palette, options = {}) => {
83
84
  color: onFilled(palette.primary[500], palette.white, palette.black),
84
85
  },
85
86
  // `color-scheme: dark` gives WebKit/Blink a dark scrollbar by default, but it's the
86
- // OS's generic dark gray, not brand-aware — style it explicitly so it matches the
87
- // canvas instead of floating as a mismatched gray bar.
88
- "::-webkit-scrollbar": {
89
- width: "10px",
90
- height: "10px",
91
- },
92
- "::-webkit-scrollbar-track": {
93
- background: palette.backgroundColor.main,
94
- },
95
- "::-webkit-scrollbar-thumb": {
96
- background: palette.gray[600],
97
- borderRadius: "6px",
98
- },
99
- "::-webkit-scrollbar-thumb:hover": {
100
- background: palette.gray[500],
101
- },
87
+ // OS's generic dark gray, not brand-aware.
88
+ ...globalScrollbarStyles(palette),
102
89
  // Chrome/Edge autofill paints its own opaque yellow/white fill behind the input
103
90
  // text via `-webkit-box-shadow` (not `background`), so a plain `bg` override never
104
91
  // reaches it — a bright light box survives on every dark autofilled field unless
@@ -159,42 +159,40 @@ export const PixelizeThemeProvider = ({ children, brand: brandProp = DEFAULT_BRA
159
159
  * `data-mode` for consumers that want to hook their own dark CSS.
160
160
  */
161
161
  useLayoutEffect(() => {
162
- var _a, _b, _c, _d, _e, _f, _g;
163
162
  const root = document.documentElement;
164
163
  root.dataset.mode = resolvedMode;
165
- const colors = resolvedTheme.colors;
166
- const sem = (_a = colors.semantic) !== null && _a !== void 0 ? _a : {};
167
- const gray = colors.gray;
164
+ const { colors } = resolvedTheme;
165
+ const { gray, semantic } = colors;
168
166
  const HUE_SCALES = [
169
167
  "primary", "gray", "red", "orange", "yellow",
170
168
  "green", "teal", "blue", "cyan", "purple", "pink",
171
169
  ];
172
- const SEMANTIC_SCALES = ["success", "error", "warning", "info"]; // nested under colors.semantic
170
+ const SEMANTIC_SCALES = ["success", "error", "warning", "info"];
173
171
  const RUNGS = [50, 100, 200, 300, 400, 500, 600, 700, 800, 900];
174
- // Single-value semantic vars → palette scale+rung. The dark gray ramp runs dark(50) → light(900),
175
- // so low rungs read as surfaces and high rungs as text — correct in dark, cleared in light.
172
+ // The dark gray ramp runs dark(50) → light(900), so low rungs read as surfaces
173
+ // and high rungs as text — correct in dark, cleared in light.
176
174
  const SEMANTIC_VARS = {
177
- "text-heading": gray === null || gray === void 0 ? void 0 : gray[900], "text-body": gray === null || gray === void 0 ? void 0 : gray[700],
178
- "text-subtle": gray === null || gray === void 0 ? void 0 : gray[500], "text-input": gray === null || gray === void 0 ? void 0 : gray[500],
179
- "bg-main": gray === null || gray === void 0 ? void 0 : gray[50], "bg-secondary": gray === null || gray === void 0 ? void 0 : gray[100], "bg-tertiary": gray === null || gray === void 0 ? void 0 : gray[100],
180
- "bg-quaternary": gray === null || gray === void 0 ? void 0 : gray[200], "bg-light": gray === null || gray === void 0 ? void 0 : gray[50], "bg-medium": gray === null || gray === void 0 ? void 0 : gray[100],
181
- "bg-accent": gray === null || gray === void 0 ? void 0 : gray[200], "bg-subtle": gray === null || gray === void 0 ? void 0 : gray[100], "bg-muted": gray === null || gray === void 0 ? void 0 : gray[200],
182
- "bg-neutral": gray === null || gray === void 0 ? void 0 : gray[100], "bg-base": gray === null || gray === void 0 ? void 0 : gray[50], "bg-table-header": gray === null || gray === void 0 ? void 0 : gray[100],
183
- "border-default": gray === null || gray === void 0 ? void 0 : gray[200], "border-light": gray === null || gray === void 0 ? void 0 : gray[100],
184
- "border-dark": gray === null || gray === void 0 ? void 0 : gray[300], "border-input": gray === null || gray === void 0 ? void 0 : gray[300],
185
- "border-error": (_b = sem.error) === null || _b === void 0 ? void 0 : _b[500], "border-success": (_c = sem.success) === null || _c === void 0 ? void 0 : _c[500],
186
- "border-warning": (_d = sem.warning) === null || _d === void 0 ? void 0 : _d[500], "border-info": (_e = sem.info) === null || _e === void 0 ? void 0 : _e[500],
175
+ "text-heading": gray[900], "text-body": gray[700],
176
+ "text-subtle": gray[500], "text-input": gray[500],
177
+ "bg-main": gray[50], "bg-secondary": gray[100], "bg-tertiary": gray[100],
178
+ "bg-quaternary": gray[200], "bg-light": gray[50], "bg-medium": gray[100],
179
+ "bg-accent": gray[200], "bg-subtle": gray[100], "bg-muted": gray[200],
180
+ "bg-neutral": gray[100], "bg-base": gray[50], "bg-table-header": gray[100],
181
+ "border-default": gray[200], "border-light": gray[100],
182
+ "border-dark": gray[300], "border-input": gray[300],
183
+ "border-error": semantic.error[500], "border-success": semantic.success[500],
184
+ "border-warning": semantic.warning[500], "border-info": semantic.info[500],
187
185
  };
188
- const set = (name, val) => val && root.style.setProperty(`--color-${name}`, val);
186
+ const set = (name, val) => root.style.setProperty(`--color-${name}`, val);
189
187
  const clear = (name) => root.style.removeProperty(`--color-${name}`);
190
188
  const allRampNames = [...HUE_SCALES, ...SEMANTIC_SCALES].flatMap((s) => RUNGS.map((r) => `${s}-${r}`));
191
189
  if (resolvedMode === "dark") {
192
190
  for (const s of HUE_SCALES)
193
191
  for (const r of RUNGS)
194
- set(`${s}-${r}`, (_f = colors[s]) === null || _f === void 0 ? void 0 : _f[r]);
192
+ set(`${s}-${r}`, colors[s][r]);
195
193
  for (const s of SEMANTIC_SCALES)
196
194
  for (const r of RUNGS)
197
- set(`${s}-${r}`, (_g = sem[s]) === null || _g === void 0 ? void 0 : _g[r]);
195
+ set(`${s}-${r}`, semantic[s][r]);
198
196
  for (const [name, val] of Object.entries(SEMANTIC_VARS))
199
197
  set(name, val);
200
198
  }
@@ -22,33 +22,26 @@ const toBrandLabel = (brand) => brand.charAt(0).toUpperCase() + brand.slice(1);
22
22
  * the dot always matches what selecting that brand actually looks like,
23
23
  * regardless of which brand/mode is currently active.
24
24
  */
25
- const brandSwatchColor = (brand) => {
26
- var _a, _b, _c, _d, _e;
27
- return (_e = (_d = (_c = (_b = (_a = brandThemes[brand]) === null || _a === void 0 ? void 0 : _a.light) === null || _b === void 0 ? void 0 : _b.colors) === null || _c === void 0 ? void 0 : _c.primary) === null || _d === void 0 ? void 0 : _d[500]) !== null && _e !== void 0 ? _e : "gray.400";
25
+ const brandSwatchColor = (brand) => brandThemes[brand].light.colors.primary[500];
26
+ const BrandSwatch = ({ brand }) => {
27
+ const { colors } = useCustomTheme();
28
+ return (_jsx(Box, { as: "span", display: "inline-block", w: "0.625rem", h: "0.625rem", borderRadius: "full", bg: brandSwatchColor(brand), border: "1px solid", borderColor: colors.boxborder[200], flexShrink: 0 }));
28
29
  };
29
- const BrandSwatch = ({ brand }) => (_jsx(Box, { as: "span", display: "inline-block", w: "0.625rem", h: "0.625rem", borderRadius: "full", bg: brandSwatchColor(brand), border: "1px solid", borderColor: "whiteAlpha.300", flexShrink: 0 }));
30
30
  /**
31
31
  * Palette values already differ per color mode (`brandThemes[brand].light|dark`), so tokens
32
32
  * are read straight from the active theme — no `useColorModeValue` pairing needed here.
33
- * Fallbacks are Chakra token names, never literal colors, for themes without a brand palette.
34
33
  */
35
34
  const useSwitcherColors = () => {
36
- var _a, _b, _c, _d, _e, _f, _g, _h, _j, _k, _l, _m, _o, _p, _q, _r, _s, _t, _u, _v, _w, _x, _y, _z, _0;
37
- const colors = useCustomTheme().colors;
35
+ const { colors } = useCustomTheme();
38
36
  return {
39
- trackBg: (_d = (_b = (_a = colors === null || colors === void 0 ? void 0 : colors.backgroundColor) === null || _a === void 0 ? void 0 : _a.secondary) !== null && _b !== void 0 ? _b : (_c = colors === null || colors === void 0 ? void 0 : colors.gray) === null || _c === void 0 ? void 0 : _c[100]) !== null && _d !== void 0 ? _d : "gray.100",
40
- activeBg: (_g = (_f = (_e = colors === null || colors === void 0 ? void 0 : colors.backgroundColor) === null || _e === void 0 ? void 0 : _e.main) !== null && _f !== void 0 ? _f : colors === null || colors === void 0 ? void 0 : colors.white) !== null && _g !== void 0 ? _g : "white",
41
- activeColor: (_l = (_j = (_h = colors === null || colors === void 0 ? void 0 : colors.primary) === null || _h === void 0 ? void 0 : _h[500]) !== null && _j !== void 0 ? _j : (_k = colors === null || colors === void 0 ? void 0 : colors.text) === null || _k === void 0 ? void 0 : _k[900]) !== null && _l !== void 0 ? _l : "inherit",
42
- mutedColor: (_q = (_o = (_m = colors === null || colors === void 0 ? void 0 : colors.text) === null || _m === void 0 ? void 0 : _m[600]) !== null && _o !== void 0 ? _o : (_p = colors === null || colors === void 0 ? void 0 : colors.gray) === null || _p === void 0 ? void 0 : _p[600]) !== null && _q !== void 0 ? _q : "gray.600",
43
- hoverBg: (_s = (_r = colors === null || colors === void 0 ? void 0 : colors.gray) === null || _r === void 0 ? void 0 : _r[100]) !== null && _s !== void 0 ? _s : "gray.100",
44
- borderColor: (_w = (_u = (_t = colors === null || colors === void 0 ? void 0 : colors.border) === null || _t === void 0 ? void 0 : _t[200]) !== null && _u !== void 0 ? _u : (_v = colors === null || colors === void 0 ? void 0 : colors.gray) === null || _v === void 0 ? void 0 : _v[200]) !== null && _w !== void 0 ? _w : "gray.200",
45
- // `--menu-bg` (and its hover/focus/active states) is now fixed centrally in the theme's
46
- // Menu component style (Theme/chakra/Menu.styles.ts) — every MenuList gets it from there.
47
- // Re-deriving it here too and pushing it back via `sx` on every render caused a redundant
48
- // Emotion style recompute per render, which showed up as flicker while hovering/scrolling
49
- // this list. Keep menuColor (Menu.styles.ts doesn't set list `color` per this component's
50
- // needs) but stop duplicating menuBg.
51
- menuColor: (_0 = (_y = (_x = colors === null || colors === void 0 ? void 0 : colors.text) === null || _x === void 0 ? void 0 : _x[900]) !== null && _y !== void 0 ? _y : (_z = colors === null || colors === void 0 ? void 0 : colors.gray) === null || _z === void 0 ? void 0 : _z[900]) !== null && _0 !== void 0 ? _0 : "gray.900",
37
+ trackBg: colors.backgroundColor.secondary,
38
+ activeBg: colors.backgroundColor.main,
39
+ activeColor: colors.primary[500],
40
+ mutedColor: colors.text[600],
41
+ hoverBg: colors.gray[100],
42
+ borderColor: colors.boxborder[200],
43
+ // NOTE: menuBg lives in Menu.styles.ts re-pushing it via `sx` flickers on every render.
44
+ menuColor: colors.text[900],
52
45
  };
53
46
  };
54
47
  const BrandMenu = ({ size }) => {
@@ -186,12 +186,8 @@ const disabled = {
186
186
  800: "#625d75",
187
187
  900: "#4b4759",
188
188
  };
189
- // Two-tone brand gradient (violet pink). Each theme overrides with its own pair.
190
- // `to` stop retuned so white gradient-button text (onGradient, accentText.ts) clears AA — the
191
- // original let white drop to 3.53 there (`from` already passed at 5.76, unchanged).
192
- // Nudged one step further (4.511 -> 4.609): the first pass cleared AA by <0.02, too thin a
193
- // margin to trust against rounding/rendering variance.
194
- const gradient = { from: "#8B3FC8", to: "#df187a" };
189
+ // Single-hue gradient: white clears AA by margin, not by hundredths. See gradientTone.test.ts.
190
+ const gradient = { from: "#8b3fc8", to: "#762d9d" };
195
191
  const palette = {
196
192
  gradient,
197
193
  primary,
@@ -18,11 +18,7 @@ const primary = {
18
18
  const palette = {
19
19
  ...neutralTokens,
20
20
  ...buildBrandInk(PRIMARY_500),
21
- // `to` stop retuned so white gradient-button text (onGradient, accentText.ts) clears AA — the
22
- // original let white drop to 2.98 there (`from` already passed at 4.83, unchanged).
23
- // Nudged one step further (4.520 -> 4.608): the first pass cleared AA by <0.02, too thin a
24
- // margin to trust against rounding/rendering variance.
25
- gradient: { from: "#6b7280", to: "#5664f6" }, // slate gray → indigo
21
+ gradient: { from: "#666d7a", to: "#4a4e59" },
26
22
  primary,
27
23
  tertiary: { ...primary },
28
24
  gray: {
@@ -25,7 +25,7 @@ export function chartInk(colors) {
25
25
  surface,
26
26
  text: colors.text[900],
27
27
  muted: colors.text[500],
28
- grid: colors.border[500],
28
+ grid: colors.boxborder[200],
29
29
  axis: colors.text[500],
30
30
  tooltipBg: colors.backgroundColor.secondary,
31
31
  };
@@ -0,0 +1,22 @@
1
+ import { onGradient } from "./accentText.js";
2
+ import { resolveAvatarFill } from "./statusTone.js";
3
+ /**
4
+ * Sinks both stops until WHITE ink clears AA, keeping each stop's hue. Any mid-tone gradient
5
+ * otherwise flips `onGradient` to black ink, so the same element reads white-on-colour in one
6
+ * brand and black-on-pastel in the next.
7
+ */
8
+ export const inkSafeGradient = (gradient) => ({
9
+ from: resolveAvatarFill(gradient.from),
10
+ to: resolveAvatarFill(gradient.to),
11
+ });
12
+ /**
13
+ * The only correct way to paint text on a gradient: returns the stops to draw AND the ink for
14
+ * them. Calling `onGradient` on raw stops is the black-text bug — it picks ink for a backdrop
15
+ * that is then painted differently.
16
+ */
17
+ export const resolveGradient = (gradient, white, black) => {
18
+ const { from, to } = inkSafeGradient(gradient);
19
+ return { from, to, ink: onGradient(from, to, white, black) };
20
+ };
21
+ /** `linear-gradient(...)` for a resolved pair — one spelling of the CSS everywhere. */
22
+ export const gradientCss = (g, angle = "135deg") => `linear-gradient(${angle}, ${g.from} 0%, ${g.to} 100%)`;
@@ -3,3 +3,6 @@ export * from "./buildBrandTokens.js";
3
3
  export * from "./buildDarkPalette.js";
4
4
  export * from "./chartColorsFromTheme.js";
5
5
  export * from "./color.js";
6
+ export * from "./scrollbar.js";
7
+ export * from "./gradientInk.js";
8
+ export * from "./placeholderInk.js";