openvibers/openvibe.shared Commits
The motion tokens on every page; Reduced motion reaches every token-timed transition (4.82.0) (#235)
Changes
@@@ -4,6 +4,20 @@ All notable changes to `openvibe-shared`. Versions follow [semver](https://semvebreaking change to any exported module, browser global or served file name is a new major.A release is the git tag `vX.Y.Z`; consumers pin the tag's tarball (see README).++## 4.82.0 — 2026-11-01++++- **The motion tokens are on every page, and Reduced motion reaches every token-timed transition** (plan L45).++ - Before this release, `--ov-dur-1..4` and `--ov-ease-out`/`-spring`/`-in-out` were set only by `ov-fx.js`, which++ loads on pages with effects. Everywhere else a site's `var(--ov-dur-2, .2s)` got its fallback, so the person's++ Reduced setting could not reach it.++ - `kit.css` now sets the same tokens, with the same values, and the same feels: calm looks are slower and never++ overshoot, loud ones are quicker.++ - `html[data-ov-motion=reduced]` sets every duration to 0, and so does a device that asks for reduced motion++ (`:root:root`, above `ov-fx.js`'s own `:root`).++ - A site that writes its transitions with the tokens now follows the look and the person's choice. The design lint++ (openvibe.report/design) counts hand-set timings.++ - `room.css` carries the same tokens.++## 4.81.0 — 2026-11-01- **Shape and elevation are tokens, and a look has a shape** (plan L45 step 2: "Paper is quiet and square, Neon glows@@@ -2,7 +2,7 @@> Versioned UI, the OpenVibe Frame (the navbar, footer and "shipped" views every site sits in), SEO, legal and release-client packages every OpenVibe site renders.--**Status:** alpha, v4.81.0 (every release is a tag; see [CHANGELOG.md](CHANGELOG.md)). Every deployed++**Status:** alpha, v4.82.0 (every release is a tag; see [CHANGELOG.md](CHANGELOG.md)). Every deployedconsumer installs a tagged release and none keeps a vendored copy([docs/migration-plan.md](docs/migration-plan.md) is done); each repository's `package.json` namesthe tag it pins.@@@ -4,7 +4,7 @@"code": true,"wave": "W2","package": "openvibe-shared",-- "version": "4.81.0",++ "version": "4.82.0","plan": "OpenVibe End-to-End Realignment & Implementation Plan, revision 3 (20 Sep 2026)","deployed": false,"deployment": "none of its own: a package released as git tags; OpenVibe.Network serves /shared/* from its pinned tag, and a site can serve its own pinned copy (openvibe-shared/serve)",@@@ -33,6 +33,15 @@--ov-elev-1: 0 1px 3px rgba(0, 0, 0, .35); /* a knob, a chip that sits on its surface */--ov-elev-2: 0 10px 24px -18px rgba(0, 0, 0, .7); /* a bar that has scrolled content under it */--ov-elev-3: 0 14px 32px rgba(0, 0, 0, .4); /* a menu or popover above the page */++ /* Motion (4.82.0): the same tokens ov-fx.js has always set, here so every page's var(--ov-dur-*) resolves and the++ * person's Reduced motion reaches every transition that uses them, not only pages with effects. */++ --ov-dur-1: .12s;++ --ov-dur-2: .2s;++ --ov-dur-3: .32s;++ --ov-dur-4: .52s;++ --ov-ease-out: cubic-bezier(.2, .8, .2, 1);++ --ov-ease-spring: cubic-bezier(.34, 1.56, .64, 1);++ --ov-ease-in-out: cubic-bezier(.65, 0, .35, 1);--ovk-radius: var(--ov-radius-2);--ovk-radius-sm: var(--ov-radius-1);--ovk-tap: 44px;@@@ -41,6 +50,17 @@--ovk-font: var(--ov-font, 'Inter', -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, 'Helvetica Neue', Arial, sans-serif);}++/* Motion feels, as ov-fx.js sets them: the calm looks are slower and never overshoot, the loud ones quicker; the++ * person's Reduced motion, or a device that asks for less, stops every token-timed transition. */++:is([data-theme=paper], [data-theme=daylight], [data-theme=cloud], [data-theme=snow], [data-theme=sand], [data-theme=rose], [data-theme=meadow], [data-theme=peach], [data-theme=lavender], [data-theme=dawn], [data-theme=solarized-light], [data-theme=catppuccin-latte], [data-theme=nord], [data-theme=nord-light]) {++ --ov-dur-1: .15s; --ov-dur-2: .25s; --ov-dur-3: .4s; --ov-dur-4: .62s; --ov-ease-spring: var(--ov-ease-out);++}++:is([data-theme=neon-tokyo], [data-theme=vapor], [data-theme=matrix], [data-theme=hacker], [data-theme=high-contrast], [data-theme=dracula], [data-theme=monokai], [data-theme=abyss]) {++ --ov-dur-1: .09s; --ov-dur-2: .15s; --ov-dur-3: .24s; --ov-dur-4: .42s; --ov-ease-spring: cubic-bezier(.3, 1.8, .6, 1);++}++html[data-ov-motion=reduced] { --ov-dur-1: 0s; --ov-dur-2: 0s; --ov-dur-3: 0s; --ov-dur-4: 0s; }++/* :root:root outranks ov-fx.js's own :root and theme feels, which load later. */++@media (prefers-reduced-motion: reduce) { :root:root { --ov-dur-1: 0s; --ov-dur-2: 0s; --ov-dur-3: 0s; --ov-dur-4: 0s; } }/* Shape personalities (plan L45: "Paper is quiet and square, Neon glows and bounces"). A quiet look has square corners* and lies flat, with a hairline where a shadow would be; a loud one is round and its raised things glow in its accent.* The ids are Network's theme catalog (as ov-fx.js's motion feels); any other look keeps the defaults above. */@@@ -1,6 +1,6 @@{"name": "openvibe-shared",-- "version": "4.81.0",++ "version": "4.82.0","description": "Shared navbar, footer, themes, icons, legal pages, SEO, auth and analytics for every OpenVibe site","main": "index.js","bin": {@@@ -30,6 +30,15 @@--ov-elev-1: 0 1px 3px rgba(0, 0, 0, .35); /* a knob, a chip that sits on its surface */--ov-elev-2: 0 10px 24px -18px rgba(0, 0, 0, .7); /* a bar that has scrolled content under it */--ov-elev-3: 0 14px 32px rgba(0, 0, 0, .4); /* a menu or popover above the page */++ /* Motion (4.82.0): the same tokens ov-fx.js has always set, here so every page's var(--ov-dur-*) resolves and the++ * person's Reduced motion reaches every transition that uses them, not only pages with effects. */++ --ov-dur-1: .12s;++ --ov-dur-2: .2s;++ --ov-dur-3: .32s;++ --ov-dur-4: .52s;++ --ov-ease-out: cubic-bezier(.2, .8, .2, 1);++ --ov-ease-spring: cubic-bezier(.34, 1.56, .64, 1);++ --ov-ease-in-out: cubic-bezier(.65, 0, .35, 1);--ovk-radius: var(--ov-radius-2);--ovk-radius-sm: var(--ov-radius-1);--ovk-tap: 44px;@@@ -26,4 +26,11 @@ assert.match(kit, /:is\(\[data-theme=neon-tokyo\][^{]*\) \{\s*--ov-radius-1: 14passert.match(kit, /--ov-elev-3: 0 0 0 1px color-mix\(in srgb, var\(--ovk-accent\)/, 'and Neon\'s raised things glow in its accent');assert.match(room, /:where\(\[data-theme=paper\][^{]*\) \{\s*--ov-radius-1: 4px;/, 'room.css: the same personalities at zero specificity');assert.match(room, /:where\(\[data-theme=neon-tokyo\][^{]*\) \{\s*--ov-radius-1: 14px;/);--console.log('kit-shape: tokens, the kit on them, and the personalities');++// Motion (4.82.0): ov-fx.js's tokens, in kit.css too, so var(--ov-dur-*) resolves on every page and Reduced reaches it.++assert.ok(kit.includes('--ov-dur-1: .12s;') && kit.includes('--ov-dur-4: .52s;') && kit.includes('--ov-ease-out: cubic-bezier(.2, .8, .2, 1);'), 'the motion tokens, as ov-fx.js sets them');++assert.match(kit, /html\[data-ov-motion=reduced\] \{ --ov-dur-1: 0s;/, 'Reduced motion stops them');++assert.match(kit, /@media \(prefers-reduced-motion: reduce\) \{ :root:root \{ --ov-dur-1: 0s;/, 'and so does a device that asks for less, over ov-fx.js\'s own :root');++assert.match(kit, /:is\(\[data-theme=paper\][^{]*\) \{\s*--ov-dur-1: \.15s;/, 'Paper is calm');++const fx = fs.readFileSync(path.join(__dirname, '..', 'ov-fx.js'), 'utf8');++assert.ok(fx.includes('--ov-dur-1:.12s;--ov-dur-2:.2s;--ov-dur-3:.32s;--ov-dur-4:.52s'), 'the same values as ov-fx.js');++console.log('kit-shape: tokens, the kit on them, the personalities and the motion');
@@ -4,6 +4,20 @@ All notable changes to `openvibe-shared`. Versions follow [semver](https://semve
@@ -4,6 +4,20 @@ All notable changes to `openvibe-shared`. Versions follow [semver](https://semve
breaking change to any exported module, browser global or served file name is a new major.
breaking change to any exported module, browser global or served file name is a new major.
A release is the git tag `vX.Y.Z`; consumers pin the tag's tarball (see README).
A release is the git tag `vX.Y.Z`; consumers pin the tag's tarball (see README).
+## 4.82.0 — 2026-11-01
+
+- **The motion tokens are on every page, and Reduced motion reaches every token-timed transition** (plan L45).
+ - Before this release, `--ov-dur-1..4` and `--ov-ease-out`/`-spring`/`-in-out` were set only by `ov-fx.js`, which
+ loads on pages with effects. Everywhere else a site's `var(--ov-dur-2, .2s)` got its fallback, so the person's
+ Reduced setting could not reach it.
+ - `kit.css` now sets the same tokens, with the same values, and the same feels: calm looks are slower and never
+ overshoot, loud ones are quicker.
+ - `html[data-ov-motion=reduced]` sets every duration to 0, and so does a device that asks for reduced motion
+ (`:root:root`, above `ov-fx.js`'s own `:root`).
+ - A site that writes its transitions with the tokens now follows the look and the person's choice. The design lint
+ (openvibe.report/design) counts hand-set timings.
+ - `room.css` carries the same tokens.
+
## 4.81.0 — 2026-11-01
## 4.81.0 — 2026-11-01
- **Shape and elevation are tokens, and a look has a shape** (plan L45 step 2: "Paper is quiet and square, Neon glows
- **Shape and elevation are tokens, and a look has a shape** (plan L45 step 2: "Paper is quiet and square, Neon glows
@@ -2,7 +2,7 @@
@@ -2,7 +2,7 @@
> Versioned UI, the OpenVibe Frame (the navbar, footer and "shipped" views every site sits in), SEO, legal and release-client packages every OpenVibe site renders.
> Versioned UI, the OpenVibe Frame (the navbar, footer and "shipped" views every site sits in), SEO, legal and release-client packages every OpenVibe site renders.
-**Status:** alpha, v4.81.0 (every release is a tag; see [CHANGELOG.md](CHANGELOG.md)). Every deployed
+**Status:** alpha, v4.82.0 (every release is a tag; see [CHANGELOG.md](CHANGELOG.md)). Every deployed
consumer installs a tagged release and none keeps a vendored copy
consumer installs a tagged release and none keeps a vendored copy
([docs/migration-plan.md](docs/migration-plan.md) is done); each repository's `package.json` names
([docs/migration-plan.md](docs/migration-plan.md) is done); each repository's `package.json` names
the tag it pins.
the tag it pins.
@@ -4,7 +4,7 @@
@@ -4,7 +4,7 @@
"code": true,
"code": true,
"wave": "W2",
"wave": "W2",
"package": "openvibe-shared",
"package": "openvibe-shared",
- "version": "4.81.0",
+ "version": "4.82.0",
"plan": "OpenVibe End-to-End Realignment & Implementation Plan, revision 3 (20 Sep 2026)",
"plan": "OpenVibe End-to-End Realignment & Implementation Plan, revision 3 (20 Sep 2026)",
"deployed": false,
"deployed": false,
"deployment": "none of its own: a package released as git tags; OpenVibe.Network serves /shared/* from its pinned tag, and a site can serve its own pinned copy (openvibe-shared/serve)",
"deployment": "none of its own: a package released as git tags; OpenVibe.Network serves /shared/* from its pinned tag, and a site can serve its own pinned copy (openvibe-shared/serve)",
@@ -33,6 +33,15 @@
@@ -33,6 +33,15 @@
--ov-elev-1: 0 1px 3px rgba(0, 0, 0, .35); /* a knob, a chip that sits on its surface */
--ov-elev-1: 0 1px 3px rgba(0, 0, 0, .35); /* a knob, a chip that sits on its surface */
--ov-elev-2: 0 10px 24px -18px rgba(0, 0, 0, .7); /* a bar that has scrolled content under it */
--ov-elev-2: 0 10px 24px -18px rgba(0, 0, 0, .7); /* a bar that has scrolled content under it */
--ov-elev-3: 0 14px 32px rgba(0, 0, 0, .4); /* a menu or popover above the page */
--ov-elev-3: 0 14px 32px rgba(0, 0, 0, .4); /* a menu or popover above the page */
+ /* Motion (4.82.0): the same tokens ov-fx.js has always set, here so every page's var(--ov-dur-*) resolves and the
+ * person's Reduced motion reaches every transition that uses them, not only pages with effects. */
+ --ov-dur-1: .12s;
+ --ov-dur-2: .2s;
+ --ov-dur-3: .32s;
+ --ov-dur-4: .52s;
+ --ov-ease-out: cubic-bezier(.2, .8, .2, 1);
+ --ov-ease-spring: cubic-bezier(.34, 1.56, .64, 1);
+ --ov-ease-in-out: cubic-bezier(.65, 0, .35, 1);
--ovk-radius: var(--ov-radius-2);
--ovk-radius: var(--ov-radius-2);
--ovk-radius-sm: var(--ov-radius-1);
--ovk-radius-sm: var(--ov-radius-1);
--ovk-tap: 44px;
--ovk-tap: 44px;
@@ -41,6 +50,17 @@
@@ -41,6 +50,17 @@
--ovk-font: var(--ov-font, 'Inter', -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, 'Helvetica Neue', Arial, sans-serif);
--ovk-font: var(--ov-font, 'Inter', -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, 'Helvetica Neue', Arial, sans-serif);
}
}
+/* Motion feels, as ov-fx.js sets them: the calm looks are slower and never overshoot, the loud ones quicker; the
+ * person's Reduced motion, or a device that asks for less, stops every token-timed transition. */
+:is([data-theme=paper], [data-theme=daylight], [data-theme=cloud], [data-theme=snow], [data-theme=sand], [data-theme=rose], [data-theme=meadow], [data-theme=peach], [data-theme=lavender], [data-theme=dawn], [data-theme=solarized-light], [data-theme=catppuccin-latte], [data-theme=nord], [data-theme=nord-light]) {
+ --ov-dur-1: .15s; --ov-dur-2: .25s; --ov-dur-3: .4s; --ov-dur-4: .62s; --ov-ease-spring: var(--ov-ease-out);
+}
+:is([data-theme=neon-tokyo], [data-theme=vapor], [data-theme=matrix], [data-theme=hacker], [data-theme=high-contrast], [data-theme=dracula], [data-theme=monokai], [data-theme=abyss]) {
+ --ov-dur-1: .09s; --ov-dur-2: .15s; --ov-dur-3: .24s; --ov-dur-4: .42s; --ov-ease-spring: cubic-bezier(.3, 1.8, .6, 1);
+}
+html[data-ov-motion=reduced] { --ov-dur-1: 0s; --ov-dur-2: 0s; --ov-dur-3: 0s; --ov-dur-4: 0s; }
+/* :root:root outranks ov-fx.js's own :root and theme feels, which load later. */
+@media (prefers-reduced-motion: reduce) { :root:root { --ov-dur-1: 0s; --ov-dur-2: 0s; --ov-dur-3: 0s; --ov-dur-4: 0s; } }
/* Shape personalities (plan L45: "Paper is quiet and square, Neon glows and bounces"). A quiet look has square corners
/* Shape personalities (plan L45: "Paper is quiet and square, Neon glows and bounces"). A quiet look has square corners
* and lies flat, with a hairline where a shadow would be; a loud one is round and its raised things glow in its accent.
* and lies flat, with a hairline where a shadow would be; a loud one is round and its raised things glow in its accent.
* The ids are Network's theme catalog (as ov-fx.js's motion feels); any other look keeps the defaults above. */
* The ids are Network's theme catalog (as ov-fx.js's motion feels); any other look keeps the defaults above. */
@@ -1,6 +1,6 @@
@@ -1,6 +1,6 @@
{
{
"name": "openvibe-shared",
"name": "openvibe-shared",
- "version": "4.81.0",
+ "version": "4.82.0",
"description": "Shared navbar, footer, themes, icons, legal pages, SEO, auth and analytics for every OpenVibe site",
"description": "Shared navbar, footer, themes, icons, legal pages, SEO, auth and analytics for every OpenVibe site",
"main": "index.js",
"main": "index.js",
"bin": {
"bin": {
@@ -30,6 +30,15 @@
@@ -30,6 +30,15 @@
--ov-elev-1: 0 1px 3px rgba(0, 0, 0, .35); /* a knob, a chip that sits on its surface */
--ov-elev-1: 0 1px 3px rgba(0, 0, 0, .35); /* a knob, a chip that sits on its surface */
--ov-elev-2: 0 10px 24px -18px rgba(0, 0, 0, .7); /* a bar that has scrolled content under it */
--ov-elev-2: 0 10px 24px -18px rgba(0, 0, 0, .7); /* a bar that has scrolled content under it */
--ov-elev-3: 0 14px 32px rgba(0, 0, 0, .4); /* a menu or popover above the page */
--ov-elev-3: 0 14px 32px rgba(0, 0, 0, .4); /* a menu or popover above the page */
+ /* Motion (4.82.0): the same tokens ov-fx.js has always set, here so every page's var(--ov-dur-*) resolves and the
+ * person's Reduced motion reaches every transition that uses them, not only pages with effects. */
+ --ov-dur-1: .12s;
+ --ov-dur-2: .2s;
+ --ov-dur-3: .32s;
+ --ov-dur-4: .52s;
+ --ov-ease-out: cubic-bezier(.2, .8, .2, 1);
+ --ov-ease-spring: cubic-bezier(.34, 1.56, .64, 1);
+ --ov-ease-in-out: cubic-bezier(.65, 0, .35, 1);
--ovk-radius: var(--ov-radius-2);
--ovk-radius: var(--ov-radius-2);
--ovk-radius-sm: var(--ov-radius-1);
--ovk-radius-sm: var(--ov-radius-1);
--ovk-tap: 44px;
--ovk-tap: 44px;
@@ -26,4 +26,11 @@ assert.match(kit, /:is\(\[data-theme=neon-tokyo\][^{]*\) \{\s*--ov-radius-1: 14p
@@ -26,4 +26,11 @@ assert.match(kit, /:is\(\[data-theme=neon-tokyo\][^{]*\) \{\s*--ov-radius-1: 14p
assert.match(kit, /--ov-elev-3: 0 0 0 1px color-mix\(in srgb, var\(--ovk-accent\)/, 'and Neon\'s raised things glow in its accent');
assert.match(kit, /--ov-elev-3: 0 0 0 1px color-mix\(in srgb, var\(--ovk-accent\)/, 'and Neon\'s raised things glow in its accent');
assert.match(room, /:where\(\[data-theme=paper\][^{]*\) \{\s*--ov-radius-1: 4px;/, 'room.css: the same personalities at zero specificity');
assert.match(room, /:where\(\[data-theme=paper\][^{]*\) \{\s*--ov-radius-1: 4px;/, 'room.css: the same personalities at zero specificity');
assert.match(room, /:where\(\[data-theme=neon-tokyo\][^{]*\) \{\s*--ov-radius-1: 14px;/);
assert.match(room, /:where\(\[data-theme=neon-tokyo\][^{]*\) \{\s*--ov-radius-1: 14px;/);
-console.log('kit-shape: tokens, the kit on them, and the personalities');
+// Motion (4.82.0): ov-fx.js's tokens, in kit.css too, so var(--ov-dur-*) resolves on every page and Reduced reaches it.
+assert.ok(kit.includes('--ov-dur-1: .12s;') && kit.includes('--ov-dur-4: .52s;') && kit.includes('--ov-ease-out: cubic-bezier(.2, .8, .2, 1);'), 'the motion tokens, as ov-fx.js sets them');
+assert.match(kit, /html\[data-ov-motion=reduced\] \{ --ov-dur-1: 0s;/, 'Reduced motion stops them');
+assert.match(kit, /@media \(prefers-reduced-motion: reduce\) \{ :root:root \{ --ov-dur-1: 0s;/, 'and so does a device that asks for less, over ov-fx.js\'s own :root');
+assert.match(kit, /:is\(\[data-theme=paper\][^{]*\) \{\s*--ov-dur-1: \.15s;/, 'Paper is calm');
+const fx = fs.readFileSync(path.join(__dirname, '..', 'ov-fx.js'), 'utf8');
+assert.ok(fx.includes('--ov-dur-1:.12s;--ov-dur-2:.2s;--ov-dur-3:.32s;--ov-dur-4:.52s'), 'the same values as ov-fx.js');
+console.log('kit-shape: tokens, the kit on them, the personalities and the motion');