@teamofsilicons/silicon-ui 0.2.0 → 0.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 (112) hide show
  1. package/README.md +4 -3
  2. package/check.mjs +14 -5
  3. package/components/activity-heatmap/activity-heatmap.module.css +4 -4
  4. package/components/alert/alert.module.css +1 -1
  5. package/components/announcement-bar/announcement-bar.module.css +6 -6
  6. package/components/avatar/avatar.d.ts +2 -2
  7. package/components/avatar/avatar.js +1 -1
  8. package/components/avatar/avatar.module.css +5 -2
  9. package/components/avatar-group/avatar-group.module.css +4 -4
  10. package/components/badge/badge.module.css +4 -4
  11. package/components/bar-chart/bar-chart.module.css +4 -4
  12. package/components/billing-toggle/billing-toggle.module.css +10 -10
  13. package/components/bottom-sheet/bottom-sheet.module.css +4 -5
  14. package/components/breadcrumb/breadcrumb.d.ts +8 -2
  15. package/components/breadcrumb/breadcrumb.js +21 -9
  16. package/components/breadcrumb/breadcrumb.module.css +7 -3
  17. package/components/brush-chart/brush-chart.module.css +9 -9
  18. package/components/button/button.d.ts +7 -2
  19. package/components/button/button.js +3 -1
  20. package/components/button/button.module.css +10 -1
  21. package/components/button-group/button-group.module.css +6 -6
  22. package/components/calendar/calendar.module.css +7 -7
  23. package/components/card/card.module.css +2 -2
  24. package/components/card-stack/card-stack.module.css +2 -3
  25. package/components/carousel/carousel.module.css +2 -2
  26. package/components/chat-thread/chat-thread.module.css +41 -41
  27. package/components/checkbox/checkbox.module.css +1 -1
  28. package/components/chip-group/chip-group.module.css +2 -2
  29. package/components/code-block/code-block.module.css +7 -14
  30. package/components/color-picker/color-picker.module.css +20 -21
  31. package/components/combobox/combobox.module.css +2 -2
  32. package/components/command-palette/command-palette.module.css +18 -18
  33. package/components/comment-thread/comment-thread.module.css +35 -35
  34. package/components/confirm-morph/confirm-morph.module.css +9 -9
  35. package/components/context-menu/context-menu.module.css +3 -3
  36. package/components/countdown/countdown.module.css +4 -4
  37. package/components/date-picker/date-picker.module.css +6 -6
  38. package/components/date-range-picker/date-range-picker.module.css +21 -21
  39. package/components/dialog/dialog.module.css +2 -2
  40. package/components/donut-chart/donut-chart.module.css +4 -4
  41. package/components/drawer/drawer.module.css +5 -5
  42. package/components/dropdown-menu/dropdown-menu.d.ts +71 -1
  43. package/components/dropdown-menu/dropdown-menu.js +100 -6
  44. package/components/dropdown-menu/dropdown-menu.module.css +15 -5
  45. package/components/elastic-slider/elastic-slider.module.css +4 -4
  46. package/components/expandable-card/expandable-card.module.css +1 -1
  47. package/components/expanding-button-group/expanding-button-group.module.css +1 -1
  48. package/components/expanding-search/expanding-search.module.css +9 -9
  49. package/components/file-dropzone/file-dropzone.module.css +21 -21
  50. package/components/file-upload/file-upload.module.css +7 -7
  51. package/components/filter-toolbar/filter-toolbar.module.css +9 -9
  52. package/components/floating-button-group/floating-button-group.module.css +6 -6
  53. package/components/gauge/gauge.module.css +2 -2
  54. package/components/hover-card/hover-card.module.css +2 -2
  55. package/components/image-compare/image-compare.module.css +4 -4
  56. package/components/inline-edit/inline-edit.module.css +12 -12
  57. package/components/json-viewer/json-viewer.module.css +12 -12
  58. package/components/line-chart/line-chart.module.css +8 -8
  59. package/components/mention-input/mention-input.module.css +8 -8
  60. package/components/metric-card/metric-card.module.css +1 -1
  61. package/components/money-input/money-input.module.css +9 -9
  62. package/components/morph-select/morph-select.module.css +13 -13
  63. package/components/multi-select/multi-select.module.css +6 -6
  64. package/components/nav-list/nav-list.d.ts +64 -0
  65. package/components/nav-list/nav-list.js +103 -0
  66. package/components/nav-list/nav-list.module.css +25 -0
  67. package/components/notification-center/notification-center.module.css +27 -27
  68. package/components/number-field/number-field.module.css +2 -2
  69. package/components/otp-input/otp-input.module.css +4 -4
  70. package/components/password-field/password-field.module.css +1 -1
  71. package/components/password-strength/password-strength.module.css +7 -7
  72. package/components/phone-input/phone-input.module.css +19 -19
  73. package/components/popover/popover.module.css +2 -2
  74. package/components/progress/progress.module.css +1 -1
  75. package/components/radio-cards/radio-cards.module.css +8 -8
  76. package/components/radio-group/radio-group.module.css +1 -1
  77. package/components/resizable-panels/resizable-panels.module.css +5 -5
  78. package/components/rich-text-editor/rich-text-editor.module.css +12 -12
  79. package/components/ridgeline/ridgeline.module.css +7 -7
  80. package/components/scroll-area/scroll-area.module.css +8 -8
  81. package/components/segmented-control/segmented-control.d.ts +3 -1
  82. package/components/segmented-control/segmented-control.js +2 -2
  83. package/components/segmented-control/segmented-control.module.css +7 -4
  84. package/components/select/select.module.css +5 -5
  85. package/components/shortcut-recorder/shortcut-recorder.module.css +15 -15
  86. package/components/signature-pad/signature-pad.module.css +11 -11
  87. package/components/slider/slider.module.css +4 -4
  88. package/components/slope-chart/slope-chart.module.css +7 -7
  89. package/components/sortable-data-table/sortable-data-table.module.css +4 -4
  90. package/components/split-button/split-button.module.css +5 -5
  91. package/components/stepper/stepper.module.css +3 -3
  92. package/components/streamgraph/streamgraph.module.css +7 -7
  93. package/components/swipe-actions/swipe-actions.module.css +5 -5
  94. package/components/switch/switch.module.css +1 -1
  95. package/components/tabs/tabs.d.ts +9 -2
  96. package/components/tabs/tabs.js +4 -2
  97. package/components/tabs/tabs.module.css +7 -2
  98. package/components/tag-input/tag-input.module.css +4 -4
  99. package/components/time-picker/time-picker.module.css +3 -3
  100. package/components/timeline/timeline.module.css +3 -3
  101. package/components/toast/toast.module.css +5 -5
  102. package/components/toast-stack/toast-stack.module.css +5 -5
  103. package/components/tooltip/tooltip.module.css +1 -1
  104. package/components/tree-view/tree-view.module.css +7 -7
  105. package/components/treemap/treemap.module.css +13 -13
  106. package/components/usage-meter/usage-meter.module.css +5 -5
  107. package/components/user-menu/user-menu.module.css +22 -22
  108. package/components/waffle-chart/waffle-chart.module.css +7 -7
  109. package/components.json +416 -1
  110. package/eslint.js +35 -3
  111. package/package.json +1 -1
  112. package/styles.css +44 -4
@@ -3,8 +3,8 @@
3
3
  /* Series colors (--series-1 to --series-4) come from registry/foundation.css. */
4
4
 
5
5
  /* Layer toggles: a rect swatch mirrors the area it names. Hover or focus previews that layer in the plot. */
6
- .legend { display: flex; flex-wrap: wrap; gap: 2px 4px; min-width: 0; margin-inline: -8px; }
7
- .toggle { display: inline-flex; min-height: 32px; align-items: center; gap: 8px; padding: 0 10px 0 8px; border: 0; border-radius: var(--radius-full); corner-shape: round; background: transparent; color: var(--text-secondary); cursor: pointer; font: inherit; font-size: var(--text-sm); line-height: var(--leading-body); -webkit-tap-highlight-color: transparent; transition: color var(--duration-fast) var(--ease-standard), background-color var(--duration-fast) var(--ease-standard), opacity var(--duration-fast) var(--ease-standard), transform var(--duration-instant) var(--ease-standard); }
6
+ .legend { display: flex; flex-wrap: wrap; gap: var(--space-hair) var(--space-tight); min-width: 0; margin-inline: calc(var(--space-related) * -1); }
7
+ .toggle { display: inline-flex; min-height: 32px; align-items: center; gap: var(--space-related); padding: 0 var(--space-group) 0 var(--space-related); border: 0; border-radius: var(--radius-full); corner-shape: round; background: transparent; color: var(--text-secondary); cursor: pointer; font: inherit; font-size: var(--text-sm); line-height: var(--leading-body); -webkit-tap-highlight-color: transparent; transition: color var(--duration-fast) var(--ease-standard), background-color var(--duration-fast) var(--ease-standard), opacity var(--duration-fast) var(--ease-standard), transform var(--duration-instant) var(--ease-standard); }
8
8
  .toggle:active { transform: scale(.97); }
9
9
  .toggle[data-active] { color: var(--foreground); background: color-mix(in oklab, var(--foreground) 5%, transparent); }
10
10
  .toggle[data-dim] { opacity: .56; }
@@ -31,20 +31,20 @@
31
31
  .label[data-hidden] { opacity: 0 !important; }
32
32
  .chart[data-layer] .label[data-dim] { opacity: 0 !important; }
33
33
 
34
- .tooltip { position: absolute; top: 0; left: 0; z-index: 1; display: grid; min-width: 156px; max-width: min(256px, 100%); gap: 4px; padding: 10px 12px; border: 1px solid var(--border); border-radius: var(--radius-control); corner-shape: var(--corner-shape); background: var(--surface-raised); box-shadow: var(--shadow-floating); opacity: 0; pointer-events: none; scale: .96; transition: opacity var(--duration-fast) var(--ease-standard), scale var(--duration-fast) var(--ease-standard); }
34
+ .tooltip { position: absolute; top: 0; left: 0; z-index: 1; display: grid; min-width: 156px; max-width: min(256px, 100%); gap: var(--space-tight); padding: var(--space-group) var(--space-group); border: 1px solid var(--border); border-radius: var(--radius-control); corner-shape: var(--corner-shape); background: var(--surface-raised); box-shadow: var(--shadow-floating); opacity: 0; pointer-events: none; scale: .96; transition: opacity var(--duration-fast) var(--ease-standard), scale var(--duration-fast) var(--ease-standard); }
35
35
  .chart[data-active] .tooltip { opacity: 1; scale: 1; }
