@nordmanai/nif 0.2.8 → 0.2.9

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 (56) hide show
  1. package/dist/index.js +572 -557
  2. package/dist/styles.css +1 -1
  3. package/dist/ui/config/nm-appearance.d.ts +13 -1
  4. package/dist/ui/lib/appearance/appearanceState.d.ts +2 -1
  5. package/package.json +1 -1
  6. package/registry/index.json +1 -1
  7. package/registry/ui/components/nm-ai/nm-ai.css +3 -3
  8. package/registry/ui/components/nm-alert/nm-alert.css +1 -1
  9. package/registry/ui/components/nm-button/nm-button.css +2 -2
  10. package/registry/ui/components/nm-button-group/nm-button-group.css +1 -1
  11. package/registry/ui/components/nm-calendar/nm-calendar.css +1 -1
  12. package/registry/ui/components/nm-card/nm-card.css +2 -2
  13. package/registry/ui/components/nm-chatbox/nm-chatbox.css +1 -1
  14. package/registry/ui/components/nm-checkbox/nm-checkbox.css +2 -2
  15. package/registry/ui/components/nm-chip/nm-chip.css +1 -1
  16. package/registry/ui/components/nm-code-block/nm-code-block.css +1 -1
  17. package/registry/ui/components/nm-collection/nm-collection.css +2 -2
  18. package/registry/ui/components/nm-color-picker/nm-color-picker.css +1 -1
  19. package/registry/ui/components/nm-combobox/nm-combobox.css +2 -2
  20. package/registry/ui/components/nm-command/nm-command.css +1 -1
  21. package/registry/ui/components/nm-composer/nm-composer.css +3 -3
  22. package/registry/ui/components/nm-date-picker/nm-date-picker.css +2 -2
  23. package/registry/ui/components/nm-dialog/nm-dialog.css +1 -1
  24. package/registry/ui/components/nm-drawer/nm-drawer.css +2 -2
  25. package/registry/ui/components/nm-dropdown/nm-dropdown.css +2 -2
  26. package/registry/ui/components/nm-dropdown-menu/nm-dropdown-menu.css +1 -1
  27. package/registry/ui/components/nm-field/nm-field.css +6 -6
  28. package/registry/ui/components/nm-hover-card/nm-hover-card.css +1 -1
  29. package/registry/ui/components/nm-input/nm-input.css +3 -3
  30. package/registry/ui/components/nm-input-group/nm-input-group.css +2 -2
  31. package/registry/ui/components/nm-message/nm-message.css +1 -1
  32. package/registry/ui/components/nm-native-select/nm-native-select.css +2 -2
  33. package/registry/ui/components/nm-popover/nm-popover.css +1 -1
  34. package/registry/ui/components/nm-prose/nm-prose.css +3 -3
  35. package/registry/ui/components/nm-questionnaire/nm-questionnaire.css +3 -3
  36. package/registry/ui/components/nm-radio-group/nm-radio-group.css +2 -2
  37. package/registry/ui/components/nm-segmented/nm-segmented.css +1 -1
  38. package/registry/ui/components/nm-select/nm-select.css +2 -2
  39. package/registry/ui/components/nm-separator/nm-separator.css +1 -1
  40. package/registry/ui/components/nm-side-panel/nm-side-panel.css +1 -1
  41. package/registry/ui/components/nm-sidebar/nm-sidebar.css +9 -9
  42. package/registry/ui/components/nm-spinner/nm-spinner.css +1 -1
  43. package/registry/ui/components/nm-switch/nm-switch.css +1 -1
  44. package/registry/ui/components/nm-table/nm-table.css +4 -4
  45. package/registry/ui/components/nm-tabs/nm-tabs.css +1 -1
  46. package/registry/ui/components/nm-textarea/nm-textarea.css +5 -5
  47. package/registry/ui/components/nm-toggle/nm-toggle.css +1 -1
  48. package/registry/ui/components/nordman-icon-button/nordman-icon-button.css +2 -2
  49. package/registry/ui/components/nordman-login/nordman-login.css +3 -3
  50. package/registry/ui/components/nordman-toggle/nordman-toggle.css +1 -1
  51. package/registry/ui/config/nm-appearance.ts +17 -0
  52. package/registry/ui/lib/appearance/appearanceState.ts +8 -0
  53. package/registry/ui/lib/appearance/applyAppearance.ts +3 -1
  54. package/registry/ui/lib/appearance/deriveTokens.ts +2 -0
  55. package/registry/ui/styles/light-appearance.css +3 -3
  56. package/registry/ui/styles/tokens.css +21 -0
