@trdrs/quickcharts 2.4.0 → 4.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 (80) hide show
  1. package/CHANGELOG.md +121 -0
  2. package/README.md +326 -25
  3. package/dist/adapters/rest.d.ts +1 -1
  4. package/dist/{ar-KSXQ2USS.js → ar-FXZ5QJUR.js} +206 -56
  5. package/dist/ar-FXZ5QJUR.js.map +1 -0
  6. package/dist/{assets-M5emOz5c.d.ts → assets-Gg-UquDA.d.ts} +285 -61
  7. package/dist/{ca_ES-JG4FM55E.js → ca_ES-3WVKFBIF.js} +206 -56
  8. package/dist/ca_ES-3WVKFBIF.js.map +1 -0
  9. package/dist/chunk-C4MEVUNK.js +11449 -0
  10. package/dist/chunk-C4MEVUNK.js.map +1 -0
  11. package/dist/{de-VSW2LHNF.js → de-V72Q3OI7.js} +206 -56
  12. package/dist/de-V72Q3OI7.js.map +1 -0
  13. package/dist/drawings.d.ts +24 -13
  14. package/dist/drawings.js +5 -1
  15. package/dist/{es-5ZXIPVOB.js → es-CNQ3OJ6E.js} +206 -56
  16. package/dist/es-CNQ3OJ6E.js.map +1 -0
  17. package/dist/feature-manifest.json +94 -11
  18. package/dist/{fr-4F6DAWGD.js → fr-5WQBCGR4.js} +206 -56
  19. package/dist/fr-5WQBCGR4.js.map +1 -0
  20. package/dist/{he_IL-B7PBQUEV.js → he_IL-WXKA77UE.js} +206 -56
  21. package/dist/he_IL-WXKA77UE.js.map +1 -0
  22. package/dist/{id_ID-CYJRMXPC.js → id_ID-XPBAYSWK.js} +206 -56
  23. package/dist/id_ID-XPBAYSWK.js.map +1 -0
  24. package/dist/index.d.ts +1834 -1671
  25. package/dist/index.js +5405 -2619
  26. package/dist/index.js.map +1 -1
  27. package/dist/{it-KTX4SG5P.js → it-DR2EBNWX.js} +206 -56
  28. package/dist/it-DR2EBNWX.js.map +1 -0
  29. package/dist/{ja-V7OURU5D.js → ja-URB2CPXO.js} +206 -56
  30. package/dist/ja-URB2CPXO.js.map +1 -0
  31. package/dist/{ko-2RNEBYVE.js → ko-OE47NYVP.js} +206 -56
  32. package/dist/ko-OE47NYVP.js.map +1 -0
  33. package/dist/{ms_MY-EY235E7Q.js → ms_MY-BKCFRK2K.js} +206 -56
  34. package/dist/ms_MY-BKCFRK2K.js.map +1 -0
  35. package/dist/{pl-ADNVRP55.js → pl-3IKQRG3Y.js} +206 -56
  36. package/dist/pl-3IKQRG3Y.js.map +1 -0
  37. package/dist/{pt-OL2DR3DO.js → pt-PZHV5EZE.js} +206 -56
  38. package/dist/pt-PZHV5EZE.js.map +1 -0
  39. package/dist/quickcharts.css +2060 -717
  40. package/dist/{resources-C0cYryO9.d.ts → resources-Le6flcEn.d.ts} +1 -1
  41. package/dist/{ru-V6YFEPAF.js → ru-BAL6RQUV.js} +206 -56
  42. package/dist/ru-BAL6RQUV.js.map +1 -0
  43. package/dist/{sv-TORXQVE7.js → sv-Y6GBGDHM.js} +206 -56
  44. package/dist/sv-Y6GBGDHM.js.map +1 -0
  45. package/dist/{symbols-BL1fD4CS.d.ts → symbols-6V22WaRX.d.ts} +1 -1
  46. package/dist/symbols.d.ts +1 -1
  47. package/dist/{th-K6SJSYSY.js → th-MAMLMZKU.js} +206 -56
  48. package/dist/th-MAMLMZKU.js.map +1 -0
  49. package/dist/theme-manifest.json +204 -16
  50. package/dist/{tr-4AEM66KW.js → tr-3LQHINUZ.js} +206 -56
  51. package/dist/tr-3LQHINUZ.js.map +1 -0
  52. package/dist/{vi-YU5XCEUU.js → vi-GR4PSDKP.js} +206 -56
  53. package/dist/vi-GR4PSDKP.js.map +1 -0
  54. package/dist/{zh-QXKRYHU5.js → zh-2RJ5VNAI.js} +206 -56
  55. package/dist/zh-2RJ5VNAI.js.map +1 -0
  56. package/dist/{zh_TW-AYPDKG4Q.js → zh_TW-XEBSACHU.js} +206 -56
  57. package/dist/zh_TW-XEBSACHU.js.map +1 -0
  58. package/package.json +1 -1
  59. package/dist/ar-KSXQ2USS.js.map +0 -1
  60. package/dist/ca_ES-JG4FM55E.js.map +0 -1
  61. package/dist/chunk-YR7NT5ZW.js +0 -6997
  62. package/dist/chunk-YR7NT5ZW.js.map +0 -1
  63. package/dist/de-VSW2LHNF.js.map +0 -1
  64. package/dist/es-5ZXIPVOB.js.map +0 -1
  65. package/dist/fr-4F6DAWGD.js.map +0 -1
  66. package/dist/he_IL-B7PBQUEV.js.map +0 -1
  67. package/dist/id_ID-CYJRMXPC.js.map +0 -1
  68. package/dist/it-KTX4SG5P.js.map +0 -1
  69. package/dist/ja-V7OURU5D.js.map +0 -1
  70. package/dist/ko-2RNEBYVE.js.map +0 -1
  71. package/dist/ms_MY-EY235E7Q.js.map +0 -1
  72. package/dist/pl-ADNVRP55.js.map +0 -1
  73. package/dist/pt-OL2DR3DO.js.map +0 -1
  74. package/dist/ru-V6YFEPAF.js.map +0 -1
  75. package/dist/sv-TORXQVE7.js.map +0 -1
  76. package/dist/th-K6SJSYSY.js.map +0 -1
  77. package/dist/tr-4AEM66KW.js.map +0 -1
  78. package/dist/vi-YU5XCEUU.js.map +0 -1
  79. package/dist/zh-QXKRYHU5.js.map +0 -1
  80. package/dist/zh_TW-AYPDKG4Q.js.map +0 -1
@@ -14,7 +14,7 @@
14
14
  --qc-canvas-paneBorder: #ebebeb;
15
15
  --qc-chrome-border: #ebebeb;
16
16
  --qc-chrome-borderStrong: #8c8c8c;
17
- --qc-chrome-caret: #0f0f0f;
17
+ --qc-chrome-caret: #707070;
18
18
  --qc-chrome-fieldBorder: #dbdbdb;
19
19
  --qc-chrome-grip: #b8b8b8;
20
20
  --qc-chrome-radius: 6px;
@@ -22,13 +22,24 @@
22
22
  --qc-chrome-scrollThumb: #9c9c9c;
23
23
  --qc-chrome-surface: #ffffff;
24
24
  --qc-chrome-surfaceRaised: #ffffff;
25
+ --qc-control-fieldEdge: #dbdbdb;
26
+ --qc-control-fieldEdgeHover: #a8a8a8;
27
+ --qc-control-fieldFill: #f2f2f2;
28
+ --qc-control-fieldInvalid: #f23645;
25
29
  --qc-control-mark: #ffffff;
30
+ --qc-control-neutral: #f2f2f2;
31
+ --qc-control-neutralHover: #ebebeb;
32
+ --qc-control-neutralInk: #000000;
33
+ --qc-control-neutralPressed: #dbdbdb;
26
34
  --qc-control-off: #9c9c9c;
27
35
  --qc-control-offHover: #8c8c8c;
28
36
  --qc-control-offPressed: #b8b8b8;
29
37
  --qc-control-on: #2e2e2e;
30
38
  --qc-control-onHover: #4a4a4a;
39
+ --qc-control-onInk: #ffffff;
31
40
  --qc-control-onPressed: #707070;
41
+ --qc-control-outline: #2e2e2e;
42
+ --qc-control-selectEdgeHover: #a8a8a8;
32
43
  --qc-drawing-fill: rgba(41, 98, 255, 0.15);
33
44
  --qc-drawing-handle: #ffffff;
34
45
  --qc-drawing-line: #2962ff;
@@ -39,15 +50,17 @@
39
50
  --qc-illustration-ink: #1e222d;
40
51
  --qc-motion-durationBase: 150ms;
41
52
  --qc-motion-durationFast: 90ms;
53
+ --qc-motion-durationGlide: 100ms;
42
54
  --qc-motion-durationModerate: 250ms;
43
55
  --qc-motion-durationSlow: 350ms;
44
56
  --qc-motion-durationSlower: 500ms;
57
+ --qc-motion-easingInOut: ease-in-out;
45
58
  --qc-motion-easingLinear: linear;
46
59
  --qc-motion-easingOut: ease-out;
47
60
  --qc-motion-easingSpring: cubic-bezier(0.175, 0.885, 0.32, 1.275);
48
61
  --qc-motion-easingStandard: ease;
49
62
  --qc-motion-scaleEnter: 0.97;
50
- --qc-overlay-scrim: rgba(0, 0, 0, 0.35);
63
+ --qc-overlay-scrim: rgba(156, 156, 156, 0.5);
51
64
  --qc-overlay-separator: #ebebeb;
52
65
  --qc-overlay-shadow: 0 2px 4px rgba(0, 0, 0, 0.2);
53
66
  --qc-overlay-surface: #ffffff;
@@ -76,14 +89,14 @@
76
89
  --qc-state-selection: rgba(31, 86, 238, 0.18);
77
90
  --qc-status-info: #1160c4;
78
91
  --qc-status-loading: #787b86;
79
- --qc-status-negative: #cc2f3c;
80
- --qc-status-positive: #067a67;
92
+ --qc-status-negative: #df323f;
93
+ --qc-status-positive: #078671;
81
94
  --qc-status-sessionAfterHours: #f5a623;
82
95
  --qc-status-sessionClosed: rgba(0, 0, 0, 0.35);
83
96
  --qc-status-sessionExtended: #4c98fb;
84
97
  --qc-status-sessionOpen: #22c55e;
85
98
  --qc-status-sessionPreMarket: #4c98fb;
86
- --qc-status-warning: #8a5a00;
99
+ --qc-status-warning: #ac6600;
87
100
  --qc-text-disabled: #b8b8b8;
88
101
  --qc-text-fontFamily: -apple-system, BlinkMacSystemFont, "Trebuchet MS", Roboto, Ubuntu, sans-serif;
89
102
  --qc-text-fontSizeAxis: 13px;
@@ -94,7 +107,7 @@
94
107
  --qc-text-highlight: #2962ff;
95
108
  --qc-text-inverse: #ffffff;
96
109
  --qc-text-link: #2962ff;
97
- --qc-text-muted: #636363;
110
+ --qc-text-muted: #6a6a6a;
98
111
  --qc-text-onCanvas: #0f0f0f;
99
112
  --qc-text-primary: #0f0f0f;
100
113
  --qc-text-secondary: #4a4a4a;
@@ -113,26 +126,39 @@
113
126
  --qc-chrome-scrollThumb: #3d3d3d;
114
127
  --qc-chrome-surface: #0f0f0f;
115
128
  --qc-chrome-surfaceRaised: #2e2e2e;
129
+ --qc-control-fieldEdge: #575757;
130
+ --qc-control-fieldEdgeHover: #707070;
131
+ --qc-control-fieldFill: #2e2e2e;
132
+ --qc-control-fieldInvalid: #f23645;
116
133
  --qc-control-mark: #2e2e2e;
134
+ --qc-control-neutral: #2e2e2e;
135
+ --qc-control-neutralHover: #3d3d3d;
136
+ --qc-control-neutralInk: #ffffff;
137
+ --qc-control-neutralPressed: #4a4a4a;
117
138
  --qc-control-off: #636363;
118
139
  --qc-control-offHover: #707070;
119
140
  --qc-control-offPressed: #636363;
120
141
  --qc-control-on: #f2f2f2;
121
142
  --qc-control-onHover: #dbdbdb;
143
+ --qc-control-onInk: #000000;
122
144
  --qc-control-onPressed: #8c8c8c;
123
- --qc-drawing-fill: rgba(76, 152, 251, 0.15);
145
+ --qc-control-outline: #ffffff;
146
+ --qc-control-selectEdgeHover: #808080;
147
+ --qc-drawing-fill: rgba(41, 98, 255, 0.15);
124
148
  --qc-drawing-handle: #0f0f0f;
125
- --qc-drawing-line: #4c98fb;
126
- --qc-drawing-selected: #4c98fb;
149
+ --qc-drawing-line: #2962ff;
150
+ --qc-drawing-selected: #1e53e5;
127
151
  --qc-drawing-text: #dbdbdb;
128
152
  --qc-illustration-accent: #1976d2;
129
153
  --qc-illustration-accentInk: #d1d4dc;
130
154
  --qc-illustration-ink: #d1d4dc;
131
155
  --qc-motion-durationBase: 150ms;
132
156
  --qc-motion-durationFast: 90ms;
157
+ --qc-motion-durationGlide: 100ms;
133
158
  --qc-motion-durationModerate: 250ms;
134
159
  --qc-motion-durationSlow: 350ms;
135
160
  --qc-motion-durationSlower: 500ms;
161
+ --qc-motion-easingInOut: ease-in-out;
136
162
  --qc-motion-easingLinear: linear;
137
163
  --qc-motion-easingOut: ease-out;
138
164
  --qc-motion-easingSpring: cubic-bezier(0.175, 0.885, 0.32, 1.275);
@@ -167,14 +193,14 @@
167
193
  --qc-state-selection: rgba(82, 160, 252, 0.22);
168
194
  --qc-status-info: #68a5ff;
169
195
  --qc-status-loading: #787b86;
170
- --qc-status-negative: #f7525f;
196
+ --qc-status-negative: #f34452;
171
197
  --qc-status-positive: #089981;
172
198
  --qc-status-sessionAfterHours: #f5a623;
173
199
  --qc-status-sessionClosed: rgba(255, 255, 255, 0.35);
174
200
  --qc-status-sessionExtended: #4c98fb;
175
201
  --qc-status-sessionOpen: #22c55e;
176
202
  --qc-status-sessionPreMarket: #4c98fb;
177
- --qc-status-warning: #f5a623;
203
+ --qc-status-warning: #ff9800;
178
204
  --qc-text-disabled: #575757;
179
205
  --qc-text-fontFamily: -apple-system, BlinkMacSystemFont, "Trebuchet MS", Roboto, Ubuntu, sans-serif;
180
206
  --qc-text-fontSizeAxis: 13px;
@@ -185,7 +211,7 @@
185
211
  --qc-text-highlight: #5280ff;
186
212
  --qc-text-inverse: #0f0f0f;
187
213
  --qc-text-link: #5b9cf6;
188
- --qc-text-muted: #9c9c9c;
214
+ --qc-text-muted: #9b9b9b;
189
215
  --qc-text-onCanvas: #dbdbdb;
190
216
  --qc-text-primary: #dbdbdb;
191
217
  --qc-text-secondary: #b8b8b8;
@@ -195,6 +221,7 @@
195
221
  [data-qc-theme] {
196
222
  --qc-motion-durationBase: 0ms !important;
197
223
  --qc-motion-durationFast: 0ms !important;
224
+ --qc-motion-durationGlide: 0ms !important;
198
225
  --qc-motion-durationModerate: 0ms !important;
199
226
  --qc-motion-durationSlow: 0ms !important;
200
227
  --qc-motion-durationSlower: 0ms !important;
@@ -237,6 +264,16 @@
237
264
  box-sizing: inherit;
238
265
  }
239
266
 
267
+ /* Every control reads in the chart's font: a button, a field or a list takes the root's family rather
268
+ * than the browser's own control font, whatever words it shows or holds. A recipe that sets a size
269
+ * or a weight keeps it, and one that names a family of its own outranks this. */
270
+ [data-qc-theme] button,
271
+ [data-qc-theme] input,
272
+ [data-qc-theme] select,
273
+ [data-qc-theme] textarea {
274
+ font-family: inherit;
275
+ }
276
+
240
277
  /* Surfaces ------------------------------------------------------------------------------------ */
241
278
 
242
279
  [data-qc-theme] .qc-surface {
@@ -342,34 +379,140 @@
342
379
  border-color: var(--qc-state-pressed);
343
380
  }
344
381
 
382
+ /* Fields -------------------------------------------------------------------------------------- */
383
+
384
+ /* A field is one box wherever the chart draws it: a text field, a select, a number field or a color
385
+ * well. A 1px edge rounds an 8px corner around a clear ground, 34px tall, with its words at 14 on 18
386
+ * and 8px in from the outer edge. */
345
387
  [data-qc-theme] .qc-field {
388
+ box-sizing: border-box;
389
+ height: 34px;
390
+ padding: 0 7px;
346
391
  color: var(--qc-text-primary);
347
392
  font: inherit;
348
- background: var(--qc-chrome-surfaceRaised);
349
- border: 1px solid var(--qc-chrome-border);
350
- border-radius: var(--qc-chrome-radius);
393
+ font-size: var(--qc-text-fontSizeBase);
394
+ line-height: 18px;
395
+ background: transparent;
396
+ border: 1px solid var(--qc-control-fieldEdge);
397
+ border-radius: 8px;
398
+ transition: border-color var(--qc-motion-durationFast) var(--qc-motion-easingLinear), box-shadow var(--qc-motion-durationFast) var(--qc-motion-easingLinear);
351
399
  }
352
400
 
353
401
  [data-qc-theme] .qc-field::placeholder {
354
402
  color: var(--qc-text-muted);
355
403
  }
356
404
 
405
+ /* The states stand in the order they outrank one another: the pointer steps the edge up, a field that
406
+ * cannot be edited and a refused value each outrank the pointer, and focus outranks them all. */
407
+ [data-qc-theme] .qc-field:hover {
408
+ border-color: var(--qc-control-fieldEdgeHover);
409
+ }
410
+
411
+ /* A field that cannot be edited stands on the read-only fill, its edge at rest under the pointer. A
412
+ * disabled one stands its words back too, in the disabled ink. */
413
+ [data-qc-theme] .qc-field[readonly] {
414
+ background: var(--qc-control-fieldFill);
415
+ border-color: var(--qc-control-fieldEdge);
416
+ }
417
+
418
+ [data-qc-theme] .qc-field:disabled,
419
+ [data-qc-theme] .qc-field[aria-disabled='true'] {
420
+ color: var(--qc-text-disabled);
421
+ background: var(--qc-control-fieldFill);
422
+ border-color: var(--qc-control-fieldEdge);
423
+ cursor: default;
424
+ }
425
+
426
+ /* A value the chart refuses turns the field's edge the invalid color, and only that: the chart says
427
+ * so with `aria-invalid`. A number past a field's bounds or off its step is a value the chart clamps
428
+ * or rounds, not one it refuses, so the field never turns red for it. */
429
+ [data-qc-theme] .qc-field[aria-invalid='true'] {
430
+ border-color: var(--qc-control-fieldInvalid);
431
+ }
432
+
433
+ /* Focus draws a 2px ring over the edge, the edge itself and the pixel inside it, so the ring follows
434
+ * the corner and stays inside the box, where no scrolling surface clips it. A text field, a select
435
+ * and a number field wear it whenever they have the keyboard; a color well and a list button wear it
436
+ * when the keyboard brought it to them, as every button does. A refused value rings in the invalid
437
+ * color. */
438
+ [data-qc-theme] .qc-field:not(button):focus,
439
+ [data-qc-theme] .qc-field:focus-visible {
440
+ border-color: var(--qc-state-focusRing);
441
+ box-shadow: inset 0 0 0 1px var(--qc-state-focusRing);
442
+ }
443
+
444
+ [data-qc-theme] .qc-field[aria-invalid='true']:not(button):focus,
445
+ [data-qc-theme] .qc-field[aria-invalid='true']:focus-visible {
446
+ border-color: var(--qc-control-fieldInvalid);
447
+ box-shadow: inset 0 0 0 1px var(--qc-control-fieldInvalid);
448
+ }
449
+
450
+ /* A select draws its own chevron: the 18px mark in the caret ink, in a 20 by 28 slot 2px in from the
451
+ * end of the box. A native select gives up the slot's room and takes the press the slot lets
452
+ * through; a list button lays the slot out after its face and turns the mark while its list is open,
453
+ * keyed on its own state, so a list button inside some other open thing does not turn. */
454
+ [data-qc-theme] .qc-select {
455
+ position: relative;
456
+ display: inline-flex;
457
+ max-width: 100%;
458
+ }
459
+
460
+ [data-qc-theme] .qc-select > .qc-field {
461
+ flex: 1 1 auto;
462
+ padding-inline-end: 25px;
463
+ appearance: none;
464
+ cursor: pointer;
465
+ }
466
+
467
+ [data-qc-theme] .qc-select-chevron {
468
+ display: flex;
469
+ flex: 0 0 20px;
470
+ align-items: center;
471
+ justify-content: center;
472
+ width: 20px;
473
+ height: 28px;
474
+ color: var(--qc-chrome-caret);
475
+ pointer-events: none;
476
+ }
477
+
478
+ [data-qc-theme] .qc-select > .qc-select-chevron {
479
+ position: absolute;
480
+ inset-block-start: 3px;
481
+ inset-inline-end: 3px;
482
+ }
483
+
484
+ [data-qc-theme] .qc-select-chevron > svg {
485
+ transition: rotate var(--qc-motion-durationSlow) var(--qc-motion-easingStandard);
486
+ }
487
+
488
+ [data-qc-theme] [aria-expanded='true'] > .qc-select-chevron > svg {
489
+ rotate: 180deg;
490
+ }
491
+
492
+ [data-qc-theme] .qc-field:disabled ~ .qc-select-chevron,
493
+ [data-qc-theme] .qc-field:disabled > .qc-select-chevron {
494
+ color: var(--qc-text-disabled);
495
+ }
496
+
497
+ /* Focus --------------------------------------------------------------------------------------- */
498
+
357
499
  [data-qc-theme] :focus-visible {
358
500
  outline: 2px solid var(--qc-state-focusRing);
359
501
  outline-offset: 1px;
360
502
  }