36
- .tipTitle { margin: 0 0 2px; color: var(--text-secondary); font-size: var(--text-xs); line-height: var(--leading-body); white-space: nowrap; font-variant-numeric: tabular-nums; }
37
- .tipRow { display: flex; min-width: 0; align-items: center; gap: 8px; margin: 0; font-size: var(--text-sm); line-height: var(--leading-body); transition: opacity var(--duration-fast) var(--ease-standard); }
36
+ .tipTitle { margin: 0 0 var(--space-hair); color: var(--text-secondary); font-size: var(--text-xs); line-height: var(--leading-body); white-space: nowrap; font-variant-numeric: tabular-nums; }
37
+ .tipRow { display: flex; min-width: 0; align-items: center; gap: var(--space-related); margin: 0; font-size: var(--text-sm); line-height: var(--leading-body); transition: opacity var(--duration-fast) var(--ease-standard); }
38
38
  .tipRow[data-dim] { opacity: .5; }
39
39
  .tipSwatch { width: 10px; height: 2.5px; flex: none; border-radius: var(--radius-full); corner-shape: round; background: var(--series); }
40
40
  .tipName { min-width: 0; flex: 1; overflow: hidden; color: var(--text-secondary); text-overflow: ellipsis; white-space: nowrap; }
41
41
  .tipRow[data-active] .tipName { color: var(--foreground); }
42
- .tipValue { flex: none; margin-left: 8px; color: var(--foreground); font-weight: 500; font-variant-numeric: tabular-nums; white-space: nowrap; }
42
+ .tipValue { flex: none; margin-left: var(--space-related); color: var(--foreground); font-weight: 500; font-variant-numeric: tabular-nums; white-space: nowrap; }
43
43
 
44
44
  .message { position: absolute; inset: 0; display: grid; place-items: center; margin: 0; color: var(--text-muted); font-size: var(--text-sm); pointer-events: none; }
45
45
 
46
46
  .axis { position: relative; min-width: 0; }
47
- .axisLabel { position: absolute; top: 8px; color: var(--text-muted); font-size: var(--text-xs); line-height: 1; white-space: nowrap; font-variant-numeric: tabular-nums; transition: opacity var(--duration-standard) var(--ease-standard); }
47
+ .axisLabel { position: absolute; top: var(--space-related); color: var(--text-muted); font-size: var(--text-xs); line-height: 1; white-space: nowrap; font-variant-numeric: tabular-nums; transition: opacity var(--duration-standard) var(--ease-standard); }
48
48
  /* New labels fade in while the stream morphs to a new range instead of popping in a single frame. */
49
49
  @starting-style { .axisLabel { opacity: 0; } }
50
50
 
@@ -8,11 +8,11 @@
8
8
  .list:focus-visible { outline: none; }
9
9
  .row { position: relative; isolation: isolate; overflow: hidden; }
10
10
  /* The content follows the finger by transform only; vertical pans stay with the page. */
11
- .content { position: relative; z-index: 10; display: flex; min-height: 64px; align-items: center; gap: var(--space-related); padding: var(--space-group) var(--space-related) var(--space-group) var(--space-inset); background: var(--surface); touch-action: pan-y; user-select: none; -webkit-user-select: none; -webkit-touch-callout: none; }
11
+ .content { position: relative; z-index: var(--layer-raised); display: flex; min-height: 64px; align-items: center; gap: var(--space-related); padding: var(--space-group) var(--space-related) var(--space-group) var(--space-inset); background: var(--surface); touch-action: pan-y; user-select: none; -webkit-user-select: none; -webkit-touch-callout: none; }
12
12
  .content::after { position: absolute; right: 0; bottom: 0; left: var(--swipe-actions-inset, var(--space-inset)); height: 1px; background: var(--border); content: ""; pointer-events: none; }
13
13
  .content img { -webkit-user-drag: none; }
14
14
  .body { min-width: 0; flex: 1 1 auto; }
15
- .more { display: grid; width: 32px; height: 32px; flex: none; place-items: center; border: 0; border-radius: calc(var(--radius-control) - 6px); background: transparent; color: var(--text-muted); cursor: pointer; -webkit-tap-highlight-color: transparent; transition: color var(--duration-fast) var(--ease-standard), background-color var(--duration-fast) var(--ease-standard); }
15
+ .more { display: grid; width: 32px; height: 32px; flex: none; place-items: center; border: 0; border-radius: calc(var(--radius-control) - var(--space-related)); background: transparent; color: var(--text-muted); cursor: pointer; -webkit-tap-highlight-color: transparent; transition: color var(--duration-fast) var(--ease-standard), background-color var(--duration-fast) var(--ease-standard); }
16
16
  /* The button anchors a menu, so a press answers with colour, never scale. */
17
17
  .more:active, .more[data-state="open"] { background: var(--surface-muted); color: var(--foreground); }
18
18
  .more:focus-visible { outline: none; }
@@ -33,18 +33,18 @@
33
33
  .anchor { position: absolute; top: 0; bottom: 0; width: 0; }
34
34
  .layer[data-side="trailing"] .anchor { left: 0; }
35
35
  .layer[data-side="leading"] .anchor { right: 0; }
36
- .glyph { position: absolute; top: 0; bottom: 0; left: calc(var(--swipe-action-width) / -2); display: flex; width: var(--swipe-action-width); flex-direction: column; align-items: center; justify-content: center; gap: 3px; }
36
+ .glyph { position: absolute; top: 0; bottom: 0; left: calc(var(--swipe-action-width) / -2); display: flex; width: var(--swipe-action-width); flex-direction: column; align-items: center; justify-content: center; gap: var(--space-tight); }
37
37
  .icon { display: grid; place-items: center; }
38
38
  .icon svg { width: 20px; height: 20px; }
39
39
  .label { font-size: var(--text-xs); font-weight: 500; letter-spacing: var(--tracking-body); line-height: var(--leading-body); white-space: nowrap; }
40
40
 
41
41
  /* The menu grows from its trigger, matching the library dropdown. */
42
- .menu { --menu-x: 0px; --menu-y: -5px; position: relative; z-index: 60; min-width: 11rem; padding: 5px; border: 1px solid var(--border); border-radius: var(--radius-container); background: var(--surface-raised); box-shadow: var(--shadow-floating); transform-origin: var(--radix-dropdown-menu-content-transform-origin); }
42
+ .menu { --menu-x: 0px; --menu-y: -5px; position: relative; z-index: var(--layer-dropdown); min-width: 11rem; padding: var(--space-tight); border: 1px solid var(--border); border-radius: var(--radius-container); background: var(--surface-raised); box-shadow: var(--shadow-floating); transform-origin: var(--radix-dropdown-menu-content-transform-origin); }
43
43
  .menu[data-side="top"] { --menu-y: 5px; }
44
44
  .menu[data-state="open"] { animation: menu-fade-in var(--duration-fast) var(--ease-enter) both, menu-rise-in var(--duration-spring) var(--ease-spring) both; }
45
45
  .menu[data-state="closed"] { animation: menu-out var(--duration-instant) var(--ease-standard) both; }
46
46
  .menu[data-state="open"] .item { animation: menu-item-in var(--duration-standard) var(--ease-enter) both; animation-delay: calc(min(var(--i, 0), 4) * 35ms); }
47
- .item { position: relative; display: flex; min-height: 36px; align-items: center; gap: 10px; padding: 0 11px; border-radius: calc(var(--radius-container) - 6px); color: var(--foreground); font-size: var(--text-sm); cursor: pointer; outline: none; transition: background-color var(--duration-instant) var(--ease-standard); }
47
+ .item { position: relative; display: flex; min-height: 36px; align-items: center; gap: var(--space-group); padding: 0 var(--space-group); border-radius: calc(var(--radius-container) - var(--space-related)); color: var(--foreground); font-size: var(--text-sm); cursor: pointer; outline: none; transition: background-color var(--duration-instant) var(--ease-standard); }
48
48
  .item[data-highlighted] { background: var(--surface-muted); }
49
49
  .item[data-tone="danger"] { color: var(--danger); }
50
50
  .item[data-tone="danger"][data-highlighted] { background: color-mix(in oklab, var(--danger) 8%, var(--surface-raised)); }
@@ -1,7 +1,7 @@
1
1
  .switch { display: inline-flex; min-height: var(--control-height-md); align-items: center; gap: var(--space-group); padding: 0; border: 0; color: var(--foreground); background: transparent; font: inherit; font-size: var(--text-sm); cursor: pointer; -webkit-tap-highlight-color: transparent; }
2
2
  .switch:disabled { cursor: not-allowed; opacity: .5; }
3
3
  /* Fixed box: the thumb moves inside it with transforms, so nothing around the switch shifts. The track crossfades between the two fills. */
4
- .track { position: relative; box-sizing: border-box; display: flex; flex: 0 0 auto; width: 42px; height: 24px; align-items: center; padding: 3px; border-radius: var(--radius-full); corner-shape: round; background: var(--control-track); isolation: isolate; transition: background-color var(--duration-fast) var(--ease-standard); }
4
+ .track { position: relative; box-sizing: border-box; display: flex; flex: 0 0 auto; width: 42px; height: 24px; align-items: center; padding: var(--space-tight); border-radius: var(--radius-full); corner-shape: round; background: var(--control-track); isolation: isolate; transition: background-color var(--duration-fast) var(--ease-standard); }
5
5
  .track::before { content: ""; position: absolute; inset: 0; z-index: -1; border-radius: inherit; corner-shape: inherit; background: var(--control-on); opacity: 0; transition: opacity var(--duration-standard) var(--ease-standard); }
