pixelize-design-library 2.4.2-beta.62 → 2.4.2-beta.63

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 (166) hide show
  1. package/CHANGELOG.md +75 -2
  2. package/COMPONENT-GOTCHAS.md +25 -6
  3. package/DESIGN-GUIDE.md +12 -5
  4. package/dist/Components/Button/Button.styles.js +51 -21
  5. package/dist/Components/Card/CardProps.d.ts +2 -2
  6. package/dist/Components/ConfirmDialog/ConfirmDialog.js +2 -1
  7. package/dist/Components/CustomModulesTable/CustomModulesTable.js +6 -4
  8. package/dist/Components/CustomModulesTable/EditModuleModal.js +2 -1
  9. package/dist/Components/DatePicker/RangeDatePicker.js +2 -1
  10. package/dist/Components/DatePicker/SingleDatePicker.js +2 -1
  11. package/dist/Components/DatePicker/TimeOnlyPicker.js +2 -1
  12. package/dist/Components/DatePicker/dayStates.js +2 -1
  13. package/dist/Components/Drawer/Drawer.js +2 -1
  14. package/dist/Components/Dropdown/DropDown.js +2 -1
  15. package/dist/Components/FileUpload/FileUpload.js +9 -2
  16. package/dist/Components/FilterSidebar/FilterSidebar.js +7 -4
  17. package/dist/Components/KanbanBoard/AccountCard.js +4 -2
  18. package/dist/Components/NavigationBar/NavigationBar.js +3 -2
  19. package/dist/Components/Notification/Notification.js +4 -3
  20. package/dist/Components/NotificationBell/NotificationPanel.js +4 -3
  21. package/dist/Components/OrganizationDetails/CreateOrgModal.js +2 -1
  22. package/dist/Components/OrganizationDetails/OrganizationDetails.js +5 -3
  23. package/dist/Components/ProfilePhotoViewer/ProfilePhotoViewer.js +7 -3
  24. package/dist/Components/SearchSelect/SearchSelect.js +42 -21
  25. package/dist/Components/SearchSelect/searchSelectNav.d.ts +13 -0
  26. package/dist/Components/SearchSelect/searchSelectNav.js +40 -0
  27. package/dist/Components/Select/SelectPopup.js +2 -1
  28. package/dist/Components/SelectSearch/SelectSearch.js +2 -1
  29. package/dist/Components/SettingRow/SettingRow.js +2 -1
  30. package/dist/Components/SettingRow/SettingsSection.js +2 -1
  31. package/dist/Components/SideBar/SecondaryBar.js +4 -3
  32. package/dist/Components/SideBar/SideBar.js +16 -13
  33. package/dist/Components/SideBar/SideBarProps.d.ts +1 -1
  34. package/dist/Components/SideBar/components/MenuItemBox.js +7 -4
  35. package/dist/Components/SideBar/components/MenuPopoverContent.js +2 -1
  36. package/dist/Components/SideBar/components/OtherApps.js +2 -1
  37. package/dist/Components/SideBar/components/PinnedSection.js +7 -4
  38. package/dist/Components/SideBar/sidebarMotion.d.ts +2 -0
  39. package/dist/Components/SideBar/sidebarMotion.js +6 -0
  40. package/dist/Components/SignInActivityTable/SignInActivityTable.js +6 -4
  41. package/dist/Components/StageProgress/StageItem.js +5 -2
  42. package/dist/Components/StageProgress/StepperStage.js +2 -2
  43. package/dist/Components/StatCard/StatCard.js +2 -1
  44. package/dist/Components/Table/Table.js +6 -2
  45. package/dist/Components/Table/components/TableActions.js +3 -2
  46. package/dist/Components/Table/filters/CompactSelect.js +2 -1
  47. package/dist/Components/Table/settings/TableSettings.js +7 -2
  48. package/dist/Components/Table/variants/classic.js +3 -2
  49. package/dist/Components/Timeline/Timeline.js +11 -4
  50. package/dist/Components/Toaster/Toaster.js +19 -8
  51. package/dist/Components/Toggle/TableToggle.js +5 -2
  52. package/dist/Components/UserDetails/AddUserModal.js +2 -1
  53. package/dist/Components/UserDetails/ChangeRoleModal.js +2 -1
  54. package/dist/Components/UserDetails/UserDetails.js +3 -1
  55. package/dist/Theme/chakra/Card.styles.d.ts +7 -1
  56. package/dist/Theme/chakra/Card.styles.js +4 -1
  57. package/dist/Theme/chakra/Menu.styles.d.ts +3 -5
  58. package/dist/Theme/chakra/Menu.styles.js +3 -0
  59. package/dist/Theme/chakra/Popover.styles.d.ts +2 -11
  60. package/dist/Theme/chakra/Popover.styles.js +2 -0
  61. package/dist/Theme/chakra/common.web.d.ts +4 -0
  62. package/dist/Theme/chakra/componentStyles.d.ts +11 -3
  63. package/dist/Theme/chakra/componentStyles.js +10 -6
  64. package/dist/Theme/chakra/motion.d.ts +1 -0
  65. package/dist/Theme/chakra/motion.js +2 -1
  66. package/dist/Theme/chakra/overlay.styles.d.ts +5 -0
  67. package/dist/Theme/chakra/overlay.styles.js +4 -1
  68. package/dist/Theme/themeProps.d.ts +4 -0
  69. package/dist/Theme/tokens/brands/index.d.ts +1 -0
  70. package/dist/Theme/tokens/brands/index.js +17 -1
  71. package/dist/Theme/tokens/brands/radiant/palette.light.js +15 -0
  72. package/dist/Theme/tokens/brands/rosewood/palette.light.js +10 -10
  73. package/dist/Theme/tokens/brands/zinc/palette.dark.d.ts +7 -29
  74. package/dist/Theme/tokens/brands/zinc/palette.dark.js +3 -35
  75. package/dist/Theme/tokens/builders/buildDarkPalette.d.ts +6 -1
  76. package/dist/Theme/tokens/builders/buildDarkPalette.js +37 -8
  77. package/dist/Theme/tokens/builders/mutedText.d.ts +1 -1
  78. package/dist/Theme/tokens/builders/mutedText.js +13 -3
  79. package/dist/Theme/tokens/builders/planeStep.d.ts +4 -0
  80. package/dist/Theme/tokens/builders/planeStep.js +20 -0
  81. package/dist/Theme/tokens/builders/planes.d.ts +4 -0
  82. package/dist/Theme/tokens/builders/planes.js +33 -0
  83. package/dist/Theme/tokens/builders/skeletonShimmer.d.ts +9 -0
  84. package/dist/Theme/tokens/builders/skeletonShimmer.js +25 -0
  85. package/dist/Theme/tokens/builders/surfaceRaised.d.ts +3 -1
  86. package/dist/Theme/tokens/builders/surfaceRaised.js +18 -8
  87. package/dist/Theme/tokens/builders/surfaceRungs.js +3 -1
  88. package/dist/Theme/tokens/primitives/index.d.ts +2 -2
  89. package/dist/Theme/tokens/primitives/index.js +4 -1
  90. package/dist/Theme/tokens/primitives/motion.d.ts +1 -0
  91. package/dist/Theme/tokens/primitives/motion.js +2 -1
  92. package/dist/Theme/tokens/primitives/shadows.d.ts +16 -0
  93. package/dist/Theme/tokens/primitives/shadows.js +56 -6
  94. package/dist/Theme/tokens/primitives/typography.js +1 -1
  95. package/dist/esm/Components/Button/Button.styles.js +54 -24
  96. package/dist/esm/Components/ConfirmDialog/ConfirmDialog.js +2 -1
  97. package/dist/esm/Components/CustomModulesTable/CustomModulesTable.js +6 -4
  98. package/dist/esm/Components/CustomModulesTable/EditModuleModal.js +2 -1
  99. package/dist/esm/Components/DatePicker/RangeDatePicker.js +2 -1
  100. package/dist/esm/Components/DatePicker/SingleDatePicker.js +2 -1
  101. package/dist/esm/Components/DatePicker/TimeOnlyPicker.js +2 -1
  102. package/dist/esm/Components/DatePicker/dayStates.js +2 -1
  103. package/dist/esm/Components/Drawer/Drawer.js +2 -1
  104. package/dist/esm/Components/Dropdown/DropDown.js +2 -1
  105. package/dist/esm/Components/FileUpload/FileUpload.js +10 -3
  106. package/dist/esm/Components/FilterSidebar/FilterSidebar.js +7 -4
  107. package/dist/esm/Components/KanbanBoard/AccountCard.js +4 -2
  108. package/dist/esm/Components/NavigationBar/NavigationBar.js +3 -2
  109. package/dist/esm/Components/Notification/Notification.js +4 -3
  110. package/dist/esm/Components/NotificationBell/NotificationPanel.js +4 -3
  111. package/dist/esm/Components/OrganizationDetails/CreateOrgModal.js +2 -1
  112. package/dist/esm/Components/OrganizationDetails/OrganizationDetails.js +5 -3
  113. package/dist/esm/Components/ProfilePhotoViewer/ProfilePhotoViewer.js +7 -3
  114. package/dist/esm/Components/SearchSelect/SearchSelect.js +42 -21
  115. package/dist/esm/Components/SearchSelect/searchSelectNav.js +32 -0
  116. package/dist/esm/Components/Select/SelectPopup.js +2 -1
  117. package/dist/esm/Components/SelectSearch/SelectSearch.js +2 -1
  118. package/dist/esm/Components/SettingRow/SettingRow.js +2 -1
  119. package/dist/esm/Components/SettingRow/SettingsSection.js +2 -1
  120. package/dist/esm/Components/SideBar/SecondaryBar.js +4 -3
  121. package/dist/esm/Components/SideBar/SideBar.js +17 -14
  122. package/dist/esm/Components/SideBar/components/MenuItemBox.js +7 -4
  123. package/dist/esm/Components/SideBar/components/MenuPopoverContent.js +2 -1
  124. package/dist/esm/Components/SideBar/components/OtherApps.js +2 -1
  125. package/dist/esm/Components/SideBar/components/PinnedSection.js +7 -4
  126. package/dist/esm/Components/SideBar/sidebarMotion.js +3 -0
  127. package/dist/esm/Components/SignInActivityTable/SignInActivityTable.js +6 -4
  128. package/dist/esm/Components/StageProgress/StageItem.js +5 -2
  129. package/dist/esm/Components/StageProgress/StepperStage.js +2 -2
  130. package/dist/esm/Components/StatCard/StatCard.js +2 -1
  131. package/dist/esm/Components/Table/Table.js +8 -4
  132. package/dist/esm/Components/Table/components/TableActions.js +3 -2
  133. package/dist/esm/Components/Table/filters/CompactSelect.js +2 -1
  134. package/dist/esm/Components/Table/settings/TableSettings.js +8 -3
  135. package/dist/esm/Components/Table/variants/classic.js +3 -2
  136. package/dist/esm/Components/Timeline/Timeline.js +11 -4
  137. package/dist/esm/Components/Toaster/Toaster.js +20 -9
  138. package/dist/esm/Components/Toggle/TableToggle.js +5 -2
  139. package/dist/esm/Components/UserDetails/AddUserModal.js +2 -1
  140. package/dist/esm/Components/UserDetails/ChangeRoleModal.js +2 -1
  141. package/dist/esm/Components/UserDetails/UserDetails.js +3 -1
  142. package/dist/esm/Theme/chakra/Card.styles.js +4 -1
  143. package/dist/esm/Theme/chakra/Menu.styles.js +3 -0
  144. package/dist/esm/Theme/chakra/Popover.styles.js +2 -0
  145. package/dist/esm/Theme/chakra/componentStyles.js +10 -6
  146. package/dist/esm/Theme/chakra/motion.js +1 -0
  147. package/dist/esm/Theme/chakra/overlay.styles.js +3 -0
  148. package/dist/esm/Theme/tokens/brands/index.js +16 -0
  149. package/dist/esm/Theme/tokens/brands/radiant/palette.light.js +15 -0
  150. package/dist/esm/Theme/tokens/brands/rosewood/palette.light.js +10 -10
  151. package/dist/esm/Theme/tokens/brands/zinc/palette.dark.js +3 -35
  152. package/dist/esm/Theme/tokens/builders/buildDarkPalette.js +38 -9
  153. package/dist/esm/Theme/tokens/builders/mutedText.js +12 -2
  154. package/dist/esm/Theme/tokens/builders/planeStep.js +14 -0
  155. package/dist/esm/Theme/tokens/builders/planes.js +28 -0
  156. package/dist/esm/Theme/tokens/builders/skeletonShimmer.js +21 -0
  157. package/dist/esm/Theme/tokens/builders/surfaceRaised.js +16 -7
  158. package/dist/esm/Theme/tokens/builders/surfaceRungs.js +3 -1
  159. package/dist/esm/Theme/tokens/primitives/index.js +1 -1
  160. package/dist/esm/Theme/tokens/primitives/motion.js +1 -0
  161. package/dist/esm/Theme/tokens/primitives/shadows.js +54 -5
  162. package/dist/esm/Theme/tokens/primitives/typography.js +1 -1
  163. package/dist/esm/index.js +1 -0
  164. package/dist/index.d.ts +1 -0
  165. package/dist/index.js +9 -5
  166. package/package.json +1 -1
