@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.
- package/README.md +4 -3
- package/check.mjs +14 -5
- package/components/activity-heatmap/activity-heatmap.module.css +4 -4
- package/components/alert/alert.module.css +1 -1
- package/components/announcement-bar/announcement-bar.module.css +6 -6
- package/components/avatar/avatar.d.ts +2 -2
- package/components/avatar/avatar.js +1 -1
- package/components/avatar/avatar.module.css +5 -2
- package/components/avatar-group/avatar-group.module.css +4 -4
- package/components/badge/badge.module.css +4 -4
- package/components/bar-chart/bar-chart.module.css +4 -4
- package/components/billing-toggle/billing-toggle.module.css +10 -10
- package/components/bottom-sheet/bottom-sheet.module.css +4 -5
- package/components/breadcrumb/breadcrumb.d.ts +8 -2
- package/components/breadcrumb/breadcrumb.js +21 -9
- package/components/breadcrumb/breadcrumb.module.css +7 -3
- package/components/brush-chart/brush-chart.module.css +9 -9
- package/components/button/button.d.ts +7 -2
- package/components/button/button.js +3 -1
- package/components/button/button.module.css +10 -1
- package/components/button-group/button-group.module.css +6 -6
- package/components/calendar/calendar.module.css +7 -7
- package/components/card/card.module.css +2 -2
- package/components/card-stack/card-stack.module.css +2 -3
- package/components/carousel/carousel.module.css +2 -2
- package/components/chat-thread/chat-thread.module.css +41 -41
- package/components/checkbox/checkbox.module.css +1 -1
- package/components/chip-group/chip-group.module.css +2 -2
- package/components/code-block/code-block.module.css +7 -14
- package/components/color-picker/color-picker.module.css +20 -21
- package/components/combobox/combobox.module.css +2 -2
- package/components/command-palette/command-palette.module.css +18 -18
- package/components/comment-thread/comment-thread.module.css +35 -35
- package/components/confirm-morph/confirm-morph.module.css +9 -9
- package/components/context-menu/context-menu.module.css +3 -3
- package/components/countdown/countdown.module.css +4 -4
- package/components/date-picker/date-picker.module.css +6 -6
- package/components/date-range-picker/date-range-picker.module.css +21 -21
- package/components/dialog/dialog.module.css +2 -2
- package/components/donut-chart/donut-chart.module.css +4 -4
- package/components/drawer/drawer.module.css +5 -5
- package/components/dropdown-menu/dropdown-menu.d.ts +71 -1
- package/components/dropdown-menu/dropdown-menu.js +100 -6
- package/components/dropdown-menu/dropdown-menu.module.css +15 -5
- package/components/elastic-slider/elastic-slider.module.css +4 -4
- package/components/expandable-card/expandable-card.module.css +1 -1
- package/components/expanding-button-group/expanding-button-group.module.css +1 -1
- package/components/expanding-search/expanding-search.module.css +9 -9
- package/components/file-dropzone/file-dropzone.module.css +21 -21
- package/components/file-upload/file-upload.module.css +7 -7
- package/components/filter-toolbar/filter-toolbar.module.css +9 -9
- package/components/floating-button-group/floating-button-group.module.css +6 -6
- package/components/gauge/gauge.module.css +2 -2
- package/components/hover-card/hover-card.module.css +2 -2
- package/components/image-compare/image-compare.module.css +4 -4
- package/components/inline-edit/inline-edit.module.css +12 -12
- package/components/json-viewer/json-viewer.module.css +12 -12
- package/components/line-chart/line-chart.module.css +8 -8
- package/components/mention-input/mention-input.module.css +8 -8
- package/components/metric-card/metric-card.module.css +1 -1
- package/components/money-input/money-input.module.css +9 -9
- package/components/morph-select/morph-select.module.css +13 -13
- package/components/multi-select/multi-select.module.css +6 -6
- package/components/nav-list/nav-list.d.ts +64 -0
- package/components/nav-list/nav-list.js +103 -0
- package/components/nav-list/nav-list.module.css +25 -0
- package/components/notification-center/notification-center.module.css +27 -27
- package/components/number-field/number-field.module.css +2 -2
- package/components/otp-input/otp-input.module.css +4 -4
- package/components/password-field/password-field.module.css +1 -1
- package/components/password-strength/password-strength.module.css +7 -7
- package/components/phone-input/phone-input.module.css +19 -19
- package/components/popover/popover.module.css +2 -2
- package/components/progress/progress.module.css +1 -1
- package/components/radio-cards/radio-cards.module.css +8 -8
- package/components/radio-group/radio-group.module.css +1 -1
- package/components/resizable-panels/resizable-panels.module.css +5 -5
- package/components/rich-text-editor/rich-text-editor.module.css +12 -12
- package/components/ridgeline/ridgeline.module.css +7 -7
- package/components/scroll-area/scroll-area.module.css +8 -8
- package/components/segmented-control/segmented-control.d.ts +3 -1
- package/components/segmented-control/segmented-control.js +2 -2
- package/components/segmented-control/segmented-control.module.css +7 -4
- package/components/select/select.module.css +5 -5
- package/components/shortcut-recorder/shortcut-recorder.module.css +15 -15
- package/components/signature-pad/signature-pad.module.css +11 -11
- package/components/slider/slider.module.css +4 -4
- package/components/slope-chart/slope-chart.module.css +7 -7
- package/components/sortable-data-table/sortable-data-table.module.css +4 -4
- package/components/split-button/split-button.module.css +5 -5
- package/components/stepper/stepper.module.css +3 -3
- package/components/streamgraph/streamgraph.module.css +7 -7
- package/components/swipe-actions/swipe-actions.module.css +5 -5
- package/components/switch/switch.module.css +1 -1
- package/components/tabs/tabs.d.ts +9 -2
- package/components/tabs/tabs.js +4 -2
- package/components/tabs/tabs.module.css +7 -2
- package/components/tag-input/tag-input.module.css +4 -4
- package/components/time-picker/time-picker.module.css +3 -3
- package/components/timeline/timeline.module.css +3 -3
- package/components/toast/toast.module.css +5 -5
- package/components/toast-stack/toast-stack.module.css +5 -5
- package/components/tooltip/tooltip.module.css +1 -1
- package/components/tree-view/tree-view.module.css +7 -7
- package/components/treemap/treemap.module.css +13 -13
- package/components/usage-meter/usage-meter.module.css +5 -5
- package/components/user-menu/user-menu.module.css +22 -22
- package/components/waffle-chart/waffle-chart.module.css +7 -7
- package/components.json +416 -1
- package/eslint.js +35 -3
- package/package.json +1 -1
- 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:
|
|
7
|
-
.toggle { display: inline-flex; min-height: 32px; align-items: center; gap:
|
|
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:
|
|
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
|
|
37
|
-
.tipRow { display: flex; min-width: 0; align-items: center; gap:
|
|
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:
|
|
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:
|
|
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:
|
|
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) -
|
|
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:
|
|
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:
|
|
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:
|
|
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:
|
|
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
|
|
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 {};
|
package/components/tabs/tabs.js
CHANGED
|
@@ -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
|
-
|
|
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) -
|
|
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:
|
|
11
|
-
.tag { position: relative; display: inline-flex; align-items: center; gap:
|
|
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
|
|
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
|
|
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:
|
|
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:
|
|
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) -
|
|
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 -
|
|
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:
|
|
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:
|
|
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:
|
|
7
|
-
padding:
|
|
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:
|
|
38
|
+
gap: var(--space-hair);
|
|
39
39
|
/* Centers the title's first line on the 30px status icon. */
|
|
40
|
-
padding-top:
|
|
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: -
|
|
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:
|
|
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:
|
|
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: -
|
|
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: -
|
|
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(
|
|
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:
|
|
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:
|
|
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:
|
|
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:
|
|
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,
|
|
16
|
-
.stylesheet { color: color-mix(in oklab,
|
|
17
|
-
.markdown { color: color-mix(in oklab,
|
|
18
|
-
.json { color: color-mix(in oklab,
|
|
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: -
|
|
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
|
|
12
|
-
.crumbButton { min-height: 32px; padding: 0
|
|
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
|
|
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:
|
|
22
|
-
.tile[data-branch][data-level="1"] { padding:
|
|
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:
|
|
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:
|
|
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:
|
|
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:
|
|
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:
|
|
51
|
-
.scaleLabel { margin-right:
|
|
52
|
-
.steps { display: inline-flex; gap:
|
|
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:
|
|
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:
|
|
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:
|
|
40
|
-
.item { display: grid; min-width: 0; justify-items: start; gap:
|
|
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:
|
|
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:
|
|
5
|
-
.trigger[data-name] { padding-right:
|
|
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: -
|
|
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:
|
|
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:
|
|
38
|
-
.panel[data-inline] { position: absolute; top: calc(100% +
|
|
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: -
|
|
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:
|
|
44
|
-
.identity { display: grid; min-width: 0; flex: 1; gap:
|
|
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:
|
|
47
|
-
.name { min-width: 0; flex: 0 1 auto; overflow: hidden; color: var(--foreground); font-size:
|
|
48
|
-
.plan { display: inline-block; min-width: 0; max-width: 55%; flex: 0 100 auto; overflow: hidden; height: 17px; padding: 0
|
|
49
|
-
.email { overflow: hidden; color: var(--text-muted); font-size:
|
|
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:
|
|
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:
|
|
70
|
-
.rowLabel { flex: 1; color: var(--foreground); font-size:
|
|
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:
|
|
74
|
-
.thumb { position: absolute; z-index: -1; top:
|
|
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:
|
|
86
|
-
.sheet { --row: 46px; --inset: 10px; position: fixed; top: auto; right: 0; bottom: 0; left: 0; z-index:
|
|
87
|
-
.handle { display: block; width: 36px; height: 5px; margin: 0 auto
|
|
88
|
-
.sheet .header { padding:
|
|
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; }
|