6
6
  .switch[data-state="checked"] .track::before { opacity: 1; }
7
7
  .thumb { flex: 0 0 auto; width: 18px; height: 18px; border-radius: var(--radius-full); corner-shape: round; background: var(--control-thumb); box-shadow: var(--control-thumb-shadow); will-change: transform; transition: background-color var(--duration-standard) var(--ease-standard); }
@@ -1,8 +1,15 @@
1
1
  import * as TabsPrimitive from "@radix-ui/react-tabs";
2
- import type { ComponentPropsWithoutRef } from "react";
2
+ import type { ComponentPropsWithoutRef, ReactNode } from "react";
3
3
  type RootProps = ComponentPropsWithoutRef<typeof TabsPrimitive.Root>;
4
4
  export declare function Tabs({ value, defaultValue, onValueChange, className, ...props }: RootProps): import("react").JSX.Element;
5
5
  export declare function TabsList({ className, ...props }: ComponentPropsWithoutRef<typeof TabsPrimitive.List>): import("react").JSX.Element;
6
- export declare function TabsTrigger({ className, children, value, ...props }: ComponentPropsWithoutRef<typeof TabsPrimitive.Trigger>): import("react").JSX.Element;
6
+ export interface TabsTriggerProps extends ComponentPropsWithoutRef<typeof TabsPrimitive.Trigger> {
7
+ /**
8
+ * An icon before the label, such as a 16px Lucide icon. It is sized, coloured with the label (muted, then the active
9
+ * colour when selected) and hidden from screen readers. For an icon-only tab, leave out the label and pass `aria-label`.
10
+ */
11
+ icon?: ReactNode;
12
+ }
13
+ export declare function TabsTrigger({ className, children, value, icon, ...props }: TabsTriggerProps): import("react").JSX.Element;
7
14
  export declare function TabsContent({ className, value, forceMount, children, ...props }: ComponentPropsWithoutRef<typeof TabsPrimitive.Content>): import("react").JSX.Element;
8
15
  export {};
@@ -78,11 +78,13 @@ export function TabsList({ className, ...props }) {
78
78
  return _jsxs("div", { ref: shell, className: styles.listShell, "data-overflow": edges.overflow, "data-left": edges.left, "data-right": edges.right, children: [edges.overflow && _jsx("button", { type: "button", className: `${styles.scrollButton} ${styles.scrollLeft}`, "aria-label": "Scroll tabs left", disabled: !edges.left, onClick: () => scrollTabs(-1), children: _jsx(NavArrowLeft, { width: 17, height: 17, "aria-hidden": "true" }) }), _jsx(motion.div, { ref: viewport, layoutScroll: true, className: styles.viewport, onFocusCapture: event => { if (event.target instanceof HTMLElement && event.target.getAttribute("role") === "tab")
79
79
  reveal(event.target); }, children: _jsx(TabsPrimitive.List, { ...props, ref: list, className: [styles.list, className].filter(Boolean).join(" ") }) }), edges.overflow && _jsx("button", { type: "button", className: `${styles.scrollButton} ${styles.scrollRight}`, "aria-label": "Scroll tabs right", disabled: !edges.right, onClick: () => scrollTabs(1), children: _jsx(NavArrowRight, { width: 17, height: 17, "aria-hidden": "true" }) })] });
80
80
  }
