@northstar-js/react 0.0.0-stage → 0.2.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (182) hide show
  1. package/LICENSE +21 -0
  2. package/dist/actions.d.ts +99 -0
  3. package/dist/actions.d.ts.map +1 -0
  4. package/dist/actions.js +61 -0
  5. package/dist/actions.js.map +1 -0
  6. package/dist/backdrops/StarBackdrop.d.ts +31 -0
  7. package/dist/backdrops/StarBackdrop.d.ts.map +1 -0
  8. package/dist/backdrops/StarBackdrop.js +84 -0
  9. package/dist/backdrops/StarBackdrop.js.map +1 -0
  10. package/dist/backdrops/index.d.ts +7 -0
  11. package/dist/backdrops/index.d.ts.map +1 -0
  12. package/dist/backdrops/index.js +8 -0
  13. package/dist/backdrops/index.js.map +1 -0
  14. package/dist/backdrops/math.d.ts +39 -0
  15. package/dist/backdrops/math.d.ts.map +1 -0
  16. package/dist/backdrops/math.js +44 -0
  17. package/dist/backdrops/math.js.map +1 -0
  18. package/dist/backdrops/scenes.d.ts +20 -0
  19. package/dist/backdrops/scenes.d.ts.map +1 -0
  20. package/dist/backdrops/scenes.js +417 -0
  21. package/dist/backdrops/scenes.js.map +1 -0
  22. package/dist/backdrops.css +141 -0
  23. package/dist/data.d.ts +91 -0
  24. package/dist/data.d.ts.map +1 -0
  25. package/dist/data.js +69 -0
  26. package/dist/data.js.map +1 -0
  27. package/dist/effects/actions.d.ts +48 -0
  28. package/dist/effects/actions.d.ts.map +1 -0
  29. package/dist/effects/actions.js +80 -0
  30. package/dist/effects/actions.js.map +1 -0
  31. package/dist/effects/controls.d.ts +84 -0
  32. package/dist/effects/controls.d.ts.map +1 -0
  33. package/dist/effects/controls.js +121 -0
  34. package/dist/effects/controls.js.map +1 -0
  35. package/dist/effects/display.d.ts +92 -0
  36. package/dist/effects/display.d.ts.map +1 -0
  37. package/dist/effects/display.js +138 -0
  38. package/dist/effects/display.js.map +1 -0
  39. package/dist/effects/hooks.d.ts +13 -0
  40. package/dist/effects/hooks.d.ts.map +1 -0
  41. package/dist/effects/hooks.js +68 -0
  42. package/dist/effects/hooks.js.map +1 -0
  43. package/dist/effects/index.d.ts +14 -0
  44. package/dist/effects/index.d.ts.map +1 -0
  45. package/dist/effects/index.js +12 -0
  46. package/dist/effects/index.js.map +1 -0
  47. package/dist/effects/loaders.d.ts +67 -0
  48. package/dist/effects/loaders.d.ts.map +1 -0
  49. package/dist/effects/loaders.js +73 -0
  50. package/dist/effects/loaders.js.map +1 -0
  51. package/dist/effects/math.d.ts +23 -0
  52. package/dist/effects/math.d.ts.map +1 -0
  53. package/dist/effects/math.js +56 -0
  54. package/dist/effects/math.js.map +1 -0
  55. package/dist/effects/navigation.d.ts +55 -0
  56. package/dist/effects/navigation.d.ts.map +1 -0
  57. package/dist/effects/navigation.js +103 -0
  58. package/dist/effects/navigation.js.map +1 -0
  59. package/dist/effects/overlays.d.ts +34 -0
  60. package/dist/effects/overlays.d.ts.map +1 -0
  61. package/dist/effects/overlays.js +56 -0
  62. package/dist/effects/overlays.js.map +1 -0
  63. package/dist/effects.css +1659 -0
  64. package/dist/feedback.d.ts +55 -0
  65. package/dist/feedback.d.ts.map +1 -0
  66. package/dist/feedback.js +60 -0
  67. package/dist/feedback.js.map +1 -0
  68. package/dist/flow.d.ts +70 -0
  69. package/dist/flow.d.ts.map +1 -0
  70. package/dist/flow.js +118 -0
  71. package/dist/flow.js.map +1 -0
  72. package/dist/forms.d.ts +130 -0
  73. package/dist/forms.d.ts.map +1 -0
  74. package/dist/forms.js +241 -0
  75. package/dist/forms.js.map +1 -0
  76. package/dist/glass.d.ts +74 -0
  77. package/dist/glass.d.ts.map +1 -0
  78. package/dist/glass.js +139 -0
  79. package/dist/glass.js.map +1 -0
  80. package/dist/illustrations/data.d.ts +103 -0
  81. package/dist/illustrations/data.d.ts.map +1 -0
  82. package/dist/illustrations/data.js +3 -0
  83. package/dist/illustrations/data.js.map +1 -0
  84. package/dist/illustrations/index.d.ts +110 -0
  85. package/dist/illustrations/index.d.ts.map +1 -0
  86. package/dist/illustrations/index.js +54 -0
  87. package/dist/illustrations/index.js.map +1 -0
  88. package/dist/illustrations/types.d.ts +30 -0
  89. package/dist/illustrations/types.d.ts.map +1 -0
  90. package/dist/illustrations/types.js +2 -0
  91. package/dist/illustrations/types.js.map +1 -0
  92. package/dist/index.d.ts +27 -0
  93. package/dist/index.d.ts.map +1 -0
  94. package/dist/index.js +13 -0
  95. package/dist/index.js.map +1 -0
  96. package/dist/internal/expand.d.ts +17 -0
  97. package/dist/internal/expand.d.ts.map +1 -0
  98. package/dist/internal/expand.js +23 -0
  99. package/dist/internal/expand.js.map +1 -0
  100. package/dist/internal/icons.d.ts +9 -0
  101. package/dist/internal/icons.d.ts.map +1 -0
  102. package/dist/internal/icons.js +12 -0
  103. package/dist/internal/icons.js.map +1 -0
  104. package/dist/internal/interaction.d.ts +21 -0
  105. package/dist/internal/interaction.d.ts.map +1 -0
  106. package/dist/internal/interaction.js +129 -0
  107. package/dist/internal/interaction.js.map +1 -0
  108. package/dist/internal/layers.d.ts +12 -0
  109. package/dist/internal/layers.d.ts.map +1 -0
  110. package/dist/internal/layers.js +108 -0
  111. package/dist/internal/layers.js.map +1 -0
  112. package/dist/internal/util.d.ts +9 -0
  113. package/dist/internal/util.d.ts.map +1 -0
  114. package/dist/internal/util.js +33 -0
  115. package/dist/internal/util.js.map +1 -0
  116. package/dist/layout.d.ts +34 -0
  117. package/dist/layout.d.ts.map +1 -0
  118. package/dist/layout.js +27 -0
  119. package/dist/layout.js.map +1 -0
  120. package/dist/motion.d.ts +36 -0
  121. package/dist/motion.d.ts.map +1 -0
  122. package/dist/motion.js +80 -0
  123. package/dist/motion.js.map +1 -0
  124. package/dist/navigation.d.ts +100 -0
  125. package/dist/navigation.d.ts.map +1 -0
  126. package/dist/navigation.js +154 -0
  127. package/dist/navigation.js.map +1 -0
  128. package/dist/northstar/BriefForm.d.ts +23 -0
  129. package/dist/northstar/BriefForm.d.ts.map +1 -0
  130. package/dist/northstar/BriefForm.js +40 -0
  131. package/dist/northstar/BriefForm.js.map +1 -0
  132. package/dist/northstar/ExportMenu.d.ts +16 -0
  133. package/dist/northstar/ExportMenu.d.ts.map +1 -0
  134. package/dist/northstar/ExportMenu.js +11 -0
  135. package/dist/northstar/ExportMenu.js.map +1 -0
  136. package/dist/northstar/PopulationPanel.d.ts +30 -0
  137. package/dist/northstar/PopulationPanel.d.ts.map +1 -0
  138. package/dist/northstar/PopulationPanel.js +18 -0
  139. package/dist/northstar/PopulationPanel.js.map +1 -0
  140. package/dist/northstar/ResearchBuilder.d.ts +26 -0
  141. package/dist/northstar/ResearchBuilder.d.ts.map +1 -0
  142. package/dist/northstar/ResearchBuilder.js +81 -0
  143. package/dist/northstar/ResearchBuilder.js.map +1 -0
  144. package/dist/northstar/ResponsesView.d.ts +20 -0
  145. package/dist/northstar/ResponsesView.d.ts.map +1 -0
  146. package/dist/northstar/ResponsesView.js +42 -0
  147. package/dist/northstar/ResponsesView.js.map +1 -0
  148. package/dist/northstar/Run.d.ts +37 -0
  149. package/dist/northstar/Run.d.ts.map +1 -0
  150. package/dist/northstar/Run.js +32 -0
  151. package/dist/northstar/Run.js.map +1 -0
  152. package/dist/northstar/StudyShell.d.ts +50 -0
  153. package/dist/northstar/StudyShell.d.ts.map +1 -0
  154. package/dist/northstar/StudyShell.js +18 -0
  155. package/dist/northstar/StudyShell.js.map +1 -0
  156. package/dist/northstar/StudyStatus.d.ts +17 -0
  157. package/dist/northstar/StudyStatus.d.ts.map +1 -0
  158. package/dist/northstar/StudyStatus.js +26 -0
  159. package/dist/northstar/StudyStatus.js.map +1 -0
  160. package/dist/northstar/index.d.ts +10 -0
  161. package/dist/northstar/index.d.ts.map +1 -0
  162. package/dist/northstar/index.js +10 -0
  163. package/dist/northstar/index.js.map +1 -0
  164. package/dist/northstar/messages.d.ts +84 -0
  165. package/dist/northstar/messages.d.ts.map +1 -0
  166. package/dist/northstar/messages.js +107 -0
  167. package/dist/northstar/messages.js.map +1 -0
  168. package/dist/overlays.d.ts +136 -0
  169. package/dist/overlays.d.ts.map +1 -0
  170. package/dist/overlays.js +447 -0
  171. package/dist/overlays.js.map +1 -0
  172. package/dist/provider.d.ts +82 -0
  173. package/dist/provider.d.ts.map +1 -0
  174. package/dist/provider.js +128 -0
  175. package/dist/provider.js.map +1 -0
  176. package/dist/styles.css +2033 -0
  177. package/dist/surface.d.ts +58 -0
  178. package/dist/surface.d.ts.map +1 -0
  179. package/dist/surface.js +39 -0
  180. package/dist/surface.js.map +1 -0
  181. package/package.json +81 -3
  182. package/README.md +0 -3