@@ -18,7 +18,7 @@
18
18
  .nm-sidebar-provider[data-height='sm'],
19
19
  .nm-sidebar-provider[data-height='lg'] {
20
20
  min-height: 0;
21
- border: var(--nm-rule) solid var(--nm-line-strong);
21
+ border: var(--nm-rule) solid var(--nm-border-strong);
22
22
  border-radius: var(--nm-radius-lg);
23
23
  }
24
24
  .nm-sidebar-provider[data-height='sm'] {
@@ -48,10 +48,10 @@
48
48
  order: 1;
49
49
  }
50
50
  .nm-sidebar[data-variant='sidebar'][data-side='left'] {
51
- border-inline-end: var(--nm-rule) solid var(--nm-divider);
51
+ border-inline-end: var(--nm-rule) solid var(--nm-border-divider);
52
52
  }
53
53
  .nm-sidebar[data-variant='sidebar'][data-side='right'] {
54
- border-inline-start: var(--nm-rule) solid var(--nm-divider);
54
+ border-inline-start: var(--nm-rule) solid var(--nm-border-divider);
55
55
  }
56
56
  .nm-sidebar[data-collapsible='offcanvas'] {
57
57
  width: 0;
@@ -95,20 +95,20 @@
95
95
  inset-block: 0;
96
96
  inset-inline-start: 0;
97
97
  width: var(--nm-sidebar-width);
98
- border-inline-end: var(--nm-rule) solid var(--nm-line-strong);
98
+ border-inline-end: var(--nm-rule) solid var(--nm-border-strong);
99
99
  background: var(--nm-raised);
100
100
  }
101
101
  .nm-sidebar[data-side='right'][data-peek] .nm-sidebar__inner {
102
102
  inset-inline-start: auto;
103
103
  inset-inline-end: 0;
104
104
  border-inline-end: 0;
105
- border-inline-start: var(--nm-rule) solid var(--nm-line-strong);
105
+ border-inline-start: var(--nm-rule) solid var(--nm-border-strong);
106
106
  }
107
107
  .nm-sidebar[data-variant='floating'][data-peek] .nm-sidebar__inner,
108
108
  .nm-sidebar[data-variant='inset'][data-peek] .nm-sidebar__inner {
109
109
  inset-block: var(--nm-space-8);
110
110
  inset-inline-start: var(--nm-space-8);
111
- border: var(--nm-rule) solid var(--nm-line-strong);
111
+ border: var(--nm-rule) solid var(--nm-border-strong);
112
112
  border-radius: var(--nm-radius-lg);
113
113
  }
114
114
  .nm-sidebar[data-variant='floating'][data-side='right'][data-peek] .nm-sidebar__inner,
@@ -132,7 +132,7 @@
132
132
  padding-inline-start: 0;
133
133
  }
134
134
  .nm-sidebar[data-variant='floating'] .nm-sidebar__inner {
135
- border: var(--nm-rule) solid var(--nm-line-strong);
135
+ border: var(--nm-rule) solid var(--nm-border-strong);
136
136
  border-radius: var(--nm-radius-lg);
137
137
  background: var(--nm-raised);
138
138
  }
@@ -392,7 +392,7 @@
392
392
  opacity: var(--control-disabled-opacity);
393
393
  }
394
394
  .nm-sidebar__menu-button[data-variant='outline'] {
395
- border-color: var(--nm-line-strong);
395
+ border-color: var(--nm-border-strong);
396
396
  background: var(--nm-raised);
397
397
  }
398
398
  .nm-sidebar__menu-button[data-variant='outline']:hover,
@@ -514,7 +514,7 @@
514
514
  margin-inline-start: calc(var(--nm-icon-pad) + var(--nm-icon-button) / 2);
515
515
  padding-inline-start: calc(var(--nm-icon-pad) + var(--nm-icon-button) / 2);
516
516
  padding-block: var(--nm-space-2);
517
- border-inline-start: var(--nm-rule) solid var(--nm-line);
517
+ border-inline-start: var(--nm-rule) solid var(--nm-border);
518
518
  }
