@tale-ui/react-styles 0.0.3

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/src/form.css ADDED
@@ -0,0 +1,26 @@
1
+ /*
2
+ * Form — @tale-ui/react
3
+ *
4
+ * Styled with @tale-ui/core design tokens.
5
+ * Form wraps Field components and provides form-level validation context.
6
+ * Base-ui Form has no direct data attributes on the root element.
7
+ *
8
+ * Usage:
9
+ * <Form className="tale-form">
10
+ * <Field.Root className="tale-field">
11
+ * <Field.Label className="tale-field__label">Name</Field.Label>
12
+ * <Input className="tale-input" name="name" />
13
+ * <Field.Error className="tale-field__error" />
14
+ * </Field.Root>
15
+ * <button className="tale-button tale-button--primary" type="submit">Submit</button>
16
+ * </Form>
17
+ */
18
+
19
+ /* ─── Form ─────────────────────────────────────────────────────────────────── */
20
+
21
+ .tale-form {
22
+ display: flex;
23
+ flex-direction: column;
24
+ gap: var(--space-m);
25
+ width: 100%;
26
+ }
package/src/index.css ADDED
@@ -0,0 +1,62 @@
1
+ /*
2
+ * @tale-ui/react-styles
3
+ *
4
+ * Opinionated CSS for @tale-ui/react components.
5
+ * Built on @tale-ui/core design tokens (--neutral-*, --color-*, --space-*, --text-*).
6
+ *
7
+ * Import order:
8
+ * 1. @tale-ui/core — tokens, foundations, layout utilities, dark-mode support
9
+ * 2. Component CSS — tale-ui specific component styles
10
+ *
11
+ * Usage:
12
+ * @import '@tale-ui/react-styles'; // all components
13
+ * @import '@tale-ui/react-styles/button'; // individual component
14
+ */
15
+
16
+ @import '@tale-ui/core';
17
+
18
+ /* ─── Form controls ─────────────────────────────────────────────────────────── */
19
+ @import './button.css';
20
+ @import './checkbox.css';
21
+ @import './radio.css';
22
+ @import './switch.css';
23
+ @import './toggle.css';
24
+ @import './input.css';
25
+ @import './number-field.css';
26
+ @import './slider.css';
27
+ @import './select.css';
28
+ @import './combobox.css';
29
+ @import './autocomplete.css';
30
+
31
+ /* ─── Layout / containers ───────────────────────────────────────────────────── */
32
+ @import './accordion.css';
33
+ @import './collapsible.css';
34
+ @import './tabs.css';
35
+ @import './scroll-area.css';
36
+ @import './separator.css';
37
+
38
+ /* ─── Overlay ───────────────────────────────────────────────────────────────── */
39
+ @import './dialog.css';
40
+ @import './alert-dialog.css';
41
+ @import './popover.css';
42
+ @import './drawer.css';
43
+ @import './tooltip.css';
44
+ @import './preview-card.css';
45
+
46
+ /* ─── Navigation ────────────────────────────────────────────────────────────── */
47
+ @import './menu.css';
48
+ @import './navigation-menu.css';
49
+
50
+ /* ─── Feedback / display ────────────────────────────────────────────────────── */
51
+ @import './progress.css';
52
+ @import './meter.css';
53
+ @import './avatar.css';
54
+ @import './toast.css';
55
+
56
+ /* ─── Form structure ────────────────────────────────────────────────────────── */
57
+ @import './field.css';
58
+ @import './fieldset.css';
59
+ @import './form.css';
60
+
61
+ /* ─── Utilities ─────────────────────────────────────────────────────────────── */
62
+ @import './toolbar.css';
package/src/input.css ADDED
@@ -0,0 +1,84 @@
1
+ /*
2
+ * Input — @tale-ui/react
3
+ *
4
+ * Styled with @tale-ui/core design tokens.
5
+ * Base-ui Input exposes:
6
+ * [data-disabled] [data-valid] [data-invalid]
7
+ * [data-touched] [data-dirty] [data-filled] [data-focused]
8
+ *
9
+ * Usage:
10
+ * <Input className="tale-input" />
11
+ */
12
+
13
+ /* ─── Base ─────────────────────────────────────────────────────────────────── */
14
+
15
+ .tale-input {
16
+ display: block;
17
+ width: 100%;
18
+ min-height: 3.6rem;
19
+ padding: var(--space-3xs) var(--space-xs);
20
+ border: 1px solid var(--neutral-26);
21
+ border-radius: 0.6rem;
22
+ background-color: var(--neutral-10);
23
+ color: var(--neutral-90);
24
+ font-family: var(--body-font-family);
25
+ font-size: var(--text-m-font-size);
26
+ line-height: 1.5;
27
+ outline: none;
28
+ transition:
29
+ border-color 0.15s ease,
30
+ box-shadow 0.15s ease,
31
+ background-color 0.15s ease;
32
+ }
33
+
34
+ .tale-input::placeholder {
35
+ color: var(--neutral-50);
36
+ }
37
+
38
+ /* ─── Focus ───────────────────────────────────────────────────────────────── */
39
+
40
+ .tale-input:focus,
41
+ .tale-input[data-focused] {
42
+ border-color: var(--color-60);
43
+ box-shadow: 0 0 0 3px color-mix(in srgb, var(--color-60) 20%, transparent);
44
+ }
45
+
46
+ /* ─── Hover ───────────────────────────────────────────────────────────────── */
47
+
48
+ .tale-input:hover:not(:focus):not([data-disabled]):not([data-invalid]) {
49
+ border-color: var(--neutral-40);
50
+ }
51
+
52
+ /* ─── Invalid state ───────────────────────────────────────────────────────── */
53
+
54
+ .tale-input[data-invalid] {
55
+ border-color: var(--red-60);
56
+ }
57
+
58
+ .tale-input[data-invalid]:focus,
59
+ .tale-input[data-invalid][data-focused] {
60
+ box-shadow: 0 0 0 3px color-mix(in srgb, var(--red-60) 20%, transparent);
61
+ }
62
+
63
+ /* ─── Disabled state ──────────────────────────────────────────────────────── */
64
+
65
+ .tale-input[data-disabled],
66
+ .tale-input:disabled {
67
+ opacity: 0.45;
68
+ cursor: not-allowed;
69
+ background-color: var(--neutral-14);
70
+ }
71
+
72
+ /* ─── Size modifiers ──────────────────────────────────────────────────────── */
73
+
74
+ .tale-input--sm {
75
+ min-height: 2.8rem;
76
+ padding: var(--space-4xs) var(--space-3xs);
77
+ font-size: var(--text-s-font-size);
78
+ }
79
+
80
+ .tale-input--lg {
81
+ min-height: 4.4rem;
82
+ padding: var(--space-2xs) var(--space-s);
83
+ font-size: var(--text-l-font-size);
84
+ }
package/src/menu.css ADDED
@@ -0,0 +1,179 @@
1
+ /*
2
+ * Menu / ContextMenu / Menubar — @tale-ui/react
3
+ *
4
+ * Styled with @tale-ui/core design tokens.
5
+ * Base-ui Menu exposes:
6
+ * Trigger: [data-popup-open]
7
+ * Popup: [data-open] [data-closed] [data-starting-style] [data-ending-style]
8
+ * [data-side] [data-align] [data-instant]
9
+ * Item: [data-highlighted] [data-disabled]
10
+ * CheckboxItem: [data-checked] [data-unchecked] [data-highlighted] [data-disabled]
11
+ * RadioItem: [data-checked] [data-unchecked] [data-highlighted] [data-disabled]
12
+ *
13
+ * Usage:
14
+ * <Menu.Root>
15
+ * <Menu.Trigger className="tale-button tale-button--neutral">Menu</Menu.Trigger>
16
+ * <Menu.Portal>
17
+ * <Menu.Positioner>
18
+ * <Menu.Popup className="tale-menu__popup">
19
+ * <Menu.Item className="tale-menu__item">Option</Menu.Item>
20
+ * <Menu.Separator className="tale-menu__separator" />
21
+ * <Menu.GroupLabel className="tale-menu__group-label">Group</Menu.GroupLabel>
22
+ * </Menu.Popup>
23
+ * </Menu.Positioner>
24
+ * </Menu.Portal>
25
+ * </Menu.Root>
26
+ */
27
+
28
+ /* ─── Popup ────────────────────────────────────────────────────────────────── */
29
+
30
+ .tale-menu__popup {
31
+ background-color: var(--neutral-10);
32
+ border: 1px solid var(--neutral-20);
33
+ border-radius: 0.8rem;
34
+ box-shadow:
35
+ 0 2px 4px rgba(0, 0, 0, 0.06),
36
+ 0 8px 24px rgba(0, 0, 0, 0.08);
37
+ padding: var(--space-4xs);
38
+ outline: none;
39
+ min-width: 16rem;
40
+ max-width: 28rem;
41
+ transition: opacity 0.15s ease, transform 0.15s ease;
42
+ }
43
+
44
+ .tale-menu__popup[data-starting-style],
45
+ .tale-menu__popup[data-ending-style] {
46
+ opacity: 0;
47
+ transform: scale(0.97);
48
+ }
49
+
50
+ /* ─── Item (base styles shared by Item, CheckboxItem, RadioItem) ────────────── */
51
+
52
+ .tale-menu__item,
53
+ .tale-menu__checkbox-item,
54
+ .tale-menu__radio-item,
55
+ .tale-menu__link-item,
56
+ .tale-menu__submenu-trigger {
57
+ display: flex;
58
+ align-items: center;
59
+ gap: var(--space-2xs);
60
+ padding: var(--space-2xs) var(--space-xs);
61
+ border-radius: 0.5rem;
62
+ color: var(--neutral-80);
63
+ font-family: var(--body-font-family);
64
+ font-size: var(--text-m-font-size);
65
+ cursor: pointer;
66
+ outline: none;
67
+ transition: background-color 0.1s ease, color 0.1s ease;
68
+ user-select: none;
69
+ border: none;
70
+ background: none;
71
+ width: 100%;
72
+ text-align: left;
73
+ text-decoration: none;
74
+ }
75
+
76
+ .tale-menu__item[data-highlighted],
77
+ .tale-menu__checkbox-item[data-highlighted],
78
+ .tale-menu__radio-item[data-highlighted],
79
+ .tale-menu__link-item[data-highlighted],
80
+ .tale-menu__submenu-trigger[data-highlighted] {
81
+ background-color: var(--neutral-14);
82
+ color: var(--neutral-90);
83
+ }
84
+
85
+ .tale-menu__item[data-disabled],
86
+ .tale-menu__checkbox-item[data-disabled],
87
+ .tale-menu__radio-item[data-disabled],
88
+ .tale-menu__link-item[data-disabled],
89
+ .tale-menu__submenu-trigger[data-disabled] {
90
+ opacity: 0.45;
91
+ cursor: not-allowed;
92
+ pointer-events: none;
93
+ }
94
+
95
+ /* ─── Checkbox/Radio item indicator ────────────────────────────────────────── */
96
+
97
+ .tale-menu__item-indicator {
98
+ width: 1.4rem;
99
+ height: 1.4rem;
100
+ flex-shrink: 0;
101
+ color: var(--color-60);
102
+ }
103
+
104
+ /* ─── Submenu trigger arrow ─────────────────────────────────────────────────── */
105
+
106
+ .tale-menu__submenu-trigger::after {
107
+ content: '›';
108
+ margin-left: auto;
109
+ color: var(--neutral-50);
110
+ }
111
+
112
+ /* ─── Group label ──────────────────────────────────────────────────────────── */
113
+
114
+ .tale-menu__group-label {
115
+ padding: var(--space-4xs) var(--space-xs);
116
+ color: var(--neutral-50);
117
+ font-family: var(--label-font-family);
118
+ font-size: var(--label-s-font-size);
119
+ font-weight: var(--label-font-weight);
120
+ text-transform: uppercase;
121
+ letter-spacing: 0.05em;
122
+ cursor: default;
123
+ }
124
+
125
+ /* ─── Separator ────────────────────────────────────────────────────────────── */
126
+
127
+ .tale-menu__separator {
128
+ height: 1px;
129
+ background-color: var(--neutral-18);
130
+ margin: var(--space-4xs) 0;
131
+ }
132
+
133
+ /* ─── Arrow ────────────────────────────────────────────────────────────────── */
134
+
135
+ .tale-menu__arrow {
136
+ width: 1rem;
137
+ height: 0.5rem;
138
+ fill: var(--neutral-10);
139
+ stroke: var(--neutral-20);
140
+ stroke-width: 1;
141
+ }
142
+
143
+ /* ─── Menubar — horizontal trigger bar ─────────────────────────────────────── */
144
+
145
+ .tale-menubar {
146
+ display: flex;
147
+ align-items: center;
148
+ gap: 0;
149
+ background-color: var(--neutral-12);
150
+ border: 1px solid var(--neutral-20);
151
+ border-radius: 0.6rem;
152
+ padding: var(--space-4xs);
153
+ }
154
+
155
+ .tale-menubar__item {
156
+ display: inline-flex;
157
+ align-items: center;
158
+ padding: var(--space-4xs) var(--space-3xs);
159
+ border-radius: 0.4rem;
160
+ border: none;
161
+ background-color: transparent;
162
+ color: var(--neutral-80);
163
+ font-family: var(--label-font-family);
164
+ font-size: var(--label-m-font-size);
165
+ font-weight: var(--label-font-weight);
166
+ cursor: pointer;
167
+ outline: none;
168
+ transition: background-color 0.15s ease, color 0.15s ease;
169
+ }
170
+
171
+ .tale-menubar__item:hover,
172
+ .tale-menubar__item[data-popup-open] {
173
+ background-color: var(--neutral-18);
174
+ color: var(--neutral-90);
175
+ }
176
+
177
+ .tale-menubar__item:focus-visible {
178
+ box-shadow: 0 0 0 2px var(--color-60);
179
+ }
package/src/meter.css ADDED
@@ -0,0 +1,61 @@
1
+ /*
2
+ * Meter — @tale-ui/react
3
+ *
4
+ * Styled with @tale-ui/core design tokens.
5
+ * A Meter is a non-interactive progress-like component for displaying a scalar value
6
+ * within a range (e.g., disk usage, battery level).
7
+ *
8
+ * Usage:
9
+ * <Meter.Root className="tale-meter" value={60} min={0} max={100}>
10
+ * <Meter.Track className="tale-meter__track">
11
+ * <Meter.Indicator className="tale-meter__indicator" />
12
+ * </Meter.Track>
13
+ * </Meter.Root>
14
+ */
15
+
16
+ /* ─── Root ─────────────────────────────────────────────────────────────────── */
17
+
18
+ .tale-meter {
19
+ display: flex;
20
+ flex-direction: column;
21
+ gap: var(--space-4xs);
22
+ width: 100%;
23
+ }
24
+
25
+ /* ─── Label ────────────────────────────────────────────────────────────────── */
26
+
27
+ .tale-meter__label {
28
+ color: var(--neutral-80);
29
+ font-family: var(--label-font-family);
30
+ font-size: var(--label-m-font-size);
31
+ font-weight: var(--label-font-weight);
32
+ }
33
+
34
+ /* ─── Track ────────────────────────────────────────────────────────────────── */
35
+
36
+ .tale-meter__track {
37
+ position: relative;
38
+ width: 100%;
39
+ height: 0.8rem;
40
+ border-radius: 9999px;
41
+ background-color: var(--neutral-20);
42
+ overflow: hidden;
43
+ }
44
+
45
+ /* ─── Indicator ────────────────────────────────────────────────────────────── */
46
+
47
+ .tale-meter__indicator {
48
+ height: 100%;
49
+ border-radius: 9999px;
50
+ background-color: var(--color-60);
51
+ transition: width 0.3s ease;
52
+ }
53
+
54
+ /* ─── Value label ──────────────────────────────────────────────────────────── */
55
+
56
+ .tale-meter__value {
57
+ color: var(--neutral-60);
58
+ font-family: var(--label-font-family);
59
+ font-size: var(--label-s-font-size);
60
+ text-align: right;
61
+ }
@@ -0,0 +1,146 @@
1
+ /*
2
+ * NavigationMenu — @tale-ui/react
3
+ *
4
+ * Styled with @tale-ui/core design tokens.
5
+ * Base-ui NavigationMenu is a horizontal nav with hover-activated content panels.
6
+ *
7
+ * Usage:
8
+ * <NavigationMenu.Root className="tale-navigation-menu">
9
+ * <NavigationMenu.List className="tale-navigation-menu__list">
10
+ * <NavigationMenu.Item>
11
+ * <NavigationMenu.Trigger className="tale-navigation-menu__trigger">Products</NavigationMenu.Trigger>
12
+ * <NavigationMenu.Portal>
13
+ * <NavigationMenu.Positioner>
14
+ * <NavigationMenu.Popup className="tale-navigation-menu__popup">
15
+ * <NavigationMenu.Content className="tale-navigation-menu__content">…</NavigationMenu.Content>
16
+ * </NavigationMenu.Popup>
17
+ * </NavigationMenu.Positioner>
18
+ * </NavigationMenu.Portal>
19
+ * </NavigationMenu.Item>
20
+ * <NavigationMenu.Item>
21
+ * <NavigationMenu.Link className="tale-navigation-menu__link" href="/about">About</NavigationMenu.Link>
22
+ * </NavigationMenu.Item>
23
+ * </NavigationMenu.List>
24
+ * </NavigationMenu.Root>
25
+ */
26
+
27
+ /* ─── Root ─────────────────────────────────────────────────────────────────── */
28
+
29
+ .tale-navigation-menu {
30
+ position: relative;
31
+ }
32
+
33
+ /* ─── List ─────────────────────────────────────────────────────────────────── */
34
+
35
+ .tale-navigation-menu__list {
36
+ display: flex;
37
+ align-items: center;
38
+ gap: var(--space-4xs);
39
+ list-style: none;
40
+ margin: 0;
41
+ padding: 0;
42
+ }
43
+
44
+ /* ─── Trigger ──────────────────────────────────────────────────────────────── */
45
+
46
+ .tale-navigation-menu__trigger {
47
+ display: inline-flex;
48
+ align-items: center;
49
+ gap: var(--space-3xs);
50
+ padding: var(--space-4xs) var(--space-3xs);
51
+ border: none;
52
+ border-radius: 0.5rem;
53
+ background-color: transparent;
54
+ color: var(--neutral-80);
55
+ font-family: var(--label-font-family);
56
+ font-size: var(--label-m-font-size);
57
+ font-weight: var(--label-font-weight);
58
+ cursor: pointer;
59
+ outline: none;
60
+ transition: background-color 0.15s ease, color 0.15s ease;
61
+ }
62
+
63
+ .tale-navigation-menu__trigger:hover,
64
+ .tale-navigation-menu__trigger[data-popup-open] {
65
+ background-color: var(--neutral-14);
66
+ color: var(--neutral-90);
67
+ }
68
+
69
+ .tale-navigation-menu__trigger:focus-visible {
70
+ box-shadow: 0 0 0 2px var(--color-60);
71
+ }
72
+
73
+ /* ─── Icon ─────────────────────────────────────────────────────────────────── */
74
+
75
+ .tale-navigation-menu__icon {
76
+ width: 1.4rem;
77
+ height: 1.4rem;
78
+ color: var(--neutral-50);
79
+ transition: transform 0.2s ease;
80
+ }
81
+
82
+ .tale-navigation-menu__trigger[data-popup-open] .tale-navigation-menu__icon {
83
+ transform: rotate(180deg);
84
+ }
85
+
86
+ /* ─── Link ─────────────────────────────────────────────────────────────────── */
87
+
88
+ .tale-navigation-menu__link {
89
+ display: inline-flex;
90
+ align-items: center;
91
+ padding: var(--space-4xs) var(--space-3xs);
92
+ border-radius: 0.5rem;
93
+ color: var(--neutral-80);
94
+ font-family: var(--label-font-family);
95
+ font-size: var(--label-m-font-size);
96
+ font-weight: var(--label-font-weight);
97
+ text-decoration: none;
98
+ outline: none;
99
+ transition: background-color 0.15s ease, color 0.15s ease;
100
+ }
101
+
102
+ .tale-navigation-menu__link:hover {
103
+ background-color: var(--neutral-14);
104
+ color: var(--neutral-90);
105
+ }
106
+
107
+ .tale-navigation-menu__link:focus-visible {
108
+ box-shadow: 0 0 0 2px var(--color-60);
109
+ }
110
+
111
+ /* ─── Popup ────────────────────────────────────────────────────────────────── */
112
+
113
+ .tale-navigation-menu__popup {
114
+ background-color: var(--neutral-10);
115
+ border: 1px solid var(--neutral-20);
116
+ border-radius: 1rem;
117
+ box-shadow:
118
+ 0 2px 4px rgba(0, 0, 0, 0.06),
119
+ 0 12px 32px rgba(0, 0, 0, 0.08);
120
+ outline: none;
121
+ transition: opacity 0.15s ease, transform 0.15s ease;
122
+ }
123
+
124
+ .tale-navigation-menu__popup[data-starting-style],
125
+ .tale-navigation-menu__popup[data-ending-style] {
126
+ opacity: 0;
127
+ transform: scale(0.97);
128
+ }
129
+
130
+ /* ─── Content ──────────────────────────────────────────────────────────────── */
131
+
132
+ .tale-navigation-menu__content {
133
+ padding: var(--space-m);
134
+ min-width: 20rem;
135
+ }
136
+
137
+ /* ─── Viewport ─────────────────────────────────────────────────────────────── */
138
+
139
+ .tale-navigation-menu__viewport {
140
+ position: absolute;
141
+ top: calc(100% + var(--space-3xs));
142
+ left: 0;
143
+ overflow: hidden;
144
+ border-radius: 1rem;
145
+ transition: width 0.3s ease, height 0.3s ease;
146
+ }
@@ -0,0 +1,133 @@
1
+ /*
2
+ * NumberField — @tale-ui/react
3
+ *
4
+ * Styled with @tale-ui/core design tokens.
5
+ * Base-ui NumberField exposes:
6
+ * Root: [data-disabled] [data-scrubbing] [data-valid] [data-invalid]
7
+ * Thumb: (scrub area cursor)
8
+ *
9
+ * Usage:
10
+ * <NumberField.Root className="tale-number-field">
11
+ * <NumberField.Group className="tale-number-field__group">
12
+ * <NumberField.Decrement className="tale-number-field__decrement">−</NumberField.Decrement>
13
+ * <NumberField.Input className="tale-number-field__input" />
14
+ * <NumberField.Increment className="tale-number-field__increment">+</NumberField.Increment>
15
+ * </NumberField.Group>
16
+ * </NumberField.Root>
17
+ */
18
+
19
+ /* ─── Root ─────────────────────────────────────────────────────────────────── */
20
+
21
+ .tale-number-field {
22
+ display: inline-flex;
23
+ flex-direction: column;
24
+ gap: var(--space-4xs);
25
+ }
26
+
27
+ /* ─── Group — wraps input + stepper buttons ───────────────────────────────── */
28
+
29
+ .tale-number-field__group {
30
+ display: inline-flex;
31
+ align-items: stretch;
32
+ border: 1px solid var(--neutral-26);
33
+ border-radius: 0.6rem;
34
+ overflow: hidden;
35
+ background-color: var(--neutral-10);
36
+ transition: border-color 0.15s ease, box-shadow 0.15s ease;
37
+ }
38
+
39
+ .tale-number-field__group:focus-within {
40
+ border-color: var(--color-60);
41
+ box-shadow: 0 0 0 3px color-mix(in srgb, var(--color-60) 20%, transparent);
42
+ }
43
+
44
+ .tale-number-field__group:hover:not(:focus-within) {
45
+ border-color: var(--neutral-40);
46
+ }
47
+
48
+ /* ─── Input ───────────────────────────────────────────────────────────────── */
49
+
50
+ .tale-number-field__input {
51
+ flex: 1;
52
+ min-width: 6rem;
53
+ min-height: 3.6rem;
54
+ padding: var(--space-3xs) var(--space-xs);
55
+ border: none;
56
+ background-color: transparent;
57
+ color: var(--neutral-90);
58
+ font-family: var(--body-font-family);
59
+ font-size: var(--text-m-font-size);
60
+ text-align: center;
61
+ outline: none;
62
+ }
63
+
64
+ .tale-number-field__input::placeholder {
65
+ color: var(--neutral-50);
66
+ }
67
+
68
+ /* ─── Stepper buttons ─────────────────────────────────────────────────────── */
69
+
70
+ .tale-number-field__decrement,
71
+ .tale-number-field__increment {
72
+ display: flex;
73
+ align-items: center;
74
+ justify-content: center;
75
+ width: 3.2rem;
76
+ min-height: 3.6rem;
77
+ border: none;
78
+ background-color: var(--neutral-14);
79
+ color: var(--neutral-70);
80
+ font-size: var(--label-m-font-size);
81
+ font-family: var(--label-font-family);
82
+ cursor: pointer;
83
+ outline: none;
84
+ transition: background-color 0.15s ease, color 0.15s ease;
85
+ user-select: none;
86
+ }
87
+
88
+ .tale-number-field__decrement {
89
+ border-right: 1px solid var(--neutral-22);
90
+ }
91
+
92
+ .tale-number-field__increment {
93
+ border-left: 1px solid var(--neutral-22);
94
+ }
95
+
96
+ .tale-number-field__decrement:hover:not(:disabled),
97
+ .tale-number-field__increment:hover:not(:disabled) {
98
+ background-color: var(--neutral-20);
99
+ color: var(--neutral-90);
100
+ }
101
+
102
+ .tale-number-field__decrement:active:not(:disabled),
103
+ .tale-number-field__increment:active:not(:disabled) {
104
+ background-color: var(--neutral-26);
105
+ }
106
+
107
+ .tale-number-field__decrement:focus-visible,
108
+ .tale-number-field__increment:focus-visible {
109
+ box-shadow: inset 0 0 0 2px var(--color-60);
110
+ }
111
+
112
+ /* ─── Disabled state ──────────────────────────────────────────────────────── */
113
+
114
+ .tale-number-field[data-disabled] .tale-number-field__group {
115
+ opacity: 0.45;
116
+ cursor: not-allowed;
117
+ }
118
+
119
+ .tale-number-field[data-disabled] .tale-number-field__input,
120
+ .tale-number-field[data-disabled] .tale-number-field__decrement,
121
+ .tale-number-field[data-disabled] .tale-number-field__increment {
122
+ pointer-events: none;
123
+ }
124
+
125
+ /* ─── Invalid state ───────────────────────────────────────────────────────── */
126
+
127
+ .tale-number-field[data-invalid] .tale-number-field__group {
128
+ border-color: var(--red-60);
129
+ }
130
+
131
+ .tale-number-field[data-invalid] .tale-number-field__group:focus-within {
132
+ box-shadow: 0 0 0 3px color-mix(in srgb, var(--red-60) 20%, transparent);
133
+ }