basalt-ui 1.40.2 → 1.41.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (55) hide show
  1. package/AGENTS.md +4 -2
  2. package/CHANGELOG.md +22 -0
  3. package/MIGRATING.md +40 -12
  4. package/README.md +1 -1
  5. package/agent/rules/basalt-batteries.md +1 -1
  6. package/agent/skills/basalt-app/SKILL.md +1 -1
  7. package/agent/skills/basalt-design/SKILL.md +1 -1
  8. package/agent/templates/DESIGN.md.tpl +1 -1
  9. package/configs/check.yml +1 -1
  10. package/configs/oxlint-plugin.js +5 -5
  11. package/configs/oxlint-plugin.test.ts +1 -1
  12. package/dist/agent/foreign.d.ts +3 -2
  13. package/dist/agent/foreign.d.ts.map +1 -1
  14. package/dist/charts/primitives/HoverOverlay.d.ts.map +1 -1
  15. package/dist/charts/primitives/HoverOverlay.js +2 -1
  16. package/dist/cli/doctor.d.ts +5 -2
  17. package/dist/cli/doctor.d.ts.map +1 -1
  18. package/dist/cli/doctor.js +29 -0
  19. package/dist/cli/index.d.ts +61 -4
  20. package/dist/cli/index.d.ts.map +1 -1
  21. package/dist/cli/index.js +112 -6
  22. package/dist/cli/init.d.ts.map +1 -1
  23. package/dist/cli/init.js +10 -0
  24. package/dist/cli/sync.d.ts.map +1 -1
  25. package/dist/cli/sync.js +18 -1
  26. package/dist/commands/shortcut-format.d.ts +9 -4
  27. package/dist/commands/shortcut-format.d.ts.map +1 -1
  28. package/dist/commands/shortcut-format.js +35 -5
  29. package/dist/content/copy-action.d.ts +1 -1
  30. package/dist/content/glyphs.d.ts +1 -1
  31. package/dist/data/virtual-list.d.ts +1 -1
  32. package/dist/theme/index.d.ts.map +1 -1
  33. package/dist/theme/index.js +14 -1
  34. package/dist/theme/segmented-control.module.css +8 -0
  35. package/dist/tokens/derive.d.ts.map +1 -1
  36. package/dist/tokens/derive.js +3 -1
  37. package/dist/tokens.css +1 -1
  38. package/llms.txt +2 -2
  39. package/package.json +1 -1
  40. package/src/agent/foreign.ts +3 -2
  41. package/src/charts/index.ts +2 -2
  42. package/src/charts/primitives/HoverOverlay.tsx +2 -1
  43. package/src/cli/doctor.ts +47 -4
  44. package/src/cli/index.ts +180 -11
  45. package/src/cli/init.ts +14 -0
  46. package/src/cli/sync.ts +24 -1
  47. package/src/commands/shortcut-format.ts +49 -10
  48. package/src/content/copy-action.tsx +1 -1
  49. package/src/content/glyphs.tsx +1 -1
  50. package/src/data/virtual-list.tsx +1 -1
  51. package/src/guard/index.ts +1 -1
  52. package/src/theme/index.ts +17 -1
  53. package/src/theme/segmented-control.module.css +8 -0
  54. package/src/tokens/derive.ts +3 -1
  55. /package/agent/templates/{CLAUDE-block.md.tpl → AGENTS-block.md.tpl} +0 -0
@@ -383,13 +383,20 @@ const basaltVariantColorResolver: VariantColorsResolver = (input) => {
383
383
  : resolved
384
384
  }
385
385
 
386
+ // `outline`: the tone's own text colour, pulled toward ink so the label keeps its hue at AA
387
+ // (grey outline badges measured 3.9:1 on the light page).
388
+ if (input.variant === 'outline') {
389
+ return { ...resolved, color: `color-mix(in srgb, ${resolved.color} 70%, var(--vx-ink))` }
390
+ }
391
+
386
392
  if (input.variant !== 'light') return resolved
387
393
  const ink = `var(--mantine-color-${colorName}-light-color)`
