@q1travel/design-system 0.17.3 → 0.18.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.
@@ -14,10 +14,10 @@ colors:
14
14
  secondary: "#a0a0a0"
15
15
  tertiary: "#006efe"
16
16
  neutral: "#1a1a1a"
17
- background-100: "#0a0a0a"
17
+ background-100: "#121212"
18
18
  background-200: "#000000"
19
19
  text-primary: "#ededed"
20
- text-secondary: "#a0a0a0"
20
+ text-secondary: "#b4b4b4"
21
21
  text-muted: "#8f8f8f"
22
22
  brand-preview-light-bg: "#ffffff"
23
23
  brand-preview-light-fg: "#171717"
@@ -25,15 +25,16 @@ colors:
25
25
  brand-preview-dark-fg: "#ededed"
26
26
  mask-visible: "#ffffff"
27
27
  mask-opaque: "#000000"
28
+ gray-50: "#161616"
28
29
  gray-100: "#1a1a1a"
29
- gray-200: "#1f1f1f"
30
- gray-300: "#292929"
31
- gray-400: "#2e2e2e"
32
- gray-500: "#454545"
33
- gray-600: "#878787"
34
- gray-700: "#8f8f8f"
35
- gray-800: "#7d7d7d"
36
- gray-900: "#a0a0a0"
30
+ gray-200: "#222222"
31
+ gray-300: "#2b2b2b"
32
+ gray-400: "#333333"
33
+ gray-500: "#585858"
34
+ gray-600: "#7d7d7d"
35
+ gray-700: "#878787"
36
+ gray-800: "#8f8f8f"
37
+ gray-900: "#b4b4b4"
37
38
  gray-1000: "#ededed"
38
39
  primary-100: "#15103a"
39
40
  primary-200: "#1a1547"
@@ -122,28 +123,47 @@ semantic-colors:
122
123
  action-on-primary: "#ffffff"
123
124
  action-text: "{colors.primary-900}"
124
125
  surface-canvas: "{colors.background-100}"
125
- surface-subtle: "{colors.gray-100}"
126
- surface-panel: "{colors.background-100}"
126
+ surface-subtle: "{colors.gray-50}"
127
+ surface-panel: "{colors.gray-100}"
128
+ surface-sunken: "{colors.gray-50}"
129
+ surface-raised: "{colors.gray-200}"
130
+ surface-overlay: "{colors.gray-300}"
131
+ surface-hover: "color-mix(in srgb, var(--q1-color-text-primary) 6%, transparent)"
132
+ surface-selected: "#1f1e38"
133
+ surface-inverse: "{colors.gray-1000}"
134
+ text-on-inverse: "#0a0a0a"
127
135
  surface-media: "#0a0a0a"
128
136
  text-on-media: "#ffffff"
129
- border: "{colors.gray-200}"
137
+ border: "{colors.gray-400}"
130
138
  border-strong: "{colors.gray-400}"
131
- border-subtle: "#1f1f1f"
139
+ border-active: "{colors.primary-900}"
140
+ border-subtle: "#2a2a2a"
132
141
  text-primary: "{colors.text-primary}"
133
142
  text-secondary: "{colors.text-secondary}"
134
143
  text-muted: "{colors.text-muted}"
135
144
  text-soft: "#9a9a9c"
145
+ text-disabled: "{colors.gray-500}"
136
146
  overlay-scrim: "rgba(2, 6, 23, 0.44)"
137
147
  selection-background: "{colors.text-primary}"
138
148
  selection-foreground: "{colors.background-100}"
139
- focus-ring: "{colors.primary}"
140
- focus: "{colors.primary-700}"
149
+ focus-ring: "{colors.primary-900}"
150
+ focus: "{colors.primary-900}"
141
151
  status-success: "{colors.green-900}"
152
+ status-success-text: "{colors.green-900}"
153
+ status-success-surface: "{colors.green-100}"
154
+ status-success-border: "#255a2f"
142
155
  status-warning: "{colors.amber-700}"
156
+ status-warning-text: "#fac053"
157
+ status-warning-surface: "{colors.amber-100}"
158
+ status-warning-border: "#754b10"
143
159
  status-danger: "{colors.red-900}"
144
- status-danger-text: "#ef5350"
160
+ status-danger-text: "#f97770"
145
161
  status-danger-surface: "{colors.red-100}"
146
- status-danger-border: "#ef5350"
162
+ status-danger-border: "#7e2f31"
163
+ status-info: "{colors.blue-900}"
164
+ status-info-text: "{colors.blue-900}"
165
+ status-info-surface: "{colors.blue-100}"
166
+ status-info-border: "#194f81"
147
167
  typography:
148
168
  heading-72:
149
169
  fontFamily: Noto Sans SC
@@ -25,9 +25,10 @@ colors:
25
25
  brand-preview-dark-fg: "#ededed"
26
26
  mask-visible: "#ffffff"
27
27
  mask-opaque: "#000000"
28
+ gray-50: "#fafafa"
28
29
  gray-100: "#f2f2f2"
29
- gray-200: "#ebebeb"
30
- gray-300: "#e6e6e6"
30
+ gray-200: "#eeeeee"
31
+ gray-300: "#ebebeb"
31
32
  gray-400: "#eaeaea"
32
33
  gray-500: "#c9c9c9"
33
34
  gray-600: "#a8a8a8"
@@ -124,26 +125,45 @@ semantic-colors:
124
125
  surface-canvas: "{colors.background-100}"
125
126
  surface-subtle: "{colors.background-200}"
126
127
  surface-panel: "{colors.background-100}"
128
+ surface-sunken: "{colors.background-100}"
129
+ surface-raised: "{colors.background-100}"
130
+ surface-overlay: "{colors.background-100}"
131
+ surface-hover: "color-mix(in srgb, var(--q1-color-text-primary) 4%, transparent)"
132
+ surface-selected: "{colors.primary-100}"
133
+ surface-inverse: "{colors.gray-1000}"
134
+ text-on-inverse: "{colors.background-100}"
127
135
  surface-media: "#0a0a0a"
128
136
  text-on-media: "#ffffff"
129
137
  border: "{colors.gray-400}"
130
138
  border-strong: "{colors.gray-500}"
139
+ border-active: "{colors.primary-700}"
131
140
  border-subtle: "rgba(203, 213, 225, 0.82)"
132
141
  text-primary: "{colors.text-primary}"
133
142
  text-secondary: "{colors.text-secondary}"
134
143
  text-muted: "{colors.text-muted}"
135
144
  text-soft: "#6e6e73"
145
+ text-disabled: "#b7b7b7"
136
146
  overlay-scrim: "rgba(2, 6, 23, 0.44)"
137
147
  selection-background: "{colors.text-primary}"
138
148
  selection-foreground: "{colors.background-100}"
139
149
  focus-ring: "{colors.primary}"
140
150
  focus: "{colors.primary-700}"
141
151
  status-success: "{colors.green-700}"
152
+ status-success-text: "{colors.green-900}"
153
+ status-success-surface: "{colors.green-100}"
154
+ status-success-border: "#a8d9ad"
142
155
  status-warning: "{colors.amber-900}"
156
+ status-warning-text: "{colors.amber-900}"
157
+ status-warning-surface: "{colors.amber-100}"
158
+ status-warning-border: "#edc47d"
143
159
  status-danger: "{colors.red-700}"
144
- status-danger-text: "#d32f2f"
160
+ status-danger-text: "#c62828"
145
161
  status-danger-surface: "{colors.red-100}"