519
519
  .nm-sidebar__menu-sub-button {
520
520
  display: flex;
@@ -3,7 +3,7 @@
3
3
  box-sizing: border-box;
4
4
  width: var(--nm-icon);
5
5
  height: var(--nm-icon);
6
- border: 2px solid var(--nm-line-strong);
6
+ border: 2px solid var(--nm-border-strong);
7
7
  border-top-color: var(--nm-fg);
8
8
  border-radius: 50%;
9
9
  animation: nm-spinner-turn 0.8s linear infinite;
@@ -7,7 +7,7 @@
7
7
  width: calc(var(--nm-switch-thumb) * 2);
8
8
  height: var(--nm-switch-thumb);
9
9
  padding: var(--nm-space-2);
10
- border: var(--nm-rule) solid var(--nm-line-strong);
10
+ border: var(--nm-rule) solid var(--nm-border-strong);
11
11
  border-radius: var(--toggle-r);
12
12
  background: var(--nm-panel);
13
13
  cursor: pointer;
@@ -32,7 +32,7 @@
32
32
 
33
33
  .nm-table__head {
34
34
  padding: var(--nm-table-pad-y) var(--nm-table-pad-x);
35
- border-bottom: var(--nm-rule) solid var(--nm-line-strong);
35
+ border-bottom: var(--nm-rule) solid var(--nm-border-strong);
36
36
  color: var(--nm-fg-muted);
37
37
  font-size: var(--nm-type-ui-sm);
38
38
  font-weight: var(--nm-weight-medium);
@@ -75,7 +75,7 @@
75
75
 
76
76
  .nm-table[data-variant='default'] .nm-table__body .nm-table__row:not(:last-child),
77
77
  .nm-table[data-variant='striped'] .nm-table__body .nm-table__row:not(:last-child) {
78
- border-bottom: var(--nm-rule) solid var(--nm-line);
78
+ border-bottom: var(--nm-rule) solid var(--nm-border);
79
79
  }
80
80
 
81
81
  .nm-table[data-variant='striped'] .nm-table__body .nm-table__row:nth-child(even) {
@@ -84,7 +84,7 @@
84
84
 
85
85
  .nm-table[data-variant='lined'] .nm-table__head,
86
86
  .nm-table[data-variant='lined'] .nm-table__cell {
87
- border: var(--nm-rule) solid var(--nm-line);
87
+ border: var(--nm-rule) solid var(--nm-border);
88
88
  }
89
89
 
90
90
  .nm-table[data-variant='plain'] .nm-table__head {
@@ -112,7 +112,7 @@
112
112
  }
113
113
 
114
114
  .nm-table__footer {
115
- border-top: var(--nm-rule) solid var(--nm-line-strong);
115
+ border-top: var(--nm-rule) solid var(--nm-border-strong);
116
116
  background: var(--nm-raised);
117
117
  font-weight: var(--nm-weight-medium);
118
118
  }
@@ -2,7 +2,7 @@
2
2
  display: flex;
3
3
  flex-wrap: wrap;
4
4
  gap: var(--nm-space-4);
5
- border-bottom: var(--nm-rule) solid var(--nm-line);
5
+ border-bottom: var(--nm-rule) solid var(--nm-border);
6
6
  }
7
7
 
8
8
  .nm-tabs__item {
@@ -4,7 +4,7 @@
4
4
  width: 100%;
5
5
  min-height: calc(var(--control-h) * 2.5);
6
6
  padding: var(--field-area-py) var(--control-px);
7
- border: var(--nm-rule) solid var(--nm-line-strong);
7
+ border: var(--nm-rule) solid var(--nm-border-strong);
8
8
  border-radius: var(--nm-control-r);
9
9
  background: var(--nm-raised);
10
10
  color: var(--nm-fg);
@@ -24,7 +24,7 @@
24
24
  }
25
25
 
26
26
  .nm-textarea:hover:not(:disabled) {
27
- border-color: var(--nm-stroke);
27
+ border-color: var(--nm-border-stroke);
28
28
  }
29
29
 
30
30
  .nm-textarea:focus-visible {
@@ -102,7 +102,7 @@
102
102
  flex: none;
103
103
  flex-direction: column;
104
104
  width: var(--nm-side-panel-basis, 50%);
105
- border-inline-start: var(--nm-rule) solid var(--nm-divider);
105
+ border-inline-start: var(--nm-rule) solid var(--nm-border-divider);
106
106
  background: var(--nm-canvas);
107
107
  }
108
108
 
@@ -133,7 +133,7 @@
133
133
  height: 100%;
134
134
  min-height: 100%;
135
135
  padding: var(--nm-space-16);
136
- border: var(--nm-rule) solid var(--nm-line-strong);
136
+ border: var(--nm-rule) solid var(--nm-border-strong);
137
137
  border-radius: var(--nm-control-r);
138
138
  outline: none;
139
139
  resize: none;
@@ -156,7 +156,7 @@
156
156
  height: 100%;
157
157
  padding: var(--nm-space-16);
158
158
  overflow-y: auto;
159
- border: var(--nm-rule) solid var(--nm-line-strong);
159
+ border: var(--nm-rule) solid var(--nm-border-strong);
160
160
  border-radius: var(--nm-control-r);
161
161
  background: var(--nm-raised);
162
162
  }
@@ -31,7 +31,7 @@
31
31
  }