@@ -1,21 +1,31 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.raisedRule = exports.withSurfaceRaised = exports.buildSurfaceRaised = exports.RAISED_OVERLAY = void 0;
3
+ exports.raisedRule = exports.withSurfaceRaised = exports.buildSurfaceRaised = exports.filledMarks = exports.RAISED_OVERLAY = void 0;
4
4
  const color_1 = require("./color");
5
5
  const outlineRung_1 = require("./outlineRung");
6
+ const planes_1 = require("./planes");
7
+ const planeStep_1 = require("./planeStep");
8
+ const semanticText_1 = require("./semanticText");
6
9
  exports.RAISED_OVERLAY = 0.07;
7
- // Never below the card, and at least one white-overlay step above the canvas.
8
- const buildSurfaceRaised = (source) => {
9
- const overlay = (0, color_1.mix)(source.backgroundColor.main, source.white, exports.RAISED_OVERLAY);
10
+ /** The filled fills a raised plane must keep at 3:1, or a button on a menu stops reading. */
11
+ const filledMarks = (colors) => [
12
+ colors.primary[500],
13
+ ...semanticText_1.SEMANTIC_TONES.map((tone) => colors.semantic[tone][500]),
14
+ ];
15
+ exports.filledMarks = filledMarks;
16
+ // Never below the card: the lighter of one white-overlay step off the canvas and a RAISED_LIFT step off the card.
17
+ const buildSurfaceRaised = (source, marks = []) => {
10
18
  const card = source.background[50];
11
- return (0, color_1.relativeLuminance)(overlay) > (0, color_1.relativeLuminance)(card) ? overlay : card;
19
+ const overlay = (0, color_1.mix)(source.backgroundColor.main, source.white, exports.RAISED_OVERLAY);
20
+ const stepped = (0, planes_1.liftUnder)(source.white, card, planes_1.RAISED_LIFT, marks);
21
+ return [overlay, stepped].reduce((top, c) => ((0, color_1.relativeLuminance)(c) > (0, color_1.relativeLuminance)(top) ? c : top), card);
12
22
  };
13
23
  exports.buildSurfaceRaised = buildSurfaceRaised;
14
24
  const withSurfaceRaised = (palette) => ({
15
25
  ...palette,
16
- surfaceRaised: (0, exports.buildSurfaceRaised)(palette),
26
+ surfaceRaised: (0, exports.buildSurfaceRaised)(palette, (0, exports.filledMarks)(palette)),
17
27
  });
18
28
  exports.withSurfaceRaised = withSurfaceRaised;
19
- // A divider inside an overlay, at the weight `boxborder[200]` has on a card.
20
- const raisedRule = (colors) => (0, outlineRung_1.liftToContrast)(colors.boxborder[200], colors.surfaceRaised, (0, color_1.contrastRatio)(colors.boxborder[200], colors.background[50]));
29
+ // A divider inside an overlay, at the weight a rule has inside a card.
30
+ const raisedRule = (colors) => (0, outlineRung_1.liftToContrast)(colors.boxborder[200], colors.surfaceRaised, (0, color_1.contrastRatio)((0, planeStep_1.cardRule)(colors), colors.background[50]));
21
31
  exports.raisedRule = raisedRule;
@@ -6,6 +6,7 @@ const color_1 = require("./color");
6
6
  const outlineRung_1 = require("./outlineRung");
7
7
  const accentText_1 = require("./accentText");
8
8
  const semanticText_1 = require("./semanticText");
9
+ const rowStates_1 = require("./rowStates");
9
10
  // NOTE: hint held to the non-text floor, not body-text — at 4.5 an empty field reads as typed-into. See CHROME-CONSISTENCY.md.
10
11
  exports.PLACEHOLDER_TEXT = outlineRung_1.AA_NON_TEXT;
11
12
  const namedSurfaces = (palette) => [
@@ -21,6 +22,7 @@ exports.hardestSurface = hardestSurface;
21
22
  // Runs last: `table.hover` is one of the surfaces, and it settles in its own rung.
22
23
  function withSurfaceRungs(palette) {
23
24
  const surfaces = (0, exports.namedSurfaces)(palette);
25
+ const accentSurfaces = [...surfaces, ...Object.values((0, rowStates_1.listRowBackgrounds)(palette))];
24
26
  const lift = (ink, target) => (0, outlineRung_1.liftToContrast)(ink, (0, exports.hardestSurface)(ink, surfaces), target);
25
27
  const settle = (ink, target) => (0, outlineRung_1.settleAcross)(ink, surfaces, target);
26
28
  const rule = (ink) => (0, outlineRung_1.ruleInk)(ink, [palette.backgroundColor.main, palette.background[50]], outlineRung_1.CHROME_RULE);
@@ -31,7 +33,7 @@ function withSurfaceRungs(palette) {
31
33
  return {
32
34
  ...palette,
33
35
  textMuted: lift(palette.textMuted, accentText_1.AA_NORMAL_TEXT),
34
- accentText: (0, accentText_1.pickAccentText)(palette.primary, (0, exports.hardestSurface)(palette.accentText, surfaces)),
36
+ accentText: (0, accentText_1.pickAccentText)(palette.primary, (0, exports.hardestSurface)(palette.accentText, accentSurfaces)),
35
37
  semanticText,
36
38
  text: { ...palette.text, 500: lift(palette.text[500], accentText_1.AA_NORMAL_TEXT) },
37
39
  header: { ...palette.header, 500: lift(palette.header[500], accentText_1.AA_NORMAL_TEXT) },
@@ -4,8 +4,8 @@ export { default as radii, RADIUS_ROLE } from "./radii";
4
4
  export type { RadiusToken, RadiusRole } from "./radii";
5
5
  export * from "./borderWidths";
6
6
  export * from "./states";
7
- export { default as shadows, shadowsDark, shadowsFor } from "./shadows";
8
- export type { ShadowRamp } from "./shadows";
7
+ export { default as shadows, shadowsDark, shadowsFor, shadowCss, ELEVATION_LAYERS, SHADOW_INK } from "./shadows";
8
+ export type { ShadowLayer, ElevationRole, ShadowRamp } from "./shadows";
9
9
  export { default as zIndices } from "./zIndices";
10
10
  export { default as breakpoints } from "./breakpoints";
11
11
  export { default as lineHeights } from "./lineHeights";
@@ -17,7 +17,7 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
17
17
  return (mod && mod.__esModule) ? mod : { "default": mod };
18
18
  };
19
19
  Object.defineProperty(exports, "__esModule", { value: true });
20
- exports.TEXT_STYLES = exports.NUMERIC_TEXT = exports.fontWeights = exports.fontSizes = exports.fonts = exports.typography = exports.letterSpacings = exports.lineHeights = exports.breakpoints = exports.zIndices = exports.shadowsFor = exports.shadowsDark = exports.shadows = exports.RADIUS_ROLE = exports.radii = exports.sizes = exports.space = void 0;
20
+ exports.TEXT_STYLES = exports.NUMERIC_TEXT = exports.fontWeights = exports.fontSizes = exports.fonts = exports.typography = exports.letterSpacings = exports.lineHeights = exports.breakpoints = exports.zIndices = exports.SHADOW_INK = exports.ELEVATION_LAYERS = exports.shadowCss = exports.shadowsFor = exports.shadowsDark = exports.shadows = exports.RADIUS_ROLE = exports.radii = exports.sizes = exports.space = void 0;
21
21
  var space_1 = require("./space");
22
22
  Object.defineProperty(exports, "space", { enumerable: true, get: function () { return __importDefault(space_1).default; } });
23
23
  var sizes_1 = require("./sizes");
@@ -31,6 +31,9 @@ var shadows_1 = require("./shadows");
31
31
  Object.defineProperty(exports, "shadows", { enumerable: true, get: function () { return __importDefault(shadows_1).default; } });
32
32
  Object.defineProperty(exports, "shadowsDark", { enumerable: true, get: function () { return shadows_1.shadowsDark; } });
33
33
  Object.defineProperty(exports, "shadowsFor", { enumerable: true, get: function () { return shadows_1.shadowsFor; } });
34
+ Object.defineProperty(exports, "shadowCss", { enumerable: true, get: function () { return shadows_1.shadowCss; } });
35
+ Object.defineProperty(exports, "ELEVATION_LAYERS", { enumerable: true, get: function () { return shadows_1.ELEVATION_LAYERS; } });
36
+ Object.defineProperty(exports, "SHADOW_INK", { enumerable: true, get: function () { return shadows_1.SHADOW_INK; } });
34
37
  var zIndices_1 = require("./zIndices");
35
38
  Object.defineProperty(exports, "zIndices", { enumerable: true, get: function () { return __importDefault(zIndices_1).default; } });
36
39
  var breakpoints_1 = require("./breakpoints");
@@ -23,6 +23,7 @@ export declare const MOTION_LOOP_MS: {
23
23
  readonly spin: 800;
24
24
  readonly sweep: 1200;
25
25
  };
26
+ export declare const MOTION_PRESS_SCALE = 0.98;
26
27
  /** A `transition` value for named properties only — `all` also animates layout and colour flips. */
27
28
  export declare const transitionFor: (properties: readonly string[], speed?: MotionSpeed, curve?: MotionCurve) => string;
28
29
  export declare const motionTransition: (speed?: MotionSpeed, curve?: MotionCurve) => {
@@ -1,6 +1,6 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.motionTransition = exports.transitionFor = exports.MOTION_LOOP_MS = exports.MOTION_EASE_IN = exports.MOTION_EASE_OUT = exports.MOTION_EASE = exports.cubicBezierCss = exports.MOTION_BEZIER = exports.MOTION_MS = void 0;
3
+ exports.motionTransition = exports.transitionFor = exports.MOTION_PRESS_SCALE = exports.MOTION_LOOP_MS = exports.MOTION_EASE_IN = exports.MOTION_EASE_OUT = exports.MOTION_EASE = exports.cubicBezierCss = exports.MOTION_BEZIER = exports.MOTION_MS = void 0;
4
4
  exports.MOTION_MS = { fast: 150, base: 200, enter: 200, exit: 200 };
5
5
  /** Pebble easing curves (mobile `pebble-spec.json` motion.easing); `in` is Pebble's `accelerate`. */
6
6
  exports.MOTION_BEZIER = {
@@ -15,6 +15,7 @@ exports.MOTION_EASE_OUT = (0, exports.cubicBezierCss)(exports.MOTION_BEZIER.out)
15
15
  exports.MOTION_EASE_IN = (0, exports.cubicBezierCss)(exports.MOTION_BEZIER.in);
16
16
  /** Periods for loops that are feedback, not transitions: skeleton pulse, spinner turn, progress sweep. */
17
17
  exports.MOTION_LOOP_MS = { pulse: 700, spin: 800, sweep: 1200 };
18
+ exports.MOTION_PRESS_SCALE = 0.98;
18
19
  /** A `transition` value for named properties only — `all` also animates layout and colour flips. */
19
20
  const transitionFor = (properties, speed = "fast", curve = "standard") => {
20
21
  if (properties.includes("all"))
@@ -1,4 +1,16 @@
1
1
  import type { ResolvedColorMode } from "../types";
2
+ export type ShadowLayer = {
3
+ x: number;
4
+ y: number;
5
+ blur: number;
6
+ spread: number;
7
+ alphaHex: string;
8
+ };
9
+ export type ElevationRole = "cardPress" | "card" | "float" | "dialog" | "sheet";
10
+ export declare const SHADOW_INK: Record<ResolvedColorMode, string>;
11
+ /** Pebble elevation stacks (mobile `pebble/elevation.ts`), per mode and role. */
12
+ export declare const ELEVATION_LAYERS: Record<ResolvedColorMode, Record<ElevationRole, readonly ShadowLayer[]>>;
13
+ export declare const shadowCss: (layers: readonly ShadowLayer[], ink: string) => string;
2
14
  /** Light-mode ramp. A theme should carry `shadowsFor(mode)`, never this one in dark. */
3
15
  declare const shadows: {
4
16
  xs: string;
@@ -12,6 +24,10 @@ declare const shadows: {
12
24
  inner: string;
13
25
  none: string;
14
26
  darkLg: string;
27
+ card: string;
28
+ float: string;
29
+ dialog: string;
30
+ sheet: string;
15
31
  };
16
32
  export type ShadowRamp = typeof shadows;
17
33
  export declare const shadowsDark: ShadowRamp;
@@ -1,21 +1,71 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.shadowsFor = exports.shadowsDark = void 0;
3
+ exports.shadowsFor = exports.shadowsDark = exports.shadowCss = exports.ELEVATION_LAYERS = exports.SHADOW_INK = void 0;
4
+ const layer = (x, y, blur, spread, alphaHex) => ({
5
+ x,
6
+ y,
7
+ blur,
8
+ spread,
9
+ alphaHex,
10
+ });
11
+ exports.SHADOW_INK = { light: "#141828", dark: "#000000" };
12
+ /** Pebble elevation stacks (mobile `pebble/elevation.ts`), per mode and role. */
13
+ exports.ELEVATION_LAYERS = {
14
+ light: {
15
+ cardPress: [layer(0, 1, 2, 0, "0d"), layer(0, 2, 6, -2, "0d")],
16
+ card: [layer(0, 1, 2, 0, "0a"), layer(0, 3, 10, -2, "0d"), layer(0, 14, 32, -14, "1f")],
17
+ float: [layer(0, 2, 6, 0, "0f"), layer(0, 16, 40, -10, "38")],
18
+ dialog: [layer(0, 4, 12, 0, "0f"), layer(0, 28, 64, -16, "4d")],
19
+ sheet: [layer(0, -2, 8, 0, "0a"), layer(0, -18, 48, -14, "33")],
20
+ },
21
+ dark: {
22
+ cardPress: [layer(0, 1, 1, 0, "3d")],
23
+ card: [layer(0, 1, 2, 0, "47")],
24
+ float: [layer(0, 2, 8, 0, "52"), layer(0, 18, 44, -10, "9e")],
25
+ dialog: [layer(0, 4, 14, 0, "59"), layer(0, 28, 64, -16, "b3")],
26
+ sheet: [layer(0, -2, 10, 0, "4d"), layer(0, -18, 48, -14, "99")],
27
+ },
28
+ };
29
+ const length = (n) => (n === 0 ? "0" : `${n}px`);
30
+ const rgbChannels = (hex) => [1, 3, 5].map((i) => parseInt(hex.slice(i, i + 2), 16)).join(", ");
31
+ const alphaOf = (alphaHex) => Math.round((parseInt(alphaHex, 16) / 255) * 100) / 100;
32
+ const shadowCss = (layers, ink) => layers
33
+ .map((l) => `${length(l.x)} ${length(l.y)} ${length(l.blur)} ${length(l.spread)} rgba(${rgbChannels(ink)}, ${alphaOf(l.alphaHex)})`)
34
+ .join(", ");
35
+ exports.shadowCss = shadowCss;
36
+ const elevationRamp = (mode) => {
37
+ const css = (role) => (0, exports.shadowCss)(exports.ELEVATION_LAYERS[mode][role], exports.SHADOW_INK[mode]);
38
+ return {
39
+ sm: css("cardPress"),
40
+ base: css("card"),
41
+ md: css("float"),
42
+ lg: css("dialog"),
43
+ card: css("card"),
44
+ float: css("float"),
45
+ dialog: css("dialog"),
46
+ sheet: css("sheet"),
47
+ };
48
+ };
49
+ const lightElevation = elevationRamp("light");
4
50
  /** Light-mode ramp. A theme should carry `shadowsFor(mode)`, never this one in dark. */
5
51
  const shadows = {
6
52
  xs: "0 0 0 1px rgba(0, 0, 0, 0.05)",
7
- sm: "0 1px 2px 0 rgba(0, 0, 0, 0.05)",
8
- base: "0 1px 3px 0 rgba(0, 0, 0, 0.1), 0 1px 2px 0 rgba(0, 0, 0, 0.06)",
9
- md: "0 4px 6px -1px rgba(0, 0, 0, 0.1), 0 2px 4px -1px rgba(0, 0, 0, 0.06)",
10
- lg: "0 10px 15px -3px rgba(0, 0, 0, 0.1), 0 4px 6px -2px rgba(0, 0, 0, 0.05)",
53
+ sm: lightElevation.sm,
54
+ base: lightElevation.base,
55
+ md: lightElevation.md,
56
+ lg: lightElevation.lg,
11
57
  xl: "0 20px 25px -5px rgba(0, 0, 0, 0.1), 0 10px 10px -5px rgba(0, 0, 0, 0.04)",
12
58
  "2xl": "0 25px 50px -12px rgba(0, 0, 0, 0.25)",
13
59
  outline: "0 0 0 3px rgba(66, 153, 225, 0.6)",
14
60
  inner: "inset 0 2px 4px 0 rgba(0, 0, 0, 0.06)",
15
61
  none: "none",
16
62
  darkLg: "0 10px 15px -3px rgba(0, 0, 0, 0.5), 0 4px 6px -2px rgba(0, 0, 0, 0.5)",
63
+ card: lightElevation.card,
64
+ float: lightElevation.float,
65
+ dialog: lightElevation.dialog,
66
+ sheet: lightElevation.sheet,
17
67
  };
18
- exports.shadowsDark = { ...shadows };
68
+ exports.shadowsDark = { ...shadows, ...elevationRamp("dark") };
19
69
  const shadowsFor = (mode) => mode === "dark" ? exports.shadowsDark : shadows;
20
70
  exports.shadowsFor = shadowsFor;
21
71
  exports.default = shadows;
@@ -5,7 +5,7 @@ exports.TEXT_STYLES = exports.NUMERIC_TEXT = exports.fontWeights = exports.fontS
5
5
  exports.fonts = {
6
6
  body: "Inter Variable, sans-serif",
7
7
  heading: "Inter Variable, sans-serif",
8
- mono: "Inter Variable, sans-serif",
8
+ mono: "ui-monospace, SFMono-Regular, Menlo, Consolas, monospace",
9
9
  };
10
10
  exports.fontSizes = {
11
11
  "xs-minus": "0.6875rem",
@@ -1,19 +1,36 @@
1
1
  import { accentTextOnCanvas } from "../../Theme/tokens/builders/accentText.js";
2
- import { darkerFillRung, labelOnFill, solidFillRung, } from "../../Theme/tokens/builders/filledSurface.js";
2
+ import { darkerFillRung, labelOnFill, resolveFilledSurface, solidFillRung, } from "../../Theme/tokens/builders/filledSurface.js";
3
3
  import { resolveGradient, gradientCss } from "../../Theme/tokens/builders/gradientInk.js";
4
4
  import { focusVisibleStyles } from "../../Theme/chakra/focusRing.styles.js";
5
- import { reducedMotionSx } from "../../Theme/chakra/motion.js";
6
- import { BUTTON_SIZES, DEFAULT_CONTROL_SIZE, transitionFor } from "../../Theme/tokens/primitives/index.js";
5
+ import { listRowBackgrounds } from "../../Theme/tokens/builders/rowStates.js";
6
+ import { MOTION_OK_QUERY, reducedMotionSx } from "../../Theme/chakra/motion.js";
7
+ import { BUTTON_SIZES, DEFAULT_CONTROL_SIZE, MOTION_PRESS_SCALE, transitionFor } from "../../Theme/tokens/primitives/index.js";
8
+ const BUTTON_TRANSITION = [
9
+ transitionFor(["background-color", "border-color", "color", "box-shadow", "filter"]),
10
+ transitionFor(["transform"], "fast", "out"),
11
+ ].join(", ");
12
+ const PRESS = {
13
+ [MOTION_OK_QUERY]: {
14
+ "&:active:not(:disabled):not([data-loading]):not([aria-disabled=true])": {
15
+ transform: `scale(${MOTION_PRESS_SCALE})`,
16
+ },
17
+ },
18
+ };
7
19
  const controlSize = (size) => {
8
20
  const { height, fontSize, paddingX } = BUTTON_SIZES[size];
9
21
  return { h: height, minW: height, fontSize, px: paddingX };
10
22
  };
11
23
  // NOTE: [500] alone measures ~4.2 on a dark canvas — resolved per-mode so outline/ghost/link text stays readable.
12
24
  const onCanvasText = (theme, colorScheme) => accentTextOnCanvas(theme.colors[colorScheme], theme.colors.backgroundColor.main);
13
- // NOTE: [50] alone measured ~1.04 (invisible) in both modes — opacity ramp fixes it where available.
25
+ // NOTE: [50] alone measured ~1.04 (invisible) in both modes — gray borrows the row-state steps.
14
26
  const onCanvasHoverBg = (theme, colorScheme, step) => {
15
27
  const scale = theme.colors[colorScheme];
16
- return "opacity" in scale ? scale.opacity[step] : scale[50];
28
+ if ("opacity" in scale)
29
+ return scale.opacity[step];
30
+ if (colorScheme !== "gray")
31
+ return scale[50];
32
+ const rows = listRowBackgrounds(theme.colors);
33
+ return step === 16 ? rows.active : rows.selectedActive;
17
34
  };
18
35
  const swatch = (theme, colorScheme) => theme.colors[colorScheme];
19
36
  const buttonSolidRung = (theme, colorScheme) => solidFillRung(swatch(theme, colorScheme), theme.colors.white);
@@ -24,6 +41,21 @@ const darkerFill = (theme, colorScheme, step) => {
24
41
  };
25
42
  /** Label for the solid variant's filled bg — derived from THAT fill, since hover/active swap it. */
26
43
  const labelFor = (theme, fill) => labelOnFill(fill, theme.colors.white, theme.colors.black);
44
+ const solidSurface = (theme, colorScheme) => {
45
+ if (colorScheme === "primary")
46
+ return resolveFilledSurface(theme.colors.primary, theme.colors);
47
+ const fill = theme.colors[colorScheme][buttonSolidRung(theme, colorScheme)];
48
+ const hoverFill = darkerFill(theme, colorScheme, 0);
49
+ const activeFill = darkerFill(theme, colorScheme, 1);
50
+ return {
51
+ fill,
52
+ color: labelFor(theme, fill),
53
+ hoverFill,
54
+ hoverColor: labelFor(theme, hoverFill),
55
+ activeFill,
56
+ activeColor: labelFor(theme, activeFill),
57
+ };
58
+ };
27
59
  // NOTE: replaces Chakra's stock ring, which failed WCAG 1.4.11 on every brand — gated by focusRing.test.ts.
28
60
  const focusRing = (theme) => focusVisibleStyles(theme.colors);
29
61
  export const Button = {
@@ -32,7 +64,7 @@ export const Button = {
32
64
  baseStyle: ({ theme }) => ({
33
65
  borderRadius: "lg",
34
66
  fontWeight: 500,
35
- transition: transitionFor(["background-color", "border-color", "color", "box-shadow", "filter"]),
67
+ transition: BUTTON_TRANSITION,
36
68
  ...reducedMotionSx(),
37
69
  _disabled: {
38
70
  opacity: 0.6,
@@ -42,35 +74,32 @@ export const Button = {
42
74
  }),
43
75
  variants: {
44
76
  solid: ({ theme, colorScheme = "primary" }) => {
45
- const fill = theme.colors[colorScheme][buttonSolidRung(theme, colorScheme)];
46
- const hoverFill = darkerFill(theme, colorScheme, 0);
47
- const activeFill = darkerFill(theme, colorScheme, 1);
48
- const hoverLabel = labelFor(theme, hoverFill);
77
+ const s = solidSurface(theme, colorScheme);
49
78
  return {
50
- bg: fill,
51
- color: labelFor(theme, fill),
79
+ bg: s.fill,
80
+ color: s.color,
52
81
  _hover: {
53
- bg: hoverFill,
54
- color: hoverLabel,
55
- boxShadow: "sm",
82
+ bg: s.hoverFill,
83
+ color: s.hoverColor,
56
84
  _disabled: {
57
- bg: hoverFill, // keep hover color on loading
58
- color: hoverLabel,
85
+ bg: s.hoverFill, // keep hover color on loading
86
+ color: s.hoverColor,
59
87
  },
60
88
  },
61
89
  _active: {
62
- bg: activeFill,
63
- color: labelFor(theme, activeFill),
90
+ bg: s.activeFill,
91
+ color: s.activeColor,
64
92
  boxShadow: "none",
65
93
  },
66
94
  _loading: {
67
- bg: hoverFill, // keep hover color while loading
68
- color: hoverLabel,
95
+ bg: s.hoverFill, // keep hover color while loading
96
+ color: s.hoverColor,
69
97
  _hover: {
70
- bg: hoverFill,
71
- color: hoverLabel,
98
+ bg: s.hoverFill,
99
+ color: s.hoverColor,
72
100
  },
73
101
  },
102
+ ...PRESS,
74
103
  ...focusRing(theme),
75
104
  };
76
105
  },
@@ -91,6 +120,7 @@ export const Button = {
91
120
  _loading: {
92
121
  color: ink,
93
122
  },
123
+ ...PRESS,
94
124
  ...focusRing(theme),
95
125
  };
96
126
  },
@@ -104,6 +134,7 @@ export const Button = {
104
134
  _active: {
105
135
  bg: onCanvasHoverBg(theme, colorScheme, 24),
106
136
  },
137
+ ...PRESS,
107
138
  ...focusRing(theme),
108
139
  }),
109
140
  link: ({ theme, colorScheme = "primary" }) => ({
@@ -140,7 +171,6 @@ export const Button = {
140
171
  _hover: {
141
172
  bgImage: bg,
142
173
  filter: "brightness(0.92)",
143
- boxShadow: "md",
144
174
  _disabled: { bgImage: bg, filter: "none" },
145
175
  },
146
176
  _active: {
@@ -3,6 +3,7 @@ import { useRef, useState } from "react";
3
3
  import { Modal, ModalOverlay, ModalContent, ModalHeader, ModalCloseButton, ModalBody, Flex, HStack, VStack, Text, } from "@chakra-ui/react";
4
4
  import { AlertTriangle } from "lucide-react";
5
5
  import { useCustomTheme } from "../../Theme/useCustomTheme.js";
6
+ import { raisedRule } from "../../Theme/tokens/builders/surfaceRaised.js";
6
7
  import Button from "../Button/Button.js";
7
8
  import TextInput from "../Input/TextInput.js";
8
9
  const ConfirmDialog = ({ isOpen, onClose, onConfirm, title, children, icon, iconBg, iconColor, tone = "destructive", cancelLabel = "Cancel", confirmLabel = "Confirm", confirmIcon, isConfirmLoading = false, disableCancelWhilePending = true, confirmationText, confirmationLabel, bodyLayout = "flush", bodySpacing = 4, actionsPt = 0, focusCancelOnOpen = true, isCentered = true, closeOnEsc, closeOnOverlayClick, }) => {
@@ -13,6 +14,6 @@ const ConfirmDialog = ({ isOpen, onClose, onConfirm, title, children, icon, icon
13
14
  const isConfirmDisabled = isConfirmLoading || (requiresTypedConfirmation && typedText !== confirmationText);
14
15
  const actions = (_jsxs(HStack, { justifyContent: "flex-end", spacing: 3, pt: actionsPt, children: [_jsx(Button, { ref: cancelRef, label: cancelLabel, onClick: onClose, variant: "outline", colorScheme: "gray", size: "sm", isDisabled: disableCancelWhilePending && isConfirmLoading }), _jsx(Button, { label: confirmLabel, onClick: onConfirm, colorScheme: tone === "destructive" ? "red" : "primary", size: "sm", isLoading: isConfirmLoading, isDisabled: isConfirmDisabled, leftIcon: confirmIcon })] }));
15
16
  const body = requiresTypedConfirmation ? (_jsxs(_Fragment, { children: [children, _jsx(TextInput, { label: confirmationLabel, value: typedText, onChange: (event) => setTypedText(event.target.value) })] })) : (children);
16
- return (_jsxs(Modal, { isOpen: isOpen, onClose: onClose, isCentered: isCentered, closeOnEsc: closeOnEsc, closeOnOverlayClick: closeOnOverlayClick, initialFocusRef: focusCancelOnOpen ? cancelRef : undefined, children: [_jsx(ModalOverlay, { backdropFilter: "blur(4px)" }), _jsxs(ModalContent, { bg: colors.surfaceRaised, borderRadius: "xl", overflow: "hidden", children: [_jsxs(ModalHeader, { borderBottom: "1px solid", borderColor: colors.boxborder[200], display: "flex", alignItems: "center", gap: 3, children: [_jsx(Flex, { align: "center", justify: "center", boxSize: "36px", borderRadius: "full", bg: iconBg, color: iconColor, children: icon !== null && icon !== void 0 ? icon : _jsx(AlertTriangle, { size: 18 }) }), _jsx(Text, { fontSize: "1.05rem", fontWeight: 600, children: title })] }), _jsx(ModalCloseButton, {}), _jsx(ModalBody, { py: 6, children: bodyLayout === "stack" ? (_jsxs(VStack, { spacing: bodySpacing, align: "stretch", children: [body, actions] })) : (_jsxs(_Fragment, { children: [body, actions] })) })] })] }));
17
+ return (_jsxs(Modal, { isOpen: isOpen, onClose: onClose, isCentered: isCentered, closeOnEsc: closeOnEsc, closeOnOverlayClick: closeOnOverlayClick, initialFocusRef: focusCancelOnOpen ? cancelRef : undefined, children: [_jsx(ModalOverlay, { backdropFilter: "blur(4px)" }), _jsxs(ModalContent, { bg: colors.surfaceRaised, borderRadius: "xl", overflow: "hidden", children: [_jsxs(ModalHeader, { borderBottom: "1px solid", borderColor: raisedRule(colors), display: "flex", alignItems: "center", gap: 3, children: [_jsx(Flex, { align: "center", justify: "center", boxSize: "36px", borderRadius: "full", bg: iconBg, color: iconColor, children: icon !== null && icon !== void 0 ? icon : _jsx(AlertTriangle, { size: 18 }) }), _jsx(Text, { fontSize: "1.05rem", fontWeight: 600, children: title })] }), _jsx(ModalCloseButton, {}), _jsx(ModalBody, { py: 6, children: bodyLayout === "stack" ? (_jsxs(VStack, { spacing: bodySpacing, align: "stretch", children: [body, actions] })) : (_jsxs(_Fragment, { children: [body, actions] })) })] })] }));
17
18
  };
18
19
  export default ConfirmDialog;
@@ -3,6 +3,7 @@ import { useMemo, useState } from "react";
3
3
  import { Box, Flex, Heading, HStack, Skeleton, Table, Tbody, Td, Text, Th, Thead, Tooltip, Tr, VStack, } from "@chakra-ui/react";
4
4
  import { Boxes, Pencil, Trash2 } from "lucide-react";
5
5
  import { useCustomTheme } from "../../Theme/useCustomTheme.js";
6
+ import { bandOn, cardRule } from "../../Theme/tokens/builders/planeStep.js";
6
7
  import Button from "../Button/Button.js";
7
8
  import EmptyState from "../EmptyState/EmptyState.js";
8
9
  import EditModuleModal from "./EditModuleModal.js";
@@ -29,20 +30,21 @@ const CustomModulesTable = ({ modules, isLoading = false, isUpdating = false, is
29
30
  const labels = useMemo(() => ({ ...DEFAULT_LABELS, ...labelOverrides }), [labelOverrides]);
30
31
  const [editTarget, setEditTarget] = useState(null);
31
32
  const [deleteTarget, setDeleteTarget] = useState(null);
32
- const border = colors.boxborder[200];
33
+ const edge = colors.boxborder[200];
33
34
  const surface = colors.background[50];
35
+ const rule = cardRule(colors);
34
36
  const muted = colors.textMuted;
35
37
  const heading = colors.text[800];
36
- const headBg = colors.backgroundColor.tableHeader;
38
+ const headBg = bandOn(colors.backgroundColor.tableHeader, surface);
37
39
  const thStyle = {
38
40
  fontSize: "0.7rem",
39
41
  textTransform: "uppercase",
40
42
  letterSpacing: "0.04em",
41
43
  color: muted,
42
- borderColor: border,
44
+ borderColor: rule,
43
45
  py: 3,
44
46
  };
45
- return (_jsxs(Box, { backgroundColor: surface, borderRadius: "xl", border: "1px solid", borderColor: border, boxShadow: "sm", overflow: "hidden", children: [_jsx(Flex, { px: 4, py: 3, borderBottom: "1px solid", borderColor: border, alignItems: "center", children: _jsx(Heading, { size: "sm", fontWeight: 600, color: heading, children: labels.title }) }), _jsx(Box, { overflowX: "auto", children: isLoading ? (_jsx(VStack, { spacing: 3, p: 4, align: "stretch", children: Array.from({ length: 4 }).map((_, idx) => (_jsx(Skeleton, { height: "18px", borderRadius: "md", startColor: colors.gray[100], endColor: colors.gray[400] }, idx))) })) : modules.length === 0 ? (_jsx(EmptyState, { icon: Boxes, title: labels.noModules, size: "sm", minH: "180px" })) : (_jsxs(Table, { variant: "simple", size: "sm", children: [_jsx(Thead, { bg: headBg, children: _jsxs(Tr, { children: [_jsx(Th, { ...thStyle, children: labels.moduleName }), _jsx(Th, { ...thStyle, children: labels.moduleOwner }), _jsx(Th, { ...thStyle, textAlign: "right", children: labels.action })] }) }), _jsx(Tbody, { children: modules.map((item) => (_jsxs(Tr, { _hover: { bg: headBg }, transition: "background 0.15s ease", children: [_jsx(Td, { borderColor: border, fontSize: "sm", fontWeight: 500, color: heading, maxW: "220px", children: _jsx(Tooltip, { label: item.moduleName, hasArrow: true, openDelay: 400, children: _jsx(Text, { noOfLines: 1, children: item.moduleName }) }) }), _jsx(Td, { borderColor: border, fontSize: "sm", color: muted, children: item.ownerLabel || "—" }), _jsx(Td, { borderColor: border, children: _jsxs(HStack, { spacing: 2, justifyContent: "flex-end", children: [_jsx(Button, { size: "xs", variant: "outline", colorScheme: "primary", leftIcon: _jsx(Pencil, { size: 13 }), label: labels.edit, onClick: () => setEditTarget(item) }), _jsx(Button, { size: "xs", variant: "outline", colorScheme: "red", leftIcon: _jsx(Trash2, { size: 13 }), label: labels.delete, onClick: () => setDeleteTarget(item) })] }) })] }, item.module_id))) })] })) }), _jsx(EditModuleModal, { isOpen: editTarget !== null, onClose: () => setEditTarget(null), initialName: (_a = editTarget === null || editTarget === void 0 ? void 0 : editTarget.moduleName) !== null && _a !== void 0 ? _a : "", isLoading: isUpdating, onSubmit: async (name) => {
47
+ return (_jsxs(Box, { backgroundColor: surface, borderRadius: "xl", border: "1px solid", borderColor: edge, boxShadow: "sm", overflow: "hidden", children: [_jsx(Flex, { px: 4, py: 3, borderBottom: "1px solid", borderColor: rule, alignItems: "center", children: _jsx(Heading, { size: "sm", fontWeight: 600, color: heading, children: labels.title }) }), _jsx(Box, { overflowX: "auto", children: isLoading ? (_jsx(VStack, { spacing: 3, p: 4, align: "stretch", children: Array.from({ length: 4 }).map((_, idx) => (_jsx(Skeleton, { height: "18px", borderRadius: "md", startColor: colors.gray[100], endColor: colors.gray[400] }, idx))) })) : modules.length === 0 ? (_jsx(EmptyState, { icon: Boxes, title: labels.noModules, size: "sm", minH: "180px" })) : (_jsxs(Table, { variant: "simple", size: "sm", children: [_jsx(Thead, { bg: headBg, children: _jsxs(Tr, { children: [_jsx(Th, { ...thStyle, children: labels.moduleName }), _jsx(Th, { ...thStyle, children: labels.moduleOwner }), _jsx(Th, { ...thStyle, textAlign: "right", children: labels.action })] }) }), _jsx(Tbody, { children: modules.map((item) => (_jsxs(Tr, { _hover: { bg: headBg }, transition: "background 0.15s ease", children: [_jsx(Td, { borderColor: rule, fontSize: "sm", fontWeight: 500, color: heading, maxW: "220px", children: _jsx(Tooltip, { label: item.moduleName, hasArrow: true, openDelay: 400, children: _jsx(Text, { noOfLines: 1, children: item.moduleName }) }) }), _jsx(Td, { borderColor: rule, fontSize: "sm", color: muted, children: item.ownerLabel || "—" }), _jsx(Td, { borderColor: rule, children: _jsxs(HStack, { spacing: 2, justifyContent: "flex-end", children: [_jsx(Button, { size: "xs", variant: "outline", colorScheme: "primary", leftIcon: _jsx(Pencil, { size: 13 }), label: labels.edit, onClick: () => setEditTarget(item) }), _jsx(Button, { size: "xs", variant: "outline", colorScheme: "red", leftIcon: _jsx(Trash2, { size: 13 }), label: labels.delete, onClick: () => setDeleteTarget(item) })] }) })] }, item.module_id))) })] })) }), _jsx(EditModuleModal, { isOpen: editTarget !== null, onClose: () => setEditTarget(null), initialName: (_a = editTarget === null || editTarget === void 0 ? void 0 : editTarget.moduleName) !== null && _a !== void 0 ? _a : "", isLoading: isUpdating, onSubmit: async (name) => {
46
48
  if (editTarget) {
47
49
  await (onUpdateModule === null || onUpdateModule === void 0 ? void 0 : onUpdateModule({
48
50
  moduleId: editTarget.module_id,
@@ -2,6 +2,7 @@ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
2
2
  import { useEffect, useState } from "react";
3
3
  import { Modal, ModalOverlay, ModalContent, ModalHeader, ModalCloseButton, ModalBody, HStack, Input, } from "@chakra-ui/react";
4
4
  import { useCustomTheme } from "../../Theme/useCustomTheme.js";
5
+ import { raisedRule } from "../../Theme/tokens/builders/surfaceRaised.js";
5
6
  import Button from "../Button/Button.js";
6
7
  const EditModuleModal = ({ isOpen, onClose, initialName, isLoading, onSubmit, labels, }) => {
7
8
  const { colors } = useCustomTheme();
@@ -10,7 +11,7 @@ const EditModuleModal = ({ isOpen, onClose, initialName, isLoading, onSubmit, la
10
11
  if (isOpen)
11
12
  setName(initialName);
12
13
  }, [isOpen, initialName]);
13
- return (_jsxs(Modal, { isOpen: isOpen, onClose: onClose, isCentered: true, children: [_jsx(ModalOverlay, { backdropFilter: "blur(4px)" }), _jsxs(ModalContent, { borderRadius: "xl", overflow: "hidden", bg: colors.surfaceRaised, children: [_jsx(ModalHeader, { borderBottom: "1px solid", borderColor: colors.boxborder[200], fontSize: "1.05rem", fontWeight: 600, children: labels.editModuleTitle }), _jsx(ModalCloseButton, {}), _jsxs(ModalBody, { py: 6, children: [_jsx(Input, { value: name, onChange: (e) => setName(e.target.value), placeholder: labels.moduleNamePlaceholder, "aria-label": labels.moduleNamePlaceholder,
14
+ return (_jsxs(Modal, { isOpen: isOpen, onClose: onClose, isCentered: true, children: [_jsx(ModalOverlay, { backdropFilter: "blur(4px)" }), _jsxs(ModalContent, { borderRadius: "xl", overflow: "hidden", bg: colors.surfaceRaised, children: [_jsx(ModalHeader, { borderBottom: "1px solid", borderColor: raisedRule(colors), fontSize: "1.05rem", fontWeight: 600, children: labels.editModuleTitle }), _jsx(ModalCloseButton, {}), _jsxs(ModalBody, { py: 6, children: [_jsx(Input, { value: name, onChange: (e) => setName(e.target.value), placeholder: labels.moduleNamePlaceholder, "aria-label": labels.moduleNamePlaceholder,
14
15
  // NOTE: [200] is the decorative divider rung — a real control's outline needs 1.4.11's 3:1, from [800].
15
16
  borderColor: colors.boxborder[500], mb: 5 }), _jsxs(HStack, { justifyContent: "flex-end", spacing: 3, children: [_jsx(Button, { label: labels.cancel, onClick: onClose, variant: "outline", colorScheme: "gray", size: "sm" }), _jsx(Button, { label: labels.update, onClick: () => onSubmit(name.trim()), colorScheme: "primary", size: "sm", isLoading: isLoading, isDisabled: !name.trim() })] })] })] })] }));
16
17
  };
@@ -10,6 +10,7 @@ import { useFieldIds } from "../Common/useFieldIds.js";
10
10
  import { readOnlyTriggerSx, resolvePickerAliases } from "./pickerField.js";
11
11
  import CalendarPanel from "./CalendarPanel.js";
12
12
  import { useCustomTheme } from "../../Theme/useCustomTheme.js";
13
+ import { raisedRule } from "../../Theme/tokens/builders/surfaceRaised.js";
13
14
  import { DEFAULT_CONTROL_SIZE } from "../../Theme/tokens/primitives/controlSizes.js";
14
15
  import { getTextInputIconSizePx, getTextInputIconWrapperSx, } from "../Input/textInputIconSize.js";
15
16
  import TimePicker from "./TimePicker.js";
@@ -225,7 +226,7 @@ export const RangeDatePicker = forwardRef(function RangeDatePicker(props, ref) {
225
226
  return;
226
227
  }
227
228
  setTempRangeEnd(setTimeFrom(endTimeBaseDate, t));
228
- }, dateFormat: timePickerFormat, isDisabled: disabled || !tempRangeEnd, size: sizeKey }))] })] })), _jsxs(Box, { display: "flex", justifyContent: "space-between", alignItems: "center", mt: 3, pt: 3, borderTop: "1px solid", borderColor: theme.colors.boxborder[200], children: [_jsx(Button, { size: "sm", variant: "ghost", colorScheme: "gray", onClick: handleClear, children: "Clear" }), _jsx(Button, { size: "sm", variant: "gradient", onClick: requestClose, children: "Apply" })] })] }) }) })] }), _jsx(FieldMessage, { error: error, errorMessage: errorMessage, helperText: helperText, helperId: ids.helperId, errorId: ids.errorId })] }));
229
+ }, dateFormat: timePickerFormat, isDisabled: disabled || !tempRangeEnd, size: sizeKey }))] })] })), _jsxs(Box, { display: "flex", justifyContent: "space-between", alignItems: "center", mt: 3, pt: 3, borderTop: "1px solid", borderColor: raisedRule(theme.colors), children: [_jsx(Button, { size: "sm", variant: "ghost", colorScheme: "gray", onClick: handleClear, children: "Clear" }), _jsx(Button, { size: "sm", variant: "gradient", onClick: requestClose, children: "Apply" })] })] }) }) })] }), _jsx(FieldMessage, { error: error, errorMessage: errorMessage, helperText: helperText, helperId: ids.helperId, errorId: ids.errorId })] }));
229
230
  });
