@kushagradhawan/kookie-ui 0.1.108 → 0.1.110

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 (79) hide show
  1. package/components.css +187 -133
  2. package/dist/cjs/components/_internal/shell-bottom.d.ts +2 -0
  3. package/dist/cjs/components/_internal/shell-bottom.d.ts.map +1 -1
  4. package/dist/cjs/components/_internal/shell-bottom.js +1 -1
  5. package/dist/cjs/components/_internal/shell-bottom.js.map +3 -3
  6. package/dist/cjs/components/_internal/shell-inspector.d.ts +2 -0
  7. package/dist/cjs/components/_internal/shell-inspector.d.ts.map +1 -1
  8. package/dist/cjs/components/_internal/shell-inspector.js +1 -1
  9. package/dist/cjs/components/_internal/shell-inspector.js.map +3 -3
  10. package/dist/cjs/components/_internal/shell-sidebar.d.ts +2 -0
  11. package/dist/cjs/components/_internal/shell-sidebar.d.ts.map +1 -1
  12. package/dist/cjs/components/_internal/shell-sidebar.js +1 -1
  13. package/dist/cjs/components/_internal/shell-sidebar.js.map +3 -3
  14. package/dist/cjs/components/shell.context.d.ts +13 -0
  15. package/dist/cjs/components/shell.context.d.ts.map +1 -1
  16. package/dist/cjs/components/shell.context.js +1 -1
  17. package/dist/cjs/components/shell.context.js.map +3 -3
  18. package/dist/cjs/components/shell.d.ts +14 -6
  19. package/dist/cjs/components/shell.d.ts.map +1 -1
  20. package/dist/cjs/components/shell.js +1 -1
  21. package/dist/cjs/components/shell.js.map +3 -3
  22. package/dist/cjs/components/sidebar.d.ts.map +1 -1
  23. package/dist/cjs/components/sidebar.js +1 -1
  24. package/dist/cjs/components/sidebar.js.map +3 -3
  25. package/dist/cjs/components/sidebar.props.d.ts +1 -1
  26. package/dist/cjs/components/sidebar.props.js +1 -1
  27. package/dist/cjs/components/sidebar.props.js.map +2 -2
  28. package/dist/esm/components/_internal/shell-bottom.d.ts +2 -0
  29. package/dist/esm/components/_internal/shell-bottom.d.ts.map +1 -1
  30. package/dist/esm/components/_internal/shell-bottom.js +1 -1
  31. package/dist/esm/components/_internal/shell-bottom.js.map +3 -3
  32. package/dist/esm/components/_internal/shell-inspector.d.ts +2 -0
  33. package/dist/esm/components/_internal/shell-inspector.d.ts.map +1 -1
  34. package/dist/esm/components/_internal/shell-inspector.js +1 -1
  35. package/dist/esm/components/_internal/shell-inspector.js.map +3 -3
  36. package/dist/esm/components/_internal/shell-sidebar.d.ts +2 -0
  37. package/dist/esm/components/_internal/shell-sidebar.d.ts.map +1 -1
  38. package/dist/esm/components/_internal/shell-sidebar.js +1 -1
  39. package/dist/esm/components/_internal/shell-sidebar.js.map +3 -3
  40. package/dist/esm/components/shell.context.d.ts +13 -0
  41. package/dist/esm/components/shell.context.d.ts.map +1 -1
  42. package/dist/esm/components/shell.context.js +1 -1
  43. package/dist/esm/components/shell.context.js.map +3 -3
  44. package/dist/esm/components/shell.d.ts +14 -6
  45. package/dist/esm/components/shell.d.ts.map +1 -1
  46. package/dist/esm/components/shell.js +1 -1
  47. package/dist/esm/components/shell.js.map +3 -3
  48. package/dist/esm/components/sidebar.d.ts.map +1 -1
  49. package/dist/esm/components/sidebar.js +1 -1
  50. package/dist/esm/components/sidebar.js.map +3 -3
  51. package/dist/esm/components/sidebar.props.d.ts +1 -1
  52. package/dist/esm/components/sidebar.props.js +1 -1
  53. package/dist/esm/components/sidebar.props.js.map +2 -2
  54. package/package.json +1 -1
  55. package/schemas/base-button.json +1 -1
  56. package/schemas/button.json +1 -1
  57. package/schemas/icon-button.json +1 -1
  58. package/schemas/index.json +6 -6
  59. package/schemas/toggle-button.json +1 -1
  60. package/schemas/toggle-icon-button.json +1 -1
  61. package/src/components/_internal/base-button.css +6 -32
  62. package/src/components/_internal/base-card.css +0 -3
  63. package/src/components/_internal/base-checkbox.css +0 -2
  64. package/src/components/_internal/base-radio.css +0 -2
  65. package/src/components/_internal/shell-bottom.tsx +15 -1
  66. package/src/components/_internal/shell-inspector.tsx +15 -1
  67. package/src/components/_internal/shell-sidebar.tsx +15 -1
  68. package/src/components/avatar.css +0 -1
  69. package/src/components/segmented-control.css +37 -37
  70. package/src/components/select.css +0 -2
  71. package/src/components/shell.context.tsx +14 -0
  72. package/src/components/shell.css +51 -28
  73. package/src/components/shell.tsx +150 -81
  74. package/src/components/sidebar.css +110 -6
  75. package/src/components/sidebar.props.tsx +1 -1
  76. package/src/components/sidebar.tsx +45 -2
  77. package/src/components/text-area.css +0 -1
  78. package/src/components/text-field.css +0 -1
  79. package/styles.css +187 -133
