@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
package/dist/index.css CHANGED
@@ -15836,7 +15836,7 @@ span.du-bois-light-typography-ellipsis-single-line {
15836
15836
  * Source: design-system/src/theme/tokens/*.json
15837
15837
  * Regenerate via: yarn theme-regenerate */
15838
15838
 
15839
- :where(:root, .du-bois-light) {
15839
+ :where(:root), :where(.du-bois-light) {
15840
15840
  --db-radius-0: 0px;
15841
15841
  --db-radius-full: 999px;
15842
15842
  --db-radius-lg: 12px;
@@ -15975,142 +15975,273 @@ span.du-bois-light-typography-ellipsis-single-line {
15975
15975
  * Source: design-system/src/theme/tokens/*.json
15976
15976
  * Regenerate via: yarn theme-regenerate */
15977
15977
 
15978
- /* Layout primitive classes — internal Du Bois use for now (not a published
15979
- * consumer API yet; see the Stefan/Sheng weekly decision to "give it a try
15980
- * just within the Du Bois components"). Two primitives, both plain CSS so they
15981
- * ride the mortar cascade like the other component styles:
15982
- *
15983
- * .ds-stack — vertical flow, even gap between direct children.
15984
- * .ds-cluster — horizontal group that wraps, even gap between children.
15985
- *
15986
- * Each primitive exposes a small set of `--ds-*` knobs, defaulted on the class
15987
- * itself (not via a `var()` fallback, which would freeze the default at every
15988
- * call site). Override any of them on the element — inline
15989
- * `style={{ '--ds-stack-gap': ... }}` or a more specific selector — without a
15990
- * new modifier class:
15991
- *
15992
- * stack: --ds-stack-gap (spacing), --ds-stack-align (align-items)
15993
- * cluster: --ds-cluster-gap (spacing), --ds-cluster-align (align-items),
15994
- * --ds-cluster-justify (justify-content)
15995
- *
15996
- * Gap defaults point at the system spacing scale (`--db-space-*`). Padding is
15997
- * intentionally NOT a knob — a layout primitive owns the space between children,
15998
- * not its own box padding. */
15978
+ /*
15979
+ Vertical "stack" of elements.
15980
+ Use this for any layout where items are laid out vertically.
15981
+
15982
+ \3c !-- Basic: default gap between each child -->
15983
+ <div class="db-stack">
15984
+ <h2>Title</h2>
15985
+ <p>Body</p>
15986
+ <button>Action</button>
15987
+ </div>
15988
+
15989
+ \3c !-- Wider gap for this instance -->
15990
+ <div class="db-stack" style="--db-stack-gap: var(--db-spacing-lg)">…</div>
15991
+
15992
+ \3c !-- Don't stretch children to full width (e.g. left-aligned buttons) -->
15993
+ <div class="db-stack" style="--db-stack-align: flex-start">…</div>
15994
+ */
15995
+ .db-stack {
15996
+ /* These variables act as the *parameters* for the stack instance. */
15997
+ --db-stack-gap: var(--db-spacing-xs);
15998
+ --db-stack-align: stretch;
15999
15999
 
16000
- .ds-stack {
16001
- --ds-stack-gap: var(--db-space-md);
16002
- --ds-stack-align: stretch;
16003
16000
  display: flex;
16004
16001
  flex-direction: column;
16005
- align-items: var(--ds-stack-align);
16006
- gap: var(--ds-stack-gap);
16002
+ align-items: var(--db-stack-align);
16003
+ gap: var(--db-stack-gap);
16007
16004
  }
16008
16005
 
16009
- /* Cluster wraps by design: a long row reflows onto multiple lines rather than
16010
- * overflowing. A row that must NOT wrap (e.g. a single-line control strip) is
16011
- * not a cluster keep it bespoke. */
16012
- .ds-cluster {
16013
- --ds-cluster-gap: var(--db-space-sm);
16014
- --ds-cluster-align: center;
16015
- --ds-cluster-justify: flex-start;
16006
+ /**
16007
+ Responsive, horizontal "cluster" of elements.
16008
+ Use this for any layout where items are laid out horizontally and should wrap on smaller viewport sizes.
16009
+
16010
+ \3c !-- Basic: items wrap as needed -->
16011
+ <div class="db-cluster">
16012
+ <span>one</span>
16013
+ <span>two</span>
16014
+ <span>three</span>
16015
+ </div>
16016
+
16017
+ \3c !-- Push children apart (e.g. title left, actions right) -->
16018
+ <div class="db-cluster" style="--db-cluster-justify: space-between">…</div>
16019
+
16020
+ \3c !-- Looser gap for this instance -->
16021
+ <div class="db-cluster" style="--db-cluster-gap: var(--db-spacing-sm)">…</div>
16022
+ */
16023
+ .db-cluster {
16024
+ /* These variables act as the *parameters* for the cluster instance. */
16025
+ --db-cluster-gap: var(--db-spacing-2xs);
16026
+ --db-cluster-align: center;
16027
+ --db-cluster-justify: flex-start;
16028
+
16016
16029
  display: flex;
16017
16030
  flex-wrap: wrap;
16018
- align-items: var(--ds-cluster-align);
16019
- justify-content: var(--ds-cluster-justify);
16020
- gap: var(--ds-cluster-gap);
16031
+ align-items: var(--db-cluster-align);
16032
+ justify-content: var(--db-cluster-justify);
16033
+ gap: var(--db-cluster-gap);
16021
16034
  }
16022
16035
 
16023
- /* Category-tier tokens shared by selection-control components:
16024
- * <Checkbox>, <Switch>, <Radio>. Each value here references a SYSTEM token
16025
- * from system-tokens.css — never a raw hex/px literal — so the only place a
16026
- * brand-level theme change has to land is the system tier.
16027
- *
16028
- * Component-tier files (e.g. design-system/Checkbox/tokens.css) inherit from
16029
- * these via `var()` so consumers can override a single selection control by
16030
- * targeting only its component tokens. */
16036
+ :where(:root), :where(.du-bois-light) {
16037
+ /* Neutral */
16038
+ --db-neutral-surface: var(--db-color-background-primary);
16039
+ --db-subtle-neutral-surface: var(--db-color-background-secondary);
16040
+ --db-strong-neutral-surface: initial; /* TODO */
16041
+
16042
+ --db-text-on-neutral-surface: var(--db-color-text-primary);
16043
+ --db-subtle-text-on-neutral-surface: var(--db-color-text-secondary);
16044
+ --db-strong-text-on-neutral-surface: initial; /* TODO */
16045
+
16046
+ --db-neutral-border: var(--db-color-border);
16047
+ --db-subtle-neutral-border: initial; /* TODO */
16048
+ --db-strong-neutral-border: var(--db-color-border-accessible);
16049
+
16050
+ --db-neutral-surface-active: var(--db-color-table-background-selected-default);
16051
+ --db-neutral-surface-hover: var(--db-color-table-background-unselected-hover);
16052
+ --db-neutral-surface-pressed: var(--db-color-table-background-selected-hover);
16053
+ --db-neutral-surface-disabled: var(--db-color-action-disabled-background);
16054
+ --db-text-on-neutral-surface-disabled: var(--db-color-action-disabled-text);
16055
+
16056
+ /* Primary */
16057
+ --db-primary-surface: var(--db-color-action-primary-background-default);
16058
+ --db-subtle-primary-surface: var(--db-color-action-default-background-hover);
16059
+ --db-strong-primary-surface: var(--db-color-action-primary-background-hover);
16060
+
16061
+ --db-text-on-primary-surface: var(--db-color-action-primary-text-default);
16062
+ --db-primary-text-on-neutral-surface: var(--db-color-action-link-default);
16063
+ --db-subtle-text-on-primary-surface: initial; /* TODO */
16064
+ --db-strong-text-on-primary-surface: var(--db-color-action-primary-text-default);
16065
+
16066
+ --db-primary-border: var(--db-color-action-primary-background-default);
16067
+ --db-subtle-primary-border: initial; /* TODO */
16068
+ --db-strong-primary-border: var(--db-color-action-primary-background-press);
16069
+
16070
+ --db-primary-surface-active: initial; /* TODO */
16071
+ --db-primary-surface-hover: var(--db-color-action-primary-background-hover);
16072
+ --db-primary-surface-pressed: var(--db-color-action-primary-background-press);
16073
+ --db-primary-surface-disabled: var(--db-color-action-disabled-background);
16074
+ --db-text-on-primary-surface-disabled: var(--db-color-action-disabled-text);
16075
+
16076
+ /* Error */
16077
+ --db-error-surface: var(--db-color-action-danger-primary-background-default);
16078
+ --db-subtle-error-surface: var(--db-color-background-danger);
16079
+ --db-strong-error-surface: var(--db-color-action-danger-primary-background-hover);
16080
+
16081
+ --db-text-on-error-surface: var(--db-color-action-danger-primary-text);
16082
+ --db-error-text-on-neutral-surface: var(--db-color-text-validation-danger);
16083
+ --db-subtle-text-on-error-surface: initial; /* TODO */
16084
+ --db-strong-text-on-error-surface: var(--db-color-action-danger-primary-text);
16085
+
16086
+ --db-error-border: var(--db-color-action-danger-default-border-default);
16087
+ --db-subtle-error-border: var(--db-color-border-danger);
16088
+ --db-strong-error-border: var(--db-color-action-danger-primary-background-press);
16089
+
16090
+ --db-error-surface-active: initial; /* TODO */
16091
+ --db-error-surface-hover: var(--db-color-action-danger-primary-background-hover);
16092
+ --db-error-surface-pressed: var(--db-color-action-danger-primary-background-press);
16093
+ --db-error-surface-disabled: var(--db-color-action-disabled-background);
16094
+ --db-text-on-error-surface-disabled: var(--db-color-action-disabled-text);
16095
+
16096
+ /* Warning */
16097
+ --db-warning-surface: initial; /* TODO */
16098
+ --db-subtle-warning-surface: var(--db-color-background-warning);
16099
+
16100
+ --db-text-on-warning-surface: initial; /* TODO */
16101
+ --db-warning-text-on-neutral-surface: var(--db-color-text-validation-warning);
16102
+
16103
+ --db-warning-border: var(--db-color-border-warning);
16104
+
16105
+ /* Success */
16106
+ --db-success-surface: initial; /* TODO */
16107
+ --db-subtle-success-surface: var(--db-color-background-success);
16108
+
16109
+ --db-text-on-success-surface: initial; /* TODO */
16110
+ --db-success-text-on-neutral-surface: var(--db-color-text-validation-success);
16111
+
16112
+ --db-success-border: initial; /* TODO */
16113
+ }
16114
+
16115
+
16116
+
16117
+ :where(:root), :where(.du-bois-light) {
16118
+ --db-layout-unit: 0.25rem; /* 4px */
16119
+ --db-density-scalar: 1;
16120
+ --db-size-scalar: 1;
16121
+ --db-spacing-scalar: 1;
16122
+
16123
+ /* Size and spacing are the same steps, but with their own scalars included in the calc. */
16031
16124
 
16032
- /* Re-declared under both theme classes as well as :root: these values are
16033
- * `var()` indirections onto SYSTEM tokens, and a custom property resolves its
16034
- * var() at its DECLARATION site. Declared only at :root, they would freeze at
16035
- * the root (light) system values and never re-read the dark system tokens
16036
- * inside a `.du-bois-dark` subtree. Re-declaring at every theme boundary makes
16037
- * the indirection re-resolve per theme. See DUBOIS-448 dark-mode scoping. */
16038
- :where(:root, .du-bois-light, .du-bois-dark) {
16039
- --db-selection-toggle-bg-default: var(--db-color-background-primary);
16040
- --db-selection-toggle-bg-hover: var(--db-color-action-default-background-hover);
16041
- --db-selection-toggle-bg-press: var(--db-color-action-default-background-press);
16042
- --db-selection-toggle-bg-checked: var(--db-color-action-primary-background-default);
16043
- --db-selection-toggle-bg-checked-hover: var(--db-color-action-primary-background-hover);
16044
- --db-selection-toggle-bg-checked-press: var(--db-color-action-primary-background-press);
16045
- --db-selection-toggle-bg-disabled: var(--db-color-action-disabled-background);
16125
+ --db-size-3xs: calc(var(--db-layout-unit) * 1 * var(--db-density-scalar) * var(--db-size-scalar)); /* 4px */
16126
+ --db-size-2xs: calc(var(--db-layout-unit) * 2 * var(--db-density-scalar) * var(--db-size-scalar)); /* 8px */
16127
+ --db-size-xs: calc(var(--db-layout-unit) * 4 * var(--db-density-scalar) * var(--db-size-scalar)); /* 16px */
16128
+ --db-size-sm: calc(var(--db-layout-unit) * 6 * var(--db-density-scalar) * var(--db-size-scalar)); /* 24px */
16129
+ --db-size-md: calc(var(--db-layout-unit) * 8 * var(--db-density-scalar) * var(--db-size-scalar)); /* 32px */
16130
+ --db-size-lg: calc(var(--db-layout-unit) * 10 * var(--db-density-scalar) * var(--db-size-scalar)); /* 40px */
16046
16131
 
16047
- --db-selection-toggle-border-default: var(--db-color-action-default-border-default);
16048
- --db-selection-toggle-border-hover: var(--db-color-action-primary-background-hover);
16049
- --db-selection-toggle-border-press: var(--db-color-action-primary-background-press);
16050
- --db-selection-toggle-border-focus: var(--db-color-action-default-border-focus);
16051
- --db-selection-toggle-border-disabled: var(--db-color-action-disabled-border);
16132
+ --db-spacing-3xs: calc(var(--db-layout-unit) * 1 * var(--db-density-scalar) * var(--db-spacing-scalar)); /* 4px */
16133
+ --db-spacing-2xs: calc(var(--db-layout-unit) * 2 * var(--db-density-scalar) * var(--db-spacing-scalar)); /* 8px */
16134
+ --db-spacing-xs: calc(var(--db-layout-unit) * 4 * var(--db-density-scalar) * var(--db-spacing-scalar)); /* 16px */
16135
+ --db-spacing-sm: calc(var(--db-layout-unit) * 6 * var(--db-density-scalar) * var(--db-spacing-scalar)); /* 24px */
16136
+ --db-spacing-md: calc(var(--db-layout-unit) * 8 * var(--db-density-scalar) * var(--db-spacing-scalar)); /* 32px */
16137
+ --db-spacing-lg: calc(var(--db-layout-unit) * 10 * var(--db-density-scalar) * var(--db-spacing-scalar)); /* 40px */
16138
+ }
16139
+
16140
+ :where(:root), :where(.du-bois-light) {
16141
+ --db-font-family:
16142
+ "DM Sans", -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, sans-serif;
16143
+ --db-mono-font-family: ui-monospace, SFMono-Regular, Menlo, monospace;
16144
+
16145
+ --db-font-size-2xs: 0.6875rem; /* 11px */
16146
+ --db-font-size-xs: 0.75rem; /* 12px */
16147
+ --db-font-size-base: 0.8125rem; /* 13px */
16148
+ --db-font-size-md: 0.875rem; /* 14px */
16149
+ --db-font-size-lg: 0.9375rem; /* 15px */
16150
+ --db-font-size-xl: 1rem; /* 16px */
16151
+ --db-font-size-2xl: 1.25rem; /* 20px */
16152
+ --db-font-size-3xl: 1.5rem; /* 24px */
16153
+ --db-font-size-4xl: 2rem; /* 32px */
16154
+
16155
+ /* Du Bois v1 ships 400 and 600 only */
16156
+ --db-font-weight-normal: 400;
16157
+ --db-font-weight-medium: initial; /* TODO */
16158
+ --db-font-weight-semibold: 600;
16159
+ --db-font-weight-bold: initial; /* TODO */
16160
+ }
16161
+
16162
+ :where(:root), :where(.du-bois-light) {
16163
+ --db-elevation-inset: initial; /* TODO */
16164
+ --db-elevation-low: 0px 2px 3px -1px rgba(0, 0, 0, 0.05), 0px 1px 0px 0px rgba(0, 0, 0, 0.02);
16165
+ --db-elevation-med: 0px 2px 16px 0px rgba(0, 0, 0, 0.08);
16166
+ --db-elevation-high: 0px 8px 40px 0px rgba(0, 0, 0, 0.13);
16167
+ }
16168
+
16169
+ :where(:root), :where(.du-bois-light) {
16170
+ --db-focus-ring-color: var(--db-color-action-default-border-focus);
16171
+ --db-focus-ring-width: 2px;
16172
+ }
16173
+
16174
+ :where(:root), :where(.du-bois-light) {
16175
+ /* Shape */
16176
+ --db-selection-toggle-border-radius: 4px;
16052
16177
 
16053
- /* Raw literal, not a system token (exception to the file rule above): the mark
16054
- * sits on the theme-invariant blue checked fill, so it must stay white in BOTH
16055
- * themes. No non-flipping white system token exists — action-primary-icon flips
16056
- * to near-black under .du-bois-dark, which made the mark nearly invisible. */
16057
- --db-selection-toggle-icon-color: #ffffff;
16058
- --db-selection-toggle-icon-color-disabled: var(--db-color-action-disabled-text);
16059
- --db-selection-toggle-text: var(--db-color-text-primary);
16060
- --db-selection-toggle-text-disabled: var(--db-color-action-disabled-text);
16178
+ /* Color */
16179
+ --db-selection-toggle-surface: var(--db-neutral-surface);
16180
+ --db-selection-toggle-mark: var(--db-text-on-primary-surface);
16181
+ --db-selection-toggle-text: var(--db-text-on-neutral-surface);
16182
+ --db-selection-toggle-border: var(--db-strong-neutral-border);
16061
16183
 
16062
- --db-selection-toggle-size: 16px;
16063
- --db-selection-toggle-border-radius: var(--db-radius-sm);
16064
- --db-selection-toggle-spacing: var(--db-space-sm);
16184
+ --db-selection-toggle-surface-hover: var(--db-neutral-surface-hover);
16185
+ --db-selection-toggle-surface-press: var(--db-neutral-surface-pressed);
16186
+ --db-selection-toggle-surface-checked: var(--db-primary-surface);
16187
+ --db-selection-toggle-surface-checked-hover: var(--db-primary-surface-hover);
16188
+ --db-selection-toggle-surface-checked-press: var(--db-primary-surface-pressed);
16189
+ --db-selection-toggle-surface-disabled: var(--db-neutral-surface-disabled);
16190
+ --db-selection-toggle-surface-checked-disabled: var(--db-neutral-surface-disabled);
16191
+
16192
+ --db-selection-toggle-border-hover: var(--db-primary-surface-hover);
16193
+ --db-selection-toggle-border-press: var(--db-primary-surface-pressed);
16194
+ --db-selection-toggle-border-disabled: var(--db-neutral-border);
16195
+
16196
+ --db-selection-toggle-mark-disabled: var(--db-text-on-neutral-surface-disabled);
16197
+ --db-selection-toggle-text-disabled: var(--db-text-on-neutral-surface-disabled);
16065
16198
 
16066
- /* Focus ring matches AntD legacy variant; offset keeps it outside the toggle.
16067
- * Hard-coded for now — Figma export doesn't include shadow tokens. */
16068
16199
  --db-selection-toggle-shadow-checked: 0 0 0 1px var(--db-color-action-primary-background-default);
16069
- --db-selection-toggle-focus-ring-width: 2px;
16070
- --db-selection-toggle-focus-ring-offset: 2px;
16200
+
16201
+ /* Density */
16202
+ --db-selection-toggle-size: var(--db-size-xs);
16203
+ --db-selection-toggle-label-spacing: var(--db-spacing-2xs);
16204
+
16205
+ /* Motion */
16071
16206
  --db-selection-toggle-transition-duration: 120ms;
16072
16207
  }
16073
16208
 
16074
- /* Component-tier tokens for <Checkbox>. Each value defaults to a CATEGORY
16075
- * (selection-toggle) token via var(); consumers can override here to retheme
16076
- * checkboxes without affecting switch / radio. */
16077
-
16078
- /* Re-declared under both theme classes (not just :root) so the var() chain onto
16079
- * category/system tokens re-resolves inside a `.du-bois-dark` subtree instead of
16080
- * freezing at the root (light) values. See DUBOIS-448 dark-mode scoping. */
16081
- :where(:root, .du-bois-light, .du-bois-dark) {
16082
- --db-checkbox-size: var(--db-selection-toggle-size);
16209
+ :where(:root), :where(.du-bois-light) {
16210
+ /* Shape */
16083
16211
  --db-checkbox-border-radius: var(--db-selection-toggle-border-radius);
16084
16212
  --db-checkbox-border-width: 1px;
16085
- --db-checkbox-spacing: var(--db-selection-toggle-spacing);
16086
16213
 
16087
- --db-checkbox-bg-default: var(--db-selection-toggle-bg-default);
16088
- --db-checkbox-bg-hover: var(--db-selection-toggle-bg-hover);
16089
- --db-checkbox-bg-press: var(--db-selection-toggle-bg-press);
16090
- --db-checkbox-bg-checked: var(--db-selection-toggle-bg-checked);
16091
- --db-checkbox-bg-checked-hover: var(--db-selection-toggle-bg-checked-hover);
16092
- --db-checkbox-bg-checked-press: var(--db-selection-toggle-bg-checked-press);
16093
- --db-checkbox-bg-disabled: var(--db-selection-toggle-bg-disabled);
16214
+ /* Color */
16215
+ --db-checkbox-surface: var(--db-selection-toggle-surface);
16216
+ --db-checkbox-surface-hover: var(--db-color-action-default-background-hover);
16217
+ --db-checkbox-surface-press: var(--db-color-action-default-background-press);
16218
+ --db-checkbox-surface-checked: var(--db-selection-toggle-surface-checked);
16219
+ --db-checkbox-surface-checked-hover: var(--db-selection-toggle-surface-checked-hover);
16220
+ --db-checkbox-surface-checked-press: var(--db-selection-toggle-surface-checked-press);
16221
+ --db-checkbox-surface-disabled: var(--db-selection-toggle-surface-disabled);
16094
16222
 
16095
- --db-checkbox-border-default: var(--db-selection-toggle-border-default);
16223
+ --db-checkbox-border: var(--db-color-action-default-border-default);
16096
16224
  --db-checkbox-border-hover: var(--db-selection-toggle-border-hover);
16097
16225
  --db-checkbox-border-press: var(--db-selection-toggle-border-press);
16098
- --db-checkbox-border-focus: var(--db-selection-toggle-border-focus);
16099
- --db-checkbox-border-disabled: var(--db-selection-toggle-border-disabled);
16226
+ --db-checkbox-focus-ring: var(--db-focus-ring-color);
16227
+ --db-checkbox-border-disabled: var(--db-color-action-disabled-border);
16100
16228
 
16101
- --db-checkbox-icon-color: var(--db-selection-toggle-icon-color);
16102
- --db-checkbox-icon-color-disabled: var(--db-selection-toggle-icon-color-disabled);
16229
+ --db-checkbox-mark: #ffffff;
16230
+ --db-checkbox-mark-disabled: var(--db-selection-toggle-mark-disabled);
16103
16231
  --db-checkbox-text: var(--db-selection-toggle-text);
16104
16232
  --db-checkbox-text-disabled: var(--db-selection-toggle-text-disabled);
16105
16233
 
16106
16234
  --db-checkbox-shadow-checked: var(--db-selection-toggle-shadow-checked);
16107
- --db-checkbox-focus-ring-width: var(--db-selection-toggle-focus-ring-width);
16108
- --db-checkbox-focus-ring-offset: var(--db-selection-toggle-focus-ring-offset);
16109
- --db-checkbox-transition-duration: var(--db-selection-toggle-transition-duration);
16110
16235
 
16111
- /* Indeterminate mark — the horizontal dash shown in the mixed state. */
16112
- --db-checkbox-indeterminate-mark-width: 8px;
16113
- --db-checkbox-indeterminate-mark-height: 3px;
16236
+ /* Density */
16237
+ --db-checkbox-size: var(--db-selection-toggle-size);
16238
+ --db-checkbox-label-spacing: var(--db-selection-toggle-label-spacing);
16239
+ --db-checkbox-focus-ring-width: var(--db-focus-ring-width);
16240
+ --db-checkbox-indeterminate-mark-width: var(--db-size-2xs); /* 8px */
16241
+ --db-checkbox-indeterminate-mark-height: calc(var(--db-size-3xs) * 0.75); /* 3px */
16242
+
16243
+ /* Motion */
16244
+ --db-checkbox-transition-duration: var(--db-selection-toggle-transition-duration);
16114
16245
  }
16115
16246
 
16116
16247
  /* Native-input <Checkbox> styles. Classic CSS only — no native nesting (the
@@ -16121,21 +16252,21 @@ span.du-bois-light-typography-ellipsis-single-line {
16121
16252
  *
16122
16253
  * Structure (assumed by the React component):
16123
16254
  *
16124
- * <label class="ds-checkbox">
16125
- * <input type="checkbox" class="ds-checkbox-input" />
16126
- * <span class="ds-checkbox-indicator"> ← border + fill react to state
16127
- * <svg class="ds-checkbox-checkmark" .../> ← visible when :checked
16128
- * <span class="ds-checkbox-dash" /> ← visible when :indeterminate
16255
+ * <label class="db-checkbox">
16256
+ * <input type="checkbox" class="db-checkbox-input" />
16257
+ * <span class="db-checkbox-indicator"> ← border + fill react to state
16258
+ * <svg class="db-checkbox-checkmark" .../> ← visible when :checked
16259
+ * <span class="db-checkbox-dash" /> ← visible when :indeterminate
16129
16260
  * </span>
16130
- * <span class="ds-checkbox-label">{children}</span>
16261
+ * <span class="db-checkbox-label">{children}</span>
16131
16262
  * </label>
16132
16263
  *
16133
- * State and hiding rules target `.ds-checkbox-input` — the checkbox's OWN input —
16264
+ * State and hiding rules target `.db-checkbox-input` — the checkbox's OWN input —
16134
16265
  * never a bare `input`: consumers may render an inline <input> (e.g. a number
16135
16266
  * field) inside the label children, and a descendant `input` selector would hide
16136
16267
  * / absolutely-position that field and mis-drive the `:has(…)` state rules. */
16137
16268
 
16138
- .ds-checkbox {
16269
+ .db-checkbox {
16139
16270
  /* `display: flex` (block-level), NOT `inline-flex`: an inline-flex root puts
16140
16271
  * the label inside an inline-line-box whose leading pushes block-level siblings
16141
16272
  * (e.g. `<FormMessage>`) down by a few pixels — making validation messages sit
@@ -16151,110 +16282,121 @@ span.du-bois-light-typography-ellipsis-single-line {
16151
16282
  user-select: none;
16152
16283
  /* No `gap` here — spacing between indicator and label, plus the trailing
16153
16284
  * whitespace that gives sibling checkboxes their visual separation, lives
16154
- * on `.ds-checkbox-label` as padding-inline. Matches AntD's `.{prefix}-checkbox + span`
16285
+ * on `.db-checkbox-label` as padding-inline. Matches AntD's `.{prefix}-checkbox + span`
16155
16286
  * rule and the prior Emotion-based NativeCheckbox implementation. */
16156
16287
  min-height: var(--db-line-height-base, 20px);
16157
16288
  width: fit-content;
16158
16289
  }
16159
16290
 
16160
- /* Hover/press live on the root (label), not on the input: the input has
16161
- * `pointer-events: none` (so a single click target stays on the label and
16162
- * label/input association toggles the box), which means `input:hover` would
16163
- * never match. Putting `:hover` on the root also makes the entire label area
16291
+ /* Hover/press live on the root (label), not on the input: the input is
16292
+ * visually hidden (opacity:0), so an `input:hover` rule wouldn't be visible
16293
+ * anyway. Putting `:hover` on the root also makes the entire label area
16164
16294
  * — not just the indicator square — drive the visual feedback. */
16165
- .ds-checkbox:hover:has(.ds-checkbox-input:not(:disabled, :checked, :indeterminate)) .ds-checkbox-indicator {
16166
- background-color: var(--db-checkbox-bg-hover);
16295
+ .db-checkbox:hover:has(.db-checkbox-input:not(:disabled, :checked, :indeterminate)) .db-checkbox-indicator {
16296
+ background-color: var(--db-checkbox-surface-hover);
16167
16297
  border-color: var(--db-checkbox-border-hover);
16168
16298
  }
16169
16299
 
16170
- .ds-checkbox:active:has(.ds-checkbox-input:not(:disabled, :checked, :indeterminate)) .ds-checkbox-indicator {
16171
- background-color: var(--db-checkbox-bg-press);
16300
+ .db-checkbox:active:has(.db-checkbox-input:not(:disabled, :checked, :indeterminate)) .db-checkbox-indicator {
16301
+ background-color: var(--db-checkbox-surface-press);
16172
16302
  border-color: var(--db-checkbox-border-press);
16173
16303
  }
16174
16304
 
16175
16305
  /* Selected fill — checked and indeterminate share the same surface. */
16176
- .ds-checkbox:has(.ds-checkbox-input:is(:checked, :indeterminate)) .ds-checkbox-indicator {
16177
- background-color: var(--db-checkbox-bg-checked);
16178
- border-color: var(--db-checkbox-bg-checked);
16306
+ .db-checkbox:has(.db-checkbox-input:is(:checked, :indeterminate)) .db-checkbox-indicator {
16307
+ background-color: var(--db-checkbox-surface-checked);
16308
+ border-color: var(--db-checkbox-surface-checked);
16179
16309
  }
16180
16310
 
16181
- .ds-checkbox:hover:has(.ds-checkbox-input:is(:checked, :indeterminate):not(:disabled)) .ds-checkbox-indicator {
16182
- background-color: var(--db-checkbox-bg-checked-hover);
16183
- border-color: var(--db-checkbox-bg-checked-hover);
16311
+ .db-checkbox:hover:has(.db-checkbox-input:is(:checked, :indeterminate):not(:disabled)) .db-checkbox-indicator {
16312
+ background-color: var(--db-checkbox-surface-checked-hover);
16313
+ border-color: var(--db-checkbox-surface-checked-hover);
16184
16314
  }
16185
16315
 
16186
- .ds-checkbox:active:has(.ds-checkbox-input:is(:checked, :indeterminate):not(:disabled)) .ds-checkbox-indicator {
16187
- background-color: var(--db-checkbox-bg-checked-press);
16188
- border-color: var(--db-checkbox-bg-checked-press);
16316
+ .db-checkbox:active:has(.db-checkbox-input:is(:checked, :indeterminate):not(:disabled)) .db-checkbox-indicator {
16317
+ background-color: var(--db-checkbox-surface-checked-press);
16318
+ border-color: var(--db-checkbox-surface-checked-press);
16189
16319
  }
16190
16320
 
16191
16321
  /* Mark visibility. */
16192
- .ds-checkbox:has(.ds-checkbox-input:checked) .ds-checkbox-checkmark {
16322
+ .db-checkbox:has(.db-checkbox-input:checked) .db-checkbox-checkmark {
16193
16323
  opacity: 1;
16194
16324
  }
16195
16325
 
16196
- .ds-checkbox:has(.ds-checkbox-input:indeterminate) .ds-checkbox-dash {
16326
+ .db-checkbox:has(.db-checkbox-input:indeterminate) .db-checkbox-dash {
16197
16327
  opacity: 1;
16198
16328
  }
16199
16329
 
16200
16330
  /* Focus-visible (keyboard only). */
16201
- .ds-checkbox:has(.ds-checkbox-input:focus-visible) .ds-checkbox-indicator {
16202
- outline: var(--db-checkbox-focus-ring-width) solid var(--db-checkbox-border-focus);
16203
- outline-offset: var(--db-checkbox-focus-ring-offset);
16331
+ .db-checkbox:has(.db-checkbox-input:focus-visible) .db-checkbox-indicator {
16332
+ outline: var(--db-checkbox-focus-ring-width) solid var(--db-checkbox-focus-ring);
16333
+ outline-offset: 4px;
16204
16334
  }
16205
16335
 
16206
16336
  /* Disabled (covers unchecked, checked, indeterminate). Sourced from
16207
16337
  * `input:disabled` so the standalone-disabled and group-disabled paths both
16208
16338
  * land here without needing a separate root modifier class. */
16209
- .ds-checkbox:has(.ds-checkbox-input:disabled) {
16339
+ .db-checkbox:has(.db-checkbox-input:disabled) {
16210
16340
  cursor: not-allowed;
16211
16341
  }
16212
16342
 
16213
- .ds-checkbox:has(.ds-checkbox-input:disabled) .ds-checkbox-label {
16343
+ .db-checkbox:has(.db-checkbox-input:disabled) .db-checkbox-label {
16214
16344
  color: var(--db-checkbox-text-disabled);
16215
16345
  }
16216
16346
 
16217
- .ds-checkbox:has(.ds-checkbox-input:disabled) .ds-checkbox-indicator {
16218
- background-color: var(--db-checkbox-bg-disabled);
16347
+ .db-checkbox:has(.db-checkbox-input:disabled) .db-checkbox-indicator {
16348
+ background-color: var(--db-checkbox-surface-disabled);
16219
16349
  border-color: var(--db-checkbox-border-disabled);
16220
16350
  box-shadow: none;
16221
16351
  }
16222
16352
 
16223
- .ds-checkbox:has(.ds-checkbox-input:disabled) .ds-checkbox-checkmark {
16224
- color: var(--db-checkbox-icon-color-disabled);
16353
+ .db-checkbox:has(.db-checkbox-input:disabled) .db-checkbox-checkmark {
16354
+ color: var(--db-checkbox-mark-disabled);
16225
16355
  }
16226
16356
 
16227
- .ds-checkbox:has(.ds-checkbox-input:disabled) .ds-checkbox-dash {
16228
- background-color: var(--db-checkbox-icon-color-disabled);
16357
+ .db-checkbox:has(.db-checkbox-input:disabled) .db-checkbox-dash {
16358
+ background-color: var(--db-checkbox-mark-disabled);
16229
16359
  }
16230
16360
 
16231
- /* Visually-hidden native input, kept interactive and in the tab order so
16232
- * `:has()` lookups above can read its state. Pointer events fall through to
16233
- * the label, so clicking anywhere toggles the box. */
16234
- .ds-checkbox .ds-checkbox-input {
16361
+ /* Visually-hidden native input (opacity:0) overlaying the indicator square,
16362
+ * kept interactive and in the tab order so `:has()` lookups above can read its
16363
+ * state. It stays pointer-clickable matching AntD's `.ant-checkbox-input`
16364
+ * so it is the top-most hit-test target over the box: `getByRole('checkbox').click()`
16365
+ * (Playwright, and any coordinate click that lands on the box) resolves to the
16366
+ * real control instead of the decorative indicator overlay. Making the input
16367
+ * `pointer-events: none` (the prior native-only behavior) is what regressed
16368
+ * interaction tests vs. the AntD variant. `cursor: inherit` tracks the label's
16369
+ * pointer / disabled `not-allowed` cursor so the box keeps AntD's cursor too. */
16370
+ .db-checkbox .db-checkbox-input {
16235
16371
  position: absolute;
16236
16372
  inset: 0;
16237
16373
  inline-size: var(--db-checkbox-size);
16238
16374
  block-size: var(--db-checkbox-size);
16239
16375
  margin: 0;
16240
16376
  opacity: 0;
16241
- pointer-events: none;
16377
+ cursor: inherit;
16242
16378
  }
16243
16379
 
16244
16380
  /* Indicator — square with the border/fill that responds to state above.
16245
16381
  * Vertical math: aligns the indicator to the cap-height of the first text
16246
16382
  * line so checkbox + label sit on the same visual baseline even when the
16247
16383
  * label wraps. */
16248
- .ds-checkbox .ds-checkbox-indicator {
16384
+ .db-checkbox .db-checkbox-indicator {
16249
16385
  display: grid;
16250
16386
  place-items: center;
16251
16387
  flex-shrink: 0;
16388
+ /* Decorative only — the overlaid input owns hit-testing. Without this, the
16389
+ * indicator (and its inherited checkmark/dash children) intercept
16390
+ * `getByRole('checkbox').click()`; clicks on any edge sliver the input does
16391
+ * not cover fall through to the label, which toggles via label/input
16392
+ * association. */
16393
+ pointer-events: none;
16252
16394
  inline-size: var(--db-checkbox-size);
16253
16395
  block-size: var(--db-checkbox-size);
16254
16396
  margin-top: calc((var(--db-line-height-base, 20px) - var(--db-checkbox-size)) / 2);
16255
- border: var(--db-checkbox-border-width) solid var(--db-checkbox-border-default);
16397
+ border: var(--db-checkbox-border-width) solid var(--db-checkbox-border);
16256
16398
  border-radius: var(--db-checkbox-border-radius);
16257
- background-color: var(--db-checkbox-bg-default);
16399
+ background-color: var(--db-checkbox-surface);
16258
16400
  box-sizing: border-box;
16259
16401
  transition:
16260
16402
  background-color var(--db-checkbox-transition-duration) ease,
@@ -16262,16 +16404,16 @@ span.du-bois-light-typography-ellipsis-single-line {
16262
16404
  box-shadow var(--db-checkbox-transition-duration) ease;
16263
16405
  }
16264
16406
 
16265
- .ds-checkbox .ds-checkbox-indicator > .ds-checkbox-checkmark {
16407
+ .db-checkbox .db-checkbox-indicator > .db-checkbox-checkmark {
16266
16408
  grid-area: 1 / 1;
16267
16409
  inline-size: 100%;
16268
16410
  block-size: 100%;
16269
- color: var(--db-checkbox-icon-color);
16411
+ color: var(--db-checkbox-mark);
16270
16412
  opacity: 0;
16271
16413
  transition: opacity var(--db-checkbox-transition-duration) ease;
16272
16414
  }
16273
16415
 
16274
- .ds-checkbox .ds-checkbox-indicator > .ds-checkbox-checkmark path {
16416
+ .db-checkbox .db-checkbox-indicator > .db-checkbox-checkmark path {
16275
16417
  fill: none;
16276
16418
  stroke: currentColor;
16277
16419
  stroke-width: 2;
@@ -16279,14 +16421,14 @@ span.du-bois-light-typography-ellipsis-single-line {
16279
16421
  stroke-linejoin: round;
16280
16422
  }
16281
16423
 
16282
- .ds-checkbox .ds-checkbox-indicator > .ds-checkbox-dash {
16424
+ .db-checkbox .db-checkbox-indicator > .db-checkbox-dash {
16283
16425
  grid-area: 1 / 1;
16284
16426
  inline-size: var(--db-checkbox-indeterminate-mark-width);
16285
16427
  block-size: var(--db-checkbox-indeterminate-mark-height);
16286
16428
  /* CSS clamps this to half the 3px height, giving fully rounded end caps so the
16287
16429
  * dash reads as a pill rather than a flat bar. */
16288
16430
  border-radius: 4px;
16289
- background-color: var(--db-checkbox-icon-color);
16431
+ background-color: var(--db-checkbox-mark);
16290
16432
  opacity: 0;
16291
16433
  transition: opacity var(--db-checkbox-transition-duration) ease;
16292
16434
  }
@@ -16296,9 +16438,9 @@ span.du-bois-light-typography-ellipsis-single-line {
16296
16438
  * `padding-right` extends the checkbox's bounding box so adjacent checkboxes in a
16297
16439
  * flex row sit ~16px apart (8px trailing + 8px group `gap`) — same visual rhythm
16298
16440
  * as the AntD variant. */
16299
- .ds-checkbox .ds-checkbox-label {
16441
+ .db-checkbox .db-checkbox-label {
16300
16442
  color: var(--db-checkbox-text);
16301
- padding-inline: var(--db-checkbox-spacing);
16443
+ padding-inline: var(--db-checkbox-label-spacing);
16302
16444
  word-break: break-word;
16303
16445
  }
16304
16446
 
@@ -16309,7 +16451,7 @@ span.du-bois-light-typography-ellipsis-single-line {
16309
16451
  *
16310
16452
  * Each helper-text class is listed once per theme (`du-bois-light-*` /
16311
16453
  * `du-bois-dark-*`). The selectors deliberately repeat the root/group class
16312
- * (`.ds-checkbox.ds-checkbox`) to push specificity to (0,3,0). That
16454
+ * (`.db-checkbox.db-checkbox`) to push specificity to (0,3,0). That
16313
16455
  * overrides `FormMessage`'s own `&&`-doubled `margin-top: 8px` declared with
16314
16456
  * Emotion at runtime — without doubling we'd lose on the specificity tie and
16315
16457
  * the validation message would keep an 8px gap below the checkbox. */
@@ -16317,115 +16459,84 @@ span.du-bois-light-typography-ellipsis-single-line {
16317
16459
  /* Single checkbox followed by Hint and/or FormMessage. Indents the helper text
16318
16460
  * by 24px so it aligns with the start of the label, and removes the default
16319
16461
  * vertical margin Hint/FormMessage carry. */
16320
- .ds-checkbox.ds-checkbox + .du-bois-light-hint,
16321
- .ds-checkbox.ds-checkbox + .du-bois-dark-hint,
16322
- .ds-checkbox.ds-checkbox + .du-bois-light-form-message,
16323
- .ds-checkbox.ds-checkbox + .du-bois-dark-form-message,
16324
- .ds-checkbox.ds-checkbox + .du-bois-light-hint + .du-bois-light-form-message,
16325
- .ds-checkbox.ds-checkbox + .du-bois-dark-hint + .du-bois-dark-form-message {
16326
- padding-left: var(--db-space-lg);
16462
+ .db-checkbox.db-checkbox + .du-bois-light-hint,
16463
+ .db-checkbox.db-checkbox + .du-bois-dark-hint,
16464
+ .db-checkbox.db-checkbox + .du-bois-light-form-message,
16465
+ .db-checkbox.db-checkbox + .du-bois-dark-form-message,
16466
+ .db-checkbox.db-checkbox + .du-bois-light-hint + .du-bois-light-form-message,
16467
+ .db-checkbox.db-checkbox + .du-bois-dark-hint + .du-bois-dark-form-message {
16468
+ padding-left: var(--db-spacing-sm);
16327
16469
  margin-top: 0;
16328
16470
  }
16329
16471
 
16330
16472
  /* Group spacing against sibling form text — 8px gap above the group when it
16331
16473
  * follows a Hint, 8px gap above a FormMessage when it follows the group.
16332
16474
  * Doubled class on the group side beats FormMessage's `&&` for the same reason. */
16333
- .du-bois-light-hint + .ds-checkbox-group.ds-checkbox-group,
16334
- .du-bois-dark-hint + .ds-checkbox-group.ds-checkbox-group,
16335
- .ds-checkbox-group.ds-checkbox-group + .du-bois-light-form-message,
16336
- .ds-checkbox-group.ds-checkbox-group + .du-bois-dark-form-message {
16337
- margin-top: var(--db-space-sm);
16475
+ .du-bois-light-hint + .db-checkbox-group.db-checkbox-group,
16476
+ .du-bois-dark-hint + .db-checkbox-group.db-checkbox-group,
16477
+ .db-checkbox-group.db-checkbox-group + .du-bois-light-form-message,
16478
+ .db-checkbox-group.db-checkbox-group + .du-bois-dark-form-message {
16479
+ margin-top: var(--db-spacing-2xs);
16338
16480
  }
16339
16481
 
16340
- /* CheckboxGroup layout. Vertical delegates to the `.ds-stack` primitive; the
16482
+ /* CheckboxGroup layout. Vertical delegates to the `.db-stack` primitive; the
16341
16483
  * horizontal default stays bespoke because it must NOT wrap (a long row of
16342
16484
  * checkboxes overflows horizontally rather than reflowing onto multiple lines),
16343
- * which is the one thing `.ds-cluster` won't do. Both wire their gap to the
16485
+ * which is the one thing `.db-cluster` won't do. Both wire their gap to the
16344
16486
  * checkbox spacing token so a retheme moves with the rest of the component. */
16345
- .ds-checkbox-group {
16487
+ .db-checkbox-group {
16346
16488
  display: flex;
16347
16489
  }
16348
16490
 
16349
- /* Horizontal (default): single non-wrapping row. `:not(.ds-stack)` keeps this
16491
+ /* Horizontal (default): single non-wrapping row. `:not(.db-stack)` keeps this
16350
16492
  * off the vertical element so it never fights the stack primitive's gap. */
16351
- .ds-checkbox-group:not(.ds-stack) {
16493
+ .db-checkbox-group:not(.db-stack) {
16352
16494
  flex-wrap: nowrap;
16353
- column-gap: var(--db-checkbox-spacing);
16495
+ column-gap: var(--db-checkbox-label-spacing);
16354
16496
  row-gap: 0;
16355
16497
  }
16356
16498
 
16357
- /* Vertical: .ds-stack supplies flex-direction + gap; we only retarget the knob. */
16358
- .ds-checkbox-group.ds-stack {
16359
- --ds-stack-gap: var(--db-checkbox-spacing);
16499
+ /* Vertical: .db-stack supplies flex-direction + gap; we only retarget the knob. */
16500
+ .db-checkbox-group.db-stack {
16501
+ --db-stack-gap: var(--db-checkbox-label-spacing);
16360
16502
  }
16361
16503
 
16362
- /* Component-tier tokens for <Radio>. Each value defaults to a CATEGORY
16363
- * (selection-toggle) token via var(); consumers can override here to retheme
16364
- * radios without affecting checkbox / switch.
16365
- *
16366
- * Radio differs from Checkbox in two ways: the indicator is a full circle
16367
- * (border-radius) and the "mark" is a filled dot rather than a checkmark/dash. */
16368
-
16369
- /* Re-declared under both theme classes (not just :root) so the var() chain onto
16370
- * category/system tokens re-resolves inside a `.du-bois-dark` subtree instead of
16371
- * freezing at the root (light) values. See DUBOIS-448 dark-mode scoping. */
16372
- :where(:root, .du-bois-light, .du-bois-dark) {
16373
- --db-radio-size: var(--db-selection-toggle-size);
16374
- /* Circle, not a rounded square — the one shape token that does NOT inherit
16375
- * the category (square) radius. */
16504
+ :where(:root), :where(.du-bois-light) {
16505
+ /* Shape */
16376
16506
  --db-radio-border-radius: var(--db-radius-full);
16377
16507
  --db-radio-border-width: 1px;
16378
- --db-radio-spacing: var(--db-selection-toggle-spacing);
16379
16508
 
16380
- --db-radio-bg-default: var(--db-selection-toggle-bg-default);
16381
- --db-radio-bg-hover: var(--db-selection-toggle-bg-hover);
16382
- --db-radio-bg-press: var(--db-selection-toggle-bg-press);
16383
- --db-radio-bg-checked: var(--db-selection-toggle-bg-checked);
16384
- --db-radio-bg-checked-hover: var(--db-selection-toggle-bg-checked-hover);
16385
- /* AntD checked active/press background is actionDefaultBackgroundPress (NOT the
16386
- * primary press), so this maps to the default press bg category token — see
16387
- * getRadioInputStyles checked active in AntDRadioInternal.tsx. */
16388
- --db-radio-bg-checked-press: var(--db-selection-toggle-bg-press);
16389
- --db-radio-bg-disabled: var(--db-selection-toggle-bg-disabled);
16509
+ /* Color */
16510
+ --db-radio-surface: var(--db-selection-toggle-surface);
16511
+ --db-radio-surface-hover: var(--db-color-action-default-background-hover);
16512
+ --db-radio-surface-press: var(--db-color-action-default-background-press);
16513
+ --db-radio-surface-checked: var(--db-selection-toggle-surface-checked);
16514
+ --db-radio-surface-checked-hover: var(--db-selection-toggle-surface-checked-hover);
16515
+ --db-radio-surface-checked-press: var(--db-color-action-default-background-press);
16516
+ --db-radio-surface-disabled: var(--db-selection-toggle-surface-disabled);
16390
16517
 
16391
- --db-radio-border-default: var(--db-selection-toggle-border-default);
16518
+ --db-radio-border: var(--db-color-action-default-border-default);
16392
16519
  --db-radio-border-hover: var(--db-selection-toggle-border-hover);
16393
16520
  --db-radio-border-press: var(--db-selection-toggle-border-press);
16394
- --db-radio-border-focus: var(--db-selection-toggle-border-focus);
16395
- --db-radio-border-disabled: var(--db-selection-toggle-border-disabled);
16396
-
16397
- /* Two-tone checked hover/press border ring (AntD getRadioInputStyles checked
16398
- * states): the border is a DARKER shade than the fill, not equal to it.
16399
- * - checked hover border = actionPrimaryBackgroundPress (== the press category
16400
- * token, which is action-primary-background-press).
16401
- * - checked press border = actionDefaultBorderPress; no selection-toggle
16402
- * category token equals this color, so reference the system token directly. */
16521
+ --db-radio-border-focus: var(--db-focus-ring-color);
16522
+ --db-radio-border-disabled: var(--db-color-action-disabled-border);
16403
16523
  --db-radio-border-checked-hover: var(--db-selection-toggle-border-press);
16404
16524
  --db-radio-border-checked-press: var(--db-color-action-default-border-press);
16525
+ --db-radio-border-unchecked-focus: var(--db-color-action-primary-background-default);
16526
+ --db-radio-outline-checked-focus: var(--db-color-action-primary-background-default);
16405
16527
 
16406
- /* Unchecked keyboard-focus border (AntD getRadioInputStyles unchecked focus):
16407
- * borderColor = actionPrimaryBackgroundDefault, with NO outline ring. No
16408
- * selection-toggle category token equals this color (the closest is a bg
16409
- * token), so reference the system token directly. */
16410
- --db-radio-border-focus-unchecked: var(--db-color-action-primary-background-default);
16411
- /* Checked focus-visible outline color (AntD: outline 1px solid
16412
- * actionPrimaryBackgroundDefault, outlineOffset 1). */
16413
- --db-radio-focus-outline-checked-color: var(--db-color-action-primary-background-default);
16414
-
16415
- /* The dot. Shares the category icon-color token (white over the filled
16416
- * primary surface) so a retheme moves checkbox checkmark + radio dot together. */
16417
- --db-radio-dot-color: var(--db-selection-toggle-icon-color);
16418
- --db-radio-dot-color-disabled: var(--db-selection-toggle-icon-color-disabled);
16528
+ --db-radio-mark: #ffffff;
16529
+ --db-radio-mark-disabled: var(--db-selection-toggle-mark-disabled);
16419
16530
  --db-radio-text: var(--db-selection-toggle-text);
16420
16531
  --db-radio-text-disabled: var(--db-selection-toggle-text-disabled);
16421
16532
 
16422
- --db-radio-focus-ring-width: var(--db-selection-toggle-focus-ring-width);
16423
- --db-radio-focus-ring-offset: var(--db-selection-toggle-focus-ring-offset);
16424
- --db-radio-transition-duration: var(--db-selection-toggle-transition-duration);
16533
+ /* Density */
16534
+ --db-radio-size: var(--db-selection-toggle-size);
16535
+ --db-radio-label-spacing: var(--db-selection-toggle-label-spacing);
16536
+ --db-radio-mark-size: var(--db-size-3xs);
16425
16537
 
16426
- /* Diameter of the inner dot. Mirrors the AntD checked `::after` size, which uses
16427
- * `theme.spacing.xs` (4px) — see getRadioInputStyles in AntDRadioInternal.tsx. */
16428
- --db-radio-dot-size: var(--db-space-xs);
16538
+ /* Motion */
16539
+ --db-radio-transition-duration: var(--db-selection-toggle-transition-duration);
16429
16540
  }
16430
16541
 
16431
16542
  /* Native-input <Radio> styles. Classic CSS only — no native nesting (the
@@ -16436,12 +16547,12 @@ span.du-bois-light-typography-ellipsis-single-line {
16436
16547
  *
16437
16548
  * Structure (assumed by the React component):
16438
16549
  *
16439
- * <label class="ds-radio">
16550
+ * <label class="db-radio">
16440
16551
  * <input type="radio" />
16441
- * <span class="ds-radio-indicator"> ← circle border + fill react to state
16442
- * <span class="ds-radio-dot" /> ← visible when :checked
16552
+ * <span class="db-radio-indicator"> ← circle border + fill react to state
16553
+ * <span class="db-radio-dot" /> ← visible when :checked
16443
16554
  * </span>
16444
- * <span class="ds-radio-label">{children}</span>
16555
+ * <span class="db-radio-label">{children}</span>
16445
16556
  * </label>
16446
16557
  *
16447
16558
  * The root only ever has one <input> descendant, so a bare `input` selector is
@@ -16450,9 +16561,9 @@ span.du-bois-light-typography-ellipsis-single-line {
16450
16561
  * checkmark/dash, and there is no indeterminate state.
16451
16562
  *
16452
16563
  * TODO(DUBOIS-452): the indicator/dot state styles below are identical to
16453
- * NativeCheckbox.css — consolidate them into a shared `.ds-selection-toggle` class. */
16564
+ * NativeCheckbox.css — consolidate them into a shared `.db-selection-toggle` class. */
16454
16565
 
16455
- .ds-radio {
16566
+ .db-radio {
16456
16567
  /* `display: flex` (block-level), NOT `inline-flex`: see NativeCheckbox.css for
16457
16568
  * the line-box / sibling-spacing rationale. */
16458
16569
  display: flex;
@@ -16464,41 +16575,41 @@ span.du-bois-light-typography-ellipsis-single-line {
16464
16575
  width: fit-content;
16465
16576
  }
16466
16577
 
16467
- /* Hover/press live on the root (label), not on the input: the input has
16468
- * `pointer-events: none`, so `input:hover` would never match, and the whole
16469
- * label area should drive the feedback. */
16470
- .ds-radio:hover:has(input:not(:disabled, :checked)) .ds-radio-indicator {
16471
- background-color: var(--db-radio-bg-hover);
16578
+ /* Hover/press live on the root (label), not on the input: the input is
16579
+ * visually hidden (opacity:0), so an `input:hover` rule wouldn't be visible
16580
+ * anyway, and the whole label area should drive the feedback. */
16581
+ .db-radio:hover:has(input:not(:disabled, :checked)) .db-radio-indicator {
16582
+ background-color: var(--db-radio-surface-hover);
16472
16583
  border-color: var(--db-radio-border-hover);
16473
16584
  }
16474
16585
 
16475
- .ds-radio:active:has(input:not(:disabled, :checked)) .ds-radio-indicator {
16476
- background-color: var(--db-radio-bg-press);
16586
+ .db-radio:active:has(input:not(:disabled, :checked)) .db-radio-indicator {
16587
+ background-color: var(--db-radio-surface-press);
16477
16588
  border-color: var(--db-radio-border-press);
16478
16589
  }
16479
16590
 
16480
16591
  /* Selected fill. */
16481
- .ds-radio:has(input:checked) .ds-radio-indicator {
16482
- background-color: var(--db-radio-bg-checked);
16483
- border-color: var(--db-radio-bg-checked);
16592
+ .db-radio:has(input:checked) .db-radio-indicator {
16593
+ background-color: var(--db-radio-surface-checked);
16594
+ border-color: var(--db-radio-surface-checked);
16484
16595
  }
16485
16596
 
16486
16597
  /* AntD getRadioInputStyles checked hover: background = actionPrimaryBackgroundHover,
16487
16598
  * borderColor = actionPrimaryBackgroundPress (a darker ring than the fill). */
16488
- .ds-radio:hover:has(input:checked:not(:disabled)) .ds-radio-indicator {
16489
- background-color: var(--db-radio-bg-checked-hover);
16599
+ .db-radio:hover:has(input:checked:not(:disabled)) .db-radio-indicator {
16600
+ background-color: var(--db-radio-surface-checked-hover);
16490
16601
  border-color: var(--db-radio-border-checked-hover);
16491
16602
  }
16492
16603
 
16493
16604
  /* AntD getRadioInputStyles checked active: background = actionDefaultBackgroundPress,
16494
16605
  * borderColor = actionDefaultBorderPress (two-tone, not flat). */
16495
- .ds-radio:active:has(input:checked:not(:disabled)) .ds-radio-indicator {
16496
- background-color: var(--db-radio-bg-checked-press);
16606
+ .db-radio:active:has(input:checked:not(:disabled)) .db-radio-indicator {
16607
+ background-color: var(--db-radio-surface-checked-press);
16497
16608
  border-color: var(--db-radio-border-checked-press);
16498
16609
  }
16499
16610
 
16500
16611
  /* Dot visibility. */
16501
- .ds-radio:has(input:checked) .ds-radio-dot {
16612
+ .db-radio:has(input:checked) .db-radio-dot {
16502
16613
  opacity: 1;
16503
16614
  }
16504
16615
 
@@ -16507,66 +16618,77 @@ span.du-bois-light-typography-ellipsis-single-line {
16507
16618
  *
16508
16619
  * UNCHECKED focus (AntD `&:not(disabled) > input:focus + inner`): only the border
16509
16620
  * color changes to actionPrimaryBackgroundDefault — NO outline ring. */
16510
- .ds-radio:has(input:focus-visible:not(:checked)) .ds-radio-indicator {
16511
- border-color: var(--db-radio-border-focus-unchecked);
16621
+ .db-radio:has(input:focus-visible:not(:checked)) .db-radio-indicator {
16622
+ border-color: var(--db-radio-border-unchecked-focus);
16512
16623
  }
16513
16624
 
16514
16625
  /* CHECKED focus-visible (AntD `&.checked &:not(disabled) > input:focus-visible + inner`):
16515
16626
  * background = actionPrimaryBackgroundDefault, borderColor = actionDefaultBorderFocus,
16516
16627
  * outline = 1px solid actionPrimaryBackgroundDefault, outlineOffset = 1. */
16517
- .ds-radio:has(input:focus-visible:checked) .ds-radio-indicator {
16518
- background-color: var(--db-radio-bg-checked);
16628
+ .db-radio:has(input:focus-visible:checked) .db-radio-indicator {
16629
+ background-color: var(--db-radio-surface-checked);
16519
16630
  border-color: var(--db-radio-border-focus);
16520
- outline: 1px solid var(--db-radio-focus-outline-checked-color);
16631
+ outline: 1px solid var(--db-radio-outline-checked-focus);
16521
16632
  outline-offset: 1px;
16522
16633
  }
16523
16634
 
16524
16635
  /* Disabled (covers checked and unchecked). Sourced from `input:disabled` so the
16525
16636
  * standalone-disabled and group-disabled paths both land here. */
16526
- .ds-radio:has(input:disabled) {
16637
+ .db-radio:has(input:disabled) {
16527
16638
  cursor: not-allowed;
16528
16639
  }
16529
16640
 
16530
- .ds-radio:has(input:disabled) .ds-radio-label {
16641
+ .db-radio:has(input:disabled) .db-radio-label {
16531
16642
  color: var(--db-radio-text-disabled);
16532
16643
  }
16533
16644
 
16534
- .ds-radio:has(input:disabled) .ds-radio-indicator {
16535
- background-color: var(--db-radio-bg-disabled);
16645
+ .db-radio:has(input:disabled) .db-radio-indicator {
16646
+ background-color: var(--db-radio-surface-disabled);
16536
16647
  border-color: var(--db-radio-border-disabled);
16537
16648
  box-shadow: none;
16538
16649
  }
16539
16650
 
16540
- .ds-radio:has(input:disabled) .ds-radio-dot {
16541
- background-color: var(--db-radio-dot-color-disabled);
16651
+ .db-radio:has(input:disabled) .db-radio-dot {
16652
+ background-color: var(--db-radio-mark-disabled);
16542
16653
  }
16543
16654
 
16544
- /* Visually-hidden native input, kept interactive and in the tab order so the
16545
- * `:has()` lookups above can read its state. Pointer events fall through to the
16546
- * label, so clicking anywhere toggles the radio. */
16547
- .ds-radio input {
16655
+ /* Visually-hidden native input (opacity:0) overlaying the indicator circle,
16656
+ * kept interactive and in the tab order so the `:has()` lookups above can read
16657
+ * its state. It stays pointer-clickable matching AntD's `.ant-radio-input`
16658
+ * so it is the top-most hit-test target over the circle: `getByRole('radio').click()`
16659
+ * (Playwright, and any coordinate click that lands on the circle) resolves to the
16660
+ * real control instead of the decorative indicator overlay. Making the input
16661
+ * `pointer-events: none` (the prior native-only behavior) is what regressed
16662
+ * interaction tests vs. the AntD variant. `cursor: inherit` tracks the label's
16663
+ * pointer / disabled `not-allowed` cursor so the circle keeps AntD's cursor too. */
16664
+ .db-radio input {
16548
16665
  position: absolute;
16549
16666
  inset: 0;
16550
16667
  inline-size: var(--db-radio-size);
16551
16668
  block-size: var(--db-radio-size);
16552
16669
  margin: 0;
16553
16670
  opacity: 0;
16554
- pointer-events: none;
16671
+ cursor: inherit;
16555
16672
  }
16556
16673
 
16557
16674
  /* Indicator — circle with the border/fill that responds to state above.
16558
16675
  * Vertical math aligns the indicator to the cap-height of the first text line
16559
16676
  * so radio + label sit on the same visual baseline even when the label wraps. */
16560
- .ds-radio .ds-radio-indicator {
16677
+ .db-radio .db-radio-indicator {
16561
16678
  display: grid;
16562
16679
  place-items: center;
16563
16680
  flex-shrink: 0;
16681
+ /* Decorative only — the overlaid input owns hit-testing. Without this, the
16682
+ * indicator (and its inherited dot child) intercept `getByRole('radio').click()`;
16683
+ * clicks on any edge sliver the input does not cover fall through to the label,
16684
+ * which toggles via label/input association. */
16685
+ pointer-events: none;
16564
16686
  inline-size: var(--db-radio-size);
16565
16687
  block-size: var(--db-radio-size);
16566
16688
  margin-top: calc((var(--db-line-height-base, 20px) - var(--db-radio-size)) / 2);
16567
- border: var(--db-radio-border-width) solid var(--db-radio-border-default);
16689
+ border: var(--db-radio-border-width) solid var(--db-radio-border);
16568
16690
  border-radius: var(--db-radio-border-radius);
16569
- background-color: var(--db-radio-bg-default);
16691
+ background-color: var(--db-radio-surface);
16570
16692
  box-sizing: border-box;
16571
16693
  transition:
16572
16694
  background-color var(--db-radio-transition-duration) ease,
@@ -16574,12 +16696,12 @@ span.du-bois-light-typography-ellipsis-single-line {
16574
16696
  box-shadow var(--db-radio-transition-duration) ease;
16575
16697
  }
16576
16698
 
16577
- .ds-radio .ds-radio-indicator > .ds-radio-dot {
16699
+ .db-radio .db-radio-indicator > .db-radio-dot {
16578
16700
  grid-area: 1 / 1;
16579
- inline-size: var(--db-radio-dot-size);
16580
- block-size: var(--db-radio-dot-size);
16701
+ inline-size: var(--db-radio-mark-size);
16702
+ block-size: var(--db-radio-mark-size);
16581
16703
  border-radius: var(--db-radius-full);
16582
- background-color: var(--db-radio-dot-color);
16704
+ background-color: var(--db-radio-mark);
16583
16705
  opacity: 0;
16584
16706
  transition: opacity var(--db-radio-transition-duration) ease;
16585
16707
  }
@@ -16587,17 +16709,17 @@ span.du-bois-light-typography-ellipsis-single-line {
16587
16709
  /* Honour the user's reduced-motion preference: drop the state-change
16588
16710
  * transitions on the indicator and dot so checking/hovering is instant. */
16589
16711
  @media (prefers-reduced-motion: reduce) {
16590
- .ds-radio .ds-radio-indicator,
16591
- .ds-radio .ds-radio-indicator > .ds-radio-dot {
16712
+ .db-radio .db-radio-indicator,
16713
+ .db-radio .db-radio-indicator > .db-radio-dot {
16592
16714
  transition: none;
16593
16715
  }
16594
16716
  }
16595
16717
 
16596
16718
  /* Padding-inline replicates the AntD `.{prefix} + span` label gap and the
16597
16719
  * trailing whitespace that separates adjacent radios in a row. */
16598
- .ds-radio .ds-radio-label {
16720
+ .db-radio .db-radio-label {
16599
16721
  color: var(--db-radio-text);
16600
- padding-inline: var(--db-radio-spacing);
16722
+ padding-inline: var(--db-radio-label-spacing);
16601
16723
  word-break: break-word;
16602
16724
  }
16603
16725
 
@@ -16605,13 +16727,13 @@ span.du-bois-light-typography-ellipsis-single-line {
16605
16727
  * indent comes from AntD's getCommonRadioGroupStyles (`& > label + hint`) and applies
16606
16728
  * to BOTH layouts. The doubled root class pushes specificity to (0,3,0) to beat
16607
16729
  * FormMessage's runtime `&&` margin. */
16608
- .ds-radio.ds-radio + .du-bois-light-hint,
16609
- .ds-radio.ds-radio + .du-bois-dark-hint,
16610
- .ds-radio.ds-radio + .du-bois-light-form-message,
16611
- .ds-radio.ds-radio + .du-bois-dark-form-message,
16612
- .ds-radio.ds-radio + .du-bois-light-hint + .du-bois-light-form-message,
16613
- .ds-radio.ds-radio + .du-bois-dark-hint + .du-bois-dark-form-message {
16614
- padding-inline-start: var(--db-space-lg);
16730
+ .db-radio.db-radio + .du-bois-light-hint,
16731
+ .db-radio.db-radio + .du-bois-dark-hint,
16732
+ .db-radio.db-radio + .du-bois-light-form-message,
16733
+ .db-radio.db-radio + .du-bois-dark-form-message,
16734
+ .db-radio.db-radio + .du-bois-light-hint + .du-bois-light-form-message,
16735
+ .db-radio.db-radio + .du-bois-dark-hint + .du-bois-dark-form-message {
16736
+ padding-inline-start: var(--db-spacing-sm);
16615
16737
  margin-top: 0;
16616
16738
  }
16617
16739
 
@@ -16619,71 +16741,71 @@ span.du-bois-light-typography-ellipsis-single-line {
16619
16741
  * after a radio gets `marginTop: -sm` (cancels the preceding radio's
16620
16742
  * `paddingBottom: sm` so the hint tucks directly under its label) and
16621
16743
  * `marginBottom: sm` (gap before the next radio). The negative top margin relies on
16622
- * the .ds-stack gap being 0 (set below). Scoped to .ds-stack so it never perturbs
16744
+ * the .db-stack gap being 0 (set below). Scoped to .db-stack so it never perturbs
16623
16745
  * the horizontal grid, where hints are positioned by grid-row instead. */
16624
- .ds-radio-group.ds-stack > .ds-radio.ds-radio + .du-bois-light-hint,
16625
- .ds-radio-group.ds-stack > .ds-radio.ds-radio + .du-bois-dark-hint,
16626
- .ds-radio-group.ds-stack > .ds-radio.ds-radio + .du-bois-light-form-message,
16627
- .ds-radio-group.ds-stack > .ds-radio.ds-radio + .du-bois-dark-form-message,
16628
- .ds-radio-group.ds-stack > .ds-radio.ds-radio + .du-bois-light-hint + .du-bois-light-form-message,
16629
- .ds-radio-group.ds-stack > .ds-radio.ds-radio + .du-bois-dark-hint + .du-bois-dark-form-message {
16630
- margin-top: calc(-1 * var(--db-space-sm));
16631
- margin-bottom: var(--db-space-sm);
16746
+ .db-radio-group.db-stack > .db-radio.db-radio + .du-bois-light-hint,
16747
+ .db-radio-group.db-stack > .db-radio.db-radio + .du-bois-dark-hint,
16748
+ .db-radio-group.db-stack > .db-radio.db-radio + .du-bois-light-form-message,
16749
+ .db-radio-group.db-stack > .db-radio.db-radio + .du-bois-dark-form-message,
16750
+ .db-radio-group.db-stack > .db-radio.db-radio + .du-bois-light-hint + .du-bois-light-form-message,
16751
+ .db-radio-group.db-stack > .db-radio.db-radio + .du-bois-dark-hint + .du-bois-dark-form-message {
16752
+ margin-top: calc(-1 * var(--db-spacing-2xs));
16753
+ margin-bottom: var(--db-spacing-2xs);
16632
16754
  }
16633
16755
 
16634
16756
  /* AntD `& > label:last-of-type + hint { marginTop: 0 }`: the last radio has no
16635
16757
  * `paddingBottom` to cancel, so its trailing hint keeps its natural top position. */
16636
- .ds-radio-group.ds-stack > .ds-radio.ds-radio:last-of-type + .du-bois-light-hint,
16637
- .ds-radio-group.ds-stack > .ds-radio.ds-radio:last-of-type + .du-bois-dark-hint,
16638
- .ds-radio-group.ds-stack > .ds-radio.ds-radio:last-of-type + .du-bois-light-form-message,
16639
- .ds-radio-group.ds-stack > .ds-radio.ds-radio:last-of-type + .du-bois-dark-form-message,
16640
- .ds-radio-group.ds-stack > .ds-radio.ds-radio:last-of-type + .du-bois-light-hint + .du-bois-light-form-message,
16641
- .ds-radio-group.ds-stack > .ds-radio.ds-radio:last-of-type + .du-bois-dark-hint + .du-bois-dark-form-message {
16758
+ .db-radio-group.db-stack > .db-radio.db-radio:last-of-type + .du-bois-light-hint,
16759
+ .db-radio-group.db-stack > .db-radio.db-radio:last-of-type + .du-bois-dark-hint,
16760
+ .db-radio-group.db-stack > .db-radio.db-radio:last-of-type + .du-bois-light-form-message,
16761
+ .db-radio-group.db-stack > .db-radio.db-radio:last-of-type + .du-bois-dark-form-message,
16762
+ .db-radio-group.db-stack > .db-radio.db-radio:last-of-type + .du-bois-light-hint + .du-bois-light-form-message,
16763
+ .db-radio-group.db-stack > .db-radio.db-radio:last-of-type + .du-bois-dark-hint + .du-bois-dark-form-message {
16642
16764
  margin-top: 0;
16643
16765
  }
16644
16766
 
16645
- .du-bois-light-hint + .ds-radio-group.ds-radio-group,
16646
- .du-bois-dark-hint + .ds-radio-group.ds-radio-group,
16647
- .ds-radio-group.ds-radio-group + .du-bois-light-form-message,
16648
- .ds-radio-group.ds-radio-group + .du-bois-dark-form-message {
16649
- margin-top: var(--db-space-sm);
16767
+ .du-bois-light-hint + .db-radio-group.db-radio-group,
16768
+ .du-bois-dark-hint + .db-radio-group.db-radio-group,
16769
+ .db-radio-group.db-radio-group + .du-bois-light-form-message,
16770
+ .db-radio-group.db-radio-group + .du-bois-dark-form-message {
16771
+ margin-top: var(--db-spacing-2xs);
16650
16772
  }
16651
16773
 
16652
16774
  /* RadioGroup layout. Vertical (the default) delegates flex-direction to the
16653
- * .ds-stack primitive; horizontal is a two-row grid (mirroring AntD). */
16654
- .ds-radio-group {
16775
+ * .db-stack primitive; horizontal is a two-row grid (mirroring AntD). */
16776
+ .db-radio-group {
16655
16777
  display: flex;
16656
16778
  }
16657
16779
 
16658
- /* Vertical: .ds-stack supplies flex-direction: column. AntD's vertical helper
16780
+ /* Vertical: .db-stack supplies flex-direction: column. AntD's vertical helper
16659
16781
  * (getVerticalRadioGroupStyles) produces its item rhythm purely from
16660
16782
  * `& > label { paddingBottom: sm }` plus the negative-margin hint trick above — it
16661
16783
  * uses NO flex gap. The negative `marginTop` on hints only works if the stack adds
16662
16784
  * no gap of its own, so we zero out the gap and reproduce the rhythm via
16663
16785
  * padding-bottom on each radio. */
16664
- .ds-radio-group.ds-stack {
16665
- --ds-stack-gap: var(--db-space-0);
16786
+ .db-radio-group.db-stack {
16787
+ --db-stack-gap: 0;
16666
16788
  }
16667
16789
 
16668
16790
  /* AntD `& > label { paddingBottom: sm }`. */
16669
- .ds-radio-group.ds-stack > .ds-radio {
16670
- padding-bottom: var(--db-space-sm);
16791
+ .db-radio-group.db-stack > .db-radio {
16792
+ padding-bottom: var(--db-spacing-2xs);
16671
16793
  }
16672
16794
 
16673
16795
  /* AntD `& > label:last-of-type { paddingBottom: 0 }`. */
16674
- .ds-radio-group.ds-stack > .ds-radio:last-of-type {
16796
+ .db-radio-group.db-stack > .db-radio:last-of-type {
16675
16797
  padding-bottom: 0;
16676
16798
  }
16677
16799
 
16678
16800
  /* AntD getVerticalRadioGroupStyles `.${prefix}-radio-tile + .${prefix}-radio-tile {
16679
- * marginTop: md }`: RadioTiles are not matched by the `.ds-radio` padding-bottom
16801
+ * marginTop: md }`: RadioTiles are not matched by the `.db-radio` padding-bottom
16680
16802
  * rhythm above (the tile's own class is du-bois-{light,dark}-radio-tile), so space
16681
- * consecutive tiles explicitly. The .ds-stack gap is 0, so this margin is the spacing. */
16682
- .ds-radio-group.ds-stack > .du-bois-light-radio-tile + .du-bois-light-radio-tile,
16683
- .ds-radio-group.ds-stack > .du-bois-light-radio-tile + .du-bois-dark-radio-tile,
16684
- .ds-radio-group.ds-stack > .du-bois-dark-radio-tile + .du-bois-light-radio-tile,
16685
- .ds-radio-group.ds-stack > .du-bois-dark-radio-tile + .du-bois-dark-radio-tile {
16686
- margin-top: var(--db-space-md);
16803
+ * consecutive tiles explicitly. The .db-stack gap is 0, so this margin is the spacing. */
16804
+ .db-radio-group.db-stack > .du-bois-light-radio-tile + .du-bois-light-radio-tile,
16805
+ .db-radio-group.db-stack > .du-bois-light-radio-tile + .du-bois-dark-radio-tile,
16806
+ .db-radio-group.db-stack > .du-bois-dark-radio-tile + .du-bois-light-radio-tile,
16807
+ .db-radio-group.db-stack > .du-bois-dark-radio-tile + .du-bois-dark-radio-tile {
16808
+ margin-top: var(--db-spacing-xs);
16687
16809
  }
16688
16810
 
16689
16811
  /* Horizontal: AntD `getHorizontalRadioGroupStyles` is a TWO-ROW grid (NOT a flex
@@ -16692,105 +16814,93 @@ span.du-bois-light-typography-ellipsis-single-line {
16692
16814
  * group class here matches that.
16693
16815
  * AntD: `display: grid; gridTemplateRows: [label] auto [hint] auto;
16694
16816
  * gridAutoColumns: max-content; gridColumnGap: md`. */
16695
- .ds-radio-group--horizontal.ds-radio-group--horizontal {
16817
+ .db-radio-group--horizontal.db-radio-group--horizontal {
16696
16818
  display: grid;
16697
16819
  grid-template-rows: [label] auto [hint] auto;
16698
16820
  grid-auto-columns: max-content;
16699
- column-gap: var(--db-space-md);
16821
+ column-gap: var(--db-spacing-xs);
16700
16822
  }
16701
16823
 
16702
16824
  /* Equal column widths: AntD `gridAutoColumns: minmax(0, 1fr)`. */
16703
- .ds-radio-group--horizontal.ds-radio-group--equal-width {
16825
+ .db-radio-group--horizontal.db-radio-group--equal-width {
16704
16826
  grid-auto-columns: minmax(0, 1fr);
16705
16827
  }
16706
16828
 
16707
16829
  /* AntD `& > label, & > .${prefix}-radio-tile { gridRow: label / label; marginRight: 0 }`:
16708
16830
  * every radio (and every RadioTile button, whose own class is
16709
- * du-bois-{light,dark}-radio-tile and is NOT matched by `> .ds-radio`) lives in the
16831
+ * du-bois-{light,dark}-radio-tile and is NOT matched by `> .db-radio`) lives in the
16710
16832
  * label row. grid-auto-flow defaults to row, so successive items advance the implicit
16711
16833
  * column. */
16712
- .ds-radio-group--horizontal > .ds-radio,
16713
- .ds-radio-group--horizontal > .du-bois-light-radio-tile,
16714
- .ds-radio-group--horizontal > .du-bois-dark-radio-tile {
16834
+ .db-radio-group--horizontal > .db-radio,
16835
+ .db-radio-group--horizontal > .du-bois-light-radio-tile,
16836
+ .db-radio-group--horizontal > .du-bois-dark-radio-tile {
16715
16837
  grid-row: label / label;
16716
16838
  margin-inline-end: 0;
16717
16839
  }
16718
16840
 
16719
16841
  /* AntD `& > label + hint { display: inline-block; gridRow: hint / hint }`: a hint
16720
16842
  * following a radio drops into the hint row of the column its radio occupies. The
16721
- * vertical negative-margin rules are scoped to .ds-stack, so nothing to reset here. */
16722
- .ds-radio-group--horizontal > .du-bois-light-hint,
16723
- .ds-radio-group--horizontal > .du-bois-dark-hint {
16843
+ * vertical negative-margin rules are scoped to .db-stack, so nothing to reset here. */
16844
+ .db-radio-group--horizontal > .du-bois-light-hint,
16845
+ .db-radio-group--horizontal > .du-bois-dark-hint {
16724
16846
  display: inline-block;
16725
16847
  grid-row: hint / hint;
16726
16848
  }
16727
16849
 
16728
16850
  /* AntD `:has(> hint) { marginTop: sm }`: when the horizontal group contains a hint,
16729
16851
  * the group itself gets a top margin (room above the two-row grid). */
16730
- .ds-radio-group--horizontal:has(> .du-bois-light-hint),
16731
- .ds-radio-group--horizontal:has(> .du-bois-dark-hint) {
16732
- margin-top: var(--db-space-sm);
16852
+ .db-radio-group--horizontal:has(> .du-bois-light-hint),
16853
+ .db-radio-group--horizontal:has(> .du-bois-dark-hint) {
16854
+ margin-top: var(--db-spacing-2xs);
16733
16855
  }
16734
16856
 
16735
16857
  /* AntD `&& + form-message { marginTop: sm }` (horizontal): a form-message following
16736
16858
  * the whole group is separated by sm. */
16737
- .ds-radio-group--horizontal + .du-bois-light-form-message,
16738
- .ds-radio-group--horizontal + .du-bois-dark-form-message {
16739
- margin-top: var(--db-space-sm);
16859
+ .db-radio-group--horizontal + .du-bois-light-form-message,
16860
+ .db-radio-group--horizontal + .du-bois-dark-form-message {
16861
+ margin-top: var(--db-spacing-2xs);
16740
16862
  }
16741
16863
 
16742
- /* Component-tier tokens for <Switch>. Colors default to the selection-toggle category tokens;
16743
- * geometry is hand-authored (the pill track + sliding thumb are unique to Switch). */
16744
-
16745
- /* Re-declared under both theme classes (not just :root) so the var() chain onto
16746
- * category/system tokens re-resolves inside a `.du-bois-dark` subtree instead of
16747
- * freezing at the root (light) values. See DUBOIS-448 dark-mode scoping. */
16748
- :where(:root, .du-bois-light, .du-bois-dark) {
16749
- --db-switch-track-width: 28px;
16750
- --db-switch-track-height: 16px;
16751
- /* Thumb fills the track height by design; expressed via track-height so the two can't drift. */
16752
- --db-switch-thumb-size: var(--db-switch-track-height);
16753
- /* Pill radius overrides the category (square) radius, mirroring Radio's circular override. */
16864
+ :where(:root), :where(.du-bois-light) {
16865
+ /* Shape */
16754
16866
  --db-switch-border-radius: var(--db-radius-full);
16755
16867
  --db-switch-border-width: 1px;
16756
- --db-switch-spacing: var(--db-selection-toggle-spacing);
16757
16868
 
16758
- --db-switch-bg-default: var(--db-selection-toggle-bg-default);
16759
- --db-switch-bg-hover: var(--db-selection-toggle-bg-hover);
16760
- --db-switch-bg-press: var(--db-selection-toggle-bg-press);
16761
- --db-switch-bg-checked: var(--db-selection-toggle-bg-checked);
16762
- --db-switch-bg-checked-hover: var(--db-selection-toggle-bg-checked-hover);
16763
- --db-switch-bg-checked-press: var(--db-selection-toggle-bg-checked-press);
16764
- --db-switch-bg-disabled: var(--db-selection-toggle-bg-disabled);
16869
+ /* Color */
16870
+ --db-switch-surface: var(--db-selection-toggle-surface);
16871
+ --db-switch-surface-hover: var(--db-color-action-default-background-hover);
16872
+ --db-switch-surface-press: var(--db-color-action-default-background-press);
16873
+ --db-switch-surface-checked: var(--db-selection-toggle-surface-checked);
16874
+ --db-switch-surface-checked-hover: var(--db-selection-toggle-surface-checked-hover);
16875
+ --db-switch-surface-checked-press: var(--db-selection-toggle-surface-checked-press);
16876
+ --db-switch-surface-disabled: var(--db-selection-toggle-surface-disabled);
16877
+ --db-switch-surface-checked-disabled: var(--db-color-action-disabled-text);
16765
16878
 
16766
- --db-switch-border-default: var(--db-selection-toggle-border-default);
16879
+ --db-switch-border: var(--db-color-action-default-border-default);
16767
16880
  --db-switch-border-hover: var(--db-selection-toggle-border-hover);
16768
16881
  --db-switch-border-press: var(--db-selection-toggle-border-press);
16769
- --db-switch-border-disabled: var(--db-selection-toggle-border-disabled);
16770
- /* AntD paints the checked track border equal to the checked fill, so these alias the checked bg. */
16771
- --db-switch-border-checked: var(--db-selection-toggle-bg-checked);
16772
- --db-switch-border-checked-hover: var(--db-selection-toggle-bg-checked-hover);
16773
- --db-switch-border-checked-press: var(--db-selection-toggle-bg-checked-press);
16774
- --db-switch-border-focus: var(--db-selection-toggle-bg-checked);
16775
- /* AntD fills the disabled+checked track with actionDisabledText; no category token matches, so
16776
- * reference the system token directly (same escape hatch Radio uses for its checked-press border). */
16777
- --db-switch-bg-checked-disabled: var(--db-color-action-disabled-text);
16882
+ --db-switch-border-disabled: var(--db-color-action-disabled-border);
16883
+ --db-switch-border-checked: var(--db-selection-toggle-surface-checked);
16884
+ --db-switch-border-checked-hover: var(--db-selection-toggle-surface-checked-hover);
16885
+ --db-switch-border-checked-press: var(--db-selection-toggle-surface-checked-press);
16886
+ --db-switch-border-focus: var(--db-selection-toggle-surface-checked);
16778
16887
 
16779
- /* AntD paints the handle the off-track surface color in every state. */
16780
- --db-switch-thumb-color: var(--db-selection-toggle-bg-default);
16888
+ --db-switch-thumb: var(--db-selection-toggle-surface);
16781
16889
 
16782
- /* A token (not inherit) so the label text flips in dark mode. */
16783
- --db-switch-text: var(--db-color-text-primary);
16890
+ --db-switch-text: var(--db-selection-toggle-text);
16784
16891
  --db-switch-text-disabled: var(--db-selection-toggle-text-disabled);
16785
16892
 
16786
- /* AntD's focus ring is a 1px outline (the category default is 2px). */
16787
- --db-switch-focus-ring-width: 1px;
16788
- --db-switch-focus-ring-offset: 1px;
16789
- --db-switch-focus-ring-color: var(--db-selection-toggle-border-focus);
16893
+ /* Density */
16894
+ --db-switch-track-width: calc(var(--db-size-xs) * 1.75); /* 28px */
16895
+ --db-switch-track-height: var(--db-size-xs); /* 16px */
16896
+ --db-switch-thumb-size: var(--db-switch-track-height);
16897
+ --db-switch-label-spacing: var(--db-selection-toggle-label-spacing);
16898
+
16899
+ /* Motion */
16790
16900
  --db-switch-transition-duration: var(--db-selection-toggle-transition-duration);
16791
16901
  }
16792
16902
 
16793
- .ds-switch {
16903
+ .db-switch {
16794
16904
  /* flex, not inline-flex: an inline-flex root's line-box leading pushes block siblings
16795
16905
  * (e.g. a following FormMessage) down a few px, breaking the form-flow spacing. */
16796
16906
  display: flex;
@@ -16798,15 +16908,15 @@ span.du-bois-light-typography-ellipsis-single-line {
16798
16908
  cursor: pointer;
16799
16909
  user-select: none;
16800
16910
  width: fit-content;
16801
- margin-inline-end: var(--db-switch-spacing);
16911
+ margin-inline-end: var(--db-switch-label-spacing);
16802
16912
  }
16803
16913
 
16804
- .ds-switch:has(input:disabled) {
16914
+ .db-switch:has(input:disabled) {
16805
16915
  cursor: not-allowed;
16806
16916
  }
16807
16917
 
16808
16918
  /* The track. `appearance: none` strips the native checkbox rendering so the input itself can be styled. */
16809
- .ds-switch input {
16919
+ .db-switch input {
16810
16920
  appearance: none;
16811
16921
  position: relative;
16812
16922
  flex-shrink: 0;
@@ -16814,9 +16924,9 @@ span.du-bois-light-typography-ellipsis-single-line {
16814
16924
  cursor: pointer;
16815
16925
  inline-size: var(--db-switch-track-width);
16816
16926
  block-size: var(--db-switch-track-height);
16817
- border: var(--db-switch-border-width) solid var(--db-switch-border-default);
16927
+ border: var(--db-switch-border-width) solid var(--db-switch-border);
16818
16928
  border-radius: var(--db-switch-border-radius);
16819
- background-color: var(--db-switch-bg-default);
16929
+ background-color: var(--db-switch-surface);
16820
16930
  box-sizing: border-box;
16821
16931
  transition:
16822
16932
  background-color var(--db-switch-transition-duration) ease,
@@ -16825,7 +16935,7 @@ span.du-bois-light-typography-ellipsis-single-line {
16825
16935
 
16826
16936
  /* The thumb. A pseudo-element keeps the input the switch's only element, so nothing can overlay it
16827
16937
  * and intercept clicks. Offset left by the border width to sit flush with the track's outer edge. */
16828
- .ds-switch input::before {
16938
+ .db-switch input::before {
16829
16939
  content: '';
16830
16940
  position: absolute;
16831
16941
  top: 50%;
@@ -16835,110 +16945,112 @@ span.du-bois-light-typography-ellipsis-single-line {
16835
16945
  border: var(--db-switch-border-width) solid;
16836
16946
  border-color: inherit;
16837
16947
  border-radius: var(--db-switch-border-radius);
16838
- background-color: var(--db-switch-thumb-color);
16948
+ background-color: var(--db-switch-thumb);
16839
16949
  box-sizing: border-box;
16840
16950
  transform: translateY(-50%);
16841
16951
  transition: transform var(--db-switch-transition-duration) ease;
16842
16952
  }
16843
16953
 
16844
16954
  /* `<label for>` propagates `:hover` to the input, so scope hover/press to the control, not `input:hover`. */
16845
- .ds-switch:hover input:not(:disabled):not(:checked) {
16846
- background-color: var(--db-switch-bg-hover);
16955
+ .db-switch:hover input:not(:disabled):not(:checked) {
16956
+ background-color: var(--db-switch-surface-hover);
16847
16957
  border-color: var(--db-switch-border-hover);
16848
16958
  }
16849
16959
 
16850
- .ds-switch:active input:not(:disabled):not(:checked) {
16851
- background-color: var(--db-switch-bg-press);
16960
+ .db-switch:active input:not(:disabled):not(:checked) {
16961
+ background-color: var(--db-switch-surface-press);
16852
16962
  border-color: var(--db-switch-border-press);
16853
16963
  }
16854
16964
 
16855
- .ds-switch input:checked {
16856
- background-color: var(--db-switch-bg-checked);
16965
+ .db-switch input:checked {
16966
+ background-color: var(--db-switch-surface-checked);
16857
16967
  border-color: var(--db-switch-border-checked);
16858
16968
  }
16859
16969
 
16860
- .ds-switch:hover input:checked:not(:disabled) {
16861
- background-color: var(--db-switch-bg-checked-hover);
16970
+ .db-switch:hover input:checked:not(:disabled) {
16971
+ background-color: var(--db-switch-surface-checked-hover);
16862
16972
  border-color: var(--db-switch-border-checked-hover);
16863
16973
  }
16864
16974
 
16865
- .ds-switch:active input:checked:not(:disabled) {
16866
- background-color: var(--db-switch-bg-checked-press);
16975
+ .db-switch:active input:checked:not(:disabled) {
16976
+ background-color: var(--db-switch-surface-checked-press);
16867
16977
  border-color: var(--db-switch-border-checked-press);
16868
16978
  }
16869
16979
 
16870
- .ds-switch input:checked::before {
16980
+ .db-switch input:checked::before {
16871
16981
  transform: translateY(-50%) translateX(calc(var(--db-switch-track-width) - var(--db-switch-thumb-size)));
16872
16982
  }
16873
16983
 
16874
16984
  /* On focus, recolor the border to the checked-fill color on top of the outline ring. Matching AntD,
16875
- * the ring sits flush when off and gains a 1px offset when checked. */
16876
- .ds-switch input:focus-visible {
16985
+ * the ring sits flush when off and gains a 1px offset when checked.
16986
+ * TODO: width/offset are hardcoded 1px to preserve the AntD look; adopt the system 2px focus ring
16987
+ * (var(--db-focus-ring-width)) in a separate change. */
16988
+ .db-switch input:focus-visible {
16877
16989
  border-color: var(--db-switch-border-focus);
16878
- outline: var(--db-switch-focus-ring-width) solid var(--db-switch-focus-ring-color);
16990
+ outline: 1px solid var(--db-focus-ring-color);
16879
16991
  outline-offset: 0;
16880
16992
  }
16881
16993
 
16882
- .ds-switch input:checked:focus-visible {
16883
- outline-offset: var(--db-switch-focus-ring-offset);
16994
+ .db-switch input:checked:focus-visible {
16995
+ outline-offset: 1px;
16884
16996
  }
16885
16997
 
16886
- .ds-switch input:disabled {
16998
+ .db-switch input:disabled {
16887
16999
  cursor: not-allowed;
16888
- background-color: var(--db-switch-bg-disabled);
17000
+ background-color: var(--db-switch-surface-disabled);
16889
17001
  border-color: var(--db-switch-border-disabled);
16890
17002
  }
16891
17003
 
16892
17004
  /* Disabled + on: more specific than the plain disabled rule, so it wins regardless of source order. */
16893
- .ds-switch input:checked:disabled {
16894
- background-color: var(--db-switch-bg-checked-disabled);
16895
- border-color: var(--db-switch-bg-checked-disabled);
17005
+ .db-switch input:checked:disabled {
17006
+ background-color: var(--db-switch-surface-checked-disabled);
17007
+ border-color: var(--db-switch-surface-checked-disabled);
16896
17008
  }
16897
17009
 
16898
17010
  @media (prefers-reduced-motion: reduce) {
16899
- .ds-switch input,
16900
- .ds-switch input::before {
17011
+ .db-switch input,
17012
+ .db-switch input::before {
16901
17013
  transition: none;
16902
17014
  }
16903
17015
  }
16904
17016
 
16905
- .ds-switch-wrapper {
17017
+ .db-switch-wrapper {
16906
17018
  display: flex;
16907
17019
  align-items: center;
16908
17020
  }
16909
17021
 
16910
- .ds-switch-wrapper .ds-switch-state-message {
17022
+ .db-switch-wrapper .db-switch-state-message {
16911
17023
  margin-inline-start: auto;
16912
- margin-inline-end: var(--db-switch-spacing);
17024
+ margin-inline-end: var(--db-switch-label-spacing);
16913
17025
  }
16914
17026
 
16915
17027
  /* `:first-child` scopes this to the label-first layout; the plain layout renders the label last. */
16916
- .ds-switch-wrapper > .du-bois-light-label:first-child,
16917
- .ds-switch-wrapper > .du-bois-dark-label:first-child {
16918
- margin-inline-end: var(--db-switch-spacing);
17028
+ .db-switch-wrapper > .du-bois-light-label:first-child,
17029
+ .db-switch-wrapper > .du-bois-dark-label:first-child {
17030
+ margin-inline-end: var(--db-switch-label-spacing);
16919
17031
  }
16920
17032
 
16921
- .ds-switch-state-message {
17033
+ .db-switch-state-message {
16922
17034
  color: var(--db-switch-text);
16923
17035
  }
16924
17036
 
16925
- /* Target the <Label>'s class, not a bare `label` — that would also match the .ds-switch root <label>. */
16926
- .ds-switch-wrapper:has(input:disabled) .du-bois-light-label,
16927
- .ds-switch-wrapper:has(input:disabled) .du-bois-dark-label {
17037
+ /* Target the <Label>'s class, not a bare `label` — that would also match the .db-switch root <label>. */
17038
+ .db-switch-wrapper:has(input:disabled) .du-bois-light-label,
17039
+ .db-switch-wrapper:has(input:disabled) .du-bois-dark-label {
16928
17040
  color: var(--db-switch-text-disabled);
16929
17041
  }
16930
17042
 
16931
17043
  /* Indent a following hint/message past the track. The class is doubled to out-specify FormMessage's
16932
17044
  * own margin rule. */
16933
- :is(.ds-switch.ds-switch, .ds-switch-wrapper.ds-switch-wrapper)
16934
- + :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)
17045
+ :is(.db-switch.db-switch, .db-switch-wrapper.db-switch-wrapper)
17046
+ + :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)
16935
17047
  + :is(.du-bois-light-hint, .du-bois-dark-hint)
16936
17048
  + :is(.du-bois-light-form-message, .du-bois-dark-form-message) {
16937
- padding-inline-start: calc(var(--db-space-sm) + var(--db-switch-track-width));
17049
+ padding-inline-start: calc(var(--db-spacing-2xs) + var(--db-switch-track-width));
16938
17050
  }
16939
17051
 
16940
- :is(.ds-switch.ds-switch, .ds-switch-wrapper.ds-switch-wrapper)
16941
- + :is(.du-bois-light-form-message, .du-bois-dark-form-message), :is(.ds-switch.ds-switch, .ds-switch-wrapper.ds-switch-wrapper)
17052
+ :is(.db-switch.db-switch, .db-switch-wrapper.db-switch-wrapper)
17053
+ + :is(.du-bois-light-form-message, .du-bois-dark-form-message), :is(.db-switch.db-switch, .db-switch-wrapper.db-switch-wrapper)
16942
17054
  + :is(.du-bois-light-hint, .du-bois-dark-hint)
16943
17055
  + :is(.du-bois-light-form-message, .du-bois-dark-form-message) {
16944
17056
  margin-top: 0;