@fungi.computer/caps 0.7.1 → 0.9.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 (45) hide show
  1. package/README.md +58 -0
  2. package/dist/blocks/app-bar.d.ts +4 -2
  3. package/dist/blocks/app-bar.js +3 -3
  4. package/dist/blocks/empty-state.d.ts +31 -4
  5. package/dist/blocks/empty-state.js +14 -4
  6. package/dist/blocks/loading-state.d.ts +41 -0
  7. package/dist/blocks/loading-state.js +18 -3
  8. package/dist/blocks/permission-grid.js +1 -1
  9. package/dist/blocks/result-state.d.ts +18 -0
  10. package/dist/blocks/result-state.js +7 -2
  11. package/dist/blocks/setup-notice.d.ts +32 -0
  12. package/dist/blocks/setup-notice.js +23 -0
  13. package/dist/components/button.js +2 -2
  14. package/dist/components/confirm-action.d.ts +6 -1
  15. package/dist/components/confirm-action.js +3 -3
  16. package/dist/components/dialog.js +1 -1
  17. package/dist/components/failure-line.d.ts +46 -0
  18. package/dist/components/failure-line.js +12 -0
  19. package/dist/components/keycap.d.ts +15 -2
  20. package/dist/components/keycap.js +3 -3
  21. package/dist/components/loader-blobs.d.ts +3 -2
  22. package/dist/components/loader-blobs.js +5 -3
  23. package/dist/components/loader.d.ts +8 -2
  24. package/dist/components/loader.js +4 -2
  25. package/dist/components/toaster.d.ts +5 -1
  26. package/dist/components/toaster.js +16 -2
  27. package/dist/styles.css +485 -28
  28. package/docs/api/README.md +2 -0
  29. package/docs/api/blocks/app-bar.md +9 -1
  30. package/docs/api/blocks/empty-state.md +30 -11
  31. package/docs/api/blocks/loading-state.md +33 -0
  32. package/docs/api/blocks/result-state.md +30 -6
  33. package/docs/api/blocks/setup-notice.md +82 -0
  34. package/docs/api/components/confirm-action.md +8 -6
  35. package/docs/api/components/data-list.md +33 -0
  36. package/docs/api/components/failure-line.md +50 -0
  37. package/docs/api/components/field.md +9 -8
  38. package/docs/api/components/icon-checkbox.md +55 -0
  39. package/docs/api/components/icon-radio.md +39 -5
  40. package/docs/api/components/keycap.md +10 -7
  41. package/docs/api/components/loader.md +18 -7
  42. package/docs/api/components/toaster.md +2 -0
  43. package/package.json +15 -6
  44. package/src/first-run.css +100 -0
  45. package/src/styles.css +394 -21
package/src/styles.css CHANGED
@@ -6,6 +6,7 @@
6
6
  @import "@fungi.computer/stipe/styles.css";
7
7
  @import "./status-tray.css";
8
8
  @import "./app-status-bar.css";
9
+ @import "./first-run.css";
9
10
 
10
11
  @plugin "@tailwindcss/typography";
11
12
 
@@ -42,6 +43,134 @@
42
43
  z-index: var(--stipe-layer-toast);
43
44
  }
44
45
 
