gbs-add-block 2.1.0 → 2.3.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 (129) hide show
  1. package/.gbs/skills/gbs-components/SKILL.md +190 -134
  2. package/.gbs/skills/gbs-components/references/install.md +25 -3
  3. package/.gbs/skills/gbs-components/references/styling.md +246 -207
  4. package/CHANGELOG.md +74 -0
  5. package/README.md +154 -23
  6. package/index.cjs +212 -3
  7. package/package.json +41 -10
  8. package/schema/passport-v1.schema.json +204 -0
  9. package/source/beta-components/accordion/passport.json +259 -0
  10. package/source/beta-components/accordion/styles.css +207 -208
  11. package/source/beta-components/alert/passport.json +250 -0
  12. package/source/beta-components/alert/styles.css +154 -155
  13. package/source/beta-components/avatar/passport.json +294 -0
  14. package/source/beta-components/avatar/styles.css +225 -226
  15. package/source/beta-components/badge/passport.json +332 -0
  16. package/source/beta-components/badge/styles.css +203 -204
  17. package/source/beta-components/breadcrumb/passport.json +243 -0
  18. package/source/beta-components/breadcrumb/styles.css +138 -140
  19. package/source/beta-components/button/passport.json +402 -0
  20. package/source/beta-components/button/passport.manual.json +31 -0
  21. package/source/beta-components/button/styles.css +232 -234
  22. package/source/beta-components/card/passport.json +337 -0
  23. package/source/beta-components/card/styles.css +230 -232
  24. package/source/beta-components/checkbox/passport.json +456 -0
  25. package/source/beta-components/checkbox/styles.css +211 -213
  26. package/source/beta-components/combobox/passport.json +456 -0
  27. package/source/beta-components/combobox/styles.css +419 -417
  28. package/source/beta-components/data-grid/agent/coerce.ts +368 -0
  29. package/source/beta-components/data-grid/agent/contract.ts +410 -0
  30. package/source/beta-components/data-grid/agent/dataset.ts +92 -0
  31. package/source/beta-components/data-grid/agent/engine.ts +470 -0
  32. package/source/beta-components/data-grid/agent/executors.ts +155 -0
  33. package/source/beta-components/data-grid/agent/index.ts +79 -0
  34. package/source/beta-components/data-grid/agent/intent.ts +324 -0
  35. package/source/beta-components/data-grid/agent/operations.ts +335 -0
  36. package/source/beta-components/data-grid/agent/validate.ts +630 -0
  37. package/source/beta-components/data-grid/agent/webmcp.ts +107 -0
  38. package/source/beta-components/data-grid/index.ts +14 -7
  39. package/source/beta-components/data-grid/passport.json +1051 -0
  40. package/source/beta-components/data-grid/passport.manual.json +255 -0
  41. package/source/beta-components/data-grid/react/AskGrid.tsx +164 -0
  42. package/source/beta-components/data-grid/react/DataGrid.tsx +39 -0
  43. package/source/beta-components/data-grid/styles.css +874 -716
  44. package/source/beta-components/date-picker/passport.json +407 -0
  45. package/source/beta-components/date-picker/styles.css +445 -446
  46. package/source/beta-components/dialog/passport.json +344 -0
  47. package/source/beta-components/dialog/styles.css +280 -279
  48. package/source/beta-components/file-uploader/passport.json +518 -0
  49. package/source/beta-components/file-uploader/styles.css +394 -396
  50. package/source/beta-components/input/passport.json +536 -0
  51. package/source/beta-components/input/styles.css +295 -297
  52. package/source/beta-components/menu/passport.json +322 -0
  53. package/source/beta-components/menu/styles.css +224 -223
  54. package/source/beta-components/modal/passport.json +289 -0
  55. package/source/beta-components/modal/styles.css +241 -240
  56. package/source/beta-components/number-input/passport.json +541 -0
  57. package/source/beta-components/number-input/styles.css +230 -231
  58. package/source/beta-components/popover/passport.json +238 -0
  59. package/source/beta-components/popover/styles.css +148 -147
  60. package/source/beta-components/progress/passport.json +270 -0
  61. package/source/beta-components/progress/styles.css +200 -201
  62. package/source/beta-components/radio-group/passport.json +477 -0
  63. package/source/beta-components/radio-group/styles.css +269 -270
  64. package/source/beta-components/shared/core/agent/adapter.ts +65 -0
  65. package/source/beta-components/shared/core/agent/history.ts +120 -0
  66. package/source/beta-components/shared/core/agent/index.ts +46 -0
  67. package/source/beta-components/shared/core/agent/numbers.ts +217 -0
  68. package/source/beta-components/shared/core/agent/schema.ts +180 -0
  69. package/source/beta-components/shared/core/agent/types.ts +169 -0
  70. package/source/beta-components/shared/core/agent/webmcp.ts +328 -0
  71. package/source/beta-components/shared/index.ts +9 -0
  72. package/source/beta-components/shared/react/GramproAIProvider.tsx +50 -0
  73. package/source/beta-components/shared/react/useAskAgent.ts +217 -0
  74. package/source/beta-components/shared/styles.css +79 -0
  75. package/source/beta-components/shared/version.json +4 -4
  76. package/source/beta-components/shared/version.ts +6 -6
  77. package/source/beta-components/skeleton/passport.json +251 -0
  78. package/source/beta-components/skeleton/styles.css +185 -187
  79. package/source/beta-components/spinner/passport.json +245 -0
  80. package/source/beta-components/spinner/styles.css +173 -174
  81. package/source/beta-components/switch/passport.json +421 -0
  82. package/source/beta-components/switch/styles.css +227 -229
  83. package/source/beta-components/tabs/passport.json +315 -0
  84. package/source/beta-components/tabs/styles.css +263 -264
  85. package/source/beta-components/textarea/passport.json +382 -0
  86. package/source/beta-components/textarea/styles.css +158 -160
  87. package/source/beta-components/toaster/passport.json +221 -0
  88. package/source/beta-components/toaster/styles.css +282 -282
  89. package/source/beta-components/tooltip/passport.json +170 -0
  90. package/source/beta-components/tooltip/styles.css +71 -73
  91. package/tools/env.cjs +61 -0
  92. package/tools/passport/cli.cjs +79 -0
  93. package/tools/passport/extract.cjs +493 -0
  94. package/tools/passport/index.cjs +185 -0
  95. package/tools/passport/merge.cjs +131 -0
  96. package/tools/passport/policy.cjs +65 -0
  97. package/tools/passport/validate.cjs +277 -0
  98. package/tools/ts-require.cjs +79 -0
  99. package/source/beta-components/accordion/__tests__/core.test.ts +0 -58
  100. package/source/beta-components/alert/__tests__/core.test.ts +0 -17
  101. package/source/beta-components/avatar/__tests__/core.test.ts +0 -88
  102. package/source/beta-components/badge/__tests__/core.test.ts +0 -46
  103. package/source/beta-components/breadcrumb/__tests__/core.test.ts +0 -58
  104. package/source/beta-components/button/__tests__/core.test.ts +0 -31
  105. package/source/beta-components/card/__tests__/core.test.ts +0 -57
  106. package/source/beta-components/checkbox/__tests__/core.test.ts +0 -40
  107. package/source/beta-components/combobox/__tests__/core.test.ts +0 -134
  108. package/source/beta-components/data-grid/__tests__/core.test.ts +0 -356
  109. package/source/beta-components/data-grid/__tests__/export.test.ts +0 -70
  110. package/source/beta-components/data-grid/__tests__/pdf.test.ts +0 -209
  111. package/source/beta-components/date-picker/__tests__/core.test.ts +0 -273
  112. package/source/beta-components/dialog/__tests__/core.test.ts +0 -86
  113. package/source/beta-components/file-uploader/__tests__/core.test.ts +0 -395
  114. package/source/beta-components/input/__tests__/core.test.ts +0 -75
  115. package/source/beta-components/menu/__tests__/core.test.ts +0 -120
  116. package/source/beta-components/modal/__tests__/core.test.ts +0 -55
  117. package/source/beta-components/number-input/__tests__/core.test.ts +0 -151
  118. package/source/beta-components/progress/__tests__/core.test.ts +0 -56
  119. package/source/beta-components/radio-group/__tests__/core.test.ts +0 -64
  120. package/source/beta-components/shared/__tests__/boundaries.test.ts +0 -95
  121. package/source/beta-components/shared/__tests__/core.test.ts +0 -55
  122. package/source/beta-components/shared/__tests__/position.test.ts +0 -143
  123. package/source/beta-components/skeleton/__tests__/core.test.ts +0 -41
  124. package/source/beta-components/spinner/__tests__/core.test.ts +0 -48
  125. package/source/beta-components/switch/__tests__/core.test.ts +0 -64
  126. package/source/beta-components/tabs/__tests__/core.test.ts +0 -51
  127. package/source/beta-components/textarea/__tests__/core.test.ts +0 -38
  128. package/source/beta-components/toaster/__tests__/core.test.ts +0 -256
  129. package/source/beta-components/tooltip/__tests__/core.test.ts +0 -42
