@databricks/design-system 2.0.2 → 2.0.4

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 (81) hide show
  1. package/CHANGELOG.md +37 -0
  2. package/dist/{WizardStepContentWrapper-DnwQIMN1.js → WizardStepContentWrapper-8bs2FwRi.js} +706 -533
  3. package/dist/WizardStepContentWrapper-8bs2FwRi.js.map +1 -0
  4. package/dist/fonts/dm-mono/DMMono-Regular.woff2 +0 -0
  5. package/dist/fonts/dm-mono/dm-mono.css +11 -0
  6. package/dist/index-dark.css +323 -225
  7. package/dist/index-dark.mitigated.css +323 -225
  8. package/dist/index.css +539 -427
  9. package/dist/index.js +259 -159
  10. package/dist/index.js.map +1 -1
  11. package/dist/index.mitigated.css +548 -436
  12. package/dist/patterns.js +3 -2
  13. package/dist/patterns.js.map +1 -1
  14. package/dist/test-utils/rtl.js +1 -1
  15. package/dist/test-utils/rtl.js.map +1 -1
  16. package/dist-types/design-system/Alert/Alert.d.ts +1 -1
  17. package/dist-types/design-system/ContextMenu/ContextMenu.d.ts +2 -2
  18. package/dist-types/design-system/DesignSystemProvider/DesignSystemProvider.d.ts +66 -0
  19. package/dist-types/design-system/DesignSystemProvider/DesignTokenScopeWithEmotionTheme.d.ts +23 -0
  20. package/dist-types/design-system/DesignSystemProvider/index.d.ts +1 -0
  21. package/dist-types/design-system/Grid/Col.d.ts +1 -3
  22. package/dist-types/design-system/Grid/NativeCol.d.ts +10 -0
  23. package/dist-types/design-system/Grid/NativeGridContext.d.ts +11 -0
  24. package/dist-types/design-system/Grid/NativeRow.d.ts +13 -0
  25. package/dist-types/design-system/Grid/Row.d.ts +3 -4
  26. package/dist-types/design-system/Grid/grid-styling.d.ts +22 -0
  27. package/dist-types/design-system/Grid/gridConstants.d.ts +2 -0
  28. package/dist-types/design-system/Grid/index.d.ts +1 -0
  29. package/dist-types/design-system/Grid/rowConstants.d.ts +7 -0
  30. package/dist-types/design-system/Grid/types.d.ts +49 -0
  31. package/dist-types/design-system/Hooks/index.d.ts +1 -1
  32. package/dist-types/design-system/Hooks/useDesignSystemTheme.d.ts +7 -7
  33. package/dist-types/design-system/Icon/LegacyAntDIcon.d.ts +21 -0
  34. package/dist-types/design-system/Icon/index.d.ts +0 -1
  35. package/dist-types/design-system/TypeaheadCombobox/TypeaheadComboboxAddButton.d.ts +4 -0
  36. package/dist-types/design-system/TypeaheadCombobox/TypeaheadComboboxCheckboxItem.d.ts +8 -0
  37. package/dist-types/design-system/TypeaheadCombobox/TypeaheadComboboxFooter.d.ts +12 -0
  38. package/dist-types/design-system/TypeaheadCombobox/TypeaheadComboboxInput.d.ts +8 -0
  39. package/dist-types/design-system/TypeaheadCombobox/TypeaheadComboboxMenu.d.ts +8 -0
  40. package/dist-types/design-system/TypeaheadCombobox/TypeaheadComboboxMenuItem.d.ts +8 -0
  41. package/dist-types/design-system/TypeaheadCombobox/TypeaheadComboboxMultiSelectInput.d.ts +8 -0
  42. package/dist-types/design-system/TypeaheadCombobox/TypeaheadComboboxRoot.d.ts +8 -0
  43. package/dist-types/design-system/TypeaheadCombobox/TypeaheadComboboxSectionHeader.d.ts +4 -0
  44. package/dist-types/design-system/TypeaheadCombobox/TypeaheadComboboxSelectedItem.d.ts +8 -0
  45. package/dist-types/design-system/TypeaheadCombobox/TypeaheadComboboxSeparator.d.ts +4 -0
  46. package/dist-types/design-system/TypeaheadCombobox/TypeaheadComboboxToggleButton.d.ts +8 -0
  47. package/dist-types/design-system/TypeaheadCombobox/hooks/downshiftHookWrappers.d.ts +8 -0
  48. package/dist-types/design-system/{TypeaheadComboboxReactAria → TypeaheadComboboxV2}/hooks/useComboboxState.d.ts +6 -0
  49. package/dist-types/design-system/TypeaheadComboboxV2/hooks/useRestoreHighlightedOption.d.ts +18 -0
  50. package/dist-types/design-system/TypeaheadComboboxV2/hooks/useTypeaheadComboboxContext.d.ts +2 -0
  51. package/dist-types/design-system/{TypeaheadComboboxReactAria → TypeaheadComboboxV2}/providers/TypeaheadComboboxContext.d.ts +6 -4
  52. package/dist-types/design-system/_shared_/Menu/index.d.ts +1 -1
  53. package/dist-types/design-system/fonts.d.ts +1 -0
  54. package/dist-types/design-system/index.d.ts +1 -1
  55. package/dist-types/test-utils/rtl/buttonVariants.d.ts +11 -0
  56. package/package.json +9 -2
  57. package/dist/WizardStepContentWrapper-DnwQIMN1.js.map +0 -1
  58. package/dist-types/design-system/Icon/AntdIcon.d.ts +0 -114
  59. package/dist-types/design-system/TypeaheadComboboxReactAria/hooks/useTypeaheadComboboxContext.d.ts +0 -2
  60. /package/dist-types/design-system/{TypeaheadComboboxReactAria → TypeaheadComboboxV2}/CountBadge.d.ts +0 -0
  61. /package/dist-types/design-system/{TypeaheadComboboxReactAria → TypeaheadComboboxV2}/TypeaheadComboboxAddButton.d.ts +0 -0
  62. /package/dist-types/design-system/{TypeaheadComboboxReactAria → TypeaheadComboboxV2}/TypeaheadComboboxCheckboxItem.d.ts +0 -0
  63. /package/dist-types/design-system/{TypeaheadComboboxReactAria → TypeaheadComboboxV2}/TypeaheadComboboxControls.d.ts +0 -0
  64. /package/dist-types/design-system/{TypeaheadComboboxReactAria → TypeaheadComboboxV2}/TypeaheadComboboxFooter.d.ts +0 -0
  65. /package/dist-types/design-system/{TypeaheadComboboxReactAria → TypeaheadComboboxV2}/TypeaheadComboboxInput.d.ts +0 -0
  66. /package/dist-types/design-system/{TypeaheadComboboxReactAria → TypeaheadComboboxV2}/TypeaheadComboboxMenu.d.ts +0 -0
  67. /package/dist-types/design-system/{TypeaheadComboboxReactAria → TypeaheadComboboxV2}/TypeaheadComboboxMenuItem.d.ts +0 -0
  68. /package/dist-types/design-system/{TypeaheadComboboxReactAria → TypeaheadComboboxV2}/TypeaheadComboboxMultiSelectInput.d.ts +0 -0
  69. /package/dist-types/design-system/{TypeaheadComboboxReactAria → TypeaheadComboboxV2}/TypeaheadComboboxRoot.d.ts +0 -0
  70. /package/dist-types/design-system/{TypeaheadComboboxReactAria → TypeaheadComboboxV2}/TypeaheadComboboxSectionHeader.d.ts +0 -0
  71. /package/dist-types/design-system/{TypeaheadComboboxReactAria → TypeaheadComboboxV2}/TypeaheadComboboxSelectedItem.d.ts +0 -0
  72. /package/dist-types/design-system/{TypeaheadComboboxReactAria → TypeaheadComboboxV2}/TypeaheadComboboxSeparator.d.ts +0 -0
  73. /package/dist-types/design-system/{TypeaheadComboboxReactAria → TypeaheadComboboxV2}/TypeaheadComboboxToggleButton.d.ts +0 -0
  74. /package/dist-types/design-system/{TypeaheadComboboxReactAria → TypeaheadComboboxV2}/hooks/footerFocus.d.ts +0 -0
  75. /package/dist-types/design-system/{TypeaheadComboboxReactAria → TypeaheadComboboxV2}/hooks/index.d.ts +0 -0
  76. /package/dist-types/design-system/{TypeaheadComboboxReactAria → TypeaheadComboboxV2}/hooks/useComboboxItems.d.ts +0 -0
  77. /package/dist-types/design-system/{TypeaheadComboboxReactAria → TypeaheadComboboxV2}/hooks/useComboboxStateProps.d.ts +0 -0
  78. /package/dist-types/design-system/{TypeaheadComboboxReactAria → TypeaheadComboboxV2}/hooks/useMultipleSelectionState.d.ts +0 -0
  79. /package/dist-types/design-system/{TypeaheadComboboxReactAria → TypeaheadComboboxV2}/hooks/useScrollOptionIntoView.d.ts +0 -0
  80. /package/dist-types/design-system/{TypeaheadComboboxReactAria → TypeaheadComboboxV2}/hooks/useVirtualizedComboboxScroll.d.ts +0 -0
  81. /package/dist-types/design-system/{TypeaheadComboboxReactAria → TypeaheadComboboxV2}/index.d.ts +0 -0