361
503
 
362
- /* A field inside its own box says it has the keyboard with the caret in it: the search fields, the
363
- * name field whose box turns the accent, and the two the color mixer carries. The ring that marks a
364
- * focused control would draw a second box inside the field's own, so those inputs stand out of it,
365
- * and hold that
366
- * against a host's focus rule from a later cascade layer too: an important declaration in an earlier
367
- * layer outranks a normal one in a later layer. */
504
+ /* A field shows it has the keyboard on its own box: a search field by the caret in it, every other
505
+ * field by the ring its edge turns. The outline that marks a focused control would draw a second
506
+ * ring outside the field's own, so fields stand out of it, and hold that against a host's focus rule
507
+ * from a later cascade layer too: an important declaration in an earlier layer outranks a normal one
508
+ * in a later layer. */
368
509
  [data-qc-theme] .qc-search-input:focus-visible,
369
510
  [data-qc-theme] .qc-picker-search:focus-visible,
370
511
  [data-qc-theme] .qc-layouts-search-input:focus-visible,
512
+ [data-qc-theme] .qc-field:focus-visible,
371
513
  [data-qc-theme] .qc-name-input:focus-visible,
372
- [data-qc-theme] .qc-drawing-hex:focus-visible {
514
+ [data-qc-theme] .qc-drawing-hex:focus-visible,
515
+ [data-qc-theme] .qc-drawing-opacity-readout:focus-visible {
373
516
  outline: none !important;
374
517
  }
375
518
 
@@ -1141,15 +1284,14 @@
1141
1284
  gap: 8px;
1142
1285
  }
1143
1286
 
1287
+ /* The fields are the chart's own 34px boxes, so an input reads the same here as in the settings
1288
+ * dialog: a number at the drawing settings' middle width, and a select no narrower. */
1144
1289
  [data-qc-theme] .qc-inputs-field {
1145
- width: 72px;
1146
- padding: 1px 4px;
1147
- font-size: var(--qc-text-fontSizeSmall);
1290
+ width: 84px;
1148
1291
  }
1149
1292
 
1150
1293
  [data-qc-theme] .qc-inputs-select {
1151
- padding: 1px 2px;
1152
- font-size: var(--qc-text-fontSizeSmall);
1294
+ min-width: 84px;
1153
1295
  }
1154
1296
 
1155
1297
  [data-qc-theme] .qc-inputs-actions {
@@ -1187,10 +1329,18 @@
1187
1329
  background: Highlight;
1188
1330
  }
1189
1331
 
1190
- [data-qc-theme] .qc-button:disabled {
1332
+ [data-qc-theme] .qc-button:disabled,
1333
+ [data-qc-theme] .qc-field:disabled {
1191
1334
  color: GrayText;
1192
1335
  }
1193
1336
 
1337
+ /* A field rings its focus in the system highlight, drawn the way its own ring is drawn. */
1338
+ [data-qc-theme] .qc-field:not(button):focus,
1339
+ [data-qc-theme] .qc-field:focus-visible {
1340
+ border-color: Highlight;
1341
+ box-shadow: inset 0 0 0 1px Highlight;
1342
+ }
1343
+
1194
1344
  [data-qc-theme] :focus-visible {
1195
1345
  outline-color: Highlight;
1196
1346
  }
@@ -1769,25 +1919,47 @@
1769
1919
  padding: 0 6px 6px;
1770
1920
  }
1771
1921
 
1772
- /* The shared color control inside a chrome row is the drawing field at the row's own height. */
1773
- [data-qc-theme] .qc-settings-row .qc-drawing-swatch-button {
1774
- height: 24px;
1775
- padding: 0 4px;
1776
- }
1777
-
1778
- [data-qc-theme] .qc-settings-row .qc-drawing-well {
1779
- width: 20px;
1780
- height: 16px;
1781
- }
1782
-
1783
1922
  /* The inline text editor over the pane, the glyph picker and the image picker. */
1784
1923
 
1785
- /* The editor sits at the drawing's own text position in the drawing's own type; its size follows
1786
- * the content and is written by the editor, because it is measured text. The ring is the focus
1787
- * role, so it reads as the field it is without a fill hiding the chart. */
1924
+ /* The text editor over the pane. Its place, size and type are written by the editor, because they
1925
+ * are the words' own. */
1788
1926
  [data-qc-theme] .qc-drawing-text-editor {
1789
1927
  position: absolute;
1790
1928
  z-index: 8;
1929
+ margin: 0;
1930
+ resize: none;
1931
+ pointer-events: auto;
1932
+ }
1933
+
1934
+ /* Over a drawing that types its words on the chart, the field is seen by nobody: the chart paints
1935
+ * the words, the caret, the selection and the placeholder, and the field only takes the keys. It
1936
+ * lies exactly over the painted words, 2px of padding around their block, in their own type with
1937
+ * nothing of its own (no spacing, features or decoration) that would part its caret from them. */
1938
+ [data-qc-theme] .qc-drawing-text-editor[data-qc-editor='inline'] {
1939
+ box-sizing: border-box;
1940
+ min-width: 0;
1941
+ max-width: none;
1942
+ padding: 2px;
1943
+ overflow: hidden;
1944
+ overflow-wrap: break-word;
1945
+ color: inherit;
1946
+ font-feature-settings: normal;
1947
+ font-kerning: auto;
1948
+ letter-spacing: normal;
1949
+ word-spacing: normal;
1950
+ text-indent: 0;
1951
+ text-transform: none;
1952
+ background: none;
1953
+ border: 0;
1954
+ outline: none;
1955
+ box-shadow: none;
1956
+ opacity: 0;
1957
+ }
1958
+
1959
+ /* Over any other drawing, the editor is a box at the drawing's own text position in the drawing's
1960
+ * own type, its size following the content. The ring is the focus role, so it reads as the field it
1961
+ * is without a fill hiding the chart. */
1962
+ [data-qc-theme] .qc-drawing-text-editor[data-qc-editor='box'] {
1791
1963
  padding: 3px 6px;
1792
1964
  overflow: hidden;
1793
1965
  text-align: center;
@@ -1797,11 +1969,9 @@
1797
1969
  border-radius: 2px;
1798
1970
  outline: none;
1799
1971
  box-shadow: 0 0 0 1px var(--qc-state-focusRing);
1800
- resize: none;
1801
- pointer-events: auto;
1802
1972
  }
1803
1973
 
1804
- [data-qc-theme] .qc-drawing-text-editor::placeholder {
1974
+ [data-qc-theme] .qc-drawing-text-editor[data-qc-editor='box']::placeholder {
1805
1975
  color: var(--qc-text-muted);
1806
1976
  }
1807
1977
 
@@ -1955,7 +2125,7 @@
1955
2125
  color: var(--qc-text-primary);
1956
2126
  background: var(--qc-chrome-surfaceRaised);
1957
2127
  border: 1px dashed var(--qc-chrome-borderStrong);
1958
- border-radius: var(--qc-chrome-radiusLarge);
2128
+ border-radius: 4px;
1959
2129
  cursor: pointer;
1960
2130
  }
1961
2131
 
@@ -1971,16 +2141,21 @@
1971
2141
  object-fit: contain;
1972
2142
  }
1973
2143
 
2144
+ /* The words a drop box states: its call at 16 on 24 with 8px around it and 8px under it, then the
2145
+ * formats and the size at 14 on 21 in the secondary ink. */
1974
2146
  [data-qc-theme] .qc-drawing-drop-words {
1975
2147
  display: flex;
1976
2148
  flex-direction: column;
1977
- gap: 4px;
1978
2149
  align-items: center;
1979
- font-size: var(--qc-text-fontSizeSmall);
2150
+ font-size: var(--qc-text-fontSizeBase);
2151
+ line-height: 21px;
1980
2152
  }
1981
2153
 
1982
2154
  [data-qc-theme] .qc-drawing-drop-title {
1983
- font-size: var(--qc-text-fontSizeBase);
2155
+ margin-bottom: 8px;
2156
+ padding: 8px;
2157
+ font-size: 16px;
2158
+ line-height: 24px;
1984
2159
  }
1985
2160
 
1986
2161
  [data-qc-theme] .qc-drawing-file {
@@ -2041,41 +2216,176 @@
2041
2216
  cursor: default;
2042
2217
  }
2043
2218
 