@@ -0,0 +1,2033 @@
1
+ /* @northstar-js/react — component styles. Uses only --ns-* custom properties
2
+ from @northstar-js/tokens (load tokens.css first). */
3
+
4
+ /* ---------------------------------------------------------------- root */
5
+
6
+ .ns-root {
7
+ --ns-control-h: var(--ns-density-control-height);
8
+ --ns-row-h: var(--ns-density-row-height);
9
+ --ns-row-pad: var(--ns-density-row-padding);
10
+ color: var(--ns-color-text-1);
11
+ font-family: var(--ns-font-family-ui);
12
+ font-size: var(--ns-font-size-13);
13
+ line-height: var(--ns-font-line-height-13);
14
+ -webkit-font-smoothing: antialiased;
15
+ }
16
+ .ns-root:not(.ns-portal) {
17
+ background: var(--ns-color-ground);
18
+ }
19
+ .ns-root[data-density='compact'] {
20
+ --ns-control-h: var(--ns-density-compact-control-height);
21
+ --ns-row-h: var(--ns-density-compact-row-height);
22
+ --ns-row-pad: var(--ns-density-compact-row-padding);
23
+ }
24
+ .ns-root[data-density='comfortable'] {
25
+ --ns-control-h: var(--ns-density-comfortable-control-height);
26
+ --ns-row-h: var(--ns-density-comfortable-row-height);
27
+ --ns-row-pad: var(--ns-density-comfortable-row-padding);
28
+ }
29
+ .ns-root *,
30
+ .ns-root *::before,
31
+ .ns-root *::after {
32
+ box-sizing: border-box;
33
+ }
34
+ .ns-portal {
35
+ position: relative;
36
+ z-index: var(--ns-z-popover);
37
+ }
38
+
39
+ .ns-visually-hidden {
40
+ position: absolute !important;
41
+ width: 1px;
42
+ height: 1px;
43
+ margin: -1px;
44
+ padding: 0;
45
+ overflow: hidden;
46
+ clip: rect(0 0 0 0);
47
+ white-space: nowrap;
48
+ border: 0;
49
+ }
50
+
51
+ /* Focus: a 2px ring in the focus role, with Day's halo behind it. */
52
+ .ns-button:focus-visible,
53
+ .ns-link:focus-visible,
54
+ .ns-switch:focus-visible,
55
+ .ns-tabs__trigger:focus-visible,
56
+ .ns-tabs__content:focus-visible,
57
+ .ns-menu__item:focus-visible,
58
+ .ns-sidebar__item:focus-visible,
59
+ .ns-table__sort:focus-visible,
60
+ .ns-tag__remove:focus-visible,
61
+ .ns-input__clear:focus-visible,
62
+ .ns-skip-link:focus-visible,
63
+ .ns-dialog:focus-visible,
64
+ .ns-sheet:focus-visible,
65
+ .ns-popover:focus-visible,
66
+ .ns-slider:focus-visible,
67
+ .ns-check__input:focus-visible + .ns-check__box,
68
+ .ns-input:focus-within,
69
+ .ns-select:focus-within,
70
+ .ns-textarea:focus-visible {
71
+ outline: 2px solid var(--ns-color-focus);
72
+ outline-offset: 1px;
73
+ box-shadow: 0 0 0 4px var(--ns-color-focus-halo);
74
+ }
75
+ .ns-input:focus-within .ns-input__control:focus-visible,
76
+ .ns-select__control:focus-visible {
77
+ outline: none;
78
+ }
79
+
80
+ /* -------------------------------------------------------------- sizes */
81
+
82
+ .ns-size-sm { --ns-h: var(--ns-size-control-sm); --ns-px: var(--ns-space-8); }
83
+ .ns-size-md { --ns-h: var(--ns-control-h, var(--ns-size-control-md)); --ns-px: var(--ns-space-12); }
84
+ .ns-size-lg { --ns-h: var(--ns-size-control-lg); --ns-px: var(--ns-space-12); }
85
+ .ns-size-xl { --ns-h: var(--ns-size-control-xl); --ns-px: var(--ns-space-16); font-size: var(--ns-font-size-15); }
86
+
87
+ @media (pointer: coarse) {
88
+ .ns-button,
89
+ .ns-input,
90
+ .ns-select,
91
+ .ns-switch-label,
92
+ .ns-check,
93
+ .ns-menu__item,
94
+ .ns-tabs__trigger,
95
+ .ns-sidebar__item,
96
+ .ns-option {
97
+ min-height: var(--ns-size-target-coarse);
98
+ }
99
+ .ns-icon-button {
100
+ min-width: var(--ns-size-target-coarse);
101
+ }
102
+ }
103
+
104
+ /* ------------------------------------------------------------ buttons */
105
+
106
+ .ns-button {
107
+ display: inline-flex;
108
+ align-items: center;
109
+ justify-content: center;
110
+ gap: var(--ns-space-6);
111
+ height: var(--ns-h, var(--ns-size-control-md));
112
+ padding: 0 var(--ns-px, var(--ns-space-12));
113
+ border: 1px solid var(--ns-color-line-2);
114
+ --ns-button-radius: var(--ns-radius-control-pill);
115
+ border-radius: var(--ns-button-radius);
116
+ background: var(--ns-color-surface-2);
117
+ color: var(--ns-color-text-1);
118
+ font: inherit;
119
+ font-weight: var(--ns-font-weight-medium);
120
+ white-space: nowrap;
121
+ cursor: pointer;
122
+ user-select: none;
123
+ transition: background-color var(--ns-motion-duration-120) var(--ns-motion-easing-settle),
124
+ border-color var(--ns-motion-duration-120) var(--ns-motion-easing-settle);
125
+ }
126
+ .ns-button:hover:not(:disabled) { background: var(--ns-color-surface-3); }
127
+ .ns-button:active:not(:disabled) { border-color: var(--ns-color-text-3); }
128
+ .ns-button:disabled {
129
+ cursor: not-allowed;
130
+ color: var(--ns-color-text-3);
131
+ background: var(--ns-color-surface-1);
132
+ border-color: var(--ns-color-line-1);
133
+ }
134
+ .ns-button--primary {
135
+ background: var(--ns-button-primary-bg);
136
+ border-color: var(--ns-button-primary-bg);
137
+ color: var(--ns-button-primary-fg);
138
+ }
139
+ .ns-button--primary:hover:not(:disabled) {
140
+ background: var(--ns-button-primary-hover);
141
+ border-color: var(--ns-button-primary-hover);
142
+ }
143
+ .ns-button--ghost {
144
+ background: transparent;
145
+ border-color: transparent;
146
+ color: var(--ns-color-text-2);
147
+ }
148
+ .ns-button--ghost:hover:not(:disabled) { color: var(--ns-color-text-1); background: var(--ns-color-surface-2); }
149
+ .ns-button--ghost:disabled { background: transparent; border-color: transparent; }
150
+ .ns-button[aria-current='page'] { color: var(--ns-color-text-1); background: var(--ns-color-surface-3); }
151
+ .ns-button.ns-tone-signal:not(.ns-button--primary) { color: var(--ns-color-signal); }
152
+ .ns-button[data-loading] { cursor: progress; }
153
+ .ns-button[data-loading] .ns-button__label { opacity: 0.7; }
154
+ .ns-icon-button { width: var(--ns-h, var(--ns-size-control-md)); padding: 0; }
155
+ .ns-icon-button svg { width: var(--ns-size-icon-sm); height: var(--ns-size-icon-sm); }
156
+ /* Icon-only: a perfect circle (pill radius on a square), the icon centred on both axes. */
157
+ .ns-icon-button:not(.ns-expand-host) { aspect-ratio: 1; flex: none; }
158
+ .ns-icon-button:not(.ns-expand-host) > .ns-button__label { display: inline-flex; align-items: center; justify-content: center; line-height: 0; }
159
+
160
+ .ns-spinner {
161
+ width: 12px;
162
+ height: 12px;
163
+ border-radius: var(--ns-radius-full);
164
+ border: 1.5px solid currentColor;
165
+ border-right-color: transparent;
166
+ animation: ns-spin 700ms linear infinite;
167
+ }
168
+ @keyframes ns-spin { to { transform: rotate(360deg); } }
169
+
170
+ .ns-button-group { display: inline-flex; gap: var(--ns-space-6); }
171
+ .ns-button-group--attached { gap: 0; }
172
+ .ns-button-group--attached > .ns-button { border-radius: 0; }
173
+ .ns-button-group--attached > .ns-button + .ns-button { margin-left: -1px; }
174
+ .ns-button-group--attached > .ns-button:first-child { border-radius: var(--ns-button-radius) 0 0 var(--ns-button-radius); }
175
+ .ns-button-group--attached > .ns-button:last-child { border-radius: 0 var(--ns-button-radius) var(--ns-button-radius) 0; }
176
+ .ns-button-group--attached > .ns-button:only-child { border-radius: var(--ns-button-radius); }
177
+ .ns-button-group--attached > .ns-button:focus-visible { position: relative; z-index: 1; }
178
+
179
+ .ns-link {
180
+ color: var(--ns-color-signal);
181
+ text-decoration: underline;
182
+ text-decoration-color: var(--ns-color-signal-edge);
183
+ text-underline-offset: 3px;
184
+ border-radius: var(--ns-radius-4);
185
+ }
186
+ .ns-link:hover { text-decoration-color: currentColor; }
187
+ .ns-link--neutral { color: var(--ns-color-text-1); text-decoration-color: var(--ns-color-line-2); }
188
+
189
+ /* -------------------------------------------------------------- forms */
190
+
191
+ .ns-field { display: flex; flex-direction: column; gap: var(--ns-space-6); }
192
+ .ns-field__label { color: var(--ns-color-text-1); font-weight: var(--ns-font-weight-medium); font-size: var(--ns-font-size-12); line-height: var(--ns-font-line-height-12); }
193
+ .ns-field__required { color: var(--ns-color-text-3); }
194
+ .ns-field__description,
195
+ .ns-field__error { margin: 0; font-size: var(--ns-font-size-12); line-height: var(--ns-font-line-height-12); color: var(--ns-color-text-2); }
196
+ .ns-field__error { color: var(--ns-color-text-1); font-weight: var(--ns-font-weight-medium); }
197
+
198
+ .ns-input,
199
+ .ns-select {
200
+ position: relative;
201
+ display: flex;
202
+ align-items: center;
203
+ gap: var(--ns-space-6);
204
+ height: var(--ns-h, var(--ns-size-control-md));
205
+ padding: 0 var(--ns-space-8);
206
+ border: 1px solid var(--ns-color-line-2);
207
+ border-radius: var(--ns-radius-6);
208
+ background: var(--ns-color-surface-1);
209
+ color: var(--ns-color-text-1);
210
+ min-width: 0;
211
+ }
212
+ .ns-input:hover:not(.ns-disabled),
213
+ .ns-select:hover { border-color: var(--ns-color-text-3); }
214
+ .ns-input__control,
215
+ .ns-select__control {
216
+ flex: 1;
217
+ min-width: 0;
218
+ height: 100%;
219
+ border: 0;
220
+ padding: 0;
221
+ background: transparent;
222
+ color: inherit;
223
+ font: inherit;
224
+ outline: none;
225
+ }
226
+ .ns-input__control::placeholder,
227
+ .ns-textarea::placeholder { color: var(--ns-color-text-3); }
228
+ .ns-input__control::-webkit-search-cancel-button { display: none; }
229
+ .ns-input__adornment { display: inline-flex; color: var(--ns-color-text-3); }
230
+ .ns-input__clear,
231
+ .ns-number__steppers button,
232
+ .ns-tag__remove {
233
+ display: inline-flex;
234
+ align-items: center;
235
+ justify-content: center;
236
+ padding: 2px;
237
+ border: 0;
238
+ border-radius: var(--ns-radius-4);
239
+ background: transparent;
240
+ color: var(--ns-color-text-3);
241
+ cursor: pointer;
242
+ }
243
+ .ns-input__clear:hover,
244
+ .ns-number__steppers button:hover:not(:disabled),
245
+ .ns-tag__remove:hover { color: var(--ns-color-text-1); background: var(--ns-color-surface-3); }
246
+ .ns-number__steppers { display: inline-flex; gap: var(--ns-space-2); }
247
+ .ns-number__steppers button:disabled { opacity: 0.4; cursor: not-allowed; }
248
+ .ns-number .ns-input__control { font-family: var(--ns-font-family-mono); font-variant-numeric: var(--ns-font-numeric-figures); }
249
+ .ns-invalid,
250
+ .ns-textarea.ns-invalid { border-color: var(--ns-color-text-1); border-style: dashed; }
251
+ .ns-disabled { opacity: 0.55; cursor: not-allowed; }
252
+
253
+ .ns-select { padding-right: var(--ns-space-24); }
254
+ .ns-select__control { appearance: none; cursor: pointer; }
255
+ .ns-select__control option { background: var(--ns-color-surface-2); color: var(--ns-color-text-1); }
256
+ .ns-select__chevron { position: absolute; right: var(--ns-space-8); display: inline-flex; color: var(--ns-color-text-3); pointer-events: none; }
257
+ .ns-combobox .ns-select__chevron { position: static; }
258
+
259
+ .ns-textarea {
260
+ min-height: 72px;
261
+ padding: var(--ns-space-8);
262
+ border: 1px solid var(--ns-color-line-2);
263
+ border-radius: var(--ns-radius-6);
264
+ background: var(--ns-color-surface-1);
265
+ color: var(--ns-color-text-1);
266
+ font: inherit;
267
+ resize: vertical;
268
+ }
269
+
270
+ .ns-combobox { position: relative; }
271
+ .ns-combobox__list,
272
+ .ns-combobox__empty {
273
+ position: absolute;
274
+ z-index: var(--ns-z-dropdown);
275
+ top: calc(100% + 4px);
276
+ left: 0;
277
+ right: 0;
278
+ max-height: 240px;
279
+ overflow: auto;
280
+ margin: 0;
281
+ padding: var(--ns-space-4);
282
+ list-style: none;
283
+ }
284
+ .ns-combobox__empty { padding: var(--ns-space-8); color: var(--ns-color-text-3); }
285
+ .ns-option {
286
+ display: flex;
287
+ align-items: center;
288
+ justify-content: space-between;
289
+ gap: var(--ns-space-8);
290
+ height: var(--ns-size-control-sm);
291
+ padding: 0 var(--ns-space-8);
292
+ border-radius: var(--ns-radius-4);
293
+ color: var(--ns-color-text-1);
294
+ cursor: pointer;
295
+ }
296
+ .ns-option[data-active] { background: var(--ns-color-surface-3); }
297
+ .ns-option[aria-disabled='true'] { color: var(--ns-color-text-3); cursor: not-allowed; }
298
+ .ns-option svg { color: var(--ns-color-signal); }
299
+
300
+ .ns-check { display: inline-flex; align-items: center; gap: var(--ns-space-8); cursor: pointer; position: relative; }
301
+ .ns-check__input { position: absolute; opacity: 0; width: 16px; height: 16px; margin: 0; cursor: inherit; }
302
+ .ns-check__box {
303
+ display: inline-flex;
304
+ align-items: center;
305
+ justify-content: center;
306
+ flex: none;
307
+ width: 16px;
308
+ height: 16px;
309
+ border: 1px solid var(--ns-color-line-2);
310
+ border-radius: var(--ns-radius-4);
311
+ background: var(--ns-color-surface-1);
312
+ color: var(--ns-button-primary-fg);
313
+ }
314
+ .ns-check__box svg { width: 12px; height: 12px; stroke-width: 2; visibility: hidden; }
315
+ .ns-check:hover .ns-check__box { border-color: var(--ns-color-text-3); }
316
+ .ns-check__input:checked + .ns-check__box,
317
+ .ns-check__input:indeterminate + .ns-check__box { background: var(--ns-color-signal-fill); border-color: var(--ns-color-signal-fill); }
318
+ .ns-check__input:checked + .ns-check__box svg,
319
+ .ns-check__input:indeterminate + .ns-check__box svg { visibility: visible; }
320
+ .ns-radio .ns-check__box { border-radius: var(--ns-radius-full); }
321
+ .ns-radio .ns-check__input:checked + .ns-check__box { background: var(--ns-color-surface-1); border-color: var(--ns-color-signal); border-width: 5px; }
322
+ .ns-check__label { color: var(--ns-color-text-1); }
323
+ .ns-radio-group { display: flex; gap: var(--ns-space-8); }
324
+ .ns-radio-group--vertical { flex-direction: column; }
325
+ .ns-radio-group--horizontal { flex-direction: row; gap: var(--ns-space-16); }
326
+
327
+ .ns-switch-label { display: inline-flex; align-items: center; gap: var(--ns-space-8); cursor: pointer; }
328
+ .ns-switch {
329
+ position: relative;
330
+ flex: none;
331
+ width: 28px;
332
+ height: 16px;
333
+ padding: 0;
334
+ border: 1px solid var(--ns-color-line-2);
335
+ border-radius: var(--ns-radius-full);
336
+ background: var(--ns-color-surface-3);
337
+ cursor: pointer;
338
+ transition: background-color var(--ns-motion-duration-120) var(--ns-motion-easing-settle);
339
+ }
340
+ .ns-switch__thumb {
341
+ position: absolute;
342
+ top: 1px;
343
+ left: 1px;
344
+ width: 12px;
345
+ height: 12px;
346
+ border-radius: var(--ns-radius-full);
347
+ background: var(--ns-color-text-2);
348
+ transition: transform var(--ns-motion-duration-120) var(--ns-motion-easing-settle);
349
+ }
350
+ .ns-switch[aria-checked='true'] { background: var(--ns-color-signal-fill); border-color: var(--ns-color-signal-fill); }
351
+ .ns-switch[aria-checked='true'] .ns-switch__thumb { transform: translateX(12px); background: var(--ns-button-primary-fg); }
352
+ .ns-switch:disabled { opacity: 0.55; cursor: not-allowed; }
353
+
354
+ .ns-slider {
355
+ appearance: none;
356
+ width: 100%;
357
+ height: 16px;
358
+ margin: 0;
359
+ background: transparent;
360
+ cursor: pointer;
361
+ border-radius: var(--ns-radius-full);
362
+ }
363
+ .ns-slider::-webkit-slider-runnable-track {
364
+ height: 4px;
365
+ border-radius: 2px;
366
+ background: linear-gradient(to right, var(--ns-color-signal) var(--ns-slider-fill, 0%), var(--ns-color-surface-3) var(--ns-slider-fill, 0%));
367
+ }
368
+ .ns-slider::-moz-range-track { height: 4px; border-radius: 2px; background: var(--ns-color-surface-3); }
369
+ .ns-slider::-moz-range-progress { height: 4px; border-radius: 2px; background: var(--ns-color-signal); }
370
+ .ns-slider::-webkit-slider-thumb {
371
+ appearance: none;
372
+ width: 14px;
373
+ height: 14px;
374
+ margin-top: -5px;
375
+ border-radius: var(--ns-radius-full);
376
+ background: var(--ns-color-text-1);
377
+ border: 2px solid var(--ns-color-ground);
378
+ }
379
+ .ns-slider::-moz-range-thumb { width: 12px; height: 12px; border-radius: var(--ns-radius-full); background: var(--ns-color-text-1); border: 2px solid var(--ns-color-ground); }
380
+ .ns-slider:disabled { opacity: 0.55; cursor: not-allowed; }
381
+
382
+ /* ----------------------------------------------------------- overlays */
383
+
384
+ .ns-pop {
385
+ border: 1px solid var(--ns-color-line-2);
386
+ border-radius: var(--ns-radius-8);
387
+ background: var(--ns-color-surface-2);
388
+ color: var(--ns-color-text-1);
389
+ box-shadow: var(--ns-elevation-2);
390
+ }
391
+ .ns-overlay {
392
+ position: fixed;
393
+ inset: 0;
394
+ background: var(--ns-color-ground);
395
+ opacity: 0.72;
396
+ animation: ns-fade var(--ns-motion-duration-200) var(--ns-motion-easing-enter);
397
+ }
398
+ .ns-overlay--dialog { z-index: var(--ns-z-dialog); }
399
+ .ns-overlay--sheet { z-index: var(--ns-z-sheet); }
400
+ @keyframes ns-fade { from { opacity: 0; } }
401
+ @keyframes ns-rise { from { opacity: 0; transform: translate(-50%, calc(-50% + 8px)); } }
402
+ @keyframes ns-slide-right { from { transform: translateX(16px); opacity: 0; } }
403
+ @keyframes ns-slide-left { from { transform: translateX(-16px); opacity: 0; } }
404
+ @keyframes ns-slide-up { from { transform: translateY(16px); opacity: 0; } }
405
+
406
+ .ns-dialog {
407
+ position: fixed;
408
+ z-index: var(--ns-z-dialog);
409
+ top: 50%;
410
+ left: 50%;
411
+ transform: translate(-50%, -50%);
412
+ display: flex;
413
+ flex-direction: column;
414
+ width: min(calc(100vw - 32px), 480px);
415
+ max-height: calc(100vh - 64px);
416
+ overflow: auto;
417
+ border: 1px solid var(--ns-color-line-2);
418
+ border-radius: var(--ns-radius-12);
419
+ background: var(--ns-color-surface-1);
420
+ box-shadow: var(--ns-elevation-3);
421
+ animation: ns-rise var(--ns-motion-duration-200) var(--ns-motion-easing-enter);
422
+ }
423
+ .ns-dialog--sm { width: min(calc(100vw - 32px), 360px); }
424
+ .ns-dialog--lg { width: min(calc(100vw - 32px), 720px); }
425
+ .ns-sheet {
426
+ position: fixed;
427
+ z-index: var(--ns-z-sheet);
428
+ display: flex;
429
+ flex-direction: column;
430
+ background: var(--ns-color-surface-1);
431
+ border: 0 solid var(--ns-color-line-2);
432
+ box-shadow: var(--ns-elevation-3);
433
+ overflow: auto;
434
+ }
435
+ .ns-sheet--right { top: 0; right: 0; bottom: 0; width: min(100vw, 420px); border-left-width: 1px; animation: ns-slide-right var(--ns-motion-duration-200) var(--ns-motion-easing-enter); }
436
+ .ns-sheet--left { top: 0; left: 0; bottom: 0; width: min(100vw, 420px); border-right-width: 1px; animation: ns-slide-left var(--ns-motion-duration-200) var(--ns-motion-easing-enter); }
437
+ .ns-sheet--bottom { left: 0; right: 0; bottom: 0; max-height: 80vh; border-top-width: 1px; border-radius: var(--ns-radius-12) var(--ns-radius-12) 0 0; animation: ns-slide-up var(--ns-motion-duration-200) var(--ns-motion-easing-enter); }
438
+ .ns-layer__header { display: flex; align-items: flex-start; gap: var(--ns-space-8); padding: var(--ns-space-16) var(--ns-space-16) var(--ns-space-8); }
439
+ .ns-layer__header > :first-child { flex: 1; }
440
+ .ns-layer__title { margin: 0; font-size: var(--ns-font-size-15); line-height: var(--ns-font-line-height-15); font-weight: var(--ns-font-weight-semibold); }
441
+ .ns-layer__description { margin: var(--ns-space-4) 0 0; color: var(--ns-color-text-2); }
442
+ .ns-layer__body { padding: var(--ns-space-8) var(--ns-space-16); flex: 1; }
443
+ .ns-layer__footer { display: flex; justify-content: flex-end; gap: var(--ns-space-8); padding: var(--ns-space-12) var(--ns-space-16); border-top: 1px solid var(--ns-color-line-1); }
444
+ .ns-layer__close { margin: -4px -4px 0 0; }
445
+ .ns-popover > .ns-layer__title { font-size: var(--ns-font-size-13); }
446
+
447
+ .ns-popover {
448
+ position: fixed;
449
+ z-index: var(--ns-z-popover);
450
+ min-width: 200px;
451
+ max-width: min(calc(100vw - 16px), 360px);
452
+ padding: var(--ns-space-12);
453
+ animation: ns-fade var(--ns-motion-duration-120) var(--ns-motion-easing-enter);
454
+ }
455
+ .ns-popover:focus { outline: none; }
456
+ .ns-menu {
457
+ position: fixed;
458
+ z-index: var(--ns-z-dropdown);
459
+ min-width: 180px;
460
+ padding: var(--ns-space-4);
461
+ animation: ns-fade var(--ns-motion-duration-120) var(--ns-motion-easing-enter);
462
+ }
463
+ .ns-menu:focus { outline: none; }
464
+ .ns-menu__item {
465
+ display: flex;
466
+ align-items: center;
467
+ gap: var(--ns-space-8);
468
+ height: var(--ns-size-control-sm);
469
+ padding: 0 var(--ns-space-8);
470
+ border-radius: var(--ns-radius-4);
471
+ color: var(--ns-color-text-1);
472
+ cursor: pointer;
473
+ outline: none;
474
+ }
475
+ .ns-menu__item:focus,
476
+ .ns-menu__item:hover { background: var(--ns-color-surface-3); }
477
+ .ns-menu__item:focus-visible { outline-offset: -2px; box-shadow: none; }
478
+ .ns-menu__item[aria-disabled='true'] { color: var(--ns-color-text-3); cursor: not-allowed; background: transparent; }
479
+ .ns-menu__icon { display: inline-flex; color: var(--ns-color-text-2); }
480
+ .ns-menu__text { flex: 1; }
481
+ .ns-menu__shortcut { color: var(--ns-color-text-3); font-size: var(--ns-font-size-11); }
482
+ .ns-menu__separator { height: 1px; margin: var(--ns-space-4) calc(-1 * var(--ns-space-4)); background: var(--ns-color-line-1); }
483
+ .ns-menu__label { padding: var(--ns-space-4) var(--ns-space-8); color: var(--ns-color-text-3); font-size: var(--ns-font-size-11); font-weight: var(--ns-font-weight-medium); }
484
+
485
+ .ns-tooltip {
486
+ position: fixed;
487
+ z-index: var(--ns-z-tooltip);
488
+ max-width: 260px;
489
+ padding: var(--ns-space-4) var(--ns-space-8);
490
+ border: 1px solid var(--ns-color-line-2);
491
+ border-radius: var(--ns-radius-6);
492
+ background: var(--ns-color-surface-3);
493
+ color: var(--ns-color-text-1);
494
+ font-size: var(--ns-font-size-12);
495
+ line-height: var(--ns-font-line-height-12);
496
+ box-shadow: var(--ns-elevation-1);
497
+ pointer-events: none;
498
+ animation: ns-fade var(--ns-motion-duration-120) var(--ns-motion-easing-enter);
499
+ }
500
+
501
+ /* ------------------------------------------------------------- toasts */
502
+
503
+ .ns-toaster { position: fixed; z-index: var(--ns-z-toast); pointer-events: none; }
504
+ .ns-toaster--bottom-right { right: var(--ns-space-16); bottom: var(--ns-space-16); }
505
+ .ns-toaster--bottom-left { left: var(--ns-space-16); bottom: var(--ns-space-16); }
506
+ .ns-toaster--top-right { right: var(--ns-space-16); top: var(--ns-space-16); }
507
+ .ns-toaster--top-left { left: var(--ns-space-16); top: var(--ns-space-16); }
508
+ .ns-toaster--bottom-center { left: 50%; bottom: var(--ns-space-16); transform: translateX(-50%); }
509
+ .ns-toaster__list { display: flex; flex-direction: column; gap: var(--ns-space-8); margin: 0; padding: 0; list-style: none; }
510
+ .ns-toaster__item { pointer-events: auto; animation: ns-slide-up var(--ns-motion-duration-200) var(--ns-motion-easing-enter); }
511
+ .ns-toast {
512
+ display: flex;
513
+ align-items: center;
514
+ gap: var(--ns-space-12);
515
+ width: min(calc(100vw - 32px), 360px);
516
+ padding: var(--ns-space-12);
517
+ border: 1px solid var(--ns-color-line-2);
518
+ border-radius: var(--ns-radius-8);
519
+ background: var(--ns-color-surface-2);
520
+ box-shadow: var(--ns-elevation-2);
521
+ }
522
+ .ns-toast.ns-tone-signal { border-left: 2px solid var(--ns-color-signal); }
523
+ .ns-toast__text { flex: 1; min-width: 0; }
524
+ .ns-toast__title { font-weight: var(--ns-font-weight-medium); }
525
+ .ns-toast__description { color: var(--ns-color-text-2); }
526
+
527
+ .ns-banner {
528
+ position: relative;
529
+ z-index: var(--ns-z-banner);
530
+ display: flex;
531
+ align-items: flex-start;
532
+ gap: var(--ns-space-12);
533
+ padding: var(--ns-space-8) var(--ns-space-12);
534
+ border: 1px solid var(--ns-color-line-2);
535
+ border-radius: var(--ns-radius-8);
536
+ background: var(--ns-color-surface-1);
537
+ }
538
+ .ns-banner.ns-tone-signal { background: var(--ns-color-signal-wash); border-color: var(--ns-color-signal-edge); }
539
+ .ns-banner__icon { display: inline-flex; padding-top: 2px; color: var(--ns-color-text-2); }
540
+ .ns-tone-signal > .ns-banner__icon { color: var(--ns-color-signal); }
541
+ .ns-banner__text { flex: 1; display: flex; flex-wrap: wrap; gap: 0 var(--ns-space-8); padding: 4px 0; }
542
+ .ns-banner__title { font-weight: var(--ns-font-weight-semibold); }
543
+ .ns-banner__body { color: var(--ns-color-text-2); }
544
+ .ns-banner__actions { display: flex; gap: var(--ns-space-8); }
545
+
546
+ /* --------------------------------------------------- layout and nav */
547
+
548
+ .ns-stack { display: flex; }
549
+ .ns-stack:is(ul, ol) { margin: 0; padding: 0; list-style: none; }
550
+ .ns-grid { display: grid; }
551
+
552
+ .ns-app-shell {
553
+ display: grid;
554
+ grid-template-columns: auto minmax(0, 1fr);
555
+ min-height: 100vh;
556
+ background: var(--ns-color-ground);
557
+ }
558
+ .ns-app-shell--no-sidebar { grid-template-columns: minmax(0, 1fr); }
559
+ .ns-app-shell__sidebar { position: sticky; top: 0; height: 100vh; }
560
+ .ns-app-shell__column { display: flex; flex-direction: column; min-width: 0; }
561
+ .ns-app-shell__main { flex: 1; padding: var(--ns-space-24); outline: none; }
562
+ .ns-skip-link {
563
+ position: absolute;
564
+ z-index: var(--ns-z-tooltip);
565
+ left: var(--ns-space-8);
566
+ top: var(--ns-space-8);
567
+ padding: var(--ns-space-6) var(--ns-space-12);
568
+ border-radius: var(--ns-radius-6);
569
+ background: var(--ns-color-surface-3);
570
+ color: var(--ns-color-text-1);
571
+ transform: translateY(-200%);
572
+ }
573
+ .ns-skip-link:focus { transform: none; }
574
+
575
+ .ns-sidebar {
576
+ display: flex;
577
+ flex-direction: column;
578
+ width: 240px;
579
+ height: 100%;
580
+ border-right: 1px solid var(--ns-color-line-1);
581
+ background: var(--ns-color-surface-1);
582
+ }
583
+ .ns-sidebar__header { padding: var(--ns-space-12); }
584
+ .ns-sidebar__body { flex: 1; overflow: auto; padding: var(--ns-space-4) var(--ns-space-8); }
585
+ .ns-sidebar__footer { padding: var(--ns-space-8); border-top: 1px solid var(--ns-color-line-1); }
586
+ .ns-sidebar__section + .ns-sidebar__section { margin-top: var(--ns-space-16); }
587
+ .ns-sidebar__section ul { margin: 0; padding: 0; list-style: none; }
588
+ .ns-sidebar__title { padding: var(--ns-space-4) var(--ns-space-8); color: var(--ns-color-text-3); font-size: var(--ns-font-size-11); font-weight: var(--ns-font-weight-medium); }
589
+ .ns-sidebar__item {
590
+ display: flex;
591
+ align-items: center;
592
+ gap: var(--ns-space-8);
593
+ height: var(--ns-size-control-sm);
594
+ padding: 0 var(--ns-space-8);
595
+ border-radius: var(--ns-radius-6);
596
+ color: var(--ns-color-text-2);
597
+ text-decoration: none;
598
+ font-weight: var(--ns-font-weight-medium);
599
+ cursor: pointer;
600
+ }
601
+ .ns-sidebar__item:hover { background: var(--ns-color-surface-2); color: var(--ns-color-text-1); }
602
+ .ns-sidebar__item[aria-current='page'] { background: var(--ns-color-surface-3); color: var(--ns-color-text-1); }
603
+ .ns-sidebar__icon { display: inline-flex; color: var(--ns-color-text-3); }
604
+ .ns-sidebar__text { flex: 1; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
605
+ .ns-sidebar__meta { color: var(--ns-color-text-3); font-family: var(--ns-font-family-mono); font-size: var(--ns-font-size-11); }
606
+
607
+ .ns-top-bar {
608
+ position: sticky;
609
+ top: 0;
610
+ z-index: var(--ns-z-banner);
611
+ display: flex;
612
+ align-items: center;
613
+ gap: var(--ns-space-12);
614
+ height: 48px;
615
+ padding: 0 var(--ns-space-16);
616
+ border-bottom: 1px solid var(--ns-color-line-1);
617
+ background: var(--ns-color-ground);
618
+ }
619
+ .ns-top-bar__center { flex: 1; min-width: 0; display: flex; align-items: center; gap: var(--ns-space-8); }
620
+ .ns-top-bar__start,
621
+ .ns-top-bar__end { display: flex; align-items: center; gap: var(--ns-space-8); }
622
+
623
+ .ns-tabs--vertical { display: flex; gap: var(--ns-space-16); }
624
+ .ns-tabs__list { display: flex; gap: var(--ns-space-4); border-bottom: 1px solid var(--ns-color-line-1); }
625
+ .ns-tabs--vertical .ns-tabs__list { flex-direction: column; border-bottom: 0; border-right: 1px solid var(--ns-color-line-1); padding-right: var(--ns-space-8); }
626
+ .ns-tabs__trigger {
627
+ position: relative;
628
+ height: var(--ns-control-h, var(--ns-size-control-md));
629
+ padding: 0 var(--ns-space-8);
630
+ border: 0;
631
+ background: transparent;
632
+ color: var(--ns-color-text-2);
633
+ font: inherit;
634
+ font-weight: var(--ns-font-weight-medium);
635
+ cursor: pointer;
636
+ border-radius: var(--ns-radius-4) var(--ns-radius-4) 0 0;
637
+ }
638
+ .ns-tabs__trigger:hover { color: var(--ns-color-text-1); }
639
+ .ns-tabs__trigger[aria-selected='true'] { color: var(--ns-color-text-1); }
640
+ .ns-tabs__trigger[aria-selected='true']::after {
641
+ content: '';
642
+ position: absolute;
643
+ left: var(--ns-space-8);
644
+ right: var(--ns-space-8);
645
+ bottom: -1px;
646
+ height: 2px;
647
+ background: var(--ns-color-signal);
648
+ }
649
+ .ns-tabs--vertical .ns-tabs__trigger { text-align: left; border-radius: var(--ns-radius-4); }
650
+ .ns-tabs--vertical .ns-tabs__trigger[aria-selected='true'] { background: var(--ns-color-surface-2); }
651
+ .ns-tabs--vertical .ns-tabs__trigger[aria-selected='true']::after { display: none; }
652
+ .ns-tabs__trigger:disabled { color: var(--ns-color-text-3); cursor: not-allowed; }
653
+ .ns-tabs__content { padding: var(--ns-space-16) 0; border-radius: var(--ns-radius-4); }
654
+
655
+ .ns-breadcrumbs ol { display: flex; flex-wrap: wrap; align-items: center; gap: var(--ns-space-6); margin: 0; padding: 0; list-style: none; }
656
+ .ns-breadcrumbs li { display: inline-flex; align-items: center; gap: var(--ns-space-6); color: var(--ns-color-text-2); }
657
+ .ns-breadcrumbs a { color: var(--ns-color-text-2); text-decoration: none; border-radius: var(--ns-radius-4); }
658
+ .ns-breadcrumbs a:hover { color: var(--ns-color-text-1); }
659
+ .ns-breadcrumbs a:focus-visible { outline: 2px solid var(--ns-color-focus); outline-offset: 1px; }
660
+ .ns-breadcrumbs [aria-current='page'] { color: var(--ns-color-text-1); }
661
+ .ns-breadcrumbs__sep { color: var(--ns-color-text-3); }
662
+
663
+ .ns-pagination { display: flex; align-items: center; gap: var(--ns-space-4); }
664
+ .ns-pagination ul { display: flex; align-items: center; gap: var(--ns-space-2); margin: 0; padding: 0; list-style: none; }
665
+ .ns-pagination__page { min-width: var(--ns-h, var(--ns-size-control-sm)); padding: 0 var(--ns-space-6); font-family: var(--ns-font-family-mono); font-variant-numeric: var(--ns-font-numeric-figures); }
666
+ .ns-pagination__gap { color: var(--ns-color-text-3); padding: 0 var(--ns-space-4); }
667
+
668
+ /* -------------------------------------------------------- data display */
669
+
670
+ .ns-table-wrap { overflow: auto; border: 1px solid var(--ns-color-line-1); border-radius: var(--ns-radius-8); background: var(--ns-color-surface-1); }
671
+ .ns-table { width: 100%; border-collapse: collapse; font-size: var(--ns-font-size-13); }
672
+ .ns-table__caption { padding: var(--ns-space-8) var(--ns-space-12); text-align: left; color: var(--ns-color-text-2); caption-side: top; }
673
+ .ns-table__th,
674
+ .ns-table__td { height: var(--ns-row-h, var(--ns-size-row-md)); padding: var(--ns-row-pad, var(--ns-space-6)) var(--ns-space-12); text-align: left; border-bottom: 1px solid var(--ns-color-line-1); }
675
+ .ns-table[data-density='compact'] { --ns-row-h: var(--ns-density-compact-row-height); --ns-row-pad: var(--ns-density-compact-row-padding); }
676
+ .ns-table[data-density='comfortable'] { --ns-row-h: var(--ns-density-comfortable-row-height); --ns-row-pad: var(--ns-density-comfortable-row-padding); }
677
+ .ns-table__th { color: var(--ns-color-text-2); font-size: var(--ns-font-size-12); font-weight: var(--ns-font-weight-medium); background: var(--ns-color-surface-1); white-space: nowrap; }
678
+ .ns-table--sticky .ns-table__th { position: sticky; top: 0; z-index: 1; }
679
+ .ns-table tbody .ns-table__row:last-child .ns-table__td { border-bottom: 0; }
680
+ .ns-table tbody .ns-table__row:hover { background: var(--ns-color-surface-2); }
681
+ .ns-table__row[aria-selected='true'] { background: var(--ns-color-signal-wash); }
682
+ .ns-numeric { text-align: right; font-family: var(--ns-font-family-mono); font-variant-numeric: var(--ns-font-numeric-figures); }
683
+ .ns-table__th.ns-numeric { font-family: inherit; }
684
+ .ns-table__sort { display: inline-flex; align-items: center; gap: var(--ns-space-4); padding: 0; border: 0; background: transparent; color: inherit; font: inherit; cursor: pointer; border-radius: var(--ns-radius-4); }
685
+ .ns-table__sort:hover { color: var(--ns-color-text-1); }
686
+ .ns-table__sort-mark { color: var(--ns-color-text-3); }
687
+ [aria-sort='ascending'] .ns-table__sort-mark,
688
+ [aria-sort='descending'] .ns-table__sort-mark { color: var(--ns-color-signal); }
689
+
690
+ .ns-list { margin: 0; padding: 0; list-style: none; }
691
+ .ns-list--divided > .ns-list__item + .ns-list__item { border-top: 1px solid var(--ns-color-line-1); }
692
+ .ns-list__item { display: flex; align-items: center; gap: var(--ns-space-12); min-height: var(--ns-row-h, var(--ns-size-row-md)); padding: var(--ns-row-pad, var(--ns-space-6)) var(--ns-space-4); }
693
+ .ns-list__text { flex: 1; min-width: 0; display: flex; flex-direction: column; }
694
+ .ns-list__title { color: var(--ns-color-text-1); font-weight: var(--ns-font-weight-medium); }
695
+ .ns-list__description { color: var(--ns-color-text-2); font-size: var(--ns-font-size-12); }
696
+ .ns-list__start,
697
+ .ns-list__end { display: inline-flex; align-items: center; gap: var(--ns-space-8); color: var(--ns-color-text-2); }
698
+
699
+ .ns-tag {
700
+ display: inline-flex;
701
+ align-items: center;
702
+ gap: var(--ns-space-4);
703
+ height: 20px;
704
+ padding: 0 var(--ns-space-6);
705
+ border: 1px solid var(--ns-color-line-2);
706
+ border-radius: var(--ns-radius-4);
707
+ color: var(--ns-color-text-2);
708
+ font-size: var(--ns-font-size-11);
709
+ font-weight: var(--ns-font-weight-medium);
710
+ white-space: nowrap;
711
+ }
712
+ .ns-tag.ns-tone-signal { color: var(--ns-color-signal); border-color: var(--ns-color-signal-edge); background: var(--ns-color-signal-wash); }
713
+ .ns-tag__remove { padding: 0; margin-right: -2px; }
714
+ .ns-tag__remove svg { width: 12px; height: 12px; }
715
+
716
+ .ns-badge {
717
+ display: inline-flex;
718
+ align-items: center;
719
+ height: 18px;
720
+ min-width: 18px;
721
+ padding: 0 var(--ns-space-6);
722
+ border-radius: var(--ns-radius-full);
723
+ font-family: var(--ns-font-family-mono);
724
+ font-size: var(--ns-font-size-11);
725
+ font-variant-numeric: var(--ns-font-numeric-figures);
726
+ justify-content: center;
727
+ }
728
+ .ns-badge--outline { border: 1px solid var(--ns-color-line-2); color: var(--ns-color-text-2); }
729
+ .ns-badge--solid { background: var(--ns-color-surface-3); color: var(--ns-color-text-1); }
730
+ .ns-badge--outline.ns-tone-signal { border-color: var(--ns-color-signal-edge); color: var(--ns-color-signal); }
731
+ .ns-badge--solid.ns-tone-signal { background: var(--ns-color-signal-fill); color: var(--ns-button-primary-fg); }
732
+
733
+ .ns-avatar {
734
+ display: inline-flex;
735
+ align-items: center;
736
+ justify-content: center;
737
+ flex: none;
738
+ border-radius: var(--ns-radius-full);
739
+ background: var(--ns-color-surface-3);
740
+ border: 1px solid var(--ns-color-line-2);
741
+ color: var(--ns-color-text-1);
742
+ font-weight: var(--ns-font-weight-semibold);
743
+ letter-spacing: 0.02em;
744
+ user-select: none;
745
+ }
746
+ .ns-avatar--sm { width: 20px; height: 20px; font-size: 9px; }
747
+ .ns-avatar--md { width: 24px; height: 24px; font-size: var(--ns-font-size-11); }
748
+ .ns-avatar--lg { width: 32px; height: 32px; font-size: var(--ns-font-size-12); }
749
+
750
+ .ns-kbd {
751
+ display: inline-flex;
752
+ align-items: center;
753
+ justify-content: center;
754
+ min-width: 16px;
755
+ height: 16px;
756
+ padding: 0 3px;
757
+ border: 1px solid var(--ns-color-line-2);
758
+ border-radius: 3px;
759
+ background: var(--ns-color-surface-3);
760
+ color: var(--ns-color-text-2);
761
+ font-family: var(--ns-font-family-mono);
762
+ font-size: 10px;
763
+ line-height: 1;
764
+ }
765
+
766
+ .ns-empty { display: flex; flex-direction: column; align-items: center; gap: var(--ns-space-8); padding: var(--ns-space-40) var(--ns-space-24); text-align: center; }
767
+ .ns-empty__icon { color: var(--ns-color-text-3); }
768
+ .ns-empty__title { margin: 0; font-size: var(--ns-font-size-15); line-height: var(--ns-font-line-height-15); font-weight: var(--ns-font-weight-medium); }
769
+ .ns-empty__description { margin: 0; max-width: 40ch; color: var(--ns-color-text-2); }
770
+ .ns-empty__action { margin-top: var(--ns-space-8); }
771
+
772
+ .ns-skeleton {
773
+ display: block;
774
+ background: var(--ns-color-surface-3);
775
+ animation: ns-pulse 1600ms var(--ns-motion-easing-travel) infinite;
776
+ }
777
+ .ns-skeleton--line { height: 12px; border-radius: var(--ns-radius-4); }
778
+ .ns-skeleton--block { height: 64px; border-radius: var(--ns-radius-8); }
779
+ .ns-skeleton--circle { width: 24px; height: 24px; border-radius: var(--ns-radius-full); }
780
+ @keyframes ns-pulse { 50% { opacity: 0.5; } }
781
+
782
+ .ns-stale {
783
+ position: relative;
784
+ padding: var(--ns-space-24) var(--ns-space-12) var(--ns-space-12);
785
+ border: 1px dashed var(--ns-color-text-3);
786
+ border-radius: var(--ns-radius-8);
787
+ }
788
+ .ns-stale__label {
789
+ position: absolute;
790
+ top: var(--ns-space-6);
791
+ left: var(--ns-space-12);
792
+ color: var(--ns-color-text-2);
793
+ font-size: var(--ns-font-size-11);
794
+ font-weight: var(--ns-font-weight-medium);
795
+ line-height: var(--ns-font-line-height-11);
796
+ }
797
+ .ns-stale__detail { color: var(--ns-color-text-3); font-weight: var(--ns-font-weight-regular); }
798
+
799
+ /* ================================================ interaction layer
800
+ Material (glass), pointer light, springs. Pointer effects have a keyboard
801
+ twin (:focus-visible / :has(:focus-visible)); every movement stops under
802
+ reduced motion, glass turns solid under reduced transparency, without
803
+ backdrop-filter, and in forced colours. */
804
+
805
+ @property --ns-orbit { syntax: '<angle>'; inherits: false; initial-value: 0deg; }
806
+
807
+ /* ---------------------------------------------------- surface, card, panel */
808
+
809
+ .ns-surface,
810
+ .ns-card,
811
+ .ns-panel {
812
+ position: relative;
813
+ isolation: isolate;
814
+ border: 1px solid var(--ns-color-line-1);
815
+ color: var(--ns-color-text-1);
816
+ }
817
+ .ns-surface.ns-material--solid { background: var(--ns-color-surface-1); }
818
+ .ns-radius-6 { border-radius: var(--ns-radius-6); }
819
+ .ns-radius-8 { border-radius: var(--ns-radius-8); }
820
+ .ns-radius-10 { border-radius: var(--ns-radius-glass-panel); }
821
+ .ns-radius-12 { border-radius: var(--ns-radius-12); }
822
+ .ns-surface.ns-material--solid.ns-depth-1 { box-shadow: var(--ns-elevation-1); }
823
+ .ns-surface.ns-material--solid.ns-depth-2 { box-shadow: var(--ns-elevation-2); }
824
+ .ns-surface.ns-material--solid.ns-depth-3 { box-shadow: var(--ns-elevation-3); background: var(--ns-color-surface-2); }
825
+
826
+ .ns-card {
827
+ display: flex;
828
+ flex-direction: column;
829
+ min-width: 0;
830
+ border-radius: var(--ns-radius-12);
831
+ background: var(--ns-color-surface-1);
832
+ box-shadow: var(--ns-elevation-1);
833
+ transition: transform var(--ns-motion-duration-release) var(--ns-motion-spring-release),
834
+ box-shadow var(--ns-motion-duration-200) var(--ns-motion-easing-settle),
835
+ border-color var(--ns-motion-duration-200) var(--ns-motion-easing-settle);
836
+ }
837
+ .ns-card__header { display: flex; align-items: flex-start; gap: var(--ns-space-12); padding: var(--ns-space-16) var(--ns-space-16) 0; }
838
+ .ns-card__heading { flex: 1; min-width: 0; }
839
+ .ns-card__title { margin: 0; font-size: var(--ns-font-size-15); line-height: var(--ns-font-line-height-15); font-weight: var(--ns-font-weight-semibold); }
840
+ .ns-card__description { margin: var(--ns-space-4) 0 0; color: var(--ns-color-text-2); }
841
+ .ns-card__actions { display: flex; gap: var(--ns-space-6); }
842
+ .ns-card__body { flex: 1; padding: var(--ns-space-16); }
843
+ .ns-card__header + .ns-card__body { padding-top: var(--ns-space-12); }
844
+ .ns-card__footer { display: flex; justify-content: flex-end; gap: var(--ns-space-8); padding: var(--ns-space-12) var(--ns-space-16); border-top: 1px solid var(--ns-color-line-1); }
845
+ .ns-card--interactive { cursor: pointer; }
846
+ .ns-card--interactive:hover,
847
+ .ns-card--interactive:has(:focus-visible) {
848
+ transform: translateY(var(--ns-material-lift));
849
+ border-color: var(--ns-color-line-2);
850
+ box-shadow: var(--ns-elevation-2), 0 12px 32px -18px var(--ns-material-glow);
851
+ }
852
+ .ns-card--interactive:active {
853
+ transform: translateY(0) scale(0.995);
854
+ transition-duration: var(--ns-motion-duration-press);
855
+ transition-timing-function: var(--ns-motion-spring-press);
856
+ }
857
+
858
+ .ns-panel { border-radius: var(--ns-radius-8); background: var(--ns-color-surface-1); overflow: hidden; }
859
+ .ns-panel__head { display: flex; align-items: center; gap: var(--ns-space-8); min-height: 40px; padding: 0 var(--ns-space-12); border-bottom: 1px solid var(--ns-color-line-1); }
860
+ .ns-panel__title { margin: 0; font-size: var(--ns-font-size-13); line-height: var(--ns-font-line-height-13); font-weight: var(--ns-font-weight-medium); }
861
+ .ns-panel__actions { margin-left: auto; display: flex; gap: var(--ns-space-6); }
862
+ .ns-panel__body { padding: var(--ns-space-12); }
863
+ .ns-panel__body--flush { padding: 0; }
864
+
865
+ /* -------------------------------------------------------------- glass */
866
+
867
+ .ns-material--glass,
868
+ .ns-button--glass.ns-button--secondary,
869
+ .ns-button--glass.ns-button--ghost:hover:not(:disabled),
870
+ .ns-tabs--glass .ns-tabs__list {
871
+ background: var(--ns-material-glass-specular),
872
+ linear-gradient(var(--ns-material-glass-tint), var(--ns-material-glass-tint)),
873
+ var(--ns-material-glass-fill);
874
+ border-color: var(--ns-material-glass-edge);
875
+ -webkit-backdrop-filter: blur(var(--ns-material-blur-md)) saturate(var(--ns-material-saturate));
876
+ backdrop-filter: blur(var(--ns-material-blur-md)) saturate(var(--ns-material-saturate));
877
+ box-shadow: inset 0 1px 0 var(--ns-material-glass-rim), var(--ns-material-shadow);
878
+ }
879
+ .ns-button--glass.ns-button--secondary,
880
+ .ns-button--glass.ns-button--ghost:hover:not(:disabled),
881
+ .ns-tabs--glass .ns-tabs__list {
882
+ -webkit-backdrop-filter: blur(var(--ns-material-blur-sm)) saturate(var(--ns-material-saturate));
883
+ backdrop-filter: blur(var(--ns-material-blur-sm)) saturate(var(--ns-material-saturate));
884
+ box-shadow: inset 0 1px 0 var(--ns-material-glass-rim);
885
+ }
886
+ .ns-depth-1.ns-material--glass {
887
+ -webkit-backdrop-filter: blur(var(--ns-material-blur-sm)) saturate(var(--ns-material-saturate));
888
+ backdrop-filter: blur(var(--ns-material-blur-sm)) saturate(var(--ns-material-saturate));
889
+ box-shadow: inset 0 1px 0 var(--ns-material-glass-rim);
890
+ }
891
+ .ns-depth-3.ns-material--glass,
892
+ .ns-dialog.ns-material--glass,
893
+ .ns-sheet.ns-material--glass {
894
+ -webkit-backdrop-filter: blur(var(--ns-material-blur-lg)) saturate(var(--ns-material-saturate));
895
+ backdrop-filter: blur(var(--ns-material-blur-lg)) saturate(var(--ns-material-saturate));
896
+ }
897
+ .ns-material--glass .ns-panel__head,
898
+ .ns-material--glass .ns-card__footer,
899
+ .ns-material--glass .ns-layer__footer,
900
+ .ns-material--glass .ns-menu__separator { border-color: var(--ns-material-glass-edge); }
901
+ .ns-material--glass .ns-menu__separator { background: var(--ns-material-glass-edge); }
902
+ .ns-material--glass .ns-menu__item:focus,
903
+ .ns-material--glass .ns-menu__item:hover { background: var(--ns-material-spotlight); }
904
+ .ns-material--glass .ns-menu__item[aria-disabled='true'] { background: transparent; }
905
+ .ns-overlay:has(+ .ns-material--glass) {
906
+ opacity: 1;
907
+ background: color-mix(in srgb, var(--ns-color-ground) 48%, transparent);
908
+ -webkit-backdrop-filter: blur(var(--ns-material-blur-sm));
909
+ backdrop-filter: blur(var(--ns-material-blur-sm));
910
+ }
911
+
912
+ /* ----------------------------------------------------- pointer light */
913
+
914
+ .ns-reactive::before,
915
+ .ns-button--glass::before {
916
+ content: '';
917
+ position: absolute;
918
+ inset: 0;
919
+ z-index: -1;
920
+ border-radius: inherit;
921
+ pointer-events: none;
922
+ background: radial-gradient(360px circle at var(--ns-mx, 50%) var(--ns-my, 0%), var(--ns-material-spotlight), transparent 62%);
923
+ opacity: 0;
924
+ transition: opacity var(--ns-motion-duration-200) var(--ns-motion-easing-settle);
925
+ }
926
+ .ns-button--glass::before { background: radial-gradient(80px circle at var(--ns-mx, 50%) var(--ns-my, 0%), var(--ns-material-spotlight), transparent 70%); }
927
+ .ns-reactive[data-pointer]::before,
928
+ .ns-reactive:has(:focus-visible)::before,
929
+ .ns-reactive:focus-visible::before,
930
+ .ns-button--glass[data-pointer]::before,
931
+ .ns-button--glass:focus-visible::before { opacity: 1; }
932
+
933
+ /* Spotlight: the border lights up where the pointer is (keyboard: along the top). */
934
+ .ns-card--spotlight::after,
935
+ .ns-card--orbit::after {
936
+ content: '';
937
+ position: absolute;
938
+ inset: -1px;
939
+ border-radius: inherit;
940
+ padding: 1px;
941
+ pointer-events: none;
942
+ background: radial-gradient(200px circle at var(--ns-mx, 50%) var(--ns-my, 0%), var(--ns-color-signal), transparent 70%);
943
+ -webkit-mask: linear-gradient(#000 0 0) content-box, linear-gradient(#000 0 0);
944
+ -webkit-mask-composite: xor;
945
+ mask: linear-gradient(#000 0 0) content-box exclude, linear-gradient(#000 0 0);
946
+ opacity: 0;
947
+ transition: opacity var(--ns-motion-duration-200) var(--ns-motion-easing-settle);
948
+ }
949
+ .ns-card--spotlight[data-pointer]::after,
950
+ .ns-card--spotlight:has(:focus-visible)::after,
951
+ .ns-card--spotlight:focus-visible::after { opacity: 1; }
952
+
953
+ /* Orbit: a short arc of light travels the border. */
954
+ .ns-card--orbit::after {
955
+ background: conic-gradient(from var(--ns-orbit), transparent 0 70%, var(--ns-color-signal) 86%, transparent 96%);
956
+ opacity: 0.9;
957
+ animation: ns-orbit 7s linear infinite;
958
+ }
959
+ @keyframes ns-orbit { to { --ns-orbit: 360deg; } }
960
+
961
+ /* ------------------------------------------------------------ buttons */
962
+
963
+ .ns-button {
964
+ position: relative;
965
+ isolation: isolate;
966
+ transform: translate(var(--ns-mag-x, 0px), var(--ns-mag-y, 0px));
967
+ transition: background-color var(--ns-motion-duration-120) var(--ns-motion-easing-settle),
968
+ border-color var(--ns-motion-duration-120) var(--ns-motion-easing-settle),
969
+ color var(--ns-motion-duration-120) var(--ns-motion-easing-settle),
970
+ box-shadow var(--ns-motion-duration-200) var(--ns-motion-easing-settle),
971
+ transform var(--ns-motion-duration-release) var(--ns-motion-spring-release);
972
+ }
973
+ .ns-button:active:not(:disabled) {
974
+ transform: translate(var(--ns-mag-x, 0px), calc(var(--ns-mag-y, 0px) + 0.5px)) scale(var(--ns-material-press));
975
+ transition-duration: var(--ns-motion-duration-press);
976
+ transition-timing-function: var(--ns-motion-spring-press);
977
+ }
978
+ .ns-button--primary { box-shadow: inset 0 1px 0 var(--ns-material-glass-rim); }
979
+ .ns-button--primary:hover:not(:disabled) { box-shadow: inset 0 1px 0 var(--ns-material-glass-rim), 0 6px 20px -8px var(--ns-material-glow); }
980
+ .ns-button--primary:active:not(:disabled) { box-shadow: inset 0 1px 2px var(--ns-color-signal), 0 0 0 3px var(--ns-material-glow); }
981
+ .ns-button--secondary:active:not(:disabled) { box-shadow: inset 0 1px 0 var(--ns-color-line-1); }
982
+ .ns-button--glass.ns-button--secondary:hover:not(:disabled) { border-color: var(--ns-color-line-2); }
983
+
984
+ /* Focus: the ring snaps in from a little way out, with a glacier glow behind it. */
985
+ .ns-button:focus-visible,
986
+ .ns-switch:focus-visible,
987
+ .ns-tabs__trigger:focus-visible,
988
+ .ns-link:focus-visible {
989
+ box-shadow: 0 0 0 4px var(--ns-color-focus-halo), 0 0 18px 2px var(--ns-material-glow);
990
+ animation: ns-ring-in var(--ns-motion-duration-200) var(--ns-motion-spring-settle);
991
+ }
992
+ @keyframes ns-ring-in { from { outline-offset: 5px; outline-color: transparent; } }
993
+
994
+ /* The north star holds still and breathes while its orbit turns round it. */
995
+ .ns-spinner--star { width: 14px; height: 14px; border: 0; border-radius: 0; animation: none; overflow: visible; }
996
+ .ns-spinner__star { transform-box: view-box; transform-origin: 50% 50%; animation: ns-star-breathe 1200ms var(--ns-motion-easing-travel) infinite; }
997
+ .ns-spinner__orbit { opacity: 0.45; stroke-dasharray: 10 31; stroke-linecap: round; transform-box: view-box; transform-origin: 50% 50%; animation: ns-spin 1100ms linear infinite; }
998
+ @keyframes ns-star-breathe { 50% { transform: scale(0.72); opacity: 0.7; } }
999
+ .ns-button[data-success] { border-color: var(--ns-color-signal-edge); }
1000
+ .ns-button--primary[data-success] { border-color: var(--ns-button-primary-bg); }
1001
+ .ns-button__check { flex: none; animation: ns-check-pop var(--ns-motion-duration-release) var(--ns-motion-spring-release); }
1002
+ .ns-button__check path { stroke-dasharray: 1; stroke-dashoffset: 1; animation: ns-draw var(--ns-motion-duration-320) var(--ns-motion-easing-settle) 60ms forwards; }
1003
+ .ns-button:not(.ns-button--primary) .ns-button__check { color: var(--ns-color-signal); }
1004
+ @keyframes ns-draw { to { stroke-dashoffset: 0; } }
1005
+ @keyframes ns-check-pop { from { transform: scale(0.4) rotate(-20deg); opacity: 0; } }
1006
+
1007
+ /* -------------------------------------------------------------- links */
1008
+
1009
+ .ns-link {
1010
+ text-decoration: none;
1011
+ background-image: linear-gradient(currentColor, currentColor), linear-gradient(var(--ns-color-signal-edge), var(--ns-color-signal-edge));
1012
+ background-size: 0% 1px, 100% 1px;
1013
+ background-position: 0 100%, 0 100%;
1014
+ background-repeat: no-repeat;
1015
+ padding-bottom: 1px;
1016
+ transition: background-size var(--ns-motion-duration-320) var(--ns-motion-easing-settle), color var(--ns-motion-duration-120) var(--ns-motion-easing-settle);
1017
+ }
1018
+ .ns-link--neutral { background-image: linear-gradient(currentColor, currentColor), linear-gradient(var(--ns-color-line-2), var(--ns-color-line-2)); }
1019
+ .ns-link:hover,
1020
+ .ns-link:focus-visible { background-size: 100% 1px, 100% 1px; }
1021
+
1022
+ /* -------------------------------------------------------------- forms */
1023
+
1024
+ .ns-input,
1025
+ .ns-select,
1026
+ .ns-textarea {
1027
+ transition: border-color var(--ns-motion-duration-120) var(--ns-motion-easing-settle),
1028
+ box-shadow var(--ns-motion-duration-200) var(--ns-motion-easing-settle);
1029
+ }
1030
+ .ns-input:focus-within,
1031
+ .ns-select:focus-within,
1032
+ .ns-textarea:focus-visible {
1033
+ border-color: var(--ns-color-signal-edge);
1034
+ box-shadow: 0 0 0 4px var(--ns-color-focus-halo), 0 0 22px -4px var(--ns-material-glow);
1035
+ }
1036
+
1037
+ .ns-switch { transition: background-color var(--ns-motion-duration-200) var(--ns-motion-easing-settle), border-color var(--ns-motion-duration-200) var(--ns-motion-easing-settle), box-shadow var(--ns-motion-duration-200) var(--ns-motion-easing-settle); }
1038
+ .ns-switch[aria-checked='true'] { box-shadow: 0 0 12px -3px var(--ns-material-glow); }
1039
+ .ns-switch__thumb {
1040
+ transition: transform var(--ns-motion-duration-release) var(--ns-motion-spring-release),
1041
+ width var(--ns-motion-duration-press) var(--ns-motion-spring-press),
1042
+ background-color var(--ns-motion-duration-120) var(--ns-motion-easing-settle);
1043
+ }
1044
+ .ns-switch:active:not(:disabled) .ns-switch__thumb { width: 15px; }
1045
+ .ns-switch[aria-checked='true']:active:not(:disabled) .ns-switch__thumb { transform: translateX(9px); }
1046
+
1047
+ /* --------------------------------------------------------------- tabs */
1048
+
1049
+ .ns-tabs__list { position: relative; }
1050
+ .ns-tabs__trigger { z-index: 1; transition: color var(--ns-motion-duration-120) var(--ns-motion-easing-settle); }
1051
+ .ns-tabs__indicator { position: absolute; top: 0; left: 0; width: 0; height: 0; z-index: 0; pointer-events: none; opacity: 0; }
1052
+ .ns-tabs__list[data-indicator] .ns-tabs__indicator { opacity: 1; }
1053
+ .ns-tabs__list[data-indicator='ready'] .ns-tabs__indicator {
1054
+ transition: transform var(--ns-motion-duration-settle) var(--ns-motion-spring-settle),
1055
+ width var(--ns-motion-duration-settle) var(--ns-motion-spring-settle),
1056
+ height var(--ns-motion-duration-settle) var(--ns-motion-spring-settle);
1057
+ }
1058
+ .ns-tabs__list[data-indicator] .ns-tabs__trigger[aria-selected='true']::after { display: none; }
1059
+ .ns-tabs__indicator::after { content: ''; position: absolute; left: var(--ns-space-8); right: var(--ns-space-8); bottom: -1px; height: 2px; border-radius: 1px; background: var(--ns-color-signal); }
1060
+ .ns-tabs--vertical .ns-tabs__indicator { border-radius: var(--ns-radius-4); background: var(--ns-color-surface-2); }
1061
+ .ns-tabs--vertical .ns-tabs__indicator::after { left: 0; right: auto; top: var(--ns-space-6); bottom: var(--ns-space-6); width: 2px; height: auto; }
1062
+ .ns-tabs--vertical .ns-tabs__list[data-indicator] .ns-tabs__trigger[aria-selected='true'] { background: transparent; }
1063
+
1064
+ .ns-tabs--pill .ns-tabs__list { display: inline-flex; gap: var(--ns-space-2); padding: 3px; border: 1px solid var(--ns-color-line-1); border-radius: var(--ns-radius-control-pill); background: var(--ns-color-surface-1); }
1065
+ .ns-tabs--pill.ns-tabs--vertical .ns-tabs__list { padding-right: 3px; border-right: 1px solid var(--ns-color-line-1); }
1066
+ .ns-tabs--pill .ns-tabs__trigger { height: calc(var(--ns-control-h, var(--ns-size-control-md)) - 6px); padding: 0 var(--ns-space-12); border-radius: var(--ns-radius-control-pill); }
1067
+ .ns-tabs--pill .ns-tabs__trigger[aria-selected='true']::after,
1068
+ .ns-tabs--pill .ns-tabs__indicator::after { display: none; }
1069
+ .ns-tabs--pill .ns-tabs__list:not([data-indicator]) .ns-tabs__trigger[aria-selected='true'],
1070
+ .ns-tabs--pill .ns-tabs__indicator { background: var(--ns-color-surface-3); box-shadow: inset 0 0 0 1px var(--ns-color-line-2); border-radius: var(--ns-radius-control-pill); }
1071
+ .ns-tabs--glass .ns-tabs__indicator {
1072
+ background: var(--ns-material-glass-specular), linear-gradient(var(--ns-material-spotlight), var(--ns-material-spotlight)), var(--ns-material-glass-fill);
1073
+ box-shadow: inset 0 1px 0 var(--ns-material-glass-rim), inset 0 0 0 1px var(--ns-material-glass-edge), 0 4px 14px -6px var(--ns-material-glow);
1074
+ }
1075
+
1076
+ /* ---------------------------------------------------- layers: springs */
1077
+
1078
+ .ns-pop[data-state] { --ns-pop-x: 0px; --ns-pop-y: -4px; transform-origin: top center; }
1079
+ .ns-pop[data-side='top'],
1080
+ .ns-tooltip[data-side='top'] { --ns-pop-y: 4px; transform-origin: bottom center; }
1081
+ .ns-pop[data-side='left'],
1082
+ .ns-tooltip[data-side='left'] { --ns-pop-x: 4px; --ns-pop-y: 0px; transform-origin: center right; }
1083
+ .ns-pop[data-side='right'],
1084
+ .ns-tooltip[data-side='right'] { --ns-pop-x: -4px; --ns-pop-y: 0px; transform-origin: center left; }
1085
+ .ns-tooltip[data-side='bottom'] { --ns-pop-y: -4px; }
1086
+ .ns-pop[data-state='open'],
1087
+ .ns-tooltip[data-state='open'] { animation: ns-layer-in var(--ns-motion-duration-release) var(--ns-motion-spring-settle); }
1088
+ .ns-pop[data-state='closed'],
1089
+ .ns-tooltip[data-state='closed'] { animation: ns-layer-out var(--ns-motion-duration-120) var(--ns-motion-easing-exit) forwards; pointer-events: none; }
1090
+ @keyframes ns-layer-in { from { opacity: 0; transform: translate(var(--ns-pop-x, 0px), var(--ns-pop-y, 4px)) scale(0.96); } }
1091
+ @keyframes ns-layer-out { to { opacity: 0; transform: translate(var(--ns-pop-x, 0px), var(--ns-pop-y, 4px)) scale(0.97); } }
1092
+
1093
+ .ns-overlay[data-state='closed'] { animation: ns-fade-out var(--ns-motion-duration-200) var(--ns-motion-easing-exit) forwards; }
1094
+ @keyframes ns-fade-out { to { opacity: 0; } }
1095
+ .ns-dialog[data-state='open'] { animation: ns-dialog-in var(--ns-motion-duration-settle) var(--ns-motion-spring-settle); }
1096
+ .ns-dialog[data-state='closed'] { animation: ns-dialog-out var(--ns-motion-duration-200) var(--ns-motion-easing-exit) forwards; pointer-events: none; }
1097
+ @keyframes ns-dialog-in { from { opacity: 0; transform: translate(-50%, calc(-50% + 12px)) scale(0.96); } }
1098
+ @keyframes ns-dialog-out { to { opacity: 0; transform: translate(-50%, calc(-50% + 6px)) scale(0.98); } }
1099
+ .ns-sheet[data-state='open'] { animation: ns-sheet-in var(--ns-motion-duration-320) var(--ns-motion-easing-enter); }
1100
+ .ns-sheet[data-state='closed'] { animation: ns-sheet-in var(--ns-motion-duration-200) var(--ns-motion-easing-exit) reverse forwards; pointer-events: none; }
1101
+ .ns-sheet--right { --ns-sheet-from: translateX(32px); }
1102
+ .ns-sheet--left { --ns-sheet-from: translateX(-32px); }
1103
+ .ns-sheet--bottom { --ns-sheet-from: translateY(32px); }
1104
+ @keyframes ns-sheet-in { from { opacity: 0; transform: var(--ns-sheet-from); } }
1105
+
1106
+ .ns-toaster__item { animation: ns-toast-in var(--ns-motion-duration-release) var(--ns-motion-spring-release); }
1107
+ @keyframes ns-toast-in { from { opacity: 0; transform: translateY(12px) scale(0.96); } }
1108
+ .ns-toast { transition: transform var(--ns-motion-duration-release) var(--ns-motion-spring-release), border-color var(--ns-motion-duration-200) var(--ns-motion-easing-settle); }
1109
+ .ns-toaster__item:hover .ns-toast,
1110
+ .ns-toaster__item:focus-within .ns-toast { transform: translateY(-1px); border-color: var(--ns-color-line-2); }
1111
+ .ns-toast.ns-material--glass.ns-tone-signal { border-left-color: var(--ns-color-signal); }
1112
+
1113
+ .ns-menu__item,
1114
+ .ns-option { transition: background-color var(--ns-motion-duration-120) var(--ns-motion-easing-settle); }
1115
+
1116
+ /* --------------------------------------------------------- data, tags */
1117
+
1118
+ .ns-table--interactive tbody .ns-table__row {
1119
+ transition: transform var(--ns-motion-duration-release) var(--ns-motion-spring-release),
1120
+ box-shadow var(--ns-motion-duration-200) var(--ns-motion-easing-settle),
1121
+ background-color var(--ns-motion-duration-120) var(--ns-motion-easing-settle);
1122
+ }
1123
+ .ns-table--interactive tbody .ns-table__row:hover,
1124
+ .ns-table--interactive tbody .ns-table__row:has(:focus-visible) {
1125
+ position: relative;
1126
+ z-index: 1;
1127
+ background: var(--ns-color-surface-2);
1128
+ transform: translateY(-1px);
1129
+ box-shadow: 0 1px 0 var(--ns-color-line-2), 0 8px 20px -14px var(--ns-material-glow);
1130
+ }
1131
+ .ns-table--interactive tbody .ns-table__row:hover > :first-child,
1132
+ .ns-table--interactive tbody .ns-table__row:has(:focus-visible) > :first-child { box-shadow: inset 2px 0 0 var(--ns-color-signal); }
1133
+
1134
+ .ns-tag { transition: border-color var(--ns-motion-duration-120) var(--ns-motion-easing-settle), box-shadow var(--ns-motion-duration-200) var(--ns-motion-easing-settle); }
1135
+ .ns-tag:has(.ns-tag__remove):hover { border-color: var(--ns-color-text-3); }
1136
+ .ns-tag.ns-tone-signal:has(.ns-tag__remove):hover { border-color: var(--ns-color-signal); box-shadow: 0 0 10px -3px var(--ns-material-glow); }
1137
+ .ns-tag__remove { transition: transform var(--ns-motion-duration-release) var(--ns-motion-spring-release); }
1138
+ .ns-tag__remove:active { transform: scale(0.82); transition-duration: var(--ns-motion-duration-press); }
1139
+
1140
+ /* ------------------------------------------------------------ fallbacks */
1141
+
1142
+ @supports not ((backdrop-filter: blur(1px)) or (-webkit-backdrop-filter: blur(1px))) {
1143
+ .ns-material--glass,
1144
+ .ns-button--glass.ns-button--secondary,
1145
+ .ns-button--glass.ns-button--ghost:hover:not(:disabled),
1146
+ .ns-tabs--glass .ns-tabs__list,
1147
+ .ns-tabs--glass .ns-tabs__indicator { background: var(--ns-material-solid); }
1148
+ }
1149
+ @media (prefers-reduced-transparency: reduce) {
1150
+ .ns-material--glass,
1151
+ .ns-button--glass.ns-button--secondary,
1152
+ .ns-button--glass.ns-button--ghost:hover:not(:disabled),
1153
+ .ns-tabs--glass .ns-tabs__list,
1154
+ .ns-tabs--glass .ns-tabs__indicator,
1155
+ .ns-overlay:has(+ .ns-material--glass) {
1156
+ background: var(--ns-material-solid);
1157
+ -webkit-backdrop-filter: none;
1158
+ backdrop-filter: none;
1159
+ }
1160
+ .ns-overlay:has(+ .ns-material--glass) { background: var(--ns-color-ground); opacity: 0.72; }
1161
+ }
1162
+ @media (forced-colors: active) {
1163
+ .ns-material--glass,
1164
+ .ns-button--glass,
1165
+ .ns-tabs--glass .ns-tabs__list,
1166
+ .ns-card,
1167
+ .ns-panel,
1168
+ .ns-surface {
1169
+ background: Canvas;
1170
+ -webkit-backdrop-filter: none;
1171
+ backdrop-filter: none;
1172
+ border-color: CanvasText;
1173
+ box-shadow: none;
1174
+ }
1175
+ .ns-reactive::before,
1176
+ .ns-button--glass::before,
1177
+ .ns-card--spotlight::after,
1178
+ .ns-card--orbit::after { display: none; }
1179
+ .ns-tabs__indicator::after { background: Highlight; }
1180
+ .ns-tabs--pill .ns-tabs__indicator { background: Highlight; box-shadow: none; }
1181
+ .ns-tabs--pill .ns-tabs__trigger[aria-selected='true'] { color: HighlightText; }
1182
+ .ns-link { text-decoration: underline; background-image: none; }
1183
+ .ns-table--interactive tbody .ns-table__row:hover > :first-child,
1184
+ .ns-table--interactive tbody .ns-table__row:has(:focus-visible) > :first-child { box-shadow: none; outline: 2px solid Highlight; outline-offset: -2px; }
1185
+ }
1186
+
1187
+ /* ------------------------------------------------------ reduced motion */
1188
+
1189
+ @media (prefers-reduced-motion: reduce) {
1190
+ .ns-root *,
1191
+ .ns-root *::before,
1192
+ .ns-root *::after {
1193
+ animation-duration: 0ms !important;
1194
+ animation-iteration-count: 1 !important;
1195
+ transition-duration: 0ms !important;
1196
+ }
1197
+ .ns-skeleton { animation: none !important; }
1198
+ .ns-spinner { animation: none !important; border-right-color: currentColor; border-style: dotted; }
1199
+ /* No movement: presses, lifts, magnets, the orbit and the turning star all
1200
+ hold still. State changes (selected tab, switch, success) still show. */
1201
+ .ns-button,
1202
+ .ns-button:active:not(:disabled),
1203
+ .ns-card--interactive,
1204
+ .ns-toast,
1205
+ .ns-tag__remove,
1206
+ .ns-table--interactive tbody .ns-table__row { transform: none !important; }
1207
+ .ns-spinner__star,
1208
+ .ns-spinner__orbit,
1209
+ .ns-card--orbit::after { animation: none !important; }
1210
+ .ns-tabs__indicator { transition: none !important; }
1211
+ }
1212
+
1213
+ /* ============================================== northstar: study workspace */
1214
+
1215
+ .ns-study-hint { font-size: var(--ns-font-size-12); line-height: var(--ns-font-line-height-12); color: var(--ns-color-text-3); }
1216
+ .ns-study-label { font-size: var(--ns-font-size-12); font-weight: var(--ns-font-weight-medium); color: var(--ns-color-text-2); }
1217
+ .ns-study-muted { color: var(--ns-color-text-3); }
1218
+ .ns-study-signal { color: var(--ns-color-signal); }
1219
+ .ns-study-mono { font-family: var(--ns-font-family-mono); font-variant-numeric: var(--ns-font-numeric-figures); }
1220
+ .ns-study-id { flex: none; width: 22px; font-family: var(--ns-font-family-mono); font-size: var(--ns-font-size-12); color: var(--ns-color-text-3); }
1221
+ .ns-study-divider { width: 1px; height: 20px; background: var(--ns-color-line-2); }
1222
+ .ns-study-panel { border: 1px solid var(--ns-color-line-1); border-radius: var(--ns-radius-8); background: var(--ns-color-surface-1); overflow: hidden; }
1223
+ .ns-study-panel__head { display: flex; align-items: center; gap: var(--ns-space-8); min-height: 36px; padding: 0 var(--ns-space-12); border-bottom: 1px solid var(--ns-color-line-1); }
1224
+ .ns-study-panel__title { margin: 0; font-size: var(--ns-font-size-13); line-height: var(--ns-font-line-height-13); font-weight: var(--ns-font-weight-medium); color: var(--ns-color-text-1); }
1225
+ .ns-study-panel__end,
1226
+ .ns-study-panel__action { margin-left: auto; }
1227
+ .ns-study-row { display: flex; align-items: center; gap: var(--ns-space-12); min-height: 36px; padding: 0 var(--ns-space-12); border-bottom: 1px solid var(--ns-color-line-1); }
1228
+ .ns-study-row:last-child { border-bottom: 0; }
1229
+ .ns-study-row:hover { background: var(--ns-color-surface-2); }
1230
+ .ns-study-row__input,
1231
+ .ns-brief__title,
1232
+ .ns-brief__decision,
1233
+ .ns-research__wording {
1234
+ flex: 1;
1235
+ min-width: 0;
1236
+ border: 1px solid transparent;
1237
+ border-radius: var(--ns-radius-6);
1238
+ background: transparent;
1239
+ color: var(--ns-color-text-1);
1240
+ font: inherit;
1241
+ padding: var(--ns-space-2) var(--ns-space-4);
1242
+ margin-left: calc(-1 * var(--ns-space-4));
1243
+ }
1244
+ .ns-study-row__input:focus-visible,
1245
+ .ns-brief__title:focus-visible,
1246
+ .ns-brief__decision:focus-visible,
1247
+ .ns-research__wording:focus-visible,
1248
+ .ns-research__anchor-input:focus-visible { outline: none; border-color: var(--ns-color-focus); box-shadow: 0 0 0 3px var(--ns-color-focus-halo); }
1249
+ .ns-study-row__ghost { flex: 1; border: 0; background: transparent; color: var(--ns-color-text-3); font: inherit; text-align: left; padding: var(--ns-space-6) 0; cursor: pointer; border-radius: var(--ns-radius-4); }
1250
+ .ns-study-row__ghost:focus-visible,
1251
+ .ns-study-icon-button:focus-visible,
1252
+ .ns-research__select:focus-visible { outline: 2px solid var(--ns-color-focus); outline-offset: -2px; }
1253
+ .ns-study-icon-button {
1254
+ display: inline-flex; align-items: center; justify-content: center;
1255
+ width: 24px; height: 24px; flex: none;
1256
+ border: 0; border-radius: var(--ns-radius-4); background: transparent; color: var(--ns-color-text-3); cursor: pointer;
1257
+ }
1258
+ .ns-study-icon-button:hover { background: var(--ns-color-surface-3); color: var(--ns-color-text-1); }
1259
+ .ns-study-icon-button:disabled { opacity: 0.4; cursor: not-allowed; background: transparent; }
1260
+ @media (pointer: coarse) { .ns-study-icon-button { width: 44px; height: 44px; } }
1261
+ .ns-study-callout {
1262
+ display: flex; gap: var(--ns-space-8); align-items: flex-start;
1263
+ padding: var(--ns-space-8) var(--ns-space-12);
1264
+ border: 1px solid var(--ns-color-signal-edge); border-radius: var(--ns-radius-6);
1265
+ background: var(--ns-color-signal-wash);
1266
+ font-size: var(--ns-font-size-12); line-height: var(--ns-font-line-height-12); color: var(--ns-color-text-1);
1267
+ max-width: 640px;
1268
+ }
1269
+ .ns-study-empty { display: flex; flex-direction: column; align-items: center; gap: var(--ns-space-6); padding: var(--ns-space-24); text-align: center; }
1270
+ .ns-study-empty p { margin: 0; }
1271
+ .ns-study-empty__title { font-weight: var(--ns-font-weight-semibold); color: var(--ns-color-text-1); }
1272
+
1273
+ /* StudyStatus */
1274
+ .ns-study-status { display: inline-flex; align-items: center; gap: var(--ns-space-6); color: var(--ns-color-text-2); font-size: var(--ns-font-size-12); font-weight: var(--ns-font-weight-medium); white-space: nowrap; }
1275
+ .ns-study-status--tag { height: 20px; padding: 0 var(--ns-space-6); border: 1px solid var(--ns-color-line-2); border-radius: var(--ns-radius-4); font-size: var(--ns-font-size-11); }
1276
+ .ns-study-status__mark { flex: none; color: var(--ns-color-text-3); }
1277
+ .ns-study-status--running .ns-study-status__mark,
1278
+ .ns-study-status--failed .ns-study-status__mark { color: var(--ns-color-signal); }
1279
+ .ns-study-status--complete .ns-study-status__mark { color: var(--ns-color-text-2); }
1280
+ .ns-study-status--archived { color: var(--ns-color-text-3); }
1281
+ .ns-study-status--running.ns-study-status--tag,
1282
+ .ns-study-status--failed.ns-study-status--tag { border-style: dashed; }
1283
+ .ns-study-status[data-motion='sweep'] .ns-study-status__mark { animation: ns-study-sweep 2.4s linear infinite; }
1284
+ @keyframes ns-study-sweep { to { transform: rotate(360deg); } }
1285
+
1286
+ /* StudyShell */
1287
+ .ns-study-shell { display: flex; flex-wrap: wrap; min-height: 100%; background: var(--ns-color-ground); color: var(--ns-color-text-1); }
1288
+ .ns-study-shell__main { flex: 999 1 560px; min-width: 0; display: flex; flex-direction: column; }
1289
+ .ns-study-shell__bar { display: flex; flex-wrap: wrap; align-items: center; gap: var(--ns-space-8); min-height: 44px; padding: 0 var(--ns-space-16); border-bottom: 1px solid var(--ns-color-line-1); }
1290
+ .ns-study-shell__crumb { display: flex; align-items: center; gap: var(--ns-space-6); color: var(--ns-color-text-3); }
1291
+ .ns-study-shell__crumb b { color: var(--ns-color-text-1); font-weight: var(--ns-font-weight-medium); }
1292
+ .ns-study-shell__spacer { flex: 1; }
1293
+ .ns-study-shell__save { font-size: var(--ns-font-size-12); color: var(--ns-color-text-3); }
1294
+ .ns-study-shell__tabs { display: flex; flex-direction: column; flex: 1; }
1295
+ .ns-study-shell__tabbar { display: flex; flex-wrap: wrap; align-items: center; gap: var(--ns-space-8); min-height: 40px; padding: 0 var(--ns-space-12); border-bottom: 1px solid var(--ns-color-line-1); }
1296
+ .ns-study-shell__tablist.ns-tabs__list { border-bottom: 0; gap: var(--ns-space-2); }
1297
+ .ns-study-shell__tab.ns-tabs__trigger { display: inline-flex; align-items: center; gap: var(--ns-space-6); height: 26px; padding: 0 var(--ns-space-12); border-radius: var(--ns-radius-control-pill); }
1298
+ .ns-study-shell__tab.ns-tabs__trigger:hover { background: var(--ns-color-surface-2); }
1299
+ .ns-study-shell__tab.ns-tabs__trigger[aria-selected='true'] { background: var(--ns-color-surface-3); box-shadow: inset 0 0 0 1px var(--ns-color-line-2); }
1300
+ .ns-study-shell__tab.ns-tabs__trigger[aria-selected='true']::after { display: none; }
1301
+ .ns-study-shell__tab.ns-tabs__trigger:focus-visible { outline: 2px solid var(--ns-color-focus); outline-offset: 1px; }
1302
+ .ns-study-shell__tab-meta { font-size: var(--ns-font-size-11); color: var(--ns-color-text-3); font-variant-numeric: var(--ns-font-numeric-figures); }
1303
+ .ns-study-shell__tab-actions { margin-left: auto; display: flex; gap: var(--ns-space-8); }
1304
+ .ns-study-shell__content.ns-tabs__content { flex: 1; padding: var(--ns-space-24) var(--ns-space-32); }
1305
+ .ns-study-shell__content:focus-visible { outline: 2px solid var(--ns-color-focus); outline-offset: -2px; }
1306
+ .ns-study-shell__aside { flex: 1 1 260px; max-width: 300px; border-left: 1px solid var(--ns-color-line-1); display: flex; flex-direction: column; }
1307
+
1308
+ /* BriefForm */
1309
+ .ns-brief { display: flex; flex-direction: column; gap: var(--ns-space-20); max-width: 820px; }
1310
+ .ns-brief__head { display: flex; flex-direction: column; gap: var(--ns-space-6); }
1311
+ .ns-brief__title { font-size: var(--ns-font-size-18); line-height: var(--ns-font-line-height-18); font-weight: var(--ns-font-weight-semibold); }
1312
+ .ns-brief__decision { resize: vertical; color: var(--ns-color-text-2); font-size: var(--ns-font-size-15); line-height: var(--ns-font-line-height-15); }
1313
+ .ns-brief__toolbar { display: flex; flex-wrap: wrap; gap: var(--ns-space-8); align-items: center; }
1314
+
1315
+ /* PopulationPanel */
1316
+ .ns-population { display: flex; flex-direction: column; gap: var(--ns-space-20); max-width: 900px; }
1317
+ .ns-population__controls { display: flex; flex-wrap: wrap; align-items: center; gap: var(--ns-space-12); }
1318
+ .ns-population__market { display: inline-flex; align-items: center; gap: var(--ns-space-8); }
1319
+ .ns-population__number { width: 120px; }
1320
+ .ns-population__grid { display: grid; grid-template-columns: repeat(auto-fit, minmax(280px, 1fr)); }
1321
+ .ns-population__group { padding: var(--ns-space-8) var(--ns-space-12) var(--ns-space-12); border-bottom: 1px solid var(--ns-color-line-1); overflow: hidden; }
1322
+ .ns-population__group-title { margin: 0 0 var(--ns-space-4); font-size: var(--ns-font-size-12); font-weight: var(--ns-font-weight-medium); color: var(--ns-color-text-3); }
1323
+ .ns-population__group svg { max-width: 100%; height: auto; }
1324
+
1325
+ /* ResearchBuilder */
1326
+ .ns-research { display: flex; flex-wrap: wrap; margin: calc(-1 * var(--ns-space-24)) calc(-1 * var(--ns-space-32)); min-height: 100%; }
1327
+ .ns-research__list { flex: 1 1 360px; max-width: 420px; border-right: 1px solid var(--ns-color-line-1); display: flex; flex-direction: column; }
1328
+ .ns-research__list-head { display: flex; align-items: center; gap: var(--ns-space-8); min-height: 40px; padding: 0 var(--ns-space-12); border-bottom: 1px solid var(--ns-color-line-1); color: var(--ns-color-text-3); font-size: var(--ns-font-size-12); font-weight: var(--ns-font-weight-medium); }
1329
+ .ns-research__items { margin: 0; padding: 0; list-style: none; }
1330
+ .ns-research__item { display: flex; align-items: center; border-bottom: 1px solid var(--ns-color-line-1); }
1331
+ .ns-research__item:hover { background: var(--ns-color-surface-2); }
1332
+ .ns-research__item--on,
1333
+ .ns-research__item--on:hover { background: var(--ns-color-surface-3); }
1334
+ .ns-research__select { flex: 1; min-width: 0; display: flex; align-items: center; gap: var(--ns-space-8); height: 36px; padding: 0 var(--ns-space-12); border: 0; background: transparent; color: var(--ns-color-text-1); font: inherit; text-align: left; cursor: pointer; }
1335
+ .ns-research__q { flex: 1; min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
1336
+ .ns-research__tools { display: inline-flex; padding-right: var(--ns-space-6); }
1337
+ .ns-research__editor { flex: 999 1 420px; min-width: 0; padding: var(--ns-space-20) var(--ns-space-24); display: flex; flex-direction: column; gap: var(--ns-space-16); }
1338
+ .ns-research__editor-head { display: flex; flex-wrap: wrap; align-items: center; gap: var(--ns-space-6); }
1339
+ .ns-research__wording { resize: vertical; font-size: var(--ns-font-size-15); line-height: var(--ns-font-line-height-15); font-weight: var(--ns-font-weight-medium); }
1340
+ .ns-research__anchors { margin: 0; padding: 0; border: 0; display: flex; flex-direction: column; gap: var(--ns-space-6); }
1341
+ .ns-research__anchors legend { margin-bottom: var(--ns-space-8); }
1342
+ .ns-research__anchor { display: grid; grid-template-columns: 20px minmax(0, 1fr) 20px; gap: var(--ns-space-8); align-items: center; }
1343
+ .ns-research__anchor-input { height: var(--ns-size-control-sm); padding: 0 var(--ns-space-8); border: 1px solid var(--ns-color-line-2); border-radius: var(--ns-radius-6); background: var(--ns-color-surface-1); color: var(--ns-color-text-1); font: inherit; }
1344
+ .ns-research__anchor-input.ns-invalid { border-color: var(--ns-color-signal-edge); background: var(--ns-color-signal-wash); }
1345
+
1346
+ /* ResponsesView */
1347
+ .ns-responses { display: flex; flex-direction: column; gap: var(--ns-space-16); max-width: 1100px; }
1348
+ .ns-responses__intro { margin: 0; max-width: 720px; }
1349
+ .ns-responses__row { display: grid; grid-template-columns: 28px minmax(0, 1.2fr) 140px minmax(0, 1fr); gap: var(--ns-space-16); align-items: center; padding: var(--ns-space-12); border-bottom: 1px solid var(--ns-color-line-1); }
1350
+ .ns-responses__row:last-child { border-bottom: 0; }
1351
+ .ns-responses__dist { min-width: 0; overflow: hidden; }
1352
+ .ns-responses__dist svg { max-width: 100%; height: auto; }
1353
+ .ns-responses__extra { grid-column: 2 / -1; color: var(--ns-color-text-2); }
1354
+ @media (max-width: 720px) {
1355
+ .ns-responses__row { grid-template-columns: 28px minmax(0, 1fr); }
1356
+ .ns-responses__figure,
1357
+ .ns-responses__dist { grid-column: 2; }
1358
+ }
1359
+
1360
+ /* RunCost, RunConfirm */
1361
+ .ns-run-cost { display: flex; flex-direction: column; gap: var(--ns-space-8); }
1362
+ .ns-run-cost__line { display: flex; justify-content: space-between; align-items: baseline; gap: var(--ns-space-12); }
1363
+ .ns-run-cost__button { width: 100%; }
1364
+ .ns-run-confirm__cost { padding: var(--ns-space-12) 0; }
1365
+
1366
+ /* Illustrations */
1367
+ .ns-illustration { display: block; max-width: 100%; height: auto; }
1368
+ .ns-illustration__orbit { animation: ns-study-sweep linear infinite; }
1369
+ .ns-lockup { display: inline-flex; align-items: center; gap: 0.35em; color: var(--ns-color-text-1); line-height: 1; }
1370
+ .ns-lockup svg { flex: none; }
1371
+ .ns-lockup__word { font-family: 'Instrument Serif', Georgia, serif; font-size: 1.1em; letter-spacing: -0.01em; }
1372
+
1373
+ @media (prefers-reduced-motion: reduce) {
1374
+ .ns-study-status[data-motion] .ns-study-status__mark,
1375
+ .ns-illustration__orbit { animation: none !important; }
1376
+ }
1377
+
1378
+ /* ===================================================== liquid layer
1379
+ Liquid glass, borderless surfaces, icon-led controls, flows and long,
1380
+ soft motion. Loaded last so it refines everything above. */
1381
+
1382
+ /* ------------------------------------------------- borderless surfaces */
1383
+
1384
+ .ns-surface,
1385
+ .ns-card,
1386
+ .ns-panel { border-color: transparent; }
1387
+ .ns-card.ns-material--solid,
1388
+ .ns-panel.ns-material--solid,
1389
+ .ns-surface.ns-material--solid { box-shadow: inset 0 0 0 1px var(--ns-material-hairline), var(--ns-elevation-1); }
1390
+ .ns-surface.ns-material--solid.ns-depth-3 { box-shadow: inset 0 0 0 1px var(--ns-material-hairline), var(--ns-elevation-3); }
1391
+ .ns-panel__head { border-bottom-color: var(--ns-material-hairline); }
1392
+ .ns-card__footer { border-top: 0; padding-top: 0; }
1393
+ .ns-card {
1394
+ transition: transform var(--ns-motion-duration-layout) var(--ns-motion-easing-glide),
1395
+ box-shadow var(--ns-motion-duration-layout) var(--ns-motion-easing-glide),
1396
+ background-color var(--ns-motion-duration-micro) var(--ns-motion-easing-hover);
1397
+ }
1398
+ .ns-card--interactive:hover,
1399
+ .ns-card--interactive:has(:focus-visible) {
1400
+ border-color: transparent;
1401
+ box-shadow: inset 0 0 0 1px var(--ns-material-hairline), var(--ns-elevation-2), 0 18px 40px -22px var(--ns-material-glow);
1402
+ }
1403
+ .ns-table-wrap { border-color: transparent; box-shadow: inset 0 0 0 1px var(--ns-material-hairline); }
1404
+ .ns-sidebar { border-right: 0; }
1405
+ .ns-sidebar__footer { border-top-color: var(--ns-material-hairline); }
1406
+ .ns-top-bar { border-bottom-color: var(--ns-material-hairline); }
1407
+ .ns-tabs__list { border-bottom-color: var(--ns-material-hairline); }
1408
+ .ns-study-panel { border-color: transparent; box-shadow: inset 0 0 0 1px var(--ns-material-hairline); }
1409
+ .ns-study-shell__bar,
1410
+ .ns-study-shell__tabbar { border-bottom-color: var(--ns-material-hairline); }
1411
+ .ns-study-shell__aside { border-left-color: var(--ns-material-hairline); }
1412
+
1413
+ /* Buttons: tonal, not outlined. The secondary button is a quiet fill. */
1414
+ .ns-button--secondary,
1415
+ .ns-button--secondary:disabled { border-color: transparent; }
1416
+ .ns-button:active:not(:disabled):not(.ns-button--primary) { border-color: transparent; }
1417
+ .ns-button-group--attached { gap: 1px; }
1418
+ .ns-button-group--attached > .ns-button + .ns-button { margin-left: 0; }
1419
+
1420
+ /* Hover in and out on the same soft curve; nothing snaps. */
1421
+ .ns-button {
1422
+ transition: background-color var(--ns-motion-duration-micro) var(--ns-motion-easing-hover),
1423
+ border-color var(--ns-motion-duration-micro) var(--ns-motion-easing-hover),
1424
+ color var(--ns-motion-duration-micro) var(--ns-motion-easing-hover),
1425
+ box-shadow var(--ns-motion-duration-micro) var(--ns-motion-easing-hover),
1426
+ padding var(--ns-motion-duration-layout) var(--ns-motion-spring-layout),
1427
+ transform var(--ns-motion-duration-release) var(--ns-motion-spring-release);
1428
+ }
1429
+ .ns-sidebar__item,
1430
+ .ns-tabs__trigger,
1431
+ .ns-menu__item,
1432
+ .ns-option,
1433
+ .ns-breadcrumbs a,
1434
+ .ns-tag {
1435
+ transition: background-color var(--ns-motion-duration-micro) var(--ns-motion-easing-hover),
1436
+ color var(--ns-motion-duration-micro) var(--ns-motion-easing-hover),
1437
+ box-shadow var(--ns-motion-duration-micro) var(--ns-motion-easing-hover),
1438
+ border-color var(--ns-motion-duration-micro) var(--ns-motion-easing-hover);
1439
+ }
1440
+ .ns-tabs__list[data-indicator='ready'] .ns-tabs__indicator {
1441
+ transition: transform var(--ns-motion-duration-layout) var(--ns-motion-spring-layout),
1442
+ width var(--ns-motion-duration-layout) var(--ns-motion-spring-layout),
1443
+ height var(--ns-motion-duration-layout) var(--ns-motion-spring-layout);
1444
+ }
1445
+
1446
+ /* ----------------------------------------------------------- liquid glass */
1447
+
1448
+ .ns-liquid,
1449
+ .ns-material--glass,
1450
+ .ns-button--glass.ns-button--secondary,
1451
+ .ns-button--glass.ns-button--ghost:hover:not(:disabled),
1452
+ .ns-tabs--glass .ns-tabs__list {
1453
+ --ns-liquid-ring: inset 0 1px 0 0 var(--ns-material-liquid-rim), inset 0 -1px 0 0 var(--ns-material-liquid-rim-low),
1454
+ inset 0 0 0 0.5px var(--ns-material-liquid-rim-low), inset 0 0 16px 0 var(--ns-material-liquid-inner);
1455
+ background: var(--ns-material-liquid-highlight),
1456
+ linear-gradient(var(--ns-material-liquid-tint), var(--ns-material-liquid-tint)),
1457
+ var(--ns-material-glass-fill);
1458
+ border-color: transparent;
1459
+ -webkit-backdrop-filter: blur(var(--ns-material-liquid-fallback-blur)) saturate(var(--ns-material-saturate));
1460
+ backdrop-filter: blur(var(--ns-material-liquid-fallback-blur)) saturate(var(--ns-material-saturate));
1461
+ box-shadow: var(--ns-liquid-ring);
1462
+ }
1463
+ .ns-liquid { position: relative; isolation: isolate; border-radius: var(--ns-liquid-radius, var(--ns-radius-glass-panel)); color: var(--ns-color-text-1); }
1464
+ .ns-liquid--tint-none { background: var(--ns-material-liquid-highlight), var(--ns-material-glass-fill); }
1465
+ .ns-liquid--tint-signal { background: var(--ns-material-liquid-highlight), linear-gradient(var(--ns-color-signal-wash), var(--ns-color-signal-wash)), var(--ns-material-glass-fill); }
1466
+ .ns-liquid--floating,
1467
+ .ns-material--glass:not(.ns-depth-1):not(.ns-button) { box-shadow: var(--ns-liquid-ring), var(--ns-material-liquid-shadow); }
1468
+ .ns-liquid__defs { position: absolute; width: 0; height: 0; overflow: hidden; pointer-events: none; }
1469
+ .ns-material--glass .ns-panel__head { border-bottom-color: var(--ns-material-liquid-rim-low); }
1470
+
1471
+ /* True refraction where url() backdrop filters work (Chromium). */
1472
+ html[data-ns-liquid='refract'] :is(.ns-liquid--md, .ns-liquid:not(.ns-liquid--sm):not(.ns-liquid--lg), .ns-material--glass) {
1473
+ -webkit-backdrop-filter: var(--ns-liquid-filter, url(#ns-liquid-md)) saturate(1.25);
1474
+ backdrop-filter: var(--ns-liquid-filter, url(#ns-liquid-md)) saturate(1.25);
1475
+ }
1476
+ html[data-ns-liquid='refract'] :is(.ns-liquid--sm, .ns-depth-1.ns-material--glass, .ns-button--glass.ns-button--secondary, .ns-button--glass.ns-button--ghost:hover:not(:disabled), .ns-tabs--glass .ns-tabs__list, .ns-toast.ns-material--glass, .ns-tooltip.ns-material--glass) {
1477
+ -webkit-backdrop-filter: var(--ns-liquid-filter, url(#ns-liquid-sm)) saturate(1.25);
1478
+ backdrop-filter: var(--ns-liquid-filter, url(#ns-liquid-sm)) saturate(1.25);
1479
+ }
1480
+ html[data-ns-liquid='refract'] :is(.ns-liquid--lg, .ns-depth-3.ns-material--glass, .ns-dialog.ns-material--glass, .ns-sheet.ns-material--glass) {
1481
+ -webkit-backdrop-filter: var(--ns-liquid-filter, url(#ns-liquid-lg)) blur(2px) saturate(1.25);
1482
+ backdrop-filter: var(--ns-liquid-filter, url(#ns-liquid-lg)) blur(2px) saturate(1.25);
1483
+ }
1484
+ .ns-tabs--glass .ns-tabs__indicator {
1485
+ background: var(--ns-material-liquid-highlight), linear-gradient(var(--ns-material-spotlight), var(--ns-material-spotlight)), var(--ns-material-glass-fill);
1486
+ box-shadow: inset 0 1px 0 var(--ns-material-liquid-rim), inset 0 0 0 0.5px var(--ns-material-liquid-rim-low), 0 6px 16px -8px var(--ns-material-glow);
1487
+ }
1488
+
1489
+ /* ------------------------------------------------------ icon-led controls */
1490
+
1491
+ .ns-reveal-label {
1492
+ display: inline-grid;
1493
+ grid-template-columns: 1fr;
1494
+ min-width: 0;
1495
+ transition: grid-template-columns var(--ns-motion-duration-layout) var(--ns-motion-spring-layout),
1496
+ opacity var(--ns-motion-duration-320) var(--ns-motion-easing-hover);
1497
+ }
1498
+ .ns-reveal-label__inner { min-width: 0; overflow: hidden; }
1499
+ /* Icon-first expand (IconButton expand and every other host) lives in the
1500
+ precision layer at the end of this file. */
1501
+
1502
+ .ns-toolbar { display: inline-flex; align-items: center; gap: var(--ns-space-2); padding: var(--ns-space-4); border-radius: var(--ns-radius-glass-bar); }
1503
+ .ns-toolbar--vertical { flex-direction: column; align-items: stretch; }
1504
+ .ns-toolbar.ns-liquid { --ns-liquid-radius: var(--ns-radius-glass-bar); }
1505
+ .ns-toolbar .ns-toolbar__item { border-radius: var(--ns-button-radius); }
1506
+ .ns-toolbar .ns-toolbar__item.ns-button--rounded { --ns-button-radius: var(--ns-radius-glass-inner); }
1507
+
1508
+ /* Sidebar: labels show in full; they wrap rather than end in an ellipsis. */
1509
+ .ns-sidebar__text { flex: 1; overflow: visible; text-overflow: clip; white-space: normal; overflow-wrap: anywhere; }
1510
+ .ns-sidebar__item { min-height: var(--ns-size-control-sm); height: auto; }
1511
+ .ns-sidebar--collapsed { width: auto; min-width: 56px; }
1512
+ .ns-sidebar--collapsed .ns-sidebar__item { gap: 0; }
1513
+ .ns-sidebar--collapsed .ns-sidebar__icon { width: var(--ns-size-icon-sm); justify-content: center; }
1514
+ .ns-sidebar--collapsed .ns-sidebar__text { flex: 0 1 auto; grid-template-columns: 0fr; opacity: 0; }
1515
+ .ns-sidebar--collapsed .ns-sidebar__text .ns-reveal-label__inner { white-space: nowrap; transition: padding var(--ns-motion-duration-layout) var(--ns-motion-spring-layout); }
1516
+ .ns-sidebar--collapsed .ns-sidebar__meta,
1517
+ .ns-sidebar--collapsed .ns-sidebar__title { opacity: 0; white-space: nowrap; transition: opacity var(--ns-motion-duration-320) var(--ns-motion-easing-hover); }
1518
+ .ns-sidebar--collapsed:is(:hover, :focus-within) .ns-sidebar__text { grid-template-columns: 1fr; opacity: 1; }
1519
+ .ns-sidebar--collapsed:is(:hover, :focus-within) .ns-sidebar__text .ns-reveal-label__inner { padding-left: var(--ns-space-8); }
1520
+ .ns-sidebar--collapsed:is(:hover, :focus-within) :is(.ns-sidebar__meta, .ns-sidebar__title) { opacity: 1; }
1521
+
1522
+ /* Secondary actions ease in on hover or focus; always there on touch. */
1523
+ .ns-hover-actions {
1524
+ display: inline-flex;
1525
+ gap: var(--ns-space-6);
1526
+ align-items: center;
1527
+ transition: opacity var(--ns-motion-duration-micro) var(--ns-motion-easing-hover), transform var(--ns-motion-duration-layout) var(--ns-motion-easing-glide);
1528
+ }
1529
+ @media (hover: hover) and (pointer: fine) {
1530
+ .ns-hover-actions { opacity: 0; transform: translateX(4px); }
1531
+ :is(.ns-card, .ns-panel, .ns-table__row, .ns-list__item, .ns-hover-scope, .ns-study-row):is(:hover, :focus-within) .ns-hover-actions,
1532
+ .ns-hover-actions:focus-within { opacity: 1; transform: none; }
1533
+ }
1534
+
1535
+ /* --------------------------------------------------------------- flows */
1536
+
1537
+ .ns-flow { display: flex; flex-direction: column; gap: var(--ns-space-24); }
1538
+ .ns-flow__head { display: flex; flex-direction: column; gap: var(--ns-space-12); }
1539
+ .ns-flow__steps { display: flex; flex-wrap: wrap; gap: var(--ns-space-4); margin: 0; padding: 0; list-style: none; }
1540
+ .ns-flow__step {
1541
+ display: inline-flex;
1542
+ align-items: center;
1543
+ gap: var(--ns-space-8);
1544
+ height: var(--ns-size-control-md);
1545
+ padding: 0 var(--ns-space-12) 0 var(--ns-space-6);
1546
+ border: 0;
1547
+ border-radius: var(--ns-radius-full);
1548
+ background: transparent;
1549
+ color: var(--ns-color-text-3);
1550
+ font: inherit;
1551
+ font-weight: var(--ns-font-weight-medium);
1552
+ cursor: pointer;
1553
+ transition: background-color var(--ns-motion-duration-micro) var(--ns-motion-easing-hover), color var(--ns-motion-duration-micro) var(--ns-motion-easing-hover);
1554
+ }
1555
+ .ns-flow__step:hover:not(:disabled) { background: var(--ns-color-surface-2); color: var(--ns-color-text-1); }
1556
+ .ns-flow__step:disabled { cursor: default; }
1557
+ .ns-flow__step:focus-visible { outline: 2px solid var(--ns-color-focus); outline-offset: 2px; }
1558
+ .ns-flow__item[data-state='complete'] .ns-flow__step { color: var(--ns-color-text-2); }
1559
+ .ns-flow__item[data-state='current'] .ns-flow__step { color: var(--ns-color-text-1); background: var(--ns-color-surface-2); }
1560
+ .ns-flow__mark {
1561
+ display: inline-grid;
1562
+ place-items: center;
1563
+ width: 20px;
1564
+ height: 20px;
1565
+ flex: none;
1566
+ border-radius: var(--ns-radius-full);
1567
+ background: var(--ns-color-surface-3);
1568
+ color: var(--ns-color-text-2);
1569
+ font-family: var(--ns-font-family-mono);
1570
+ font-size: var(--ns-font-size-11);
1571
+ font-variant-numeric: var(--ns-font-numeric-figures);
1572
+ transition: background-color var(--ns-motion-duration-320) var(--ns-motion-easing-glide), color var(--ns-motion-duration-320) var(--ns-motion-easing-glide),
1573
+ transform var(--ns-motion-duration-layout) var(--ns-motion-spring-release);
1574
+ }
1575
+ .ns-flow__mark svg { width: 12px; height: 12px; }
1576
+ .ns-flow__item[data-state='complete'] .ns-flow__mark { background: var(--ns-color-signal-wash); color: var(--ns-color-signal); }
1577
+ .ns-flow__item[data-state='current'] .ns-flow__mark { background: var(--ns-button-primary-bg); color: var(--ns-button-primary-fg); transform: scale(1.06); }
1578
+ .ns-flow__rail { position: relative; height: 2px; border-radius: 1px; background: var(--ns-color-surface-3); overflow: hidden; }
1579
+ .ns-flow__fill { position: absolute; inset: 0; transform-origin: 0 50%; background: var(--ns-color-signal); border-radius: inherit; transition: transform var(--ns-motion-duration-layout) var(--ns-motion-spring-layout); }
1580
+ .ns-flow__stage { position: relative; min-width: 0; }
1581
+ .ns-flow__panel { display: flex; flex-direction: column; gap: var(--ns-space-16); animation: ns-step-in var(--ns-motion-duration-layout) var(--ns-motion-easing-glide); }
1582
+ .ns-flow[data-direction='back'] .ns-flow__panel { animation-name: ns-step-in-back; }
1583
+ .ns-flow--vt .ns-flow__panel { animation: none; }
1584
+ .ns-flow__panel-head { display: flex; flex-direction: column; gap: var(--ns-space-4); }
1585
+ .ns-flow__eyebrow { color: var(--ns-color-text-3); font-family: var(--ns-font-family-mono); font-size: var(--ns-font-size-11); font-variant-numeric: var(--ns-font-numeric-figures); }
1586
+ .ns-flow__title { margin: 0; font-size: var(--ns-font-size-18); line-height: var(--ns-font-line-height-18); font-weight: var(--ns-font-weight-semibold); outline: none; }
1587
+ .ns-flow__description { margin: 0; color: var(--ns-color-text-2); }
1588
+ .ns-flow--compact .ns-flow__head { gap: 0; }
1589
+ @keyframes ns-step-in { from { opacity: 0; transform: translateX(20px); } }
1590
+ @keyframes ns-step-in-back { from { opacity: 0; transform: translateX(-20px); } }
1591
+
1592
+ .ns-next-action { display: flex; flex-wrap: wrap; align-items: center; justify-content: flex-end; gap: var(--ns-space-8); }
1593
+ .ns-next-action__hint { margin-right: auto; color: var(--ns-color-text-3); font-size: var(--ns-font-size-12); }
1594
+ .ns-next-action__back svg { width: 14px; height: 14px; }
1595
+ .ns-next-action__back .ns-button__label,
1596
+ .ns-next-action__go .ns-button__label { display: inline-flex; align-items: center; gap: var(--ns-space-6); }
1597
+ .ns-next-action__arrow { display: inline-flex; transition: transform var(--ns-motion-duration-layout) var(--ns-motion-easing-glide); }
1598
+ .ns-next-action__arrow svg { width: 14px; height: 14px; }
1599
+ .ns-next-action__go:is(:hover, :focus-visible) .ns-next-action__arrow { transform: translateX(3px); }
1600
+
1601
+ /* View transitions for steps and tabs: the old view slips away, the new one glides in. */
1602
+ ::view-transition-old(ns-step) { animation: ns-vt-out var(--ns-motion-duration-micro) var(--ns-motion-easing-exit) both; }
1603
+ ::view-transition-new(ns-step) { animation: ns-vt-in var(--ns-motion-duration-layout) var(--ns-motion-easing-glide) both; }
1604
+ ::view-transition-group(ns-step) { animation-duration: var(--ns-motion-duration-layout); animation-timing-function: var(--ns-motion-spring-layout); }
1605
+ html[data-ns-flow-dir='back']::view-transition-new(ns-step) { animation-name: ns-vt-in-back; }
1606
+ html[data-ns-flow-dir='back']::view-transition-old(ns-step) { animation-name: ns-vt-out-back; }
1607
+ @keyframes ns-vt-in { from { opacity: 0; transform: translateX(16px); filter: blur(2px); } }
1608
+ @keyframes ns-vt-in-back { from { opacity: 0; transform: translateX(-16px); filter: blur(2px); } }
1609
+ @keyframes ns-vt-out { to { opacity: 0; transform: translateX(-8px); } }
1610
+ @keyframes ns-vt-out-back { to { opacity: 0; transform: translateX(8px); } }
1611
+
1612
+ /* StudyShell: a sliding pill under the tabs, and the guided flow. */
1613
+ .ns-study-shell__tablist .ns-tabs__indicator { border-radius: var(--ns-radius-control-pill); background: var(--ns-color-surface-3); }
1614
+ .ns-study-shell__tablist .ns-tabs__indicator::after { display: none; }
1615
+ .ns-study-shell__tablist[data-indicator] .ns-study-shell__tab.ns-tabs__trigger[aria-selected='true'] { background: transparent; box-shadow: none; }
1616
+ .ns-study-shell__flow { flex: 1; padding: var(--ns-space-20) var(--ns-space-32) var(--ns-space-32); }
1617
+ .ns-study-shell__next { margin-top: var(--ns-space-8); padding-top: var(--ns-space-16); }
1618
+
1619
+ /* ------------------------------------------------------------- reveal */
1620
+
1621
+ .ns-reveal,
1622
+ .ns-reveal--stagger > * {
1623
+ transition: opacity var(--ns-motion-duration-reveal) var(--ns-motion-easing-glide),
1624
+ transform var(--ns-motion-duration-reveal) var(--ns-motion-easing-glide),
1625
+ filter var(--ns-motion-duration-reveal) var(--ns-motion-easing-glide);
1626
+ transition-delay: var(--ns-reveal-delay, 0ms);
1627
+ }
1628
+ .ns-reveal[data-reveal='pending']:not(.ns-reveal--stagger) { opacity: 0; }
1629
+ .ns-reveal--rise[data-reveal='pending']:not(.ns-reveal--stagger) { transform: translateY(16px); }
1630
+ .ns-reveal--scale[data-reveal='pending']:not(.ns-reveal--stagger) { transform: scale(0.97); filter: blur(4px); }
1631
+ .ns-reveal--stagger[data-reveal='pending'] > * { opacity: 0; transform: translateY(10px); }
1632
+ .ns-reveal--stagger > * { transition-delay: calc(var(--ns-reveal-delay, 0ms) + var(--ns-i, 0) * var(--ns-motion-duration-stagger)); }
1633
+ .ns-reveal--stagger > :nth-child(2) { --ns-i: 1; }
1634
+ .ns-reveal--stagger > :nth-child(3) { --ns-i: 2; }
1635
+ .ns-reveal--stagger > :nth-child(4) { --ns-i: 3; }
1636
+ .ns-reveal--stagger > :nth-child(5) { --ns-i: 4; }
1637
+ .ns-reveal--stagger > :nth-child(6) { --ns-i: 5; }
1638
+ .ns-reveal--stagger > :nth-child(7) { --ns-i: 6; }
1639
+ .ns-reveal--stagger > :nth-child(8) { --ns-i: 7; }
1640
+ .ns-reveal--stagger > :nth-child(n + 9) { --ns-i: 8; }
1641
+
1642
+ /* ---------------------------------------------------------- fallbacks */
1643
+
1644
+ @supports not ((backdrop-filter: blur(1px)) or (-webkit-backdrop-filter: blur(1px))) {
1645
+ .ns-liquid,
1646
+ .ns-material--glass { background: var(--ns-material-liquid-highlight), var(--ns-material-solid); }
1647
+ }
1648
+ @media (prefers-reduced-transparency: reduce) {
1649
+ .ns-liquid,
1650
+ .ns-material--glass,
1651
+ html[data-ns-liquid='refract'] :is(.ns-liquid, .ns-material--glass) {
1652
+ background: var(--ns-material-solid);
1653
+ -webkit-backdrop-filter: none;
1654
+ backdrop-filter: none;
1655
+ }
1656
+ }
1657
+ @media (forced-colors: active) {
1658
+ .ns-liquid,
1659
+ html[data-ns-liquid='refract'] :is(.ns-liquid, .ns-material--glass) {
1660
+ background: Canvas;
1661
+ -webkit-backdrop-filter: none;
1662
+ backdrop-filter: none;
1663
+ border: 1px solid CanvasText;
1664
+ box-shadow: none;
1665
+ }
1666
+ .ns-card,
1667
+ .ns-panel,
1668
+ .ns-surface,
1669
+ .ns-button--secondary { border-color: CanvasText; }
1670
+ .ns-flow__item[data-state='current'] .ns-flow__mark { background: Highlight; color: HighlightText; }
1671
+ .ns-flow__fill { background: Highlight; }
1672
+ .ns-hover-actions { opacity: 1; transform: none; }
1673
+ }
1674
+ @media (prefers-reduced-motion: reduce) {
1675
+ .ns-reveal[data-reveal],
1676
+ .ns-reveal--stagger[data-reveal] > * { opacity: 1 !important; transform: none !important; filter: none !important; }
1677
+ .ns-flow__panel { animation: none !important; }
1678
+ .ns-flow__mark,
1679
+ .ns-next-action__arrow,
1680
+ .ns-hover-actions,
1681
+ .ns-card--interactive { transform: none !important; }
1682
+ ::view-transition-group(*),
1683
+ ::view-transition-old(*),
1684
+ ::view-transition-new(*) { animation: none !important; }
1685
+ }
1686
+
1687
+ /* ==================================================== precision layer
1688
+ Icon-first expand everywhere and tighter glass corners (radius.glass.*). */
1689
+
1690
+ /* ------------------------------------------------------ icon-first expand
1691
+ A host (`ns-expand-host`) shows its icon; its ExpandLabel is collapsed to
1692
+ 0fr and eases to 1fr, so layout measures the whole label (no ellipsis, no
1693
+ width guessing, no jank). Hover, keyboard focus, selection, an open menu
1694
+ and data-expand="always" open it; touch screens always show it. */
1695
+
1696
+ .ns-expand-icon { display: inline-flex; flex: none; align-items: center; justify-content: center; }
1697
+ .ns-button__icon { display: inline-flex; flex: none; }
1698
+ .ns-expand-host { --ns-expand-gap: var(--ns-space-6); }
1699
+ .ns-expand-host .ns-expand {
1700
+ grid-template-columns: 0fr;
1701
+ opacity: 0;
1702
+ transition: grid-template-columns var(--ns-motion-duration-layout) var(--ns-motion-easing-glide),
1703
+ opacity var(--ns-motion-duration-320) var(--ns-motion-easing-hover);
1704
+ }
1705
+ .ns-expand-host .ns-expand__inner {
1706
+ white-space: nowrap;
1707
+ padding-inline: 0;
1708
+ transition: padding var(--ns-motion-duration-layout) var(--ns-motion-easing-glide);
1709
+ }
1710
+ .ns-expand-host:is(:hover, :focus-visible, :has(:focus-visible), [data-expand='always'], [aria-selected='true'], [aria-expanded='true']) .ns-expand { grid-template-columns: 1fr; opacity: 1; }
1711
+ .ns-expand-host:is(:hover, :focus-visible, :has(:focus-visible), [data-expand='always'], [aria-selected='true'], [aria-expanded='true']) .ns-expand__inner { padding-inline: var(--ns-expand-gap) var(--ns-expand-tail, 0px); }
1712
+ .ns-expand-host:is(:hover, :focus-visible, :has(:focus-visible), [data-expand='always'], [aria-selected='true'], [aria-expanded='true']) .ns-expand--end .ns-expand__inner { padding-inline: var(--ns-expand-tail, 0px) var(--ns-expand-gap); }
1713
+ @media (hover: none) {
1714
+ .ns-expand-host .ns-expand { grid-template-columns: 1fr; opacity: 1; }
1715
+ .ns-expand-host .ns-expand__inner { padding-inline: var(--ns-expand-gap) var(--ns-expand-tail, 0px); }
1716
+ .ns-expand-host .ns-expand--end .ns-expand__inner { padding-inline: var(--ns-expand-tail, 0px) var(--ns-expand-gap); }
1717
+ }
1718
+
1719
+ /* Buttons, icon buttons, menu triggers, pagination steps: square while closed. */
1720
+ .ns-button.ns-expand-host {
1721
+ --ns-expand-tail: var(--ns-space-2);
1722
+ gap: 0;
1723
+ min-width: var(--ns-h, var(--ns-size-control-md));
1724
+ padding-inline: calc((var(--ns-h, var(--ns-size-control-md)) - var(--ns-size-icon-sm)) / 2);
1725
+ }
1726
+ .ns-icon-button.ns-expand-host { width: auto; }
1727
+ .ns-button.ns-expand-host .ns-expand-icon { min-width: var(--ns-size-icon-sm); }
1728
+ .ns-button.ns-expand-host .ns-expand-icon svg { width: var(--ns-size-icon-sm); height: var(--ns-size-icon-sm); }
1729
+ .ns-run-cost__button--expand { width: auto; align-self: flex-start; }
1730
+
1731
+ /* Tabs: icon tabs open to their labels; the selected one stays open. */
1732
+ .ns-tabs__trigger--icon { display: inline-flex; align-items: center; gap: var(--ns-space-6); }
1733
+ .ns-tabs__trigger--icon.ns-expand-host { gap: 0; }
1734
+ .ns-tabs__icon { color: var(--ns-color-text-3); transition: color var(--ns-motion-duration-micro) var(--ns-motion-easing-hover); }
1735
+ .ns-tabs__trigger:is(:hover, [aria-selected='true']) .ns-tabs__icon { color: currentColor; }
1736
+
1737
+ /* Breadcrumbs: collapsed crumbs show an icon or an ellipsis and open in full. */
1738
+ .ns-breadcrumbs--collapse li > :is(a, span):not(.ns-breadcrumbs__sep) { display: inline-flex; align-items: center; }
1739
+ .ns-breadcrumbs__more {
1740
+ display: inline-block;
1741
+ overflow: hidden;
1742
+ max-width: 1.25em;
1743
+ transition: max-width var(--ns-motion-duration-layout) var(--ns-motion-easing-glide), opacity var(--ns-motion-duration-micro) var(--ns-motion-easing-hover);
1744
+ }
1745
+ .ns-breadcrumbs li.ns-expand-host { --ns-expand-gap: 0px; }
1746
+ .ns-breadcrumbs li.ns-expand-host:has(.ns-breadcrumbs__icon svg) { --ns-expand-gap: var(--ns-space-4); }
1747
+ .ns-breadcrumbs--collapse:has(:focus-visible) .ns-expand { grid-template-columns: 1fr; opacity: 1; }
1748
+ .ns-breadcrumbs--collapse:has(:focus-visible) .ns-breadcrumbs__more,
1749
+ .ns-expand-host:is(:hover, :has(:focus-visible)) .ns-breadcrumbs__more { max-width: 0; opacity: 0; }
1750
+ .ns-breadcrumbs--collapse:has(:focus-visible) .ns-expand__inner { padding-inline: var(--ns-expand-gap) 0; }
1751
+ @media (hover: none) { .ns-breadcrumbs__more { max-width: 0; opacity: 0; } }
1752
+
1753
+ /* Tags, badges and the study status chip. */
1754
+ .ns-tag.ns-expand-host,
1755
+ .ns-badge.ns-expand-host,
1756
+ .ns-study-status.ns-expand-host { gap: 0; --ns-expand-gap: var(--ns-space-4); }
1757
+ .ns-study-status.ns-expand-host { --ns-expand-gap: var(--ns-space-6); }
1758
+ .ns-badge.ns-expand-host { padding-inline: var(--ns-space-4); }
1759
+ .ns-tag.ns-expand-host .ns-tag__remove { margin-left: var(--ns-space-4); }
1760
+ .ns-tag__icon svg,
1761
+ .ns-badge__icon svg { width: 12px; height: 12px; }
1762
+ .ns-badge__icon { margin-right: var(--ns-space-2); }
1763
+ .ns-badge.ns-expand-host .ns-badge__icon { margin-right: 0; }
1764
+
1765
+ /* Back in a flow: the arrow leads, the word follows on hover and focus. */
1766
+ .ns-next-action__back.ns-expand-host .ns-expand-icon svg { width: 14px; height: 14px; }
1767
+
1768
+ /* Ghost buttons on glass hover with light, not an opaque fill. */
1769
+ :where(.ns-liquid, .ns-material--glass, [data-material='glass']) .ns-button--ghost:not(.ns-button--glass):hover:not(:disabled) { background: var(--ns-material-spotlight); }
1770
+
1771
+ /* ---------------------------------------------------------- glass radii */
1772
+
1773
+ .ns-card.ns-material--glass,
1774
+ .ns-panel.ns-material--glass,
1775
+ .ns-dialog.ns-material--glass,
1776
+ :where(.ns-surface.ns-material--glass) { border-radius: var(--ns-radius-glass-panel); }
1777
+ .ns-sheet--bottom.ns-material--glass { border-radius: var(--ns-radius-glass-panel) var(--ns-radius-glass-panel) 0 0; }
1778
+ .ns-tabs--glass .ns-tabs__list { border-radius: var(--ns-radius-control-pill); }
1779
+ .ns-tabs--glass .ns-tabs__trigger,
1780
+ .ns-tabs--glass .ns-tabs__indicator { border-radius: var(--ns-radius-control-pill); }
1781
+ .ns-button--glass { border-radius: var(--ns-button-radius); }
1782
+
1783
+ /* --------------------------------------------- precision layer fallbacks */
1784
+
1785
+ @media (forced-colors: active) {
1786
+ .ns-expand-host .ns-expand { opacity: 1; }
1787
+ }
1788
+ @media (prefers-reduced-motion: reduce) {
1789
+ .ns-expand-host .ns-expand,
1790
+ .ns-expand-host .ns-expand__inner,
1791
+ .ns-breadcrumbs__more { transition: none !important; }
1792
+ }
1793
+
1794
+ /* ==================================================== shape and texture
1795
+ Every button is a pill (radius.control.pill): a capsule, or a circle when
1796
+ it is square (icon-only, or an icon-first button while its label is
1797
+ closed). `shape="rounded"` (.ns-button--rounded) opts out: radius.control.
1798
+ rounded off glass, radius.glass.control on it. Ends of a pill take a
1799
+ little more padding so the label does not crowd the curve. */
1800
+
1801
+ .ns-button:where(:not(.ns-icon-button, .ns-expand-host, .ns-button--rounded)) { padding-inline: calc(var(--ns-px, var(--ns-space-12)) + var(--ns-space-2)); }
1802
+ .ns-button.ns-button--rounded,
1803
+ .ns-pagination--rounded .ns-button { --ns-button-radius: var(--ns-radius-control-rounded); }
1804
+ :where(.ns-liquid, .ns-material--glass, [data-material='glass']) .ns-button.ns-button--rounded,
1805
+ .ns-button.ns-button--rounded.ns-button--glass { --ns-button-radius: var(--ns-radius-glass-control); }
1806
+ .ns-tabs--rounded.ns-tabs--pill .ns-tabs__list { border-radius: var(--ns-radius-8); }
1807
+ .ns-tabs--rounded.ns-tabs--pill .ns-tabs__trigger,
1808
+ .ns-tabs--rounded.ns-tabs--pill .ns-tabs__indicator { border-radius: var(--ns-radius-6); }
1809
+ .ns-tabs--rounded.ns-tabs--glass .ns-tabs__list { border-radius: var(--ns-radius-glass-bar); }
1810
+ .ns-tabs--rounded.ns-tabs--glass :is(.ns-tabs__trigger, .ns-tabs__indicator) { border-radius: var(--ns-radius-glass-control); }
1811
+
1812
+ /* ------------------------------------------------------ tactile texture
1813
+ A fine brushed micro-texture on every button, under the label: two
1814
+ periods of horizontal lines (3px light, 5px dark, coprime so they never
1815
+ band), a soft highlight across the top and a low inner bevel. It lives in
1816
+ ::after (z-index -1 inside the button's own stacking context), so it never
1817
+ fights the button's background or box-shadow. Per variant: secondary and
1818
+ primary always (primary in its Glacier-tuned signal-* set), ghost only on
1819
+ hover and focus, disabled never. This is the soft finish
1820
+ (finish="soft"); the machined spin finish below and glass's specular
1821
+ switch it off. Per theme through
1822
+ material.texture.*; text on every textured body is gated in
1823
+ tooling/contrast at its lightest and darkest point. */
1824
+
1825
+ .ns-button {
1826
+ --ns-tex-on: 0;
1827
+ --ns-tex-light: var(--ns-material-texture-light);
1828
+ --ns-tex-dark: var(--ns-material-texture-dark);
1829
+ --ns-tex-top: var(--ns-material-texture-top);
1830
+ --ns-tex-hi: var(--ns-material-texture-bevel-hi);
1831
+ --ns-tex-lo: var(--ns-material-texture-bevel-lo);
1832
+ }
1833
+ .ns-button--primary {
1834
+ --ns-tex-light: var(--ns-material-texture-signal-light);
1835
+ --ns-tex-dark: var(--ns-material-texture-signal-dark);
1836
+ --ns-tex-top: var(--ns-material-texture-signal-top);
1837
+ --ns-tex-hi: var(--ns-material-texture-signal-bevel-hi);
1838
+ --ns-tex-lo: var(--ns-material-texture-signal-bevel-lo);
1839
+ }
1840
+ .ns-button::after {
1841
+ content: '';
1842
+ position: absolute;
1843
+ inset: 0;
1844
+ z-index: -1;
1845
+ border-radius: inherit;
1846
+ pointer-events: none;
1847
+ background:
1848
+ linear-gradient(180deg, var(--ns-tex-top), transparent 56%),
1849
+ repeating-linear-gradient(180deg, var(--ns-tex-light) 0 1px, transparent 1px 3px),
1850
+ repeating-linear-gradient(180deg, var(--ns-tex-dark) 0 1px, transparent 1px 5px);
1851
+ box-shadow: inset 0 1px 0 var(--ns-tex-hi), inset 0 -1px 0 var(--ns-tex-lo);
1852
+ opacity: var(--ns-tex-on);
1853
+ transition: opacity var(--ns-motion-duration-micro) var(--ns-motion-easing-hover);
1854
+ }
1855
+ .ns-button:is(.ns-button--secondary, .ns-button--primary) { --ns-tex-on: 1; }
1856
+ .ns-button.ns-button--ghost:is(:hover, :focus-visible, [aria-expanded='true'], [aria-current='page']):not(:disabled, .ns-button--glass) { --ns-tex-on: 1; }
1857
+ .ns-button:disabled,
1858
+ .ns-button.ns-button--glass { --ns-tex-on: 0; }
1859
+ /* Pressed: the light comes from below, so the face reads as pushed in. */
1860
+ .ns-button:active:not(:disabled)::after { box-shadow: inset 0 1px 2px var(--ns-tex-lo), inset 0 -1px 0 var(--ns-tex-hi); }
1861
+ /* ConstellationButton is a button too (effects.css carries its texture). */
1862
+
1863
+ /* --------------------------------------------- shape and texture fallbacks */
1864
+
1865
+ @media (prefers-reduced-transparency: reduce) {
1866
+ .ns-button::after { background: none; }
1867
+ }
1868
+ @media (prefers-contrast: more) {
1869
+ .ns-button::after { display: none; }
1870
+ .ns-button:is(.ns-button--secondary, .ns-button--ghost:hover) { border-color: var(--ns-color-text-2); }
1871
+ }
1872
+ @media (forced-colors: active) {
1873
+ .ns-button::after { display: none; }
1874
+ .ns-button { border: 1px solid ButtonText; }
1875
+ }
1876
+ @media (prefers-reduced-motion: reduce) {
1877
+ .ns-button::after { transition: none; }
1878
+ }
1879
+
1880
+ /* ===================================================== machined spin
1881
+ The default finish of every button, on glass and off it: Button,
1882
+ IconButton, ToolbarItem, Menu.Trigger, pagination, toasts, layer close
1883
+ buttons and the effects ConstellationButton. finish="soft" (or
1884
+ NorthstarProvider buttonFinish="soft", which marks its root with
1885
+ data-button-finish) keeps the soft finish above: tonal fill and tactile
1886
+ texture. tone="silver" is an alias for spin. Glass buttons keep glass.
1887
+
1888
+ ::before is the metal: a conic sweep of seven machined stops under a fine
1889
+ concentric grain, both centred on the button, so an icon-only circle is
1890
+ a turned knob. It sits one pixel past the border, so the bevel ring is
1891
+ flush. ::after is the light band that slides across on hover and focus.
1892
+ While hovered, the sweep turns a few degrees with the pointer
1893
+ (--ns-pointer-x/-y, written by usePointerTracking; @property eases it;
1894
+ without a pointer it holds still). Primary and tone="signal" are
1895
+ Glacier-anodized. Ghost has no metal at rest; a faint wash of it fades in
1896
+ on hover, focus and selection. Disabled is matte and flat. Pressed drops
1897
+ 1px, dims a little and flips the bevel. Colours per theme through
1898
+ material.spin.*, motion through the material.spin scale; ink on the
1899
+ lightest and darkest stop of every body is gated in tooling/contrast. */
1900
+
1901
+ @property --ns-spin-angle { syntax: '<angle>'; inherits: false; initial-value: 200deg; }
1902
+
1903
+ :is(.ns-button, .ns-fx-cbutton):not(.ns-button--glass, [data-finish='soft'], [data-button-finish='soft'] :not([data-finish='spin'])) {
1904
+ --ns-tex-on: 0;
1905
+ --ns-spin-on: 1;
1906
+ --ns-spin-1: var(--ns-material-spin-stop-1);
1907
+ --ns-spin-2: var(--ns-material-spin-stop-2);
1908
+ --ns-spin-3: var(--ns-material-spin-stop-3);
1909
+ --ns-spin-4: var(--ns-material-spin-stop-4);
1910
+ --ns-spin-5: var(--ns-material-spin-stop-5);
1911
+ --ns-spin-6: var(--ns-material-spin-stop-6);
1912
+ --ns-spin-7: var(--ns-material-spin-stop-7);
1913
+ --ns-spin-ink: var(--ns-material-spin-ink);
1914
+ --ns-spin-grain: var(--ns-material-spin-grain-light);
1915
+ --ns-spin-grain-dark: var(--ns-material-spin-grain-dark);
1916
+ border-color: transparent;
1917
+ transition: color var(--ns-motion-duration-micro) var(--ns-motion-easing-hover),
1918
+ box-shadow var(--ns-motion-duration-micro) var(--ns-motion-easing-hover),
1919
+ filter var(--ns-motion-duration-micro) var(--ns-motion-easing-hover),
1920
+ padding var(--ns-motion-duration-layout) var(--ns-motion-spring-layout),
1921
+ transform var(--ns-motion-duration-release) var(--ns-motion-spring-release);
1922
+ }
1923
+ :is(.ns-button, .ns-fx-cbutton):not(.ns-button--glass, [data-finish='soft'], [data-button-finish='soft'] :not([data-finish='spin'])):is(.ns-button--primary, .ns-fx-cbutton--primary, .ns-tone-signal:not(.ns-button--ghost)) {
1924
+ --ns-spin-1: var(--ns-material-spin-signal-stop-1);
1925
+ --ns-spin-2: var(--ns-material-spin-signal-stop-2);
1926
+ --ns-spin-3: var(--ns-material-spin-signal-stop-3);
1927
+ --ns-spin-4: var(--ns-material-spin-signal-stop-4);
1928
+ --ns-spin-5: var(--ns-material-spin-signal-stop-5);
1929
+ --ns-spin-6: var(--ns-material-spin-signal-stop-6);
1930
+ --ns-spin-7: var(--ns-material-spin-signal-stop-7);
1931
+ --ns-spin-ink: var(--ns-material-spin-signal-ink);
1932
+ --ns-spin-grain: var(--ns-material-spin-signal-grain-light);
1933
+ }
1934
+ :is(.ns-button, .ns-fx-cbutton):not(.ns-button--glass, [data-finish='soft'], [data-button-finish='soft'] :not([data-finish='spin'])):not(.ns-button--ghost) {
1935
+ color: var(--ns-spin-ink);
1936
+ text-shadow: 0 1px 0 var(--ns-material-spin-emboss);
1937
+ box-shadow: var(--ns-material-spin-shadow);
1938
+ }
1939
+ :is(.ns-button, .ns-fx-cbutton):not(.ns-button--glass, [data-finish='soft'], [data-button-finish='soft'] :not([data-finish='spin']))::before {
1940
+ content: '';
1941
+ position: absolute;
1942
+ inset: -1px;
1943
+ z-index: -1;
1944
+ border-radius: inherit;
1945
+ pointer-events: none;
1946
+ --ns-spin-angle: var(--ns-material-spin-angle);
1947
+ background:
1948
+ repeating-radial-gradient(circle at 50% 50%, var(--ns-spin-grain-dark) 0 1px, var(--ns-spin-grain) 1px 2px),
1949
+ conic-gradient(from var(--ns-spin-angle) at 50% 50%, var(--ns-spin-1), var(--ns-spin-2) 8%, var(--ns-spin-3) 22%, var(--ns-spin-4) 38%, var(--ns-spin-5) 52%, var(--ns-spin-6) 68%, var(--ns-spin-7) 84%, var(--ns-spin-1));
1950
+ opacity: var(--ns-spin-on);
1951
+ transition: opacity var(--ns-motion-duration-micro) var(--ns-motion-easing-hover),
1952
+ --ns-spin-angle var(--ns-motion-duration-layout) var(--ns-motion-easing-glide);
1953
+ }
1954
+ :is(.ns-button, .ns-fx-cbutton):not(.ns-button--glass, [data-finish='soft'], [data-button-finish='soft'] :not([data-finish='spin']))::after {
1955
+ inset: -1px;
1956
+ box-shadow: none;
1957
+ background: linear-gradient(100deg, transparent 30%, var(--ns-material-spin-sheen) 50%, transparent 70%) 120% 0 / 260% 100% no-repeat;
1958
+ opacity: var(--ns-spin-on);
1959
+ transition: opacity var(--ns-motion-duration-micro) var(--ns-motion-easing-hover),
1960
+ background-position var(--ns-material-spin-sweep) var(--ns-material-spin-sweep-easing);
1961
+ }
1962
+ /* Hover: the band slides across, the metal brightens a touch and the sweep turns with the pointer. */
1963
+ :is(.ns-button, .ns-fx-cbutton):not(.ns-button--glass, [data-finish='soft'], [data-button-finish='soft'] :not([data-finish='spin'])):is(:hover, :focus-visible):not(:disabled)::after { background-position: -20% 0; }
1964
+ :is(.ns-button, .ns-fx-cbutton):not(.ns-button--glass, [data-finish='soft'], [data-button-finish='soft'] :not([data-finish='spin'])):hover:not(:disabled) { filter: brightness(1.04); }
1965
+ :is(.ns-button, .ns-fx-cbutton):not(.ns-button--glass, [data-finish='soft'], [data-button-finish='soft'] :not([data-finish='spin'])):hover:not(:disabled)::before {
1966
+ --ns-spin-angle: calc(var(--ns-material-spin-angle) + var(--ns-pointer-x, 0) * var(--ns-material-spin-turn) / 2 + var(--ns-pointer-y, 0) * var(--ns-material-spin-turn) / 6);
1967
+ }
1968
+ /* Pressed: down a pixel, a little smaller and darker, and the bevel flips. */
1969
+ :is(.ns-button, .ns-fx-cbutton):not(.ns-button--glass, [data-finish='soft'], [data-button-finish='soft'] :not([data-finish='spin'])):active:not(:disabled) {
1970
+ transform: translate(var(--ns-mag-x, 0px), calc(var(--ns-mag-y, 0px) + 1px)) scale(var(--ns-material-spin-press));
1971
+ filter: brightness(0.96);
1972
+ transition-duration: var(--ns-motion-duration-press);
1973
+ transition-timing-function: var(--ns-motion-spring-press);
1974
+ }
1975
+ :is(.ns-button, .ns-fx-cbutton):not(.ns-button--glass, [data-finish='soft'], [data-button-finish='soft'] :not([data-finish='spin'])):not(.ns-button--ghost):active:not(:disabled) { box-shadow: var(--ns-material-spin-shadow-press); }
1976
+ :is(.ns-button, .ns-fx-cbutton):not(.ns-button--glass, [data-finish='soft'], [data-button-finish='soft'] :not([data-finish='spin'])):active:not(:disabled)::after { box-shadow: none; }
1977
+ /* Focus: the Glacier ring (color.focus), 2px, standing 3px off the metal. */
1978
+ :is(.ns-button, .ns-fx-cbutton):not(.ns-button--glass, [data-finish='soft'], [data-button-finish='soft'] :not([data-finish='spin'])):focus-visible { outline: 2px solid var(--ns-color-focus); outline-offset: 3px; }
1979
+ :is(.ns-button, .ns-fx-cbutton):not(.ns-button--glass, [data-finish='soft'], [data-button-finish='soft'] :not([data-finish='spin'])):not(.ns-button--ghost):focus-visible { box-shadow: var(--ns-material-spin-shadow); }
1980
+ /* Ghost: no metal at rest; the faint wash on hover, focus, an open menu and the current page. */
1981
+ :is(.ns-button, .ns-fx-cbutton):not(.ns-button--glass, [data-finish='soft'], [data-button-finish='soft'] :not([data-finish='spin'])).ns-button--ghost { --ns-spin-on: 0; }
1982
+ :is(.ns-button, .ns-fx-cbutton):not(.ns-button--glass, [data-finish='soft'], [data-button-finish='soft'] :not([data-finish='spin'])).ns-button--ghost:is(:hover, :focus-visible, [aria-expanded='true'], [aria-current='page']):not(:disabled) {
1983
+ --ns-spin-on: var(--ns-material-spin-ghost);
1984
+ background: transparent;
1985
+ box-shadow: inset 0 0 0 1px var(--ns-material-spin-ghost-edge);
1986
+ }
1987
+ :is(.ns-button, .ns-fx-cbutton):not(.ns-button--glass, [data-finish='soft'], [data-button-finish='soft'] :not([data-finish='spin'])) .ns-button__check { color: currentColor; }
1988
+ /* Disabled: matte and flat, no grain, sheen or bevel. Loading keeps its metal. */
1989
+ :is(.ns-button, .ns-fx-cbutton):not(.ns-button--glass, [data-finish='soft'], [data-button-finish='soft'] :not([data-finish='spin'])):disabled:not([data-loading]) {
1990
+ --ns-spin-on: 1;
1991
+ color: var(--ns-material-spin-matte-ink);
1992
+ text-shadow: none;
1993
+ box-shadow: inset 0 0 0 1px var(--ns-color-line-2);
1994
+ filter: none;
1995
+ opacity: 1;
1996
+ }
1997
+ :is(.ns-button, .ns-fx-cbutton):not(.ns-button--glass, [data-finish='soft'], [data-button-finish='soft'] :not([data-finish='spin'])):disabled:not([data-loading])::before { background: var(--ns-material-spin-matte); }
1998
+ :is(.ns-button, .ns-fx-cbutton):not(.ns-button--glass, [data-finish='soft'], [data-button-finish='soft'] :not([data-finish='spin'])):disabled:not([data-loading])::after { display: none; }
1999
+ :is(.ns-button, .ns-fx-cbutton):not(.ns-button--glass, [data-finish='soft'], [data-button-finish='soft'] :not([data-finish='spin'])).ns-button--ghost:disabled:not([data-loading]) { --ns-spin-on: 0; color: var(--ns-color-text-3); }
2000
+
2001
+ /* ----------------------------------------------- machined spin fallbacks */
2002
+
2003
+ @media (prefers-reduced-transparency: reduce) {
2004
+ /* No grain: the sweep alone. */
2005
+ :is(.ns-button, .ns-fx-cbutton):not(.ns-button--glass, [data-finish='soft'], [data-button-finish='soft'] :not([data-finish='spin'])) { --ns-spin-grain: transparent; --ns-spin-grain-dark: transparent; }
2006
+ }
2007
+ @media (prefers-contrast: more) {
2008
+ /* A flat fill at the lightest stop, outlined in ink. */
2009
+ :is(.ns-button, .ns-fx-cbutton):not(.ns-button--glass, [data-finish='soft'], [data-button-finish='soft'] :not([data-finish='spin']))::before { background: var(--ns-spin-2); }
2010
+ :is(.ns-button, .ns-fx-cbutton):not(.ns-button--glass, [data-finish='soft'], [data-button-finish='soft'] :not([data-finish='spin']))::after { display: none; }
2011
+ :is(.ns-button, .ns-fx-cbutton):not(.ns-button--glass, [data-finish='soft'], [data-button-finish='soft'] :not([data-finish='spin'])):not(.ns-button--ghost) { box-shadow: 0 0 0 1px var(--ns-spin-ink); text-shadow: none; }
2012
+ }
2013
+ @media (forced-colors: active) {
2014
+ :is(.ns-button, .ns-fx-cbutton):not(.ns-button--glass, [data-finish='soft'], [data-button-finish='soft'] :not([data-finish='spin']))::before,
2015
+ :is(.ns-button, .ns-fx-cbutton):not(.ns-button--glass, [data-finish='soft'], [data-button-finish='soft'] :not([data-finish='spin']))::after { display: none; }
2016
+ :is(.ns-button, .ns-fx-cbutton):not(.ns-button--glass, [data-finish='soft'], [data-button-finish='soft'] :not([data-finish='spin'])) {
2017
+ background: ButtonFace;
2018
+ color: ButtonText;
2019
+ border: 1px solid ButtonText;
2020
+ box-shadow: none;
2021
+ text-shadow: none;
2022
+ filter: none;
2023
+ }
2024
+ :is(.ns-button, .ns-fx-cbutton):not(.ns-button--glass, [data-finish='soft'], [data-button-finish='soft'] :not([data-finish='spin'])):disabled,
2025
+ :is(.ns-button, .ns-fx-cbutton):not(.ns-button--glass, [data-finish='soft'], [data-button-finish='soft'] :not([data-finish='spin'])):disabled:not([data-loading]) { background: ButtonFace; color: GrayText; border-color: GrayText; box-shadow: none; }
2026
+ :is(.ns-button, .ns-fx-cbutton):not(.ns-button--glass, [data-finish='soft'], [data-button-finish='soft'] :not([data-finish='spin'])):focus-visible { outline-color: Highlight; }
2027
+ }
2028
+ @media (prefers-reduced-motion: reduce) {
2029
+ /* No sliding band and no turning sweep; the press holds still too. */
2030
+ :is(.ns-button, .ns-fx-cbutton):not(.ns-button--glass, [data-finish='soft'], [data-button-finish='soft'] :not([data-finish='spin']))::after { display: none; }
2031
+ :is(.ns-button, .ns-fx-cbutton):not(.ns-button--glass, [data-finish='soft'], [data-button-finish='soft'] :not([data-finish='spin'])):hover:not(:disabled)::before { --ns-spin-angle: var(--ns-material-spin-angle); }
2032
+ :is(.ns-button, .ns-fx-cbutton):not(.ns-button--glass, [data-finish='soft'], [data-button-finish='soft'] :not([data-finish='spin']))::before { transition: none; }
2033
+ }