@q1travel/design-system 0.17.2 → 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.
@@ -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;
@@ -1615,14 +1654,12 @@
1615
1654
  flex 居中,不是 padding 自然撑开),radius-2(6px) 已一致;禁用项只换色不降 opacity(
1616
1655
  Radio/Note/Modal 已建立的「禁用色彩降级、opacity 恒 1」家族规则)。 */
1617
1656
  .menu__popup {
1618
- position: absolute;
1619
- z-index: 40;
1620
1657
  min-width: 200px;
1621
1658
  max-width: 20rem;
1622
1659
  padding: var(--q1-space-2);
1623
1660
  border: 1px solid var(--q1-color-border-overlay);
1624
1661
  border-radius: var(--q1-radius-4);
1625
- background: var(--q1-color-bg-panel);
1662
+ background: var(--q1-color-bg-overlay);
1626
1663
  box-shadow: var(--q1-shadow-popover);
1627
1664
  }
1628
1665
  .menu__popup[data-state] {
@@ -1632,19 +1669,6 @@
1632
1669
  opacity var(--q1-duration-fast) var(--q1-ease-out),
1633
1670
  transform var(--q1-duration-fast) var(--q1-ease-out);
1634
1671
  }
1635
- .menu__popup--start {
1636
- left: 0;
1637
- }
1638
- .menu__popup--end {
1639
- right: 0;
1640
- }
1641
- .menu__popup--bottom {
1642
- top: calc(100% + var(--q1-space-2));
1643
- }
1644
- /* 位置碰撞检测:向下展开会超出视口底部时翻转到触发器上方。 */
1645
- .menu__popup--top {
1646
- bottom: calc(100% + var(--q1-space-2));
1647
- }
1648
1672
  .menu__popup[data-state].menu__popup--start.menu__popup--bottom {
1649
1673
  transform-origin: left top;
1650
1674
  }
@@ -1708,7 +1732,7 @@
1708
1732
  .menu__item:hover:not([aria-disabled='true']),
1709
1733
  .menu__item:focus-visible {
1710
1734
  outline: none;
1711
- background: color-mix(in srgb, var(--q1-color-text-primary) 6%, transparent);
1735
+ background: var(--q1-color-bg-hover);
1712
1736
  }
1713
1737
  .menu__item[aria-disabled='true'],
