@tokis/theme 1.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (50) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +51 -0
  3. package/package.json +69 -0
  4. package/src/base/index.css +19 -0
  5. package/src/base/reset.css +76 -0
  6. package/src/base/variables.css +206 -0
  7. package/src/components/accordion.css +124 -0
  8. package/src/components/alert.css +196 -0
  9. package/src/components/app-bar.css +69 -0
  10. package/src/components/avatar.css +199 -0
  11. package/src/components/bottom-nav.css +79 -0
  12. package/src/components/button.css +213 -0
  13. package/src/components/card.css +248 -0
  14. package/src/components/charts.css +38 -0
  15. package/src/components/checkbox.css +158 -0
  16. package/src/components/circular-progress.css +62 -0
  17. package/src/components/codeblock.css +229 -0
  18. package/src/components/command-palette.css +183 -0
  19. package/src/components/confirm-dialog.css +95 -0
  20. package/src/components/context-menu.css +82 -0
  21. package/src/components/dialog.css +149 -0
  22. package/src/components/drawer.css +167 -0
  23. package/src/components/dropdown.css +33 -0
  24. package/src/components/emptystate.css +42 -0
  25. package/src/components/extended.css +663 -0
  26. package/src/components/hover-card.css +29 -0
  27. package/src/components/index.css +40 -0
  28. package/src/components/infinite-scroll.css +45 -0
  29. package/src/components/input.css +201 -0
  30. package/src/components/nav-rail.css +104 -0
  31. package/src/components/navigation.css +273 -0
  32. package/src/components/pagination.css +91 -0
  33. package/src/components/progress.css +192 -0
  34. package/src/components/result.css +58 -0
  35. package/src/components/search-field.css +102 -0
  36. package/src/components/select.css +175 -0
  37. package/src/components/slider.css +115 -0
  38. package/src/components/snackbar.css +234 -0
  39. package/src/components/statistic.css +70 -0
  40. package/src/components/stepper.css +131 -0
  41. package/src/components/switch.css +107 -0
  42. package/src/components/tabs.css +152 -0
  43. package/src/components/timeline.css +125 -0
  44. package/src/components/toggle.css +103 -0
  45. package/src/components/tooltip.css +113 -0
  46. package/src/components/treeview.css +107 -0
  47. package/src/components/virtual-list.css +19 -0
  48. package/src/index.css +6 -0
  49. package/src/utilities/index.css +2 -0
  50. package/src/utilities/layout.css +28 -0
