@gemboss/website-ui 0.7.0 → 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.
- package/AGENTS.md +18 -3
- package/CHANGELOG.md +129 -0
- package/README.md +8 -8
- package/bin/lib/check.mjs +72 -1
- package/css/effects.css +71 -0
- package/css/header.css +176 -0
- package/css/tokens.css +7 -0
- package/demo/header.html +356 -0
- package/demo/index.html +2 -0
- package/demo/spotlight.html +291 -0
- package/docs/components.md +116 -4
- package/docs/markup-contract.md +135 -5
- package/docs/theming.md +9 -2
- package/js/website.js +168 -4
- package/js/website.mjs +208 -4
- package/package.json +1 -1
- package/skill/SKILL.md +6 -0
- package/system.json +13 -1
- package/templates/header.html +34 -6
- package/website.css +256 -1
- package/website.min.css +1 -1
package/website.css
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
/*! @gemboss/website-ui 0.
|
|
1
|
+
/*! @gemboss/website-ui 0.9.0 | generated by scripts/build.mjs from the files in css/. Edit those and not this file */
|
|
2
2
|
/* @gemboss/website-ui tokens. GENERATED from system.json by scripts/build.mjs: do not edit by hand. */
|
|
3
3
|
:root {
|
|
4
4
|
color-scheme: light;
|
|
@@ -70,6 +70,13 @@
|
|
|
70
70
|
--gw-ease: cubic-bezier(.22,1,.36,1);
|
|
71
71
|
--gw-reveal-ms: 700ms;
|
|
72
72
|
--gw-spin-ms: 700ms;
|
|
73
|
+
--gw-spot-radius: 260px;
|
|
74
|
+
--gw-spot-radius-action: 120px;
|
|
75
|
+
--gw-spot-strength: 22%;
|
|
76
|
+
--gw-spot-strength-action: 38%;
|
|
77
|
+
--gw-spot-strength-stage: 40%;
|
|
78
|
+
--gw-spot-ms: 550ms;
|
|
79
|
+
--gw-spot-ease: cubic-bezier(.16,1,.3,1);
|
|
73
80
|
--gw-wash-pink: #ff6f5e;
|
|
74
81
|
--gw-wash-violet: #7c8af7;
|
|
75
82
|
--gw-wash-sky: #43b0ff;
|
|
@@ -1039,6 +1046,182 @@ html.is-menu-open .gw-header { position: fixed; top: 0; left: 0; right: 0; }
|
|
|
1039
1046
|
.gw-header--float { background: var(--gw-surface); }
|
|
1040
1047
|
}
|
|
1041
1048
|
|
|
1049
|
+
/* ---- 0.8.0: the drill-down mobile menu (gap #41) and the language switcher (gap #29) --------------------------------
|
|
1050
|
+
Every rule below selects a part 0.7.0 does not have (data-gw-menu="drill", the script's .is-drill, the menu's
|
|
1051
|
+
__head, __back, __title, __heading and __icon, .gw-lang), so a 0.7.0 header looks and works exactly as before. */
|
|
1052
|
+
|
|
1053
|
+
/* The drill-down menu, as gemboss.ai's phone menu (v4, approved 15/10/2026), opt-in on the sheet:
|
|
1054
|
+
<div class="gw-mobile-menu" data-gw-menu="drill">. Its look needs only the attribute: top-level rows of 64px with
|
|
1055
|
+
24px words and one hairline each, a level's links with an optional icon and line, and the actions in a bar that
|
|
1056
|
+
stays at the bottom of the sheet while the list scrolls (the sheet has no bottom padding, so nothing peeks out under
|
|
1057
|
+
the bar; nor sideways while a level slides in). Without the script the groups are the 0.7.0 <details> that open in
|
|
1058
|
+
place, their chevron pointing down. */
|
|
1059
|
+
.gw-mobile-menu[data-gw-menu="drill"] { display: flex; flex-direction: column; overflow-x: hidden; padding-bottom: 0; }
|
|
1060
|
+
.gw-mobile-menu[data-gw-menu="drill"] > nav { display: flex; flex: 1 0 auto; flex-direction: column; }
|
|
1061
|
+
.gw-mobile-menu[data-gw-menu="drill"] .gw-mobile-menu__group > summary,
|
|
1062
|
+
.gw-mobile-menu[data-gw-menu="drill"] .gw-mobile-menu__top { min-height: 64px; font-size: 24px; letter-spacing: -0.01em; }
|
|
1063
|
+
.gw-mobile-menu[data-gw-menu="drill"] .gw-mobile-menu__group > summary::after { width: 20px; height: 20px; -webkit-mask-size: 20px; mask-size: 20px; }
|
|
1064
|
+
.gw-mobile-menu[data-gw-menu="drill"] .gw-mobile-menu__list { padding: 0; }
|
|
1065
|
+
.gw-mobile-menu[data-gw-menu="drill"] .gw-mobile-menu__list .gw-mobile-menu__link {
|
|
1066
|
+
gap: 12px;
|
|
1067
|
+
min-height: 56px;
|
|
1068
|
+
padding-block: 12px;
|
|
1069
|
+
border-bottom: 1px solid var(--gw-line);
|
|
1070
|
+
color: var(--gw-ink);
|
|
1071
|
+
font-weight: 500;
|
|
1072
|
+
}
|
|
1073
|
+
.gw-mobile-menu[data-gw-menu="drill"] .gw-mobile-menu__link b { display: block; font-size: 16px; font-weight: 500; line-height: 20px; }
|
|
1074
|
+
.gw-mobile-menu[data-gw-menu="drill"] .gw-mobile-menu__link i { display: block; margin-top: 2px; color: var(--gw-muted); font-size: 13px; font-style: normal; line-height: 18px; }
|
|
1075
|
+
/* a level's optional parts: a muted heading over a run of links, a 32px icon tile before a link's words */
|
|
1076
|
+
.gw-mobile-menu__heading { padding: 16px 0 8px; color: var(--gw-muted); font-size: 12px; font-weight: 500; line-height: 1.5; }
|
|
1077
|
+
.gw-mobile-menu__icon {
|
|
1078
|
+
display: grid;
|
|
1079
|
+
place-items: center;
|
|
1080
|
+
flex: none;
|
|
1081
|
+
width: 32px;
|
|
1082
|
+
height: 32px;
|
|
1083
|
+
border: 1px solid var(--gw-line);
|
|
1084
|
+
border-radius: var(--gw-radius-action);
|
|
1085
|
+
color: var(--gw-muted);
|
|
1086
|
+
}
|
|
1087
|
+
.gw-mobile-menu__icon svg { width: 16px; height: 16px; }
|
|
1088
|
+
/* a level's last link, to the section's own page: its row opens the level instead of going there */
|
|
1089
|
+
.gw-mobile-menu__all { display: flex; align-items: center; gap: 6px; min-height: 56px; color: var(--gw-accent-strong); font-size: 16px; font-weight: 500; }
|
|
1090
|
+
.gw-mobile-menu__all::after { content: "\2192"; }
|
|
1091
|
+
/* the action bar: what is not a button (Sign in, the language) on the first line, the last one on the right; the
|
|
1092
|
+
buttons side by side under it (gw-btn--lg: 48px, as gemboss.ai) */
|
|
1093
|
+
.gw-mobile-menu[data-gw-menu="drill"] .gw-mobile-menu__actions {
|
|
1094
|
+
position: sticky;
|
|
1095
|
+
bottom: 0;
|
|
1096
|
+
z-index: 1;
|
|
1097
|
+
grid-template-columns: minmax(0, 1fr) minmax(0, 1fr);
|
|
1098
|
+
align-items: center;
|
|
1099
|
+
gap: 8px 16px;
|
|
1100
|
+
margin-top: auto;
|
|
1101
|
+
padding-block: 12px calc(12px + env(safe-area-inset-bottom));
|
|
1102
|
+
border-top: 1px solid var(--gw-line);
|
|
1103
|
+
background: var(--gw-bg);
|
|
1104
|
+
}
|
|
1105
|
+
.gw-mobile-menu[data-gw-menu="drill"] .gw-mobile-menu__actions > .gw-btn { grid-row: 2; }
|
|
1106
|
+
.gw-mobile-menu[data-gw-menu="drill"] .gw-mobile-menu__actions > :not(.gw-btn) { grid-row: 1; }
|
|
1107
|
+
.gw-mobile-menu[data-gw-menu="drill"] .gw-mobile-menu__actions > :not(.gw-btn):last-child { grid-column: 2; justify-self: end; }
|
|
1108
|
+
.gw-mobile-menu[data-gw-menu="drill"] .gw-mobile-menu__actions > .gw-mobile-menu__link { color: var(--gw-ink); font-weight: 500; }
|
|
1109
|
+
|
|
1110
|
+
/* Wired (.is-drill, set by website.js): a group's row points right and opens its level, which shows alone
|
|
1111
|
+
(.is-drilled) under its head: Back on the left, the level's title in the middle. The sheet starts where the header
|
|
1112
|
+
ends (--gw-menu-top, measured by the script) and the header stays in place, so an announcement bar above it does not
|
|
1113
|
+
jump away. */
|
|
1114
|
+
.gw-mobile-menu.is-drill { top: var(--gw-menu-top, calc(var(--gw-header-height) + 1px)); }
|
|
1115
|
+
html.is-menu-open .gw-header:has(> .gw-mobile-menu.is-drill) { position: sticky; }
|
|
1116
|
+
.gw-mobile-menu.is-drill .gw-mobile-menu__group > summary::after { transform: rotate(-90deg); transition: none; }
|
|
1117
|
+
.gw-mobile-menu.is-drilled > nav > :not([open], .gw-mobile-menu__actions),
|
|
1118
|
+
.gw-mobile-menu.is-drilled .gw-mobile-menu__group[open] > summary { display: none; }
|
|
1119
|
+
.gw-mobile-menu__head { display: none; }
|
|
1120
|
+
.gw-mobile-menu.is-drilled .gw-mobile-menu__group[open] > .gw-mobile-menu__head {
|
|
1121
|
+
display: grid;
|
|
1122
|
+
grid-template-columns: minmax(0, 1fr) auto minmax(0, 1fr);
|
|
1123
|
+
align-items: center;
|
|
1124
|
+
gap: 8px;
|
|
1125
|
+
min-height: 56px;
|
|
1126
|
+
margin-bottom: 8px;
|
|
1127
|
+
border-bottom: 1px solid var(--gw-line);
|
|
1128
|
+
}
|
|
1129
|
+
.gw-mobile-menu__back {
|
|
1130
|
+
display: inline-flex;
|
|
1131
|
+
align-items: center;
|
|
1132
|
+
justify-self: start;
|
|
1133
|
+
gap: 4px;
|
|
1134
|
+
min-height: var(--gw-tap-min);
|
|
1135
|
+
padding: 0 8px 0 0;
|
|
1136
|
+
border: 0;
|
|
1137
|
+
background: transparent;
|
|
1138
|
+
color: var(--gw-muted);
|
|
1139
|
+
font-size: 16px;
|
|
1140
|
+
line-height: 1.5;
|
|
1141
|
+
}
|
|
1142
|
+
.gw-mobile-menu__back:hover { color: var(--gw-ink); }
|
|
1143
|
+
.gw-mobile-menu__back::before {
|
|
1144
|
+
content: "";
|
|
1145
|
+
flex: none;
|
|
1146
|
+
width: 16px;
|
|
1147
|
+
height: 16px;
|
|
1148
|
+
background: currentColor;
|
|
1149
|
+
-webkit-mask: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24'%3E%3Cpath d='M15 18l-6-6 6-6' fill='none' stroke='%23000' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'/%3E%3C/svg%3E") center / 16px no-repeat;
|
|
1150
|
+
mask: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24'%3E%3Cpath d='M15 18l-6-6 6-6' fill='none' stroke='%23000' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'/%3E%3C/svg%3E") center / 16px no-repeat;
|
|
1151
|
+
}
|
|
1152
|
+
.gw-mobile-menu__title { color: var(--gw-ink); font-size: 16px; font-weight: 600; letter-spacing: 0; line-height: 1.5; text-align: center; }
|
|
1153
|
+
/* a level slides in from the right, the top level back in from the left; under reduced motion they just switch */
|
|
1154
|
+
@media (prefers-reduced-motion: no-preference) {
|
|
1155
|
+
.gw-mobile-menu.is-drilled .gw-mobile-menu__group[open] { animation: gw-drill-in 0.24s var(--gw-ease); }
|
|
1156
|
+
.gw-mobile-menu.is-back > nav > :not(.gw-mobile-menu__actions) { animation: gw-drill-back 0.24s var(--gw-ease); }
|
|
1157
|
+
}
|
|
1158
|
+
@keyframes gw-drill-in { from { opacity: 0; transform: translateX(32px); } }
|
|
1159
|
+
@keyframes gw-drill-back { from { opacity: 0; transform: translateX(-32px); } }
|
|
1160
|
+
|
|
1161
|
+
/* The language switcher: <div class="gw-lang" data-gw-lang hidden>, a ghost button with the globe and the current
|
|
1162
|
+
language's short code, and its list of the other languages, a small popover card (the card radius of the site's
|
|
1163
|
+
profile, one hairline, the raised shadow). website.js fills the list from the page's <link rel="alternate" hreflang>
|
|
1164
|
+
and takes `hidden` away when there is another language. In the header's actions it shows from 1080px, where the nav
|
|
1165
|
+
is; below that a second one sits in the mobile menu's action bar, and its list opens upward. */
|
|
1166
|
+
.gw-lang { position: relative; flex: none; }
|
|
1167
|
+
.gw-header__actions > .gw-lang { display: none; }
|
|
1168
|
+
.gw-lang__btn {
|
|
1169
|
+
display: inline-flex;
|
|
1170
|
+
align-items: center;
|
|
1171
|
+
gap: 6px;
|
|
1172
|
+
height: 40px;
|
|
1173
|
+
padding: 0 12px;
|
|
1174
|
+
border: 0;
|
|
1175
|
+
border-radius: var(--gw-radius-action);
|
|
1176
|
+
background: transparent;
|
|
1177
|
+
color: var(--gw-ink-2);
|
|
1178
|
+
font-size: 14px;
|
|
1179
|
+
font-weight: 500;
|
|
1180
|
+
line-height: 1.4;
|
|
1181
|
+
white-space: nowrap;
|
|
1182
|
+
}
|
|
1183
|
+
.gw-lang__btn:hover,
|
|
1184
|
+
.gw-lang__btn[aria-expanded="true"] { background: var(--gw-bg-soft); color: var(--gw-ink); }
|
|
1185
|
+
.gw-lang__btn svg { flex: none; width: 18px; height: 18px; }
|
|
1186
|
+
.gw-lang__menu {
|
|
1187
|
+
position: absolute;
|
|
1188
|
+
top: calc(100% + 8px);
|
|
1189
|
+
right: 0;
|
|
1190
|
+
z-index: 1;
|
|
1191
|
+
display: grid;
|
|
1192
|
+
gap: 2px;
|
|
1193
|
+
min-width: 200px;
|
|
1194
|
+
margin: 0;
|
|
1195
|
+
padding: 8px;
|
|
1196
|
+
list-style: none;
|
|
1197
|
+
border: 1px solid var(--gw-line);
|
|
1198
|
+
border-radius: var(--gw-radius-card);
|
|
1199
|
+
background: var(--gw-surface);
|
|
1200
|
+
box-shadow: var(--gw-shadow-raised);
|
|
1201
|
+
}
|
|
1202
|
+
.gw-lang__link {
|
|
1203
|
+
display: flex;
|
|
1204
|
+
align-items: center;
|
|
1205
|
+
min-height: 40px;
|
|
1206
|
+
padding: 0 12px;
|
|
1207
|
+
border-radius: var(--gw-radius-action);
|
|
1208
|
+
color: var(--gw-ink);
|
|
1209
|
+
font-size: 14px;
|
|
1210
|
+
font-weight: 500;
|
|
1211
|
+
white-space: nowrap;
|
|
1212
|
+
}
|
|
1213
|
+
.gw-lang__link:hover { background: var(--gw-bg-soft); }
|
|
1214
|
+
.gw-mobile-menu .gw-lang__btn { padding: 0 8px 0 0; color: var(--gw-muted); font-size: 16px; }
|
|
1215
|
+
.gw-mobile-menu .gw-lang__btn:hover,
|
|
1216
|
+
.gw-mobile-menu .gw-lang__btn[aria-expanded="true"] { background: transparent; color: var(--gw-ink); }
|
|
1217
|
+
.gw-mobile-menu .gw-lang__menu { top: auto; right: auto; bottom: calc(100% + 8px); left: 0; }
|
|
1218
|
+
@media (max-width: 768px), (pointer: coarse) {
|
|
1219
|
+
.gw-lang__btn, .gw-lang__link { min-height: var(--gw-tap-min); }
|
|
1220
|
+
}
|
|
1221
|
+
@media (min-width: 1080px) {
|
|
1222
|
+
.gw-header__actions > .gw-lang { display: block; }
|
|
1223
|
+
}
|
|
1224
|
+
|
|
1042
1225
|
/* footer: brand block, link columns, bottom row. One hairline on top, white like the page. */
|
|
1043
1226
|
.gw-footer {
|
|
1044
1227
|
padding-block: 64px 40px;
|
|
@@ -2053,3 +2236,75 @@ a.gw-rating-badge:hover { border-color: var(--gw-line-strong); }
|
|
|
2053
2236
|
.gw-rating-badge__body { display: grid; gap: 2px; min-width: 0; }
|
|
2054
2237
|
.gw-rating-badge__score { display: flex; align-items: center; gap: 8px; color: var(--gw-ink); font-size: 16px; font-weight: 600; font-variant-numeric: tabular-nums; }
|
|
2055
2238
|
.gw-rating-badge__count { color: var(--gw-muted); }
|
|
2239
|
+
|
|
2240
|
+
/* effects: the spotlight (0.9.0, Chris 25/10/2026, issue #74), a named hover effect for the things you click.
|
|
2241
|
+
data-gw-spot on an <a href>, a <button>, or a card that holds exactly one of them (a plan card, the mega menu's
|
|
2242
|
+
feature card, the primary button of a night band, a .gw-card--link): a soft light in the brand's accent follows the
|
|
2243
|
+
pointer over it. Opt-in per element: a page without the attribute does not change.
|
|
2244
|
+
website.js wires the host (data-gw-ready="spot") and puts .gw-spot on the element that carries the light: the host,
|
|
2245
|
+
or the one its data-gw-spot="<selector>" names inside it. It writes the pointer's place there (--gw-spot-x,
|
|
2246
|
+
--gw-spot-y, trailing it a little every frame); this file draws the light on its ::before, under its words, in its
|
|
2247
|
+
own corners (border-radius: inherit, so the radius profile holds), and grows the light's radius on hover.
|
|
2248
|
+
- Pointer devices only: nothing here applies without (hover: hover) and (pointer: fine).
|
|
2249
|
+
- Keyboard focus (on the host, or on the one action of a card) shows the same light, centred.
|
|
2250
|
+
- Reduced motion: the light stands still, centred, and appears without a transition.
|
|
2251
|
+
- Words under the light: while a thing is lit, its muted words read --gw-ink-2 (the token, set as --gw-muted on the
|
|
2252
|
+
host), so they keep 4.5:1 at the light's middle; they turn back once the light has gone. A colour, no movement.
|
|
2253
|
+
- Without @property or color-mix(), website.js puts .gw-spot nowhere: no light at all, nothing half drawn.
|
|
2254
|
+
- One colour, the accent family, as the page has it (the -dark family in dark mode and in night bands). Never on a
|
|
2255
|
+
heading or running text: a heading stays ink, with no gradient and no accent words (check: spot-target).
|
|
2256
|
+
The radius is the one animated property that is neither transform nor opacity: it repaints one layer of one
|
|
2257
|
+
element. Registered, so it can transition; inherited, so the ::before (and an inner element) reads the host's. */
|
|
2258
|
+
@property --gw-spot-r {
|
|
2259
|
+
syntax: "<length>";
|
|
2260
|
+
inherits: true;
|
|
2261
|
+
initial-value: 0px;
|
|
2262
|
+
}
|
|
2263
|
+
|
|
2264
|
+
@media (hover: hover) and (pointer: fine) {
|
|
2265
|
+
/* the host: no light at rest (a lit card does not light a lit button inside it), the light's size on hover and focus */
|
|
2266
|
+
[data-gw-ready~="spot"] { --gw-spot-r: 0px; }
|
|
2267
|
+
[data-gw-ready~="spot"]:is(:hover, :focus-visible) { --gw-spot-r: var(--gw-spot-radius); --gw-muted: var(--gw-ink-2); }
|
|
2268
|
+
/* a card whose one action has the keyboard focus; a rule of its own, so a browser without :has() drops only it */
|
|
2269
|
+
[data-gw-ready~="spot"]:has(:focus-visible) { --gw-spot-r: var(--gw-spot-radius); --gw-muted: var(--gw-ink-2); }
|
|
2270
|
+
.gw-btn[data-gw-ready~="spot"]:is(:hover, :focus-visible) { --gw-spot-r: var(--gw-spot-radius-action); }
|
|
2271
|
+
|
|
2272
|
+
/* the element that carries the light: positioned for its layer, isolated so the layer sits under its words.
|
|
2273
|
+
:where(), so a site's own position for an inner element wins. */
|
|
2274
|
+
:where(.gw-spot) { position: relative; isolation: isolate; }
|
|
2275
|
+
/* the light. Not on a busy button: its ::before is the ring. */
|
|
2276
|
+
.gw-spot:not([aria-busy="true"])::before {
|
|
2277
|
+
--gw-spot-mix: var(--gw-spot-strength);
|
|
2278
|
+
content: "";
|
|
2279
|
+
position: absolute;
|
|
2280
|
+
inset: 0;
|
|
2281
|
+
z-index: -1;
|
|
2282
|
+
border-radius: inherit;
|
|
2283
|
+
background: radial-gradient(circle var(--gw-spot-r) at var(--gw-spot-x, 50%) var(--gw-spot-y, 50%), color-mix(in srgb, var(--gw-accent) var(--gw-spot-mix), transparent), transparent 70%);
|
|
2284
|
+
pointer-events: none;
|
|
2285
|
+
transition: --gw-spot-r var(--gw-spot-ms) var(--gw-spot-ease);
|
|
2286
|
+
}
|
|
2287
|
+
/* a button is small and filled: a stronger light. Its words keep their contrast: the light is the accent over the
|
|
2288
|
+
button's fill, so under the accent action profile it lies between the accent and the accent-strong, the two fills
|
|
2289
|
+
the build checks the words on. */
|
|
2290
|
+
.gw-btn.gw-spot:not([aria-busy="true"])::before { --gw-spot-mix: var(--gw-spot-strength-action); }
|
|
2291
|
+
/* the mega menu's feature card is the Stage, a night ground: a stronger light, or it would not show */
|
|
2292
|
+
.gw-mega__feature.gw-spot:not([aria-busy="true"])::before { --gw-spot-mix: var(--gw-spot-strength-stage); }
|
|
2293
|
+
|
|
2294
|
+
/* words under the light: lit, muted words are ink-2 at once (rules above); back to muted only once the light has gone
|
|
2295
|
+
out (a colour that waits the light's time, no movement). :where(), so a part's own transition wins. */
|
|
2296
|
+
:where([data-gw-ready~="spot"] *) { transition: color 0s linear var(--gw-spot-ms); }
|
|
2297
|
+
:where([data-gw-ready~="spot"]:is(:hover, :focus-visible) *) { transition-delay: 0s; }
|
|
2298
|
+
:where([data-gw-ready~="spot"]:has(:focus-visible) *) { transition-delay: 0s; }
|
|
2299
|
+
|
|
2300
|
+
/* keyboard focus: the light in the middle, so focus is never weaker than hover */
|
|
2301
|
+
:is([data-gw-ready~="spot"]:focus-visible, [data-gw-ready~="spot"]:focus-visible *).gw-spot::before { --gw-spot-x: 50%; --gw-spot-y: 50%; }
|
|
2302
|
+
:is([data-gw-ready~="spot"]:has(:focus-visible), [data-gw-ready~="spot"]:has(:focus-visible) *).gw-spot::before { --gw-spot-x: 50%; --gw-spot-y: 50%; }
|
|
2303
|
+
}
|
|
2304
|
+
|
|
2305
|
+
/* reduced motion: a still light in the middle, there at once and gone at once, the words with it (website.js follows
|
|
2306
|
+
no pointer then) */
|
|
2307
|
+
@media (hover: hover) and (pointer: fine) and (prefers-reduced-motion: reduce) {
|
|
2308
|
+
.gw-spot:not([aria-busy="true"])::before { --gw-spot-x: 50%; --gw-spot-y: 50%; transition: none; }
|
|
2309
|
+
:where([data-gw-ready~="spot"] *) { transition: none; }
|
|
2310
|
+
}
|