146
- status-danger-border: "#d32f2f"
162
+ status-danger-border: "#f5b9b8"
163
+ status-info: "{colors.blue-700}"
164
+ status-info-text: "#0064b8"
165
+ status-info-surface: "{colors.blue-100}"
166
+ status-info-border: "#abcff0"
147
167
  typography:
148
168
  heading-72:
149
169
  fontFamily: Noto Sans SC
@@ -96,7 +96,9 @@ Examples:
96
96
 
97
97
  `--q1-color-status-danger` is the bright red for fills and strokes only; use `--q1-color-status-danger-text` for text and weak notices without an underline. `--q1-color-status-danger-surface` and `--q1-color-status-danger-border` keep the background and stroke roles separate. `--q1-color-text-soft`, `--q1-color-border-subtle`, and `--q1-color-overlay-scrim` cover tertiary text, quiet separators, and overlay scrims.
98
98
 
99
- `--q1-color-focus` resolves to `--q1-color-primary-700`. `--q1-shadow-focus` draws a 1px canvas contrast ring and a 3px focus color ring, keeping keyboard focus visible against a purple control or dark surface. `--q1-shadow-focus-danger` remains the field family's invalid-control ring and does not change with this focus-ring migration.
99
+ `--q1-color-focus` resolves to `--q1-color-primary-700` in light mode and `--q1-color-primary-900` in dark mode. `--q1-shadow-focus` draws a 2px canvas gap and a 2px focus ring for controls that use a shadow. Button-family controls use a 2px outline with a 2px offset; inputs use `--q1-color-border-active` plus a 1px inset stroke and the gapless translucent `--q1-shadow-focus-input` glow for pointer and keyboard focus. Invalid inputs use `--q1-shadow-focus-input-danger` for a red inset stroke and glow. Text links keep a fine underline at rest, deepen it on hover, and use a 3px focus-color underline for keyboard focus. Forced colors use a system Highlight outline.
100
+
101
+ Migration: `--q1-color-bg-panel` remains `#ffffff` in light mode and changes from `#0a0a0a` to `#1a1a1a` in dark mode. The dark canvas, raised surface, and overlay now use `#121212`, `#222222`, and `#2b2b2b`. Downstream overrides that manually raised panel or overlay backgrounds should be reviewed. `--q1-shadow-focus` keeps a canvas gap and uses a 2px focus ring; input focus adds a 1px inset stroke while preserving the translucent glow. Consumers with custom focus visuals should update their screenshots and forced-colors fallback. The unused `--q1-shadow-card` name is removed before release.
100
102
 
101
103
  ### Component Tokens
102
104
 
@@ -3,9 +3,10 @@
3
3
  /* color-scheme 不在此声明:tokens.css 随包发布,全局副作用交消费方应用掌管(门户侧在 global.css)。 */
4
4
  --q1-color-background-100: #ffffff;
5
5
  --q1-color-background-200: #fafafa;
6
+ --q1-color-gray-50: #fafafa;
6
7
  --q1-color-gray-100: #f2f2f2;
7
- --q1-color-gray-200: #ebebeb;
8
- --q1-color-gray-300: #e6e6e6;
8
+ --q1-color-gray-200: #eeeeee;
9
+ --q1-color-gray-300: #ebebeb;
9
10
  --q1-color-gray-400: #eaeaea;
10
11
  --q1-color-gray-500: #c9c9c9;
11
12
  --q1-color-gray-600: #a8a8a8;
@@ -119,27 +120,45 @@
119
120
  --q1-color-bg-canvas: var(--q1-color-background-100);
120
121
  --q1-color-bg-subtle: var(--q1-color-background-200);
121
122
  --q1-color-bg-panel: var(--q1-color-background-100);
123
+ --q1-color-bg-sunken: var(--q1-color-background-100);
124
+ --q1-color-bg-raised: var(--q1-color-background-100);
125
+ --q1-color-bg-overlay: var(--q1-color-background-100);
126
+ --q1-color-bg-hover: color-mix(in srgb, var(--q1-color-text-primary) 4%, transparent);
127
+ --q1-color-bg-selected: var(--q1-color-primary-100);
128
+ --q1-color-bg-inverse: var(--q1-color-gray-1000);
129
+ --q1-color-text-on-inverse: var(--q1-color-background-100);
122
130
  --q1-color-bg-media: #0a0a0a;
123
131
  --q1-color-text-on-media: #ffffff;
124
132
  --q1-color-border: var(--q1-color-gray-400);
125
133
  --q1-color-border-subtle: rgba(203, 213, 225, 0.82);
126
134
  --q1-color-border-strong: var(--q1-color-gray-500);
135
+ --q1-color-border-active: var(--q1-color-primary-700);
127
136
  --q1-color-text-primary: var(--q1-color-gray-1000);
128
137
  --q1-color-text-secondary: var(--q1-color-gray-900);
129
138
  --q1-color-text-muted: #6b6b6b;
130
139
  --q1-color-text-soft: #6e6e73;
140
+ --q1-color-text-disabled: #b7b7b7;
131
141
  --q1-color-overlay-scrim: rgba(2, 6, 23, 0.44);
132
142
  --q1-color-focus: var(--q1-color-primary-700);
133
143
  --q1-color-selection-bg: var(--q1-color-text-primary);
134
144
  --q1-color-selection-fg: var(--q1-color-bg-canvas);
135
145
  --q1-color-status-success: var(--q1-color-green-700);
146
+ --q1-color-status-success-text: var(--q1-color-green-900);
147
+ --q1-color-status-success-surface: var(--q1-color-green-100);
148
+ --q1-color-status-success-border: #a8d9ad;
136
149
  --q1-color-status-warning: var(--q1-color-amber-900);
150
+ --q1-color-status-warning-text: var(--q1-color-amber-900);
151
+ --q1-color-status-warning-surface: var(--q1-color-amber-100);
152
+ --q1-color-status-warning-border: #edc47d;
137
153
  --q1-color-status-danger: var(--q1-color-red-700);
138
154
  /* status-danger 是亮红,只用于填充和描边;文字或无下划线弱提示使用 danger-text。 */
139
- --q1-color-status-danger-text: #d32f2f;
155
+ --q1-color-status-danger-text: #c62828;
140
156
  --q1-color-status-danger-surface: var(--q1-color-red-100);
141
- --q1-color-status-danger-border: #d32f2f;
157
+ --q1-color-status-danger-border: #f5b9b8;
142
158
  --q1-color-status-info: var(--q1-color-blue-700);
159
+ --q1-color-status-info-text: #0064b8;
160
+ --q1-color-status-info-surface: var(--q1-color-blue-100);
161
+ --q1-color-status-info-border: #abcff0;
143
162
  --q1-font-sans: "Noto Sans SC", "PingFang SC", "Microsoft YaHei UI", sans-serif;
144
163
  --q1-font-mono: "Geist Mono", ui-monospace, "SFMono-Regular", Menlo, Consolas, monospace;
145
164
  --q1-font-weight-regular: 400;
@@ -240,7 +259,9 @@
240
259
  --q1-radius-5: 16px;
241
260
  /* 胶囊:半径大于任何可能的半高即可,具体数值不参与计算。 */
242
261
  --q1-radius-full: 9999px;
