@cplieger/web-terminal-ui 8.1.1 → 8.1.2
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/README.md +1 -1
- package/css/00-tokens.css +1 -1
- package/css/30-tabs.css +66 -80
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -164,7 +164,7 @@ are importable from `…/features/<name>` (`clipboard`, `context-menu`,
|
|
|
164
164
|
background activity that outlives a turn (a workflow run, in the
|
|
165
165
|
`web-terminal-kiro` case). It is a rounded-square ring rather than a disc, so
|
|
166
166
|
it does not read as another status dot, and band width carries its three
|
|
167
|
-
states: a 2px band
|
|
167
|
+
states: a 2px band whose centre closes and reopens while a background task is running, a
|
|
168
168
|
1px band with a halo while one is paused and resumable, and a 2px band with
|
|
169
169
|
that same halo while one is blocked on the user. The state and the count are
|
|
170
170
|
announced in the tab's accessible name and repeated as the mark's hover
|
package/css/00-tokens.css
CHANGED
|
@@ -178,7 +178,7 @@
|
|
|
178
178
|
with nothing enforcing it.
|
|
179
179
|
Shared with marotte's `--dot-beat-dur` (01-tokens.css) for the reason the
|
|
180
180
|
--status-* inks are: one signal across the two apps, beat included. */
|
|
181
|
-
--dot-beat-dur: 1.
|
|
181
|
+
--dot-beat-dur: 1.6s;
|
|
182
182
|
--dur-standard: 0.2s;
|
|
183
183
|
--dur-enter: 0.25s;
|
|
184
184
|
--dur-exit: 0.15s;
|
package/css/30-tabs.css
CHANGED
|
@@ -993,7 +993,8 @@
|
|
|
993
993
|
three states the channel is BAND WIDTH, in a deliberate 2:1 ratio, because
|
|
994
994
|
waiting and input share one ink.
|
|
995
995
|
|
|
996
|
-
A
|
|
996
|
+
A 3px radius of its own (--wt-mark-radius, which the working state's clip reads
|
|
997
|
+
too), not --radius-sm: the smallest token rung is 4px, which on
|
|
997
998
|
a 9px box reads as a circle and defeats the silhouette.
|
|
998
999
|
|
|
999
1000
|
It costs ZERO layout while no state is set. The footprint cancel is a negative
|
|
@@ -1010,12 +1011,13 @@
|
|
|
1010
1011
|
/* waiting and input both speak through this ink and separate by band alone;
|
|
1011
1012
|
working overrides it. */
|
|
1012
1013
|
--wt-mark-ink: var(--status-input);
|
|
1014
|
+
--wt-mark-radius: 3px;
|
|
1013
1015
|
|
|
1014
1016
|
width: var(--wt-mark-size);
|
|
1015
1017
|
height: var(--wt-mark-size);
|
|
1016
1018
|
flex: none;
|
|
1017
1019
|
position: relative;
|
|
1018
|
-
border-radius:
|
|
1020
|
+
border-radius: var(--wt-mark-radius);
|
|
1019
1021
|
/* Zero-width at rest, so the ring is drawn entirely by a state's band. The
|
|
1020
1022
|
colour rides --wt-mark-ink here rather than in each state, so a state sets
|
|
1021
1023
|
one variable and one width. */
|
|
@@ -1051,86 +1053,64 @@
|
|
|
1051
1053
|
opacity var(--dur-enter) var(--ease-enter) var(--dur-standard);
|
|
1052
1054
|
}
|
|
1053
1055
|
|
|
1054
|
-
/* Working: the heavier bare band, plus a
|
|
1055
|
-
layer
|
|
1056
|
-
|
|
1057
|
-
|
|
1056
|
+
/* Working: the heavier bare band, plus a hole that closes on the beat. Its own
|
|
1057
|
+
compositing layer so the overlay layers snap against the ring rather than the
|
|
1058
|
+
page: their offset from it is whole pixels (the rounded inset below), so the
|
|
1059
|
+
closing circle stays centred however the chip centres a 9px mark (17.5px down). */
|
|
1058
1060
|
:where(.wt-root) .wt-activity-mark[data-activity="working"] {
|
|
1059
1061
|
--wt-mark-ink: var(--status-working);
|
|
1060
|
-
/* The band, named because the
|
|
1061
|
-
the mark's inradius less this. Paired with the declaration it describes so the
|
|
1062
|
-
two cannot drift apart on width. */
|
|
1062
|
+
/* The band, named because the closing overlay below derives the hole from it. */
|
|
1063
1063
|
--wt-mark-band: 2px;
|
|
1064
1064
|
|
|
1065
1065
|
border-width: var(--wt-mark-band);
|
|
1066
1066
|
transform: translateZ(0);
|
|
1067
|
+
/* The overlays' clip. `overflow` clips at the padding box, which under border-box
|
|
1068
|
+
sizing IS the hole; where supported the clip is the mark's own outline instead,
|
|
1069
|
+
because the hole's rounded inner corners as a clip edge leave an anti-aliased
|
|
1070
|
+
seam against the band's own (measured at dpr 2: four pixels 15% dark at the
|
|
1071
|
+
peak). Over the band the ink paints the band's own colour. */
|
|
1072
|
+
overflow: hidden;
|
|
1067
1073
|
}
|
|
1068
1074
|
|
|
1069
|
-
|
|
1070
|
-
|
|
1071
|
-
|
|
1072
|
-
|
|
1073
|
-
|
|
1074
|
-
|
|
1075
|
-
|
|
1076
|
-
|
|
1077
|
-
|
|
1078
|
-
|
|
1079
|
-
|
|
1080
|
-
|
|
1081
|
-
|
|
1082
|
-
|
|
1083
|
-
|
|
1084
|
-
|
|
1085
|
-
EVERY NUMBER HERE IS A RELATION, and the port that copied marotte's LITERALS is
|
|
1086
|
-
what left this rule running with nothing visible to show. Two of them were
|
|
1087
|
-
arithmetic for an 8px mark with a 2px band: `inset: -1px` put the overlay on that
|
|
1088
|
-
mark's own border box, and the core stop `70%` is where the core reaches the
|
|
1089
|
-
hole's CORNER there — sqrt(2) * (size / 2 - band) / (size / 2) = 70.71%. At 9px
|
|
1090
|
-
and 2px the same relation is 78.57%, so the copied 70% ended the solid core at
|
|
1091
|
-
2.45px while the mask opens only at 2.5px: core and visible mask did not
|
|
1092
|
-
intersect at all, the beat lit nothing the mask kept, and 4 pixels of a 9x9 mark
|
|
1093
|
-
moved between trough and peak against marotte's 20 (measured at dpr 1, both
|
|
1094
|
-
marks, sRGB). Written as relations they survive any size: the inset IS the band,
|
|
1095
|
-
the core stop IS the hole's corner radius, the mask's hole IS its inradius. So
|
|
1096
|
-
port marotte's `.tab-run-dot` (`12-tabs.css`, "THE GLOW BEAT") — the same mark
|
|
1097
|
-
solving the same problem, with the mask from the start — by its relations, never
|
|
1098
|
-
by its numbers. sqrt(2) is spelled to four decimals because the synced stylelint
|
|
1099
|
-
sets `number-max-precision: 4` outside colour functions.
|
|
1100
|
-
|
|
1101
|
-
NOTHING HERE EXTENDS PAST THE MARK. `box-sizing: border-box` (01-scope.css) puts
|
|
1102
|
-
the padding box — an absolutely positioned child's containing block — INSIDE the
|
|
1103
|
-
band, so `inset: calc(-1 * var(--wt-mark-band))` grows the overlay back out to
|
|
1104
|
-
exactly the mark's own border box and no further. Read it as "fill the mark", not
|
|
1105
|
-
as "overhang it": a larger inset would reach outside, where a feathered edge's
|
|
1106
|
-
visible radius moves with the beat and renders differently at every pixel
|
|
1107
|
-
density. `border-radius: 50%` is the same discipline on the last literal, and it
|
|
1108
|
-
is inert BY CONSTRUCTION rather than by measurement, which is why no assertion
|
|
1109
|
-
pins it: for side S and radius r the clip's 45° boundary is (S/2 - r) * sqrt(2) + r,
|
|
1110
|
-
monotonically decreasing in r, so the inscribed circle is the WORST case for
|
|
1111
|
-
reaching the hole's corners — and it still clears them for any band at or above
|
|
1112
|
-
S/2 * (1 - 1/sqrt(2)), 1.32px here against 2px. Do not assert it, and do not drop
|
|
1113
|
-
it either: it is what keeps a literal radius out of a rule whose whole defect was
|
|
1114
|
-
literals. */
|
|
1075
|
+
@supports (clip-path: inset(0 round 1px)) {
|
|
1076
|
+
:where(.wt-root) .wt-activity-mark[data-activity="working"] {
|
|
1077
|
+
overflow: visible;
|
|
1078
|
+
clip-path: inset(0 round var(--wt-mark-radius));
|
|
1079
|
+
}
|
|
1080
|
+
}
|
|
1081
|
+
|
|
1082
|
+
/* The close: the square hole fills from its corners, passes through its inscribed
|
|
1083
|
+
circle and shrinks to nothing, then reopens. Compositor-only: ::before is ink
|
|
1084
|
+
around a transparent circle of the hole's corner radius sqrt(2) * h, scaled down
|
|
1085
|
+
to --wt-mark-close and clipped by the parent; half-size (h + 1px) /
|
|
1086
|
+
--wt-mark-close keeps its edge under the band at the peak (a 71px layer, ~20 KB
|
|
1087
|
+
at dpr 1). Scaling leaves a 0.35px pinhole that reads as a dark pixel, so ::after
|
|
1088
|
+
fades a fill over the hole as the scale bottoms out. Every length is a relation to
|
|
1089
|
+
--wt-mark-size and --wt-mark-band (sqrt(2) to the stylelint's 4 decimals). */
|
|
1115
1090
|
:where(.wt-root) .wt-activity-mark[data-activity="working"]::before {
|
|
1091
|
+
--wt-mark-hole: calc(var(--wt-mark-size) / 2 - var(--wt-mark-band));
|
|
1092
|
+
--wt-mark-close: 0.1;
|
|
1093
|
+
|
|
1116
1094
|
content: "";
|
|
1117
1095
|
position: absolute;
|
|
1118
|
-
inset:
|
|
1119
|
-
border-radius: 50%;
|
|
1096
|
+
inset: round(down, var(--wt-mark-hole) - (var(--wt-mark-hole) + 1px) / var(--wt-mark-close), 1px);
|
|
1120
1097
|
background: radial-gradient(
|
|
1121
|
-
|
|
1122
|
-
|
|
1123
|
-
|
|
1124
|
-
transparent 92%
|
|
1098
|
+
circle,
|
|
1099
|
+
transparent 0 calc(1.4142 * var(--wt-mark-hole)),
|
|
1100
|
+
var(--wt-mark-ink) calc(1.4142 * var(--wt-mark-hole) + 0.5px)
|
|
1125
1101
|
);
|
|
1126
|
-
opacity: 0;
|
|
1127
1102
|
animation: wt-activity-breath var(--dot-beat-dur) ease-in-out infinite;
|
|
1103
|
+
will-change: transform;
|
|
1104
|
+
}
|
|
1105
|
+
|
|
1106
|
+
:where(.wt-root) .wt-activity-mark[data-activity="working"]::after {
|
|
1107
|
+
content: "";
|
|
1108
|
+
position: absolute;
|
|
1109
|
+
inset: -1px;
|
|
1110
|
+
background: var(--wt-mark-ink);
|
|
1111
|
+
opacity: 0;
|
|
1112
|
+
animation: wt-activity-seal var(--dot-beat-dur) ease-in-out infinite;
|
|
1128
1113
|
will-change: opacity;
|
|
1129
|
-
mask: radial-gradient(
|
|
1130
|
-
closest-side,
|
|
1131
|
-
transparent 0 calc(var(--wt-mark-size) / 2 - var(--wt-mark-band)),
|
|
1132
|
-
#000 calc(var(--wt-mark-size) / 2 - var(--wt-mark-band))
|
|
1133
|
-
);
|
|
1134
1114
|
}
|
|
1135
1115
|
|
|
1136
1116
|
/* Waiting: the thin band plus a static halo. Stopped and resumable, nobody being
|
|
@@ -1205,25 +1185,30 @@
|
|
|
1205
1185
|
}
|
|
1206
1186
|
}
|
|
1207
1187
|
|
|
1208
|
-
/* The activity mark's
|
|
1209
|
-
|
|
1210
|
-
|
|
1211
|
-
The dot's glow ENVELOPE, at a lower CEILING, and the ceiling is where the two
|
|
1212
|
-
deliberately part. 0.55 rather than 1 is marotte's number for the same mark
|
|
1213
|
-
(`12-tabs.css`), and it is what keeps a strip of busy tabs reading as one pulse
|
|
1214
|
-
instead of a row of flashes — the dot can afford 1 because its overlay lifts a
|
|
1215
|
-
solid disc of its own hue and has almost no headroom above its own backdrop,
|
|
1216
|
-
while this one is masked onto a 2px band over the page and has all of it. Used by
|
|
1217
|
-
the mark alone, so the value moves nothing else. */
|
|
1188
|
+
/* The activity mark's close: open, shut, open, on the dot glow's envelope so the
|
|
1189
|
+
hole shuts as the disc beside it peaks. Transform only, so it never repaints. */
|
|
1218
1190
|
@keyframes wt-activity-breath {
|
|
1219
1191
|
0%,
|
|
1220
1192
|
70%,
|
|
1193
|
+
100% {
|
|
1194
|
+
transform: scale(1);
|
|
1195
|
+
}
|
|
1196
|
+
|
|
1197
|
+
35% {
|
|
1198
|
+
transform: scale(var(--wt-mark-close));
|
|
1199
|
+
}
|
|
1200
|
+
}
|
|
1201
|
+
|
|
1202
|
+
@keyframes wt-activity-seal {
|
|
1203
|
+
0%,
|
|
1204
|
+
20%,
|
|
1205
|
+
50%,
|
|
1221
1206
|
100% {
|
|
1222
1207
|
opacity: 0;
|
|
1223
1208
|
}
|
|
1224
1209
|
|
|
1225
1210
|
35% {
|
|
1226
|
-
opacity:
|
|
1211
|
+
opacity: 1;
|
|
1227
1212
|
}
|
|
1228
1213
|
}
|
|
1229
1214
|
|
|
@@ -1270,13 +1255,14 @@
|
|
|
1270
1255
|
by band alone (3px bare / 1px halo / 2px halo).
|
|
1271
1256
|
|
|
1272
1257
|
Re-pointing --wt-mark-band rather than declaring `border-width` keeps the number
|
|
1273
|
-
in the one place the state's own rule reads it from, the
|
|
1258
|
+
in the one place the state's own rule reads it from, the overlay's hole included
|
|
1274
1259
|
— which is moot here only because the overlay is gone one rule below. */
|
|
1275
1260
|
:where(.wt-root) .wt-activity-mark[data-activity="working"] {
|
|
1276
1261
|
--wt-mark-band: 3px;
|
|
1277
1262
|
}
|
|
1278
1263
|
|
|
1279
|
-
:where(.wt-root) .wt-activity-mark[data-activity="working"]::before
|
|
1264
|
+
:where(.wt-root) .wt-activity-mark[data-activity="working"]::before,
|
|
1265
|
+
:where(.wt-root) .wt-activity-mark[data-activity="working"]::after {
|
|
1280
1266
|
content: none;
|
|
1281
1267
|
}
|
|
1282
1268
|
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@cplieger/web-terminal-ui",
|
|
3
|
-
"version": "8.1.
|
|
3
|
+
"version": "8.1.2",
|
|
4
4
|
"type": "module",
|
|
5
5
|
"description": "Reference touch-first browser UI for @cplieger/web-terminal-engine: a composable kernel + feature modules (tabs, activity monitor, mobile toolbar, context menu, IME, predictive echo, viewport handling) and CSS. One createTerminal() call.",
|
|
6
6
|
"license": "MPL-2.0",
|