1714
1738
  .menu__item--locked {
@@ -3471,11 +3495,11 @@ a[href]:has(> .book):focus-visible {
3471
3495
  color: var(--q1-color-text-muted);
3472
3496
  }
3473
3497
 
3474
- /* 错误边框保留校验含义,键盘焦点另用共享 focus token 表达当前位置。 */
3475
- .form-field--error .select-control .form-control--select:focus-visible,
3476
- .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 {
3477
3501
  border-color: var(--q1-color-status-danger);
3478
- box-shadow: var(--q1-input-focus-ring, var(--q1-shadow-focus));
3502
+ box-shadow: var(--q1-shadow-focus-input-danger);
3479
3503
  }
3480
3504
 
3481
3505
  .select-control--prefixed .form-control {
@@ -3933,7 +3957,7 @@ a[href]:has(> .book):focus-visible {
3933
3957
  padding: var(--q1-space-4);
3934
3958
  border: 1px solid var(--q1-color-border-overlay);
3935
3959
  border-radius: var(--q1-radius-3);
3936
- background: var(--q1-color-bg-panel);
3960
+ background: var(--q1-color-bg-overlay);
3937
3961
  box-shadow: var(--q1-shadow-popover);
3938
3962
  }
3939
3963
 
@@ -4191,15 +4215,11 @@ a[href]:has(> .book):focus-visible {
4191
4215
  }
4192
4216
 
4193
4217
  .cal-period__menu {
4194
- position: absolute;
4195
- top: calc(100% + var(--q1-space-2));
4196
- left: 0;
4197
- z-index: 20;
4198
4218
  display: flex;
4199
4219
  min-width: 380px;
4200
4220
  border: 1px solid var(--q1-color-border-overlay);
4201
4221
  border-radius: var(--q1-radius-3);
4202
- background: var(--q1-color-bg-panel);
4222
+ background: var(--q1-color-bg-overlay);
4203
4223
  box-shadow: var(--q1-shadow-popover);
4204
4224
  overflow: hidden;
4205
4225
  }
@@ -5365,7 +5385,7 @@ a.context-card__trigger {
5365
5385
  padding: var(--q1-space-3) var(--q1-space-4);
5366
5386
  border: 1px solid var(--q1-color-border-overlay);
5367
5387
  border-radius: var(--q1-radius-2);
5368
- background: var(--q1-color-bg-panel);
5388
+ background: var(--q1-color-bg-overlay);
5369
5389
  box-shadow: var(--q1-shadow-popover);
5370
5390
  opacity: 0;
5371
5391
  visibility: hidden;
@@ -5591,7 +5611,7 @@ a.context-card__trigger {
5591
5611
  /* 浮层家族规则:发丝边框 + 恒黑阴影(此前用 mask-opaque 混色躲过了阴影清扫)。 */
5592
5612
  border: 1px solid var(--q1-color-border-overlay);
5593
5613
  border-radius: var(--q1-radius-2);
5594
- background: var(--q1-color-bg-panel);
5614
+ background: var(--q1-color-bg-overlay);
5595
5615
  box-shadow: var(--q1-shadow-popover);
5596
5616
  opacity: 0;
5597
5617
  visibility: hidden;
@@ -6293,7 +6313,7 @@ a.q1-card:focus-visible {
6293
6313
  }
6294
6314
 
6295
6315
  .show-more__trigger[data-pointer-pressed='true'] {
6296
- background: var(--q1-color-bg-subtle);
6316
+ background: var(--q1-color-bg-hover);
6297
6317
  border-color: var(--q1-color-border-strong);
6298
6318
  color: var(--q1-color-text-primary);
6299
6319
  opacity: 0.96;
@@ -6413,8 +6433,8 @@ a.q1-card:focus-visible {
6413
6433
  background-color: color-mix(in srgb, var(--q1-color-text-primary) 8%, transparent);
6414
6434
  }
6415
6435
  .collapse__trigger:focus-visible {
6416
- outline: none;
6417
- 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;
6418
6438
  }
6419
6439
  .collapse__title {
6420
6440
  font-size: 14px;
@@ -7872,8 +7892,9 @@ a.q1-card:focus-visible {
7872
7892
  }
7873
7893
  .split-button__primary:focus-visible,
7874
7894
  .split-button__toggle:focus-visible {
7875
- outline: none;
7876
- box-shadow: var(--q1-shadow-focus);
7895
+ outline: 2px solid var(--q1-color-focus);
7896
+ outline-offset: 2px;
7897
+ box-shadow: none;
7877
7898
  z-index: 1;
7878
7899
  }
7879
7900
  .split-button__icon {
@@ -8049,7 +8070,7 @@ a.q1-card:focus-visible {
8049
8070
  padding: 0 var(--q1-space-3);
8050
8071
  border: 1px solid var(--q1-color-border-strong);
8051
8072
  border-radius: var(--q1-radius-2);
8052
- background: var(--q1-color-bg-panel);
8073
+ background: var(--q1-color-bg-sunken);
8053
8074
  }
8054
8075
 
8055
8076
  .combobox--sm .combobox__control {
@@ -8066,18 +8087,21 @@ a.q1-card:focus-visible {
8066
8087
  font-size: var(--q1-font-size-copy-16);
8067
8088
  line-height: var(--q1-line-height-copy-16);
8068
8089
  }
8069
- .combobox__control:focus-within {
8070
- border-color: var(--q1-color-action-primary);
8071
- 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);
8072
8093
  }
8073
8094
  .combobox--error .combobox__control {
8074
- border-color: var(--q1-color-red-700);
8095
+ border-color: var(--q1-color-status-danger);
8075
8096
  }
8076
- .combobox--error .combobox__control:focus-within {
8077
- 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);
8078
8100
  }
8079
8101
  .combobox--disabled .combobox__control {
8080
- opacity: 0.55;
8102
+ background: var(--q1-color-gray-100);
8103
+ color: var(--q1-color-text-disabled);
8104
+ opacity: 1;
8081
8105
  }
8082
8106
  .combobox--readonly .combobox__input {
8083
8107
  caret-color: transparent;
@@ -8122,11 +8146,6 @@ a.q1-card:focus-visible {
8122
8146
  box-shadow: var(--q1-shadow-focus);
8123
8147
  }
8124
8148
  .combobox__popup {
8125
- position: absolute;
8126
- top: calc(100% + var(--q1-space-1));
8127
- left: 0;
8128
- right: 0;
8129
- z-index: 40;
8130
8149
  max-height: 240px;
8131
8150
  overflow-y: auto;
8132
8151
  overflow-x: hidden;
@@ -8135,7 +8154,7 @@ a.q1-card:focus-visible {
8135
8154
  list-style: none;
8136
8155
  border: 1px solid var(--q1-color-border-overlay);
8137
8156
  border-radius: var(--q1-radius-3);
8138
- background: var(--q1-color-bg-panel);
8157
+ background: var(--q1-color-bg-overlay);
8139
8158
  box-shadow: var(--q1-shadow-popover);
8140
8159
  }
8141
8160
  .combobox__listbox {
@@ -8232,16 +8251,22 @@ a.q1-card:focus-visible {
8232
8251
  padding: var(--q1-space-2) var(--q1-space-3);
8233
8252
  border: 1px solid var(--q1-color-border-strong);
8234
8253
  border-radius: var(--q1-radius-2);
8235
- background: var(--q1-color-bg-panel);
8254
+ background: var(--q1-color-bg-sunken);
8236
8255
  color: var(--q1-color-text-primary);
8237
8256
  font: inherit;
8238
8257
  font-size: 14px;
8239
8258
  font-weight: 500;
8240
8259
  cursor: pointer;
8241
8260
  }
8242
- .multi-select__trigger:focus-visible {
8261
+ .multi-select__trigger:focus {
8243
8262
  outline: none;
8244
- 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;
8245
8270
  }
8246
8271
  .multi-select__placeholder {
8247
8272
  color: var(--q1-color-text-secondary);
@@ -8249,15 +8274,11 @@ a.q1-card:focus-visible {
8249
8274
  }
8250
8275
  /* 菜单 radius-4(12px)、padding space-2(8px)、行高 32px。 */
8251
8276
  .multi-select__menu {
8252
- position: absolute;
8253
- top: calc(100% + var(--q1-space-1));
8254
- left: 0;
8255
- z-index: 40;
8256
8277
  min-width: 240px;
8257
8278
  padding: var(--q1-space-2);
8258
8279
  border: 1px solid var(--q1-color-border-overlay);
8259
8280
  border-radius: var(--q1-radius-4);
8260
- background: var(--q1-color-bg-panel);
8281
+ background: var(--q1-color-bg-overlay);
8261
8282
  box-shadow: var(--q1-shadow-popover);
8262
8283
  }
8263
8284
  .multi-select__bulk {
@@ -8429,7 +8450,7 @@ a.q1-card:focus-visible {
8429
8450
  overflow: hidden;
8430
8451
  border: 1px solid var(--q1-color-border-overlay);
8431
8452
  border-radius: var(--q1-radius-4);
8432
- background: var(--q1-color-bg-panel);
8453
+ background: var(--q1-color-bg-raised);
8433
8454
  box-shadow: var(--q1-shadow-modal);
8434
8455
  }
8435
8456
  .search-dialog__search {
@@ -8705,7 +8726,7 @@ a.q1-card:focus-visible {
8705
8726
  max-width: 540px;
8706
8727
  border: 1px solid var(--q1-color-border-overlay);
8707
8728
  border-radius: var(--q1-radius-4);
8708
- background: var(--q1-color-bg-panel);
8729
+ background: var(--q1-color-bg-raised);
8709
8730
  box-shadow: var(--q1-shadow-modal);
8710
8731
  }
8711
8732
  .modal__header {
@@ -8885,7 +8906,7 @@ a.q1-card:focus-visible {
8885
8906
  border: 1px solid var(--q1-color-border-overlay);
8886
8907
  border-bottom: 0;
8887
8908
  border-radius: var(--q1-radius-4) var(--q1-radius-4) 0 0;
8888
- background: var(--q1-color-bg-panel);
8909
+ background: var(--q1-color-bg-raised);
8889
8910
  /* 方向性面板自持阴影(不走 --q1-shadow-popover/modal,两者的偏移都朝下)。
8890
8911
  两层同向朝上:接触层交代面板压在页面底边,环境层交代它离底面多高。 */
8891
8912
  box-shadow:
@@ -9030,7 +9051,7 @@ a.q1-card:focus-visible {
9030
9051
  flex-direction: column;
9031
9052
  border: 1px solid var(--q1-color-border-overlay);
9032
9053
  border-radius: var(--q1-radius-4);
9033
- background: var(--q1-color-bg-panel);
9054
+ background: var(--q1-color-bg-raised);
9034
9055
  /* 方向性面板自持阴影,理由同 Drawer。接触层不带方向:Sheet 四个方向共用此规则,
9035
9056
  带方向的接触层在 top 档会朝错边。 */
9036
9057
  box-shadow:
@@ -10010,7 +10031,7 @@ a.q1-navigation__item[aria-disabled='true'] {
10010
10031
  overflow: hidden;
10011
10032
  border: 1px solid var(--q1-color-border-overlay);
10012
10033
  border-radius: var(--q1-radius-3);
10013
- background: var(--q1-color-bg-panel);
10034
+ background: var(--q1-color-bg-overlay);
10014
10035
  color: var(--q1-color-text-primary);
10015
10036
  box-shadow: var(--q1-shadow-popover);
10016
10037
  }
@@ -10796,6 +10817,7 @@ a.q1-navigation__item[aria-disabled='true'] {
10796
10817
  color: var(--q1-color-action-text);
10797
10818
  text-decoration: underline;
10798
10819
  text-decoration-thickness: 1px;
10820
+ text-decoration-color: color-mix(in srgb, currentColor 55%, transparent);
10799
10821
  text-underline-offset: 0.2em;
10800
10822
  text-decoration-skip-ink: auto;
10801
10823
  border-radius: var(--q1-radius-1);
@@ -10809,11 +10831,17 @@ a.q1-navigation__item[aria-disabled='true'] {
10809
10831
 
10810
10832
  .q1-link:hover {
10811
10833
  color: var(--q1-color-text-primary);
10834
+ text-decoration-thickness: 2px;
10835
+ text-decoration-color: currentColor;
10812
10836
  }
10813
10837
 
10814
10838
  .q1-link:focus-visible {
10815
- outline: 2px solid currentColor;
10816
- 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;
10817
10845
  }
10818
10846
 
10819
10847
  /* muted:正文密度很高、链接很多的段落里,主色会把整段打成一片蓝。
@@ -10831,6 +10859,38 @@ a.q1-navigation__item[aria-disabled='true'] {
10831
10859
  text-decoration-thickness: 2px;
10832
10860
  }
10833
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
+
10834
10894
  /* 无 href 的静态文本:不是链接,因此不给链接色也不给下划线,避免看起来能点。 */
10835
10895
  .q1-link--static {
10836
10896
  color: var(--q1-color-text-secondary);
@@ -10998,12 +11058,17 @@ a.q1-navigation__item[aria-disabled='true'] {
10998
11058
  .cal-field__clear:focus-visible,
10999
11059
  .cal-field__caret:focus-visible,
11000
11060
  .cal-inputs__apply:focus-visible,
11001
- .cal-period__trigger:focus-visible,
11002
11061
  .cal-period__option:focus-visible {
11003
11062
  outline: none;
11004
11063
  box-shadow: var(--q1-shadow-focus);
11005
11064
  }
11006
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
+
11007
11072
  .calendar__nav-btn:disabled,
11008
11073
  .calendar__nav-btn:disabled:hover {
11009
11074
  background: transparent;
@@ -12339,10 +12404,9 @@ a.q1-navigation__item[aria-disabled='true'] {
12339
12404
  calc(100vw - 2 * var(--q1-space-2))
12340
12405
  );
12341
12406
  max-width: calc(100vw - 2 * var(--q1-space-2));
12342
- max-height: var(--dots-menu-max-height, calc(100vh - 2 * var(--q1-space-2)));
12407
+ max-height: calc(100vh - 2 * var(--q1-space-2));
12343
12408
  overflow-y: auto;
12344
12409
  opacity: 1;
12345
- translate: var(--dots-menu-offset-x, 0) 0;
12346
12410
  transform: scale(1);
12347
12411
  }
12348
12412