@glimstone/core 4.0.0 → 4.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/tokens.css CHANGED
@@ -594,6 +594,70 @@ body {
594
594
  background-color: var(--carbon-hover);
595
595
  }
596
596
 
597
+ /* A drag on the square or the bar is the picker's, never a scroll of the
598
+ page. The handle shows the colour it stands on. */
599
+ .glim-picker-sv,
600
+ .glim-picker-hue { touch-action: none; }
601
+ .glim-picker-dot { background-color: var(--glim-picker-colour, transparent); }
602
+
603
+ /* The ColorPicker components: the widget, the preview with the name it
604
+ proposes and the hex field, and Apply. Without an anchor the panel sits in
605
+ the page on whatever surface holds it; with one it floats on the body, above
606
+ windows and below toasts, like a menu. */
607
+ .glim-picker-panel {
608
+ --glim-picker-colour: transparent;
609
+ display: flex;
610
+ flex-direction: column;
611
+ gap: 0.75rem;
612
+ width: 18.5rem;
613
+ max-width: 100%;
614
+ }
615
+ .glim-picker-panel .glim-picker-sv { height: 10rem; }
616
+ .glim-picker-panel .glim-picker-dot {
617
+ width: 1.1rem;
618
+ height: 1.1rem;
619
+ margin: -0.55rem 0 0 -0.55rem;
620
+ }
621
+ .glim-picker-panel--float {
622
+ position: fixed;
623
+ z-index: 60;
624
+ padding: 0.8rem;
625
+ border-radius: var(--radius-card);
626
+ background-color: var(--carbon-surface);
627
+ box-shadow: var(--elevation), var(--hairline);
628
+ }
629
+ .glim-picker-foot {
630
+ display: flex;
631
+ align-items: center;
632
+ gap: 0.55rem;
633
+ }
634
+ .glim-picker-swatch {
635
+ width: 1.6rem;
636
+ height: 1.6rem;
637
+ flex: none;
638
+ border-radius: var(--radius-pill);
639
+ background-color: var(--glim-picker-colour);
640
+ box-shadow: 0 0 0 2px color-mix(in srgb, var(--glim-picker-colour) 30%, transparent), inset 0 0 0 1px var(--carbon-border);
641
+ }
642
+ .glim-picker-name {
643
+ flex: 1;
644
+ min-width: 0;
645
+ overflow: hidden;
646
+ font-weight: 600;
647
+ text-overflow: ellipsis;
648
+ white-space: nowrap;
649
+ }
650
+ .glim-picker-foot .glim-picker-hex {
651
+ width: 6.2rem;
652
+ height: var(--btn-h);
653
+ flex: none;
654
+ margin-inline-start: auto;
655
+ }
656
+ .glim-picker-actions {
657
+ display: flex;
658
+ justify-content: flex-end;
659
+ }
660
+
597
661
  /* Rainbow, the accent in its plural form (docs/design-language.md; the JS side
598
662
  is hueVars and applyRainbow in packages/core/src/appearance.ts). An element that owns
599
663
  a palette position sets --item-hue and carries .glim-hue, and these rules
@@ -721,6 +785,9 @@ body {
721
785
  0% { left: -35%; }
722
786
  100% { left: 100%; }
723
787
  }
788
+ @keyframes glim-progress-sheen {
789
+ to { translate: 100% 0; }
790
+ }
724
791
  /* Translation only. This runs on the route wrapper while the cards inside it
725
792
  animate their own transforms, and a scale or rotation on an ancestor makes
726
793
  the engine resample the whole subtree, so the page trembles before it
@@ -906,6 +973,10 @@ body {
906
973
  --motion-slosh-splash-tilt: 7deg;
907
974
  --motion-slosh-splash-run: 3.4;
908
975
  --motion-slosh-splash-ripple: 1.5;
976
+ /* A progress bar without a value: one sweep of its light across the
977
+ track. Its sheen: one pass over the filled part. */
978
+ --motion-indeterminate-dur: 1.4s;
979
+ --motion-progress-sheen-dur: 1.6s;
909
980
  }