@@ -15662,7 +15662,7 @@ span.du-bois-light-typography-ellipsis-single-line {
15662
15662
  * Source: design-system/src/theme/tokens/*.json
15663
15663
  * Regenerate via: yarn theme-regenerate */
15664
15664
 
15665
- :where(:root, .du-bois-light) {
15665
+ :where(:root), :where(.du-bois-light) {
15666
15666
  --db-radius-0: 0px;
15667
15667
  --db-radius-full: 999px;
15668
15668
  --db-radius-lg: 12px;
@@ -15801,142 +15801,273 @@ span.du-bois-light-typography-ellipsis-single-line {
15801
15801
  * Source: design-system/src/theme/tokens/*.json
15802
15802
  * Regenerate via: yarn theme-regenerate */
15803
15803
 
15804
- /* Layout primitive classes — internal Du Bois use for now (not a published
15805
- * consumer API yet; see the Stefan/Sheng weekly decision to "give it a try
15806
- * just within the Du Bois components"). Two primitives, both plain CSS so they
15807
- * ride the mortar cascade like the other component styles:
15808
- *
15809
- * .ds-stack — vertical flow, even gap between direct children.
15810
- * .ds-cluster — horizontal group that wraps, even gap between children.
15811
- *
15812
- * Each primitive exposes a small set of `--ds-*` knobs, defaulted on the class
15813
- * itself (not via a `var()` fallback, which would freeze the default at every
15814
- * call site). Override any of them on the element — inline
15815
- * `style={{ '--ds-stack-gap': ... }}` or a more specific selector — without a
15816
- * new modifier class:
15817
- *
15818
- * stack: --ds-stack-gap (spacing), --ds-stack-align (align-items)
15819
- * cluster: --ds-cluster-gap (spacing), --ds-cluster-align (align-items),
15820
- * --ds-cluster-justify (justify-content)
15821
- *
15822
- * Gap defaults point at the system spacing scale (`--db-space-*`). Padding is
15823
- * intentionally NOT a knob — a layout primitive owns the space between children,
15824
- * not its own box padding. */
15804
+ /*
15805
+ Vertical "stack" of elements.
15806
+ Use this for any layout where items are laid out vertically.
15807
+
15808
+ \3c !-- Basic: default gap between each child -->
15809
+ <div class="db-stack">
15810
+ <h2>Title</h2>
15811
+ <p>Body</p>
15812
+ <button>Action</button>
15813
+ </div>
15814
+
15815
+ \3c !-- Wider gap for this instance -->
15816
+ <div class="db-stack" style="--db-stack-gap: var(--db-spacing-lg)">…</div>
15817
+
15818
+ \3c !-- Don't stretch children to full width (e.g. left-aligned buttons) -->
15819
+ <div class="db-stack" style="--db-stack-align: flex-start">…</div>
15820
+ */
15821
+ .db-stack {
15822
+ /* These variables act as the *parameters* for the stack instance. */
15823
+ --db-stack-gap: var(--db-spacing-xs);
15824
+ --db-stack-align: stretch;
15825
15825
 
15826
- .ds-stack {
15827
- --ds-stack-gap: var(--db-space-md);
15828
- --ds-stack-align: stretch;
15829
15826
  display: flex;
15830
15827
  flex-direction: column;
15831
- align-items: var(--ds-stack-align);
15832
- gap: var(--ds-stack-gap);
15828
+ align-items: var(--db-stack-align);
15829
+ gap: var(--db-stack-gap);
15833
15830
  }
15834
15831
 
15835
- /* Cluster wraps by design: a long row reflows onto multiple lines rather than
15836
- * overflowing. A row that must NOT wrap (e.g. a single-line control strip) is
15837
- * not a cluster keep it bespoke. */
15838
- .ds-cluster {
15839
- --ds-cluster-gap: var(--db-space-sm);
15840
- --ds-cluster-align: center;
15841
- --ds-cluster-justify: flex-start;
15832
+ /**
15833
+ Responsive, horizontal "cluster" of elements.
15834
+ Use this for any layout where items are laid out horizontally and should wrap on smaller viewport sizes.
15835
+
15836
+ \3c !-- Basic: items wrap as needed -->
15837
+ <div class="db-cluster">
15838
+ <span>one</span>
15839
+ <span>two</span>
15840
+ <span>three</span>
15841
+ </div>
15842
+
15843
+ \3c !-- Push children apart (e.g. title left, actions right) -->
15844
+ <div class="db-cluster" style="--db-cluster-justify: space-between">…</div>
15845
+
15846
+ \3c !-- Looser gap for this instance -->
15847
+ <div class="db-cluster" style="--db-cluster-gap: var(--db-spacing-sm)">…</div>
15848
+ */
15849
+ .db-cluster {
15850
+ /* These variables act as the *parameters* for the cluster instance. */
15851
+ --db-cluster-gap: var(--db-spacing-2xs);
15852
+ --db-cluster-align: center;
15853
+ --db-cluster-justify: flex-start;
15854
+
15842
15855
  display: flex;
15843
15856
  flex-wrap: wrap;
15844
- align-items: var(--ds-cluster-align);
15845
- justify-content: var(--ds-cluster-justify);
15846
- gap: var(--ds-cluster-gap);
15857
+ align-items: var(--db-cluster-align);
15858
+ justify-content: var(--db-cluster-justify);
15859
+ gap: var(--db-cluster-gap);
15847
15860
  }
15848
15861
 
15849
- /* Category-tier tokens shared by selection-control components:
15850
- * <Checkbox>, <Switch>, <Radio>. Each value here references a SYSTEM token
15851
- * from system-tokens.css — never a raw hex/px literal — so the only place a
15852
- * brand-level theme change has to land is the system tier.
15853
- *
15854
- * Component-tier files (e.g. design-system/Checkbox/tokens.css) inherit from
15855
- * these via `var()` so consumers can override a single selection control by
15856
- * targeting only its component tokens. */
15857
-
15858
- /* Re-declared under both theme classes as well as :root: these values are
15859
- * `var()` indirections onto SYSTEM tokens, and a custom property resolves its
15860
- * var() at its DECLARATION site. Declared only at :root, they would freeze at
15861
- * the root (light) system values and never re-read the dark system tokens
15862
- * inside a `.du-bois-dark` subtree. Re-declaring at every theme boundary makes
15863
- * the indirection re-resolve per theme. See DUBOIS-448 dark-mode scoping. */
15864
- :where(:root, .du-bois-light, .du-bois-dark) {
15865
- --db-selection-toggle-bg-default: var(--db-color-background-primary);
15866
- --db-selection-toggle-bg-hover: var(--db-color-action-default-background-hover);
15867
- --db-selection-toggle-bg-press: var(--db-color-action-default-background-press);
15868
- --db-selection-toggle-bg-checked: var(--db-color-action-primary-background-default);
15869
- --db-selection-toggle-bg-checked-hover: var(--db-color-action-primary-background-hover);
15870
- --db-selection-toggle-bg-checked-press: var(--db-color-action-primary-background-press);
15871
- --db-selection-toggle-bg-disabled: var(--db-color-action-disabled-background);
15872
-
15873
- --db-selection-toggle-border-default: var(--db-color-action-default-border-default);
15874
- --db-selection-toggle-border-hover: var(--db-color-action-primary-background-hover);
15875
- --db-selection-toggle-border-press: var(--db-color-action-primary-background-press);
15876
- --db-selection-toggle-border-focus: var(--db-color-action-default-border-focus);
15877
- --db-selection-toggle-border-disabled: var(--db-color-action-disabled-border);
15878
-
15879
- /* Raw literal, not a system token (exception to the file rule above): the mark
15880
- * sits on the theme-invariant blue checked fill, so it must stay white in BOTH
15881
- * themes. No non-flipping white system token exists — action-primary-icon flips
15882
- * to near-black under .du-bois-dark, which made the mark nearly invisible. */
15883
- --db-selection-toggle-icon-color: #ffffff;
15884
- --db-selection-toggle-icon-color-disabled: var(--db-color-action-disabled-text);
15885
- --db-selection-toggle-text: var(--db-color-text-primary);
15886
- --db-selection-toggle-text-disabled: var(--db-color-action-disabled-text);
15887
-
15888
- --db-selection-toggle-size: 16px;
15889
- --db-selection-toggle-border-radius: var(--db-radius-sm);
15890
- --db-selection-toggle-spacing: var(--db-space-sm);
15891
-
15892
- /* Focus ring matches AntD legacy variant; offset keeps it outside the toggle.
15893
- * Hard-coded for now — Figma export doesn't include shadow tokens. */
15862
+ :where(:root), :where(.du-bois-light) {
15863
+ /* Neutral */
15864
+ --db-neutral-surface: var(--db-color-background-primary);
15865
+ --db-subtle-neutral-surface: var(--db-color-background-secondary);
15866
+ --db-strong-neutral-surface: initial; /* TODO */
15867
+
15868
+ --db-text-on-neutral-surface: var(--db-color-text-primary);
15869
+ --db-subtle-text-on-neutral-surface: var(--db-color-text-secondary);
15870
+ --db-strong-text-on-neutral-surface: initial; /* TODO */
15871
+
15872
+ --db-neutral-border: var(--db-color-border);
15873
+ --db-subtle-neutral-border: initial; /* TODO */
15874
+ --db-strong-neutral-border: var(--db-color-border-accessible);
15875
+
15876
+ --db-neutral-surface-active: var(--db-color-table-background-selected-default);
15877
+ --db-neutral-surface-hover: var(--db-color-table-background-unselected-hover);
15878
+ --db-neutral-surface-pressed: var(--db-color-table-background-selected-hover);
15879
+ --db-neutral-surface-disabled: var(--db-color-action-disabled-background);
15880
+ --db-text-on-neutral-surface-disabled: var(--db-color-action-disabled-text);
15881
+
15882
+ /* Primary */
15883
+ --db-primary-surface: var(--db-color-action-primary-background-default);
15884
+ --db-subtle-primary-surface: var(--db-color-action-default-background-hover);
15885
+ --db-strong-primary-surface: var(--db-color-action-primary-background-hover);
15886
+
15887
+ --db-text-on-primary-surface: var(--db-color-action-primary-text-default);
15888
+ --db-primary-text-on-neutral-surface: var(--db-color-action-link-default);
15889
+ --db-subtle-text-on-primary-surface: initial; /* TODO */
15890
+ --db-strong-text-on-primary-surface: var(--db-color-action-primary-text-default);
15891
+
15892
+ --db-primary-border: var(--db-color-action-primary-background-default);
15893
+ --db-subtle-primary-border: initial; /* TODO */
15894
+ --db-strong-primary-border: var(--db-color-action-primary-background-press);
15895
+
15896
+ --db-primary-surface-active: initial; /* TODO */
15897
+ --db-primary-surface-hover: var(--db-color-action-primary-background-hover);
15898
+ --db-primary-surface-pressed: var(--db-color-action-primary-background-press);
15899
+ --db-primary-surface-disabled: var(--db-color-action-disabled-background);
15900
+ --db-text-on-primary-surface-disabled: var(--db-color-action-disabled-text);
15901
+
15902
+ /* Error */
15903
+ --db-error-surface: var(--db-color-action-danger-primary-background-default);
15904
+ --db-subtle-error-surface: var(--db-color-background-danger);
15905
+ --db-strong-error-surface: var(--db-color-action-danger-primary-background-hover);
15906
+
15907
+ --db-text-on-error-surface: var(--db-color-action-danger-primary-text);
15908
+ --db-error-text-on-neutral-surface: var(--db-color-text-validation-danger);
15909
+ --db-subtle-text-on-error-surface: initial; /* TODO */
15910
+ --db-strong-text-on-error-surface: var(--db-color-action-danger-primary-text);
15911
+
15912
+ --db-error-border: var(--db-color-action-danger-default-border-default);
15913
+ --db-subtle-error-border: var(--db-color-border-danger);
15914
+ --db-strong-error-border: var(--db-color-action-danger-primary-background-press);
15915
+
15916
+ --db-error-surface-active: initial; /* TODO */
15917
+ --db-error-surface-hover: var(--db-color-action-danger-primary-background-hover);
15918
+ --db-error-surface-pressed: var(--db-color-action-danger-primary-background-press);
15919
+ --db-error-surface-disabled: var(--db-color-action-disabled-background);
15920
+ --db-text-on-error-surface-disabled: var(--db-color-action-disabled-text);
15921
+
15922
+ /* Warning */
15923
+ --db-warning-surface: initial; /* TODO */
15924
+ --db-subtle-warning-surface: var(--db-color-background-warning);
15925
+
15926
+ --db-text-on-warning-surface: initial; /* TODO */
15927
+ --db-warning-text-on-neutral-surface: var(--db-color-text-validation-warning);
15928
+
15929
+ --db-warning-border: var(--db-color-border-warning);
15930
+
15931
+ /* Success */
15932
+ --db-success-surface: initial; /* TODO */
15933
+ --db-subtle-success-surface: var(--db-color-background-success);
15934
+
15935
+ --db-text-on-success-surface: initial; /* TODO */
15936
+ --db-success-text-on-neutral-surface: var(--db-color-text-validation-success);
15937
+
15938
+ --db-success-border: initial; /* TODO */
15939
+ }
15940
+
15941
+
15942
+
15943
+ :where(:root), :where(.du-bois-light) {
15944
+ --db-layout-unit: 0.25rem; /* 4px */
15945
+ --db-density-scalar: 1;
15946
+ --db-size-scalar: 1;
15947
+ --db-spacing-scalar: 1;
15948
+
15949
+ /* Size and spacing are the same steps, but with their own scalars included in the calc. */
15950
+
15951
+ --db-size-3xs: calc(var(--db-layout-unit) * 1 * var(--db-density-scalar) * var(--db-size-scalar)); /* 4px */
15952
+ --db-size-2xs: calc(var(--db-layout-unit) * 2 * var(--db-density-scalar) * var(--db-size-scalar)); /* 8px */
15953
+ --db-size-xs: calc(var(--db-layout-unit) * 4 * var(--db-density-scalar) * var(--db-size-scalar)); /* 16px */
15954
+ --db-size-sm: calc(var(--db-layout-unit) * 6 * var(--db-density-scalar) * var(--db-size-scalar)); /* 24px */
15955
+ --db-size-md: calc(var(--db-layout-unit) * 8 * var(--db-density-scalar) * var(--db-size-scalar)); /* 32px */
15956
+ --db-size-lg: calc(var(--db-layout-unit) * 10 * var(--db-density-scalar) * var(--db-size-scalar)); /* 40px */
15957
+
15958
+ --db-spacing-3xs: calc(var(--db-layout-unit) * 1 * var(--db-density-scalar) * var(--db-spacing-scalar)); /* 4px */
15959
+ --db-spacing-2xs: calc(var(--db-layout-unit) * 2 * var(--db-density-scalar) * var(--db-spacing-scalar)); /* 8px */
15960
+ --db-spacing-xs: calc(var(--db-layout-unit) * 4 * var(--db-density-scalar) * var(--db-spacing-scalar)); /* 16px */
15961
+ --db-spacing-sm: calc(var(--db-layout-unit) * 6 * var(--db-density-scalar) * var(--db-spacing-scalar)); /* 24px */
15962
+ --db-spacing-md: calc(var(--db-layout-unit) * 8 * var(--db-density-scalar) * var(--db-spacing-scalar)); /* 32px */
15963
+ --db-spacing-lg: calc(var(--db-layout-unit) * 10 * var(--db-density-scalar) * var(--db-spacing-scalar)); /* 40px */
15964
+ }
15965
+
15966
+ :where(:root), :where(.du-bois-light) {
15967
+ --db-font-family:
15968
+ "DM Sans", -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, sans-serif;
15969
+ --db-mono-font-family: ui-monospace, SFMono-Regular, Menlo, monospace;
15970
+
15971
+ --db-font-size-2xs: 0.6875rem; /* 11px */
15972
+ --db-font-size-xs: 0.75rem; /* 12px */
15973
+ --db-font-size-base: 0.8125rem; /* 13px */
15974
+ --db-font-size-md: 0.875rem; /* 14px */
15975
+ --db-font-size-lg: 0.9375rem; /* 15px */
15976
+ --db-font-size-xl: 1rem; /* 16px */
15977
+ --db-font-size-2xl: 1.25rem; /* 20px */
15978
+ --db-font-size-3xl: 1.5rem; /* 24px */
15979
+ --db-font-size-4xl: 2rem; /* 32px */
15980
+
15981
+ /* Du Bois v1 ships 400 and 600 only */
15982
+ --db-font-weight-normal: 400;
15983
+ --db-font-weight-medium: initial; /* TODO */
15984
+ --db-font-weight-semibold: 600;
15985
+ --db-font-weight-bold: initial; /* TODO */
15986
+ }
15987
+
15988
+ :where(:root), :where(.du-bois-light) {
15989
+ --db-elevation-inset: initial; /* TODO */
15990
+ --db-elevation-low: 0px 2px 3px -1px rgba(0, 0, 0, 0.05), 0px 1px 0px 0px rgba(0, 0, 0, 0.02);
15991
+ --db-elevation-med: 0px 2px 16px 0px rgba(0, 0, 0, 0.08);
15992
+ --db-elevation-high: 0px 8px 40px 0px rgba(0, 0, 0, 0.13);
15993
+ }
15994
+
15995
+ :where(:root), :where(.du-bois-light) {
15996
+ --db-focus-ring-color: var(--db-color-action-default-border-focus);
15997
+ --db-focus-ring-width: 2px;
15998
+ }
15999
+
16000
+ :where(:root), :where(.du-bois-light) {
16001
+ /* Shape */
16002
+ --db-selection-toggle-border-radius: 4px;
16003
+
16004
+ /* Color */
16005
+ --db-selection-toggle-surface: var(--db-neutral-surface);
16006
+ --db-selection-toggle-mark: var(--db-text-on-primary-surface);
16007
+ --db-selection-toggle-text: var(--db-text-on-neutral-surface);
16008
+ --db-selection-toggle-border: var(--db-strong-neutral-border);
16009
+
16010
+ --db-selection-toggle-surface-hover: var(--db-neutral-surface-hover);
16011
+ --db-selection-toggle-surface-press: var(--db-neutral-surface-pressed);
16012
+ --db-selection-toggle-surface-checked: var(--db-primary-surface);
16013
+ --db-selection-toggle-surface-checked-hover: var(--db-primary-surface-hover);
16014
+ --db-selection-toggle-surface-checked-press: var(--db-primary-surface-pressed);
16015
+ --db-selection-toggle-surface-disabled: var(--db-neutral-surface-disabled);
16016
+ --db-selection-toggle-surface-checked-disabled: var(--db-neutral-surface-disabled);
16017
+
16018
+ --db-selection-toggle-border-hover: var(--db-primary-surface-hover);
16019
+ --db-selection-toggle-border-press: var(--db-primary-surface-pressed);
16020
+ --db-selection-toggle-border-disabled: var(--db-neutral-border);
16021
+
16022
+ --db-selection-toggle-mark-disabled: var(--db-text-on-neutral-surface-disabled);
16023
+ --db-selection-toggle-text-disabled: var(--db-text-on-neutral-surface-disabled);
16024
+
15894
16025
  --db-selection-toggle-shadow-checked: 0 0 0 1px var(--db-color-action-primary-background-default);
15895
- --db-selection-toggle-focus-ring-width: 2px;
15896
- --db-selection-toggle-focus-ring-offset: 2px;
16026
+
16027
+ /* Density */
16028
+ --db-selection-toggle-size: var(--db-size-xs);
16029
+ --db-selection-toggle-label-spacing: var(--db-spacing-2xs);
16030
+
16031
+ /* Motion */
15897
16032
  --db-selection-toggle-transition-duration: 120ms;
15898
16033
  }
15899
16034
 
15900
- /* Component-tier tokens for <Checkbox>. Each value defaults to a CATEGORY
15901
- * (selection-toggle) token via var(); consumers can override here to retheme
15902
- * checkboxes without affecting switch / radio. */
15903
-
15904
- /* Re-declared under both theme classes (not just :root) so the var() chain onto
15905
- * category/system tokens re-resolves inside a `.du-bois-dark` subtree instead of
15906
- * freezing at the root (light) values. See DUBOIS-448 dark-mode scoping. */
15907
- :where(:root, .du-bois-light, .du-bois-dark) {
15908
- --db-checkbox-size: var(--db-selection-toggle-size);
16035
+ :where(:root), :where(.du-bois-light) {
16036
+ /* Shape */
15909
16037
  --db-checkbox-border-radius: var(--db-selection-toggle-border-radius);
15910
16038
  --db-checkbox-border-width: 1px;
15911
- --db-checkbox-spacing: var(--db-selection-toggle-spacing);
15912
16039
 
15913
- --db-checkbox-bg-default: var(--db-selection-toggle-bg-default);
15914
- --db-checkbox-bg-hover: var(--db-selection-toggle-bg-hover);
15915
- --db-checkbox-bg-press: var(--db-selection-toggle-bg-press);
15916
- --db-checkbox-bg-checked: var(--db-selection-toggle-bg-checked);
15917
- --db-checkbox-bg-checked-hover: var(--db-selection-toggle-bg-checked-hover);
15918
- --db-checkbox-bg-checked-press: var(--db-selection-toggle-bg-checked-press);
15919
- --db-checkbox-bg-disabled: var(--db-selection-toggle-bg-disabled);
16040
+ /* Color */
16041
+ --db-checkbox-surface: var(--db-selection-toggle-surface);
16042
+ --db-checkbox-surface-hover: var(--db-color-action-default-background-hover);
16043
+ --db-checkbox-surface-press: var(--db-color-action-default-background-press);
16044
+ --db-checkbox-surface-checked: var(--db-selection-toggle-surface-checked);
16045
+ --db-checkbox-surface-checked-hover: var(--db-selection-toggle-surface-checked-hover);
16046
+ --db-checkbox-surface-checked-press: var(--db-selection-toggle-surface-checked-press);
16047
+ --db-checkbox-surface-disabled: var(--db-selection-toggle-surface-disabled);
15920
16048
 
15921
- --db-checkbox-border-default: var(--db-selection-toggle-border-default);
16049
+ --db-checkbox-border: var(--db-color-action-default-border-default);
15922
16050
  --db-checkbox-border-hover: var(--db-selection-toggle-border-hover);
15923
16051
  --db-checkbox-border-press: var(--db-selection-toggle-border-press);
15924
- --db-checkbox-border-focus: var(--db-selection-toggle-border-focus);
15925
- --db-checkbox-border-disabled: var(--db-selection-toggle-border-disabled);
16052
+ --db-checkbox-focus-ring: var(--db-focus-ring-color);
16053
+ --db-checkbox-border-disabled: var(--db-color-action-disabled-border);
15926
16054
 
15927
- --db-checkbox-icon-color: var(--db-selection-toggle-icon-color);
15928
- --db-checkbox-icon-color-disabled: var(--db-selection-toggle-icon-color-disabled);
16055
+ --db-checkbox-mark: #ffffff;
16056
+ --db-checkbox-mark-disabled: var(--db-selection-toggle-mark-disabled);
15929
16057
  --db-checkbox-text: var(--db-selection-toggle-text);
15930
16058
  --db-checkbox-text-disabled: var(--db-selection-toggle-text-disabled);
15931
16059
 
15932
16060
  --db-checkbox-shadow-checked: var(--db-selection-toggle-shadow-checked);
15933
- --db-checkbox-focus-ring-width: var(--db-selection-toggle-focus-ring-width);
15934
- --db-checkbox-focus-ring-offset: var(--db-selection-toggle-focus-ring-offset);
15935
- --db-checkbox-transition-duration: var(--db-selection-toggle-transition-duration);
15936
16061
 
15937
- /* Indeterminate mark — the horizontal dash shown in the mixed state. */
15938
- --db-checkbox-indeterminate-mark-width: 8px;
15939
- --db-checkbox-indeterminate-mark-height: 3px;
16062
+ /* Density */
16063
+ --db-checkbox-size: var(--db-selection-toggle-size);
16064
+ --db-checkbox-label-spacing: var(--db-selection-toggle-label-spacing);
16065
+ --db-checkbox-focus-ring-width: var(--db-focus-ring-width);
16066
+ --db-checkbox-indeterminate-mark-width: var(--db-size-2xs); /* 8px */
16067
+ --db-checkbox-indeterminate-mark-height: calc(var(--db-size-3xs) * 0.75); /* 3px */
16068
+
16069
+ /* Motion */
16070
+ --db-checkbox-transition-duration: var(--db-selection-toggle-transition-duration);
15940
16071
  }
15941
16072
 
15942
16073
  /* Native-input <Checkbox> styles. Classic CSS only — no native nesting (the
@@ -15947,21 +16078,21 @@ span.du-bois-light-typography-ellipsis-single-line {
15947
16078
  *
15948
16079
  * Structure (assumed by the React component):
15949
16080
  *
15950
- * <label class="ds-checkbox">
15951
- * <input type="checkbox" class="ds-checkbox-input" />
15952
- * <span class="ds-checkbox-indicator"> ← border + fill react to state
15953
- * <svg class="ds-checkbox-checkmark" .../> ← visible when :checked
15954
- * <span class="ds-checkbox-dash" /> ← visible when :indeterminate
16081
+ * <label class="db-checkbox">
16082
+ * <input type="checkbox" class="db-checkbox-input" />
16083
+ * <span class="db-checkbox-indicator"> ← border + fill react to state
16084
+ * <svg class="db-checkbox-checkmark" .../> ← visible when :checked
16085
+ * <span class="db-checkbox-dash" /> ← visible when :indeterminate
15955
16086
  * </span>
15956
- * <span class="ds-checkbox-label">{children}</span>
16087
+ * <span class="db-checkbox-label">{children}</span>
15957
16088
  * </label>
15958
16089
  *
15959
- * State and hiding rules target `.ds-checkbox-input` — the checkbox's OWN input —
16090
+ * State and hiding rules target `.db-checkbox-input` — the checkbox's OWN input —
15960
16091
  * never a bare `input`: consumers may render an inline <input> (e.g. a number
15961
16092
  * field) inside the label children, and a descendant `input` selector would hide
15962
16093
  * / absolutely-position that field and mis-drive the `:has(…)` state rules. */
15963
16094
 
15964
- .ds-checkbox {
16095
+ .db-checkbox {
15965
16096
  /* `display: flex` (block-level), NOT `inline-flex`: an inline-flex root puts
15966
16097
  * the label inside an inline-line-box whose leading pushes block-level siblings
15967
16098
  * (e.g. `<FormMessage>`) down by a few pixels — making validation messages sit
@@ -15977,110 +16108,121 @@ span.du-bois-light-typography-ellipsis-single-line {
15977
16108
  user-select: none;
15978
16109
  /* No `gap` here — spacing between indicator and label, plus the trailing
15979
16110
  * whitespace that gives sibling checkboxes their visual separation, lives
15980
- * on `.ds-checkbox-label` as padding-inline. Matches AntD's `.{prefix}-checkbox + span`
16111
+ * on `.db-checkbox-label` as padding-inline. Matches AntD's `.{prefix}-checkbox + span`
15981
16112
  * rule and the prior Emotion-based NativeCheckbox implementation. */
15982
16113
  min-height: var(--db-line-height-base, 20px);
15983
16114
  width: fit-content;
15984
16115
  }
15985
16116
 
15986
- /* Hover/press live on the root (label), not on the input: the input has
15987
- * `pointer-events: none` (so a single click target stays on the label and
15988
- * label/input association toggles the box), which means `input:hover` would
15989
- * never match. Putting `:hover` on the root also makes the entire label area
16117
+ /* Hover/press live on the root (label), not on the input: the input is
16118
+ * visually hidden (opacity:0), so an `input:hover` rule wouldn't be visible
16119
+ * anyway. Putting `:hover` on the root also makes the entire label area
15990
16120
  * — not just the indicator square — drive the visual feedback. */
15991
- .ds-checkbox:hover:has(.ds-checkbox-input:not(:disabled, :checked, :indeterminate)) .ds-checkbox-indicator {
15992
- background-color: var(--db-checkbox-bg-hover);
16121
+ .db-checkbox:hover:has(.db-checkbox-input:not(:disabled, :checked, :indeterminate)) .db-checkbox-indicator {
16122
+ background-color: var(--db-checkbox-surface-hover);
15993
16123
  border-color: var(--db-checkbox-border-hover);
15994
16124
  }
15995
16125
 
15996
- .ds-checkbox:active:has(.ds-checkbox-input:not(:disabled, :checked, :indeterminate)) .ds-checkbox-indicator {
15997
- background-color: var(--db-checkbox-bg-press);
16126
+ .db-checkbox:active:has(.db-checkbox-input:not(:disabled, :checked, :indeterminate)) .db-checkbox-indicator {
16127
+ background-color: var(--db-checkbox-surface-press);
15998
16128
  border-color: var(--db-checkbox-border-press);
15999
16129
  }
16000
16130
 
16001
16131
  /* Selected fill — checked and indeterminate share the same surface. */
16002
- .ds-checkbox:has(.ds-checkbox-input:is(:checked, :indeterminate)) .ds-checkbox-indicator {
16003
- background-color: var(--db-checkbox-bg-checked);
16004
- border-color: var(--db-checkbox-bg-checked);
16132
+ .db-checkbox:has(.db-checkbox-input:is(:checked, :indeterminate)) .db-checkbox-indicator {
16133
+ background-color: var(--db-checkbox-surface-checked);
16134
+ border-color: var(--db-checkbox-surface-checked);
16005
16135
  }
16006
16136
 
16007
- .ds-checkbox:hover:has(.ds-checkbox-input:is(:checked, :indeterminate):not(:disabled)) .ds-checkbox-indicator {
16008
- background-color: var(--db-checkbox-bg-checked-hover);
16009
- border-color: var(--db-checkbox-bg-checked-hover);
16137
+ .db-checkbox:hover:has(.db-checkbox-input:is(:checked, :indeterminate):not(:disabled)) .db-checkbox-indicator {
16138
+ background-color: var(--db-checkbox-surface-checked-hover);
16139
+ border-color: var(--db-checkbox-surface-checked-hover);
16010
16140
  }
16011
16141
 
16012
- .ds-checkbox:active:has(.ds-checkbox-input:is(:checked, :indeterminate):not(:disabled)) .ds-checkbox-indicator {
16013
- background-color: var(--db-checkbox-bg-checked-press);
16014
- border-color: var(--db-checkbox-bg-checked-press);
16142
+ .db-checkbox:active:has(.db-checkbox-input:is(:checked, :indeterminate):not(:disabled)) .db-checkbox-indicator {
16143
+ background-color: var(--db-checkbox-surface-checked-press);
16144
+ border-color: var(--db-checkbox-surface-checked-press);
16015
16145
  }
16016
16146
 
16017
16147
  /* Mark visibility. */
16018
- .ds-checkbox:has(.ds-checkbox-input:checked) .ds-checkbox-checkmark {
16148
+ .db-checkbox:has(.db-checkbox-input:checked) .db-checkbox-checkmark {
16019
16149
  opacity: 1;
16020
16150
  }
16021
16151
 
16022
- .ds-checkbox:has(.ds-checkbox-input:indeterminate) .ds-checkbox-dash {
16152
+ .db-checkbox:has(.db-checkbox-input:indeterminate) .db-checkbox-dash {
16023
16153
  opacity: 1;
16024
16154
  }
16025
16155
 
16026
16156
  /* Focus-visible (keyboard only). */
16027
- .ds-checkbox:has(.ds-checkbox-input:focus-visible) .ds-checkbox-indicator {
16028
- outline: var(--db-checkbox-focus-ring-width) solid var(--db-checkbox-border-focus);
16029
- outline-offset: var(--db-checkbox-focus-ring-offset);
16157
+ .db-checkbox:has(.db-checkbox-input:focus-visible) .db-checkbox-indicator {
16158
+ outline: var(--db-checkbox-focus-ring-width) solid var(--db-checkbox-focus-ring);
16159
+ outline-offset: 4px;
16030
16160
  }
16031
16161
 
16032
16162
  /* Disabled (covers unchecked, checked, indeterminate). Sourced from
16033
16163
  * `input:disabled` so the standalone-disabled and group-disabled paths both
16034
16164
  * land here without needing a separate root modifier class. */
16035
- .ds-checkbox:has(.ds-checkbox-input:disabled) {
16165
+ .db-checkbox:has(.db-checkbox-input:disabled) {
16036
16166
  cursor: not-allowed;
16037
16167
  }
16038
16168
 
16039
- .ds-checkbox:has(.ds-checkbox-input:disabled) .ds-checkbox-label {
16169
+ .db-checkbox:has(.db-checkbox-input:disabled) .db-checkbox-label {
16040
16170
  color: var(--db-checkbox-text-disabled);
16041
16171
  }
16042
16172
 
16043
- .ds-checkbox:has(.ds-checkbox-input:disabled) .ds-checkbox-indicator {
16044
- background-color: var(--db-checkbox-bg-disabled);
16173
+ .db-checkbox:has(.db-checkbox-input:disabled) .db-checkbox-indicator {
16174
+ background-color: var(--db-checkbox-surface-disabled);
16045
16175
  border-color: var(--db-checkbox-border-disabled);
16046
16176
  box-shadow: none;
16047
16177
  }
16048
16178
 
16049
- .ds-checkbox:has(.ds-checkbox-input:disabled) .ds-checkbox-checkmark {
16050
- color: var(--db-checkbox-icon-color-disabled);
16179
+ .db-checkbox:has(.db-checkbox-input:disabled) .db-checkbox-checkmark {
16180
+ color: var(--db-checkbox-mark-disabled);
16051
16181
  }
16052
16182
 
16053
- .ds-checkbox:has(.ds-checkbox-input:disabled) .ds-checkbox-dash {
16054
- background-color: var(--db-checkbox-icon-color-disabled);
16183
+ .db-checkbox:has(.db-checkbox-input:disabled) .db-checkbox-dash {
16184
+ background-color: var(--db-checkbox-mark-disabled);
16055
16185
  }
16056
16186
 
16057
- /* Visually-hidden native input, kept interactive and in the tab order so
16058
- * `:has()` lookups above can read its state. Pointer events fall through to
16059
- * the label, so clicking anywhere toggles the box. */
16060
- .ds-checkbox .ds-checkbox-input {
16187
+ /* Visually-hidden native input (opacity:0) overlaying the indicator square,
16188
+ * kept interactive and in the tab order so `:has()` lookups above can read its
16189
+ * state. It stays pointer-clickable matching AntD's `.ant-checkbox-input`
16190
+ * so it is the top-most hit-test target over the box: `getByRole('checkbox').click()`
16191
+ * (Playwright, and any coordinate click that lands on the box) resolves to the
16192
+ * real control instead of the decorative indicator overlay. Making the input
16193
+ * `pointer-events: none` (the prior native-only behavior) is what regressed
16194
+ * interaction tests vs. the AntD variant. `cursor: inherit` tracks the label's
16195
+ * pointer / disabled `not-allowed` cursor so the box keeps AntD's cursor too. */
16196
+ .db-checkbox .db-checkbox-input {
16061
16197
  position: absolute;
16062
16198
  inset: 0;
16063
16199
  inline-size: var(--db-checkbox-size);
16064
16200
  block-size: var(--db-checkbox-size);
16065
16201
  margin: 0;
16066
16202
  opacity: 0;
16067
- pointer-events: none;
16203
+ cursor: inherit;
16068
16204
  }
16069
16205
 
16070
16206
  /* Indicator — square with the border/fill that responds to state above.
16071
16207
  * Vertical math: aligns the indicator to the cap-height of the first text
16072
16208
  * line so checkbox + label sit on the same visual baseline even when the
16073
16209
  * label wraps. */
16074
- .ds-checkbox .ds-checkbox-indicator {
16210
+ .db-checkbox .db-checkbox-indicator {
16075
16211
  display: grid;
16076
16212
  place-items: center;
16077
16213
  flex-shrink: 0;
16214
+ /* Decorative only — the overlaid input owns hit-testing. Without this, the
16215
+ * indicator (and its inherited checkmark/dash children) intercept
16216
+ * `getByRole('checkbox').click()`; clicks on any edge sliver the input does
16217
+ * not cover fall through to the label, which toggles via label/input
16218
+ * association. */
16219
+ pointer-events: none;
16078
16220
  inline-size: var(--db-checkbox-size);
16079
16221
  block-size: var(--db-checkbox-size);
16080
16222
  margin-top: calc((var(--db-line-height-base, 20px) - var(--db-checkbox-size)) / 2);
16081
- border: var(--db-checkbox-border-width) solid var(--db-checkbox-border-default);
16223
+ border: var(--db-checkbox-border-width) solid var(--db-checkbox-border);
16082
16224
  border-radius: var(--db-checkbox-border-radius);
16083
- background-color: var(--db-checkbox-bg-default);
16225
+ background-color: var(--db-checkbox-surface);
16084
16226
  box-sizing: border-box;
16085
16227
  transition:
16086
16228
  background-color var(--db-checkbox-transition-duration) ease,
@@ -16088,16 +16230,16 @@ span.du-bois-light-typography-ellipsis-single-line {
16088
16230
  box-shadow var(--db-checkbox-transition-duration) ease;
16089
16231
  }
16090
16232
 
16091
- .ds-checkbox .ds-checkbox-indicator > .ds-checkbox-checkmark {
16233
+ .db-checkbox .db-checkbox-indicator > .db-checkbox-checkmark {
16092
16234
  grid-area: 1 / 1;
16093
16235
  inline-size: 100%;
16094
16236
  block-size: 100%;
16095
- color: var(--db-checkbox-icon-color);
16237
+ color: var(--db-checkbox-mark);
16096
16238
  opacity: 0;
16097
16239
  transition: opacity var(--db-checkbox-transition-duration) ease;
16098
16240
  }
16099
16241
 
16100
- .ds-checkbox .ds-checkbox-indicator > .ds-checkbox-checkmark path {
16242
+ .db-checkbox .db-checkbox-indicator > .db-checkbox-checkmark path {
16101
16243
  fill: none;
16102
16244
  stroke: currentColor;
16103
16245
  stroke-width: 2;
@@ -16105,14 +16247,14 @@ span.du-bois-light-typography-ellipsis-single-line {
16105
16247
  stroke-linejoin: round;
16106
16248
  }
16107
16249
 
16108
- .ds-checkbox .ds-checkbox-indicator > .ds-checkbox-dash {
16250
+ .db-checkbox .db-checkbox-indicator > .db-checkbox-dash {
16109
16251
  grid-area: 1 / 1;
16110
16252
  inline-size: var(--db-checkbox-indeterminate-mark-width);
16111
16253
  block-size: var(--db-checkbox-indeterminate-mark-height);
16112
16254
  /* CSS clamps this to half the 3px height, giving fully rounded end caps so the
16113
16255
  * dash reads as a pill rather than a flat bar. */
16114
16256
  border-radius: 4px;
16115
- background-color: var(--db-checkbox-icon-color);
16257
+ background-color: var(--db-checkbox-mark);
16116
16258
  opacity: 0;
16117
16259
  transition: opacity var(--db-checkbox-transition-duration) ease;
16118
16260
  }
@@ -16122,9 +16264,9 @@ span.du-bois-light-typography-ellipsis-single-line {
16122
16264
  * `padding-right` extends the checkbox's bounding box so adjacent checkboxes in a
16123
16265
  * flex row sit ~16px apart (8px trailing + 8px group `gap`) — same visual rhythm
16124
16266
  * as the AntD variant. */
16125
- .ds-checkbox .ds-checkbox-label {
16267
+ .db-checkbox .db-checkbox-label {
16126
16268
  color: var(--db-checkbox-text);
16127
- padding-inline: var(--db-checkbox-spacing);
16269
+ padding-inline: var(--db-checkbox-label-spacing);
16128
16270
  word-break: break-word;
16129
16271
  }
16130
16272
 
@@ -16135,7 +16277,7 @@ span.du-bois-light-typography-ellipsis-single-line {
16135
16277
  *
16136
16278
  * Each helper-text class is listed once per theme (`du-bois-light-*` /
16137
16279
  * `du-bois-dark-*`). The selectors deliberately repeat the root/group class
16138
- * (`.ds-checkbox.ds-checkbox`) to push specificity to (0,3,0). That
16280
+ * (`.db-checkbox.db-checkbox`) to push specificity to (0,3,0). That
16139
16281
  * overrides `FormMessage`'s own `&&`-doubled `margin-top: 8px` declared with
16140
16282
  * Emotion at runtime — without doubling we'd lose on the specificity tie and
16141
16283
  * the validation message would keep an 8px gap below the checkbox. */
@@ -16143,115 +16285,84 @@ span.du-bois-light-typography-ellipsis-single-line {
16143
16285
  /* Single checkbox followed by Hint and/or FormMessage. Indents the helper text
16144
16286
  * by 24px so it aligns with the start of the label, and removes the default
16145
16287
  * vertical margin Hint/FormMessage carry. */
16146
- .ds-checkbox.ds-checkbox + .du-bois-light-hint,
16147
- .ds-checkbox.ds-checkbox + .du-bois-dark-hint,
16148
- .ds-checkbox.ds-checkbox + .du-bois-light-form-message,
16149
- .ds-checkbox.ds-checkbox + .du-bois-dark-form-message,
16150
- .ds-checkbox.ds-checkbox + .du-bois-light-hint + .du-bois-light-form-message,
16151
- .ds-checkbox.ds-checkbox + .du-bois-dark-hint + .du-bois-dark-form-message {
16152
- padding-left: var(--db-space-lg);
16288
+ .db-checkbox.db-checkbox + .du-bois-light-hint,
16289
+ .db-checkbox.db-checkbox + .du-bois-dark-hint,
16290
+ .db-checkbox.db-checkbox + .du-bois-light-form-message,
16291
+ .db-checkbox.db-checkbox + .du-bois-dark-form-message,
16292
+ .db-checkbox.db-checkbox + .du-bois-light-hint + .du-bois-light-form-message,
16293
+ .db-checkbox.db-checkbox + .du-bois-dark-hint + .du-bois-dark-form-message {
16294
+ padding-left: var(--db-spacing-sm);
16153
16295
  margin-top: 0;
16154
16296
  }
16155
16297
 
16156
16298
  /* Group spacing against sibling form text — 8px gap above the group when it
16157
16299
  * follows a Hint, 8px gap above a FormMessage when it follows the group.
16158
16300
  * Doubled class on the group side beats FormMessage's `&&` for the same reason. */
16159
- .du-bois-light-hint + .ds-checkbox-group.ds-checkbox-group,
16160
- .du-bois-dark-hint + .ds-checkbox-group.ds-checkbox-group,
16161
- .ds-checkbox-group.ds-checkbox-group + .du-bois-light-form-message,
16162
- .ds-checkbox-group.ds-checkbox-group + .du-bois-dark-form-message {
16163
- margin-top: var(--db-space-sm);
16301
+ .du-bois-light-hint + .db-checkbox-group.db-checkbox-group,
16302
+ .du-bois-dark-hint + .db-checkbox-group.db-checkbox-group,
16303
+ .db-checkbox-group.db-checkbox-group + .du-bois-light-form-message,
16304
+ .db-checkbox-group.db-checkbox-group + .du-bois-dark-form-message {
16305
+ margin-top: var(--db-spacing-2xs);
16164
16306
  }
16165
16307
 
16166
- /* CheckboxGroup layout. Vertical delegates to the `.ds-stack` primitive; the
16308
+ /* CheckboxGroup layout. Vertical delegates to the `.db-stack` primitive; the
16167
16309
  * horizontal default stays bespoke because it must NOT wrap (a long row of
16168
16310
  * checkboxes overflows horizontally rather than reflowing onto multiple lines),
16169
- * which is the one thing `.ds-cluster` won't do. Both wire their gap to the
16311
+ * which is the one thing `.db-cluster` won't do. Both wire their gap to the
16170
16312
  * checkbox spacing token so a retheme moves with the rest of the component. */
16171
- .ds-checkbox-group {
16313
+ .db-checkbox-group {
16172
16314
  display: flex;
16173
16315
  }
16174
16316
 
16175
- /* Horizontal (default): single non-wrapping row. `:not(.ds-stack)` keeps this
16317
+ /* Horizontal (default): single non-wrapping row. `:not(.db-stack)` keeps this
16176
16318
  * off the vertical element so it never fights the stack primitive's gap. */
16177
- .ds-checkbox-group:not(.ds-stack) {
16319
+ .db-checkbox-group:not(.db-stack) {
16178
16320
  flex-wrap: nowrap;
16179
- column-gap: var(--db-checkbox-spacing);
16321
+ column-gap: var(--db-checkbox-label-spacing);
16180
16322
  row-gap: 0;
16181
16323
  }
16182
16324
 
16183
- /* Vertical: .ds-stack supplies flex-direction + gap; we only retarget the knob. */
16184
- .ds-checkbox-group.ds-stack {
16185
- --ds-stack-gap: var(--db-checkbox-spacing);
16325
+ /* Vertical: .db-stack supplies flex-direction + gap; we only retarget the knob. */
16326
+ .db-checkbox-group.db-stack {
16327
+ --db-stack-gap: var(--db-checkbox-label-spacing);
16186
16328
  }
16187
16329
 
16188
- /* Component-tier tokens for <Radio>. Each value defaults to a CATEGORY
16189
- * (selection-toggle) token via var(); consumers can override here to retheme
16190
- * radios without affecting checkbox / switch.
16191
- *
16192
- * Radio differs from Checkbox in two ways: the indicator is a full circle
16193
- * (border-radius) and the "mark" is a filled dot rather than a checkmark/dash. */
16194
-
16195
- /* Re-declared under both theme classes (not just :root) so the var() chain onto
16196
- * category/system tokens re-resolves inside a `.du-bois-dark` subtree instead of
16197
- * freezing at the root (light) values. See DUBOIS-448 dark-mode scoping. */
16198
- :where(:root, .du-bois-light, .du-bois-dark) {
16199
- --db-radio-size: var(--db-selection-toggle-size);
16200
- /* Circle, not a rounded square — the one shape token that does NOT inherit
16201
- * the category (square) radius. */
16330
+ :where(:root), :where(.du-bois-light) {
16331
+ /* Shape */
16202
16332
  --db-radio-border-radius: var(--db-radius-full);
16203
16333
  --db-radio-border-width: 1px;
16204
- --db-radio-spacing: var(--db-selection-toggle-spacing);
16205
-
16206
- --db-radio-bg-default: var(--db-selection-toggle-bg-default);
16207
- --db-radio-bg-hover: var(--db-selection-toggle-bg-hover);
16208
- --db-radio-bg-press: var(--db-selection-toggle-bg-press);
16209
- --db-radio-bg-checked: var(--db-selection-toggle-bg-checked);
16210
- --db-radio-bg-checked-hover: var(--db-selection-toggle-bg-checked-hover);
16211
- /* AntD checked active/press background is actionDefaultBackgroundPress (NOT the
16212
- * primary press), so this maps to the default press bg category token — see
16213
- * getRadioInputStyles checked active in AntDRadioInternal.tsx. */
16214
- --db-radio-bg-checked-press: var(--db-selection-toggle-bg-press);
16215
- --db-radio-bg-disabled: var(--db-selection-toggle-bg-disabled);
16216
-
16217
- --db-radio-border-default: var(--db-selection-toggle-border-default);
16334
+
16335
+ /* Color */
16336
+ --db-radio-surface: var(--db-selection-toggle-surface);
16337
+ --db-radio-surface-hover: var(--db-color-action-default-background-hover);
16338
+ --db-radio-surface-press: var(--db-color-action-default-background-press);
16339
+ --db-radio-surface-checked: var(--db-selection-toggle-surface-checked);
16340
+ --db-radio-surface-checked-hover: var(--db-selection-toggle-surface-checked-hover);
16341
+ --db-radio-surface-checked-press: var(--db-color-action-default-background-press);
16342
+ --db-radio-surface-disabled: var(--db-selection-toggle-surface-disabled);
16343
+
16344
+ --db-radio-border: var(--db-color-action-default-border-default);
16218
16345
  --db-radio-border-hover: var(--db-selection-toggle-border-hover);
16219
16346
  --db-radio-border-press: var(--db-selection-toggle-border-press);
16220
- --db-radio-border-focus: var(--db-selection-toggle-border-focus);
16221
- --db-radio-border-disabled: var(--db-selection-toggle-border-disabled);
16222
-
16223
- /* Two-tone checked hover/press border ring (AntD getRadioInputStyles checked
16224
- * states): the border is a DARKER shade than the fill, not equal to it.
16225
- * - checked hover border = actionPrimaryBackgroundPress (== the press category
16226
- * token, which is action-primary-background-press).
16227
- * - checked press border = actionDefaultBorderPress; no selection-toggle
16228
- * category token equals this color, so reference the system token directly. */
16347
+ --db-radio-border-focus: var(--db-focus-ring-color);
16348
+ --db-radio-border-disabled: var(--db-color-action-disabled-border);
16229
16349
  --db-radio-border-checked-hover: var(--db-selection-toggle-border-press);
16230
16350
  --db-radio-border-checked-press: var(--db-color-action-default-border-press);
16351
+ --db-radio-border-unchecked-focus: var(--db-color-action-primary-background-default);
16352
+ --db-radio-outline-checked-focus: var(--db-color-action-primary-background-default);
16231
16353
 
16232
- /* Unchecked keyboard-focus border (AntD getRadioInputStyles unchecked focus):
16233
- * borderColor = actionPrimaryBackgroundDefault, with NO outline ring. No
16234
- * selection-toggle category token equals this color (the closest is a bg
16235
- * token), so reference the system token directly. */
16236
- --db-radio-border-focus-unchecked: var(--db-color-action-primary-background-default);
16237
- /* Checked focus-visible outline color (AntD: outline 1px solid
16238
- * actionPrimaryBackgroundDefault, outlineOffset 1). */
16239
- --db-radio-focus-outline-checked-color: var(--db-color-action-primary-background-default);
16240
-
16241
- /* The dot. Shares the category icon-color token (white over the filled
16242
- * primary surface) so a retheme moves checkbox checkmark + radio dot together. */
16243
- --db-radio-dot-color: var(--db-selection-toggle-icon-color);
16244
- --db-radio-dot-color-disabled: var(--db-selection-toggle-icon-color-disabled);
16354
+ --db-radio-mark: #ffffff;
16355
+ --db-radio-mark-disabled: var(--db-selection-toggle-mark-disabled);
16245
16356
  --db-radio-text: var(--db-selection-toggle-text);
16246
16357
  --db-radio-text-disabled: var(--db-selection-toggle-text-disabled);
16247
16358
 
16248
- --db-radio-focus-ring-width: var(--db-selection-toggle-focus-ring-width);
16249
- --db-radio-focus-ring-offset: var(--db-selection-toggle-focus-ring-offset);
16250
- --db-radio-transition-duration: var(--db-selection-toggle-transition-duration);
16359
+ /* Density */
16360
+ --db-radio-size: var(--db-selection-toggle-size);
16361
+ --db-radio-label-spacing: var(--db-selection-toggle-label-spacing);
16362
+ --db-radio-mark-size: var(--db-size-3xs);
16251
16363
 
16252
- /* Diameter of the inner dot. Mirrors the AntD checked `::after` size, which uses
16253
- * `theme.spacing.xs` (4px) — see getRadioInputStyles in AntDRadioInternal.tsx. */
16254
- --db-radio-dot-size: var(--db-space-xs);
16364
+ /* Motion */
16365
+ --db-radio-transition-duration: var(--db-selection-toggle-transition-duration);
16255
16366
  }
16256
16367
 
16257
16368
  /* Native-input <Radio> styles. Classic CSS only — no native nesting (the
@@ -16262,12 +16373,12 @@ span.du-bois-light-typography-ellipsis-single-line {
16262
16373
  *
16263
16374
  * Structure (assumed by the React component):
16264
16375
  *
16265
- * <label class="ds-radio">
16376
+ * <label class="db-radio">
16266
16377
  * <input type="radio" />
16267
- * <span class="ds-radio-indicator"> ← circle border + fill react to state
16268
- * <span class="ds-radio-dot" /> ← visible when :checked
16378
+ * <span class="db-radio-indicator"> ← circle border + fill react to state
16379
+ * <span class="db-radio-dot" /> ← visible when :checked
16269
16380
  * </span>
16270
- * <span class="ds-radio-label">{children}</span>
16381
+ * <span class="db-radio-label">{children}</span>
16271
16382
  * </label>
16272
16383
  *
16273
16384
  * The root only ever has one <input> descendant, so a bare `input` selector is
@@ -16276,9 +16387,9 @@ span.du-bois-light-typography-ellipsis-single-line {
16276
16387
  * checkmark/dash, and there is no indeterminate state.
16277
16388
  *
16278
16389
  * TODO(DUBOIS-452): the indicator/dot state styles below are identical to
16279
- * NativeCheckbox.css — consolidate them into a shared `.ds-selection-toggle` class. */
16390
+ * NativeCheckbox.css — consolidate them into a shared `.db-selection-toggle` class. */
16280
16391
 
16281
- .ds-radio {
16392
+ .db-radio {
16282
16393
  /* `display: flex` (block-level), NOT `inline-flex`: see NativeCheckbox.css for
16283
16394
  * the line-box / sibling-spacing rationale. */
16284
16395
  display: flex;
@@ -16290,41 +16401,41 @@ span.du-bois-light-typography-ellipsis-single-line {
16290
16401
  width: fit-content;
16291
16402
  }
16292
16403
 
16293
- /* Hover/press live on the root (label), not on the input: the input has
16294
- * `pointer-events: none`, so `input:hover` would never match, and the whole
16295
- * label area should drive the feedback. */
16296
- .ds-radio:hover:has(input:not(:disabled, :checked)) .ds-radio-indicator {
16297
- background-color: var(--db-radio-bg-hover);
16404
+ /* Hover/press live on the root (label), not on the input: the input is
16405
+ * visually hidden (opacity:0), so an `input:hover` rule wouldn't be visible
16406
+ * anyway, and the whole label area should drive the feedback. */
16407
+ .db-radio:hover:has(input:not(:disabled, :checked)) .db-radio-indicator {
16408
+ background-color: var(--db-radio-surface-hover);
16298
16409
  border-color: var(--db-radio-border-hover);
16299
16410
  }
16300
16411
 
16301
- .ds-radio:active:has(input:not(:disabled, :checked)) .ds-radio-indicator {
16302
- background-color: var(--db-radio-bg-press);
16412
+ .db-radio:active:has(input:not(:disabled, :checked)) .db-radio-indicator {
16413
+ background-color: var(--db-radio-surface-press);
16303
16414
  border-color: var(--db-radio-border-press);
16304
16415
  }
16305
16416
 
16306
16417
  /* Selected fill. */
16307
- .ds-radio:has(input:checked) .ds-radio-indicator {
16308
- background-color: var(--db-radio-bg-checked);
16309
- border-color: var(--db-radio-bg-checked);
16418
+ .db-radio:has(input:checked) .db-radio-indicator {
16419
+ background-color: var(--db-radio-surface-checked);
16420
+ border-color: var(--db-radio-surface-checked);
16310
16421
  }
16311
16422
 
16312
16423
  /* AntD getRadioInputStyles checked hover: background = actionPrimaryBackgroundHover,
16313
16424
  * borderColor = actionPrimaryBackgroundPress (a darker ring than the fill). */
16314
- .ds-radio:hover:has(input:checked:not(:disabled)) .ds-radio-indicator {
16315
- background-color: var(--db-radio-bg-checked-hover);
16425
+ .db-radio:hover:has(input:checked:not(:disabled)) .db-radio-indicator {
16426
+ background-color: var(--db-radio-surface-checked-hover);
16316
16427
  border-color: var(--db-radio-border-checked-hover);
16317
16428
  }
16318
16429
 
16319
16430
  /* AntD getRadioInputStyles checked active: background = actionDefaultBackgroundPress,
16320
16431
  * borderColor = actionDefaultBorderPress (two-tone, not flat). */
16321
- .ds-radio:active:has(input:checked:not(:disabled)) .ds-radio-indicator {
16322
- background-color: var(--db-radio-bg-checked-press);
16432
+ .db-radio:active:has(input:checked:not(:disabled)) .db-radio-indicator {
16433
+ background-color: var(--db-radio-surface-checked-press);
16323
16434
  border-color: var(--db-radio-border-checked-press);
16324
16435
  }
16325
16436
 
16326
16437
  /* Dot visibility. */
16327
- .ds-radio:has(input:checked) .ds-radio-dot {
16438
+ .db-radio:has(input:checked) .db-radio-dot {
16328
16439
  opacity: 1;
16329
16440
  }
16330
16441
 
@@ -16333,66 +16444,77 @@ span.du-bois-light-typography-ellipsis-single-line {
16333
16444
  *
16334
16445
  * UNCHECKED focus (AntD `&:not(disabled) > input:focus + inner`): only the border
16335
16446
  * color changes to actionPrimaryBackgroundDefault — NO outline ring. */
16336
- .ds-radio:has(input:focus-visible:not(:checked)) .ds-radio-indicator {
16337
- border-color: var(--db-radio-border-focus-unchecked);
16447
+ .db-radio:has(input:focus-visible:not(:checked)) .db-radio-indicator {
16448
+ border-color: var(--db-radio-border-unchecked-focus);
16338
16449
  }
16339
16450
 
16340
16451
  /* CHECKED focus-visible (AntD `&.checked &:not(disabled) > input:focus-visible + inner`):
16341
16452
  * background = actionPrimaryBackgroundDefault, borderColor = actionDefaultBorderFocus,
16342
16453
  * outline = 1px solid actionPrimaryBackgroundDefault, outlineOffset = 1. */
16343
- .ds-radio:has(input:focus-visible:checked) .ds-radio-indicator {
16344
- background-color: var(--db-radio-bg-checked);
16454
+ .db-radio:has(input:focus-visible:checked) .db-radio-indicator {
16455
+ background-color: var(--db-radio-surface-checked);
16345
16456
  border-color: var(--db-radio-border-focus);
16346
- outline: 1px solid var(--db-radio-focus-outline-checked-color);
16457
+ outline: 1px solid var(--db-radio-outline-checked-focus);
16347
16458
  outline-offset: 1px;
16348
16459
  }
16349
16460
 
16350
16461
  /* Disabled (covers checked and unchecked). Sourced from `input:disabled` so the
16351
16462
  * standalone-disabled and group-disabled paths both land here. */
16352
- .ds-radio:has(input:disabled) {
16463
+ .db-radio:has(input:disabled) {
16353
16464
  cursor: not-allowed;
16354
16465
  }
16355
16466
 
16356
- .ds-radio:has(input:disabled) .ds-radio-label {
16467
+ .db-radio:has(input:disabled) .db-radio-label {
16357
16468
  color: var(--db-radio-text-disabled);
16358
16469
  }
16359
16470
 
16360
- .ds-radio:has(input:disabled) .ds-radio-indicator {
16361
- background-color: var(--db-radio-bg-disabled);
16471
+ .db-radio:has(input:disabled) .db-radio-indicator {
16472
+ background-color: var(--db-radio-surface-disabled);
16362
16473
  border-color: var(--db-radio-border-disabled);
16363
16474
  box-shadow: none;
16364
16475
  }
16365
16476
 
16366
- .ds-radio:has(input:disabled) .ds-radio-dot {
16367
- background-color: var(--db-radio-dot-color-disabled);
16477
+ .db-radio:has(input:disabled) .db-radio-dot {
16478
+ background-color: var(--db-radio-mark-disabled);
16368
16479
  }
16369
16480
 
16370
- /* Visually-hidden native input, kept interactive and in the tab order so the
16371
- * `:has()` lookups above can read its state. Pointer events fall through to the
16372
- * label, so clicking anywhere toggles the radio. */
16373
- .ds-radio input {
16481
+ /* Visually-hidden native input (opacity:0) overlaying the indicator circle,
16482
+ * kept interactive and in the tab order so the `:has()` lookups above can read
16483
+ * its state. It stays pointer-clickable matching AntD's `.ant-radio-input`
16484
+ * so it is the top-most hit-test target over the circle: `getByRole('radio').click()`
16485
+ * (Playwright, and any coordinate click that lands on the circle) resolves to the
16486
+ * real control instead of the decorative indicator overlay. Making the input
16487
+ * `pointer-events: none` (the prior native-only behavior) is what regressed
16488
+ * interaction tests vs. the AntD variant. `cursor: inherit` tracks the label's
16489
+ * pointer / disabled `not-allowed` cursor so the circle keeps AntD's cursor too. */
16490
+ .db-radio input {
16374
16491
  position: absolute;
16375
16492
  inset: 0;
16376
16493
  inline-size: var(--db-radio-size);
16377
16494
  block-size: var(--db-radio-size);
16378
16495
  margin: 0;
16379
16496
  opacity: 0;
16380
- pointer-events: none;
16497
+ cursor: inherit;
16381
16498
  }
16382
16499
 
16383
16500
  /* Indicator — circle with the border/fill that responds to state above.
16384
16501
  * Vertical math aligns the indicator to the cap-height of the first text line
16385
16502
  * so radio + label sit on the same visual baseline even when the label wraps. */
16386
- .ds-radio .ds-radio-indicator {
16503
+ .db-radio .db-radio-indicator {
16387
16504
  display: grid;
16388
16505
  place-items: center;
16389
16506
  flex-shrink: 0;
16507
+ /* Decorative only — the overlaid input owns hit-testing. Without this, the
16508
+ * indicator (and its inherited dot child) intercept `getByRole('radio').click()`;
16509
+ * clicks on any edge sliver the input does not cover fall through to the label,
16510
+ * which toggles via label/input association. */
16511
+ pointer-events: none;
16390
16512
  inline-size: var(--db-radio-size);
16391
16513
  block-size: var(--db-radio-size);
16392
16514
  margin-top: calc((var(--db-line-height-base, 20px) - var(--db-radio-size)) / 2);
16393
- border: var(--db-radio-border-width) solid var(--db-radio-border-default);
16515
+ border: var(--db-radio-border-width) solid var(--db-radio-border);
16394
16516
  border-radius: var(--db-radio-border-radius);
16395
- background-color: var(--db-radio-bg-default);
16517
+ background-color: var(--db-radio-surface);
16396
16518
  box-sizing: border-box;
16397
16519
  transition:
16398
16520
  background-color var(--db-radio-transition-duration) ease,
@@ -16400,12 +16522,12 @@ span.du-bois-light-typography-ellipsis-single-line {
16400
16522
  box-shadow var(--db-radio-transition-duration) ease;
16401
16523
  }
16402
16524
 
16403
- .ds-radio .ds-radio-indicator > .ds-radio-dot {
16525
+ .db-radio .db-radio-indicator > .db-radio-dot {
16404
16526
  grid-area: 1 / 1;
16405
- inline-size: var(--db-radio-dot-size);
16406
- block-size: var(--db-radio-dot-size);
16527
+ inline-size: var(--db-radio-mark-size);
16528
+ block-size: var(--db-radio-mark-size);
16407
16529
  border-radius: var(--db-radius-full);
16408
- background-color: var(--db-radio-dot-color);
16530
+ background-color: var(--db-radio-mark);
16409
16531
  opacity: 0;
16410
16532
  transition: opacity var(--db-radio-transition-duration) ease;
16411
16533
  }
@@ -16413,17 +16535,17 @@ span.du-bois-light-typography-ellipsis-single-line {
16413
16535
  /* Honour the user's reduced-motion preference: drop the state-change
16414
16536
  * transitions on the indicator and dot so checking/hovering is instant. */
16415
16537
  @media (prefers-reduced-motion: reduce) {
16416
- .ds-radio .ds-radio-indicator,
16417
- .ds-radio .ds-radio-indicator > .ds-radio-dot {
16538
+ .db-radio .db-radio-indicator,
16539
+ .db-radio .db-radio-indicator > .db-radio-dot {
16418
16540
  transition: none;
16419
16541
  }
16420
16542
  }
16421
16543
 
16422
16544
  /* Padding-inline replicates the AntD `.{prefix} + span` label gap and the
16423
16545
  * trailing whitespace that separates adjacent radios in a row. */
16424
- .ds-radio .ds-radio-label {
16546
+ .db-radio .db-radio-label {
16425
16547
  color: var(--db-radio-text);
16426
- padding-inline: var(--db-radio-spacing);
16548
+ padding-inline: var(--db-radio-label-spacing);
16427
16549
  word-break: break-word;
16428
16550
  }
16429
16551
 
@@ -16431,13 +16553,13 @@ span.du-bois-light-typography-ellipsis-single-line {
16431
16553
  * indent comes from AntD's getCommonRadioGroupStyles (`& > label + hint`) and applies
16432
16554
  * to BOTH layouts. The doubled root class pushes specificity to (0,3,0) to beat
16433
16555
  * FormMessage's runtime `&&` margin. */
16434
- .ds-radio.ds-radio + .du-bois-light-hint,
16435
- .ds-radio.ds-radio + .du-bois-dark-hint,
16436
- .ds-radio.ds-radio + .du-bois-light-form-message,
16437
- .ds-radio.ds-radio + .du-bois-dark-form-message,
16438
- .ds-radio.ds-radio + .du-bois-light-hint + .du-bois-light-form-message,
16439
- .ds-radio.ds-radio + .du-bois-dark-hint + .du-bois-dark-form-message {
16440
- padding-inline-start: var(--db-space-lg);
16556
+ .db-radio.db-radio + .du-bois-light-hint,
16557
+ .db-radio.db-radio + .du-bois-dark-hint,
16558
+ .db-radio.db-radio + .du-bois-light-form-message,
16559
+ .db-radio.db-radio + .du-bois-dark-form-message,
16560
+ .db-radio.db-radio + .du-bois-light-hint + .du-bois-light-form-message,
16561
+ .db-radio.db-radio + .du-bois-dark-hint + .du-bois-dark-form-message {
16562
+ padding-inline-start: var(--db-spacing-sm);
16441
16563
  margin-top: 0;
16442
16564
  }
16443
16565
 
@@ -16445,71 +16567,71 @@ span.du-bois-light-typography-ellipsis-single-line {
16445
16567
  * after a radio gets `marginTop: -sm` (cancels the preceding radio's
16446
16568
  * `paddingBottom: sm` so the hint tucks directly under its label) and
16447
16569
  * `marginBottom: sm` (gap before the next radio). The negative top margin relies on
16448
- * the .ds-stack gap being 0 (set below). Scoped to .ds-stack so it never perturbs
16570
+ * the .db-stack gap being 0 (set below). Scoped to .db-stack so it never perturbs
16449
16571
  * the horizontal grid, where hints are positioned by grid-row instead. */
16450
- .ds-radio-group.ds-stack > .ds-radio.ds-radio + .du-bois-light-hint,
16451
- .ds-radio-group.ds-stack > .ds-radio.ds-radio + .du-bois-dark-hint,
16452
- .ds-radio-group.ds-stack > .ds-radio.ds-radio + .du-bois-light-form-message,
16453
- .ds-radio-group.ds-stack > .ds-radio.ds-radio + .du-bois-dark-form-message,
16454
- .ds-radio-group.ds-stack > .ds-radio.ds-radio + .du-bois-light-hint + .du-bois-light-form-message,
16455
- .ds-radio-group.ds-stack > .ds-radio.ds-radio + .du-bois-dark-hint + .du-bois-dark-form-message {
16456
- margin-top: calc(-1 * var(--db-space-sm));
16457
- margin-bottom: var(--db-space-sm);
16572
+ .db-radio-group.db-stack > .db-radio.db-radio + .du-bois-light-hint,
16573
+ .db-radio-group.db-stack > .db-radio.db-radio + .du-bois-dark-hint,
16574
+ .db-radio-group.db-stack > .db-radio.db-radio + .du-bois-light-form-message,
16575
+ .db-radio-group.db-stack > .db-radio.db-radio + .du-bois-dark-form-message,
16576
+ .db-radio-group.db-stack > .db-radio.db-radio + .du-bois-light-hint + .du-bois-light-form-message,
16577
+ .db-radio-group.db-stack > .db-radio.db-radio + .du-bois-dark-hint + .du-bois-dark-form-message {
16578
+ margin-top: calc(-1 * var(--db-spacing-2xs));
16579
+ margin-bottom: var(--db-spacing-2xs);
16458
16580
  }
16459
16581
 
16460
16582
  /* AntD `& > label:last-of-type + hint { marginTop: 0 }`: the last radio has no
16461
16583
  * `paddingBottom` to cancel, so its trailing hint keeps its natural top position. */
16462
- .ds-radio-group.ds-stack > .ds-radio.ds-radio:last-of-type + .du-bois-light-hint,
16463
- .ds-radio-group.ds-stack > .ds-radio.ds-radio:last-of-type + .du-bois-dark-hint,
16464
- .ds-radio-group.ds-stack > .ds-radio.ds-radio:last-of-type + .du-bois-light-form-message,
16465
- .ds-radio-group.ds-stack > .ds-radio.ds-radio:last-of-type + .du-bois-dark-form-message,
16466
- .ds-radio-group.ds-stack > .ds-radio.ds-radio:last-of-type + .du-bois-light-hint + .du-bois-light-form-message,
16467
- .ds-radio-group.ds-stack > .ds-radio.ds-radio:last-of-type + .du-bois-dark-hint + .du-bois-dark-form-message {
16584
+ .db-radio-group.db-stack > .db-radio.db-radio:last-of-type + .du-bois-light-hint,
16585
+ .db-radio-group.db-stack > .db-radio.db-radio:last-of-type + .du-bois-dark-hint,
16586
+ .db-radio-group.db-stack > .db-radio.db-radio:last-of-type + .du-bois-light-form-message,
16587
+ .db-radio-group.db-stack > .db-radio.db-radio:last-of-type + .du-bois-dark-form-message,
16588
+ .db-radio-group.db-stack > .db-radio.db-radio:last-of-type + .du-bois-light-hint + .du-bois-light-form-message,
16589
+ .db-radio-group.db-stack > .db-radio.db-radio:last-of-type + .du-bois-dark-hint + .du-bois-dark-form-message {
16468
16590
  margin-top: 0;
16469
16591
  }
16470
16592
 
16471
- .du-bois-light-hint + .ds-radio-group.ds-radio-group,
16472
- .du-bois-dark-hint + .ds-radio-group.ds-radio-group,
16473
- .ds-radio-group.ds-radio-group + .du-bois-light-form-message,
16474
- .ds-radio-group.ds-radio-group + .du-bois-dark-form-message {
16475
- margin-top: var(--db-space-sm);
16593
+ .du-bois-light-hint + .db-radio-group.db-radio-group,
16594
+ .du-bois-dark-hint + .db-radio-group.db-radio-group,
16595
+ .db-radio-group.db-radio-group + .du-bois-light-form-message,
16596
+ .db-radio-group.db-radio-group + .du-bois-dark-form-message {
16597
+ margin-top: var(--db-spacing-2xs);
16476
16598
  }
16477
16599
 
16478
16600
  /* RadioGroup layout. Vertical (the default) delegates flex-direction to the
16479
- * .ds-stack primitive; horizontal is a two-row grid (mirroring AntD). */
16480
- .ds-radio-group {
16601
+ * .db-stack primitive; horizontal is a two-row grid (mirroring AntD). */
16602
+ .db-radio-group {
16481
16603
  display: flex;
16482
16604
  }
16483
16605
 
16484
- /* Vertical: .ds-stack supplies flex-direction: column. AntD's vertical helper
16606
+ /* Vertical: .db-stack supplies flex-direction: column. AntD's vertical helper
16485
16607
  * (getVerticalRadioGroupStyles) produces its item rhythm purely from
16486
16608
  * `& > label { paddingBottom: sm }` plus the negative-margin hint trick above — it
16487
16609
  * uses NO flex gap. The negative `marginTop` on hints only works if the stack adds
16488
16610
  * no gap of its own, so we zero out the gap and reproduce the rhythm via
16489
16611
  * padding-bottom on each radio. */
16490
- .ds-radio-group.ds-stack {
16491
- --ds-stack-gap: var(--db-space-0);
16612
+ .db-radio-group.db-stack {
16613
+ --db-stack-gap: 0;
16492
16614
  }
16493
16615
 
16494
16616
  /* AntD `& > label { paddingBottom: sm }`. */
16495
- .ds-radio-group.ds-stack > .ds-radio {
16496
- padding-bottom: var(--db-space-sm);
16617
+ .db-radio-group.db-stack > .db-radio {
16618
+ padding-bottom: var(--db-spacing-2xs);
16497
16619
  }
16498
16620
 
16499
16621
  /* AntD `& > label:last-of-type { paddingBottom: 0 }`. */
16500
- .ds-radio-group.ds-stack > .ds-radio:last-of-type {
16622
+ .db-radio-group.db-stack > .db-radio:last-of-type {
16501
16623
  padding-bottom: 0;
16502
16624
  }
16503
16625
 
16504
16626
  /* AntD getVerticalRadioGroupStyles `.${prefix}-radio-tile + .${prefix}-radio-tile {
16505
- * marginTop: md }`: RadioTiles are not matched by the `.ds-radio` padding-bottom
16627
+ * marginTop: md }`: RadioTiles are not matched by the `.db-radio` padding-bottom
16506
16628
  * rhythm above (the tile's own class is du-bois-{light,dark}-radio-tile), so space
16507
- * consecutive tiles explicitly. The .ds-stack gap is 0, so this margin is the spacing. */
16508
- .ds-radio-group.ds-stack > .du-bois-light-radio-tile + .du-bois-light-radio-tile,
16509
- .ds-radio-group.ds-stack > .du-bois-light-radio-tile + .du-bois-dark-radio-tile,
16510
- .ds-radio-group.ds-stack > .du-bois-dark-radio-tile + .du-bois-light-radio-tile,
16511
- .ds-radio-group.ds-stack > .du-bois-dark-radio-tile + .du-bois-dark-radio-tile {
16512
- margin-top: var(--db-space-md);
16629
+ * consecutive tiles explicitly. The .db-stack gap is 0, so this margin is the spacing. */
16630
+ .db-radio-group.db-stack > .du-bois-light-radio-tile + .du-bois-light-radio-tile,
16631
+ .db-radio-group.db-stack > .du-bois-light-radio-tile + .du-bois-dark-radio-tile,
16632
+ .db-radio-group.db-stack > .du-bois-dark-radio-tile + .du-bois-light-radio-tile,
16633
+ .db-radio-group.db-stack > .du-bois-dark-radio-tile + .du-bois-dark-radio-tile {
16634
+ margin-top: var(--db-spacing-xs);
16513
16635
  }
16514
16636
 
16515
16637
  /* Horizontal: AntD `getHorizontalRadioGroupStyles` is a TWO-ROW grid (NOT a flex
@@ -16518,105 +16640,93 @@ span.du-bois-light-typography-ellipsis-single-line {
16518
16640
  * group class here matches that.
16519
16641
  * AntD: `display: grid; gridTemplateRows: [label] auto [hint] auto;
16520
16642
  * gridAutoColumns: max-content; gridColumnGap: md`. */
16521
- .ds-radio-group--horizontal.ds-radio-group--horizontal {
16643
+ .db-radio-group--horizontal.db-radio-group--horizontal {
16522
16644
  display: grid;
16523
16645
  grid-template-rows: [label] auto [hint] auto;
16524
16646
  grid-auto-columns: max-content;
16525
- column-gap: var(--db-space-md);
16647
+ column-gap: var(--db-spacing-xs);
16526
16648
  }
16527
16649
 
16528
16650
  /* Equal column widths: AntD `gridAutoColumns: minmax(0, 1fr)`. */
16529
- .ds-radio-group--horizontal.ds-radio-group--equal-width {
16651
+ .db-radio-group--horizontal.db-radio-group--equal-width {
16530
16652
  grid-auto-columns: minmax(0, 1fr);
16531
16653
  }
16532
16654
 
16533
16655
  /* AntD `& > label, & > .${prefix}-radio-tile { gridRow: label / label; marginRight: 0 }`:
16534
16656
  * every radio (and every RadioTile button, whose own class is
16535
- * du-bois-{light,dark}-radio-tile and is NOT matched by `> .ds-radio`) lives in the
16657
+ * du-bois-{light,dark}-radio-tile and is NOT matched by `> .db-radio`) lives in the
16536
16658
  * label row. grid-auto-flow defaults to row, so successive items advance the implicit
16537
16659
  * column. */
16538
- .ds-radio-group--horizontal > .ds-radio,
16539
- .ds-radio-group--horizontal > .du-bois-light-radio-tile,
16540
- .ds-radio-group--horizontal > .du-bois-dark-radio-tile {
16660
+ .db-radio-group--horizontal > .db-radio,
16661
+ .db-radio-group--horizontal > .du-bois-light-radio-tile,
16662
+ .db-radio-group--horizontal > .du-bois-dark-radio-tile {
16541
16663
  grid-row: label / label;
16542
16664
  margin-inline-end: 0;
16543
16665
  }
16544
16666
 
16545
16667
  /* AntD `& > label + hint { display: inline-block; gridRow: hint / hint }`: a hint
16546
16668
  * following a radio drops into the hint row of the column its radio occupies. The
16547
- * vertical negative-margin rules are scoped to .ds-stack, so nothing to reset here. */
16548
- .ds-radio-group--horizontal > .du-bois-light-hint,
16549
- .ds-radio-group--horizontal > .du-bois-dark-hint {
16669
+ * vertical negative-margin rules are scoped to .db-stack, so nothing to reset here. */
16670
+ .db-radio-group--horizontal > .du-bois-light-hint,
16671
+ .db-radio-group--horizontal > .du-bois-dark-hint {
16550
16672
  display: inline-block;
16551
16673
  grid-row: hint / hint;
16552
16674
  }
16553
16675
 
16554
16676
  /* AntD `:has(> hint) { marginTop: sm }`: when the horizontal group contains a hint,
16555
16677
  * the group itself gets a top margin (room above the two-row grid). */
16556
- .ds-radio-group--horizontal:has(> .du-bois-light-hint),
16557
- .ds-radio-group--horizontal:has(> .du-bois-dark-hint) {
16558
- margin-top: var(--db-space-sm);
16678
+ .db-radio-group--horizontal:has(> .du-bois-light-hint),
16679
+ .db-radio-group--horizontal:has(> .du-bois-dark-hint) {
16680
+ margin-top: var(--db-spacing-2xs);
16559
16681
  }
16560
16682
 
16561
16683
  /* AntD `&& + form-message { marginTop: sm }` (horizontal): a form-message following
16562
16684
  * the whole group is separated by sm. */
16563
- .ds-radio-group--horizontal + .du-bois-light-form-message,
16564
- .ds-radio-group--horizontal + .du-bois-dark-form-message {
16565
- margin-top: var(--db-space-sm);
16685
+ .db-radio-group--horizontal + .du-bois-light-form-message,
16686
+ .db-radio-group--horizontal + .du-bois-dark-form-message {
16687
+ margin-top: var(--db-spacing-2xs);
16566
16688
  }
16567
16689
 
16568
- /* Component-tier tokens for <Switch>. Colors default to the selection-toggle category tokens;
16569
- * geometry is hand-authored (the pill track + sliding thumb are unique to Switch). */
16570
-
16571
- /* Re-declared under both theme classes (not just :root) so the var() chain onto
16572
- * category/system tokens re-resolves inside a `.du-bois-dark` subtree instead of
16573
- * freezing at the root (light) values. See DUBOIS-448 dark-mode scoping. */
16574
- :where(:root, .du-bois-light, .du-bois-dark) {
16575
- --db-switch-track-width: 28px;
16576
- --db-switch-track-height: 16px;
16577
- /* Thumb fills the track height by design; expressed via track-height so the two can't drift. */
16578
- --db-switch-thumb-size: var(--db-switch-track-height);
16579
- /* Pill radius overrides the category (square) radius, mirroring Radio's circular override. */
16690
+ :where(:root), :where(.du-bois-light) {
16691
+ /* Shape */
16580
16692
  --db-switch-border-radius: var(--db-radius-full);
16581
16693
  --db-switch-border-width: 1px;
16582
- --db-switch-spacing: var(--db-selection-toggle-spacing);
16583
16694
 
16584
- --db-switch-bg-default: var(--db-selection-toggle-bg-default);
16585
- --db-switch-bg-hover: var(--db-selection-toggle-bg-hover);
16586
- --db-switch-bg-press: var(--db-selection-toggle-bg-press);
16587
- --db-switch-bg-checked: var(--db-selection-toggle-bg-checked);
16588
- --db-switch-bg-checked-hover: var(--db-selection-toggle-bg-checked-hover);
16589
- --db-switch-bg-checked-press: var(--db-selection-toggle-bg-checked-press);
16590
- --db-switch-bg-disabled: var(--db-selection-toggle-bg-disabled);
16695
+ /* Color */
16696
+ --db-switch-surface: var(--db-selection-toggle-surface);
16697
+ --db-switch-surface-hover: var(--db-color-action-default-background-hover);
16698
+ --db-switch-surface-press: var(--db-color-action-default-background-press);
16699
+ --db-switch-surface-checked: var(--db-selection-toggle-surface-checked);
16700
+ --db-switch-surface-checked-hover: var(--db-selection-toggle-surface-checked-hover);
16701
+ --db-switch-surface-checked-press: var(--db-selection-toggle-surface-checked-press);
16702
+ --db-switch-surface-disabled: var(--db-selection-toggle-surface-disabled);
16703
+ --db-switch-surface-checked-disabled: var(--db-color-action-disabled-text);
16591
16704
 
16592
- --db-switch-border-default: var(--db-selection-toggle-border-default);
16705
+ --db-switch-border: var(--db-color-action-default-border-default);
16593
16706
  --db-switch-border-hover: var(--db-selection-toggle-border-hover);
16594
16707
  --db-switch-border-press: var(--db-selection-toggle-border-press);
16595
- --db-switch-border-disabled: var(--db-selection-toggle-border-disabled);
16596
- /* AntD paints the checked track border equal to the checked fill, so these alias the checked bg. */
16597
- --db-switch-border-checked: var(--db-selection-toggle-bg-checked);
16598
- --db-switch-border-checked-hover: var(--db-selection-toggle-bg-checked-hover);
16599
- --db-switch-border-checked-press: var(--db-selection-toggle-bg-checked-press);
16600
- --db-switch-border-focus: var(--db-selection-toggle-bg-checked);
16601
- /* AntD fills the disabled+checked track with actionDisabledText; no category token matches, so
16602
- * reference the system token directly (same escape hatch Radio uses for its checked-press border). */
16603
- --db-switch-bg-checked-disabled: var(--db-color-action-disabled-text);
16604
-
16605
- /* AntD paints the handle the off-track surface color in every state. */
16606
- --db-switch-thumb-color: var(--db-selection-toggle-bg-default);
16607
-
16608
- /* A token (not inherit) so the label text flips in dark mode. */
16609
- --db-switch-text: var(--db-color-text-primary);
16708
+ --db-switch-border-disabled: var(--db-color-action-disabled-border);
16709
+ --db-switch-border-checked: var(--db-selection-toggle-surface-checked);
16710
+ --db-switch-border-checked-hover: var(--db-selection-toggle-surface-checked-hover);
16711
+ --db-switch-border-checked-press: var(--db-selection-toggle-surface-checked-press);
16712
+ --db-switch-border-focus: var(--db-selection-toggle-surface-checked);
16713
+
16714
+ --db-switch-thumb: var(--db-selection-toggle-surface);
16715
+
16716
+ --db-switch-text: var(--db-selection-toggle-text);
16610
16717
  --db-switch-text-disabled: var(--db-selection-toggle-text-disabled);
16611
16718
 
16612
- /* AntD's focus ring is a 1px outline (the category default is 2px). */
16613
- --db-switch-focus-ring-width: 1px;
16614
- --db-switch-focus-ring-offset: 1px;
16615
- --db-switch-focus-ring-color: var(--db-selection-toggle-border-focus);
16719
+ /* Density */
16720
+ --db-switch-track-width: calc(var(--db-size-xs) * 1.75); /* 28px */
16721
+ --db-switch-track-height: var(--db-size-xs); /* 16px */
16722
+ --db-switch-thumb-size: var(--db-switch-track-height);
16723
+ --db-switch-label-spacing: var(--db-selection-toggle-label-spacing);
16724
+
16725
+ /* Motion */
16616
16726
  --db-switch-transition-duration: var(--db-selection-toggle-transition-duration);
16617
16727
  }
16618
16728
 
16619
- .ds-switch {
16729
+ .db-switch {
16620
16730
  /* flex, not inline-flex: an inline-flex root's line-box leading pushes block siblings
16621
16731
  * (e.g. a following FormMessage) down a few px, breaking the form-flow spacing. */
16622
16732
  display: flex;
@@ -16624,15 +16734,15 @@ span.du-bois-light-typography-ellipsis-single-line {
16624
16734
  cursor: pointer;
16625
16735
  user-select: none;
16626
16736
  width: fit-content;
16627
- margin-inline-end: var(--db-switch-spacing);
16737
+ margin-inline-end: var(--db-switch-label-spacing);
16628
16738
  }
16629
16739
 
16630
- .ds-switch:has(input:disabled) {
16740
+ .db-switch:has(input:disabled) {
16631
16741
  cursor: not-allowed;
16632
16742
  }
16633
16743
 
16634
16744
  /* The track. `appearance: none` strips the native checkbox rendering so the input itself can be styled. */
16635
- .ds-switch input {
16745
+ .db-switch input {
16636
16746
  appearance: none;
16637
16747
  position: relative;
16638
16748
  flex-shrink: 0;
@@ -16640,9 +16750,9 @@ span.du-bois-light-typography-ellipsis-single-line {
16640
16750
  cursor: pointer;
16641
16751
  inline-size: var(--db-switch-track-width);
16642
16752
  block-size: var(--db-switch-track-height);
16643
- border: var(--db-switch-border-width) solid var(--db-switch-border-default);
16753
+ border: var(--db-switch-border-width) solid var(--db-switch-border);
16644
16754
  border-radius: var(--db-switch-border-radius);
16645
- background-color: var(--db-switch-bg-default);
16755
+ background-color: var(--db-switch-surface);
16646
16756
  box-sizing: border-box;
16647
16757
  transition:
16648
16758
  background-color var(--db-switch-transition-duration) ease,
@@ -16651,7 +16761,7 @@ span.du-bois-light-typography-ellipsis-single-line {
16651
16761
 
16652
16762
  /* The thumb. A pseudo-element keeps the input the switch's only element, so nothing can overlay it
16653
16763
  * and intercept clicks. Offset left by the border width to sit flush with the track's outer edge. */
16654
- .ds-switch input::before {
16764
+ .db-switch input::before {
16655
16765
  content: '';
16656
16766
  position: absolute;
16657
16767
  top: 50%;
@@ -16661,110 +16771,112 @@ span.du-bois-light-typography-ellipsis-single-line {
16661
16771
  border: var(--db-switch-border-width) solid;
16662
16772
  border-color: inherit;
16663
16773
  border-radius: var(--db-switch-border-radius);
16664
- background-color: var(--db-switch-thumb-color);
16774
+ background-color: var(--db-switch-thumb);
16665
16775
  box-sizing: border-box;
16666
16776
  transform: translateY(-50%);
16667
16777
  transition: transform var(--db-switch-transition-duration) ease;
16668
16778
  }
16669
16779
 
16670
16780
  /* `<label for>` propagates `:hover` to the input, so scope hover/press to the control, not `input:hover`. */
16671
- .ds-switch:hover input:not(:disabled):not(:checked) {
16672
- background-color: var(--db-switch-bg-hover);
16781
+ .db-switch:hover input:not(:disabled):not(:checked) {
16782
+ background-color: var(--db-switch-surface-hover);
16673
16783
  border-color: var(--db-switch-border-hover);
16674
16784
  }
16675
16785
 
16676
- .ds-switch:active input:not(:disabled):not(:checked) {
16677
- background-color: var(--db-switch-bg-press);
16786
+ .db-switch:active input:not(:disabled):not(:checked) {
16787
+ background-color: var(--db-switch-surface-press);
16678
16788
  border-color: var(--db-switch-border-press);
16679
16789
  }
16680
16790
 
16681
- .ds-switch input:checked {
16682
- background-color: var(--db-switch-bg-checked);
16791
+ .db-switch input:checked {
16792
+ background-color: var(--db-switch-surface-checked);
16683
16793
  border-color: var(--db-switch-border-checked);
16684
16794
  }
16685
16795
 
16686
- .ds-switch:hover input:checked:not(:disabled) {
16687
- background-color: var(--db-switch-bg-checked-hover);
16796
+ .db-switch:hover input:checked:not(:disabled) {
16797
+ background-color: var(--db-switch-surface-checked-hover);
16688
16798
  border-color: var(--db-switch-border-checked-hover);
16689
16799
  }
16690
16800
 
16691
- .ds-switch:active input:checked:not(:disabled) {
16692
- background-color: var(--db-switch-bg-checked-press);
16801
+ .db-switch:active input:checked:not(:disabled) {
16802
+ background-color: var(--db-switch-surface-checked-press);
16693
16803
  border-color: var(--db-switch-border-checked-press);
16694
16804
  }
16695
16805
 
16696
- .ds-switch input:checked::before {
16806
+ .db-switch input:checked::before {
16697
16807
  transform: translateY(-50%) translateX(calc(var(--db-switch-track-width) - var(--db-switch-thumb-size)));
16698
16808
  }
16699
16809
 
16700
16810
  /* On focus, recolor the border to the checked-fill color on top of the outline ring. Matching AntD,
16701
- * the ring sits flush when off and gains a 1px offset when checked. */
16702
- .ds-switch input:focus-visible {
16811
+ * the ring sits flush when off and gains a 1px offset when checked.
16812
+ * TODO: width/offset are hardcoded 1px to preserve the AntD look; adopt the system 2px focus ring
16813
+ * (var(--db-focus-ring-width)) in a separate change. */
16814
+ .db-switch input:focus-visible {
16703
16815
  border-color: var(--db-switch-border-focus);
16704
- outline: var(--db-switch-focus-ring-width) solid var(--db-switch-focus-ring-color);
16816
+ outline: 1px solid var(--db-focus-ring-color);
16705
16817
  outline-offset: 0;
16706
16818
  }
16707
16819
 
16708
- .ds-switch input:checked:focus-visible {
16709
- outline-offset: var(--db-switch-focus-ring-offset);
16820
+ .db-switch input:checked:focus-visible {
16821
+ outline-offset: 1px;
16710
16822
  }
16711
16823
 
16712
- .ds-switch input:disabled {
16824
+ .db-switch input:disabled {
16713
16825
  cursor: not-allowed;
16714
- background-color: var(--db-switch-bg-disabled);
16826
+ background-color: var(--db-switch-surface-disabled);
16715
16827
  border-color: var(--db-switch-border-disabled);
16716
16828
  }
16717
16829
 
16718
16830
  /* Disabled + on: more specific than the plain disabled rule, so it wins regardless of source order. */
16719
- .ds-switch input:checked:disabled {
16720
- background-color: var(--db-switch-bg-checked-disabled);
16721
- border-color: var(--db-switch-bg-checked-disabled);
16831
+ .db-switch input:checked:disabled {
16832
+ background-color: var(--db-switch-surface-checked-disabled);
16833
+ border-color: var(--db-switch-surface-checked-disabled);
16722
16834
  }
16723
16835
 
16724
16836
  @media (prefers-reduced-motion: reduce) {
16725
- .ds-switch input,
16726
- .ds-switch input::before {
16837
+ .db-switch input,
16838
+ .db-switch input::before {
16727
16839
  transition: none;
16728
16840
  }
16729
16841
  }
16730
16842
 
16731
- .ds-switch-wrapper {
16843
+ .db-switch-wrapper {
16732
16844
  display: flex;
16733
16845
  align-items: center;
16734
16846
  }
16735
16847
 
16736
- .ds-switch-wrapper .ds-switch-state-message {
16848
+ .db-switch-wrapper .db-switch-state-message {
16737
16849
  margin-inline-start: auto;
16738
- margin-inline-end: var(--db-switch-spacing);
16850
+ margin-inline-end: var(--db-switch-label-spacing);
16739
16851
  }
16740
16852
 
16741
16853
  /* `:first-child` scopes this to the label-first layout; the plain layout renders the label last. */
16742
- .ds-switch-wrapper > .du-bois-light-label:first-child,
16743
- .ds-switch-wrapper > .du-bois-dark-label:first-child {
16744
- margin-inline-end: var(--db-switch-spacing);
16854
+ .db-switch-wrapper > .du-bois-light-label:first-child,
16855
+ .db-switch-wrapper > .du-bois-dark-label:first-child {
16856
+ margin-inline-end: var(--db-switch-label-spacing);
16745
16857
  }
16746
16858
 
16747
- .ds-switch-state-message {
16859
+ .db-switch-state-message {
16748
16860
  color: var(--db-switch-text);
16749
16861
  }
16750
16862
 
16751
- /* Target the <Label>'s class, not a bare `label` — that would also match the .ds-switch root <label>. */
16752
- .ds-switch-wrapper:has(input:disabled) .du-bois-light-label,
16753
- .ds-switch-wrapper:has(input:disabled) .du-bois-dark-label {
16863
+ /* Target the <Label>'s class, not a bare `label` — that would also match the .db-switch root <label>. */
16864
+ .db-switch-wrapper:has(input:disabled) .du-bois-light-label,
16865
+ .db-switch-wrapper:has(input:disabled) .du-bois-dark-label {
16754
16866
  color: var(--db-switch-text-disabled);
16755
16867
  }
16756
16868
 
16757
16869
  /* Indent a following hint/message past the track. The class is doubled to out-specify FormMessage's
16758
16870
  * own margin rule. */
16759
- :is(.ds-switch.ds-switch, .ds-switch-wrapper.ds-switch-wrapper)
16760
- + :is(.du-bois-light-hint, .du-bois-dark-hint, .du-bois-light-form-message, .du-bois-dark-form-message), :is(.ds-switch.ds-switch, .ds-switch-wrapper.ds-switch-wrapper)
16871
+ :is(.db-switch.db-switch, .db-switch-wrapper.db-switch-wrapper)
16872
+ + :is(.du-bois-light-hint, .du-bois-dark-hint, .du-bois-light-form-message, .du-bois-dark-form-message), :is(.db-switch.db-switch, .db-switch-wrapper.db-switch-wrapper)
16761
16873
  + :is(.du-bois-light-hint, .du-bois-dark-hint)
16762
16874
  + :is(.du-bois-light-form-message, .du-bois-dark-form-message) {
16763
- padding-inline-start: calc(var(--db-space-sm) + var(--db-switch-track-width));
16875
+ padding-inline-start: calc(var(--db-spacing-2xs) + var(--db-switch-track-width));
16764
16876
  }
16765
16877
 
16766
- :is(.ds-switch.ds-switch, .ds-switch-wrapper.ds-switch-wrapper)
16767
- + :is(.du-bois-light-form-message, .du-bois-dark-form-message), :is(.ds-switch.ds-switch, .ds-switch-wrapper.ds-switch-wrapper)
16878
+ :is(.db-switch.db-switch, .db-switch-wrapper.db-switch-wrapper)
16879
+ + :is(.du-bois-light-form-message, .du-bois-dark-form-message), :is(.db-switch.db-switch, .db-switch-wrapper.db-switch-wrapper)
16768
16880
  + :is(.du-bois-light-hint, .du-bois-dark-hint)
16769
16881
  + :is(.du-bois-light-form-message, .du-bois-dark-form-message) {
16770
16882
  margin-top: 0;