230
231
  RangeDatePicker.displayName = "RangeDatePicker";
231
232
  export default RangeDatePicker;
@@ -5,6 +5,7 @@ import { format, parse, isValid, isSameDay, isBefore, isAfter, addDays, } from "
5
5
  import { CalendarIcon } from "lucide-react";
6
6
  import Button from "../Button/Button.js";
7
7
  import { useCustomTheme } from "../../Theme/useCustomTheme.js";
8
+ import { raisedRule } from "../../Theme/tokens/builders/surfaceRaised.js";
8
9
  import { DEFAULT_CONTROL_SIZE } from "../../Theme/tokens/primitives/controlSizes.js";
9
10
  import { getTextInputIconSizePx, getTextInputIconWrapperSx, } from "../Input/textInputIconSize.js";
10
11
  import { isStringValueProps, } from "./DatePickerProps.js";
@@ -987,7 +988,7 @@ function SingleDatePickerInner(props, ref) {
987
988
  setTempDate(updatedDate);
988
989
  setInputValue(format(updatedDate, resolvedDateFormat));
989
990
  setIsTyping(false);
990
- }, isDisabled: disabled })) })), _jsxs(Box, { display: "flex", justifyContent: "space-between", alignItems: "center", mt: 3, pt: 3, borderTop: "1px solid", borderColor: theme.colors.boxborder[200], children: [_jsx(Button, { size: "sm", variant: "ghost", colorScheme: "gray", onClick: () => {
991
+ }, isDisabled: disabled })) })), _jsxs(Box, { display: "flex", justifyContent: "space-between", alignItems: "center", mt: 3, pt: 3, borderTop: "1px solid", borderColor: raisedRule(theme.colors), children: [_jsx(Button, { size: "sm", variant: "ghost", colorScheme: "gray", onClick: () => {
991
992
  setTempDate(null);
992
993
  requestClose(null);
993
994
  }, children: "Clear" }), _jsx(Button, { size: "sm", variant: "gradient", onClick: () => requestClose(), children: "Apply" })] })] }) }) })] }), _jsx(FieldMessage, { error: error, errorMessage: errorMessage, helperText: helperText, helperId: ids.helperId, errorId: ids.errorId })] }));
