@octane-xplat/ui 0.7.3 → 0.9.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/dist/native/Button.tsrx.js +1 -1
- package/dist/native/KeyboardAvoiding.mobile.tsrx.js +2 -2
- package/dist/native/Markdown.tsrx.js +233 -0
- package/dist/native/Overlay.tsrx.js +15 -26
- package/dist/native/PinInput.tsrx.js +25 -7
- package/dist/native/Popover.tsrx.js +17 -18
- package/dist/native/Pressable.tsrx.js +4 -1
- package/dist/native/SearchInput.tsrx.js +6 -3
- package/dist/native/Sheet.tsrx.js +22 -37
- package/dist/native/TextArea.tsrx.js +6 -3
- package/dist/native/TextInput.tsrx.js +6 -3
- package/dist/native/VirtualList.tsrx.js +305 -121
- package/dist/native/index.shared.js +7 -5
- package/dist/native/keyboard-inset.mobile.js +5 -5
- package/dist/native/navigation-request.js +26 -0
- package/dist/native/octane-client-build.json +1 -1
- package/dist/native/overlay-lifetime.mobile.js +65 -0
- package/dist/native/pan.tsrx.js +16 -2
- package/dist/native/route-table.js +90 -10
- package/dist/native/route.js +26 -16
- package/dist/native/shared.js +7 -5
- package/dist/native/sheet-service.js +1 -1
- package/dist/native/svg.mobile.js +1 -1
- package/dist/native/text-focus.js +10 -0
- package/dist/native/text-write.js +18 -11
- package/dist/native/toast-anchor.tsrx.js +1 -1
- package/dist/native/ui.js +7 -6
- package/dist/native/vendor/ui-svg/index.android.js +2 -2
- package/dist/native/vendor/ui-svg/index.ios.js +2 -2
- package/dist/native/vendor/ui-svg/{index.common.js → src/index.common.js} +1 -1
- package/dist/native/virtual-list-cell-pool.js +63 -0
- package/dist/web/Button.web.tsrx.js +1 -1
- package/dist/web/KeyboardAvoiding.web.tsrx.js +78 -0
- package/dist/web/Markdown.tsrx.js +98 -0
- package/dist/web/Overlay.web.tsrx.js +81 -32
- package/dist/web/PinInput.web.tsrx.js +24 -10
- package/dist/web/Pressable.web.tsrx.js +169 -53
- package/dist/web/SearchInput.web.tsrx.js +2 -2
- package/dist/web/Sheet.web.tsrx.js +20 -7
- package/dist/web/TextArea.web.tsrx.js +22 -17
- package/dist/web/TextInput.web.tsrx.js +2 -2
- package/dist/web/VirtualList.web.tsrx.js +220 -109
- package/dist/web/WebView.web.tsrx.js +3 -3
- package/dist/web/{index.shared.js → index.shared.web.js} +7 -5
- package/dist/web/modal-focus.web.js +95 -0
- package/dist/web/navigation-request.js +26 -0
- package/dist/web/octane-client-build.json +1 -1
- package/dist/web/pan.web.tsrx.js +27 -10
- package/dist/web/route-table.js +90 -10
- package/dist/web/route.web.js +88 -22
- package/dist/web/sheet-service.web.js +8 -0
- package/dist/web/theme/colorScheme.web.js +31 -4
- package/dist/web/ui.js +8 -6
- package/dist/web/virtual-list-cell-pool.js +63 -0
- package/package.json +21 -19
- package/platforms/android/native-api-usage.json +7 -7
- package/src/CommandPalette.tsrx +1 -0
- package/src/Grid.tsrx +2 -0
- package/src/Icon.macos.tsrx +1 -0
- package/src/KeyboardAvoiding.macos.tsrx +7 -1
- package/src/KeyboardAvoiding.mobile.tsrx +2 -2
- package/src/KeyboardAvoiding.tsrx +15 -0
- package/src/KeyboardAvoiding.web.tsrx +15 -0
- package/src/Markdown.tsrx +121 -0
- package/src/Meter.tsrx +1 -0
- package/src/Overlay.tsrx +15 -30
- package/src/Overlay.web.tsrx +12 -3
- package/src/PinInput.macos.tsrx +20 -6
- package/src/PinInput.mobile.test.ts +107 -0
- package/src/PinInput.tsrx +20 -6
- package/src/PinInput.web.test.tsrx +42 -0
- package/src/PinInput.web.tsrx +20 -6
- package/src/Popover.tsrx +17 -17
- package/src/Pressable.tsrx +1 -1
- package/src/Pressable.web.test.tsrx +36 -0
- package/src/Pressable.web.tsrx +37 -6
- package/src/RouteHost.macos.tsrx +1 -0
- package/src/SearchInput.tsrx +4 -3
- package/src/SearchInput.web.tsrx +1 -1
- package/src/Sheet.tsrx +20 -41
- package/src/Sheet.web.tsrx +9 -1
- package/src/Text.tsrx +2 -0
- package/src/TextArea.tsrx +6 -5
- package/src/TextArea.web.test.tsrx +39 -0
- package/src/TextArea.web.tsrx +7 -5
- package/src/TextInput.tsrx +6 -6
- package/src/TextInput.web.tsrx +1 -1
- package/src/VirtualList.macos.tsrx +93 -6
- package/src/VirtualList.mobile.test.tsrx +232 -0
- package/src/VirtualList.tsrx +285 -81
- package/src/VirtualList.web.tsrx +131 -25
- package/src/WebView.tsrx +1 -0
- package/src/WebView.web.tsrx +3 -0
- package/src/android/BottomNavigationView.android.tsrx +1 -0
- package/src/android/MaterialDialog.android.tsrx +1 -0
- package/src/anim.macos.tsrx +1 -0
- package/src/apply-native-modifiers.native.ts +4 -1
- package/src/child-array.ts +12 -7
- package/src/colorScheme.macos.ts +1 -0
- package/src/controls.macos.tsrx +4 -1
- package/src/data-driver.mobile.test.ts +120 -0
- package/src/data-lifecycle.mobile.test.ts +251 -0
- package/src/escape-props.ts +2 -0
- package/src/grid-auto-placement.ts +54 -12
- package/src/grid-placement.ts +1 -1
- package/src/hosted-unsupported.macos.tsrx +1 -0
- package/src/index.macos.ts +23 -3
- package/src/index.mobile.ts +0 -1
- package/src/index.shared.ts +22 -1
- package/src/index.shared.web.ts +291 -0
- package/src/index.web.ts +1 -1
- package/src/input-readiness.web.test.tsrx +82 -0
- package/src/ios/UITabBar.ios.tsrx +1 -0
- package/src/keyboard-inset.mobile.test.ts +62 -0
- package/src/keyboard-inset.mobile.ts +63 -43
- package/src/layout-shells.macos.tsrx +1 -5
- package/src/macos-extras.macos.tsrx +2 -0
- package/src/modal-focus.web.test.tsrx +63 -0
- package/src/modal-focus.web.ts +162 -0
- package/src/navigation-request.ts +37 -0
- package/src/overlay-lifecycle.mobile.test.ts +316 -0
- package/src/overlay-lifetime.mobile.ts +107 -0
- package/src/pan.mobile.test.tsrx +116 -0
- package/src/pan.tsrx +20 -2
- package/src/pan.web.tsrx +35 -7
- package/src/platformProps.ts +1 -0
- package/src/popover.mobile.test.ts +9 -1
- package/src/pressable-accessibility.mobile.test.ts +30 -0
- package/src/props.ts +163 -3
- package/src/refresh.ts +6 -1
- package/src/refresh.web.test.ts +77 -77
- package/src/route-android.test.ts +162 -0
- package/src/route-history.web.test.ts +80 -0
- package/src/route-navigation.web.test.ts +173 -0
- package/src/route-table.test.ts +188 -9
- package/src/route-table.ts +138 -10
- package/src/route.macos.ts +56 -13
- package/src/route.ts +54 -24
- package/src/route.web.ts +141 -24
- package/src/sheet-detents.ts +5 -3
- package/src/sheet-service.macos.ts +5 -1
- package/src/sheet-service.web.ts +8 -0
- package/src/sheet-snap.test.ts +23 -23
- package/src/sheet-snap.ts +6 -1
- package/src/svg.mobile.ts +9 -3
- package/src/tap-to-blur.ios.ts +48 -32
- package/src/tap-to-blur.mobile.ts +23 -15
- package/src/text-focus.ts +12 -0
- package/src/text-input.mobile.test.ts +89 -0
- package/src/text-write.ts +21 -11
- package/src/theme/colorScheme.linux.ts +2 -4
- package/src/theme/colorScheme.web.ts +51 -4
- package/src/theme/theme-scheme.macos.ts +8 -2
- package/src/theme/tokens.css +1736 -1730
- package/src/translate.macos.ts +4 -1
- package/src/virtual-list-cell-pool.test.ts +53 -0
- package/src/virtual-list-cell-pool.ts +81 -0
- package/src/virtual-list-layout.test.ts +11 -8
- package/src/virtual-list-layout.ts +4 -8
- package/src/windows.linux.ts +7 -2
- package/src/windows.macos.ts +1 -0
- package/types/generated/.tsrx-typegen-manifest.json +13 -3
- package/types/generated/KeyboardAvoiding.d.ts +3 -0
- package/types/generated/KeyboardAvoiding.web.d.ts +2 -0
- package/types/generated/Markdown.d.ts +59 -0
- package/types/generated/TextArea.d.ts +2 -2
- package/types/generated/TextArea.web.d.ts +1 -1
- package/types/generated/TextInput.d.ts +2 -3
- package/types/generated/VirtualList.d.ts +3 -3
- package/types/generated/index.mobile.d.ts +0 -1
- package/types/generated/index.shared.d.ts +6 -3
- package/types/generated/index.shared.web.d.ts +114 -0
- package/types/generated/index.web.d.ts +1 -1
- package/types/generated/modal-focus.web.d.ts +3 -0
- package/types/generated/navigation-request.d.ts +10 -0
- package/types/generated/overlay-lifetime.mobile.d.ts +10 -0
- package/types/generated/props.d.ts +111 -3
- package/types/generated/route-table.d.ts +14 -3
- package/types/generated/svg.mobile.d.ts +2 -2
- package/types/generated/text-focus.d.ts +3 -0
- package/types/generated/text-write.d.ts +3 -1
- package/types/generated/theme/colorScheme.web.d.ts +5 -0
- package/types/generated/virtual-list-cell-pool.d.ts +18 -0
- package/types/index.macos.d.ts +15 -3
- /package/src/vendor/ui-svg/{index.android.ts → src/index.android.ts} +0 -0
- /package/src/vendor/ui-svg/{index.common.ts → src/index.common.ts} +0 -0
- /package/src/vendor/ui-svg/{index.ios.ts → src/index.ios.ts} +0 -0
- /package/src/vendor/ui-svg/{index.ts → src/index.ts} +0 -0
- /package/src/vendor/ui-svg/{typings → src/typings}/SVGKit.d.ts +0 -0
- /package/src/vendor/ui-svg/{typings → src/typings}/android.d.ts +0 -0
- /package/src/vendor/ui-svg/{typings → src/typings}/ios.d.ts +0 -0
- /package/types/generated/vendor/ui-svg/{index.common.d.ts → src/index.common.d.ts} +0 -0
- /package/types/generated/vendor/ui-svg/{index.d.ts → src/index.d.ts} +0 -0
- /package/types/generated/vendor/ui-svg/{index.ios.d.ts → src/index.ios.d.ts} +0 -0
package/src/theme/tokens.css
CHANGED
|
@@ -1,48 +1,53 @@
|
|
|
1
1
|
/* Design tokens — NS reads :root/.ns-root; web reads :root/.dark.
|
|
2
2
|
Numbers are dip (native) = px (web) by leaf convention. */
|
|
3
3
|
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
4
|
+
@layer xplat.reset, xplat.base, xplat.tokens, xplat.components, xplat.recipes, xplat.utilities;
|
|
5
|
+
|
|
6
|
+
@layer xplat.tokens {
|
|
7
|
+
:root,
|
|
8
|
+
.ns-root {
|
|
9
|
+
--color-primary: #171717;
|
|
10
|
+
/* Token names double as the future Tailwind theme keys: text-onprimary
|
|
8
11
|
resolves --color-onprimary, bg-danger resolves --color-danger. Keep
|
|
9
12
|
class-name segments and var-name segments identical. */
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
13
|
+
--color-onprimary: #fafafa;
|
|
14
|
+
--color-surface: #ffffff;
|
|
15
|
+
--color-surface-secondary: #fafafa;
|
|
16
|
+
--color-text: #0a0a0a;
|
|
17
|
+
--color-text-secondary: #666666;
|
|
18
|
+
--color-border: #eaeaea;
|
|
19
|
+
--color-border-strong: #d4d4d4;
|
|
20
|
+
--color-danger: #dc2626;
|
|
21
|
+
/* Family lists are deliberately generic. Apps override these with their
|
|
19
22
|
web @font-face family and the platform's registered native name. */
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
23
|
+
--font-sans: system-ui, sans-serif;
|
|
24
|
+
--font-mono: ui-monospace, monospace;
|
|
25
|
+
--space-4: 16px;
|
|
26
|
+
/* Corner scale — rounded-rectangle radii. Smooth (squircle) corners are
|
|
24
27
|
the default corner treatment: every class that consumes a token also
|
|
25
28
|
declares `corner-shape: squircle`. Full-radius circles opt out —
|
|
26
29
|
`corner-shape` would reshape them into squircle disks on iOS/Chromium. */
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
}
|
|
30
|
+
--radius-sm: 6px;
|
|
31
|
+
--radius-md: 8px;
|
|
32
|
+
--radius-lg: 12px;
|
|
33
|
+
--radius-xl: 16px;
|
|
34
|
+
}
|
|
32
35
|
|
|
33
|
-
.ns-dark,
|
|
34
|
-
.dark {
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
36
|
+
.ns-dark,
|
|
37
|
+
.dark {
|
|
38
|
+
--color-primary: #ededed;
|
|
39
|
+
--color-onprimary: #171717;
|
|
40
|
+
--color-surface: #0a0a0a;
|
|
41
|
+
--color-surface-secondary: #141414;
|
|
42
|
+
--color-text: #ededed;
|
|
43
|
+
--color-text-secondary: #a1a1a1;
|
|
44
|
+
--color-border: #2e2e2e;
|
|
45
|
+
--color-border-strong: #4a4a4a;
|
|
46
|
+
}
|
|
43
47
|
}
|
|
44
48
|
|
|
45
|
-
|
|
49
|
+
@layer xplat.components {
|
|
50
|
+
/* xplat-web-only:start — DOM normalization. NativeScript is the reference
|
|
46
51
|
box model: dip sizes are outer boxes, and a border paints from
|
|
47
52
|
width+color alone. The DOM's UA stylesheet diverges on both counts, so
|
|
48
53
|
normalize the deltas once instead of patching individual rules:
|
|
@@ -54,31 +59,31 @@
|
|
|
54
59
|
phantom ~3px edges wherever a rule sets only one side's width.
|
|
55
60
|
- <img> is a leaf, not inline text (no baseline descender gap).
|
|
56
61
|
- .vx-app columns are flex like their native screen containers. */
|
|
57
|
-
*,
|
|
58
|
-
*::before,
|
|
59
|
-
*::after {
|
|
60
|
-
|
|
61
|
-
}
|
|
62
|
-
* {
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
}
|
|
66
|
-
img {
|
|
67
|
-
|
|
68
|
-
}
|
|
69
|
-
.vx-app {
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
}
|
|
73
|
-
/* Native has no scroll chaining — a ScrollView just bounces inside
|
|
62
|
+
*,
|
|
63
|
+
*::before,
|
|
64
|
+
*::after {
|
|
65
|
+
box-sizing: border-box;
|
|
66
|
+
}
|
|
67
|
+
* {
|
|
68
|
+
border-width: 0;
|
|
69
|
+
border-style: solid;
|
|
70
|
+
}
|
|
71
|
+
img {
|
|
72
|
+
display: block;
|
|
73
|
+
}
|
|
74
|
+
.vx-app {
|
|
75
|
+
display: flex;
|
|
76
|
+
flex-direction: column;
|
|
77
|
+
}
|
|
78
|
+
/* Native has no scroll chaining — a ScrollView just bounces inside
|
|
74
79
|
itself because the parent is never a scroller. contain is the DOM
|
|
75
80
|
equivalent: scroll stays in the leaf it started in. */
|
|
76
|
-
.vx-scroll {
|
|
77
|
-
|
|
78
|
-
}
|
|
79
|
-
/* xplat-web-only:end */
|
|
81
|
+
.vx-scroll {
|
|
82
|
+
overscroll-behavior: contain;
|
|
83
|
+
}
|
|
84
|
+
/* xplat-web-only:end */
|
|
80
85
|
|
|
81
|
-
/* Shared normalization — NS FlexboxLayout defaults flex children to
|
|
86
|
+
/* Shared normalization — NS FlexboxLayout defaults flex children to
|
|
82
87
|
shrink:1 with NO min-content floor (its shrink pass clamps at
|
|
83
88
|
effectiveMinWidth/Height = the explicit min-* prop, default 0), so an
|
|
84
89
|
overflowing column crushes intrinsic children toward zero where the
|
|
@@ -86,1865 +91,1866 @@ img {
|
|
|
86
91
|
reason — do the same on both engines. `*` is zero-specificity: flex-1
|
|
87
92
|
(the shorthand sets shrink:1) and .shrink still opt back in, and
|
|
88
93
|
truncation patterns pair them with min-w-0/min-h-0. */
|
|
89
|
-
* {
|
|
90
|
-
|
|
91
|
-
}
|
|
94
|
+
* {
|
|
95
|
+
flex-shrink: 0;
|
|
96
|
+
}
|
|
92
97
|
|
|
93
|
-
/* vocabulary base styles */
|
|
98
|
+
/* vocabulary base styles */
|
|
94
99
|
|
|
95
|
-
.vx-view,
|
|
96
|
-
.vx-row {
|
|
97
|
-
|
|
98
|
-
}
|
|
100
|
+
.vx-view,
|
|
101
|
+
.vx-row {
|
|
102
|
+
display: flex;
|
|
103
|
+
}
|
|
99
104
|
|
|
100
|
-
.vx-view {
|
|
101
|
-
|
|
102
|
-
}
|
|
105
|
+
.vx-view {
|
|
106
|
+
flex-direction: column;
|
|
107
|
+
}
|
|
103
108
|
|
|
104
|
-
/* Safe-area values are zero when the viewport has no display cutout. */
|
|
105
|
-
.vx-safe-area {
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
}
|
|
109
|
+
/* Safe-area values are zero when the viewport has no display cutout. */
|
|
110
|
+
.vx-safe-area {
|
|
111
|
+
padding-top: constant(safe-area-inset-top);
|
|
112
|
+
padding-right: constant(safe-area-inset-right);
|
|
113
|
+
padding-bottom: constant(safe-area-inset-bottom);
|
|
114
|
+
padding-left: constant(safe-area-inset-left);
|
|
115
|
+
}
|
|
111
116
|
|
|
112
|
-
.vx-safe-area {
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
}
|
|
117
|
+
.vx-safe-area {
|
|
118
|
+
padding-top: env(safe-area-inset-top);
|
|
119
|
+
padding-right: env(safe-area-inset-right);
|
|
120
|
+
padding-bottom: env(safe-area-inset-bottom);
|
|
121
|
+
padding-left: env(safe-area-inset-left);
|
|
122
|
+
}
|
|
118
123
|
|
|
119
|
-
.vx-keyboard-avoiding {
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
}
|
|
123
|
-
/* Self-drawn drawer — shared geometry. Native grid children overlay the
|
|
124
|
+
.vx-keyboard-avoiding {
|
|
125
|
+
display: flex;
|
|
126
|
+
flex-direction: column;
|
|
127
|
+
}
|
|
128
|
+
/* Self-drawn drawer — shared geometry. Native grid children overlay the
|
|
124
129
|
cell (panel pins left via horizontalAlignment in the leaf); DOM
|
|
125
130
|
positioning extras are web-only below. */
|
|
126
|
-
.vx-drawer-backdrop {
|
|
127
|
-
|
|
128
|
-
}
|
|
129
|
-
.vx-drawer-panel {
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
}
|
|
133
|
-
/* xplat-web-only:start */
|
|
134
|
-
.vx-drawer {
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
}
|
|
140
|
-
.vx-drawer-main {
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
}
|
|
145
|
-
.vx-drawer-backdrop {
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
}
|
|
149
|
-
.vx-drawer-panel {
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
}
|
|
158
|
-
/* xplat-web-only:end */
|
|
131
|
+
.vx-drawer-backdrop {
|
|
132
|
+
background-color: rgba(0, 0, 0, 0.4);
|
|
133
|
+
}
|
|
134
|
+
.vx-drawer-panel {
|
|
135
|
+
width: 280px;
|
|
136
|
+
background-color: var(--color-surface);
|
|
137
|
+
}
|
|
138
|
+
/* xplat-web-only:start */
|
|
139
|
+
.vx-drawer {
|
|
140
|
+
display: flex;
|
|
141
|
+
flex-direction: row;
|
|
142
|
+
position: relative;
|
|
143
|
+
overflow: hidden;
|
|
144
|
+
}
|
|
145
|
+
.vx-drawer-main {
|
|
146
|
+
display: flex;
|
|
147
|
+
flex: 1;
|
|
148
|
+
min-width: 0;
|
|
149
|
+
}
|
|
150
|
+
.vx-drawer-backdrop {
|
|
151
|
+
position: absolute;
|
|
152
|
+
inset: 0;
|
|
153
|
+
}
|
|
154
|
+
.vx-drawer-panel {
|
|
155
|
+
position: absolute;
|
|
156
|
+
z-index: 1;
|
|
157
|
+
top: 0;
|
|
158
|
+
bottom: 0;
|
|
159
|
+
left: 0;
|
|
160
|
+
overflow: auto;
|
|
161
|
+
box-shadow: 0 4px 12px rgba(0, 0, 0, 0.25);
|
|
162
|
+
}
|
|
163
|
+
/* xplat-web-only:end */
|
|
159
164
|
|
|
160
|
-
.vx-row {
|
|
161
|
-
|
|
162
|
-
}
|
|
165
|
+
.vx-row {
|
|
166
|
+
flex-direction: row;
|
|
167
|
+
}
|
|
163
168
|
|
|
164
|
-
.vx-grid,
|
|
165
|
-
.vx-stack {
|
|
166
|
-
|
|
167
|
-
}
|
|
169
|
+
.vx-grid,
|
|
170
|
+
.vx-stack {
|
|
171
|
+
display: grid;
|
|
172
|
+
}
|
|
168
173
|
|
|
169
|
-
.vx-stack > * {
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
}
|
|
174
|
+
.vx-stack > * {
|
|
175
|
+
grid-area: 1 / 1;
|
|
176
|
+
horizontal-align: left;
|
|
177
|
+
vertical-align: top;
|
|
178
|
+
}
|
|
174
179
|
|
|
175
|
-
/* xplat-web-only:start — Absolute's native leaf is absolutelayout; CSS
|
|
180
|
+
/* xplat-web-only:start — Absolute's native leaf is absolutelayout; CSS
|
|
176
181
|
positioning is web-only (children position via left/top props) */
|
|
177
|
-
.vx-absolute {
|
|
178
|
-
|
|
179
|
-
}
|
|
182
|
+
.vx-absolute {
|
|
183
|
+
position: relative;
|
|
184
|
+
}
|
|
180
185
|
|
|
181
|
-
.vx-absolute > * {
|
|
182
|
-
|
|
183
|
-
}
|
|
184
|
-
/* xplat-web-only:end */
|
|
186
|
+
.vx-absolute > * {
|
|
187
|
+
position: absolute;
|
|
188
|
+
}
|
|
189
|
+
/* xplat-web-only:end */
|
|
185
190
|
|
|
186
|
-
.vx-spacer {
|
|
187
|
-
|
|
188
|
-
}
|
|
191
|
+
.vx-spacer {
|
|
192
|
+
flex-grow: 1;
|
|
193
|
+
}
|
|
189
194
|
|
|
190
|
-
.vx-pressable {
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
}
|
|
195
|
+
.vx-pressable {
|
|
196
|
+
display: flex;
|
|
197
|
+
flex-direction: column;
|
|
198
|
+
user-select: none;
|
|
199
|
+
}
|
|
195
200
|
|
|
196
|
-
/* web press feedback */
|
|
197
|
-
.vx-pressable:active {
|
|
198
|
-
|
|
199
|
-
}
|
|
200
|
-
/* native press feedback (NS pseudo — dead rule on web, and vice versa) */
|
|
201
|
-
.vx-pressable:pressed {
|
|
202
|
-
|
|
203
|
-
}
|
|
201
|
+
/* web press feedback */
|
|
202
|
+
.vx-pressable:active {
|
|
203
|
+
opacity: 0.85;
|
|
204
|
+
}
|
|
205
|
+
/* native press feedback (NS pseudo — dead rule on web, and vice versa) */
|
|
206
|
+
.vx-pressable:pressed {
|
|
207
|
+
opacity: 0.85;
|
|
208
|
+
}
|
|
204
209
|
|
|
205
|
-
/* xplat-web-only:start — overlays/toasts/popovers render through RootLayout
|
|
210
|
+
/* xplat-web-only:start — overlays/toasts/popovers render through RootLayout
|
|
206
211
|
or showModal on native; these portal/positioning rules are web-only */
|
|
207
|
-
.vx-overlay {
|
|
208
|
-
|
|
209
|
-
}
|
|
212
|
+
.vx-overlay {
|
|
213
|
+
z-index: 1000;
|
|
214
|
+
}
|
|
210
215
|
|
|
211
|
-
.vx-overlay-shade {
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
}
|
|
216
|
+
.vx-overlay-shade {
|
|
217
|
+
position: absolute;
|
|
218
|
+
inset: 0;
|
|
219
|
+
background-color: rgba(0, 0, 0, 0.4);
|
|
220
|
+
}
|
|
216
221
|
|
|
217
|
-
.vx-overlay-content {
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
}
|
|
222
|
+
.vx-overlay-content {
|
|
223
|
+
position: relative;
|
|
224
|
+
z-index: 1;
|
|
225
|
+
}
|
|
221
226
|
|
|
222
|
-
.vx-popover {
|
|
223
|
-
|
|
224
|
-
}
|
|
227
|
+
.vx-popover {
|
|
228
|
+
z-index: 1001;
|
|
229
|
+
}
|
|
225
230
|
|
|
226
|
-
.vx-popover-backdrop {
|
|
227
|
-
|
|
228
|
-
}
|
|
231
|
+
.vx-popover-backdrop {
|
|
232
|
+
background-color: transparent;
|
|
233
|
+
}
|
|
229
234
|
|
|
230
|
-
.vx-tooltip {
|
|
231
|
-
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
|
|
235
|
-
|
|
236
|
-
|
|
237
|
-
|
|
238
|
-
|
|
239
|
-
|
|
240
|
-
}
|
|
235
|
+
.vx-tooltip {
|
|
236
|
+
padding: 4px 8px;
|
|
237
|
+
border-width: 1px;
|
|
238
|
+
border-color: var(--color-border);
|
|
239
|
+
border-radius: var(--radius-sm);
|
|
240
|
+
corner-shape: squircle;
|
|
241
|
+
background-color: var(--color-surface);
|
|
242
|
+
color: var(--color-text);
|
|
243
|
+
font-size: 12px;
|
|
244
|
+
line-height: 16px;
|
|
245
|
+
}
|
|
241
246
|
|
|
242
|
-
.vx-toast-host {
|
|
243
|
-
|
|
244
|
-
|
|
245
|
-
|
|
246
|
-
|
|
247
|
-
|
|
248
|
-
|
|
249
|
-
|
|
250
|
-
}
|
|
247
|
+
.vx-toast-host {
|
|
248
|
+
position: fixed;
|
|
249
|
+
z-index: 1002;
|
|
250
|
+
left: 0;
|
|
251
|
+
right: 0;
|
|
252
|
+
display: flex;
|
|
253
|
+
justify-content: center;
|
|
254
|
+
pointer-events: none;
|
|
255
|
+
}
|
|
251
256
|
|
|
252
|
-
.vx-toast-top {
|
|
253
|
-
|
|
254
|
-
}
|
|
255
|
-
.vx-toast-bottom {
|
|
256
|
-
|
|
257
|
-
}
|
|
257
|
+
.vx-toast-top {
|
|
258
|
+
top: 24px;
|
|
259
|
+
}
|
|
260
|
+
.vx-toast-bottom {
|
|
261
|
+
bottom: 24px;
|
|
262
|
+
}
|
|
258
263
|
|
|
259
|
-
.vx-toast {
|
|
260
|
-
|
|
261
|
-
}
|
|
262
|
-
/* xplat-web-only:end */
|
|
264
|
+
.vx-toast {
|
|
265
|
+
pointer-events: auto;
|
|
266
|
+
}
|
|
267
|
+
/* xplat-web-only:end */
|
|
263
268
|
|
|
264
|
-
/* Normalized OS-widget reset — TextInput/TextArea are real
|
|
269
|
+
/* Normalized OS-widget reset — TextInput/TextArea are real
|
|
265
270
|
<input>/<textarea>/TextField/TextView; the leaves emit vx-input/
|
|
266
271
|
vx-textarea unconditionally so the platform chrome is stripped before
|
|
267
272
|
app styles apply. On Android the transparent background replaces the
|
|
268
273
|
default EditText drawable (kills the Material underline); zero padding
|
|
269
274
|
removes native insets. Legitimate semantics — IME, secure entry,
|
|
270
275
|
selection, autofill, caret, focus — stay platform-native by design. */
|
|
271
|
-
.vx-input,
|
|
272
|
-
.vx-textarea {
|
|
273
|
-
|
|
274
|
-
|
|
275
|
-
|
|
276
|
-
|
|
277
|
-
|
|
278
|
-
|
|
279
|
-
|
|
280
|
-
|
|
281
|
-
}
|
|
282
|
-
/* xplat-web-only:start — DOM-only reset: element UA chrome and the
|
|
276
|
+
.vx-input,
|
|
277
|
+
.vx-textarea {
|
|
278
|
+
padding: 0;
|
|
279
|
+
margin: 0;
|
|
280
|
+
border-width: 0;
|
|
281
|
+
background-color: transparent;
|
|
282
|
+
color: var(--color-text);
|
|
283
|
+
font-size: 14px;
|
|
284
|
+
/* NS placeholder color; web uses the ::placeholder pseudo below. */
|
|
285
|
+
placeholder-color: var(--color-text-secondary);
|
|
286
|
+
}
|
|
287
|
+
/* xplat-web-only:start — DOM-only reset: element UA chrome and the
|
|
283
288
|
focus outline (normalized to the same thin ring on both). */
|
|
284
|
-
.vx-input,
|
|
285
|
-
.vx-textarea {
|
|
286
|
-
|
|
287
|
-
|
|
288
|
-
|
|
289
|
-
}
|
|
290
|
-
.vx-input:focus,
|
|
291
|
-
.vx-textarea:focus {
|
|
292
|
-
|
|
293
|
-
|
|
294
|
-
}
|
|
295
|
-
/* xplat-web-only:end */
|
|
289
|
+
.vx-input,
|
|
290
|
+
.vx-textarea {
|
|
291
|
+
appearance: none;
|
|
292
|
+
-webkit-appearance: none;
|
|
293
|
+
outline: none;
|
|
294
|
+
}
|
|
295
|
+
.vx-input:focus,
|
|
296
|
+
.vx-textarea:focus {
|
|
297
|
+
outline: 1px solid var(--color-primary);
|
|
298
|
+
outline-offset: -1px;
|
|
299
|
+
}
|
|
300
|
+
/* xplat-web-only:end */
|
|
296
301
|
|
|
297
|
-
/* auto-grow owns height — the manual resize handle has no native analog */
|
|
298
|
-
/* xplat-web-only:start */
|
|
299
|
-
.vx-textarea {
|
|
300
|
-
|
|
301
|
-
}
|
|
302
|
-
/* xplat-web-only:end */
|
|
302
|
+
/* auto-grow owns height — the manual resize handle has no native analog */
|
|
303
|
+
/* xplat-web-only:start */
|
|
304
|
+
.vx-textarea {
|
|
305
|
+
resize: none;
|
|
306
|
+
}
|
|
307
|
+
/* xplat-web-only:end */
|
|
303
308
|
|
|
304
|
-
/* WebView chrome reset — the web leaf is a real <iframe>: strip the UA's
|
|
309
|
+
/* WebView chrome reset — the web leaf is a real <iframe>: strip the UA's
|
|
305
310
|
inset border and the inline-element baseline gap. WKWebView and
|
|
306
311
|
android.webkit.WebView ship chrome-free, so there is no native reset. */
|
|
307
|
-
/* xplat-web-only:start */
|
|
308
|
-
.vx-webview {
|
|
309
|
-
|
|
310
|
-
|
|
311
|
-
}
|
|
312
|
-
/* xplat-web-only:end */
|
|
312
|
+
/* xplat-web-only:start */
|
|
313
|
+
.vx-webview {
|
|
314
|
+
display: block;
|
|
315
|
+
border-width: 0;
|
|
316
|
+
}
|
|
317
|
+
/* xplat-web-only:end */
|
|
313
318
|
|
|
314
|
-
/* Video — surface-hosted leaf: the engine surface fills the frame and the
|
|
319
|
+
/* Video — surface-hosted leaf: the engine surface fills the frame and the
|
|
315
320
|
self-drawn transport layers stack on top in the same grid cell
|
|
316
321
|
(vx-stack). NS-side rules only — DOM resets sit in the web block. */
|
|
317
|
-
.vx-video {
|
|
318
|
-
|
|
319
|
-
}
|
|
322
|
+
.vx-video {
|
|
323
|
+
background-color: #000;
|
|
324
|
+
}
|
|
320
325
|
|
|
321
|
-
.vx-video > * {
|
|
322
|
-
|
|
323
|
-
|
|
324
|
-
}
|
|
326
|
+
.vx-video > * {
|
|
327
|
+
horizontal-align: stretch;
|
|
328
|
+
vertical-align: stretch;
|
|
329
|
+
}
|
|
325
330
|
|
|
326
|
-
.vx-video-centerbtn {
|
|
327
|
-
|
|
328
|
-
|
|
329
|
-
|
|
330
|
-
|
|
331
|
-
|
|
332
|
-
|
|
333
|
-
}
|
|
331
|
+
.vx-video-centerbtn {
|
|
332
|
+
width: 56px;
|
|
333
|
+
height: 56px;
|
|
334
|
+
border-radius: 28px;
|
|
335
|
+
background-color: rgba(0, 0, 0, 0.55);
|
|
336
|
+
align-items: center;
|
|
337
|
+
justify-content: center;
|
|
338
|
+
}
|
|
334
339
|
|
|
335
|
-
.vx-video-bar {
|
|
336
|
-
|
|
337
|
-
|
|
338
|
-
}
|
|
340
|
+
.vx-video-bar {
|
|
341
|
+
background-color: rgba(0, 0, 0, 0.45);
|
|
342
|
+
padding: 4px 8px;
|
|
343
|
+
}
|
|
339
344
|
|
|
340
|
-
.vx-video-btn {
|
|
341
|
-
|
|
342
|
-
}
|
|
345
|
+
.vx-video-btn {
|
|
346
|
+
padding: 4px;
|
|
347
|
+
}
|
|
343
348
|
|
|
344
|
-
/* Full-frame tap layer — hit target only, never paints. */
|
|
345
|
-
.vx-video-tap {
|
|
346
|
-
|
|
347
|
-
}
|
|
349
|
+
/* Full-frame tap layer — hit target only, never paints. */
|
|
350
|
+
.vx-video-tap {
|
|
351
|
+
background-color: transparent;
|
|
352
|
+
}
|
|
348
353
|
|
|
349
|
-
.vx-video-time {
|
|
350
|
-
|
|
351
|
-
|
|
352
|
-
|
|
353
|
-
|
|
354
|
-
}
|
|
354
|
+
.vx-video-time {
|
|
355
|
+
color: #fff;
|
|
356
|
+
font-size: 11px;
|
|
357
|
+
min-width: 34px;
|
|
358
|
+
text-align: center;
|
|
359
|
+
}
|
|
355
360
|
|
|
356
|
-
/* xplat-web-only:start — the <video> element is inline and overlays would
|
|
361
|
+
/* xplat-web-only:start — the <video> element is inline and overlays would
|
|
357
362
|
otherwise swallow pointer events; native layers are hit-transparent by
|
|
358
363
|
default, so none of this exists on NS. */
|
|
359
|
-
.vx-video-surface {
|
|
360
|
-
|
|
361
|
-
|
|
362
|
-
|
|
363
|
-
}
|
|
364
|
+
.vx-video-surface {
|
|
365
|
+
display: block;
|
|
366
|
+
width: 100%;
|
|
367
|
+
height: 100%;
|
|
368
|
+
}
|
|
364
369
|
|
|
365
|
-
.vx-video-poster,
|
|
366
|
-
.vx-video-barwrap {
|
|
367
|
-
|
|
368
|
-
}
|
|
370
|
+
.vx-video-poster,
|
|
371
|
+
.vx-video-barwrap {
|
|
372
|
+
pointer-events: none;
|
|
373
|
+
}
|
|
369
374
|
|
|
370
|
-
.vx-video-barwrap > * {
|
|
371
|
-
|
|
372
|
-
}
|
|
375
|
+
.vx-video-barwrap > * {
|
|
376
|
+
pointer-events: auto;
|
|
377
|
+
}
|
|
373
378
|
|
|
374
|
-
.vx-video-poster {
|
|
375
|
-
|
|
376
|
-
}
|
|
379
|
+
.vx-video-poster {
|
|
380
|
+
object-fit: cover;
|
|
381
|
+
}
|
|
377
382
|
|
|
378
|
-
/* xplat-web-only:end */
|
|
383
|
+
/* xplat-web-only:end */
|
|
379
384
|
|
|
380
|
-
/* xplat-web-only:start */
|
|
381
|
-
/* Modal ROUTES (pushRoute presentation:'modal') — the URL stays underneath,
|
|
385
|
+
/* xplat-web-only:start */
|
|
386
|
+
/* Modal ROUTES (pushRoute presentation:'modal') — the URL stays underneath,
|
|
382
387
|
so the overlay is a fixed layer over the shell rather than a dialog. */
|
|
383
|
-
.vx-modalroute {
|
|
384
|
-
|
|
385
|
-
|
|
386
|
-
|
|
387
|
-
|
|
388
|
-
|
|
389
|
-
|
|
390
|
-
}
|
|
388
|
+
.vx-modalroute {
|
|
389
|
+
position: fixed;
|
|
390
|
+
inset: 0;
|
|
391
|
+
z-index: 1000;
|
|
392
|
+
display: flex;
|
|
393
|
+
align-items: stretch;
|
|
394
|
+
justify-content: stretch;
|
|
395
|
+
}
|
|
391
396
|
|
|
392
|
-
.vx-modalroute-shade {
|
|
393
|
-
|
|
394
|
-
|
|
395
|
-
|
|
396
|
-
|
|
397
|
-
|
|
398
|
-
|
|
399
|
-
}
|
|
397
|
+
.vx-modalroute-shade {
|
|
398
|
+
position: absolute;
|
|
399
|
+
inset: 0;
|
|
400
|
+
border: 0;
|
|
401
|
+
padding: 0;
|
|
402
|
+
background: rgba(0, 0, 0, 0.4);
|
|
403
|
+
cursor: default;
|
|
404
|
+
}
|
|
400
405
|
|
|
401
|
-
.vx-modalroute-body {
|
|
402
|
-
|
|
403
|
-
|
|
404
|
-
|
|
405
|
-
|
|
406
|
-
|
|
407
|
-
|
|
408
|
-
}
|
|
409
|
-
/* xplat-web-only:end */
|
|
406
|
+
.vx-modalroute-body {
|
|
407
|
+
position: relative;
|
|
408
|
+
flex: 1;
|
|
409
|
+
min-width: 0;
|
|
410
|
+
overflow: auto;
|
|
411
|
+
color: var(--color-text);
|
|
412
|
+
background-color: var(--color-surface);
|
|
413
|
+
}
|
|
414
|
+
/* xplat-web-only:end */
|
|
410
415
|
|
|
411
|
-
/* xplat-web-only:start — placeholder pseudos are DOM-only. Muted like
|
|
416
|
+
/* xplat-web-only:start — placeholder pseudos are DOM-only. Muted like
|
|
412
417
|
real placeholder text, not currentColor (a full-opacity hint reads as
|
|
413
418
|
a typed value); --placeholder-color is the per-field prop escape. */
|
|
414
|
-
input::placeholder,
|
|
415
|
-
textarea::placeholder {
|
|
416
|
-
|
|
417
|
-
}
|
|
418
|
-
/* xplat-web-only:end */
|
|
419
|
+
input::placeholder,
|
|
420
|
+
textarea::placeholder {
|
|
421
|
+
color: var(--placeholder-color, var(--color-text-secondary));
|
|
422
|
+
}
|
|
423
|
+
/* xplat-web-only:end */
|
|
419
424
|
|
|
420
|
-
/* xplat-web-only:start — form controls don't inherit the body font in the
|
|
425
|
+
/* xplat-web-only:start — form controls don't inherit the body font in the
|
|
421
426
|
DOM (UA stylesheet wins); without this they render in the UA face. */
|
|
422
|
-
input,
|
|
423
|
-
textarea,
|
|
424
|
-
select,
|
|
425
|
-
button {
|
|
426
|
-
|
|
427
|
-
}
|
|
428
|
-
/* xplat-web-only:end */
|
|
427
|
+
input,
|
|
428
|
+
textarea,
|
|
429
|
+
select,
|
|
430
|
+
button {
|
|
431
|
+
font-family: inherit;
|
|
432
|
+
}
|
|
433
|
+
/* xplat-web-only:end */
|
|
429
434
|
|
|
430
|
-
/* Self-drawn spinner — the border ring is shared (native rotates the
|
|
435
|
+
/* Self-drawn spinner — the border ring is shared (native rotates the
|
|
431
436
|
view via `animate`; DOM spins via the keyframes below). */
|
|
432
|
-
.vx-spinner {
|
|
433
|
-
|
|
434
|
-
|
|
435
|
-
|
|
436
|
-
|
|
437
|
-
|
|
438
|
-
|
|
439
|
-
}
|
|
440
|
-
/* Pull-to-refresh — the overlay strip hosting the spinner. Its height is
|
|
437
|
+
.vx-spinner {
|
|
438
|
+
width: 24px;
|
|
439
|
+
height: 24px;
|
|
440
|
+
border-width: 2px;
|
|
441
|
+
border-color: var(--color-text-secondary);
|
|
442
|
+
border-right-color: transparent;
|
|
443
|
+
border-radius: 50%;
|
|
444
|
+
}
|
|
445
|
+
/* Pull-to-refresh — the overlay strip hosting the spinner. Its height is
|
|
441
446
|
the default `refreshThreshold` (64px web / 64dip native); the leaf
|
|
442
447
|
translates it in/out — reveal math lives in refresh.*.ts. */
|
|
443
|
-
.vx-refresh {
|
|
444
|
-
|
|
445
|
-
|
|
446
|
-
|
|
447
|
-
|
|
448
|
-
|
|
449
|
-
}
|
|
450
|
-
/* xplat-web-only:start — the DOM leaf needs explicit clipping plus the
|
|
448
|
+
.vx-refresh {
|
|
449
|
+
display: flex;
|
|
450
|
+
flex-direction: column;
|
|
451
|
+
align-items: center;
|
|
452
|
+
justify-content: center;
|
|
453
|
+
height: 64px;
|
|
454
|
+
}
|
|
455
|
+
/* xplat-web-only:start — the DOM leaf needs explicit clipping plus the
|
|
451
456
|
absolute overlay; native clips via the wrapper grid
|
|
452
457
|
(clipsToBounds/ViewGroup) and stacks children in one cell. */
|
|
453
|
-
.vx-refresh-wrap {
|
|
454
|
-
|
|
455
|
-
|
|
456
|
-
|
|
457
|
-
|
|
458
|
-
}
|
|
459
|
-
.vx-refresh-wrap > .vx-scroll {
|
|
460
|
-
|
|
461
|
-
|
|
462
|
-
}
|
|
463
|
-
.vx-refresh {
|
|
464
|
-
|
|
465
|
-
|
|
466
|
-
|
|
467
|
-
|
|
468
|
-
}
|
|
469
|
-
/* xplat-web-only:end */
|
|
470
|
-
/* xplat-web-only:start — DOM needs an inline-block box + CSS animation;
|
|
458
|
+
.vx-refresh-wrap {
|
|
459
|
+
position: relative;
|
|
460
|
+
overflow: hidden;
|
|
461
|
+
display: flex;
|
|
462
|
+
flex-direction: column;
|
|
463
|
+
}
|
|
464
|
+
.vx-refresh-wrap > .vx-scroll {
|
|
465
|
+
flex: 1;
|
|
466
|
+
min-height: 0;
|
|
467
|
+
}
|
|
468
|
+
.vx-refresh {
|
|
469
|
+
position: absolute;
|
|
470
|
+
top: 0;
|
|
471
|
+
left: 0;
|
|
472
|
+
right: 0;
|
|
473
|
+
}
|
|
474
|
+
/* xplat-web-only:end */
|
|
475
|
+
/* xplat-web-only:start — DOM needs an inline-block box + CSS animation;
|
|
471
476
|
the native leaf drives view.animate instead */
|
|
472
|
-
.vx-spinner {
|
|
473
|
-
|
|
474
|
-
|
|
475
|
-
|
|
476
|
-
}
|
|
477
|
+
.vx-spinner {
|
|
478
|
+
display: inline-block;
|
|
479
|
+
box-sizing: border-box;
|
|
480
|
+
animation: vx-spinner-turn 0.8s linear infinite;
|
|
481
|
+
}
|
|
477
482
|
|
|
478
|
-
@keyframes vx-spinner-turn {
|
|
479
|
-
|
|
480
|
-
|
|
483
|
+
@keyframes vx-spinner-turn {
|
|
484
|
+
to {
|
|
485
|
+
transform: rotate(360deg);
|
|
486
|
+
}
|
|
481
487
|
}
|
|
482
|
-
|
|
483
|
-
/* xplat-web-only:end */
|
|
488
|
+
/* xplat-web-only:end */
|
|
484
489
|
|
|
485
|
-
/* Self-drawn switch — flex track + thumb. `--on` flips justify-content,
|
|
490
|
+
/* Self-drawn switch — flex track + thumb. `--on` flips justify-content,
|
|
486
491
|
which slides the thumb; identical geometry on web and native. */
|
|
487
|
-
.vx-switch {
|
|
488
|
-
|
|
489
|
-
|
|
490
|
-
|
|
491
|
-
|
|
492
|
-
|
|
493
|
-
|
|
494
|
-
|
|
495
|
-
|
|
496
|
-
}
|
|
497
|
-
.vx-switch--on {
|
|
498
|
-
|
|
499
|
-
|
|
500
|
-
}
|
|
501
|
-
.vx-switch-thumb {
|
|
502
|
-
|
|
503
|
-
|
|
504
|
-
|
|
505
|
-
|
|
506
|
-
}
|
|
507
|
-
/* xplat-web-only:start — the DOM host is a div; flex + cursor live here */
|
|
508
|
-
.vx-switch {
|
|
509
|
-
|
|
510
|
-
|
|
511
|
-
}
|
|
512
|
-
/* xplat-web-only:end */
|
|
492
|
+
.vx-switch {
|
|
493
|
+
width: 48px;
|
|
494
|
+
height: 28px;
|
|
495
|
+
padding-left: 3px;
|
|
496
|
+
padding-right: 3px;
|
|
497
|
+
border-radius: 14px;
|
|
498
|
+
background-color: var(--color-border);
|
|
499
|
+
justify-content: flex-start;
|
|
500
|
+
align-items: center;
|
|
501
|
+
}
|
|
502
|
+
.vx-switch--on {
|
|
503
|
+
background-color: var(--color-primary);
|
|
504
|
+
justify-content: flex-end;
|
|
505
|
+
}
|
|
506
|
+
.vx-switch-thumb {
|
|
507
|
+
width: 22px;
|
|
508
|
+
height: 22px;
|
|
509
|
+
border-radius: 50%;
|
|
510
|
+
background-color: var(--color-surface);
|
|
511
|
+
}
|
|
512
|
+
/* xplat-web-only:start — the DOM host is a div; flex + cursor live here */
|
|
513
|
+
.vx-switch {
|
|
514
|
+
display: flex;
|
|
515
|
+
cursor: pointer;
|
|
516
|
+
}
|
|
517
|
+
/* xplat-web-only:end */
|
|
513
518
|
|
|
514
|
-
/* Self-drawn slider — host is a grid (native) / relative div (web);
|
|
519
|
+
/* Self-drawn slider — host is a grid (native) / relative div (web);
|
|
515
520
|
track + fill + thumb overlay the same box. */
|
|
516
|
-
.vx-slider {
|
|
517
|
-
|
|
518
|
-
}
|
|
519
|
-
.vx-slider-track {
|
|
520
|
-
|
|
521
|
-
|
|
522
|
-
|
|
523
|
-
|
|
524
|
-
}
|
|
525
|
-
.vx-slider-fill {
|
|
526
|
-
|
|
527
|
-
|
|
528
|
-
|
|
529
|
-
|
|
530
|
-
}
|
|
531
|
-
.vx-slider-thumb {
|
|
532
|
-
|
|
533
|
-
|
|
534
|
-
|
|
535
|
-
|
|
536
|
-
|
|
537
|
-
}
|
|
538
|
-
/* xplat-web-only:start — absolute positioning is DOM-only; native grid
|
|
521
|
+
.vx-slider {
|
|
522
|
+
height: 28px;
|
|
523
|
+
}
|
|
524
|
+
.vx-slider-track {
|
|
525
|
+
height: 4px;
|
|
526
|
+
border-radius: 2px;
|
|
527
|
+
background-color: var(--color-border);
|
|
528
|
+
vertical-align: middle;
|
|
529
|
+
}
|
|
530
|
+
.vx-slider-fill {
|
|
531
|
+
height: 4px;
|
|
532
|
+
border-radius: 2px;
|
|
533
|
+
background-color: var(--color-primary);
|
|
534
|
+
vertical-align: middle;
|
|
535
|
+
}
|
|
536
|
+
.vx-slider-thumb {
|
|
537
|
+
width: 20px;
|
|
538
|
+
height: 20px;
|
|
539
|
+
border-radius: 50%;
|
|
540
|
+
background-color: var(--color-primary);
|
|
541
|
+
vertical-align: middle;
|
|
542
|
+
}
|
|
543
|
+
/* xplat-web-only:start — absolute positioning is DOM-only; native grid
|
|
539
544
|
children center via vertical-align and pin via margin-left. */
|
|
540
|
-
.vx-slider {
|
|
541
|
-
|
|
542
|
-
}
|
|
543
|
-
.vx-slider-track,
|
|
544
|
-
.vx-slider-fill {
|
|
545
|
-
|
|
546
|
-
|
|
547
|
-
|
|
548
|
-
|
|
549
|
-
|
|
550
|
-
}
|
|
551
|
-
.vx-slider-thumb {
|
|
552
|
-
|
|
553
|
-
|
|
554
|
-
|
|
555
|
-
}
|
|
556
|
-
/* xplat-web-only:end */
|
|
545
|
+
.vx-slider {
|
|
546
|
+
position: relative;
|
|
547
|
+
}
|
|
548
|
+
.vx-slider-track,
|
|
549
|
+
.vx-slider-fill {
|
|
550
|
+
position: absolute;
|
|
551
|
+
top: 50%;
|
|
552
|
+
left: 0;
|
|
553
|
+
right: 0;
|
|
554
|
+
transform: translateY(-50%);
|
|
555
|
+
}
|
|
556
|
+
.vx-slider-thumb {
|
|
557
|
+
position: absolute;
|
|
558
|
+
top: 50%;
|
|
559
|
+
transform: translate(-50%, -50%);
|
|
560
|
+
}
|
|
561
|
+
/* xplat-web-only:end */
|
|
557
562
|
|
|
558
|
-
/* xplat-web-only:start — Pager's web leaf is a mandatory scroll-snap row:
|
|
563
|
+
/* xplat-web-only:start — Pager's web leaf is a mandatory scroll-snap row:
|
|
559
564
|
one page per item at 100% host width so scrollLeft / clientWidth is a
|
|
560
565
|
clean page index. Native pages are sized by the widget itself, so the
|
|
561
566
|
whole block is DOM-only. Scrollbar hidden (native has none); contain
|
|
562
567
|
keeps the swipe from chaining to a parent scroller, matching .vx-scroll. */
|
|
563
|
-
.vx-pager {
|
|
564
|
-
|
|
565
|
-
|
|
566
|
-
|
|
567
|
-
|
|
568
|
-
|
|
569
|
-
|
|
570
|
-
|
|
571
|
-
|
|
572
|
-
}
|
|
573
|
-
.vx-pager::-webkit-scrollbar {
|
|
574
|
-
|
|
575
|
-
}
|
|
576
|
-
.vx-pager-page {
|
|
577
|
-
|
|
578
|
-
|
|
579
|
-
|
|
580
|
-
|
|
581
|
-
|
|
582
|
-
}
|
|
583
|
-
/* xplat-web-only:end */
|
|
568
|
+
.vx-pager {
|
|
569
|
+
display: flex;
|
|
570
|
+
flex-direction: row;
|
|
571
|
+
overflow-x: auto;
|
|
572
|
+
overflow-y: hidden;
|
|
573
|
+
scroll-snap-type: x mandatory;
|
|
574
|
+
overscroll-behavior-x: contain;
|
|
575
|
+
scrollbar-width: none;
|
|
576
|
+
touch-action: pan-x;
|
|
577
|
+
}
|
|
578
|
+
.vx-pager::-webkit-scrollbar {
|
|
579
|
+
display: none;
|
|
580
|
+
}
|
|
581
|
+
.vx-pager-page {
|
|
582
|
+
flex: 0 0 100%;
|
|
583
|
+
min-width: 0;
|
|
584
|
+
display: flex;
|
|
585
|
+
flex-direction: column;
|
|
586
|
+
scroll-snap-align: start;
|
|
587
|
+
}
|
|
588
|
+
/* xplat-web-only:end */
|
|
584
589
|
|
|
585
|
-
/* Phase-1 self-drawn components — functional geometry + token chrome only;
|
|
590
|
+
/* Phase-1 self-drawn components — functional geometry + token chrome only;
|
|
586
591
|
visual design is the app's job. */
|
|
587
592
|
|
|
588
|
-
/* Button — row-direction pressable (vx-pressable already supplies display
|
|
593
|
+
/* Button — row-direction pressable (vx-pressable already supplies display
|
|
589
594
|
and press feedback). */
|
|
590
|
-
.vx-button {
|
|
591
|
-
|
|
592
|
-
|
|
593
|
-
|
|
594
|
-
}
|
|
595
|
+
.vx-button {
|
|
596
|
+
flex-direction: row;
|
|
597
|
+
align-items: center;
|
|
598
|
+
justify-content: center;
|
|
599
|
+
}
|
|
595
600
|
|
|
596
|
-
/* Collapsible/Accordion — column stacks. */
|
|
597
|
-
.vx-collapsible,
|
|
598
|
-
.vx-collapsible-content,
|
|
599
|
-
.vx-accordion,
|
|
600
|
-
.vx-accordion-item {
|
|
601
|
-
|
|
602
|
-
}
|
|
601
|
+
/* Collapsible/Accordion — column stacks. */
|
|
602
|
+
.vx-collapsible,
|
|
603
|
+
.vx-collapsible-content,
|
|
604
|
+
.vx-accordion,
|
|
605
|
+
.vx-accordion-item {
|
|
606
|
+
flex-direction: column;
|
|
607
|
+
}
|
|
603
608
|
|
|
604
|
-
/* Checkbox — 20px box + check glyph; --on fills with primary. */
|
|
605
|
-
.vx-checkbox-row {
|
|
606
|
-
|
|
607
|
-
|
|
608
|
-
}
|
|
609
|
-
.vx-checkbox {
|
|
610
|
-
|
|
611
|
-
|
|
612
|
-
|
|
613
|
-
|
|
614
|
-
|
|
615
|
-
|
|
616
|
-
|
|
617
|
-
}
|
|
618
|
-
.vx-checkbox--on .vx-checkbox {
|
|
619
|
-
|
|
620
|
-
|
|
621
|
-
}
|
|
622
|
-
.vx-checkbox-check {
|
|
623
|
-
|
|
624
|
-
|
|
625
|
-
|
|
626
|
-
}
|
|
627
|
-
.vx-checkbox--on .vx-checkbox-check {
|
|
628
|
-
|
|
629
|
-
}
|
|
630
|
-
.vx-checkbox-label {
|
|
631
|
-
|
|
632
|
-
}
|
|
633
|
-
.vx-checkbox--disabled {
|
|
634
|
-
|
|
635
|
-
}
|
|
609
|
+
/* Checkbox — 20px box + check glyph; --on fills with primary. */
|
|
610
|
+
.vx-checkbox-row {
|
|
611
|
+
flex-direction: row;
|
|
612
|
+
align-items: center;
|
|
613
|
+
}
|
|
614
|
+
.vx-checkbox {
|
|
615
|
+
width: 20px;
|
|
616
|
+
height: 20px;
|
|
617
|
+
border-width: 1px;
|
|
618
|
+
border-color: var(--color-border);
|
|
619
|
+
border-radius: var(--radius-sm);
|
|
620
|
+
align-items: center;
|
|
621
|
+
justify-content: center;
|
|
622
|
+
}
|
|
623
|
+
.vx-checkbox--on .vx-checkbox {
|
|
624
|
+
background-color: var(--color-primary);
|
|
625
|
+
border-color: var(--color-primary);
|
|
626
|
+
}
|
|
627
|
+
.vx-checkbox-check {
|
|
628
|
+
font-size: 14px;
|
|
629
|
+
line-height: 20px;
|
|
630
|
+
color: var(--color-onprimary);
|
|
631
|
+
}
|
|
632
|
+
.vx-checkbox--on .vx-checkbox-check {
|
|
633
|
+
color: var(--color-onprimary);
|
|
634
|
+
}
|
|
635
|
+
.vx-checkbox-label {
|
|
636
|
+
margin-left: 8px;
|
|
637
|
+
}
|
|
638
|
+
.vx-checkbox--disabled {
|
|
639
|
+
opacity: 0.5;
|
|
640
|
+
}
|
|
636
641
|
|
|
637
|
-
/* Radio group — column/row of dot options. */
|
|
638
|
-
.vx-radio-group {
|
|
639
|
-
|
|
640
|
-
}
|
|
641
|
-
.vx-radio-group--row {
|
|
642
|
-
|
|
643
|
-
}
|
|
644
|
-
.vx-radio-row {
|
|
645
|
-
|
|
646
|
-
|
|
647
|
-
}
|
|
648
|
-
.vx-radio {
|
|
649
|
-
|
|
650
|
-
|
|
651
|
-
|
|
652
|
-
|
|
653
|
-
|
|
654
|
-
|
|
655
|
-
|
|
656
|
-
}
|
|
657
|
-
.vx-radio--on .vx-radio {
|
|
658
|
-
|
|
659
|
-
}
|
|
660
|
-
.vx-radio-dot {
|
|
661
|
-
|
|
662
|
-
|
|
663
|
-
|
|
664
|
-
|
|
665
|
-
}
|
|
666
|
-
.vx-radio-label {
|
|
667
|
-
|
|
668
|
-
}
|
|
669
|
-
.vx-radio--disabled {
|
|
670
|
-
|
|
671
|
-
}
|
|
642
|
+
/* Radio group — column/row of dot options. */
|
|
643
|
+
.vx-radio-group {
|
|
644
|
+
flex-direction: column;
|
|
645
|
+
}
|
|
646
|
+
.vx-radio-group--row {
|
|
647
|
+
flex-direction: row;
|
|
648
|
+
}
|
|
649
|
+
.vx-radio-row {
|
|
650
|
+
flex-direction: row;
|
|
651
|
+
align-items: center;
|
|
652
|
+
}
|
|
653
|
+
.vx-radio {
|
|
654
|
+
width: 18px;
|
|
655
|
+
height: 18px;
|
|
656
|
+
border-width: 1px;
|
|
657
|
+
border-color: var(--color-border);
|
|
658
|
+
border-radius: 50%;
|
|
659
|
+
align-items: center;
|
|
660
|
+
justify-content: center;
|
|
661
|
+
}
|
|
662
|
+
.vx-radio--on .vx-radio {
|
|
663
|
+
border-color: var(--color-primary);
|
|
664
|
+
}
|
|
665
|
+
.vx-radio-dot {
|
|
666
|
+
width: 8px;
|
|
667
|
+
height: 8px;
|
|
668
|
+
border-radius: 50%;
|
|
669
|
+
background-color: var(--color-primary);
|
|
670
|
+
}
|
|
671
|
+
.vx-radio-label {
|
|
672
|
+
margin-left: 8px;
|
|
673
|
+
}
|
|
674
|
+
.vx-radio--disabled {
|
|
675
|
+
opacity: 0.5;
|
|
676
|
+
}
|
|
672
677
|
|
|
673
|
-
/* SegmentedControl — equal-width segments in a rounded track; `--on`
|
|
678
|
+
/* SegmentedControl — equal-width segments in a rounded track; `--on`
|
|
674
679
|
raises the selected one. flex-basis is dead on NS (the shorthand parser
|
|
675
680
|
drops it and the standalone property isn't registered), so width:0 +
|
|
676
681
|
flex-grow:1 is what distributes segments equally on both engines. */
|
|
677
|
-
.vx-segmented {
|
|
678
|
-
|
|
679
|
-
|
|
680
|
-
|
|
681
|
-
|
|
682
|
-
|
|
683
|
-
|
|
684
|
-
|
|
685
|
-
|
|
686
|
-
}
|
|
687
|
-
.vx-segment {
|
|
688
|
-
|
|
689
|
-
|
|
690
|
-
|
|
691
|
-
|
|
692
|
-
|
|
693
|
-
|
|
694
|
-
|
|
695
|
-
|
|
696
|
-
|
|
697
|
-
|
|
698
|
-
}
|
|
699
|
-
.vx-segment--on {
|
|
700
|
-
|
|
701
|
-
}
|
|
702
|
-
.vx-segment-label {
|
|
703
|
-
|
|
704
|
-
|
|
705
|
-
}
|
|
706
|
-
.vx-segment--on .vx-segment-label {
|
|
707
|
-
|
|
708
|
-
|
|
709
|
-
}
|
|
710
|
-
.vx-segmented--disabled,
|
|
711
|
-
.vx-segment--disabled {
|
|
712
|
-
|
|
713
|
-
}
|
|
714
|
-
/* xplat-web-only:start — the DOM hosts are divs; flex + cursor live here */
|
|
715
|
-
.vx-segmented {
|
|
716
|
-
|
|
717
|
-
}
|
|
718
|
-
.vx-segment {
|
|
719
|
-
|
|
720
|
-
|
|
721
|
-
|
|
722
|
-
}
|
|
723
|
-
.vx-segment:focus {
|
|
724
|
-
|
|
725
|
-
|
|
726
|
-
}
|
|
727
|
-
.vx-segment--disabled {
|
|
728
|
-
|
|
729
|
-
}
|
|
730
|
-
/* xplat-web-only:end */
|
|
682
|
+
.vx-segmented {
|
|
683
|
+
flex-direction: row;
|
|
684
|
+
padding: 3px;
|
|
685
|
+
border-width: 1px;
|
|
686
|
+
border-color: var(--color-border);
|
|
687
|
+
border-radius: var(--radius-md);
|
|
688
|
+
corner-shape: squircle;
|
|
689
|
+
background-color: var(--color-surface-secondary);
|
|
690
|
+
color: var(--color-text);
|
|
691
|
+
}
|
|
692
|
+
.vx-segment {
|
|
693
|
+
flex-grow: 1;
|
|
694
|
+
width: 0;
|
|
695
|
+
flex-direction: row;
|
|
696
|
+
align-items: center;
|
|
697
|
+
justify-content: center;
|
|
698
|
+
padding-top: 6px;
|
|
699
|
+
padding-bottom: 6px;
|
|
700
|
+
padding-left: 10px;
|
|
701
|
+
padding-right: 10px;
|
|
702
|
+
border-radius: var(--radius-sm);
|
|
703
|
+
}
|
|
704
|
+
.vx-segment--on {
|
|
705
|
+
background-color: var(--color-surface);
|
|
706
|
+
}
|
|
707
|
+
.vx-segment-label {
|
|
708
|
+
font-size: 13px;
|
|
709
|
+
color: var(--color-text-secondary);
|
|
710
|
+
}
|
|
711
|
+
.vx-segment--on .vx-segment-label {
|
|
712
|
+
color: var(--color-text);
|
|
713
|
+
font-weight: 600;
|
|
714
|
+
}
|
|
715
|
+
.vx-segmented--disabled,
|
|
716
|
+
.vx-segment--disabled {
|
|
717
|
+
opacity: 0.5;
|
|
718
|
+
}
|
|
719
|
+
/* xplat-web-only:start — the DOM hosts are divs; flex + cursor live here */
|
|
720
|
+
.vx-segmented {
|
|
721
|
+
display: flex;
|
|
722
|
+
}
|
|
723
|
+
.vx-segment {
|
|
724
|
+
display: flex;
|
|
725
|
+
cursor: pointer;
|
|
726
|
+
user-select: none;
|
|
727
|
+
}
|
|
728
|
+
.vx-segment:focus {
|
|
729
|
+
outline: 1px solid var(--color-primary);
|
|
730
|
+
outline-offset: -1px;
|
|
731
|
+
}
|
|
732
|
+
.vx-segment--disabled {
|
|
733
|
+
cursor: default;
|
|
734
|
+
}
|
|
735
|
+
/* xplat-web-only:end */
|
|
731
736
|
|
|
732
|
-
/* SearchInput — chrome-reset field: bordered shell, leading glyph, the
|
|
737
|
+
/* SearchInput — chrome-reset field: bordered shell, leading glyph, the
|
|
733
738
|
field owns the remaining width, self-drawn clear. The web leaf hides the
|
|
734
739
|
engine's own search-cancel button so native's (hand-drawn) matches. */
|
|
735
|
-
.vx-search {
|
|
736
|
-
|
|
737
|
-
|
|
738
|
-
|
|
739
|
-
|
|
740
|
-
|
|
741
|
-
|
|
742
|
-
|
|
743
|
-
|
|
744
|
-
|
|
745
|
-
|
|
746
|
-
|
|
747
|
-
|
|
748
|
-
}
|
|
749
|
-
.vx-search-icon {
|
|
750
|
-
|
|
751
|
-
}
|
|
752
|
-
.vx-search-field {
|
|
753
|
-
|
|
754
|
-
|
|
755
|
-
|
|
756
|
-
|
|
757
|
-
|
|
758
|
-
}
|
|
759
|
-
.vx-search-clear {
|
|
760
|
-
|
|
761
|
-
|
|
762
|
-
|
|
763
|
-
|
|
764
|
-
|
|
765
|
-
|
|
766
|
-
|
|
767
|
-
}
|
|
768
|
-
.vx-search--disabled {
|
|
769
|
-
|
|
770
|
-
}
|
|
771
|
-
/* xplat-web-only:start — the DOM host/field/buttons need display + the UA
|
|
740
|
+
.vx-search {
|
|
741
|
+
flex-direction: row;
|
|
742
|
+
align-items: center;
|
|
743
|
+
padding-top: 6px;
|
|
744
|
+
padding-bottom: 6px;
|
|
745
|
+
padding-left: 10px;
|
|
746
|
+
padding-right: 6px;
|
|
747
|
+
border-width: 1px;
|
|
748
|
+
border-color: var(--color-border);
|
|
749
|
+
border-radius: var(--radius-md);
|
|
750
|
+
corner-shape: squircle;
|
|
751
|
+
background-color: var(--color-surface);
|
|
752
|
+
color: var(--color-text);
|
|
753
|
+
}
|
|
754
|
+
.vx-search-icon {
|
|
755
|
+
color: var(--color-text-secondary);
|
|
756
|
+
}
|
|
757
|
+
.vx-search-field {
|
|
758
|
+
flex-grow: 1;
|
|
759
|
+
padding-left: 8px;
|
|
760
|
+
padding-right: 8px;
|
|
761
|
+
font-size: 14px;
|
|
762
|
+
color: var(--color-text);
|
|
763
|
+
}
|
|
764
|
+
.vx-search-clear {
|
|
765
|
+
width: 24px;
|
|
766
|
+
height: 24px;
|
|
767
|
+
border-radius: 9999px;
|
|
768
|
+
align-items: center;
|
|
769
|
+
justify-content: center;
|
|
770
|
+
background-color: var(--color-surface-secondary);
|
|
771
|
+
color: var(--color-text-secondary);
|
|
772
|
+
}
|
|
773
|
+
.vx-search--disabled {
|
|
774
|
+
opacity: 0.5;
|
|
775
|
+
}
|
|
776
|
+
/* xplat-web-only:start — the DOM host/field/buttons need display + the UA
|
|
772
777
|
reset; native's flexbox children carry these from the class already. */
|
|
773
|
-
.vx-search {
|
|
774
|
-
|
|
775
|
-
}
|
|
776
|
-
.vx-search-icon {
|
|
777
|
-
|
|
778
|
-
|
|
779
|
-
}
|
|
780
|
-
.vx-search-field {
|
|
781
|
-
|
|
782
|
-
|
|
783
|
-
|
|
784
|
-
|
|
785
|
-
|
|
786
|
-
|
|
787
|
-
}
|
|
788
|
-
input.vx-search-field::-webkit-search-cancel-button {
|
|
789
|
-
|
|
790
|
-
}
|
|
791
|
-
.vx-search-clear {
|
|
792
|
-
|
|
793
|
-
|
|
794
|
-
|
|
795
|
-
|
|
796
|
-
}
|
|
797
|
-
/* xplat-web-only:end */
|
|
798
|
-
|
|
799
|
-
/* Anchored menus — panel + item rows (the Popover leaf positions it). */
|
|
800
|
-
.vx-menu {
|
|
801
|
-
|
|
802
|
-
|
|
803
|
-
|
|
804
|
-
|
|
805
|
-
|
|
806
|
-
|
|
807
|
-
|
|
808
|
-
|
|
809
|
-
}
|
|
810
|
-
.vx-menu-list {
|
|
811
|
-
|
|
812
|
-
}
|
|
813
|
-
.vx-menu-item {
|
|
814
|
-
|
|
815
|
-
|
|
816
|
-
|
|
817
|
-
|
|
818
|
-
}
|
|
819
|
-
.vx-menu-item--disabled {
|
|
820
|
-
|
|
821
|
-
}
|
|
822
|
-
/* xplat-web-only:start — hover affordance and cursor are DOM-only */
|
|
823
|
-
.vx-menu-item {
|
|
824
|
-
|
|
825
|
-
}
|
|
826
|
-
.vx-menu-item:hover {
|
|
827
|
-
|
|
828
|
-
}
|
|
829
|
-
/* xplat-web-only:end */
|
|
830
|
-
|
|
831
|
-
/* Badge — inline chip row. */
|
|
832
|
-
.vx-badge {
|
|
833
|
-
|
|
834
|
-
|
|
835
|
-
|
|
836
|
-
|
|
837
|
-
|
|
838
|
-
|
|
839
|
-
}
|
|
840
|
-
/* xplat-web-only:start — span is inline by default; needs inline-flex */
|
|
841
|
-
.vx-badge {
|
|
842
|
-
|
|
843
|
-
}
|
|
844
|
-
/* xplat-web-only:end */
|
|
778
|
+
.vx-search {
|
|
779
|
+
display: flex;
|
|
780
|
+
}
|
|
781
|
+
.vx-search-icon {
|
|
782
|
+
display: inline-flex;
|
|
783
|
+
flex: none;
|
|
784
|
+
}
|
|
785
|
+
.vx-search-field {
|
|
786
|
+
min-width: 0;
|
|
787
|
+
border: 0;
|
|
788
|
+
background: none;
|
|
789
|
+
outline: none;
|
|
790
|
+
appearance: none;
|
|
791
|
+
-webkit-appearance: none;
|
|
792
|
+
}
|
|
793
|
+
input.vx-search-field::-webkit-search-cancel-button {
|
|
794
|
+
display: none;
|
|
795
|
+
}
|
|
796
|
+
.vx-search-clear {
|
|
797
|
+
display: inline-flex;
|
|
798
|
+
border: 0;
|
|
799
|
+
padding: 0;
|
|
800
|
+
cursor: pointer;
|
|
801
|
+
}
|
|
802
|
+
/* xplat-web-only:end */
|
|
803
|
+
|
|
804
|
+
/* Anchored menus — panel + item rows (the Popover leaf positions it). */
|
|
805
|
+
.vx-menu {
|
|
806
|
+
min-width: 140px;
|
|
807
|
+
padding: 4px;
|
|
808
|
+
border-width: 1px;
|
|
809
|
+
border-color: var(--color-border);
|
|
810
|
+
border-radius: var(--radius-md);
|
|
811
|
+
corner-shape: squircle;
|
|
812
|
+
background-color: var(--color-surface);
|
|
813
|
+
color: var(--color-text);
|
|
814
|
+
}
|
|
815
|
+
.vx-menu-list {
|
|
816
|
+
flex-direction: column;
|
|
817
|
+
}
|
|
818
|
+
.vx-menu-item {
|
|
819
|
+
flex-direction: row;
|
|
820
|
+
align-items: center;
|
|
821
|
+
padding: 6px 10px;
|
|
822
|
+
border-radius: var(--radius-sm);
|
|
823
|
+
}
|
|
824
|
+
.vx-menu-item--disabled {
|
|
825
|
+
opacity: 0.5;
|
|
826
|
+
}
|
|
827
|
+
/* xplat-web-only:start — hover affordance and cursor are DOM-only */
|
|
828
|
+
.vx-menu-item {
|
|
829
|
+
cursor: pointer;
|
|
830
|
+
}
|
|
831
|
+
.vx-menu-item:hover {
|
|
832
|
+
background-color: var(--color-border);
|
|
833
|
+
}
|
|
834
|
+
/* xplat-web-only:end */
|
|
835
|
+
|
|
836
|
+
/* Badge — inline chip row. */
|
|
837
|
+
.vx-badge {
|
|
838
|
+
flex-direction: row;
|
|
839
|
+
align-items: center;
|
|
840
|
+
border-radius: var(--radius-sm);
|
|
841
|
+
padding: 1px 6px;
|
|
842
|
+
font-size: 12px;
|
|
843
|
+
line-height: 16px;
|
|
844
|
+
}
|
|
845
|
+
/* xplat-web-only:start — span is inline by default; needs inline-flex */
|
|
846
|
+
.vx-badge {
|
|
847
|
+
display: inline-flex;
|
|
848
|
+
}
|
|
849
|
+
/* xplat-web-only:end */
|
|
845
850
|
|
|
846
|
-
/* Separator — hairline rule; --h spans width, --v spans height. */
|
|
847
|
-
.vx-separator--h {
|
|
848
|
-
|
|
849
|
-
|
|
850
|
-
}
|
|
851
|
-
.vx-separator--v {
|
|
852
|
-
|
|
853
|
-
|
|
854
|
-
|
|
855
|
-
}
|
|
851
|
+
/* Separator — hairline rule; --h spans width, --v spans height. */
|
|
852
|
+
.vx-separator--h {
|
|
853
|
+
height: 1px;
|
|
854
|
+
background-color: var(--color-border);
|
|
855
|
+
}
|
|
856
|
+
.vx-separator--v {
|
|
857
|
+
width: 1px;
|
|
858
|
+
align-self: stretch;
|
|
859
|
+
background-color: var(--color-border);
|
|
860
|
+
}
|
|
856
861
|
|
|
857
|
-
/* Skeleton — placeholder block. */
|
|
858
|
-
.vx-skeleton {
|
|
859
|
-
|
|
860
|
-
|
|
861
|
-
|
|
862
|
-
}
|
|
862
|
+
/* Skeleton — placeholder block. */
|
|
863
|
+
.vx-skeleton {
|
|
864
|
+
background-color: var(--color-border);
|
|
865
|
+
border-radius: var(--radius-md);
|
|
866
|
+
corner-shape: squircle;
|
|
867
|
+
}
|
|
863
868
|
|
|
864
|
-
/* Avatar — centered fallback inside the circle. */
|
|
865
|
-
.vx-avatar {
|
|
866
|
-
|
|
867
|
-
|
|
868
|
-
|
|
869
|
-
}
|
|
870
|
-
.vx-avatar-group {
|
|
871
|
-
|
|
872
|
-
|
|
873
|
-
}
|
|
874
|
-
/* xplat-web-only:start — display:flex for the div-based flex classes */
|
|
875
|
-
.vx-collapsible,
|
|
876
|
-
.vx-collapsible-content,
|
|
877
|
-
.vx-accordion,
|
|
878
|
-
.vx-accordion-item,
|
|
879
|
-
.vx-checkbox-row,
|
|
880
|
-
.vx-checkbox,
|
|
881
|
-
.vx-radio-group,
|
|
882
|
-
.vx-radio-row,
|
|
883
|
-
.vx-radio,
|
|
884
|
-
.vx-menu-list,
|
|
885
|
-
.vx-menu-item,
|
|
886
|
-
.vx-contextmenu,
|
|
887
|
-
.vx-avatar,
|
|
888
|
-
.vx-avatar-group,
|
|
889
|
-
.vx-avatar-group-item {
|
|
890
|
-
|
|
891
|
-
}
|
|
892
|
-
.vx-checkbox-row,
|
|
893
|
-
.vx-radio-row {
|
|
894
|
-
|
|
895
|
-
}
|
|
896
|
-
.vx-checkbox-check {
|
|
897
|
-
|
|
898
|
-
}
|
|
899
|
-
/* xplat-web-only:end */
|
|
869
|
+
/* Avatar — centered fallback inside the circle. */
|
|
870
|
+
.vx-avatar {
|
|
871
|
+
align-items: center;
|
|
872
|
+
justify-content: center;
|
|
873
|
+
background-color: var(--color-border);
|
|
874
|
+
}
|
|
875
|
+
.vx-avatar-group {
|
|
876
|
+
flex-direction: row;
|
|
877
|
+
align-items: center;
|
|
878
|
+
}
|
|
879
|
+
/* xplat-web-only:start — display:flex for the div-based flex classes */
|
|
880
|
+
.vx-collapsible,
|
|
881
|
+
.vx-collapsible-content,
|
|
882
|
+
.vx-accordion,
|
|
883
|
+
.vx-accordion-item,
|
|
884
|
+
.vx-checkbox-row,
|
|
885
|
+
.vx-checkbox,
|
|
886
|
+
.vx-radio-group,
|
|
887
|
+
.vx-radio-row,
|
|
888
|
+
.vx-radio,
|
|
889
|
+
.vx-menu-list,
|
|
890
|
+
.vx-menu-item,
|
|
891
|
+
.vx-contextmenu,
|
|
892
|
+
.vx-avatar,
|
|
893
|
+
.vx-avatar-group,
|
|
894
|
+
.vx-avatar-group-item {
|
|
895
|
+
display: flex;
|
|
896
|
+
}
|
|
897
|
+
.vx-checkbox-row,
|
|
898
|
+
.vx-radio-row {
|
|
899
|
+
cursor: pointer;
|
|
900
|
+
}
|
|
901
|
+
.vx-checkbox-check {
|
|
902
|
+
display: block;
|
|
903
|
+
}
|
|
904
|
+
/* xplat-web-only:end */
|
|
900
905
|
|
|
901
|
-
/* Phase-2 form field layer. */
|
|
906
|
+
/* Phase-2 form field layer. */
|
|
902
907
|
|
|
903
|
-
/* FormField — label / control / message column. */
|
|
904
|
-
.vx-field {
|
|
905
|
-
|
|
906
|
-
}
|
|
907
|
-
.vx-field-label {
|
|
908
|
-
|
|
909
|
-
|
|
910
|
-
|
|
911
|
-
|
|
912
|
-
}
|
|
913
|
-
.vx-field-required {
|
|
914
|
-
|
|
915
|
-
}
|
|
916
|
-
.vx-field-msg {
|
|
917
|
-
|
|
918
|
-
|
|
919
|
-
|
|
920
|
-
|
|
921
|
-
}
|
|
922
|
-
.vx-field-msg--error {
|
|
923
|
-
|
|
924
|
-
}
|
|
925
|
-
.vx-fieldgroup {
|
|
926
|
-
|
|
927
|
-
}
|
|
928
|
-
.vx-fieldgroup-label {
|
|
929
|
-
|
|
930
|
-
|
|
931
|
-
|
|
932
|
-
|
|
933
|
-
}
|
|
908
|
+
/* FormField — label / control / message column. */
|
|
909
|
+
.vx-field {
|
|
910
|
+
flex-direction: column;
|
|
911
|
+
}
|
|
912
|
+
.vx-field-label {
|
|
913
|
+
font-size: 13px;
|
|
914
|
+
line-height: 20px;
|
|
915
|
+
font-weight: 500;
|
|
916
|
+
margin-bottom: 4px;
|
|
917
|
+
}
|
|
918
|
+
.vx-field-required {
|
|
919
|
+
color: var(--color-danger);
|
|
920
|
+
}
|
|
921
|
+
.vx-field-msg {
|
|
922
|
+
font-size: 12px;
|
|
923
|
+
line-height: 16px;
|
|
924
|
+
margin-top: 4px;
|
|
925
|
+
color: var(--color-text-secondary);
|
|
926
|
+
}
|
|
927
|
+
.vx-field-msg--error {
|
|
928
|
+
color: var(--color-danger);
|
|
929
|
+
}
|
|
930
|
+
.vx-fieldgroup {
|
|
931
|
+
flex-direction: column;
|
|
932
|
+
}
|
|
933
|
+
.vx-fieldgroup-label {
|
|
934
|
+
font-size: 13px;
|
|
935
|
+
line-height: 20px;
|
|
936
|
+
font-weight: 600;
|
|
937
|
+
margin-bottom: 8px;
|
|
938
|
+
}
|
|
934
939
|
|
|
935
|
-
/* ListItem — a reusable shared row; callers own the surrounding list chrome. */
|
|
936
|
-
.vx-listitem {
|
|
937
|
-
|
|
938
|
-
|
|
939
|
-
|
|
940
|
-
|
|
941
|
-
|
|
942
|
-
}
|
|
943
|
-
.vx-listitem-leading,
|
|
944
|
-
.vx-listitem-trailing {
|
|
945
|
-
|
|
946
|
-
|
|
947
|
-
}
|
|
948
|
-
.vx-listitem-content {
|
|
949
|
-
|
|
950
|
-
|
|
951
|
-
}
|
|
952
|
-
.vx-listitem-title {
|
|
953
|
-
|
|
954
|
-
}
|
|
955
|
-
.vx-listitem-supporting {
|
|
956
|
-
|
|
957
|
-
|
|
958
|
-
|
|
959
|
-
}
|
|
940
|
+
/* ListItem — a reusable shared row; callers own the surrounding list chrome. */
|
|
941
|
+
.vx-listitem {
|
|
942
|
+
flex-direction: row;
|
|
943
|
+
align-items: center;
|
|
944
|
+
width: 100%;
|
|
945
|
+
padding: 10px 12px;
|
|
946
|
+
gap: 12px;
|
|
947
|
+
}
|
|
948
|
+
.vx-listitem-leading,
|
|
949
|
+
.vx-listitem-trailing {
|
|
950
|
+
flex-shrink: 0;
|
|
951
|
+
align-items: center;
|
|
952
|
+
}
|
|
953
|
+
.vx-listitem-content {
|
|
954
|
+
flex-direction: column;
|
|
955
|
+
flex-grow: 1;
|
|
956
|
+
}
|
|
957
|
+
.vx-listitem-title {
|
|
958
|
+
font-weight: 500;
|
|
959
|
+
}
|
|
960
|
+
.vx-listitem-supporting {
|
|
961
|
+
font-size: 12px;
|
|
962
|
+
line-height: 16px;
|
|
963
|
+
color: var(--color-text-secondary);
|
|
964
|
+
}
|
|
960
965
|
|
|
961
|
-
/* InputNumber — steppers flanking a centered field. */
|
|
962
|
-
.vx-inputnumber {
|
|
963
|
-
|
|
964
|
-
|
|
965
|
-
}
|
|
966
|
-
.vx-inputnumber-step {
|
|
967
|
-
|
|
968
|
-
|
|
969
|
-
|
|
970
|
-
|
|
971
|
-
|
|
972
|
-
|
|
973
|
-
}
|
|
974
|
-
.vx-inputnumber-field {
|
|
975
|
-
|
|
976
|
-
|
|
977
|
-
|
|
978
|
-
|
|
979
|
-
}
|
|
980
|
-
.vx-inputnumber--disabled {
|
|
981
|
-
|
|
982
|
-
}
|
|
966
|
+
/* InputNumber — steppers flanking a centered field. */
|
|
967
|
+
.vx-inputnumber {
|
|
968
|
+
flex-direction: row;
|
|
969
|
+
align-items: center;
|
|
970
|
+
}
|
|
971
|
+
.vx-inputnumber-step {
|
|
972
|
+
padding: 4px 10px;
|
|
973
|
+
border-width: 1px;
|
|
974
|
+
border-color: var(--color-border);
|
|
975
|
+
border-radius: var(--radius-sm);
|
|
976
|
+
align-items: center;
|
|
977
|
+
justify-content: center;
|
|
978
|
+
}
|
|
979
|
+
.vx-inputnumber-field {
|
|
980
|
+
width: 64px;
|
|
981
|
+
margin-left: 8px;
|
|
982
|
+
margin-right: 8px;
|
|
983
|
+
text-align: center;
|
|
984
|
+
}
|
|
985
|
+
.vx-inputnumber--disabled {
|
|
986
|
+
opacity: 0.5;
|
|
987
|
+
}
|
|
983
988
|
|
|
984
|
-
/* PinInput — row of single cells. */
|
|
985
|
-
.vx-pininput {
|
|
986
|
-
|
|
987
|
-
}
|
|
988
|
-
.vx-pininput-cell {
|
|
989
|
-
|
|
990
|
-
|
|
991
|
-
|
|
992
|
-
}
|
|
993
|
-
.vx-pininput--disabled {
|
|
994
|
-
|
|
995
|
-
}
|
|
989
|
+
/* PinInput — row of single cells. */
|
|
990
|
+
.vx-pininput {
|
|
991
|
+
flex-direction: row;
|
|
992
|
+
}
|
|
993
|
+
.vx-pininput-cell {
|
|
994
|
+
width: 40px;
|
|
995
|
+
margin-right: 8px;
|
|
996
|
+
text-align: center;
|
|
997
|
+
}
|
|
998
|
+
.vx-pininput--disabled {
|
|
999
|
+
opacity: 0.5;
|
|
1000
|
+
}
|
|
996
1001
|
|
|
997
|
-
/* Select — trigger row + check column inside the anchored listbox. */
|
|
998
|
-
.vx-select-trigger {
|
|
999
|
-
|
|
1000
|
-
|
|
1001
|
-
|
|
1002
|
-
|
|
1003
|
-
|
|
1004
|
-
|
|
1005
|
-
|
|
1006
|
-
}
|
|
1007
|
-
.vx-select--disabled {
|
|
1008
|
-
|
|
1009
|
-
}
|
|
1010
|
-
.vx-select-placeholder {
|
|
1011
|
-
|
|
1012
|
-
}
|
|
1013
|
-
.vx-select-caret {
|
|
1014
|
-
|
|
1015
|
-
}
|
|
1016
|
-
.vx-select-check {
|
|
1017
|
-
|
|
1018
|
-
}
|
|
1019
|
-
.vx-select-search {
|
|
1020
|
-
|
|
1021
|
-
}
|
|
1002
|
+
/* Select — trigger row + check column inside the anchored listbox. */
|
|
1003
|
+
.vx-select-trigger {
|
|
1004
|
+
flex-direction: row;
|
|
1005
|
+
align-items: center;
|
|
1006
|
+
justify-content: space-between;
|
|
1007
|
+
padding: 6px 10px;
|
|
1008
|
+
border-width: 1px;
|
|
1009
|
+
border-color: var(--color-border);
|
|
1010
|
+
border-radius: var(--radius-sm);
|
|
1011
|
+
}
|
|
1012
|
+
.vx-select--disabled {
|
|
1013
|
+
opacity: 0.5;
|
|
1014
|
+
}
|
|
1015
|
+
.vx-select-placeholder {
|
|
1016
|
+
color: var(--color-text-secondary);
|
|
1017
|
+
}
|
|
1018
|
+
.vx-select-caret {
|
|
1019
|
+
margin-left: 8px;
|
|
1020
|
+
}
|
|
1021
|
+
.vx-select-check {
|
|
1022
|
+
width: 16px;
|
|
1023
|
+
}
|
|
1024
|
+
.vx-select-search {
|
|
1025
|
+
margin-bottom: 4px;
|
|
1026
|
+
}
|
|
1022
1027
|
|
|
1023
|
-
/* InputTags — wrapped chip row + trailing field. */
|
|
1024
|
-
.vx-inputtags {
|
|
1025
|
-
|
|
1026
|
-
|
|
1027
|
-
|
|
1028
|
-
}
|
|
1029
|
-
.vx-inputtags-tag {
|
|
1030
|
-
|
|
1031
|
-
|
|
1032
|
-
|
|
1033
|
-
|
|
1034
|
-
|
|
1035
|
-
|
|
1036
|
-
|
|
1037
|
-
}
|
|
1038
|
-
.vx-inputtags-remove {
|
|
1039
|
-
|
|
1040
|
-
}
|
|
1041
|
-
.vx-inputtags-field {
|
|
1042
|
-
|
|
1043
|
-
|
|
1044
|
-
}
|
|
1045
|
-
.vx-inputtags--disabled {
|
|
1046
|
-
|
|
1047
|
-
}
|
|
1028
|
+
/* InputTags — wrapped chip row + trailing field. */
|
|
1029
|
+
.vx-inputtags {
|
|
1030
|
+
flex-direction: row;
|
|
1031
|
+
flex-wrap: wrap;
|
|
1032
|
+
align-items: center;
|
|
1033
|
+
}
|
|
1034
|
+
.vx-inputtags-tag {
|
|
1035
|
+
flex-direction: row;
|
|
1036
|
+
align-items: center;
|
|
1037
|
+
padding: 1px 6px;
|
|
1038
|
+
margin-right: 4px;
|
|
1039
|
+
margin-bottom: 4px;
|
|
1040
|
+
border-radius: var(--radius-sm);
|
|
1041
|
+
background-color: var(--color-border);
|
|
1042
|
+
}
|
|
1043
|
+
.vx-inputtags-remove {
|
|
1044
|
+
margin-left: 4px;
|
|
1045
|
+
}
|
|
1046
|
+
.vx-inputtags-field {
|
|
1047
|
+
flex: 1;
|
|
1048
|
+
min-width: 80px;
|
|
1049
|
+
}
|
|
1050
|
+
.vx-inputtags--disabled {
|
|
1051
|
+
opacity: 0.5;
|
|
1052
|
+
}
|
|
1048
1053
|
|
|
1049
|
-
/* InputRating — glyph row; --on lights the cell. */
|
|
1050
|
-
.vx-rating {
|
|
1051
|
-
|
|
1052
|
-
}
|
|
1053
|
-
.vx-rating-cell {
|
|
1054
|
-
|
|
1055
|
-
}
|
|
1056
|
-
.vx-rating-glyph {
|
|
1057
|
-
|
|
1058
|
-
|
|
1059
|
-
|
|
1060
|
-
}
|
|
1061
|
-
.vx-rating-cell--on .vx-rating-glyph {
|
|
1062
|
-
|
|
1063
|
-
}
|
|
1064
|
-
.vx-rating--disabled {
|
|
1065
|
-
|
|
1066
|
-
}
|
|
1054
|
+
/* InputRating — glyph row; --on lights the cell. */
|
|
1055
|
+
.vx-rating {
|
|
1056
|
+
flex-direction: row;
|
|
1057
|
+
}
|
|
1058
|
+
.vx-rating-cell {
|
|
1059
|
+
padding: 2px;
|
|
1060
|
+
}
|
|
1061
|
+
.vx-rating-glyph {
|
|
1062
|
+
font-size: 20px;
|
|
1063
|
+
line-height: 24px;
|
|
1064
|
+
color: var(--color-border);
|
|
1065
|
+
}
|
|
1066
|
+
.vx-rating-cell--on .vx-rating-glyph {
|
|
1067
|
+
color: var(--color-primary);
|
|
1068
|
+
}
|
|
1069
|
+
.vx-rating--disabled {
|
|
1070
|
+
opacity: 0.5;
|
|
1071
|
+
}
|
|
1067
1072
|
|
|
1068
|
-
/* CheckboxGroup — column/row of checkboxes. */
|
|
1069
|
-
.vx-checkbox-group {
|
|
1070
|
-
|
|
1071
|
-
}
|
|
1072
|
-
.vx-checkbox-group--row {
|
|
1073
|
-
|
|
1074
|
-
}
|
|
1075
|
-
/* xplat-web-only:start — display:flex for the div/span flex classes */
|
|
1076
|
-
.vx-field,
|
|
1077
|
-
.vx-fieldgroup,
|
|
1078
|
-
.vx-listitem,
|
|
1079
|
-
.vx-listitem-leading,
|
|
1080
|
-
.vx-listitem-content,
|
|
1081
|
-
.vx-listitem-trailing,
|
|
1082
|
-
.vx-inputnumber,
|
|
1083
|
-
.vx-inputnumber-step,
|
|
1084
|
-
.vx-select-trigger,
|
|
1085
|
-
.vx-select-list,
|
|
1086
|
-
.vx-inputtags,
|
|
1087
|
-
.vx-inputtags-tag,
|
|
1088
|
-
.vx-rating,
|
|
1089
|
-
.vx-rating-cell,
|
|
1090
|
-
.vx-checkbox-group {
|
|
1091
|
-
|
|
1092
|
-
}
|
|
1093
|
-
.vx-rating-cell {
|
|
1094
|
-
|
|
1095
|
-
}
|
|
1096
|
-
/* xplat-web-only:end */
|
|
1073
|
+
/* CheckboxGroup — column/row of checkboxes. */
|
|
1074
|
+
.vx-checkbox-group {
|
|
1075
|
+
flex-direction: column;
|
|
1076
|
+
}
|
|
1077
|
+
.vx-checkbox-group--row {
|
|
1078
|
+
flex-direction: row;
|
|
1079
|
+
}
|
|
1080
|
+
/* xplat-web-only:start — display:flex for the div/span flex classes */
|
|
1081
|
+
.vx-field,
|
|
1082
|
+
.vx-fieldgroup,
|
|
1083
|
+
.vx-listitem,
|
|
1084
|
+
.vx-listitem-leading,
|
|
1085
|
+
.vx-listitem-content,
|
|
1086
|
+
.vx-listitem-trailing,
|
|
1087
|
+
.vx-inputnumber,
|
|
1088
|
+
.vx-inputnumber-step,
|
|
1089
|
+
.vx-select-trigger,
|
|
1090
|
+
.vx-select-list,
|
|
1091
|
+
.vx-inputtags,
|
|
1092
|
+
.vx-inputtags-tag,
|
|
1093
|
+
.vx-rating,
|
|
1094
|
+
.vx-rating-cell,
|
|
1095
|
+
.vx-checkbox-group {
|
|
1096
|
+
display: flex;
|
|
1097
|
+
}
|
|
1098
|
+
.vx-rating-cell {
|
|
1099
|
+
cursor: pointer;
|
|
1100
|
+
}
|
|
1101
|
+
/* xplat-web-only:end */
|
|
1097
1102
|
|
|
1098
|
-
/* Phase-3 navigation & wayfinding. */
|
|
1103
|
+
/* Phase-3 navigation & wayfinding. */
|
|
1099
1104
|
|
|
1100
|
-
/* Breadcrumb — inline trail. */
|
|
1101
|
-
.vx-breadcrumb {
|
|
1102
|
-
|
|
1103
|
-
|
|
1104
|
-
|
|
1105
|
-
}
|
|
1106
|
-
.vx-breadcrumb-item {
|
|
1107
|
-
|
|
1108
|
-
|
|
1109
|
-
}
|
|
1110
|
-
.vx-breadcrumb-sep {
|
|
1111
|
-
|
|
1112
|
-
|
|
1113
|
-
|
|
1114
|
-
}
|
|
1115
|
-
.vx-breadcrumb-link {
|
|
1116
|
-
|
|
1117
|
-
}
|
|
1105
|
+
/* Breadcrumb — inline trail. */
|
|
1106
|
+
.vx-breadcrumb {
|
|
1107
|
+
flex-direction: row;
|
|
1108
|
+
align-items: center;
|
|
1109
|
+
flex-wrap: wrap;
|
|
1110
|
+
}
|
|
1111
|
+
.vx-breadcrumb-item {
|
|
1112
|
+
flex-direction: row;
|
|
1113
|
+
align-items: center;
|
|
1114
|
+
}
|
|
1115
|
+
.vx-breadcrumb-sep {
|
|
1116
|
+
margin-left: 6px;
|
|
1117
|
+
margin-right: 6px;
|
|
1118
|
+
color: var(--color-text-secondary);
|
|
1119
|
+
}
|
|
1120
|
+
.vx-breadcrumb-link {
|
|
1121
|
+
color: var(--color-primary);
|
|
1122
|
+
}
|
|
1118
1123
|
|
|
1119
|
-
/* Pagination — windowed page buttons. */
|
|
1120
|
-
.vx-pagination {
|
|
1121
|
-
|
|
1122
|
-
|
|
1123
|
-
}
|
|
1124
|
-
.vx-page-btn {
|
|
1125
|
-
|
|
1126
|
-
|
|
1127
|
-
|
|
1128
|
-
|
|
1129
|
-
|
|
1130
|
-
|
|
1131
|
-
|
|
1132
|
-
|
|
1133
|
-
|
|
1134
|
-
}
|
|
1135
|
-
.vx-page-btn--on {
|
|
1136
|
-
|
|
1137
|
-
|
|
1138
|
-
|
|
1139
|
-
}
|
|
1140
|
-
.vx-page-ellipsis {
|
|
1141
|
-
|
|
1142
|
-
|
|
1143
|
-
}
|
|
1144
|
-
.vx-pagination--disabled {
|
|
1145
|
-
|
|
1146
|
-
}
|
|
1124
|
+
/* Pagination — windowed page buttons. */
|
|
1125
|
+
.vx-pagination {
|
|
1126
|
+
flex-direction: row;
|
|
1127
|
+
align-items: center;
|
|
1128
|
+
}
|
|
1129
|
+
.vx-page-btn {
|
|
1130
|
+
min-width: 28px;
|
|
1131
|
+
height: 28px;
|
|
1132
|
+
padding: 0 6px;
|
|
1133
|
+
margin-right: 4px;
|
|
1134
|
+
border-width: 1px;
|
|
1135
|
+
border-color: var(--color-border);
|
|
1136
|
+
border-radius: var(--radius-sm);
|
|
1137
|
+
align-items: center;
|
|
1138
|
+
justify-content: center;
|
|
1139
|
+
}
|
|
1140
|
+
.vx-page-btn--on {
|
|
1141
|
+
background-color: var(--color-primary);
|
|
1142
|
+
border-color: var(--color-primary);
|
|
1143
|
+
color: var(--color-onprimary);
|
|
1144
|
+
}
|
|
1145
|
+
.vx-page-ellipsis {
|
|
1146
|
+
margin-right: 4px;
|
|
1147
|
+
color: var(--color-text-secondary);
|
|
1148
|
+
}
|
|
1149
|
+
.vx-pagination--disabled {
|
|
1150
|
+
opacity: 0.5;
|
|
1151
|
+
}
|
|
1147
1152
|
|
|
1148
|
-
/* Stepper — dot + label cells joined by a hairline. */
|
|
1149
|
-
.vx-stepper {
|
|
1150
|
-
|
|
1151
|
-
|
|
1152
|
-
}
|
|
1153
|
-
.vx-stepper-cell {
|
|
1154
|
-
|
|
1155
|
-
|
|
1156
|
-
}
|
|
1157
|
-
.vx-stepper-line {
|
|
1158
|
-
|
|
1159
|
-
|
|
1160
|
-
|
|
1161
|
-
}
|
|
1162
|
-
.vx-stepper-line--done {
|
|
1163
|
-
|
|
1164
|
-
}
|
|
1165
|
-
.vx-step {
|
|
1166
|
-
|
|
1167
|
-
|
|
1168
|
-
}
|
|
1169
|
-
.vx-step-dot {
|
|
1170
|
-
|
|
1171
|
-
|
|
1172
|
-
|
|
1173
|
-
|
|
1174
|
-
|
|
1175
|
-
|
|
1176
|
-
|
|
1177
|
-
|
|
1178
|
-
|
|
1179
|
-
}
|
|
1180
|
-
.vx-step--on .vx-step-dot {
|
|
1181
|
-
|
|
1182
|
-
|
|
1183
|
-
}
|
|
1184
|
-
.vx-step--done .vx-step-dot {
|
|
1185
|
-
|
|
1186
|
-
|
|
1187
|
-
|
|
1188
|
-
}
|
|
1189
|
-
.vx-step-label {
|
|
1190
|
-
|
|
1191
|
-
}
|
|
1192
|
-
.vx-step--disabled {
|
|
1193
|
-
|
|
1194
|
-
}
|
|
1153
|
+
/* Stepper — dot + label cells joined by a hairline. */
|
|
1154
|
+
.vx-stepper {
|
|
1155
|
+
flex-direction: row;
|
|
1156
|
+
align-items: center;
|
|
1157
|
+
}
|
|
1158
|
+
.vx-stepper-cell {
|
|
1159
|
+
flex-direction: row;
|
|
1160
|
+
align-items: center;
|
|
1161
|
+
}
|
|
1162
|
+
.vx-stepper-line {
|
|
1163
|
+
width: 24px;
|
|
1164
|
+
height: 1px;
|
|
1165
|
+
background-color: var(--color-border);
|
|
1166
|
+
}
|
|
1167
|
+
.vx-stepper-line--done {
|
|
1168
|
+
background-color: var(--color-primary);
|
|
1169
|
+
}
|
|
1170
|
+
.vx-step {
|
|
1171
|
+
flex-direction: row;
|
|
1172
|
+
align-items: center;
|
|
1173
|
+
}
|
|
1174
|
+
.vx-step-dot {
|
|
1175
|
+
width: 24px;
|
|
1176
|
+
height: 24px;
|
|
1177
|
+
border-width: 1px;
|
|
1178
|
+
border-color: var(--color-border);
|
|
1179
|
+
border-radius: 50%;
|
|
1180
|
+
text-align: center;
|
|
1181
|
+
font-size: 12px;
|
|
1182
|
+
line-height: 22px;
|
|
1183
|
+
color: var(--color-text-secondary);
|
|
1184
|
+
}
|
|
1185
|
+
.vx-step--on .vx-step-dot {
|
|
1186
|
+
border-color: var(--color-primary);
|
|
1187
|
+
color: var(--color-primary);
|
|
1188
|
+
}
|
|
1189
|
+
.vx-step--done .vx-step-dot {
|
|
1190
|
+
background-color: var(--color-primary);
|
|
1191
|
+
border-color: var(--color-primary);
|
|
1192
|
+
color: var(--color-onprimary);
|
|
1193
|
+
}
|
|
1194
|
+
.vx-step-label {
|
|
1195
|
+
margin-left: 6px;
|
|
1196
|
+
}
|
|
1197
|
+
.vx-step--disabled {
|
|
1198
|
+
opacity: 0.5;
|
|
1199
|
+
}
|
|
1195
1200
|
|
|
1196
|
-
/* NavigationMenu — row/column of nav items. */
|
|
1197
|
-
.vx-navmenu,
|
|
1198
|
-
.vx-navmenu--row {
|
|
1199
|
-
|
|
1200
|
-
|
|
1201
|
-
}
|
|
1202
|
-
.vx-navmenu--col {
|
|
1203
|
-
|
|
1204
|
-
|
|
1205
|
-
}
|
|
1206
|
-
.vx-navmenu-item {
|
|
1207
|
-
|
|
1208
|
-
|
|
1209
|
-
|
|
1210
|
-
|
|
1211
|
-
}
|
|
1212
|
-
.vx-navmenu-item--on {
|
|
1213
|
-
|
|
1214
|
-
}
|
|
1215
|
-
.vx-navmenu-item--disabled {
|
|
1216
|
-
|
|
1217
|
-
}
|
|
1218
|
-
.vx-navmenu-label {
|
|
1219
|
-
|
|
1220
|
-
}
|
|
1201
|
+
/* NavigationMenu — row/column of nav items. */
|
|
1202
|
+
.vx-navmenu,
|
|
1203
|
+
.vx-navmenu--row {
|
|
1204
|
+
flex-direction: row;
|
|
1205
|
+
align-items: center;
|
|
1206
|
+
}
|
|
1207
|
+
.vx-navmenu--col {
|
|
1208
|
+
flex-direction: column;
|
|
1209
|
+
align-items: flex-start;
|
|
1210
|
+
}
|
|
1211
|
+
.vx-navmenu-item {
|
|
1212
|
+
flex-direction: row;
|
|
1213
|
+
align-items: center;
|
|
1214
|
+
padding: 6px 10px;
|
|
1215
|
+
border-radius: var(--radius-sm);
|
|
1216
|
+
}
|
|
1217
|
+
.vx-navmenu-item--on {
|
|
1218
|
+
background-color: var(--color-border);
|
|
1219
|
+
}
|
|
1220
|
+
.vx-navmenu-item--disabled {
|
|
1221
|
+
opacity: 0.5;
|
|
1222
|
+
}
|
|
1223
|
+
.vx-navmenu-label {
|
|
1224
|
+
margin-left: 4px;
|
|
1225
|
+
}
|
|
1221
1226
|
|
|
1222
|
-
/* CommandPalette — panel centered by the overlay layer. */
|
|
1223
|
-
.vx-commandpalette {
|
|
1224
|
-
|
|
1225
|
-
|
|
1226
|
-
|
|
1227
|
-
|
|
1228
|
-
|
|
1229
|
-
|
|
1230
|
-
|
|
1231
|
-
|
|
1232
|
-
}
|
|
1233
|
-
/* xplat-web-only:start — native uses Screen.mainScreen.widthDIPs */
|
|
1234
|
-
.vx-commandpalette {
|
|
1235
|
-
|
|
1227
|
+
/* CommandPalette — panel centered by the overlay layer. */
|
|
1228
|
+
.vx-commandpalette {
|
|
1229
|
+
width: 360px;
|
|
1230
|
+
padding: 8px;
|
|
1231
|
+
border-width: 1px;
|
|
1232
|
+
border-color: var(--color-border);
|
|
1233
|
+
border-radius: var(--radius-md);
|
|
1234
|
+
corner-shape: squircle;
|
|
1235
|
+
background-color: var(--color-surface);
|
|
1236
|
+
color: var(--color-text);
|
|
1237
|
+
}
|
|
1238
|
+
/* xplat-web-only:start — native uses Screen.mainScreen.widthDIPs */
|
|
1239
|
+
.vx-commandpalette {
|
|
1240
|
+
/* The overlay-content wrapper shrink-wraps the palette, so % would resolve
|
|
1236
1241
|
* against the palette itself instead of the available viewport. */
|
|
1237
|
-
|
|
1238
|
-
}
|
|
1239
|
-
/* xplat-web-only:end */
|
|
1240
|
-
.vx-cmdk-search {
|
|
1241
|
-
|
|
1242
|
-
}
|
|
1243
|
-
/* xplat-web-only:start — display, centering, and cursor are DOM-only */
|
|
1244
|
-
.vx-breadcrumb,
|
|
1245
|
-
.vx-breadcrumb-item,
|
|
1246
|
-
.vx-pagination,
|
|
1247
|
-
.vx-page-btn,
|
|
1248
|
-
.vx-stepper,
|
|
1249
|
-
.vx-stepper-cell,
|
|
1250
|
-
.vx-step,
|
|
1251
|
-
.vx-navmenu,
|
|
1252
|
-
.vx-navmenu-item {
|
|
1253
|
-
|
|
1254
|
-
}
|
|
1255
|
-
.vx-cmdk-layer .vx-overlay-content {
|
|
1256
|
-
|
|
1257
|
-
|
|
1258
|
-
|
|
1259
|
-
|
|
1260
|
-
}
|
|
1261
|
-
.vx-page-btn,
|
|
1262
|
-
.vx-breadcrumb-link,
|
|
1263
|
-
.vx-step,
|
|
1264
|
-
.vx-navmenu-item {
|
|
1265
|
-
|
|
1266
|
-
}
|
|
1267
|
-
/* xplat-web-only:end */
|
|
1242
|
+
max-width: 90vw;
|
|
1243
|
+
}
|
|
1244
|
+
/* xplat-web-only:end */
|
|
1245
|
+
.vx-cmdk-search {
|
|
1246
|
+
margin-bottom: 4px;
|
|
1247
|
+
}
|
|
1248
|
+
/* xplat-web-only:start — display, centering, and cursor are DOM-only */
|
|
1249
|
+
.vx-breadcrumb,
|
|
1250
|
+
.vx-breadcrumb-item,
|
|
1251
|
+
.vx-pagination,
|
|
1252
|
+
.vx-page-btn,
|
|
1253
|
+
.vx-stepper,
|
|
1254
|
+
.vx-stepper-cell,
|
|
1255
|
+
.vx-step,
|
|
1256
|
+
.vx-navmenu,
|
|
1257
|
+
.vx-navmenu-item {
|
|
1258
|
+
display: flex;
|
|
1259
|
+
}
|
|
1260
|
+
.vx-cmdk-layer .vx-overlay-content {
|
|
1261
|
+
position: absolute;
|
|
1262
|
+
top: 15%;
|
|
1263
|
+
left: 50%;
|
|
1264
|
+
transform: translateX(-50%);
|
|
1265
|
+
}
|
|
1266
|
+
.vx-page-btn,
|
|
1267
|
+
.vx-breadcrumb-link,
|
|
1268
|
+
.vx-step,
|
|
1269
|
+
.vx-navmenu-item {
|
|
1270
|
+
cursor: pointer;
|
|
1271
|
+
}
|
|
1272
|
+
/* xplat-web-only:end */
|
|
1268
1273
|
|
|
1269
|
-
/* Phase-4 data display. */
|
|
1274
|
+
/* Phase-4 data display. */
|
|
1270
1275
|
|
|
1271
|
-
/* Table — header + bounded rows (unvirtualized by design). */
|
|
1272
|
-
.vx-table {
|
|
1273
|
-
|
|
1274
|
-
|
|
1275
|
-
|
|
1276
|
-
|
|
1277
|
-
}
|
|
1278
|
-
.vx-table-head,
|
|
1279
|
-
.vx-table-row {
|
|
1280
|
-
|
|
1281
|
-
}
|
|
1282
|
-
.vx-table-th {
|
|
1283
|
-
|
|
1284
|
-
}
|
|
1285
|
-
.vx-table-cell {
|
|
1286
|
-
|
|
1287
|
-
}
|
|
1288
|
-
.vx-table-head {
|
|
1289
|
-
|
|
1290
|
-
|
|
1291
|
-
}
|
|
1292
|
-
.vx-table-empty {
|
|
1293
|
-
|
|
1294
|
-
|
|
1295
|
-
}
|
|
1276
|
+
/* Table — header + bounded rows (unvirtualized by design). */
|
|
1277
|
+
.vx-table {
|
|
1278
|
+
flex-direction: column;
|
|
1279
|
+
border-width: 1px;
|
|
1280
|
+
border-color: var(--color-border);
|
|
1281
|
+
border-radius: var(--radius-md);
|
|
1282
|
+
}
|
|
1283
|
+
.vx-table-head,
|
|
1284
|
+
.vx-table-row {
|
|
1285
|
+
flex-direction: row;
|
|
1286
|
+
}
|
|
1287
|
+
.vx-table-th {
|
|
1288
|
+
font-weight: 600;
|
|
1289
|
+
}
|
|
1290
|
+
.vx-table-cell {
|
|
1291
|
+
padding: 8px 12px;
|
|
1292
|
+
}
|
|
1293
|
+
.vx-table-head {
|
|
1294
|
+
border-bottom-width: 1px;
|
|
1295
|
+
border-bottom-color: var(--color-border);
|
|
1296
|
+
}
|
|
1297
|
+
.vx-table-empty {
|
|
1298
|
+
padding: 16px;
|
|
1299
|
+
align-items: center;
|
|
1300
|
+
}
|
|
1296
1301
|
|
|
1297
|
-
/* Timeline — dot + connector rail beside content. */
|
|
1298
|
-
.vx-timeline {
|
|
1299
|
-
|
|
1300
|
-
}
|
|
1301
|
-
.vx-timeline-item {
|
|
1302
|
-
|
|
1303
|
-
}
|
|
1304
|
-
.vx-timeline-rail {
|
|
1305
|
-
|
|
1306
|
-
|
|
1307
|
-
|
|
1308
|
-
}
|
|
1309
|
-
.vx-timeline-dot {
|
|
1310
|
-
|
|
1311
|
-
|
|
1312
|
-
|
|
1313
|
-
|
|
1314
|
-
|
|
1315
|
-
|
|
1316
|
-
|
|
1317
|
-
}
|
|
1318
|
-
.vx-timeline-line {
|
|
1319
|
-
|
|
1320
|
-
|
|
1321
|
-
|
|
1322
|
-
}
|
|
1323
|
-
.vx-timeline-body {
|
|
1324
|
-
|
|
1325
|
-
|
|
1326
|
-
|
|
1327
|
-
}
|
|
1328
|
-
.vx-timeline-time {
|
|
1329
|
-
|
|
1330
|
-
|
|
1331
|
-
|
|
1332
|
-
}
|
|
1333
|
-
.vx-timeline-title {
|
|
1334
|
-
|
|
1335
|
-
}
|
|
1336
|
-
.vx-timeline-desc {
|
|
1337
|
-
|
|
1338
|
-
}
|
|
1302
|
+
/* Timeline — dot + connector rail beside content. */
|
|
1303
|
+
.vx-timeline {
|
|
1304
|
+
flex-direction: column;
|
|
1305
|
+
}
|
|
1306
|
+
.vx-timeline-item {
|
|
1307
|
+
flex-direction: row;
|
|
1308
|
+
}
|
|
1309
|
+
.vx-timeline-rail {
|
|
1310
|
+
flex-direction: column;
|
|
1311
|
+
align-items: center;
|
|
1312
|
+
width: 20px;
|
|
1313
|
+
}
|
|
1314
|
+
.vx-timeline-dot {
|
|
1315
|
+
width: 10px;
|
|
1316
|
+
height: 10px;
|
|
1317
|
+
margin-top: 5px;
|
|
1318
|
+
border-radius: 50%;
|
|
1319
|
+
background-color: var(--color-primary);
|
|
1320
|
+
align-items: center;
|
|
1321
|
+
justify-content: center;
|
|
1322
|
+
}
|
|
1323
|
+
.vx-timeline-line {
|
|
1324
|
+
width: 1px;
|
|
1325
|
+
flex: 1;
|
|
1326
|
+
background-color: var(--color-border);
|
|
1327
|
+
}
|
|
1328
|
+
.vx-timeline-body {
|
|
1329
|
+
flex-direction: column;
|
|
1330
|
+
padding-left: 10px;
|
|
1331
|
+
padding-bottom: 16px;
|
|
1332
|
+
}
|
|
1333
|
+
.vx-timeline-time {
|
|
1334
|
+
font-size: 12px;
|
|
1335
|
+
line-height: 16px;
|
|
1336
|
+
color: var(--color-text-secondary);
|
|
1337
|
+
}
|
|
1338
|
+
.vx-timeline-title {
|
|
1339
|
+
font-weight: 600;
|
|
1340
|
+
}
|
|
1341
|
+
.vx-timeline-desc {
|
|
1342
|
+
color: var(--color-text-secondary);
|
|
1343
|
+
}
|
|
1339
1344
|
|
|
1340
|
-
/* Tree — indented collapsible rows. */
|
|
1341
|
-
.vx-tree {
|
|
1342
|
-
|
|
1343
|
-
}
|
|
1344
|
-
.vx-tree-node {
|
|
1345
|
-
|
|
1346
|
-
}
|
|
1347
|
-
.vx-tree-row {
|
|
1348
|
-
|
|
1349
|
-
|
|
1350
|
-
|
|
1351
|
-
}
|
|
1352
|
-
.vx-tree-row--disabled {
|
|
1353
|
-
|
|
1354
|
-
}
|
|
1355
|
-
.vx-tree-caret {
|
|
1356
|
-
|
|
1357
|
-
|
|
1358
|
-
}
|
|
1345
|
+
/* Tree — indented collapsible rows. */
|
|
1346
|
+
.vx-tree {
|
|
1347
|
+
flex-direction: column;
|
|
1348
|
+
}
|
|
1349
|
+
.vx-tree-node {
|
|
1350
|
+
flex-direction: column;
|
|
1351
|
+
}
|
|
1352
|
+
.vx-tree-row {
|
|
1353
|
+
flex-direction: row;
|
|
1354
|
+
align-items: center;
|
|
1355
|
+
padding: 4px 0;
|
|
1356
|
+
}
|
|
1357
|
+
.vx-tree-row--disabled {
|
|
1358
|
+
opacity: 0.5;
|
|
1359
|
+
}
|
|
1360
|
+
.vx-tree-caret {
|
|
1361
|
+
width: 14px;
|
|
1362
|
+
margin-left: 4px;
|
|
1363
|
+
}
|
|
1359
1364
|
|
|
1360
|
-
/* Alert — icon + body callout; tone picks border/text colors. */
|
|
1361
|
-
.vx-alert {
|
|
1362
|
-
|
|
1363
|
-
|
|
1364
|
-
|
|
1365
|
-
|
|
1366
|
-
|
|
1367
|
-
|
|
1368
|
-
}
|
|
1369
|
-
.vx-alert-body {
|
|
1370
|
-
|
|
1371
|
-
|
|
1372
|
-
|
|
1373
|
-
}
|
|
1374
|
-
.vx-alert-title {
|
|
1375
|
-
|
|
1376
|
-
}
|
|
1377
|
-
.vx-alert--error {
|
|
1378
|
-
|
|
1379
|
-
}
|
|
1380
|
-
.vx-alert--warning {
|
|
1381
|
-
|
|
1382
|
-
}
|
|
1383
|
-
.vx-alert--success {
|
|
1384
|
-
|
|
1385
|
-
}
|
|
1386
|
-
.vx-alert--info {
|
|
1387
|
-
|
|
1388
|
-
}
|
|
1365
|
+
/* Alert — icon + body callout; tone picks border/text colors. */
|
|
1366
|
+
.vx-alert {
|
|
1367
|
+
flex-direction: row;
|
|
1368
|
+
padding: 10px 12px;
|
|
1369
|
+
border-width: 1px;
|
|
1370
|
+
border-radius: var(--radius-md);
|
|
1371
|
+
corner-shape: squircle;
|
|
1372
|
+
border-color: var(--color-border);
|
|
1373
|
+
}
|
|
1374
|
+
.vx-alert-body {
|
|
1375
|
+
flex-direction: column;
|
|
1376
|
+
flex: 1;
|
|
1377
|
+
margin-left: 8px;
|
|
1378
|
+
}
|
|
1379
|
+
.vx-alert-title {
|
|
1380
|
+
font-weight: 600;
|
|
1381
|
+
}
|
|
1382
|
+
.vx-alert--error {
|
|
1383
|
+
border-color: var(--color-danger);
|
|
1384
|
+
}
|
|
1385
|
+
.vx-alert--warning {
|
|
1386
|
+
border-color: var(--color-warning, #d9a400);
|
|
1387
|
+
}
|
|
1388
|
+
.vx-alert--success {
|
|
1389
|
+
border-color: var(--color-success, #2e9e5b);
|
|
1390
|
+
}
|
|
1391
|
+
.vx-alert--info {
|
|
1392
|
+
border-color: var(--color-primary);
|
|
1393
|
+
}
|
|
1389
1394
|
|
|
1390
|
-
/* Card — sectioned container. */
|
|
1391
|
-
.vx-card {
|
|
1392
|
-
|
|
1393
|
-
|
|
1394
|
-
|
|
1395
|
-
|
|
1396
|
-
|
|
1397
|
-
|
|
1398
|
-
}
|
|
1399
|
-
.vx-card-header {
|
|
1400
|
-
|
|
1401
|
-
|
|
1402
|
-
|
|
1403
|
-
}
|
|
1404
|
-
.vx-card-body {
|
|
1405
|
-
|
|
1406
|
-
|
|
1407
|
-
}
|
|
1408
|
-
.vx-card-footer {
|
|
1409
|
-
|
|
1410
|
-
|
|
1411
|
-
|
|
1412
|
-
}
|
|
1395
|
+
/* Card — sectioned container. */
|
|
1396
|
+
.vx-card {
|
|
1397
|
+
flex-direction: column;
|
|
1398
|
+
border-width: 1px;
|
|
1399
|
+
border-color: var(--color-border);
|
|
1400
|
+
border-radius: var(--radius-md);
|
|
1401
|
+
corner-shape: squircle;
|
|
1402
|
+
background-color: var(--color-surface);
|
|
1403
|
+
}
|
|
1404
|
+
.vx-card-header {
|
|
1405
|
+
padding: 12px;
|
|
1406
|
+
border-bottom-width: 1px;
|
|
1407
|
+
border-bottom-color: var(--color-border);
|
|
1408
|
+
}
|
|
1409
|
+
.vx-card-body {
|
|
1410
|
+
padding: 12px;
|
|
1411
|
+
flex-direction: column;
|
|
1412
|
+
}
|
|
1413
|
+
.vx-card-footer {
|
|
1414
|
+
padding: 12px;
|
|
1415
|
+
border-top-width: 1px;
|
|
1416
|
+
border-top-color: var(--color-border);
|
|
1417
|
+
}
|
|
1413
1418
|
|
|
1414
|
-
/* Chip — pressable pill with selected + remove states. */
|
|
1415
|
-
.vx-chip {
|
|
1416
|
-
|
|
1417
|
-
|
|
1418
|
-
|
|
1419
|
-
|
|
1420
|
-
|
|
1421
|
-
|
|
1422
|
-
|
|
1423
|
-
|
|
1424
|
-
}
|
|
1425
|
-
.vx-chip--on {
|
|
1426
|
-
|
|
1427
|
-
|
|
1428
|
-
|
|
1429
|
-
}
|
|
1430
|
-
.vx-chip--disabled {
|
|
1431
|
-
|
|
1432
|
-
}
|
|
1433
|
-
.vx-chip-remove {
|
|
1434
|
-
|
|
1435
|
-
}
|
|
1419
|
+
/* Chip — pressable pill with selected + remove states. */
|
|
1420
|
+
.vx-chip {
|
|
1421
|
+
flex-direction: row;
|
|
1422
|
+
align-items: center;
|
|
1423
|
+
padding: 3px 10px;
|
|
1424
|
+
border-width: 1px;
|
|
1425
|
+
border-color: var(--color-border);
|
|
1426
|
+
border-radius: var(--radius-md);
|
|
1427
|
+
corner-shape: squircle;
|
|
1428
|
+
font-size: 13px;
|
|
1429
|
+
}
|
|
1430
|
+
.vx-chip--on {
|
|
1431
|
+
background-color: var(--color-primary);
|
|
1432
|
+
border-color: var(--color-primary);
|
|
1433
|
+
color: var(--color-onprimary);
|
|
1434
|
+
}
|
|
1435
|
+
.vx-chip--disabled {
|
|
1436
|
+
opacity: 0.5;
|
|
1437
|
+
}
|
|
1438
|
+
.vx-chip-remove {
|
|
1439
|
+
margin-left: 6px;
|
|
1440
|
+
}
|
|
1436
1441
|
|
|
1437
|
-
/* Kbd — keycap glyph. */
|
|
1438
|
-
.vx-kbd {
|
|
1439
|
-
|
|
1440
|
-
|
|
1441
|
-
|
|
1442
|
-
|
|
1443
|
-
|
|
1444
|
-
|
|
1445
|
-
}
|
|
1442
|
+
/* Kbd — keycap glyph. */
|
|
1443
|
+
.vx-kbd {
|
|
1444
|
+
padding: 1px 5px;
|
|
1445
|
+
border-width: 1px;
|
|
1446
|
+
border-color: var(--color-border);
|
|
1447
|
+
border-bottom-width: 2px;
|
|
1448
|
+
border-radius: var(--radius-sm);
|
|
1449
|
+
font-size: 12px;
|
|
1450
|
+
}
|
|
1446
1451
|
|
|
1447
|
-
/* Empty — centered placeholder. */
|
|
1448
|
-
.vx-empty {
|
|
1449
|
-
|
|
1450
|
-
|
|
1451
|
-
|
|
1452
|
-
}
|
|
1453
|
-
.vx-empty-title {
|
|
1454
|
-
|
|
1455
|
-
|
|
1456
|
-
}
|
|
1457
|
-
.vx-empty-desc {
|
|
1458
|
-
|
|
1459
|
-
|
|
1460
|
-
}
|
|
1452
|
+
/* Empty — centered placeholder. */
|
|
1453
|
+
.vx-empty {
|
|
1454
|
+
flex-direction: column;
|
|
1455
|
+
align-items: center;
|
|
1456
|
+
padding: 24px;
|
|
1457
|
+
}
|
|
1458
|
+
.vx-empty-title {
|
|
1459
|
+
font-weight: 600;
|
|
1460
|
+
margin-top: 8px;
|
|
1461
|
+
}
|
|
1462
|
+
.vx-empty-desc {
|
|
1463
|
+
color: var(--color-text-secondary);
|
|
1464
|
+
margin-top: 2px;
|
|
1465
|
+
}
|
|
1461
1466
|
|
|
1462
|
-
/* Banner — notice strip. */
|
|
1463
|
-
.vx-banner {
|
|
1464
|
-
|
|
1465
|
-
|
|
1466
|
-
|
|
1467
|
-
|
|
1468
|
-
|
|
1469
|
-
|
|
1470
|
-
|
|
1471
|
-
}
|
|
1472
|
-
.vx-banner-body {
|
|
1473
|
-
|
|
1474
|
-
|
|
1475
|
-
|
|
1476
|
-
}
|
|
1477
|
-
.vx-banner-dismiss {
|
|
1478
|
-
|
|
1479
|
-
}
|
|
1467
|
+
/* Banner — notice strip. */
|
|
1468
|
+
.vx-banner {
|
|
1469
|
+
flex-direction: row;
|
|
1470
|
+
align-items: center;
|
|
1471
|
+
padding: 8px 12px;
|
|
1472
|
+
border-width: 1px;
|
|
1473
|
+
border-color: var(--color-border);
|
|
1474
|
+
border-radius: var(--radius-md);
|
|
1475
|
+
background-color: var(--color-surface);
|
|
1476
|
+
}
|
|
1477
|
+
.vx-banner-body {
|
|
1478
|
+
flex-direction: column;
|
|
1479
|
+
flex: 1;
|
|
1480
|
+
margin-left: 8px;
|
|
1481
|
+
}
|
|
1482
|
+
.vx-banner-dismiss {
|
|
1483
|
+
margin-left: 8px;
|
|
1484
|
+
}
|
|
1480
1485
|
|
|
1481
|
-
/* User — avatar + text column. */
|
|
1482
|
-
.vx-user {
|
|
1483
|
-
|
|
1484
|
-
|
|
1485
|
-
}
|
|
1486
|
-
.vx-user-body {
|
|
1487
|
-
|
|
1488
|
-
|
|
1489
|
-
}
|
|
1490
|
-
.vx-user-name {
|
|
1491
|
-
|
|
1492
|
-
}
|
|
1493
|
-
.vx-user-desc {
|
|
1494
|
-
|
|
1495
|
-
|
|
1496
|
-
|
|
1497
|
-
}
|
|
1486
|
+
/* User — avatar + text column. */
|
|
1487
|
+
.vx-user {
|
|
1488
|
+
flex-direction: row;
|
|
1489
|
+
align-items: center;
|
|
1490
|
+
}
|
|
1491
|
+
.vx-user-body {
|
|
1492
|
+
flex-direction: column;
|
|
1493
|
+
margin-left: 10px;
|
|
1494
|
+
}
|
|
1495
|
+
.vx-user-name {
|
|
1496
|
+
font-weight: 600;
|
|
1497
|
+
}
|
|
1498
|
+
.vx-user-desc {
|
|
1499
|
+
font-size: 12px;
|
|
1500
|
+
line-height: 16px;
|
|
1501
|
+
color: var(--color-text-secondary);
|
|
1502
|
+
}
|
|
1498
1503
|
|
|
1499
|
-
/* ProgressGroup — stacked labeled meters. */
|
|
1500
|
-
.vx-progressgroup {
|
|
1501
|
-
|
|
1502
|
-
}
|
|
1503
|
-
.vx-progressgroup-row {
|
|
1504
|
-
|
|
1505
|
-
|
|
1506
|
-
}
|
|
1507
|
-
.vx-progressgroup-label {
|
|
1508
|
-
|
|
1509
|
-
}
|
|
1510
|
-
/* xplat-web-only:start — display:flex for the div-based flex classes */
|
|
1511
|
-
.vx-table,
|
|
1512
|
-
.vx-table-head,
|
|
1513
|
-
.vx-table-row,
|
|
1514
|
-
.vx-timeline,
|
|
1515
|
-
.vx-timeline-item,
|
|
1516
|
-
.vx-timeline-rail,
|
|
1517
|
-
.vx-timeline-body,
|
|
1518
|
-
.vx-tree,
|
|
1519
|
-
.vx-tree-node,
|
|
1520
|
-
.vx-tree-row,
|
|
1521
|
-
.vx-alert,
|
|
1522
|
-
.vx-alert-body,
|
|
1523
|
-
.vx-card,
|
|
1524
|
-
.vx-card-body,
|
|
1525
|
-
.vx-banner,
|
|
1526
|
-
.vx-banner-body,
|
|
1527
|
-
.vx-user,
|
|
1528
|
-
.vx-user-body,
|
|
1529
|
-
.vx-progressgroup,
|
|
1530
|
-
.vx-progressgroup-row {
|
|
1531
|
-
|
|
1532
|
-
}
|
|
1533
|
-
.vx-table-row--pressable,
|
|
1534
|
-
.vx-tree-row,
|
|
1535
|
-
.vx-user--pressable,
|
|
1536
|
-
.vx-banner-dismiss,
|
|
1537
|
-
.vx-chip-remove {
|
|
1538
|
-
|
|
1539
|
-
}
|
|
1540
|
-
/* xplat-web-only:end */
|
|
1504
|
+
/* ProgressGroup — stacked labeled meters. */
|
|
1505
|
+
.vx-progressgroup {
|
|
1506
|
+
flex-direction: column;
|
|
1507
|
+
}
|
|
1508
|
+
.vx-progressgroup-row {
|
|
1509
|
+
flex-direction: row;
|
|
1510
|
+
align-items: center;
|
|
1511
|
+
}
|
|
1512
|
+
.vx-progressgroup-label {
|
|
1513
|
+
margin-left: 8px;
|
|
1514
|
+
}
|
|
1515
|
+
/* xplat-web-only:start — display:flex for the div-based flex classes */
|
|
1516
|
+
.vx-table,
|
|
1517
|
+
.vx-table-head,
|
|
1518
|
+
.vx-table-row,
|
|
1519
|
+
.vx-timeline,
|
|
1520
|
+
.vx-timeline-item,
|
|
1521
|
+
.vx-timeline-rail,
|
|
1522
|
+
.vx-timeline-body,
|
|
1523
|
+
.vx-tree,
|
|
1524
|
+
.vx-tree-node,
|
|
1525
|
+
.vx-tree-row,
|
|
1526
|
+
.vx-alert,
|
|
1527
|
+
.vx-alert-body,
|
|
1528
|
+
.vx-card,
|
|
1529
|
+
.vx-card-body,
|
|
1530
|
+
.vx-banner,
|
|
1531
|
+
.vx-banner-body,
|
|
1532
|
+
.vx-user,
|
|
1533
|
+
.vx-user-body,
|
|
1534
|
+
.vx-progressgroup,
|
|
1535
|
+
.vx-progressgroup-row {
|
|
1536
|
+
display: flex;
|
|
1537
|
+
}
|
|
1538
|
+
.vx-table-row--pressable,
|
|
1539
|
+
.vx-tree-row,
|
|
1540
|
+
.vx-user--pressable,
|
|
1541
|
+
.vx-banner-dismiss,
|
|
1542
|
+
.vx-chip-remove {
|
|
1543
|
+
cursor: pointer;
|
|
1544
|
+
}
|
|
1545
|
+
/* xplat-web-only:end */
|
|
1541
1546
|
|
|
1542
|
-
.vx-heading {
|
|
1543
|
-
|
|
1544
|
-
}
|
|
1545
|
-
/* NativeScript reads the numeric prefix of font-size; keep this scale in px. */
|
|
1546
|
-
.vx-h1 {
|
|
1547
|
-
|
|
1548
|
-
|
|
1549
|
-
}
|
|
1550
|
-
.vx-h2 {
|
|
1551
|
-
|
|
1552
|
-
|
|
1553
|
-
}
|
|
1554
|
-
.vx-h3 {
|
|
1555
|
-
|
|
1556
|
-
|
|
1557
|
-
}
|
|
1558
|
-
.vx-h4 {
|
|
1559
|
-
|
|
1560
|
-
|
|
1561
|
-
}
|
|
1562
|
-
.vx-h5 {
|
|
1563
|
-
|
|
1564
|
-
|
|
1565
|
-
}
|
|
1566
|
-
.vx-h6 {
|
|
1567
|
-
|
|
1568
|
-
|
|
1569
|
-
}
|
|
1547
|
+
.vx-heading {
|
|
1548
|
+
margin: 0;
|
|
1549
|
+
}
|
|
1550
|
+
/* NativeScript reads the numeric prefix of font-size; keep this scale in px. */
|
|
1551
|
+
.vx-h1 {
|
|
1552
|
+
font-size: 32px;
|
|
1553
|
+
font-weight: bold;
|
|
1554
|
+
}
|
|
1555
|
+
.vx-h2 {
|
|
1556
|
+
font-size: 24px;
|
|
1557
|
+
font-weight: bold;
|
|
1558
|
+
}
|
|
1559
|
+
.vx-h3 {
|
|
1560
|
+
font-size: 18.72px;
|
|
1561
|
+
font-weight: bold;
|
|
1562
|
+
}
|
|
1563
|
+
.vx-h4 {
|
|
1564
|
+
font-size: 16px;
|
|
1565
|
+
font-weight: bold;
|
|
1566
|
+
}
|
|
1567
|
+
.vx-h5 {
|
|
1568
|
+
font-size: 13.28px;
|
|
1569
|
+
font-weight: bold;
|
|
1570
|
+
}
|
|
1571
|
+
.vx-h6 {
|
|
1572
|
+
font-size: 10.72px;
|
|
1573
|
+
font-weight: bold;
|
|
1574
|
+
}
|
|
1570
1575
|
|
|
1571
|
-
/* utilities (hand-written subset — do NOT adopt Tailwind until
|
|
1576
|
+
/* utilities (hand-written subset — do NOT adopt Tailwind until
|
|
1572
1577
|
NativeScript/tailwind#226 is resolved; the plugin strips core-supported
|
|
1573
1578
|
props incl. gap, drops all @media, and rewrites invisible→collapse) */
|
|
1574
1579
|
|
|
1575
|
-
/* flex-1 keeps Tailwind v4's exact emission (`flex: 1 1 0%`) — web gets
|
|
1580
|
+
/* flex-1 keeps Tailwind v4's exact emission (`flex: 1 1 0%`) — web gets
|
|
1576
1581
|
identical semantics, NS parses grow/shrink out of the shorthand and
|
|
1577
1582
|
ignores the basis token it can't model. */
|
|
1578
|
-
.flex-1 {
|
|
1579
|
-
|
|
1580
|
-
}
|
|
1581
|
-
/* Flex divergence guards — NS FlexboxLayout diverges from web flexbox on
|
|
1583
|
+
.flex-1 {
|
|
1584
|
+
flex: 1 1 0%;
|
|
1585
|
+
}
|
|
1586
|
+
/* Flex divergence guards — NS FlexboxLayout diverges from web flexbox on
|
|
1582
1587
|
* shrinkability: grow children never shrink below intrinsic width, fixed
|
|
1583
1588
|
* children get crushed, and auto-height rows re-measure grow children at
|
|
1584
1589
|
* zero height. The shared `* { flex-shrink: 0 }` default (RN semantics)
|
|
1585
1590
|
* makes .shrink the opt-in for a shrinkable child; min-w-0/min-h-0 lower
|
|
1586
1591
|
* the min-content floor so it can actually shrink, and shrink-0 remains
|
|
1587
1592
|
* for local overrides. All four are plain CSS on web. */
|
|
1588
|
-
.min-w-0 {
|
|
1589
|
-
|
|
1590
|
-
}
|
|
1591
|
-
.min-h-0 {
|
|
1592
|
-
|
|
1593
|
-
}
|
|
1594
|
-
.shrink {
|
|
1595
|
-
|
|
1596
|
-
}
|
|
1597
|
-
.shrink-0 {
|
|
1598
|
-
|
|
1599
|
-
}
|
|
1600
|
-
.grow {
|
|
1601
|
-
|
|
1602
|
-
}
|
|
1603
|
-
.items-center {
|
|
1604
|
-
|
|
1605
|
-
}
|
|
1606
|
-
.items-baseline {
|
|
1607
|
-
|
|
1608
|
-
}
|
|
1609
|
-
.items-start {
|
|
1610
|
-
|
|
1611
|
-
}
|
|
1612
|
-
.justify-center {
|
|
1613
|
-
|
|
1614
|
-
}
|
|
1615
|
-
.justify-between {
|
|
1616
|
-
|
|
1617
|
-
}
|
|
1618
|
-
.flex-wrap {
|
|
1619
|
-
|
|
1620
|
-
}
|
|
1621
|
-
.gap-4 {
|
|
1622
|
-
|
|
1623
|
-
}
|
|
1624
|
-
.gap-3 {
|
|
1625
|
-
|
|
1626
|
-
}
|
|
1627
|
-
.gap-6 {
|
|
1628
|
-
|
|
1629
|
-
}
|
|
1593
|
+
.min-w-0 {
|
|
1594
|
+
min-width: 0;
|
|
1595
|
+
}
|
|
1596
|
+
.min-h-0 {
|
|
1597
|
+
min-height: 0;
|
|
1598
|
+
}
|
|
1599
|
+
.shrink {
|
|
1600
|
+
flex-shrink: 1;
|
|
1601
|
+
}
|
|
1602
|
+
.shrink-0 {
|
|
1603
|
+
flex-shrink: 0;
|
|
1604
|
+
}
|
|
1605
|
+
.grow {
|
|
1606
|
+
flex-grow: 1;
|
|
1607
|
+
}
|
|
1608
|
+
.items-center {
|
|
1609
|
+
align-items: center;
|
|
1610
|
+
}
|
|
1611
|
+
.items-baseline {
|
|
1612
|
+
align-items: baseline;
|
|
1613
|
+
}
|
|
1614
|
+
.items-start {
|
|
1615
|
+
align-items: flex-start;
|
|
1616
|
+
}
|
|
1617
|
+
.justify-center {
|
|
1618
|
+
justify-content: center;
|
|
1619
|
+
}
|
|
1620
|
+
.justify-between {
|
|
1621
|
+
justify-content: space-between;
|
|
1622
|
+
}
|
|
1623
|
+
.flex-wrap {
|
|
1624
|
+
flex-wrap: wrap;
|
|
1625
|
+
}
|
|
1626
|
+
.gap-4 {
|
|
1627
|
+
gap: 16px;
|
|
1628
|
+
}
|
|
1629
|
+
.gap-3 {
|
|
1630
|
+
gap: 12px;
|
|
1631
|
+
}
|
|
1632
|
+
.gap-6 {
|
|
1633
|
+
gap: 24px;
|
|
1634
|
+
}
|
|
1630
1635
|
|
|
1631
|
-
/* Native Labels keep their natural font height even with line-height set, so
|
|
1636
|
+
/* Native Labels keep their natural font height even with line-height set, so
|
|
1632
1637
|
min-height aligns utilities whose natural metrics fall below their leading.
|
|
1633
1638
|
Tailwind pairs every text-* size with a leading, same here. */
|
|
1634
|
-
.text-2xl {
|
|
1635
|
-
|
|
1636
|
-
|
|
1637
|
-
|
|
1638
|
-
}
|
|
1639
|
-
.text-xl {
|
|
1640
|
-
|
|
1641
|
-
|
|
1642
|
-
|
|
1643
|
-
}
|
|
1644
|
-
.text-lg {
|
|
1645
|
-
|
|
1646
|
-
|
|
1647
|
-
|
|
1648
|
-
}
|
|
1649
|
-
.text-sm {
|
|
1650
|
-
|
|
1651
|
-
|
|
1652
|
-
|
|
1653
|
-
}
|
|
1654
|
-
.font-bold {
|
|
1655
|
-
|
|
1656
|
-
}
|
|
1657
|
-
.font-semibold {
|
|
1658
|
-
|
|
1659
|
-
}
|
|
1660
|
-
.text-muted {
|
|
1661
|
-
|
|
1662
|
-
}
|
|
1639
|
+
.text-2xl {
|
|
1640
|
+
font-size: 28px;
|
|
1641
|
+
line-height: 36px;
|
|
1642
|
+
min-height: 36px;
|
|
1643
|
+
}
|
|
1644
|
+
.text-xl {
|
|
1645
|
+
font-size: 20px;
|
|
1646
|
+
line-height: 28px;
|
|
1647
|
+
min-height: 28px;
|
|
1648
|
+
}
|
|
1649
|
+
.text-lg {
|
|
1650
|
+
font-size: 18px;
|
|
1651
|
+
line-height: 28px;
|
|
1652
|
+
min-height: 28px;
|
|
1653
|
+
}
|
|
1654
|
+
.text-sm {
|
|
1655
|
+
font-size: 13px;
|
|
1656
|
+
line-height: 20px;
|
|
1657
|
+
min-height: 20px;
|
|
1658
|
+
}
|
|
1659
|
+
.font-bold {
|
|
1660
|
+
font-weight: bold;
|
|
1661
|
+
}
|
|
1662
|
+
.font-semibold {
|
|
1663
|
+
font-weight: 600;
|
|
1664
|
+
}
|
|
1665
|
+
.text-muted {
|
|
1666
|
+
color: var(--color-text-secondary);
|
|
1667
|
+
}
|
|
1663
1668
|
|
|
1664
|
-
/* Corner utilities — consume the --radius-* scale and carry the smooth
|
|
1669
|
+
/* Corner utilities — consume the --radius-* scale and carry the smooth
|
|
1665
1670
|
(squircle) corner treatment. Circles stay circular: .rounded-full omits
|
|
1666
1671
|
corner-shape deliberately (squircle at full radius = a squircle disk,
|
|
1667
1672
|
not a circle). Opt out per element with `corner-shape: round`. */
|
|
1668
|
-
.rounded-sm {
|
|
1669
|
-
|
|
1670
|
-
|
|
1671
|
-
}
|
|
1672
|
-
.rounded-md {
|
|
1673
|
-
|
|
1674
|
-
|
|
1675
|
-
}
|
|
1676
|
-
.rounded-lg {
|
|
1677
|
-
|
|
1678
|
-
|
|
1679
|
-
}
|
|
1680
|
-
.rounded-xl {
|
|
1681
|
-
|
|
1682
|
-
|
|
1683
|
-
}
|
|
1684
|
-
.rounded-full {
|
|
1685
|
-
|
|
1686
|
-
}
|
|
1673
|
+
.rounded-sm {
|
|
1674
|
+
border-radius: var(--radius-sm);
|
|
1675
|
+
corner-shape: squircle;
|
|
1676
|
+
}
|
|
1677
|
+
.rounded-md {
|
|
1678
|
+
border-radius: var(--radius-md);
|
|
1679
|
+
corner-shape: squircle;
|
|
1680
|
+
}
|
|
1681
|
+
.rounded-lg {
|
|
1682
|
+
border-radius: var(--radius-lg);
|
|
1683
|
+
corner-shape: squircle;
|
|
1684
|
+
}
|
|
1685
|
+
.rounded-xl {
|
|
1686
|
+
border-radius: var(--radius-xl);
|
|
1687
|
+
corner-shape: squircle;
|
|
1688
|
+
}
|
|
1689
|
+
.rounded-full {
|
|
1690
|
+
border-radius: 9999px;
|
|
1691
|
+
}
|
|
1687
1692
|
|
|
1688
|
-
.bg-primary {
|
|
1689
|
-
|
|
1690
|
-
}
|
|
1691
|
-
.text-onprimary {
|
|
1692
|
-
|
|
1693
|
-
}
|
|
1694
|
-
.bg-danger {
|
|
1695
|
-
|
|
1696
|
-
}
|
|
1697
|
-
/* xplat-web-only:start — box-shadow is inert on native (elevation is
|
|
1693
|
+
.bg-primary {
|
|
1694
|
+
background-color: var(--color-primary);
|
|
1695
|
+
}
|
|
1696
|
+
.text-onprimary {
|
|
1697
|
+
color: var(--color-onprimary);
|
|
1698
|
+
}
|
|
1699
|
+
.bg-danger {
|
|
1700
|
+
background-color: var(--color-danger);
|
|
1701
|
+
}
|
|
1702
|
+
/* xplat-web-only:start — box-shadow is inert on native (elevation is
|
|
1698
1703
|
Android-only; no shared mapping yet) */
|
|
1699
|
-
.shadow-2 {
|
|
1700
|
-
|
|
1701
|
-
}
|
|
1702
|
-
/* xplat-web-only:end */
|
|
1703
|
-
|
|
1704
|
-
.btn {
|
|
1705
|
-
|
|
1706
|
-
|
|
1707
|
-
|
|
1708
|
-
|
|
1709
|
-
|
|
1710
|
-
|
|
1711
|
-
|
|
1712
|
-
|
|
1713
|
-
|
|
1714
|
-
|
|
1715
|
-
|
|
1716
|
-
|
|
1717
|
-
}
|
|
1704
|
+
.shadow-2 {
|
|
1705
|
+
box-shadow: 0 4px 12px rgba(0, 0, 0, 0.25);
|
|
1706
|
+
}
|
|
1707
|
+
/* xplat-web-only:end */
|
|
1708
|
+
|
|
1709
|
+
.btn {
|
|
1710
|
+
padding-top: 10px;
|
|
1711
|
+
padding-right: 16px;
|
|
1712
|
+
padding-bottom: 10px;
|
|
1713
|
+
padding-left: 16px;
|
|
1714
|
+
border-radius: var(--radius-md);
|
|
1715
|
+
corner-shape: squircle;
|
|
1716
|
+
font-size: 14px;
|
|
1717
|
+
font-weight: 500;
|
|
1718
|
+
align-items: center;
|
|
1719
|
+
justify-content: center;
|
|
1720
|
+
text-decoration: none;
|
|
1721
|
+
color: var(--color-text);
|
|
1722
|
+
}
|
|
1718
1723
|
|
|
1719
|
-
/* Secondary = the same control reading quiet: hairline border, surface
|
|
1724
|
+
/* Secondary = the same control reading quiet: hairline border, surface
|
|
1720
1725
|
fill, body-text label. Reserve .bg-primary for the one decisive action
|
|
1721
1726
|
in a group. */
|
|
1722
|
-
.btn-secondary {
|
|
1723
|
-
|
|
1724
|
-
|
|
1725
|
-
|
|
1726
|
-
|
|
1727
|
-
}
|
|
1727
|
+
.btn-secondary {
|
|
1728
|
+
background-color: var(--color-surface);
|
|
1729
|
+
border-width: 1px;
|
|
1730
|
+
border-color: var(--color-border);
|
|
1731
|
+
color: var(--color-text);
|
|
1732
|
+
}
|
|
1728
1733
|
|
|
1729
|
-
/* xplat-web-only:start — controls that render as real <a>/<button> need
|
|
1734
|
+
/* xplat-web-only:start — controls that render as real <a>/<button> need
|
|
1730
1735
|
inline layout and UA resets; the pressable/nav-link leaves are divs on
|
|
1731
1736
|
web and don't hit these rules. */
|
|
1732
|
-
a.btn {
|
|
1733
|
-
|
|
1734
|
-
}
|
|
1735
|
-
a.chip {
|
|
1736
|
-
|
|
1737
|
-
|
|
1738
|
-
}
|
|
1739
|
-
/* xplat-web-only:end */
|
|
1737
|
+
a.btn {
|
|
1738
|
+
display: inline-flex;
|
|
1739
|
+
}
|
|
1740
|
+
a.chip {
|
|
1741
|
+
display: inline-flex;
|
|
1742
|
+
align-items: center;
|
|
1743
|
+
}
|
|
1744
|
+
/* xplat-web-only:end */
|
|
1740
1745
|
|
|
1741
|
-
/* Tab shell — web divs/buttons + the Android SwapTabs fallback (iOS draws
|
|
1746
|
+
/* Tab shell — web divs/buttons + the Android SwapTabs fallback (iOS draws
|
|
1742
1747
|
its own UITabBar and never sees these). */
|
|
1743
|
-
.vx-tabbar {
|
|
1744
|
-
|
|
1745
|
-
|
|
1746
|
-
|
|
1747
|
-
}
|
|
1748
|
-
.vx-tab {
|
|
1749
|
-
|
|
1750
|
-
|
|
1751
|
-
|
|
1752
|
-
|
|
1753
|
-
|
|
1754
|
-
|
|
1755
|
-
|
|
1756
|
-
|
|
1757
|
-
}
|
|
1758
|
-
.vx-tab.active {
|
|
1759
|
-
|
|
1760
|
-
}
|
|
1761
|
-
.vx-tabicon {
|
|
1762
|
-
|
|
1763
|
-
}
|
|
1748
|
+
.vx-tabbar {
|
|
1749
|
+
border-bottom-width: 1px;
|
|
1750
|
+
border-bottom-color: var(--color-border);
|
|
1751
|
+
background-color: var(--color-surface);
|
|
1752
|
+
}
|
|
1753
|
+
.vx-tab {
|
|
1754
|
+
align-items: center;
|
|
1755
|
+
justify-content: center;
|
|
1756
|
+
padding-top: 10px;
|
|
1757
|
+
padding-right: 16px;
|
|
1758
|
+
padding-bottom: 10px;
|
|
1759
|
+
padding-left: 16px;
|
|
1760
|
+
font-size: 14px;
|
|
1761
|
+
color: var(--color-text-secondary);
|
|
1762
|
+
}
|
|
1763
|
+
.vx-tab.active {
|
|
1764
|
+
color: var(--color-text);
|
|
1765
|
+
}
|
|
1766
|
+
.vx-tabicon {
|
|
1767
|
+
margin-right: 6px;
|
|
1768
|
+
}
|
|
1764
1769
|
|
|
1765
|
-
/* xplat-web-only:start — DOM defaults are display:block (div) and
|
|
1770
|
+
/* xplat-web-only:start — DOM defaults are display:block (div) and
|
|
1766
1771
|
inline-block (button); every flex-bearing vx- class needs an explicit
|
|
1767
1772
|
display or flex-direction/align-items/justify-content are inert. */
|
|
1768
|
-
.vx-tabs {
|
|
1769
|
-
|
|
1770
|
-
|
|
1771
|
-
|
|
1772
|
-
|
|
1773
|
-
}
|
|
1774
|
-
.vx-tabbar {
|
|
1775
|
-
|
|
1776
|
-
|
|
1777
|
-
}
|
|
1778
|
-
.vx-tabpane {
|
|
1779
|
-
|
|
1780
|
-
|
|
1781
|
-
|
|
1782
|
-
|
|
1783
|
-
}
|
|
1784
|
-
button.vx-tab {
|
|
1785
|
-
|
|
1786
|
-
|
|
1787
|
-
|
|
1788
|
-
}
|
|
1789
|
-
/* xplat-web-only:end */
|
|
1773
|
+
.vx-tabs {
|
|
1774
|
+
display: flex;
|
|
1775
|
+
flex-direction: column;
|
|
1776
|
+
flex: 1;
|
|
1777
|
+
min-height: 0;
|
|
1778
|
+
}
|
|
1779
|
+
.vx-tabbar {
|
|
1780
|
+
display: flex;
|
|
1781
|
+
flex-direction: row;
|
|
1782
|
+
}
|
|
1783
|
+
.vx-tabpane {
|
|
1784
|
+
flex: 1;
|
|
1785
|
+
min-height: 0;
|
|
1786
|
+
display: flex;
|
|
1787
|
+
flex-direction: column;
|
|
1788
|
+
}
|
|
1789
|
+
button.vx-tab {
|
|
1790
|
+
display: flex;
|
|
1791
|
+
background: none;
|
|
1792
|
+
cursor: pointer;
|
|
1793
|
+
}
|
|
1794
|
+
/* xplat-web-only:end */
|
|
1790
1795
|
|
|
1791
|
-
/* harness experiment styles */
|
|
1796
|
+
/* harness experiment styles */
|
|
1792
1797
|
|
|
1793
|
-
.vx-app {
|
|
1794
|
-
|
|
1795
|
-
|
|
1796
|
-
|
|
1797
|
-
}
|
|
1798
|
+
.vx-app {
|
|
1799
|
+
padding: 24px;
|
|
1800
|
+
background-color: var(--color-surface);
|
|
1801
|
+
color: var(--color-text);
|
|
1802
|
+
}
|
|
1798
1803
|
|
|
1799
|
-
.vx-app .text-xl,
|
|
1800
|
-
.vx-app Text,
|
|
1801
|
-
.vx-app label {
|
|
1802
|
-
|
|
1803
|
-
}
|
|
1804
|
+
.vx-app .text-xl,
|
|
1805
|
+
.vx-app Text,
|
|
1806
|
+
.vx-app label {
|
|
1807
|
+
color: var(--color-text);
|
|
1808
|
+
}
|
|
1804
1809
|
|
|
1805
|
-
/* `.vx-app label` above (descendant + type) outranks single-class text
|
|
1810
|
+
/* `.vx-app label` above (descendant + type) outranks single-class text
|
|
1806
1811
|
colors inside the app root — roles that must win escalate here. */
|
|
1807
|
-
.vx-app .text-onprimary {
|
|
1808
|
-
|
|
1809
|
-
}
|
|
1810
|
-
.vx-app .text-muted {
|
|
1811
|
-
|
|
1812
|
-
}
|
|
1813
|
-
.vx-app .vx-tab label {
|
|
1814
|
-
|
|
1815
|
-
}
|
|
1816
|
-
.vx-app .vx-tab.active label {
|
|
1817
|
-
|
|
1818
|
-
}
|
|
1819
|
-
.vx-app .chip-on label {
|
|
1820
|
-
|
|
1821
|
-
}
|
|
1822
|
-
/* Danger surfaces keep white text in both themes (on-primary flips). */
|
|
1823
|
-
.bg-danger .text-onprimary {
|
|
1824
|
-
|
|
1825
|
-
}
|
|
1812
|
+
.vx-app .text-onprimary {
|
|
1813
|
+
color: var(--color-onprimary);
|
|
1814
|
+
}
|
|
1815
|
+
.vx-app .text-muted {
|
|
1816
|
+
color: var(--color-text-secondary);
|
|
1817
|
+
}
|
|
1818
|
+
.vx-app .vx-tab label {
|
|
1819
|
+
color: var(--color-text-secondary);
|
|
1820
|
+
}
|
|
1821
|
+
.vx-app .vx-tab.active label {
|
|
1822
|
+
color: var(--color-text);
|
|
1823
|
+
}
|
|
1824
|
+
.vx-app .chip-on label {
|
|
1825
|
+
color: var(--color-onprimary);
|
|
1826
|
+
}
|
|
1827
|
+
/* Danger surfaces keep white text in both themes (on-primary flips). */
|
|
1828
|
+
.bg-danger .text-onprimary {
|
|
1829
|
+
color: #ffffff;
|
|
1830
|
+
}
|
|
1826
1831
|
|
|
1827
|
-
.input {
|
|
1828
|
-
|
|
1829
|
-
|
|
1830
|
-
|
|
1831
|
-
|
|
1832
|
-
|
|
1833
|
-
|
|
1834
|
-
|
|
1835
|
-
|
|
1836
|
-
|
|
1837
|
-
|
|
1838
|
-
|
|
1839
|
-
|
|
1832
|
+
.input {
|
|
1833
|
+
padding-top: 10px;
|
|
1834
|
+
padding-right: 12px;
|
|
1835
|
+
padding-bottom: 10px;
|
|
1836
|
+
padding-left: 12px;
|
|
1837
|
+
border-width: 1px;
|
|
1838
|
+
border-color: var(--color-border);
|
|
1839
|
+
border-radius: var(--radius-md);
|
|
1840
|
+
corner-shape: squircle;
|
|
1841
|
+
font-size: 14px;
|
|
1842
|
+
background-color: var(--color-surface);
|
|
1843
|
+
color: var(--color-text);
|
|
1844
|
+
/* NS TextField/TextView placeholder color (ignored on web — the
|
|
1840
1845
|
::placeholder pseudo above covers it there). */
|
|
1841
|
-
|
|
1842
|
-
}
|
|
1846
|
+
placeholder-color: var(--color-text-secondary);
|
|
1847
|
+
}
|
|
1843
1848
|
|
|
1844
|
-
.chip {
|
|
1845
|
-
|
|
1846
|
-
|
|
1847
|
-
|
|
1848
|
-
|
|
1849
|
-
|
|
1850
|
-
|
|
1851
|
-
|
|
1852
|
-
|
|
1853
|
-
|
|
1854
|
-
|
|
1855
|
-
|
|
1856
|
-
|
|
1857
|
-
}
|
|
1849
|
+
.chip {
|
|
1850
|
+
background-color: var(--color-surface);
|
|
1851
|
+
color: var(--color-text);
|
|
1852
|
+
padding-top: 5px;
|
|
1853
|
+
padding-right: 12px;
|
|
1854
|
+
padding-bottom: 5px;
|
|
1855
|
+
padding-left: 12px;
|
|
1856
|
+
border-width: 1px;
|
|
1857
|
+
border-color: var(--color-border);
|
|
1858
|
+
border-radius: var(--radius-md);
|
|
1859
|
+
corner-shape: squircle;
|
|
1860
|
+
font-size: 13px;
|
|
1861
|
+
text-decoration: none;
|
|
1862
|
+
}
|
|
1858
1863
|
|
|
1859
|
-
/* Selected chip — the one filled element in a group of bordered peers. */
|
|
1860
|
-
.chip-on {
|
|
1861
|
-
|
|
1862
|
-
|
|
1863
|
-
|
|
1864
|
-
}
|
|
1864
|
+
/* Selected chip — the one filled element in a group of bordered peers. */
|
|
1865
|
+
.chip-on {
|
|
1866
|
+
background-color: var(--color-primary);
|
|
1867
|
+
border-color: var(--color-primary);
|
|
1868
|
+
color: var(--color-onprimary);
|
|
1869
|
+
}
|
|
1865
1870
|
|
|
1866
|
-
.cell {
|
|
1867
|
-
|
|
1868
|
-
|
|
1869
|
-
|
|
1870
|
-
}
|
|
1871
|
+
.cell {
|
|
1872
|
+
padding: 12px;
|
|
1873
|
+
border-bottom-width: 1px;
|
|
1874
|
+
border-bottom-color: var(--color-border);
|
|
1875
|
+
}
|
|
1871
1876
|
|
|
1872
|
-
.gap-2 {
|
|
1873
|
-
|
|
1874
|
-
}
|
|
1877
|
+
.gap-2 {
|
|
1878
|
+
gap: 8px;
|
|
1879
|
+
}
|
|
1875
1880
|
|
|
1876
|
-
/* In-window sheet — bottom-anchored panel (matches the native RootLayout
|
|
1881
|
+
/* In-window sheet — bottom-anchored panel (matches the native RootLayout
|
|
1877
1882
|
sheet). Layer is pointer-events:none; backdrop + panel re-enable. */
|
|
1878
|
-
.vx-sheet-layer {
|
|
1879
|
-
|
|
1880
|
-
}
|
|
1883
|
+
.vx-sheet-layer {
|
|
1884
|
+
z-index: 1100;
|
|
1885
|
+
}
|
|
1881
1886
|
|
|
1882
|
-
.vx-sheet-backdrop {
|
|
1883
|
-
|
|
1884
|
-
}
|
|
1887
|
+
.vx-sheet-backdrop {
|
|
1888
|
+
background: rgba(0, 0, 0, 0.4);
|
|
1889
|
+
}
|
|
1885
1890
|
|
|
1886
|
-
.vx-sheet {
|
|
1887
|
-
|
|
1888
|
-
|
|
1889
|
-
|
|
1890
|
-
|
|
1891
|
-
|
|
1892
|
-
|
|
1893
|
-
|
|
1894
|
-
|
|
1895
|
-
|
|
1896
|
-
}
|
|
1891
|
+
.vx-sheet {
|
|
1892
|
+
max-height: 85%;
|
|
1893
|
+
padding: 24px;
|
|
1894
|
+
border-width: 1px;
|
|
1895
|
+
border-color: var(--color-border);
|
|
1896
|
+
border-top-left-radius: var(--radius-xl);
|
|
1897
|
+
border-top-right-radius: var(--radius-xl);
|
|
1898
|
+
corner-shape: squircle;
|
|
1899
|
+
background-color: var(--color-surface);
|
|
1900
|
+
color: var(--color-text);
|
|
1901
|
+
}
|
|
1897
1902
|
|
|
1898
|
-
/* xplat-web-only:start — DOM positioning + hit-testing for the sheet.
|
|
1903
|
+
/* xplat-web-only:start — DOM positioning + hit-testing for the sheet.
|
|
1899
1904
|
The native leaf renders on RootLayout with its own geometry. */
|
|
1900
|
-
.vx-sheet-layer {
|
|
1901
|
-
|
|
1902
|
-
|
|
1903
|
-
|
|
1904
|
-
}
|
|
1905
|
+
.vx-sheet-layer {
|
|
1906
|
+
position: fixed;
|
|
1907
|
+
inset: 0;
|
|
1908
|
+
pointer-events: none;
|
|
1909
|
+
}
|
|
1905
1910
|
|
|
1906
|
-
.vx-sheet-backdrop,
|
|
1907
|
-
.vx-sheet {
|
|
1908
|
-
|
|
1909
|
-
|
|
1910
|
-
|
|
1911
|
-
}
|
|
1911
|
+
.vx-sheet-backdrop,
|
|
1912
|
+
.vx-sheet {
|
|
1913
|
+
position: absolute;
|
|
1914
|
+
inset: 0;
|
|
1915
|
+
pointer-events: auto;
|
|
1916
|
+
}
|
|
1912
1917
|
|
|
1913
|
-
.vx-sheet {
|
|
1914
|
-
|
|
1915
|
-
|
|
1916
|
-
|
|
1917
|
-
}
|
|
1918
|
-
/* xplat-web-only:end */
|
|
1918
|
+
.vx-sheet {
|
|
1919
|
+
top: auto;
|
|
1920
|
+
bottom: 0;
|
|
1921
|
+
overflow: auto;
|
|
1922
|
+
}
|
|
1923
|
+
/* xplat-web-only:end */
|
|
1919
1924
|
|
|
1920
|
-
.vx-sheet-grabber {
|
|
1921
|
-
|
|
1922
|
-
|
|
1923
|
-
|
|
1924
|
-
|
|
1925
|
-
}
|
|
1925
|
+
.vx-sheet-grabber {
|
|
1926
|
+
display: flex;
|
|
1927
|
+
align-items: center;
|
|
1928
|
+
justify-content: center;
|
|
1929
|
+
height: 28px;
|
|
1930
|
+
}
|
|
1926
1931
|
|
|
1927
|
-
.vx-sheet-grip {
|
|
1928
|
-
|
|
1929
|
-
|
|
1930
|
-
|
|
1931
|
-
|
|
1932
|
-
|
|
1933
|
-
}
|
|
1932
|
+
.vx-sheet-grip {
|
|
1933
|
+
width: 36px;
|
|
1934
|
+
height: 4px;
|
|
1935
|
+
border-radius: 999px;
|
|
1936
|
+
background-color: var(--color-text-secondary);
|
|
1937
|
+
opacity: 0.4;
|
|
1938
|
+
}
|
|
1934
1939
|
|
|
1935
|
-
/* xplat-web-only:start — detents size the panel to the largest fraction
|
|
1940
|
+
/* xplat-web-only:start — detents size the panel to the largest fraction
|
|
1936
1941
|
(overriding the 85% cap) and overlay the grabber; native stacks it as a
|
|
1937
1942
|
top-aligned grid child. touch-action keeps drags off native scroll. */
|
|
1938
|
-
.vx-sheet-detents {
|
|
1939
|
-
|
|
1940
|
-
}
|
|
1941
|
-
.vx-sheet-detents > .vx-sheet-grabber {
|
|
1942
|
-
|
|
1943
|
-
|
|
1944
|
-
|
|
1945
|
-
|
|
1946
|
-
|
|
1947
|
-
|
|
1948
|
-
|
|
1943
|
+
.vx-sheet-detents {
|
|
1944
|
+
max-height: none;
|
|
1945
|
+
}
|
|
1946
|
+
.vx-sheet-detents > .vx-sheet-grabber {
|
|
1947
|
+
position: absolute;
|
|
1948
|
+
top: 0;
|
|
1949
|
+
left: 0;
|
|
1950
|
+
right: 0;
|
|
1951
|
+
z-index: 2;
|
|
1952
|
+
cursor: grab;
|
|
1953
|
+
touch-action: none;
|
|
1954
|
+
}
|
|
1955
|
+
/* xplat-web-only:end */
|
|
1949
1956
|
}
|
|
1950
|
-
/* xplat-web-only:end */
|