46
+ /* Unlayered on purpose: Sonner injects an unlayered sheet at runtime, which
47
+ would outrank anything inside a cascade layer. */
48
+ /* Sonner paints from --normal-* and per-type variables; point them at the
49
+ Stipe tokens so latte, mocha and any data-theme switch are followed. */
50
+ .caps-toaster[data-sonner-toaster][data-sonner-theme] {
51
+ font-family: inherit;
52
+ --border-radius: var(--radius-box);
53
+ --normal-bg: var(--stipe-surface-raised);
54
+ --normal-bg-hover: var(--color-base-200);
55
+ --normal-border: var(--stipe-hairline-quiet);
56
+ --normal-border-hover: var(--stipe-hairline);
57
+ --normal-text: var(--color-base-content);
58
+ --success-bg: color-mix(
59
+ in oklab,
60
+ var(--color-success) 10%,
61
+ var(--stipe-surface-raised)
62
+ );
63
+ --success-border: color-mix(in oklab, var(--color-success) 35%, transparent);
64
+ --success-text: var(--color-base-content);
65
+ --info-bg: color-mix(
66
+ in oklab,
67
+ var(--color-info) 10%,
68
+ var(--stipe-surface-raised)
69
+ );
70
+ --info-border: color-mix(in oklab, var(--color-info) 35%, transparent);
71
+ --info-text: var(--color-base-content);
72
+ --warning-bg: color-mix(
73
+ in oklab,
74
+ var(--color-warning) 12%,
75
+ var(--stipe-surface-raised)
76
+ );
77
+ --warning-border: color-mix(in oklab, var(--color-warning) 40%, transparent);
78
+ --warning-text: var(--color-base-content);
79
+ --error-bg: color-mix(
80
+ in oklab,
81
+ var(--color-error) 10%,
82
+ var(--stipe-surface-raised)
83
+ );
84
+ --error-border: color-mix(in oklab, var(--color-error) 40%, transparent);
85
+ --error-text: var(--color-base-content);
86
+ }
87
+ .caps-toaster[data-sonner-toaster] [data-sonner-toast][data-styled="true"] {
88
+ font-size: var(--text-sm);
89
+ line-height: 1.35;
90
+ box-shadow: 0 0.25rem 0.75rem
91
+ color-mix(
92
+ in oklab,
93
+ var(--color-base-content) calc(var(--depth) * 14%),
94
+ transparent
95
+ );
96
+ }
97
+ .caps-toaster[data-sonner-toaster] [data-sonner-toast][data-styled] {
98
+ align-items: flex-start;
99
+ font-family: inherit;
100
+ }
101
+ /* The icon sits on the title line, not centred on a two-line block. */
102
+ .caps-toaster[data-sonner-toaster]
103
+ [data-sonner-toast][data-styled]
104
+ [data-icon] {
105
+ align-items: center;
106
+ height: calc(var(--text-sm) * 1.35);
107
+ margin: 0;
108
+ }
109
+ .caps-toaster[data-sonner-toaster]
110
+ [data-sonner-toast][data-styled]
111
+ [data-description] {
112
+ color: color-mix(in oklab, var(--color-base-content) 78%, transparent);
113
+ }
114
+ /* One close position: inline at the end, top-aligned with the first line. */
115
+ .caps-toaster[data-sonner-toaster]
116
+ [data-sonner-toast][data-styled]
117
+ [data-close-button] {
118
+ position: static;
119
+ order: 99;
120
+ align-self: flex-start;
121
+ margin-inline-start: auto;
122
+ transform: none;
123
+ flex: none;
124
+ }
125
+ .caps-toaster[data-sonner-toaster]
126
+ [data-sonner-toast][data-styled]
127
+ [data-icon] {
128
+ color: var(--color-base-content);
129
+ }
130
+ .caps-toaster[data-sonner-toaster]
131
+ [data-sonner-toast][data-styled][data-type="success"]
132
+ [data-icon] {
133
+ color: var(--color-success);
134
+ }
135
+ .caps-toaster[data-sonner-toaster]
136
+ [data-sonner-toast][data-styled][data-type="error"]
137
+ [data-icon] {
138
+ color: var(--color-error);
139
+ }
140
+ .caps-toaster[data-sonner-toaster]
141
+ [data-sonner-toast][data-styled][data-type="warning"]
142
+ [data-icon] {
143
+ color: var(--color-warning);
144
+ }
145
+ .caps-toaster[data-sonner-toaster]
146
+ [data-sonner-toast][data-styled][data-type="info"]
147
+ [data-icon] {
148
+ color: var(--color-info);
149
+ }
150
+ .caps-toaster[data-sonner-toaster]
151
+ [data-sonner-toast][data-styled]
152
+ [data-close-button] {
153
+ width: 1.25rem;
154
+ height: 1.25rem;
155
+ color: var(--color-base-content);
156
+ background: var(--stipe-surface-raised);
157
+ border: var(--border) solid var(--stipe-hairline);
158
+ transition-duration: var(--stipe-motion-fast);
159
+ }
160
+ .caps-toaster[data-sonner-toaster]
161
+ [data-sonner-toast][data-styled]
162
+ [data-close-button]:hover {
163
+ background: var(--color-base-200);
164
+ border-color: var(--stipe-hairline);
165
+ }
166
+ .caps-toaster[data-sonner-toaster]
167
+ [data-sonner-toast][data-styled]
168
+ [data-close-button]:focus-visible {
169
+ outline: 2px solid var(--caps-focus-ring);
170
+ outline-offset: 1px;
171
+ box-shadow: none;
172
+ }
173
+
45
174
  @layer caps-dropdown {
46
175
  .caps-dropdown-popup {
47
176
  max-height: var(--available-height);
@@ -121,7 +250,7 @@
121
250
  --tw-prose-bold: var(--color-base-content);
122
251
  --tw-prose-counters: var(--stipe-fg-muted);
123
252
  --tw-prose-bullets: var(--stipe-fg-muted);
124
- --tw-prose-hr: var(--stipe-hairline);
253
+ --tw-prose-hr: var(--stipe-hairline-quiet);
125
254
  --tw-prose-quotes: var(--color-base-content);
126
255
  --tw-prose-quote-borders: var(--stipe-linework);
127
256
  --tw-prose-captions: var(--stipe-fg-muted);
@@ -130,7 +259,7 @@
130
259
  --tw-prose-pre-code: var(--color-base-content);
131
260
  --tw-prose-pre-bg: var(--color-base-200);
132
261
  --tw-prose-th-borders: var(--stipe-linework);
133
- --tw-prose-td-borders: var(--stipe-hairline);
262
+ --tw-prose-td-borders: var(--stipe-hairline-quiet);
134
263
  font-family: var(--font-sans);
135
264
  line-height: var(--caps-prose-leading, 1.75);
136
265
  }
@@ -171,6 +300,14 @@
171
300
  outline: none;
172
301
  box-shadow: none;
173
302
  }