243
- --q1-shadow-focus: 0 0 0 1px var(--q1-color-bg-canvas), 0 0 0 3px var(--q1-color-focus);
262
+ --q1-shadow-focus: 0 0 0 2px var(--q1-color-bg-canvas), 0 0 0 4px var(--q1-color-focus);
263
+ --q1-shadow-focus-input: inset 0 0 0 1px var(--q1-color-border-active), 0 0 0 3px color-mix(in srgb, var(--q1-color-focus) 24%, transparent);
264
+ --q1-shadow-focus-input-danger: inset 0 0 0 1px var(--q1-color-status-danger), 0 0 0 3px color-mix(in srgb, var(--q1-color-status-danger) 24%, transparent);
244
265
  /* 危险态环:字段家族错误态与危险动作共用。比默认焦点环宽一档、淡一档——红色本身已经足够响,
245
266
  同样浓度会盖过 1px 红描边。取值沿用字段错误态的既有标定,status-danger 明暗各有取值。 */
246
267
  --q1-shadow-focus-danger: 0 0 0 4px color-mix(in srgb, var(--q1-color-status-danger) 16%, transparent);
@@ -274,17 +295,18 @@
274
295
 
275
296
  :root[data-theme='dark'] {
276
297
  /* 画布抬灰:表面自带浮起感,纯黑仅留给 background-200 底壳。 */
277
- --q1-color-background-100: #0a0a0a;
298
+ --q1-color-background-100: #121212;
278
299
  --q1-color-background-200: #000000;
300
+ --q1-color-gray-50: #161616;
279
301
  --q1-color-gray-100: #1a1a1a;
280
- --q1-color-gray-200: #1f1f1f;
281
- --q1-color-gray-300: #292929;
282
- --q1-color-gray-400: #2e2e2e;
283
- --q1-color-gray-500: #454545;
284
- --q1-color-gray-600: #878787;
285
- --q1-color-gray-700: #8f8f8f;
286
- --q1-color-gray-800: #7d7d7d;
287
- --q1-color-gray-900: #a0a0a0;
302
+ --q1-color-gray-200: #222222;
303
+ --q1-color-gray-300: #2b2b2b;
304
+ --q1-color-gray-400: #333333;
305
+ --q1-color-gray-500: #585858;
306
+ --q1-color-gray-600: #7d7d7d;
307
+ --q1-color-gray-700: #878787;
308
+ --q1-color-gray-800: #8f8f8f;
309
+ --q1-color-gray-900: #b4b4b4;
288
310
  --q1-color-gray-1000: #ededed;
289
311
  /* Dark Primary ramp — interpolated between the dark Blue and Purple ramps
290
312
  (Primary #533afd sits between them in hue), left-dark to right-light to
@@ -377,28 +399,46 @@
377
399
  --q1-color-scale-green: var(--q1-color-green-700);
378
400
  --q1-color-scale-teal: var(--q1-color-teal-700);
379
401
  --q1-color-bg-canvas: var(--q1-color-background-100);
380
- --q1-color-bg-subtle: var(--q1-color-gray-100);
381
- --q1-color-bg-panel: var(--q1-color-background-100);
402
+ --q1-color-bg-subtle: var(--q1-color-gray-50);
403
+ --q1-color-bg-panel: var(--q1-color-gray-100);
404
+ --q1-color-bg-sunken: var(--q1-color-bg-subtle);
405
+ --q1-color-bg-raised: var(--q1-color-gray-200);
406
+ --q1-color-bg-overlay: var(--q1-color-gray-300);
407
+ --q1-color-bg-hover: color-mix(in srgb, var(--q1-color-text-primary) 6%, transparent);
408
+ --q1-color-bg-selected: #1f1e38;
409
+ --q1-color-bg-inverse: var(--q1-color-gray-1000);
410
+ --q1-color-text-on-inverse: #0a0a0a;
382
411
  --q1-color-bg-media: #0a0a0a;
383
412
  --q1-color-text-on-media: #ffffff;
384
- --q1-color-border: var(--q1-color-gray-200);
385
- --q1-color-border-subtle: #1f1f1f;
413
+ --q1-color-border: var(--q1-color-gray-400);
414
+ --q1-color-border-subtle: #2a2a2a;
386
415
  /* 降档:控件描边不再泛白。 */
387
416
  --q1-color-border-strong: var(--q1-color-gray-400);
417
+ --q1-color-border-active: var(--q1-color-primary-900);
388
418
  --q1-color-border-overlay: color-mix(in srgb, #ffffff 14%, transparent);
389
419
  --q1-color-text-primary: var(--q1-color-gray-1000);
390
420
  --q1-color-text-secondary: var(--q1-color-gray-900);
391
- --q1-color-text-muted: var(--q1-color-gray-700);
421
+ --q1-color-text-muted: var(--q1-color-gray-800);
392
422
  --q1-color-text-soft: #9a9a9c;
423
+ --q1-color-text-disabled: var(--q1-color-gray-500);
393
424
  --q1-color-overlay-scrim: rgba(2, 6, 23, 0.44);
394
- --q1-color-focus: var(--q1-color-primary-700);
425
+ --q1-color-focus: var(--q1-color-primary-900);
395
426
  --q1-color-status-success: var(--q1-color-green-900);
427
+ --q1-color-status-success-text: var(--q1-color-green-900);
428
+ --q1-color-status-success-surface: var(--q1-color-green-100);
429
+ --q1-color-status-success-border: #255a2f;
396
430
  --q1-color-status-warning: var(--q1-color-amber-700);
431
+ --q1-color-status-warning-text: #fac053;
432
+ --q1-color-status-warning-surface: var(--q1-color-amber-100);
433
+ --q1-color-status-warning-border: #754b10;
397
434
  --q1-color-status-danger: var(--q1-color-red-900);
398
- --q1-color-status-danger-text: #ef5350;
435
+ --q1-color-status-danger-text: #f97770;
399
436
  --q1-color-status-danger-surface: var(--q1-color-red-100);
400
- --q1-color-status-danger-border: #ef5350;
437
+ --q1-color-status-danger-border: #7e2f31;
401
438
  --q1-color-status-info: var(--q1-color-blue-900);
439
+ --q1-color-status-info-text: var(--q1-color-blue-900);
440
+ --q1-color-status-info-surface: var(--q1-color-blue-100);
441
+ --q1-color-status-info-border: #194f81;
402
442
  /* Override only the press state: the dark Primary ramp runs left-dark to
403
443
  right-light, so Primary-900 is a light tint. Point action-press at a darker
404
444
  step so default -> hover -> press keeps getting darker (hover still
@@ -461,8 +501,9 @@
461
501
  }
462
502
 
463
503
  .button:focus-visible {
464
- outline: none;
465
- box-shadow: var(--q1-shadow-focus);
504
+ outline: 2px solid var(--q1-color-focus);
505
+ outline-offset: 2px;
506
+ box-shadow: none;
466
507
  }
467
508
 
468
509
  .button--primary {
@@ -591,7 +632,7 @@
591
632
  @media (hover: hover) and (pointer: fine) {
592
633
  .button:not(.button--icon):not(.button--selected):not(:disabled):not([aria-disabled='true']):hover {
593
634
  border-color: var(--q1-color-text-secondary);
594
- background: var(--q1-color-bg-subtle);
635
+ background: var(--q1-color-bg-hover);
595
636
  }
596
637
 
597
638
  .button--primary:not(.button--icon):not(.button--selected):not(:disabled):not([aria-disabled='true']):hover {
@@ -848,7 +889,7 @@
848
889
  overflow: hidden;
849
890
  border: 1px solid var(--q1-input-border, var(--q1-color-border-strong));
850
891
  border-radius: var(--q1-radius-2);
851
- background: var(--q1-input-bg, var(--q1-color-bg-panel));
892
+ background: var(--q1-input-bg, var(--q1-color-bg-sunken));
852
893
  font-size: var(--q1-font-size-label-14);
853
894
  }
854
895
 
@@ -858,25 +899,25 @@
858
899
  border-color: var(--q1-color-text-secondary);
859
900
  }
860
901
 
861
- .input-control:focus-within {
862
- border-color: var(--q1-input-border-focus, var(--q1-color-action-primary));
863
- box-shadow: var(--q1-input-focus-ring, var(--q1-shadow-focus));
902
+ .input-control:has(.form-control:focus) {
903
+ border-color: var(--q1-input-border-focus, var(--q1-color-border-active));
904
+ box-shadow: var(--q1-input-focus-ring, var(--q1-shadow-focus-input));
864
905
  }
865
906
 
866
907
  .form-field--error .input-control,
867
908
  .input-control:has(.form-control[aria-invalid='true']) {
868
909
  border-color: var(--q1-color-status-danger);
869
- box-shadow: var(--q1-shadow-focus-danger);
910
+ box-shadow: none;
870
911
  }
871
912
 
872
- .form-field--error .input-control:focus-within,
873
- .input-control:has(.form-control[aria-invalid='true']):focus-within {
913
+ .form-field--error .input-control:has(.form-control:focus),
914
+ .input-control:has(.form-control[aria-invalid='true']:focus) {
874
915
  border-color: var(--q1-color-status-danger);
875
- box-shadow: var(--q1-input-focus-ring, var(--q1-shadow-focus));
916
+ box-shadow: var(--q1-shadow-focus-input-danger);
876
917
  }
877
918
 
878
919
  .input-control:has(.form-control:disabled) {
879
- background: var(--q1-color-bg-subtle);
920
+ background: var(--q1-color-gray-100);
880
921
  }
881
922
 
882
923
  .input-control:has(.form-control:disabled) .input-control__prefix,
@@ -910,7 +951,6 @@
910
951
  }
911
952
 
912
953
  .input-control .form-control:focus,
913
- .input-control .form-control:focus-visible,
914
954
  .form-field--error .input-control .form-control,
915
955
  .input-control .form-control[aria-invalid='true'] {
916
956
  box-shadow: none;
@@ -920,7 +960,7 @@
920
960
  background: transparent;
921
961
  }
922
962
 
923
- /* 前后缀默认带灰块底色 + 朝向 input 一侧的 1px 分隔线;禁用态下外框同为 bg-subtle,块与外框同色成扁平、仅剩分隔线,属本品牌层取舍。 */
963
+ /* 前后缀默认带灰块底色 + 朝向 input 一侧的 1px 分隔线;禁用态下外框改用 gray-100,前后缀块保持分隔线,属本品牌层取舍。 */
924
964
  .input-control__prefix {
925
965
  flex: none;
926
966
  display: inline-flex;
@@ -1048,7 +1088,7 @@
1048
1088
  min-height: 40px;
1049
1089
  border: 1px solid var(--q1-input-border, var(--q1-color-border-strong));
1050
1090
  border-radius: var(--q1-radius-2);
1051
- background: var(--q1-input-bg, var(--q1-color-bg-panel));
1091
+ background: var(--q1-input-bg, var(--q1-color-bg-sunken));
1052
1092
  color: var(--q1-input-fg, var(--q1-color-text-primary));
1053
1093
  font: inherit;
1054
1094
  font-size: var(--q1-font-size-label-14);
@@ -1139,26 +1179,32 @@
1139
1179
  overflow: hidden;
1140
1180
  border: 1px solid var(--q1-color-border-strong);
1141
1181
  border-radius: var(--q1-radius-2);
1142
- background: var(--q1-color-bg-panel);
1182
+ background: var(--q1-color-bg-sunken);
1143
1183
  }
1144
1184
 
1145
1185
  .textarea-control:hover:not(:has(.form-control:disabled)) {
1146
1186
  border-color: var(--q1-color-text-secondary);
1147
1187
  }
1148
1188
 
1149
- .textarea-control:focus-within {
1150
- border-color: var(--q1-color-action-primary);
1151
- box-shadow: var(--q1-shadow-focus);
1189
+ .textarea-control:has(.form-control:focus) {
1190
+ border-color: var(--q1-color-border-active);
1191
+ box-shadow: var(--q1-shadow-focus-input);
1152
1192
  }
1153
1193
 
1154
1194
  .form-field--error .textarea-control,
1155
1195
  .textarea-control:has(.form-control[aria-invalid='true']) {
1156
1196
  border-color: var(--q1-color-status-danger);
1157
- box-shadow: var(--q1-shadow-focus-danger);
1197
+ box-shadow: none;
1198
+ }
1199
+
1200
+ .form-field--error .textarea-control:has(.form-control:focus),
1201
+ .textarea-control:has(.form-control[aria-invalid='true']:focus) {
1202
+ border-color: var(--q1-color-status-danger);
1203
+ box-shadow: var(--q1-shadow-focus-input-danger);
1158
1204
  }
1159
1205
 
1160
1206
  .textarea-control:has(.form-control:disabled) {
1161
- background: var(--q1-color-bg-subtle);
1207
+ background: var(--q1-color-gray-100);
1162
1208
  }
1163
1209
 
1164
1210
  /* 尺寸档圆角随内部控件对齐(同 input-control 的 :has 尺寸档规则)。 */
@@ -1177,7 +1223,6 @@
1177
1223
  }
1178
1224
 
1179
1225
  .textarea-control .form-control:focus,
1180
- .textarea-control .form-control:focus-visible,
1181
1226
  .form-field--error .textarea-control .form-control,
1182
1227
  .textarea-control .form-control[aria-invalid='true'] {
1183
1228
  box-shadow: none;
@@ -1211,37 +1256,31 @@
1211
1256
  border-color: var(--q1-color-text-secondary);
1212
1257
  }
1213
1258
 
1214
- /* 焦点态自带 `outline: none`(见 .form-control 基类),消费方**不需要**再写一遍——
1215
- 实测那 18 处焦点环覆写全都多写了这一行,因为从调用点看不到组件内部已经处理过。
1216
- 文本输入用 :focus 与 :focus-visible 行为一致:规范规定文本输入获焦时 :focus-visible
1217
- 无条件匹配,焦点环在点击时也该出现,否则用户不知道自己在往哪儿打字。 */
1259
+ /* 输入类指针与键盘焦点一致,边框与半透明光晕紧贴。 */
1218
1260
  .form-control:focus,
1219
- .form-control:focus-visible,
1220
1261
  .q1-verification-code:has(input:focus-visible) .q1-verification-code__slot[data-active] {
1221
- border-color: var(--q1-input-border-focus, var(--q1-color-action-primary));
1222
- box-shadow: var(--q1-input-focus-ring, var(--q1-shadow-focus));
1262
+ border-color: var(--q1-input-border-focus, var(--q1-color-border-active));
1263
+ box-shadow: var(--q1-input-focus-ring, var(--q1-shadow-focus-input));
1223
1264
  }
1224
1265
 
1225
- /* 错误态:纯红 1px 环 + 红 16% 的 4px 外晕,字段家族共享。 */
1266
+ /* 静止错误态保留红边,聚焦时加红色内描边与光晕。 */
1226
1267
  .form-field--error .form-control,
1227
1268
  .form-control[aria-invalid='true'],
1228
1269
  .q1-verification-code:has(input[aria-invalid='true']) .q1-verification-code__slot {
1229
1270
  border-color: var(--q1-color-status-danger);
1230
- box-shadow: var(--q1-shadow-focus-danger);
1271
+ box-shadow: none;
1231
1272
  }
1232
1273
 
1233
1274
  .form-field--error > .form-control--input:focus,
1234
- .form-field--error > .form-control--input:focus-visible,
1235
- .form-control--input[aria-invalid='true']:not(.input-control .form-control):focus,
1236
- .form-control--input[aria-invalid='true']:not(.input-control .form-control):focus-visible {
1275
+ .form-control--input[aria-invalid='true']:not(.input-control .form-control):focus {
1237
1276
  border-color: var(--q1-color-status-danger);
1238
- box-shadow: var(--q1-input-focus-ring, var(--q1-shadow-focus));
1277
+ box-shadow: var(--q1-shadow-focus-input-danger);
1239
1278
  }
1240
1279
 
1241
1280
  /* 禁用态:底色抬灰而非降透明度;opacity:1 归零 Chrome UA 对禁用控件的默认 0.7。 */
1242
1281
  .q1-verification-code:has(input:disabled) .q1-verification-code__slot,
1243
1282
  .form-control:disabled {
1244
- background: var(--q1-color-bg-subtle);
1283
+ background: var(--q1-color-gray-100);
1245
1284
  color: var(--q1-color-text-muted);
1246
1285
  cursor: not-allowed;
1247
1286
  opacity: 1;
@@ -1620,7 +1659,7 @@
1620
1659
  padding: var(--q1-space-2);
1621
1660
  border: 1px solid var(--q1-color-border-overlay);
1622
1661
  border-radius: var(--q1-radius-4);
1623
- background: var(--q1-color-bg-panel);
1662
+ background: var(--q1-color-bg-overlay);
1624
1663
  box-shadow: var(--q1-shadow-popover);
1625
1664
  }
1626
1665
  .menu__popup[data-state] {
@@ -1693,7 +1732,7 @@
1693
1732
  .menu__item:hover:not([aria-disabled='true']),
1694
1733
  .menu__item:focus-visible {
1695
1734
  outline: none;
1696
- background: color-mix(in srgb, var(--q1-color-text-primary) 6%, transparent);
1735
+ background: var(--q1-color-bg-hover);
1697
1736
  }
1698
1737
  .menu__item[aria-disabled='true'],
1699
1738
  .menu__item--locked {
@@ -3456,11 +3495,11 @@ a[href]:has(> .book):focus-visible {
3456
3495
  color: var(--q1-color-text-muted);
3457
3496
  }
3458
3497
 
3459
- /* 错误边框保留校验含义,键盘焦点另用共享 focus token 表达当前位置。 */
3460
- .form-field--error .select-control .form-control--select:focus-visible,
3461
- .select-control .form-control--select[aria-invalid='true']:focus-visible {
3498
+ /* 错误边框保留校验含义,焦点再加同色内描边与光晕。 */
3499
+ .form-field--error .select-control .form-control--select:focus,
3500
+ .select-control .form-control--select[aria-invalid='true']:focus {
3462
3501
  border-color: var(--q1-color-status-danger);
3463
- box-shadow: var(--q1-input-focus-ring, var(--q1-shadow-focus));
3502
+ box-shadow: var(--q1-shadow-focus-input-danger);
3464
3503
  }
3465
3504
 
3466
3505
  .select-control--prefixed .form-control {
@@ -3918,7 +3957,7 @@ a[href]:has(> .book):focus-visible {
3918
3957
  padding: var(--q1-space-4);
3919
3958
  border: 1px solid var(--q1-color-border-overlay);
3920
3959
  border-radius: var(--q1-radius-3);
3921
- background: var(--q1-color-bg-panel);
3960
+ background: var(--q1-color-bg-overlay);
3922
3961
  box-shadow: var(--q1-shadow-popover);
3923
3962
  }
3924
3963
 
@@ -4180,7 +4219,7 @@ a[href]:has(> .book):focus-visible {
4180
4219
  min-width: 380px;
4181
4220
  border: 1px solid var(--q1-color-border-overlay);
4182
4221
  border-radius: var(--q1-radius-3);
4183
- background: var(--q1-color-bg-panel);
4222
+ background: var(--q1-color-bg-overlay);
4184
4223
  box-shadow: var(--q1-shadow-popover);
4185
4224
  overflow: hidden;
4186
4225
  }
@@ -5346,7 +5385,7 @@ a.context-card__trigger {
5346
5385
  padding: var(--q1-space-3) var(--q1-space-4);
5347
5386
  border: 1px solid var(--q1-color-border-overlay);
5348
5387
  border-radius: var(--q1-radius-2);
5349
- background: var(--q1-color-bg-panel);
5388
+ background: var(--q1-color-bg-overlay);
5350
5389
  box-shadow: var(--q1-shadow-popover);
5351
5390
  opacity: 0;
5352
5391
  visibility: hidden;
@@ -5572,7 +5611,7 @@ a.context-card__trigger {
5572
5611
  /* 浮层家族规则:发丝边框 + 恒黑阴影(此前用 mask-opaque 混色躲过了阴影清扫)。 */
5573
5612
  border: 1px solid var(--q1-color-border-overlay);
5574
5613
  border-radius: var(--q1-radius-2);
5575
- background: var(--q1-color-bg-panel);
5614
+ background: var(--q1-color-bg-overlay);
5576
5615
  box-shadow: var(--q1-shadow-popover);
5577
5616
  opacity: 0;
5578
5617
  visibility: hidden;
@@ -6274,7 +6313,7 @@ a.q1-card:focus-visible {
6274
6313
  }
6275
6314
 
6276
6315
  .show-more__trigger[data-pointer-pressed='true'] {
6277
- background: var(--q1-color-bg-subtle);
6316
+ background: var(--q1-color-bg-hover);
6278
6317
  border-color: var(--q1-color-border-strong);
6279
6318
  color: var(--q1-color-text-primary);
6280
6319
  opacity: 0.96;
@@ -6394,8 +6433,8 @@ a.q1-card:focus-visible {
6394
6433
  background-color: color-mix(in srgb, var(--q1-color-text-primary) 8%, transparent);
6395
6434
  }
6396
6435
  .collapse__trigger:focus-visible {
6397
- outline: none;
6398
- box-shadow: inset 0 0 0 1px var(--q1-color-bg-canvas), inset 0 0 0 3px var(--q1-color-focus);
6436
+ outline: 2px solid var(--q1-color-focus);
6437
+ outline-offset: 2px;
6399
6438
  }
6400
6439
  .collapse__title {
6401
6440
  font-size: 14px;
@@ -7853,8 +7892,9 @@ a.q1-card:focus-visible {
7853
7892
  }
7854
7893
  .split-button__primary:focus-visible,
7855
7894
  .split-button__toggle:focus-visible {
7856
- outline: none;
7857
- box-shadow: var(--q1-shadow-focus);
7895
+ outline: 2px solid var(--q1-color-focus);
7896
+ outline-offset: 2px;
7897
+ box-shadow: none;
7858
7898
  z-index: 1;
7859
7899
  }
7860
7900
  .split-button__icon {
@@ -8030,7 +8070,7 @@ a.q1-card:focus-visible {
8030
8070
  padding: 0 var(--q1-space-3);
8031
8071
  border: 1px solid var(--q1-color-border-strong);
8032
8072
  border-radius: var(--q1-radius-2);
8033
- background: var(--q1-color-bg-panel);
8073
+ background: var(--q1-color-bg-sunken);
8034
8074
  }
8035
8075
 
8036
8076
  .combobox--sm .combobox__control {
@@ -8047,18 +8087,21 @@ a.q1-card:focus-visible {
8047
8087
  font-size: var(--q1-font-size-copy-16);
8048
8088
  line-height: var(--q1-line-height-copy-16);
8049
8089
  }
8050
- .combobox__control:focus-within {
8051
- border-color: var(--q1-color-action-primary);
8052
- box-shadow: var(--q1-shadow-focus);
8090
+ .combobox__control:has(.combobox__input:focus) {
8091
+ border-color: var(--q1-color-border-active);
8092
+ box-shadow: var(--q1-shadow-focus-input);
8053
8093
  }
8054
8094
  .combobox--error .combobox__control {
8055
- border-color: var(--q1-color-red-700);
8095
+ border-color: var(--q1-color-status-danger);
8056
8096
  }
8057
- .combobox--error .combobox__control:focus-within {
8058
- box-shadow: 0 0 0 3px color-mix(in srgb, var(--q1-color-red-700) 24%, transparent);
8097
+ .combobox--error .combobox__control:has(.combobox__input:focus) {
8098
+ border-color: var(--q1-color-status-danger);
8099
+ box-shadow: var(--q1-shadow-focus-input-danger);
8059
8100
  }
8060
8101
  .combobox--disabled .combobox__control {
8061
- opacity: 0.55;
8102
+ background: var(--q1-color-gray-100);
8103
+ color: var(--q1-color-text-disabled);
8104
+ opacity: 1;
8062
8105
  }
8063
8106
  .combobox--readonly .combobox__input {
8064
8107
  caret-color: transparent;
@@ -8111,7 +8154,7 @@ a.q1-card:focus-visible {
8111
8154
  list-style: none;
8112
8155
  border: 1px solid var(--q1-color-border-overlay);
8113
8156
  border-radius: var(--q1-radius-3);
8114
- background: var(--q1-color-bg-panel);
8157
+ background: var(--q1-color-bg-overlay);
8115
8158
  box-shadow: var(--q1-shadow-popover);
8116
8159
  }
8117
8160
  .combobox__listbox {
@@ -8208,16 +8251,22 @@ a.q1-card:focus-visible {
8208
8251
  padding: var(--q1-space-2) var(--q1-space-3);
8209
8252
  border: 1px solid var(--q1-color-border-strong);
8210
8253
  border-radius: var(--q1-radius-2);
8211
- background: var(--q1-color-bg-panel);
8254
+ background: var(--q1-color-bg-sunken);
8212
8255
  color: var(--q1-color-text-primary);
8213
8256
  font: inherit;
8214
8257
  font-size: 14px;
8215
8258
  font-weight: 500;
8216
8259
  cursor: pointer;
8217
8260
  }
8218
- .multi-select__trigger:focus-visible {
8261
+ .multi-select__trigger:focus {
8219
8262
  outline: none;
8220
- box-shadow: var(--q1-shadow-focus);
8263
+ border-color: var(--q1-color-border-active);
8264
+ box-shadow: var(--q1-shadow-focus-input);
8265
+ }
8266
+ .multi-select__trigger:disabled {
8267
+ background: var(--q1-color-gray-100);
8268
+ color: var(--q1-color-text-disabled);
8269
+ opacity: 1;
8221
8270
  }
8222
8271
  .multi-select__placeholder {
8223
8272
  color: var(--q1-color-text-secondary);
@@ -8229,7 +8278,7 @@ a.q1-card:focus-visible {
8229
8278
  padding: var(--q1-space-2);
8230
8279
  border: 1px solid var(--q1-color-border-overlay);
8231
8280
  border-radius: var(--q1-radius-4);
8232
- background: var(--q1-color-bg-panel);
8281
+ background: var(--q1-color-bg-overlay);
8233
8282
  box-shadow: var(--q1-shadow-popover);
8234
8283
  }
8235
8284
  .multi-select__bulk {
@@ -8401,7 +8450,7 @@ a.q1-card:focus-visible {
8401
8450
  overflow: hidden;
8402
8451
  border: 1px solid var(--q1-color-border-overlay);
8403
8452
  border-radius: var(--q1-radius-4);
8404
- background: var(--q1-color-bg-panel);
8453
+ background: var(--q1-color-bg-raised);
8405
8454
  box-shadow: var(--q1-shadow-modal);
8406
8455
  }
8407
8456
  .search-dialog__search {
@@ -8677,7 +8726,7 @@ a.q1-card:focus-visible {
8677
8726
  max-width: 540px;
8678
8727
  border: 1px solid var(--q1-color-border-overlay);
8679
8728
  border-radius: var(--q1-radius-4);
8680
- background: var(--q1-color-bg-panel);
8729
+ background: var(--q1-color-bg-raised);
8681
8730
  box-shadow: var(--q1-shadow-modal);
8682
8731
  }
8683
8732
  .modal__header {
@@ -8857,7 +8906,7 @@ a.q1-card:focus-visible {
8857
8906
  border: 1px solid var(--q1-color-border-overlay);
8858
8907
  border-bottom: 0;
8859
8908
  border-radius: var(--q1-radius-4) var(--q1-radius-4) 0 0;
8860
- background: var(--q1-color-bg-panel);
8909
+ background: var(--q1-color-bg-raised);
8861
8910
  /* 方向性面板自持阴影(不走 --q1-shadow-popover/modal,两者的偏移都朝下)。
8862
8911
  两层同向朝上:接触层交代面板压在页面底边,环境层交代它离底面多高。 */
8863
8912
  box-shadow:
@@ -9002,7 +9051,7 @@ a.q1-card:focus-visible {
9002
9051
  flex-direction: column;
9003
9052
  border: 1px solid var(--q1-color-border-overlay);
9004
9053
  border-radius: var(--q1-radius-4);
9005
- background: var(--q1-color-bg-panel);
9054
+ background: var(--q1-color-bg-raised);
9006
9055
  /* 方向性面板自持阴影,理由同 Drawer。接触层不带方向:Sheet 四个方向共用此规则,
9007
9056
  带方向的接触层在 top 档会朝错边。 */
9008
9057
  box-shadow:
@@ -9982,7 +10031,7 @@ a.q1-navigation__item[aria-disabled='true'] {
9982
10031
  overflow: hidden;
9983
10032
  border: 1px solid var(--q1-color-border-overlay);
9984
10033
  border-radius: var(--q1-radius-3);
9985
- background: var(--q1-color-bg-panel);
10034
+ background: var(--q1-color-bg-overlay);
9986
10035
  color: var(--q1-color-text-primary);
9987
10036
  box-shadow: var(--q1-shadow-popover);
9988
10037
  }
@@ -10768,6 +10817,7 @@ a.q1-navigation__item[aria-disabled='true'] {
10768
10817
  color: var(--q1-color-action-text);
10769
10818
  text-decoration: underline;
10770
10819
  text-decoration-thickness: 1px;
10820
+ text-decoration-color: color-mix(in srgb, currentColor 55%, transparent);
10771
10821
  text-underline-offset: 0.2em;
10772
10822
  text-decoration-skip-ink: auto;
10773
10823
  border-radius: var(--q1-radius-1);
@@ -10781,11 +10831,17 @@ a.q1-navigation__item[aria-disabled='true'] {
10781
10831
 
10782
10832
  .q1-link:hover {
10783
10833
  color: var(--q1-color-text-primary);
10834
+ text-decoration-thickness: 2px;
10835
+ text-decoration-color: currentColor;
10784
10836
  }
10785
10837
 
10786
10838
  .q1-link:focus-visible {
10787
- outline: 2px solid currentColor;
10788
- outline-offset: 2px;
10839
+ outline: none;
10840
+ color: var(--q1-color-text-primary);
10841
+ text-decoration-thickness: 3px;
10842
+ text-decoration-color: var(--q1-color-focus);
10843
+ text-underline-offset: 0.25em;
10844
+ transition: none;
10789
10845
  }
10790
10846
 
10791
10847
  /* muted:正文密度很高、链接很多的段落里,主色会把整段打成一片蓝。
@@ -10803,6 +10859,38 @@ a.q1-navigation__item[aria-disabled='true'] {
10803
10859
  text-decoration-thickness: 2px;
10804
10860
  }
10805
10861
 
10862
+ @media (forced-colors: active) {
10863
+ :focus-visible,
10864
+ .control-option:has(input:focus-visible) .control-option__visual,
10865
+ .theme-switcher__option:has(input:focus-visible),
10866
+ .radio-headless-card:has(input:focus-visible) {
10867
+ outline: 2px solid Highlight;
10868
+ outline-offset: 2px;
10869
+ }
10870
+
10871
+ .form-control:focus,
10872
+ .input-control:has(.form-control:focus),
10873
+ .textarea-control:has(.form-control:focus),
10874
+ .combobox__control:has(.combobox__input:focus),
10875
+ .multi-select__trigger:focus,
10876
+ .cal-period__trigger:focus,
10877
+ .q1-verification-code:has(input:focus) {
10878
+ outline: 2px solid Highlight;
10879
+ outline-offset: 0;
10880
+ }
10881
+
10882
+ .input-control .form-control:focus,
10883
+ .textarea-control .form-control:focus,
10884
+ .combobox__input:focus {
10885
+ outline: none;
10886
+ }
10887
+
10888
+ .q1-link:focus-visible {
10889
+ outline: 2px solid Highlight;
10890
+ outline-offset: 2px;
10891
+ }
10892
+ }
10893
+
10806
10894
  /* 无 href 的静态文本:不是链接,因此不给链接色也不给下划线,避免看起来能点。 */
10807
10895
  .q1-link--static {
10808
10896
  color: var(--q1-color-text-secondary);
@@ -10970,12 +11058,17 @@ a.q1-navigation__item[aria-disabled='true'] {
10970
11058
  .cal-field__clear:focus-visible,
10971
11059
  .cal-field__caret:focus-visible,
10972
11060
  .cal-inputs__apply:focus-visible,
10973
- .cal-period__trigger:focus-visible,
10974
11061
  .cal-period__option:focus-visible {
10975
11062
  outline: none;
10976
11063
  box-shadow: var(--q1-shadow-focus);
10977
11064
  }
10978
11065
 
11066
+ .cal-period__trigger:focus {
11067
+ outline: none;
11068
+ border-color: var(--q1-color-border-active);
11069
+ box-shadow: var(--q1-shadow-focus-input);
11070
+ }
11071
+
10979
11072
  .calendar__nav-btn:disabled,
10980
11073
  .calendar__nav-btn:disabled:hover {
10981
11074
  background: transparent;
@@ -1,9 +1,10 @@
1
1
  :root {
2
2
  --q1-color-background-100: #ffffff;
3
3
  --q1-color-background-200: #fafafa;
4
+ --q1-color-gray-50: #fafafa;
4
5
  --q1-color-gray-100: #f2f2f2;
5
- --q1-color-gray-200: #ebebeb;
6
- --q1-color-gray-300: #e6e6e6;
6
+ --q1-color-gray-200: #eeeeee;
7
+ --q1-color-gray-300: #ebebeb;
7
8
  --q1-color-gray-400: #eaeaea;
8
9
  --q1-color-gray-500: #c9c9c9;
9
10
  --q1-color-gray-600: #a8a8a8;
@@ -115,26 +116,44 @@
115
116
  --q1-color-bg-canvas: var(--q1-color-background-100);
116
117
  --q1-color-bg-subtle: var(--q1-color-background-200);
117
118
  --q1-color-bg-panel: var(--q1-color-background-100);
119
+ --q1-color-bg-sunken: var(--q1-color-background-100);
120
+ --q1-color-bg-raised: var(--q1-color-background-100);
121
+ --q1-color-bg-overlay: var(--q1-color-background-100);
122
+ --q1-color-bg-hover: color-mix(in srgb, var(--q1-color-text-primary) 4%, transparent);
123
+ --q1-color-bg-selected: var(--q1-color-primary-100);
124
+ --q1-color-bg-inverse: var(--q1-color-gray-1000);
125
+ --q1-color-text-on-inverse: var(--q1-color-background-100);
118
126
  --q1-color-bg-media: #0a0a0a;
119
127
  --q1-color-text-on-media: #ffffff;
120
128
  --q1-color-border: var(--q1-color-gray-400);
121
129
  --q1-color-border-subtle: rgba(203, 213, 225, 0.82);
122
130
  --q1-color-border-strong: var(--q1-color-gray-500);
131
+ --q1-color-border-active: var(--q1-color-primary-700);
123
132
  --q1-color-text-primary: var(--q1-color-gray-1000);
124
133
  --q1-color-text-secondary: var(--q1-color-gray-900);
125
134
  --q1-color-text-muted: #6b6b6b;
126
135
  --q1-color-text-soft: #6e6e73;
136
+ --q1-color-text-disabled: #b7b7b7;
127
137
  --q1-color-overlay-scrim: rgba(2, 6, 23, 0.44);
128
138
  --q1-color-focus: var(--q1-color-primary-700);
129
139
  --q1-color-selection-bg: var(--q1-color-text-primary);
130
140
  --q1-color-selection-fg: var(--q1-color-bg-canvas);
131
141
  --q1-color-status-success: var(--q1-color-green-700);
142
+ --q1-color-status-success-text: var(--q1-color-green-900);
143
+ --q1-color-status-success-surface: var(--q1-color-green-100);
144
+ --q1-color-status-success-border: #a8d9ad;
132
145
  --q1-color-status-warning: var(--q1-color-amber-900);
146
+ --q1-color-status-warning-text: var(--q1-color-amber-900);
147
+ --q1-color-status-warning-surface: var(--q1-color-amber-100);
148
+ --q1-color-status-warning-border: #edc47d;
133
149
  --q1-color-status-danger: var(--q1-color-red-700);
134
- --q1-color-status-danger-text: #d32f2f;
150
+ --q1-color-status-danger-text: #c62828;
135
151
  --q1-color-status-danger-surface: var(--q1-color-red-100);
136
- --q1-color-status-danger-border: #d32f2f;
152
+ --q1-color-status-danger-border: #f5b9b8;
137
153
  --q1-color-status-info: var(--q1-color-blue-700);
154
+ --q1-color-status-info-text: #0064b8;
155
+ --q1-color-status-info-surface: var(--q1-color-blue-100);
156
+ --q1-color-status-info-border: #abcff0;
138
157
  --q1-font-sans: "Noto Sans SC", "PingFang SC", "Microsoft YaHei UI", sans-serif;
139
158
  --q1-font-mono: "Geist Mono", ui-monospace, "SFMono-Regular", Menlo, Consolas, monospace;
140
159
  --q1-font-weight-regular: 400;
@@ -227,7 +246,9 @@
227
246
  --q1-radius-4: 12px;
228
247
  --q1-radius-5: 16px;
229
248
  --q1-radius-full: 9999px;
230
- --q1-shadow-focus: 0 0 0 1px var(--q1-color-bg-canvas), 0 0 0 3px var(--q1-color-focus);
249
+ --q1-shadow-focus: 0 0 0 2px var(--q1-color-bg-canvas), 0 0 0 4px var(--q1-color-focus);
250
+ --q1-shadow-focus-input: inset 0 0 0 1px var(--q1-color-border-active), 0 0 0 3px color-mix(in srgb, var(--q1-color-focus) 24%, transparent);
251
+ --q1-shadow-focus-input-danger: inset 0 0 0 1px var(--q1-color-status-danger), 0 0 0 3px color-mix(in srgb, var(--q1-color-status-danger) 24%, transparent);
231
252
  --q1-shadow-focus-danger: 0 0 0 4px color-mix(in srgb, var(--q1-color-status-danger) 16%, transparent);
232
253
  --q1-shadow-popover: 0 1px 3px color-mix(in srgb, var(--q1-color-shadow) 10%, transparent),
233
254
  0 8px 28px color-mix(in srgb, var(--q1-color-shadow) 14%, transparent);
@@ -246,17 +267,18 @@
246
267
  }
247
268
 
248
269
  :root[data-theme='dark'] {
249
- --q1-color-background-100: #0a0a0a;
270
+ --q1-color-background-100: #121212;
250
271
  --q1-color-background-200: #000000;
272
+ --q1-color-gray-50: #161616;
251
273
  --q1-color-gray-100: #1a1a1a;
252
- --q1-color-gray-200: #1f1f1f;
253
- --q1-color-gray-300: #292929;
254
- --q1-color-gray-400: #2e2e2e;
255
- --q1-color-gray-500: #454545;
256
- --q1-color-gray-600: #878787;
257
- --q1-color-gray-700: #8f8f8f;
258
- --q1-color-gray-800: #7d7d7d;
259
- --q1-color-gray-900: #a0a0a0;
274
+ --q1-color-gray-200: #222222;
275
+ --q1-color-gray-300: #2b2b2b;
276
+ --q1-color-gray-400: #333333;
277
+ --q1-color-gray-500: #585858;
278
+ --q1-color-gray-600: #7d7d7d;
279
+ --q1-color-gray-700: #878787;
280
+ --q1-color-gray-800: #8f8f8f;
281
+ --q1-color-gray-900: #b4b4b4;
260
282
  --q1-color-gray-1000: #ededed;
261
283
  --q1-color-primary-100: #15103a;
262
284
  --q1-color-primary-200: #1a1547;
@@ -360,28 +382,46 @@
360
382
  --q1-color-shadow: #000000;
361
383
  --q1-color-border-overlay: color-mix(in srgb, #ffffff 14%, transparent);
362
384
  --q1-color-bg-canvas: var(--q1-color-background-100);
363
- --q1-color-bg-subtle: var(--q1-color-gray-100);
364
- --q1-color-bg-panel: var(--q1-color-background-100);
385
+ --q1-color-bg-subtle: var(--q1-color-gray-50);
386
+ --q1-color-bg-panel: var(--q1-color-gray-100);
387
+ --q1-color-bg-sunken: var(--q1-color-bg-subtle);
388
+ --q1-color-bg-raised: var(--q1-color-gray-200);
389
+ --q1-color-bg-overlay: var(--q1-color-gray-300);
390
+ --q1-color-bg-hover: color-mix(in srgb, var(--q1-color-text-primary) 6%, transparent);
391
+ --q1-color-bg-selected: #1f1e38;
392
+ --q1-color-bg-inverse: var(--q1-color-gray-1000);
393
+ --q1-color-text-on-inverse: #0a0a0a;
365
394
  --q1-color-bg-media: #0a0a0a;
366
395
  --q1-color-text-on-media: #ffffff;
367
- --q1-color-border: var(--q1-color-gray-200);
368
- --q1-color-border-subtle: #1f1f1f;
396
+ --q1-color-border: var(--q1-color-gray-400);
397
+ --q1-color-border-subtle: #2a2a2a;
369
398
  --q1-color-border-strong: var(--q1-color-gray-400);
399
+ --q1-color-border-active: var(--q1-color-primary-900);
370
400
  --q1-color-text-primary: var(--q1-color-gray-1000);
371
401
  --q1-color-text-secondary: var(--q1-color-gray-900);
372
- --q1-color-text-muted: var(--q1-color-gray-700);
402
+ --q1-color-text-muted: var(--q1-color-gray-800);
373
403
  --q1-color-text-soft: #9a9a9c;
404
+ --q1-color-text-disabled: var(--q1-color-gray-500);
374
405
  --q1-color-overlay-scrim: rgba(2, 6, 23, 0.44);
375
- --q1-color-focus: var(--q1-color-primary-700);
406
+ --q1-color-focus: var(--q1-color-primary-900);
376
407
  --q1-color-selection-bg: var(--q1-color-text-primary);
377
408
  --q1-color-selection-fg: var(--q1-color-bg-canvas);
378
409
  --q1-color-status-success: var(--q1-color-green-900);
410
+ --q1-color-status-success-text: var(--q1-color-green-900);
411
+ --q1-color-status-success-surface: var(--q1-color-green-100);
412
+ --q1-color-status-success-border: #255a2f;
379
413
  --q1-color-status-warning: var(--q1-color-amber-700);
414
+ --q1-color-status-warning-text: #fac053;
415
+ --q1-color-status-warning-surface: var(--q1-color-amber-100);
416
+ --q1-color-status-warning-border: #754b10;
380
417
  --q1-color-status-danger: var(--q1-color-red-900);
381
- --q1-color-status-danger-text: #ef5350;
418
+ --q1-color-status-danger-text: #f97770;
382
419
  --q1-color-status-danger-surface: var(--q1-color-red-100);
383
- --q1-color-status-danger-border: #ef5350;
420
+ --q1-color-status-danger-border: #7e2f31;
384
421
  --q1-color-status-info: var(--q1-color-blue-900);
422
+ --q1-color-status-info-text: var(--q1-color-blue-900);
423
+ --q1-color-status-info-surface: var(--q1-color-blue-100);
424
+ --q1-color-status-info-border: #194f81;
385
425
  --q1-font-sans: "Noto Sans SC", "PingFang SC", "Microsoft YaHei UI", sans-serif;
386
426
  --q1-font-mono: "Geist Mono", ui-monospace, "SFMono-Regular", Menlo, Consolas, monospace;
387
427
  --q1-font-weight-regular: 400;
@@ -474,7 +514,9 @@
474
514
  --q1-radius-4: 12px;
475
515
  --q1-radius-5: 16px;
476
516
  --q1-radius-full: 9999px;
477
- --q1-shadow-focus: 0 0 0 1px var(--q1-color-bg-canvas), 0 0 0 3px var(--q1-color-focus);
517
+ --q1-shadow-focus: 0 0 0 2px var(--q1-color-bg-canvas), 0 0 0 4px var(--q1-color-focus);
518
+ --q1-shadow-focus-input: inset 0 0 0 1px var(--q1-color-border-active), 0 0 0 3px color-mix(in srgb, var(--q1-color-focus) 24%, transparent);
519
+ --q1-shadow-focus-input-danger: inset 0 0 0 1px var(--q1-color-status-danger), 0 0 0 3px color-mix(in srgb, var(--q1-color-status-danger) 24%, transparent);
478
520
  --q1-shadow-focus-danger: 0 0 0 4px color-mix(in srgb, var(--q1-color-status-danger) 16%, transparent);
479
521
  --q1-shadow-popover: 0 1px 3px color-mix(in srgb, var(--q1-color-shadow) 10%, transparent),
480
522
  0 8px 28px color-mix(in srgb, var(--q1-color-shadow) 14%, transparent);
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@q1travel/design-system",
3
- "version": "0.17.3",
3
+ "version": "0.18.0",
4
4
  "description": "React components, design tokens, and interface contracts for q1travel products.",
5
5
  "keywords": [
6
6
  "react",