@@ -0,0 +1,213 @@
1
+ /* ============================================================
2
+ Tokis — Button
3
+ ============================================================ */
4
+
5
+ .tokis-btn {
6
+ display: inline-flex;
7
+ align-items: center;
8
+ justify-content: center;
9
+ gap: var(--tokis-spacing-2);
10
+ padding: 0 var(--tokis-spacing-4);
11
+ height: 40px;
12
+ font-size: var(--tokis-font-size-sm);
13
+ font-weight: var(--tokis-font-weight-medium);
14
+ font-family: inherit;
15
+ line-height: 1;
16
+ border-radius: var(--tokis-radius-md);
17
+ border: 1px solid transparent;
18
+ cursor: pointer;
19
+ user-select: none;
20
+ white-space: nowrap;
21
+ text-decoration: none;
22
+ transition:
23
+ background-color var(--tokis-duration-fast) var(--tokis-ease-out),
24
+ border-color var(--tokis-duration-fast) var(--tokis-ease-out),
25
+ color var(--tokis-duration-fast) var(--tokis-ease-out),
26
+ box-shadow var(--tokis-duration-fast) var(--tokis-ease-out),
27
+ transform var(--tokis-duration-fast) var(--tokis-ease-out),
28
+ opacity var(--tokis-duration-fast) var(--tokis-ease-out);
29
+ position: relative;
30
+ overflow: hidden;
31
+ outline: none;
32
+ -webkit-tap-highlight-color: transparent;
33
+ }
34
+
35
+ .tokis-btn:focus-visible {
36
+ box-shadow: 0 0 0 3px var(--tokis-color-focus-ring);
37
+ }
38
+
39
+ .tokis-btn:active:not([disabled]):not([aria-disabled="true"]) {
40
+ transform: translateY(1px);
41
+ }
42
+
43
+ .tokis-btn[disabled],
44
+ .tokis-btn[aria-disabled="true"] {
45
+ opacity: 0.45;
46
+ cursor: not-allowed;
47
+ pointer-events: none;
48
+ }
49
+
50
+ /* ── Variants ──────────────────────────────────────────────── */
51
+
52
+ .tokis-btn--primary {
53
+ background: var(--tokis-color-primary);
54
+ color: var(--tokis-text-on-primary);
55
+ border-color: var(--tokis-color-primary);
56
+ }
57
+ .tokis-btn--primary:hover:not([disabled]):not([aria-disabled="true"]) {
58
+ background: var(--tokis-color-primary-hover);
59
+ border-color: var(--tokis-color-primary-hover);
60
+ }
61
+ .tokis-btn--primary:focus-visible {
62
+ box-shadow: 0 0 0 3px var(--tokis-color-focus-ring);
63
+ }
64
+
65
+ .tokis-btn--secondary {
66
+ background: var(--tokis-color-surface-raised);
67
+ color: var(--tokis-text-primary);
68
+ border-color: var(--tokis-color-border);
69
+ box-shadow: var(--tokis-shadow-xs);
70
+ }
71
+ .tokis-btn--secondary:hover:not([disabled]):not([aria-disabled="true"]) {
72
+ background: var(--tokis-color-surface-hover);
73
+ border-color: var(--tokis-color-border-strong);
74
+ }
75
+
76
+ .tokis-btn--ghost {
77
+ background: transparent;
78
+ color: var(--tokis-text-primary);
79
+ border-color: transparent;
80
+ }
81
+ .tokis-btn--ghost:hover:not([disabled]):not([aria-disabled="true"]) {
82
+ background: var(--tokis-color-surface-hover);
83
+ }
84
+
85
+ .tokis-btn--destructive {
86
+ background: var(--tokis-color-error);
87
+ color: var(--tokis-text-inverse);
88
+ border-color: var(--tokis-color-error);
89
+ }
90
+ .tokis-btn--destructive:hover:not([disabled]):not([aria-disabled="true"]) {
91
+ background: color-mix(in srgb, var(--tokis-color-error) 85%, black);
92
+ border-color: color-mix(in srgb, var(--tokis-color-error) 85%, black);
93
+ }
94
+ .tokis-btn--destructive:focus-visible {
95
+ box-shadow: 0 0 0 3px var(--tokis-color-focus-ring-error);
96
+ }
97
+
98
+ .tokis-btn--outline {
99
+ background: transparent;
100
+ color: var(--tokis-color-primary);
101
+ border-color: var(--tokis-color-primary);
102
+ }
103
+ .tokis-btn--outline:hover:not([disabled]):not([aria-disabled="true"]) {
104
+ background: var(--tokis-color-primary-subtle);
105
+ }
106
+
107
+ .tokis-btn--link {
108
+ background: transparent;
109
+ color: var(--tokis-text-link);
110
+ border-color: transparent;
111
+ height: auto;
112
+ padding: 0;
113
+ text-decoration: underline;
114
+ text-decoration-color: transparent;
115
+ text-underline-offset: 3px;
116
+ }
117
+ .tokis-btn--link:hover:not([disabled]):not([aria-disabled="true"]) {
118
+ text-decoration-color: currentColor;
119
+ }
120
+ .tokis-btn--link:focus-visible {
121
+ box-shadow: none;
122
+ text-decoration-color: currentColor;
123
+ outline: 2px solid var(--tokis-color-primary);
124
+ outline-offset: 2px;
125
+ border-radius: var(--tokis-radius-xs);
126
+ }
127
+
128
+ /* ── Sizes ─────────────────────────────────────────────────── */
129
+
130
+ .tokis-btn--sm {
131
+ height: 32px;
132
+ padding: 0 var(--tokis-spacing-3);
133
+ font-size: var(--tokis-font-size-xs);
134
+ border-radius: var(--tokis-radius-sm);
135
+ gap: var(--tokis-spacing-1);
136
+ }
137
+ .tokis-btn--lg {
138
+ height: 48px;
139
+ padding: 0 var(--tokis-spacing-6);
140
+ font-size: var(--tokis-font-size-md);
141
+ border-radius: var(--tokis-radius-lg);
142
+ }
143
+ .tokis-btn--xl {
144
+ height: 56px;
145
+ padding: 0 var(--tokis-spacing-8);
146
+ font-size: var(--tokis-font-size-lg);
147
+ border-radius: var(--tokis-radius-lg);
148
+ }
149
+
150
+ .tokis-btn--icon-only {
151
+ width: 40px;
152
+ padding: 0;
153
+ }
154
+ .tokis-btn--icon-only.tokis-btn--sm { width: 32px; }
155
+ .tokis-btn--icon-only.tokis-btn--lg { width: 48px; }
156
+ .tokis-btn--icon-only.tokis-btn--xl { width: 56px; }
157
+
158
+ .tokis-btn--full { width: 100%; }
159
+ .tokis-btn--loading { pointer-events: none; }
160
+
161
+ .tokis-btn--loading::after {
162
+ content: '';
163
+ position: absolute;
164
+ inset: 0;
165
+ border-radius: inherit;
166
+ background: linear-gradient(90deg, transparent, rgba(255,255,255,0.12), transparent);
167
+ animation: tokis-btn-shimmer 1.2s ease-in-out infinite;
168
+ }
169
+
170
+ @keyframes tokis-btn-shimmer {
171
+ from { transform: translateX(-100%); }
172
+ to { transform: translateX(200%); }
173
+ }
174
+
175
+ /* ── Parts ─────────────────────────────────────────────────── */
176
+
177
+ .tokis-btn__icon {
178
+ flex-shrink: 0;
179
+ display: inline-flex;
180
+ align-items: center;
181
+ justify-content: center;
182
+ }
183
+ .tokis-btn__label { /* inherits from parent */ }
184
+
185
+ /* ── Button Group ───────────────────────────────────────────── */
186
+
187
+ .tokis-btn-group {
188
+ display: inline-flex;
189
+ }
190
+ .tokis-btn-group .tokis-btn {
191
+ border-radius: 0;
192
+ }
193
+ .tokis-btn-group .tokis-btn:first-child {
194
+ border-radius: var(--tokis-radius-md) 0 0 var(--tokis-radius-md);
195
+ }
196
+ .tokis-btn-group .tokis-btn:last-child {
197
+ border-radius: 0 var(--tokis-radius-md) var(--tokis-radius-md) 0;
198
+ }
199
+ .tokis-btn-group .tokis-btn--secondary + .tokis-btn--secondary {
200
+ border-left-color: transparent;
201
+ }
202
+
203
+ /* ── Reduced motion ─────────────────────────────────────────── */
204
+
205
+ @media (prefers-reduced-motion: reduce) {
206
+ .tokis-btn {
207
+ transition: none;
208
+ }
209
+ .tokis-btn:active:not([disabled]):not([aria-disabled="true"]) {
210
+ transform: none;
211
+ }
212
+ .tokis-btn--loading::after { animation: none; }
213
+ }
@@ -0,0 +1,248 @@
1
+ /* ============================================================
2
+ Tokis — Card, Divider, List, Table
3
+ ============================================================ */
4
+
5
+ /* ── Card ───────────────────────────────────────────────────── */
6
+
7
+ .tokis-card {
8
+ background: var(--tokis-color-surface-raised);
9
+ border: 1px solid var(--tokis-color-border);
10
+ border-radius: var(--tokis-radius-xl);
11
+ overflow: hidden;
12
+ display: flex;
13
+ flex-direction: column;
14
+ }
15
+
16
+ .tokis-card--elevated {
17
+ box-shadow: var(--tokis-shadow-md);
18
+ border-color: transparent;
19
+ }
20
+
21
+ .tokis-card--clickable {
22
+ cursor: pointer;
23
+ transition:
24
+ box-shadow var(--tokis-duration-fast) var(--tokis-ease-out),
25
+ transform var(--tokis-duration-fast) var(--tokis-ease-out),
26
+ border-color var(--tokis-duration-fast) var(--tokis-ease-out);
27
+ text-decoration: none;
28
+ color: inherit;
29
+ outline: none;
30
+ }
31
+ .tokis-card--clickable:hover {
32
+ box-shadow: 0 0 0 2px var(--tokis-color-primary-subtle), var(--tokis-shadow-lg);
33
+ transform: translateY(-2px);
34
+ border-color: var(--tokis-color-border-strong);
35
+ }
36
+ .tokis-card--clickable:focus-visible {
37
+ box-shadow: 0 0 0 3px var(--tokis-color-focus-ring);
38
+ outline: none;
39
+ }
40
+ .tokis-card--clickable:active {
41
+ transform: translateY(-1px);
42
+ box-shadow: var(--tokis-shadow-md);
43
+ }
44
+
45
+ .tokis-card--ghost {
46
+ background: transparent;
47
+ border-color: transparent;
48
+ box-shadow: none;
49
+ }
50
+
51
+ .tokis-card-header {
52
+ padding: var(--tokis-spacing-5) var(--tokis-spacing-5) 0;
53
+ }
54
+ .tokis-card-body {
55
+ padding: var(--tokis-spacing-5);
56
+ flex: 1;
57
+ }
58
+ .tokis-card-footer {
59
+ padding: 0 var(--tokis-spacing-5) var(--tokis-spacing-5);
60
+ display: flex;
61
+ gap: var(--tokis-spacing-2);
62
+ align-items: center;
63
+ }
64
+ .tokis-card-footer--border {
65
+ border-top: 1px solid var(--tokis-color-border);
66
+ padding-top: var(--tokis-spacing-4);
67
+ margin-top: var(--tokis-spacing-1);
68
+ }
69
+
70
+ .tokis-card-title {
71
+ font-size: var(--tokis-font-size-lg);
72
+ font-weight: var(--tokis-font-weight-semibold);
73
+ color: var(--tokis-text-primary);
74
+ line-height: var(--tokis-line-height-tight);
75
+ letter-spacing: var(--tokis-letter-spacing-tight);
76
+ margin-bottom: var(--tokis-spacing-1);
77
+ }
78
+ .tokis-card-description {
79
+ font-size: var(--tokis-font-size-sm);
80
+ color: var(--tokis-text-secondary);
81
+ line-height: var(--tokis-line-height-normal);
82
+ }
83
+
84
+ .tokis-card-image {
85
+ width: 100%;
86
+ aspect-ratio: 16/9;
87
+ object-fit: cover;
88
+ display: block;
89
+ }
90
+
91
+ /* ── Divider ────────────────────────────────────────────────── */
92
+
93
+ .tokis-divider {
94
+ border: none;
95
+ border-top: 1px solid var(--tokis-color-border);
96
+ margin: 0;
97
+ flex-shrink: 0;
98
+ }
99
+ .tokis-divider--vertical {
100
+ border-top: none;
101
+ border-left: 1px solid var(--tokis-color-border);
102
+ height: auto;
103
+ align-self: stretch;
104
+ }
105
+ .tokis-divider--with-text {
106
+ display: flex;
107
+ align-items: center;
108
+ gap: var(--tokis-spacing-3);
109
+ border: none;
110
+ }
111
+ .tokis-divider--with-text::before,
112
+ .tokis-divider--with-text::after {
113
+ content: '';
114
+ flex: 1;
115
+ height: 1px;
116
+ background: var(--tokis-color-border);
117
+ }
118
+ .tokis-divider__text {
119
+ font-size: var(--tokis-font-size-xs);
120
+ color: var(--tokis-text-tertiary);
121
+ white-space: nowrap;
122
+ font-weight: var(--tokis-font-weight-medium);
123
+ text-transform: uppercase;
124
+ letter-spacing: var(--tokis-letter-spacing-wide);
125
+ }
126
+
127
+ /* ── List ───────────────────────────────────────────────────── */
128
+
129
+ .tokis-list {
130
+ display: flex;
131
+ flex-direction: column;
132
+ gap: 1px;
133
+ }
134
+
135
+ .tokis-list-item {
136
+ display: flex;
137
+ align-items: center;
138
+ gap: var(--tokis-spacing-3);
139
+ padding: var(--tokis-spacing-3) var(--tokis-spacing-4);
140
+ font-size: var(--tokis-font-size-sm);
141
+ color: var(--tokis-text-primary);
142
+ transition: background var(--tokis-duration-fast) var(--tokis-ease-out);
143
+ border-radius: var(--tokis-radius-md);
144
+ outline: none;
145
+ }
146
+
147
+ .tokis-list-item--clickable {
148
+ cursor: pointer;
149
+ }
150
+ .tokis-list-item--clickable:hover {
151
+ background: var(--tokis-color-surface-hover);
152
+ }
153
+ .tokis-list-item--clickable:focus-visible {
154
+ box-shadow: 0 0 0 2px inset var(--tokis-color-focus-ring);
155
+ background: var(--tokis-color-surface-hover);
156
+ }
157
+ .tokis-list-item--selected {
158
+ background: var(--tokis-color-primary-subtle);
159
+ color: var(--tokis-color-primary);
160
+ }
161
+ .tokis-list-item--selected:hover {
162
+ background: var(--tokis-color-primary-subtle);
163
+ }
164
+
165
+ .tokis-list-item__icon { flex-shrink: 0; color: var(--tokis-text-tertiary); }
166
+ .tokis-list-item__content { flex: 1; min-width: 0; }
167
+ .tokis-list-item__primary {
168
+ font-weight: var(--tokis-font-weight-medium);
169
+ white-space: nowrap;
170
+ overflow: hidden;
171
+ text-overflow: ellipsis;
172
+ }
173
+ .tokis-list-item__secondary {
174
+ font-size: var(--tokis-font-size-xs);
175
+ color: var(--tokis-text-secondary);
176
+ white-space: nowrap;
177
+ overflow: hidden;
178
+ text-overflow: ellipsis;
179
+ margin-top: 1px;
180
+ }
181
+ .tokis-list-item__end { flex-shrink: 0; color: var(--tokis-text-tertiary); }
182
+
183
+ /* ── Table ──────────────────────────────────────────────────── */
184
+
185
+ .tokis-table-container {
186
+ width: 100%;
187
+ overflow-x: auto;
188
+ border: 1px solid var(--tokis-color-border);
189
+ border-radius: var(--tokis-radius-lg);
190
+ scrollbar-width: thin;
191
+ scrollbar-color: var(--tokis-color-border) transparent;
192
+ }
193
+ .tokis-table-container::-webkit-scrollbar { height: 6px; }
194
+ .tokis-table-container::-webkit-scrollbar-track { background: transparent; }
195
+ .tokis-table-container::-webkit-scrollbar-thumb {
196
+ background: var(--tokis-color-border);
197
+ border-radius: var(--tokis-radius-full);
198
+ }
199
+
200
+ .tokis-table {
201
+ width: 100%;
202
+ border-collapse: collapse;
203
+ font-size: var(--tokis-font-size-sm);
204
+ }
205
+
206
+ .tokis-table thead {
207
+ background: var(--tokis-color-neutral-50);
208
+ border-bottom: 1px solid var(--tokis-color-border);
209
+ }
210
+
211
+ .tokis-table th {
212
+ padding: var(--tokis-spacing-3) var(--tokis-spacing-4);
213
+ font-weight: var(--tokis-font-weight-semibold);
214
+ color: var(--tokis-text-secondary);
215
+ text-align: left;
216
+ white-space: nowrap;
217
+ font-size: var(--tokis-font-size-xs);
218
+ text-transform: uppercase;
219
+ letter-spacing: var(--tokis-letter-spacing-wide);
220
+ user-select: none;
221
+ }
222
+
223
+ .tokis-table th[aria-sort] { cursor: pointer; }
224
+ .tokis-table th[aria-sort]:hover { color: var(--tokis-text-primary); }
225
+
226
+ .tokis-table td {
227
+ padding: var(--tokis-spacing-3) var(--tokis-spacing-4);
228
+ color: var(--tokis-text-primary);
229
+ border-bottom: 1px solid var(--tokis-color-border);
230
+ vertical-align: middle;
231
+ }
232
+
233
+ .tokis-table tbody tr:last-child td { border-bottom: none; }
234
+ .tokis-table tbody tr:hover td { background: var(--tokis-color-surface-hover); }
235
+ .tokis-table--striped tbody tr:nth-child(even) td { background: var(--tokis-color-neutral-50); }
236
+ .tokis-table--striped tbody tr:nth-child(even):hover td { background: var(--tokis-color-surface-hover); }
237
+
238
+ /* Row selected state */
239
+ .tokis-table tbody tr[aria-selected="true"] td {
240
+ background: var(--tokis-color-primary-subtle);
241
+ }
242
+
243
+ /* ── Reduced motion ─────────────────────────────────────────── */
244
+
245
+ @media (prefers-reduced-motion: reduce) {
246
+ .tokis-card--clickable { transition: none; }
247
+ .tokis-list-item { transition: none; }
248
+ }
@@ -0,0 +1,38 @@
1
+ /* ── Charts ──────────────────────────────────────────────── */
2
+
3
+ .tokis-chart {
4
+ width: 100%;
5
+ }
6
+
7
+ .tokis-chart svg {
8
+ display: block;
9
+ overflow: visible;
10
+ }
11
+
12
+ .tokis-chart__legend {
13
+ display: flex;
14
+ flex-wrap: wrap;
15
+ gap: var(--tokis-spacing-3);
16
+ padding: var(--tokis-spacing-3) 0 0;
17
+ }
18
+
19
+ .tokis-chart__legend-item {
20
+ display: inline-flex;
21
+ align-items: center;
22
+ gap: var(--tokis-spacing-2);
23
+ font-size: var(--tokis-font-size-xs);
24
+ color: var(--tokis-text-secondary);
25
+ }
26
+
27
+ .tokis-chart__legend-dot {
28
+ width: 10px;
29
+ height: 10px;
30
+ border-radius: 50%;
31
+ flex-shrink: 0;
32
+ }
33
+
34
+ /* Sparkline */
35
+ .tokis-sparkline {
36
+ display: inline-block;
37
+ vertical-align: middle;
38
+ }
@@ -0,0 +1,158 @@
1
+ /* ============================================================
2
+ Tokis — Checkbox & Radio
3
+ ============================================================ */
4
+
5
+ .tokis-checkbox-root,
6
+ .tokis-radio-root {
7
+ display: inline-flex;
8
+ align-items: flex-start;
9
+ gap: var(--tokis-spacing-2);
10
+ cursor: pointer;
11
+ user-select: none;
12
+ }
13
+
14
+ /* ── Native input (visually hidden, accessible) ─────────────── */
15
+
16
+ .tokis-checkbox-native,
17
+ .tokis-radio-native {
18
+ position: absolute;
19
+ width: 1px;
20
+ height: 1px;
21
+ padding: 0;
22
+ margin: -1px;
23
+ overflow: hidden;
24
+ clip: rect(0, 0, 0, 0);
25
+ white-space: nowrap;
26
+ border-width: 0;
27
+ }
28
+
29
+ .tokis-checkbox-root[data-disabled="true"],
30
+ .tokis-radio-root[data-disabled="true"] {
31
+ opacity: 0.45;
32
+ cursor: not-allowed;
33
+ pointer-events: none;
34
+ }
35
+
36
+ /* ── Control ────────────────────────────────────────────────── */
37
+
38
+ .tokis-checkbox-control,
39
+ .tokis-radio-control {
40
+ flex-shrink: 0;
41
+ width: 18px;
42
+ height: 18px;
43
+ border: 1.5px solid var(--tokis-color-border-strong);
44
+ background: var(--tokis-color-surface-raised);
45
+ border-radius: var(--tokis-radius-sm);
46
+ display: flex;
47
+ align-items: center;
48
+ justify-content: center;
49
+ transition:
50
+ background var(--tokis-duration-fast) var(--tokis-ease-out),
51
+ border-color var(--tokis-duration-fast) var(--tokis-ease-out),
52
+ box-shadow var(--tokis-duration-fast) var(--tokis-ease-out);
53
+ position: relative;
54
+ margin-top: 2px;
55
+ outline: none;
56
+ }
57
+
58
+ .tokis-radio-control {
59
+ border-radius: var(--tokis-radius-full);
60
+ }
61
+
62
+ /* Hover — root is now a label element */
63
+ .tokis-checkbox-root:hover:not([data-disabled]) .tokis-checkbox-control:not([data-checked="true"]),
64
+ .tokis-radio-root:hover:not([data-disabled]) .tokis-radio-control:not([data-checked="true"]) {
65
+ border-color: var(--tokis-color-primary);
66
+ background: var(--tokis-color-primary-subtle);
67
+ }
68
+
69
+ /* Checked states */
70
+ .tokis-checkbox-control[data-checked="true"],
71
+ .tokis-checkbox-control[data-indeterminate="true"] {
72
+ background: var(--tokis-color-primary);
73
+ border-color: var(--tokis-color-primary);
74
+ }
75
+
76
+ .tokis-radio-control[data-checked="true"] {
77
+ border-color: var(--tokis-color-primary);
78
+ }
79
+
80
+ /* Focus — triggered by native input focus-visible */
81
+ .tokis-checkbox-native:focus-visible + .tokis-checkbox-control,
82
+ .tokis-radio-native:focus-visible + .tokis-radio-control {
83
+ box-shadow: 0 0 0 3px var(--tokis-color-focus-ring);
84
+ border-color: var(--tokis-color-primary);
85
+ }
86
+
87
+ /* ── Indicators ─────────────────────────────────────────────── */
88
+
89
+ /* Checkmark */
90
+ .tokis-checkbox-control[data-checked="true"]::after {
91
+ content: '';
92
+ display: block;
93
+ width: 5px;
94
+ height: 9px;
95
+ border: 2px solid var(--tokis-text-inverse);
96
+ border-top: none;
97
+ border-left: none;
98
+ transform: rotate(45deg) translateY(-1px);
99
+ }
100
+
101
+ /* Indeterminate */
102
+ .tokis-checkbox-control[data-indeterminate="true"]::after {
103
+ content: '';
104
+ display: block;
105
+ width: 8px;
106
+ height: 2px;
107
+ background: var(--tokis-text-inverse);
108
+ border-radius: var(--tokis-radius-full);
109
+ }
110
+
111
+ /* Radio dot */
112
+ .tokis-radio-control[data-checked="true"]::after {
113
+ content: '';
114
+ display: block;
115
+ width: 8px;
116
+ height: 8px;
117
+ border-radius: var(--tokis-radius-full);
118
+ background: var(--tokis-color-primary);
119
+ }
120
+
121
+ /* ── Labels ─────────────────────────────────────────────────── */
122
+
123
+ .tokis-checkbox-label,
124
+ .tokis-radio-label {
125
+ font-size: var(--tokis-font-size-sm);
126
+ color: var(--tokis-text-primary);
127
+ line-height: 1.5;
128
+ }
129
+
130
+ .tokis-checkbox-description,
131
+ .tokis-radio-description {
132
+ font-size: var(--tokis-font-size-xs);
133
+ color: var(--tokis-text-secondary);
134
+ margin-top: 2px;
135
+ line-height: 1.4;
136
+ }
137
+
138
+ /* ── Radio Group ────────────────────────────────────────────── */
139
+
140
+ .tokis-radio-group {
141
+ display: flex;
142
+ flex-direction: column;
143
+ gap: var(--tokis-spacing-3);
144
+ }
145
+ .tokis-radio-group--horizontal {
146
+ flex-direction: row;
147
+ flex-wrap: wrap;
148
+ gap: var(--tokis-spacing-4);
149
+ }
150
+
151
+ /* ── Reduced motion ─────────────────────────────────────────── */
152
+
153
+ @media (prefers-reduced-motion: reduce) {
154
+ .tokis-checkbox-control,
155
+ .tokis-radio-control {
156
+ transition: none;
157
+ }
158
+ }