@@ -13,6 +13,7 @@ import { TimePickerInput } from "./TimePickerInput.js";
13
13
  import PickerPortal, { usePickerPortal } from "./PickerPortal.js";
14
14
  import { useExclusiveOverlay } from "../../Hooks/useExclusiveOverlay.js";
15
15
  import { useCustomTheme } from "../../Theme/useCustomTheme.js";
16
+ import { raisedRule } from "../../Theme/tokens/builders/surfaceRaised.js";
16
17
  import { DEFAULT_CONTROL_SIZE } from "../../Theme/tokens/primitives/controlSizes.js";
17
18
  const formatToPlaceholder = (formatStr) => formatStr.replace(/h{1,2}/gi, "HH").replace(/m{1,2}/gi, "mm").replace(/a{1,2}/gi, "AM");
18
19
  function TimeOnlyPickerInner(props, ref) {
@@ -99,7 +100,7 @@ function TimeOnlyPickerInner(props, ref) {
99
100
  openPicker();
100
101
  }, error: error, size: sizeKey }) }) }) }), _jsx(PickerPortal, { isMounted: pickerPortal.isMounted, children: _jsx(PopoverContent, { width: "auto", p: 4, ref: popoverRef, boxShadow: "lg", borderRadius: "xl", bg: theme.colors.surfaceRaised, children: _jsxs(PopoverBody, { children: [_jsx(TimePicker, { date: resolvedTempDate, dateFormat: dateFormat, onChange: (updatedDate) => {
101
102
  handleTimePickerChange(updatedDate);
102
- } }), _jsxs(Box, { display: "flex", justifyContent: "space-between", mt: 4, pt: 4, borderTop: "1px solid", borderColor: theme.colors.boxborder[200], children: [_jsx(ChakraButton, { size: "sm", variant: "ghost", onClick: handleClear, children: "Clear" }), _jsx(ChakraButton, { size: "sm", colorScheme: "primary", onClick: handleOk, children: "OK" })] })] }) }) })] }), _jsx(FieldMessage, { error: error, errorMessage: errorMessage, helperText: helperText, helperId: ids.helperId, errorId: ids.errorId })] }));
103
+ } }), _jsxs(Box, { display: "flex", justifyContent: "space-between", mt: 4, pt: 4, borderTop: "1px solid", borderColor: raisedRule(theme.colors), children: [_jsx(ChakraButton, { size: "sm", variant: "ghost", onClick: handleClear, children: "Clear" }), _jsx(ChakraButton, { size: "sm", colorScheme: "primary", onClick: handleOk, children: "OK" })] })] }) }) })] }), _jsx(FieldMessage, { error: error, errorMessage: errorMessage, helperText: helperText, helperId: ids.helperId, errorId: ids.errorId })] }));
103
104
  }