@@ -1,264 +1,263 @@
1
- /*
2
- * Tabs styles.
3
- *
4
- * Tokens read the shared --gbs-* variables when they are set on an ancestor
5
- * (set them on :root to theme every component at once) and fall back to the
6
- * same default palette otherwise. Rules live in the `gbs` layer; declare
7
- * where it sits in your global CSS, e.g. `@layer reset, gbs, app,
8
- * utilities;`, and anything in a later layer overrides them.
9
- */
10
-
11
- @layer gbs {
12
- .tb-root {
13
- --tb-bg: var(--gbs-bg, var(--dg-bg, light-dark(#ffffff, #0b0b0e)));
14
- --tb-fg: var(--gbs-fg, var(--dg-fg, light-dark(#18181b, #f4f4f5)));
15
- --tb-muted: var(--gbs-muted, var(--dg-muted, light-dark(#71717a, #a1a1aa)));
16
- /*
17
- * Unselected tabs are darker than ordinary muted text. A tab is a control,
18
- * not a hint, and the strip usually sits on the page's own background
19
- * rather than on a white card — where the shared muted grey only just
20
- * clears 4.5:1, and misses it on anything tinted.
21
- */
22
- --tb-tab-fg: var(--gbs-tab-fg, light-dark(#5b5b64, #a1a1aa));
23
- --tb-border: var(--gbs-border, var(--dg-border, light-dark(#e4e4e7, #27272a)));
24
- --tb-hover: var(--gbs-hover, var(--dg-hover, light-dark(#f4f4f5, #1f1f23)));
25
- --tb-track: var(--gbs-subtle, light-dark(#f4f4f5, #18181b));
26
- --tb-accent: var(--gbs-accent, var(--dg-accent, light-dark(#2563eb, #60a5fa)));
27
- --tb-accent-soft: var(--gbs-accent-soft, var(--dg-accent-soft, light-dark(#eff6ff, #172554)));
28
- --tb-focus: var(--gbs-focus, var(--dg-focus, light-dark(#2563eb, #60a5fa)));
29
- --tb-radius: var(--gbs-radius, var(--dg-radius, 8px));
30
- --tb-font-size: var(--gbs-font-size, var(--dg-font-size, 13px));
31
- --tb-height: 36px;
32
- --tb-px: 12px;
33
- --tb-duration: 200ms;
34
-
35
- color-scheme: inherit;
36
- display: flex;
37
- flex-direction: column;
38
- gap: 12px;
39
- min-width: 0;
40
- font-size: var(--tb-font-size);
41
- line-height: 1.4;
42
- color: var(--tb-fg);
43
- }
44
-
45
- :where(.dark, [data-theme="dark"]) .tb-root {
46
- color-scheme: dark;
47
- }
48
- :where(.light, [data-theme="light"]) .tb-root {
49
- color-scheme: light;
50
- }
51
-
52
- :where(.tb-root) *,
53
- :where(.tb-root) *::before,
54
- :where(.tb-root) *::after {
55
- box-sizing: border-box;
56
- }
57
-
58
- .tb-root[data-size="sm"] {
59
- --tb-height: 30px;
60
- --tb-px: 10px;
61
- --tb-font-size: 12px;
62
- }
63
- .tb-root[data-size="lg"] {
64
- --tb-height: 44px;
65
- --tb-px: 16px;
66
- --tb-font-size: 14px;
67
- }
68
- .tb-root[data-orientation="vertical"] {
69
- flex-direction: row;
70
- gap: 20px;
71
- }
72
-
73
- /* ---------------------------------------------------------------- list */
74
-
75
- .tb-list {
76
- position: relative;
77
- display: flex;
78
- flex: none;
79
- gap: 2px;
80
- overflow-x: auto;
81
- scrollbar-width: none;
82
- }
83
- .tb-root[data-orientation="vertical"] .tb-list {
84
- flex-direction: column;
85
- overflow: visible;
86
- }
87
-
88
- .tb-tab {
89
- position: relative;
90
- z-index: 1;
91
- display: inline-flex;
92
- flex: none;
93
- align-items: center;
94
- justify-content: center;
95
- gap: 6px;
96
- height: var(--tb-height);
97
- padding: 0 var(--tb-px);
98
- border: 0;
99
- border-radius: calc(var(--tb-radius) - 2px);
100
- background: transparent;
101
- color: var(--tb-tab-fg);
102
- font: inherit;
103
- font-weight: 500;
104
- white-space: nowrap;
105
- cursor: pointer;
106
- transition: color 120ms ease;
107
- }
108
- .tb-root[data-orientation="vertical"] .tb-tab {
109
- justify-content: flex-start;
110
- }
111
- .tb-tab:hover:not([aria-disabled="true"]),
112
- .tb-tab[aria-selected="true"] {
113
- color: var(--tb-fg);
114
- }
115
- .tb-tab:focus-visible {
116
- outline: 2px solid var(--tb-focus);
117
- outline-offset: -2px;
118
- }
119
- .tb-tab[aria-disabled="true"] {
120
- opacity: 0.45;
121
- cursor: not-allowed;
122
- }
123
- .tb-icon {
124
- display: inline-flex;
125
- }
126
- .tb-icon > svg {
127
- width: 1.1em;
128
- height: 1.1em;
129
- }
130
- .tb-badge {
131
- min-width: 18px;
132
- padding: 1px 6px;
133
- border-radius: 999px;
134
- background: var(--tb-hover);
135
- color: var(--tb-fg);
136
- font-size: 0.85em;
137
- font-variant-numeric: tabular-nums;
138
- line-height: 1.4;
139
- text-align: center;
140
- }
141
- .tb-tab[aria-selected="true"] .tb-badge {
142
- background: var(--tb-accent-soft);
143
- color: var(--tb-accent);
144
- }
145
-
146
- /* The indicator is measured in JS; it slides between tabs. */
147
- .tb-indicator {
148
- position: absolute;
149
- z-index: 0;
150
- pointer-events: none;
151
- opacity: 0;
152
- transition:
153
- left var(--tb-duration) ease,
154
- top var(--tb-duration) ease,
155
- width var(--tb-duration) ease,
156
- height var(--tb-duration) ease;
157
- }
158
- .tb-list[style*="--tb-indicator-size"] .tb-indicator {
159
- opacity: 1;
160
- }
161
-
162
- /* ---------------------------------------------------------------- line */
163
-
164
- .tb-root[data-variant="line"] .tb-list {
165
- border-bottom: 1px solid var(--tb-border);
166
- }
167
- .tb-root[data-variant="line"] .tb-indicator {
168
- bottom: -1px;
169
- left: var(--tb-indicator-start);
170
- width: var(--tb-indicator-size);
171
- height: 2px;
172
- border-radius: 2px;
173
- background: var(--tb-accent);
174
- }
175
- .tb-root[data-variant="line"][data-orientation="vertical"] .tb-list {
176
- border-bottom: 0;
177
- border-inline-end: 1px solid var(--tb-border);
178
- }
179
- .tb-root[data-variant="line"][data-orientation="vertical"] .tb-indicator {
180
- top: var(--tb-indicator-start);
181
- bottom: auto;
182
- left: auto;
183
- inset-inline-end: -1px;
184
- width: 2px;
185
- height: var(--tb-indicator-size);
186
- }
187
-
188
- /* --------------------------------------------------------------- pills */
189
-
190
- .tb-root[data-variant="pills"] .tb-indicator {
191
- top: 0;
192
- left: var(--tb-indicator-start);
193
- width: var(--tb-indicator-size);
194
- height: 100%;
195
- border-radius: calc(var(--tb-radius) - 2px);
196
- background: var(--tb-accent-soft);
197
- }
198
- .tb-root[data-variant="pills"] .tb-tab[aria-selected="true"] {
199
- color: var(--tb-accent);
200
- }
201
- .tb-root[data-variant="pills"][data-orientation="vertical"] .tb-indicator {
202
- top: var(--tb-indicator-start);
203
- left: 0;
204
- width: 100%;
205
- height: var(--tb-indicator-size);
206
- }
207
-
208
- /* ------------------------------------------------------------ enclosed */
209
-
210
- .tb-root[data-variant="enclosed"] .tb-list {
211
- padding: 3px;
212
- border-radius: var(--tb-radius);
213
- background: var(--tb-track);
214
- }
215
- .tb-root[data-variant="enclosed"] .tb-indicator {
216
- top: 3px;
217
- bottom: 3px;
218
- left: var(--tb-indicator-start);
219
- width: var(--tb-indicator-size);
220
- border-radius: calc(var(--tb-radius) - 2px);
221
- background: var(--tb-bg);
222
- box-shadow: 0 1px 3px light-dark(rgb(0 0 0 / 0.12), rgb(0 0 0 / 0.5));
223
- }
224
- .tb-root[data-variant="enclosed"] .tb-tab {
225
- height: calc(var(--tb-height) - 6px);
226
- }
227
- .tb-root[data-variant="enclosed"][data-orientation="vertical"] .tb-indicator {
228
- top: var(--tb-indicator-start);
229
- bottom: auto;
230
- left: 3px;
231
- right: 3px;
232
- width: auto;
233
- height: var(--tb-indicator-size);
234
- }
235
-
236
- /* Before the indicator is measured (server render), mark the selected tab statically. */
237
- .tb-root[data-variant="line"] .tb-list:not([style*="--tb-indicator-size"]) .tb-tab[aria-selected="true"] {
238
- box-shadow: inset 0 -2px 0 var(--tb-accent);
239
- }
240
-
241
- /* --------------------------------------------------------------- panel */
242
-
243
- .tb-panel {
244
- flex: 1 1 auto;
245
- min-width: 0;
246
- border-radius: 4px;
247
- }
248
- .tb-panel:focus-visible {
249
- outline: 2px solid var(--tb-focus);
250
- outline-offset: 4px;
251
- }
252
-
253
- @media (prefers-reduced-motion: reduce) {
254
- .tb-root {
255
- --tb-duration: 0s;
256
- }
257
- }
258
-
259
- @media (forced-colors: active) {
260
- .tb-indicator {
261
- background: Highlight;
262
- }
263
- }
264
- }
1
+ /*
2
+ * Tabs styles.
3
+ *
4
+ * Tokens read the shared --gbs-* variables when they are set on an ancestor
5
+ * (set them on :root to theme every component at once) and fall back to the
6
+ * same default palette otherwise. Rules are unlayered: they beat a framework
7
+ * reset on specificity, and lose to anything you pass through `className`.
8
+ * With Tailwind v4, import this file after the framework and inside its
9
+ * components layer - see the README.
10
+ */
11
+
12
+ .tb-root {
13
+ --tb-bg: var(--gbs-bg, var(--dg-bg, light-dark(#ffffff, #0b0b0e)));
14
+ --tb-fg: var(--gbs-fg, var(--dg-fg, light-dark(#18181b, #f4f4f5)));
15
+ --tb-muted: var(--gbs-muted, var(--dg-muted, light-dark(#71717a, #a1a1aa)));
16
+ /*
17
+ * Unselected tabs are darker than ordinary muted text. A tab is a control,
18
+ * not a hint, and the strip usually sits on the page's own background
19
+ * rather than on a white card — where the shared muted grey only just
20
+ * clears 4.5:1, and misses it on anything tinted.
21
+ */
22
+ --tb-tab-fg: var(--gbs-tab-fg, light-dark(#5b5b64, #a1a1aa));
23
+ --tb-border: var(--gbs-border, var(--dg-border, light-dark(#e4e4e7, #27272a)));
24
+ --tb-hover: var(--gbs-hover, var(--dg-hover, light-dark(#f4f4f5, #1f1f23)));
25
+ --tb-track: var(--gbs-subtle, light-dark(#f4f4f5, #18181b));
26
+ --tb-accent: var(--gbs-accent, var(--dg-accent, light-dark(#2563eb, #60a5fa)));
27
+ --tb-accent-soft: var(--gbs-accent-soft, var(--dg-accent-soft, light-dark(#eff6ff, #172554)));
28
+ --tb-focus: var(--gbs-focus, var(--dg-focus, light-dark(#2563eb, #60a5fa)));
29
+ --tb-radius: var(--gbs-radius, var(--dg-radius, 8px));
30
+ --tb-font-size: var(--gbs-font-size, var(--dg-font-size, 13px));
31
+ --tb-height: 36px;
32
+ --tb-px: 12px;
33
+ --tb-duration: 200ms;
34
+
35
+ color-scheme: inherit;
36
+ display: flex;
37
+ flex-direction: column;
38
+ gap: 12px;
39
+ min-width: 0;
40
+ font-size: var(--tb-font-size);
41
+ line-height: 1.4;
42
+ color: var(--tb-fg);
43
+ }
44
+
45
+ :where(.dark, [data-theme="dark"]) .tb-root {
46
+ color-scheme: dark;
47
+ }
48
+ :where(.light, [data-theme="light"]) .tb-root {
49
+ color-scheme: light;
50
+ }
51
+
52
+ :where(.tb-root) *,
53
+ :where(.tb-root) *::before,
54
+ :where(.tb-root) *::after {
55
+ box-sizing: border-box;
56
+ }
57
+
58
+ .tb-root[data-size="sm"] {
59
+ --tb-height: 30px;
60
+ --tb-px: 10px;
61
+ --tb-font-size: 12px;
62
+ }
63
+ .tb-root[data-size="lg"] {
64
+ --tb-height: 44px;
65
+ --tb-px: 16px;
66
+ --tb-font-size: 14px;
67
+ }
68
+ .tb-root[data-orientation="vertical"] {
69
+ flex-direction: row;
70
+ gap: 20px;
71
+ }
72
+
73
+ /* ---------------------------------------------------------------- list */
74
+
75
+ .tb-list {
76
+ position: relative;
77
+ display: flex;
78
+ flex: none;
79
+ gap: 2px;
80
+ overflow-x: auto;
81
+ scrollbar-width: none;
82
+ }
83
+ .tb-root[data-orientation="vertical"] .tb-list {
84
+ flex-direction: column;
85
+ overflow: visible;
86
+ }
87
+
88
+ .tb-tab {
89
+ position: relative;
90
+ z-index: 1;
91
+ display: inline-flex;
92
+ flex: none;
93
+ align-items: center;
94
+ justify-content: center;
95
+ gap: 6px;
96
+ height: var(--tb-height);
97
+ padding: 0 var(--tb-px);
98
+ border: 0;
99
+ border-radius: calc(var(--tb-radius) - 2px);
100
+ background: transparent;
101
+ color: var(--tb-tab-fg);
102
+ font: inherit;
103
+ font-weight: 500;
104
+ white-space: nowrap;
105
+ cursor: pointer;
106
+ transition: color 120ms ease;
107
+ }
108
+ .tb-root[data-orientation="vertical"] .tb-tab {
109
+ justify-content: flex-start;
110
+ }
111
+ .tb-tab:hover:not([aria-disabled="true"]),
112
+ .tb-tab[aria-selected="true"] {
113
+ color: var(--tb-fg);
114
+ }
115
+ .tb-tab:focus-visible {
116
+ outline: 2px solid var(--tb-focus);
117
+ outline-offset: -2px;
118
+ }
119
+ .tb-tab[aria-disabled="true"] {
120
+ opacity: 0.45;
121
+ cursor: not-allowed;
122
+ }
123
+ .tb-icon {
124
+ display: inline-flex;
125
+ }
126
+ .tb-icon > svg {
127
+ width: 1.1em;
128
+ height: 1.1em;
129
+ }
130
+ .tb-badge {
131
+ min-width: 18px;
132
+ padding: 1px 6px;
133
+ border-radius: 999px;
134
+ background: var(--tb-hover);
135
+ color: var(--tb-fg);
136
+ font-size: 0.85em;
137
+ font-variant-numeric: tabular-nums;
138
+ line-height: 1.4;
139
+ text-align: center;
140
+ }
141
+ .tb-tab[aria-selected="true"] .tb-badge {
142
+ background: var(--tb-accent-soft);
143
+ color: var(--tb-accent);
144
+ }
145
+
146
+ /* The indicator is measured in JS; it slides between tabs. */
147
+ .tb-indicator {
148
+ position: absolute;
149
+ z-index: 0;
150
+ pointer-events: none;
151
+ opacity: 0;
152
+ transition:
153
+ left var(--tb-duration) ease,
154
+ top var(--tb-duration) ease,
155
+ width var(--tb-duration) ease,
156
+ height var(--tb-duration) ease;
157
+ }
158
+ .tb-list[style*="--tb-indicator-size"] .tb-indicator {
159
+ opacity: 1;
160
+ }
161
+
162
+ /* ---------------------------------------------------------------- line */
163
+
164
+ .tb-root[data-variant="line"] .tb-list {
165
+ border-bottom: 1px solid var(--tb-border);
166
+ }
167
+ .tb-root[data-variant="line"] .tb-indicator {
168
+ bottom: -1px;
169
+ left: var(--tb-indicator-start);
170
+ width: var(--tb-indicator-size);
171
+ height: 2px;
172
+ border-radius: 2px;
173
+ background: var(--tb-accent);
174
+ }
175
+ .tb-root[data-variant="line"][data-orientation="vertical"] .tb-list {
176
+ border-bottom: 0;
177
+ border-inline-end: 1px solid var(--tb-border);
178
+ }
179
+ .tb-root[data-variant="line"][data-orientation="vertical"] .tb-indicator {
180
+ top: var(--tb-indicator-start);
181
+ bottom: auto;
182
+ left: auto;
183
+ inset-inline-end: -1px;
184
+ width: 2px;
185
+ height: var(--tb-indicator-size);
186
+ }
187
+
188
+ /* --------------------------------------------------------------- pills */
189
+
190
+ .tb-root[data-variant="pills"] .tb-indicator {
191
+ top: 0;
192
+ left: var(--tb-indicator-start);
193
+ width: var(--tb-indicator-size);
194
+ height: 100%;
195
+ border-radius: calc(var(--tb-radius) - 2px);
196
+ background: var(--tb-accent-soft);
197
+ }
198
+ .tb-root[data-variant="pills"] .tb-tab[aria-selected="true"] {
199
+ color: var(--tb-accent);
200
+ }
201
+ .tb-root[data-variant="pills"][data-orientation="vertical"] .tb-indicator {
202
+ top: var(--tb-indicator-start);
203
+ left: 0;
204
+ width: 100%;
205
+ height: var(--tb-indicator-size);
206
+ }
207
+
208
+ /* ------------------------------------------------------------ enclosed */
209
+
210
+ .tb-root[data-variant="enclosed"] .tb-list {
211
+ padding: 3px;
212
+ border-radius: var(--tb-radius);
213
+ background: var(--tb-track);
214
+ }
215
+ .tb-root[data-variant="enclosed"] .tb-indicator {
216
+ top: 3px;
217
+ bottom: 3px;
218
+ left: var(--tb-indicator-start);
219
+ width: var(--tb-indicator-size);
220
+ border-radius: calc(var(--tb-radius) - 2px);
221
+ background: var(--tb-bg);
222
+ box-shadow: 0 1px 3px light-dark(rgb(0 0 0 / 0.12), rgb(0 0 0 / 0.5));
223
+ }
224
+ .tb-root[data-variant="enclosed"] .tb-tab {
225
+ height: calc(var(--tb-height) - 6px);
226
+ }
227
+ .tb-root[data-variant="enclosed"][data-orientation="vertical"] .tb-indicator {
228
+ top: var(--tb-indicator-start);
229
+ bottom: auto;
230
+ left: 3px;
231
+ right: 3px;
232
+ width: auto;
233
+ height: var(--tb-indicator-size);
234
+ }
235
+
236
+ /* Before the indicator is measured (server render), mark the selected tab statically. */
237
+ .tb-root[data-variant="line"] .tb-list:not([style*="--tb-indicator-size"]) .tb-tab[aria-selected="true"] {
238
+ box-shadow: inset 0 -2px 0 var(--tb-accent);
239
+ }
240
+
241
+ /* --------------------------------------------------------------- panel */
242
+
243
+ .tb-panel {
244
+ flex: 1 1 auto;
245
+ min-width: 0;
246
+ border-radius: 4px;
247
+ }
248
+ .tb-panel:focus-visible {
249
+ outline: 2px solid var(--tb-focus);
250
+ outline-offset: 4px;
251
+ }
252
+
253
+ @media (prefers-reduced-motion: reduce) {
254
+ .tb-root {
255
+ --tb-duration: 0s;
256
+ }
257
+ }
258
+
259
+ @media (forced-colors: active) {
260
+ .tb-indicator {
261
+ background: Highlight;
262
+ }
263
+ }