openvibers/openvibe.shared Commits

Shared 1.28.1: the account panel's sections keep their height (the accounts block no longer collapses into a sliver with its own scrollbar on phones) and its rows match the menu rows; the OpenVibe.Codes mark at rest shows its V (the looping draw animation was paused at its first, undrawn frame); phones no longer reserve 84-96 px of empty space under the footer (--ov-footer-clearance opts in). npm test 41/41.

OP OpenVibers committed 28 Sept 2026 · 8c5df1b1e1 · 7 files, +25 −13


Changes

ddiff --git a/CHANGELOG.md b/CHANGELOG.md
iindex cd237a4..c8f40bd 100644
---- a/CHANGELOG.md
++++ b/CHANGELOG.md
@@@ -4,6 +4,13 @@ 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.
A release is the git tag `vX.Y.Z`; consumers pin the tag's tarball (see README).
++## 1.28.1 — 2026-09-28
++
++Fixes the owner reported from phones.
++- **Account panel:** the panel scrolls as a whole and its sections keep their height. The panel is a flex column, which let its sections shrink, so on a height-limited phone screen the accounts block ("Switch to Anonymous", "Add another account") collapsed into a sliver with its own scrollbar. The account rows now have the menu rows' size, weight and icon width.
++- **OpenVibe.Codes mark:** a mark at rest (every page after the first of a visit) paused the codes variant's looping V animation at its first frame, where the V is not drawn yet, so the logo showed only the ring and the dot. At rest the V is now fully drawn.
++- **Footer:** phones no longer reserve 84–96 px of empty space under the footer. A page with a fixed bottom bar sets `--ov-footer-clearance` to its height; the default is none.
++
## 1.28.0 — 2026-09-28
**`openvibe-shared/config` on PostgreSQL** (ADR-035: Media, Network and Live keep their configuration here). Given an openvibe-sdk/db handle, `createConfigStore` uses the new `config-pg.js`, which is the same store on the async handle. Revisions are immutable, activation is atomic, the last-known-good revision is restored when `onActivate` fails, secret values are redacted with a per-namespace fingerprint key, legacy values are imported, and so on. On this path `createConfigStore` returns a promise of the store: it has read, restored or seeded its active revision when the promise resolves. `get()` and `revision()` stay in memory. The other methods are async. The tables come from the service's migrations: `configSchema()` is their DDL, the SQLite schema converted. `adminRoutes` awaits either kind of store. The better-sqlite3 path is unchanged. `test/config-pg.test.js` runs every scenario of `test/config.test.js` on PGlite (openvibe-sdk v0.20.4, which returns `bytea` as a Buffer, is a dev dependency).
ddiff --git a/STATUS.json b/STATUS.json
iindex 9a4f610..9f95d4e 100644
---- a/STATUS.json
++++ b/STATUS.json
@@@ -4,7 +4,7 @@
"code": true,
"wave": "W2",
"package": "openvibe-shared",
-- "version": "1.28.0",
++ "version": "1.28.1",
"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)",
ddiff --git a/footer.js b/footer.js
iindex 3ac3d20..9c2d4ee 100644
---- a/footer.js
++++ b/footer.js
@@@ -364,8 +364,8 @@
.ovf-compact-meta{color:var(--text-muted,#8b93ad);font-size:.74rem}
@media (max-width:900px){.ovf-cols{grid-template-columns:repeat(2,minmax(0,1fr))}.ovf-col--brand{grid-column:1/-1}}
@media (max-width:560px){
-- .ovf{padding-bottom:calc(96px + env(safe-area-inset-bottom,0px))}
-- .ovf[data-variant="compact"]{padding-bottom:calc(84px + env(safe-area-inset-bottom,0px))}
++ .ovf{padding-bottom:calc(20px + var(--ov-footer-clearance,0px) + env(safe-area-inset-bottom,0px))}
++ .ovf[data-variant="compact"]{padding-bottom:calc(14px + var(--ov-footer-clearance,0px) + env(safe-area-inset-bottom,0px))}
.ovf-cols{gap:22px 16px}
.ovf-bar{justify-content:center;text-align:center;padding-inline:0}
.ovf-legal-inline{justify-content:center}
ddiff --git a/navbar.js b/navbar.js
iindex 7de301b..50e0f49 100644
---- a/navbar.js
++++ b/navbar.js
@@@ -236,6 +236,10 @@
animation: openvibe-slide-down .2s ease;
}
.openvibe-navbar-dropdown.open { display: flex; }
++ /* The panel scrolls as a whole; its sections keep their height. A flex column lets children shrink by
++ default, which squeezed the accounts block into a sliver with its own scrollbar when the panel was
++ height-limited (phones). */
++ .openvibe-navbar-dropdown > * { flex-shrink: 0; }
/* Panels never leave the screen: dvh is the VISIBLE height on phones (100vh reaches behind the address
bar), the panel scrolls inside itself, and it is never wider than the viewport. */
.openvibe-navbar-dropdown, .ovnav-launcher {
@@@ -260,15 +264,15 @@
max-height: 140px; overflow-y: auto;
}
.openvibe-navbar-dropdown-accounts .account-item {
-- display: flex; align-items: center; gap: 8px; padding: 6px 8px;
-- border-radius: 6px; cursor: pointer; font-size: 12px;
-- color: var(--text-secondary, #b0b0b8); transition: background .12s;
++ display: flex; align-items: center; gap: 8px; padding: 8px;
++ border-radius: 6px; cursor: pointer; font-size: 12px; font-weight: 500;
++ color: var(--text-primary, #e0e0e0); transition: background .12s;
}
.openvibe-navbar-dropdown-accounts .account-item:hover { background: var(--bg-hover, #2f2f3d); }
.openvibe-navbar-dropdown-accounts .account-item img { width: 24px; height: 24px; border-radius: 50%; }
.openvibe-navbar-dropdown-accounts .account-item.active { color: var(--accent-light, #60a5fa); font-weight: 600; }
.openvibe-navbar-dropdown-accounts .add-account {
-- display: flex; align-items: center; gap: 8px; padding: 6px 8px;
++ display: flex; align-items: center; gap: 8px; padding: 8px;
border-radius: 6px; cursor: pointer; font-size: 12px;
color: var(--text-muted, #707080); transition: background .12s;
text-decoration: none;
@@@ -1405,11 +1409,11 @@
</div>
`).join('')}
<div class="account-item" data-account-id="anon" style="${isAnon ? 'display:none' : ''}">
-- <span style="width:24px;text-align:center">${navIcon('fa-user-secret')}</span>
++ <span style="width:18px;text-align:center">${navIcon('fa-user-secret')}</span>
<span>Switch to Anonymous</span>
</div>
<a class="add-account" id="openvibe-add-account" href="${escapeAttr(addAccountHref)}">
-- <span style="width:24px;text-align:center">${navIcon('fa-plus')}</span>
++ <span style="width:18px;text-align:center">${navIcon('fa-plus')}</span>
<span>Add another account</span>
</a>
</div>
ddiff --git a/ov-mark.js b/ov-mark.js
iindex 1cb2e62..e3ac07f 100644
---- a/ov-mark.js
++++ b/ov-mark.js
@@@ -58,7 +58,8 @@
.ov-mark:hover .c{animation-duration:.9s}
.ov-mark[data-static] svg,.ov-mark[data-static] .g,.ov-mark[data-static] .c,.ov-mark[data-static] .v,.ov-mark[data-static] .d{animation:none!important}
.ov-mark[data-static] .o{display:none}
--.ov-mark[data-ov]:not([data-ovm-run]) svg,.ov-mark[data-ov]:not([data-ovm-run]) .g,.ov-mark[data-ov]:not([data-ovm-run]) .c,.ov-mark[data-ov]:not([data-ovm-run]) .d,.ov-mark[data-ov][data-variant=codes]:not([data-ovm-run]) .v{animation-play-state:paused!important}
++.ov-mark[data-ov]:not([data-ovm-run]) svg,.ov-mark[data-ov]:not([data-ovm-run]) .g,.ov-mark[data-ov]:not([data-ovm-run]) .c,.ov-mark[data-ov]:not([data-ovm-run]) .d{animation-play-state:paused!important}
++.ov-mark[data-ov][data-variant=codes]:not([data-ovm-run]) .v{animation:none!important;stroke-dashoffset:0}
.ov-mark .p{fill:none;stroke:currentColor;stroke-width:4.4;stroke-linecap:round;transform:rotate(-90deg);transform-box:fill-box;transform-origin:center;stroke-dasharray:113.1;stroke-dashoffset:calc(113.1px * (1 - var(--ovm-p,0)));opacity:0;transition:stroke-dashoffset .35s cubic-bezier(.2,.8,.2,1),opacity .2s}
.ov-mark[data-progress] .p{opacity:1}
.ov-mark[data-progress] .c,.ov-mark[data-progress] .o{opacity:.25}
ddiff --git a/package-lock.json b/package-lock.json
iindex a03e1a4..fc8b7c0 100644
---- a/package-lock.json
++++ b/package-lock.json
@@@ -1,12 +1,12 @@
{
"name": "openvibe-shared",
-- "version": "1.28.0",
++ "version": "1.28.1",
"lockfileVersion": 3,
"requires": true,
"packages": {
"": {
"name": "openvibe-shared",
-- "version": "1.28.0",
++ "version": "1.28.1",
"license": "MIT",
"dependencies": {
"jsonwebtoken": "^9.0.0"
ddiff --git a/package.json b/package.json
iindex 38fb791..20e4022 100644
---- a/package.json
++++ b/package.json
@@@ -1,6 +1,6 @@
{
"name": "openvibe-shared",
-- "version": "1.28.0",
++ "version": "1.28.1",
"description": "Shared navbar, footer, themes, icons, legal pages, SEO, auth and analytics for every OpenVibe site",
"main": "index.js",
"exports": {