303
+ /* A busy ghost is pending, not disabled: it keeps its ink. */
304
+ .caps-button.btn-ghost[aria-busy="true"]:is(
305
+ :disabled,
306
+ [aria-disabled="true"]
307
+ ) {
308
+ --btn-fg: var(--color-base-content);
309
+ color: var(--color-base-content);
310
+ }
174
311
  }
175
312
 
176
313
  @layer components {
@@ -223,7 +360,7 @@
223
360
  align-items: center;
224
361
  justify-content: space-between;
225
362
  gap: var(--spacing-sm);
226
- border-bottom: var(--border) solid var(--stipe-hairline);
363
+ border-bottom: var(--border) solid var(--stipe-hairline-quiet);
227
364
  padding: var(--spacing-xs) var(--spacing-xs) var(--spacing-xs)
228
365
  var(--spacing-md);
229
366
  }
@@ -397,6 +534,11 @@
397
534
  color: var(--marginalia-ink);
398
535
  font-size: 0.875em;
399
536
  }
537
+ @media (pointer: coarse) {
538
+ .caps-keycap[data-touch="hide"] {
539
+ display: none;
540
+ }
541
+ }
400
542
  .caps-keycap {
401
543
  display: inline-grid;
402
544
  min-width: var(--caps-keycap-legend-min-size, 2rem);
@@ -1555,6 +1697,22 @@
1555
1697
  .caps-shortcuts dd {
1556
1698
  margin: 0;
1557
1699
  }
1700
+ /* A default dialog keeps a 16px gutter on each side (more where the device
1701
+ has a safe-area inset) and never outgrows the screen vertically. */
1702
+ .caps-dialog-popup-default {
1703
+ width: min(
1704
+ var(--container-lg),
1705
+ calc(
1706
+ 100% - max(1rem, env(safe-area-inset-left)) -
1707
+ max(1rem, env(safe-area-inset-right))
1708
+ )
1709
+ );
1710
+ max-width: none;
1711
+ max-height: calc(
1712
+ 100dvh - max(1rem, env(safe-area-inset-top)) -
1713
+ max(1rem, env(safe-area-inset-bottom))
1714
+ );
1715
+ }
1558
1716
  dialog.caps-surface {
1559
1717
  color: inherit;
1560
1718
  }
@@ -2306,15 +2464,14 @@
2306
2464
  color-mix(in oklch, var(--color-base-content) 22%, var(--color-base-100));
2307
2465
  border-radius: var(--radius-box);
2308
2466
  background: var(--color-base-100);
2309
- overflow-x: auto;
2467
+ container-type: inline-size;
2310
2468
  }