388
394
  return {
389
395
  ...resolved,
390
396
  background: `color-mix(in srgb, ${ink} 13%, transparent)`,
391
397
  hover: `color-mix(in srgb, ${ink} 20%, transparent)`,
392
- color: ink,
398
+ // Same pull toward ink as `outline`: the saturated tone text sat at 3.2–4.4:1 on its own tint.
399
+ color: `color-mix(in srgb, ${ink} 70%, var(--vx-ink))`,
393
400
  border: 'none',
394
401
  }
395
402
  }
@@ -1464,6 +1471,12 @@ function buildCssVariablesResolver(data: PaletteData): CSSVariablesResolver {
1464
1471
  '--mantine-color-default-border': 'transparent',
1465
1472
  '--mantine-color-dimmed': `var(--vx-neutral, ${NEUTRAL.neutral.light})`, // secondary / muted text
1466
1473
  '--mantine-color-text': `var(--vx-ink, ${INK.ink.light})`, // primary body/heading text
1474
+ // Field errors: Mantine's own error red measures 1.98:1 (dark) / 4.37:1 (light). The solid status red
1475
+ // pulled toward ink clears AA on every text surface in both schemes.
1476
+ '--mantine-color-error': 'color-mix(in srgb, var(--vx-bad-solid) 85%, var(--vx-ink))',
1477
+ // Links: Mantine reads the accent FILL shade (4.38:1 on the light page, under WCAG AA); the hover
1478
+ // accent is the next step darker and clears 4.5:1 on every light text surface.
1479
+ '--mantine-color-anchor': 'var(--vx-accent-hover)',
1467
1480
  // `--app-shell-border-color` is set by `components.AppShell.extend({ vars })` above — this
1468
1481
  // entry was dead (an element-level declaration always beats an inherited `:root` value).
1469
1482
  // THE strict-surface lever. Mantine components do NOT chain border/surface colors through
@@ -1492,6 +1505,9 @@ function buildCssVariablesResolver(data: PaletteData): CSSVariablesResolver {
1492
1505
  '--mantine-color-default-border': 'transparent',
1493
1506
  '--mantine-color-dimmed': `var(--vx-neutral, ${NEUTRAL.neutral.dark})`,
1494
1507
  '--mantine-color-text': `var(--vx-ink, ${INK.ink.dark})`,
1508
+ // Field errors: Mantine's own error red measures 1.98:1 (dark) / 4.37:1 (light). The solid status red
1509
+ // pulled toward ink clears AA on every text surface in both schemes.
1510
+ '--mantine-color-error': 'color-mix(in srgb, var(--vx-bad-solid) 85%, var(--vx-ink))',
1495
1511
  // See the light block above — `--app-shell-border-color` is set by `AppShell.extend` now.
1496
1512
  // Dark components read `--mantine-color-dark-4` (border) raw. `buildDarkTuple` already sets
1497
1513
  // dark-4, but to a slightly lighter step than the hairline token, so layout borders read
@@ -13,6 +13,14 @@
13
13
  font-weight: 600;
14
14
  }
15
15
 
16
+ /*
17
+ * Inactive labels read ink2, not Mantine's gray-7 (4.0:1 on the light track): the active segment is
18
+ * told apart by the raised pill and weight 600, so the inactive text can stay at full AA contrast.
19
+ */
20
+ .label:not([data-active], [data-disabled]) {
21
+ color: var(--vx-ink2);
22
+ }
23
+
16
24
  /*
17
25
  * Mantine's own `.control` ships `flex: 1` with no `min-width` override, so its initial value
18
26
  * (`auto`) floors every option at its min-content width — a `fullWidth` track therefore still
@@ -307,7 +307,9 @@ const SURFACE_TONE: Record<Side, Record<SurfaceKey, number>> = {
307
307
  export type InkKey = 'ink' | 'ink2' | 'muted' | 'faint'
308
308
 
309
309
  const INK_TONE: Record<Side, Record<InkKey, number>> = {
310
- light: { ink: 15.16, ink2: 27.09, muted: 34.88, faint: 48.44 },
310
+ // light `faint` is tone 44.5 so tertiary text clears WCAG AA (4.5:1) on every text surface
311
+ // (bg / panel / subtle / field); 48.44 landed at 4.23–4.31:1 on bg and subtle.
312
+ light: { ink: 15.16, ink2: 27.09, muted: 34.88, faint: 44.5 },
311
313
  dark: { ink: 90.94, ink2: 88.12, muted: 84.91, faint: 66.24 },
312
314
  }
313
315