104
105
  export const TimeOnlyPicker = forwardRef(TimeOnlyPickerInner);
105
106
  TimeOnlyPicker.displayName = "TimeOnlyPicker";
@@ -1,3 +1,4 @@
1
+ import { recessOn } from "../../Theme/tokens/builders/planeStep.js";
1
2
  // Ascending precedence — when a day carries several keys, a later one's visual overrides an earlier one's.
2
3
  export const DAY_STATE_KEYS = [
3
4
  "weekly-off",
@@ -9,7 +10,7 @@ export const DAY_STATE_KEYS = [
9
10
  // NOTE: token roles per THEME-CONTRACT.md, not raw rungs — e.g. holiday uses semanticText, never semantic[500].
10
11
  const VISUALS = {
11
12
  "weekly-off": (colors) => ({
12
- cellBg: colors.backgroundColor.muted,
13
+ cellBg: recessOn(colors.backgroundColor.muted, colors.surfaceRaised),
13
14
  color: colors.textMuted,
14
15
  }),
15
16
  holiday: (colors) => ({
@@ -1,6 +1,7 @@
1
1
  import { Fragment as _Fragment, jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
2
2
  import React from "react";
3
3
  import { useCustomTheme } from "../../Theme/useCustomTheme.js";
4
+ import { raisedRule } from "../../Theme/tokens/builders/surfaceRaised.js";
4
5
  import { warnDroppedSlotChildren } from "../Modal/warnDroppedSlotChildren.js";
5
6
  import { Drawer as ChakraDrawer, DrawerBody as ChakraDrawerBody, DrawerFooter as ChakraDrawerFooter, DrawerHeader as ChakraDrawerHeader, DrawerOverlay, DrawerContent, DrawerCloseButton, } from "@chakra-ui/react";
6
7
  export const DrawerHeader = ({ children }) => {
@@ -35,5 +36,5 @@ export default function Drawer({ isOpen, onClose, placement = "right", size = "x
35
36
  const bodySlot = findSlot(children, DrawerBody);
36
37
  const footerSlot = findSlot(children, DrawerFooter);
37
38
  warnDroppedSlotChildren("Drawer", children, [DrawerHeader, DrawerBody, DrawerFooter]);
38
- return (_jsxs(ChakraDrawer, { isOpen: isOpen, placement: placement, onClose: onClose, size: size, variant: (_a = variant !== null && variant !== void 0 ? variant : vaiant) !== null && _a !== void 0 ? _a : "solid", id: id, initialFocusRef: initialFocusRef, finalFocusRef: finalFocusRef, closeOnOverlayClick: closeOnOverlayClick, closeOnEsc: closeOnEsc, children: [_jsx(DrawerOverlay, {}), _jsxs(DrawerContent, { ...contentProps, children: [!hideCloseButton && _jsx(DrawerCloseButton, {}), headerSlot && (_jsx(ChakraDrawerHeader, { borderBottomWidth: "1px", borderColor: colors.boxborder[200], ...headerSlot.props, children: headerSlot })), _jsx(ChakraDrawerBody, { ...((_b = bodySlot === null || bodySlot === void 0 ? void 0 : bodySlot.props) !== null && _b !== void 0 ? _b : {}), children: bodySlot }), footerSlot && (_jsx(ChakraDrawerFooter, { borderTopWidth: "1px", borderColor: colors.boxborder[200], ...footerSlot.props, children: footerSlot })), portalChildren] })] }));
39
+ return (_jsxs(ChakraDrawer, { isOpen: isOpen, placement: placement, onClose: onClose, size: size, variant: (_a = variant !== null && variant !== void 0 ? variant : vaiant) !== null && _a !== void 0 ? _a : "solid", id: id, initialFocusRef: initialFocusRef, finalFocusRef: finalFocusRef, closeOnOverlayClick: closeOnOverlayClick, closeOnEsc: closeOnEsc, children: [_jsx(DrawerOverlay, {}), _jsxs(DrawerContent, { ...contentProps, children: [!hideCloseButton && _jsx(DrawerCloseButton, {}), headerSlot && (_jsx(ChakraDrawerHeader, { borderBottomWidth: "1px", borderColor: raisedRule(colors), ...headerSlot.props, children: headerSlot })), _jsx(ChakraDrawerBody, { ...((_b = bodySlot === null || bodySlot === void 0 ? void 0 : bodySlot.props) !== null && _b !== void 0 ? _b : {}), children: bodySlot }), footerSlot && (_jsx(ChakraDrawerFooter, { borderTopWidth: "1px", borderColor: raisedRule(colors), ...footerSlot.props, children: footerSlot })), portalChildren] })] }));
39
40
  }
@@ -3,6 +3,7 @@ import { forwardRef, useCallback, useEffect, useId, useMemo, useRef, useState }
3
3
  import { Box, Flex, Button, useDisclosure, List, ListItem, Portal, } from "@chakra-ui/react";
4
4
  import { motion, useReducedMotion } from "framer-motion";
5
5
  import { useCustomTheme } from "../../Theme/useCustomTheme.js";
6
+ import { raisedRule } from "../../Theme/tokens/builders/surfaceRaised.js";
6
7
  import { scrollbarStyles } from "../../Theme/tokens/builders/scrollbar.js";
7
8
  import { listRowBackgrounds } from "../../Theme/tokens/builders/rowStates.js";
8
9
  import { useExclusiveOverlay } from "../../Hooks/useExclusiveOverlay.js";
@@ -257,7 +258,7 @@ const Dropdown = forwardRef(({ dropDownButtonStyle, ButtonText, options, handleO
257
258
  color: theme.colors.accentText,
258
259
  boxShadow: `inset 0 0 0 2px ${theme.colors.focusRing.ring}`,
259
260
  }, borderBottom: divider
260
- ? `${BORDER_WIDTHS.hairline} solid ${theme.colors.boxborder[200]}`
261
+ ? `${BORDER_WIDTHS.hairline} solid ${raisedRule(theme.colors)}`
261
262
  : undefined, sx: { "&:last-child": { borderBottom: "none" }, ...reducedMotionSx() }, style: ItemStyle, fontWeight: 500, children: [option.image && (_jsx(Box, { as: option.image, boxSize: s.img, flexShrink: 0, color: theme.colors.textMuted, style: ImageStyle })), _jsx(Box, { as: "span", fontSize: rowSpec.fontSize, isTruncated: true, style: LabelStyle, children: option.label })] }, option.id))) }));
262
263
  };
263
264
  return (_jsxs(Box, { ref: dropdownRef, position: "relative", display: "inline-block", children: [dropDownToggleOption(), isOpen && (_jsx(Portal, { children: _jsx(MotionBox, { ref: setMenuRef, position: "fixed", zIndex: "popover", initial: prefersReducedMotion ? false : { opacity: 0, y: -6 }, animate: { opacity: 1, y: 0 }, exit: { opacity: 0, y: -6 }, style: {
@@ -12,16 +12,23 @@ import { TextLabel } from "../Common/FormLabel.js";
12
12
  import FieldMessage from "../Common/FieldMessage.js";
13
13
  import { useFieldIds } from "../Common/useFieldIds.js";
14
14
  import { FIELD_RADIUS, FIELD_TRANSITION } from "../Common/fieldStyles.js";
15
- import { focusVisibleStyles } from "../../Theme/chakra/focusRing.styles.js";
15
+ import { focusVisibleRing, focusVisibleStyles } from "../../Theme/chakra/focusRing.styles.js";
16
16
  import { BORDER_WIDTHS } from "../../Theme/tokens/primitives/borderWidths.js";
17
17
  const FileThumbnail = ({ file, radius, onPreview, }) => {
18
18
  const url = useObjectUrl(file);
19
- return (_jsxs(Box, { boxSize: "2.5rem", cursor: "pointer", position: "relative", _hover: {
19
+ const { colors } = useCustomTheme();
20
+ const preview = () => url && onPreview(url);
21
+ return (_jsxs(Box, { role: "button", tabIndex: 0, "aria-label": `Preview ${file.name}`, boxSize: "2.5rem", cursor: "pointer", position: "relative", _focusVisible: focusVisibleRing(colors), _hover: {
20
22
  ".hover-icon": {
21
23
  opacity: 1,
22
24
  bg: "blackAlpha.500",
23
25
  },
24
- }, onClick: () => url && onPreview(url), children: [_jsx("img", { src: url, alt: file.name, style: {
26
+ }, onClick: preview, onKeyDown: (event) => {
27
+ if (event.key !== "Enter" && event.key !== " ")
28
+ return;
29
+ event.preventDefault();
30
+ preview();
31
+ }, children: [_jsx("img", { src: url, alt: file.name, style: {
25
32
  width: "100%",
26
33
  height: "100%",
27
34
  objectFit: "cover",