32
32
 
33
33
  .nm-toggle-button[data-variant='outline'] {
34
- border-color: var(--nm-line-strong);
34
+ border-color: var(--nm-border-strong);
35
35
  }
36
36
 
37
37
  .nm-toggle-button:hover:not([data-disabled]) {
@@ -33,7 +33,7 @@
33
33
  /* Raised sits on a surface of its own with an edge, so it reads on any background. Panel has no edge. */
34
34
  .nm-icon-button--raised {
35
35
  background: var(--nm-raised);
36
- box-shadow: inset 0 0 0 var(--nm-rule) var(--nm-line-strong);
36
+ box-shadow: inset 0 0 0 var(--nm-rule) var(--nm-border-strong);
37
37
  }
38
38
 
39
39
  .nm-icon-button--quiet {
@@ -48,7 +48,7 @@
48
48
  .nm-icon-button--quiet.nm-icon-button--active:not(:disabled) {
49
49
  background: var(--nm-raised);
50
50
  color: var(--nm-fg);
51
- box-shadow: inset 0 0 0 var(--nm-rule) var(--nm-line);
51
+ box-shadow: inset 0 0 0 var(--nm-rule) var(--nm-border);
52
52
  }
53
53
 
54
54
  .nm-icon-button--solid {
@@ -47,7 +47,7 @@
47
47
  .nm-login__error {
48
48
  margin: 0;
49
49
  color: var(--nm-fg);
50
- border: var(--nm-rule) solid var(--nm-line-strong);
50
+ border: var(--nm-rule) solid var(--nm-border-strong);
51
51
  border-radius: var(--nm-control-r);
52
52
  padding: var(--control-px);
53
53
  font-size: var(--control-fs);
@@ -89,7 +89,7 @@
89
89
  width: 100%;
90
90
  height: var(--nm-field-h);
91
91
  padding: 0 var(--control-px);
92
- border: var(--nm-rule) solid var(--nm-line-strong);
92
+ border: var(--nm-rule) solid var(--nm-border-strong);
93
93
  border-radius: var(--nm-control-r);
94
94
  background: var(--nm-raised);
95
95
  color: var(--nm-fg);
@@ -98,7 +98,7 @@
98
98
  }
99
99
 
100
100
  .nm-login__control:focus {
101
- border-color: var(--nm-stroke);
101
+ border-color: var(--nm-border-stroke);
102
102
  outline: none;
103
103
  }
104
104
 
@@ -6,7 +6,7 @@
6
6
  max-width: 100%;
7
7
  overflow-x: auto;
8
8
  padding: var(--toggle-pad);
9
- border: var(--nm-rule) solid var(--nm-line-strong);
9
+ border: var(--nm-rule) solid var(--nm-border-strong);
10
10
  border-radius: var(--toggle-r);
11
11
  }
12
12
 
@@ -55,6 +55,21 @@ export const NM_UI_SPACE_PERCENT = {
55
55
  default: 100,
56
56
  } as const;
57
57
 
58
+ /**
59
+ * How visible the borders are. Every border colour in the kit is mixed through one strength, so default is the kit as
60
+ * drawn, subtle is barely there, and none removes them. Geometry does not change: the border turns transparent and keeps
61
+ * its width. Fills and tracks that share the line colours are untouched, and so are state borders: focus, selection, checked and
62
+ * error keep their colour.
63
+ */
64
+ export const NM_BORDER_STYLES = ['default', 'subtle', 'none'] as const;
65
+ export type NmBorderStyle = (typeof NM_BORDER_STYLES)[number];
66
+ export const NM_BORDER_STRENGTH: Record<NmBorderStyle, string> = {
67
+ default: '100%',
68
+ subtle: '35%',
69
+ none: '0%',
70
+ };
71
+ /** Set on the root beside the tokens, so a product can style a state without the appearance script: `:root[data-nm-borders="none"]`. */
72
+ export const NM_BORDER_ATTRIBUTE = 'data-nm-borders' as const;
58
73
  export const NM_APPEARANCE_CONTRAST = {
59
74
  min: 0,
60
75
  max: 100,
@@ -183,6 +198,7 @@ export const NM_APPEARANCE_DEFAULTS = {
183
198
  uiRadiusPercent: NM_UI_RADIUS_PERCENT.default,
184
199
  uiSpacePercent: NM_UI_SPACE_PERCENT.default,
185
200
  contrast: NM_APPEARANCE_CONTRAST.default,
201
+ borders: 'default' as NmBorderStyle,
186
202
  } as const;
187
203
 
188
204
  export const NM_APPEARANCE_CSS_VARS = [
@@ -241,6 +257,7 @@ export const NM_APPEARANCE_CSS_VARS = [
241
257
  '--nm-ui-chip-min-height',
242
258
  '--nm-radius-scale',
243
259
  '--nm-space-scale',
260
+ '--nm-border-strength',
244
261
  '--text-primary',
245
262
  '--text-secondary',
246
263
  '--text-tertiary',
@@ -4,6 +4,7 @@ import {
4
4
  NM_APPEARANCE_DEFAULTS,
5
5
  NM_APPEARANCE_MODES,
6
6
  NM_APPEARANCE_STORAGE_KEY,
7
+ NM_BORDER_STYLES,
7
8
  NM_UI_FONT_SIZE_PX,
8
9
  NM_UI_FONT_WEIGHT,
9
10
  NM_UI_ICON_SIZE_PX,
@@ -12,6 +13,7 @@ import {
12
13
  findThemePreset,
13
14
  type NmAccentPreset,
14
15
  type NmAppearanceMode,
16
+ type NmBorderStyle,
15
17
  } from '../../config/nm-appearance.ts';
16
18
  import { normalizeHexColor } from './color.ts';
17
19
 
@@ -28,6 +30,7 @@ export type NmAppearanceState = {
28
30
  uiRadiusPercent: number;
29
31
  uiSpacePercent: number;
30
32
  contrast: number;
33
+ borders: NmBorderStyle;
31
34
  };
32
35
 
33
36
  export { NM_APPEARANCE_STORAGE_KEY };
@@ -36,6 +39,9 @@ function isMode(value: unknown): value is NmAppearanceMode {
36
39
  return typeof value === 'string' && (NM_APPEARANCE_MODES as readonly string[]).includes(value);
37
40
  }
38
41
 
42
+ function isBorderStyle(value: unknown): value is NmBorderStyle {
43
+ return typeof value === 'string' && (NM_BORDER_STYLES as readonly string[]).includes(value);
44
+ }
39
45
  function isAccentPreset(value: unknown): value is NmAccentPreset {
40
46
  return typeof value === 'string' && (NM_ACCENT_PRESETS as readonly string[]).includes(value);
41
47
  }
@@ -82,6 +88,7 @@ export function createDefaultAppearanceState(): NmAppearanceState {
82
88
  uiRadiusPercent: NM_APPEARANCE_DEFAULTS.uiRadiusPercent,
83
89
  uiSpacePercent: NM_APPEARANCE_DEFAULTS.uiSpacePercent,
84
90
  contrast: NM_APPEARANCE_CONTRAST.default,
91
+ borders: NM_APPEARANCE_DEFAULTS.borders,
85
92
  };
86
93
  return applyThemePresetPalette(base);
87
94
  }
@@ -185,6 +192,7 @@ export function parseAppearanceState(raw: unknown): NmAppearanceState {
185
192
  NM_APPEARANCE_CONTRAST.max,
186
193
  defaults.contrast,
187
194
  ),
195
+ borders: isBorderStyle(record.borders) ? record.borders : defaults.borders,
188
196
  };
189
197
  }
190
198
 
@@ -1,5 +1,5 @@
1
1
  import type { NmAppearanceState } from './appearanceState.ts';
2
- import { NM_APPEARANCE_APPLIED_EVENT, NM_APPEARANCE_CSS_VARS } from '../../config/nm-appearance.ts';
2
+ import { NM_APPEARANCE_APPLIED_EVENT, NM_APPEARANCE_CSS_VARS, NM_BORDER_ATTRIBUTE } from '../../config/nm-appearance.ts';
3
3
  import { resolveAppearanceScheme } from './appearanceState.ts';
4
4
  import { deriveAppearanceTokens } from './deriveTokens.ts';
5
5
  import { createLogger } from '../../kit-logger.ts';
@@ -17,6 +17,7 @@ export function clearAppliedAppearance(root: HTMLElement = document.documentElem
17
17
  NM_APPEARANCE_CSS_VARS.forEach((property) => {
18
18
  root.style.removeProperty(property);
19
19
  });
20
+ root.removeAttribute(NM_BORDER_ATTRIBUTE);
20
21
  }
21
22
 
22
23
  export function applyAppearanceState(
@@ -29,6 +30,7 @@ export function applyAppearanceState(
29
30
  Object.entries(tokens).forEach(([property, value]) => {
30
31
  root.style.setProperty(property, value);
31
32
  });
33
+ root.setAttribute(NM_BORDER_ATTRIBUTE, state.borders);
32
34
  if (typeof window !== 'undefined') {
33
35
  window.dispatchEvent(new CustomEvent(NM_APPEARANCE_APPLIED_EVENT));
34
36
  }
@@ -2,6 +2,7 @@ import type { NmAppearanceState } from './appearanceState.ts';
2
2
  import {
3
3
  NM_ACCENT_HEX,
4
4
  NM_APPEARANCE_CONTRAST,
5
+ NM_BORDER_STRENGTH,
5
6
  NM_THEME_PRESETS,
6
7
  NM_UI_FONT_SIZE_PX,
7
8
  NM_UI_FONT_WEIGHT,
@@ -205,6 +206,7 @@ export function deriveAppearanceTokens(
205
206
  ...deriveUiControlTokens(state.uiFontSizePx, state.uiIconSizePx),
206
207
  ...deriveRadiusScale(state.uiRadiusPercent),
207
208
  ...deriveSpaceScale(state.uiSpacePercent),
209
+ '--nm-border-strength': NM_BORDER_STRENGTH[state.borders],
208
210
  };
209
211
 
210
212
  return {
@@ -1,10 +1,10 @@
1
1
  html.light .nm-panel-bar {
2
- border-bottom-color: var(--nm-line);
2
+ border-bottom-color: var(--nm-border);
3
3
  }
4
4
 
5
5
  html.light .nm-collection__stage-bar {
6
- border-bottom-color: var(--nm-line);
7
- border-left-color: var(--nm-line);
6
+ border-bottom-color: var(--nm-border);
7
+ border-left-color: var(--nm-border);
8
8
  }
9
9
 
10
10
  html.light .nm-list-item:not(.nm-list-item--face) {
@@ -321,6 +321,18 @@
321
321
  --nm-knot-pulse: 3.2s;
322
322
  --nm-knot-pulse-min: 0.4;
323
323
  --nm-rule: 1px;
324
+ /* Borders. Every border colour is one of the line colours mixed through one strength, so a product can turn its
325
+ borders subtle or off in one place while the fills and tracks that share those colours keep theirs. The border
326
+ keeps its width and turns transparent, so nothing moves. State is not part of this: focus, selection, checked and error
327
+ borders keep the foreground or destructive colour, so a keyboard user and an active tab are never lost. */
328
+ --nm-border-strength: 100%;
329
+ --nm-border: color-mix(in srgb, var(--nm-line) var(--nm-border-strength), transparent);
330
+ --nm-border-strong: color-mix(in srgb, var(--nm-line-strong) var(--nm-border-strength), transparent);
331
+ --nm-border-stroke: color-mix(in srgb, var(--nm-stroke) var(--nm-border-strength), transparent);
332
+ --nm-border-divider: color-mix(in srgb, var(--nm-divider) var(--nm-border-strength), transparent);
333
+ /* A control whose only shape is its border (checkbox, radio) takes this fill, so it still has a shape with the
334
+ borders off. Transparent until then. */
335
+ --nm-borderless-fill: transparent;
324
336
  --nm-rule-dash: 4px;
325
337
  --nm-rule-gap: 4px;
326
338
  --nm-rule-pair: 2.5rem;
@@ -439,3 +451,12 @@ html.light {
439
451
  --nm-syntax-function: #6f42c1;
440
452
  --nm-syntax-constant: #005cc5;
441
453
  }
454
+
455
+ /* The border setting without the appearance script: set the attribute on the root. */
456
+ :root[data-nm-borders='subtle'] {
457
+ --nm-border-strength: 35%;
458
+ }
459
+ :root[data-nm-borders='none'] {
460
+ --nm-border-strength: 0%;
461
+ --nm-borderless-fill: var(--nm-inset);
462
+ }