2044
- [data-qc-theme] .qc-drawing-select,
2045
- [data-qc-theme] .qc-drawing-input,
2046
- [data-qc-theme] .qc-drawing-number {
2047
- height: 34px;
2048
- padding: 0 10px;
2049
- font-size: var(--qc-text-fontSizeBase);
2219
+ /* On a settings page a row lays out nothing of its own: its label and its controls are the grid's
2220
+ * two cells, each 50px tall around a 34px control. A label stands 20px clear of the controls and
2221
+ * wraps rather than cutting a word short; the controls stand 8px apart. */
2222
+ [data-qc-theme] .qc-drawing-page > .qc-drawing-row {
2223
+ display: contents;
2224
+ }
2225
+
2226
+ [data-qc-theme] .qc-drawing-page .qc-drawing-row-label {
2227
+ display: flex;
2228
+ align-items: center;
2229
+ min-width: 0;
2230
+ min-height: 50px;
2231
+ padding: 8px 20px 8px 0;
2232
+ overflow: visible;
2233
+ color: var(--qc-text-primary);
2234
+ white-space: normal;
2235
+ overflow-wrap: break-word;
2236
+ }
2237
+
2238
+ [data-qc-theme] .qc-drawing-page .qc-drawing-row-controls {
2239
+ flex-wrap: nowrap;
2240
+ gap: 8px;
2241
+ min-width: 0;
2242
+ min-height: 50px;
2243
+ padding: 8px 0;
2244
+ }
2245
+
2246
+ /* A checkbox row: the 18px box 8px before its words, across both columns in a 50px row. */
2247
+ [data-qc-theme] .qc-drawing-page > .qc-drawing-toggle {
2248
+ min-height: 50px;
2050
2249
  }
2051
2250
 
2251
+ [data-qc-theme] .qc-drawing-row-full {
2252
+ display: flex;
2253
+ align-items: center;
2254
+ gap: 8px;
2255
+ min-height: 50px;
2256
+ padding: 8px 0;
2257
+ }
2258
+
2259
+ /* A section title: 11px capitals in the muted ink, in a 32px row, or in a field row's 50px where it
2260
+ * heads a list of inputs. */
2261
+ [data-qc-theme] .qc-drawing-page > .qc-drawing-section {
2262
+ display: flex;
2263
+ align-items: center;
2264
+ height: 32px;
2265
+ padding: 0;
2266
+ letter-spacing: normal;
2267
+ }
2268
+
2269
+ [data-qc-theme] .qc-drawing-page > .qc-drawing-section--row {
2270
+ height: 50px;
2271
+ }
2272
+
2273
+ /* A checkbox row in a list of inputs stands 34px, 8px around its box. */
2274
+ [data-qc-theme] .qc-drawing-page > .qc-drawing-toggle--compact {
2275
+ min-height: 34px;
2276
+ }
2277
+
2278
+ /* A row nested under the switch before it sets its label, or its labelling checkbox, 26px in. */
2279
+ [data-qc-theme] .qc-drawing-page > .qc-drawing-row--nested > .qc-drawing-row-label {
2280
+ padding-inline-start: 26px;
2281
+ }
2282
+
2283
+ /* A band on one line: its switch 16px before its name, then its multiplier 8px after the name. */
2284
+ [data-qc-theme] .qc-drawing-page > .qc-drawing-band-row > .qc-drawing-toggle {
2285
+ gap: 16px;
2286
+ }
2287
+
2288
+ [data-qc-theme] .qc-drawing-group-gap {
2289
+ height: 16px;
2290
+ }
2291
+
2292
+ /* The text fields, list buttons and number fields are the chart's 34px field box; these rules give
2293
+ * them their widths and lay a list button's face out: its words 8px in, cut short with an ellipsis,
2294
+ * then the chevron's slot 2px from the end. */
2052
2295
  [data-qc-theme] .qc-drawing-select {
2053
- min-width: 140px;
2296
+ display: inline-flex;
2297
+ flex: 0 0 auto;
2298
+ align-items: center;
2299
+ width: 100px;
2300
+ padding: 0 2px 0 7px;
2301
+ text-align: start;
2302
+ cursor: pointer;
2303
+ }
2304
+
2305
+ /* A list button's edge steps further under the pointer than another field's, below the states that
2306
+ * outrank the pointer: a field that cannot be used, a refused value and the keyboard's ring. */
2307
+ [data-qc-theme] .qc-drawing-select:hover:not(:disabled):not([aria-invalid='true']):not(:focus-visible) {
2308
+ border-color: var(--qc-control-selectEdgeHover);
2309
+ }
2310
+
2311
+ [data-qc-theme] .qc-drawing-select[data-width='medium'] {
2312
+ width: 150px;
2313
+ }
2314
+
2315
+ [data-qc-theme] .qc-drawing-select[data-width='wide'] {
2316
+ width: 180px;
2317
+ }
2318
+
2319
+ [data-qc-theme] .qc-drawing-select-value {
2320
+ flex: 1 1 auto;
2321
+ min-width: 0;
2322
+ padding-inline-end: 6px;
2323
+ overflow: hidden;
2324
+ text-overflow: ellipsis;
2325
+ white-space: nowrap;
2326
+ }
2327
+
2328
+ /* A list's rows: 32px, the words at 14 on 18 and 8px in; a row with a mark carries the 28px mark 4px
2329
+ * in and its name 6px after it; a row of a list of switches carries the settings rows' 18px checkbox
2330
+ * 8px in and its name 10px after it. The chosen row of a list of choices inverts; a ticked switch
2331
+ * keeps the list's ground, its box saying it is on. A list button's list is as wide as its
2332
+ * longest row, never narrower than the button that opened it (the button sets that floor, and a
2333
+ * list of switches is held to the button's own width). */
2334
+ [data-qc-theme] .qc-drawing-menu.qc-drawing-select-list {
2335
+ width: max-content;
2336
+ min-width: 0;
2337
+ }
2338
+
2339
+ [data-qc-theme] .qc-drawing-list-row {
2340
+ height: 32px;
2341
+ gap: 0;
2342
+ padding: 0 8px;
2343
+ line-height: 18px;
2344
+ border-radius: 6px;
2345
+ }
2346
+
2347
+ [data-qc-theme] .qc-drawing-list-row--mark {
2348
+ gap: 6px;
2349
+ padding: 0 14px 0 4px;
2350
+ }
2351
+
2352
+ [data-qc-theme] .qc-drawing-list-row--check {
2353
+ gap: 10px;
2354
+ padding: 0 8px;
2054
2355
  }
2055
2356
 
2056
2357
  [data-qc-theme] .qc-drawing-input[data-width='short'] {
2057
2358
  width: 96px;
2058
2359
  }
2059
2360
 
2060
- [data-qc-theme] .qc-drawing-input[data-width='wide'] {
2361
+ /* The text area is the field box 100px tall across the page, 172px for a tool that is its words (a
2362
+ * text, a note, a callout), its words 8px in from the sides and 5px from the top. */
2363
+ [data-qc-theme] .qc-drawing-textarea {
2061
2364
  width: 100%;
2365
+ height: 100px;
2366
+ margin: 0;
2367
+ padding: 4px 7px;
2368
+ resize: none;
2062
2369
  }
2063
2370
 
2064
- [data-qc-theme] .qc-drawing-textarea {
2065
- width: 100%;
2066
- min-height: 80px;
2067
- margin-top: 4px;
2068
- padding: 8px 10px;
2069
- font-size: var(--qc-text-fontSizeBase);
2070
- resize: vertical;
2371
+ [data-qc-theme] .qc-drawing-textarea[data-size='tall'] {
2372
+ height: 172px;
2071
2373
  }
2072
2374
 
2073
- /* The number field owns the last 26px of its box for the stepper, revealed on hover or focus. */
2375
+ /* The number field keeps the end of its box for its steppers whether they show or not: a 22 by 28
2376
+ * slot 2px in from the edge, the words stopping 2px short of it, the arrows revealed on hover or
2377
+ * focus. A field that cannot be used keeps no slot and shows no arrows, its words running to 4px
2378
+ * from its edge. The pointer on a stepper is on the field, so the edge steps up there too, at the
2379
+ * weight of the field's own pointer state. */
2074
2380
  [data-qc-theme] .qc-drawing-number-wrap {
2075
2381
  position: relative;
2076
2382
  display: inline-flex;
2077
2383
  }
2078
2384
 
2385
+ [data-qc-theme] :where(.qc-drawing-number-wrap:hover) > .qc-field {
2386
+ border-color: var(--qc-control-fieldEdgeHover);
2387
+ }
2388
+
2079
2389
  [data-qc-theme] .qc-drawing-number-wrap[data-width='short'] {
2080
2390
  width: 64px;
2081
2391
  }
@@ -2084,6 +2394,10 @@
2084
2394
  width: 84px;
2085
2395
  }
2086
2396
 
2397
+ [data-qc-theme] .qc-drawing-number-wrap[data-width='field'] {
2398
+ width: 100px;
2399
+ }
2400
+
2087
2401
  [data-qc-theme] .qc-drawing-number-wrap[data-width='wide'] {
2088
2402
  width: 112px;
2089
2403
  }
@@ -2103,11 +2417,10 @@
2103
2417
 
2104
2418
  [data-qc-theme] .qc-drawing-steppers {
2105
2419
  position: absolute;
2106
- top: 50%;
2107
- inset-inline-end: 4px;
2420
+ inset-block: 3px;
2421
+ inset-inline-end: 3px;
2108
2422
  display: none;
2109
2423
  flex-direction: column;
2110
- transform: translateY(-50%);
2111
2424
  }
2112
2425
 
2113
2426
  [data-qc-theme] .qc-drawing-number-wrap:hover .qc-drawing-steppers,
@@ -2115,18 +2428,27 @@
2115
2428
  display: flex;
2116
2429
  }
2117
2430
 
2431
+ [data-qc-theme] .qc-drawing-number:disabled {
2432
+ padding-inline-end: 4px;
2433
+ }
2434
+
2435
+ [data-qc-theme] .qc-drawing-number:disabled + .qc-drawing-steppers {
2436
+ display: none;
2437
+ }
2438
+
2118
2439
  [data-qc-theme] .qc-drawing-stepper {
2119
2440
  display: flex;
2120
2441
  align-items: center;
2121
2442
  justify-content: center;
2122
2443
  width: 22px;
2123
- height: 13px;
2444
+ height: 14px;
2124
2445
  padding: 0;
2125
- color: var(--qc-text-muted);
2446
+ color: var(--qc-chrome-caret);
2126
2447
  background: none;
2127
2448
  border: 0;
2128
- border-radius: var(--qc-chrome-radius);
2449
+ border-radius: 4px;
2129
2450
  cursor: pointer;
2451
+ transition: color var(--qc-motion-durationSlow) var(--qc-motion-easingStandard), background-color var(--qc-motion-durationSlow) var(--qc-motion-easingStandard);
2130
2452
  }
2131
2453
 
2132
2454
  [data-qc-theme] .qc-drawing-stepper[data-up='true'] svg {
@@ -2135,29 +2457,55 @@
2135
2457
 
2136
2458
  [data-qc-theme] .qc-drawing-stepper:hover {
2137
2459
  color: var(--qc-text-primary);
2138
- background: var(--qc-state-hover);
2460
+ background: var(--qc-state-pressed);
2461
+ }
2462
+
2463
+ /* The color popover and the shared color control inside it.
2464
+ *
2465
+ * The popover hangs under the swatch button that opened it, as wide as what it holds wherever it
2466
+ * opens, a 6px corner on the overlay ground, its column 6px clear of its top and bottom: the
2467
+ * palette, then for a stroke the Thickness and Line style rows. It never narrows to the room it
2468
+ * finds: the placement moves it to stay inside the box instead. A color button holding its popover
2469
+ * open rings itself as a field with the keyboard does. */
2470
+ [data-qc-theme] .qc-drawing-popover--color {
2471
+ width: max-content;
2472
+ max-width: none;
2473
+ }
2474
+
2475
+ [data-qc-theme] .qc-drawing-color-popover {
2476
+ padding: 6px 0;
2477
+ }
2478
+
2479
+ [data-qc-theme] .qc-drawing-swatch-button[aria-expanded='true'] {
2480
+ border-color: var(--qc-state-focusRing);
2481
+ box-shadow: inset 0 0 0 1px var(--qc-state-focusRing);
2139
2482
  }
2140
2483
 
2141
- /* Swatches: a ten-wide grid of squares, the plus cell, and the custom panel it opens in place. */
2484
+ /* The palette is 224px wide inside 6px by 12px: a ten-wide grid of 17px cells, each carrying its own
2485
+ * 3px gutter, in blocks that keep 6px under them (the greys and the ten hues; the six ramps; the
2486
+ * colors this viewer mixed with the plus after them), a 1px rule 12px clear of the blocks either
2487
+ * side, and the opacity under a 12px muted title. The blocks pull their outer gutters back off the
2488
+ * padding, and the rule and the title stand clear by their own margins, which take a block's in. */
2142
2489
  [data-qc-theme] .qc-drawing-palette {
2143
- display: flex;
2144
- flex-direction: column;
2490
+ box-sizing: content-box;
2491
+ width: 224px;
2492
+ padding: 6px 12px;
2493
+ }
2494
+
2495
+ /* A palette that is a popover's whole content keeps the popover column's 6px inside its own, and
2496
+ * inside a panel that pads already, the palette pads the rest of the way rather than again. */
2497
+ [data-qc-theme] .qc-drawing-popover > .qc-drawing-palette {
2145
2498
  padding: 12px;
2146
2499
  }
2147
2500
 
2148
- /* Inside a panel that pads already, the palette pads the rest of the way rather than again. */
2149
- [data-qc-theme] .qc-inline-panel > .qc-drawing-palette {
2501
+ [data-qc-theme] .qc-inline-panel .qc-drawing-palette {
2150
2502
  padding: 6px;
2151
2503
  }
2152
2504
 
2153
2505
  [data-qc-theme] .qc-drawing-swatches {
2154
- display: flex;
2155
- flex-direction: column;
2506
+ display: block;
2156
2507
  }
2157
2508
 
2158
- /* A block is a group of rows that stand together; the gap falls between blocks, never between the
2159
- * rows inside one, so the ten hues read as one field of colour rather than ten loose lines. The
2160
- * negative inline margin pulls the outer cells' own gutters back off the panel's padding. */
2161
2509
  [data-qc-theme] .qc-drawing-swatch-block {
2162
2510
  margin: 0 -3px 6px;
2163
2511
  }
@@ -2166,10 +2514,9 @@
2166
2514
  display: flex;
2167
2515
  }
2168
2516
 
2169
- /* Each cell carries its own 3px gutter rather than the row spacing them, which leaves room inside
2170
- * the cell for the ring a chosen colour wears without moving its neighbours. */
2171
2517
  [data-qc-theme] .qc-drawing-swatch {
2172
2518
  position: relative;
2519
+ flex: 0 0 17px;
2173
2520
  width: 17px;
2174
2521
  height: 17px;
2175
2522
  margin: 3px;
@@ -2177,79 +2524,243 @@
2177
2524
  background: var(--qcd-swatch);
2178
2525
  border: 0;
2179
2526
  border-radius: 2px;
2527
+ outline: none;
2180
2528
  cursor: pointer;
2181
2529
  }
2182
2530
 
2183
- /* A cell pale enough to vanish into the panel behind it says so, and takes the panel's own edge. */
2184
- [data-qc-theme] .qc-drawing-swatch[data-qc-pale='true'] {
2185
- box-shadow: inset 0 0 0 1px var(--qc-chrome-border);
2186
- }
2187
-
2188
- /* The chosen colour is ringed from OUTSIDE, so the swatch keeps its whole face: a ring drawn
2189
- * inside would eat the colour it is pointing at, which is the one thing the reader is judging. */
2190
- [data-qc-theme] .qc-drawing-swatch[data-qc-active='true']::after {
2531
+ /* A cell's ring stands 2px outside it, 2px wide on a 6px corner, and fades in and out: the field's
2532
+ * edge under the pointer, the primary ink around the chosen color (over its neighbours), and the
2533
+ * focus color where the keyboard stands. */
2534
+ [data-qc-theme] .qc-drawing-swatch::after {
2191
2535
  position: absolute;
2192
2536
  inset: -4px;
2193
- border: 2px solid var(--qc-text-primary);
2194
- border-radius: var(--qc-chrome-radius);
2537
+ border: 2px solid transparent;
2538
+ border-radius: 6px;
2195
2539
  content: '';
2540
+ pointer-events: none;
2541
+ transition: border-color var(--qc-motion-durationSlow) var(--qc-motion-easingStandard);
2196
2542
  }
2197
2543
 
2198
- /* The plus is two hairlines on the cell's own grid: a drawn cross lands dead centre where a glyph
2199
- * would ride high and left of it. The cell carries no fill and no outline of its own. */
2200
- [data-qc-theme] .qc-drawing-swatch-plus {
2201
- background: none;
2202
- box-shadow: none;
2544
+ [data-qc-theme] .qc-drawing-swatch:hover::after {
2545
+ border-color: var(--qc-control-fieldEdge);
2203
2546
  }
2204
2547
 
2205
- [data-qc-theme] .qc-drawing-swatch-plus::before,
2206
- [data-qc-theme] .qc-drawing-swatch-plus::after {
2207
- position: absolute;
2208
- inset: 8px 2px;
2209
- background: var(--qc-text-primary);
2210
- content: '';
2548
+ [data-qc-theme] .qc-drawing-swatch[data-qc-active='true']::after {
2549
+ z-index: 1;
2550
+ border-color: var(--qc-text-primary);
2551
+ }
2552
+
2553
+ [data-qc-theme] .qc-drawing-swatch:focus-visible::after {
2554
+ border-color: var(--qc-state-focusRing);
2555
+ }
2556
+
2557
+ /* On a light panel the palest cell takes the panel's own edge, where it would otherwise vanish. */
2558
+ [data-qc-theme='light'] .qc-drawing-swatch[data-qc-pale='true'] {
2559
+ box-shadow: inset 0 0 0 1px var(--qc-chrome-border);
2560
+ }
2561
+
2562
+ /* The plus: a cell with no fill of its own, crossed at its middle by two 13px hairlines in the
2563
+ * primary ink, washed in the hover fill under the pointer and ringed inside its own edge where the
2564
+ * keyboard stands. */
2565
+ [data-qc-theme] .qc-drawing-swatch-plus {
2566
+ position: relative;
2567
+ flex: 0 0 17px;
2568
+ width: 17px;
2569
+ height: 17px;
2570
+ margin: 3px;
2571
+ padding: 0;
2572
+ background: none;
2573
+ border: 0;
2574
+ border-radius: 2px;
2575
+ outline: none;
2576
+ cursor: pointer;
2577
+ transition: background-color var(--qc-motion-durationSlow) var(--qc-motion-easingStandard);
2578
+ }
2579
+
2580
+ [data-qc-theme] .qc-drawing-swatch-plus:hover {
2581
+ background: var(--qc-state-hover);
2582
+ }
2583
+
2584
+ [data-qc-theme] .qc-drawing-swatch-plus::before,
2585
+ [data-qc-theme] .qc-drawing-swatch-plus::after {
2586
+ position: absolute;
2587
+ background: var(--qc-text-primary);
2588
+ content: '';
2211
2589
  }
2212
2590
 
2213
2591
  [data-qc-theme] .qc-drawing-swatch-plus::before {
2214
- inset: 2px 8px;
2592
+ top: calc(50% - 6.5px);
2593
+ left: calc(50% - 0.5px);
2594
+ width: 1px;
2595
+ height: 13px;
2596
+ }
2597
+
2598
+ [data-qc-theme] .qc-drawing-swatch-plus::after {
2599
+ top: calc(50% - 0.5px);
2600
+ left: calc(50% - 6.5px);
2601
+ width: 13px;
2602
+ height: 1px;
2603
+ }
2604
+
2605
+ [data-qc-theme] .qc-drawing-swatch-plus:focus-visible {
2606
+ border: 2px solid var(--qc-state-focusRing);
2607
+ border-radius: 4px;
2215
2608
  }
2216
2609
 
2217
- /* The rule between the offered colours and the ones this viewer mixed. */
2218
2610
  [data-qc-theme] .qc-drawing-separator {
2219
2611
  height: 1px;
2220
- margin: 6px 0 12px;
2612
+ margin: 12px 0;
2221
2613
  background: var(--qc-overlay-separator);
2222
2614
  }
2223
2615
 
2224
- /* A quiet label over a section of the panel: the room above it is its own, so the panel holding
2225
- * it keeps no gap of its own to add to this. */
2226
2616
  [data-qc-theme] .qc-drawing-section-title {
2227
2617
  margin: 12px 0 4px;
2228
2618
  color: var(--qc-text-muted);
2229
- font-size: calc(var(--qc-text-fontSizeBase) - 2px);
2619
+ font-size: 12px;
2620
+ line-height: 14px;
2230
2621
  }
2231
2622
 
2232
- [data-qc-theme] .qc-drawing-palette-opacity {
2623
+ /* The opacity: a 10px track filling the row beside the percent field. The track fades from nothing
2624
+ * into the color over the checked ground, inside a 1px edge of the color on a 4px corner; the 12px
2625
+ * knob travels it less its own width, a pixel proud of it above and below, and glides to a value
2626
+ * the keyboard or a press gives it but follows a drag at once. The keyboard's ring stands 4px
2627
+ * around the track. */
2628
+ [data-qc-theme] .qc-drawing-opacity-row {
2233
2629
  display: flex;
2234
- flex-direction: column;
2630
+ align-items: center;
2235
2631
  }
2236
2632
 
2237
- [data-qc-theme] .qc-drawing-custom {
2633
+ [data-qc-theme] .qc-drawing-opacity {
2634
+ position: relative;
2635
+ flex: 1 0 auto;
2636
+ height: 10px;
2637
+ background: repeating-conic-gradient(from 270deg, var(--qcd-check) 0% 25%, transparent 0% 50%) 1px 50% / 8px 8px, var(--qcd-ground);
2638
+ border-radius: 5px;
2639
+ outline: none;
2640
+ touch-action: none;
2641
+ }
2642
+
2643
+ [data-qc-theme] .qc-drawing-opacity-fade {
2644
+ position: absolute;
2645
+ inset: 0;
2646
+ background: linear-gradient(to right, transparent, var(--qcd-swatch));
2647
+ border: 1px solid var(--qcd-swatch);
2648
+ border-radius: 4px;
2649
+ }
2650
+
2651
+ [data-qc-theme][dir='rtl'] .qc-drawing-opacity,
2652
+ [data-qc-theme] [dir='rtl'] .qc-drawing-opacity {
2653
+ background-position: right 1px top 50%;
2654
+ }
2655
+
2656
+ [data-qc-theme][dir='rtl'] .qc-drawing-opacity-fade,
2657
+ [data-qc-theme] [dir='rtl'] .qc-drawing-opacity-fade {
2658
+ background: linear-gradient(to left, transparent, var(--qcd-swatch));
2659
+ }
2660
+
2661
+ [data-qc-theme] .qc-drawing-opacity-travel {
2662
+ position: absolute;
2663
+ top: 0;
2664
+ inset-inline-start: 0;
2665
+ width: calc(100% - 12px);
2666
+ }
2667
+
2668
+ [data-qc-theme] .qc-drawing-opacity-knob {
2669
+ position: absolute;
2670
+ top: 0;
2671
+ width: 12px;
2672
+ height: 12px;
2673
+ margin-top: -1px;
2674
+ background: var(--qcd-black);
2675
+ border: 2px solid var(--qcd-white);
2676
+ border-radius: 50%;
2677
+ box-shadow: 0 1px 2px hsl(var(--qcd-angle-0) 0% 0% / 0.5);
2678
+ pointer-events: none;
2679
+ }
2680
+
2681
+ [data-qc-theme] .qc-drawing-opacity:not([data-qc-dragging='true']) .qc-drawing-opacity-knob {
2682
+ transition: inset-inline-start var(--qc-motion-durationGlide) var(--qc-motion-easingStandard);
2683
+ }
2684
+
2685
+ [data-qc-theme] .qc-drawing-opacity:focus-visible::after {
2686
+ position: absolute;
2687
+ inset: -4px;
2688
+ border: 2px solid var(--qc-state-focusRing);
2689
+ border-radius: 6px;
2690
+ content: '';
2691
+ pointer-events: none;
2692
+ }
2693
+
2694
+ /* The popover's two fields are 26px boxes on a 4px corner, 1px edged in the field's own edge, which
2695
+ * turns the focus color while the field has the keyboard and the invalid color for a value the
2696
+ * field refuses. The percent field is 47px, 8px after the track, its figure set to the end and the
2697
+ * unit standing in the room it keeps there. */
2698
+ [data-qc-theme] .qc-drawing-opacity-field {
2699
+ position: relative;
2238
2700
  display: flex;
2239
- flex-direction: column;
2240
- gap: 12px;
2241
- width: 224px;
2701
+ flex: 0 0 auto;
2702
+ align-items: center;
2703
+ }
2704
+
2705
+ [data-qc-theme] .qc-drawing-opacity-readout,
2706
+ [data-qc-theme] .qc-drawing-hex {
2707
+ box-sizing: border-box;
2708
+ height: 26px;
2709
+ margin: 0;
2710
+ margin-inline-start: 8px;
2711
+ color: var(--qc-text-primary);
2712
+ font: inherit;
2713
+ font-size: 14px;
2714
+ line-height: 24px;
2715
+ background: none;
2716
+ border: 1px solid var(--qc-control-fieldEdge);
2717
+ border-radius: 4px;
2718
+ outline: none;
2719
+ }
2720
+
2721
+ [data-qc-theme] .qc-drawing-opacity-readout {
2722
+ width: 47px;
2723
+ padding: 0;
2724
+ padding-inline-start: 5px;
2725
+ padding-inline-end: 14px;
2726
+ text-align: end;
2727
+ }
2728
+
2729
+ [data-qc-theme] .qc-drawing-opacity-readout:focus,
2730
+ [data-qc-theme] .qc-drawing-hex:focus {
2731
+ border-color: var(--qc-state-focusRing);
2732
+ }
2733
+
2734
+ [data-qc-theme] .qc-drawing-hex[aria-invalid='true'] {
2735
+ border-color: var(--qc-control-fieldInvalid);
2736
+ }
2737
+
2738
+ [data-qc-theme] .qc-drawing-opacity-unit,
2739
+ [data-qc-theme] .qc-drawing-hex-mark {
2740
+ position: absolute;
2741
+ top: 5px;
2742
+ color: var(--qc-text-primary);
2743
+ line-height: 16px;
2744
+ pointer-events: none;
2745
+ }
2746
+
2747
+ [data-qc-theme] .qc-drawing-opacity-unit {
2748
+ inset-inline-start: 40px;
2242
2749
  }
2243
2750
 
2751
+ /* The custom editor, standing alone in the popover in the palette's place: a 26px row of the held
2752
+ * color's 26px well, its hex and Add, 12px over a 184px area of saturation and brightness that
2753
+ * stands 7px before a 17px hue strip. The hash stands in the room the hex field keeps before its
2754
+ * digits; Add is the primary action at the row's end, a 28px button on an 8px corner. */
2244
2755
  [data-qc-theme] .qc-drawing-custom-row {
2245
2756
  display: flex;
2246
- gap: 8px;
2247
- align-items: center;
2757
+ align-items: flex-start;
2248
2758
  height: 26px;
2759
+ margin-bottom: 12px;
2249
2760
  }
2250
2761
 
2251
2762
  [data-qc-theme] .qc-drawing-custom-swatch {
2252
- flex: 0 0 auto;
2763
+ flex: 0 0 26px;
2253
2764
  width: 26px;
2254
2765
  height: 26px;
2255
2766
  background: var(--qcd-swatch);
@@ -2257,43 +2768,26 @@
2257
2768
  }
2258
2769
 
2259
2770
  [data-qc-theme] .qc-drawing-hex-wrap {
2771
+ position: relative;
2260
2772
  display: flex;
2261
2773
  flex: 0 0 auto;
2262
2774
  align-items: center;
2263
- width: 68px;
2264
- min-width: 0;
2265
2775
  height: 26px;
2266
- padding: 0 5px;
2267
- border: 1px solid var(--qc-chrome-grip);
2268
- border-radius: 4px;
2269
- }
2270
-
2271
- [data-qc-theme] .qc-drawing-hex-wrap > .qc-muted {
2272
- flex: 0 0 7px;
2273
2776
  }
2274
2777
 
2275
- /* A field says it has the keyboard on its OWN box: its edge turns the ring colour, one line on the
2276
- * field's exact edge following its corner. A ring the browser draws would sit square outside a
2277
- * rounded field and belong to nothing. */
2278
- [data-qc-theme] .qc-drawing-hex-wrap:focus-within,
2279
- [data-qc-theme] .qc-drawing-opacity-readout:focus-visible {
2280
- border-color: var(--qc-state-focusRing);
2778
+ [data-qc-theme] .qc-drawing-hex-mark {
2779
+ inset-inline-start: 0;
2780
+ width: 21px;
2781
+ text-align: end;
2281
2782
  }
2282
2783
 
2283
2784
  [data-qc-theme] .qc-drawing-hex {
2284
- width: 100%;
2285
- min-width: 0;
2785
+ width: 68px;
2286
2786
  padding: 0;
2287
- color: var(--qc-text-primary);
2288
- font: inherit;
2289
- font-variant-numeric: tabular-nums;
2290
- background: none;
2291
- border: 0;
2292
- outline: none;
2787
+ padding-inline-start: 12px;
2788
+ padding-inline-end: 5px;
2293
2789
  }
2294
2790
 
2295
- /* The Add button takes the colour the mixer is holding. It is sized to its own word and pushed to
2296
- * the end of the row; its fill and ink are the primary recipe's. */
2297
2791
  [data-qc-theme] .qc-drawing-add {
2298
2792
  display: inline-flex;
2299
2793
  flex: 0 0 auto;
@@ -2302,6 +2796,9 @@
2302
2796
  height: 28px;
2303
2797
  margin-inline-start: auto;
2304
2798
  padding: 0 7px;
2799
+ font-size: 14px;
2800
+ line-height: 18px;
2801
+ border-radius: 8px;
2305
2802
  }
2306
2803
 
2307
2804
  [data-qc-theme] .qc-drawing-custom-tracks {
@@ -2309,28 +2806,43 @@
2309
2806
  gap: 7px;
2310
2807
  }
2311
2808
 
2312
- /* The saturation and value square over the current hue, and the hue strip beside it. The square
2313
- * keeps square corners: the black it fades into is a second layer over its whole face, and a
2314
- * rounded corner would show the hue beneath it. */
2809
+ /* The area is the hue under a fade to white across it and a fade to black down it, on a 2px corner
2810
+ * that clips its knob: a 14px ring standing a pixel past the point it marks. The strip runs the hue
2811
+ * wheel from top to bottom; its knob is a 9px bar 2px proud of either side, travelling the strip
2812
+ * less 3px at either end. Both knobs glide to a value the keyboard gives them and follow a drag at
2813
+ * once. */
2315
2814
  [data-qc-theme] .qc-drawing-sv {
2316
2815
  position: relative;
2317
2816
  flex: 1 1 auto;
2318
2817
  height: 184px;
2319
- background: linear-gradient(to top, var(--qcd-black), transparent), linear-gradient(to right, var(--qcd-white), var(--qcd-hue));
2818
+ overflow: hidden;
2819
+ background: linear-gradient(to top, var(--qcd-black), transparent), linear-gradient(to right, var(--qcd-white), transparent), var(--qcd-hue);
2820
+ border-radius: 2px;
2320
2821
  cursor: crosshair;
2822
+ touch-action: none;
2823
+ }
2824
+
2825
+ [data-qc-theme][dir='rtl'] .qc-drawing-sv,
2826
+ [data-qc-theme] [dir='rtl'] .qc-drawing-sv {
2827
+ background: linear-gradient(to top, var(--qcd-black), transparent), linear-gradient(to left, var(--qcd-white), transparent), var(--qcd-hue);
2321
2828
  }
2322
2829
 
2323
2830
  [data-qc-theme] .qc-drawing-sv-dot {
2324
2831
  position: absolute;
2325
- width: 12px;
2326
- height: 12px;
2832
+ width: 14px;
2833
+ height: 14px;
2834
+ margin-top: -6px;
2835
+ margin-inline-start: -6px;
2327
2836
  border: 2px solid var(--qcd-white);
2328
2837
  border-radius: 50%;
2329
- box-shadow: var(--qc-overlay-shadow);
2330
- transform: translate(-50%, -50%);
2838
+ box-shadow: 0 1px 2px hsl(var(--qcd-angle-0) 0% 0% / 0.5);
2331
2839
  pointer-events: none;
2332
2840
  }
2333
2841
 
2842
+ [data-qc-theme] .qc-drawing-sv:not([data-qc-dragging='true']) .qc-drawing-sv-dot {
2843
+ transition: inset-inline-start var(--qc-motion-durationFast) var(--qc-motion-easingStandard), top var(--qc-motion-durationFast) var(--qc-motion-easingStandard);
2844
+ }
2845
+
2334
2846
  [data-qc-theme] .qc-drawing-hue {
2335
2847
  position: relative;
2336
2848
  flex: 0 0 17px;
@@ -2347,38 +2859,70 @@
2347
2859
  );
2348
2860
  border-radius: 2px;
2349
2861
  cursor: pointer;
2862
+ touch-action: none;
2863
+ }
2864
+
2865
+ [data-qc-theme] .qc-drawing-hue-travel {
2866
+ position: absolute;
2867
+ inset: 3px 0;
2350
2868
  }
2351
2869
 
2352
2870
  [data-qc-theme] .qc-drawing-hue-dot {
2353
2871
  position: absolute;
2354
2872
  inset-inline: -2px;
2355
- height: 6px;
2873
+ height: 9px;
2874
+ margin-top: -4px;
2356
2875
  border: 2px solid var(--qcd-white);
2357
2876
  border-radius: 2px;
2358
- box-shadow: var(--qc-overlay-shadow);
2359
- transform: translateY(-50%);
2877
+ box-shadow: 0 1px 2px hsl(var(--qcd-angle-0) 0% 0% / 0.5);
2360
2878
  pointer-events: none;
2361
2879
  }
2362
2880
 
2363
- /* Black and white are the poles of the value axis the square fades between, and the two the
2364
- * opacity knob is drawn from. They are color arithmetic, not theme roles: every mode has them. */
2881
+ [data-qc-theme] .qc-drawing-hue:not([data-qc-dragging='true']) .qc-drawing-hue-dot {
2882
+ transition: top var(--qc-motion-durationFast) var(--qc-motion-easingStandard);
2883
+ }
2884
+
2885
+ /* The well a color button holds its color in: 24px on a 3px corner, the color at its opacity over
2886
+ * the checked ground the opacity track fades over, in 6px squares. */
2887
+ [data-qc-theme] .qc-drawing-well {
2888
+ display: block;
2889
+ width: 24px;
2890
+ height: 24px;
2891
+ overflow: hidden;
2892
+ background: repeating-conic-gradient(from 270deg, var(--qcd-check) 0% 25%, transparent 0% 50%) 0 0 / 12px 12px, var(--qcd-ground);
2893
+ border-radius: 3px;
2894
+ }
2895
+
2896
+ [data-qc-theme] .qc-drawing-well-fill {
2897
+ display: block;
2898
+ width: 100%;
2899
+ height: 100%;
2900
+ background: var(--qcd-swatch);
2901
+ }
2902
+
2903
+ /* Black and white are the poles of the value axis the area fades between, and the two the knobs
2904
+ * are drawn from. They are color arithmetic, not theme roles: every mode has them. */
2365
2905
  [data-qc-theme] .qc-drawing-custom,
2366
- [data-qc-theme] .qc-drawing-opacity-row {
2906
+ [data-qc-theme] .qc-drawing-opacity-row,
2907
+ [data-qc-theme] .qc-drawing-well,
2908
+ [data-qc-theme] .qc-drawing-dual {
2367
2909
  --qcd-angle-0: 0deg;
2368
2910
  --qcd-black: hsl(var(--qcd-angle-0) 0% 0%);
2369
2911
  --qcd-white: hsl(var(--qcd-angle-0) 0% 100%);
2370
2912
  }
2371
2913
 
2372
- /* What "see-through" is drawn as under the fade: a slate check at two fifths, the same in every
2373
- * mode, on the mode's own pole. It is the checker every image editor uses for nothing-here, so a
2374
- * low opacity reads as the drawing thinning out rather than as the track running out of paint. */
2375
- [data-qc-theme] .qc-drawing-opacity-row {
2914
+ /* What "see-through" is drawn as under a fade: a slate check at two fifths, the same in every mode,
2915
+ * on the mode's own pole. It is the checker every image editor uses for nothing-here, so a low
2916
+ * opacity reads as the color thinning out rather than as the track running out of paint. */
2917
+ [data-qc-theme] .qc-drawing-opacity-row,
2918
+ [data-qc-theme] .qc-drawing-well {
2376
2919
  --qcd-check-hue: 224deg;
2377
2920
  --qcd-check: hsl(var(--qcd-check-hue) 15% 19% / 0.4);
2378
2921
  --qcd-ground: var(--qcd-black);
2379
2922
  }
2380
2923
 
2381
- [data-qc-theme='light'] .qc-drawing-opacity-row {
2924
+ [data-qc-theme='light'] .qc-drawing-opacity-row,
2925
+ [data-qc-theme='light'] .qc-drawing-well {
2382
2926
  --qcd-ground: var(--qcd-white);
2383
2927
  }
2384
2928
 
@@ -2397,136 +2941,202 @@
2397
2941
  --qcd-hue-300: hsl(var(--qcd-angle-300) 100% 50%);
2398
2942
  }
2399
2943
 
2400
- /* The opacity slider fades a checked ground into the color being set. */
2401
- [data-qc-theme] .qc-drawing-opacity-row {
2944
+ /* The Thickness and Line style rows, 12px in: a muted title, then a row of joined 32px segments,
2945
+ * each a radio wearing its mark in the on fill. The one chosen takes that fill, its mark cut from
2946
+ * it in the inverse ink; a segment under the pointer washes in the hover fill, and the keyboard's
2947
+ * ring stands 4px around the segment it is on. A thickness mark is a line across its segment as
2948
+ * heavy as the width it stands for; a line style's is drawn on a 30 by 24 cell, a 30px line, four
2949
+ * 5px dashes or six 2px dots 3px apart. */
2950
+ [data-qc-theme] .qc-drawing-stroke-section {
2951
+ padding: 0 12px;
2952
+ }
2953
+
2954
+ [data-qc-theme] .qc-drawing-stroke-section > .qc-drawing-section-title {
2955
+ margin: 6px 0 4px;
2956
+ }
2957
+
2958
+ [data-qc-theme] .qc-drawing-stroke-section--style {
2959
+ margin-top: 12px;
2960
+ }
2961
+
2962
+ [data-qc-theme] .qc-drawing-stroke-section--style > .qc-drawing-section-title {
2963
+ margin-top: 0;
2964
+ }
2965
+
2966
+ [data-qc-theme] .qc-drawing-segments {
2402
2967
  display: flex;
2403
- gap: 8px;
2404
- align-items: center;
2405
2968
  }
2406
2969
 
2407
- [data-qc-theme] .qc-drawing-opacity {
2408
- flex: 1 1 auto;
2409
- width: auto;
2410
- height: 10px;
2970
+ [data-qc-theme] .qc-drawing-segment {
2971
+ position: relative;
2972
+ display: inline-flex;
2973
+ flex: 1 1 0;
2974
+ align-items: center;
2975
+ justify-content: center;
2976
+ box-sizing: border-box;
2977
+ height: 32px;
2411
2978
  margin: 0;
2412
- /* Three layers, top down: the fade into the color, the 8px check it fades over (two 4px squares
2413
- * to a tile, top left and bottom right), and the ground the check stands on. */
2414
- background:
2415
- linear-gradient(to right, transparent, var(--qcd-swatch)),
2416
- repeating-conic-gradient(from 270deg, var(--qcd-check) 0% 25%, transparent 0% 50%) 1px 50% / 8px 8px,
2417
- var(--qcd-ground);
2418
- border: 1px solid var(--qcd-swatch);
2419
- border-radius: 5px;
2979
+ padding: 0 12px;
2980
+ color: var(--qc-control-on);
2981
+ background: none;
2982
+ border: 1px solid var(--qc-control-fieldEdge);
2983
+ border-radius: 0;
2420
2984
  outline: none;
2421
- appearance: none;
2422
- accent-color: var(--qc-state-accent);
2985
+ cursor: pointer;
2423
2986
  }
2424
2987
 
2425
- /* The thumb is a disc a hand can take: it says so with the pointer cursor, and it is drawn from
2426
- * the two poles rather than from the theme, so it reads at both ends of the fade in either mode. */
2427
- [data-qc-theme] .qc-drawing-opacity::-webkit-slider-thumb {
2428
- width: 12px;
2429
- height: 12px;
2430
- background: var(--qcd-black);
2431
- border: 2px solid var(--qcd-white);
2432
- border-radius: 50%;
2433
- box-shadow: 0 1px 2px hsl(var(--qcd-angle-0) 0% 0% / 0.5);
2434
- cursor: pointer;
2435
- appearance: none;
2988
+ [data-qc-theme] .qc-drawing-segment--wide {
2989
+ padding: 0 22px;
2436
2990
  }
2437
2991
 
2438
- [data-qc-theme] .qc-drawing-opacity::-moz-range-thumb {
2439
- width: 12px;
2440
- height: 12px;
2441
- background: var(--qcd-black);
2442
- border: 2px solid var(--qcd-white);
2443
- border-radius: 50%;
2444
- box-shadow: 0 1px 2px hsl(var(--qcd-angle-0) 0% 0% / 0.5);
2445
- cursor: pointer;
2992
+ [data-qc-theme] .qc-drawing-segment + .qc-drawing-segment {
2993
+ margin-inline-start: -1px;
2446
2994
  }
2447
2995
 
2448
- /* The readout is a FIELD beside the track: outlined rather than washed, because it is a number a
2449
- * viewer types over and not a chip the panel is showing them. */
2450
- [data-qc-theme] .qc-drawing-opacity-field {
2451
- position: relative;
2452
- flex: 0 0 auto;
2996
+ [data-qc-theme] .qc-drawing-segment:first-child {
2997
+ border-start-start-radius: 3px;
2998
+ border-end-start-radius: 3px;
2453
2999
  }
2454
3000
 
2455
- [data-qc-theme] .qc-drawing-opacity-readout {
2456
- width: 47px;
2457
- height: 26px;
2458
- padding: 0 14px 0 5px;
2459
- color: var(--qc-text-primary);
2460
- font: inherit;
2461
- font-variant-numeric: tabular-nums;
2462
- background: none;
2463
- border: 1px solid var(--qc-chrome-grip);
2464
- border-radius: 4px;
2465
- outline: none;
3001
+ [data-qc-theme] .qc-drawing-segment:last-child {
3002
+ border-start-end-radius: 3px;
3003
+ border-end-end-radius: 3px;
2466
3004
  }
2467
3005
 
2468
- /* The unit sits in the room the field keeps at its end, so a typed number never runs under it. */
2469
- [data-qc-theme] .qc-drawing-opacity-unit {
3006
+ [data-qc-theme] .qc-drawing-segment:hover {
3007
+ background: var(--qc-state-hover);
3008
+ }
3009
+
3010
+ [data-qc-theme] .qc-drawing-segment[aria-checked='true'] {
3011
+ z-index: 1;
3012
+ color: var(--qc-control-onInk);
3013
+ background: var(--qc-control-on);
3014
+ border-color: var(--qc-control-on);
3015
+ }
3016
+
3017
+ [data-qc-theme] .qc-drawing-segment:focus-visible::after {
2470
3018
  position: absolute;
2471
- inset-block: 0;
2472
- inset-inline-end: 5px;
2473
- display: flex;
2474
- align-items: center;
2475
- color: var(--qc-text-primary);
3019
+ inset: -4px;
3020
+ z-index: 1;
3021
+ border: 2px solid var(--qc-state-focusRing);
3022
+ border-radius: 4px;
3023
+ content: '';
2476
3024
  pointer-events: none;
2477
3025
  }
2478
3026
 
2479
- /* The swatch button: a well holding the color, and for a stroke, the stroke at its thickness. */
2480
- [data-qc-theme] .qc-drawing-swatch-button {
3027
+ [data-qc-theme] .qc-drawing-thickness-mark {
3028
+ display: block;
3029
+ flex: 1 1 auto;
3030
+ background: currentColor;
3031
+ }
3032
+
3033
+ [data-qc-theme] .qc-drawing-style-mark {
2481
3034
  display: flex;
2482
- gap: 6px;
3035
+ flex: 0 0 30px;
3036
+ gap: 3px;
2483
3037
  align-items: center;
2484
3038
  justify-content: center;
2485
- height: 34px;
2486
- padding: 0 8px;
2487
- cursor: pointer;
2488
- }
2489
-
2490
- [data-qc-theme] .qc-drawing-well {
2491
- display: block;
2492
- width: 24px;
3039
+ width: 30px;
2493
3040
  height: 24px;
2494
3041
  overflow: hidden;
2495
- background: repeating-conic-gradient(var(--qc-chrome-border) 0% 25%, var(--qc-chrome-surfaceRaised) 0% 50%) 0 0 / 8px 8px;
2496
- border-radius: 3px;
2497
3042
  }
2498
3043
 
2499
- [data-qc-theme] .qc-drawing-well-fill {
2500
- display: block;
2501
- width: 100%;
2502
- height: 100%;
2503
- background: var(--qcd-swatch);
3044
+ [data-qc-theme] .qc-drawing-style-seg {
3045
+ flex: 0 0 auto;
3046
+ width: 5px;
3047
+ height: 1px;
3048
+ background: currentColor;
2504
3049
  }
2505
3050
 
2506
- [data-qc-theme] .qc-drawing-swatch-panel {
2507
- display: flex;
2508
- flex-direction: column;
2509
- gap: 6px;
2510
- padding-bottom: 8px;
3051
+ [data-qc-theme] .qc-drawing-style-mark[data-style='solid'] > .qc-drawing-style-seg {
3052
+ width: 30px;
2511
3053
  }
2512
3054
 
2513
- [data-qc-theme] .qc-drawing-swatch-panel > .qc-muted {
2514
- padding: 0 12px;
3055
+ [data-qc-theme] .qc-drawing-style-mark[data-style='dotted'] > .qc-drawing-style-seg {
3056
+ width: 2px;
3057
+ height: 2px;
2515
3058
  }
2516
3059
 
2517
- [data-qc-theme] .qc-drawing-option-row {
2518
- display: flex;
2519
- gap: 4px;
2520
- padding: 0 12px;
3060
+ /* The line-end list is as wide as its rows. A row it does not hold dims its ink under the pointer. */
3061
+ [data-qc-theme] .qc-drawing-menu.qc-drawing-line-ends {
3062
+ width: max-content;
3063
+ min-width: 0;
3064
+ }
3065
+
3066
+ /* The keyboard rings a list's row inside the row's own edge, where the list's rounded corners cannot
3067
+ * cut it. A row of a list of choices or of switches rings its edge on a 6px corner, with 2px of the
3068
+ * list's ground inside the ring, so the ring stands clear of a chosen row's fill; a row of a list of
3069
+ * marks (a line end, a thickness, a line style) rings 2px inside its edge on a 9px corner. */
3070
+ [data-qc-theme] .qc-drawing-list .qc-drawing-list-row {
3071
+ position: relative;
3072
+ outline: none;
3073
+ }
3074
+
3075
+ [data-qc-theme] .qc-drawing-select-list:not(.qc-drawing-mark-list) .qc-drawing-list-row:focus-visible::before,
3076
+ [data-qc-theme] .qc-drawing-select-list:not(.qc-drawing-mark-list) .qc-drawing-list-row:focus-visible::after {
3077
+ position: absolute;
3078
+ z-index: 1;
3079
+ box-sizing: border-box;
3080
+ border-style: solid;
3081
+ border-width: 2px;
3082
+ content: '';
3083
+ pointer-events: none;
3084
+ }
3085
+
3086
+ [data-qc-theme] .qc-drawing-select-list:not(.qc-drawing-mark-list) .qc-drawing-list-row:focus-visible::after {
3087
+ inset: 0;
3088
+ border-color: var(--qc-state-focusRing);
3089
+ border-radius: 6px;
3090
+ }
3091
+
3092
+ [data-qc-theme] .qc-drawing-select-list:not(.qc-drawing-mark-list) .qc-drawing-list-row:focus-visible::before {
3093
+ inset: 2px;
3094
+ border-color: var(--qc-overlay-surface);
3095
+ border-radius: 4px;
3096
+ }
3097
+
3098
+ [data-qc-theme] .qc-drawing-line-ends .qc-drawing-list-row[aria-selected='true'] {
3099
+ color: var(--qc-control-onInk);
3100
+ }
3101
+
3102
+ [data-qc-theme] .qc-drawing-line-ends .qc-drawing-list-row:not([aria-selected='true']):hover {
3103
+ color: var(--qc-state-hoverInk);
3104
+ }
3105
+
3106
+ [data-qc-theme] .qc-drawing-line-ends .qc-drawing-list-row:focus-visible::after,
3107
+ [data-qc-theme] .qc-drawing-mark-list .qc-drawing-list-row:focus-visible::after {
3108
+ position: absolute;
3109
+ inset: 2px;
3110
+ z-index: 1;
3111
+ border: 2px solid var(--qc-state-focusRing);
3112
+ border-radius: 9px;
3113
+ content: '';
3114
+ pointer-events: none;
2521
3115
  }
2522
3116
 
2523
- [data-qc-theme] .qc-drawing-option {
3117
+ /* The swatch button: a well holding the color, and for a stroke, the stroke at its thickness. */
3118
+ [data-qc-theme] .qc-drawing-swatch-button {
2524
3119
  display: flex;
2525
- flex: 1 1 auto;
3120
+ gap: 6px;
2526
3121
  align-items: center;
2527
3122
  justify-content: center;
2528
- height: 30px;
2529
- padding: 0;
3123
+ height: 34px;
3124
+ padding: 0 8px;
3125
+ cursor: pointer;
3126
+ }
3127
+
3128
+ /* On a settings page the swatch button is the 34px field with a 6px corner around its 24px well, 4px
3129
+ * in; with a stroke the preview stands 8px after the well and 3px clear of the end, 75px in all. */
3130
+ [data-qc-theme] .qc-drawing-page .qc-drawing-swatch-button {
3131
+ flex: 0 0 auto;
3132
+ gap: 8px;
3133
+ min-width: 34px;
3134
+ padding: 0 4px;
3135
+ border-radius: 6px;
3136
+ }
3137
+
3138
+ [data-qc-theme] .qc-drawing-page .qc-drawing-swatch-button > .qc-drawing-stroke {
3139
+ margin-inline-end: 3px;
2530
3140
  }
2531
3141
 
2532
3142
  /* The stroke preview: segments at the thickness, in currentColor or the drawing's own color. */
@@ -2547,12 +3157,13 @@
2547
3157
  background: var(--qcd-swatch, currentColor);
2548
3158
  }
2549
3159
 
3160
+ /* A line-end picker is a 34px field whose face is the end's own 28px mark. */
2550
3161
  [data-qc-theme] .qc-drawing-line-end {
2551
3162
  display: flex;
3163
+ flex: 0 0 34px;
2552
3164
  align-items: center;
2553
3165
  justify-content: center;
2554
3166
  width: 34px;
2555
- height: 34px;
2556
3167
  padding: 0;
2557
3168
  cursor: pointer;
2558
3169
  }
@@ -2563,74 +3174,15 @@
2563
3174
  transform: scaleX(-1);
2564
3175
  }
2565
3176
 
2566
- /* The dialog's page strip: equal tabs, each with its own rail segment, the active one bright. */
2567
- [data-qc-theme] .qc-drawing-tabs {
2568
- display: flex;
2569
- align-items: stretch;
2570
- padding-bottom: 8px;
2571
- }
2572
-
2573
- [data-qc-theme] .qc-drawing-tab {
2574
- display: flex;
2575
- flex: 1 1 0;
2576
- flex-direction: column;
2577
- gap: 6px;
2578
- padding: 2px 0 0;
2579
- color: var(--qc-text-muted);
2580
- font: inherit;
2581
- font-weight: 500;
2582
- background: none;
2583
- border: 0;
2584
- cursor: pointer;
2585
- }
2586
-
2587
- [data-qc-theme] .qc-drawing-tab:hover {
2588
- color: var(--qc-text-secondary);
2589
- }
2590
-
2591
- [data-qc-theme] .qc-drawing-tab[aria-selected='true'] {
2592
- color: var(--qc-text-primary);
2593
- }
2594
-
2595
- [data-qc-theme] .qc-drawing-tab-rail {
2596
- height: 2px;
2597
- background: var(--qc-chrome-border);
2598
- }
2599
-
2600
- [data-qc-theme] .qc-drawing-tab:first-child .qc-drawing-tab-rail {
2601
- border-start-start-radius: 2px;
2602
- border-end-start-radius: 2px;
2603
- }
2604
-
2605
- [data-qc-theme] .qc-drawing-tab:last-child .qc-drawing-tab-rail {
2606
- border-start-end-radius: 2px;
2607
- border-end-end-radius: 2px;
2608
- }
2609
-
2610
- [data-qc-theme] .qc-drawing-tab[aria-selected='true'] .qc-drawing-tab-rail {
2611
- background: var(--qc-text-primary);
2612
- }
2613
-
2614
- /* One visibility bucket: the checkbox beside the word, then from, the two-thumb range, and to. */
2615
- [data-qc-theme] .qc-drawing-visibility-row {
2616
- display: grid;
2617
- grid-template-columns: 96px 1fr;
2618
- gap: 12px;
2619
- align-items: center;
2620
- min-height: 50px;
2621
- }
2622
-
2623
- [data-qc-theme] .qc-drawing-visibility-controls {
2624
- display: flex;
2625
- gap: 8px;
2626
- align-items: center;
2627
- }
2628
-
3177
+ /* One visibility bucket: the checkbox and the name as the label, then from, the two-thumb range and
3178
+ * to. The range is a 10px track 100px wide, 9px after from and 8px before to, its span between the
3179
+ * two thumbs filled. */
2629
3180
  [data-qc-theme] .qc-drawing-dual {
2630
3181
  position: relative;
2631
- flex: 1 1 auto;
2632
- min-width: 96px;
2633
- height: 16px;
3182
+ flex: 0 0 100px;
3183
+ width: 100px;
3184
+ height: 12px;
3185
+ margin-inline-start: 1px;
2634
3186
  }
2635
3187
 
2636
3188
  [data-qc-theme] .qc-drawing-dual-track {
@@ -2638,18 +3190,22 @@
2638
3190
  inset-inline: 0;
2639
3191
  top: 50%;
2640
3192
  height: 10px;
2641
- background: var(--qc-chrome-border);
3193
+ background: var(--qc-state-pressed);
2642
3194
  border-radius: 5px;
2643
3195
  transform: translateY(-50%);
2644
3196
  }
2645
3197
 
3198
+ /* The span the thumbs travel: the track less half a thumb at either end. */
3199
+ [data-qc-theme] .qc-drawing-dual-span {
3200
+ position: absolute;
3201
+ inset: 0 6px;
3202
+ }
3203
+
2646
3204
  [data-qc-theme] .qc-drawing-dual-fill {
2647
3205
  position: absolute;
2648
- top: 50%;
2649
- height: 10px;
2650
- background: var(--qc-text-secondary);
2651
- border-radius: 5px;
2652
- transform: translateY(-50%);
3206
+ top: 0;
3207
+ bottom: 0;
3208
+ background: var(--qc-text-primary);
2653
3209
  }
2654
3210
 
2655
3211
  [data-qc-theme] .qc-drawing-dual-input {
@@ -2663,22 +3219,29 @@
2663
3219
  pointer-events: none;
2664
3220
  }
2665
3221
 
3222
+ /* The two-thumb range's thumbs are the opacity knob: a dark disc with a 2px light rim, drawn from
3223
+ * the two poles so they read at both ends of the track in either mode. */
2666
3224
  [data-qc-theme] .qc-drawing-dual-input::-webkit-slider-thumb {
2667
3225
  width: 12px;
2668
3226
  height: 12px;
2669
- background: var(--qc-text-primary);
2670
- border: 2px solid var(--qc-chrome-surface);
3227
+ background: var(--qcd-black);
3228
+ border: 2px solid var(--qcd-white);
2671
3229
  border-radius: 50%;
3230
+ box-shadow: 0 1px 2px hsl(var(--qcd-angle-0) 0% 0% / 0.5);
3231
+ cursor: pointer;
2672
3232
  appearance: none;
2673
3233
  pointer-events: auto;
2674
3234
  }
2675
3235
 
2676
3236
  [data-qc-theme] .qc-drawing-dual-input::-moz-range-thumb {
2677
- width: 10px;
2678
- height: 10px;
2679
- background: var(--qc-text-primary);
2680
- border: 2px solid var(--qc-chrome-surface);
3237
+ box-sizing: border-box;
3238
+ width: 12px;
3239
+ height: 12px;
3240
+ background: var(--qcd-black);
3241
+ border: 2px solid var(--qcd-white);
2681
3242
  border-radius: 50%;
3243
+ box-shadow: 0 1px 2px hsl(var(--qcd-angle-0) 0% 0% / 0.5);
3244
+ cursor: pointer;
2682
3245
  pointer-events: auto;
2683
3246
  }
2684
3247
 
@@ -2694,50 +3257,39 @@
2694
3257
  align-items: center;
2695
3258
  }
2696
3259
 
2697
- [data-qc-theme] .qc-drawing-weight {
2698
- width: 28px;
2699
- height: 28px;
2700
- padding: 0;
2701
- }
2702
-
2703
- /* A row of cells wider than the dialog slides sideways under the pointer already on it; a bar
2704
- * beneath it would be chrome the table does not own. */
2705
- [data-qc-theme] .qc-drawing-table {
2706
- display: flex;
2707
- flex-direction: column;
2708
- gap: 4px;
2709
- overflow-x: auto;
2710
- scrollbar-width: none;
2711
- }
2712
-
2713
- [data-qc-theme] .qc-drawing-table::-webkit-scrollbar {
2714
- display: none;
2715
- }
2716
-
2717
- [data-qc-theme] .qc-drawing-table-row {
3260
+ /* The weight and slant toggles: a 34px field with a 6px corner around the 28px mark, filled while
3261
+ * held, the mark cut from the fill in the inverse ink. */
3262
+ [data-qc-theme] .qc-drawing-font-toggle {
2718
3263
  display: flex;
2719
- gap: 4px;
2720
- }
2721
-
2722
- [data-qc-theme] .qc-drawing-table-actions {
2723
- display: flex;
2724
- flex-wrap: wrap;
2725
- gap: 6px;
2726
- padding-top: 4px;
3264
+ flex: 0 0 34px;
3265
+ align-items: center;
3266
+ justify-content: center;
3267
+ width: 34px;
3268
+ padding: 0;
3269
+ border-radius: 6px;
3270
+ cursor: pointer;
2727
3271
  }
2728
3272
 
2729
- [data-qc-theme] .qc-drawing-table-actions .qc-button {
2730
- padding: 4px 8px;
2731
- font-size: var(--qc-text-fontSizeSmall);
3273
+ [data-qc-theme] .qc-drawing-font-toggle[aria-pressed='true'] {
3274
+ color: var(--qc-text-inverse);
3275
+ background: var(--qc-control-onPressed);
3276
+ border-color: var(--qc-control-onPressed);
2732
3277
  }
2733
3278
 
2734
- /* Forced colors: a swatch IS its color, so it keeps it, with a system border to stand on. */
3279
+ /* Forced colors: a swatch IS its color, so it keeps it, with a system border to stand on. The color
3280
+ * popover's compact fields edge their focus in the system highlight. */
2735
3281
  @media (forced-colors: active) {
2736
3282
  [data-qc-theme] .qc-drawing-swatch,
2737
3283
  [data-qc-theme] .qc-drawing-color-strip {
2738
3284
  forced-color-adjust: none;
2739
3285
  border: 1px solid ButtonText;
2740
3286
  }
3287
+
3288
+ [data-qc-theme] .qc-drawing-hex:focus,
3289
+ [data-qc-theme] .qc-drawing-opacity-readout:focus {
3290
+ forced-color-adjust: none;
3291
+ border-color: Highlight;
3292
+ }
2741
3293
  }
2742
3294
 
2743
3295
  /* The selected drawing's settings bar, the settings dialog and the template dialogs. Same scoping
@@ -2791,242 +3343,677 @@
2791
3343
  transition: background-color var(--qc-motion-durationFast) var(--qc-motion-easingLinear);
2792
3344
  }
2793
3345
 
2794
- [data-qc-theme] .qc-drawing-bar-wide {
2795
- width: auto;
2796
- padding: 0 11px 0 10px;
2797
- font-variant-numeric: tabular-nums;
3346
+ [data-qc-theme] .qc-drawing-bar-wide {
3347
+ width: auto;
3348
+ padding: 0 11px 0 10px;
3349
+ font-variant-numeric: tabular-nums;
3350
+ }
3351
+
3352
+ /* The ink does not move between these states: the bar's controls read at full strength whatever
3353
+ * the pointer is doing, and what answers it is the wash below. */
3354
+ [data-qc-theme] .qc-drawing-bar-button:hover,
3355
+ [data-qc-theme] .qc-drawing-bar-button:focus-visible,
3356
+ [data-qc-theme] .qc-drawing-bar-button[aria-expanded='true'],
3357
+ [data-qc-theme] .qc-drawing-bar-button[aria-pressed='true'] {
3358
+ background: none;
3359
+ }
3360
+
3361
+ [data-qc-theme] .qc-drawing-bar-button:hover::before,
3362
+ [data-qc-theme] .qc-drawing-bar-button:focus-visible::before {
3363
+ background: var(--qc-state-hover);
3364
+ }
3365
+
3366
+ /* An open menu fills its WHOLE cell, square, the way one does on the chart's own toolbar: the
3367
+ * panel hangs off the bottom edge of the control, and a rounded pill inset from that edge leaves
3368
+ * a gap the panel appears to float away from. */
3369
+ [data-qc-theme] .qc-drawing-bar-button[aria-expanded='true']::before {
3370
+ inset: 0;
3371
+ border-radius: 0;
3372
+ background: var(--qc-state-hover);
3373
+ }
3374
+
3375
+ /* A LOCKED drawing is a held mode, the same kind of state as a running replay, and says so the way
3376
+ * this product says "on": the emphasis fill with the ink cut out of it. Neutral, never an accent,
3377
+ * because locked is a fact about the drawing rather than a warning about it. */
3378
+ [data-qc-theme] .qc-drawing-bar-button[aria-pressed='true'] {
3379
+ color: var(--qc-text-inverse);
3380
+ }
3381
+
3382
+ [data-qc-theme] .qc-drawing-bar-button[aria-pressed='true']::before {
3383
+ background: var(--qc-control-on);
3384
+ }
3385
+
3386
+ [data-qc-theme] .qc-drawing-bar-button[aria-pressed='true']:hover::before {
3387
+ background: var(--qc-control-onHover);
3388
+ }
3389
+
3390
+ [data-qc-theme] .qc-drawing-bar-button[disabled] {
3391
+ color: var(--qc-text-disabled);
3392
+ }
3393
+
3394
+ [data-qc-theme] .qc-drawing-bar-button[disabled]::before {
3395
+ background: none;
3396
+ }
3397
+
3398
+ [data-qc-theme] .qc-drawing-width-bar {
3399
+ display: flex;
3400
+ flex: 0 0 auto;
3401
+ align-items: center;
3402
+ }
3403
+
3404
+ /* The bar's menus: a 4px-padded column of 34px rows, sized by content, or 240px wide for the
3405
+ * templates, More and timeframe lists, or 176px for the stacking moves. */
3406
+ [data-qc-theme] .qc-drawing-bar-menu {
3407
+ min-width: 0;
3408
+ width: max-content;
3409
+ }
3410
+
3411
+ [data-qc-theme] .qc-drawing-bar-menu[data-width='wide'] {
3412
+ width: 240px;
3413
+ }
3414
+
3415
+ [data-qc-theme] .qc-drawing-bar-menu[data-width='narrow'] {
3416
+ width: 176px;
3417
+ }
3418
+
3419
+ [data-qc-theme] .qc-drawing-bar-menu .qc-separator {
3420
+ margin: 2px 8px;
3421
+ }
3422
+
3423
+ /* A row's mark sits at its own width, 8px from the label; a row with no mark of its own under a
3424
+ * marked one takes a 28px spacer, which is the mark's grid, so the labels share a column. */
3425
+ [data-qc-theme] .qc-drawing-bar-row {
3426
+ border-radius: var(--qc-chrome-radius);
3427
+ }
3428
+
3429
+ [data-qc-theme] .qc-drawing-bar-row .qc-menu-icon {
3430
+ flex: 0 0 auto;
3431
+ width: auto;
3432
+ min-width: 0;
3433
+ opacity: 0.8;
3434
+ }
3435
+
3436
+ [data-qc-theme] .qc-drawing-bar-row .qc-menu-icon:empty {
3437
+ width: 28px;
3438
+ }
3439
+
3440
+ [data-qc-theme] .qc-drawing-bar-row .qc-menu-hint {
3441
+ padding: 0;
3442
+ font-size: var(--qc-text-fontSizeMicro);
3443
+ }
3444
+
3445
+ [data-qc-theme] .qc-drawing-bar-arrow {
3446
+ display: flex;
3447
+ flex: 0 0 auto;
3448
+ opacity: 0.7;
3449
+ }
3450
+
3451
+ /* A chosen row in one of the bar's menus inverts, exactly as a chosen row does in every other menu
3452
+ * the chart opens. */
3453
+ [data-qc-theme] .qc-drawing-bar-row[data-qc-active='true'] {
3454
+ color: var(--qc-text-inverse);
3455
+ background: var(--qc-control-on);
3456
+ }
3457
+
3458
+ [data-qc-theme] .qc-drawing-bar-row[disabled] {
3459
+ color: var(--qc-text-secondary);
3460
+ opacity: 0.4;
3461
+ pointer-events: none;
3462
+ }
3463
+
3464
+ /* A color control's face: the channel's glyph over a strip of the current color. */
3465
+ [data-qc-theme] .qc-drawing-color-face {
3466
+ display: flex;
3467
+ flex-direction: column;
3468
+ align-items: center;
3469
+ gap: 4px;
3470
+ }
3471
+
3472
+ [data-qc-theme] .qc-drawing-color-strip {
3473
+ width: 22px;
3474
+ height: 4px;
3475
+ background: var(--qcd-swatch);
3476
+ border-radius: 2px;
3477
+ }
3478
+
3479
+ [data-qc-theme] .qc-drawing-color-strip[data-empty='true'] {
3480
+ background: none;
3481
+ box-shadow: inset 0 0 0 1px var(--qc-chrome-borderStrong);
3482
+ }
3483
+
3484
+ /* The dialogs: a titled box on the scrim, draggable by its header. */
3485
+ [data-qc-theme] .qc-drawing-dialog {
3486
+ position: relative;
3487
+ max-height: calc(100% - 16px);
3488
+ }
3489
+
3490
+ /* The header: the name at 20 on 28 in a 68px band 20px in, then what the dialog adds after it (the
3491
+ * settings dialog's pencil), and the close 34px at the far end, 3px past the padding so its mark
3492
+ * lines up with the page's edge. The header is the handle the dialog is carried by. */
3493
+ [data-qc-theme] .qc-drawing-dialog .qc-drawing-dialog-header {
3494
+ display: flex;
3495
+ flex: 0 0 auto;
3496
+ align-items: center;
3497
+ justify-content: flex-start;
3498
+ gap: 0;
3499
+ height: 68px;
3500
+ padding: 0 20px;
3501
+ cursor: grab;
3502
+ user-select: none;
3503
+ }
3504
+
3505
+ [data-qc-theme] .qc-drawing-dialog-title {
3506
+ min-width: 0;
3507
+ overflow: hidden;
3508
+ font-size: 20px;
3509
+ font-weight: 600;
3510
+ line-height: 28px;
3511
+ text-overflow: ellipsis;
3512
+ white-space: nowrap;
3513
+ }
3514
+
3515
+ [data-qc-theme] .qc-drawing-dialog .qc-dialog-close {
3516
+ flex: 0 0 34px;
3517
+ margin-inline-start: auto;
3518
+ margin-inline-end: -3px;
3519
+ border-radius: 8px;
3520
+ }
3521
+
3522
+ /* The body 20px in from the sides; a drop box stands 8px under the header. */
3523
+ [data-qc-theme] .qc-drawing-dialog-body {
3524
+ display: flex;
3525
+ flex: 1 1 auto;
3526
+ flex-direction: column;
3527
+ min-height: 0;
3528
+ padding: 0 20px;
3529
+ overflow-y: auto;
3530
+ }
3531
+
3532
+ [data-qc-theme] .qc-drawing-dialog-body > .qc-drawing-drop {
3533
+ margin-top: 8px;
3534
+ }
3535
+
3536
+ /* The image picker's transparency: its name at the start and its 180px track at the end of a 46px
3537
+ * line, each 10px down the line's 26px middle, 24px above the footer. */
3538
+ [data-qc-theme] .qc-drawing-picker-opacity {
3539
+ display: flex;
3540
+ align-items: center;
3541
+ justify-content: space-between;
3542
+ margin-bottom: 24px;
3543
+ padding: 10px 0;
3544
+ }
3545
+
3546
+ [data-qc-theme] .qc-drawing-picker-opacity > * {
3547
+ margin-top: 10px;
3548
+ }
3549
+
3550
+ [data-qc-theme] .qc-drawing-picker-opacity > .qc-drawing-band-opacity {
3551
+ flex: 0 0 180px;
3552
+ width: 180px;
3553
+ margin-top: 10px;
3554
+ }
3555
+
3556
+ /* A drawing dialog's footer: what it leads with at the start (the settings dialog's Template list
3557
+ * button), then Cancel and the primary action 12px apart at the end, all 34px with an 8px corner,
3558
+ * over a 1px rule. Cancel is outlined in the outline role and takes the emphasis fill under the
3559
+ * pointer; the primary action wears the fill. */
3560
+ [data-qc-theme] .qc-drawing-dialog-footer {
3561
+ display: flex;
3562
+ align-items: center;
3563
+ justify-content: flex-end;
3564
+ padding: 16px 20px;
3565
+ border-top: 1px solid var(--qc-overlay-separator);
3566
+ }
3567
+
3568
+ [data-qc-theme] .qc-drawing-footer-gap {
3569
+ flex: 1 1 auto;
3570
+ }
3571
+
3572
+ [data-qc-theme] .qc-drawing-dialog-copy {
3573
+ margin: 4px 0 8px;
3574
+ }
3575
+
3576
+ [data-qc-theme] .qc-drawing-field-label {
3577
+ display: block;
3578
+ margin: 6px 0 4px;
3579
+ }
3580
+
3581
+ /* The settings dialog: a card at least 380px wide that grows to the widest page it shows, its
3582
+ * header, the page strip, the page and the footer stacked. */
3583
+ [data-qc-theme] .qc-drawing-settings-dialog {
3584
+ width: max-content;
3585
+ min-width: min(380px, calc(100% - 16px));
3586
+ max-width: calc(100% - 16px);
3587
+ }
3588
+
3589
+ /* The settings dialog's pencil stands 5px after the name in a 34px cell. */
3590
+ [data-qc-theme] .qc-drawing-rename {
3591
+ display: flex;
3592
+ flex: 0 0 34px;
3593
+ align-items: center;
3594
+ justify-content: center;
3595
+ width: 34px;
3596
+ height: 34px;
3597
+ margin-inline-start: 5px;
3598
+ padding: 0;
3599
+ color: var(--qc-text-primary);
3600
+ background: none;
3601
+ border: 0;
3602
+ border-radius: 2px;
3603
+ cursor: pointer;
3604
+ }
3605
+
3606
+ [data-qc-theme] .qc-drawing-rename:hover {
3607
+ background: var(--qc-state-hover);
3608
+ }
3609
+
3610
+ /* Renaming, the header is the name's field alone, as wide as the header and in the name's own type. */
3611
+ [data-qc-theme] .qc-drawing-dialog-header[data-qc-renaming='true'] > :not(.qc-drawing-rename-field) {
3612
+ display: none;
3613
+ }
3614
+
3615
+ [data-qc-theme] .qc-drawing-rename-field {
3616
+ flex: 1 1 auto;
3617
+ min-width: 0;
3618
+ font-size: 20px;
3619
+ font-weight: 600;
3620
+ line-height: 28px;
3621
+ }
3622
+
3623
+ /* The page strip: the tabs at 16 on 24, 12px apart, over a 4px track as wide as the page; the bar
3624
+ * standing on the track under the shown page glides to the next one. A tab under the pointer that
3625
+ * is not shown dims to the muted ink. */
3626
+ [data-qc-theme] .qc-drawing-tabs-slot {
3627
+ position: relative;
3628
+ flex: 0 0 auto;
3629
+ padding: 0 20px;
3630
+ }
3631
+
3632
+ [data-qc-theme] .qc-drawing-tabs-track {
3633
+ position: absolute;
3634
+ inset-inline: 20px;
3635
+ bottom: 0;
3636
+ height: 4px;
3637
+ background: var(--qc-overlay-separator);
3638
+ border-radius: 2px;
3639
+ }
3640
+
3641
+ [data-qc-theme] .qc-drawing-tabs {
3642
+ position: relative;
3643
+ display: inline-flex;
3644
+ vertical-align: top;
3645
+ white-space: nowrap;
3646
+ }
3647
+
3648
+ [data-qc-theme] .qc-drawing-tab {
3649
+ position: relative;
3650
+ margin: 0 12px;
3651
+ padding: 0 0 8px;
3652
+ color: var(--qc-text-primary);
3653
+ font: inherit;
3654
+ font-size: 16px;
3655
+ font-weight: 600;
3656
+ line-height: 24px;
3657
+ background: none;
3658
+ border: 0;
3659
+ border-radius: 4px;
3660
+ outline: none;
3661
+ cursor: pointer;
3662
+ }
3663
+
3664
+ [data-qc-theme] .qc-drawing-tab:first-of-type {
3665
+ margin-inline-start: 0;
3666
+ }
3667
+
3668
+ [data-qc-theme] .qc-drawing-tab:last-of-type {
3669
+ margin-inline-end: 0;
3670
+ }
3671
+
3672
+ [data-qc-theme] .qc-drawing-tab:not([aria-selected='true']):hover {
3673
+ color: var(--qc-text-muted);
3674
+ }
3675
+
3676
+ /* The keyboard's ring stands 10px out to either side of the label and over the bar's height. */
3677
+ [data-qc-theme] .qc-drawing-tab:focus-visible::after {
3678
+ position: absolute;
3679
+ inset: -2px -10px 0;
3680
+ border: 2px solid var(--qc-state-focusRing);
3681
+ border-radius: 8px;
3682
+ content: '';
3683
+ pointer-events: none;
3684
+ }
3685
+
3686
+ [data-qc-theme] .qc-drawing-tab-bar {
3687
+ position: absolute;
3688
+ bottom: 0;
3689
+ left: 0;
3690
+ height: 4px;
3691
+ background: var(--qc-control-on);
3692
+ border-radius: 2px;
3693
+ pointer-events: none;
3694
+ }
3695
+
3696
+ [data-qc-theme] .qc-drawing-tabs[data-qc-placed='true'] > .qc-drawing-tab-bar {
3697
+ transition: transform var(--qc-motion-durationGlide) var(--qc-motion-easingInOut), width var(--qc-motion-durationGlide) var(--qc-motion-easingInOut);
3698
+ }
3699
+
3700
+ /* The body scrolls the page alone, and keeps room for a short one. */
3701
+ [data-qc-theme] .qc-drawing-settings-dialog .qc-drawing-dialog-body {
3702
+ display: block;
3703
+ min-height: 145px;
3704
+ padding: 0;
3705
+ }
3706
+
3707
+ /* The page: a two-column grid inside 16px by 20px, the labels' column as wide as the widest label
3708
+ * and its 20px gap, the controls' column the rest. Everything on the page that is not a labelled
3709
+ * row stands across both columns. */
3710
+ [data-qc-theme] .qc-drawing-page {
3711
+ display: grid;
3712
+ grid-template-columns: auto minmax(0, 1fr);
3713
+ padding: 16px 20px;
3714
+ }
3715
+
3716
+ [data-qc-theme] .qc-drawing-page > :not(.qc-drawing-row) {
3717
+ grid-column: 1 / -1;
3718
+ }
3719
+
3720
+ [data-qc-theme] .qc-drawing-page > .qc-button {
3721
+ justify-self: start;
3722
+ }
3723
+
3724
+ [data-qc-theme] .qc-drawing-template-button {
3725
+ display: inline-flex;
3726
+ flex: 0 0 auto;
3727
+ align-items: center;
3728
+ width: 100px;
3729
+ padding: 0 2px 0 8px;
3730
+ cursor: pointer;
3731
+ }
3732
+
3733
+ /* While its menu is open the Template button keeps the focus ring, and its chevron points up. */
3734
+ [data-qc-theme] .qc-drawing-template-button[aria-expanded='true'] {
3735
+ border-color: var(--qc-state-focusRing);
3736
+ box-shadow: inset 0 0 0 1px var(--qc-state-focusRing);
3737
+ }
3738
+
3739
+ [data-qc-theme] .qc-drawing-footer-button {
3740
+ display: inline-flex;
3741
+ align-items: center;
3742
+ justify-content: center;
3743
+ height: 34px;
3744
+ padding: 0 11px;
3745
+ font-size: 16px;
3746
+ line-height: 24px;
3747
+ border-radius: 8px;
3748
+ }
3749
+
3750
+ [data-qc-theme] .qc-drawing-footer-button + .qc-drawing-footer-button {
3751
+ margin-inline-start: 12px;
2798
3752
  }
2799
3753
 
2800
- /* The ink does not move between these states: the bar's controls read at full strength whatever
2801
- * the pointer is doing, and what answers it is the wash below. */
2802
- [data-qc-theme] .qc-drawing-bar-button:hover,
2803
- [data-qc-theme] .qc-drawing-bar-button:focus-visible,
2804
- [data-qc-theme] .qc-drawing-bar-button[aria-expanded='true'],
2805
- [data-qc-theme] .qc-drawing-bar-button[aria-pressed='true'] {
2806
- background: none;
3754
+ [data-qc-theme] .qc-drawing-cancel {
3755
+ color: var(--qc-control-outline);
3756
+ border-color: var(--qc-control-outline);
2807
3757
  }
2808
3758
 
2809
- [data-qc-theme] .qc-drawing-bar-button:hover::before,
2810
- [data-qc-theme] .qc-drawing-bar-button:focus-visible::before {
2811
- background: var(--qc-state-hover);
3759
+ [data-qc-theme] .qc-drawing-cancel:hover:not([disabled]) {
3760
+ color: var(--qc-text-inverse);
3761
+ background: var(--qc-control-on);
3762
+ border-color: var(--qc-control-on);
2812
3763
  }
2813
3764
 
2814
- /* An open menu fills its WHOLE cell, square, the way one does on the chart's own toolbar: the
2815
- * panel hangs off the bottom edge of the control, and a rounded pill inset from that edge leaves
2816
- * a gap the panel appears to float away from. */
2817
- [data-qc-theme] .qc-drawing-bar-button[aria-expanded='true']::before {
2818
- inset: 0;
2819
- border-radius: 0;
2820
- background: var(--qc-state-hover);
3765
+ [data-qc-theme] .qc-drawing-cancel:active:not([disabled]) {
3766
+ color: var(--qc-text-inverse);
3767
+ background: var(--qc-control-onPressed);
3768
+ border-color: var(--qc-control-onPressed);
2821
3769
  }
2822
3770
 
2823
- /* A LOCKED drawing is a held mode, the same kind of state as a running replay, and says so the way
2824
- * this product says "on": the emphasis fill with the ink cut out of it. Neutral, never an accent,
2825
- * because locked is a fact about the drawing rather than a warning about it. */
2826
- [data-qc-theme] .qc-drawing-bar-button[aria-pressed='true'] {
2827
- color: var(--qc-text-inverse);
3771
+ /* The lists the dialog opens stand on a 10px corner; the Template menu is as wide as its words. */
3772
+ [data-qc-theme] .qc-drawing-popover--list {
3773
+ border-radius: 10px;
2828
3774
  }
2829
3775
 
2830
- [data-qc-theme] .qc-drawing-bar-button[aria-pressed='true']::before {
2831
- background: var(--qc-control-on);
3776
+ [data-qc-theme] .qc-drawing-menu.qc-drawing-template-menu {
3777
+ width: max-content;
3778
+ min-width: 0;
2832
3779
  }
2833
3780
 
2834
- [data-qc-theme] .qc-drawing-bar-button[aria-pressed='true']:hover::before {
2835
- background: var(--qc-control-onHover);
3781
+ /* A saved template's row: its name, then the 26px slot at the end where its remove control
3782
+ * stands. The whole row lifts under the pointer. */
3783
+ [data-qc-theme] .qc-drawing-template-menu .qc-drawing-flyout-row {
3784
+ height: 32px;
3785
+ border-radius: 6px;
2836
3786
  }
2837
3787
 
2838
- [data-qc-theme] .qc-drawing-bar-button[disabled] {
2839
- color: var(--qc-text-disabled);
3788
+ [data-qc-theme] .qc-drawing-template-menu .qc-drawing-flyout-row > .qc-drawing-list-row {
3789
+ flex: 1 1 auto;
3790
+ width: auto;
3791
+ min-width: 0;
2840
3792
  }
2841
3793
 
2842
- [data-qc-theme] .qc-drawing-bar-button[disabled]::before {
2843
- background: none;
3794
+ [data-qc-theme] .qc-drawing-template-menu .qc-drawing-star {
3795
+ position: static;
3796
+ flex: 0 0 22px;
3797
+ width: 22px;
3798
+ height: 22px;
3799
+ margin-inline-end: 4px;
2844
3800
  }
2845
3801
 
2846
- [data-qc-theme] .qc-drawing-width-bar {
2847
- display: flex;
2848
- flex: 0 0 auto;
2849
- align-items: center;
3802
+ [data-qc-theme] .qc-drawing-note {
3803
+ padding: 2px 0 4px;
3804
+ font-size: var(--qc-text-fontSizeSmall);
2850
3805
  }
2851
3806
 
2852
- /* The bar's menus: a 4px-padded column of 34px rows, sized by content, or 240px wide for the
2853
- * templates, More and timeframe lists, or 176px for the stacking moves. */
2854
- [data-qc-theme] .qc-drawing-bar-menu {
2855
- min-width: 0;
2856
- width: max-content;
3807
+ /* The plane's live region: read by assistive technology, never seen. Clipped rather than hidden,
3808
+ * because a hidden node is not announced. */
3809
+ [data-qc-theme] .qc-drawing-status {
3810
+ position: absolute;
3811
+ width: 1px;
3812
+ height: 1px;
3813
+ overflow: hidden;
3814
+ clip-path: inset(50%);
3815
+ white-space: nowrap;
2857
3816
  }
2858
3817
 
2859
- [data-qc-theme] .qc-drawing-bar-menu[data-width='wide'] {
2860
- width: 240px;
3818
+ /* A leveled tool's level grid: two levels to a 34px line, 8px between lines and 8px above the
3819
+ * first, each level its 18px switch, its 100px value and its 34px well 8px apart, the second level
3820
+ * 48px after the first's well, the line 412px across whatever its levels hold. A level switched off
3821
+ * keeps its well, and its stroke where it shows one, on the read-only fill, dimmed. */
3822
+ [data-qc-theme] .qc-drawing-page > .qc-drawing-level-row {
3823
+ min-width: 412px;
3824
+ min-height: 34px;
3825
+ margin-bottom: 8px;
3826
+ padding: 0;
2861
3827
  }
2862
3828
 
2863
- [data-qc-theme] .qc-drawing-bar-menu[data-width='narrow'] {
2864
- width: 176px;
3829
+ [data-qc-theme] .qc-drawing-page > :not(.qc-drawing-level-row) + .qc-drawing-level-row {
3830
+ margin-top: 8px;
2865
3831
  }
2866
3832
 
2867
- [data-qc-theme] .qc-drawing-bar-menu .qc-separator {
2868
- margin: 2px 8px;
3833
+ [data-qc-theme] .qc-drawing-level-row > :nth-child(4) {
3834
+ margin-inline-start: 40px;
2869
3835
  }
2870
3836
 
2871
- /* A row's mark sits at its own width, 8px from the label; a row with no mark of its own under a
2872
- * marked one takes a 28px spacer, which is the mark's grid, so the labels share a column. */
2873
- [data-qc-theme] .qc-drawing-bar-row {
2874
- border-radius: var(--qc-chrome-radius);
3837
+ /* A gann grid: two lines to a 34px line, 8px between lines and 8px above the first, each line its
3838
+ * switch with its place or its ratio, 78px across so every well stands in line, then its well 8px
3839
+ * after; the second line 48px after the first's well, the line 412px across. A fan's rays stand one
3840
+ * to a 50px line. */
3841
+ [data-qc-theme] .qc-drawing-page > .qc-drawing-ratio-row {
3842
+ min-width: 412px;
3843
+ min-height: 34px;
3844
+ margin-bottom: 8px;
3845
+ padding: 0;
2875
3846
  }
2876
3847
 
2877
- [data-qc-theme] .qc-drawing-bar-row .qc-menu-icon {
2878
- flex: 0 0 auto;
2879
- width: auto;
2880
- min-width: 0;
2881
- opacity: 0.8;
3848
+ [data-qc-theme] .qc-drawing-page > :not(.qc-drawing-ratio-row) + .qc-drawing-ratio-row {
3849
+ margin-top: 8px;
2882
3850
  }
2883
3851
 
2884
- [data-qc-theme] .qc-drawing-bar-row .qc-menu-icon:empty {
2885
- width: 28px;
3852
+ [data-qc-theme] .qc-drawing-ratio-row > :nth-child(3) {
3853
+ margin-inline-start: 40px;
2886
3854
  }
2887
3855
 
2888
- [data-qc-theme] .qc-drawing-bar-row .qc-menu-hint {
2889
- padding: 0;
2890
- font-size: var(--qc-text-fontSizeMicro);
3856
+ [data-qc-theme] .qc-drawing-ratio-switch {
3857
+ flex: 0 0 78px;
3858
+ min-width: 0;
3859
+ min-height: 34px;
2891
3860
  }
2892
3861
 
2893
- [data-qc-theme] .qc-drawing-bar-arrow {
2894
- display: flex;
2895
- flex: 0 0 auto;
2896
- opacity: 0.7;
3862
+ /* An image's page: its caption across the page over the box that chooses the picture, 8px above it. */
3863
+ [data-qc-theme] .qc-drawing-page > .qc-drawing-row--caption > .qc-drawing-row-label {
3864
+ grid-column: 1 / -1;
3865
+ min-height: 0;
3866
+ padding: 0;
2897
3867
  }
2898
3868
 
2899
- /* A chosen row in one of the bar's menus inverts, exactly as a chosen row does in every other menu
2900
- * the chart opens. */
2901
- [data-qc-theme] .qc-drawing-bar-row[data-qc-active='true'] {
2902
- color: var(--qc-text-inverse);
2903
- background: var(--qc-control-on);
3869
+ [data-qc-theme] .qc-drawing-page > .qc-drawing-row--caption > .qc-drawing-row-controls {
3870
+ display: none;
2904
3871
  }
2905
3872
 
2906
- [data-qc-theme] .qc-drawing-bar-row[disabled] {
2907
- color: var(--qc-text-secondary);
2908
- opacity: 0.4;
2909
- pointer-events: none;
3873
+ [data-qc-theme] .qc-drawing-page > .qc-drawing-drop {
3874
+ margin-top: 8px;
2910
3875
  }
2911
3876
 
2912
- /* A color control's face: the channel's glyph over a strip of the current color. */
2913
- [data-qc-theme] .qc-drawing-color-face {
2914
- display: flex;
2915
- flex-direction: column;
3877
+ /* A signpost's emoji: a field-sized button wearing the glyph's artwork, or the glyph itself where
3878
+ * the artwork has not come. */
3879
+ [data-qc-theme] .qc-drawing-emoji-button {
3880
+ display: inline-flex;
2916
3881
  align-items: center;
2917
- gap: 4px;
3882
+ justify-content: center;
3883
+ width: 36px;
3884
+ height: 34px;
3885
+ padding: 0;
3886
+ border-radius: 6px;
2918
3887
  }
2919
3888
 
2920
- [data-qc-theme] .qc-drawing-color-strip {
2921
- width: 22px;
2922
- height: 4px;
2923
- background: var(--qcd-swatch);
2924
- border-radius: 2px;
3889
+ [data-qc-theme] .qc-drawing-emoji-button .qc-drawing-glyph-art {
3890
+ width: 24px;
3891
+ height: 24px;
2925
3892
  }
2926
3893
 
2927
- [data-qc-theme] .qc-drawing-color-strip[data-empty='true'] {
2928
- background: none;
2929
- box-shadow: inset 0 0 0 1px var(--qc-chrome-borderStrong);
3894
+ /* An emoji well beside a switch that is off stands dimmed on the field's fill, as a color well does. */
3895
+ [data-qc-theme] .qc-drawing-emoji-button[data-qc-dim='true'] {
3896
+ background: var(--qc-control-fieldFill);
2930
3897
  }
2931
3898
 
2932
- /* The dialogs: a titled box on the scrim, draggable by its header. */
2933
- [data-qc-theme] .qc-drawing-dialog {
2934
- position: relative;
2935
- max-height: calc(100% - 16px);
3899
+ [data-qc-theme] .qc-drawing-emoji-button[data-qc-dim='true'] > * {
3900
+ opacity: 0.5;
2936
3901
  }
2937
3902
 
2938
- [data-qc-theme] .qc-drawing-dialog-header {
2939
- display: flex;
2940
- align-items: center;
2941
- justify-content: space-between;
2942
- gap: 8px;
2943
- padding: 12px 14px 8px;
2944
- cursor: move;
2945
- user-select: none;
3903
+ [data-qc-theme] .qc-drawing-emoji-face {
3904
+ font-size: 20px;
3905
+ line-height: 1;
2946
3906
  }
2947
3907
 
2948
- [data-qc-theme] .qc-drawing-dialog-title {
2949
- overflow: hidden;
2950
- text-overflow: ellipsis;
2951
- white-space: nowrap;
3908
+ [data-qc-theme] .qc-drawing-swatch-button[data-qc-dim='true'] {
3909
+ background: var(--qc-control-fieldFill);
2952
3910
  }
2953
3911
 
2954
- [data-qc-theme] .qc-drawing-dialog-body {
2955
- display: flex;
2956
- flex: 1 1 auto;
2957
- flex-direction: column;
2958
- gap: 4px;
2959
- min-height: 0;
2960
- padding: 0 14px 8px;
2961
- overflow-y: auto;
3912
+ [data-qc-theme] .qc-drawing-swatch-button[data-qc-dim='true'] > .qc-drawing-well,
3913
+ [data-qc-theme] .qc-drawing-swatch-button[data-qc-dim='true'] > .qc-drawing-stroke {
3914
+ opacity: 0.5;
2962
3915
  }
2963
3916
 
2964
- [data-qc-theme] .qc-drawing-dialog-footer {
2965
- display: flex;
2966
- align-items: center;
2967
- gap: 8px;
2968
- padding: 10px 14px;
2969
- border-top: 1px solid var(--qc-overlay-separator);
3917
+ /* The one color while the levels differ: the well split corner to corner between the color it
3918
+ * offers and a second hue, so it reads as several colors rather than one. */
3919
+ [data-qc-theme] .qc-drawing-swatch-button[data-qc-mixed='true'] .qc-drawing-well-fill {
3920
+ background: linear-gradient(to top right, var(--qcd-swatch) 50%, var(--qcd-paired) 50%);
2970
3921
  }
2971
3922
 
2972
- [data-qc-theme] .qc-drawing-dialog-footer .qc-button {
2973
- padding: 5px 12px;
3923
+ /* A list button whose face is a mark: 76px around a 50px bar of the chosen thickness, or 34px
3924
+ * around the chosen style's 28px mark. A thickness list stands 12px wider than its button, each
3925
+ * choice its bar alone; a style list is as wide as its words. */
3926
+ [data-qc-theme] .qc-drawing-select--mark {
3927
+ justify-content: center;
3928
+ padding: 0;
2974
3929
  }
2975
3930
 
2976
- [data-qc-theme] .qc-drawing-footer-gap {
2977
- flex: 1 1 auto;
3931
+ [data-qc-theme] .qc-drawing-select--mark[data-mark='thickness'] {
3932
+ width: 76px;
2978
3933
  }
2979
3934
 
2980
- [data-qc-theme] .qc-drawing-dialog-copy {
2981
- margin: 4px 0 8px;
3935
+ [data-qc-theme] .qc-drawing-select--mark[data-mark='style'] {
3936
+ width: 34px;
2982
3937
  }
2983
3938
 
2984
- [data-qc-theme] .qc-drawing-field-label {
3939
+ [data-qc-theme] .qc-drawing-thickness-bar {
2985
3940
  display: block;
2986
- margin: 6px 0 4px;
3941
+ flex: 0 0 auto;
3942
+ width: 50px;
3943
+ background: currentColor;
2987
3944
  }
2988
3945
 
2989
- [data-qc-theme] .qc-drawing-settings-dialog {
2990
- width: min(380px, calc(100% - 16px));
2991
- max-height: min(560px, calc(100% - 16px));
3946
+ [data-qc-theme] .qc-drawing-mark-list[data-mark='thickness'] {
3947
+ width: 88px;
2992
3948
  }
2993
3949
 
2994
- [data-qc-theme] .qc-drawing-page {
2995
- display: flex;
2996
- flex-direction: column;
2997
- gap: 2px;
2998
- padding-top: 2px;
3950
+ [data-qc-theme] .qc-drawing-mark-list[data-mark='style'] {
3951
+ width: max-content;
2999
3952
  }
3000
3953
 
3001
- [data-qc-theme] .qc-drawing-template-button {
3002
- display: flex;
3003
- align-items: center;
3004
- gap: 4px;
3954
+ [data-qc-theme] .qc-drawing-list-row--bar {
3955
+ justify-content: center;
3005
3956
  }
3006
3957
 
3007
- [data-qc-theme] .qc-drawing-caret {
3008
- display: flex;
3009
- transition: transform var(--qc-motion-durationFast) var(--qc-motion-easingLinear);
3958
+ /* The chosen thickness or style is cut from the emphasis fill in the ink of a mark. */
3959
+ [data-qc-theme] .qc-drawing-mark-list .qc-drawing-list-row[aria-selected='true'] {
3960
+ color: var(--qc-control-onInk);
3010
3961
  }
3011
3962
 
3012
- [data-qc-theme] .qc-drawing-template-button[aria-expanded='true'] .qc-drawing-caret {
3013
- transform: rotate(180deg);
3963
+ /* The bands' opacity: a 148px track 10px tall on a 5px corner that fades from nothing into the
3964
+ * drawings' line color over the checked ground the color popover's track stands on, inside a 1px
3965
+ * edge of that color; its 12px knob is the popover's, a dark disc with a light rim, a pixel proud
3966
+ * of the track above and below. */
3967
+ [data-qc-theme] .qc-drawing-band-opacity {
3968
+ --qcd-angle-0: 0deg;
3969
+ --qcd-black: hsl(var(--qcd-angle-0) 0% 0%);
3970
+ --qcd-white: hsl(var(--qcd-angle-0) 0% 100%);
3971
+ --qcd-check-hue: 224deg;
3972
+ --qcd-check: hsl(var(--qcd-check-hue) 15% 19% / 0.4);
3973
+ --qcd-ground: var(--qcd-black);
3974
+ flex: 0 0 148px;
3975
+ width: 148px;
3976
+ height: 10px;
3977
+ margin: 0;
3978
+ background:
3979
+ linear-gradient(to right, transparent, var(--qc-drawing-line)),
3980
+ repeating-conic-gradient(from 270deg, var(--qcd-check) 0% 25%, transparent 0% 50%) 1px 50% / 8px 8px,
3981
+ var(--qcd-ground);
3982
+ border: 1px solid var(--qc-drawing-line);
3983
+ border-radius: 5px;
3984
+ outline: none;
3985
+ cursor: pointer;
3986
+ appearance: none;
3014
3987
  }
3015
3988
 
3016
- [data-qc-theme] .qc-drawing-note {
3017
- padding: 2px 0 4px;
3018
- font-size: var(--qc-text-fontSizeSmall);
3989
+ [data-qc-theme='light'] .qc-drawing-band-opacity {
3990
+ --qcd-ground: var(--qcd-white);
3019
3991
  }
3020
3992
 
3021
- /* The plane's live region: read by assistive technology, never seen. Clipped rather than hidden,
3022
- * because a hidden node is not announced. */
3023
- [data-qc-theme] .qc-drawing-status {
3024
- position: absolute;
3025
- width: 1px;
3026
- height: 1px;
3027
- overflow: hidden;
3028
- clip-path: inset(50%);
3029
- white-space: nowrap;
3993
+ [data-qc-theme] .qc-drawing-band-opacity:focus-visible {
3994
+ box-shadow: 0 0 0 2px var(--qc-state-focusRing);
3995
+ }
3996
+
3997
+ [data-qc-theme] .qc-drawing-band-opacity::-webkit-slider-thumb {
3998
+ width: 12px;
3999
+ height: 12px;
4000
+ background: var(--qcd-black);
4001
+ border: 2px solid var(--qcd-white);
4002
+ border-radius: 50%;
4003
+ box-shadow: 0 1px 2px hsl(var(--qcd-angle-0) 0% 0% / 0.5);
4004
+ cursor: pointer;
4005
+ appearance: none;
4006
+ }
4007
+
4008
+ [data-qc-theme] .qc-drawing-band-opacity::-moz-range-thumb {
4009
+ box-sizing: border-box;
4010
+ width: 12px;
4011
+ height: 12px;
4012
+ background: var(--qcd-black);
4013
+ border: 2px solid var(--qcd-white);
4014
+ border-radius: 50%;
4015
+ box-shadow: 0 1px 2px hsl(var(--qcd-angle-0) 0% 0% / 0.5);
4016
+ cursor: pointer;
3030
4017
  }
3031
4018
 
3032
4019
  /* The drawing toolbar: the column down the chart's inline-start edge, its split cells, its flyouts
@@ -3809,20 +4796,18 @@
3809
4796
  padding-inline: 0;
3810
4797
  }
3811
4798
 
4799
+ /* A row that holds fields stands 42px, the drawing settings' row: the chart's 34px field box with
4800
+ * room above and below it. */
3812
4801
  [data-qc-theme] .qc-settings-row {
3813
4802
  display: flex;
3814
4803
  align-items: center;
3815
4804
  gap: 8px;
3816
- min-height: 30px;
3817
- }
3818
-
3819
- [data-qc-theme] .qc-settings-row .qc-field {
3820
- padding: 2px 4px;
3821
- font-size: var(--qc-text-fontSizeSmall);
4805
+ min-height: 42px;
3822
4806
  }
3823
4807
 
4808
+ [data-qc-theme] .qc-settings-page .qc-field-row,
3824
4809
  [data-qc-theme] .qc-settings-page .qc-inputs-row {
3825
- min-height: 30px;
4810
+ min-height: 42px;
3826
4811
  }
3827
4812
 
3828
4813
  /* THE PICKER ON A NARROW SCREEN. The dialog is a two-column reading room — a 200px rail of
@@ -4367,8 +5352,9 @@
4367
5352
 
4368
5353
  /* A chosen row inverts, the emphasis fill behind the inverse ink, and carries nothing else: no
4369
5354
  * accent tint, no decorative dot. The row's own `aria-checked` is what a reader is told. A row that
4370
- * IS a switch is not a choice among rows: its track says it is on, and the row stays as it is. */
4371
- [data-qc-theme] .qc-menu-row[aria-checked='true']:not([role='switch']) {
5355
+ * IS a switch or a checkbox is not a choice among rows: its track or its box says it is on, and the
5356
+ * row stays as it is. */
5357
+ [data-qc-theme] .qc-menu-row[aria-checked='true']:not([role='switch']):not([role='menuitemcheckbox']) {
4372
5358
  color: var(--qc-text-inverse);
4373
5359
  background: var(--qc-control-on);
4374
5360
  }
@@ -4462,6 +5448,12 @@
4462
5448
  pointer-events: auto;
4463
5449
  }
4464
5450
 
5451
+ /* A dialog that edits what it stands over leaves it undimmed: the backdrop still takes the press
5452
+ * that closes the dialog, and paints nothing. */
5453
+ [data-qc-theme] .qc-dialog-scrim[data-qc-veil='none'] {
5454
+ background: transparent;
5455
+ }
5456
+
4465
5457
  [data-qc-theme] .qc-dialog {
4466
5458
  display: flex;
4467
5459
  flex-direction: column;
@@ -4554,41 +5546,34 @@
4554
5546
  line-height: 21px;
4555
5547
  }
4556
5548
 
4557
- /* The field's box draws its outline, which steps up under the pointer and turns the accent, doubled
4558
- * outward, while the caret is in it. */
5549
+ /* The name's box is the chart's field box around a bare input that fills it: the box draws the edge,
5550
+ * which steps up under the pointer, and rings while the caret is in it. The ring is the field's own,
5551
+ * over the edge and following whatever corner the box has. */
4559
5552
  [data-qc-theme] .qc-name-box {
4560
5553
  display: flex;
4561
- height: 34px;
4562
- box-sizing: border-box;
4563
- align-items: center;
4564
- border: 1px solid var(--qc-chrome-fieldBorder);
4565
- border-radius: var(--qc-chrome-radius);
4566
- }
4567
-
4568
- [data-qc-theme] .qc-name-box:hover {
4569
- border-color: var(--qc-chrome-borderStrong);
5554
+ align-items: stretch;
5555
+ padding: 0;
4570
5556
  }
4571
5557
 
4572
5558
  [data-qc-theme] .qc-name-box:focus-within {
4573
5559
  border-color: var(--qc-state-focusRing);
5560
+ box-shadow: inset 0 0 0 1px var(--qc-state-focusRing);
4574
5561
  }
4575
5562
 
4576
5563
  [data-qc-theme] .qc-name-input {
4577
- min-width: 0;
4578
- height: 24px;
4579
5564
  flex: 1 1 auto;
4580
- padding: 0 8px;
4581
- color: var(--qc-text-primary);
5565
+ min-width: 0;
5566
+ height: 100%;
5567
+ padding: 0 7px;
5568
+ color: inherit;
4582
5569
  font: inherit;
4583
- font-size: calc(var(--qc-text-fontSizeBase) + 2px);
4584
- line-height: 24px;
4585
5570
  background: none;
4586
5571
  border: 0;
4587
5572
  outline: none;
4588
5573
  }
4589
5574
 
4590
5575
  [data-qc-theme] .qc-name-input::placeholder {
4591
- color: var(--qc-text-disabled);
5576
+ color: var(--qc-text-muted);
4592
5577
  }
4593
5578
 
4594
5579
  [data-qc-theme] .qc-prompt-actions {
@@ -4669,6 +5654,14 @@
4669
5654
  padding: 4px 12px;
4670
5655
  }
4671
5656
 
5657
+ /* Forced colors: the name's box rings its focus in the system highlight, as every field does. */
5658
+ @media (forced-colors: active) {
5659
+ [data-qc-theme] .qc-name-box:focus-within {
5660
+ border-color: Highlight;
5661
+ box-shadow: inset 0 0 0 1px Highlight;
5662
+ }
5663
+ }
5664
+
4672
5665
  /* The replay transport's reserved row below the chart grid, and the date picker.
4673
5666
  *
4674
5667
  * The row is in the root's own flow and positions nothing: it reserves 49px of the column between
@@ -4787,205 +5780,541 @@
4787
5780
  padding: 6px 0;
4788
5781
  }
4789
5782
 
4790
- [data-qc-theme] .qc-replay-menu .qc-menu-row {
4791
- gap: 6px;
4792
- padding-block: 0;
4793
- padding-inline: 12px 14px;
4794
- border-radius: 0;
5783
+ [data-qc-theme] .qc-replay-menu .qc-menu-row {
5784
+ gap: 6px;
5785
+ padding-block: 0;
5786
+ padding-inline: 12px 14px;
5787
+ border-radius: 0;
5788
+ }
5789
+
5790
+ [data-qc-theme] .qc-replay-menu .qc-menu-row:hover {
5791
+ color: var(--qc-state-hoverInk);
5792
+ }
5793
+
5794
+ [data-qc-theme] .qc-replay-menu .qc-menu-row[aria-checked='true'],
5795
+ [data-qc-theme] .qc-replay-menu .qc-menu-row[aria-checked='true']:hover {
5796
+ color: var(--qc-text-inverse);
5797
+ }
5798
+
5799
+ /* The current starting point wears its mark and its words in the ink cut from the emphasis fill. */
5800
+ [data-qc-theme] .qc-replay-start-menu .qc-menu-row[aria-checked='true'],
5801
+ [data-qc-theme] .qc-replay-start-menu .qc-menu-row[aria-checked='true']:hover {
5802
+ color: var(--qc-control-onInk);
5803
+ }
5804
+
5805
+ [data-qc-theme] .qc-replay-menu .qc-menu-row--marked {
5806
+ height: 34px;
5807
+ padding-inline-start: 8px;
5808
+ }
5809
+
5810
+ [data-qc-theme] .qc-replay-menu .qc-menu-heading {
5811
+ padding: 0 12px;
5812
+ }
5813
+
5814
+ /* A speed's rate reads in the row's own ink and size, held against the far edge. The speed itself
5815
+ * never gives up its width to the rate; the list grows to fit its words from the 196px it opens at. */
5816
+ [data-qc-theme] .qc-replay-menu .qc-menu-label {
5817
+ flex: 0 0 auto;
5818
+ }
5819
+
5820
+ [data-qc-theme] .qc-replay-menu .qc-menu-hint {
5821
+ margin-inline-start: auto;
5822
+ padding: 0;
5823
+ padding-inline-start: 12px;
5824
+ color: inherit;
5825
+ font-size: var(--qc-text-fontSizeBase);
5826
+ }
5827
+
5828
+ [data-qc-theme] .qc-menu-panel.qc-replay-speed-menu {
5829
+ min-width: 196px;
5830
+ }
5831
+
5832
+ [data-qc-theme] .qc-replay-menu .qc-switch-row {
5833
+ padding-inline: 12px 10px;
5834
+ }
5835
+
5836
+ /* The starting points carry the same 28-grid marks the drawing toolbar does, so the gutter is the
5837
+ * mark's own width; a list whose rows carry no mark keeps no gutter for one. */
5838
+ [data-qc-theme] .qc-replay-menu .qc-menu-icon {
5839
+ flex: 0 0 28px;
5840
+ width: 28px;
5841
+ }
5842
+
5843
+ [data-qc-theme] .qc-replay-menu .qc-menu-icon:empty {
5844
+ display: none;
5845
+ }
5846
+
5847
+ /* Logical grid columns handle both a theme-root dir and an ancestor dir without transforms or
5848
+ * negative overflow. When content cannot fit, this intrinsic strip is the row's scroll content. */
5849
+
5850
+ /* The session's mark: a filled disc with the rewind cut out of it in the ground's own ink. The DISC
5851
+ * carries the state — quiet grey while replay is still asking where to start, the accent once it is
5852
+ * running — because the shape is what a viewer recognises and the colour is what tells them how far
5853
+ * along it is. */
5854
+ [data-qc-theme] .qc-legend-replay {
5855
+ display: inline-flex;
5856
+ align-items: center;
5857
+ gap: 4px;
5858
+ color: var(--qc-text-link);
5859
+ font-weight: 500;
5860
+ }
5861
+
5862
+ /* The quiet disc is MIXED toward the plot rather than made translucent: the cut-out is one ink in
5863
+ * both modes, so the disc has to land mid-grey in both for that ink to read on it. A plain 30% wash
5864
+ * lands near-black over a dark plot and near-white over a light one. */
5865
+ [data-qc-theme] .qc-legend-replay[data-qc-phase='arming'] {
5866
+ color: color-mix(in srgb, var(--qc-text-secondary) 70%, var(--qc-canvas-background));
5867
+ }
5868
+
5869
+ /* The arming guide: a rule at the pointer and a wash over everything after it. It is drawn from the
5870
+ * pointer to the END of the plot, because replay starts where the pointer is and what is dimmed is
5871
+ * the future about to be rewound past. Above the canvas, below the chrome, and never in the way of
5872
+ * the click it is asking for. */
5873
+ [data-qc-theme] .qc-replay-guide {
5874
+ position: absolute;
5875
+ inset-block: 0;
5876
+ inset-inline-end: 0;
5877
+ z-index: 5;
5878
+ /* HALF the dialog scrim. The same role dims the chart in both places, but a dialog has taken the
5879
+ * chart away entirely while this has only marked part of it as about to be rewound past: the plot
5880
+ * under the wash still has to be readable, because it is what the viewer is choosing from. */
5881
+ background: color-mix(in srgb, var(--qc-overlay-scrim) 50%, transparent);
5882
+ border-inline-start: 1px solid var(--qc-text-secondary);
5883
+ pointer-events: none;
5884
+ }
5885
+
5886
+ /* The shears ride the rule at the pointer, centred across it. NO plate behind them: open strokes
5887
+ * let the rule stay whole through the mark, where a filled disc would cut a hole in the very line
5888
+ * the mark is pointing at. */
5889
+ [data-qc-theme] .qc-replay-cut {
5890
+ position: absolute;
5891
+ inset-inline-start: 0;
5892
+ color: var(--qc-text-primary);
5893
+ transform: translate(-50%, -50%);
5894
+ }
5895
+
5896
+ /* While the question is open the plot draws no pointer of its own. The shears on the rule are the
5897
+ * pointer, and an arrow or a crosshair beside them would be a second claim about where a click
5898
+ * would land. */
5899
+ [data-qc-theme] .qc-pane[data-qc-replay-arming='true'] {
5900
+ cursor: none;
5901
+ }
5902
+
5903
+ [data-qc-theme] .qc-replay-watermark {
5904
+ position: absolute;
5905
+ inset: 0;
5906
+ z-index: 2;
5907
+ display: flex;
5908
+ align-items: center;
5909
+ justify-content: center;
5910
+ gap: 12px;
5911
+ color: var(--qc-text-onCanvas);
5912
+ font-size: calc(var(--qc-text-fontSizeTitle) * 4);
5913
+ line-height: 1;
5914
+ opacity: 0.07;
5915
+ pointer-events: none;
5916
+ user-select: none;
5917
+ }
5918
+
5919
+ /* The date picker. */
5920
+
5921
+ /* The card stands 302px wide over the undimmed chart: a 68px header, the fields, the calendar and the
5922
+ * chip, and a 67px footer. The header carries the title at 20 on 28, which is the handle the card is
5923
+ * carried by, and the close in a 34px cell whose mark stands 3px past the header's padding. */
5924
+ [data-qc-theme] .qc-date-header {
5925
+ display: flex;
5926
+ flex: 0 0 auto;
5927
+ align-items: center;
5928
+ height: 68px;
5929
+ padding: 0 20px;
5930
+ }
5931
+
5932
+ [data-qc-theme] .qc-date-title {
5933
+ flex: 1 1 auto;
5934
+ min-width: 0;
5935
+ padding: 17px 0;
5936
+ cursor: grab;
5937
+ user-select: none;
5938
+ }
5939
+
5940
+ [data-qc-theme] .qc-date-title-text {
5941
+ display: block;
5942
+ overflow: hidden;
5943
+ color: var(--qc-text-primary);
5944
+ font-size: 20px;
5945
+ font-weight: 600;
5946
+ line-height: 28px;
5947
+ text-overflow: ellipsis;
5948
+ white-space: nowrap;
5949
+ }
5950
+
5951
+ [data-qc-theme] .qc-date-dialog .qc-dialog-close {
5952
+ flex: 0 0 34px;
5953
+ margin-inline-end: -3px;
5954
+ border-radius: 8px;
5955
+ }
5956
+
5957
+ /* The body is a dialog body that sits 17px under the header, edge to edge, and scrolls only in a
5958
+ * viewport shorter than the card. */
5959
+ [data-qc-theme] .qc-date-content {
5960
+ gap: 0;
5961
+ padding: 17px 0 0;
5962
+ }
5963
+
5964
+ /* The fields stand side by side, 150px and 100px with 12px between, 16px over the calendar. Each is
5965
+ * the chart's 34px field box with a 28px mark 3px in from its end, in the caret's ink and the field's
5966
+ * own ink under the pointer: the date's page of days, and the clock that opens the time list. */
5967
+ [data-qc-theme] .qc-date-fields {
5968
+ display: grid;
5969
+ grid-template-columns: 150px 100px;
5970
+ grid-template-rows: 34px;
5971
+ gap: 12px;
5972
+ margin-bottom: 16px;
5973
+ padding: 0 20px;
5974
+ }
5975
+
5976
+ [data-qc-theme] .qc-date-box {
5977
+ position: relative;
5978
+ display: flex;
5979
+ }
5980
+
5981
+ [data-qc-theme] .qc-date-box > .qc-field {
5982
+ flex: 1 1 auto;
5983
+ width: 100%;
5984
+ min-width: 0;
5985
+ padding-inline-end: 33px;
5986
+ font-variant-numeric: tabular-nums;
5987
+ }
5988
+
5989
+ [data-qc-theme] .qc-date-box-mark {
5990
+ position: absolute;
5991
+ inset-block-start: 3px;
5992
+ inset-inline-end: 3px;
5993
+ display: flex;
5994
+ align-items: center;
5995
+ justify-content: center;
5996
+ width: 28px;
5997
+ height: 28px;
5998
+ padding: 0;
5999
+ color: var(--qc-chrome-caret);
6000
+ background: none;
6001
+ border: 0;
6002
+ pointer-events: none;
6003
+ }
6004
+
6005
+ [data-qc-theme] .qc-date-box:hover > .qc-date-box-mark {
6006
+ color: var(--qc-text-primary);
6007
+ }
6008
+
6009
+ [data-qc-theme] .qc-date-clock {
6010
+ cursor: pointer;
6011
+ pointer-events: auto;
6012
+ }
6013
+
6014
+ /* The calendar: 286px on 8px margins, its 262px of content inside 12px, a 34px row of the arrows
6015
+ * around the heading, a 22px band 12px either side, and a 226px view, the whole at least 332px tall.
6016
+ * It reads left to right in every language, as a calendar's columns do. */
6017
+ [data-qc-theme] .qc-date-calendar {
6018
+ display: flex;
6019
+ flex-direction: column;
6020
+ min-height: 332px;
6021
+ margin: 0 8px;
6022
+ padding: 1px 12px 15px;
6023
+ direction: ltr;
6024
+ user-select: none;
6025
+ }
6026
+
6027
+ [data-qc-theme] .qc-date-nav {
6028
+ display: flex;
6029
+ flex: 0 0 34px;
6030
+ align-items: center;
6031
+ justify-content: space-between;
6032
+ padding: 0 3px;
6033
+ }
6034
+
6035
+ /* Every press in the calendar is a 34px cell on an 8px corner with its words at 16 on 24. Under the
6036
+ * pointer it takes the hover fill and its words and mark brighten to the quiet ink; a day or a cell
6037
+ * that cannot be chosen keeps the disabled ink and takes no fill. */
6038
+ [data-qc-theme] .qc-date-step,
6039
+ [data-qc-theme] .qc-date-heading,
6040
+ [data-qc-theme] .qc-date-day,
6041
+ [data-qc-theme] .qc-date-cell {
6042
+ display: flex;
6043
+ align-items: center;
6044
+ justify-content: center;
6045
+ height: 34px;
6046
+ font-size: 16px;
6047
+ line-height: 24px;
6048
+ white-space: nowrap;
6049
+ border-color: transparent;
6050
+ border-radius: 8px;
6051
+ }
6052
+
6053
+ [data-qc-theme] .qc-date-step {
6054
+ flex: 0 0 34px;
6055
+ width: 34px;
6056
+ padding: 0;
6057
+ }
6058
+
6059
+ [data-qc-theme] .qc-date-heading {
6060
+ padding: 0 11px;
6061
+ }
6062
+
6063
+ [data-qc-theme] .qc-date-dialog .qc-dialog-close:hover,
6064
+ [data-qc-theme] .qc-date-step:hover:not([disabled]),
6065
+ [data-qc-theme] .qc-date-heading:hover,
6066
+ [data-qc-theme] .qc-date-day:hover:not([disabled]):not([aria-selected='true']),
6067
+ [data-qc-theme] .qc-date-cell:hover:not([disabled]):not([aria-selected='true']) {
6068
+ color: var(--qc-control-neutralInk);
6069
+ }
6070
+
6071
+ /* The band over the grid, on the quiet fill: the weekdays spread across it in the muted ink, or the
6072
+ * word for the months or the years. */
6073
+ [data-qc-theme] .qc-date-band {
6074
+ display: flex;
6075
+ flex: 0 0 22px;
6076
+ align-items: center;
6077
+ justify-content: space-around;
6078
+ margin: 12px 0;
6079
+ padding: 2px 0;
6080
+ color: var(--qc-text-muted);
6081
+ font-size: 14px;
6082
+ line-height: 18px;
6083
+ background: var(--qc-control-neutral);
6084
+ border-radius: 6px;
4795
6085
  }
4796
6086
 
4797
- [data-qc-theme] .qc-replay-menu .qc-menu-row:hover {
4798
- color: var(--qc-state-hoverInk);
6087
+ [data-qc-theme] .qc-date-view {
6088
+ flex: 0 0 226px;
4799
6089
  }
4800
6090
 
4801
- [data-qc-theme] .qc-replay-menu .qc-menu-row[aria-checked='true'],
4802
- [data-qc-theme] .qc-replay-menu .qc-menu-row[aria-checked='true']:hover {
4803
- color: var(--qc-text-inverse);
6091
+ /* The days: weeks of seven 34px cells 4px apart, the first week against the end and the last against
6092
+ * the start, so each column is one weekday and no day of another month stands in a gap. The chosen day
6093
+ * is on the emphasis fill in the ink cut from it, and today wears a 2px bar under its number in the
6094
+ * number's own ink. */
6095
+ [data-qc-theme] .qc-date-weeks {
6096
+ display: flex;
6097
+ flex-direction: column;
6098
+ gap: 4px;
4804
6099
  }
4805
6100
 
4806
- [data-qc-theme] .qc-replay-menu .qc-menu-row--marked {
4807
- height: 34px;
4808
- padding-inline-start: 8px;
6101
+ [data-qc-theme] .qc-date-week {
6102
+ display: flex;
6103
+ justify-content: space-between;
4809
6104
  }
4810
6105
 
4811
- [data-qc-theme] .qc-replay-menu .qc-menu-heading {
4812
- padding: 0 12px;
6106
+ [data-qc-theme] .qc-date-week:first-child {
6107
+ justify-content: flex-end;
4813
6108
  }
4814
6109
 
4815
- /* A speed's rate reads in the row's own ink and size, held against the far edge. The speed itself
4816
- * never gives up its width to the rate; the list grows to fit its words from the 196px it opens at. */
4817
- [data-qc-theme] .qc-replay-menu .qc-menu-label {
4818
- flex: 0 0 auto;
6110
+ [data-qc-theme] .qc-date-week:last-child {
6111
+ justify-content: flex-start;
4819
6112
  }
4820
6113
 
4821
- [data-qc-theme] .qc-replay-menu .qc-menu-hint {
4822
- margin-inline-start: auto;
6114
+ [data-qc-theme] .qc-date-week:first-child > .qc-date-day + .qc-date-day,
6115
+ [data-qc-theme] .qc-date-week:last-child > .qc-date-day + .qc-date-day {
6116
+ margin-inline-start: 4px;
6117
+ }
6118
+
6119
+ [data-qc-theme] .qc-date-day {
6120
+ position: relative;
6121
+ flex: 0 0 34px;
6122
+ width: 34px;
4823
6123
  padding: 0;
4824
- padding-inline-start: 12px;
4825
- color: inherit;
4826
- font-size: var(--qc-text-fontSizeBase);
4827
6124
  }
4828
6125
 
4829
- [data-qc-theme] .qc-menu-panel.qc-replay-speed-menu {
4830
- min-width: 196px;
6126
+ [data-qc-theme] .qc-date-day[aria-selected='true']:not([disabled]) {
6127
+ color: var(--qc-control-onInk);
6128
+ background: var(--qc-control-on);
6129
+ border-color: var(--qc-control-on);
4831
6130
  }
4832
6131
 
4833
- [data-qc-theme] .qc-replay-menu .qc-switch-row {
4834
- padding-inline: 12px 10px;
6132
+ [data-qc-theme] .qc-date-day[aria-current='date']::before {
6133
+ position: absolute;
6134
+ inset-inline: 6px;
6135
+ top: 100%;
6136
+ height: 2px;
6137
+ margin-top: -6px;
6138
+ background: currentColor;
6139
+ border-radius: 1px;
6140
+ content: '';
4835
6141
  }
4836
6142
 
4837
- /* The starting points carry the same 28-grid marks the drawing toolbar does, so the gutter is the
4838
- * mark's own width; a list whose rows carry no mark keeps no gutter for one. */
4839
- [data-qc-theme] .qc-replay-menu .qc-menu-icon {
4840
- flex: 0 0 28px;
4841
- width: 28px;
6143
+ /* The months, three to a row 30px apart, and the years, four to a row 14px apart, 3px between
6144
+ * columns. The chosen month or year stands on the quiet fill, a step up under the pointer. */
6145
+ [data-qc-theme] .qc-date-months,
6146
+ [data-qc-theme] .qc-date-years {
6147
+ display: grid;
6148
+ grid-auto-rows: 34px;
6149
+ column-gap: 3px;
4842
6150
  }
4843
6151
 
4844
- [data-qc-theme] .qc-replay-menu .qc-menu-icon:empty {
4845
- display: none;
6152
+ [data-qc-theme] .qc-date-months {
6153
+ grid-template-columns: repeat(3, minmax(0, 1fr));
6154
+ row-gap: 30px;
4846
6155
  }
4847
6156
 
4848
- /* Logical grid columns handle both a theme-root dir and an ancestor dir without transforms or
4849
- * negative overflow. When content cannot fit, this intrinsic strip is the row's scroll content. */
6157
+ [data-qc-theme] .qc-date-years {
6158
+ grid-template-columns: repeat(4, minmax(0, 1fr));
6159
+ row-gap: 14px;
6160
+ }
4850
6161
 
4851
- /* The session's mark: a filled disc with the rewind cut out of it in the ground's own ink. The DISC
4852
- * carries the state — quiet grey while replay is still asking where to start, the accent once it is
4853
- * running — because the shape is what a viewer recognises and the colour is what tells them how far
4854
- * along it is. */
4855
- [data-qc-theme] .qc-legend-replay {
4856
- display: inline-flex;
4857
- align-items: center;
4858
- gap: 4px;
4859
- color: var(--qc-text-link);
4860
- font-weight: 500;
6162
+ [data-qc-theme] .qc-date-row {
6163
+ display: contents;
4861
6164
  }
4862
6165
 
4863
- /* The quiet disc is MIXED toward the plot rather than made translucent: the cut-out is one ink in
4864
- * both modes, so the disc has to land mid-grey in both for that ink to read on it. A plain 30% wash
4865
- * lands near-black over a dark plot and near-white over a light one. */
4866
- [data-qc-theme] .qc-legend-replay[data-qc-phase='arming'] {
4867
- color: color-mix(in srgb, var(--qc-text-secondary) 70%, var(--qc-canvas-background));
6166
+ [data-qc-theme] .qc-date-cell {
6167
+ min-width: 0;
6168
+ padding: 0 11px;
4868
6169
  }
4869
6170
 
4870
- /* The arming guide: a rule at the pointer and a wash over everything after it. It is drawn from the
4871
- * pointer to the END of the plot, because replay starts where the pointer is and what is dimmed is
4872
- * the future about to be rewound past. Above the canvas, below the chrome, and never in the way of
4873
- * the click it is asking for. */
4874
- [data-qc-theme] .qc-replay-guide {
4875
- position: absolute;
4876
- inset-block: 0;
4877
- inset-inline-end: 0;
4878
- z-index: 5;
4879
- /* HALF the dialog scrim. The same role dims the chart in both places, but a dialog has taken the
4880
- * chart away entirely while this has only marked part of it as about to be rewound past: the plot
4881
- * under the wash still has to be readable, because it is what the viewer is choosing from. */
4882
- background: color-mix(in srgb, var(--qc-overlay-scrim) 50%, transparent);
4883
- border-inline-start: 1px solid var(--qc-text-secondary);
4884
- pointer-events: none;
6171
+ [data-qc-theme] .qc-date-years .qc-date-cell {
6172
+ padding: 0 4px;
4885
6173
  }
4886
6174
 
4887
- /* The shears ride the rule at the pointer, centred across it. NO plate behind them: open strokes
4888
- * let the rule stay whole through the mark, where a filled disc would cut a hole in the very line
4889
- * the mark is pointing at. */
4890
- [data-qc-theme] .qc-replay-cut {
4891
- position: absolute;
4892
- inset-inline-start: 0;
4893
- color: var(--qc-text-primary);
4894
- transform: translate(-50%, -50%);
6175
+ [data-qc-theme] .qc-date-cell[aria-selected='true']:not([disabled]) {
6176
+ color: var(--qc-control-neutralInk);
6177
+ background: var(--qc-control-neutral);
6178
+ border-color: var(--qc-control-neutral);
4895
6179
  }
4896
6180
 
4897
- /* While the question is open the plot draws no pointer of its own. The shears on the rule are the
4898
- * pointer, and an arrow or a crosshair beside them would be a second claim about where a click
4899
- * would land. */
4900
- [data-qc-theme] .qc-pane[data-qc-replay-arming='true'] {
4901
- cursor: none;
6181
+ [data-qc-theme] .qc-date-cell[aria-selected='true']:not([disabled]):hover {
6182
+ background: var(--qc-control-neutralHover);
6183
+ border-color: var(--qc-control-neutralHover);
4902
6184
  }
4903
6185
 
4904
- [data-qc-theme] .qc-replay-watermark {
4905
- position: absolute;
4906
- inset: 0;
4907
- z-index: 2;
6186
+ /* The chip under the calendar: 40px tall, its words at 16 on 24 and 15px in, centred and 10px over
6187
+ * the footer, on the quiet fill a step up under the pointer and another while pressed. */
6188
+ [data-qc-theme] .qc-date-first-row {
4908
6189
  display: flex;
4909
- align-items: center;
4910
6190
  justify-content: center;
4911
- gap: 12px;
4912
- color: var(--qc-text-onCanvas);
4913
- font-size: calc(var(--qc-text-fontSizeTitle) * 4);
4914
- line-height: 1;
4915
- opacity: 0.07;
4916
- pointer-events: none;
4917
- user-select: none;
4918
6191
  }
4919
6192
 
4920
- /* The date picker. */
4921
- [data-qc-theme] .qc-date-fields {
4922
- display: flex;
4923
- gap: 8px;
6193
+ [data-qc-theme] .qc-date-first {
6194
+ display: inline-flex;
6195
+ align-items: center;
6196
+ justify-content: center;
6197
+ height: 40px;
6198
+ margin-bottom: 10px;
6199
+ padding: 0 15px;
6200
+ color: var(--qc-control-neutralInk);
6201
+ font-size: 16px;
6202
+ line-height: 24px;
6203
+ white-space: nowrap;
6204
+ background: var(--qc-control-neutral);
6205
+ border-color: var(--qc-control-neutral);
6206
+ border-radius: 8px;
4924
6207
  }
4925
6208
 
4926
- [data-qc-theme] .qc-date-field {
4927
- flex: 1 1 auto;
4928
- min-width: 0;
4929
- padding: 6px 8px;
4930
- font-variant-numeric: tabular-nums;
6209
+ [data-qc-theme] .qc-date-first:hover {
6210
+ background: var(--qc-control-neutralHover);
6211
+ border-color: var(--qc-control-neutralHover);
4931
6212
  }
4932
6213
 
4933
- [data-qc-theme] .qc-date-time {
4934
- flex: 0 0 74px;
4935
- padding: 6px 8px;
4936
- font-variant-numeric: tabular-nums;
6214
+ [data-qc-theme] .qc-date-first:active {
6215
+ background: var(--qc-control-neutralPressed);
6216
+ border-color: var(--qc-control-neutralPressed);
4937
6217
  }
4938
6218
 
4939
- [data-qc-theme] .qc-date-nav {
6219
+ /* The footer under a 1px rule: Cancel and Select at its end, 34px tall and 12px apart, their words at
6220
+ * 16 on 24 and 11px in. Cancel is outlined in the outline role and takes the emphasis fill under the
6221
+ * pointer; Select wears the fill. */
6222
+ [data-qc-theme] .qc-date-footer {
4940
6223
  display: flex;
4941
- align-items: center;
4942
- justify-content: space-between;
4943
- padding: 6px 0 2px;
6224
+ flex: 0 0 auto;
6225
+ justify-content: flex-end;
6226
+ padding: 16px 20px;
6227
+ border-top: 1px solid var(--qc-overlay-separator);
4944
6228
  }
4945
6229
 
4946
- [data-qc-theme] .qc-date-nav .qc-button {
6230
+ [data-qc-theme] .qc-date-footer .qc-button {
4947
6231
  display: inline-flex;
4948
6232
  align-items: center;
4949
6233
  justify-content: center;
4950
- width: 28px;
4951
- height: 28px;
4952
- padding: 0;
4953
- border-color: transparent;
6234
+ height: 34px;
6235
+ padding: 0 11px;
6236
+ font-size: 16px;
6237
+ line-height: 24px;
6238
+ white-space: nowrap;
6239
+ border-radius: 8px;
6240
+ }
6241
+
6242
+ [data-qc-theme] .qc-date-footer .qc-button + .qc-button {
6243
+ margin-inline-start: 12px;
4954
6244
  }
4955
6245
 
4956
- [data-qc-theme] .qc-date-grid {
6246
+ [data-qc-theme] .qc-date-cancel {
6247
+ color: var(--qc-control-outline);
6248
+ border-color: var(--qc-control-outline);
6249
+ }
6250
+
6251
+ [data-qc-theme] .qc-date-cancel:hover:not([disabled]) {
6252
+ color: var(--qc-text-inverse);
6253
+ background: var(--qc-control-on);
6254
+ border-color: var(--qc-control-on);
6255
+ }
6256
+
6257
+ [data-qc-theme] .qc-date-cancel:active:not([disabled]) {
6258
+ color: var(--qc-text-inverse);
6259
+ background: var(--qc-control-onPressed);
6260
+ border-color: var(--qc-control-onPressed);
6261
+ }
6262
+
6263
+ /* The time list stands on the dialog's backdrop directly under the time field and as wide as it, at
6264
+ * most 231px tall over a scroll of its own: the day in quarter hours on 32px rows with their words
6265
+ * 12px in. The time the field holds is on the emphasis fill; the row under the pointer, or the one
6266
+ * the keyboard walked to, takes the hover fill and dims its words. */
6267
+ [data-qc-theme] .qc-date-times {
6268
+ position: absolute;
6269
+ z-index: 1;
4957
6270
  display: flex;
4958
6271
  flex-direction: column;
4959
- gap: 2px;
6272
+ max-height: 231px;
6273
+ overflow: hidden;
4960
6274
  }
4961
6275
 
4962
- [data-qc-theme] .qc-date-row {
4963
- display: grid;
4964
- grid-template-columns: repeat(7, 1fr);
4965
- gap: 2px;
6276
+ [data-qc-theme] .qc-date-times-body {
6277
+ position: relative;
4966
6278
  }
4967
6279
 
4968
- [data-qc-theme] .qc-date-head {
4969
- display: flex;
4970
- align-items: center;
4971
- justify-content: center;
4972
- height: 24px;
6280
+ [data-qc-theme] .qc-date-times-rows {
6281
+ padding: 6px 0;
4973
6282
  }
4974
6283
 
4975
- [data-qc-theme] .qc-date-day {
6284
+ [data-qc-theme] .qc-date-time-option {
4976
6285
  display: flex;
4977
6286
  align-items: center;
4978
- justify-content: center;
4979
- height: 28px;
4980
- padding: 0;
6287
+ height: 32px;
6288
+ padding-block: 0;
6289
+ padding-inline: 12px 10px;
6290
+ color: var(--qc-text-primary);
6291
+ font-size: 14px;
6292
+ line-height: 16px;
4981
6293
  font-variant-numeric: tabular-nums;
4982
- border-color: transparent;
6294
+ cursor: default;
6295
+ user-select: none;
4983
6296
  }
4984
6297
 
4985
- [data-qc-theme] .qc-date-day[aria-selected='true'] {
4986
- color: var(--qc-state-markInk);
4987
- background: var(--qc-state-accent);
4988
- border-color: var(--qc-state-accent);
6298
+ [data-qc-theme] .qc-date-time-option:hover,
6299
+ [data-qc-theme] .qc-date-time-option[data-qc-active='true'] {
6300
+ color: var(--qc-state-hoverInk);
6301
+ background: var(--qc-state-hover);
6302
+ }
6303
+
6304
+ [data-qc-theme] .qc-date-time-option[aria-selected='true'] {
6305
+ color: var(--qc-control-onInk);
6306
+ background: var(--qc-control-on);
6307
+ }
6308
+
6309
+ /* Forced colors: what is chosen in the calendar and the time list stands in the system highlight. */
6310
+ @media (forced-colors: active) {
6311
+ [data-qc-theme] .qc-date-day[aria-selected='true'],
6312
+ [data-qc-theme] .qc-date-cell[aria-selected='true'],
6313
+ [data-qc-theme] .qc-date-time-option[aria-selected='true'] {
6314
+ forced-color-adjust: none;
6315
+ color: HighlightText;
6316
+ background: Highlight;
6317
+ }
4989
6318
  }
4990
6319
 
4991
6320
  /* The thin bar beside a list the viewer scrolls to find something: the search results, the
@@ -5236,34 +6565,18 @@
5236
6565
  padding-top: 0;
5237
6566
  }
5238
6567
 
5239
- [data-qc-theme] .qc-search-scope {
5240
- display: inline-flex;
6568
+ /* The classes' own group in the strip: their chips, 4px apart, as one run the scope stands apart
6569
+ * from. */
6570
+ [data-qc-theme] .qc-search-class-group {
6571
+ display: flex;
5241
6572
  flex: 0 0 auto;
5242
- align-items: center;
5243
- gap: 7px;
5244
- height: 28px;
5245
- margin-inline-start: auto;
5246
- padding: 0 10px 0 6px;
5247
- color: var(--qc-text-primary);
5248
- font-size: var(--qc-text-fontSizeBase);
5249
- line-height: 18px;
5250
- background: var(--qc-state-hover);
5251
- border-radius: 14px;
5252
- white-space: nowrap;
5253
- }
5254
-
5255
- [data-qc-theme] .qc-search-scope-mark {
5256
- display: inline-flex;
5257
- flex: 0 0 18px;
5258
- align-items: center;
5259
- justify-content: center;
5260
- width: 18px;
5261
- height: 18px;
5262
- overflow: hidden;
6573
+ gap: 4px;
5263
6574
  }
5264
6575
 
5265
- /* A class rests on the neutral fill, steps deeper under the pointer and deeper again while pressed. */
5266
- [data-qc-theme] .qc-search-class {
6576
+ /* A class rests on the neutral fill, steps deeper under the pointer and deeper again while pressed.
6577
+ * The scope chip is the same tab in the same states. */
6578
+ [data-qc-theme] .qc-search-class,
6579
+ [data-qc-theme] .qc-search-scope {
5267
6580
  flex: 0 0 auto;
5268
6581
  height: 28px;
5269
6582
  padding: 0 11px;
@@ -5276,26 +6589,52 @@
5276
6589
  white-space: nowrap;
5277
6590
  }
5278
6591
 
5279
- [data-qc-theme] .qc-search-class:hover {
6592
+ [data-qc-theme] .qc-search-class:hover,
6593
+ [data-qc-theme] .qc-search-scope:hover {
5280
6594
  background: var(--qc-state-pressed);
5281
6595
  border-color: var(--qc-state-pressed);
5282
6596
  }
5283
6597
 
5284
- [data-qc-theme] .qc-search-class:active {
6598
+ [data-qc-theme] .qc-search-class:active,
6599
+ [data-qc-theme] .qc-search-scope:active {
5285
6600
  background: var(--qc-state-pressedHover);
5286
6601
  border-color: var(--qc-state-pressedHover);
5287
6602
  }
5288
6603
 
5289
6604
  /* The chosen class INVERTS, under the pointer as at rest: one tab out of a row has to be
5290
- * unmistakable at a glance, and a deeper step of the same fill would only be a louder hover. */
6605
+ * unmistakable at a glance, and a deeper step of the same fill would only be a louder hover. A
6606
+ * scope that limits the search inverts the same way. */
5291
6607
  [data-qc-theme] .qc-search-class[aria-pressed='true'],
5292
6608
  [data-qc-theme] .qc-search-class[aria-pressed='true']:hover,
5293
- [data-qc-theme] .qc-search-class[aria-pressed='true']:active {
6609
+ [data-qc-theme] .qc-search-class[aria-pressed='true']:active,
6610
+ [data-qc-theme] .qc-search-scope[aria-pressed='true'],
6611
+ [data-qc-theme] .qc-search-scope[aria-pressed='true']:hover,
6612
+ [data-qc-theme] .qc-search-scope[aria-pressed='true']:active {
5294
6613
  color: var(--qc-text-inverse);
5295
6614
  background: var(--qc-control-on);
5296
6615
  border-color: var(--qc-control-on);
5297
6616
  }
5298
6617
 
6618
+ /* The scope stands at the far edge of the strip: the host's mark 6px in from the chip's leading
6619
+ * edge and 7px before the scope's name. */
6620
+ [data-qc-theme] .qc-search-scope {
6621
+ display: inline-flex;
6622
+ align-items: center;
6623
+ gap: 7px;
6624
+ margin-inline-start: auto;
6625
+ padding-inline: 6px 10px;
6626
+ }
6627
+
6628
+ [data-qc-theme] .qc-search-scope-mark {
6629
+ display: inline-flex;
6630
+ flex: 0 0 18px;
6631
+ align-items: center;
6632
+ justify-content: center;
6633
+ width: 18px;
6634
+ height: 18px;
6635
+ overflow: hidden;
6636
+ }
6637
+
5299
6638
  [data-qc-theme] .qc-search-list {
5300
6639
  flex: 1 1 auto;
5301
6640
  min-height: 0;
@@ -5748,14 +7087,18 @@
5748
7087
  font-size: 14px;
5749
7088
  }
5750
7089
 
7090
+ /* A color here keeps its swatch: a 38 by 34 box on the raised fill, its well 3px in from the edge on
7091
+ * a corner that follows the box's. The edge, its step under the pointer and the focus ring are the
7092
+ * field's own, and a well that cannot be used stands on the read-only fill as every field does. */
5751
7093
  [data-qc-theme] .qc-settings-menu .qc-settings-row .qc-drawing-swatch-button {
5752
7094
  box-sizing: border-box;
5753
7095
  width: 38px;
5754
7096
  height: 34px;
5755
7097
  padding: 3px;
7098
+ }
7099
+
7100
+ [data-qc-theme] .qc-settings-menu .qc-settings-row .qc-drawing-swatch-button:enabled {
5756
7101
  background: var(--qc-chrome-surfaceRaised);
5757
- border-color: var(--qc-chrome-fieldBorder);
5758
- border-radius: 6px;
5759
7102
  }
5760
7103
 
5761
7104
  [data-qc-theme] .qc-settings-menu .qc-settings-row .qc-drawing-well {