@@ -160,7 +160,6 @@
160
160
 
161
161
  &:where(:checked, [data-state='checked'])::before {
162
162
  background-color: var(--accent-3);
163
- box-shadow: var(--shadow-1);
164
163
 
165
164
  /* Theme-level translucent override */
166
165
  :where([data-panel-background='translucent'], [data-material='translucent']) & {
@@ -191,7 +190,6 @@
191
190
 
192
191
  &::before {
193
192
  background-color: var(--accent-3);
194
- box-shadow: var(--shadow-1);
195
193
 
196
194
  /* Theme-level translucent override for active */
197
195
  :where([data-panel-background='translucent'], [data-material='translucent']) & {
@@ -2,7 +2,7 @@ import * as React from 'react';
2
2
  import classNames from 'classnames';
3
3
  import * as Sheet from '../sheet.js';
4
4
  import { VisuallyHidden } from '../visually-hidden.js';
5
- import { useShell } from '../shell.context.js';
5
+ import { useShell, useInset } from '../shell.context.js';
6
6
  import { useResponsivePresentation, useResponsiveInitialState } from '../shell.hooks.js';
7
7
  import { PaneResizeContext } from './shell-resize.js';
8
8
  import { BottomHandle, PaneHandle } from './shell-handles.js';
@@ -23,6 +23,8 @@ type BottomPublicProps = PaneBaseProps &
23
23
  onSizeChange?: (size: number, meta: BottomSizeChangeMeta) => void;
24
24
  sizeUpdate?: 'throttle' | 'debounce';
25
25
  sizeUpdateMs?: number;
26
+ /** When true, adds margin and triggers gray backdrop on Shell. */
27
+ inset?: boolean;
26
28
  };
27
29
 
28
30
  type BottomComponent = React.ForwardRefExoticComponent<BottomPublicProps & React.RefAttributes<HTMLDivElement>> & { Handle: typeof BottomHandle };
@@ -39,6 +41,7 @@ const BOTTOM_DOM_PROP_KEYS = [
39
41
  'sizeUpdate',
40
42
  'sizeUpdateMs',
41
43
  'style',
44
+ 'inset',
42
45
  ] as const satisfies readonly (keyof BottomPublicProps)[];
43
46
 
44
47
  export const Bottom = React.forwardRef<HTMLDivElement, BottomPublicProps>((initialProps, ref) => {
@@ -70,9 +73,19 @@ export const Bottom = React.forwardRef<HTMLDivElement, BottomPublicProps>((initi
70
73
  onSizeChange,
71
74
  sizeUpdate,
72
75
  sizeUpdateMs = 50,
76
+ inset,
73
77
  } = initialProps;
74
78
  const bottomDomProps = extractPaneDomProps(initialProps, BOTTOM_DOM_PROP_KEYS);
75
79
  const shell = useShell();
80
+ const { registerInset, unregisterInset } = useInset();
81
+
82
+ // Register/unregister inset
83
+ React.useEffect(() => {
84
+ if (inset) {
85
+ registerInset('bottom');
86
+ return () => unregisterInset('bottom');
87
+ }
88
+ }, [inset, registerInset, unregisterInset]);
76
89
  const resolvedPresentation = useResponsivePresentation(presentation);
77
90
  const isOverlay = resolvedPresentation === 'overlay';
78
91
  const isStacked = resolvedPresentation === 'stacked';
@@ -375,6 +388,7 @@ export const Bottom = React.forwardRef<HTMLDivElement, BottomPublicProps>((initi
375
388
  data-peek={shell.peekTarget === 'bottom' || undefined}
376
389
  data-presentation={shell.currentBreakpointReady ? resolvedPresentation : undefined}
377
390
  data-open={(shell.currentBreakpointReady && isStacked && isExpanded) || undefined}
391
+ data-inset={inset || undefined}
378
392
  style={{
379
393
  ...style,
380
394
  ['--bottom-size' as any]: `${expandedSize}px`,
@@ -2,7 +2,7 @@ import * as React from 'react';
2
2
  import classNames from 'classnames';
3
3
  import * as Sheet from '../sheet.js';
4
4
  import { VisuallyHidden } from '../visually-hidden.js';
5
- import { useShell } from '../shell.context.js';
5
+ import { useShell, useInset } from '../shell.context.js';
6
6
  import { useResponsivePresentation, useResponsiveInitialState } from '../shell.hooks.js';
7
7
  import { PaneResizeContext } from './shell-resize.js';
8
8
  import { InspectorHandle, PaneHandle } from './shell-handles.js';
@@ -23,6 +23,8 @@ type InspectorPublicProps = PaneBaseProps &
23
23
  onSizeChange?: (size: number, meta: InspectorSizeChangeMeta) => void;
24
24
  sizeUpdate?: 'throttle' | 'debounce';
25
25
  sizeUpdateMs?: number;
26
+ /** When true, adds margin and triggers gray backdrop on Shell. */
27
+ inset?: boolean;
26
28
  };
27
29
 
28
30
  type InspectorComponent = React.ForwardRefExoticComponent<InspectorPublicProps & React.RefAttributes<HTMLDivElement>> & { Handle: typeof InspectorHandle };
@@ -39,6 +41,7 @@ const INSPECTOR_DOM_PROP_KEYS = [
39
41
  'sizeUpdate',
40
42
  'sizeUpdateMs',
41
43
  'style',
44
+ 'inset',
42
45
  ] as const satisfies readonly (keyof InspectorPublicProps)[];
43
46
 
44
47
  export const Inspector = React.forwardRef<HTMLDivElement, InspectorPublicProps>((initialProps, ref) => {
@@ -70,9 +73,19 @@ export const Inspector = React.forwardRef<HTMLDivElement, InspectorPublicProps>(
70
73
  sizeUpdateMs = 50,
71
74
  size,
72
75
  defaultSize,
76
+ inset,
73
77
  } = initialProps;
74
78
  const inspectorDomProps = extractPaneDomProps(initialProps, INSPECTOR_DOM_PROP_KEYS);
75
79
  const shell = useShell();
80
+ const { registerInset, unregisterInset } = useInset();
81
+
82
+ // Register/unregister inset
83
+ React.useEffect(() => {
84
+ if (inset) {
85
+ registerInset('inspector');
86
+ return () => unregisterInset('inspector');
87
+ }
88
+ }, [inset, registerInset, unregisterInset]);
76
89
  const resolvedPresentation = useResponsivePresentation(presentation);
77
90
  const isOverlay = resolvedPresentation === 'overlay';
78
91
  const isStacked = resolvedPresentation === 'stacked';
@@ -377,6 +390,7 @@ export const Inspector = React.forwardRef<HTMLDivElement, InspectorPublicProps>(
377
390
  data-peek={shell.peekTarget === 'inspector' || undefined}
378
391
  data-presentation={shell.currentBreakpointReady ? resolvedPresentation : undefined}
379
392
  data-open={(shell.currentBreakpointReady && isStacked && isExpanded) || undefined}
393
+ data-inset={inset || undefined}
380
394
  style={{
381
395
  ...style,
382
396
  ['--inspector-size' as any]: `${expandedSize}px`,
@@ -2,7 +2,7 @@ import * as React from 'react';
2
2
  import classNames from 'classnames';
3
3
  import * as Sheet from '../sheet.js';
4
4
  import { VisuallyHidden } from '../visually-hidden.js';
5
- import { useShell } from '../shell.context.js';
5
+ import { useShell, useInset } from '../shell.context.js';
6
6
  import { useResponsivePresentation, useResponsiveInitialState } from '../shell.hooks.js';
7
7
  import { PaneResizeContext } from './shell-resize.js';
8
8
  import { extractPaneDomProps } from './shell-prop-helpers.js';
@@ -30,6 +30,8 @@ type SidebarPublicProps = Omit<SidebarPaneProps, 'mode' | 'defaultMode' | 'onMod
30
30
  onSizeChange?: (size: number, meta: { reason: 'init' | 'resize' | 'controlled' }) => void;
31
31
  sizeUpdate?: 'throttle' | 'debounce';
32
32
  sizeUpdateMs?: number;
33
+ /** When true, adds margin and triggers gray backdrop on Shell. */
34
+ inset?: boolean;
33
35
  } & (SidebarControlledProps | SidebarUncontrolledProps);
34
36
 
35
37
  type SidebarComponent = React.ForwardRefExoticComponent<SidebarPublicProps & React.RefAttributes<HTMLDivElement>> & { Handle: typeof SidebarHandle };
@@ -48,6 +50,7 @@ const SIDEBAR_DOM_PROP_KEYS = [
48
50
  'sizeUpdate',
49
51
  'sizeUpdateMs',
50
52
  'style',
53
+ 'inset',
51
54
  ] as const satisfies readonly (keyof SidebarPublicProps)[];
52
55
 
53
56
  export const Sidebar = React.forwardRef<HTMLDivElement, SidebarPublicProps>((initialProps, ref) => {
@@ -81,9 +84,19 @@ export const Sidebar = React.forwardRef<HTMLDivElement, SidebarPublicProps>((ini
81
84
  onSizeChange,
82
85
  sizeUpdate,
83
86
  sizeUpdateMs = 50,
87
+ inset,
84
88
  } = initialProps;
85
89
  const sidebarDomProps = extractPaneDomProps(initialProps, SIDEBAR_DOM_PROP_KEYS);
86
90
  const shell = useShell();
91
+ const { registerInset, unregisterInset } = useInset();
92
+
93
+ // Register/unregister inset
94
+ React.useEffect(() => {
95
+ if (inset) {
96
+ registerInset('sidebar');
97
+ return () => unregisterInset('sidebar');
98
+ }
99
+ }, [inset, registerInset, unregisterInset]);
87
100
  const resolvedPresentation = useResponsivePresentation(presentation);
88
101
  const isOverlay = resolvedPresentation === 'overlay';
89
102
  const isStacked = resolvedPresentation === 'stacked';
@@ -430,6 +443,7 @@ export const Sidebar = React.forwardRef<HTMLDivElement, SidebarPublicProps>((ini
430
443
  data-peek={shell.peekTarget === 'sidebar' || undefined}
431
444
  data-presentation={shell.currentBreakpointReady ? resolvedPresentation : undefined}
432
445
  data-open={(shell.currentBreakpointReady && isStacked && isContentVisible) || undefined}
446
+ data-inset={inset || undefined}
433
447
  style={{
434
448
  ...style,
435
449
  ['--sidebar-size' as any]: `${expandedSize}px`,
@@ -104,7 +104,6 @@
104
104
  padding-top: var(--classic-active-padding-offset-2);
105
105
  padding-bottom: 0;
106
106
  background-color: var(--gray-3);
107
- box-shadow: var(--shadow-1);
108
107
 
109
108
  /* Theme-level translucent override for active */
110
109
  :where([data-panel-background='translucent'], [data-material='translucent']) & {
@@ -66,7 +66,7 @@
66
66
  /* */
67
67
  /* * * * * * * * * * * * * * * * * * * */
68
68
 
69
- .rt-SegmentedControlRoot.rt-r-orientation-vertical {
69
+ .rt-SegmentedControlRoot:where(.rt-r-orientation-vertical) {
70
70
  grid-auto-flow: row;
71
71
  grid-auto-columns: unset;
72
72
  grid-auto-rows: 1fr;
@@ -75,7 +75,7 @@
75
75
  }
76
76
 
77
77
  /* Square items for icon-only in vertical */
78
- .rt-SegmentedControlRoot.rt-r-orientation-vertical:has([data-icon-only]) {
78
+ .rt-SegmentedControlRoot:where(.rt-r-orientation-vertical):has([data-icon-only]) {
79
79
  grid-auto-columns: unset;
80
80
  grid-auto-rows: minmax(var(--segmented-control-height), 1fr);
81
81
  }
@@ -103,18 +103,18 @@
103
103
  }
104
104
 
105
105
  /* Vertical orientation - item layout */
106
- .rt-r-orientation-vertical .rt-SegmentedControlItem {
106
+ :where(.rt-r-orientation-vertical) .rt-SegmentedControlItem {
107
107
  flex-direction: column;
108
108
  }
109
109
 
110
110
  /* Vertical orientation - item border radius */
111
- .rt-r-orientation-vertical .rt-SegmentedControlItem:first-child {
111
+ :where(.rt-r-orientation-vertical) .rt-SegmentedControlItem:first-child {
112
112
  border-top-left-radius: inherit;
113
113
  border-top-right-radius: inherit;
114
114
  border-bottom-left-radius: 0;
115
115
  }
116
116
 
117
- .rt-r-orientation-vertical .rt-SegmentedControlItem:nth-last-child(2) {
117
+ :where(.rt-r-orientation-vertical) .rt-SegmentedControlItem:nth-last-child(2) {
118
118
  border-bottom-left-radius: inherit;
119
119
  border-bottom-right-radius: inherit;
120
120
  border-top-right-radius: 0;
@@ -202,7 +202,7 @@
202
202
  }
203
203
 
204
204
  /* Vertical orientation - separator */
205
- .rt-r-orientation-vertical .rt-SegmentedControlItemSeparator {
205
+ :where(.rt-r-orientation-vertical) .rt-SegmentedControlItemSeparator {
206
206
  margin-left: calc(var(--space-1) * 0.75); /* 3px */
207
207
  margin-right: calc(var(--space-1) * 0.75); /* 3px */
208
208
  margin-top: calc(-1 * var(--border-width-standard) * 0.5); /* -0.5px */
@@ -313,71 +313,71 @@
313
313
  }
314
314
 
315
315
  /* Vertical orientation - indicator height based on number of items */
316
- .rt-r-orientation-vertical .rt-SegmentedControlIndicator {
316
+ :where(.rt-r-orientation-vertical) .rt-SegmentedControlIndicator {
317
317
  width: 100%;
318
318
  height: unset;
319
319
  }
320
320
 
321
- .rt-r-orientation-vertical .rt-SegmentedControlIndicator:nth-child(2) {
321
+ :where(.rt-r-orientation-vertical) .rt-SegmentedControlIndicator:nth-child(2) {
322
322
  height: calc(100% / 1);
323
323
  }
324
- .rt-r-orientation-vertical .rt-SegmentedControlIndicator:nth-child(3) {
324
+ :where(.rt-r-orientation-vertical) .rt-SegmentedControlIndicator:nth-child(3) {
325
325
  height: calc(100% / 2);
326
326
  }
327
- .rt-r-orientation-vertical .rt-SegmentedControlIndicator:nth-child(4) {
327
+ :where(.rt-r-orientation-vertical) .rt-SegmentedControlIndicator:nth-child(4) {
328
328
  height: calc(100% / 3);
329
329
  }
330
- .rt-r-orientation-vertical .rt-SegmentedControlIndicator:nth-child(5) {
330
+ :where(.rt-r-orientation-vertical) .rt-SegmentedControlIndicator:nth-child(5) {
331
331
  height: calc(100% / 4);
332
332
  }
333
- .rt-r-orientation-vertical .rt-SegmentedControlIndicator:nth-child(6) {
333
+ :where(.rt-r-orientation-vertical) .rt-SegmentedControlIndicator:nth-child(6) {
334
334
  height: calc(100% / 5);
335
335
  }
336
- .rt-r-orientation-vertical .rt-SegmentedControlIndicator:nth-child(7) {
336
+ :where(.rt-r-orientation-vertical) .rt-SegmentedControlIndicator:nth-child(7) {
337
337
  height: calc(100% / 6);
338
338
  }
339
- .rt-r-orientation-vertical .rt-SegmentedControlIndicator:nth-child(8) {
339
+ :where(.rt-r-orientation-vertical) .rt-SegmentedControlIndicator:nth-child(8) {
340
340
  height: calc(100% / 7);
341
341
  }
342
- .rt-r-orientation-vertical .rt-SegmentedControlIndicator:nth-child(9) {
342
+ :where(.rt-r-orientation-vertical) .rt-SegmentedControlIndicator:nth-child(9) {
343
343
  height: calc(100% / 8);
344
344
  }
345
- .rt-r-orientation-vertical .rt-SegmentedControlIndicator:nth-child(10) {
345
+ :where(.rt-r-orientation-vertical) .rt-SegmentedControlIndicator:nth-child(10) {
346
346
  height: calc(100% / 9);
347
347
  }
348
- .rt-r-orientation-vertical .rt-SegmentedControlIndicator:nth-child(11) {
348
+ :where(.rt-r-orientation-vertical) .rt-SegmentedControlIndicator:nth-child(11) {
349
349
  height: calc(100% / 10);
350
350
  }
351
351
 
352
352
  /* Vertical transforms */
353
- .rt-r-orientation-vertical .rt-SegmentedControlItem[data-state='on']:nth-child(1) ~ .rt-SegmentedControlIndicator {
353
+ :where(.rt-r-orientation-vertical) .rt-SegmentedControlItem[data-state='on']:nth-child(1) ~ .rt-SegmentedControlIndicator {
354
354
  transform: translateY(0%);
355
355
  }
356
- .rt-r-orientation-vertical .rt-SegmentedControlItem[data-state='on']:nth-child(2) ~ .rt-SegmentedControlIndicator {
356
+ :where(.rt-r-orientation-vertical) .rt-SegmentedControlItem[data-state='on']:nth-child(2) ~ .rt-SegmentedControlIndicator {
357
357
  transform: translateY(100%);
358
358
  }
359
- .rt-r-orientation-vertical .rt-SegmentedControlItem[data-state='on']:nth-child(3) ~ .rt-SegmentedControlIndicator {
359
+ :where(.rt-r-orientation-vertical) .rt-SegmentedControlItem[data-state='on']:nth-child(3) ~ .rt-SegmentedControlIndicator {
360
360
  transform: translateY(200%);
361
361
  }
362
- .rt-r-orientation-vertical .rt-SegmentedControlItem[data-state='on']:nth-child(4) ~ .rt-SegmentedControlIndicator {
362
+ :where(.rt-r-orientation-vertical) .rt-SegmentedControlItem[data-state='on']:nth-child(4) ~ .rt-SegmentedControlIndicator {
363
363
  transform: translateY(300%);
364
364
  }
365
- .rt-r-orientation-vertical .rt-SegmentedControlItem[data-state='on']:nth-child(5) ~ .rt-SegmentedControlIndicator {
365
+ :where(.rt-r-orientation-vertical) .rt-SegmentedControlItem[data-state='on']:nth-child(5) ~ .rt-SegmentedControlIndicator {
366
366
  transform: translateY(400%);
367
367
  }
368
- .rt-r-orientation-vertical .rt-SegmentedControlItem[data-state='on']:nth-child(6) ~ .rt-SegmentedControlIndicator {
368
+ :where(.rt-r-orientation-vertical) .rt-SegmentedControlItem[data-state='on']:nth-child(6) ~ .rt-SegmentedControlIndicator {
369
369
  transform: translateY(500%);
370
370
  }
371
- .rt-r-orientation-vertical .rt-SegmentedControlItem[data-state='on']:nth-child(7) ~ .rt-SegmentedControlIndicator {
371
+ :where(.rt-r-orientation-vertical) .rt-SegmentedControlItem[data-state='on']:nth-child(7) ~ .rt-SegmentedControlIndicator {
372
372
  transform: translateY(600%);
373
373
  }
374
- .rt-r-orientation-vertical .rt-SegmentedControlItem[data-state='on']:nth-child(8) ~ .rt-SegmentedControlIndicator {
374
+ :where(.rt-r-orientation-vertical) .rt-SegmentedControlItem[data-state='on']:nth-child(8) ~ .rt-SegmentedControlIndicator {
375
375
  transform: translateY(700%);
376
376
  }
377
- .rt-r-orientation-vertical .rt-SegmentedControlItem[data-state='on']:nth-child(9) ~ .rt-SegmentedControlIndicator {
377
+ :where(.rt-r-orientation-vertical) .rt-SegmentedControlItem[data-state='on']:nth-child(9) ~ .rt-SegmentedControlIndicator {
378
378
  transform: translateY(800%);
379
379
  }
380
- .rt-r-orientation-vertical .rt-SegmentedControlItem[data-state='on']:nth-child(10) ~ .rt-SegmentedControlIndicator {
380
+ :where(.rt-r-orientation-vertical) .rt-SegmentedControlItem[data-state='on']:nth-child(10) ~ .rt-SegmentedControlIndicator {
381
381
  transform: translateY(900%);
382
382
  }
383
383
 
@@ -577,45 +577,45 @@
577
577
  }
578
578
 
579
579
  /* Vertical icon-only - minimum square height */
580
- .rt-r-orientation-vertical .rt-SegmentedControlItem[data-icon-only] {
580
+ :where(.rt-r-orientation-vertical) .rt-SegmentedControlItem[data-icon-only] {
581
581
  min-width: unset;
582
582
  min-height: var(--segmented-control-height);
583
583
  }
584
584
 
585
585
  /* Vertical icon-only - remove top/bottom padding */
586
- .rt-r-orientation-vertical .rt-SegmentedControlItem[data-icon-only] .rt-SegmentedControlItemLabel {
586
+ :where(.rt-r-orientation-vertical) .rt-SegmentedControlItem[data-icon-only] .rt-SegmentedControlItemLabel {
587
587
  padding-top: 0;
588
588
  padding-bottom: 0;
589
589
  }
590
590
 
591
591
  /* Vertical icon-only root width (explicit since nested :has() in @breakpoints may not work) */
592
- .rt-SegmentedControlRoot.rt-r-orientation-vertical.rt-r-size-1:has([data-icon-only]) {
592
+ .rt-SegmentedControlRoot:where(.rt-r-orientation-vertical):where(.rt-r-size-1):has([data-icon-only]) {
593
593
  width: var(--space-5);
594
594
  }
595
- .rt-SegmentedControlRoot.rt-r-orientation-vertical.rt-r-size-2:has([data-icon-only]) {
595
+ .rt-SegmentedControlRoot:where(.rt-r-orientation-vertical):where(.rt-r-size-2):has([data-icon-only]) {
596
596
  width: var(--space-6);
597
597
  }
598
- .rt-SegmentedControlRoot.rt-r-orientation-vertical.rt-r-size-3:has([data-icon-only]) {
598
+ .rt-SegmentedControlRoot:where(.rt-r-orientation-vertical):where(.rt-r-size-3):has([data-icon-only]) {
599
599
  width: var(--space-7);
600
600
  }
601
- .rt-SegmentedControlRoot.rt-r-orientation-vertical.rt-r-size-4:has([data-icon-only]) {
601
+ .rt-SegmentedControlRoot:where(.rt-r-orientation-vertical):where(.rt-r-size-4):has([data-icon-only]) {
602
602
  width: var(--space-8);
603
603
  }
604
604
 
605
605
  /* Vertical text items need vertical padding */
606
- .rt-r-orientation-vertical.rt-r-size-1 .rt-SegmentedControlItemLabel {
606
+ :where(.rt-r-orientation-vertical):where(.rt-r-size-1) .rt-SegmentedControlItemLabel {
607
607
  padding-top: var(--space-1);
608
608
  padding-bottom: var(--space-1);
609
609
  }
610
- .rt-r-orientation-vertical.rt-r-size-2 .rt-SegmentedControlItemLabel {
610
+ :where(.rt-r-orientation-vertical):where(.rt-r-size-2) .rt-SegmentedControlItemLabel {
611
611
  padding-top: var(--space-2);
612
612
  padding-bottom: var(--space-2);
613
613
  }
614
- .rt-r-orientation-vertical.rt-r-size-3 .rt-SegmentedControlItemLabel {
614
+ :where(.rt-r-orientation-vertical):where(.rt-r-size-3) .rt-SegmentedControlItemLabel {
615
615
  padding-top: var(--space-2);
616
616
  padding-bottom: var(--space-2);
617
617
  }
618
- .rt-r-orientation-vertical.rt-r-size-4 .rt-SegmentedControlItemLabel {
618
+ :where(.rt-r-orientation-vertical):where(.rt-r-size-4) .rt-SegmentedControlItemLabel {
619
619
  padding-top: var(--space-3);
620
620
  padding-bottom: var(--space-3);
621
621
  }
@@ -400,7 +400,6 @@
400
400
 
401
401
  &:where([data-state='open']) {
402
402
  background-color: var(--accent-3);
403
- box-shadow: var(--shadow-1);
404
403
 
405
404
  /* Theme-level translucent override for open */
406
405
  :where([data-panel-background='translucent'], [data-material='translucent']) & {
@@ -419,7 +418,6 @@
419
418
 
420
419
  &:where(:active:not([data-state='open'], [data-disabled])) {
421
420
  background-color: var(--accent-3);
422
- box-shadow: var(--shadow-1);
423
421
 
424
422
  /* Theme-level translucent override for active */
425
423
  :where([data-panel-background='translucent'], [data-material='translucent']) & {
@@ -134,3 +134,17 @@ export function useComposition() {
134
134
  if (!ctx) throw new Error('useComposition must be used within Shell.Root');
135
135
  return ctx;
136
136
  }
137
+
138
+ // Inset slice - tracks which panes have inset for gray backdrop
139
+ export type InsetPaneId = 'left' | 'sidebar' | 'content' | 'inspector' | 'bottom';
140
+ export const InsetContext = React.createContext<{
141
+ insetPanes: Set<InsetPaneId>;
142
+ registerInset: (id: InsetPaneId) => void;
143
+ unregisterInset: (id: InsetPaneId) => void;
144
+ hasAnyInset: boolean;
145
+ } | null>(null as any);
146
+ export function useInset() {
147
+ const ctx = React.useContext(InsetContext);
148
+ if (!ctx) throw new Error('useInset must be used within Shell.Root');
149
+ return ctx;
150
+ }
@@ -78,19 +78,13 @@
78
78
  width: var(--rail-size, 64px);
79
79
  }
80
80
 
81
+ /* Collapsed rail: stay in flow during transition, then hide */
81
82
  .rt-ShellRail[data-mode='collapsed'] {
82
83
  width: 0px;
83
84
  /* Delay container collapse until content fade completes */
84
85
  transition-delay: var(--motion-duration-small);
85
86
  }
86
87
 
87
- /* Keep collapsed panes out of flow to avoid layout blips when exiting peek */
88
- .rt-ShellRail[data-mode='collapsed'] {
89
- position: absolute;
90
- inset-block: 0;
91
- inset-inline-start: 0;
92
- }
93
-
94
88
  /* Peek overlay rules consolidated later to avoid duplication */
95
89
 
96
90
  .rt-ShellRailContent {
@@ -102,16 +96,20 @@
102
96
 
103
97
  /* Content animation: fade out first, then fade in after width settles */
104
98
  opacity: 0;
99
+ pointer-events: none;
105
100
  transition: opacity var(--motion-duration-small) var(--motion-ease-standard) var(--motion-duration-small);
106
101
  }
107
102
 
108
103
  .rt-ShellRailContent[data-visible] {
109
104
  opacity: 1;
105
+ pointer-events: auto;
110
106
  }
111
107
 
112
108
  .rt-ShellRail[data-mode='collapsed'] .rt-ShellRailContent {
113
- /* Exit animation: fade out content first */
109
+ /* Exit animation: fade out content first, then collapse */
114
110
  opacity: 0;
111
+ width: 0;
112
+ visibility: hidden;
115
113
  transition: opacity var(--motion-duration-small) var(--motion-ease-standard);
116
114
  }
117
115
 
@@ -133,19 +131,13 @@
133
131
  width: var(--panel-size, 288px);
134
132
  }
135
133
 
134
+ /* Collapsed panel: stay in flow during transition, then hide */
136
135
  .rt-ShellPanel:not([data-visible]) {
137
136
  width: 0px;
138
137
  /* Delay container collapse until content fade completes */
139
138
  transition-delay: var(--motion-duration-small);
140
139
  }
141
140
 
142
- /* Keep collapsed panel out of flow to avoid layout blips when exiting peek */
143
- .rt-ShellPanel:not([data-visible]) {
144
- position: absolute;
145
- inset-block: 0;
146
- inset-inline-start: var(--peek-rail-width, var(--rail-size, 64px));
147
- }
148
-
149
141
  .rt-ShellPanelContent {
150
142
  display: flex;
151
143
  flex-direction: column;
@@ -155,16 +147,20 @@
155
147
 
156
148
  /* Content animation */
157
149
  opacity: 0;
150
+ pointer-events: none;
158
151
  transition: opacity var(--motion-duration-small) var(--motion-ease-standard) var(--motion-duration-small);
159
152
  }
160
153
 
161
154
  .rt-ShellPanelContent[data-visible] {
162
155
  opacity: 1;
156
+ pointer-events: auto;
163
157
  }
164
158
 
165
159
  .rt-ShellPanel:not([data-visible]) .rt-ShellPanelContent {
166
- /* Exit animation: fade out content first */
160
+ /* Exit animation: fade out content first, then collapse */
167
161
  opacity: 0;
162
+ width: 0;
163
+ visibility: hidden;
168
164
  transition: opacity var(--motion-duration-small) var(--motion-ease-standard);
169
165
  }
170
166
 
@@ -195,14 +191,9 @@
195
191
  width: var(--sidebar-thin-size, 64px);
196
192
  }
197
193
 
198
- /* Keep collapsed sidebar out of flow to avoid layout blips when exiting peek */
194
+ /* Collapsed sidebar: stay in flow during transition, then hide */
199
195
  .rt-ShellSidebar[data-mode='collapsed'] {
200
196
  width: 0px;
201
- position: absolute;
202
- inset-block: 0;
203
- inset-inline-start: 0;
204
- flex-shrink: 0;
205
- flex-basis: 0;
206
197
  /* Delay container collapse until content fade completes */
207
198
  transition-delay: var(--motion-duration-small);
208
199
  }
@@ -216,6 +207,7 @@
216
207
 
217
208
  /* Content animation */
218
209
  opacity: 0;
210
+ pointer-events: none;
219
211
  transition: opacity var(--motion-duration-small) var(--motion-ease-standard) var(--motion-duration-small);
220
212
  }
221
213
 
@@ -226,6 +218,7 @@
226
218
 
227
219
  .rt-ShellSidebarContent[data-visible] {
228
220
  opacity: 1;
221
+ pointer-events: auto;
229
222
  }
230
223
 
231
224
  /* Sidebar presentation switch sequencing (thin ↔ expanded) */
@@ -245,8 +238,10 @@
245
238
  }
246
239
 
247
240
  .rt-ShellSidebar[data-mode='collapsed'] .rt-ShellSidebarContent {
248
- /* Exit animation: fade out content first */
241
+ /* Exit animation: fade out content first, then collapse */
249
242
  opacity: 0;
243
+ width: 0;
244
+ visibility: hidden;
250
245
  transition: opacity var(--motion-duration-small) var(--motion-ease-standard);
251
246
  }
252
247
 
@@ -320,16 +315,20 @@
320
315
 
321
316
  /* Content animation */
322
317
  opacity: 0;
318
+ pointer-events: none;
323
319
  transition: opacity var(--motion-duration-small) var(--motion-ease-standard) var(--motion-duration-small);
324
320
  }
325
321
 
326
322
  .rt-ShellInspectorContent[data-visible] {
327
323
  opacity: 1;
324
+ pointer-events: auto;
328
325
  }
329
326
 
330
327
  .rt-ShellInspector[data-mode='collapsed'] .rt-ShellInspectorContent {
331
- /* Exit animation: fade out content first */
328
+ /* Exit animation: fade out content first, then collapse */
332
329
  opacity: 0;
330
+ width: 0;
331
+ visibility: hidden;
333
332
  transition: opacity var(--motion-duration-small) var(--motion-ease-standard);
334
333
  }
335
334
 
@@ -351,11 +350,9 @@
351
350
  height: var(--bottom-size, 200px);
352
351
  }
353
352
 
353
+ /* Collapsed bottom: stay in flow during transition, then hide */
354
354
  .rt-ShellBottom[data-mode='collapsed'] {
355
355
  height: 0px;
356
- position: absolute;
357
- inset-inline: 0;
358
- inset-block-end: 0;
359
356
  /* Delay container collapse until content fade completes */
360
357
  transition-delay: var(--motion-duration-small);
361
358
  }
@@ -369,11 +366,13 @@
369
366
 
370
367
  /* Content animation */
371
368
  opacity: 0;
369
+ pointer-events: none;
372
370
  transition: opacity var(--motion-duration-small) var(--motion-ease-standard) var(--motion-duration-small);
373
371
  }
374
372
 
375
373
  .rt-ShellBottomContent[data-visible] {
376
374
  opacity: 1;
375
+ pointer-events: auto;
377
376
  }
378
377
 
379
378
  /* Disable transitions during active resize */
@@ -401,8 +400,10 @@
401
400
  }
402
401
 
403
402
  .rt-ShellBottom[data-mode='collapsed'] .rt-ShellBottomContent {
404
- /* Exit animation: fade out content first */
403
+ /* Exit animation: fade out content first, then collapse */
405
404
  opacity: 0;
405
+ height: 0;
406
+ visibility: hidden;
406
407
  transition: opacity var(--motion-duration-small) var(--motion-ease-standard);
407
408
  }
408
409
 
@@ -618,3 +619,25 @@
618
619
  .rt-ShellBottom[data-peek][data-mode='collapsed'] {
619
620
  height: var(--bottom-size, 200px);
620
621
  }
622
+
623
+ /* --- Inset mode: floating panes with gray backdrop --- */
624
+
625
+ /* Shell body gets gray backdrop when any pane has inset */
626
+ .rt-ShellBody[data-has-inset] {
627
+ background: var(--gray-2);
628
+ }
629
+
630
+ /* Inset pane shared styles */
631
+ .rt-ShellLeft[data-inset],
632
+ .rt-ShellSidebar[data-inset],
633
+ .rt-ShellContent[data-inset],
634
+ .rt-ShellInspector[data-inset],
635
+ .rt-ShellBottom[data-inset] {
636
+ --shell-inset-gap: var(--space-2);
637
+ margin: var(--shell-inset-gap);
638
+ border-radius: var(--radius-3);
639
+ background: var(--color-background);
640
+ box-shadow: var(--shadow-2);
641
+ /* Override height: 100% so margin doesn't overflow */
642
+ height: auto;
643
+ }