81
- export function TabsTrigger({ className, children, value, ...props }) {
81
+ export function TabsTrigger({ className, children, value, icon, ...props }) {
82
82
  const { active } = useContext(TabsContext);
83
83
  const reduced = useReducedMotion();
84
84
  // The LayoutGroup in Tabs scopes the highlight to this instance, so it glides between triggers but never flies in from another tab set.
85
- return _jsxs(TabsPrimitive.Trigger, { ...props, value: value, "data-value": value, className: [styles.trigger, className].filter(Boolean).join(" "), children: [active === value && _jsx(motion.span, { className: styles.selection, layoutId: "selection", layoutDependency: active, transition: reduced ? { duration: 0 } : motionTokens.spring.morph, "aria-hidden": "true" }), _jsx("span", { className: styles.triggerLabel, children: children })] });
85
+ // An icon with no label is a square tab instead of a text tab's minimum width.
86
+ const iconOnly = !!icon && (children === undefined || children === null || children === false);
87
+ return _jsxs(TabsPrimitive.Trigger, { ...props, value: value, "data-value": value, "data-icon-only": iconOnly || undefined, className: [styles.trigger, className].filter(Boolean).join(" "), children: [active === value && _jsx(motion.span, { className: styles.selection, layoutId: "selection", layoutDependency: active, transition: reduced ? { duration: 0 } : motionTokens.spring.morph, "aria-hidden": "true" }), _jsxs("span", { className: styles.triggerLabel, children: [icon ? _jsx("span", { className: styles.icon, "aria-hidden": "true", children: icon }) : null, children] })] });
86
88
  }
87
89
  const panelMotion = {
88
90
  enter: (direction) => ({ opacity: 0, x: direction * 8 }),
@@ -13,11 +13,16 @@
13
13
  .scrollRight { right: 0; border-radius: 0 var(--radius-control) var(--radius-control) 0; }
14
14
  .scrollButton:disabled { opacity: 0; pointer-events: none; }
15
15
  .scrollButton:focus-visible { --focus-outline-offset: -3px; }
16
- .trigger { position: relative; -webkit-tap-highlight-color: transparent; display: inline-grid; min-width: 5.5rem; place-items: center; flex: 0 0 auto; min-height: var(--control-height-sm); border: 0; border-radius: calc(var(--radius-control) - 3px); padding: 0 var(--space-group); background: transparent; color: var(--text-muted); font: inherit; font-size: var(--text-sm); font-weight: 500; white-space: nowrap; cursor: pointer; transition: color var(--duration-fast) var(--ease-standard); }
16
+ .trigger { position: relative; -webkit-tap-highlight-color: transparent; display: inline-grid; min-width: 5.5rem; place-items: center; flex: 0 0 auto; min-height: var(--control-height-sm); border: 0; border-radius: calc(var(--radius-control) - var(--space-tight)); padding: 0 var(--space-group); background: transparent; color: var(--text-muted); font: inherit; font-size: var(--text-sm); font-weight: 500; white-space: nowrap; cursor: pointer; transition: color var(--duration-fast) var(--ease-standard); }
17
17
  @media (hover: hover) and (pointer: fine) { .trigger:hover { color: var(--foreground); } }
18
18
  .trigger:active { color: var(--foreground); }.trigger[data-state="active"] { color: var(--accent-strong); }
19
19
  .selection { position: absolute; z-index: -1; inset: 0; border: 1px solid var(--border); border-radius: inherit; corner-shape: inherit; background: var(--surface); box-shadow: var(--shadow-resting); will-change: transform; }
20
- .triggerLabel { position: relative; z-index: 1; }
20
+ .triggerLabel { position: relative; z-index: 1; display: inline-flex; align-items: center; gap: var(--space-related); }
21
+ /* An icon before the label: one size for every tab set, coloured with the label so it follows hover and selection. */
22
+ .icon { display: inline-grid; flex: none; place-items: center; color: currentColor; }
23
+ .icon svg { width: 16px; height: 16px; }
24
+ /* Icon-only tabs are square, the height of the strip's controls. */
25
+ .trigger[data-icon-only] { min-width: var(--control-height-sm); padding: 0; }
21
26
  .trigger:disabled { cursor: not-allowed; opacity: .5; }
22
27
  .content { margin-top: var(--space-inset); color: var(--text-secondary); font-size: var(--text-sm); line-height: var(--leading-body); }
23
28
  /* The outgoing panel is lifted out of flow by the presence animation; drop its margin so it stays in place and ignore stray clicks. */
@@ -7,18 +7,18 @@
7
7
  @media (hover: hover) and (pointer: fine) { .control:hover:not(:focus-within) { border-color: var(--border-strong); } }
8
8
  .control:focus-within { border-color: var(--foreground); box-shadow: 0 0 0 3px var(--focus-ring); outline: 2px solid transparent; outline-offset: 2px; }
9
9
  /* Equal 7px padding makes one row fill the minimum height exactly, so existing tags hold their line when a second row opens. */
10
- .content { position: relative; display: flex; flex-wrap: wrap; align-items: center; align-content: flex-start; gap: 6px; min-height: calc(var(--control-height-md) - 2px); box-sizing: border-box; padding: 7px; cursor: text; }
11
- .tag { position: relative; display: inline-flex; align-items: center; gap: 3px; min-height: 28px; box-sizing: border-box; border: 1px solid var(--border); border-radius: var(--radius-full); corner-shape: round; padding: 0 4px 0 9px; background: var(--surface-muted); color: var(--foreground); font-size: var(--text-sm); white-space: nowrap; cursor: default; }
10
+ .content { position: relative; display: flex; flex-wrap: wrap; align-items: center; align-content: flex-start; gap: var(--space-related); min-height: calc(var(--control-height-md) - 2px); box-sizing: border-box; padding: var(--space-related); cursor: text; }
11
+ .tag { position: relative; display: inline-flex; align-items: center; gap: var(--space-tight); min-height: 28px; box-sizing: border-box; border: 1px solid var(--border); border-radius: var(--radius-full); corner-shape: round; padding: 0 var(--space-tight) 0 var(--space-related); background: var(--surface-muted); color: var(--foreground); font-size: var(--text-sm); white-space: nowrap; cursor: default; }
12
12
  .tag button { display: grid; width: 22px; height: 22px; place-items: center; border: 0; border-radius: 50%; corner-shape: round; background: transparent; color: var(--text-secondary); cursor: pointer; transition: background-color var(--duration-fast) var(--ease-standard), color var(--duration-fast) var(--ease-standard), transform var(--duration-spring) var(--ease-spring); }
13
13
  @media (hover: hover) and (pointer: fine) { .tag button:hover { background: var(--surface); color: var(--foreground); } }
14
14
  .tag button:focus-visible { background: var(--surface); color: var(--foreground); outline: none; box-shadow: inset 0 0 0 1.5px var(--focus-ring); }
15
15
  /* Quick press, spring release. */
16
16
  .tag button:active { transform: scale(.96); transition: background-color var(--duration-fast) var(--ease-standard), color var(--duration-fast) var(--ease-standard), transform var(--duration-instant) var(--ease-standard); }
17
- .content input { flex: 1 1 100px; min-width: 80px; min-height: 28px; box-sizing: border-box; border: 0; padding: 0 5px; background: transparent; color: var(--foreground); font: inherit; font-size: var(--text-sm); }
17
+ .content input { flex: 1 1 100px; min-width: 80px; min-height: 28px; box-sizing: border-box; border: 0; padding: 0 var(--space-tight); background: transparent; color: var(--foreground); font: inherit; font-size: var(--text-sm); }
18
18
  .content input:focus, .content input:focus-visible { outline: none; }
19
19
  .content input::placeholder { color: transparent; }
20
20
  /* The visible placeholder is drawn here so it can rise in when the last tag leaves. The native one stays for assistive tech. Inset matches the content and input padding. */
21
- .placeholder { position: absolute; inset: 0; display: flex; align-items: center; overflow: hidden; padding: 0 12px; color: var(--text-muted); font-size: var(--text-sm); white-space: nowrap; pointer-events: none; }
21
+ .placeholder { position: absolute; inset: 0; display: flex; align-items: center; overflow: hidden; padding: 0 var(--space-group); color: var(--text-muted); font-size: var(--text-sm); white-space: nowrap; pointer-events: none; }
22
22
  /* The pick ring rides above the pills and sizes itself to the picked tag, so it can glide between tags without scaling its border. */
23
23
  .ring { position: absolute; top: 0; left: 0; z-index: 1; box-sizing: border-box; border: 1px solid var(--accent); border-radius: var(--radius-full); corner-shape: round; background: var(--accent-subtle); opacity: 0; pointer-events: none; }
24
24
  /* A resting tag is not a stacking context (its filter ends at none), so its label and button sit above the ring while its fill stays below. */
@@ -2,7 +2,7 @@
2
2
  .label { font-size: var(--text-sm); font-weight: 500; line-height: var(--leading-body); }
3
3
  .anchor { position: relative; min-width: 0; }
4
4
  /* The trigger anchors the menu, so press feedback stays in color; it never scales. */
5
- .trigger { position: relative; display: flex; width: 100%; min-height: var(--control-height-md); align-items: center; gap: 9px; border: 1px solid var(--border); border-radius: var(--radius-control); corner-shape: var(--corner-shape); padding: 0 12px; background: var(--surface); color: var(--foreground); font: inherit; font-size: var(--text-sm); text-align: left; cursor: pointer; transition: border-color var(--duration-fast) var(--ease-standard), background-color var(--duration-fast) var(--ease-standard), box-shadow var(--duration-fast) var(--ease-standard); }
5
+ .trigger { position: relative; display: flex; width: 100%; min-height: var(--control-height-md); align-items: center; gap: var(--space-related); border: 1px solid var(--border); border-radius: var(--radius-control); corner-shape: var(--corner-shape); padding: 0 var(--space-group); background: var(--surface); color: var(--foreground); font: inherit; font-size: var(--text-sm); text-align: left; cursor: pointer; transition: border-color var(--duration-fast) var(--ease-standard), background-color var(--duration-fast) var(--ease-standard), box-shadow var(--duration-fast) var(--ease-standard); }
6
6
  @media (hover: hover) and (pointer: fine) { .trigger:hover:not(:disabled) { border-color: var(--border-strong); background: var(--surface-muted); } }
7
7
  .trigger:active:not(:disabled), .trigger[aria-expanded="true"] { border-color: var(--border-strong); background: var(--surface-muted); }
8
8
  .trigger:disabled { opacity: .5; cursor: not-allowed; }
@@ -15,9 +15,9 @@
15
15
  .chevron { flex: 0 0 auto; color: var(--text-muted); transition: transform var(--duration-spring) var(--ease-spring); }
16
16
  .trigger[aria-expanded="true"] .chevron { transform: rotate(180deg); }
17
17
  .description { font-size: var(--text-xs); }
18
- .menu { position: absolute; z-index: 80; top: calc(100% + 6px); right: 0; left: 0; max-height: 250px; overflow-y: auto; overscroll-behavior: contain; border: 1px solid var(--border); border-radius: var(--radius-container); corner-shape: var(--corner-shape); padding: 5px; background: var(--surface-raised); box-shadow: var(--shadow-floating); transform-origin: top center; will-change: transform, opacity; }
18
+ .menu { position: absolute; z-index: var(--layer-dropdown); top: calc(100% + var(--space-related)); right: 0; left: 0; max-height: 250px; overflow-y: auto; overscroll-behavior: contain; border: 1px solid var(--border); border-radius: var(--radius-container); corner-shape: var(--corner-shape); padding: var(--space-tight); background: var(--surface-raised); box-shadow: var(--shadow-floating); transform-origin: top center; will-change: transform, opacity; }
19
19
  /* Arrow keys move the highlight often, so it changes almost instantly. The dot marks the chosen time, so only one row is ever highlighted. */
20
- .option { display: flex; width: 100%; min-height: 36px; align-items: center; justify-content: space-between; border: 0; border-radius: calc(var(--radius-container) - 5px); corner-shape: var(--corner-shape); padding: 0 12px; background: transparent; color: var(--foreground); font: inherit; font-size: var(--text-sm); font-variant-numeric: tabular-nums; text-align: left; cursor: pointer; transition: background-color 80ms var(--ease-standard); }
20
+ .option { display: flex; width: 100%; min-height: 36px; align-items: center; justify-content: space-between; border: 0; border-radius: calc(var(--radius-container) - var(--space-tight)); corner-shape: var(--corner-shape); padding: 0 var(--space-group); background: transparent; color: var(--foreground); font: inherit; font-size: var(--text-sm); font-variant-numeric: tabular-nums; text-align: left; cursor: pointer; transition: background-color 80ms var(--ease-standard); }
21
21
  .option[data-active="true"] { background: var(--surface-muted); }
22
22
  .dot { width: 6px; height: 6px; border-radius: var(--radius-full); corner-shape: round; background: var(--foreground); }
23
23
  @media (prefers-reduced-motion: reduce) { .trigger, .chevron, .option { transition: none; } }
@@ -28,14 +28,14 @@
28
28
  .marker[data-tone="danger"] { background: color-mix(in oklab, var(--danger) 12%, var(--surface)); color: var(--danger); }
29
29
  .marker svg { width: 14px; height: 14px; stroke-width: 2; }
30
30
  /* The line runs from just under this marker to just above the next one and draws downward from its top. */
31
- .segment { position: absolute; top: calc(var(--marker-top) + var(--marker) + var(--line-gap)); bottom: calc(var(--line-gap) - var(--marker-top)); left: calc(var(--marker) / 2 - .5px); width: 1px; background: var(--border-strong); transform-origin: 50% 0; }
31
+ .segment { position: absolute; top: calc(var(--marker-top) + var(--marker) + var(--line-gap)); bottom: calc(var(--line-gap) - var(--marker-top)); left: calc(var(--marker) / 2 - var(--space-hair)); width: 1px; background: var(--border-strong); transform-origin: 50% 0; }
32
32
 
33
33
  .content { min-width: 0; }
34
- .trigger { display: grid; width: 100%; grid-template-columns: minmax(0, 1fr) auto; align-items: start; column-gap: var(--space-group); margin: 0; padding: 12px var(--space-group); border: 0; border-radius: var(--radius-control); corner-shape: var(--corner-shape); background: transparent; color: inherit; font: inherit; text-align: left; -webkit-tap-highlight-color: transparent; transition: background-color var(--duration-fast) var(--ease-standard); }
34
+ .trigger { display: grid; width: 100%; grid-template-columns: minmax(0, 1fr) auto; align-items: start; column-gap: var(--space-group); margin: 0; padding: var(--space-group) var(--space-group); border: 0; border-radius: var(--radius-control); corner-shape: var(--corner-shape); background: transparent; color: inherit; font: inherit; text-align: left; -webkit-tap-highlight-color: transparent; transition: background-color var(--duration-fast) var(--ease-standard); }
35
35
  button.trigger { grid-template-columns: minmax(0, 1fr) auto 16px; cursor: pointer; }
36
36
  @media (hover: hover) and (pointer: fine) { button.trigger:hover { background: var(--surface-muted); } }
37
37
  button.trigger:active { background: var(--surface-muted); }
38
- .text { display: grid; min-width: 0; gap: 2px; }
38
+ .text { display: grid; min-width: 0; gap: var(--space-hair); }
39
39
  .title { color: var(--text-secondary); font-size: var(--text-sm); line-height: 20px; }
40
40
  .actor { color: var(--foreground); font-weight: 500; }
41
41
  .meta { color: var(--text-muted); font-size: var(--text-xs); line-height: var(--leading-body); }
@@ -3,8 +3,8 @@
3
3
  width: min(100%, 26rem);
4
4
  min-width: 0;
5
5
  align-items: flex-start;
6
- gap: 0.75rem;
7
- padding: 0.875rem 0.875rem 0.875rem 1rem;
6
+ gap: var(--space-group);
7
+ padding: var(--space-inset) var(--space-inset) var(--space-inset) var(--space-inset);
8
8
  border: 1px solid var(--border);
9
9
  border-radius: var(--radius-container); corner-shape: var(--corner-shape);
10
10
  background: color-mix(in oklab, var(--surface) 94%, var(--background));
@@ -35,9 +35,9 @@
35
35
  position: relative;
36
36
  display: grid;
37
37
  min-width: 0;
38
- gap: 0.125rem;
38
+ gap: var(--space-hair);
39
39
  /* Centers the title's first line on the 30px status icon. */
40
- padding-top: 0.3125rem;
40
+ padding-top: var(--space-tight);
41
41
  }
42
42
 
43
43
  .title {
@@ -69,7 +69,7 @@
69
69
  height: 2rem;
70
70
  flex: 0 0 auto;
71
71
  place-items: center;
72
- margin: -0.0625rem -0.125rem 0 0;
72
+ margin: calc(var(--space-hair) * -1) calc(var(--space-hair) * -1) 0 0;
73
73
  border: 0;
74
74
  border-radius: var(--radius-full); corner-shape: round;
75
75
  background: transparent;
@@ -1,5 +1,5 @@
1
1
  /* The region only holds the list; it never blocks clicks outside the toasts themselves. */
2
- .viewport { position: fixed; z-index: 60; bottom: var(--space-section); width: min(22.5rem, calc(100% - var(--space-block))); pointer-events: none; }
2
+ .viewport { position: fixed; z-index: var(--layer-toast); bottom: var(--space-section); width: min(22.5rem, calc(100% - var(--space-block))); pointer-events: none; }
3
3
  .bottom-right { right: var(--space-section); }
4
4
  .bottom-left { left: var(--space-section); }
5
5
  .bottom-center { right: 0; left: 0; margin-inline: auto; }
@@ -32,14 +32,14 @@
32
32
  .copy { position: relative; min-width: 0; flex: 1; font-size: var(--text-sm); letter-spacing: var(--tracking-body); line-height: 20px; }
33
33
  .title { position: relative; display: block; font-weight: 500; }
34
34
  .line { display: block; }
35
- .description { display: block; margin-top: 2px; color: var(--text-secondary); }
35
+ .description { display: block; margin-top: var(--space-hair); color: var(--text-secondary); }
36
36
 
37
37
  /* Clips only while its width folds, so the focus ring stays whole at rest. */
38
- .actionSlot { display: flex; flex: none; justify-content: flex-end; margin-top: -4px; }
38
+ .actionSlot { display: flex; flex: none; justify-content: flex-end; margin-top: calc(var(--space-tight) * -1); }
39
39
  .actionSlot[data-moving="true"] { overflow: hidden; }
40
40
  .action, .close { flex: none; border: 1px solid transparent; font: inherit; cursor: pointer; -webkit-tap-highlight-color: transparent; transition: scale var(--duration-spring) var(--ease-spring), background-color var(--duration-fast) var(--ease-standard), border-color var(--duration-fast) var(--ease-standard), color var(--duration-fast) var(--ease-standard); }
41
41
  .action { height: 28px; padding: 0 var(--space-group); border-color: var(--border); border-radius: var(--radius-full); corner-shape: round; background: var(--surface); color: var(--foreground); font-size: var(--text-sm); font-weight: 500; white-space: nowrap; }
42
- .close { display: grid; width: 28px; height: 28px; margin: -4px -2px 0 0; place-items: center; border-radius: var(--radius-full); corner-shape: round; background: transparent; color: var(--text-muted); }
42
+ .close { display: grid; width: 28px; height: 28px; margin: calc(var(--space-tight) * -1) calc(var(--space-hair) * -1) 0 0; place-items: center; border-radius: var(--radius-full); corner-shape: round; background: transparent; color: var(--text-muted); }
43
43
  @media (hover: hover) and (pointer: fine) {
44
44
  .action:hover { border-color: var(--border-strong); background: var(--surface-muted); }
45
45
  .close:hover { background: var(--surface-muted); color: var(--foreground); }
@@ -49,7 +49,7 @@
49
49
  /* A narrow toast keeps its copy wide: the action drops under the copy instead of squeezing it. */
50
50
  @container (max-width: 21rem) {
51
51
  .content { flex-wrap: wrap; row-gap: var(--space-related); }
52
- .actionSlot { order: 1; flex-basis: 100%; justify-content: flex-start; margin-top: 0; padding-left: calc(18px + var(--space-group)); }
52
+ .actionSlot { order: 1; flex-basis: 100%; justify-content: flex-start; margin-top: 0; padding-left: calc(var(--space-comfort) + var(--space-group)); }
53
53
  }
54
54
  .srOnly { position: absolute; width: 1px; height: 1px; overflow: hidden; clip-path: inset(50%); white-space: nowrap; }
55
55
 
@@ -1,4 +1,4 @@
1
- .tooltip { --tooltip-y: 3px; z-index: 90; max-width: 15rem; padding: var(--space-group) var(--space-inset); border: 1px solid color-mix(in oklab, var(--background) 14%, var(--foreground)); border-radius: var(--radius-control); background: var(--foreground); color: var(--background); box-shadow: var(--shadow-raised); font-size: var(--text-sm); font-weight: 400; line-height: var(--leading-body); transform-origin: var(--radix-tooltip-content-transform-origin); transition: opacity var(--duration-fast) var(--ease-enter), transform var(--duration-fast) var(--ease-enter); }
1
+ .tooltip { --tooltip-y: 3px; z-index: var(--layer-tooltip); max-width: 15rem; padding: var(--space-group) var(--space-inset); border: 1px solid color-mix(in oklab, var(--background) 14%, var(--foreground)); border-radius: var(--radius-control); background: var(--foreground); color: var(--background); box-shadow: var(--shadow-raised); font-size: var(--text-sm); font-weight: 400; line-height: var(--leading-body); transform-origin: var(--radix-tooltip-content-transform-origin); transition: opacity var(--duration-fast) var(--ease-enter), transform var(--duration-fast) var(--ease-enter); }
2
2
  .tooltip[data-side="bottom"] { --tooltip-y: -3px; }
3
3
  /* The first tooltip waits, then rises a few pixels from its trigger. Within the skip window the next one only fades.
4
4
  Transitions instead of keyframes, so returning to the trigger while it fades out reverses the fade instead of restarting it. */
@@ -1,21 +1,21 @@
1
- .tree { display: block; width: 100%; min-width: 0; box-sizing: border-box; padding: 6px 8px 8px; border: 1px solid var(--border); border-radius: var(--radius-control); background: var(--surface); color: var(--foreground); overflow: hidden; }
1
+ .tree { display: block; width: 100%; min-width: 0; box-sizing: border-box; padding: var(--space-related) var(--space-related) var(--space-related); border: 1px solid var(--border); border-radius: var(--radius-control); background: var(--surface); color: var(--foreground); overflow: hidden; }
2
2
  /* Rows clip only while their height animates (Motion sets overflow), so the selection can glide between them unclipped. */
3
3
  .row { position: relative; display: flow-root; min-width: 0; height: 38px; }
4
- .item { position: relative; display: flex; width: 100%; min-width: 0; height: 36px; margin-top: 2px; align-items: center; gap: 8px; padding: 0 10px; padding-left: calc(10px + (var(--tree-depth) - 1) * 18px); border: 0; border-radius: var(--radius-detail); background: transparent; color: var(--text-secondary); font: inherit; font-size: var(--text-sm); line-height: 1; text-align: left; cursor: pointer; outline: none; transition: color var(--duration-fast) var(--ease-standard), background-color var(--duration-fast) var(--ease-standard); }
4
+ .item { position: relative; display: flex; width: 100%; min-width: 0; height: 36px; margin-top: var(--space-hair); align-items: center; gap: var(--space-related); padding: 0 var(--space-group); padding-left: calc(var(--space-group) + (var(--tree-depth) - 1) * var(--space-comfort)); border: 0; border-radius: var(--radius-detail); background: transparent; color: var(--text-secondary); font: inherit; font-size: var(--text-sm); line-height: 1; text-align: left; cursor: pointer; outline: none; transition: color var(--duration-fast) var(--ease-standard), background-color var(--duration-fast) var(--ease-standard); }
5
5
  /* Selection changes color only; a heavier weight would reflow the label. */
6
6
  .item[aria-selected="true"] { color: var(--foreground); }
7
7
  .selection { position: absolute; inset: 0; z-index: 0; border-radius: var(--radius-detail); background: var(--surface-muted); }
8
- .branch { position: absolute; top: 4px; bottom: 4px; left: calc(16.5px + (var(--tree-depth) - 2) * 18px); z-index: 1; width: 1px; background: var(--border); transform-origin: top; pointer-events: none; }
8
+ .branch { position: absolute; top: var(--space-tight); bottom: var(--space-tight); left: calc(var(--space-inset) + (var(--tree-depth) - 2) * var(--space-comfort)); z-index: 1; width: 1px; background: var(--border); transform-origin: top; pointer-events: none; }
9
9
  .disclosure, .icon, .label { position: relative; z-index: 1; }
10
10
  .disclosure { display: grid; width: 14px; height: 16px; flex: 0 0 14px; place-items: center; color: var(--text-muted); }
11
11
  .icon { display: grid; width: 16px; height: 16px; flex: 0 0 16px; place-items: center; color: var(--text-muted); transition: color var(--duration-fast) var(--ease-standard); }
12
12
  .folder { color: var(--text-secondary); }
13
13
  .item[aria-expanded="true"] .folder, .item[aria-selected="true"] .folder { color: var(--foreground); }
14
14
  .folderGlyph { position: absolute; inset: 0; display: grid; place-items: center; }
15
- .typescript { color: color-mix(in oklab, #3178c6 78%, var(--foreground)); }
16
- .stylesheet { color: color-mix(in oklab, #8b6ace 73%, var(--foreground)); }
17
- .markdown { color: color-mix(in oklab, #38896b 74%, var(--foreground)); }
18
- .json { color: color-mix(in oklab, #c48637 78%, var(--foreground)); }
15
+ .typescript { color: color-mix(in oklab, var(--file-typescript) 78%, var(--foreground)); }
16
+ .stylesheet { color: color-mix(in oklab, var(--file-stylesheet) 73%, var(--foreground)); }
17
+ .markdown { color: color-mix(in oklab, var(--file-markdown) 74%, var(--foreground)); }
18
+ .json { color: color-mix(in oklab, var(--file-json) 78%, var(--foreground)); }
19
19
  /* Its own line height: the row sets 1, and the clipped box (needed for the ellipsis) would cut descenders like g. */
20
20
  .label { min-width: 0; overflow: hidden; line-height: 1.45; text-overflow: ellipsis; white-space: nowrap; }
21
21
  @media (hover: hover) and (pointer: fine) { .item:hover { background: var(--surface-muted); color: var(--foreground); } }
@@ -5,32 +5,32 @@
5
5
  /* Breadcrumb on the left, the total of what fills the view on the right. */
6
6
  .bar { display: flex; min-width: 0; align-items: center; justify-content: space-between; gap: var(--space-group); }
7
7
  /* Pull the trail back by the crumb padding, so the first label lines up with the tiles and the title. */
8
- .crumbs { min-width: 0; margin-left: -4px; }
8
+ .crumbs { min-width: 0; margin-left: calc(var(--space-tight) * -1); }
9
9
  .crumbList { position: relative; display: flex; min-width: 0; min-height: 32px; flex-wrap: wrap; align-items: center; margin: 0; padding: 0; list-style: none; }
10
10
  .crumb { display: inline-flex; align-items: center; min-width: 0; }
11
- .crumbSep { padding: 0 4px; color: var(--border-strong); font-size: var(--text-sm); }
12
- .crumbButton { min-height: 32px; padding: 0 6px; margin: 0 -2px; border: 0; border-radius: var(--radius-detail); background: transparent; color: var(--text-secondary); cursor: pointer; font: inherit; font-size: var(--text-sm); line-height: var(--leading-body); white-space: nowrap; -webkit-tap-highlight-color: transparent; transition: color var(--duration-fast) var(--ease-standard), background-color var(--duration-fast) var(--ease-standard), transform var(--duration-instant) var(--ease-standard); }
11
+ .crumbSep { padding: 0 var(--space-tight); color: var(--border-strong); font-size: var(--text-sm); }
12
+ .crumbButton { min-height: 32px; padding: 0 var(--space-related); margin: 0 calc(var(--space-hair) * -1); border: 0; border-radius: var(--radius-detail); background: transparent; color: var(--text-secondary); cursor: pointer; font: inherit; font-size: var(--text-sm); line-height: var(--leading-body); white-space: nowrap; -webkit-tap-highlight-color: transparent; transition: color var(--duration-fast) var(--ease-standard), background-color var(--duration-fast) var(--ease-standard), transform var(--duration-instant) var(--ease-standard); }
13
13
  .crumbButton:active { transform: scale(.97); }
14
- .crumbCurrent { padding: 0 4px; color: var(--foreground); font-size: var(--text-sm); font-weight: 500; line-height: var(--leading-body); white-space: nowrap; }
14
+ .crumbCurrent { padding: 0 var(--space-tight); color: var(--foreground); font-size: var(--text-sm); font-weight: 500; line-height: var(--leading-body); white-space: nowrap; }
15
15
  @media (hover: hover) and (pointer: fine) { .crumbButton:hover { background: color-mix(in oklab, var(--foreground) 5%, transparent); color: var(--foreground); } }
16
16
  .total { position: relative; display: inline-grid; flex: none; justify-items: end; overflow: hidden; margin: 0; color: var(--foreground); font-size: var(--text-sm); font-weight: 500; line-height: var(--leading-body); font-variant-numeric: tabular-nums; }
17
17
  .totalValue { display: block; }
18
18
 
19
19
  /* Tiles are absolutely placed and sized each frame, so text never scales while a tile grows or shrinks. */
20
20
  .stage { position: relative; min-width: 0; overflow: hidden; border-radius: var(--radius-control); outline: none; user-select: none; -webkit-user-select: none; -webkit-tap-highlight-color: transparent; }
21
- .tile { position: absolute; top: 0; left: 0; display: flex; flex-direction: column; gap: 1px; overflow: hidden; padding: 6px 8px; border-radius: var(--radius-detail); background: var(--fill); color: var(--foreground); cursor: pointer; visibility: hidden; will-change: transform, width, height; transition: background-color var(--duration-considered) var(--ease-standard), color var(--duration-considered) var(--ease-standard), filter var(--duration-fast) var(--ease-standard), box-shadow var(--duration-fast) var(--ease-standard); }
22
- .tile[data-branch][data-level="1"] { padding: 3px 8px; border-radius: var(--radius-detail); background: color-mix(in oklab, var(--hue) 9%, var(--surface)); color: var(--foreground); cursor: zoom-in; }
21
+ .tile { position: absolute; top: 0; left: 0; display: flex; flex-direction: column; gap: 1px; overflow: hidden; padding: var(--space-related) var(--space-related); border-radius: var(--radius-detail); background: var(--fill); color: var(--foreground); cursor: pointer; visibility: hidden; will-change: transform, width, height; transition: background-color var(--duration-considered) var(--ease-standard), color var(--duration-considered) var(--ease-standard), filter var(--duration-fast) var(--ease-standard), box-shadow var(--duration-fast) var(--ease-standard); }
22
+ .tile[data-branch][data-level="1"] { padding: var(--space-tight) var(--space-related); border-radius: var(--radius-detail); background: color-mix(in oklab, var(--hue) 9%, var(--surface)); color: var(--foreground); cursor: zoom-in; }
23
23
  .tileLabel, .tileValue { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; font-size: var(--text-xs); line-height: 16px; opacity: 0; transition: opacity var(--duration-fast) var(--ease-standard); }
24
24
  .tileLabel { font-weight: 500; }
25
25
  .tileValue { opacity: 0; font-variant-numeric: tabular-nums; }
26
26
  .tile[data-room="name"] .tileLabel, .tile[data-room="full"] .tileLabel, .tile[data-room="full"] .tileValue { opacity: 1; }
27
27
  .tile[data-room="full"] .tileValue { opacity: .72; }
28
28
  /* A branch on the top level prints its name and total on one header line. */
29
- .tile[data-branch][data-level="1"] { flex-direction: row; align-items: baseline; justify-content: space-between; gap: 8px; }
29
+ .tile[data-branch][data-level="1"] { flex-direction: row; align-items: baseline; justify-content: space-between; gap: var(--space-related); }
30
30
  .tile[data-branch][data-level="1"] .tileValue { flex: none; opacity: .6; }
31
31
  .tile[data-branch][data-level="1"][data-room="none"] .tileLabel, .tile[data-branch][data-level="1"][data-room="none"] .tileValue { opacity: 0; }
32
32
  .tile[data-branch][data-level="1"][data-room="name"] .tileValue { opacity: .6; }
33
- .tile[data-level="2"] { padding: 5px 7px; }
33
+ .tile[data-level="2"] { padding: var(--space-tight) var(--space-related); }
34
34
 
35
35
  .tile[data-active] { box-shadow: inset 0 0 0 2px var(--foreground); }
36
36
  .tile[data-lineage] { box-shadow: inset 0 0 0 1px color-mix(in oklab, var(--hue) 70%, transparent); }
@@ -38,18 +38,18 @@
38
38
 
39
39
  .message { position: absolute; inset: 0; display: grid; place-items: center; margin: 0; color: var(--text-muted); font-size: var(--text-sm); pointer-events: none; }
40
40
 
41
- .tooltip { position: absolute; top: 0; left: 0; z-index: 50; display: grid; min-width: 160px; max-width: min(240px, 100%); grid-template-columns: minmax(0, 1fr); gap: 2px; padding: 10px 12px; border: 1px solid var(--border); border-radius: var(--radius-control); background: var(--surface-raised); box-shadow: var(--shadow-floating); opacity: 0; pointer-events: none; scale: .96; transition: opacity var(--duration-fast) var(--ease-standard), scale var(--duration-fast) var(--ease-standard); }
41
+ .tooltip { position: absolute; top: 0; left: 0; z-index: var(--layer-tooltip); display: grid; min-width: 160px; max-width: min(240px, 100%); grid-template-columns: minmax(0, 1fr); gap: var(--space-hair); padding: var(--space-group) var(--space-group); border: 1px solid var(--border); border-radius: var(--radius-control); background: var(--surface-raised); box-shadow: var(--shadow-floating); opacity: 0; pointer-events: none; scale: .96; transition: opacity var(--duration-fast) var(--ease-standard), scale var(--duration-fast) var(--ease-standard); }
42
42
  .stage[data-active] .tooltip { opacity: 1; scale: 1; }
43
43
  .tipTitle { margin: 0; overflow: hidden; color: var(--text-muted); font-size: var(--text-xs); line-height: var(--leading-body); text-overflow: ellipsis; white-space: nowrap; }
44
- .tipValue { display: flex; align-items: baseline; justify-content: space-between; gap: 12px; margin: 0; font-size: var(--text-sm); line-height: 1.35; }
44
+ .tipValue { display: flex; align-items: baseline; justify-content: space-between; gap: var(--space-group); margin: 0; font-size: var(--text-sm); line-height: 1.35; }
45
45
  .tipName { min-width: 0; overflow: hidden; color: var(--foreground); text-overflow: ellipsis; white-space: nowrap; }
46
46
  .tipAmount { flex: none; color: var(--foreground); font-weight: 500; font-variant-numeric: tabular-nums; }
47
47
  .tipNote { margin: 0; color: var(--text-muted); font-size: var(--text-xs); line-height: var(--leading-body); font-variant-numeric: tabular-nums; }
48
48
 
49
49
  /* The color scale: stepped swatches from light to dark, never a gradient. */
50
- .scale { display: flex; min-width: 0; flex-wrap: wrap; align-items: center; gap: 8px; color: var(--text-muted); font-size: var(--text-xs); line-height: var(--leading-body); font-variant-numeric: tabular-nums; }
51
- .scaleLabel { margin-right: 4px; color: var(--text-secondary); }
52
- .steps { display: inline-flex; gap: 2px; }
50
+ .scale { display: flex; min-width: 0; flex-wrap: wrap; align-items: center; gap: var(--space-related); color: var(--text-muted); font-size: var(--text-xs); line-height: var(--leading-body); font-variant-numeric: tabular-nums; }
51
+ .scaleLabel { margin-right: var(--space-tight); color: var(--text-secondary); }
52
+ .steps { display: inline-flex; gap: var(--space-hair); }
53
53
  .step { width: 18px; height: 10px; border-radius: var(--radius-detail); background: var(--fill); }
54
54
 
55
55
  .srOnly { position: absolute; width: 1px; height: 1px; overflow: hidden; clip-path: inset(50%); white-space: nowrap; }
@@ -6,7 +6,7 @@
6
6
 
7
7
  /* The status mark hugs its words: its width springs to each message and grows from the right edge, so the text never slides. */
8
8
  .badge { display: inline-flex; flex: none; height: 28px; justify-content: flex-end; overflow: hidden; border-radius: var(--radius-full); corner-shape: round; background: var(--surface-muted); color: var(--text-secondary); font-size: var(--text-xs); font-weight: 500; line-height: 1; transition: background-color var(--duration-standard) var(--ease-standard), color var(--duration-standard) var(--ease-standard); }
9
- .badgeInner { display: inline-flex; flex: none; align-items: center; gap: 6px; padding: 0 var(--space-group); white-space: nowrap; }
9
+ .badgeInner { display: inline-flex; flex: none; align-items: center; gap: var(--space-related); padding: 0 var(--space-group); white-space: nowrap; }
10
10
  .badgeIcon { display: grid; place-items: center; }
11
11
  .badge[data-status="near"] { background: color-mix(in oklab, var(--warning) 14%, var(--surface)); color: var(--foreground); }
12
12
  .badge[data-status="near"] .badgeIcon { color: var(--warning); }
@@ -20,7 +20,7 @@
20
20
  .swapText { display: block; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
21
21
 
22
22
  /* The bar leaves room above and below the track for the limit marker. */
23
- .bar { position: relative; padding-block: 5px; }
23
+ .bar { position: relative; padding-block: var(--space-tight); }
24
24
  .track { position: relative; height: 14px; overflow: hidden; border-radius: var(--radius-full); corner-shape: round; background: color-mix(in oklab, var(--foreground) 7%, var(--surface)); isolation: isolate; -webkit-tap-highlight-color: transparent; }
25
25
  .segment { position: absolute; inset: 0; transition: opacity var(--duration-fast) var(--ease-standard); }
26
26
  .segment[data-index="0"], .swatch[data-index="0"] { background: var(--segment-0); }
@@ -36,8 +36,8 @@
36
36
  .limit { position: absolute; top: 0; bottom: 0; left: -1px; width: 2px; border-radius: var(--radius-full); corner-shape: round; background: var(--foreground); pointer-events: none; }
37
37
 
38
38
  /* The legend doubles as the keyboard path: arrow keys move between categories, focus previews one, a press pins it. */
39
- .legend { display: grid; grid-template-columns: repeat(auto-fit, minmax(108px, 1fr)); gap: 2px; margin: 0 calc(var(--space-related) * -1); }
40
- .item { display: grid; min-width: 0; justify-items: start; gap: 2px; padding: var(--space-related); border: 0; border-radius: calc(var(--radius-control) - 6px); corner-shape: var(--corner-shape); background: transparent; color: inherit; font: inherit; text-align: left; cursor: pointer; -webkit-tap-highlight-color: transparent; transition: background-color var(--duration-fast) var(--ease-standard), opacity var(--duration-fast) var(--ease-standard); }
39
+ .legend { display: grid; grid-template-columns: repeat(auto-fit, minmax(108px, 1fr)); gap: var(--space-hair); margin: 0 calc(var(--space-related) * -1); }
40
+ .item { display: grid; min-width: 0; justify-items: start; gap: var(--space-hair); padding: var(--space-related); border: 0; border-radius: calc(var(--radius-control) - var(--space-related)); corner-shape: var(--corner-shape); background: transparent; color: inherit; font: inherit; text-align: left; cursor: pointer; -webkit-tap-highlight-color: transparent; transition: background-color var(--duration-fast) var(--ease-standard), opacity var(--duration-fast) var(--ease-standard); }
41
41
  @media (hover: hover) and (pointer: fine) { .item:hover { background: var(--surface-muted); } }
42
42
  .item[aria-pressed="true"] { background: var(--surface-muted); }
43
43
  .item[data-highlight="off"] { opacity: .45; }
@@ -47,7 +47,7 @@
47
47
  .swatch { grid-area: 1 / 1; width: 10px; height: 10px; border-radius: var(--radius-detail); corner-shape: var(--corner-shape); }
48
48
  .swatch[data-index="free"] { background: color-mix(in oklab, var(--foreground) 7%, var(--surface)); box-shadow: inset 0 0 0 1px var(--border-strong); }
49
49
  .keyIcon { grid-area: 1 / 1; display: grid; place-items: center; color: var(--danger); }
50
- .itemValue { display: flex; align-items: baseline; gap: 4px; padding-left: 20px; color: var(--foreground); font-size: var(--text-base); font-weight: 500; line-height: var(--leading-body); }
50
+ .itemValue { display: flex; align-items: baseline; gap: var(--space-tight); padding-left: var(--space-comfort); color: var(--foreground); font-size: var(--text-base); font-weight: 500; line-height: var(--leading-body); }
51
51
  .itemUnit { color: var(--text-secondary); font-size: var(--text-sm); font-weight: 400; }
52
52
 
53
53
  /* A rolling number: each digit is a clipped wheel that feathers at its edges, and new columns open from zero width. */
@@ -1,17 +1,17 @@
1
1
  .root { position: relative; display: inline-flex; flex: none; vertical-align: middle; }
2
2
 
3
3
  /* The trigger anchors the menu, so it answers hover and press with color, never with scale. */
4
- .trigger { --presence-surface: var(--user-menu-surface, var(--surface)); position: relative; display: inline-flex; height: 40px; flex: none; align-items: center; gap: var(--space-related); margin: 0; padding: 4px; border: 0; border-radius: var(--radius-full); corner-shape: round; background: transparent; color: var(--foreground); font: inherit; font-family: var(--font-body); font-size: var(--text-sm); letter-spacing: var(--tracking-body); cursor: pointer; -webkit-tap-highlight-color: transparent; transition: background-color var(--duration-fast) var(--ease-standard); }
5
- .trigger[data-name] { padding-right: 10px; }
4
+ .trigger { --presence-surface: var(--user-menu-surface, var(--surface)); position: relative; display: inline-flex; height: 40px; flex: none; align-items: center; gap: var(--space-related); margin: 0; padding: var(--space-tight); border: 0; border-radius: var(--radius-full); corner-shape: round; background: transparent; color: var(--foreground); font: inherit; font-family: var(--font-body); font-size: var(--text-sm); letter-spacing: var(--tracking-body); cursor: pointer; -webkit-tap-highlight-color: transparent; transition: background-color var(--duration-fast) var(--ease-standard); }
5
+ .trigger[data-name] { padding-right: var(--space-group); }
6
6
  @media (hover: hover) and (pointer: fine) { .trigger:hover { --presence-surface: var(--surface-muted); background: var(--surface-muted); } }
7
7
  .trigger[data-state="open"] { --presence-surface: var(--surface-muted); background: var(--surface-muted); }
8
8
  .trigger:active { --presence-surface: color-mix(in oklab, var(--surface-muted), var(--foreground) 8%); background: color-mix(in oklab, var(--surface-muted), var(--foreground) 8%); }
9
9
  .triggerName { max-width: 11rem; overflow: hidden; font-weight: 500; line-height: 1; text-overflow: ellipsis; white-space: nowrap; }
10
- .chevron { flex: none; margin-left: -2px; color: var(--text-muted); transition: transform var(--duration-spring) var(--ease-spring), color var(--duration-fast) var(--ease-standard); }
10
+ .chevron { flex: none; margin-left: calc(var(--space-hair) * -1); color: var(--text-muted); transition: transform var(--duration-spring) var(--ease-spring), color var(--duration-fast) var(--ease-standard); }
11
11
  .trigger:hover .chevron, .trigger[data-state="open"] .chevron { color: var(--foreground); }
12
12
  .trigger[data-state="open"] .chevron { transform: rotate(180deg); }
13
13
  @media (max-width: 639px) {
14
- .trigger[data-name] { padding-right: 4px; }
14
+ .trigger[data-name] { padding-right: var(--space-tight); }
15
15
  .triggerName, .chevron { display: none; }
16
16
  }
17
17
 
@@ -34,19 +34,19 @@
34
34
  .dot[data-status="offline"] { --dot-color: var(--text-muted); }
35
35
 
36
36
  /* The panel scales out of the avatar it belongs to; the component sets the origin once it is placed. */
37
- .panel { --presence-surface: var(--surface-raised); --row: 32px; --inset: 4px; --menu-radius: var(--radius-detail); --menu-line: color-mix(in oklab, var(--foreground) 9%, transparent); position: fixed; top: 0; left: 0; z-index: 60; box-sizing: border-box; width: 15.5rem; max-width: calc(100vw - 24px); padding: var(--inset); border: .5px solid var(--border); border-radius: var(--menu-radius); background: var(--surface-raised); box-shadow: var(--shadow-floating); color: var(--foreground); font-family: var(--font-body); letter-spacing: -.01em; line-height: 1.3; text-align: left; outline: none; transform-origin: var(--origin-x, 100%) var(--origin-y, 0px); }
38
- .panel[data-inline] { position: absolute; top: calc(100% + 8px); left: auto; }
37
+ .panel { --presence-surface: var(--surface-raised); --row: 32px; --inset: 4px; --menu-radius: var(--radius-detail); --menu-line: color-mix(in oklab, var(--foreground) 9%, transparent); position: fixed; top: 0; left: 0; z-index: var(--layer-dropdown); box-sizing: border-box; width: 15.5rem; max-width: calc(100vw - 24px); padding: var(--inset); border: .5px solid var(--border); border-radius: var(--menu-radius); background: var(--surface-raised); box-shadow: var(--shadow-floating); color: var(--foreground); font-family: var(--font-body); letter-spacing: -.01em; line-height: 1.3; text-align: left; outline: none; transform-origin: var(--origin-x, 100%) var(--origin-y, 0px); }
38
+ .panel[data-inline] { position: absolute; top: calc(100% + var(--space-related)); left: auto; }
39
39
  .panel[data-inline][data-align="end"] { right: 0; }
40
40
  .panel[data-inline][data-align="start"] { left: 0; }
41
- .panel[data-inline][data-align="center"] { left: 50%; margin-left: -7.75rem; }
41
+ .panel[data-inline][data-align="center"] { left: 50%; margin-left: calc(calc(var(--space-screen) + var(--space-page)) * -1); }
42
42
 
43
- .header { display: flex; align-items: center; gap: 10px; padding: 8px 8px 8px; }
44
- .identity { display: grid; min-width: 0; flex: 1; gap: 2px; }
43
+ .header { display: flex; align-items: center; gap: var(--space-group); padding: var(--space-related) var(--space-related) var(--space-related); }
44
+ .identity { display: grid; min-width: 0; flex: 1; gap: var(--space-hair); }
45
45
  /* The name keeps its room; a long plan or role shrinks and truncates first. */
46
- .nameRow { display: flex; min-width: 0; align-items: center; gap: 6px; }
47
- .name { min-width: 0; flex: 0 1 auto; overflow: hidden; color: var(--foreground); font-size: 13px; font-weight: 500; letter-spacing: -.012em; line-height: 1.25; text-overflow: ellipsis; white-space: nowrap; }
48
- .plan { display: inline-block; min-width: 0; max-width: 55%; flex: 0 100 auto; overflow: hidden; height: 17px; padding: 0 5px; border: .5px solid var(--menu-line); border-radius: var(--radius-detail); corner-shape: var(--corner-shape); background: color-mix(in oklab, var(--foreground) 4%, transparent); color: var(--text-secondary); font-size: 11px; font-weight: 500; letter-spacing: -.005em; line-height: 16px; text-overflow: ellipsis; white-space: nowrap; }
49
- .email { overflow: hidden; color: var(--text-muted); font-size: 12px; letter-spacing: -.008em; line-height: 1.3; text-overflow: ellipsis; white-space: nowrap; }
46
+ .nameRow { display: flex; min-width: 0; align-items: center; gap: var(--space-related); }
47
+ .name { min-width: 0; flex: 0 1 auto; overflow: hidden; color: var(--foreground); font-size: var(--text-sm); font-weight: 500; letter-spacing: -.012em; line-height: 1.25; text-overflow: ellipsis; white-space: nowrap; }
48
+ .plan { display: inline-block; min-width: 0; max-width: 55%; flex: 0 100 auto; overflow: hidden; height: 17px; padding: 0 var(--space-tight); border: .5px solid var(--menu-line); border-radius: var(--radius-detail); corner-shape: var(--corner-shape); background: color-mix(in oklab, var(--foreground) 4%, transparent); color: var(--text-secondary); font-size: var(--text-xs); font-weight: 500; letter-spacing: -.005em; line-height: 16px; text-overflow: ellipsis; white-space: nowrap; }
49
+ .email { overflow: hidden; color: var(--text-muted); font-size: var(--text-xs); letter-spacing: -.008em; line-height: 1.3; text-overflow: ellipsis; white-space: nowrap; }
50
50
 
51
51
  .list { position: relative; }
52
52
  .separator { height: .5px; margin: var(--inset) calc(var(--inset) * -1); background: var(--menu-line); }
@@ -55,7 +55,7 @@
55
55
  /* One highlight follows the pointer and the keyboard. It is the only hover treatment in the menu. */
56
56
  .highlight { position: absolute; top: 0; right: 0; left: 0; border-radius: var(--radius-detail); corner-shape: var(--corner-shape); background: color-mix(in oklab, var(--foreground) 6%, transparent); opacity: 0; pointer-events: none; }
57
57
 
58
- .item { position: relative; display: flex; width: 100%; height: var(--row); box-sizing: border-box; align-items: center; gap: 10px; margin: 0; padding: 0 8px; border: 0; border-radius: var(--radius-detail); corner-shape: var(--corner-shape); background: transparent; color: var(--foreground); font: inherit; font-size: 13px; text-align: left; cursor: pointer; outline: none; user-select: none; -webkit-tap-highlight-color: transparent; transition: color var(--duration-fast) var(--ease-standard); }
58
+ .item { position: relative; display: flex; width: 100%; height: var(--row); box-sizing: border-box; align-items: center; gap: var(--space-group); margin: 0; padding: 0 var(--space-related); border: 0; border-radius: var(--radius-detail); corner-shape: var(--corner-shape); background: transparent; color: var(--foreground); font: inherit; font-size: var(--text-sm); text-align: left; cursor: pointer; outline: none; user-select: none; -webkit-tap-highlight-color: transparent; transition: color var(--duration-fast) var(--ease-standard); }
59
59
  .icon { display: inline-grid; width: 16px; flex: none; place-items: center; color: var(--text-secondary); transition: color var(--duration-fast) var(--ease-standard); }
60
60
  .item:focus .icon { color: var(--foreground); }
61
61
  .itemLabel { position: relative; display: inline-flex; min-width: 0; flex: 1; }
@@ -66,12 +66,12 @@
66
66
  .keys { display: inline-flex; flex: none; align-items: center; gap: 1px; margin-left: auto; color: var(--text-muted); font-family: var(--font-body); font-size: var(--text-xs); letter-spacing: 0; opacity: .8; font-variant-numeric: tabular-nums; }
67
67
  .key { display: inline-block; min-width: 1.05em; font: inherit; text-align: center; }
68
68
 
69
- .row { position: relative; display: flex; height: 36px; align-items: center; gap: 10px; padding: 0 4px 0 8px; }
70
- .rowLabel { flex: 1; color: var(--foreground); font-size: 13px; }
69
+ .row { position: relative; display: flex; height: 36px; align-items: center; gap: var(--space-group); padding: 0 var(--space-tight) 0 var(--space-related); }
70
+ .rowLabel { flex: 1; color: var(--foreground); font-size: var(--text-sm); }
71
71
  .row .icon .dot { --dot-size: 10px; }
72
72
  /* The thumb slides under the icons; the group owns the stacking context. */
73
- .segments { --segment: 28px; position: relative; isolation: isolate; display: inline-grid; height: 26px; flex: none; grid-auto-columns: var(--segment); grid-auto-flow: column; padding: 2px; border-radius: var(--radius-detail); corner-shape: var(--corner-shape); background: color-mix(in oklab, var(--foreground) 5%, transparent); }
74
- .thumb { position: absolute; z-index: -1; top: 2px; bottom: 2px; left: 2px; width: var(--segment); border-radius: var(--radius-detail); corner-shape: var(--corner-shape); background: var(--surface-raised); box-shadow: 0 1px 1.5px oklch(0% 0 0 / .08), 0 0 0 .5px var(--menu-line); transform: translateX(calc(var(--index) * 100%)); transition: transform var(--duration-spring) var(--ease-spring); }
73
+ .segments { --segment: 28px; position: relative; isolation: isolate; display: inline-grid; height: 26px; flex: none; grid-auto-columns: var(--segment); grid-auto-flow: column; padding: var(--space-hair); border-radius: var(--radius-detail); corner-shape: var(--corner-shape); background: color-mix(in oklab, var(--foreground) 5%, transparent); }
74
+ .thumb { position: absolute; z-index: -1; top: var(--space-hair); bottom: var(--space-hair); left: var(--space-hair); width: var(--segment); border-radius: var(--radius-detail); corner-shape: var(--corner-shape); background: var(--surface-raised); box-shadow: var(--shadow-thumb), 0 0 0 .5px var(--menu-line); transform: translateX(calc(var(--index) * 100%)); transition: transform var(--duration-spring) var(--ease-spring); }
75
75
  :global([data-theme="dark"]) .thumb { background: color-mix(in oklab, var(--foreground) 20%, var(--surface-raised)); box-shadow: none; }
76
76
  .segment { display: grid; place-items: center; margin: 0; padding: 0; border: 0; border-radius: var(--radius-detail); corner-shape: var(--corner-shape); background: transparent; color: var(--text-muted); cursor: pointer; outline: none; -webkit-tap-highlight-color: transparent; transition: color var(--duration-fast) var(--ease-standard); }
77
77
  .segment .dot { --dot-size: 9px; --presence-surface: var(--surface-raised); }
@@ -82,10 +82,10 @@
82
82
  @keyframes user-menu-spin { to { transform: rotate(360deg); } }
83
83
 
84
84
  /* Below 640px the same content rises as a bottom sheet with larger rows. */
85
- .scrim { position: fixed; inset: 0; z-index: 70; background: oklch(0% 0 0 / .32); -webkit-tap-highlight-color: transparent; }
86
- .sheet { --row: 46px; --inset: 10px; position: fixed; top: auto; right: 0; bottom: 0; left: 0; z-index: 71; width: auto; max-width: none; max-height: 88dvh; overflow-y: auto; overscroll-behavior: contain; padding: 8px var(--inset) calc(12px + env(safe-area-inset-bottom)); border-bottom: 0; border-radius: var(--radius-container) var(--radius-container) 0 0; corner-shape: var(--corner-shape); }
87
- .handle { display: block; width: 36px; height: 5px; margin: 0 auto 10px; border-radius: var(--radius-full); corner-shape: round; background: var(--border-strong); cursor: grab; }
88
- .sheet .header { padding: 4px 8px 12px; }
85
+ .scrim { position: fixed; inset: 0; z-index: var(--layer-overlay); background: var(--scrim); -webkit-tap-highlight-color: transparent; }
86
+ .sheet { --row: 46px; --inset: 10px; position: fixed; top: auto; right: 0; bottom: 0; left: 0; z-index: var(--layer-dialog); width: auto; max-width: none; max-height: 88dvh; overflow-y: auto; overscroll-behavior: contain; padding: var(--space-related) var(--inset) calc(var(--space-group) + env(safe-area-inset-bottom)); border-bottom: 0; border-radius: var(--radius-container) var(--radius-container) 0 0; corner-shape: var(--corner-shape); }
87
+ .handle { display: block; width: 36px; height: 5px; margin: 0 auto var(--space-group); border-radius: var(--radius-full); corner-shape: round; background: var(--border-strong); cursor: grab; }
88
+ .sheet .header { padding: var(--space-tight) var(--space-related) var(--space-group); }
89
89
  .sheet .item, .sheet .rowLabel { font-size: var(--text-base); }
90
90
  .sheet .row { height: 52px; }
91
91
  .sheet .segments { --segment: 40px; height: 34px; }