910
981
  :root[data-motion='subtle'] {
911
982
  --motion-control-dur: 80ms;
@@ -950,6 +1021,8 @@ body {
950
1021
  --motion-slosh-splash-tilt: 4deg;
951
1022
  --motion-slosh-splash-run: 2.2;
952
1023
  --motion-slosh-splash-ripple: 1;
1024
+ --motion-indeterminate-dur: 2.2s;
1025
+ --motion-progress-sheen-dur: 2.6s;
953
1026
  }
954
1027
  :root[data-motion='off'] {
955
1028
  --motion-control-dur: 0s;
@@ -998,7 +1071,27 @@ body {
998
1071
  --motion-slosh-splash-tilt: 0deg;
999
1072
  --motion-slosh-splash-run: 0;
1000
1073
  --motion-slosh-splash-ripple: 0;
1074
+ /* Long rather than 0; both stop outright at this level, below. */
1075
+ --motion-indeterminate-dur: 60s;
1076
+ --motion-progress-sheen-dur: 60s;
1077
+ }
1078
+ /* A progress bar without a value sends a short light across its track, and
1079
+ a running one a sheen over its fill. A meter never moves: it shows a level
1080
+ that stands, and a light on it would say something is under way. Both
1081
+ stop at "off", where a bar without a value keeps its stripes, and under
1082
+ reduced motion even for storm: wanting more movement is not wanting
1083
+ something that never stops. */
1084
+ :root:not([data-motion='off']) .glim-progress--busy > .glim-progress-fill {
1085
+ width: 35%;
1086
+ background: var(--accent);
1087
+ opacity: 1;
1088
+ animation: glim-indeterminate var(--motion-indeterminate-dur) ease-in-out infinite;
1001
1089
  }
1090
+ :root:not([data-motion='off']) .glim-progress:not(.glim-progress--busy, .glim-progress--paused, .glim-progress--done, .glim-progress--failed) .glim-progress-fill::after {
1091
+ animation: glim-progress-sheen var(--motion-progress-sheen-dur) ease-in-out infinite;
1092
+ }
1093
+ .glim-progress-fill { transition: width var(--motion-control-dur) linear; }
1094
+
1002
1095
  :root[data-motion='off'] * { transition-duration: 0s !important; }
1003
1096
  :root[data-motion='subtle'] .transition,
1004
1097
  :root[data-motion='subtle'] .transition-colors,
@@ -1071,6 +1164,8 @@ body {
1071
1164
  --motion-slosh-splash-tilt: 10deg;
1072
1165
  --motion-slosh-splash-run: 4.8;
1073
1166
  --motion-slosh-splash-ripple: 2;
1167
+ --motion-indeterminate-dur: 0.9s;
1168
+ --motion-progress-sheen-dur: 1.1s;
1074
1169
  }
1075
1170
  :root[data-motion='storm'][dir="rtl"] { --glim-toast-slide: -44px; }
1076
1171
 
@@ -2718,7 +2813,7 @@ body {
2718
2813
  :where([class*="glim-"]) :where(*, ::before, ::after) {
2719
2814
  box-sizing: border-box;
2720
2815
  }
2721
- :where(.glim-btn, .glim-badge, .glim-readme-btn, .glim-toggle-track, .glim-toast-dismiss, .glim-window-button, .glim-give-network, .glim-give-coin, .glim-give-amount, .glim-sel-seg, .glim-num-field) {
2816
+ :where(.glim-btn, .glim-badge, .glim-readme-btn, .glim-toggle-track, .glim-toast-dismiss, .glim-window-button, .glim-give-network, .glim-give-coin, .glim-give-amount, .glim-sel-seg, .glim-num-field, .glim-menu-item, .glim-menu-head-edit, .glim-menubar-item, .glim-checkbox, .glim-input, .glim-secret-eye) {
2722
2817
  margin: 0;
2723
2818
  padding: 0;
2724
2819
  border: 0 solid;
@@ -3815,4 +3910,438 @@ body {
3815
3910
  .glim-subcard .glim-sel--chip .glim-sel-seg:not(.glim-active):not(:disabled):hover {
3816
3911
  background-color: var(--carbon-hover-raised);
3817
3912
  }
3913
+
3914
+ /* The general window (Window): the confirm surface's frame, grown to hold a
3915
+ form, a list or a whole tool at three widths. Its notch sits in the card's
3916
+ padding, so the body starts far enough down to clear it, and the start of
3917
+ the foot holds one quiet line, such as where the work carries on. */
3918
+ .glim-window { max-width: 40rem; }
3919
+ .glim-window--wide { max-width: 58rem; }
3920
+ .glim-window--full {
3921
+ max-width: 80rem;
3922
+ height: calc(100vh - 2rem - var(--window-bar));
3923
+ max-height: none;
3924
+ }
3925
+ .glim-window-title { margin: 0; }
3926
+ .glim-window-body {
3927
+ display: flex;
3928
+ flex-direction: column;
3929
+ gap: 1rem;
3930
+ padding-top: 1.75rem;
3931
+ }
3932
+ .glim-window-start {
3933
+ margin-inline-end: auto;
3934
+ font-size: var(--text-meta);
3935
+ color: var(--carbon-text-muted);
3936
+ }
3937
+
3938
+ /* The context menu and the menus of the bar (ContextMenu, MenuBar). Both sit
3939
+ on the body, so no card or scroll box clips them, and a submenu is a menu
3940
+ of its own beside its row: inside the first one, that menu's scrolling
3941
+ would cut it off. Above windows, below toasts and bubbles. */
3942
+ .glim-menu {
3943
+ position: fixed;
3944
+ z-index: 60;
3945
+ display: flex;
3946
+ flex-direction: column;
3947
+ min-width: 16rem;
3948
+ max-height: calc(100vh - 2rem);
3949
+ overflow: auto;
3950
+ padding: 0.35rem;
3951
+ border-radius: var(--radius-card);
3952
+ background-color: var(--carbon-surface);
3953
+ box-shadow: var(--elevation), var(--hairline);
3954
+ }
3955
+ .glim-menu-item {
3956
+ display: flex;
3957
+ flex: none;
3958
+ align-items: center;
3959
+ gap: 0.6rem;
3960
+ height: 2rem;
3961
+ padding-inline: 0.6rem;
3962
+ border-radius: var(--radius-control);
3963
+ font-size: var(--text-body);
3964
+ text-align: start;
3965
+ white-space: nowrap;
3966
+ cursor: pointer;
3967
+ }
3968
+ /* A menu the pointer opened carries data-pointer until a key is pressed in
3969
+ it, so the first row it focused stays unlit (focusFirstMenuRow). */
3970
+ .glim-menu-item:hover,
3971
+ .glim-menu:not([data-pointer]) .glim-menu-item:focus-visible,
3972
+ .glim-menu-item[aria-expanded="true"] { background-color: var(--carbon-hover); }
3973
+ .glim-menu-item:disabled {
3974
+ opacity: 0.45;
3975
+ cursor: default;
3976
+ }
3977
+ .glim-menu-item:disabled:hover { background-color: transparent; }
3978
+ /* The current choice of a radio group, washed rather than filled, since the
3979
+ tick at its end already says which. */
3980
+ .glim-menu-item--current { background-color: var(--accent-soft); }
3981
+ /* Also the empty room of a row without a glyph, so every label starts at one edge. */
3982
+ .glim-menu-glyph {
3983
+ display: inline-grid;
3984
+ flex: none;
3985
+ width: 0.95rem;
3986
+ height: 0.95rem;
3987
+ color: var(--accent-glyph);
3988
+ }
3989
+ .glim-menu-glyph > svg {
3990
+ width: 100%;
3991
+ height: 100%;
3992
+ }
3993
+ .glim-menu-dot {
3994
+ flex: none;
3995
+ width: 0.95rem;
3996
+ height: 0.95rem;
3997
+ border-radius: var(--radius-pill);
3998
+ }
3999
+ .glim-menu-label {
4000
+ flex: 1 1 auto;
4001
+ min-width: 0;
4002
+ overflow: hidden;
4003
+ text-overflow: ellipsis;
4004
+ }
4005
+ .glim-menu-end {
4006
+ display: inline-flex;
4007
+ flex: none;
4008
+ align-items: center;
4009
+ margin-inline-start: auto;
4010
+ }
4011
+ .glim-menu-tick { color: var(--accent-glyph); }
4012
+ .glim-menu-count {
4013
+ padding-inline-start: 1.2rem;
4014
+ font-size: var(--text-meta);
4015
+ color: var(--carbon-text-muted);
4016
+ }
4017
+ .glim-menu-caret { color: var(--carbon-text-muted); }
4018
+ .glim-menu-caret svg {
4019
+ width: 0.7rem;
4020
+ height: 0.7rem;
4021
+ rotate: -90deg;
4022
+ }
4023
+ .glim-menu-caret:dir(rtl) svg { rotate: 90deg; }
4024
+ .glim-menu-sep {
4025
+ flex: none;
4026
+ height: 1px;
4027
+ margin: 0.3rem 0.4rem;
4028
+ background-color: color-mix(in srgb, var(--carbon-text) 9%, transparent);
4029
+ }
4030
+ .glim-menu-head {
4031
+ display: flex;
4032
+ align-items: center;
4033
+ gap: 0.5rem;
4034
+ min-height: 1.6rem;
4035
+ padding-block: 0.35rem 0.2rem;
4036
+ padding-inline: 0.6rem 0.3rem;
4037
+ font-size: var(--text-meta);
4038
+ letter-spacing: 0.14em;
4039
+ text-transform: uppercase;
4040
+ color: var(--carbon-text-muted);
4041
+ }
4042
+ .glim-menu-head-edit {
4043
+ display: grid;
4044
+ flex: none;
4045
+ place-items: center;
4046
+ width: 1.6rem;
4047
+ height: 1.6rem;
4048
+ margin-inline-start: auto;
4049
+ border-radius: var(--radius-control);
4050
+ color: var(--accent-glyph);
4051
+ cursor: pointer;
4052
+ }
4053
+ .glim-menu-head-edit:hover,
4054
+ .glim-menu:not([data-pointer]) .glim-menu-head-edit:focus-visible { background-color: var(--carbon-hover); }
4055
+ .glim-menu-head-edit svg {
4056
+ width: 0.85rem;
4057
+ height: 0.85rem;
4058
+ }
4059
+
4060
+ /* The menu bar of a desktop-style app's head row: bare words that take the
4061
+ second surface under the pointer and while their menu is open. */
4062
+ .glim-menubar {
4063
+ display: flex;
4064
+ flex: none;
4065
+ align-items: center;
4066
+ gap: 2px;
4067
+ }
4068
+ .glim-menubar-item {
4069
+ height: 2.2rem;
4070
+ padding-inline: 0.7rem;
4071
+ border-radius: var(--radius-pill);
4072
+ font-weight: 500;
4073
+ color: var(--carbon-text-sub);
4074
+ cursor: pointer;
4075
+ }
4076
+ .glim-menubar-item:hover,
4077
+ .glim-menubar-item[aria-expanded="true"] {
4078
+ background-color: var(--carbon-surface2);
4079
+ color: var(--carbon-text);
4080
+ }
4081
+
4082
+ /* The checkbox (Checkbox, and the box of a menu's checkbox item): the one
4083
+ place a box stands instead of a switch (rule 39). Drawn rather than the
4084
+ system's, at the control radius held small enough to stay a box, and when
4085
+ ticked the accent with the tick in its contrast ink. */
4086
+ .glim-checkbox {
4087
+ display: inline-flex;
4088
+ align-items: center;
4089
+ gap: 0.6rem;
4090
+ min-height: 2rem;
4091
+ padding-inline: 0.4rem;
4092
+ border-radius: var(--radius-control);
4093
+ text-align: start;
4094
+ cursor: pointer;
4095
+ }
4096
+ .glim-checkbox:hover { background-color: var(--carbon-hover); }
4097
+ .glim-checkbox:disabled {
4098
+ opacity: 0.55;
4099
+ cursor: default;
4100
+ }
4101
+ .glim-checkbox:disabled:hover { background-color: transparent; }
4102
+ .glim-checkbox-box {
4103
+ display: grid;
4104
+ flex: none;
4105
+ place-items: center;
4106
+ width: 1.125rem;
4107
+ height: 1.125rem;
4108
+ border-radius: min(var(--radius-control), 5px);
4109
+ background-color: color-mix(in srgb, var(--carbon-surface3) 60%, transparent);
4110
+ color: transparent;
4111
+ }
4112
+ .glim-checkbox-box > svg {
4113
+ width: 0.75rem;
4114
+ height: 0.75rem;
4115
+ }
4116
+ [aria-checked="true"] > .glim-checkbox-box {
4117
+ background-color: var(--accent);
4118
+ color: var(--accent-contrast);
4119
+ }
4120
+ /* The slim checkbox: the box alone, for a row or a cell of a dense list,
4121
+ where the frame's padding and hover ground would crowd the row. The row
4122
+ around it gives the hover, and the box only firms up. */
4123
+ .glim-checkbox--slim {
4124
+ min-height: 0;
4125
+ padding: 0;
4126
+ border-radius: min(var(--radius-control), 5px);
4127
+ }
4128
+ .glim-checkbox--slim:hover { background-color: transparent; }
4129
+ .glim-checkbox--slim[aria-checked="false"]:not(:disabled):hover > .glim-checkbox-box {
4130
+ background-color: var(--carbon-surface3);
4131
+ }
4132
+
4133
+ /* A key cap (Kbd), in the app's own type rather than the browser's monospace. */
4134
+ .glim-kbd {
4135
+ display: inline-grid;
4136
+ place-items: center;
4137
+ height: 1.2rem;
4138
+ padding-inline: 0.4rem;
4139
+ border-radius: var(--radius-control);
4140
+ background-color: var(--carbon-surface3);
4141
+ font-family: inherit;
4142
+ font-size: var(--text-meta);
4143
+ color: var(--carbon-text-sub);
4144
+ white-space: nowrap;
4145
+ }
4146
+
4147
+ /* The data pill (Pill): one value of a row, quiet at rest. A state takes a
4148
+ wash of its solid colour over the second surface, so the text keeps the
4149
+ body ink and a column of pills still reads as one column. */
4150
+ .glim-pill {
4151
+ display: inline-flex;
4152
+ flex: none;
4153
+ align-items: center;
4154
+ height: 1.35rem;
4155
+ padding-inline: 0.55rem;
4156
+ border-radius: var(--radius-pill);
4157
+ background-color: var(--carbon-surface2);
4158
+ font-size: var(--text-meta);
4159
+ color: var(--carbon-text-sub);
4160
+ white-space: nowrap;
4161
+ }
4162
+ .glim-pill--state { background-color: var(--carbon-surface3); color: var(--carbon-text); }
4163
+ .glim-pill--ok { background-color: color-mix(in srgb, var(--carbon-surface2), var(--status-ok-solid) 30%); color: var(--carbon-text); }
4164
+ .glim-pill--warn { background-color: color-mix(in srgb, var(--carbon-surface2), var(--status-warn-solid) 35%); color: var(--carbon-text); }
4165
+ .glim-pill--fail { background-color: color-mix(in srgb, var(--carbon-surface2), var(--status-fail-solid) 35%); color: var(--carbon-text); }
4166
+
4167
+ /* A text field (PasswordField, CopyField): borderless and filled (rule 14),
4168
+ a step up the ramp on focus and inside a sub-card, like the number field.
4169
+ It fills its column; a width belongs to the wrapper around it. */
4170
+ .glim-input {
4171
+ width: 100%;
4172
+ min-width: 0;
4173
+ height: var(--btn-h);
4174
+ padding-inline: 0.75rem;
4175
+ border-radius: var(--radius-control);
4176
+ background-color: var(--carbon-surface2);
4177
+ color: var(--carbon-text);
4178
+ font-size: var(--text-body);
4179
+ line-height: 1.25rem;
4180
+ }
4181
+ .glim-input:focus,
4182
+ .glim-well .glim-input { background-color: var(--carbon-surface3); }
4183
+ .glim-well .glim-input:focus { background-color: var(--carbon-hover-raised); }
4184
+ .glim-input:disabled {
4185
+ opacity: 0.5;
4186
+ cursor: not-allowed;
4187
+ }
4188
+ .glim-input::placeholder { color: var(--carbon-text-muted); }
4189
+ .glim-input--mono {
4190
+ font-family: ui-monospace, "Cascadia Code", Menlo, Consolas, monospace;
4191
+ font-size: var(--text-subline);
4192
+ text-overflow: ellipsis;
4193
+ }
4194
+
4195
+ /* The reveal eye ("The reveal eye" in the design language): a bare glyph in
4196
+ the field's trailing padding, neutral, and the wrapper as wide as a plain
4197
+ field. Edge draws an eye of its own into every password field, which
4198
+ would stand beside this one. */
4199
+ .glim-secret {
4200
+ position: relative;
4201
+ display: block;
4202
+ width: 100%;
4203
+ min-width: 0;
4204
+ }
4205
+ .glim-secret > .glim-input { padding-inline-end: 2.4rem; }
4206
+ .glim-secret > .glim-input::-ms-reveal { display: none; }
4207
+ .glim-secret-eye {
4208
+ position: absolute;
4209
+ inset-inline-end: 0.35rem;
4210
+ top: 50%;
4211
+ translate: 0 -50%;
4212
+ display: grid;
4213
+ place-items: center;
4214
+ width: 1.6rem;
4215
+ height: 1.6rem;
4216
+ border-radius: var(--radius-control);
4217
+ color: var(--carbon-text-muted);
4218
+ cursor: pointer;
4219
+ }
4220
+ .glim-secret-eye:hover { color: var(--carbon-text); }
4221
+ .glim-secret-eye > svg {
4222
+ width: 0.95rem;
4223
+ height: 0.95rem;
4224
+ }
4225
+
4226
+ /* A value to copy (CopyField): the value in monospace, read-only so it can
4227
+ still be selected and scrolled, and its button beside it. */
4228
+ .glim-copy {
4229
+ display: flex;
4230
+ align-items: center;
4231
+ gap: 0.4rem;
4232
+ width: 100%;
4233
+ min-width: 0;
4234
+ }
4235
+ .glim-copy > .glim-input { flex: 1; }
4236
+
4237
+ /* Words for a screen reader alone, such as the "Copied" a copy button
4238
+ announces. */
4239
+ .glim-sr-only {
4240
+ position: absolute;
4241
+ width: 1px;
4242
+ height: 1px;
4243
+ margin: -1px;
4244
+ overflow: hidden;
4245
+ clip-path: inset(50%);
4246
+ white-space: nowrap;
4247
+ }
4248
+
4249
+ /* The meter (Meter): a level on the third surface, thin beside a row's name
4250
+ or as wide as its column. At its threshold the fill turns to the fault
4251
+ colour. In the active row of a rail it takes the row's contrast ink, as
4252
+ the row's count does. */
4253
+ .glim-meter-track {
4254
+ position: relative;
4255
+ display: block;
4256
+ overflow: hidden;
4257
+ border-radius: var(--radius-pill);
4258
+ background-color: var(--carbon-surface3);
4259
+ }
4260
+ .glim-meter-track--small {
4261
+ display: inline-block;
4262
+ flex: none;
4263
+ width: 2.6rem;
4264
+ height: 0.35rem;
4265
+ vertical-align: middle;
4266
+ }
4267
+ .glim-meter-track--medium {
4268
+ width: 100%;
4269
+ height: 0.55rem;
4270
+ }
4271
+ .glim-meter-fill {
4272
+ display: block;
4273
+ height: 100%;
4274
+ border-radius: inherit;
4275
+ background-color: var(--accent);
4276
+ }
4277
+ /* The quiet meter: slim and grey, for a footer line or a dense list, where
4278
+ an accent bar on every row would outshout the names beside it. Inside a
4279
+ button it takes the accent when the button is reached, as the button's
4280
+ own glyph does (rule 40). The threshold still turns it red. */
4281
+ .glim-meter-track--quiet {
4282
+ height: 0.35rem;
4283
+ background-color: var(--carbon-surface2);
4284
+ }
4285
+ .glim-meter-track--quiet > .glim-meter-fill { background-color: var(--carbon-text-muted); }
4286
+ :is(button, a):is(:hover, :focus-visible) .glim-meter-track--quiet:not(.glim-meter-track--full) > .glim-meter-fill {
4287
+ background-color: var(--accent);
4288
+ }
4289
+ .glim-meter-track--full .glim-meter-fill { background-color: var(--status-fail-solid); }
4290
+ .glim-active .glim-meter-track { background-color: color-mix(in srgb, var(--accent-contrast) 22%, transparent); }
4291
+ .glim-active .glim-meter-fill { background-color: var(--accent-contrast); }
4292
+
4293
+ /* The progress bar (ProgressBar): a thicker track whose fill carries a
4294
+ sheen while the work runs. Paused takes the waiting tone and a failure
4295
+ the fault colour (rule 4). */
4296
+ .glim-progress {
4297
+ position: relative;
4298
+ display: block;
4299
+ width: 100%;
4300
+ height: 0.6rem;
4301
+ overflow: hidden;
4302
+ border-radius: var(--radius-pill);
4303
+ background-color: var(--carbon-surface3);
4304
+ }
4305
+ .glim-progress-fill {
4306
+ position: absolute;
4307
+ inset-block: 0;
4308
+ inset-inline-start: 0;
4309
+ overflow: hidden;
4310
+ border-radius: inherit;
4311
+ background-color: var(--accent);
4312
+ }
4313
+ .glim-progress-fill::after {
4314
+ content: "";
4315
+ position: absolute;
4316
+ inset: 0;
4317
+ background: linear-gradient(100deg, transparent 20%, rgb(255 255 255 / 0.45) 50%, transparent 80%);
4318
+ translate: -100% 0;
4319
+ }
4320
+ .glim-progress--paused .glim-progress-fill { background-color: var(--status-neutral-solid); }
4321
+ .glim-progress--failed .glim-progress-fill { background-color: var(--status-fail-solid); }
4322
+
4323
+ /* Without a value the track shows stripes, which no value could be
4324
+ mistaken for. A progress bar swaps them for a light that crosses the
4325
+ track, set up in the motion gate. */
4326
+ :is(.glim-meter-track--busy, .glim-progress--busy) > :is(.glim-meter-fill, .glim-progress-fill) {
4327
+ position: absolute;
4328
+ inset-block: 0;
4329
+ left: 0;
4330
+ width: 100%;
4331
+ background: repeating-linear-gradient(-45deg, var(--accent) 0 4px, transparent 4px 8px);
4332
+ opacity: 0.5;
4333
+ }
4334
+ .glim-meter-track--quiet.glim-meter-track--busy > .glim-meter-fill {
4335
+ background: repeating-linear-gradient(-45deg, var(--carbon-text-muted) 0 4px, transparent 4px 8px);
4336
+ }
4337
+ }
4338
+
4339
+ /* Outside the layer, or the house ring's offset would win: inside a menu the
4340
+ ring is drawn on the row, where the menu's edge cannot clip it. */
4341
+ .glim-menu-item:focus-visible,
4342
+ .glim-menu-head-edit:focus-visible { outline-offset: -2px; }
4343
+ .glim-menu[data-pointer] :focus-visible { outline: none; }
4344
+
4345
+ @media (prefers-reduced-motion: no-preference) {
4346
+ .glim-checkbox-box { transition: background-color var(--motion-control-dur) ease; }
3818
4347
  }