@cplieger/web-terminal-ui 3.0.4 → 3.1.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.
package/css/03-v3.css DELETED
@@ -1,705 +0,0 @@
1
- /* ===== v3 kernel + feature styles =====
2
- The v3 kernel builds named layout regions (wt-region-*) as siblings of the
3
- terminal surface (.term, styled in 02-app.css), and features mount chrome into
4
- region slots. The regions are transparent groupings (display: contents) so
5
- each feature's element floats over the fixed-inset terminal exactly as the
6
- pre-v3 chrome did; the terminal-core, key-toolbar (.key-toolbar/.kb-*), and
7
- cursor/color styles in 02-app.css are reused unchanged.
8
-
9
- Note: this is the pragmatic first-cut v3 stylesheet. The design's section 22.8
10
- per-feature CSS split (core.css + mobile-toolbar.css/context-menu.css/tabs.css/
11
- activity.css/animations.css + a css-manifest.mjs assembler) is a tracked
12
- follow-up; the classes below are the seams that split will carve along. */
13
-
14
- /* Regions + slots are transparent: they group a feature's DOM without imposing
15
- layout, so a feature element inside them positions itself (fixed) over the
16
- terminal, and an absent feature contributes nothing. */
17
- .wt-region,
18
- .wt-slot {
19
- display: contents;
20
- }
21
-
22
- /* ===== Shared button primitive (44px touch target) ===== */
23
- .wt-btn {
24
- display: inline-flex;
25
- align-items: center;
26
- justify-content: center;
27
- min-width: var(--touch-target);
28
- min-height: var(--touch-target);
29
- background: transparent;
30
- color: var(--text);
31
- border: none;
32
- border-radius: var(--radius-inner);
33
- font: inherit;
34
- cursor: pointer;
35
- touch-action: manipulation;
36
- user-select: none;
37
- }
38
-
39
- .wt-btn:active {
40
- background: var(--text-active);
41
- }
42
-
43
- .wt-btn svg {
44
- width: var(--icon);
45
- height: var(--icon);
46
- stroke: currentcolor;
47
- fill: none;
48
- stroke-width: 2;
49
- stroke-linecap: round;
50
- stroke-linejoin: round;
51
- }
52
-
53
- /* ===== Toast (kernel shared primitive) ===== */
54
- .wt-toast {
55
- position: fixed;
56
- bottom: calc(var(--sp-3) + var(--kb-inset, 0px));
57
- left: 50%;
58
- transform: translateX(-50%);
59
- max-width: calc(100% - 2 * var(--sp-3));
60
- padding: var(--sp-1) var(--sp-3);
61
- background: var(--surface);
62
- backdrop-filter: var(--blur);
63
- border: 1px solid oklch(70% 0.1 160deg / 30%);
64
- border-radius: var(--radius);
65
- color: var(--text);
66
- font-family: var(--font-ui);
67
- font-size: 0.8125rem;
68
- font-weight: 500;
69
- text-align: center;
70
- z-index: 40;
71
- display: none;
72
- opacity: 0;
73
- }
74
-
75
- .wt-toast.visible {
76
- display: block;
77
- opacity: 1;
78
- }
79
-
80
- /* ===== Connection banner (connectionBanner feature) ===== */
81
- .wt-conn-banner {
82
- position: fixed;
83
- bottom: calc(var(--sp-3) + var(--kb-inset, 0px));
84
- left: 50%;
85
- transform: translateX(-50%);
86
- max-width: calc(100% - 2 * var(--sp-3));
87
- padding: var(--sp-1) var(--sp-3);
88
- background: var(--surface);
89
- backdrop-filter: var(--blur);
90
- border: 1px solid var(--border);
91
- border-radius: var(--radius);
92
- color: var(--text);
93
- font-family: var(--font-ui);
94
- font-size: 0.8125rem;
95
- font-weight: 500;
96
- text-align: center;
97
- z-index: 20;
98
- display: none;
99
- }
100
-
101
- .wt-conn-banner.visible {
102
- display: block;
103
- }
104
-
105
- .wt-conn-banner[data-state="reconnecting"] {
106
- border-color: oklch(70% 0.15 60deg / 40%);
107
- }
108
-
109
- .wt-conn-banner[data-state="offline"] {
110
- color: #f55;
111
- border-color: oklch(60% 0.2 25deg / 50%);
112
- }
113
-
114
- .wt-conn-banner[data-state="restarted"] {
115
- color: #fa5;
116
- border-color: oklch(70% 0.15 60deg / 40%);
117
- }
118
-
119
- /* Desktop: move both the banner and toast to top-center so they don't collide
120
- with the bottom-anchored scroll-to-bottom control. */
121
- @media (pointer: fine) {
122
- .wt-conn-banner,
123
- .wt-toast {
124
- top: var(--sp-3);
125
- bottom: auto;
126
- }
127
- }
128
-
129
- /* ===== Scroll-to-bottom (scrollToBottom feature) ===== */
130
- .wt-scroll-bottom {
131
- position: fixed;
132
- left: 50%;
133
- bottom: calc(var(--safe-bottom, 0px) + var(--sp-3) + var(--kb-inset, 0px));
134
- transform: translateX(-50%);
135
- gap: var(--sp-1);
136
- padding: var(--sp-2) var(--sp-3);
137
- background: var(--surface);
138
- backdrop-filter: var(--blur);
139
- border: 1px solid var(--border);
140
- border-radius: var(--radius);
141
- font-size: 0.875rem;
142
- font-weight: 500;
143
- z-index: 10;
144
- display: none;
145
- }
146
-
147
- /* The scroll slot gets .scrolled-up toggled by the feature; show the button. */
148
- .wt-slot-scroll.scrolled-up .wt-scroll-bottom {
149
- display: inline-flex;
150
- }
151
-
152
- /* ===== Context menu (contextMenu feature) ===== */
153
- .wt-ctx-menu {
154
- position: fixed;
155
- display: none;
156
- flex-direction: column;
157
- background: var(--surface);
158
- backdrop-filter: var(--blur);
159
- border: 1px solid var(--border);
160
- border-radius: var(--radius);
161
- padding: var(--sp-1);
162
- z-index: 30;
163
- }
164
-
165
- .wt-ctx-menu.visible {
166
- display: flex;
167
- }
168
-
169
- .wt-ctx-menu button {
170
- background: transparent;
171
- color: var(--text);
172
- border: none;
173
- border-radius: var(--radius-inner);
174
- font-family: var(--font-ui);
175
- font-size: 0.8125rem;
176
- font-weight: 500;
177
- padding: var(--sp-1) var(--sp-3);
178
- cursor: pointer;
179
- text-align: left;
180
- }
181
-
182
- .wt-ctx-menu button:active {
183
- background: var(--text-active);
184
- }
185
-
186
- @media (pointer: coarse) {
187
- .wt-ctx-menu button {
188
- min-height: var(--touch-target);
189
- padding-block: var(--sp-2);
190
- touch-action: manipulation;
191
- }
192
- }
193
-
194
- /* ===== Tab bar (tabs feature) ===== */
195
- .wt-region-top-bar {
196
- /* On desktop the tab strip docks to the top; the region is transparent, so
197
- the bar element below owns its own fixed placement. */
198
- display: contents;
199
- }
200
-
201
- .wt-tab-bar {
202
- position: fixed;
203
- top: calc(var(--safe-top, 0px) + var(--vv-top, 0px));
204
- left: 0;
205
- right: 0;
206
- display: flex;
207
- align-items: center;
208
- gap: 2px;
209
- padding: var(--sp-1);
210
- background: var(--surface);
211
- backdrop-filter: var(--blur);
212
- border-bottom: 1px solid var(--border);
213
- overflow-x: auto;
214
- z-index: 15;
215
- }
216
-
217
- .wt-tab {
218
- display: inline-flex;
219
- align-items: center;
220
- gap: var(--sp-1);
221
- padding: var(--sp-1) var(--sp-2);
222
- /* A transparent border is reserved on every tab so toggling the inactive
223
- outline (below) never shifts the strip's layout. */
224
- border: 1px solid transparent;
225
- border-radius: var(--radius-inner);
226
- color: color-mix(in oklch, var(--text) 70%, transparent);
227
- font-family: var(--font-ui);
228
- font-size: 0.8125rem;
229
- cursor: pointer;
230
- white-space: nowrap;
231
- user-select: none;
232
- }
233
-
234
- /* Inactive tabs read as outlined chips (so adjacent tabs stay visually
235
- separated) and take a subtle fill on hover. */
236
- .wt-tab:not(.wt-tab-active) {
237
- border-color: var(--border);
238
- }
239
-
240
- .wt-tab:not(.wt-tab-active):hover {
241
- background: var(--text-active);
242
- color: var(--text);
243
- }
244
-
245
- .wt-tab-active {
246
- background: color-mix(in oklch, var(--text) 10%, var(--surface));
247
- color: var(--text);
248
- }
249
-
250
- .wt-tab-label {
251
- max-width: 20ch;
252
- overflow: hidden;
253
- text-overflow: ellipsis;
254
- }
255
-
256
- /* A little breathing room after the activity dot, before the label. */
257
- .wt-tab-dot {
258
- margin-right: 2px;
259
- }
260
-
261
- /* The tab close (×): a centered, muted square glyph button with a box on hover.
262
- font: inherit so the glyph uses the UI font and centers cleanly in its box. */
263
- .wt-tab-close {
264
- display: inline-flex;
265
- align-items: center;
266
- justify-content: center;
267
- width: 1.375rem;
268
- height: 1.375rem;
269
- padding: 0;
270
- background: transparent;
271
- border: none;
272
- border-radius: var(--radius-inner);
273
- color: color-mix(in oklch, var(--text) 60%, transparent);
274
- font: inherit;
275
- font-size: 1rem;
276
- line-height: 1;
277
- cursor: pointer;
278
- }
279
-
280
- .wt-tab-close:hover {
281
- background: var(--text-active);
282
- color: var(--text);
283
- }
284
-
285
- /* On an inactive tab the close appears only on hover, kept in the layout via
286
- visibility so the tab width never jumps; on the active tab it is always shown. */
287
- .wt-tab:not(.wt-tab-active) .wt-tab-close {
288
- visibility: hidden;
289
- }
290
-
291
- .wt-tab:not(.wt-tab-active):hover .wt-tab-close {
292
- visibility: visible;
293
- }
294
-
295
- /* The add-tab (+) button: its hover box matches an active tab's box (it
296
- stretches to the strip height and uses the same active-tab fill), it centers
297
- its glyph, and a left margin keeps its hover box clear of the last tab's. */
298
- .wt-tab-new {
299
- display: inline-flex;
300
- align-items: center;
301
- justify-content: center;
302
- align-self: stretch;
303
- min-width: 1.875rem;
304
- margin-left: var(--sp-2);
305
- padding: 0 var(--sp-1);
306
- background: transparent;
307
- border: none;
308
- border-radius: var(--radius-inner);
309
- color: color-mix(in oklch, var(--text) 60%, transparent);
310
- font: inherit;
311
- font-size: 1.1rem;
312
- line-height: 1;
313
- cursor: pointer;
314
- }
315
-
316
- .wt-tab-new:hover {
317
- background: color-mix(in oklch, var(--text) 10%, var(--surface));
318
- color: var(--text);
319
- }
320
-
321
- /* Close-all: a right-anchored text button (pushed to the far end of the strip). */
322
- .wt-tab-closeall {
323
- display: inline-flex;
324
- align-items: center;
325
- justify-content: center;
326
- align-self: stretch;
327
- margin-left: auto;
328
- padding: 0 var(--sp-2);
329
- background: transparent;
330
- border: none;
331
- border-radius: var(--radius-inner);
332
- color: color-mix(in oklch, var(--text) 60%, transparent);
333
- font-family: var(--font-ui);
334
- font-size: 0.75rem;
335
- white-space: nowrap;
336
- cursor: pointer;
337
- }
338
-
339
- .wt-tab-closeall:hover {
340
- background: var(--text-active);
341
- color: var(--text);
342
- }
343
-
344
- /* Push the terminal surface below the fixed tab strip so it does not overlap
345
- the first rows. The tabs feature marks the surface (.wt-with-topbar) and keeps
346
- the measured strip height in --wt-tabbar-h. The surface is position:fixed
347
- inset:0, so a top offset is what clears it. Desktop only: the strip is hidden
348
- on a coarse pointer, where the switcher docks to the bottom instead, so the
349
- surface stays full-height there. (The prior `.wt-tab-bar ~ .term` /
350
- `:has(> .wt-tab-bar) .term` rule never matched: the bar lives inside a
351
- display:contents region, so it is neither a DOM sibling nor an ancestor of
352
- .term.) */
353
- @media (pointer: fine) {
354
- .term.wt-with-topbar {
355
- top: var(--wt-tabbar-h, 40px);
356
- }
357
- }
358
-
359
- /* ===== Activity dots (activityMonitor via tabs) =====
360
- Four-state, distinguishable without color (shape + motion, not hue alone),
361
- per section 12 / WCAG 1.4.1. The one .wt-status-dot vocabulary is shared by
362
- the desktop strip, the mobile switcher, and the overview sheet rows. */
363
- .wt-status-dot {
364
- width: 9px;
365
- height: 9px;
366
- border-radius: 50%;
367
- flex: none;
368
- /* Default / idle (a new session with no turn yet): a hollow grey dot, so
369
- "nothing has happened" reads as an outline rather than a filled state.
370
- The fill (solid vs hollow) is the non-hue cue that separates the idle state
371
- from the filled done/working/input states (WCAG 1.4.1). */
372
- background: transparent;
373
- border: 1.5px solid color-mix(in oklch, var(--text) 45%, transparent);
374
- }
375
-
376
- .wt-status-dot[data-status="idle"] {
377
- background: transparent;
378
- border: 1.5px solid color-mix(in oklch, var(--text) 45%, transparent);
379
- }
380
-
381
- /* Agent working: solid pulsing purple, matching Kiro IDE's "thinking" color
382
- (#a78bfa). Motion is the primary non-hue cue. Server-side this is driven by
383
- the OSC 9;4 progress signal, so it tracks agent activity, not the user typing
384
- at the prompt. */
385
- .wt-status-dot[data-status="working"] {
386
- background: #a78bfa;
387
- border-color: #a78bfa;
388
- animation: wt-pulse 1.2s ease-in-out infinite;
389
- }
390
-
391
- /* Agent done / ready: solid green, matching Kiro IDE's "Ready" (#22c55e), no
392
- motion. The filled dot distinguishes it from the hollow idle without hue. */
393
- .wt-status-dot[data-status="done"] {
394
- background: #22c55e;
395
- border-color: #22c55e;
396
- }
397
-
398
- /* User action required (permission / approval): solid amber matching Kiro IDE's
399
- "waiting-approval" (#fbbf24), plus a ring so it reads as "needs you" via shape
400
- as well as hue. It persists until you act on or switch into the tab. */
401
- .wt-status-dot[data-status="input"] {
402
- background: #fbbf24;
403
- border-color: #fbbf24;
404
- box-shadow: 0 0 0 2px oklch(85% 0.16 85deg / 40%);
405
- }
406
-
407
- /* Exited: a dim hollow dot, static; distinct from idle by its lower opacity. */
408
- .wt-status-dot[data-status="exited"] {
409
- background: transparent;
410
- border: 1.5px solid color-mix(in oklch, var(--text) 30%, transparent);
411
- opacity: 0.5;
412
- }
413
-
414
- @keyframes wt-pulse {
415
- 50% {
416
- opacity: 0.4;
417
- }
418
- }
419
-
420
- /* Reduced-motion (or the animations feature off): drop the pulse, keep color. */
421
- @media (prefers-reduced-motion: reduce) {
422
- .wt-status-dot[data-status="working"] {
423
- animation: none;
424
- }
425
- }
426
-
427
- /* ===== Animations feature =====
428
- Motion is off unless the animations feature marks the root .wt-animate (and
429
- the OS is not in reduced-motion). Transitions are declared here, gated on it. */
430
- .wt-animate .wt-toast,
431
- .wt-animate .wt-conn-banner,
432
- .wt-animate .wt-scroll-bottom,
433
- .wt-animate .wt-ctx-menu {
434
- transition:
435
- opacity var(--dur-standard) var(--ease-standard),
436
- display var(--dur-standard) allow-discrete;
437
- }
438
-
439
- .wt-animate .wt-tab,
440
- .wt-animate .wt-tab-close,
441
- .wt-animate .wt-tab-new,
442
- .wt-animate .wt-tab-closeall {
443
- transition:
444
- background-color var(--dur-micro) var(--ease-standard),
445
- color var(--dur-micro) var(--ease-standard);
446
- }
447
-
448
- /* ===== Mobile bottom-switcher (tabs feature, section 12) =====
449
- The switcher is the mobile tab surface: it shows the active tab and a
450
- position indicator as a tap/swipe target, plus a >=44px overview control that
451
- carries the aggregate needs-input badge. Hidden on a fine pointer, where the
452
- top strip is used instead; the top strip is correspondingly hidden on a
453
- coarse pointer so tabs live in the thumb zone. */
454
- .wt-switcher {
455
- display: none;
456
- }
457
-
458
- @media (pointer: coarse) {
459
- .wt-tab-bar,
460
- .wt-tab-new {
461
- display: none;
462
- }
463
-
464
- .wt-switcher {
465
- position: fixed;
466
- left: 0;
467
- right: 0;
468
- /* Lift above the soft keyboard rather than hiding, so the switch surface
469
- stays reachable in the terminal's primary working state (section 12). */
470
- bottom: calc(var(--safe-bottom, 0px) + var(--kb-inset, 0px));
471
- display: flex;
472
- align-items: stretch;
473
- gap: var(--sp-1);
474
- padding: var(--sp-1);
475
- background: var(--surface);
476
- backdrop-filter: var(--blur);
477
- border-top: 1px solid var(--border);
478
- z-index: 25;
479
- }
480
- }
481
-
482
- .wt-switcher-current {
483
- flex: 1 1 auto;
484
- display: flex;
485
- align-items: center;
486
- gap: var(--sp-2);
487
- min-height: var(--touch-target);
488
- padding: 0 var(--sp-2);
489
- background: transparent;
490
- color: var(--text);
491
- border: none;
492
- border-radius: var(--radius-inner);
493
- font-family: var(--font-ui);
494
- font-size: 0.875rem;
495
- cursor: pointer;
496
- overflow: hidden;
497
- /* Read horizontal swipe here; let vertical scrolling pass through. */
498
- touch-action: pan-y;
499
- }
500
-
501
- .wt-switcher-current:active {
502
- background: var(--text-active);
503
- }
504
-
505
- .wt-switcher-label {
506
- flex: 1 1 auto;
507
- overflow: hidden;
508
- text-overflow: ellipsis;
509
- white-space: nowrap;
510
- text-align: left;
511
- }
512
-
513
- .wt-switcher-pos {
514
- flex: none;
515
- color: color-mix(in oklch, var(--text) 60%, transparent);
516
- font-variant-numeric: tabular-nums;
517
- font-size: 0.8125rem;
518
- }
519
-
520
- .wt-switcher-overview {
521
- position: relative;
522
- flex: none;
523
- padding: 0 var(--sp-3);
524
- font-family: var(--font-ui);
525
- font-size: 0.8125rem;
526
- font-weight: 600;
527
- border: 1px solid var(--border);
528
- }
529
-
530
- .wt-switcher-count {
531
- font-variant-numeric: tabular-nums;
532
- }
533
-
534
- /* Aggregate needs-input attention: a background tab is blocked on you. Shape +
535
- color (a ring plus a corner glyph), never hue alone (WCAG 1.4.1). */
536
- .wt-switcher-overview[data-attention="input"] {
537
- border-color: oklch(70% 0.18 25deg);
538
- box-shadow: 0 0 0 2px oklch(70% 0.18 25deg / 35%);
539
- }
540
-
541
- .wt-switcher-overview[data-attention="input"]::after {
542
- content: "";
543
- position: absolute;
544
- top: 3px;
545
- right: 3px;
546
- width: 8px;
547
- height: 8px;
548
- border-radius: 50%;
549
- background: oklch(70% 0.18 25deg);
550
- }
551
-
552
- /* ===== Overview sheet (tabs feature, section 12) =====
553
- A modal, focus-trapped bottom sheet listing every tab; distinct from the
554
- non-modal overlay (context menu). Opened from the switcher; mobile-only in
555
- practice (the switcher that opens it is hidden on a fine pointer). */
556
- .wt-sheet-scrim {
557
- position: fixed;
558
- inset: 0;
559
- background: oklch(0% 0 0deg / 50%);
560
- z-index: 45;
561
- display: none;
562
- }
563
-
564
- .wt-sheet-scrim.visible {
565
- display: block;
566
- }
567
-
568
- .wt-sheet {
569
- position: fixed;
570
- left: 0;
571
- right: 0;
572
- bottom: 0;
573
- max-height: 70vh;
574
- display: flex;
575
- flex-direction: column;
576
- gap: var(--sp-2);
577
- padding: var(--sp-3);
578
- padding-bottom: calc(var(--sp-3) + var(--safe-bottom, 0px));
579
- background: var(--surface);
580
- backdrop-filter: var(--blur);
581
- border-top: 1px solid var(--border);
582
- border-radius: var(--radius) var(--radius) 0 0;
583
- z-index: 46;
584
- overflow-y: auto;
585
- }
586
-
587
- .wt-sheet[hidden] {
588
- display: none;
589
- }
590
-
591
- .wt-sheet-header {
592
- display: flex;
593
- align-items: center;
594
- justify-content: space-between;
595
- gap: var(--sp-2);
596
- }
597
-
598
- .wt-sheet-title {
599
- font-family: var(--font-ui);
600
- font-size: 0.9375rem;
601
- font-weight: 600;
602
- color: var(--text);
603
- }
604
-
605
- .wt-sheet-new {
606
- flex: none;
607
- padding: 0 var(--sp-3);
608
- font-family: var(--font-ui);
609
- font-size: 0.8125rem;
610
- font-weight: 500;
611
- border: 1px solid var(--border);
612
- }
613
-
614
- .wt-sheet-list {
615
- list-style: none;
616
- margin: 0;
617
- padding: 0;
618
- display: flex;
619
- flex-direction: column;
620
- gap: 2px;
621
- }
622
-
623
- .wt-sheet-row {
624
- display: flex;
625
- align-items: stretch;
626
- gap: var(--sp-1);
627
- }
628
-
629
- .wt-sheet-select {
630
- flex: 1 1 auto;
631
- display: flex;
632
- align-items: center;
633
- gap: var(--sp-2);
634
- min-height: var(--touch-target);
635
- padding: 0 var(--sp-2);
636
- background: transparent;
637
- color: var(--text);
638
- border: none;
639
- border-radius: var(--radius-inner);
640
- font-family: var(--font-ui);
641
- font-size: 0.875rem;
642
- text-align: left;
643
- cursor: pointer;
644
- overflow: hidden;
645
- }
646
-
647
- .wt-sheet-row-active .wt-sheet-select {
648
- background: color-mix(in oklch, var(--text) 10%, var(--surface));
649
- }
650
-
651
- .wt-sheet-select:active {
652
- background: var(--text-active);
653
- }
654
-
655
- .wt-sheet-row-label {
656
- flex: 1 1 auto;
657
- overflow: hidden;
658
- text-overflow: ellipsis;
659
- white-space: nowrap;
660
- }
661
-
662
- .wt-sheet-close {
663
- flex: none;
664
- border: 1px solid var(--border);
665
- font-size: 1rem;
666
- }
667
-
668
- /* ===== Catching-up cue (tabs feature, sections 12/13) =====
669
- A switched-into tab's cached screen is stale until its resume delta lands, so
670
- it must not read as live. This unobtrusive cue shows only if the delta has not
671
- arrived shortly after the switch, and clears on the first screen frame. */
672
- .wt-catchup {
673
- position: fixed;
674
- top: calc(var(--safe-top, 0px) + var(--vv-top, 0px) + 44px);
675
- left: 50%;
676
- transform: translateX(-50%);
677
- padding: 2px var(--sp-2);
678
- background: var(--surface);
679
- backdrop-filter: var(--blur);
680
- border: 1px solid var(--border);
681
- border-radius: var(--radius);
682
- color: color-mix(in oklch, var(--text) 75%, transparent);
683
- font-family: var(--font-ui);
684
- font-size: 0.75rem;
685
- z-index: 24;
686
- display: none;
687
- }
688
-
689
- .wt-catchup.visible {
690
- display: block;
691
- }
692
-
693
- /* ===== Switch motion (animations feature) =====
694
- A subtle content fade on switch, so the cache-first repaint reads as a change
695
- rather than a flicker. Gated on .wt-animate (and prefers-reduced-motion is
696
- respected because the animations feature does not set .wt-animate then). */
697
- .wt-animate .term.wt-switching .term-output {
698
- animation: wt-switch-in var(--dur-standard) var(--ease-standard);
699
- }
700
-
701
- @keyframes wt-switch-in {
702
- from {
703
- opacity: 0.55;
704
- }
705
- }