2311
2469
  .caps-permission-grid-caption {
2312
2470
  display: flex;
2313
2471
  flex-direction: column;
2314
2472
  gap: var(--spacing-2xs);
2315
2473
  padding: var(--spacing-sm) var(--spacing-md);
2316
- border-bottom: var(--border) solid
2317
- color-mix(in oklch, var(--color-base-content) 22%, var(--color-base-100));
2474
+ border-bottom: var(--border) solid var(--stipe-hairline-quiet);
2318
2475
  }
2319
2476
  .caps-permission-grid-title {
2320
2477
  font-family: var(--font-mono);
@@ -2330,8 +2487,18 @@
2330
2487
  .caps-permission-grid table {
2331
2488
  width: 100%;
2332
2489
  border-collapse: collapse;
2490
+ table-layout: fixed;
2333
2491
  font-size: 0.875rem;
2334
2492
  }
2493
+ .caps-permission-grid-col-state {
2494
+ width: 5rem;
2495
+ }
2496
+ .caps-permission-grid-col-scope {
2497
+ width: 28%;
2498
+ }
2499
+ .caps-permission-grid-col-control {
2500
+ width: 5.5rem;
2501
+ }
2335
2502
  .caps-permission-grid thead th {
2336
2503
  padding: var(--spacing-xs) var(--spacing-md);
2337
2504
  font-family: var(--font-mono);
@@ -2341,8 +2508,7 @@
2341
2508
  text-align: start;
2342
2509
  text-transform: uppercase;
2343
2510
  opacity: 0.7;
2344
- border-bottom: var(--border) solid
2345
- color-mix(in oklch, var(--color-base-content) 22%, var(--color-base-100));
2511
+ border-bottom: var(--border) solid var(--stipe-hairline-quiet);
2346
2512
  }
2347
2513
  .caps-permission-grid tbody td,
2348
2514
  .caps-permission-grid tbody th {
@@ -2350,14 +2516,13 @@
2350
2516
  text-align: start;
2351
2517
  vertical-align: middle;
2352
2518
  font-weight: 400;
2353
- border-bottom: var(--border) dashed
2354
- color-mix(in oklch, var(--color-base-content) 14%, var(--color-base-100));
2519
+ border-bottom: var(--border) solid var(--stipe-hairline-quiet);
2355
2520
  }
2356
2521
  .caps-permission-grid tbody tr:last-child > * {
2357
2522
  border-bottom: 0;
2358
2523
  }
2359
2524
  .caps-permission-grid-index {
2360
- width: 1%;
2525
+ width: 5.5rem;
2361
2526
  white-space: nowrap;
2362
2527
  font-family: var(--font-mono);
2363
2528
  font-size: 0.75rem;
@@ -2366,7 +2531,12 @@
2366
2531
  .caps-permission-grid-index > span {
2367
2532
  display: block;
2368
2533
  }
2534
+ .caps-permission-grid-index {
2535
+ overflow: hidden;
2536
+ }
2369
2537
  .caps-permission-grid-group {
2538
+ overflow: hidden;
2539
+ text-overflow: ellipsis;
2370
2540
  font-size: 0.625rem;
2371
2541
  letter-spacing: 0.08em;
2372
2542
  text-transform: uppercase;
@@ -2414,6 +2584,41 @@
2414
2584
  font-size: 0.75rem;
2415
2585
  opacity: 0.8;
2416
2586
  }
2587
+ /* On a narrow grid (a phone, or a narrow window) the index column and extra
2588
+ padding go, so the switch column is never pushed off the sheet. */
2589
+ @container (width <= 30rem) {
2590
+ .caps-permission-grid-index {
2591
+ display: none;
2592
+ }
2593
+ .caps-permission-grid-col-state {
2594
+ width: 3.25rem;
2595
+ }
2596
+ .caps-permission-grid-col-scope {
2597
+ width: 5.5rem;
2598
+ }
2599
+ .caps-permission-grid-col-control {
2600
+ width: 3.75rem;
2601
+ }
2602
+ .caps-permission-grid thead th,
2603
+ .caps-permission-grid tbody td,
2604
+ .caps-permission-grid tbody th {
2605
+ padding-inline: var(--spacing-xs);
2606
+ }
2607
+ .caps-permission-grid-capability {
2608
+ gap: var(--spacing-xs);
2609
+ }
2610
+ .caps-permission-grid-mark {
2611
+ width: 1.25rem;
2612
+ height: 1.25rem;
2613
+ }
2614
+ .caps-permission-grid-state {
2615
+ font-size: 0.625rem;
2616
+ letter-spacing: 0.02em;
2617
+ }
2618
+ .caps-permission-grid-scope {
2619
+ font-size: 0.6875rem;
2620
+ }
2621
+ }
2417
2622
  .caps-alert {
2418
2623
  display: flex;
2419
2624
  align-items: flex-start;
@@ -3107,7 +3312,7 @@
3107
3312
  }
3108
3313
  .result-state {
3109
3314
  display: grid;
3110
- gap: var(--spacing-md);
3315
+ gap: var(--spacing-sm);
3111
3316
  justify-items: start;
3112
3317
  padding: var(--spacing-xl);
3113
3318
  border: var(--border) solid var(--color-base-300);
@@ -3125,9 +3330,106 @@
3125
3330
  background: var(--color-base-200);
3126
3331
  color: var(--color-base-content);
3127
3332
  }
3128
- .result-state h2 {
3333
+ .result-state > * {
3334
+ margin: 0;
3335
+ }
3336
+ .result-state :is(h2, h3, h4) {
3337
+ display: flex;
3338
+ align-items: center;
3339
+ gap: var(--spacing-sm);
3129
3340
  font-size: var(--text-xl);
3130
- font-weight: 700;
3341
+ font-weight: 600;
3342
+ }
3343
+ .result-state[data-tone="failed"] .result-state-visual {
3344
+ color: var(--color-error);
3345
+ }
3346
+ .result-state[data-tone="done"] .result-state-visual {
3347
+ color: var(--color-success);
3348
+ }
3349
+ .result-state[data-tone="failed"] {
3350
+ border-color: color-mix(
3351
+ in oklab,
3352
+ var(--color-error) 45%,
3353
+ var(--color-base-300)
3354
+ );
3355
+ }
3356
+ .result-state[data-tone="done"] {
3357
+ border-color: color-mix(
3358
+ in oklab,
3359
+ var(--color-success) 45%,
3360
+ var(--color-base-300)
3361
+ );
3362
+ }
3363
+ .result-state-visual {
3364
+ display: grid;
3365
+ place-items: center;
3366
+ max-width: 100%;
3367
+ color: var(--color-primary);
3368
+ }
3369
+ .result-state-steps {
3370
+ display: grid;
3371
+ gap: var(--spacing-xs);
3372
+ margin: 0;
3373
+ padding-inline-start: var(--spacing-lg);
3374
+ font-size: var(--text-sm);
3375
+ list-style: decimal;
3376
+ }
3377
+ .result-state-visual > svg {
3378
+ width: 3rem;
3379
+ height: 3rem;
3380
+ }
3381
+ .caps-loading-state[data-framed="false"] {
3382
+ min-height: 0;
3383
+ padding: 0;
3384
+ border: 0;
3385
+ border-radius: 0;
3386
+ background: transparent;
3387
+ }
3388
+ .caps-loading-state-copy {
3389
+ display: grid;
3390
+ flex: 0 1 auto;
3391
+ min-width: 0;
3392
+ gap: var(--spacing-2xs);
3393
+ }
3394
+ /* One fixed slot per size, so copy aligns down a column of states. */
3395
+ .caps-loading-state > .caps-loader {
3396
+ width: 4rem;
3397
+ }
3398
+ .caps-loading-state[data-size="sm"] > .caps-loader {
3399
+ width: 2rem;
3400
+ }
3401
+ .caps-loading-state[data-size="lg"] > .caps-loader {
3402
+ width: 7rem;
3403
+ }
3404
+ /* With an App icon the state stacks: icon, then loader, then copy. */
3405
+ .caps-loading-state[data-icon] {
3406
+ flex-direction: column;
3407
+ justify-content: center;
3408
+ gap: var(--spacing-sm);
3409
+ text-align: center;
3410
+ }
3411
+ .caps-loading-state[data-icon] > .caps-loader {
3412
+ width: auto;
3413
+ }
3414
+ .caps-loading-state-icon {
3415
+ display: grid;
3416
+ place-items: center;
3417
+ width: 3rem;
3418
+ height: 3rem;
3419
+ }
3420
+ .caps-loading-state-icon > svg {
3421
+ width: 100%;
3422
+ height: 100%;
3423
+ }
3424
+ .caps-loading-state-retry {
3425
+ flex: none;
3426
+ }
3427
+ .caps-loading-state-detail {
3428
+ color: var(--stipe-fg-muted);
3429
+ font-size: var(--text-sm);
3430
+ }
3431
+ .caps-loading-state[data-size="lg"] {
3432
+ min-height: 6rem;
3131
3433
  }
3132
3434
  .result-state-actions {
3133
3435
  display: flex;
@@ -3738,7 +4040,7 @@
3738
4040
  }
3739
4041
  .caps-pricing-card-banded .caps-pricing-card-description {
3740
4042
  padding-bottom: var(--spacing-md);
3741
- border-bottom: var(--border) solid var(--stipe-hairline);
4043
+ border-bottom: var(--border) solid var(--stipe-hairline-quiet);
3742
4044
  color: var(--color-base-content);
3743
4045
  font-size: var(--text-base);
3744
4046
  }
@@ -4035,7 +4337,7 @@
4035
4337
  border-top: calc(var(--border) * 2) solid var(--color-base-content);
4036
4338
  }
4037
4339
  .caps-spec-faq-item {
4038
- border-bottom: var(--border) solid var(--stipe-hairline);
4340
+ border-bottom: var(--border) solid var(--stipe-hairline-quiet);
4039
4341
  }
4040
4342
  .caps-spec-faq-question {
4041
4343
  display: grid;
@@ -5687,6 +5989,33 @@
5687
5989
  opacity: 1;
5688
5990
  }
5689
5991
 
5992
+ /* Pending is not disabled: a busy button keeps its full face, shows its
5993
+ loader and only refuses clicks. */
5994
+ .caps-button[aria-busy="true"]:is(:disabled, [aria-disabled="true"]) {
5995
+ cursor: progress;
5996
+ }
5997
+ /* Three orbiting beads at one text height: dots that read as motion. */
5998
+ .caps-button > .caps-loader {
5999
+ width: 1.25rem;
6000
+ height: 1.25rem;
6001
+ margin-inline-end: calc(var(--spacing-xs) * -0.5);
6002
+ }
6003
+ .caps-button-filled[aria-busy="true"]:is(:disabled, [aria-disabled="true"]) {
6004
+ opacity: 1;
6005
+ background-color: var(--btn-bg);
6006
+ color: var(--btn-fg);
6007
+ border-color: var(--caps-button-filled-edge);
6008
+ box-shadow: var(--caps-button-filled-drop);
6009
+ }
6010
+ .caps-button.btn-outline[aria-busy="true"]:is(
6011
+ :disabled,
6012
+ [aria-disabled="true"]
6013
+ ) {
6014
+ background-color: var(--caps-key-face);
6015
+ color: var(--caps-button-outline-ink, var(--color-base-content));
6016
+ outline: none;
6017
+ }
6018
+
5690
6019
  /* Finishes are inherited values; roles and native states stay on the button. */
5691
6020
  .caps-button-filled,
5692
6021
  .caps-button.btn-outline {
@@ -7828,7 +8157,7 @@
7828
8157
  .empty-state-bubble .empty-state-title {
7829
8158
  margin: 0;
7830
8159
  font-size: var(--text-lg);
7831
- font-weight: 800;
8160
+ font-weight: 600;
7832
8161
  line-height: 1.25;
7833
8162
  text-wrap: balance;
7834
8163
  }
@@ -7851,11 +8180,40 @@
7851
8180
  .empty-state-panel .empty-state-actions {
7852
8181
  justify-content: center;
7853
8182
  }
8183
+ .empty-state-panel > .empty-state-visual {
8184
+ min-height: 0;
8185
+ margin-block-end: 0;
8186
+ }
8187
+ .empty-state-suggestions .caps-button {
8188
+ min-height: 2rem;
8189
+ height: 2rem;
8190
+ font-size: var(--text-xs);
8191
+ }
8192
+ /* A chip that cannot be chosen is muted and flat: no plate, no rim. */
8193
+ .empty-state-suggestions
8194
+ .caps-button:is(:disabled, [aria-disabled="true"]):not([aria-busy="true"]) {
8195
+ opacity: 0.5;
8196
+ outline: none;
8197
+ box-shadow: none;
8198
+ }
8199
+ .empty-state-primary {
8200
+ display: grid;
8201
+ justify-items: start;
8202
+ gap: var(--spacing-2xs);
8203
+ margin-block-start: var(--spacing-sm);
8204
+ }
8205
+ .empty-state-panel .empty-state-primary {
8206
+ justify-items: center;
8207
+ }
8208
+ .empty-state-reason {
8209
+ color: var(--stipe-fg-muted);
8210
+ font-size: var(--text-sm);
8211
+ }
7854
8212
  .empty-state-suggestions {
7855
8213
  display: flex;
7856
8214
  flex-wrap: wrap;
7857
- gap: var(--spacing-xs);
7858
- margin: var(--spacing-xs) 0 0;
8215
+ gap: var(--spacing-sm);
8216
+ margin: var(--spacing-sm) 0 0;
7859
8217
  padding: 0;
7860
8218
  list-style: none;
7861
8219
  }
@@ -8083,7 +8441,7 @@
8083
8441
  margin: 0;
8084
8442
  color: var(--color-base-content);
8085
8443
  font-size: var(--text-sm);
8086
- font-weight: 700;
8444
+ font-weight: 600;
8087
8445
  }
8088
8446
  .empty-state-hint p {
8089
8447
  max-width: 30rem;
@@ -8109,7 +8467,7 @@
8109
8467
  margin: 0;
8110
8468
  color: var(--color-base-content);
8111
8469
  font-size: var(--text-sm);
8112
- font-weight: 700;
8470
+ font-weight: 600;
8113
8471
  line-height: 1.5;
8114
8472
  }
8115
8473
  .empty-state-quiet > p {
@@ -8839,6 +9197,21 @@
8839
9197
  min-width: var(--caps-keycap-label-min-width, auto);
8840
9198
  line-height: var(--caps-keycap-label-line-height, inherit);
8841
9199
  }
9200
+ /* An inline shortcut caption: reads as text, never as another button. */
9201
+ .caps-keycap[data-size="hint"] {
9202
+ display: inline-block;
9203
+ min-width: 0;
9204
+ min-height: 0;
9205
+ margin-inline: var(--spacing-2xs);
9206
+ padding: 0 var(--spacing-2xs);
9207
+ border-radius: var(--radius-selector);
9208
+ border-color: var(--stipe-hairline-quiet);
9209
+ background: transparent;
9210
+ box-shadow: none;
9211
+ color: color-mix(in oklab, var(--color-base-content) 65%, transparent);
9212
+ font-size: var(--text-xs);
9213
+ line-height: 1.25;
9214
+ }
8842
9215
  .caps-keycap-button .caps-keycap {
8843
9216
  flex: var(--caps-keycap-shortcut-flex, 0 1 auto);
8844
9217
  min-width: var(