openvibers/openvibe.live Commits

Live: the navbar is transparent over the home hero at the top and fades into its glass bar as you scroll; openvibe-shared v2.15.0. (#52)

OP OpenVibers committed 8 Oct 2026 · a1aa23566f · 6 files, +21 −30

Live toggled .nav-hero-top itself on route changes and scroll, but the shared navbar renders after the route on a
fresh load and re-renders after sign-in, so the class was missing and the bar stayed solid at the top. Shared 2.15.0
keeps the at-the-top state (.ovnav-top) on every render and scroll and draws the hero scrim; Live now only marks the
home route with body.ov-nav-overlay. Live's own scroll listener goes.


Claude-Session: https://claude.ai/code/session_01K8AYn3FF3HE7CPfM262qdh

Co-authored-by: Claude Opus 5.5 <[email protected]>

Changes

ddiff --git a/README.md b/README.md
iindex af768edb..4bfaf54d 100644
---- a/README.md
++++ b/README.md
@@@ -173,5 +173,5 @@ Minimum `.env`: `BASE_URL`, `JWT_SECRET`, `OV_NETWORK_URL`, `OV_NETWORK_INTERNAL
<!-- versions:start -->
- openvibe-contracts: v0.112.0
- openvibe-sdk: v0.35.0
--- openvibe-shared: v2.13.3
++- openvibe-shared: v2.15.0
<!-- versions:end -->
ddiff --git a/STATUS.json b/STATUS.json
iindex 24e2c033..976f5085 100644
---- a/STATUS.json
++++ b/STATUS.json
@@@ -7,7 +7,7 @@
"domain": "openvibe.live (www, ingest, whip)",
"contracts": "openvibe-contracts v0.112.0",
"sdk": "openvibe-sdk v0.35.0",
-- "shared": "openvibe-shared v2.13.3",
++ "shared": "openvibe-shared v2.15.0",
"capabilities": [
"live.chat_context.read",
"live.chat_effects.write",
ddiff --git a/package-lock.json b/package-lock.json
iindex 323d2eac..dc575640 100644
---- a/package-lock.json
++++ b/package-lock.json
@@@ -26,7 +26,7 @@
"onnxruntime-node": "^1.20.0",
"openvibe-contracts": "https://codeload.github.com/OpenVibers/OpenVibe.Contracts/tar.gz/refs/tags/v0.112.0",
"openvibe-sdk": "https://codeload.github.com/OpenVibers/OpenVibe.SDK/tar.gz/refs/tags/v0.35.1",
-- "openvibe-shared": "https://codeload.github.com/OpenVibers/OpenVibe.Shared/tar.gz/refs/tags/v2.13.3",
++ "openvibe-shared": "https://codeload.github.com/OpenVibers/OpenVibe.Shared/tar.gz/refs/tags/v2.15.0",
"pg": "^8.23.1",
"sanitize-html": "^2.17.7",
"sdp-transform": "^3.0.0",
@@@ -2888,9 +2888,9 @@
}
},
"node_modules/openvibe-shared": {
-- "version": "2.13.3",
-- "resolved": "https://codeload.github.com/OpenVibers/OpenVibe.Shared/tar.gz/refs/tags/v2.13.3",
-- "integrity": "sha512-pKRAMWWh5iJJwgOY3Hr0N+6yRa0j7FASDozeVz9LBxsJ65gMLXXHfdhrWpGuke42tzRt/234ATHk9vQdTmWNNA==",
++ "version": "2.15.0",
++ "resolved": "https://codeload.github.com/OpenVibers/OpenVibe.Shared/tar.gz/refs/tags/v2.15.0",
++ "integrity": "sha512-xApTyiUBVDQLTdnKEjjr/9uUU4+T5gofz9DqXv0MrLVINmW88uwbfoEht3kAlG9mp1792U6kIFEblJDHn2wyMQ==",
"license": "MIT",
"dependencies": {
"jsonwebtoken": "^9.0.0"
ddiff --git a/package.json b/package.json
iindex 22ef1e10..b9a81f81 100644
---- a/package.json
++++ b/package.json
@@@ -1,7 +1,7 @@
{
"name": "live",
"version": "1.0.0",
-- "description": "OpenVibe.Live \u2014 free & open live streaming. Part of the OpenVibe network (media by OpenVibe.Media, identity by OpenVibe.Network).",
++ "description": "OpenVibe.Live — free & open live streaming. Part of the OpenVibe network (media by OpenVibe.Media, identity by OpenVibe.Network).",
"main": "server/index.js",
"scripts": {
"start": "node server/index.js",
@@@ -44,7 +44,7 @@
"onnxruntime-node": "^1.20.0",
"openvibe-contracts": "https://codeload.github.com/OpenVibers/OpenVibe.Contracts/tar.gz/refs/tags/v0.112.0",
"openvibe-sdk": "https://codeload.github.com/OpenVibers/OpenVibe.SDK/tar.gz/refs/tags/v0.35.1",
-- "openvibe-shared": "https://codeload.github.com/OpenVibers/OpenVibe.Shared/tar.gz/refs/tags/v2.13.3",
++ "openvibe-shared": "https://codeload.github.com/OpenVibers/OpenVibe.Shared/tar.gz/refs/tags/v2.15.0",
"pg": "^8.23.1",
"sanitize-html": "^2.17.7",
"sdp-transform": "^3.0.0",
ddiff --git a/public/css/style.css b/public/css/style.css
iindex 075721d6..b9951d5e 100644
---- a/public/css/style.css
++++ b/public/css/style.css
@@@ -921,20 +921,16 @@ html { -webkit-tap-highlight-color: transparent; }
overflow: visible;
transition: background 0.4s ease, border-color 0.4s ease, box-shadow 0.4s ease, backdrop-filter 0.4s ease;
}
--/* At the top of the home hero the nav bar is transparent so it blends into the hero; its
-- glass background fades in the moment you scroll down. A soft top scrim keeps the nav text
-- readable over the hero art. */
--.navbar.nav-hero-top {
++/* At the top of the home hero the bar is transparent so it blends into the hero, and its glass background fades in the
++ moment you scroll: body.ov-nav-overlay (app.js, the home route) plus the shared navbar's own .ovnav-top state, which
++ also draws the soft scrim that keeps the nav text readable over the hero art (openvibe-shared 2.15.0). */
++body.ov-nav-overlay .navbar.ovnav-top {
background: transparent;
border-bottom-color: transparent;
box-shadow: none;
backdrop-filter: none;
-webkit-backdrop-filter: none;
}
--.navbar.nav-hero-top::before {
-- content: ''; position: absolute; inset: 0; z-index: -1; pointer-events: none;
-- background: linear-gradient(180deg, rgba(0,0,0,0.38) 0%, transparent 100%);
--}
/* Home hero rises UNDER the transparent nav (its art fills the very top); the copy is padded
clear of the nav so nothing hides behind it. */
#page-home.page { padding-top: 0; }
@@@ -11414,7 +11410,9 @@ body.ov-panel-open #floating-chat-fab { opacity: 0; pointer-events: none; transf
backdrop-filter: blur(18px); -webkit-backdrop-filter: blur(18px);
--ovnav-h: var(--navbar-h);
}
--.openvibe-navbar.navbar.nav-hero-top { background: transparent; border-bottom-color: transparent; box-shadow: none; backdrop-filter: none; -webkit-backdrop-filter: none; }
++/* Over the home hero at the very top (body.ov-nav-overlay from app.js, .ovnav-top from the shared navbar): no background
++ at all, the hero shows through under the navbar's own soft scrim. */
++body.ov-nav-overlay .openvibe-navbar.navbar.ovnav-top { background: transparent; border-bottom-color: transparent; box-shadow: none; backdrop-filter: none; -webkit-backdrop-filter: none; }
.openvibe-navbar.navbar .openvibe-navbar-links a.ovnav-link { font-size: 0.86rem; padding: 7px 11px; border-radius: 10px; }
.openvibe-navbar.navbar .openvibe-navbar-links a.ovnav-link.active { color: var(--text-primary); background: color-mix(in srgb, var(--accent) 16%, transparent); }
.openvibe-navbar.navbar .openvibe-navbar-dropdown { position: fixed; top: calc(var(--navbar-h) + 6px); right: 8px; }
ddiff --git a/public/js/app.js b/public/js/app.js
iindex bb8d261b..9d3b9e25 100644
---- a/public/js/app.js
++++ b/public/js/app.js
@@@ -1306,21 +1306,14 @@ function showPage(page) {
updateNavHeroTransparency();
}
--// Transparent nav over the home hero: it blends into the hero at the very top and its glass
--// background fades in as soon as you scroll down. Only on the home page — every other page
--// keeps its solid nav from the top.
++// The home hero runs under the bar: body.ov-nav-overlay tells the shared navbar (openvibe-shared 2.15.0) to sit over it.
++// The navbar keeps its own at-the-top state (.ovnav-top) on every render and scroll, so the bar is transparent over the
++// hero at the very top and fades into its frosted look as you scroll — also right after a fresh load or a sign-in, when
++// the bar renders after the route.
function updateNavHeroTransparency() {
-- const nav = document.querySelector('.navbar');
-- if (!nav) return;
const homeActive = document.getElementById('page-home')?.classList.contains('active');
-- const atTop = (window.scrollY || window.pageYOffset || 0) < 28;
-- nav.classList.toggle('nav-hero-top', !!homeActive && atTop);
--}
--// One class toggle per animation frame at most — the handler fired on every scroll event,
--// which on phones (with a blurred nav over an animated hero) showed up as scroll jank.
--let _navScrollRaf = 0;
--window.addEventListener('scroll', () => { if (_navScrollRaf) return; _navScrollRaf = requestAnimationFrame(() => { _navScrollRaf = 0; updateNavHeroTransparency(); }); }, { passive: true });
--window.addEventListener('resize', updateNavHeroTransparency, { passive: true });
++ document.body.classList.toggle('ov-nav-overlay', !!homeActive);
++}
/* ── Channel Page (/:username) ────────────────────────────────── */
let currentChannelUsername = null; // is the current channel's user owner-rank?