openvibers/openvibe.sites Commits

openvibe.bot and openvibe.actor get front doors for their visions (owner, 2026-09-29; plan T15/T16): a site with a vision renders a split hero with a labelled design preview (Bot: the robot panel with live video, drive pad, buttons, battery and stop; Actor: an agent's activity ending in an approval request), how it works in three steps, buy-or-bring-your-own for Bot, what it does, templates for Actor, how it connects to Live, openre.stream, Media, Chat, Bot and Codes, and questions (also FAQPage JSON-LD). Bot: get your robot online in minutes, an open control panel for any robot, streaming optional. Actor: your agent in the cloud, connected to everything OpenVibe. They stay honest: a Build status block says the service is not running yet with the placeholder marker other repositories check. Every other site renders as before.

OP OpenVibers committed 29 Sept 2026 · 336f46c5e9 · 72 files, +2101 −138


Changes

ddiff --git a/build.js b/build.js
iindex f8c0e77..8c22dc0 100644
---- a/build.js
++++ b/build.js
@@@ -115,6 +115,93 @@ function highlight(h) {
</section>`;
}
++// A product with a worked-out vision (site.vision, owner 2026-09-29: Bot and Actor) gets a front door instead of the plain
++// "what it will be" grid: a split hero with a labelled design preview, how it works, the choices, what it does, how it
++// connects to the network, and its questions. It stays honest: the build status (with MARKER) says nothing is live yet.
++function visionViz(v) {
++ const z = v.viz || {};
++ if (z.kind === 'panel') {
++ return `<figure class="viz" aria-label="${esc(z.label)}">
++ <div class="viz-top"><span class="dot"></span><b>${esc(z.name)}</b><span class="muted">online</span><span class="lat"><i class="fa-solid fa-signal" aria-hidden="true"></i> ${esc(z.latency)}</span></div>
++ <div class="viz-video" aria-hidden="true"><div class="scan"></div><span class="onair"><i class="fa-solid fa-circle" aria-hidden="true"></i> ${esc(z.onair)}</span><span class="cam"><i class="fa-solid fa-video" aria-hidden="true"></i> Front camera</span></div>
++ <div class="viz-ctrl" aria-hidden="true">
++ <div class="dpad"><span class="u"><i class="fa-solid fa-caret-up"></i></span><span class="l"><i class="fa-solid fa-caret-left"></i></span><span class="c"></span><span class="r"><i class="fa-solid fa-caret-right"></i></span><span class="d"><i class="fa-solid fa-caret-down"></i></span></div>
++ <div class="viz-side">
++ <div class="keys">${(z.keys || []).map((k) => `<span><i class="fa-solid ${esc(k[0])}"></i> ${esc(k[1])}</span>`).join('')}</div>
++ <div class="meter"><span>Battery</span><i style="--v:${Number(z.battery) || 0}%"></i><b>${Number(z.battery) || 0}%</b></div>
++ <div class="estop">STOP</div>
++ </div>
++ </div>
++ <figcaption>${esc(z.caption)}</figcaption>
++ </figure>`;
++ }
++ if (z.kind === 'agent') {
++ return `<figure class="viz" aria-label="${esc(z.label)}">
++ <div class="viz-top"><span class="av"><i class="fa-solid ${esc(z.icon)}" aria-hidden="true"></i></span><b>${esc(z.name)}</b><span class="muted">${esc(z.role)}</span><span class="lat"><i class="fa-solid fa-cloud" aria-hidden="true"></i> ${esc(z.state)}</span></div>
++ <ol class="feed">${(z.steps || []).map((t) => `<li><i class="fa-solid fa-circle-check" aria-hidden="true"></i><span>${esc(t)}</span></li>`).join('')}
++ <li class="ask"><i class="fa-solid fa-hand" aria-hidden="true"></i><span>${esc(z.ask)}</span><span class="pills" aria-hidden="true"><span class="ok">Approve</span><span>Not yet</span></span></li></ol>
++ <figcaption>${esc(z.caption)}</figcaption>
++ </figure>`;
++ }
++ return '';
++}
++function vision(site) {
++ const v = site.vision;
++ const cards = (list) => list.map(([ic, h, d, href]) => href
++ ? `<a class="card" href="${esc(href)}"><div class="ic"><i class="fa-solid ${esc(ic)}" aria-hidden="true"></i></div><b>${esc(h)}</b><span>${esc(d)}</span><span class="go">${esc(href.replace(/^https?:\/\//, '').replace(/\/$/, ''))} →</span></a>`
++ : `<div class="card"><div class="ic"><i class="fa-solid ${esc(ic)}" aria-hidden="true"></i></div><b>${esc(h)}</b><span>${esc(d)}</span></div>`).join('\n ');
++ return ` <section id="what">
++ <h2>${esc(v.stepsTitle)}</h2>
++ <p class="lead2">${esc(v.stepsLead)}</p>
++ <ol class="steps">
++ ${v.steps.map(([h, d], i) => `<li><span class="n">${i + 1}</span><b>${esc(h)}</b><span>${esc(d)}</span></li>`).join('\n ')}
++ </ol>
++ </section>
++${v.choices ? `
++ <section>
++ <h2>${esc(v.choices.title)}</h2>
++ <p class="lead2">${esc(v.choices.lead)}</p>
++ <div class="choice">
++ ${v.choices.items.map((c) => `<div class="card big"><div class="ic"><i class="fa-solid ${esc(c.icon)}" aria-hidden="true"></i></div><b>${esc(c.title)}</b><span>${esc(c.text)}</span>${c.chips ? `<div class="chips">${c.chips.map((x) => `<span>${esc(x)}</span>`).join('')}</div>` : ''}</div>`).join('\n ')}
++ </div>
++ </section>` : ''}
++
++ <section>
++ <h2>${esc(v.featuresTitle)}</h2>
++ <p class="lead2">${esc(v.featuresLead)}</p>
++ <div class="grid three">
++ ${cards(v.features)}
++ </div>
++ </section>
++${v.templates ? `
++ <section>
++ <h2>${esc(v.templates.title)}</h2>
++ <p class="lead2">${esc(v.templates.lead)}</p>
++ <div class="chips big">${v.templates.items.map(([ic, t]) => `<span><i class="fa-solid ${esc(ic)}" aria-hidden="true"></i>${esc(t)}</span>`).join('')}</div>
++ </section>` : ''}
++
++ <section class="meanwhile">
++ <h2>${esc(v.connectTitle)}</h2>
++ <p class="lead2">${esc(v.connectLead)}</p>
++ <div class="grid">
++ ${cards(v.connect)}
++ </div>
++ </section>
++${site.faq && site.faq.length ? `
++ <section id="questions" class="faq">
++ <h2>Questions</h2>
++ ${site.faq.map(([q, ans]) => `<details><summary>${esc(q)}</summary><p>${esc(ans)}</p></details>`).join('\n ')}
++ </section>` : ''}
++
++ <section class="build">
++ <div class="card">
++ <b><i class="fa-solid fa-person-digging" aria-hidden="true"></i> Build status</b>
++ <span>${esc(v.building)} Its own service is not running yet: ${MARKER}.${site.launch ? ` It opens with ${esc(site.launch)}.` : ''} · as of ${esc(facts.generated)} · <a href="/status.json">status.json</a></span>
++ </div>
++ </section>
++`;
++}
++
function page(site) {
const core = site.core || NET.core;
const url = `https://${site.domain}/`;
@@@ -227,7 +314,50 @@ a.card:hover{transform:translateY(-3px);border-color:rgba(var(--site-rgb),.6);bo
.strip h3{font-size:19px;font-weight:700;margin:12px 0 8px}
.strip p{font-size:14px;color:var(--text-secondary);max-width:600px;margin:0 auto 18px;line-height:1.6}
.strip .ov-mark{width:44px;height:44px}
--@media (max-width:600px){.hero{padding-top:56px}.ctas .btn{width:100%;justify-content:center}}
++.hero.split{display:grid;grid-template-columns:minmax(0,1.05fr) minmax(0,1fr);gap:40px;align-items:center;text-align:left;padding-top:64px}
++.hero.split .ctas{justify-content:flex-start}.hero.split p.lead{margin:0}
++.viz{background:var(--bg-card);border:1px solid var(--border);border-radius:20px;padding:14px;box-shadow:0 30px 80px rgba(0,0,0,.45),0 0 0 1px rgba(var(--site-rgb),.08);animation:rise .7s .25s cubic-bezier(.2,.8,.2,1) both;text-align:left}
++.viz figcaption{margin-top:10px;font-size:11.5px;color:var(--text-muted);text-align:center}
++.viz-top{display:flex;align-items:center;gap:8px;font-size:13px;padding:2px 4px 12px}
++.viz-top b{font-weight:700}.viz-top .muted{color:var(--text-muted)}
++.viz-top .lat{margin-left:auto;font-size:12px;color:var(--site);background:rgba(var(--site-rgb),.1);border:1px solid rgba(var(--site-rgb),.3);padding:3px 9px;border-radius:999px}
++.viz-top .dot{width:8px;height:8px;border-radius:50%;background:#22c55e;box-shadow:0 0 0 4px rgba(34,197,94,.18)}
++.viz-top .av{width:26px;height:26px;border-radius:8px;display:grid;place-items:center;background:rgba(var(--site-rgb),.15);color:var(--site);font-size:13px}
++.viz-video{position:relative;aspect-ratio:16/9;border-radius:14px;overflow:hidden;background:radial-gradient(120% 90% at 30% 20%,rgba(var(--site-rgb),.28),transparent 60%),linear-gradient(160deg,#1a2338,#0b1020 70%);border:1px solid var(--border)}
++.viz-video::after{content:'';position:absolute;left:10%;right:10%;bottom:0;height:42%;background:linear-gradient(transparent,rgba(0,0,0,.35)),repeating-linear-gradient(90deg,rgba(255,255,255,.05) 0 1px,transparent 1px 38px);transform:perspective(220px) rotateX(58deg);transform-origin:bottom}
++.viz-video .scan{position:absolute;inset:0;background:linear-gradient(transparent 0,rgba(255,255,255,.04) 50%,transparent 100%);background-size:100% 6px;opacity:.5}
++.viz-video .onair{position:absolute;top:10px;left:10px;font-size:11px;font-weight:700;padding:3px 8px;border-radius:6px;background:rgba(239,68,68,.9);color:#fff}.viz-video .onair i{font-size:7px;vertical-align:2px;margin-right:3px}
++.viz-video .cam{position:absolute;bottom:10px;right:10px;font-size:11px;color:#dbe4f5;background:rgba(0,0,0,.45);padding:3px 8px;border-radius:6px}
++.viz-ctrl{display:flex;gap:14px;align-items:center;margin-top:12px}
++.dpad{display:grid;grid-template-columns:repeat(3,34px);grid-template-rows:repeat(3,34px);gap:4px;flex:none}
++.dpad span{display:grid;place-items:center;border-radius:9px;background:var(--bg-hover);color:var(--text-primary);font-size:15px;border:1px solid var(--border)}
++.dpad .u{grid-area:1/2}.dpad .l{grid-area:2/1}.dpad .c{grid-area:2/2;background:rgba(var(--site-rgb),.15);border-color:rgba(var(--site-rgb),.35)}.dpad .r{grid-area:2/3}.dpad .d{grid-area:3/2}
++.dpad .u{background:rgba(var(--site-rgb),.22);border-color:rgba(var(--site-rgb),.5)}
++.viz-side{flex:1;min-width:0;display:grid;gap:8px}
++.viz-side .keys{display:flex;flex-wrap:wrap;gap:6px}
++.viz-side .keys span{font-size:11.5px;padding:5px 9px;border-radius:8px;background:var(--bg-secondary);border:1px solid var(--border);color:var(--text-secondary)}
++.viz-side .meter{display:flex;align-items:center;gap:8px;font-size:11.5px;color:var(--text-muted)}
++.viz-side .meter i{flex:1;height:6px;border-radius:9px;background:linear-gradient(90deg,#22c55e var(--v),var(--bg-hover) var(--v))}
++.viz-side .meter b{color:var(--text-secondary);font-weight:600}
++.viz-side .estop{justify-self:end;font-size:12px;font-weight:800;letter-spacing:.08em;color:#fff;background:#dc2626;border-radius:10px;padding:7px 16px;box-shadow:0 0 0 3px rgba(220,38,38,.25)}
++.feed{list-style:none;display:grid;gap:8px;padding:2px}
++.feed li{display:flex;align-items:flex-start;gap:10px;font-size:13.5px;line-height:1.45;padding:10px 12px;border-radius:12px;background:var(--bg-secondary);border:1px solid var(--border);color:var(--text-secondary)}
++.feed li i{color:#22c55e;margin-top:3px}
++.feed li.ask{flex-wrap:wrap;border-color:rgba(var(--site-rgb),.45);background:rgba(var(--site-rgb),.08);color:var(--text-primary)}.feed li.ask i{color:var(--site)}.feed li.ask>span:first-of-type{flex:1;min-width:160px}
++.feed .pills{display:flex;gap:6px;margin-left:auto}.feed .pills span{font-size:12px;font-weight:600;padding:4px 11px;border-radius:999px;border:1px solid var(--border);color:var(--text-secondary)}.feed .pills .ok{background:var(--site);border-color:var(--site);color:#0b0d10}
++.steps{list-style:none;display:grid;grid-template-columns:repeat(auto-fit,minmax(230px,1fr));gap:14px;counter-reset:s}
++.steps li{position:relative;background:var(--bg-card);border:1px solid var(--border);border-radius:16px;padding:20px 20px 20px;display:flex;flex-direction:column;gap:8px}
++.steps .n{width:30px;height:30px;border-radius:50%;display:grid;place-items:center;font-weight:800;font-size:14px;color:#0b0d10;background:var(--site)}
++.steps b{font-size:15px}.steps span:last-child{font-size:13px;color:var(--text-secondary);line-height:1.55}
++.grid.three{grid-template-columns:repeat(auto-fit,minmax(280px,1fr))}
++.choice{display:grid;grid-template-columns:repeat(auto-fit,minmax(280px,1fr));gap:14px}
++.card.big{padding:24px}.card.big b{font-size:17px}
++.chips{display:flex;flex-wrap:wrap;gap:7px;margin-top:6px}
++.chips span{font-size:12.5px;padding:6px 11px;border-radius:999px;border:1px solid var(--border);background:var(--bg-secondary);color:var(--text-secondary)}
++.chips.big span{font-size:13.5px;padding:9px 14px;color:var(--text-primary)}.chips.big span i{color:var(--site);margin-right:8px}
++.build .card{border-style:dashed;background:rgba(0,0,0,.15)}.build .card b i{color:var(--site);margin-right:6px}.build .card span a{color:var(--text-secondary)}.build .card code{font-size:12px}
++@media (max-width:860px){.hero.split{grid-template-columns:1fr;text-align:center;gap:28px}.hero.split .ctas{justify-content:center}.hero.split p.lead{margin:0 auto}}
++@media (max-width:600px){.hero{padding-top:56px}.ctas .btn{width:100%;justify-content:center}.viz-ctrl{flex-direction:column;align-items:stretch}.dpad{align-self:center}}
@media (prefers-reduced-motion:reduce){*{animation:none!important;transition:none!important}}
${site.statusApi ? STATUS_CSS : ''}</style>
</head>
@@@ -235,18 +365,19 @@ ${site.statusApi ? STATUS_CSS : ''}</style>
<div class="orbs"><i></i><i></i><i></i></div>
<div id="navbar-mount"></div>
<main class="wrap">
-- <header class="hero">
++ <header class="hero${site.vision ? ' split' : ''}">${site.vision ? '<div class="hero-main">' : ''}
<div class="mark"><i class="fa-solid ${esc(site.icon)}" aria-hidden="true"></i></div>
-- <div class="badge"><span class="ov-mark" data-size="16" data-variant="${esc(site.tld)}"></span> Part of the OpenVibe network · <b>${esc(STANDING[standing(site)].label)}</b></div>
++ <div class="badge"><span class="ov-mark" data-size="16" data-variant="${esc(site.tld)}"></span> Part of the OpenVibe network · <b>${esc(site.vision ? site.vision.badge : STANDING[standing(site)].label)}</b></div>
<h1>${site.hostParts ? `<span class="d">${esc(site.hostParts[0])}</span><span class="tld">.${esc(site.hostParts[1])}</span>` : `${esc(core)}<span class="d">.</span><span class="tld">${esc(site.name.split('.').pop())}</span>`}</h1>
<div class="tag">${esc(site.tagline)}</div>
<p class="lead">${esc(site.description)}</p>
<div class="ctas">
${primary ? `<a class="btn btn-primary" href="${esc(primary[1])}"><i class="fa-solid fa-arrow-right"></i> ${esc(primary[0])}</a>` : `<a class="btn btn-primary" href="${NET.networkUrl}/login?return=${encodeURIComponent(url)}"><i class="fa-solid fa-right-to-bracket"></i> Sign in with OpenVibe</a>`}
-- <a class="btn" href="${NET.networkUrl}/#network"><i class="fa-solid fa-circle-nodes"></i> The whole network</a>
++ ${site.vision && site.vision.cta ? `<a class="btn" href="${esc(site.vision.cta[1])}"><i class="fa-solid ${esc(site.vision.cta[2])}"></i> ${esc(site.vision.cta[0])}</a>` : `<a class="btn" href="${NET.networkUrl}/#network"><i class="fa-solid fa-circle-nodes"></i> The whole network</a>`}
<a class="btn" href="${esc(NET.discord)}" rel="noopener"><i class="fa-brands fa-discord"></i> Follow the build</a>
</div>
-- <p class="status"><i class="fa-solid fa-clock" aria-hidden="true"></i> Status: <b>${esc(STANDING[standing(site)].label)}</b> · ${statusText(site)} · as of ${esc(facts.generated)} · <a href="/status.json">status.json</a></p>
++ ${site.vision ? `</div>
++ ${visionViz(site.vision)}` : `<p class="status"><i class="fa-solid fa-clock" aria-hidden="true"></i> Status: <b>${esc(STANDING[standing(site)].label)}</b> · ${statusText(site)} · as of ${esc(facts.generated)} · <a href="/status.json">status.json</a></p>`}
</header>
${site.highlight ? highlight(site.highlight) : ''}
@@@ -257,7 +388,7 @@ ${notice ? ` <section id="what" class="meanwhile">
${site.links.map(([h, href, d]) => `<a class="card" href="${esc(href)}"><div class="ic"><i class="fa-solid fa-arrow-up-right-from-square" aria-hidden="true"></i></div><b>${esc(h)}</b><span>${esc(d)}</span><span class="go">${esc(href.replace(/^https?:\/\//, '').replace(/\/$/, ''))} →</span></a>`).join('\n ')}
</div>
</section>
--${site.statusApi ? liveStatus(site) : ''}` : ` <section id="what">
++${site.statusApi ? liveStatus(site) : ''}` : site.vision ? vision(site) : ` <section id="what">
<h2>What ${esc(site.name)} will be</h2>
<p class="lead2">Same account, same themes, same navbar as every other OpenVibe site — built in the open, run by its community.</p>
<div class="grid">
@@@ -303,7 +434,7 @@ ${require('openvibe-shared/frame').footer({ service: site.tld, variant: 'full' }
<script src="${SHARED('footer.js')}"></script>
<script>
(function () {
-- if (window.OpenVibeNavbar) { try { OpenVibeNavbar.init({ service: '${esc(site.tld)}', apiBase: '${NET.networkUrl}', links: [{ label: '${notice ? 'Where to go' : 'What it will be'}', href: '#what' }, { label: 'The network', href: '${NET.networkUrl}/#network', external: false }], history: { type: 'page', title: '${esc(site.name)}' } }); } catch (e) {} }
++ if (window.OpenVibeNavbar) { try { OpenVibeNavbar.init({ service: '${esc(site.tld)}', apiBase: '${NET.networkUrl}', links: [{ label: '${notice ? 'Where to go' : site.vision ? 'How it works' : 'What it will be'}', href: '#what' }, { label: 'The network', href: '${NET.networkUrl}/#network', external: false }], history: { type: 'page', title: '${esc(site.name)}' } }); } catch (e) {} }
if (window.OpenVibeFooter) { try { OpenVibeFooter.init({ service: '${esc(site.tld)}', variant: 'full', links: [{ heading: '${esc(site.name)}', items: [{ name: 'Sign in', url: '${NET.networkUrl}/login?return=${encodeURIComponent(url)}' }, { name: 'The network', url: '${NET.networkUrl}/#network' }, { name: 'Discord', url: '${esc(NET.discord)}' }] }] }); } catch (e) {} }
})();
</script>
ddiff --git a/dist/admin.openvibe.network/index.html b/dist/admin.openvibe.network/index.html
iindex 566e99a..338b1ac 100644
---- a/dist/admin.openvibe.network/index.html
++++ b/dist/admin.openvibe.network/index.html
@@@ -87,7 +87,50 @@ a.card:hover{transform:translateY(-3px);border-color:rgba(var(--site-rgb),.6);bo
.strip h3{font-size:19px;font-weight:700;margin:12px 0 8px}
.strip p{font-size:14px;color:var(--text-secondary);max-width:600px;margin:0 auto 18px;line-height:1.6}
.strip .ov-mark{width:44px;height:44px}
--@media (max-width:600px){.hero{padding-top:56px}.ctas .btn{width:100%;justify-content:center}}
++.hero.split{display:grid;grid-template-columns:minmax(0,1.05fr) minmax(0,1fr);gap:40px;align-items:center;text-align:left;padding-top:64px}
++.hero.split .ctas{justify-content:flex-start}.hero.split p.lead{margin:0}
++.viz{background:var(--bg-card);border:1px solid var(--border);border-radius:20px;padding:14px;box-shadow:0 30px 80px rgba(0,0,0,.45),0 0 0 1px rgba(var(--site-rgb),.08);animation:rise .7s .25s cubic-bezier(.2,.8,.2,1) both;text-align:left}
++.viz figcaption{margin-top:10px;font-size:11.5px;color:var(--text-muted);text-align:center}
++.viz-top{display:flex;align-items:center;gap:8px;font-size:13px;padding:2px 4px 12px}
++.viz-top b{font-weight:700}.viz-top .muted{color:var(--text-muted)}
++.viz-top .lat{margin-left:auto;font-size:12px;color:var(--site);background:rgba(var(--site-rgb),.1);border:1px solid rgba(var(--site-rgb),.3);padding:3px 9px;border-radius:999px}
++.viz-top .dot{width:8px;height:8px;border-radius:50%;background:#22c55e;box-shadow:0 0 0 4px rgba(34,197,94,.18)}
++.viz-top .av{width:26px;height:26px;border-radius:8px;display:grid;place-items:center;background:rgba(var(--site-rgb),.15);color:var(--site);font-size:13px}
++.viz-video{position:relative;aspect-ratio:16/9;border-radius:14px;overflow:hidden;background:radial-gradient(120% 90% at 30% 20%,rgba(var(--site-rgb),.28),transparent 60%),linear-gradient(160deg,#1a2338,#0b1020 70%);border:1px solid var(--border)}
++.viz-video::after{content:'';position:absolute;left:10%;right:10%;bottom:0;height:42%;background:linear-gradient(transparent,rgba(0,0,0,.35)),repeating-linear-gradient(90deg,rgba(255,255,255,.05) 0 1px,transparent 1px 38px);transform:perspective(220px) rotateX(58deg);transform-origin:bottom}
++.viz-video .scan{position:absolute;inset:0;background:linear-gradient(transparent 0,rgba(255,255,255,.04) 50%,transparent 100%);background-size:100% 6px;opacity:.5}
++.viz-video .onair{position:absolute;top:10px;left:10px;font-size:11px;font-weight:700;padding:3px 8px;border-radius:6px;background:rgba(239,68,68,.9);color:#fff}.viz-video .onair i{font-size:7px;vertical-align:2px;margin-right:3px}
++.viz-video .cam{position:absolute;bottom:10px;right:10px;font-size:11px;color:#dbe4f5;background:rgba(0,0,0,.45);padding:3px 8px;border-radius:6px}
++.viz-ctrl{display:flex;gap:14px;align-items:center;margin-top:12px}
++.dpad{display:grid;grid-template-columns:repeat(3,34px);grid-template-rows:repeat(3,34px);gap:4px;flex:none}
++.dpad span{display:grid;place-items:center;border-radius:9px;background:var(--bg-hover);color:var(--text-primary);font-size:15px;border:1px solid var(--border)}
++.dpad .u{grid-area:1/2}.dpad .l{grid-area:2/1}.dpad .c{grid-area:2/2;background:rgba(var(--site-rgb),.15);border-color:rgba(var(--site-rgb),.35)}.dpad .r{grid-area:2/3}.dpad .d{grid-area:3/2}
++.dpad .u{background:rgba(var(--site-rgb),.22);border-color:rgba(var(--site-rgb),.5)}
++.viz-side{flex:1;min-width:0;display:grid;gap:8px}
++.viz-side .keys{display:flex;flex-wrap:wrap;gap:6px}
++.viz-side .keys span{font-size:11.5px;padding:5px 9px;border-radius:8px;background:var(--bg-secondary);border:1px solid var(--border);color:var(--text-secondary)}
++.viz-side .meter{display:flex;align-items:center;gap:8px;font-size:11.5px;color:var(--text-muted)}
++.viz-side .meter i{flex:1;height:6px;border-radius:9px;background:linear-gradient(90deg,#22c55e var(--v),var(--bg-hover) var(--v))}
++.viz-side .meter b{color:var(--text-secondary);font-weight:600}
++.viz-side .estop{justify-self:end;font-size:12px;font-weight:800;letter-spacing:.08em;color:#fff;background:#dc2626;border-radius:10px;padding:7px 16px;box-shadow:0 0 0 3px rgba(220,38,38,.25)}
++.feed{list-style:none;display:grid;gap:8px;padding:2px}
++.feed li{display:flex;align-items:flex-start;gap:10px;font-size:13.5px;line-height:1.45;padding:10px 12px;border-radius:12px;background:var(--bg-secondary);border:1px solid var(--border);color:var(--text-secondary)}
++.feed li i{color:#22c55e;margin-top:3px}
++.feed li.ask{flex-wrap:wrap;border-color:rgba(var(--site-rgb),.45);background:rgba(var(--site-rgb),.08);color:var(--text-primary)}.feed li.ask i{color:var(--site)}.feed li.ask>span:first-of-type{flex:1;min-width:160px}
++.feed .pills{display:flex;gap:6px;margin-left:auto}.feed .pills span{font-size:12px;font-weight:600;padding:4px 11px;border-radius:999px;border:1px solid var(--border);color:var(--text-secondary)}.feed .pills .ok{background:var(--site);border-color:var(--site);color:#0b0d10}
++.steps{list-style:none;display:grid;grid-template-columns:repeat(auto-fit,minmax(230px,1fr));gap:14px;counter-reset:s}
++.steps li{position:relative;background:var(--bg-card);border:1px solid var(--border);border-radius:16px;padding:20px 20px 20px;display:flex;flex-direction:column;gap:8px}
++.steps .n{width:30px;height:30px;border-radius:50%;display:grid;place-items:center;font-weight:800;font-size:14px;color:#0b0d10;background:var(--site)}
++.steps b{font-size:15px}.steps span:last-child{font-size:13px;color:var(--text-secondary);line-height:1.55}
++.grid.three{grid-template-columns:repeat(auto-fit,minmax(280px,1fr))}
++.choice{display:grid;grid-template-columns:repeat(auto-fit,minmax(280px,1fr));gap:14px}
++.card.big{padding:24px}.card.big b{font-size:17px}
++.chips{display:flex;flex-wrap:wrap;gap:7px;margin-top:6px}
++.chips span{font-size:12.5px;padding:6px 11px;border-radius:999px;border:1px solid var(--border);background:var(--bg-secondary);color:var(--text-secondary)}
++.chips.big span{font-size:13.5px;padding:9px 14px;color:var(--text-primary)}.chips.big span i{color:var(--site);margin-right:8px}
++.build .card{border-style:dashed;background:rgba(0,0,0,.15)}.build .card b i{color:var(--site);margin-right:6px}.build .card span a{color:var(--text-secondary)}.build .card code{font-size:12px}
++@media (max-width:860px){.hero.split{grid-template-columns:1fr;text-align:center;gap:28px}.hero.split .ctas{justify-content:center}.hero.split p.lead{margin:0 auto}}
++@media (max-width:600px){.hero{padding-top:56px}.ctas .btn{width:100%;justify-content:center}.viz-ctrl{flex-direction:column;align-items:stretch}.dpad{align-self:center}}
@media (prefers-reduced-motion:reduce){*{animation:none!important;transition:none!important}}
</style>
</head>
ddiff --git a/dist/admin.openvibe.network/release.json b/dist/admin.openvibe.network/release.json
iindex 15331fc..1cf01e6 100644
---- a/dist/admin.openvibe.network/release.json
++++ b/dist/admin.openvibe.network/release.json
@@@ -1,6 +1,6 @@
{
"service": "admin",
-- "release": "048c077ded26",
++ "release": "4e2dec5e2993",
"released_at": "2026-09-29T00:00:00.000Z",
"booted_at": null,
"contracts_version": null,
ddiff --git a/dist/ai.openvibe.network/index.html b/dist/ai.openvibe.network/index.html
iindex 543aa32..f45fd54 100644
---- a/dist/ai.openvibe.network/index.html
++++ b/dist/ai.openvibe.network/index.html
@@@ -87,7 +87,50 @@ a.card:hover{transform:translateY(-3px);border-color:rgba(var(--site-rgb),.6);bo
.strip h3{font-size:19px;font-weight:700;margin:12px 0 8px}
.strip p{font-size:14px;color:var(--text-secondary);max-width:600px;margin:0 auto 18px;line-height:1.6}
.strip .ov-mark{width:44px;height:44px}
--@media (max-width:600px){.hero{padding-top:56px}.ctas .btn{width:100%;justify-content:center}}
++.hero.split{display:grid;grid-template-columns:minmax(0,1.05fr) minmax(0,1fr);gap:40px;align-items:center;text-align:left;padding-top:64px}
++.hero.split .ctas{justify-content:flex-start}.hero.split p.lead{margin:0}
++.viz{background:var(--bg-card);border:1px solid var(--border);border-radius:20px;padding:14px;box-shadow:0 30px 80px rgba(0,0,0,.45),0 0 0 1px rgba(var(--site-rgb),.08);animation:rise .7s .25s cubic-bezier(.2,.8,.2,1) both;text-align:left}
++.viz figcaption{margin-top:10px;font-size:11.5px;color:var(--text-muted);text-align:center}
++.viz-top{display:flex;align-items:center;gap:8px;font-size:13px;padding:2px 4px 12px}
++.viz-top b{font-weight:700}.viz-top .muted{color:var(--text-muted)}
++.viz-top .lat{margin-left:auto;font-size:12px;color:var(--site);background:rgba(var(--site-rgb),.1);border:1px solid rgba(var(--site-rgb),.3);padding:3px 9px;border-radius:999px}
++.viz-top .dot{width:8px;height:8px;border-radius:50%;background:#22c55e;box-shadow:0 0 0 4px rgba(34,197,94,.18)}
++.viz-top .av{width:26px;height:26px;border-radius:8px;display:grid;place-items:center;background:rgba(var(--site-rgb),.15);color:var(--site);font-size:13px}
++.viz-video{position:relative;aspect-ratio:16/9;border-radius:14px;overflow:hidden;background:radial-gradient(120% 90% at 30% 20%,rgba(var(--site-rgb),.28),transparent 60%),linear-gradient(160deg,#1a2338,#0b1020 70%);border:1px solid var(--border)}
++.viz-video::after{content:'';position:absolute;left:10%;right:10%;bottom:0;height:42%;background:linear-gradient(transparent,rgba(0,0,0,.35)),repeating-linear-gradient(90deg,rgba(255,255,255,.05) 0 1px,transparent 1px 38px);transform:perspective(220px) rotateX(58deg);transform-origin:bottom}
++.viz-video .scan{position:absolute;inset:0;background:linear-gradient(transparent 0,rgba(255,255,255,.04) 50%,transparent 100%);background-size:100% 6px;opacity:.5}
++.viz-video .onair{position:absolute;top:10px;left:10px;font-size:11px;font-weight:700;padding:3px 8px;border-radius:6px;background:rgba(239,68,68,.9);color:#fff}.viz-video .onair i{font-size:7px;vertical-align:2px;margin-right:3px}
++.viz-video .cam{position:absolute;bottom:10px;right:10px;font-size:11px;color:#dbe4f5;background:rgba(0,0,0,.45);padding:3px 8px;border-radius:6px}
++.viz-ctrl{display:flex;gap:14px;align-items:center;margin-top:12px}
++.dpad{display:grid;grid-template-columns:repeat(3,34px);grid-template-rows:repeat(3,34px);gap:4px;flex:none}
++.dpad span{display:grid;place-items:center;border-radius:9px;background:var(--bg-hover);color:var(--text-primary);font-size:15px;border:1px solid var(--border)}
++.dpad .u{grid-area:1/2}.dpad .l{grid-area:2/1}.dpad .c{grid-area:2/2;background:rgba(var(--site-rgb),.15);border-color:rgba(var(--site-rgb),.35)}.dpad .r{grid-area:2/3}.dpad .d{grid-area:3/2}
++.dpad .u{background:rgba(var(--site-rgb),.22);border-color:rgba(var(--site-rgb),.5)}
++.viz-side{flex:1;min-width:0;display:grid;gap:8px}
++.viz-side .keys{display:flex;flex-wrap:wrap;gap:6px}
++.viz-side .keys span{font-size:11.5px;padding:5px 9px;border-radius:8px;background:var(--bg-secondary);border:1px solid var(--border);color:var(--text-secondary)}
++.viz-side .meter{display:flex;align-items:center;gap:8px;font-size:11.5px;color:var(--text-muted)}
++.viz-side .meter i{flex:1;height:6px;border-radius:9px;background:linear-gradient(90deg,#22c55e var(--v),var(--bg-hover) var(--v))}
++.viz-side .meter b{color:var(--text-secondary);font-weight:600}
++.viz-side .estop{justify-self:end;font-size:12px;font-weight:800;letter-spacing:.08em;color:#fff;background:#dc2626;border-radius:10px;padding:7px 16px;box-shadow:0 0 0 3px rgba(220,38,38,.25)}
++.feed{list-style:none;display:grid;gap:8px;padding:2px}
++.feed li{display:flex;align-items:flex-start;gap:10px;font-size:13.5px;line-height:1.45;padding:10px 12px;border-radius:12px;background:var(--bg-secondary);border:1px solid var(--border);color:var(--text-secondary)}
++.feed li i{color:#22c55e;margin-top:3px}
++.feed li.ask{flex-wrap:wrap;border-color:rgba(var(--site-rgb),.45);background:rgba(var(--site-rgb),.08);color:var(--text-primary)}.feed li.ask i{color:var(--site)}.feed li.ask>span:first-of-type{flex:1;min-width:160px}
++.feed .pills{display:flex;gap:6px;margin-left:auto}.feed .pills span{font-size:12px;font-weight:600;padding:4px 11px;border-radius:999px;border:1px solid var(--border);color:var(--text-secondary)}.feed .pills .ok{background:var(--site);border-color:var(--site);color:#0b0d10}
++.steps{list-style:none;display:grid;grid-template-columns:repeat(auto-fit,minmax(230px,1fr));gap:14px;counter-reset:s}
++.steps li{position:relative;background:var(--bg-card);border:1px solid var(--border);border-radius:16px;padding:20px 20px 20px;display:flex;flex-direction:column;gap:8px}
++.steps .n{width:30px;height:30px;border-radius:50%;display:grid;place-items:center;font-weight:800;font-size:14px;color:#0b0d10;background:var(--site)}
++.steps b{font-size:15px}.steps span:last-child{font-size:13px;color:var(--text-secondary);line-height:1.55}
++.grid.three{grid-template-columns:repeat(auto-fit,minmax(280px,1fr))}
++.choice{display:grid;grid-template-columns:repeat(auto-fit,minmax(280px,1fr));gap:14px}
++.card.big{padding:24px}.card.big b{font-size:17px}
++.chips{display:flex;flex-wrap:wrap;gap:7px;margin-top:6px}
++.chips span{font-size:12.5px;padding:6px 11px;border-radius:999px;border:1px solid var(--border);background:var(--bg-secondary);color:var(--text-secondary)}
++.chips.big span{font-size:13.5px;padding:9px 14px;color:var(--text-primary)}.chips.big span i{color:var(--site);margin-right:8px}
++.build .card{border-style:dashed;background:rgba(0,0,0,.15)}.build .card b i{color:var(--site);margin-right:6px}.build .card span a{color:var(--text-secondary)}.build .card code{font-size:12px}
++@media (max-width:860px){.hero.split{grid-template-columns:1fr;text-align:center;gap:28px}.hero.split .ctas{justify-content:center}.hero.split p.lead{margin:0 auto}}
++@media (max-width:600px){.hero{padding-top:56px}.ctas .btn{width:100%;justify-content:center}.viz-ctrl{flex-direction:column;align-items:stretch}.dpad{align-self:center}}
@media (prefers-reduced-motion:reduce){*{animation:none!important;transition:none!important}}
</style>
</head>
ddiff --git a/dist/ai.openvibe.network/release.json b/dist/ai.openvibe.network/release.json
iindex 7c1f4f7..7ab76a6 100644
---- a/dist/ai.openvibe.network/release.json
++++ b/dist/ai.openvibe.network/release.json
@@@ -1,6 +1,6 @@
{
"service": "ai",
-- "release": "65fd798d06f3",
++ "release": "7d2d151a6842",
"released_at": "2026-09-29T00:00:00.000Z",
"booted_at": null,
"contracts_version": null,
ddiff --git a/dist/ai.openvibe.services/index.html b/dist/ai.openvibe.services/index.html
iindex 9f90d49..644708d 100644
---- a/dist/ai.openvibe.services/index.html
++++ b/dist/ai.openvibe.services/index.html
@@@ -87,7 +87,50 @@ a.card:hover{transform:translateY(-3px);border-color:rgba(var(--site-rgb),.6);bo
.strip h3{font-size:19px;font-weight:700;margin:12px 0 8px}
.strip p{font-size:14px;color:var(--text-secondary);max-width:600px;margin:0 auto 18px;line-height:1.6}
.strip .ov-mark{width:44px;height:44px}
--@media (max-width:600px){.hero{padding-top:56px}.ctas .btn{width:100%;justify-content:center}}
++.hero.split{display:grid;grid-template-columns:minmax(0,1.05fr) minmax(0,1fr);gap:40px;align-items:center;text-align:left;padding-top:64px}
++.hero.split .ctas{justify-content:flex-start}.hero.split p.lead{margin:0}
++.viz{background:var(--bg-card);border:1px solid var(--border);border-radius:20px;padding:14px;box-shadow:0 30px 80px rgba(0,0,0,.45),0 0 0 1px rgba(var(--site-rgb),.08);animation:rise .7s .25s cubic-bezier(.2,.8,.2,1) both;text-align:left}
++.viz figcaption{margin-top:10px;font-size:11.5px;color:var(--text-muted);text-align:center}
++.viz-top{display:flex;align-items:center;gap:8px;font-size:13px;padding:2px 4px 12px}
++.viz-top b{font-weight:700}.viz-top .muted{color:var(--text-muted)}
++.viz-top .lat{margin-left:auto;font-size:12px;color:var(--site);background:rgba(var(--site-rgb),.1);border:1px solid rgba(var(--site-rgb),.3);padding:3px 9px;border-radius:999px}
++.viz-top .dot{width:8px;height:8px;border-radius:50%;background:#22c55e;box-shadow:0 0 0 4px rgba(34,197,94,.18)}
++.viz-top .av{width:26px;height:26px;border-radius:8px;display:grid;place-items:center;background:rgba(var(--site-rgb),.15);color:var(--site);font-size:13px}
++.viz-video{position:relative;aspect-ratio:16/9;border-radius:14px;overflow:hidden;background:radial-gradient(120% 90% at 30% 20%,rgba(var(--site-rgb),.28),transparent 60%),linear-gradient(160deg,#1a2338,#0b1020 70%);border:1px solid var(--border)}
++.viz-video::after{content:'';position:absolute;left:10%;right:10%;bottom:0;height:42%;background:linear-gradient(transparent,rgba(0,0,0,.35)),repeating-linear-gradient(90deg,rgba(255,255,255,.05) 0 1px,transparent 1px 38px);transform:perspective(220px) rotateX(58deg);transform-origin:bottom}
++.viz-video .scan{position:absolute;inset:0;background:linear-gradient(transparent 0,rgba(255,255,255,.04) 50%,transparent 100%);background-size:100% 6px;opacity:.5}
++.viz-video .onair{position:absolute;top:10px;left:10px;font-size:11px;font-weight:700;padding:3px 8px;border-radius:6px;background:rgba(239,68,68,.9);color:#fff}.viz-video .onair i{font-size:7px;vertical-align:2px;margin-right:3px}
++.viz-video .cam{position:absolute;bottom:10px;right:10px;font-size:11px;color:#dbe4f5;background:rgba(0,0,0,.45);padding:3px 8px;border-radius:6px}
++.viz-ctrl{display:flex;gap:14px;align-items:center;margin-top:12px}
++.dpad{display:grid;grid-template-columns:repeat(3,34px);grid-template-rows:repeat(3,34px);gap:4px;flex:none}
++.dpad span{display:grid;place-items:center;border-radius:9px;background:var(--bg-hover);color:var(--text-primary);font-size:15px;border:1px solid var(--border)}
++.dpad .u{grid-area:1/2}.dpad .l{grid-area:2/1}.dpad .c{grid-area:2/2;background:rgba(var(--site-rgb),.15);border-color:rgba(var(--site-rgb),.35)}.dpad .r{grid-area:2/3}.dpad .d{grid-area:3/2}
++.dpad .u{background:rgba(var(--site-rgb),.22);border-color:rgba(var(--site-rgb),.5)}
++.viz-side{flex:1;min-width:0;display:grid;gap:8px}
++.viz-side .keys{display:flex;flex-wrap:wrap;gap:6px}
++.viz-side .keys span{font-size:11.5px;padding:5px 9px;border-radius:8px;background:var(--bg-secondary);border:1px solid var(--border);color:var(--text-secondary)}
++.viz-side .meter{display:flex;align-items:center;gap:8px;font-size:11.5px;color:var(--text-muted)}
++.viz-side .meter i{flex:1;height:6px;border-radius:9px;background:linear-gradient(90deg,#22c55e var(--v),var(--bg-hover) var(--v))}
++.viz-side .meter b{color:var(--text-secondary);font-weight:600}
++.viz-side .estop{justify-self:end;font-size:12px;font-weight:800;letter-spacing:.08em;color:#fff;background:#dc2626;border-radius:10px;padding:7px 16px;box-shadow:0 0 0 3px rgba(220,38,38,.25)}
++.feed{list-style:none;display:grid;gap:8px;padding:2px}
++.feed li{display:flex;align-items:flex-start;gap:10px;font-size:13.5px;line-height:1.45;padding:10px 12px;border-radius:12px;background:var(--bg-secondary);border:1px solid var(--border);color:var(--text-secondary)}
++.feed li i{color:#22c55e;margin-top:3px}
++.feed li.ask{flex-wrap:wrap;border-color:rgba(var(--site-rgb),.45);background:rgba(var(--site-rgb),.08);color:var(--text-primary)}.feed li.ask i{color:var(--site)}.feed li.ask>span:first-of-type{flex:1;min-width:160px}
++.feed .pills{display:flex;gap:6px;margin-left:auto}.feed .pills span{font-size:12px;font-weight:600;padding:4px 11px;border-radius:999px;border:1px solid var(--border);color:var(--text-secondary)}.feed .pills .ok{background:var(--site);border-color:var(--site);color:#0b0d10}
++.steps{list-style:none;display:grid;grid-template-columns:repeat(auto-fit,minmax(230px,1fr));gap:14px;counter-reset:s}
++.steps li{position:relative;background:var(--bg-card);border:1px solid var(--border);border-radius:16px;padding:20px 20px 20px;display:flex;flex-direction:column;gap:8px}
++.steps .n{width:30px;height:30px;border-radius:50%;display:grid;place-items:center;font-weight:800;font-size:14px;color:#0b0d10;background:var(--site)}
++.steps b{font-size:15px}.steps span:last-child{font-size:13px;color:var(--text-secondary);line-height:1.55}
++.grid.three{grid-template-columns:repeat(auto-fit,minmax(280px,1fr))}
++.choice{display:grid;grid-template-columns:repeat(auto-fit,minmax(280px,1fr));gap:14px}
++.card.big{padding:24px}.card.big b{font-size:17px}
++.chips{display:flex;flex-wrap:wrap;gap:7px;margin-top:6px}
++.chips span{font-size:12.5px;padding:6px 11px;border-radius:999px;border:1px solid var(--border);background:var(--bg-secondary);color:var(--text-secondary)}
++.chips.big span{font-size:13.5px;padding:9px 14px;color:var(--text-primary)}.chips.big span i{color:var(--site);margin-right:8px}
++.build .card{border-style:dashed;background:rgba(0,0,0,.15)}.build .card b i{color:var(--site);margin-right:6px}.build .card span a{color:var(--text-secondary)}.build .card code{font-size:12px}
++@media (max-width:860px){.hero.split{grid-template-columns:1fr;text-align:center;gap:28px}.hero.split .ctas{justify-content:center}.hero.split p.lead{margin:0 auto}}
++@media (max-width:600px){.hero{padding-top:56px}.ctas .btn{width:100%;justify-content:center}.viz-ctrl{flex-direction:column;align-items:stretch}.dpad{align-self:center}}
@media (prefers-reduced-motion:reduce){*{animation:none!important;transition:none!important}}
</style>
</head>
ddiff --git a/dist/ai.openvibe.services/release.json b/dist/ai.openvibe.services/release.json
iindex 44373c5..502f14e 100644
---- a/dist/ai.openvibe.services/release.json
++++ b/dist/ai.openvibe.services/release.json
@@@ -1,6 +1,6 @@
{
"service": "ai",
-- "release": "87098ee4da69",
++ "release": "d9c70520ecef",
"released_at": "2026-09-29T00:00:00.000Z",
"booted_at": null,
"contracts_version": null,
ddiff --git a/dist/api.openvibe.network/index.html b/dist/api.openvibe.network/index.html
iindex 2cc2c88..7ae4eb3 100644
---- a/dist/api.openvibe.network/index.html
++++ b/dist/api.openvibe.network/index.html
@@@ -87,7 +87,50 @@ a.card:hover{transform:translateY(-3px);border-color:rgba(var(--site-rgb),.6);bo
.strip h3{font-size:19px;font-weight:700;margin:12px 0 8px}
.strip p{font-size:14px;color:var(--text-secondary);max-width:600px;margin:0 auto 18px;line-height:1.6}
.strip .ov-mark{width:44px;height:44px}
--@media (max-width:600px){.hero{padding-top:56px}.ctas .btn{width:100%;justify-content:center}}
++.hero.split{display:grid;grid-template-columns:minmax(0,1.05fr) minmax(0,1fr);gap:40px;align-items:center;text-align:left;padding-top:64px}
++.hero.split .ctas{justify-content:flex-start}.hero.split p.lead{margin:0}
++.viz{background:var(--bg-card);border:1px solid var(--border);border-radius:20px;padding:14px;box-shadow:0 30px 80px rgba(0,0,0,.45),0 0 0 1px rgba(var(--site-rgb),.08);animation:rise .7s .25s cubic-bezier(.2,.8,.2,1) both;text-align:left}
++.viz figcaption{margin-top:10px;font-size:11.5px;color:var(--text-muted);text-align:center}
++.viz-top{display:flex;align-items:center;gap:8px;font-size:13px;padding:2px 4px 12px}
++.viz-top b{font-weight:700}.viz-top .muted{color:var(--text-muted)}
++.viz-top .lat{margin-left:auto;font-size:12px;color:var(--site);background:rgba(var(--site-rgb),.1);border:1px solid rgba(var(--site-rgb),.3);padding:3px 9px;border-radius:999px}
++.viz-top .dot{width:8px;height:8px;border-radius:50%;background:#22c55e;box-shadow:0 0 0 4px rgba(34,197,94,.18)}
++.viz-top .av{width:26px;height:26px;border-radius:8px;display:grid;place-items:center;background:rgba(var(--site-rgb),.15);color:var(--site);font-size:13px}
++.viz-video{position:relative;aspect-ratio:16/9;border-radius:14px;overflow:hidden;background:radial-gradient(120% 90% at 30% 20%,rgba(var(--site-rgb),.28),transparent 60%),linear-gradient(160deg,#1a2338,#0b1020 70%);border:1px solid var(--border)}
++.viz-video::after{content:'';position:absolute;left:10%;right:10%;bottom:0;height:42%;background:linear-gradient(transparent,rgba(0,0,0,.35)),repeating-linear-gradient(90deg,rgba(255,255,255,.05) 0 1px,transparent 1px 38px);transform:perspective(220px) rotateX(58deg);transform-origin:bottom}
++.viz-video .scan{position:absolute;inset:0;background:linear-gradient(transparent 0,rgba(255,255,255,.04) 50%,transparent 100%);background-size:100% 6px;opacity:.5}
++.viz-video .onair{position:absolute;top:10px;left:10px;font-size:11px;font-weight:700;padding:3px 8px;border-radius:6px;background:rgba(239,68,68,.9);color:#fff}.viz-video .onair i{font-size:7px;vertical-align:2px;margin-right:3px}
++.viz-video .cam{position:absolute;bottom:10px;right:10px;font-size:11px;color:#dbe4f5;background:rgba(0,0,0,.45);padding:3px 8px;border-radius:6px}
++.viz-ctrl{display:flex;gap:14px;align-items:center;margin-top:12px}
++.dpad{display:grid;grid-template-columns:repeat(3,34px);grid-template-rows:repeat(3,34px);gap:4px;flex:none}
++.dpad span{display:grid;place-items:center;border-radius:9px;background:var(--bg-hover);color:var(--text-primary);font-size:15px;border:1px solid var(--border)}
++.dpad .u{grid-area:1/2}.dpad .l{grid-area:2/1}.dpad .c{grid-area:2/2;background:rgba(var(--site-rgb),.15);border-color:rgba(var(--site-rgb),.35)}.dpad .r{grid-area:2/3}.dpad .d{grid-area:3/2}
++.dpad .u{background:rgba(var(--site-rgb),.22);border-color:rgba(var(--site-rgb),.5)}
++.viz-side{flex:1;min-width:0;display:grid;gap:8px}
++.viz-side .keys{display:flex;flex-wrap:wrap;gap:6px}
++.viz-side .keys span{font-size:11.5px;padding:5px 9px;border-radius:8px;background:var(--bg-secondary);border:1px solid var(--border);color:var(--text-secondary)}
++.viz-side .meter{display:flex;align-items:center;gap:8px;font-size:11.5px;color:var(--text-muted)}
++.viz-side .meter i{flex:1;height:6px;border-radius:9px;background:linear-gradient(90deg,#22c55e var(--v),var(--bg-hover) var(--v))}
++.viz-side .meter b{color:var(--text-secondary);font-weight:600}
++.viz-side .estop{justify-self:end;font-size:12px;font-weight:800;letter-spacing:.08em;color:#fff;background:#dc2626;border-radius:10px;padding:7px 16px;box-shadow:0 0 0 3px rgba(220,38,38,.25)}
++.feed{list-style:none;display:grid;gap:8px;padding:2px}
++.feed li{display:flex;align-items:flex-start;gap:10px;font-size:13.5px;line-height:1.45;padding:10px 12px;border-radius:12px;background:var(--bg-secondary);border:1px solid var(--border);color:var(--text-secondary)}
++.feed li i{color:#22c55e;margin-top:3px}
++.feed li.ask{flex-wrap:wrap;border-color:rgba(var(--site-rgb),.45);background:rgba(var(--site-rgb),.08);color:var(--text-primary)}.feed li.ask i{color:var(--site)}.feed li.ask>span:first-of-type{flex:1;min-width:160px}
++.feed .pills{display:flex;gap:6px;margin-left:auto}.feed .pills span{font-size:12px;font-weight:600;padding:4px 11px;border-radius:999px;border:1px solid var(--border);color:var(--text-secondary)}.feed .pills .ok{background:var(--site);border-color:var(--site);color:#0b0d10}
++.steps{list-style:none;display:grid;grid-template-columns:repeat(auto-fit,minmax(230px,1fr));gap:14px;counter-reset:s}
++.steps li{position:relative;background:var(--bg-card);border:1px solid var(--border);border-radius:16px;padding:20px 20px 20px;display:flex;flex-direction:column;gap:8px}
++.steps .n{width:30px;height:30px;border-radius:50%;display:grid;place-items:center;font-weight:800;font-size:14px;color:#0b0d10;background:var(--site)}
++.steps b{font-size:15px}.steps span:last-child{font-size:13px;color:var(--text-secondary);line-height:1.55}
++.grid.three{grid-template-columns:repeat(auto-fit,minmax(280px,1fr))}
++.choice{display:grid;grid-template-columns:repeat(auto-fit,minmax(280px,1fr));gap:14px}
++.card.big{padding:24px}.card.big b{font-size:17px}
++.chips{display:flex;flex-wrap:wrap;gap:7px;margin-top:6px}
++.chips span{font-size:12.5px;padding:6px 11px;border-radius:999px;border:1px solid var(--border);background:var(--bg-secondary);color:var(--text-secondary)}
++.chips.big span{font-size:13.5px;padding:9px 14px;color:var(--text-primary)}.chips.big span i{color:var(--site);margin-right:8px}
++.build .card{border-style:dashed;background:rgba(0,0,0,.15)}.build .card b i{color:var(--site);margin-right:6px}.build .card span a{color:var(--text-secondary)}.build .card code{font-size:12px}
++@media (max-width:860px){.hero.split{grid-template-columns:1fr;text-align:center;gap:28px}.hero.split .ctas{justify-content:center}.hero.split p.lead{margin:0 auto}}
++@media (max-width:600px){.hero{padding-top:56px}.ctas .btn{width:100%;justify-content:center}.viz-ctrl{flex-direction:column;align-items:stretch}.dpad{align-self:center}}
@media (prefers-reduced-motion:reduce){*{animation:none!important;transition:none!important}}
</style>
</head>
ddiff --git a/dist/api.openvibe.network/release.json b/dist/api.openvibe.network/release.json
iindex 874911e..585f92b 100644
---- a/dist/api.openvibe.network/release.json
++++ b/dist/api.openvibe.network/release.json
@@@ -1,6 +1,6 @@
{
"service": "api",
-- "release": "a7ba4fb27175",
++ "release": "4dc46ad3c820",
"released_at": "2026-09-29T00:00:00.000Z",
"booted_at": null,
"contracts_version": null,
ddiff --git a/dist/auth.openvibe.network/index.html b/dist/auth.openvibe.network/index.html
iindex f916c92..3fdf726 100644
---- a/dist/auth.openvibe.network/index.html
++++ b/dist/auth.openvibe.network/index.html
@@@ -87,7 +87,50 @@ a.card:hover{transform:translateY(-3px);border-color:rgba(var(--site-rgb),.6);bo
.strip h3{font-size:19px;font-weight:700;margin:12px 0 8px}
.strip p{font-size:14px;color:var(--text-secondary);max-width:600px;margin:0 auto 18px;line-height:1.6}
.strip .ov-mark{width:44px;height:44px}
--@media (max-width:600px){.hero{padding-top:56px}.ctas .btn{width:100%;justify-content:center}}
++.hero.split{display:grid;grid-template-columns:minmax(0,1.05fr) minmax(0,1fr);gap:40px;align-items:center;text-align:left;padding-top:64px}
++.hero.split .ctas{justify-content:flex-start}.hero.split p.lead{margin:0}
++.viz{background:var(--bg-card);border:1px solid var(--border);border-radius:20px;padding:14px;box-shadow:0 30px 80px rgba(0,0,0,.45),0 0 0 1px rgba(var(--site-rgb),.08);animation:rise .7s .25s cubic-bezier(.2,.8,.2,1) both;text-align:left}
++.viz figcaption{margin-top:10px;font-size:11.5px;color:var(--text-muted);text-align:center}
++.viz-top{display:flex;align-items:center;gap:8px;font-size:13px;padding:2px 4px 12px}
++.viz-top b{font-weight:700}.viz-top .muted{color:var(--text-muted)}
++.viz-top .lat{margin-left:auto;font-size:12px;color:var(--site);background:rgba(var(--site-rgb),.1);border:1px solid rgba(var(--site-rgb),.3);padding:3px 9px;border-radius:999px}
++.viz-top .dot{width:8px;height:8px;border-radius:50%;background:#22c55e;box-shadow:0 0 0 4px rgba(34,197,94,.18)}
++.viz-top .av{width:26px;height:26px;border-radius:8px;display:grid;place-items:center;background:rgba(var(--site-rgb),.15);color:var(--site);font-size:13px}
++.viz-video{position:relative;aspect-ratio:16/9;border-radius:14px;overflow:hidden;background:radial-gradient(120% 90% at 30% 20%,rgba(var(--site-rgb),.28),transparent 60%),linear-gradient(160deg,#1a2338,#0b1020 70%);border:1px solid var(--border)}
++.viz-video::after{content:'';position:absolute;left:10%;right:10%;bottom:0;height:42%;background:linear-gradient(transparent,rgba(0,0,0,.35)),repeating-linear-gradient(90deg,rgba(255,255,255,.05) 0 1px,transparent 1px 38px);transform:perspective(220px) rotateX(58deg);transform-origin:bottom}
++.viz-video .scan{position:absolute;inset:0;background:linear-gradient(transparent 0,rgba(255,255,255,.04) 50%,transparent 100%);background-size:100% 6px;opacity:.5}
++.viz-video .onair{position:absolute;top:10px;left:10px;font-size:11px;font-weight:700;padding:3px 8px;border-radius:6px;background:rgba(239,68,68,.9);color:#fff}.viz-video .onair i{font-size:7px;vertical-align:2px;margin-right:3px}
++.viz-video .cam{position:absolute;bottom:10px;right:10px;font-size:11px;color:#dbe4f5;background:rgba(0,0,0,.45);padding:3px 8px;border-radius:6px}
++.viz-ctrl{display:flex;gap:14px;align-items:center;margin-top:12px}
++.dpad{display:grid;grid-template-columns:repeat(3,34px);grid-template-rows:repeat(3,34px);gap:4px;flex:none}
++.dpad span{display:grid;place-items:center;border-radius:9px;background:var(--bg-hover);color:var(--text-primary);font-size:15px;border:1px solid var(--border)}
++.dpad .u{grid-area:1/2}.dpad .l{grid-area:2/1}.dpad .c{grid-area:2/2;background:rgba(var(--site-rgb),.15);border-color:rgba(var(--site-rgb),.35)}.dpad .r{grid-area:2/3}.dpad .d{grid-area:3/2}
++.dpad .u{background:rgba(var(--site-rgb),.22);border-color:rgba(var(--site-rgb),.5)}
++.viz-side{flex:1;min-width:0;display:grid;gap:8px}
++.viz-side .keys{display:flex;flex-wrap:wrap;gap:6px}
++.viz-side .keys span{font-size:11.5px;padding:5px 9px;border-radius:8px;background:var(--bg-secondary);border:1px solid var(--border);color:var(--text-secondary)}
++.viz-side .meter{display:flex;align-items:center;gap:8px;font-size:11.5px;color:var(--text-muted)}
++.viz-side .meter i{flex:1;height:6px;border-radius:9px;background:linear-gradient(90deg,#22c55e var(--v),var(--bg-hover) var(--v))}
++.viz-side .meter b{color:var(--text-secondary);font-weight:600}
++.viz-side .estop{justify-self:end;font-size:12px;font-weight:800;letter-spacing:.08em;color:#fff;background:#dc2626;border-radius:10px;padding:7px 16px;box-shadow:0 0 0 3px rgba(220,38,38,.25)}
++.feed{list-style:none;display:grid;gap:8px;padding:2px}
++.feed li{display:flex;align-items:flex-start;gap:10px;font-size:13.5px;line-height:1.45;padding:10px 12px;border-radius:12px;background:var(--bg-secondary);border:1px solid var(--border);color:var(--text-secondary)}
++.feed li i{color:#22c55e;margin-top:3px}
++.feed li.ask{flex-wrap:wrap;border-color:rgba(var(--site-rgb),.45);background:rgba(var(--site-rgb),.08);color:var(--text-primary)}.feed li.ask i{color:var(--site)}.feed li.ask>span:first-of-type{flex:1;min-width:160px}
++.feed .pills{display:flex;gap:6px;margin-left:auto}.feed .pills span{font-size:12px;font-weight:600;padding:4px 11px;border-radius:999px;border:1px solid var(--border);color:var(--text-secondary)}.feed .pills .ok{background:var(--site);border-color:var(--site);color:#0b0d10}
++.steps{list-style:none;display:grid;grid-template-columns:repeat(auto-fit,minmax(230px,1fr));gap:14px;counter-reset:s}
++.steps li{position:relative;background:var(--bg-card);border:1px solid var(--border);border-radius:16px;padding:20px 20px 20px;display:flex;flex-direction:column;gap:8px}
++.steps .n{width:30px;height:30px;border-radius:50%;display:grid;place-items:center;font-weight:800;font-size:14px;color:#0b0d10;background:var(--site)}
++.steps b{font-size:15px}.steps span:last-child{font-size:13px;color:var(--text-secondary);line-height:1.55}
++.grid.three{grid-template-columns:repeat(auto-fit,minmax(280px,1fr))}
++.choice{display:grid;grid-template-columns:repeat(auto-fit,minmax(280px,1fr));gap:14px}
++.card.big{padding:24px}.card.big b{font-size:17px}
++.chips{display:flex;flex-wrap:wrap;gap:7px;margin-top:6px}
++.chips span{font-size:12.5px;padding:6px 11px;border-radius:999px;border:1px solid var(--border);background:var(--bg-secondary);color:var(--text-secondary)}
++.chips.big span{font-size:13.5px;padding:9px 14px;color:var(--text-primary)}.chips.big span i{color:var(--site);margin-right:8px}
++.build .card{border-style:dashed;background:rgba(0,0,0,.15)}.build .card b i{color:var(--site);margin-right:6px}.build .card span a{color:var(--text-secondary)}.build .card code{font-size:12px}
++@media (max-width:860px){.hero.split{grid-template-columns:1fr;text-align:center;gap:28px}.hero.split .ctas{justify-content:center}.hero.split p.lead{margin:0 auto}}
++@media (max-width:600px){.hero{padding-top:56px}.ctas .btn{width:100%;justify-content:center}.viz-ctrl{flex-direction:column;align-items:stretch}.dpad{align-self:center}}
@media (prefers-reduced-motion:reduce){*{animation:none!important;transition:none!important}}
</style>
</head>
ddiff --git a/dist/auth.openvibe.network/release.json b/dist/auth.openvibe.network/release.json
iindex f233047..a34b560 100644
---- a/dist/auth.openvibe.network/release.json
++++ b/dist/auth.openvibe.network/release.json
@@@ -1,6 +1,6 @@
{
"service": "auth",
-- "release": "b64a21d70133",
++ "release": "2d9159294e65",
"released_at": "2026-09-29T00:00:00.000Z",
"booted_at": null,
"contracts_version": null,
ddiff --git a/dist/openre.stream/index.html b/dist/openre.stream/index.html
iindex 944e184..74e1e7a 100644
---- a/dist/openre.stream/index.html
++++ b/dist/openre.stream/index.html
@@@ -87,7 +87,50 @@ a.card:hover{transform:translateY(-3px);border-color:rgba(var(--site-rgb),.6);bo
.strip h3{font-size:19px;font-weight:700;margin:12px 0 8px}
.strip p{font-size:14px;color:var(--text-secondary);max-width:600px;margin:0 auto 18px;line-height:1.6}
.strip .ov-mark{width:44px;height:44px}
--@media (max-width:600px){.hero{padding-top:56px}.ctas .btn{width:100%;justify-content:center}}
++.hero.split{display:grid;grid-template-columns:minmax(0,1.05fr) minmax(0,1fr);gap:40px;align-items:center;text-align:left;padding-top:64px}
++.hero.split .ctas{justify-content:flex-start}.hero.split p.lead{margin:0}
++.viz{background:var(--bg-card);border:1px solid var(--border);border-radius:20px;padding:14px;box-shadow:0 30px 80px rgba(0,0,0,.45),0 0 0 1px rgba(var(--site-rgb),.08);animation:rise .7s .25s cubic-bezier(.2,.8,.2,1) both;text-align:left}
++.viz figcaption{margin-top:10px;font-size:11.5px;color:var(--text-muted);text-align:center}
++.viz-top{display:flex;align-items:center;gap:8px;font-size:13px;padding:2px 4px 12px}
++.viz-top b{font-weight:700}.viz-top .muted{color:var(--text-muted)}
++.viz-top .lat{margin-left:auto;font-size:12px;color:var(--site);background:rgba(var(--site-rgb),.1);border:1px solid rgba(var(--site-rgb),.3);padding:3px 9px;border-radius:999px}
++.viz-top .dot{width:8px;height:8px;border-radius:50%;background:#22c55e;box-shadow:0 0 0 4px rgba(34,197,94,.18)}
++.viz-top .av{width:26px;height:26px;border-radius:8px;display:grid;place-items:center;background:rgba(var(--site-rgb),.15);color:var(--site);font-size:13px}
++.viz-video{position:relative;aspect-ratio:16/9;border-radius:14px;overflow:hidden;background:radial-gradient(120% 90% at 30% 20%,rgba(var(--site-rgb),.28),transparent 60%),linear-gradient(160deg,#1a2338,#0b1020 70%);border:1px solid var(--border)}
++.viz-video::after{content:'';position:absolute;left:10%;right:10%;bottom:0;height:42%;background:linear-gradient(transparent,rgba(0,0,0,.35)),repeating-linear-gradient(90deg,rgba(255,255,255,.05) 0 1px,transparent 1px 38px);transform:perspective(220px) rotateX(58deg);transform-origin:bottom}
++.viz-video .scan{position:absolute;inset:0;background:linear-gradient(transparent 0,rgba(255,255,255,.04) 50%,transparent 100%);background-size:100% 6px;opacity:.5}
++.viz-video .onair{position:absolute;top:10px;left:10px;font-size:11px;font-weight:700;padding:3px 8px;border-radius:6px;background:rgba(239,68,68,.9);color:#fff}.viz-video .onair i{font-size:7px;vertical-align:2px;margin-right:3px}
++.viz-video .cam{position:absolute;bottom:10px;right:10px;font-size:11px;color:#dbe4f5;background:rgba(0,0,0,.45);padding:3px 8px;border-radius:6px}
++.viz-ctrl{display:flex;gap:14px;align-items:center;margin-top:12px}
++.dpad{display:grid;grid-template-columns:repeat(3,34px);grid-template-rows:repeat(3,34px);gap:4px;flex:none}
++.dpad span{display:grid;place-items:center;border-radius:9px;background:var(--bg-hover);color:var(--text-primary);font-size:15px;border:1px solid var(--border)}
++.dpad .u{grid-area:1/2}.dpad .l{grid-area:2/1}.dpad .c{grid-area:2/2;background:rgba(var(--site-rgb),.15);border-color:rgba(var(--site-rgb),.35)}.dpad .r{grid-area:2/3}.dpad .d{grid-area:3/2}
++.dpad .u{background:rgba(var(--site-rgb),.22);border-color:rgba(var(--site-rgb),.5)}
++.viz-side{flex:1;min-width:0;display:grid;gap:8px}
++.viz-side .keys{display:flex;flex-wrap:wrap;gap:6px}
++.viz-side .keys span{font-size:11.5px;padding:5px 9px;border-radius:8px;background:var(--bg-secondary);border:1px solid var(--border);color:var(--text-secondary)}
++.viz-side .meter{display:flex;align-items:center;gap:8px;font-size:11.5px;color:var(--text-muted)}
++.viz-side .meter i{flex:1;height:6px;border-radius:9px;background:linear-gradient(90deg,#22c55e var(--v),var(--bg-hover) var(--v))}
++.viz-side .meter b{color:var(--text-secondary);font-weight:600}
++.viz-side .estop{justify-self:end;font-size:12px;font-weight:800;letter-spacing:.08em;color:#fff;background:#dc2626;border-radius:10px;padding:7px 16px;box-shadow:0 0 0 3px rgba(220,38,38,.25)}
++.feed{list-style:none;display:grid;gap:8px;padding:2px}
++.feed li{display:flex;align-items:flex-start;gap:10px;font-size:13.5px;line-height:1.45;padding:10px 12px;border-radius:12px;background:var(--bg-secondary);border:1px solid var(--border);color:var(--text-secondary)}
++.feed li i{color:#22c55e;margin-top:3px}
++.feed li.ask{flex-wrap:wrap;border-color:rgba(var(--site-rgb),.45);background:rgba(var(--site-rgb),.08);color:var(--text-primary)}.feed li.ask i{color:var(--site)}.feed li.ask>span:first-of-type{flex:1;min-width:160px}
++.feed .pills{display:flex;gap:6px;margin-left:auto}.feed .pills span{font-size:12px;font-weight:600;padding:4px 11px;border-radius:999px;border:1px solid var(--border);color:var(--text-secondary)}.feed .pills .ok{background:var(--site);border-color:var(--site);color:#0b0d10}
++.steps{list-style:none;display:grid;grid-template-columns:repeat(auto-fit,minmax(230px,1fr));gap:14px;counter-reset:s}
++.steps li{position:relative;background:var(--bg-card);border:1px solid var(--border);border-radius:16px;padding:20px 20px 20px;display:flex;flex-direction:column;gap:8px}
++.steps .n{width:30px;height:30px;border-radius:50%;display:grid;place-items:center;font-weight:800;font-size:14px;color:#0b0d10;background:var(--site)}
++.steps b{font-size:15px}.steps span:last-child{font-size:13px;color:var(--text-secondary);line-height:1.55}
++.grid.three{grid-template-columns:repeat(auto-fit,minmax(280px,1fr))}
++.choice{display:grid;grid-template-columns:repeat(auto-fit,minmax(280px,1fr));gap:14px}
++.card.big{padding:24px}.card.big b{font-size:17px}
++.chips{display:flex;flex-wrap:wrap;gap:7px;margin-top:6px}
++.chips span{font-size:12.5px;padding:6px 11px;border-radius:999px;border:1px solid var(--border);background:var(--bg-secondary);color:var(--text-secondary)}
++.chips.big span{font-size:13.5px;padding:9px 14px;color:var(--text-primary)}.chips.big span i{color:var(--site);margin-right:8px}
++.build .card{border-style:dashed;background:rgba(0,0,0,.15)}.build .card b i{color:var(--site);margin-right:6px}.build .card span a{color:var(--text-secondary)}.build .card code{font-size:12px}
++@media (max-width:860px){.hero.split{grid-template-columns:1fr;text-align:center;gap:28px}.hero.split .ctas{justify-content:center}.hero.split p.lead{margin:0 auto}}
++@media (max-width:600px){.hero{padding-top:56px}.ctas .btn{width:100%;justify-content:center}.viz-ctrl{flex-direction:column;align-items:stretch}.dpad{align-self:center}}
@media (prefers-reduced-motion:reduce){*{animation:none!important;transition:none!important}}
</style>
</head>
ddiff --git a/dist/openre.stream/release.json b/dist/openre.stream/release.json
iindex c52d875..535cfb5 100644
---- a/dist/openre.stream/release.json
++++ b/dist/openre.stream/release.json
@@@ -1,6 +1,6 @@
{
"service": "stream",
-- "release": "a47f8c8d8a9a",
++ "release": "12285800442e",
"released_at": "2026-09-29T00:00:00.000Z",
"booted_at": null,
"contracts_version": null,
ddiff --git a/dist/openvibe.actor/index.html b/dist/openvibe.actor/index.html
iindex c62ea3a..441bae9 100644
---- a/dist/openvibe.actor/index.html
++++ b/dist/openvibe.actor/index.html
@@@ -3,9 +3,9 @@
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
--<title>OpenVibe.Actor — AI agents that act for you, with your permission.</title>
--<meta name="description" content="OpenVibe.Actor will give you persistent AI agents that work across OpenVibe and, when you allow it, other sites and apps: they use OpenVibe&#39;s own APIs first and a sandboxed browser when they must. You decide what each agent may do, for once, a session, a while or always, and anything with real consequences (buying, sending, publishing, applying, moving a robot) waits for your approval, wherever you are on the network.">
--<meta name="keywords" content="ai agent platform, open source ai agent, personal ai assistant, browser automation agent, ai agent permissions">
++<title>OpenVibe.Actor — Your agent in the cloud, connected to everything OpenVibe.</title>
++<meta name="description" content="OpenVibe.Actor gives you an AI agent that lives in OpenVibe&#39;s cloud and works for you around the clock. It remembers, runs on schedules and triggers, uses every OpenVibe product as a tool, browses and codes in a sandbox, and asks before it does anything that matters. Talk to it from any OpenVibe site, in chat, or from your own apps.">
++<meta name="keywords" content="cloud ai agent, hosted ai agent, personal ai agent, ai agent with memory, autonomous ai assistant, ai agent platform, open source ai agent, mcp server, ai agent approvals">
<meta name="robots" content="index, follow, max-image-preview:large">
<meta name="theme-color" content="#a78bfa">
<link rel="canonical" href="https://openvibe.actor/">
@@@ -16,15 +16,15 @@
<meta property="og:type" content="website">
<meta property="og:site_name" content="OpenVibe.Actor">
<meta property="og:url" content="https://openvibe.actor/">
--<meta property="og:title" content="OpenVibe.Actor — AI agents that act for you, with your permission.">
--<meta property="og:description" content="OpenVibe.Actor will give you persistent AI agents that work across OpenVibe and, when you allow it, other sites and apps: they use OpenVibe&#39;s own APIs first and a sandboxed browser when they must. You decide what each agent may do, for once, a session, a while or always, and anything with real consequences (buying, sending, publishing, applying, moving a robot) waits for your approval, wherever you are on the network.">
++<meta property="og:title" content="OpenVibe.Actor — Your agent in the cloud, connected to everything OpenVibe.">
++<meta property="og:description" content="OpenVibe.Actor gives you an AI agent that lives in OpenVibe&#39;s cloud and works for you around the clock. It remembers, runs on schedules and triggers, uses every OpenVibe product as a tool, browses and codes in a sandbox, and asks before it does anything that matters. Talk to it from any OpenVibe site, in chat, or from your own apps.">
<meta property="og:image" content="https://openvibe.network/assets/logo-512.png">
<meta property="og:image:alt" content="OpenVibe">
<meta name="twitter:card" content="summary">
--<meta name="twitter:title" content="OpenVibe.Actor — AI agents that act for you, with your permission.">
--<meta name="twitter:description" content="OpenVibe.Actor will give you persistent AI agents that work across OpenVibe and, when you allow it, other sites and apps: they use OpenVibe&#39;s own APIs first and a sandboxed browser when they must. You decide what each agent may do, for once, a session, a while or always, and anything with real consequences (buying, sending, publishing, applying, moving a robot) waits for your approval, wherever you are on the network.">
++<meta name="twitter:title" content="OpenVibe.Actor — Your agent in the cloud, connected to everything OpenVibe.">
++<meta name="twitter:description" content="OpenVibe.Actor gives you an AI agent that lives in OpenVibe&#39;s cloud and works for you around the clock. It remembers, runs on schedules and triggers, uses every OpenVibe product as a tool, browses and codes in a sandbox, and asks before it does anything that matters. Talk to it from any OpenVibe site, in chat, or from your own apps.">
<meta name="twitter:image" content="https://openvibe.network/assets/logo-512.png">
--<script type="application/ld+json">{"@context":"https://schema.org","@graph":[{"@type":"WebSite","@id":"https://openvibe.actor/#site","url":"https://openvibe.actor/","name":"OpenVibe.Actor","description":"OpenVibe.Actor will give you persistent AI agents that work across OpenVibe and, when you allow it, other sites and apps: they use OpenVibe's own APIs first and a sandboxed browser when they must. You decide what each agent may do, for once, a session, a while or always, and anything with real consequences (buying, sending, publishing, applying, moving a robot) waits for your approval, wherever you are on the network.","inLanguage":"en","publisher":{"@type":"Organization","@id":"https://openvibe.network/#org","name":"OpenVibe","url":"https://openvibe.network/","logo":"https://openvibe.network/assets/logo-512.png","sameAs":["https://github.com/OpenVibers","https://discord.gg/M6MuRUaeJj"]},"isPartOf":{"@type":"WebSite","@id":"https://openvibe.network/#site","name":"OpenVibe.Network","url":"https://openvibe.network/"}},{"@type":"WebPage","@id":"https://openvibe.actor/#page","url":"https://openvibe.actor/","name":"OpenVibe.Actor — AI agents that act for you, with your permission.","description":"OpenVibe.Actor will give you persistent AI agents that work across OpenVibe and, when you allow it, other sites and apps: they use OpenVibe's own APIs first and a sandboxed browser when they must. You decide what each agent may do, for once, a session, a while or always, and anything with real consequences (buying, sending, publishing, applying, moving a robot) waits for your approval, wherever you are on the network.","isPartOf":{"@id":"https://openvibe.actor/#site"},"datePublished":"2026-09-17","dateModified":"2026-09-29","breadcrumb":{"@type":"BreadcrumbList","itemListElement":[{"@type":"ListItem","position":1,"name":"OpenVibe","item":"https://openvibe.network/"},{"@type":"ListItem","position":2,"name":"OpenVibe.Actor","item":"https://openvibe.actor/"}]}}]}</script>
++<script type="application/ld+json">{"@context":"https://schema.org","@graph":[{"@type":"WebSite","@id":"https://openvibe.actor/#site","url":"https://openvibe.actor/","name":"OpenVibe.Actor","description":"OpenVibe.Actor gives you an AI agent that lives in OpenVibe's cloud and works for you around the clock. It remembers, runs on schedules and triggers, uses every OpenVibe product as a tool, browses and codes in a sandbox, and asks before it does anything that matters. Talk to it from any OpenVibe site, in chat, or from your own apps.","inLanguage":"en","publisher":{"@type":"Organization","@id":"https://openvibe.network/#org","name":"OpenVibe","url":"https://openvibe.network/","logo":"https://openvibe.network/assets/logo-512.png","sameAs":["https://github.com/OpenVibers","https://discord.gg/M6MuRUaeJj"]},"isPartOf":{"@type":"WebSite","@id":"https://openvibe.network/#site","name":"OpenVibe.Network","url":"https://openvibe.network/"}},{"@type":"WebPage","@id":"https://openvibe.actor/#page","url":"https://openvibe.actor/","name":"OpenVibe.Actor — Your agent in the cloud, connected to everything OpenVibe.","description":"OpenVibe.Actor gives you an AI agent that lives in OpenVibe's cloud and works for you around the clock. It remembers, runs on schedules and triggers, uses every OpenVibe product as a tool, browses and codes in a sandbox, and asks before it does anything that matters. Talk to it from any OpenVibe site, in chat, or from your own apps.","isPartOf":{"@id":"https://openvibe.actor/#site"},"datePublished":"2026-09-17","dateModified":"2026-09-29","breadcrumb":{"@type":"BreadcrumbList","itemListElement":[{"@type":"ListItem","position":1,"name":"OpenVibe","item":"https://openvibe.network/"},{"@type":"ListItem","position":2,"name":"OpenVibe.Actor","item":"https://openvibe.actor/"}]}},{"@type":"FAQPage","@id":"https://openvibe.actor/#faq","mainEntity":[{"@type":"Question","name":"How is this different from a chat assistant?","acceptedAnswer":{"@type":"Answer","text":"It keeps working when you leave: it has memory, schedules and triggers, and it can act across OpenVibe with the permissions you give it."}},{"@type":"Question","name":"Can it do things without asking?","acceptedAnswer":{"@type":"Answer","text":"Only what you allow. You grant each tool, and anything with consequences waits for your approval. Every action is logged, and you can stop an agent at any time."}},{"@type":"Question","name":"Which AI models does it use?","acceptedAnswer":{"@type":"Answer","text":"Any model OpenVibe.AI routes to, including open and local models, or your own API key."}},{"@type":"Question","name":"Can other apps use my agent?","acceptedAnswer":{"@type":"Answer","text":"Yes: an API, webhooks and an MCP server connect it to other tools and assistants."}},{"@type":"Question","name":"What will it cost?","acceptedAnswer":{"@type":"Answer","text":"You will be able to start without paying, within limits published before launch; heavier use and bigger models will be paid."}}]}]}</script>
<script>(function(){try{var raw=localStorage.getItem('ov_theme');if(!raw)return;var t=JSON.parse(raw),v=t&&t.variables;if(!v)return;var el=document.documentElement;for(var k in v)if(k.charAt(0)==='-')el.style.setProperty(k,v[k]);if(t.id)el.setAttribute('data-theme',t.id);}catch(_){}})();</script>
<script src="/shared/theme-loader.js?v=ee4a6754d0f7" defer></script>
<link rel="preconnect" href="https://cdnjs.cloudflare.com" crossorigin>
@@@ -87,7 +87,50 @@ a.card:hover{transform:translateY(-3px);border-color:rgba(var(--site-rgb),.6);bo
.strip h3{font-size:19px;font-weight:700;margin:12px 0 8px}
.strip p{font-size:14px;color:var(--text-secondary);max-width:600px;margin:0 auto 18px;line-height:1.6}
.strip .ov-mark{width:44px;height:44px}
--@media (max-width:600px){.hero{padding-top:56px}.ctas .btn{width:100%;justify-content:center}}
++.hero.split{display:grid;grid-template-columns:minmax(0,1.05fr) minmax(0,1fr);gap:40px;align-items:center;text-align:left;padding-top:64px}
++.hero.split .ctas{justify-content:flex-start}.hero.split p.lead{margin:0}
++.viz{background:var(--bg-card);border:1px solid var(--border);border-radius:20px;padding:14px;box-shadow:0 30px 80px rgba(0,0,0,.45),0 0 0 1px rgba(var(--site-rgb),.08);animation:rise .7s .25s cubic-bezier(.2,.8,.2,1) both;text-align:left}
++.viz figcaption{margin-top:10px;font-size:11.5px;color:var(--text-muted);text-align:center}
++.viz-top{display:flex;align-items:center;gap:8px;font-size:13px;padding:2px 4px 12px}
++.viz-top b{font-weight:700}.viz-top .muted{color:var(--text-muted)}
++.viz-top .lat{margin-left:auto;font-size:12px;color:var(--site);background:rgba(var(--site-rgb),.1);border:1px solid rgba(var(--site-rgb),.3);padding:3px 9px;border-radius:999px}
++.viz-top .dot{width:8px;height:8px;border-radius:50%;background:#22c55e;box-shadow:0 0 0 4px rgba(34,197,94,.18)}
++.viz-top .av{width:26px;height:26px;border-radius:8px;display:grid;place-items:center;background:rgba(var(--site-rgb),.15);color:var(--site);font-size:13px}
++.viz-video{position:relative;aspect-ratio:16/9;border-radius:14px;overflow:hidden;background:radial-gradient(120% 90% at 30% 20%,rgba(var(--site-rgb),.28),transparent 60%),linear-gradient(160deg,#1a2338,#0b1020 70%);border:1px solid var(--border)}
++.viz-video::after{content:'';position:absolute;left:10%;right:10%;bottom:0;height:42%;background:linear-gradient(transparent,rgba(0,0,0,.35)),repeating-linear-gradient(90deg,rgba(255,255,255,.05) 0 1px,transparent 1px 38px);transform:perspective(220px) rotateX(58deg);transform-origin:bottom}
++.viz-video .scan{position:absolute;inset:0;background:linear-gradient(transparent 0,rgba(255,255,255,.04) 50%,transparent 100%);background-size:100% 6px;opacity:.5}
++.viz-video .onair{position:absolute;top:10px;left:10px;font-size:11px;font-weight:700;padding:3px 8px;border-radius:6px;background:rgba(239,68,68,.9);color:#fff}.viz-video .onair i{font-size:7px;vertical-align:2px;margin-right:3px}
++.viz-video .cam{position:absolute;bottom:10px;right:10px;font-size:11px;color:#dbe4f5;background:rgba(0,0,0,.45);padding:3px 8px;border-radius:6px}
++.viz-ctrl{display:flex;gap:14px;align-items:center;margin-top:12px}
++.dpad{display:grid;grid-template-columns:repeat(3,34px);grid-template-rows:repeat(3,34px);gap:4px;flex:none}
++.dpad span{display:grid;place-items:center;border-radius:9px;background:var(--bg-hover);color:var(--text-primary);font-size:15px;border:1px solid var(--border)}
++.dpad .u{grid-area:1/2}.dpad .l{grid-area:2/1}.dpad .c{grid-area:2/2;background:rgba(var(--site-rgb),.15);border-color:rgba(var(--site-rgb),.35)}.dpad .r{grid-area:2/3}.dpad .d{grid-area:3/2}
++.dpad .u{background:rgba(var(--site-rgb),.22);border-color:rgba(var(--site-rgb),.5)}
++.viz-side{flex:1;min-width:0;display:grid;gap:8px}
++.viz-side .keys{display:flex;flex-wrap:wrap;gap:6px}
++.viz-side .keys span{font-size:11.5px;padding:5px 9px;border-radius:8px;background:var(--bg-secondary);border:1px solid var(--border);color:var(--text-secondary)}
++.viz-side .meter{display:flex;align-items:center;gap:8px;font-size:11.5px;color:var(--text-muted)}
++.viz-side .meter i{flex:1;height:6px;border-radius:9px;background:linear-gradient(90deg,#22c55e var(--v),var(--bg-hover) var(--v))}
++.viz-side .meter b{color:var(--text-secondary);font-weight:600}
++.viz-side .estop{justify-self:end;font-size:12px;font-weight:800;letter-spacing:.08em;color:#fff;background:#dc2626;border-radius:10px;padding:7px 16px;box-shadow:0 0 0 3px rgba(220,38,38,.25)}
++.feed{list-style:none;display:grid;gap:8px;padding:2px}
++.feed li{display:flex;align-items:flex-start;gap:10px;font-size:13.5px;line-height:1.45;padding:10px 12px;border-radius:12px;background:var(--bg-secondary);border:1px solid var(--border);color:var(--text-secondary)}
++.feed li i{color:#22c55e;margin-top:3px}
++.feed li.ask{flex-wrap:wrap;border-color:rgba(var(--site-rgb),.45);background:rgba(var(--site-rgb),.08);color:var(--text-primary)}.feed li.ask i{color:var(--site)}.feed li.ask>span:first-of-type{flex:1;min-width:160px}
++.feed .pills{display:flex;gap:6px;margin-left:auto}.feed .pills span{font-size:12px;font-weight:600;padding:4px 11px;border-radius:999px;border:1px solid var(--border);color:var(--text-secondary)}.feed .pills .ok{background:var(--site);border-color:var(--site);color:#0b0d10}
++.steps{list-style:none;display:grid;grid-template-columns:repeat(auto-fit,minmax(230px,1fr));gap:14px;counter-reset:s}
++.steps li{position:relative;background:var(--bg-card);border:1px solid var(--border);border-radius:16px;padding:20px 20px 20px;display:flex;flex-direction:column;gap:8px}
++.steps .n{width:30px;height:30px;border-radius:50%;display:grid;place-items:center;font-weight:800;font-size:14px;color:#0b0d10;background:var(--site)}
++.steps b{font-size:15px}.steps span:last-child{font-size:13px;color:var(--text-secondary);line-height:1.55}
++.grid.three{grid-template-columns:repeat(auto-fit,minmax(280px,1fr))}
++.choice{display:grid;grid-template-columns:repeat(auto-fit,minmax(280px,1fr));gap:14px}
++.card.big{padding:24px}.card.big b{font-size:17px}
++.chips{display:flex;flex-wrap:wrap;gap:7px;margin-top:6px}
++.chips span{font-size:12.5px;padding:6px 11px;border-radius:999px;border:1px solid var(--border);background:var(--bg-secondary);color:var(--text-secondary)}
++.chips.big span{font-size:13.5px;padding:9px 14px;color:var(--text-primary)}.chips.big span i{color:var(--site);margin-right:8px}
++.build .card{border-style:dashed;background:rgba(0,0,0,.15)}.build .card b i{color:var(--site);margin-right:6px}.build .card span a{color:var(--text-secondary)}.build .card code{font-size:12px}
++@media (max-width:860px){.hero.split{grid-template-columns:1fr;text-align:center;gap:28px}.hero.split .ctas{justify-content:center}.hero.split p.lead{margin:0 auto}}
++@media (max-width:600px){.hero{padding-top:56px}.ctas .btn{width:100%;justify-content:center}.viz-ctrl{flex-direction:column;align-items:stretch}.dpad{align-self:center}}
@media (prefers-reduced-motion:reduce){*{animation:none!important;transition:none!important}}
</style>
</head>
@@@ -95,41 +138,83 @@ a.card:hover{transform:translateY(-3px);border-color:rgba(var(--site-rgb),.6);bo
<div class="orbs"><i></i><i></i><i></i></div>
<div id="navbar-mount"></div>
<main class="wrap">
-- <header class="hero">
++ <header class="hero split"><div class="hero-main">
<div class="mark"><i class="fa-solid fa-user-astronaut" aria-hidden="true"></i></div>
-- <div class="badge"><span class="ov-mark" data-size="16" data-variant="actor"></span> Part of the OpenVibe network · <b>planned</b></div>
++ <div class="badge"><span class="ov-mark" data-size="16" data-variant="actor"></span> Part of the OpenVibe network · <b>being built</b></div>
<h1>OpenVibe<span class="d">.</span><span class="tld">Actor</span></h1>
-- <div class="tag">AI agents that act for you, with your permission.</div>
-- <p class="lead">OpenVibe.Actor will give you persistent AI agents that work across OpenVibe and, when you allow it, other sites and apps: they use OpenVibe&#39;s own APIs first and a sandboxed browser when they must. You decide what each agent may do, for once, a session, a while or always, and anything with real consequences (buying, sending, publishing, applying, moving a robot) waits for your approval, wherever you are on the network.</p>
++ <div class="tag">Your agent in the cloud, connected to everything OpenVibe.</div>
++ <p class="lead">OpenVibe.Actor gives you an AI agent that lives in OpenVibe&#39;s cloud and works for you around the clock. It remembers, runs on schedules and triggers, uses every OpenVibe product as a tool, browses and codes in a sandbox, and asks before it does anything that matters. Talk to it from any OpenVibe site, in chat, or from your own apps.</p>
<div class="ctas">
<a class="btn btn-primary" href="https://openvibe.network/login?return=https%3A%2F%2Fopenvibe.actor%2F"><i class="fa-solid fa-right-to-bracket"></i> Sign in with OpenVibe</a>
-- <a class="btn" href="https://openvibe.network/#network"><i class="fa-solid fa-circle-nodes"></i> The whole network</a>
++ <a class="btn" href="https://openvibe.network/#network"><i class="fa-solid fa-circle-nodes"></i> See the network</a>
<a class="btn" href="https://discord.gg/M6MuRUaeJj" rel="noopener"><i class="fa-brands fa-discord"></i> Follow the build</a>
</div>
-- <p class="status"><i class="fa-solid fa-clock" aria-hidden="true"></i> Status: <b>planned</b> · <strong>OpenVibe.Actor</strong> is planned; its repository and code do not exist yet: this page is a placeholder, nothing here is live yet. The public launch is waiting for agent principals and delegated grants on OpenVibe.Network and the agent service. · as of 2026-09-29 · <a href="/status.json">status.json</a></p>
++ </div>
++ <figure class="viz" aria-label="Design preview: an agent&#39;s activity feed ending in a request for approval">
++ <div class="viz-top"><span class="av"><i class="fa-solid fa-user-astronaut" aria-hidden="true"></i></span><b>Nova</b><span class="muted">stream co-host</span><span class="lat"><i class="fa-solid fa-cloud" aria-hidden="true"></i> always on</span></div>
++ <ol class="feed"><li><i class="fa-solid fa-circle-check" aria-hidden="true"></i><span>Watched tonight&#39;s stream and marked 3 highlights</span></li><li><i class="fa-solid fa-circle-check" aria-hidden="true"></i><span>Clipped the best one on OpenVibe.Media</span></li><li><i class="fa-solid fa-circle-check" aria-hidden="true"></i><span>Drafted a post for your blog with the clip</span></li>
++ <li class="ask"><i class="fa-solid fa-hand" aria-hidden="true"></i><span>Publish the post on openvibe.blog?</span><span class="pills" aria-hidden="true"><span class="ok">Approve</span><span>Not yet</span></span></li></ol>
++ <figcaption>Design preview of an agent at work</figcaption>
++ </figure>
</header>
<section id="what">
-- <h2>What OpenVibe.Actor will be</h2>
-- <p class="lead2">Same account, same themes, same navbar as every other OpenVibe site — built in the open, run by its community.</p>
-- <div class="grid">
-- <div class="card"><div class="ic"><i class="fa-solid fa-user-astronaut" aria-hidden="true"></i></div><b>Your agents</b><span>Personas, memory, tools, schedules and budgets you control.</span></div>
-- <div class="card"><div class="ic"><i class="fa-solid fa-user-astronaut" aria-hidden="true"></i></div><b>Permission first</b><span>Delegated grants and approvals, never an all-powerful account.</span></div>
-- <div class="card"><div class="ic"><i class="fa-solid fa-user-astronaut" aria-hidden="true"></i></div><b>Any model</b><span>Routed through OpenVibe.AI: hosted, open or local models.</span></div>
-- <div class="card"><div class="ic"><i class="fa-solid fa-user-astronaut" aria-hidden="true"></i></div><b>Works with everything</b><span>Watch, Website, Work, Bot, Events, Tools and more.</span></div>
++ <h2>Start in a minute</h2>
++ <p class="lead2">Describe what you want or start from a template. Change anything later.</p>
++ <ol class="steps">
++ <li><span class="n">1</span><b>Create an agent</b><span>Pick a template or describe the job in your own words. Choose its model and its personality.</span></li>
++ <li><span class="n">2</span><b>Decide what it may do</b><span>Grant it tools one by one. Anything with consequences, like publishing, spending or moving a robot, waits for your approval.</span></li>
++ <li><span class="n">3</span><b>Let it work</b><span>It runs in the cloud on schedules and triggers, and you can reach it from any OpenVibe site.</span></li>
++ </ol>
++ </section>
++
++
++ <section>
++ <h2>What your agent can do</h2>
++ <p class="lead2">An agent is only as useful as what it can reach. Yours can reach the whole network.</p>
++ <div class="grid three">
++ <div class="card"><div class="ic"><i class="fa-solid fa-cloud" aria-hidden="true"></i></div><b>Always on</b><span>Runs in OpenVibe&#39;s cloud around the clock. Close your laptop; it keeps going.</span></div>
++ <div class="card"><div class="ic"><i class="fa-solid fa-circle-nodes" aria-hidden="true"></i></div><b>Uses the whole network</b><span>Live, Chat, Blog, Wiki, Community, Tools, Media, Host, Bot and more, each through its own API.</span></div>
++ <div class="card"><div class="ic"><i class="fa-solid fa-window-maximize" aria-hidden="true"></i></div><b>Browses and codes</b><span>A sandboxed browser and code runner for work outside the network.</span></div>
++ <div class="card"><div class="ic"><i class="fa-solid fa-brain" aria-hidden="true"></i></div><b>Remembers</b><span>Long-term memory you can read, edit and wipe.</span></div>
++ <div class="card"><div class="ic"><i class="fa-solid fa-hand" aria-hidden="true"></i></div><b>Asks first</b><span>An approval inbox, a full activity log, spending limits and a kill switch.</span></div>
++ <div class="card"><div class="ic"><i class="fa-solid fa-shuffle" aria-hidden="true"></i></div><b>Any model</b><span>Routed through OpenVibe.AI: hosted, open or local models, or your own key.</span></div>
</div>
</section>
++ <section>
++ <h2>Start from a template</h2>
++ <p class="lead2">Each one is a starting point you can change.</p>
++ <div class="chips big"><span><i class="fa-solid fa-tower-broadcast" aria-hidden="true"></i>Stream co-host</span><span><i class="fa-solid fa-shield" aria-hidden="true"></i>Chat moderator</span><span><i class="fa-solid fa-magnifying-glass" aria-hidden="true"></i>Research assistant</span><span><i class="fa-solid fa-globe" aria-hidden="true"></i>Site builder</span><span><i class="fa-solid fa-robot" aria-hidden="true"></i>Robot pilot</span><span><i class="fa-solid fa-calendar-check" aria-hidden="true"></i>Personal assistant</span></div>
++ </section>
++
<section class="meanwhile">
-- <h2>Meanwhile, on the network</h2>
-- <p class="lead2">Most of this already exists somewhere on OpenVibe — start there today.</p>
++ <h2>Reachable everywhere</h2>
++ <p class="lead2">Your agent is part of the network, not a separate app.</p>
<div class="grid">
-- <a class="card" href="https://openvibe.tools"><div class="ic"><i class="fa-solid fa-arrow-up-right-from-square" aria-hidden="true"></i></div><b>OpenVibe.Tools</b><span>Tools agents will call, usable by people today.</span><span class="go">openvibe.tools →</span></a>
-- <a class="card" href="https://openvibe.codes"><div class="ic"><i class="fa-solid fa-arrow-up-right-from-square" aria-hidden="true"></i></div><b>OpenVibe.Codes</b><span>The API and SDK agents are built on.</span><span class="go">openvibe.codes →</span></a>
++ <div class="card"><div class="ic"><i class="fa-solid fa-bars" aria-hidden="true"></i></div><b>On every OpenVibe site</b><span>An agent button in the navbar, with the page you are on as context.</span></div>
++ <a class="card" href="https://openvibe.chat"><div class="ic"><i class="fa-solid fa-comments" aria-hidden="true"></i></div><b>In chat</b><span>Direct messages on OpenVibe.Chat and @mentions in Live chat and Community threads.</span><span class="go">openvibe.chat →</span></a>
++ <a class="card" href="https://openvibe.bot"><div class="ic"><i class="fa-solid fa-robot" aria-hidden="true"></i></div><b>With your robots</b><span>Give it a robot on OpenVibe.Bot to patrol, check on or perform with, with your approval.</span><span class="go">openvibe.bot →</span></a>
++ <a class="card" href="https://openvibe.codes"><div class="ic"><i class="fa-solid fa-plug" aria-hidden="true"></i></div><b>From your own apps</b><span>An API, webhooks and an MCP server, so other assistants can use OpenVibe tools and talk to your agent.</span><span class="go">openvibe.codes →</span></a>
</div>
</section>
++ <section id="questions" class="faq">
++ <h2>Questions</h2>
++ <details><summary>How is this different from a chat assistant?</summary><p>It keeps working when you leave: it has memory, schedules and triggers, and it can act across OpenVibe with the permissions you give it.</p></details>
++ <details><summary>Can it do things without asking?</summary><p>Only what you allow. You grant each tool, and anything with consequences waits for your approval. Every action is logged, and you can stop an agent at any time.</p></details>
++ <details><summary>Which AI models does it use?</summary><p>Any model OpenVibe.AI routes to, including open and local models, or your own API key.</p></details>
++ <details><summary>Can other apps use my agent?</summary><p>Yes: an API, webhooks and an MCP server connect it to other tools and assistants.</p></details>
++ <details><summary>What will it cost?</summary><p>You will be able to start without paying, within limits published before launch; heavier use and bigger models will be paid.</p></details>
++ </section>
++
++ <section class="build">
++ <div class="card">
++ <b><i class="fa-solid fa-person-digging" aria-hidden="true"></i> Build status</b>
++ <span>OpenVibe.Actor is being built now, on the network&#39;s accounts, AI router and event system that already run. Its own service is not running yet: this page is a placeholder, nothing here is live yet. It opens with agent accounts with delegated permissions on OpenVibe.Network and the Actor service. · as of 2026-09-29 · <a href="/status.json">status.json</a></span>
++ </div>
++ </section>
<section class="net">
<h2>The OpenVibe network</h2>
@@@ -279,7 +364,7 @@ a.card:hover{transform:translateY(-3px);border-color:rgba(var(--site-rgb),.6);bo
<script src="/shared/footer.js?v=a85ab893be88"></script>
<script>
(function () {
-- if (window.OpenVibeNavbar) { try { OpenVibeNavbar.init({ service: 'actor', apiBase: 'https://openvibe.network', links: [{ label: 'What it will be', href: '#what' }, { label: 'The network', href: 'https://openvibe.network/#network', external: false }], history: { type: 'page', title: 'OpenVibe.Actor' } }); } catch (e) {} }
++ if (window.OpenVibeNavbar) { try { OpenVibeNavbar.init({ service: 'actor', apiBase: 'https://openvibe.network', links: [{ label: 'How it works', href: '#what' }, { label: 'The network', href: 'https://openvibe.network/#network', external: false }], history: { type: 'page', title: 'OpenVibe.Actor' } }); } catch (e) {} }
if (window.OpenVibeFooter) { try { OpenVibeFooter.init({ service: 'actor', variant: 'full', links: [{ heading: 'OpenVibe.Actor', items: [{ name: 'Sign in', url: 'https://openvibe.network/login?return=https%3A%2F%2Fopenvibe.actor%2F' }, { name: 'The network', url: 'https://openvibe.network/#network' }, { name: 'Discord', url: 'https://discord.gg/M6MuRUaeJj' }] }] }); } catch (e) {} }
})();
</script>
ddiff --git a/dist/openvibe.actor/manifest.webmanifest b/dist/openvibe.actor/manifest.webmanifest
iindex feb2984..5115b7a 100644
---- a/dist/openvibe.actor/manifest.webmanifest
++++ b/dist/openvibe.actor/manifest.webmanifest
@@@ -1,7 +1,7 @@
{
"name": "OpenVibe.Actor",
"short_name": "Actor",
-- "description": "AI agents that act for you, with your permission.",
++ "description": "Your agent in the cloud, connected to everything OpenVibe.",
"start_url": "/",
"scope": "/",
"display": "standalone",
ddiff --git a/dist/openvibe.actor/release.json b/dist/openvibe.actor/release.json
iindex 72c3219..542471c 100644
---- a/dist/openvibe.actor/release.json
++++ b/dist/openvibe.actor/release.json
@@@ -1,6 +1,6 @@
{
"service": "actor",
-- "release": "8f57dc63e5d8",
++ "release": "d726e134d007",
"released_at": "2026-09-29T00:00:00.000Z",
"booted_at": null,
"contracts_version": null,
ddiff --git a/dist/openvibe.actor/status.json b/dist/openvibe.actor/status.json
iindex a6e0728..ac1bb73 100644
---- a/dist/openvibe.actor/status.json
++++ b/dist/openvibe.actor/status.json
@@@ -8,7 +8,7 @@
"repoExists": false,
"repoStage": "charter-only",
"service": null,
-- "launchWaitsFor": "agent principals and delegated grants on OpenVibe.Network and the agent service",
++ "launchWaitsFor": "agent accounts with delegated permissions on OpenVibe.Network and the Actor service",
"factsAsOf": "2026-09-29",
"network": "https://openvibe.network",
"updated": "2026-09-29",
ddiff --git a/dist/openvibe.bot/index.html b/dist/openvibe.bot/index.html
iindex ef8be3d..30e3e3d 100644
---- a/dist/openvibe.bot/index.html
++++ b/dist/openvibe.bot/index.html
@@@ -3,9 +3,9 @@
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
--<title>OpenVibe.Bot — Robots, cameras and devices you can share safely.</title>
--<meta name="description" content="OpenVibe.Bot will let you register robots, Raspberry Pis, cameras, motors, sensors and other devices, pair them securely, and control them yourself or hand control to friends, stream viewers, apps or your AI agents with timed turns, queues and permissions. Safety runs on the device too: heartbeats, command time limits, speed and range limits and an emergency stop that works without the cloud. OpenVibe.Live already runs stream-controlled robots; Bot makes the device its own thing.">
--<meta name="keywords" content="remote control robot, stream controlled robot, raspberry pi robot control, telepresence robot, iot device control api">
++<title>OpenVibe.Bot — Get your robot online in minutes.</title>
++<meta name="description" content="OpenVibe.Bot is an open control panel for robots. Add a robot, pair it with one command or a QR code, and drive it from any browser with live video, real controls and a stop button that always works. Buy a ready-made bot or bring your own Raspberry Pi, ESP32, ROS 2 robot or phone. Share control, automate it, hand it to your AI agent, and stream it to OpenVibe.Live or openre.stream when you want to.">
++<meta name="keywords" content="robot control panel, control a robot from the browser, remote control robot online, raspberry pi robot web control, esp32 robot control, ros 2 web control, telepresence robot, stream a robot live, open source robot controller">
<meta name="robots" content="index, follow, max-image-preview:large">
<meta name="theme-color" content="#f472b6">
<link rel="canonical" href="https://openvibe.bot/">
@@@ -16,15 +16,15 @@
<meta property="og:type" content="website">
<meta property="og:site_name" content="OpenVibe.Bot">
<meta property="og:url" content="https://openvibe.bot/">
--<meta property="og:title" content="OpenVibe.Bot — Robots, cameras and devices you can share safely.">
--<meta property="og:description" content="OpenVibe.Bot will let you register robots, Raspberry Pis, cameras, motors, sensors and other devices, pair them securely, and control them yourself or hand control to friends, stream viewers, apps or your AI agents with timed turns, queues and permissions. Safety runs on the device too: heartbeats, command time limits, speed and range limits and an emergency stop that works without the cloud. OpenVibe.Live already runs stream-controlled robots; Bot makes the device its own thing.">
++<meta property="og:title" content="OpenVibe.Bot — Get your robot online in minutes.">
++<meta property="og:description" content="OpenVibe.Bot is an open control panel for robots. Add a robot, pair it with one command or a QR code, and drive it from any browser with live video, real controls and a stop button that always works. Buy a ready-made bot or bring your own Raspberry Pi, ESP32, ROS 2 robot or phone. Share control, automate it, hand it to your AI agent, and stream it to OpenVibe.Live or openre.stream when you want to.">
<meta property="og:image" content="https://openvibe.network/assets/logo-512.png">
<meta property="og:image:alt" content="OpenVibe">
<meta name="twitter:card" content="summary">
--<meta name="twitter:title" content="OpenVibe.Bot — Robots, cameras and devices you can share safely.">
--<meta name="twitter:description" content="OpenVibe.Bot will let you register robots, Raspberry Pis, cameras, motors, sensors and other devices, pair them securely, and control them yourself or hand control to friends, stream viewers, apps or your AI agents with timed turns, queues and permissions. Safety runs on the device too: heartbeats, command time limits, speed and range limits and an emergency stop that works without the cloud. OpenVibe.Live already runs stream-controlled robots; Bot makes the device its own thing.">
++<meta name="twitter:title" content="OpenVibe.Bot — Get your robot online in minutes.">
++<meta name="twitter:description" content="OpenVibe.Bot is an open control panel for robots. Add a robot, pair it with one command or a QR code, and drive it from any browser with live video, real controls and a stop button that always works. Buy a ready-made bot or bring your own Raspberry Pi, ESP32, ROS 2 robot or phone. Share control, automate it, hand it to your AI agent, and stream it to OpenVibe.Live or openre.stream when you want to.">
<meta name="twitter:image" content="https://openvibe.network/assets/logo-512.png">
--<script type="application/ld+json">{"@context":"https://schema.org","@graph":[{"@type":"WebSite","@id":"https://openvibe.bot/#site","url":"https://openvibe.bot/","name":"OpenVibe.Bot","description":"OpenVibe.Bot will let you register robots, Raspberry Pis, cameras, motors, sensors and other devices, pair them securely, and control them yourself or hand control to friends, stream viewers, apps or your AI agents with timed turns, queues and permissions. Safety runs on the device too: heartbeats, command time limits, speed and range limits and an emergency stop that works without the cloud. OpenVibe.Live already runs stream-controlled robots; Bot makes the device its own thing.","inLanguage":"en","publisher":{"@type":"Organization","@id":"https://openvibe.network/#org","name":"OpenVibe","url":"https://openvibe.network/","logo":"https://openvibe.network/assets/logo-512.png","sameAs":["https://github.com/OpenVibers","https://discord.gg/M6MuRUaeJj"]},"isPartOf":{"@type":"WebSite","@id":"https://openvibe.network/#site","name":"OpenVibe.Network","url":"https://openvibe.network/"}},{"@type":"WebPage","@id":"https://openvibe.bot/#page","url":"https://openvibe.bot/","name":"OpenVibe.Bot — Robots, cameras and devices you can share safely.","description":"OpenVibe.Bot will let you register robots, Raspberry Pis, cameras, motors, sensors and other devices, pair them securely, and control them yourself or hand control to friends, stream viewers, apps or your AI agents with timed turns, queues and permissions. Safety runs on the device too: heartbeats, command time limits, speed and range limits and an emergency stop that works without the cloud. OpenVibe.Live already runs stream-controlled robots; Bot makes the device its own thing.","isPartOf":{"@id":"https://openvibe.bot/#site"},"datePublished":"2026-09-17","dateModified":"2026-09-29","breadcrumb":{"@type":"BreadcrumbList","itemListElement":[{"@type":"ListItem","position":1,"name":"OpenVibe","item":"https://openvibe.network/"},{"@type":"ListItem","position":2,"name":"OpenVibe.Bot","item":"https://openvibe.bot/"}]}}]}</script>
++<script type="application/ld+json">{"@context":"https://schema.org","@graph":[{"@type":"WebSite","@id":"https://openvibe.bot/#site","url":"https://openvibe.bot/","name":"OpenVibe.Bot","description":"OpenVibe.Bot is an open control panel for robots. Add a robot, pair it with one command or a QR code, and drive it from any browser with live video, real controls and a stop button that always works. Buy a ready-made bot or bring your own Raspberry Pi, ESP32, ROS 2 robot or phone. Share control, automate it, hand it to your AI agent, and stream it to OpenVibe.Live or openre.stream when you want to.","inLanguage":"en","publisher":{"@type":"Organization","@id":"https://openvibe.network/#org","name":"OpenVibe","url":"https://openvibe.network/","logo":"https://openvibe.network/assets/logo-512.png","sameAs":["https://github.com/OpenVibers","https://discord.gg/M6MuRUaeJj"]},"isPartOf":{"@type":"WebSite","@id":"https://openvibe.network/#site","name":"OpenVibe.Network","url":"https://openvibe.network/"}},{"@type":"WebPage","@id":"https://openvibe.bot/#page","url":"https://openvibe.bot/","name":"OpenVibe.Bot — Get your robot online in minutes.","description":"OpenVibe.Bot is an open control panel for robots. Add a robot, pair it with one command or a QR code, and drive it from any browser with live video, real controls and a stop button that always works. Buy a ready-made bot or bring your own Raspberry Pi, ESP32, ROS 2 robot or phone. Share control, automate it, hand it to your AI agent, and stream it to OpenVibe.Live or openre.stream when you want to.","isPartOf":{"@id":"https://openvibe.bot/#site"},"datePublished":"2026-09-17","dateModified":"2026-09-29","breadcrumb":{"@type":"BreadcrumbList","itemListElement":[{"@type":"ListItem","position":1,"name":"OpenVibe","item":"https://openvibe.network/"},{"@type":"ListItem","position":2,"name":"OpenVibe.Bot","item":"https://openvibe.bot/"}]}},{"@type":"FAQPage","@id":"https://openvibe.bot/#faq","mainEntity":[{"@type":"Question","name":"Do I need to open ports on my router?","acceptedAnswer":{"@type":"Answer","text":"No. The robot connects out to OpenVibe, and video and controls travel over WebRTC, so it works behind ordinary home and mobile networks."}},{"@type":"Question","name":"Is it only for streaming?","acceptedAnswer":{"@type":"Answer","text":"No. Streaming is optional. Bot is a control panel for your robot first: drive it, check on it, share it and automate it."}},{"@type":"Question","name":"What hardware works?","acceptedAnswer":{"@type":"Answer","text":"A Raspberry Pi or another Linux board, an ESP32, a ROS 2 robot, an Android phone, or an ONVIF or RTSP camera. The curated kits list exactly what to buy."}},{"@type":"Question","name":"How does it keep the robot safe?","acceptedAnswer":{"@type":"Answer","text":"The device stops its motors by itself when commands or the connection stop. There is an emergency stop in the panel, limits on speed, range and time, and every command is logged."}},{"@type":"Question","name":"What will it cost?","acceptedAnswer":{"@type":"Answer","text":"Controlling your own robot will not cost anything. Limits and any paid extras will be published before launch."}}]}]}</script>
<script>(function(){try{var raw=localStorage.getItem('ov_theme');if(!raw)return;var t=JSON.parse(raw),v=t&&t.variables;if(!v)return;var el=document.documentElement;for(var k in v)if(k.charAt(0)==='-')el.style.setProperty(k,v[k]);if(t.id)el.setAttribute('data-theme',t.id);}catch(_){}})();</script>
<script src="/shared/theme-loader.js?v=ee4a6754d0f7" defer></script>
<link rel="preconnect" href="https://cdnjs.cloudflare.com" crossorigin>
@@@ -87,7 +87,50 @@ a.card:hover{transform:translateY(-3px);border-color:rgba(var(--site-rgb),.6);bo
.strip h3{font-size:19px;font-weight:700;margin:12px 0 8px}
.strip p{font-size:14px;color:var(--text-secondary);max-width:600px;margin:0 auto 18px;line-height:1.6}
.strip .ov-mark{width:44px;height:44px}
--@media (max-width:600px){.hero{padding-top:56px}.ctas .btn{width:100%;justify-content:center}}
++.hero.split{display:grid;grid-template-columns:minmax(0,1.05fr) minmax(0,1fr);gap:40px;align-items:center;text-align:left;padding-top:64px}
++.hero.split .ctas{justify-content:flex-start}.hero.split p.lead{margin:0}
++.viz{background:var(--bg-card);border:1px solid var(--border);border-radius:20px;padding:14px;box-shadow:0 30px 80px rgba(0,0,0,.45),0 0 0 1px rgba(var(--site-rgb),.08);animation:rise .7s .25s cubic-bezier(.2,.8,.2,1) both;text-align:left}
++.viz figcaption{margin-top:10px;font-size:11.5px;color:var(--text-muted);text-align:center}
++.viz-top{display:flex;align-items:center;gap:8px;font-size:13px;padding:2px 4px 12px}
++.viz-top b{font-weight:700}.viz-top .muted{color:var(--text-muted)}
++.viz-top .lat{margin-left:auto;font-size:12px;color:var(--site);background:rgba(var(--site-rgb),.1);border:1px solid rgba(var(--site-rgb),.3);padding:3px 9px;border-radius:999px}
++.viz-top .dot{width:8px;height:8px;border-radius:50%;background:#22c55e;box-shadow:0 0 0 4px rgba(34,197,94,.18)}
++.viz-top .av{width:26px;height:26px;border-radius:8px;display:grid;place-items:center;background:rgba(var(--site-rgb),.15);color:var(--site);font-size:13px}
++.viz-video{position:relative;aspect-ratio:16/9;border-radius:14px;overflow:hidden;background:radial-gradient(120% 90% at 30% 20%,rgba(var(--site-rgb),.28),transparent 60%),linear-gradient(160deg,#1a2338,#0b1020 70%);border:1px solid var(--border)}
++.viz-video::after{content:'';position:absolute;left:10%;right:10%;bottom:0;height:42%;background:linear-gradient(transparent,rgba(0,0,0,.35)),repeating-linear-gradient(90deg,rgba(255,255,255,.05) 0 1px,transparent 1px 38px);transform:perspective(220px) rotateX(58deg);transform-origin:bottom}
++.viz-video .scan{position:absolute;inset:0;background:linear-gradient(transparent 0,rgba(255,255,255,.04) 50%,transparent 100%);background-size:100% 6px;opacity:.5}
++.viz-video .onair{position:absolute;top:10px;left:10px;font-size:11px;font-weight:700;padding:3px 8px;border-radius:6px;background:rgba(239,68,68,.9);color:#fff}.viz-video .onair i{font-size:7px;vertical-align:2px;margin-right:3px}
++.viz-video .cam{position:absolute;bottom:10px;right:10px;font-size:11px;color:#dbe4f5;background:rgba(0,0,0,.45);padding:3px 8px;border-radius:6px}
++.viz-ctrl{display:flex;gap:14px;align-items:center;margin-top:12px}
++.dpad{display:grid;grid-template-columns:repeat(3,34px);grid-template-rows:repeat(3,34px);gap:4px;flex:none}
++.dpad span{display:grid;place-items:center;border-radius:9px;background:var(--bg-hover);color:var(--text-primary);font-size:15px;border:1px solid var(--border)}
++.dpad .u{grid-area:1/2}.dpad .l{grid-area:2/1}.dpad .c{grid-area:2/2;background:rgba(var(--site-rgb),.15);border-color:rgba(var(--site-rgb),.35)}.dpad .r{grid-area:2/3}.dpad .d{grid-area:3/2}
++.dpad .u{background:rgba(var(--site-rgb),.22);border-color:rgba(var(--site-rgb),.5)}
++.viz-side{flex:1;min-width:0;display:grid;gap:8px}
++.viz-side .keys{display:flex;flex-wrap:wrap;gap:6px}
++.viz-side .keys span{font-size:11.5px;padding:5px 9px;border-radius:8px;background:var(--bg-secondary);border:1px solid var(--border);color:var(--text-secondary)}
++.viz-side .meter{display:flex;align-items:center;gap:8px;font-size:11.5px;color:var(--text-muted)}
++.viz-side .meter i{flex:1;height:6px;border-radius:9px;background:linear-gradient(90deg,#22c55e var(--v),var(--bg-hover) var(--v))}
++.viz-side .meter b{color:var(--text-secondary);font-weight:600}
++.viz-side .estop{justify-self:end;font-size:12px;font-weight:800;letter-spacing:.08em;color:#fff;background:#dc2626;border-radius:10px;padding:7px 16px;box-shadow:0 0 0 3px rgba(220,38,38,.25)}
++.feed{list-style:none;display:grid;gap:8px;padding:2px}
++.feed li{display:flex;align-items:flex-start;gap:10px;font-size:13.5px;line-height:1.45;padding:10px 12px;border-radius:12px;background:var(--bg-secondary);border:1px solid var(--border);color:var(--text-secondary)}
++.feed li i{color:#22c55e;margin-top:3px}
++.feed li.ask{flex-wrap:wrap;border-color:rgba(var(--site-rgb),.45);background:rgba(var(--site-rgb),.08);color:var(--text-primary)}.feed li.ask i{color:var(--site)}.feed li.ask>span:first-of-type{flex:1;min-width:160px}
++.feed .pills{display:flex;gap:6px;margin-left:auto}.feed .pills span{font-size:12px;font-weight:600;padding:4px 11px;border-radius:999px;border:1px solid var(--border);color:var(--text-secondary)}.feed .pills .ok{background:var(--site);border-color:var(--site);color:#0b0d10}
++.steps{list-style:none;display:grid;grid-template-columns:repeat(auto-fit,minmax(230px,1fr));gap:14px;counter-reset:s}
++.steps li{position:relative;background:var(--bg-card);border:1px solid var(--border);border-radius:16px;padding:20px 20px 20px;display:flex;flex-direction:column;gap:8px}
++.steps .n{width:30px;height:30px;border-radius:50%;display:grid;place-items:center;font-weight:800;font-size:14px;color:#0b0d10;background:var(--site)}
++.steps b{font-size:15px}.steps span:last-child{font-size:13px;color:var(--text-secondary);line-height:1.55}
++.grid.three{grid-template-columns:repeat(auto-fit,minmax(280px,1fr))}
++.choice{display:grid;grid-template-columns:repeat(auto-fit,minmax(280px,1fr));gap:14px}
++.card.big{padding:24px}.card.big b{font-size:17px}
++.chips{display:flex;flex-wrap:wrap;gap:7px;margin-top:6px}
++.chips span{font-size:12.5px;padding:6px 11px;border-radius:999px;border:1px solid var(--border);background:var(--bg-secondary);color:var(--text-secondary)}
++.chips.big span{font-size:13.5px;padding:9px 14px;color:var(--text-primary)}.chips.big span i{color:var(--site);margin-right:8px}
++.build .card{border-style:dashed;background:rgba(0,0,0,.15)}.build .card b i{color:var(--site);margin-right:6px}.build .card span a{color:var(--text-secondary)}.build .card code{font-size:12px}
++@media (max-width:860px){.hero.split{grid-template-columns:1fr;text-align:center;gap:28px}.hero.split .ctas{justify-content:center}.hero.split p.lead{margin:0 auto}}
++@media (max-width:600px){.hero{padding-top:56px}.ctas .btn{width:100%;justify-content:center}.viz-ctrl{flex-direction:column;align-items:stretch}.dpad{align-self:center}}
@media (prefers-reduced-motion:reduce){*{animation:none!important;transition:none!important}}
</style>
</head>
@@@ -95,41 +138,93 @@ a.card:hover{transform:translateY(-3px);border-color:rgba(var(--site-rgb),.6);bo
<div class="orbs"><i></i><i></i><i></i></div>
<div id="navbar-mount"></div>
<main class="wrap">
-- <header class="hero">
++ <header class="hero split"><div class="hero-main">
<div class="mark"><i class="fa-solid fa-robot" aria-hidden="true"></i></div>
-- <div class="badge"><span class="ov-mark" data-size="16" data-variant="bot"></span> Part of the OpenVibe network · <b>planned</b></div>
++ <div class="badge"><span class="ov-mark" data-size="16" data-variant="bot"></span> Part of the OpenVibe network · <b>being built</b></div>
<h1>OpenVibe<span class="d">.</span><span class="tld">Bot</span></h1>
-- <div class="tag">Robots, cameras and devices you can share safely.</div>
-- <p class="lead">OpenVibe.Bot will let you register robots, Raspberry Pis, cameras, motors, sensors and other devices, pair them securely, and control them yourself or hand control to friends, stream viewers, apps or your AI agents with timed turns, queues and permissions. Safety runs on the device too: heartbeats, command time limits, speed and range limits and an emergency stop that works without the cloud. OpenVibe.Live already runs stream-controlled robots; Bot makes the device its own thing.</p>
++ <div class="tag">Get your robot online in minutes.</div>
++ <p class="lead">OpenVibe.Bot is an open control panel for robots. Add a robot, pair it with one command or a QR code, and drive it from any browser with live video, real controls and a stop button that always works. Buy a ready-made bot or bring your own Raspberry Pi, ESP32, ROS 2 robot or phone. Share control, automate it, hand it to your AI agent, and stream it to OpenVibe.Live or openre.stream when you want to.</p>
<div class="ctas">
<a class="btn btn-primary" href="https://openvibe.network/login?return=https%3A%2F%2Fopenvibe.bot%2F"><i class="fa-solid fa-right-to-bracket"></i> Sign in with OpenVibe</a>
-- <a class="btn" href="https://openvibe.network/#network"><i class="fa-solid fa-circle-nodes"></i> The whole network</a>
++ <a class="btn" href="https://openvibe.live"><i class="fa-solid fa-tower-broadcast"></i> Robots on Live today</a>
<a class="btn" href="https://discord.gg/M6MuRUaeJj" rel="noopener"><i class="fa-brands fa-discord"></i> Follow the build</a>
</div>
-- <p class="status"><i class="fa-solid fa-clock" aria-hidden="true"></i> Status: <b>planned</b> · <strong>OpenVibe.Bot</strong> is planned; its repository and code do not exist yet: this page is a placeholder, nothing here is live yet. The public launch is waiting for device pairing and control leases split out of OpenVibe.Live. · as of 2026-09-29 · <a href="/status.json">status.json</a></p>
++ </div>
++ <figure class="viz" aria-label="Design preview: a robot control panel with live video, a drive pad, buttons, battery level and a stop button">
++ <div class="viz-top"><span class="dot"></span><b>Rover-1</b><span class="muted">online</span><span class="lat"><i class="fa-solid fa-signal" aria-hidden="true"></i> 84 ms</span></div>
++ <div class="viz-video" aria-hidden="true"><div class="scan"></div><span class="onair"><i class="fa-solid fa-circle" aria-hidden="true"></i> Streaming to openvibe.live</span><span class="cam"><i class="fa-solid fa-video" aria-hidden="true"></i> Front camera</span></div>
++ <div class="viz-ctrl" aria-hidden="true">
++ <div class="dpad"><span class="u"><i class="fa-solid fa-caret-up"></i></span><span class="l"><i class="fa-solid fa-caret-left"></i></span><span class="c"></span><span class="r"><i class="fa-solid fa-caret-right"></i></span><span class="d"><i class="fa-solid fa-caret-down"></i></span></div>
++ <div class="viz-side">
++ <div class="keys"><span><i class="fa-solid fa-lightbulb"></i> Lights</span><span><i class="fa-solid fa-bullhorn"></i> Horn</span><span><i class="fa-solid fa-comment"></i> Speak</span><span><i class="fa-solid fa-camera-rotate"></i> Camera</span></div>
++ <div class="meter"><span>Battery</span><i style="--v:82%"></i><b>82%</b></div>
++ <div class="estop">STOP</div>
++ </div>
++ </div>
++ <figcaption>Design preview of the robot panel</figcaption>
++ </figure>
</header>
<section id="what">
-- <h2>What OpenVibe.Bot will be</h2>
-- <p class="lead2">Same account, same themes, same navbar as every other OpenVibe site — built in the open, run by its community.</p>
-- <div class="grid">
-- <div class="card"><div class="ic"><i class="fa-solid fa-robot" aria-hidden="true"></i></div><b>Pair devices</b><span>Revocable device keys and one-time pairing codes, not stream keys.</span></div>
-- <div class="card"><div class="ic"><i class="fa-solid fa-robot" aria-hidden="true"></i></div><b>Share control</b><span>Owner, whitelist, queues, timed turns, moderators and apps.</span></div>
-- <div class="card"><div class="ic"><i class="fa-solid fa-robot" aria-hidden="true"></i></div><b>Safe on the device</b><span>Dead-man stop, command limits and local emergency stop.</span></div>
-- <div class="card"><div class="ic"><i class="fa-solid fa-robot" aria-hidden="true"></i></div><b>Stream it</b><span>Connect a device to a Live stream, a game or a website.</span></div>
++ <h2>Online in three steps</h2>
++ <p class="lead2">No port forwarding, no stream keys, no config files.</p>
++ <ol class="steps">
++ <li><span class="n">1</span><b>Add a robot</b><span>Name it and pick what it is: a rover, an arm, a camera, a phone on wheels or your own design.</span></li>
++ <li><span class="n">2</span><b>Pair it</b><span>Paste one command on the robot, flash a ready-made card, or scan a QR code. It gets its own key, which you can revoke any time.</span></li>
++ <li><span class="n">3</span><b>Drive it</b><span>Live video and controls in any browser, phone included, with a stop button that always works.</span></li>
++ </ol>
++ </section>
++
++ <section>
++ <h2>Buy one or bring your own</h2>
++ <p class="lead2">Start with hardware that is known to work, or use what you already have.</p>
++ <div class="choice">
++ <div class="card big"><div class="ic"><i class="fa-solid fa-box-open" aria-hidden="true"></i></div><b>Get a robot</b><span>Curated kits with parts lists, tested settings and build guides, and ready-made bots that arrive paired to your account.</span><div class="chips"><span>Rover kits</span><span>Telepresence bots</span><span>Pan-tilt cameras</span><span>Robot arms</span></div></div>
++ <div class="card big"><div class="ic"><i class="fa-solid fa-screwdriver-wrench" aria-hidden="true"></i></div><b>Bring your own</b><span>Anything with motors, a camera or sensors. Install the OpenVibe device agent or add the library, and your robot shows up in the panel.</span><div class="chips"><span>Raspberry Pi and Linux boards</span><span>ESP32</span><span>ROS 2</span><span>Android phones</span><span>ONVIF and RTSP cameras</span><span>Serial motor boards</span></div></div>
++ </div>
++ </section>
++
++ <section>
++ <h2>More than a stream</h2>
++ <p class="lead2">A control panel for anything you build, whether or not anyone is watching.</p>
++ <div class="grid three">
++ <div class="card"><div class="ic"><i class="fa-solid fa-gamepad" aria-hidden="true"></i></div><b>Real controls</b><span>Drive pad, keyboard, touch joystick and gamepad; buttons, sliders, servos and camera pan-tilt, laid out from your robot&#39;s profile.</span></div>
++ <div class="card"><div class="ic"><i class="fa-solid fa-bolt" aria-hidden="true"></i></div><b>Low latency</b><span>Video and commands over WebRTC, so driving feels direct. Works behind ordinary home and mobile networks.</span></div>
++ <div class="card"><div class="ic"><i class="fa-solid fa-user-group" aria-hidden="true"></i></div><b>Share control</b><span>Invite friends as operators, or open a public queue with timed turns, cooldowns and per-role limits.</span></div>
++ <div class="card"><div class="ic"><i class="fa-solid fa-shield-halved" aria-hidden="true"></i></div><b>Safe by default</b><span>The robot stops itself when commands stop. An emergency stop, speed and range limits and time windows, all logged.</span></div>
++ <div class="card"><div class="ic"><i class="fa-solid fa-diagram-project" aria-hidden="true"></i></div><b>Automate it</b><span>Schedules, triggers and webhooks, plus an API and SDKs for your own apps.</span></div>
++ <div class="card"><div class="ic"><i class="fa-solid fa-user-astronaut" aria-hidden="true"></i></div><b>Hand it to your agent</b><span>Let your OpenVibe.Actor agent patrol, check on or perform with your robot, with your approval.</span></div>
</div>
</section>
++
<section class="meanwhile">
-- <h2>Meanwhile, on the network</h2>
-- <p class="lead2">Most of this already exists somewhere on OpenVibe — start there today.</p>
++ <h2>Stream it, record it, connect it</h2>
++ <p class="lead2">Optional, one toggle each. Your robot does not need an audience to be useful.</p>
<div class="grid">
-- <a class="card" href="https://openvibe.live"><div class="ic"><i class="fa-solid fa-arrow-up-right-from-square" aria-hidden="true"></i></div><b>Robots on OpenVibe.Live</b><span>Stream-controlled robots and cameras run on Live today.</span><span class="go">openvibe.live →</span></a>
-- <a class="card" href="https://github.com/OpenVibers/OpenVibe.Extensions"><div class="ic"><i class="fa-solid fa-arrow-up-right-from-square" aria-hidden="true"></i></div><b>OpenVibe.Extensions</b><span>Device-side agents and hardware scripts.</span><span class="go">github.com/OpenVibers/OpenVibe.Extensions →</span></a>
++ <a class="card" href="https://openvibe.live"><div class="ic"><i class="fa-solid fa-tower-broadcast" aria-hidden="true"></i></div><b>Stream to OpenVibe.Live</b><span>Put the robot&#39;s camera on your channel; viewers can drive it from chat or the panel.</span><span class="go">openvibe.live →</span></a>
++ <a class="card" href="https://openre.stream"><div class="ic"><i class="fa-solid fa-satellite-dish" aria-hidden="true"></i></div><b>Stream through openre.stream</b><span>Low-latency ingest and restreaming to other platforms from the same camera.</span><span class="go">openre.stream →</span></a>
++ <a class="card" href="https://openvibe.media"><div class="ic"><i class="fa-solid fa-photo-film" aria-hidden="true"></i></div><b>Record to OpenVibe.Media</b><span>Keep every run as a video and cut clips from it.</span><span class="go">openvibe.media →</span></a>
++ <a class="card" href="https://openvibe.codes"><div class="ic"><i class="fa-solid fa-code" aria-hidden="true"></i></div><b>Build on it</b><span>The API, SDKs and examples.</span><span class="go">openvibe.codes →</span></a>
</div>
</section>
++ <section id="questions" class="faq">
++ <h2>Questions</h2>
++ <details><summary>Do I need to open ports on my router?</summary><p>No. The robot connects out to OpenVibe, and video and controls travel over WebRTC, so it works behind ordinary home and mobile networks.</p></details>
++ <details><summary>Is it only for streaming?</summary><p>No. Streaming is optional. Bot is a control panel for your robot first: drive it, check on it, share it and automate it.</p></details>
++ <details><summary>What hardware works?</summary><p>A Raspberry Pi or another Linux board, an ESP32, a ROS 2 robot, an Android phone, or an ONVIF or RTSP camera. The curated kits list exactly what to buy.</p></details>
++ <details><summary>How does it keep the robot safe?</summary><p>The device stops its motors by itself when commands or the connection stop. There is an emergency stop in the panel, limits on speed, range and time, and every command is logged.</p></details>
++ <details><summary>What will it cost?</summary><p>Controlling your own robot will not cost anything. Limits and any paid extras will be published before launch.</p></details>
++ </section>
++
++ <section class="build">
++ <div class="card">
++ <b><i class="fa-solid fa-person-digging" aria-hidden="true"></i> Build status</b>
++ <span>OpenVibe.Bot is being built now, starting with our own robots; stream-controlled robots already run on OpenVibe.Live. Its own service is not running yet: this page is a placeholder, nothing here is live yet. It opens with the Bot service, its device agent and the first robots paired. · as of 2026-09-29 · <a href="/status.json">status.json</a></span>
++ </div>
++ </section>
<section class="net">
<h2>The OpenVibe network</h2>
@@@ -279,7 +374,7 @@ a.card:hover{transform:translateY(-3px);border-color:rgba(var(--site-rgb),.6);bo
<script src="/shared/footer.js?v=a85ab893be88"></script>
<script>
(function () {
-- if (window.OpenVibeNavbar) { try { OpenVibeNavbar.init({ service: 'bot', apiBase: 'https://openvibe.network', links: [{ label: 'What it will be', href: '#what' }, { label: 'The network', href: 'https://openvibe.network/#network', external: false }], history: { type: 'page', title: 'OpenVibe.Bot' } }); } catch (e) {} }
++ if (window.OpenVibeNavbar) { try { OpenVibeNavbar.init({ service: 'bot', apiBase: 'https://openvibe.network', links: [{ label: 'How it works', href: '#what' }, { label: 'The network', href: 'https://openvibe.network/#network', external: false }], history: { type: 'page', title: 'OpenVibe.Bot' } }); } catch (e) {} }
if (window.OpenVibeFooter) { try { OpenVibeFooter.init({ service: 'bot', variant: 'full', links: [{ heading: 'OpenVibe.Bot', items: [{ name: 'Sign in', url: 'https://openvibe.network/login?return=https%3A%2F%2Fopenvibe.bot%2F' }, { name: 'The network', url: 'https://openvibe.network/#network' }, { name: 'Discord', url: 'https://discord.gg/M6MuRUaeJj' }] }] }); } catch (e) {} }
})();
</script>
ddiff --git a/dist/openvibe.bot/manifest.webmanifest b/dist/openvibe.bot/manifest.webmanifest
iindex a4c8902..4e093a1 100644
---- a/dist/openvibe.bot/manifest.webmanifest
++++ b/dist/openvibe.bot/manifest.webmanifest
@@@ -1,7 +1,7 @@
{
"name": "OpenVibe.Bot",
"short_name": "Bot",
-- "description": "Robots, cameras and devices you can share safely.",
++ "description": "Get your robot online in minutes.",
"start_url": "/",
"scope": "/",
"display": "standalone",
ddiff --git a/dist/openvibe.bot/release.json b/dist/openvibe.bot/release.json
iindex 089e123..3b106e1 100644
---- a/dist/openvibe.bot/release.json
++++ b/dist/openvibe.bot/release.json
@@@ -1,6 +1,6 @@
{
"service": "bot",
-- "release": "8a4eab12c1ba",
++ "release": "d6dcf5253182",
"released_at": "2026-09-29T00:00:00.000Z",
"booted_at": null,
"contracts_version": null,
ddiff --git a/dist/openvibe.bot/status.json b/dist/openvibe.bot/status.json
iindex 4b2d1d8..44a40d0 100644
---- a/dist/openvibe.bot/status.json
++++ b/dist/openvibe.bot/status.json
@@@ -8,7 +8,7 @@
"repoExists": false,
"repoStage": "charter-only",
"service": null,
-- "launchWaitsFor": "device pairing and control leases split out of OpenVibe.Live",
++ "launchWaitsFor": "the Bot service, its device agent and the first robots paired",
"factsAsOf": "2026-09-29",
"network": "https://openvibe.network",
"updated": "2026-09-29",
ddiff --git a/dist/openvibe.coupons/index.html b/dist/openvibe.coupons/index.html
iindex 5e314a5..1796a4a 100644
---- a/dist/openvibe.coupons/index.html
++++ b/dist/openvibe.coupons/index.html
@@@ -87,7 +87,50 @@ a.card:hover{transform:translateY(-3px);border-color:rgba(var(--site-rgb),.6);bo
.strip h3{font-size:19px;font-weight:700;margin:12px 0 8px}
.strip p{font-size:14px;color:var(--text-secondary);max-width:600px;margin:0 auto 18px;line-height:1.6}
.strip .ov-mark{width:44px;height:44px}
--@media (max-width:600px){.hero{padding-top:56px}.ctas .btn{width:100%;justify-content:center}}
++.hero.split{display:grid;grid-template-columns:minmax(0,1.05fr) minmax(0,1fr);gap:40px;align-items:center;text-align:left;padding-top:64px}
++.hero.split .ctas{justify-content:flex-start}.hero.split p.lead{margin:0}
++.viz{background:var(--bg-card);border:1px solid var(--border);border-radius:20px;padding:14px;box-shadow:0 30px 80px rgba(0,0,0,.45),0 0 0 1px rgba(var(--site-rgb),.08);animation:rise .7s .25s cubic-bezier(.2,.8,.2,1) both;text-align:left}
++.viz figcaption{margin-top:10px;font-size:11.5px;color:var(--text-muted);text-align:center}
++.viz-top{display:flex;align-items:center;gap:8px;font-size:13px;padding:2px 4px 12px}
++.viz-top b{font-weight:700}.viz-top .muted{color:var(--text-muted)}
++.viz-top .lat{margin-left:auto;font-size:12px;color:var(--site);background:rgba(var(--site-rgb),.1);border:1px solid rgba(var(--site-rgb),.3);padding:3px 9px;border-radius:999px}
++.viz-top .dot{width:8px;height:8px;border-radius:50%;background:#22c55e;box-shadow:0 0 0 4px rgba(34,197,94,.18)}
++.viz-top .av{width:26px;height:26px;border-radius:8px;display:grid;place-items:center;background:rgba(var(--site-rgb),.15);color:var(--site);font-size:13px}
++.viz-video{position:relative;aspect-ratio:16/9;border-radius:14px;overflow:hidden;background:radial-gradient(120% 90% at 30% 20%,rgba(var(--site-rgb),.28),transparent 60%),linear-gradient(160deg,#1a2338,#0b1020 70%);border:1px solid var(--border)}
++.viz-video::after{content:'';position:absolute;left:10%;right:10%;bottom:0;height:42%;background:linear-gradient(transparent,rgba(0,0,0,.35)),repeating-linear-gradient(90deg,rgba(255,255,255,.05) 0 1px,transparent 1px 38px);transform:perspective(220px) rotateX(58deg);transform-origin:bottom}
++.viz-video .scan{position:absolute;inset:0;background:linear-gradient(transparent 0,rgba(255,255,255,.04) 50%,transparent 100%);background-size:100% 6px;opacity:.5}
++.viz-video .onair{position:absolute;top:10px;left:10px;font-size:11px;font-weight:700;padding:3px 8px;border-radius:6px;background:rgba(239,68,68,.9);color:#fff}.viz-video .onair i{font-size:7px;vertical-align:2px;margin-right:3px}
++.viz-video .cam{position:absolute;bottom:10px;right:10px;font-size:11px;color:#dbe4f5;background:rgba(0,0,0,.45);padding:3px 8px;border-radius:6px}
++.viz-ctrl{display:flex;gap:14px;align-items:center;margin-top:12px}
++.dpad{display:grid;grid-template-columns:repeat(3,34px);grid-template-rows:repeat(3,34px);gap:4px;flex:none}
++.dpad span{display:grid;place-items:center;border-radius:9px;background:var(--bg-hover);color:var(--text-primary);font-size:15px;border:1px solid var(--border)}
++.dpad .u{grid-area:1/2}.dpad .l{grid-area:2/1}.dpad .c{grid-area:2/2;background:rgba(var(--site-rgb),.15);border-color:rgba(var(--site-rgb),.35)}.dpad .r{grid-area:2/3}.dpad .d{grid-area:3/2}
++.dpad .u{background:rgba(var(--site-rgb),.22);border-color:rgba(var(--site-rgb),.5)}
++.viz-side{flex:1;min-width:0;display:grid;gap:8px}
++.viz-side .keys{display:flex;flex-wrap:wrap;gap:6px}
++.viz-side .keys span{font-size:11.5px;padding:5px 9px;border-radius:8px;background:var(--bg-secondary);border:1px solid var(--border);color:var(--text-secondary)}
++.viz-side .meter{display:flex;align-items:center;gap:8px;font-size:11.5px;color:var(--text-muted)}
++.viz-side .meter i{flex:1;height:6px;border-radius:9px;background:linear-gradient(90deg,#22c55e var(--v),var(--bg-hover) var(--v))}
++.viz-side .meter b{color:var(--text-secondary);font-weight:600}
++.viz-side .estop{justify-self:end;font-size:12px;font-weight:800;letter-spacing:.08em;color:#fff;background:#dc2626;border-radius:10px;padding:7px 16px;box-shadow:0 0 0 3px rgba(220,38,38,.25)}
++.feed{list-style:none;display:grid;gap:8px;padding:2px}
++.feed li{display:flex;align-items:flex-start;gap:10px;font-size:13.5px;line-height:1.45;padding:10px 12px;border-radius:12px;background:var(--bg-secondary);border:1px solid var(--border);color:var(--text-secondary)}
++.feed li i{color:#22c55e;margin-top:3px}
++.feed li.ask{flex-wrap:wrap;border-color:rgba(var(--site-rgb),.45);background:rgba(var(--site-rgb),.08);color:var(--text-primary)}.feed li.ask i{color:var(--site)}.feed li.ask>span:first-of-type{flex:1;min-width:160px}
++.feed .pills{display:flex;gap:6px;margin-left:auto}.feed .pills span{font-size:12px;font-weight:600;padding:4px 11px;border-radius:999px;border:1px solid var(--border);color:var(--text-secondary)}.feed .pills .ok{background:var(--site);border-color:var(--site);color:#0b0d10}
++.steps{list-style:none;display:grid;grid-template-columns:repeat(auto-fit,minmax(230px,1fr));gap:14px;counter-reset:s}
++.steps li{position:relative;background:var(--bg-card);border:1px solid var(--border);border-radius:16px;padding:20px 20px 20px;display:flex;flex-direction:column;gap:8px}
++.steps .n{width:30px;height:30px;border-radius:50%;display:grid;place-items:center;font-weight:800;font-size:14px;color:#0b0d10;background:var(--site)}
++.steps b{font-size:15px}.steps span:last-child{font-size:13px;color:var(--text-secondary);line-height:1.55}
++.grid.three{grid-template-columns:repeat(auto-fit,minmax(280px,1fr))}
++.choice{display:grid;grid-template-columns:repeat(auto-fit,minmax(280px,1fr));gap:14px}
++.card.big{padding:24px}.card.big b{font-size:17px}
++.chips{display:flex;flex-wrap:wrap;gap:7px;margin-top:6px}
++.chips span{font-size:12.5px;padding:6px 11px;border-radius:999px;border:1px solid var(--border);background:var(--bg-secondary);color:var(--text-secondary)}
++.chips.big span{font-size:13.5px;padding:9px 14px;color:var(--text-primary)}.chips.big span i{color:var(--site);margin-right:8px}
++.build .card{border-style:dashed;background:rgba(0,0,0,.15)}.build .card b i{color:var(--site);margin-right:6px}.build .card span a{color:var(--text-secondary)}.build .card code{font-size:12px}
++@media (max-width:860px){.hero.split{grid-template-columns:1fr;text-align:center;gap:28px}.hero.split .ctas{justify-content:center}.hero.split p.lead{margin:0 auto}}
++@media (max-width:600px){.hero{padding-top:56px}.ctas .btn{width:100%;justify-content:center}.viz-ctrl{flex-direction:column;align-items:stretch}.dpad{align-self:center}}
@media (prefers-reduced-motion:reduce){*{animation:none!important;transition:none!important}}
</style>
</head>
ddiff --git a/dist/openvibe.coupons/release.json b/dist/openvibe.coupons/release.json
iindex c048521..0737f4e 100644
---- a/dist/openvibe.coupons/release.json
++++ b/dist/openvibe.coupons/release.json
@@@ -1,6 +1,6 @@
{
"service": "coupons",
-- "release": "74c34d28b8d7",
++ "release": "35ee1dcacac8",
"released_at": "2026-09-29T00:00:00.000Z",
"booted_at": null,
"contracts_version": null,
ddiff --git a/dist/openvibe.deals/index.html b/dist/openvibe.deals/index.html
iindex 7fabe86..1517ac3 100644
---- a/dist/openvibe.deals/index.html
++++ b/dist/openvibe.deals/index.html
@@@ -87,7 +87,50 @@ a.card:hover{transform:translateY(-3px);border-color:rgba(var(--site-rgb),.6);bo
.strip h3{font-size:19px;font-weight:700;margin:12px 0 8px}
.strip p{font-size:14px;color:var(--text-secondary);max-width:600px;margin:0 auto 18px;line-height:1.6}
.strip .ov-mark{width:44px;height:44px}
--@media (max-width:600px){.hero{padding-top:56px}.ctas .btn{width:100%;justify-content:center}}
++.hero.split{display:grid;grid-template-columns:minmax(0,1.05fr) minmax(0,1fr);gap:40px;align-items:center;text-align:left;padding-top:64px}
++.hero.split .ctas{justify-content:flex-start}.hero.split p.lead{margin:0}
++.viz{background:var(--bg-card);border:1px solid var(--border);border-radius:20px;padding:14px;box-shadow:0 30px 80px rgba(0,0,0,.45),0 0 0 1px rgba(var(--site-rgb),.08);animation:rise .7s .25s cubic-bezier(.2,.8,.2,1) both;text-align:left}
++.viz figcaption{margin-top:10px;font-size:11.5px;color:var(--text-muted);text-align:center}
++.viz-top{display:flex;align-items:center;gap:8px;font-size:13px;padding:2px 4px 12px}
++.viz-top b{font-weight:700}.viz-top .muted{color:var(--text-muted)}
++.viz-top .lat{margin-left:auto;font-size:12px;color:var(--site);background:rgba(var(--site-rgb),.1);border:1px solid rgba(var(--site-rgb),.3);padding:3px 9px;border-radius:999px}
++.viz-top .dot{width:8px;height:8px;border-radius:50%;background:#22c55e;box-shadow:0 0 0 4px rgba(34,197,94,.18)}
++.viz-top .av{width:26px;height:26px;border-radius:8px;display:grid;place-items:center;background:rgba(var(--site-rgb),.15);color:var(--site);font-size:13px}
++.viz-video{position:relative;aspect-ratio:16/9;border-radius:14px;overflow:hidden;background:radial-gradient(120% 90% at 30% 20%,rgba(var(--site-rgb),.28),transparent 60%),linear-gradient(160deg,#1a2338,#0b1020 70%);border:1px solid var(--border)}
++.viz-video::after{content:'';position:absolute;left:10%;right:10%;bottom:0;height:42%;background:linear-gradient(transparent,rgba(0,0,0,.35)),repeating-linear-gradient(90deg,rgba(255,255,255,.05) 0 1px,transparent 1px 38px);transform:perspective(220px) rotateX(58deg);transform-origin:bottom}
++.viz-video .scan{position:absolute;inset:0;background:linear-gradient(transparent 0,rgba(255,255,255,.04) 50%,transparent 100%);background-size:100% 6px;opacity:.5}
++.viz-video .onair{position:absolute;top:10px;left:10px;font-size:11px;font-weight:700;padding:3px 8px;border-radius:6px;background:rgba(239,68,68,.9);color:#fff}.viz-video .onair i{font-size:7px;vertical-align:2px;margin-right:3px}
++.viz-video .cam{position:absolute;bottom:10px;right:10px;font-size:11px;color:#dbe4f5;background:rgba(0,0,0,.45);padding:3px 8px;border-radius:6px}
++.viz-ctrl{display:flex;gap:14px;align-items:center;margin-top:12px}
++.dpad{display:grid;grid-template-columns:repeat(3,34px);grid-template-rows:repeat(3,34px);gap:4px;flex:none}
++.dpad span{display:grid;place-items:center;border-radius:9px;background:var(--bg-hover);color:var(--text-primary);font-size:15px;border:1px solid var(--border)}
++.dpad .u{grid-area:1/2}.dpad .l{grid-area:2/1}.dpad .c{grid-area:2/2;background:rgba(var(--site-rgb),.15);border-color:rgba(var(--site-rgb),.35)}.dpad .r{grid-area:2/3}.dpad .d{grid-area:3/2}
++.dpad .u{background:rgba(var(--site-rgb),.22);border-color:rgba(var(--site-rgb),.5)}
++.viz-side{flex:1;min-width:0;display:grid;gap:8px}
++.viz-side .keys{display:flex;flex-wrap:wrap;gap:6px}
++.viz-side .keys span{font-size:11.5px;padding:5px 9px;border-radius:8px;background:var(--bg-secondary);border:1px solid var(--border);color:var(--text-secondary)}
++.viz-side .meter{display:flex;align-items:center;gap:8px;font-size:11.5px;color:var(--text-muted)}
++.viz-side .meter i{flex:1;height:6px;border-radius:9px;background:linear-gradient(90deg,#22c55e var(--v),var(--bg-hover) var(--v))}
++.viz-side .meter b{color:var(--text-secondary);font-weight:600}
++.viz-side .estop{justify-self:end;font-size:12px;font-weight:800;letter-spacing:.08em;color:#fff;background:#dc2626;border-radius:10px;padding:7px 16px;box-shadow:0 0 0 3px rgba(220,38,38,.25)}
++.feed{list-style:none;display:grid;gap:8px;padding:2px}
++.feed li{display:flex;align-items:flex-start;gap:10px;font-size:13.5px;line-height:1.45;padding:10px 12px;border-radius:12px;background:var(--bg-secondary);border:1px solid var(--border);color:var(--text-secondary)}
++.feed li i{color:#22c55e;margin-top:3px}
++.feed li.ask{flex-wrap:wrap;border-color:rgba(var(--site-rgb),.45);background:rgba(var(--site-rgb),.08);color:var(--text-primary)}.feed li.ask i{color:var(--site)}.feed li.ask>span:first-of-type{flex:1;min-width:160px}
++.feed .pills{display:flex;gap:6px;margin-left:auto}.feed .pills span{font-size:12px;font-weight:600;padding:4px 11px;border-radius:999px;border:1px solid var(--border);color:var(--text-secondary)}.feed .pills .ok{background:var(--site);border-color:var(--site);color:#0b0d10}
++.steps{list-style:none;display:grid;grid-template-columns:repeat(auto-fit,minmax(230px,1fr));gap:14px;counter-reset:s}
++.steps li{position:relative;background:var(--bg-card);border:1px solid var(--border);border-radius:16px;padding:20px 20px 20px;display:flex;flex-direction:column;gap:8px}
++.steps .n{width:30px;height:30px;border-radius:50%;display:grid;place-items:center;font-weight:800;font-size:14px;color:#0b0d10;background:var(--site)}
++.steps b{font-size:15px}.steps span:last-child{font-size:13px;color:var(--text-secondary);line-height:1.55}
++.grid.three{grid-template-columns:repeat(auto-fit,minmax(280px,1fr))}
++.choice{display:grid;grid-template-columns:repeat(auto-fit,minmax(280px,1fr));gap:14px}
++.card.big{padding:24px}.card.big b{font-size:17px}
++.chips{display:flex;flex-wrap:wrap;gap:7px;margin-top:6px}
++.chips span{font-size:12.5px;padding:6px 11px;border-radius:999px;border:1px solid var(--border);background:var(--bg-secondary);color:var(--text-secondary)}
++.chips.big span{font-size:13.5px;padding:9px 14px;color:var(--text-primary)}.chips.big span i{color:var(--site);margin-right:8px}
++.build .card{border-style:dashed;background:rgba(0,0,0,.15)}.build .card b i{color:var(--site);margin-right:6px}.build .card span a{color:var(--text-secondary)}.build .card code{font-size:12px}
++@media (max-width:860px){.hero.split{grid-template-columns:1fr;text-align:center;gap:28px}.hero.split .ctas{justify-content:center}.hero.split p.lead{margin:0 auto}}
++@media (max-width:600px){.hero{padding-top:56px}.ctas .btn{width:100%;justify-content:center}.viz-ctrl{flex-direction:column;align-items:stretch}.dpad{align-self:center}}
@media (prefers-reduced-motion:reduce){*{animation:none!important;transition:none!important}}
</style>
</head>
ddiff --git a/dist/openvibe.deals/release.json b/dist/openvibe.deals/release.json
iindex 5c06550..1c5ba6d 100644
---- a/dist/openvibe.deals/release.json
++++ b/dist/openvibe.deals/release.json
@@@ -1,6 +1,6 @@
{
"service": "deals",
-- "release": "0ea3d47ec59b",
++ "release": "c650df3e7943",
"released_at": "2026-09-29T00:00:00.000Z",
"booted_at": null,
"contracts_version": null,
ddiff --git a/dist/openvibe.download/index.html b/dist/openvibe.download/index.html
iindex e50b24e..b00da61 100644
---- a/dist/openvibe.download/index.html
++++ b/dist/openvibe.download/index.html
@@@ -87,7 +87,50 @@ a.card:hover{transform:translateY(-3px);border-color:rgba(var(--site-rgb),.6);bo
.strip h3{font-size:19px;font-weight:700;margin:12px 0 8px}
.strip p{font-size:14px;color:var(--text-secondary);max-width:600px;margin:0 auto 18px;line-height:1.6}
.strip .ov-mark{width:44px;height:44px}
--@media (max-width:600px){.hero{padding-top:56px}.ctas .btn{width:100%;justify-content:center}}
++.hero.split{display:grid;grid-template-columns:minmax(0,1.05fr) minmax(0,1fr);gap:40px;align-items:center;text-align:left;padding-top:64px}
++.hero.split .ctas{justify-content:flex-start}.hero.split p.lead{margin:0}
++.viz{background:var(--bg-card);border:1px solid var(--border);border-radius:20px;padding:14px;box-shadow:0 30px 80px rgba(0,0,0,.45),0 0 0 1px rgba(var(--site-rgb),.08);animation:rise .7s .25s cubic-bezier(.2,.8,.2,1) both;text-align:left}
++.viz figcaption{margin-top:10px;font-size:11.5px;color:var(--text-muted);text-align:center}
++.viz-top{display:flex;align-items:center;gap:8px;font-size:13px;padding:2px 4px 12px}
++.viz-top b{font-weight:700}.viz-top .muted{color:var(--text-muted)}
++.viz-top .lat{margin-left:auto;font-size:12px;color:var(--site);background:rgba(var(--site-rgb),.1);border:1px solid rgba(var(--site-rgb),.3);padding:3px 9px;border-radius:999px}
++.viz-top .dot{width:8px;height:8px;border-radius:50%;background:#22c55e;box-shadow:0 0 0 4px rgba(34,197,94,.18)}
++.viz-top .av{width:26px;height:26px;border-radius:8px;display:grid;place-items:center;background:rgba(var(--site-rgb),.15);color:var(--site);font-size:13px}
++.viz-video{position:relative;aspect-ratio:16/9;border-radius:14px;overflow:hidden;background:radial-gradient(120% 90% at 30% 20%,rgba(var(--site-rgb),.28),transparent 60%),linear-gradient(160deg,#1a2338,#0b1020 70%);border:1px solid var(--border)}
++.viz-video::after{content:'';position:absolute;left:10%;right:10%;bottom:0;height:42%;background:linear-gradient(transparent,rgba(0,0,0,.35)),repeating-linear-gradient(90deg,rgba(255,255,255,.05) 0 1px,transparent 1px 38px);transform:perspective(220px) rotateX(58deg);transform-origin:bottom}
++.viz-video .scan{position:absolute;inset:0;background:linear-gradient(transparent 0,rgba(255,255,255,.04) 50%,transparent 100%);background-size:100% 6px;opacity:.5}
++.viz-video .onair{position:absolute;top:10px;left:10px;font-size:11px;font-weight:700;padding:3px 8px;border-radius:6px;background:rgba(239,68,68,.9);color:#fff}.viz-video .onair i{font-size:7px;vertical-align:2px;margin-right:3px}
++.viz-video .cam{position:absolute;bottom:10px;right:10px;font-size:11px;color:#dbe4f5;background:rgba(0,0,0,.45);padding:3px 8px;border-radius:6px}
++.viz-ctrl{display:flex;gap:14px;align-items:center;margin-top:12px}
++.dpad{display:grid;grid-template-columns:repeat(3,34px);grid-template-rows:repeat(3,34px);gap:4px;flex:none}
++.dpad span{display:grid;place-items:center;border-radius:9px;background:var(--bg-hover);color:var(--text-primary);font-size:15px;border:1px solid var(--border)}
++.dpad .u{grid-area:1/2}.dpad .l{grid-area:2/1}.dpad .c{grid-area:2/2;background:rgba(var(--site-rgb),.15);border-color:rgba(var(--site-rgb),.35)}.dpad .r{grid-area:2/3}.dpad .d{grid-area:3/2}
++.dpad .u{background:rgba(var(--site-rgb),.22);border-color:rgba(var(--site-rgb),.5)}
++.viz-side{flex:1;min-width:0;display:grid;gap:8px}
++.viz-side .keys{display:flex;flex-wrap:wrap;gap:6px}
++.viz-side .keys span{font-size:11.5px;padding:5px 9px;border-radius:8px;background:var(--bg-secondary);border:1px solid var(--border);color:var(--text-secondary)}
++.viz-side .meter{display:flex;align-items:center;gap:8px;font-size:11.5px;color:var(--text-muted)}
++.viz-side .meter i{flex:1;height:6px;border-radius:9px;background:linear-gradient(90deg,#22c55e var(--v),var(--bg-hover) var(--v))}
++.viz-side .meter b{color:var(--text-secondary);font-weight:600}
++.viz-side .estop{justify-self:end;font-size:12px;font-weight:800;letter-spacing:.08em;color:#fff;background:#dc2626;border-radius:10px;padding:7px 16px;box-shadow:0 0 0 3px rgba(220,38,38,.25)}
++.feed{list-style:none;display:grid;gap:8px;padding:2px}
++.feed li{display:flex;align-items:flex-start;gap:10px;font-size:13.5px;line-height:1.45;padding:10px 12px;border-radius:12px;background:var(--bg-secondary);border:1px solid var(--border);color:var(--text-secondary)}
++.feed li i{color:#22c55e;margin-top:3px}
++.feed li.ask{flex-wrap:wrap;border-color:rgba(var(--site-rgb),.45);background:rgba(var(--site-rgb),.08);color:var(--text-primary)}.feed li.ask i{color:var(--site)}.feed li.ask>span:first-of-type{flex:1;min-width:160px}
++.feed .pills{display:flex;gap:6px;margin-left:auto}.feed .pills span{font-size:12px;font-weight:600;padding:4px 11px;border-radius:999px;border:1px solid var(--border);color:var(--text-secondary)}.feed .pills .ok{background:var(--site);border-color:var(--site);color:#0b0d10}
++.steps{list-style:none;display:grid;grid-template-columns:repeat(auto-fit,minmax(230px,1fr));gap:14px;counter-reset:s}
++.steps li{position:relative;background:var(--bg-card);border:1px solid var(--border);border-radius:16px;padding:20px 20px 20px;display:flex;flex-direction:column;gap:8px}
++.steps .n{width:30px;height:30px;border-radius:50%;display:grid;place-items:center;font-weight:800;font-size:14px;color:#0b0d10;background:var(--site)}
++.steps b{font-size:15px}.steps span:last-child{font-size:13px;color:var(--text-secondary);line-height:1.55}
++.grid.three{grid-template-columns:repeat(auto-fit,minmax(280px,1fr))}
++.choice{display:grid;grid-template-columns:repeat(auto-fit,minmax(280px,1fr));gap:14px}
++.card.big{padding:24px}.card.big b{font-size:17px}
++.chips{display:flex;flex-wrap:wrap;gap:7px;margin-top:6px}
++.chips span{font-size:12.5px;padding:6px 11px;border-radius:999px;border:1px solid var(--border);background:var(--bg-secondary);color:var(--text-secondary)}
++.chips.big span{font-size:13.5px;padding:9px 14px;color:var(--text-primary)}.chips.big span i{color:var(--site);margin-right:8px}
++.build .card{border-style:dashed;background:rgba(0,0,0,.15)}.build .card b i{color:var(--site);margin-right:6px}.build .card span a{color:var(--text-secondary)}.build .card code{font-size:12px}
++@media (max-width:860px){.hero.split{grid-template-columns:1fr;text-align:center;gap:28px}.hero.split .ctas{justify-content:center}.hero.split p.lead{margin:0 auto}}
++@media (max-width:600px){.hero{padding-top:56px}.ctas .btn{width:100%;justify-content:center}.viz-ctrl{flex-direction:column;align-items:stretch}.dpad{align-self:center}}
@media (prefers-reduced-motion:reduce){*{animation:none!important;transition:none!important}}
</style>
</head>
ddiff --git a/dist/openvibe.download/release.json b/dist/openvibe.download/release.json
iindex 6accd4c..eb9382f 100644
---- a/dist/openvibe.download/release.json
++++ b/dist/openvibe.download/release.json
@@@ -1,6 +1,6 @@
{
"service": "download",
-- "release": "b441873e1043",
++ "release": "f31103a9b687",
"released_at": "2026-09-29T00:00:00.000Z",
"booted_at": null,
"contracts_version": null,
ddiff --git a/dist/openvibe.events/index.html b/dist/openvibe.events/index.html
iindex 94eb1f4..d573d7d 100644
---- a/dist/openvibe.events/index.html
++++ b/dist/openvibe.events/index.html
@@@ -87,7 +87,50 @@ a.card:hover{transform:translateY(-3px);border-color:rgba(var(--site-rgb),.6);bo
.strip h3{font-size:19px;font-weight:700;margin:12px 0 8px}
.strip p{font-size:14px;color:var(--text-secondary);max-width:600px;margin:0 auto 18px;line-height:1.6}
.strip .ov-mark{width:44px;height:44px}
--@media (max-width:600px){.hero{padding-top:56px}.ctas .btn{width:100%;justify-content:center}}
++.hero.split{display:grid;grid-template-columns:minmax(0,1.05fr) minmax(0,1fr);gap:40px;align-items:center;text-align:left;padding-top:64px}
++.hero.split .ctas{justify-content:flex-start}.hero.split p.lead{margin:0}
++.viz{background:var(--bg-card);border:1px solid var(--border);border-radius:20px;padding:14px;box-shadow:0 30px 80px rgba(0,0,0,.45),0 0 0 1px rgba(var(--site-rgb),.08);animation:rise .7s .25s cubic-bezier(.2,.8,.2,1) both;text-align:left}
++.viz figcaption{margin-top:10px;font-size:11.5px;color:var(--text-muted);text-align:center}
++.viz-top{display:flex;align-items:center;gap:8px;font-size:13px;padding:2px 4px 12px}
++.viz-top b{font-weight:700}.viz-top .muted{color:var(--text-muted)}
++.viz-top .lat{margin-left:auto;font-size:12px;color:var(--site);background:rgba(var(--site-rgb),.1);border:1px solid rgba(var(--site-rgb),.3);padding:3px 9px;border-radius:999px}
++.viz-top .dot{width:8px;height:8px;border-radius:50%;background:#22c55e;box-shadow:0 0 0 4px rgba(34,197,94,.18)}
++.viz-top .av{width:26px;height:26px;border-radius:8px;display:grid;place-items:center;background:rgba(var(--site-rgb),.15);color:var(--site);font-size:13px}
++.viz-video{position:relative;aspect-ratio:16/9;border-radius:14px;overflow:hidden;background:radial-gradient(120% 90% at 30% 20%,rgba(var(--site-rgb),.28),transparent 60%),linear-gradient(160deg,#1a2338,#0b1020 70%);border:1px solid var(--border)}
++.viz-video::after{content:'';position:absolute;left:10%;right:10%;bottom:0;height:42%;background:linear-gradient(transparent,rgba(0,0,0,.35)),repeating-linear-gradient(90deg,rgba(255,255,255,.05) 0 1px,transparent 1px 38px);transform:perspective(220px) rotateX(58deg);transform-origin:bottom}
++.viz-video .scan{position:absolute;inset:0;background:linear-gradient(transparent 0,rgba(255,255,255,.04) 50%,transparent 100%);background-size:100% 6px;opacity:.5}
++.viz-video .onair{position:absolute;top:10px;left:10px;font-size:11px;font-weight:700;padding:3px 8px;border-radius:6px;background:rgba(239,68,68,.9);color:#fff}.viz-video .onair i{font-size:7px;vertical-align:2px;margin-right:3px}
++.viz-video .cam{position:absolute;bottom:10px;right:10px;font-size:11px;color:#dbe4f5;background:rgba(0,0,0,.45);padding:3px 8px;border-radius:6px}
++.viz-ctrl{display:flex;gap:14px;align-items:center;margin-top:12px}
++.dpad{display:grid;grid-template-columns:repeat(3,34px);grid-template-rows:repeat(3,34px);gap:4px;flex:none}
++.dpad span{display:grid;place-items:center;border-radius:9px;background:var(--bg-hover);color:var(--text-primary);font-size:15px;border:1px solid var(--border)}
++.dpad .u{grid-area:1/2}.dpad .l{grid-area:2/1}.dpad .c{grid-area:2/2;background:rgba(var(--site-rgb),.15);border-color:rgba(var(--site-rgb),.35)}.dpad .r{grid-area:2/3}.dpad .d{grid-area:3/2}
++.dpad .u{background:rgba(var(--site-rgb),.22);border-color:rgba(var(--site-rgb),.5)}
++.viz-side{flex:1;min-width:0;display:grid;gap:8px}
++.viz-side .keys{display:flex;flex-wrap:wrap;gap:6px}
++.viz-side .keys span{font-size:11.5px;padding:5px 9px;border-radius:8px;background:var(--bg-secondary);border:1px solid var(--border);color:var(--text-secondary)}
++.viz-side .meter{display:flex;align-items:center;gap:8px;font-size:11.5px;color:var(--text-muted)}
++.viz-side .meter i{flex:1;height:6px;border-radius:9px;background:linear-gradient(90deg,#22c55e var(--v),var(--bg-hover) var(--v))}
++.viz-side .meter b{color:var(--text-secondary);font-weight:600}
++.viz-side .estop{justify-self:end;font-size:12px;font-weight:800;letter-spacing:.08em;color:#fff;background:#dc2626;border-radius:10px;padding:7px 16px;box-shadow:0 0 0 3px rgba(220,38,38,.25)}
++.feed{list-style:none;display:grid;gap:8px;padding:2px}
++.feed li{display:flex;align-items:flex-start;gap:10px;font-size:13.5px;line-height:1.45;padding:10px 12px;border-radius:12px;background:var(--bg-secondary);border:1px solid var(--border);color:var(--text-secondary)}
++.feed li i{color:#22c55e;margin-top:3px}
++.feed li.ask{flex-wrap:wrap;border-color:rgba(var(--site-rgb),.45);background:rgba(var(--site-rgb),.08);color:var(--text-primary)}.feed li.ask i{color:var(--site)}.feed li.ask>span:first-of-type{flex:1;min-width:160px}
++.feed .pills{display:flex;gap:6px;margin-left:auto}.feed .pills span{font-size:12px;font-weight:600;padding:4px 11px;border-radius:999px;border:1px solid var(--border);color:var(--text-secondary)}.feed .pills .ok{background:var(--site);border-color:var(--site);color:#0b0d10}
++.steps{list-style:none;display:grid;grid-template-columns:repeat(auto-fit,minmax(230px,1fr));gap:14px;counter-reset:s}
++.steps li{position:relative;background:var(--bg-card);border:1px solid var(--border);border-radius:16px;padding:20px 20px 20px;display:flex;flex-direction:column;gap:8px}
++.steps .n{width:30px;height:30px;border-radius:50%;display:grid;place-items:center;font-weight:800;font-size:14px;color:#0b0d10;background:var(--site)}
++.steps b{font-size:15px}.steps span:last-child{font-size:13px;color:var(--text-secondary);line-height:1.55}
++.grid.three{grid-template-columns:repeat(auto-fit,minmax(280px,1fr))}
++.choice{display:grid;grid-template-columns:repeat(auto-fit,minmax(280px,1fr));gap:14px}
++.card.big{padding:24px}.card.big b{font-size:17px}
++.chips{display:flex;flex-wrap:wrap;gap:7px;margin-top:6px}
++.chips span{font-size:12.5px;padding:6px 11px;border-radius:999px;border:1px solid var(--border);background:var(--bg-secondary);color:var(--text-secondary)}
++.chips.big span{font-size:13.5px;padding:9px 14px;color:var(--text-primary)}.chips.big span i{color:var(--site);margin-right:8px}
++.build .card{border-style:dashed;background:rgba(0,0,0,.15)}.build .card b i{color:var(--site);margin-right:6px}.build .card span a{color:var(--text-secondary)}.build .card code{font-size:12px}
++@media (max-width:860px){.hero.split{grid-template-columns:1fr;text-align:center;gap:28px}.hero.split .ctas{justify-content:center}.hero.split p.lead{margin:0 auto}}
++@media (max-width:600px){.hero{padding-top:56px}.ctas .btn{width:100%;justify-content:center}.viz-ctrl{flex-direction:column;align-items:stretch}.dpad{align-self:center}}
@media (prefers-reduced-motion:reduce){*{animation:none!important;transition:none!important}}
</style>
</head>
ddiff --git a/dist/openvibe.events/release.json b/dist/openvibe.events/release.json
iindex 9b6a266..cabea7f 100644
---- a/dist/openvibe.events/release.json
++++ b/dist/openvibe.events/release.json
@@@ -1,6 +1,6 @@
{
"service": "events",
-- "release": "39f08f6a7383",
++ "release": "775d8a75ec2d",
"released_at": "2026-09-29T00:00:00.000Z",
"booted_at": null,
"contracts_version": null,
ddiff --git a/dist/openvibe.food/index.html b/dist/openvibe.food/index.html
iindex 773ac2e..6da7e17 100644
---- a/dist/openvibe.food/index.html
++++ b/dist/openvibe.food/index.html
@@@ -87,7 +87,50 @@ a.card:hover{transform:translateY(-3px);border-color:rgba(var(--site-rgb),.6);bo
.strip h3{font-size:19px;font-weight:700;margin:12px 0 8px}
.strip p{font-size:14px;color:var(--text-secondary);max-width:600px;margin:0 auto 18px;line-height:1.6}
.strip .ov-mark{width:44px;height:44px}
--@media (max-width:600px){.hero{padding-top:56px}.ctas .btn{width:100%;justify-content:center}}
++.hero.split{display:grid;grid-template-columns:minmax(0,1.05fr) minmax(0,1fr);gap:40px;align-items:center;text-align:left;padding-top:64px}
++.hero.split .ctas{justify-content:flex-start}.hero.split p.lead{margin:0}
++.viz{background:var(--bg-card);border:1px solid var(--border);border-radius:20px;padding:14px;box-shadow:0 30px 80px rgba(0,0,0,.45),0 0 0 1px rgba(var(--site-rgb),.08);animation:rise .7s .25s cubic-bezier(.2,.8,.2,1) both;text-align:left}
++.viz figcaption{margin-top:10px;font-size:11.5px;color:var(--text-muted);text-align:center}
++.viz-top{display:flex;align-items:center;gap:8px;font-size:13px;padding:2px 4px 12px}
++.viz-top b{font-weight:700}.viz-top .muted{color:var(--text-muted)}
++.viz-top .lat{margin-left:auto;font-size:12px;color:var(--site);background:rgba(var(--site-rgb),.1);border:1px solid rgba(var(--site-rgb),.3);padding:3px 9px;border-radius:999px}
++.viz-top .dot{width:8px;height:8px;border-radius:50%;background:#22c55e;box-shadow:0 0 0 4px rgba(34,197,94,.18)}
++.viz-top .av{width:26px;height:26px;border-radius:8px;display:grid;place-items:center;background:rgba(var(--site-rgb),.15);color:var(--site);font-size:13px}
++.viz-video{position:relative;aspect-ratio:16/9;border-radius:14px;overflow:hidden;background:radial-gradient(120% 90% at 30% 20%,rgba(var(--site-rgb),.28),transparent 60%),linear-gradient(160deg,#1a2338,#0b1020 70%);border:1px solid var(--border)}
++.viz-video::after{content:'';position:absolute;left:10%;right:10%;bottom:0;height:42%;background:linear-gradient(transparent,rgba(0,0,0,.35)),repeating-linear-gradient(90deg,rgba(255,255,255,.05) 0 1px,transparent 1px 38px);transform:perspective(220px) rotateX(58deg);transform-origin:bottom}
++.viz-video .scan{position:absolute;inset:0;background:linear-gradient(transparent 0,rgba(255,255,255,.04) 50%,transparent 100%);background-size:100% 6px;opacity:.5}
++.viz-video .onair{position:absolute;top:10px;left:10px;font-size:11px;font-weight:700;padding:3px 8px;border-radius:6px;background:rgba(239,68,68,.9);color:#fff}.viz-video .onair i{font-size:7px;vertical-align:2px;margin-right:3px}
++.viz-video .cam{position:absolute;bottom:10px;right:10px;font-size:11px;color:#dbe4f5;background:rgba(0,0,0,.45);padding:3px 8px;border-radius:6px}
++.viz-ctrl{display:flex;gap:14px;align-items:center;margin-top:12px}
++.dpad{display:grid;grid-template-columns:repeat(3,34px);grid-template-rows:repeat(3,34px);gap:4px;flex:none}
++.dpad span{display:grid;place-items:center;border-radius:9px;background:var(--bg-hover);color:var(--text-primary);font-size:15px;border:1px solid var(--border)}
++.dpad .u{grid-area:1/2}.dpad .l{grid-area:2/1}.dpad .c{grid-area:2/2;background:rgba(var(--site-rgb),.15);border-color:rgba(var(--site-rgb),.35)}.dpad .r{grid-area:2/3}.dpad .d{grid-area:3/2}
++.dpad .u{background:rgba(var(--site-rgb),.22);border-color:rgba(var(--site-rgb),.5)}
++.viz-side{flex:1;min-width:0;display:grid;gap:8px}
++.viz-side .keys{display:flex;flex-wrap:wrap;gap:6px}
++.viz-side .keys span{font-size:11.5px;padding:5px 9px;border-radius:8px;background:var(--bg-secondary);border:1px solid var(--border);color:var(--text-secondary)}
++.viz-side .meter{display:flex;align-items:center;gap:8px;font-size:11.5px;color:var(--text-muted)}
++.viz-side .meter i{flex:1;height:6px;border-radius:9px;background:linear-gradient(90deg,#22c55e var(--v),var(--bg-hover) var(--v))}
++.viz-side .meter b{color:var(--text-secondary);font-weight:600}
++.viz-side .estop{justify-self:end;font-size:12px;font-weight:800;letter-spacing:.08em;color:#fff;background:#dc2626;border-radius:10px;padding:7px 16px;box-shadow:0 0 0 3px rgba(220,38,38,.25)}
++.feed{list-style:none;display:grid;gap:8px;padding:2px}
++.feed li{display:flex;align-items:flex-start;gap:10px;font-size:13.5px;line-height:1.45;padding:10px 12px;border-radius:12px;background:var(--bg-secondary);border:1px solid var(--border);color:var(--text-secondary)}
++.feed li i{color:#22c55e;margin-top:3px}
++.feed li.ask{flex-wrap:wrap;border-color:rgba(var(--site-rgb),.45);background:rgba(var(--site-rgb),.08);color:var(--text-primary)}.feed li.ask i{color:var(--site)}.feed li.ask>span:first-of-type{flex:1;min-width:160px}
++.feed .pills{display:flex;gap:6px;margin-left:auto}.feed .pills span{font-size:12px;font-weight:600;padding:4px 11px;border-radius:999px;border:1px solid var(--border);color:var(--text-secondary)}.feed .pills .ok{background:var(--site);border-color:var(--site);color:#0b0d10}
++.steps{list-style:none;display:grid;grid-template-columns:repeat(auto-fit,minmax(230px,1fr));gap:14px;counter-reset:s}
++.steps li{position:relative;background:var(--bg-card);border:1px solid var(--border);border-radius:16px;padding:20px 20px 20px;display:flex;flex-direction:column;gap:8px}
++.steps .n{width:30px;height:30px;border-radius:50%;display:grid;place-items:center;font-weight:800;font-size:14px;color:#0b0d10;background:var(--site)}
++.steps b{font-size:15px}.steps span:last-child{font-size:13px;color:var(--text-secondary);line-height:1.55}
++.grid.three{grid-template-columns:repeat(auto-fit,minmax(280px,1fr))}
++.choice{display:grid;grid-template-columns:repeat(auto-fit,minmax(280px,1fr));gap:14px}
++.card.big{padding:24px}.card.big b{font-size:17px}
++.chips{display:flex;flex-wrap:wrap;gap:7px;margin-top:6px}
++.chips span{font-size:12.5px;padding:6px 11px;border-radius:999px;border:1px solid var(--border);background:var(--bg-secondary);color:var(--text-secondary)}
++.chips.big span{font-size:13.5px;padding:9px 14px;color:var(--text-primary)}.chips.big span i{color:var(--site);margin-right:8px}
++.build .card{border-style:dashed;background:rgba(0,0,0,.15)}.build .card b i{color:var(--site);margin-right:6px}.build .card span a{color:var(--text-secondary)}.build .card code{font-size:12px}
++@media (max-width:860px){.hero.split{grid-template-columns:1fr;text-align:center;gap:28px}.hero.split .ctas{justify-content:center}.hero.split p.lead{margin:0 auto}}
++@media (max-width:600px){.hero{padding-top:56px}.ctas .btn{width:100%;justify-content:center}.viz-ctrl{flex-direction:column;align-items:stretch}.dpad{align-self:center}}
@media (prefers-reduced-motion:reduce){*{animation:none!important;transition:none!important}}
</style>
</head>
ddiff --git a/dist/openvibe.food/release.json b/dist/openvibe.food/release.json
iindex 67f349b..fddcc78 100644
---- a/dist/openvibe.food/release.json
++++ b/dist/openvibe.food/release.json
@@@ -1,6 +1,6 @@
{
"service": "food",
-- "release": "b9cc6e51c98d",
++ "release": "33fe172f4ba8",
"released_at": "2026-09-29T00:00:00.000Z",
"booted_at": null,
"contracts_version": null,
ddiff --git a/dist/openvibe.help/index.html b/dist/openvibe.help/index.html
iindex c819ce7..51fa27c 100644
---- a/dist/openvibe.help/index.html
++++ b/dist/openvibe.help/index.html
@@@ -87,7 +87,50 @@ a.card:hover{transform:translateY(-3px);border-color:rgba(var(--site-rgb),.6);bo
.strip h3{font-size:19px;font-weight:700;margin:12px 0 8px}
.strip p{font-size:14px;color:var(--text-secondary);max-width:600px;margin:0 auto 18px;line-height:1.6}
.strip .ov-mark{width:44px;height:44px}
--@media (max-width:600px){.hero{padding-top:56px}.ctas .btn{width:100%;justify-content:center}}
++.hero.split{display:grid;grid-template-columns:minmax(0,1.05fr) minmax(0,1fr);gap:40px;align-items:center;text-align:left;padding-top:64px}
++.hero.split .ctas{justify-content:flex-start}.hero.split p.lead{margin:0}
++.viz{background:var(--bg-card);border:1px solid var(--border);border-radius:20px;padding:14px;box-shadow:0 30px 80px rgba(0,0,0,.45),0 0 0 1px rgba(var(--site-rgb),.08);animation:rise .7s .25s cubic-bezier(.2,.8,.2,1) both;text-align:left}
++.viz figcaption{margin-top:10px;font-size:11.5px;color:var(--text-muted);text-align:center}
++.viz-top{display:flex;align-items:center;gap:8px;font-size:13px;padding:2px 4px 12px}
++.viz-top b{font-weight:700}.viz-top .muted{color:var(--text-muted)}
++.viz-top .lat{margin-left:auto;font-size:12px;color:var(--site);background:rgba(var(--site-rgb),.1);border:1px solid rgba(var(--site-rgb),.3);padding:3px 9px;border-radius:999px}
++.viz-top .dot{width:8px;height:8px;border-radius:50%;background:#22c55e;box-shadow:0 0 0 4px rgba(34,197,94,.18)}
++.viz-top .av{width:26px;height:26px;border-radius:8px;display:grid;place-items:center;background:rgba(var(--site-rgb),.15);color:var(--site);font-size:13px}
++.viz-video{position:relative;aspect-ratio:16/9;border-radius:14px;overflow:hidden;background:radial-gradient(120% 90% at 30% 20%,rgba(var(--site-rgb),.28),transparent 60%),linear-gradient(160deg,#1a2338,#0b1020 70%);border:1px solid var(--border)}
++.viz-video::after{content:'';position:absolute;left:10%;right:10%;bottom:0;height:42%;background:linear-gradient(transparent,rgba(0,0,0,.35)),repeating-linear-gradient(90deg,rgba(255,255,255,.05) 0 1px,transparent 1px 38px);transform:perspective(220px) rotateX(58deg);transform-origin:bottom}
++.viz-video .scan{position:absolute;inset:0;background:linear-gradient(transparent 0,rgba(255,255,255,.04) 50%,transparent 100%);background-size:100% 6px;opacity:.5}
++.viz-video .onair{position:absolute;top:10px;left:10px;font-size:11px;font-weight:700;padding:3px 8px;border-radius:6px;background:rgba(239,68,68,.9);color:#fff}.viz-video .onair i{font-size:7px;vertical-align:2px;margin-right:3px}
++.viz-video .cam{position:absolute;bottom:10px;right:10px;font-size:11px;color:#dbe4f5;background:rgba(0,0,0,.45);padding:3px 8px;border-radius:6px}
++.viz-ctrl{display:flex;gap:14px;align-items:center;margin-top:12px}
++.dpad{display:grid;grid-template-columns:repeat(3,34px);grid-template-rows:repeat(3,34px);gap:4px;flex:none}
++.dpad span{display:grid;place-items:center;border-radius:9px;background:var(--bg-hover);color:var(--text-primary);font-size:15px;border:1px solid var(--border)}
++.dpad .u{grid-area:1/2}.dpad .l{grid-area:2/1}.dpad .c{grid-area:2/2;background:rgba(var(--site-rgb),.15);border-color:rgba(var(--site-rgb),.35)}.dpad .r{grid-area:2/3}.dpad .d{grid-area:3/2}
++.dpad .u{background:rgba(var(--site-rgb),.22);border-color:rgba(var(--site-rgb),.5)}
++.viz-side{flex:1;min-width:0;display:grid;gap:8px}
++.viz-side .keys{display:flex;flex-wrap:wrap;gap:6px}
++.viz-side .keys span{font-size:11.5px;padding:5px 9px;border-radius:8px;background:var(--bg-secondary);border:1px solid var(--border);color:var(--text-secondary)}
++.viz-side .meter{display:flex;align-items:center;gap:8px;font-size:11.5px;color:var(--text-muted)}
++.viz-side .meter i{flex:1;height:6px;border-radius:9px;background:linear-gradient(90deg,#22c55e var(--v),var(--bg-hover) var(--v))}
++.viz-side .meter b{color:var(--text-secondary);font-weight:600}
++.viz-side .estop{justify-self:end;font-size:12px;font-weight:800;letter-spacing:.08em;color:#fff;background:#dc2626;border-radius:10px;padding:7px 16px;box-shadow:0 0 0 3px rgba(220,38,38,.25)}
++.feed{list-style:none;display:grid;gap:8px;padding:2px}
++.feed li{display:flex;align-items:flex-start;gap:10px;font-size:13.5px;line-height:1.45;padding:10px 12px;border-radius:12px;background:var(--bg-secondary);border:1px solid var(--border);color:var(--text-secondary)}
++.feed li i{color:#22c55e;margin-top:3px}
++.feed li.ask{flex-wrap:wrap;border-color:rgba(var(--site-rgb),.45);background:rgba(var(--site-rgb),.08);color:var(--text-primary)}.feed li.ask i{color:var(--site)}.feed li.ask>span:first-of-type{flex:1;min-width:160px}
++.feed .pills{display:flex;gap:6px;margin-left:auto}.feed .pills span{font-size:12px;font-weight:600;padding:4px 11px;border-radius:999px;border:1px solid var(--border);color:var(--text-secondary)}.feed .pills .ok{background:var(--site);border-color:var(--site);color:#0b0d10}
++.steps{list-style:none;display:grid;grid-template-columns:repeat(auto-fit,minmax(230px,1fr));gap:14px;counter-reset:s}
++.steps li{position:relative;background:var(--bg-card);border:1px solid var(--border);border-radius:16px;padding:20px 20px 20px;display:flex;flex-direction:column;gap:8px}
++.steps .n{width:30px;height:30px;border-radius:50%;display:grid;place-items:center;font-weight:800;font-size:14px;color:#0b0d10;background:var(--site)}
++.steps b{font-size:15px}.steps span:last-child{font-size:13px;color:var(--text-secondary);line-height:1.55}
++.grid.three{grid-template-columns:repeat(auto-fit,minmax(280px,1fr))}
++.choice{display:grid;grid-template-columns:repeat(auto-fit,minmax(280px,1fr));gap:14px}
++.card.big{padding:24px}.card.big b{font-size:17px}
++.chips{display:flex;flex-wrap:wrap;gap:7px;margin-top:6px}
++.chips span{font-size:12.5px;padding:6px 11px;border-radius:999px;border:1px solid var(--border);background:var(--bg-secondary);color:var(--text-secondary)}
++.chips.big span{font-size:13.5px;padding:9px 14px;color:var(--text-primary)}.chips.big span i{color:var(--site);margin-right:8px}
++.build .card{border-style:dashed;background:rgba(0,0,0,.15)}.build .card b i{color:var(--site);margin-right:6px}.build .card span a{color:var(--text-secondary)}.build .card code{font-size:12px}
++@media (max-width:860px){.hero.split{grid-template-columns:1fr;text-align:center;gap:28px}.hero.split .ctas{justify-content:center}.hero.split p.lead{margin:0 auto}}
++@media (max-width:600px){.hero{padding-top:56px}.ctas .btn{width:100%;justify-content:center}.viz-ctrl{flex-direction:column;align-items:stretch}.dpad{align-self:center}}
@media (prefers-reduced-motion:reduce){*{animation:none!important;transition:none!important}}
</style>
</head>
ddiff --git a/dist/openvibe.help/release.json b/dist/openvibe.help/release.json
iindex 47a8fd0..287b0e5 100644
---- a/dist/openvibe.help/release.json
++++ b/dist/openvibe.help/release.json
@@@ -1,6 +1,6 @@
{
"service": "help",
-- "release": "48ec28a6807c",
++ "release": "ff05ba62a0a6",
"released_at": "2026-09-29T00:00:00.000Z",
"booted_at": null,
"contracts_version": null,
ddiff --git a/dist/openvibe.homes/index.html b/dist/openvibe.homes/index.html
iindex 4c96184..7b59170 100644
---- a/dist/openvibe.homes/index.html
++++ b/dist/openvibe.homes/index.html
@@@ -87,7 +87,50 @@ a.card:hover{transform:translateY(-3px);border-color:rgba(var(--site-rgb),.6);bo
.strip h3{font-size:19px;font-weight:700;margin:12px 0 8px}
.strip p{font-size:14px;color:var(--text-secondary);max-width:600px;margin:0 auto 18px;line-height:1.6}
.strip .ov-mark{width:44px;height:44px}
--@media (max-width:600px){.hero{padding-top:56px}.ctas .btn{width:100%;justify-content:center}}
++.hero.split{display:grid;grid-template-columns:minmax(0,1.05fr) minmax(0,1fr);gap:40px;align-items:center;text-align:left;padding-top:64px}
++.hero.split .ctas{justify-content:flex-start}.hero.split p.lead{margin:0}
++.viz{background:var(--bg-card);border:1px solid var(--border);border-radius:20px;padding:14px;box-shadow:0 30px 80px rgba(0,0,0,.45),0 0 0 1px rgba(var(--site-rgb),.08);animation:rise .7s .25s cubic-bezier(.2,.8,.2,1) both;text-align:left}
++.viz figcaption{margin-top:10px;font-size:11.5px;color:var(--text-muted);text-align:center}
++.viz-top{display:flex;align-items:center;gap:8px;font-size:13px;padding:2px 4px 12px}
++.viz-top b{font-weight:700}.viz-top .muted{color:var(--text-muted)}
++.viz-top .lat{margin-left:auto;font-size:12px;color:var(--site);background:rgba(var(--site-rgb),.1);border:1px solid rgba(var(--site-rgb),.3);padding:3px 9px;border-radius:999px}
++.viz-top .dot{width:8px;height:8px;border-radius:50%;background:#22c55e;box-shadow:0 0 0 4px rgba(34,197,94,.18)}
++.viz-top .av{width:26px;height:26px;border-radius:8px;display:grid;place-items:center;background:rgba(var(--site-rgb),.15);color:var(--site);font-size:13px}
++.viz-video{position:relative;aspect-ratio:16/9;border-radius:14px;overflow:hidden;background:radial-gradient(120% 90% at 30% 20%,rgba(var(--site-rgb),.28),transparent 60%),linear-gradient(160deg,#1a2338,#0b1020 70%);border:1px solid var(--border)}
++.viz-video::after{content:'';position:absolute;left:10%;right:10%;bottom:0;height:42%;background:linear-gradient(transparent,rgba(0,0,0,.35)),repeating-linear-gradient(90deg,rgba(255,255,255,.05) 0 1px,transparent 1px 38px);transform:perspective(220px) rotateX(58deg);transform-origin:bottom}
++.viz-video .scan{position:absolute;inset:0;background:linear-gradient(transparent 0,rgba(255,255,255,.04) 50%,transparent 100%);background-size:100% 6px;opacity:.5}
++.viz-video .onair{position:absolute;top:10px;left:10px;font-size:11px;font-weight:700;padding:3px 8px;border-radius:6px;background:rgba(239,68,68,.9);color:#fff}.viz-video .onair i{font-size:7px;vertical-align:2px;margin-right:3px}
++.viz-video .cam{position:absolute;bottom:10px;right:10px;font-size:11px;color:#dbe4f5;background:rgba(0,0,0,.45);padding:3px 8px;border-radius:6px}
++.viz-ctrl{display:flex;gap:14px;align-items:center;margin-top:12px}
++.dpad{display:grid;grid-template-columns:repeat(3,34px);grid-template-rows:repeat(3,34px);gap:4px;flex:none}
++.dpad span{display:grid;place-items:center;border-radius:9px;background:var(--bg-hover);color:var(--text-primary);font-size:15px;border:1px solid var(--border)}
++.dpad .u{grid-area:1/2}.dpad .l{grid-area:2/1}.dpad .c{grid-area:2/2;background:rgba(var(--site-rgb),.15);border-color:rgba(var(--site-rgb),.35)}.dpad .r{grid-area:2/3}.dpad .d{grid-area:3/2}
++.dpad .u{background:rgba(var(--site-rgb),.22);border-color:rgba(var(--site-rgb),.5)}
++.viz-side{flex:1;min-width:0;display:grid;gap:8px}
++.viz-side .keys{display:flex;flex-wrap:wrap;gap:6px}
++.viz-side .keys span{font-size:11.5px;padding:5px 9px;border-radius:8px;background:var(--bg-secondary);border:1px solid var(--border);color:var(--text-secondary)}
++.viz-side .meter{display:flex;align-items:center;gap:8px;font-size:11.5px;color:var(--text-muted)}
++.viz-side .meter i{flex:1;height:6px;border-radius:9px;background:linear-gradient(90deg,#22c55e var(--v),var(--bg-hover) var(--v))}
++.viz-side .meter b{color:var(--text-secondary);font-weight:600}
++.viz-side .estop{justify-self:end;font-size:12px;font-weight:800;letter-spacing:.08em;color:#fff;background:#dc2626;border-radius:10px;padding:7px 16px;box-shadow:0 0 0 3px rgba(220,38,38,.25)}
++.feed{list-style:none;display:grid;gap:8px;padding:2px}
++.feed li{display:flex;align-items:flex-start;gap:10px;font-size:13.5px;line-height:1.45;padding:10px 12px;border-radius:12px;background:var(--bg-secondary);border:1px solid var(--border);color:var(--text-secondary)}
++.feed li i{color:#22c55e;margin-top:3px}
++.feed li.ask{flex-wrap:wrap;border-color:rgba(var(--site-rgb),.45);background:rgba(var(--site-rgb),.08);color:var(--text-primary)}.feed li.ask i{color:var(--site)}.feed li.ask>span:first-of-type{flex:1;min-width:160px}
++.feed .pills{display:flex;gap:6px;margin-left:auto}.feed .pills span{font-size:12px;font-weight:600;padding:4px 11px;border-radius:999px;border:1px solid var(--border);color:var(--text-secondary)}.feed .pills .ok{background:var(--site);border-color:var(--site);color:#0b0d10}
++.steps{list-style:none;display:grid;grid-template-columns:repeat(auto-fit,minmax(230px,1fr));gap:14px;counter-reset:s}
++.steps li{position:relative;background:var(--bg-card);border:1px solid var(--border);border-radius:16px;padding:20px 20px 20px;display:flex;flex-direction:column;gap:8px}
++.steps .n{width:30px;height:30px;border-radius:50%;display:grid;place-items:center;font-weight:800;font-size:14px;color:#0b0d10;background:var(--site)}
++.steps b{font-size:15px}.steps span:last-child{font-size:13px;color:var(--text-secondary);line-height:1.55}
++.grid.three{grid-template-columns:repeat(auto-fit,minmax(280px,1fr))}
++.choice{display:grid;grid-template-columns:repeat(auto-fit,minmax(280px,1fr));gap:14px}
++.card.big{padding:24px}.card.big b{font-size:17px}
++.chips{display:flex;flex-wrap:wrap;gap:7px;margin-top:6px}
++.chips span{font-size:12.5px;padding:6px 11px;border-radius:999px;border:1px solid var(--border);background:var(--bg-secondary);color:var(--text-secondary)}
++.chips.big span{font-size:13.5px;padding:9px 14px;color:var(--text-primary)}.chips.big span i{color:var(--site);margin-right:8px}
++.build .card{border-style:dashed;background:rgba(0,0,0,.15)}.build .card b i{color:var(--site);margin-right:6px}.build .card span a{color:var(--text-secondary)}.build .card code{font-size:12px}
++@media (max-width:860px){.hero.split{grid-template-columns:1fr;text-align:center;gap:28px}.hero.split .ctas{justify-content:center}.hero.split p.lead{margin:0 auto}}
++@media (max-width:600px){.hero{padding-top:56px}.ctas .btn{width:100%;justify-content:center}.viz-ctrl{flex-direction:column;align-items:stretch}.dpad{align-self:center}}
@media (prefers-reduced-motion:reduce){*{animation:none!important;transition:none!important}}
</style>
</head>
ddiff --git a/dist/openvibe.homes/release.json b/dist/openvibe.homes/release.json
iindex 7439cea..984581a 100644
---- a/dist/openvibe.homes/release.json
++++ b/dist/openvibe.homes/release.json
@@@ -1,6 +1,6 @@
{
"service": "homes",
-- "release": "f7cb5aaecb7f",
++ "release": "b7b52e6c88f7",
"released_at": "2026-09-29T00:00:00.000Z",
"booted_at": null,
"contracts_version": null,
ddiff --git a/dist/openvibe.host/index.html b/dist/openvibe.host/index.html
iindex 23d5e46..46c4297 100644
---- a/dist/openvibe.host/index.html
++++ b/dist/openvibe.host/index.html
@@@ -87,7 +87,50 @@ a.card:hover{transform:translateY(-3px);border-color:rgba(var(--site-rgb),.6);bo
.strip h3{font-size:19px;font-weight:700;margin:12px 0 8px}
.strip p{font-size:14px;color:var(--text-secondary);max-width:600px;margin:0 auto 18px;line-height:1.6}
.strip .ov-mark{width:44px;height:44px}
--@media (max-width:600px){.hero{padding-top:56px}.ctas .btn{width:100%;justify-content:center}}
++.hero.split{display:grid;grid-template-columns:minmax(0,1.05fr) minmax(0,1fr);gap:40px;align-items:center;text-align:left;padding-top:64px}
++.hero.split .ctas{justify-content:flex-start}.hero.split p.lead{margin:0}
++.viz{background:var(--bg-card);border:1px solid var(--border);border-radius:20px;padding:14px;box-shadow:0 30px 80px rgba(0,0,0,.45),0 0 0 1px rgba(var(--site-rgb),.08);animation:rise .7s .25s cubic-bezier(.2,.8,.2,1) both;text-align:left}
++.viz figcaption{margin-top:10px;font-size:11.5px;color:var(--text-muted);text-align:center}
++.viz-top{display:flex;align-items:center;gap:8px;font-size:13px;padding:2px 4px 12px}
++.viz-top b{font-weight:700}.viz-top .muted{color:var(--text-muted)}
++.viz-top .lat{margin-left:auto;font-size:12px;color:var(--site);background:rgba(var(--site-rgb),.1);border:1px solid rgba(var(--site-rgb),.3);padding:3px 9px;border-radius:999px}
++.viz-top .dot{width:8px;height:8px;border-radius:50%;background:#22c55e;box-shadow:0 0 0 4px rgba(34,197,94,.18)}
++.viz-top .av{width:26px;height:26px;border-radius:8px;display:grid;place-items:center;background:rgba(var(--site-rgb),.15);color:var(--site);font-size:13px}
++.viz-video{position:relative;aspect-ratio:16/9;border-radius:14px;overflow:hidden;background:radial-gradient(120% 90% at 30% 20%,rgba(var(--site-rgb),.28),transparent 60%),linear-gradient(160deg,#1a2338,#0b1020 70%);border:1px solid var(--border)}
++.viz-video::after{content:'';position:absolute;left:10%;right:10%;bottom:0;height:42%;background:linear-gradient(transparent,rgba(0,0,0,.35)),repeating-linear-gradient(90deg,rgba(255,255,255,.05) 0 1px,transparent 1px 38px);transform:perspective(220px) rotateX(58deg);transform-origin:bottom}
++.viz-video .scan{position:absolute;inset:0;background:linear-gradient(transparent 0,rgba(255,255,255,.04) 50%,transparent 100%);background-size:100% 6px;opacity:.5}
++.viz-video .onair{position:absolute;top:10px;left:10px;font-size:11px;font-weight:700;padding:3px 8px;border-radius:6px;background:rgba(239,68,68,.9);color:#fff}.viz-video .onair i{font-size:7px;vertical-align:2px;margin-right:3px}
++.viz-video .cam{position:absolute;bottom:10px;right:10px;font-size:11px;color:#dbe4f5;background:rgba(0,0,0,.45);padding:3px 8px;border-radius:6px}
++.viz-ctrl{display:flex;gap:14px;align-items:center;margin-top:12px}
++.dpad{display:grid;grid-template-columns:repeat(3,34px);grid-template-rows:repeat(3,34px);gap:4px;flex:none}
++.dpad span{display:grid;place-items:center;border-radius:9px;background:var(--bg-hover);color:var(--text-primary);font-size:15px;border:1px solid var(--border)}
++.dpad .u{grid-area:1/2}.dpad .l{grid-area:2/1}.dpad .c{grid-area:2/2;background:rgba(var(--site-rgb),.15);border-color:rgba(var(--site-rgb),.35)}.dpad .r{grid-area:2/3}.dpad .d{grid-area:3/2}
++.dpad .u{background:rgba(var(--site-rgb),.22);border-color:rgba(var(--site-rgb),.5)}
++.viz-side{flex:1;min-width:0;display:grid;gap:8px}
++.viz-side .keys{display:flex;flex-wrap:wrap;gap:6px}
++.viz-side .keys span{font-size:11.5px;padding:5px 9px;border-radius:8px;background:var(--bg-secondary);border:1px solid var(--border);color:var(--text-secondary)}
++.viz-side .meter{display:flex;align-items:center;gap:8px;font-size:11.5px;color:var(--text-muted)}
++.viz-side .meter i{flex:1;height:6px;border-radius:9px;background:linear-gradient(90deg,#22c55e var(--v),var(--bg-hover) var(--v))}
++.viz-side .meter b{color:var(--text-secondary);font-weight:600}
++.viz-side .estop{justify-self:end;font-size:12px;font-weight:800;letter-spacing:.08em;color:#fff;background:#dc2626;border-radius:10px;padding:7px 16px;box-shadow:0 0 0 3px rgba(220,38,38,.25)}
++.feed{list-style:none;display:grid;gap:8px;padding:2px}
++.feed li{display:flex;align-items:flex-start;gap:10px;font-size:13.5px;line-height:1.45;padding:10px 12px;border-radius:12px;background:var(--bg-secondary);border:1px solid var(--border);color:var(--text-secondary)}
++.feed li i{color:#22c55e;margin-top:3px}
++.feed li.ask{flex-wrap:wrap;border-color:rgba(var(--site-rgb),.45);background:rgba(var(--site-rgb),.08);color:var(--text-primary)}.feed li.ask i{color:var(--site)}.feed li.ask>span:first-of-type{flex:1;min-width:160px}
++.feed .pills{display:flex;gap:6px;margin-left:auto}.feed .pills span{font-size:12px;font-weight:600;padding:4px 11px;border-radius:999px;border:1px solid var(--border);color:var(--text-secondary)}.feed .pills .ok{background:var(--site);border-color:var(--site);color:#0b0d10}
++.steps{list-style:none;display:grid;grid-template-columns:repeat(auto-fit,minmax(230px,1fr));gap:14px;counter-reset:s}
++.steps li{position:relative;background:var(--bg-card);border:1px solid var(--border);border-radius:16px;padding:20px 20px 20px;display:flex;flex-direction:column;gap:8px}
++.steps .n{width:30px;height:30px;border-radius:50%;display:grid;place-items:center;font-weight:800;font-size:14px;color:#0b0d10;background:var(--site)}
++.steps b{font-size:15px}.steps span:last-child{font-size:13px;color:var(--text-secondary);line-height:1.55}
++.grid.three{grid-template-columns:repeat(auto-fit,minmax(280px,1fr))}
++.choice{display:grid;grid-template-columns:repeat(auto-fit,minmax(280px,1fr));gap:14px}
++.card.big{padding:24px}.card.big b{font-size:17px}
++.chips{display:flex;flex-wrap:wrap;gap:7px;margin-top:6px}
++.chips span{font-size:12.5px;padding:6px 11px;border-radius:999px;border:1px solid var(--border);background:var(--bg-secondary);color:var(--text-secondary)}
++.chips.big span{font-size:13.5px;padding:9px 14px;color:var(--text-primary)}.chips.big span i{color:var(--site);margin-right:8px}
++.build .card{border-style:dashed;background:rgba(0,0,0,.15)}.build .card b i{color:var(--site);margin-right:6px}.build .card span a{color:var(--text-secondary)}.build .card code{font-size:12px}
++@media (max-width:860px){.hero.split{grid-template-columns:1fr;text-align:center;gap:28px}.hero.split .ctas{justify-content:center}.hero.split p.lead{margin:0 auto}}
++@media (max-width:600px){.hero{padding-top:56px}.ctas .btn{width:100%;justify-content:center}.viz-ctrl{flex-direction:column;align-items:stretch}.dpad{align-self:center}}
@media (prefers-reduced-motion:reduce){*{animation:none!important;transition:none!important}}
</style>
</head>
ddiff --git a/dist/openvibe.host/release.json b/dist/openvibe.host/release.json
iindex 22fc986..ef102f3 100644
---- a/dist/openvibe.host/release.json
++++ b/dist/openvibe.host/release.json
@@@ -1,6 +1,6 @@
{
"service": "host",
-- "release": "f63347076f3f",
++ "release": "073bff41498e",
"released_at": "2026-09-29T00:00:00.000Z",
"booted_at": null,
"contracts_version": null,
ddiff --git a/dist/openvibe.news/index.html b/dist/openvibe.news/index.html
iindex db6f0b1..047fe1f 100644
---- a/dist/openvibe.news/index.html
++++ b/dist/openvibe.news/index.html
@@@ -87,7 +87,50 @@ a.card:hover{transform:translateY(-3px);border-color:rgba(var(--site-rgb),.6);bo
.strip h3{font-size:19px;font-weight:700;margin:12px 0 8px}
.strip p{font-size:14px;color:var(--text-secondary);max-width:600px;margin:0 auto 18px;line-height:1.6}
.strip .ov-mark{width:44px;height:44px}
--@media (max-width:600px){.hero{padding-top:56px}.ctas .btn{width:100%;justify-content:center}}
++.hero.split{display:grid;grid-template-columns:minmax(0,1.05fr) minmax(0,1fr);gap:40px;align-items:center;text-align:left;padding-top:64px}
++.hero.split .ctas{justify-content:flex-start}.hero.split p.lead{margin:0}
++.viz{background:var(--bg-card);border:1px solid var(--border);border-radius:20px;padding:14px;box-shadow:0 30px 80px rgba(0,0,0,.45),0 0 0 1px rgba(var(--site-rgb),.08);animation:rise .7s .25s cubic-bezier(.2,.8,.2,1) both;text-align:left}
++.viz figcaption{margin-top:10px;font-size:11.5px;color:var(--text-muted);text-align:center}
++.viz-top{display:flex;align-items:center;gap:8px;font-size:13px;padding:2px 4px 12px}
++.viz-top b{font-weight:700}.viz-top .muted{color:var(--text-muted)}
++.viz-top .lat{margin-left:auto;font-size:12px;color:var(--site);background:rgba(var(--site-rgb),.1);border:1px solid rgba(var(--site-rgb),.3);padding:3px 9px;border-radius:999px}
++.viz-top .dot{width:8px;height:8px;border-radius:50%;background:#22c55e;box-shadow:0 0 0 4px rgba(34,197,94,.18)}
++.viz-top .av{width:26px;height:26px;border-radius:8px;display:grid;place-items:center;background:rgba(var(--site-rgb),.15);color:var(--site);font-size:13px}
++.viz-video{position:relative;aspect-ratio:16/9;border-radius:14px;overflow:hidden;background:radial-gradient(120% 90% at 30% 20%,rgba(var(--site-rgb),.28),transparent 60%),linear-gradient(160deg,#1a2338,#0b1020 70%);border:1px solid var(--border)}
++.viz-video::after{content:'';position:absolute;left:10%;right:10%;bottom:0;height:42%;background:linear-gradient(transparent,rgba(0,0,0,.35)),repeating-linear-gradient(90deg,rgba(255,255,255,.05) 0 1px,transparent 1px 38px);transform:perspective(220px) rotateX(58deg);transform-origin:bottom}
++.viz-video .scan{position:absolute;inset:0;background:linear-gradient(transparent 0,rgba(255,255,255,.04) 50%,transparent 100%);background-size:100% 6px;opacity:.5}
++.viz-video .onair{position:absolute;top:10px;left:10px;font-size:11px;font-weight:700;padding:3px 8px;border-radius:6px;background:rgba(239,68,68,.9);color:#fff}.viz-video .onair i{font-size:7px;vertical-align:2px;margin-right:3px}
++.viz-video .cam{position:absolute;bottom:10px;right:10px;font-size:11px;color:#dbe4f5;background:rgba(0,0,0,.45);padding:3px 8px;border-radius:6px}
++.viz-ctrl{display:flex;gap:14px;align-items:center;margin-top:12px}
++.dpad{display:grid;grid-template-columns:repeat(3,34px);grid-template-rows:repeat(3,34px);gap:4px;flex:none}
++.dpad span{display:grid;place-items:center;border-radius:9px;background:var(--bg-hover);color:var(--text-primary);font-size:15px;border:1px solid var(--border)}
++.dpad .u{grid-area:1/2}.dpad .l{grid-area:2/1}.dpad .c{grid-area:2/2;background:rgba(var(--site-rgb),.15);border-color:rgba(var(--site-rgb),.35)}.dpad .r{grid-area:2/3}.dpad .d{grid-area:3/2}
++.dpad .u{background:rgba(var(--site-rgb),.22);border-color:rgba(var(--site-rgb),.5)}
++.viz-side{flex:1;min-width:0;display:grid;gap:8px}
++.viz-side .keys{display:flex;flex-wrap:wrap;gap:6px}
++.viz-side .keys span{font-size:11.5px;padding:5px 9px;border-radius:8px;background:var(--bg-secondary);border:1px solid var(--border);color:var(--text-secondary)}
++.viz-side .meter{display:flex;align-items:center;gap:8px;font-size:11.5px;color:var(--text-muted)}
++.viz-side .meter i{flex:1;height:6px;border-radius:9px;background:linear-gradient(90deg,#22c55e var(--v),var(--bg-hover) var(--v))}
++.viz-side .meter b{color:var(--text-secondary);font-weight:600}
++.viz-side .estop{justify-self:end;font-size:12px;font-weight:800;letter-spacing:.08em;color:#fff;background:#dc2626;border-radius:10px;padding:7px 16px;box-shadow:0 0 0 3px rgba(220,38,38,.25)}
++.feed{list-style:none;display:grid;gap:8px;padding:2px}
++.feed li{display:flex;align-items:flex-start;gap:10px;font-size:13.5px;line-height:1.45;padding:10px 12px;border-radius:12px;background:var(--bg-secondary);border:1px solid var(--border);color:var(--text-secondary)}
++.feed li i{color:#22c55e;margin-top:3px}
++.feed li.ask{flex-wrap:wrap;border-color:rgba(var(--site-rgb),.45);background:rgba(var(--site-rgb),.08);color:var(--text-primary)}.feed li.ask i{color:var(--site)}.feed li.ask>span:first-of-type{flex:1;min-width:160px}
++.feed .pills{display:flex;gap:6px;margin-left:auto}.feed .pills span{font-size:12px;font-weight:600;padding:4px 11px;border-radius:999px;border:1px solid var(--border);color:var(--text-secondary)}.feed .pills .ok{background:var(--site);border-color:var(--site);color:#0b0d10}
++.steps{list-style:none;display:grid;grid-template-columns:repeat(auto-fit,minmax(230px,1fr));gap:14px;counter-reset:s}
++.steps li{position:relative;background:var(--bg-card);border:1px solid var(--border);border-radius:16px;padding:20px 20px 20px;display:flex;flex-direction:column;gap:8px}
++.steps .n{width:30px;height:30px;border-radius:50%;display:grid;place-items:center;font-weight:800;font-size:14px;color:#0b0d10;background:var(--site)}
++.steps b{font-size:15px}.steps span:last-child{font-size:13px;color:var(--text-secondary);line-height:1.55}
++.grid.three{grid-template-columns:repeat(auto-fit,minmax(280px,1fr))}
++.choice{display:grid;grid-template-columns:repeat(auto-fit,minmax(280px,1fr));gap:14px}
++.card.big{padding:24px}.card.big b{font-size:17px}
++.chips{display:flex;flex-wrap:wrap;gap:7px;margin-top:6px}
++.chips span{font-size:12.5px;padding:6px 11px;border-radius:999px;border:1px solid var(--border);background:var(--bg-secondary);color:var(--text-secondary)}
++.chips.big span{font-size:13.5px;padding:9px 14px;color:var(--text-primary)}.chips.big span i{color:var(--site);margin-right:8px}
++.build .card{border-style:dashed;background:rgba(0,0,0,.15)}.build .card b i{color:var(--site);margin-right:6px}.build .card span a{color:var(--text-secondary)}.build .card code{font-size:12px}
++@media (max-width:860px){.hero.split{grid-template-columns:1fr;text-align:center;gap:28px}.hero.split .ctas{justify-content:center}.hero.split p.lead{margin:0 auto}}
++@media (max-width:600px){.hero{padding-top:56px}.ctas .btn{width:100%;justify-content:center}.viz-ctrl{flex-direction:column;align-items:stretch}.dpad{align-self:center}}
@media (prefers-reduced-motion:reduce){*{animation:none!important;transition:none!important}}
</style>
</head>
ddiff --git a/dist/openvibe.news/release.json b/dist/openvibe.news/release.json
iindex 7e8251a..c1104bc 100644
---- a/dist/openvibe.news/release.json
++++ b/dist/openvibe.news/release.json
@@@ -1,6 +1,6 @@
{
"service": "news",
-- "release": "7860fdb46fd7",
++ "release": "ed41915d231f",
"released_at": "2026-09-29T00:00:00.000Z",
"booted_at": null,
"contracts_version": null,
ddiff --git a/dist/openvibe.pics/index.html b/dist/openvibe.pics/index.html
iindex 3bd3970..192be67 100644
---- a/dist/openvibe.pics/index.html
++++ b/dist/openvibe.pics/index.html
@@@ -87,7 +87,50 @@ a.card:hover{transform:translateY(-3px);border-color:rgba(var(--site-rgb),.6);bo
.strip h3{font-size:19px;font-weight:700;margin:12px 0 8px}
.strip p{font-size:14px;color:var(--text-secondary);max-width:600px;margin:0 auto 18px;line-height:1.6}
.strip .ov-mark{width:44px;height:44px}
--@media (max-width:600px){.hero{padding-top:56px}.ctas .btn{width:100%;justify-content:center}}
++.hero.split{display:grid;grid-template-columns:minmax(0,1.05fr) minmax(0,1fr);gap:40px;align-items:center;text-align:left;padding-top:64px}
++.hero.split .ctas{justify-content:flex-start}.hero.split p.lead{margin:0}
++.viz{background:var(--bg-card);border:1px solid var(--border);border-radius:20px;padding:14px;box-shadow:0 30px 80px rgba(0,0,0,.45),0 0 0 1px rgba(var(--site-rgb),.08);animation:rise .7s .25s cubic-bezier(.2,.8,.2,1) both;text-align:left}
++.viz figcaption{margin-top:10px;font-size:11.5px;color:var(--text-muted);text-align:center}
++.viz-top{display:flex;align-items:center;gap:8px;font-size:13px;padding:2px 4px 12px}
++.viz-top b{font-weight:700}.viz-top .muted{color:var(--text-muted)}
++.viz-top .lat{margin-left:auto;font-size:12px;color:var(--site);background:rgba(var(--site-rgb),.1);border:1px solid rgba(var(--site-rgb),.3);padding:3px 9px;border-radius:999px}
++.viz-top .dot{width:8px;height:8px;border-radius:50%;background:#22c55e;box-shadow:0 0 0 4px rgba(34,197,94,.18)}
++.viz-top .av{width:26px;height:26px;border-radius:8px;display:grid;place-items:center;background:rgba(var(--site-rgb),.15);color:var(--site);font-size:13px}
++.viz-video{position:relative;aspect-ratio:16/9;border-radius:14px;overflow:hidden;background:radial-gradient(120% 90% at 30% 20%,rgba(var(--site-rgb),.28),transparent 60%),linear-gradient(160deg,#1a2338,#0b1020 70%);border:1px solid var(--border)}
++.viz-video::after{content:'';position:absolute;left:10%;right:10%;bottom:0;height:42%;background:linear-gradient(transparent,rgba(0,0,0,.35)),repeating-linear-gradient(90deg,rgba(255,255,255,.05) 0 1px,transparent 1px 38px);transform:perspective(220px) rotateX(58deg);transform-origin:bottom}
++.viz-video .scan{position:absolute;inset:0;background:linear-gradient(transparent 0,rgba(255,255,255,.04) 50%,transparent 100%);background-size:100% 6px;opacity:.5}
++.viz-video .onair{position:absolute;top:10px;left:10px;font-size:11px;font-weight:700;padding:3px 8px;border-radius:6px;background:rgba(239,68,68,.9);color:#fff}.viz-video .onair i{font-size:7px;vertical-align:2px;margin-right:3px}
++.viz-video .cam{position:absolute;bottom:10px;right:10px;font-size:11px;color:#dbe4f5;background:rgba(0,0,0,.45);padding:3px 8px;border-radius:6px}
++.viz-ctrl{display:flex;gap:14px;align-items:center;margin-top:12px}
++.dpad{display:grid;grid-template-columns:repeat(3,34px);grid-template-rows:repeat(3,34px);gap:4px;flex:none}
++.dpad span{display:grid;place-items:center;border-radius:9px;background:var(--bg-hover);color:var(--text-primary);font-size:15px;border:1px solid var(--border)}
++.dpad .u{grid-area:1/2}.dpad .l{grid-area:2/1}.dpad .c{grid-area:2/2;background:rgba(var(--site-rgb),.15);border-color:rgba(var(--site-rgb),.35)}.dpad .r{grid-area:2/3}.dpad .d{grid-area:3/2}
++.dpad .u{background:rgba(var(--site-rgb),.22);border-color:rgba(var(--site-rgb),.5)}
++.viz-side{flex:1;min-width:0;display:grid;gap:8px}
++.viz-side .keys{display:flex;flex-wrap:wrap;gap:6px}
++.viz-side .keys span{font-size:11.5px;padding:5px 9px;border-radius:8px;background:var(--bg-secondary);border:1px solid var(--border);color:var(--text-secondary)}
++.viz-side .meter{display:flex;align-items:center;gap:8px;font-size:11.5px;color:var(--text-muted)}
++.viz-side .meter i{flex:1;height:6px;border-radius:9px;background:linear-gradient(90deg,#22c55e var(--v),var(--bg-hover) var(--v))}
++.viz-side .meter b{color:var(--text-secondary);font-weight:600}
++.viz-side .estop{justify-self:end;font-size:12px;font-weight:800;letter-spacing:.08em;color:#fff;background:#dc2626;border-radius:10px;padding:7px 16px;box-shadow:0 0 0 3px rgba(220,38,38,.25)}
++.feed{list-style:none;display:grid;gap:8px;padding:2px}
++.feed li{display:flex;align-items:flex-start;gap:10px;font-size:13.5px;line-height:1.45;padding:10px 12px;border-radius:12px;background:var(--bg-secondary);border:1px solid var(--border);color:var(--text-secondary)}
++.feed li i{color:#22c55e;margin-top:3px}
++.feed li.ask{flex-wrap:wrap;border-color:rgba(var(--site-rgb),.45);background:rgba(var(--site-rgb),.08);color:var(--text-primary)}.feed li.ask i{color:var(--site)}.feed li.ask>span:first-of-type{flex:1;min-width:160px}
++.feed .pills{display:flex;gap:6px;margin-left:auto}.feed .pills span{font-size:12px;font-weight:600;padding:4px 11px;border-radius:999px;border:1px solid var(--border);color:var(--text-secondary)}.feed .pills .ok{background:var(--site);border-color:var(--site);color:#0b0d10}
++.steps{list-style:none;display:grid;grid-template-columns:repeat(auto-fit,minmax(230px,1fr));gap:14px;counter-reset:s}
++.steps li{position:relative;background:var(--bg-card);border:1px solid var(--border);border-radius:16px;padding:20px 20px 20px;display:flex;flex-direction:column;gap:8px}
++.steps .n{width:30px;height:30px;border-radius:50%;display:grid;place-items:center;font-weight:800;font-size:14px;color:#0b0d10;background:var(--site)}
++.steps b{font-size:15px}.steps span:last-child{font-size:13px;color:var(--text-secondary);line-height:1.55}
++.grid.three{grid-template-columns:repeat(auto-fit,minmax(280px,1fr))}
++.choice{display:grid;grid-template-columns:repeat(auto-fit,minmax(280px,1fr));gap:14px}
++.card.big{padding:24px}.card.big b{font-size:17px}
++.chips{display:flex;flex-wrap:wrap;gap:7px;margin-top:6px}
++.chips span{font-size:12.5px;padding:6px 11px;border-radius:999px;border:1px solid var(--border);background:var(--bg-secondary);color:var(--text-secondary)}
++.chips.big span{font-size:13.5px;padding:9px 14px;color:var(--text-primary)}.chips.big span i{color:var(--site);margin-right:8px}
++.build .card{border-style:dashed;background:rgba(0,0,0,.15)}.build .card b i{color:var(--site);margin-right:6px}.build .card span a{color:var(--text-secondary)}.build .card code{font-size:12px}
++@media (max-width:860px){.hero.split{grid-template-columns:1fr;text-align:center;gap:28px}.hero.split .ctas{justify-content:center}.hero.split p.lead{margin:0 auto}}
++@media (max-width:600px){.hero{padding-top:56px}.ctas .btn{width:100%;justify-content:center}.viz-ctrl{flex-direction:column;align-items:stretch}.dpad{align-self:center}}
@media (prefers-reduced-motion:reduce){*{animation:none!important;transition:none!important}}
</style>
</head>
ddiff --git a/dist/openvibe.pics/release.json b/dist/openvibe.pics/release.json
iindex a445053..70900c9 100644
---- a/dist/openvibe.pics/release.json
++++ b/dist/openvibe.pics/release.json
@@@ -1,6 +1,6 @@
{
"service": "pics",
-- "release": "8f5b4b79af95",
++ "release": "e72016bc0394",
"released_at": "2026-09-29T00:00:00.000Z",
"booted_at": null,
"contracts_version": null,
ddiff --git a/dist/openvibe.quest/index.html b/dist/openvibe.quest/index.html
iindex 3fd250a..d85b18d 100644
---- a/dist/openvibe.quest/index.html
++++ b/dist/openvibe.quest/index.html
@@@ -87,7 +87,50 @@ a.card:hover{transform:translateY(-3px);border-color:rgba(var(--site-rgb),.6);bo
.strip h3{font-size:19px;font-weight:700;margin:12px 0 8px}
.strip p{font-size:14px;color:var(--text-secondary);max-width:600px;margin:0 auto 18px;line-height:1.6}
.strip .ov-mark{width:44px;height:44px}
--@media (max-width:600px){.hero{padding-top:56px}.ctas .btn{width:100%;justify-content:center}}
++.hero.split{display:grid;grid-template-columns:minmax(0,1.05fr) minmax(0,1fr);gap:40px;align-items:center;text-align:left;padding-top:64px}
++.hero.split .ctas{justify-content:flex-start}.hero.split p.lead{margin:0}
++.viz{background:var(--bg-card);border:1px solid var(--border);border-radius:20px;padding:14px;box-shadow:0 30px 80px rgba(0,0,0,.45),0 0 0 1px rgba(var(--site-rgb),.08);animation:rise .7s .25s cubic-bezier(.2,.8,.2,1) both;text-align:left}
++.viz figcaption{margin-top:10px;font-size:11.5px;color:var(--text-muted);text-align:center}
++.viz-top{display:flex;align-items:center;gap:8px;font-size:13px;padding:2px 4px 12px}
++.viz-top b{font-weight:700}.viz-top .muted{color:var(--text-muted)}
++.viz-top .lat{margin-left:auto;font-size:12px;color:var(--site);background:rgba(var(--site-rgb),.1);border:1px solid rgba(var(--site-rgb),.3);padding:3px 9px;border-radius:999px}
++.viz-top .dot{width:8px;height:8px;border-radius:50%;background:#22c55e;box-shadow:0 0 0 4px rgba(34,197,94,.18)}
++.viz-top .av{width:26px;height:26px;border-radius:8px;display:grid;place-items:center;background:rgba(var(--site-rgb),.15);color:var(--site);font-size:13px}
++.viz-video{position:relative;aspect-ratio:16/9;border-radius:14px;overflow:hidden;background:radial-gradient(120% 90% at 30% 20%,rgba(var(--site-rgb),.28),transparent 60%),linear-gradient(160deg,#1a2338,#0b1020 70%);border:1px solid var(--border)}
++.viz-video::after{content:'';position:absolute;left:10%;right:10%;bottom:0;height:42%;background:linear-gradient(transparent,rgba(0,0,0,.35)),repeating-linear-gradient(90deg,rgba(255,255,255,.05) 0 1px,transparent 1px 38px);transform:perspective(220px) rotateX(58deg);transform-origin:bottom}
++.viz-video .scan{position:absolute;inset:0;background:linear-gradient(transparent 0,rgba(255,255,255,.04) 50%,transparent 100%);background-size:100% 6px;opacity:.5}
++.viz-video .onair{position:absolute;top:10px;left:10px;font-size:11px;font-weight:700;padding:3px 8px;border-radius:6px;background:rgba(239,68,68,.9);color:#fff}.viz-video .onair i{font-size:7px;vertical-align:2px;margin-right:3px}
++.viz-video .cam{position:absolute;bottom:10px;right:10px;font-size:11px;color:#dbe4f5;background:rgba(0,0,0,.45);padding:3px 8px;border-radius:6px}
++.viz-ctrl{display:flex;gap:14px;align-items:center;margin-top:12px}
++.dpad{display:grid;grid-template-columns:repeat(3,34px);grid-template-rows:repeat(3,34px);gap:4px;flex:none}
++.dpad span{display:grid;place-items:center;border-radius:9px;background:var(--bg-hover);color:var(--text-primary);font-size:15px;border:1px solid var(--border)}
++.dpad .u{grid-area:1/2}.dpad .l{grid-area:2/1}.dpad .c{grid-area:2/2;background:rgba(var(--site-rgb),.15);border-color:rgba(var(--site-rgb),.35)}.dpad .r{grid-area:2/3}.dpad .d{grid-area:3/2}
++.dpad .u{background:rgba(var(--site-rgb),.22);border-color:rgba(var(--site-rgb),.5)}
++.viz-side{flex:1;min-width:0;display:grid;gap:8px}
++.viz-side .keys{display:flex;flex-wrap:wrap;gap:6px}
++.viz-side .keys span{font-size:11.5px;padding:5px 9px;border-radius:8px;background:var(--bg-secondary);border:1px solid var(--border);color:var(--text-secondary)}
++.viz-side .meter{display:flex;align-items:center;gap:8px;font-size:11.5px;color:var(--text-muted)}
++.viz-side .meter i{flex:1;height:6px;border-radius:9px;background:linear-gradient(90deg,#22c55e var(--v),var(--bg-hover) var(--v))}
++.viz-side .meter b{color:var(--text-secondary);font-weight:600}
++.viz-side .estop{justify-self:end;font-size:12px;font-weight:800;letter-spacing:.08em;color:#fff;background:#dc2626;border-radius:10px;padding:7px 16px;box-shadow:0 0 0 3px rgba(220,38,38,.25)}
++.feed{list-style:none;display:grid;gap:8px;padding:2px}
++.feed li{display:flex;align-items:flex-start;gap:10px;font-size:13.5px;line-height:1.45;padding:10px 12px;border-radius:12px;background:var(--bg-secondary);border:1px solid var(--border);color:var(--text-secondary)}
++.feed li i{color:#22c55e;margin-top:3px}
++.feed li.ask{flex-wrap:wrap;border-color:rgba(var(--site-rgb),.45);background:rgba(var(--site-rgb),.08);color:var(--text-primary)}.feed li.ask i{color:var(--site)}.feed li.ask>span:first-of-type{flex:1;min-width:160px}
++.feed .pills{display:flex;gap:6px;margin-left:auto}.feed .pills span{font-size:12px;font-weight:600;padding:4px 11px;border-radius:999px;border:1px solid var(--border);color:var(--text-secondary)}.feed .pills .ok{background:var(--site);border-color:var(--site);color:#0b0d10}
++.steps{list-style:none;display:grid;grid-template-columns:repeat(auto-fit,minmax(230px,1fr));gap:14px;counter-reset:s}
++.steps li{position:relative;background:var(--bg-card);border:1px solid var(--border);border-radius:16px;padding:20px 20px 20px;display:flex;flex-direction:column;gap:8px}
++.steps .n{width:30px;height:30px;border-radius:50%;display:grid;place-items:center;font-weight:800;font-size:14px;color:#0b0d10;background:var(--site)}
++.steps b{font-size:15px}.steps span:last-child{font-size:13px;color:var(--text-secondary);line-height:1.55}
++.grid.three{grid-template-columns:repeat(auto-fit,minmax(280px,1fr))}
++.choice{display:grid;grid-template-columns:repeat(auto-fit,minmax(280px,1fr));gap:14px}
++.card.big{padding:24px}.card.big b{font-size:17px}
++.chips{display:flex;flex-wrap:wrap;gap:7px;margin-top:6px}
++.chips span{font-size:12.5px;padding:6px 11px;border-radius:999px;border:1px solid var(--border);background:var(--bg-secondary);color:var(--text-secondary)}
++.chips.big span{font-size:13.5px;padding:9px 14px;color:var(--text-primary)}.chips.big span i{color:var(--site);margin-right:8px}
++.build .card{border-style:dashed;background:rgba(0,0,0,.15)}.build .card b i{color:var(--site);margin-right:6px}.build .card span a{color:var(--text-secondary)}.build .card code{font-size:12px}
++@media (max-width:860px){.hero.split{grid-template-columns:1fr;text-align:center;gap:28px}.hero.split .ctas{justify-content:center}.hero.split p.lead{margin:0 auto}}
++@media (max-width:600px){.hero{padding-top:56px}.ctas .btn{width:100%;justify-content:center}.viz-ctrl{flex-direction:column;align-items:stretch}.dpad{align-self:center}}
@media (prefers-reduced-motion:reduce){*{animation:none!important;transition:none!important}}
</style>
</head>
ddiff --git a/dist/openvibe.quest/release.json b/dist/openvibe.quest/release.json
iindex 0cde168..8de67ae 100644
---- a/dist/openvibe.quest/release.json
++++ b/dist/openvibe.quest/release.json
@@@ -1,6 +1,6 @@
{
"service": "quest",
-- "release": "60f2d7cbdd53",
++ "release": "61a9d8435854",
"released_at": "2026-09-29T00:00:00.000Z",
"booted_at": null,
"contracts_version": null,
ddiff --git a/dist/openvibe.rent/index.html b/dist/openvibe.rent/index.html
iindex 5659269..c2399e5 100644
---- a/dist/openvibe.rent/index.html
++++ b/dist/openvibe.rent/index.html
@@@ -87,7 +87,50 @@ a.card:hover{transform:translateY(-3px);border-color:rgba(var(--site-rgb),.6);bo
.strip h3{font-size:19px;font-weight:700;margin:12px 0 8px}
.strip p{font-size:14px;color:var(--text-secondary);max-width:600px;margin:0 auto 18px;line-height:1.6}
.strip .ov-mark{width:44px;height:44px}
--@media (max-width:600px){.hero{padding-top:56px}.ctas .btn{width:100%;justify-content:center}}
++.hero.split{display:grid;grid-template-columns:minmax(0,1.05fr) minmax(0,1fr);gap:40px;align-items:center;text-align:left;padding-top:64px}
++.hero.split .ctas{justify-content:flex-start}.hero.split p.lead{margin:0}
++.viz{background:var(--bg-card);border:1px solid var(--border);border-radius:20px;padding:14px;box-shadow:0 30px 80px rgba(0,0,0,.45),0 0 0 1px rgba(var(--site-rgb),.08);animation:rise .7s .25s cubic-bezier(.2,.8,.2,1) both;text-align:left}
++.viz figcaption{margin-top:10px;font-size:11.5px;color:var(--text-muted);text-align:center}
++.viz-top{display:flex;align-items:center;gap:8px;font-size:13px;padding:2px 4px 12px}
++.viz-top b{font-weight:700}.viz-top .muted{color:var(--text-muted)}
++.viz-top .lat{margin-left:auto;font-size:12px;color:var(--site);background:rgba(var(--site-rgb),.1);border:1px solid rgba(var(--site-rgb),.3);padding:3px 9px;border-radius:999px}
++.viz-top .dot{width:8px;height:8px;border-radius:50%;background:#22c55e;box-shadow:0 0 0 4px rgba(34,197,94,.18)}
++.viz-top .av{width:26px;height:26px;border-radius:8px;display:grid;place-items:center;background:rgba(var(--site-rgb),.15);color:var(--site);font-size:13px}
++.viz-video{position:relative;aspect-ratio:16/9;border-radius:14px;overflow:hidden;background:radial-gradient(120% 90% at 30% 20%,rgba(var(--site-rgb),.28),transparent 60%),linear-gradient(160deg,#1a2338,#0b1020 70%);border:1px solid var(--border)}
++.viz-video::after{content:'';position:absolute;left:10%;right:10%;bottom:0;height:42%;background:linear-gradient(transparent,rgba(0,0,0,.35)),repeating-linear-gradient(90deg,rgba(255,255,255,.05) 0 1px,transparent 1px 38px);transform:perspective(220px) rotateX(58deg);transform-origin:bottom}
++.viz-video .scan{position:absolute;inset:0;background:linear-gradient(transparent 0,rgba(255,255,255,.04) 50%,transparent 100%);background-size:100% 6px;opacity:.5}
++.viz-video .onair{position:absolute;top:10px;left:10px;font-size:11px;font-weight:700;padding:3px 8px;border-radius:6px;background:rgba(239,68,68,.9);color:#fff}.viz-video .onair i{font-size:7px;vertical-align:2px;margin-right:3px}
++.viz-video .cam{position:absolute;bottom:10px;right:10px;font-size:11px;color:#dbe4f5;background:rgba(0,0,0,.45);padding:3px 8px;border-radius:6px}
++.viz-ctrl{display:flex;gap:14px;align-items:center;margin-top:12px}
++.dpad{display:grid;grid-template-columns:repeat(3,34px);grid-template-rows:repeat(3,34px);gap:4px;flex:none}
++.dpad span{display:grid;place-items:center;border-radius:9px;background:var(--bg-hover);color:var(--text-primary);font-size:15px;border:1px solid var(--border)}
++.dpad .u{grid-area:1/2}.dpad .l{grid-area:2/1}.dpad .c{grid-area:2/2;background:rgba(var(--site-rgb),.15);border-color:rgba(var(--site-rgb),.35)}.dpad .r{grid-area:2/3}.dpad .d{grid-area:3/2}
++.dpad .u{background:rgba(var(--site-rgb),.22);border-color:rgba(var(--site-rgb),.5)}
++.viz-side{flex:1;min-width:0;display:grid;gap:8px}
++.viz-side .keys{display:flex;flex-wrap:wrap;gap:6px}
++.viz-side .keys span{font-size:11.5px;padding:5px 9px;border-radius:8px;background:var(--bg-secondary);border:1px solid var(--border);color:var(--text-secondary)}
++.viz-side .meter{display:flex;align-items:center;gap:8px;font-size:11.5px;color:var(--text-muted)}
++.viz-side .meter i{flex:1;height:6px;border-radius:9px;background:linear-gradient(90deg,#22c55e var(--v),var(--bg-hover) var(--v))}
++.viz-side .meter b{color:var(--text-secondary);font-weight:600}
++.viz-side .estop{justify-self:end;font-size:12px;font-weight:800;letter-spacing:.08em;color:#fff;background:#dc2626;border-radius:10px;padding:7px 16px;box-shadow:0 0 0 3px rgba(220,38,38,.25)}
++.feed{list-style:none;display:grid;gap:8px;padding:2px}
++.feed li{display:flex;align-items:flex-start;gap:10px;font-size:13.5px;line-height:1.45;padding:10px 12px;border-radius:12px;background:var(--bg-secondary);border:1px solid var(--border);color:var(--text-secondary)}
++.feed li i{color:#22c55e;margin-top:3px}
++.feed li.ask{flex-wrap:wrap;border-color:rgba(var(--site-rgb),.45);background:rgba(var(--site-rgb),.08);color:var(--text-primary)}.feed li.ask i{color:var(--site)}.feed li.ask>span:first-of-type{flex:1;min-width:160px}
++.feed .pills{display:flex;gap:6px;margin-left:auto}.feed .pills span{font-size:12px;font-weight:600;padding:4px 11px;border-radius:999px;border:1px solid var(--border);color:var(--text-secondary)}.feed .pills .ok{background:var(--site);border-color:var(--site);color:#0b0d10}
++.steps{list-style:none;display:grid;grid-template-columns:repeat(auto-fit,minmax(230px,1fr));gap:14px;counter-reset:s}
++.steps li{position:relative;background:var(--bg-card);border:1px solid var(--border);border-radius:16px;padding:20px 20px 20px;display:flex;flex-direction:column;gap:8px}
++.steps .n{width:30px;height:30px;border-radius:50%;display:grid;place-items:center;font-weight:800;font-size:14px;color:#0b0d10;background:var(--site)}
++.steps b{font-size:15px}.steps span:last-child{font-size:13px;color:var(--text-secondary);line-height:1.55}
++.grid.three{grid-template-columns:repeat(auto-fit,minmax(280px,1fr))}
++.choice{display:grid;grid-template-columns:repeat(auto-fit,minmax(280px,1fr));gap:14px}
++.card.big{padding:24px}.card.big b{font-size:17px}
++.chips{display:flex;flex-wrap:wrap;gap:7px;margin-top:6px}
++.chips span{font-size:12.5px;padding:6px 11px;border-radius:999px;border:1px solid var(--border);background:var(--bg-secondary);color:var(--text-secondary)}
++.chips.big span{font-size:13.5px;padding:9px 14px;color:var(--text-primary)}.chips.big span i{color:var(--site);margin-right:8px}
++.build .card{border-style:dashed;background:rgba(0,0,0,.15)}.build .card b i{color:var(--site);margin-right:6px}.build .card span a{color:var(--text-secondary)}.build .card code{font-size:12px}
++@media (max-width:860px){.hero.split{grid-template-columns:1fr;text-align:center;gap:28px}.hero.split .ctas{justify-content:center}.hero.split p.lead{margin:0 auto}}
++@media (max-width:600px){.hero{padding-top:56px}.ctas .btn{width:100%;justify-content:center}.viz-ctrl{flex-direction:column;align-items:stretch}.dpad{align-self:center}}
@media (prefers-reduced-motion:reduce){*{animation:none!important;transition:none!important}}
</style>
</head>
ddiff --git a/dist/openvibe.rent/release.json b/dist/openvibe.rent/release.json
iindex 04e8926..8aa028b 100644
---- a/dist/openvibe.rent/release.json
++++ b/dist/openvibe.rent/release.json
@@@ -1,6 +1,6 @@
{
"service": "rent",
-- "release": "52cd959f20b1",
++ "release": "c4da9315548d",
"released_at": "2026-09-29T00:00:00.000Z",
"booted_at": null,
"contracts_version": null,
ddiff --git a/dist/openvibe.reviews/index.html b/dist/openvibe.reviews/index.html
iindex 4b26269..1dc3d2b 100644
---- a/dist/openvibe.reviews/index.html
++++ b/dist/openvibe.reviews/index.html
@@@ -87,7 +87,50 @@ a.card:hover{transform:translateY(-3px);border-color:rgba(var(--site-rgb),.6);bo
.strip h3{font-size:19px;font-weight:700;margin:12px 0 8px}
.strip p{font-size:14px;color:var(--text-secondary);max-width:600px;margin:0 auto 18px;line-height:1.6}
.strip .ov-mark{width:44px;height:44px}
--@media (max-width:600px){.hero{padding-top:56px}.ctas .btn{width:100%;justify-content:center}}
++.hero.split{display:grid;grid-template-columns:minmax(0,1.05fr) minmax(0,1fr);gap:40px;align-items:center;text-align:left;padding-top:64px}
++.hero.split .ctas{justify-content:flex-start}.hero.split p.lead{margin:0}
++.viz{background:var(--bg-card);border:1px solid var(--border);border-radius:20px;padding:14px;box-shadow:0 30px 80px rgba(0,0,0,.45),0 0 0 1px rgba(var(--site-rgb),.08);animation:rise .7s .25s cubic-bezier(.2,.8,.2,1) both;text-align:left}
++.viz figcaption{margin-top:10px;font-size:11.5px;color:var(--text-muted);text-align:center}
++.viz-top{display:flex;align-items:center;gap:8px;font-size:13px;padding:2px 4px 12px}
++.viz-top b{font-weight:700}.viz-top .muted{color:var(--text-muted)}
++.viz-top .lat{margin-left:auto;font-size:12px;color:var(--site);background:rgba(var(--site-rgb),.1);border:1px solid rgba(var(--site-rgb),.3);padding:3px 9px;border-radius:999px}
++.viz-top .dot{width:8px;height:8px;border-radius:50%;background:#22c55e;box-shadow:0 0 0 4px rgba(34,197,94,.18)}
++.viz-top .av{width:26px;height:26px;border-radius:8px;display:grid;place-items:center;background:rgba(var(--site-rgb),.15);color:var(--site);font-size:13px}
++.viz-video{position:relative;aspect-ratio:16/9;border-radius:14px;overflow:hidden;background:radial-gradient(120% 90% at 30% 20%,rgba(var(--site-rgb),.28),transparent 60%),linear-gradient(160deg,#1a2338,#0b1020 70%);border:1px solid var(--border)}
++.viz-video::after{content:'';position:absolute;left:10%;right:10%;bottom:0;height:42%;background:linear-gradient(transparent,rgba(0,0,0,.35)),repeating-linear-gradient(90deg,rgba(255,255,255,.05) 0 1px,transparent 1px 38px);transform:perspective(220px) rotateX(58deg);transform-origin:bottom}
++.viz-video .scan{position:absolute;inset:0;background:linear-gradient(transparent 0,rgba(255,255,255,.04) 50%,transparent 100%);background-size:100% 6px;opacity:.5}
++.viz-video .onair{position:absolute;top:10px;left:10px;font-size:11px;font-weight:700;padding:3px 8px;border-radius:6px;background:rgba(239,68,68,.9);color:#fff}.viz-video .onair i{font-size:7px;vertical-align:2px;margin-right:3px}
++.viz-video .cam{position:absolute;bottom:10px;right:10px;font-size:11px;color:#dbe4f5;background:rgba(0,0,0,.45);padding:3px 8px;border-radius:6px}
++.viz-ctrl{display:flex;gap:14px;align-items:center;margin-top:12px}
++.dpad{display:grid;grid-template-columns:repeat(3,34px);grid-template-rows:repeat(3,34px);gap:4px;flex:none}
++.dpad span{display:grid;place-items:center;border-radius:9px;background:var(--bg-hover);color:var(--text-primary);font-size:15px;border:1px solid var(--border)}
++.dpad .u{grid-area:1/2}.dpad .l{grid-area:2/1}.dpad .c{grid-area:2/2;background:rgba(var(--site-rgb),.15);border-color:rgba(var(--site-rgb),.35)}.dpad .r{grid-area:2/3}.dpad .d{grid-area:3/2}
++.dpad .u{background:rgba(var(--site-rgb),.22);border-color:rgba(var(--site-rgb),.5)}
++.viz-side{flex:1;min-width:0;display:grid;gap:8px}
++.viz-side .keys{display:flex;flex-wrap:wrap;gap:6px}
++.viz-side .keys span{font-size:11.5px;padding:5px 9px;border-radius:8px;background:var(--bg-secondary);border:1px solid var(--border);color:var(--text-secondary)}
++.viz-side .meter{display:flex;align-items:center;gap:8px;font-size:11.5px;color:var(--text-muted)}
++.viz-side .meter i{flex:1;height:6px;border-radius:9px;background:linear-gradient(90deg,#22c55e var(--v),var(--bg-hover) var(--v))}
++.viz-side .meter b{color:var(--text-secondary);font-weight:600}
++.viz-side .estop{justify-self:end;font-size:12px;font-weight:800;letter-spacing:.08em;color:#fff;background:#dc2626;border-radius:10px;padding:7px 16px;box-shadow:0 0 0 3px rgba(220,38,38,.25)}
++.feed{list-style:none;display:grid;gap:8px;padding:2px}
++.feed li{display:flex;align-items:flex-start;gap:10px;font-size:13.5px;line-height:1.45;padding:10px 12px;border-radius:12px;background:var(--bg-secondary);border:1px solid var(--border);color:var(--text-secondary)}
++.feed li i{color:#22c55e;margin-top:3px}
++.feed li.ask{flex-wrap:wrap;border-color:rgba(var(--site-rgb),.45);background:rgba(var(--site-rgb),.08);color:var(--text-primary)}.feed li.ask i{color:var(--site)}.feed li.ask>span:first-of-type{flex:1;min-width:160px}
++.feed .pills{display:flex;gap:6px;margin-left:auto}.feed .pills span{font-size:12px;font-weight:600;padding:4px 11px;border-radius:999px;border:1px solid var(--border);color:var(--text-secondary)}.feed .pills .ok{background:var(--site);border-color:var(--site);color:#0b0d10}
++.steps{list-style:none;display:grid;grid-template-columns:repeat(auto-fit,minmax(230px,1fr));gap:14px;counter-reset:s}
++.steps li{position:relative;background:var(--bg-card);border:1px solid var(--border);border-radius:16px;padding:20px 20px 20px;display:flex;flex-direction:column;gap:8px}
++.steps .n{width:30px;height:30px;border-radius:50%;display:grid;place-items:center;font-weight:800;font-size:14px;color:#0b0d10;background:var(--site)}
++.steps b{font-size:15px}.steps span:last-child{font-size:13px;color:var(--text-secondary);line-height:1.55}
++.grid.three{grid-template-columns:repeat(auto-fit,minmax(280px,1fr))}
++.choice{display:grid;grid-template-columns:repeat(auto-fit,minmax(280px,1fr));gap:14px}
++.card.big{padding:24px}.card.big b{font-size:17px}
++.chips{display:flex;flex-wrap:wrap;gap:7px;margin-top:6px}
++.chips span{font-size:12.5px;padding:6px 11px;border-radius:999px;border:1px solid var(--border);background:var(--bg-secondary);color:var(--text-secondary)}
++.chips.big span{font-size:13.5px;padding:9px 14px;color:var(--text-primary)}.chips.big span i{color:var(--site);margin-right:8px}
++.build .card{border-style:dashed;background:rgba(0,0,0,.15)}.build .card b i{color:var(--site);margin-right:6px}.build .card span a{color:var(--text-secondary)}.build .card code{font-size:12px}
++@media (max-width:860px){.hero.split{grid-template-columns:1fr;text-align:center;gap:28px}.hero.split .ctas{justify-content:center}.hero.split p.lead{margin:0 auto}}
++@media (max-width:600px){.hero{padding-top:56px}.ctas .btn{width:100%;justify-content:center}.viz-ctrl{flex-direction:column;align-items:stretch}.dpad{align-self:center}}
@media (prefers-reduced-motion:reduce){*{animation:none!important;transition:none!important}}
</style>
</head>
ddiff --git a/dist/openvibe.reviews/release.json b/dist/openvibe.reviews/release.json
iindex 4ad1169..62e8139 100644
---- a/dist/openvibe.reviews/release.json
++++ b/dist/openvibe.reviews/release.json
@@@ -1,6 +1,6 @@
{
"service": "reviews",
-- "release": "b33fec5ccfe3",
++ "release": "d33908ce7111",
"released_at": "2026-09-29T00:00:00.000Z",
"booted_at": null,
"contracts_version": null,
ddiff --git a/dist/openvibe.run/index.html b/dist/openvibe.run/index.html
iindex a82508c..7e63502 100644
---- a/dist/openvibe.run/index.html
++++ b/dist/openvibe.run/index.html
@@@ -87,7 +87,50 @@ a.card:hover{transform:translateY(-3px);border-color:rgba(var(--site-rgb),.6);bo
.strip h3{font-size:19px;font-weight:700;margin:12px 0 8px}
.strip p{font-size:14px;color:var(--text-secondary);max-width:600px;margin:0 auto 18px;line-height:1.6}
.strip .ov-mark{width:44px;height:44px}
--@media (max-width:600px){.hero{padding-top:56px}.ctas .btn{width:100%;justify-content:center}}
++.hero.split{display:grid;grid-template-columns:minmax(0,1.05fr) minmax(0,1fr);gap:40px;align-items:center;text-align:left;padding-top:64px}
++.hero.split .ctas{justify-content:flex-start}.hero.split p.lead{margin:0}
++.viz{background:var(--bg-card);border:1px solid var(--border);border-radius:20px;padding:14px;box-shadow:0 30px 80px rgba(0,0,0,.45),0 0 0 1px rgba(var(--site-rgb),.08);animation:rise .7s .25s cubic-bezier(.2,.8,.2,1) both;text-align:left}
++.viz figcaption{margin-top:10px;font-size:11.5px;color:var(--text-muted);text-align:center}
++.viz-top{display:flex;align-items:center;gap:8px;font-size:13px;padding:2px 4px 12px}
++.viz-top b{font-weight:700}.viz-top .muted{color:var(--text-muted)}
++.viz-top .lat{margin-left:auto;font-size:12px;color:var(--site);background:rgba(var(--site-rgb),.1);border:1px solid rgba(var(--site-rgb),.3);padding:3px 9px;border-radius:999px}
++.viz-top .dot{width:8px;height:8px;border-radius:50%;background:#22c55e;box-shadow:0 0 0 4px rgba(34,197,94,.18)}
++.viz-top .av{width:26px;height:26px;border-radius:8px;display:grid;place-items:center;background:rgba(var(--site-rgb),.15);color:var(--site);font-size:13px}
++.viz-video{position:relative;aspect-ratio:16/9;border-radius:14px;overflow:hidden;background:radial-gradient(120% 90% at 30% 20%,rgba(var(--site-rgb),.28),transparent 60%),linear-gradient(160deg,#1a2338,#0b1020 70%);border:1px solid var(--border)}
++.viz-video::after{content:'';position:absolute;left:10%;right:10%;bottom:0;height:42%;background:linear-gradient(transparent,rgba(0,0,0,.35)),repeating-linear-gradient(90deg,rgba(255,255,255,.05) 0 1px,transparent 1px 38px);transform:perspective(220px) rotateX(58deg);transform-origin:bottom}
++.viz-video .scan{position:absolute;inset:0;background:linear-gradient(transparent 0,rgba(255,255,255,.04) 50%,transparent 100%);background-size:100% 6px;opacity:.5}
++.viz-video .onair{position:absolute;top:10px;left:10px;font-size:11px;font-weight:700;padding:3px 8px;border-radius:6px;background:rgba(239,68,68,.9);color:#fff}.viz-video .onair i{font-size:7px;vertical-align:2px;margin-right:3px}
++.viz-video .cam{position:absolute;bottom:10px;right:10px;font-size:11px;color:#dbe4f5;background:rgba(0,0,0,.45);padding:3px 8px;border-radius:6px}
++.viz-ctrl{display:flex;gap:14px;align-items:center;margin-top:12px}
++.dpad{display:grid;grid-template-columns:repeat(3,34px);grid-template-rows:repeat(3,34px);gap:4px;flex:none}
++.dpad span{display:grid;place-items:center;border-radius:9px;background:var(--bg-hover);color:var(--text-primary);font-size:15px;border:1px solid var(--border)}
++.dpad .u{grid-area:1/2}.dpad .l{grid-area:2/1}.dpad .c{grid-area:2/2;background:rgba(var(--site-rgb),.15);border-color:rgba(var(--site-rgb),.35)}.dpad .r{grid-area:2/3}.dpad .d{grid-area:3/2}
++.dpad .u{background:rgba(var(--site-rgb),.22);border-color:rgba(var(--site-rgb),.5)}
++.viz-side{flex:1;min-width:0;display:grid;gap:8px}
++.viz-side .keys{display:flex;flex-wrap:wrap;gap:6px}
++.viz-side .keys span{font-size:11.5px;padding:5px 9px;border-radius:8px;background:var(--bg-secondary);border:1px solid var(--border);color:var(--text-secondary)}
++.viz-side .meter{display:flex;align-items:center;gap:8px;font-size:11.5px;color:var(--text-muted)}
++.viz-side .meter i{flex:1;height:6px;border-radius:9px;background:linear-gradient(90deg,#22c55e var(--v),var(--bg-hover) var(--v))}
++.viz-side .meter b{color:var(--text-secondary);font-weight:600}
++.viz-side .estop{justify-self:end;font-size:12px;font-weight:800;letter-spacing:.08em;color:#fff;background:#dc2626;border-radius:10px;padding:7px 16px;box-shadow:0 0 0 3px rgba(220,38,38,.25)}
++.feed{list-style:none;display:grid;gap:8px;padding:2px}
++.feed li{display:flex;align-items:flex-start;gap:10px;font-size:13.5px;line-height:1.45;padding:10px 12px;border-radius:12px;background:var(--bg-secondary);border:1px solid var(--border);color:var(--text-secondary)}
++.feed li i{color:#22c55e;margin-top:3px}
++.feed li.ask{flex-wrap:wrap;border-color:rgba(var(--site-rgb),.45);background:rgba(var(--site-rgb),.08);color:var(--text-primary)}.feed li.ask i{color:var(--site)}.feed li.ask>span:first-of-type{flex:1;min-width:160px}
++.feed .pills{display:flex;gap:6px;margin-left:auto}.feed .pills span{font-size:12px;font-weight:600;padding:4px 11px;border-radius:999px;border:1px solid var(--border);color:var(--text-secondary)}.feed .pills .ok{background:var(--site);border-color:var(--site);color:#0b0d10}
++.steps{list-style:none;display:grid;grid-template-columns:repeat(auto-fit,minmax(230px,1fr));gap:14px;counter-reset:s}
++.steps li{position:relative;background:var(--bg-card);border:1px solid var(--border);border-radius:16px;padding:20px 20px 20px;display:flex;flex-direction:column;gap:8px}
++.steps .n{width:30px;height:30px;border-radius:50%;display:grid;place-items:center;font-weight:800;font-size:14px;color:#0b0d10;background:var(--site)}
++.steps b{font-size:15px}.steps span:last-child{font-size:13px;color:var(--text-secondary);line-height:1.55}
++.grid.three{grid-template-columns:repeat(auto-fit,minmax(280px,1fr))}
++.choice{display:grid;grid-template-columns:repeat(auto-fit,minmax(280px,1fr));gap:14px}
++.card.big{padding:24px}.card.big b{font-size:17px}
++.chips{display:flex;flex-wrap:wrap;gap:7px;margin-top:6px}
++.chips span{font-size:12.5px;padding:6px 11px;border-radius:999px;border:1px solid var(--border);background:var(--bg-secondary);color:var(--text-secondary)}
++.chips.big span{font-size:13.5px;padding:9px 14px;color:var(--text-primary)}.chips.big span i{color:var(--site);margin-right:8px}
++.build .card{border-style:dashed;background:rgba(0,0,0,.15)}.build .card b i{color:var(--site);margin-right:6px}.build .card span a{color:var(--text-secondary)}.build .card code{font-size:12px}
++@media (max-width:860px){.hero.split{grid-template-columns:1fr;text-align:center;gap:28px}.hero.split .ctas{justify-content:center}.hero.split p.lead{margin:0 auto}}
++@media (max-width:600px){.hero{padding-top:56px}.ctas .btn{width:100%;justify-content:center}.viz-ctrl{flex-direction:column;align-items:stretch}.dpad{align-self:center}}
@media (prefers-reduced-motion:reduce){*{animation:none!important;transition:none!important}}
</style>
</head>
ddiff --git a/dist/openvibe.run/release.json b/dist/openvibe.run/release.json
iindex 690a2e4..c912cf0 100644
---- a/dist/openvibe.run/release.json
++++ b/dist/openvibe.run/release.json
@@@ -1,6 +1,6 @@
{
"service": "run",
-- "release": "0c90b1047a94",
++ "release": "685bc59d6098",
"released_at": "2026-09-29T00:00:00.000Z",
"booted_at": null,
"contracts_version": null,
ddiff --git a/dist/openvibe.services/index.html b/dist/openvibe.services/index.html
iindex ffad477..1a68d04 100644
---- a/dist/openvibe.services/index.html
++++ b/dist/openvibe.services/index.html
@@@ -87,7 +87,50 @@ a.card:hover{transform:translateY(-3px);border-color:rgba(var(--site-rgb),.6);bo
.strip h3{font-size:19px;font-weight:700;margin:12px 0 8px}
.strip p{font-size:14px;color:var(--text-secondary);max-width:600px;margin:0 auto 18px;line-height:1.6}
.strip .ov-mark{width:44px;height:44px}
--@media (max-width:600px){.hero{padding-top:56px}.ctas .btn{width:100%;justify-content:center}}
++.hero.split{display:grid;grid-template-columns:minmax(0,1.05fr) minmax(0,1fr);gap:40px;align-items:center;text-align:left;padding-top:64px}
++.hero.split .ctas{justify-content:flex-start}.hero.split p.lead{margin:0}
++.viz{background:var(--bg-card);border:1px solid var(--border);border-radius:20px;padding:14px;box-shadow:0 30px 80px rgba(0,0,0,.45),0 0 0 1px rgba(var(--site-rgb),.08);animation:rise .7s .25s cubic-bezier(.2,.8,.2,1) both;text-align:left}
++.viz figcaption{margin-top:10px;font-size:11.5px;color:var(--text-muted);text-align:center}
++.viz-top{display:flex;align-items:center;gap:8px;font-size:13px;padding:2px 4px 12px}
++.viz-top b{font-weight:700}.viz-top .muted{color:var(--text-muted)}
++.viz-top .lat{margin-left:auto;font-size:12px;color:var(--site);background:rgba(var(--site-rgb),.1);border:1px solid rgba(var(--site-rgb),.3);padding:3px 9px;border-radius:999px}
++.viz-top .dot{width:8px;height:8px;border-radius:50%;background:#22c55e;box-shadow:0 0 0 4px rgba(34,197,94,.18)}
++.viz-top .av{width:26px;height:26px;border-radius:8px;display:grid;place-items:center;background:rgba(var(--site-rgb),.15);color:var(--site);font-size:13px}
++.viz-video{position:relative;aspect-ratio:16/9;border-radius:14px;overflow:hidden;background:radial-gradient(120% 90% at 30% 20%,rgba(var(--site-rgb),.28),transparent 60%),linear-gradient(160deg,#1a2338,#0b1020 70%);border:1px solid var(--border)}
++.viz-video::after{content:'';position:absolute;left:10%;right:10%;bottom:0;height:42%;background:linear-gradient(transparent,rgba(0,0,0,.35)),repeating-linear-gradient(90deg,rgba(255,255,255,.05) 0 1px,transparent 1px 38px);transform:perspective(220px) rotateX(58deg);transform-origin:bottom}
++.viz-video .scan{position:absolute;inset:0;background:linear-gradient(transparent 0,rgba(255,255,255,.04) 50%,transparent 100%);background-size:100% 6px;opacity:.5}
++.viz-video .onair{position:absolute;top:10px;left:10px;font-size:11px;font-weight:700;padding:3px 8px;border-radius:6px;background:rgba(239,68,68,.9);color:#fff}.viz-video .onair i{font-size:7px;vertical-align:2px;margin-right:3px}
++.viz-video .cam{position:absolute;bottom:10px;right:10px;font-size:11px;color:#dbe4f5;background:rgba(0,0,0,.45);padding:3px 8px;border-radius:6px}
++.viz-ctrl{display:flex;gap:14px;align-items:center;margin-top:12px}
++.dpad{display:grid;grid-template-columns:repeat(3,34px);grid-template-rows:repeat(3,34px);gap:4px;flex:none}
++.dpad span{display:grid;place-items:center;border-radius:9px;background:var(--bg-hover);color:var(--text-primary);font-size:15px;border:1px solid var(--border)}
++.dpad .u{grid-area:1/2}.dpad .l{grid-area:2/1}.dpad .c{grid-area:2/2;background:rgba(var(--site-rgb),.15);border-color:rgba(var(--site-rgb),.35)}.dpad .r{grid-area:2/3}.dpad .d{grid-area:3/2}
++.dpad .u{background:rgba(var(--site-rgb),.22);border-color:rgba(var(--site-rgb),.5)}
++.viz-side{flex:1;min-width:0;display:grid;gap:8px}
++.viz-side .keys{display:flex;flex-wrap:wrap;gap:6px}
++.viz-side .keys span{font-size:11.5px;padding:5px 9px;border-radius:8px;background:var(--bg-secondary);border:1px solid var(--border);color:var(--text-secondary)}
++.viz-side .meter{display:flex;align-items:center;gap:8px;font-size:11.5px;color:var(--text-muted)}
++.viz-side .meter i{flex:1;height:6px;border-radius:9px;background:linear-gradient(90deg,#22c55e var(--v),var(--bg-hover) var(--v))}
++.viz-side .meter b{color:var(--text-secondary);font-weight:600}
++.viz-side .estop{justify-self:end;font-size:12px;font-weight:800;letter-spacing:.08em;color:#fff;background:#dc2626;border-radius:10px;padding:7px 16px;box-shadow:0 0 0 3px rgba(220,38,38,.25)}
++.feed{list-style:none;display:grid;gap:8px;padding:2px}
++.feed li{display:flex;align-items:flex-start;gap:10px;font-size:13.5px;line-height:1.45;padding:10px 12px;border-radius:12px;background:var(--bg-secondary);border:1px solid var(--border);color:var(--text-secondary)}
++.feed li i{color:#22c55e;margin-top:3px}
++.feed li.ask{flex-wrap:wrap;border-color:rgba(var(--site-rgb),.45);background:rgba(var(--site-rgb),.08);color:var(--text-primary)}.feed li.ask i{color:var(--site)}.feed li.ask>span:first-of-type{flex:1;min-width:160px}
++.feed .pills{display:flex;gap:6px;margin-left:auto}.feed .pills span{font-size:12px;font-weight:600;padding:4px 11px;border-radius:999px;border:1px solid var(--border);color:var(--text-secondary)}.feed .pills .ok{background:var(--site);border-color:var(--site);color:#0b0d10}
++.steps{list-style:none;display:grid;grid-template-columns:repeat(auto-fit,minmax(230px,1fr));gap:14px;counter-reset:s}
++.steps li{position:relative;background:var(--bg-card);border:1px solid var(--border);border-radius:16px;padding:20px 20px 20px;display:flex;flex-direction:column;gap:8px}
++.steps .n{width:30px;height:30px;border-radius:50%;display:grid;place-items:center;font-weight:800;font-size:14px;color:#0b0d10;background:var(--site)}
++.steps b{font-size:15px}.steps span:last-child{font-size:13px;color:var(--text-secondary);line-height:1.55}
++.grid.three{grid-template-columns:repeat(auto-fit,minmax(280px,1fr))}
++.choice{display:grid;grid-template-columns:repeat(auto-fit,minmax(280px,1fr));gap:14px}
++.card.big{padding:24px}.card.big b{font-size:17px}
++.chips{display:flex;flex-wrap:wrap;gap:7px;margin-top:6px}
++.chips span{font-size:12.5px;padding:6px 11px;border-radius:999px;border:1px solid var(--border);background:var(--bg-secondary);color:var(--text-secondary)}
++.chips.big span{font-size:13.5px;padding:9px 14px;color:var(--text-primary)}.chips.big span i{color:var(--site);margin-right:8px}
++.build .card{border-style:dashed;background:rgba(0,0,0,.15)}.build .card b i{color:var(--site);margin-right:6px}.build .card span a{color:var(--text-secondary)}.build .card code{font-size:12px}
++@media (max-width:860px){.hero.split{grid-template-columns:1fr;text-align:center;gap:28px}.hero.split .ctas{justify-content:center}.hero.split p.lead{margin:0 auto}}
++@media (max-width:600px){.hero{padding-top:56px}.ctas .btn{width:100%;justify-content:center}.viz-ctrl{flex-direction:column;align-items:stretch}.dpad{align-self:center}}
@media (prefers-reduced-motion:reduce){*{animation:none!important;transition:none!important}}
</style>
</head>
ddiff --git a/dist/openvibe.services/release.json b/dist/openvibe.services/release.json
iindex 3e8044c..c736aae 100644
---- a/dist/openvibe.services/release.json
++++ b/dist/openvibe.services/release.json
@@@ -1,6 +1,6 @@
{
"service": "services",
-- "release": "6f42ac8e6dec",
++ "release": "3c4ff0411564",
"released_at": "2026-09-29T00:00:00.000Z",
"booted_at": null,
"contracts_version": null,
ddiff --git a/dist/openvibe.space/index.html b/dist/openvibe.space/index.html
iindex dffa1e0..6d84008 100644
---- a/dist/openvibe.space/index.html
++++ b/dist/openvibe.space/index.html
@@@ -87,7 +87,50 @@ a.card:hover{transform:translateY(-3px);border-color:rgba(var(--site-rgb),.6);bo
.strip h3{font-size:19px;font-weight:700;margin:12px 0 8px}
.strip p{font-size:14px;color:var(--text-secondary);max-width:600px;margin:0 auto 18px;line-height:1.6}
.strip .ov-mark{width:44px;height:44px}
--@media (max-width:600px){.hero{padding-top:56px}.ctas .btn{width:100%;justify-content:center}}
++.hero.split{display:grid;grid-template-columns:minmax(0,1.05fr) minmax(0,1fr);gap:40px;align-items:center;text-align:left;padding-top:64px}
++.hero.split .ctas{justify-content:flex-start}.hero.split p.lead{margin:0}
++.viz{background:var(--bg-card);border:1px solid var(--border);border-radius:20px;padding:14px;box-shadow:0 30px 80px rgba(0,0,0,.45),0 0 0 1px rgba(var(--site-rgb),.08);animation:rise .7s .25s cubic-bezier(.2,.8,.2,1) both;text-align:left}
++.viz figcaption{margin-top:10px;font-size:11.5px;color:var(--text-muted);text-align:center}
++.viz-top{display:flex;align-items:center;gap:8px;font-size:13px;padding:2px 4px 12px}
++.viz-top b{font-weight:700}.viz-top .muted{color:var(--text-muted)}
++.viz-top .lat{margin-left:auto;font-size:12px;color:var(--site);background:rgba(var(--site-rgb),.1);border:1px solid rgba(var(--site-rgb),.3);padding:3px 9px;border-radius:999px}
++.viz-top .dot{width:8px;height:8px;border-radius:50%;background:#22c55e;box-shadow:0 0 0 4px rgba(34,197,94,.18)}
++.viz-top .av{width:26px;height:26px;border-radius:8px;display:grid;place-items:center;background:rgba(var(--site-rgb),.15);color:var(--site);font-size:13px}
++.viz-video{position:relative;aspect-ratio:16/9;border-radius:14px;overflow:hidden;background:radial-gradient(120% 90% at 30% 20%,rgba(var(--site-rgb),.28),transparent 60%),linear-gradient(160deg,#1a2338,#0b1020 70%);border:1px solid var(--border)}
++.viz-video::after{content:'';position:absolute;left:10%;right:10%;bottom:0;height:42%;background:linear-gradient(transparent,rgba(0,0,0,.35)),repeating-linear-gradient(90deg,rgba(255,255,255,.05) 0 1px,transparent 1px 38px);transform:perspective(220px) rotateX(58deg);transform-origin:bottom}
++.viz-video .scan{position:absolute;inset:0;background:linear-gradient(transparent 0,rgba(255,255,255,.04) 50%,transparent 100%);background-size:100% 6px;opacity:.5}
++.viz-video .onair{position:absolute;top:10px;left:10px;font-size:11px;font-weight:700;padding:3px 8px;border-radius:6px;background:rgba(239,68,68,.9);color:#fff}.viz-video .onair i{font-size:7px;vertical-align:2px;margin-right:3px}
++.viz-video .cam{position:absolute;bottom:10px;right:10px;font-size:11px;color:#dbe4f5;background:rgba(0,0,0,.45);padding:3px 8px;border-radius:6px}
++.viz-ctrl{display:flex;gap:14px;align-items:center;margin-top:12px}
++.dpad{display:grid;grid-template-columns:repeat(3,34px);grid-template-rows:repeat(3,34px);gap:4px;flex:none}
++.dpad span{display:grid;place-items:center;border-radius:9px;background:var(--bg-hover);color:var(--text-primary);font-size:15px;border:1px solid var(--border)}
++.dpad .u{grid-area:1/2}.dpad .l{grid-area:2/1}.dpad .c{grid-area:2/2;background:rgba(var(--site-rgb),.15);border-color:rgba(var(--site-rgb),.35)}.dpad .r{grid-area:2/3}.dpad .d{grid-area:3/2}
++.dpad .u{background:rgba(var(--site-rgb),.22);border-color:rgba(var(--site-rgb),.5)}
++.viz-side{flex:1;min-width:0;display:grid;gap:8px}
++.viz-side .keys{display:flex;flex-wrap:wrap;gap:6px}
++.viz-side .keys span{font-size:11.5px;padding:5px 9px;border-radius:8px;background:var(--bg-secondary);border:1px solid var(--border);color:var(--text-secondary)}
++.viz-side .meter{display:flex;align-items:center;gap:8px;font-size:11.5px;color:var(--text-muted)}
++.viz-side .meter i{flex:1;height:6px;border-radius:9px;background:linear-gradient(90deg,#22c55e var(--v),var(--bg-hover) var(--v))}
++.viz-side .meter b{color:var(--text-secondary);font-weight:600}
++.viz-side .estop{justify-self:end;font-size:12px;font-weight:800;letter-spacing:.08em;color:#fff;background:#dc2626;border-radius:10px;padding:7px 16px;box-shadow:0 0 0 3px rgba(220,38,38,.25)}
++.feed{list-style:none;display:grid;gap:8px;padding:2px}
++.feed li{display:flex;align-items:flex-start;gap:10px;font-size:13.5px;line-height:1.45;padding:10px 12px;border-radius:12px;background:var(--bg-secondary);border:1px solid var(--border);color:var(--text-secondary)}
++.feed li i{color:#22c55e;margin-top:3px}
++.feed li.ask{flex-wrap:wrap;border-color:rgba(var(--site-rgb),.45);background:rgba(var(--site-rgb),.08);color:var(--text-primary)}.feed li.ask i{color:var(--site)}.feed li.ask>span:first-of-type{flex:1;min-width:160px}
++.feed .pills{display:flex;gap:6px;margin-left:auto}.feed .pills span{font-size:12px;font-weight:600;padding:4px 11px;border-radius:999px;border:1px solid var(--border);color:var(--text-secondary)}.feed .pills .ok{background:var(--site);border-color:var(--site);color:#0b0d10}
++.steps{list-style:none;display:grid;grid-template-columns:repeat(auto-fit,minmax(230px,1fr));gap:14px;counter-reset:s}
++.steps li{position:relative;background:var(--bg-card);border:1px solid var(--border);border-radius:16px;padding:20px 20px 20px;display:flex;flex-direction:column;gap:8px}
++.steps .n{width:30px;height:30px;border-radius:50%;display:grid;place-items:center;font-weight:800;font-size:14px;color:#0b0d10;background:var(--site)}
++.steps b{font-size:15px}.steps span:last-child{font-size:13px;color:var(--text-secondary);line-height:1.55}
++.grid.three{grid-template-columns:repeat(auto-fit,minmax(280px,1fr))}
++.choice{display:grid;grid-template-columns:repeat(auto-fit,minmax(280px,1fr));gap:14px}
++.card.big{padding:24px}.card.big b{font-size:17px}
++.chips{display:flex;flex-wrap:wrap;gap:7px;margin-top:6px}
++.chips span{font-size:12.5px;padding:6px 11px;border-radius:999px;border:1px solid var(--border);background:var(--bg-secondary);color:var(--text-secondary)}
++.chips.big span{font-size:13.5px;padding:9px 14px;color:var(--text-primary)}.chips.big span i{color:var(--site);margin-right:8px}
++.build .card{border-style:dashed;background:rgba(0,0,0,.15)}.build .card b i{color:var(--site);margin-right:6px}.build .card span a{color:var(--text-secondary)}.build .card code{font-size:12px}
++@media (max-width:860px){.hero.split{grid-template-columns:1fr;text-align:center;gap:28px}.hero.split .ctas{justify-content:center}.hero.split p.lead{margin:0 auto}}
++@media (max-width:600px){.hero{padding-top:56px}.ctas .btn{width:100%;justify-content:center}.viz-ctrl{flex-direction:column;align-items:stretch}.dpad{align-self:center}}
@media (prefers-reduced-motion:reduce){*{animation:none!important;transition:none!important}}
</style>
</head>
ddiff --git a/dist/openvibe.space/release.json b/dist/openvibe.space/release.json
iindex 6fc0f12..2260cbc 100644
---- a/dist/openvibe.space/release.json
++++ b/dist/openvibe.space/release.json
@@@ -1,6 +1,6 @@
{
"service": "space",
-- "release": "8c49a43fd341",
++ "release": "48f1d864bd53",
"released_at": "2026-09-29T00:00:00.000Z",
"booted_at": null,
"contracts_version": null,
ddiff --git a/dist/openvibe.tips/index.html b/dist/openvibe.tips/index.html
iindex 38440c1..5e93f78 100644
---- a/dist/openvibe.tips/index.html
++++ b/dist/openvibe.tips/index.html
@@@ -87,7 +87,50 @@ a.card:hover{transform:translateY(-3px);border-color:rgba(var(--site-rgb),.6);bo
.strip h3{font-size:19px;font-weight:700;margin:12px 0 8px}
.strip p{font-size:14px;color:var(--text-secondary);max-width:600px;margin:0 auto 18px;line-height:1.6}
.strip .ov-mark{width:44px;height:44px}
--@media (max-width:600px){.hero{padding-top:56px}.ctas .btn{width:100%;justify-content:center}}
++.hero.split{display:grid;grid-template-columns:minmax(0,1.05fr) minmax(0,1fr);gap:40px;align-items:center;text-align:left;padding-top:64px}
++.hero.split .ctas{justify-content:flex-start}.hero.split p.lead{margin:0}
++.viz{background:var(--bg-card);border:1px solid var(--border);border-radius:20px;padding:14px;box-shadow:0 30px 80px rgba(0,0,0,.45),0 0 0 1px rgba(var(--site-rgb),.08);animation:rise .7s .25s cubic-bezier(.2,.8,.2,1) both;text-align:left}
++.viz figcaption{margin-top:10px;font-size:11.5px;color:var(--text-muted);text-align:center}
++.viz-top{display:flex;align-items:center;gap:8px;font-size:13px;padding:2px 4px 12px}
++.viz-top b{font-weight:700}.viz-top .muted{color:var(--text-muted)}
++.viz-top .lat{margin-left:auto;font-size:12px;color:var(--site);background:rgba(var(--site-rgb),.1);border:1px solid rgba(var(--site-rgb),.3);padding:3px 9px;border-radius:999px}
++.viz-top .dot{width:8px;height:8px;border-radius:50%;background:#22c55e;box-shadow:0 0 0 4px rgba(34,197,94,.18)}
++.viz-top .av{width:26px;height:26px;border-radius:8px;display:grid;place-items:center;background:rgba(var(--site-rgb),.15);color:var(--site);font-size:13px}
++.viz-video{position:relative;aspect-ratio:16/9;border-radius:14px;overflow:hidden;background:radial-gradient(120% 90% at 30% 20%,rgba(var(--site-rgb),.28),transparent 60%),linear-gradient(160deg,#1a2338,#0b1020 70%);border:1px solid var(--border)}
++.viz-video::after{content:'';position:absolute;left:10%;right:10%;bottom:0;height:42%;background:linear-gradient(transparent,rgba(0,0,0,.35)),repeating-linear-gradient(90deg,rgba(255,255,255,.05) 0 1px,transparent 1px 38px);transform:perspective(220px) rotateX(58deg);transform-origin:bottom}
++.viz-video .scan{position:absolute;inset:0;background:linear-gradient(transparent 0,rgba(255,255,255,.04) 50%,transparent 100%);background-size:100% 6px;opacity:.5}
++.viz-video .onair{position:absolute;top:10px;left:10px;font-size:11px;font-weight:700;padding:3px 8px;border-radius:6px;background:rgba(239,68,68,.9);color:#fff}.viz-video .onair i{font-size:7px;vertical-align:2px;margin-right:3px}
++.viz-video .cam{position:absolute;bottom:10px;right:10px;font-size:11px;color:#dbe4f5;background:rgba(0,0,0,.45);padding:3px 8px;border-radius:6px}
++.viz-ctrl{display:flex;gap:14px;align-items:center;margin-top:12px}
++.dpad{display:grid;grid-template-columns:repeat(3,34px);grid-template-rows:repeat(3,34px);gap:4px;flex:none}
++.dpad span{display:grid;place-items:center;border-radius:9px;background:var(--bg-hover);color:var(--text-primary);font-size:15px;border:1px solid var(--border)}
++.dpad .u{grid-area:1/2}.dpad .l{grid-area:2/1}.dpad .c{grid-area:2/2;background:rgba(var(--site-rgb),.15);border-color:rgba(var(--site-rgb),.35)}.dpad .r{grid-area:2/3}.dpad .d{grid-area:3/2}
++.dpad .u{background:rgba(var(--site-rgb),.22);border-color:rgba(var(--site-rgb),.5)}
++.viz-side{flex:1;min-width:0;display:grid;gap:8px}
++.viz-side .keys{display:flex;flex-wrap:wrap;gap:6px}
++.viz-side .keys span{font-size:11.5px;padding:5px 9px;border-radius:8px;background:var(--bg-secondary);border:1px solid var(--border);color:var(--text-secondary)}
++.viz-side .meter{display:flex;align-items:center;gap:8px;font-size:11.5px;color:var(--text-muted)}
++.viz-side .meter i{flex:1;height:6px;border-radius:9px;background:linear-gradient(90deg,#22c55e var(--v),var(--bg-hover) var(--v))}
++.viz-side .meter b{color:var(--text-secondary);font-weight:600}
++.viz-side .estop{justify-self:end;font-size:12px;font-weight:800;letter-spacing:.08em;color:#fff;background:#dc2626;border-radius:10px;padding:7px 16px;box-shadow:0 0 0 3px rgba(220,38,38,.25)}
++.feed{list-style:none;display:grid;gap:8px;padding:2px}
++.feed li{display:flex;align-items:flex-start;gap:10px;font-size:13.5px;line-height:1.45;padding:10px 12px;border-radius:12px;background:var(--bg-secondary);border:1px solid var(--border);color:var(--text-secondary)}
++.feed li i{color:#22c55e;margin-top:3px}
++.feed li.ask{flex-wrap:wrap;border-color:rgba(var(--site-rgb),.45);background:rgba(var(--site-rgb),.08);color:var(--text-primary)}.feed li.ask i{color:var(--site)}.feed li.ask>span:first-of-type{flex:1;min-width:160px}
++.feed .pills{display:flex;gap:6px;margin-left:auto}.feed .pills span{font-size:12px;font-weight:600;padding:4px 11px;border-radius:999px;border:1px solid var(--border);color:var(--text-secondary)}.feed .pills .ok{background:var(--site);border-color:var(--site);color:#0b0d10}
++.steps{list-style:none;display:grid;grid-template-columns:repeat(auto-fit,minmax(230px,1fr));gap:14px;counter-reset:s}
++.steps li{position:relative;background:var(--bg-card);border:1px solid var(--border);border-radius:16px;padding:20px 20px 20px;display:flex;flex-direction:column;gap:8px}
++.steps .n{width:30px;height:30px;border-radius:50%;display:grid;place-items:center;font-weight:800;font-size:14px;color:#0b0d10;background:var(--site)}
++.steps b{font-size:15px}.steps span:last-child{font-size:13px;color:var(--text-secondary);line-height:1.55}
++.grid.three{grid-template-columns:repeat(auto-fit,minmax(280px,1fr))}
++.choice{display:grid;grid-template-columns:repeat(auto-fit,minmax(280px,1fr));gap:14px}
++.card.big{padding:24px}.card.big b{font-size:17px}
++.chips{display:flex;flex-wrap:wrap;gap:7px;margin-top:6px}
++.chips span{font-size:12.5px;padding:6px 11px;border-radius:999px;border:1px solid var(--border);background:var(--bg-secondary);color:var(--text-secondary)}
++.chips.big span{font-size:13.5px;padding:9px 14px;color:var(--text-primary)}.chips.big span i{color:var(--site);margin-right:8px}
++.build .card{border-style:dashed;background:rgba(0,0,0,.15)}.build .card b i{color:var(--site);margin-right:6px}.build .card span a{color:var(--text-secondary)}.build .card code{font-size:12px}
++@media (max-width:860px){.hero.split{grid-template-columns:1fr;text-align:center;gap:28px}.hero.split .ctas{justify-content:center}.hero.split p.lead{margin:0 auto}}
++@media (max-width:600px){.hero{padding-top:56px}.ctas .btn{width:100%;justify-content:center}.viz-ctrl{flex-direction:column;align-items:stretch}.dpad{align-self:center}}
@media (prefers-reduced-motion:reduce){*{animation:none!important;transition:none!important}}
</style>
</head>
ddiff --git a/dist/openvibe.tips/release.json b/dist/openvibe.tips/release.json
iindex 0a3d568..953a38a 100644
---- a/dist/openvibe.tips/release.json
++++ b/dist/openvibe.tips/release.json
@@@ -1,6 +1,6 @@
{
"service": "tips",
-- "release": "442a36f0bc11",
++ "release": "bbdd22624542",
"released_at": "2026-09-29T00:00:00.000Z",
"booted_at": null,
"contracts_version": null,
ddiff --git a/dist/openvibe.trade/index.html b/dist/openvibe.trade/index.html
iindex 604c86a..82257b6 100644
---- a/dist/openvibe.trade/index.html
++++ b/dist/openvibe.trade/index.html
@@@ -87,7 +87,50 @@ a.card:hover{transform:translateY(-3px);border-color:rgba(var(--site-rgb),.6);bo
.strip h3{font-size:19px;font-weight:700;margin:12px 0 8px}
.strip p{font-size:14px;color:var(--text-secondary);max-width:600px;margin:0 auto 18px;line-height:1.6}
.strip .ov-mark{width:44px;height:44px}
--@media (max-width:600px){.hero{padding-top:56px}.ctas .btn{width:100%;justify-content:center}}
++.hero.split{display:grid;grid-template-columns:minmax(0,1.05fr) minmax(0,1fr);gap:40px;align-items:center;text-align:left;padding-top:64px}
++.hero.split .ctas{justify-content:flex-start}.hero.split p.lead{margin:0}
++.viz{background:var(--bg-card);border:1px solid var(--border);border-radius:20px;padding:14px;box-shadow:0 30px 80px rgba(0,0,0,.45),0 0 0 1px rgba(var(--site-rgb),.08);animation:rise .7s .25s cubic-bezier(.2,.8,.2,1) both;text-align:left}
++.viz figcaption{margin-top:10px;font-size:11.5px;color:var(--text-muted);text-align:center}
++.viz-top{display:flex;align-items:center;gap:8px;font-size:13px;padding:2px 4px 12px}
++.viz-top b{font-weight:700}.viz-top .muted{color:var(--text-muted)}
++.viz-top .lat{margin-left:auto;font-size:12px;color:var(--site);background:rgba(var(--site-rgb),.1);border:1px solid rgba(var(--site-rgb),.3);padding:3px 9px;border-radius:999px}
++.viz-top .dot{width:8px;height:8px;border-radius:50%;background:#22c55e;box-shadow:0 0 0 4px rgba(34,197,94,.18)}
++.viz-top .av{width:26px;height:26px;border-radius:8px;display:grid;place-items:center;background:rgba(var(--site-rgb),.15);color:var(--site);font-size:13px}
++.viz-video{position:relative;aspect-ratio:16/9;border-radius:14px;overflow:hidden;background:radial-gradient(120% 90% at 30% 20%,rgba(var(--site-rgb),.28),transparent 60%),linear-gradient(160deg,#1a2338,#0b1020 70%);border:1px solid var(--border)}
++.viz-video::after{content:'';position:absolute;left:10%;right:10%;bottom:0;height:42%;background:linear-gradient(transparent,rgba(0,0,0,.35)),repeating-linear-gradient(90deg,rgba(255,255,255,.05) 0 1px,transparent 1px 38px);transform:perspective(220px) rotateX(58deg);transform-origin:bottom}
++.viz-video .scan{position:absolute;inset:0;background:linear-gradient(transparent 0,rgba(255,255,255,.04) 50%,transparent 100%);background-size:100% 6px;opacity:.5}
++.viz-video .onair{position:absolute;top:10px;left:10px;font-size:11px;font-weight:700;padding:3px 8px;border-radius:6px;background:rgba(239,68,68,.9);color:#fff}.viz-video .onair i{font-size:7px;vertical-align:2px;margin-right:3px}
++.viz-video .cam{position:absolute;bottom:10px;right:10px;font-size:11px;color:#dbe4f5;background:rgba(0,0,0,.45);padding:3px 8px;border-radius:6px}
++.viz-ctrl{display:flex;gap:14px;align-items:center;margin-top:12px}
++.dpad{display:grid;grid-template-columns:repeat(3,34px);grid-template-rows:repeat(3,34px);gap:4px;flex:none}
++.dpad span{display:grid;place-items:center;border-radius:9px;background:var(--bg-hover);color:var(--text-primary);font-size:15px;border:1px solid var(--border)}
++.dpad .u{grid-area:1/2}.dpad .l{grid-area:2/1}.dpad .c{grid-area:2/2;background:rgba(var(--site-rgb),.15);border-color:rgba(var(--site-rgb),.35)}.dpad .r{grid-area:2/3}.dpad .d{grid-area:3/2}
++.dpad .u{background:rgba(var(--site-rgb),.22);border-color:rgba(var(--site-rgb),.5)}
++.viz-side{flex:1;min-width:0;display:grid;gap:8px}
++.viz-side .keys{display:flex;flex-wrap:wrap;gap:6px}
++.viz-side .keys span{font-size:11.5px;padding:5px 9px;border-radius:8px;background:var(--bg-secondary);border:1px solid var(--border);color:var(--text-secondary)}
++.viz-side .meter{display:flex;align-items:center;gap:8px;font-size:11.5px;color:var(--text-muted)}
++.viz-side .meter i{flex:1;height:6px;border-radius:9px;background:linear-gradient(90deg,#22c55e var(--v),var(--bg-hover) var(--v))}
++.viz-side .meter b{color:var(--text-secondary);font-weight:600}
++.viz-side .estop{justify-self:end;font-size:12px;font-weight:800;letter-spacing:.08em;color:#fff;background:#dc2626;border-radius:10px;padding:7px 16px;box-shadow:0 0 0 3px rgba(220,38,38,.25)}
++.feed{list-style:none;display:grid;gap:8px;padding:2px}
++.feed li{display:flex;align-items:flex-start;gap:10px;font-size:13.5px;line-height:1.45;padding:10px 12px;border-radius:12px;background:var(--bg-secondary);border:1px solid var(--border);color:var(--text-secondary)}
++.feed li i{color:#22c55e;margin-top:3px}
++.feed li.ask{flex-wrap:wrap;border-color:rgba(var(--site-rgb),.45);background:rgba(var(--site-rgb),.08);color:var(--text-primary)}.feed li.ask i{color:var(--site)}.feed li.ask>span:first-of-type{flex:1;min-width:160px}
++.feed .pills{display:flex;gap:6px;margin-left:auto}.feed .pills span{font-size:12px;font-weight:600;padding:4px 11px;border-radius:999px;border:1px solid var(--border);color:var(--text-secondary)}.feed .pills .ok{background:var(--site);border-color:var(--site);color:#0b0d10}
++.steps{list-style:none;display:grid;grid-template-columns:repeat(auto-fit,minmax(230px,1fr));gap:14px;counter-reset:s}
++.steps li{position:relative;background:var(--bg-card);border:1px solid var(--border);border-radius:16px;padding:20px 20px 20px;display:flex;flex-direction:column;gap:8px}
++.steps .n{width:30px;height:30px;border-radius:50%;display:grid;place-items:center;font-weight:800;font-size:14px;color:#0b0d10;background:var(--site)}
++.steps b{font-size:15px}.steps span:last-child{font-size:13px;color:var(--text-secondary);line-height:1.55}
++.grid.three{grid-template-columns:repeat(auto-fit,minmax(280px,1fr))}
++.choice{display:grid;grid-template-columns:repeat(auto-fit,minmax(280px,1fr));gap:14px}
++.card.big{padding:24px}.card.big b{font-size:17px}
++.chips{display:flex;flex-wrap:wrap;gap:7px;margin-top:6px}
++.chips span{font-size:12.5px;padding:6px 11px;border-radius:999px;border:1px solid var(--border);background:var(--bg-secondary);color:var(--text-secondary)}
++.chips.big span{font-size:13.5px;padding:9px 14px;color:var(--text-primary)}.chips.big span i{color:var(--site);margin-right:8px}
++.build .card{border-style:dashed;background:rgba(0,0,0,.15)}.build .card b i{color:var(--site);margin-right:6px}.build .card span a{color:var(--text-secondary)}.build .card code{font-size:12px}
++@media (max-width:860px){.hero.split{grid-template-columns:1fr;text-align:center;gap:28px}.hero.split .ctas{justify-content:center}.hero.split p.lead{margin:0 auto}}
++@media (max-width:600px){.hero{padding-top:56px}.ctas .btn{width:100%;justify-content:center}.viz-ctrl{flex-direction:column;align-items:stretch}.dpad{align-self:center}}
@media (prefers-reduced-motion:reduce){*{animation:none!important;transition:none!important}}
</style>
</head>
ddiff --git a/dist/openvibe.trade/release.json b/dist/openvibe.trade/release.json
iindex 296c73b..60c32ad 100644
---- a/dist/openvibe.trade/release.json
++++ b/dist/openvibe.trade/release.json
@@@ -1,6 +1,6 @@
{
"service": "trade",
-- "release": "239f915e9368",
++ "release": "93c7a5251945",
"released_at": "2026-09-29T00:00:00.000Z",
"booted_at": null,
"contracts_version": null,
ddiff --git a/dist/openvibe.video/index.html b/dist/openvibe.video/index.html
iindex e5f4e45..7040be1 100644
---- a/dist/openvibe.video/index.html
++++ b/dist/openvibe.video/index.html
@@@ -87,7 +87,50 @@ a.card:hover{transform:translateY(-3px);border-color:rgba(var(--site-rgb),.6);bo
.strip h3{font-size:19px;font-weight:700;margin:12px 0 8px}
.strip p{font-size:14px;color:var(--text-secondary);max-width:600px;margin:0 auto 18px;line-height:1.6}
.strip .ov-mark{width:44px;height:44px}
--@media (max-width:600px){.hero{padding-top:56px}.ctas .btn{width:100%;justify-content:center}}
++.hero.split{display:grid;grid-template-columns:minmax(0,1.05fr) minmax(0,1fr);gap:40px;align-items:center;text-align:left;padding-top:64px}
++.hero.split .ctas{justify-content:flex-start}.hero.split p.lead{margin:0}
++.viz{background:var(--bg-card);border:1px solid var(--border);border-radius:20px;padding:14px;box-shadow:0 30px 80px rgba(0,0,0,.45),0 0 0 1px rgba(var(--site-rgb),.08);animation:rise .7s .25s cubic-bezier(.2,.8,.2,1) both;text-align:left}
++.viz figcaption{margin-top:10px;font-size:11.5px;color:var(--text-muted);text-align:center}
++.viz-top{display:flex;align-items:center;gap:8px;font-size:13px;padding:2px 4px 12px}
++.viz-top b{font-weight:700}.viz-top .muted{color:var(--text-muted)}
++.viz-top .lat{margin-left:auto;font-size:12px;color:var(--site);background:rgba(var(--site-rgb),.1);border:1px solid rgba(var(--site-rgb),.3);padding:3px 9px;border-radius:999px}
++.viz-top .dot{width:8px;height:8px;border-radius:50%;background:#22c55e;box-shadow:0 0 0 4px rgba(34,197,94,.18)}
++.viz-top .av{width:26px;height:26px;border-radius:8px;display:grid;place-items:center;background:rgba(var(--site-rgb),.15);color:var(--site);font-size:13px}
++.viz-video{position:relative;aspect-ratio:16/9;border-radius:14px;overflow:hidden;background:radial-gradient(120% 90% at 30% 20%,rgba(var(--site-rgb),.28),transparent 60%),linear-gradient(160deg,#1a2338,#0b1020 70%);border:1px solid var(--border)}
++.viz-video::after{content:'';position:absolute;left:10%;right:10%;bottom:0;height:42%;background:linear-gradient(transparent,rgba(0,0,0,.35)),repeating-linear-gradient(90deg,rgba(255,255,255,.05) 0 1px,transparent 1px 38px);transform:perspective(220px) rotateX(58deg);transform-origin:bottom}
++.viz-video .scan{position:absolute;inset:0;background:linear-gradient(transparent 0,rgba(255,255,255,.04) 50%,transparent 100%);background-size:100% 6px;opacity:.5}
++.viz-video .onair{position:absolute;top:10px;left:10px;font-size:11px;font-weight:700;padding:3px 8px;border-radius:6px;background:rgba(239,68,68,.9);color:#fff}.viz-video .onair i{font-size:7px;vertical-align:2px;margin-right:3px}
++.viz-video .cam{position:absolute;bottom:10px;right:10px;font-size:11px;color:#dbe4f5;background:rgba(0,0,0,.45);padding:3px 8px;border-radius:6px}
++.viz-ctrl{display:flex;gap:14px;align-items:center;margin-top:12px}
++.dpad{display:grid;grid-template-columns:repeat(3,34px);grid-template-rows:repeat(3,34px);gap:4px;flex:none}
++.dpad span{display:grid;place-items:center;border-radius:9px;background:var(--bg-hover);color:var(--text-primary);font-size:15px;border:1px solid var(--border)}
++.dpad .u{grid-area:1/2}.dpad .l{grid-area:2/1}.dpad .c{grid-area:2/2;background:rgba(var(--site-rgb),.15);border-color:rgba(var(--site-rgb),.35)}.dpad .r{grid-area:2/3}.dpad .d{grid-area:3/2}
++.dpad .u{background:rgba(var(--site-rgb),.22);border-color:rgba(var(--site-rgb),.5)}
++.viz-side{flex:1;min-width:0;display:grid;gap:8px}
++.viz-side .keys{display:flex;flex-wrap:wrap;gap:6px}
++.viz-side .keys span{font-size:11.5px;padding:5px 9px;border-radius:8px;background:var(--bg-secondary);border:1px solid var(--border);color:var(--text-secondary)}
++.viz-side .meter{display:flex;align-items:center;gap:8px;font-size:11.5px;color:var(--text-muted)}
++.viz-side .meter i{flex:1;height:6px;border-radius:9px;background:linear-gradient(90deg,#22c55e var(--v),var(--bg-hover) var(--v))}
++.viz-side .meter b{color:var(--text-secondary);font-weight:600}
++.viz-side .estop{justify-self:end;font-size:12px;font-weight:800;letter-spacing:.08em;color:#fff;background:#dc2626;border-radius:10px;padding:7px 16px;box-shadow:0 0 0 3px rgba(220,38,38,.25)}
++.feed{list-style:none;display:grid;gap:8px;padding:2px}
++.feed li{display:flex;align-items:flex-start;gap:10px;font-size:13.5px;line-height:1.45;padding:10px 12px;border-radius:12px;background:var(--bg-secondary);border:1px solid var(--border);color:var(--text-secondary)}
++.feed li i{color:#22c55e;margin-top:3px}
++.feed li.ask{flex-wrap:wrap;border-color:rgba(var(--site-rgb),.45);background:rgba(var(--site-rgb),.08);color:var(--text-primary)}.feed li.ask i{color:var(--site)}.feed li.ask>span:first-of-type{flex:1;min-width:160px}
++.feed .pills{display:flex;gap:6px;margin-left:auto}.feed .pills span{font-size:12px;font-weight:600;padding:4px 11px;border-radius:999px;border:1px solid var(--border);color:var(--text-secondary)}.feed .pills .ok{background:var(--site);border-color:var(--site);color:#0b0d10}
++.steps{list-style:none;display:grid;grid-template-columns:repeat(auto-fit,minmax(230px,1fr));gap:14px;counter-reset:s}
++.steps li{position:relative;background:var(--bg-card);border:1px solid var(--border);border-radius:16px;padding:20px 20px 20px;display:flex;flex-direction:column;gap:8px}
++.steps .n{width:30px;height:30px;border-radius:50%;display:grid;place-items:center;font-weight:800;font-size:14px;color:#0b0d10;background:var(--site)}
++.steps b{font-size:15px}.steps span:last-child{font-size:13px;color:var(--text-secondary);line-height:1.55}
++.grid.three{grid-template-columns:repeat(auto-fit,minmax(280px,1fr))}
++.choice{display:grid;grid-template-columns:repeat(auto-fit,minmax(280px,1fr));gap:14px}
++.card.big{padding:24px}.card.big b{font-size:17px}
++.chips{display:flex;flex-wrap:wrap;gap:7px;margin-top:6px}
++.chips span{font-size:12.5px;padding:6px 11px;border-radius:999px;border:1px solid var(--border);background:var(--bg-secondary);color:var(--text-secondary)}
++.chips.big span{font-size:13.5px;padding:9px 14px;color:var(--text-primary)}.chips.big span i{color:var(--site);margin-right:8px}
++.build .card{border-style:dashed;background:rgba(0,0,0,.15)}.build .card b i{color:var(--site);margin-right:6px}.build .card span a{color:var(--text-secondary)}.build .card code{font-size:12px}
++@media (max-width:860px){.hero.split{grid-template-columns:1fr;text-align:center;gap:28px}.hero.split .ctas{justify-content:center}.hero.split p.lead{margin:0 auto}}
++@media (max-width:600px){.hero{padding-top:56px}.ctas .btn{width:100%;justify-content:center}.viz-ctrl{flex-direction:column;align-items:stretch}.dpad{align-self:center}}
@media (prefers-reduced-motion:reduce){*{animation:none!important;transition:none!important}}
</style>
</head>
ddiff --git a/dist/openvibe.video/release.json b/dist/openvibe.video/release.json
iindex d10c8b0..dc840e1 100644
---- a/dist/openvibe.video/release.json
++++ b/dist/openvibe.video/release.json
@@@ -1,6 +1,6 @@
{
"service": "video",
-- "release": "507359603b9f",
++ "release": "e9c38e4e184a",
"released_at": "2026-09-29T00:00:00.000Z",
"booted_at": null,
"contracts_version": null,
ddiff --git a/dist/openvibe.vip/index.html b/dist/openvibe.vip/index.html
iindex 03f9931..09aa7c7 100644
---- a/dist/openvibe.vip/index.html
++++ b/dist/openvibe.vip/index.html
@@@ -87,7 +87,50 @@ a.card:hover{transform:translateY(-3px);border-color:rgba(var(--site-rgb),.6);bo
.strip h3{font-size:19px;font-weight:700;margin:12px 0 8px}
.strip p{font-size:14px;color:var(--text-secondary);max-width:600px;margin:0 auto 18px;line-height:1.6}
.strip .ov-mark{width:44px;height:44px}
--@media (max-width:600px){.hero{padding-top:56px}.ctas .btn{width:100%;justify-content:center}}
++.hero.split{display:grid;grid-template-columns:minmax(0,1.05fr) minmax(0,1fr);gap:40px;align-items:center;text-align:left;padding-top:64px}
++.hero.split .ctas{justify-content:flex-start}.hero.split p.lead{margin:0}
++.viz{background:var(--bg-card);border:1px solid var(--border);border-radius:20px;padding:14px;box-shadow:0 30px 80px rgba(0,0,0,.45),0 0 0 1px rgba(var(--site-rgb),.08);animation:rise .7s .25s cubic-bezier(.2,.8,.2,1) both;text-align:left}
++.viz figcaption{margin-top:10px;font-size:11.5px;color:var(--text-muted);text-align:center}
++.viz-top{display:flex;align-items:center;gap:8px;font-size:13px;padding:2px 4px 12px}
++.viz-top b{font-weight:700}.viz-top .muted{color:var(--text-muted)}
++.viz-top .lat{margin-left:auto;font-size:12px;color:var(--site);background:rgba(var(--site-rgb),.1);border:1px solid rgba(var(--site-rgb),.3);padding:3px 9px;border-radius:999px}
++.viz-top .dot{width:8px;height:8px;border-radius:50%;background:#22c55e;box-shadow:0 0 0 4px rgba(34,197,94,.18)}
++.viz-top .av{width:26px;height:26px;border-radius:8px;display:grid;place-items:center;background:rgba(var(--site-rgb),.15);color:var(--site);font-size:13px}
++.viz-video{position:relative;aspect-ratio:16/9;border-radius:14px;overflow:hidden;background:radial-gradient(120% 90% at 30% 20%,rgba(var(--site-rgb),.28),transparent 60%),linear-gradient(160deg,#1a2338,#0b1020 70%);border:1px solid var(--border)}
++.viz-video::after{content:'';position:absolute;left:10%;right:10%;bottom:0;height:42%;background:linear-gradient(transparent,rgba(0,0,0,.35)),repeating-linear-gradient(90deg,rgba(255,255,255,.05) 0 1px,transparent 1px 38px);transform:perspective(220px) rotateX(58deg);transform-origin:bottom}
++.viz-video .scan{position:absolute;inset:0;background:linear-gradient(transparent 0,rgba(255,255,255,.04) 50%,transparent 100%);background-size:100% 6px;opacity:.5}
++.viz-video .onair{position:absolute;top:10px;left:10px;font-size:11px;font-weight:700;padding:3px 8px;border-radius:6px;background:rgba(239,68,68,.9);color:#fff}.viz-video .onair i{font-size:7px;vertical-align:2px;margin-right:3px}
++.viz-video .cam{position:absolute;bottom:10px;right:10px;font-size:11px;color:#dbe4f5;background:rgba(0,0,0,.45);padding:3px 8px;border-radius:6px}
++.viz-ctrl{display:flex;gap:14px;align-items:center;margin-top:12px}
++.dpad{display:grid;grid-template-columns:repeat(3,34px);grid-template-rows:repeat(3,34px);gap:4px;flex:none}
++.dpad span{display:grid;place-items:center;border-radius:9px;background:var(--bg-hover);color:var(--text-primary);font-size:15px;border:1px solid var(--border)}
++.dpad .u{grid-area:1/2}.dpad .l{grid-area:2/1}.dpad .c{grid-area:2/2;background:rgba(var(--site-rgb),.15);border-color:rgba(var(--site-rgb),.35)}.dpad .r{grid-area:2/3}.dpad .d{grid-area:3/2}
++.dpad .u{background:rgba(var(--site-rgb),.22);border-color:rgba(var(--site-rgb),.5)}
++.viz-side{flex:1;min-width:0;display:grid;gap:8px}
++.viz-side .keys{display:flex;flex-wrap:wrap;gap:6px}
++.viz-side .keys span{font-size:11.5px;padding:5px 9px;border-radius:8px;background:var(--bg-secondary);border:1px solid var(--border);color:var(--text-secondary)}
++.viz-side .meter{display:flex;align-items:center;gap:8px;font-size:11.5px;color:var(--text-muted)}
++.viz-side .meter i{flex:1;height:6px;border-radius:9px;background:linear-gradient(90deg,#22c55e var(--v),var(--bg-hover) var(--v))}
++.viz-side .meter b{color:var(--text-secondary);font-weight:600}
++.viz-side .estop{justify-self:end;font-size:12px;font-weight:800;letter-spacing:.08em;color:#fff;background:#dc2626;border-radius:10px;padding:7px 16px;box-shadow:0 0 0 3px rgba(220,38,38,.25)}
++.feed{list-style:none;display:grid;gap:8px;padding:2px}
++.feed li{display:flex;align-items:flex-start;gap:10px;font-size:13.5px;line-height:1.45;padding:10px 12px;border-radius:12px;background:var(--bg-secondary);border:1px solid var(--border);color:var(--text-secondary)}
++.feed li i{color:#22c55e;margin-top:3px}
++.feed li.ask{flex-wrap:wrap;border-color:rgba(var(--site-rgb),.45);background:rgba(var(--site-rgb),.08);color:var(--text-primary)}.feed li.ask i{color:var(--site)}.feed li.ask>span:first-of-type{flex:1;min-width:160px}
++.feed .pills{display:flex;gap:6px;margin-left:auto}.feed .pills span{font-size:12px;font-weight:600;padding:4px 11px;border-radius:999px;border:1px solid var(--border);color:var(--text-secondary)}.feed .pills .ok{background:var(--site);border-color:var(--site);color:#0b0d10}
++.steps{list-style:none;display:grid;grid-template-columns:repeat(auto-fit,minmax(230px,1fr));gap:14px;counter-reset:s}
++.steps li{position:relative;background:var(--bg-card);border:1px solid var(--border);border-radius:16px;padding:20px 20px 20px;display:flex;flex-direction:column;gap:8px}
++.steps .n{width:30px;height:30px;border-radius:50%;display:grid;place-items:center;font-weight:800;font-size:14px;color:#0b0d10;background:var(--site)}
++.steps b{font-size:15px}.steps span:last-child{font-size:13px;color:var(--text-secondary);line-height:1.55}
++.grid.three{grid-template-columns:repeat(auto-fit,minmax(280px,1fr))}
++.choice{display:grid;grid-template-columns:repeat(auto-fit,minmax(280px,1fr));gap:14px}
++.card.big{padding:24px}.card.big b{font-size:17px}
++.chips{display:flex;flex-wrap:wrap;gap:7px;margin-top:6px}
++.chips span{font-size:12.5px;padding:6px 11px;border-radius:999px;border:1px solid var(--border);background:var(--bg-secondary);color:var(--text-secondary)}
++.chips.big span{font-size:13.5px;padding:9px 14px;color:var(--text-primary)}.chips.big span i{color:var(--site);margin-right:8px}
++.build .card{border-style:dashed;background:rgba(0,0,0,.15)}.build .card b i{color:var(--site);margin-right:6px}.build .card span a{color:var(--text-secondary)}.build .card code{font-size:12px}
++@media (max-width:860px){.hero.split{grid-template-columns:1fr;text-align:center;gap:28px}.hero.split .ctas{justify-content:center}.hero.split p.lead{margin:0 auto}}
++@media (max-width:600px){.hero{padding-top:56px}.ctas .btn{width:100%;justify-content:center}.viz-ctrl{flex-direction:column;align-items:stretch}.dpad{align-self:center}}
@media (prefers-reduced-motion:reduce){*{animation:none!important;transition:none!important}}
</style>
</head>
ddiff --git a/dist/openvibe.vip/release.json b/dist/openvibe.vip/release.json
iindex e87853c..b751c05 100644
---- a/dist/openvibe.vip/release.json
++++ b/dist/openvibe.vip/release.json
@@@ -1,6 +1,6 @@
{
"service": "vip",
-- "release": "14e1cfc08e3d",
++ "release": "3cf1ce50fcfa",
"released_at": "2026-09-29T00:00:00.000Z",
"booted_at": null,
"contracts_version": null,
ddiff --git a/dist/openvibe.watch/index.html b/dist/openvibe.watch/index.html
iindex 886626f..62c4699 100644
---- a/dist/openvibe.watch/index.html
++++ b/dist/openvibe.watch/index.html
@@@ -87,7 +87,50 @@ a.card:hover{transform:translateY(-3px);border-color:rgba(var(--site-rgb),.6);bo
.strip h3{font-size:19px;font-weight:700;margin:12px 0 8px}
.strip p{font-size:14px;color:var(--text-secondary);max-width:600px;margin:0 auto 18px;line-height:1.6}
.strip .ov-mark{width:44px;height:44px}
--@media (max-width:600px){.hero{padding-top:56px}.ctas .btn{width:100%;justify-content:center}}
++.hero.split{display:grid;grid-template-columns:minmax(0,1.05fr) minmax(0,1fr);gap:40px;align-items:center;text-align:left;padding-top:64px}
++.hero.split .ctas{justify-content:flex-start}.hero.split p.lead{margin:0}
++.viz{background:var(--bg-card);border:1px solid var(--border);border-radius:20px;padding:14px;box-shadow:0 30px 80px rgba(0,0,0,.45),0 0 0 1px rgba(var(--site-rgb),.08);animation:rise .7s .25s cubic-bezier(.2,.8,.2,1) both;text-align:left}
++.viz figcaption{margin-top:10px;font-size:11.5px;color:var(--text-muted);text-align:center}
++.viz-top{display:flex;align-items:center;gap:8px;font-size:13px;padding:2px 4px 12px}
++.viz-top b{font-weight:700}.viz-top .muted{color:var(--text-muted)}
++.viz-top .lat{margin-left:auto;font-size:12px;color:var(--site);background:rgba(var(--site-rgb),.1);border:1px solid rgba(var(--site-rgb),.3);padding:3px 9px;border-radius:999px}
++.viz-top .dot{width:8px;height:8px;border-radius:50%;background:#22c55e;box-shadow:0 0 0 4px rgba(34,197,94,.18)}
++.viz-top .av{width:26px;height:26px;border-radius:8px;display:grid;place-items:center;background:rgba(var(--site-rgb),.15);color:var(--site);font-size:13px}
++.viz-video{position:relative;aspect-ratio:16/9;border-radius:14px;overflow:hidden;background:radial-gradient(120% 90% at 30% 20%,rgba(var(--site-rgb),.28),transparent 60%),linear-gradient(160deg,#1a2338,#0b1020 70%);border:1px solid var(--border)}
++.viz-video::after{content:'';position:absolute;left:10%;right:10%;bottom:0;height:42%;background:linear-gradient(transparent,rgba(0,0,0,.35)),repeating-linear-gradient(90deg,rgba(255,255,255,.05) 0 1px,transparent 1px 38px);transform:perspective(220px) rotateX(58deg);transform-origin:bottom}
++.viz-video .scan{position:absolute;inset:0;background:linear-gradient(transparent 0,rgba(255,255,255,.04) 50%,transparent 100%);background-size:100% 6px;opacity:.5}
++.viz-video .onair{position:absolute;top:10px;left:10px;font-size:11px;font-weight:700;padding:3px 8px;border-radius:6px;background:rgba(239,68,68,.9);color:#fff}.viz-video .onair i{font-size:7px;vertical-align:2px;margin-right:3px}
++.viz-video .cam{position:absolute;bottom:10px;right:10px;font-size:11px;color:#dbe4f5;background:rgba(0,0,0,.45);padding:3px 8px;border-radius:6px}
++.viz-ctrl{display:flex;gap:14px;align-items:center;margin-top:12px}
++.dpad{display:grid;grid-template-columns:repeat(3,34px);grid-template-rows:repeat(3,34px);gap:4px;flex:none}
++.dpad span{display:grid;place-items:center;border-radius:9px;background:var(--bg-hover);color:var(--text-primary);font-size:15px;border:1px solid var(--border)}
++.dpad .u{grid-area:1/2}.dpad .l{grid-area:2/1}.dpad .c{grid-area:2/2;background:rgba(var(--site-rgb),.15);border-color:rgba(var(--site-rgb),.35)}.dpad .r{grid-area:2/3}.dpad .d{grid-area:3/2}
++.dpad .u{background:rgba(var(--site-rgb),.22);border-color:rgba(var(--site-rgb),.5)}
++.viz-side{flex:1;min-width:0;display:grid;gap:8px}
++.viz-side .keys{display:flex;flex-wrap:wrap;gap:6px}
++.viz-side .keys span{font-size:11.5px;padding:5px 9px;border-radius:8px;background:var(--bg-secondary);border:1px solid var(--border);color:var(--text-secondary)}
++.viz-side .meter{display:flex;align-items:center;gap:8px;font-size:11.5px;color:var(--text-muted)}
++.viz-side .meter i{flex:1;height:6px;border-radius:9px;background:linear-gradient(90deg,#22c55e var(--v),var(--bg-hover) var(--v))}
++.viz-side .meter b{color:var(--text-secondary);font-weight:600}
++.viz-side .estop{justify-self:end;font-size:12px;font-weight:800;letter-spacing:.08em;color:#fff;background:#dc2626;border-radius:10px;padding:7px 16px;box-shadow:0 0 0 3px rgba(220,38,38,.25)}
++.feed{list-style:none;display:grid;gap:8px;padding:2px}
++.feed li{display:flex;align-items:flex-start;gap:10px;font-size:13.5px;line-height:1.45;padding:10px 12px;border-radius:12px;background:var(--bg-secondary);border:1px solid var(--border);color:var(--text-secondary)}
++.feed li i{color:#22c55e;margin-top:3px}
++.feed li.ask{flex-wrap:wrap;border-color:rgba(var(--site-rgb),.45);background:rgba(var(--site-rgb),.08);color:var(--text-primary)}.feed li.ask i{color:var(--site)}.feed li.ask>span:first-of-type{flex:1;min-width:160px}
++.feed .pills{display:flex;gap:6px;margin-left:auto}.feed .pills span{font-size:12px;font-weight:600;padding:4px 11px;border-radius:999px;border:1px solid var(--border);color:var(--text-secondary)}.feed .pills .ok{background:var(--site);border-color:var(--site);color:#0b0d10}
++.steps{list-style:none;display:grid;grid-template-columns:repeat(auto-fit,minmax(230px,1fr));gap:14px;counter-reset:s}
++.steps li{position:relative;background:var(--bg-card);border:1px solid var(--border);border-radius:16px;padding:20px 20px 20px;display:flex;flex-direction:column;gap:8px}
++.steps .n{width:30px;height:30px;border-radius:50%;display:grid;place-items:center;font-weight:800;font-size:14px;color:#0b0d10;background:var(--site)}
++.steps b{font-size:15px}.steps span:last-child{font-size:13px;color:var(--text-secondary);line-height:1.55}
++.grid.three{grid-template-columns:repeat(auto-fit,minmax(280px,1fr))}
++.choice{display:grid;grid-template-columns:repeat(auto-fit,minmax(280px,1fr));gap:14px}
++.card.big{padding:24px}.card.big b{font-size:17px}
++.chips{display:flex;flex-wrap:wrap;gap:7px;margin-top:6px}
++.chips span{font-size:12.5px;padding:6px 11px;border-radius:999px;border:1px solid var(--border);background:var(--bg-secondary);color:var(--text-secondary)}
++.chips.big span{font-size:13.5px;padding:9px 14px;color:var(--text-primary)}.chips.big span i{color:var(--site);margin-right:8px}
++.build .card{border-style:dashed;background:rgba(0,0,0,.15)}.build .card b i{color:var(--site);margin-right:6px}.build .card span a{color:var(--text-secondary)}.build .card code{font-size:12px}
++@media (max-width:860px){.hero.split{grid-template-columns:1fr;text-align:center;gap:28px}.hero.split .ctas{justify-content:center}.hero.split p.lead{margin:0 auto}}
++@media (max-width:600px){.hero{padding-top:56px}.ctas .btn{width:100%;justify-content:center}.viz-ctrl{flex-direction:column;align-items:stretch}.dpad{align-self:center}}
@media (prefers-reduced-motion:reduce){*{animation:none!important;transition:none!important}}
</style>
</head>
ddiff --git a/dist/openvibe.watch/release.json b/dist/openvibe.watch/release.json
iindex f625b71..743a833 100644
---- a/dist/openvibe.watch/release.json
++++ b/dist/openvibe.watch/release.json
@@@ -1,6 +1,6 @@
{
"service": "watch",
-- "release": "888e9326a89e",
++ "release": "db3af1fe5690",
"released_at": "2026-09-29T00:00:00.000Z",
"booted_at": null,
"contracts_version": null,
ddiff --git a/dist/openvibe.website/index.html b/dist/openvibe.website/index.html
iindex 46a9158..a9d037e 100644
---- a/dist/openvibe.website/index.html
++++ b/dist/openvibe.website/index.html
@@@ -87,7 +87,50 @@ a.card:hover{transform:translateY(-3px);border-color:rgba(var(--site-rgb),.6);bo
.strip h3{font-size:19px;font-weight:700;margin:12px 0 8px}
.strip p{font-size:14px;color:var(--text-secondary);max-width:600px;margin:0 auto 18px;line-height:1.6}
.strip .ov-mark{width:44px;height:44px}
--@media (max-width:600px){.hero{padding-top:56px}.ctas .btn{width:100%;justify-content:center}}
++.hero.split{display:grid;grid-template-columns:minmax(0,1.05fr) minmax(0,1fr);gap:40px;align-items:center;text-align:left;padding-top:64px}
++.hero.split .ctas{justify-content:flex-start}.hero.split p.lead{margin:0}
++.viz{background:var(--bg-card);border:1px solid var(--border);border-radius:20px;padding:14px;box-shadow:0 30px 80px rgba(0,0,0,.45),0 0 0 1px rgba(var(--site-rgb),.08);animation:rise .7s .25s cubic-bezier(.2,.8,.2,1) both;text-align:left}
++.viz figcaption{margin-top:10px;font-size:11.5px;color:var(--text-muted);text-align:center}
++.viz-top{display:flex;align-items:center;gap:8px;font-size:13px;padding:2px 4px 12px}
++.viz-top b{font-weight:700}.viz-top .muted{color:var(--text-muted)}
++.viz-top .lat{margin-left:auto;font-size:12px;color:var(--site);background:rgba(var(--site-rgb),.1);border:1px solid rgba(var(--site-rgb),.3);padding:3px 9px;border-radius:999px}
++.viz-top .dot{width:8px;height:8px;border-radius:50%;background:#22c55e;box-shadow:0 0 0 4px rgba(34,197,94,.18)}
++.viz-top .av{width:26px;height:26px;border-radius:8px;display:grid;place-items:center;background:rgba(var(--site-rgb),.15);color:var(--site);font-size:13px}
++.viz-video{position:relative;aspect-ratio:16/9;border-radius:14px;overflow:hidden;background:radial-gradient(120% 90% at 30% 20%,rgba(var(--site-rgb),.28),transparent 60%),linear-gradient(160deg,#1a2338,#0b1020 70%);border:1px solid var(--border)}
++.viz-video::after{content:'';position:absolute;left:10%;right:10%;bottom:0;height:42%;background:linear-gradient(transparent,rgba(0,0,0,.35)),repeating-linear-gradient(90deg,rgba(255,255,255,.05) 0 1px,transparent 1px 38px);transform:perspective(220px) rotateX(58deg);transform-origin:bottom}
++.viz-video .scan{position:absolute;inset:0;background:linear-gradient(transparent 0,rgba(255,255,255,.04) 50%,transparent 100%);background-size:100% 6px;opacity:.5}
++.viz-video .onair{position:absolute;top:10px;left:10px;font-size:11px;font-weight:700;padding:3px 8px;border-radius:6px;background:rgba(239,68,68,.9);color:#fff}.viz-video .onair i{font-size:7px;vertical-align:2px;margin-right:3px}
++.viz-video .cam{position:absolute;bottom:10px;right:10px;font-size:11px;color:#dbe4f5;background:rgba(0,0,0,.45);padding:3px 8px;border-radius:6px}
++.viz-ctrl{display:flex;gap:14px;align-items:center;margin-top:12px}
++.dpad{display:grid;grid-template-columns:repeat(3,34px);grid-template-rows:repeat(3,34px);gap:4px;flex:none}
++.dpad span{display:grid;place-items:center;border-radius:9px;background:var(--bg-hover);color:var(--text-primary);font-size:15px;border:1px solid var(--border)}
++.dpad .u{grid-area:1/2}.dpad .l{grid-area:2/1}.dpad .c{grid-area:2/2;background:rgba(var(--site-rgb),.15);border-color:rgba(var(--site-rgb),.35)}.dpad .r{grid-area:2/3}.dpad .d{grid-area:3/2}
++.dpad .u{background:rgba(var(--site-rgb),.22);border-color:rgba(var(--site-rgb),.5)}
++.viz-side{flex:1;min-width:0;display:grid;gap:8px}
++.viz-side .keys{display:flex;flex-wrap:wrap;gap:6px}
++.viz-side .keys span{font-size:11.5px;padding:5px 9px;border-radius:8px;background:var(--bg-secondary);border:1px solid var(--border);color:var(--text-secondary)}
++.viz-side .meter{display:flex;align-items:center;gap:8px;font-size:11.5px;color:var(--text-muted)}
++.viz-side .meter i{flex:1;height:6px;border-radius:9px;background:linear-gradient(90deg,#22c55e var(--v),var(--bg-hover) var(--v))}
++.viz-side .meter b{color:var(--text-secondary);font-weight:600}
++.viz-side .estop{justify-self:end;font-size:12px;font-weight:800;letter-spacing:.08em;color:#fff;background:#dc2626;border-radius:10px;padding:7px 16px;box-shadow:0 0 0 3px rgba(220,38,38,.25)}
++.feed{list-style:none;display:grid;gap:8px;padding:2px}
++.feed li{display:flex;align-items:flex-start;gap:10px;font-size:13.5px;line-height:1.45;padding:10px 12px;border-radius:12px;background:var(--bg-secondary);border:1px solid var(--border);color:var(--text-secondary)}
++.feed li i{color:#22c55e;margin-top:3px}
++.feed li.ask{flex-wrap:wrap;border-color:rgba(var(--site-rgb),.45);background:rgba(var(--site-rgb),.08);color:var(--text-primary)}.feed li.ask i{color:var(--site)}.feed li.ask>span:first-of-type{flex:1;min-width:160px}
++.feed .pills{display:flex;gap:6px;margin-left:auto}.feed .pills span{font-size:12px;font-weight:600;padding:4px 11px;border-radius:999px;border:1px solid var(--border);color:var(--text-secondary)}.feed .pills .ok{background:var(--site);border-color:var(--site);color:#0b0d10}
++.steps{list-style:none;display:grid;grid-template-columns:repeat(auto-fit,minmax(230px,1fr));gap:14px;counter-reset:s}
++.steps li{position:relative;background:var(--bg-card);border:1px solid var(--border);border-radius:16px;padding:20px 20px 20px;display:flex;flex-direction:column;gap:8px}
++.steps .n{width:30px;height:30px;border-radius:50%;display:grid;place-items:center;font-weight:800;font-size:14px;color:#0b0d10;background:var(--site)}
++.steps b{font-size:15px}.steps span:last-child{font-size:13px;color:var(--text-secondary);line-height:1.55}
++.grid.three{grid-template-columns:repeat(auto-fit,minmax(280px,1fr))}
++.choice{display:grid;grid-template-columns:repeat(auto-fit,minmax(280px,1fr));gap:14px}
++.card.big{padding:24px}.card.big b{font-size:17px}
++.chips{display:flex;flex-wrap:wrap;gap:7px;margin-top:6px}
++.chips span{font-size:12.5px;padding:6px 11px;border-radius:999px;border:1px solid var(--border);background:var(--bg-secondary);color:var(--text-secondary)}
++.chips.big span{font-size:13.5px;padding:9px 14px;color:var(--text-primary)}.chips.big span i{color:var(--site);margin-right:8px}
++.build .card{border-style:dashed;background:rgba(0,0,0,.15)}.build .card b i{color:var(--site);margin-right:6px}.build .card span a{color:var(--text-secondary)}.build .card code{font-size:12px}
++@media (max-width:860px){.hero.split{grid-template-columns:1fr;text-align:center;gap:28px}.hero.split .ctas{justify-content:center}.hero.split p.lead{margin:0 auto}}
++@media (max-width:600px){.hero{padding-top:56px}.ctas .btn{width:100%;justify-content:center}.viz-ctrl{flex-direction:column;align-items:stretch}.dpad{align-self:center}}
@media (prefers-reduced-motion:reduce){*{animation:none!important;transition:none!important}}
</style>
</head>
ddiff --git a/dist/openvibe.website/release.json b/dist/openvibe.website/release.json
iindex 6e91eaa..bf2e945 100644
---- a/dist/openvibe.website/release.json
++++ b/dist/openvibe.website/release.json
@@@ -1,6 +1,6 @@
{
"service": "website",
-- "release": "5f73cfa6fe28",
++ "release": "7ed1a86c7726",
"released_at": "2026-09-29T00:00:00.000Z",
"booted_at": null,
"contracts_version": null,
ddiff --git a/dist/realtime.openvibe.network/index.html b/dist/realtime.openvibe.network/index.html
iindex f1c74e8..388dca3 100644
---- a/dist/realtime.openvibe.network/index.html
++++ b/dist/realtime.openvibe.network/index.html
@@@ -87,7 +87,50 @@ a.card:hover{transform:translateY(-3px);border-color:rgba(var(--site-rgb),.6);bo
.strip h3{font-size:19px;font-weight:700;margin:12px 0 8px}
.strip p{font-size:14px;color:var(--text-secondary);max-width:600px;margin:0 auto 18px;line-height:1.6}
.strip .ov-mark{width:44px;height:44px}
--@media (max-width:600px){.hero{padding-top:56px}.ctas .btn{width:100%;justify-content:center}}
++.hero.split{display:grid;grid-template-columns:minmax(0,1.05fr) minmax(0,1fr);gap:40px;align-items:center;text-align:left;padding-top:64px}
++.hero.split .ctas{justify-content:flex-start}.hero.split p.lead{margin:0}
++.viz{background:var(--bg-card);border:1px solid var(--border);border-radius:20px;padding:14px;box-shadow:0 30px 80px rgba(0,0,0,.45),0 0 0 1px rgba(var(--site-rgb),.08);animation:rise .7s .25s cubic-bezier(.2,.8,.2,1) both;text-align:left}
++.viz figcaption{margin-top:10px;font-size:11.5px;color:var(--text-muted);text-align:center}
++.viz-top{display:flex;align-items:center;gap:8px;font-size:13px;padding:2px 4px 12px}
++.viz-top b{font-weight:700}.viz-top .muted{color:var(--text-muted)}
++.viz-top .lat{margin-left:auto;font-size:12px;color:var(--site);background:rgba(var(--site-rgb),.1);border:1px solid rgba(var(--site-rgb),.3);padding:3px 9px;border-radius:999px}
++.viz-top .dot{width:8px;height:8px;border-radius:50%;background:#22c55e;box-shadow:0 0 0 4px rgba(34,197,94,.18)}
++.viz-top .av{width:26px;height:26px;border-radius:8px;display:grid;place-items:center;background:rgba(var(--site-rgb),.15);color:var(--site);font-size:13px}
++.viz-video{position:relative;aspect-ratio:16/9;border-radius:14px;overflow:hidden;background:radial-gradient(120% 90% at 30% 20%,rgba(var(--site-rgb),.28),transparent 60%),linear-gradient(160deg,#1a2338,#0b1020 70%);border:1px solid var(--border)}
++.viz-video::after{content:'';position:absolute;left:10%;right:10%;bottom:0;height:42%;background:linear-gradient(transparent,rgba(0,0,0,.35)),repeating-linear-gradient(90deg,rgba(255,255,255,.05) 0 1px,transparent 1px 38px);transform:perspective(220px) rotateX(58deg);transform-origin:bottom}
++.viz-video .scan{position:absolute;inset:0;background:linear-gradient(transparent 0,rgba(255,255,255,.04) 50%,transparent 100%);background-size:100% 6px;opacity:.5}
++.viz-video .onair{position:absolute;top:10px;left:10px;font-size:11px;font-weight:700;padding:3px 8px;border-radius:6px;background:rgba(239,68,68,.9);color:#fff}.viz-video .onair i{font-size:7px;vertical-align:2px;margin-right:3px}
++.viz-video .cam{position:absolute;bottom:10px;right:10px;font-size:11px;color:#dbe4f5;background:rgba(0,0,0,.45);padding:3px 8px;border-radius:6px}
++.viz-ctrl{display:flex;gap:14px;align-items:center;margin-top:12px}
++.dpad{display:grid;grid-template-columns:repeat(3,34px);grid-template-rows:repeat(3,34px);gap:4px;flex:none}
++.dpad span{display:grid;place-items:center;border-radius:9px;background:var(--bg-hover);color:var(--text-primary);font-size:15px;border:1px solid var(--border)}
++.dpad .u{grid-area:1/2}.dpad .l{grid-area:2/1}.dpad .c{grid-area:2/2;background:rgba(var(--site-rgb),.15);border-color:rgba(var(--site-rgb),.35)}.dpad .r{grid-area:2/3}.dpad .d{grid-area:3/2}
++.dpad .u{background:rgba(var(--site-rgb),.22);border-color:rgba(var(--site-rgb),.5)}
++.viz-side{flex:1;min-width:0;display:grid;gap:8px}
++.viz-side .keys{display:flex;flex-wrap:wrap;gap:6px}
++.viz-side .keys span{font-size:11.5px;padding:5px 9px;border-radius:8px;background:var(--bg-secondary);border:1px solid var(--border);color:var(--text-secondary)}
++.viz-side .meter{display:flex;align-items:center;gap:8px;font-size:11.5px;color:var(--text-muted)}
++.viz-side .meter i{flex:1;height:6px;border-radius:9px;background:linear-gradient(90deg,#22c55e var(--v),var(--bg-hover) var(--v))}
++.viz-side .meter b{color:var(--text-secondary);font-weight:600}
++.viz-side .estop{justify-self:end;font-size:12px;font-weight:800;letter-spacing:.08em;color:#fff;background:#dc2626;border-radius:10px;padding:7px 16px;box-shadow:0 0 0 3px rgba(220,38,38,.25)}
++.feed{list-style:none;display:grid;gap:8px;padding:2px}
++.feed li{display:flex;align-items:flex-start;gap:10px;font-size:13.5px;line-height:1.45;padding:10px 12px;border-radius:12px;background:var(--bg-secondary);border:1px solid var(--border);color:var(--text-secondary)}
++.feed li i{color:#22c55e;margin-top:3px}
++.feed li.ask{flex-wrap:wrap;border-color:rgba(var(--site-rgb),.45);background:rgba(var(--site-rgb),.08);color:var(--text-primary)}.feed li.ask i{color:var(--site)}.feed li.ask>span:first-of-type{flex:1;min-width:160px}
++.feed .pills{display:flex;gap:6px;margin-left:auto}.feed .pills span{font-size:12px;font-weight:600;padding:4px 11px;border-radius:999px;border:1px solid var(--border);color:var(--text-secondary)}.feed .pills .ok{background:var(--site);border-color:var(--site);color:#0b0d10}
++.steps{list-style:none;display:grid;grid-template-columns:repeat(auto-fit,minmax(230px,1fr));gap:14px;counter-reset:s}
++.steps li{position:relative;background:var(--bg-card);border:1px solid var(--border);border-radius:16px;padding:20px 20px 20px;display:flex;flex-direction:column;gap:8px}
++.steps .n{width:30px;height:30px;border-radius:50%;display:grid;place-items:center;font-weight:800;font-size:14px;color:#0b0d10;background:var(--site)}
++.steps b{font-size:15px}.steps span:last-child{font-size:13px;color:var(--text-secondary);line-height:1.55}
++.grid.three{grid-template-columns:repeat(auto-fit,minmax(280px,1fr))}
++.choice{display:grid;grid-template-columns:repeat(auto-fit,minmax(280px,1fr));gap:14px}
++.card.big{padding:24px}.card.big b{font-size:17px}
++.chips{display:flex;flex-wrap:wrap;gap:7px;margin-top:6px}
++.chips span{font-size:12.5px;padding:6px 11px;border-radius:999px;border:1px solid var(--border);background:var(--bg-secondary);color:var(--text-secondary)}
++.chips.big span{font-size:13.5px;padding:9px 14px;color:var(--text-primary)}.chips.big span i{color:var(--site);margin-right:8px}
++.build .card{border-style:dashed;background:rgba(0,0,0,.15)}.build .card b i{color:var(--site);margin-right:6px}.build .card span a{color:var(--text-secondary)}.build .card code{font-size:12px}
++@media (max-width:860px){.hero.split{grid-template-columns:1fr;text-align:center;gap:28px}.hero.split .ctas{justify-content:center}.hero.split p.lead{margin:0 auto}}
++@media (max-width:600px){.hero{padding-top:56px}.ctas .btn{width:100%;justify-content:center}.viz-ctrl{flex-direction:column;align-items:stretch}.dpad{align-self:center}}
@media (prefers-reduced-motion:reduce){*{animation:none!important;transition:none!important}}
</style>
</head>
ddiff --git a/dist/realtime.openvibe.network/release.json b/dist/realtime.openvibe.network/release.json
iindex 8d3144f..4905709 100644
---- a/dist/realtime.openvibe.network/release.json
++++ b/dist/realtime.openvibe.network/release.json
@@@ -1,6 +1,6 @@
{
"service": "realtime",
-- "release": "62bc5976ae34",
++ "release": "b271aa178d7e",
"released_at": "2026-09-29T00:00:00.000Z",
"booted_at": null,
"contracts_version": null,
ddiff --git a/dist/status.openvibe.network/index.html b/dist/status.openvibe.network/index.html
iindex 1d2871e..04c6651 100644
---- a/dist/status.openvibe.network/index.html
++++ b/dist/status.openvibe.network/index.html
@@@ -87,7 +87,50 @@ a.card:hover{transform:translateY(-3px);border-color:rgba(var(--site-rgb),.6);bo
.strip h3{font-size:19px;font-weight:700;margin:12px 0 8px}
.strip p{font-size:14px;color:var(--text-secondary);max-width:600px;margin:0 auto 18px;line-height:1.6}
.strip .ov-mark{width:44px;height:44px}
--@media (max-width:600px){.hero{padding-top:56px}.ctas .btn{width:100%;justify-content:center}}
++.hero.split{display:grid;grid-template-columns:minmax(0,1.05fr) minmax(0,1fr);gap:40px;align-items:center;text-align:left;padding-top:64px}
++.hero.split .ctas{justify-content:flex-start}.hero.split p.lead{margin:0}
++.viz{background:var(--bg-card);border:1px solid var(--border);border-radius:20px;padding:14px;box-shadow:0 30px 80px rgba(0,0,0,.45),0 0 0 1px rgba(var(--site-rgb),.08);animation:rise .7s .25s cubic-bezier(.2,.8,.2,1) both;text-align:left}
++.viz figcaption{margin-top:10px;font-size:11.5px;color:var(--text-muted);text-align:center}
++.viz-top{display:flex;align-items:center;gap:8px;font-size:13px;padding:2px 4px 12px}
++.viz-top b{font-weight:700}.viz-top .muted{color:var(--text-muted)}
++.viz-top .lat{margin-left:auto;font-size:12px;color:var(--site);background:rgba(var(--site-rgb),.1);border:1px solid rgba(var(--site-rgb),.3);padding:3px 9px;border-radius:999px}
++.viz-top .dot{width:8px;height:8px;border-radius:50%;background:#22c55e;box-shadow:0 0 0 4px rgba(34,197,94,.18)}
++.viz-top .av{width:26px;height:26px;border-radius:8px;display:grid;place-items:center;background:rgba(var(--site-rgb),.15);color:var(--site);font-size:13px}
++.viz-video{position:relative;aspect-ratio:16/9;border-radius:14px;overflow:hidden;background:radial-gradient(120% 90% at 30% 20%,rgba(var(--site-rgb),.28),transparent 60%),linear-gradient(160deg,#1a2338,#0b1020 70%);border:1px solid var(--border)}
++.viz-video::after{content:'';position:absolute;left:10%;right:10%;bottom:0;height:42%;background:linear-gradient(transparent,rgba(0,0,0,.35)),repeating-linear-gradient(90deg,rgba(255,255,255,.05) 0 1px,transparent 1px 38px);transform:perspective(220px) rotateX(58deg);transform-origin:bottom}
++.viz-video .scan{position:absolute;inset:0;background:linear-gradient(transparent 0,rgba(255,255,255,.04) 50%,transparent 100%);background-size:100% 6px;opacity:.5}
++.viz-video .onair{position:absolute;top:10px;left:10px;font-size:11px;font-weight:700;padding:3px 8px;border-radius:6px;background:rgba(239,68,68,.9);color:#fff}.viz-video .onair i{font-size:7px;vertical-align:2px;margin-right:3px}
++.viz-video .cam{position:absolute;bottom:10px;right:10px;font-size:11px;color:#dbe4f5;background:rgba(0,0,0,.45);padding:3px 8px;border-radius:6px}
++.viz-ctrl{display:flex;gap:14px;align-items:center;margin-top:12px}
++.dpad{display:grid;grid-template-columns:repeat(3,34px);grid-template-rows:repeat(3,34px);gap:4px;flex:none}
++.dpad span{display:grid;place-items:center;border-radius:9px;background:var(--bg-hover);color:var(--text-primary);font-size:15px;border:1px solid var(--border)}
++.dpad .u{grid-area:1/2}.dpad .l{grid-area:2/1}.dpad .c{grid-area:2/2;background:rgba(var(--site-rgb),.15);border-color:rgba(var(--site-rgb),.35)}.dpad .r{grid-area:2/3}.dpad .d{grid-area:3/2}
++.dpad .u{background:rgba(var(--site-rgb),.22);border-color:rgba(var(--site-rgb),.5)}
++.viz-side{flex:1;min-width:0;display:grid;gap:8px}
++.viz-side .keys{display:flex;flex-wrap:wrap;gap:6px}
++.viz-side .keys span{font-size:11.5px;padding:5px 9px;border-radius:8px;background:var(--bg-secondary);border:1px solid var(--border);color:var(--text-secondary)}
++.viz-side .meter{display:flex;align-items:center;gap:8px;font-size:11.5px;color:var(--text-muted)}
++.viz-side .meter i{flex:1;height:6px;border-radius:9px;background:linear-gradient(90deg,#22c55e var(--v),var(--bg-hover) var(--v))}
++.viz-side .meter b{color:var(--text-secondary);font-weight:600}
++.viz-side .estop{justify-self:end;font-size:12px;font-weight:800;letter-spacing:.08em;color:#fff;background:#dc2626;border-radius:10px;padding:7px 16px;box-shadow:0 0 0 3px rgba(220,38,38,.25)}
++.feed{list-style:none;display:grid;gap:8px;padding:2px}
++.feed li{display:flex;align-items:flex-start;gap:10px;font-size:13.5px;line-height:1.45;padding:10px 12px;border-radius:12px;background:var(--bg-secondary);border:1px solid var(--border);color:var(--text-secondary)}
++.feed li i{color:#22c55e;margin-top:3px}
++.feed li.ask{flex-wrap:wrap;border-color:rgba(var(--site-rgb),.45);background:rgba(var(--site-rgb),.08);color:var(--text-primary)}.feed li.ask i{color:var(--site)}.feed li.ask>span:first-of-type{flex:1;min-width:160px}
++.feed .pills{display:flex;gap:6px;margin-left:auto}.feed .pills span{font-size:12px;font-weight:600;padding:4px 11px;border-radius:999px;border:1px solid var(--border);color:var(--text-secondary)}.feed .pills .ok{background:var(--site);border-color:var(--site);color:#0b0d10}
++.steps{list-style:none;display:grid;grid-template-columns:repeat(auto-fit,minmax(230px,1fr));gap:14px;counter-reset:s}
++.steps li{position:relative;background:var(--bg-card);border:1px solid var(--border);border-radius:16px;padding:20px 20px 20px;display:flex;flex-direction:column;gap:8px}
++.steps .n{width:30px;height:30px;border-radius:50%;display:grid;place-items:center;font-weight:800;font-size:14px;color:#0b0d10;background:var(--site)}
++.steps b{font-size:15px}.steps span:last-child{font-size:13px;color:var(--text-secondary);line-height:1.55}
++.grid.three{grid-template-columns:repeat(auto-fit,minmax(280px,1fr))}
++.choice{display:grid;grid-template-columns:repeat(auto-fit,minmax(280px,1fr));gap:14px}
++.card.big{padding:24px}.card.big b{font-size:17px}
++.chips{display:flex;flex-wrap:wrap;gap:7px;margin-top:6px}
++.chips span{font-size:12.5px;padding:6px 11px;border-radius:999px;border:1px solid var(--border);background:var(--bg-secondary);color:var(--text-secondary)}
++.chips.big span{font-size:13.5px;padding:9px 14px;color:var(--text-primary)}.chips.big span i{color:var(--site);margin-right:8px}
++.build .card{border-style:dashed;background:rgba(0,0,0,.15)}.build .card b i{color:var(--site);margin-right:6px}.build .card span a{color:var(--text-secondary)}.build .card code{font-size:12px}
++@media (max-width:860px){.hero.split{grid-template-columns:1fr;text-align:center;gap:28px}.hero.split .ctas{justify-content:center}.hero.split p.lead{margin:0 auto}}
++@media (max-width:600px){.hero{padding-top:56px}.ctas .btn{width:100%;justify-content:center}.viz-ctrl{flex-direction:column;align-items:stretch}.dpad{align-self:center}}
@media (prefers-reduced-motion:reduce){*{animation:none!important;transition:none!important}}
.live .sum{font-size:14px;color:var(--text-secondary);margin-bottom:14px;line-height:1.6}
.live .sum b{color:var(--text-primary)}
ddiff --git a/dist/status.openvibe.network/release.json b/dist/status.openvibe.network/release.json
iindex d9ea0de..ffa0333 100644
---- a/dist/status.openvibe.network/release.json
++++ b/dist/status.openvibe.network/release.json
@@@ -1,6 +1,6 @@
{
"service": "status",
-- "release": "da30bb979607",
++ "release": "e2fecfa09c74",
"released_at": "2026-09-29T00:00:00.000Z",
"booted_at": null,
"contracts_version": null,
ddiff --git a/dist/themes.openvibe.network/index.html b/dist/themes.openvibe.network/index.html
iindex 3dff02c..b427d2c 100644
---- a/dist/themes.openvibe.network/index.html
++++ b/dist/themes.openvibe.network/index.html
@@@ -87,7 +87,50 @@ a.card:hover{transform:translateY(-3px);border-color:rgba(var(--site-rgb),.6);bo
.strip h3{font-size:19px;font-weight:700;margin:12px 0 8px}
.strip p{font-size:14px;color:var(--text-secondary);max-width:600px;margin:0 auto 18px;line-height:1.6}
.strip .ov-mark{width:44px;height:44px}
--@media (max-width:600px){.hero{padding-top:56px}.ctas .btn{width:100%;justify-content:center}}
++.hero.split{display:grid;grid-template-columns:minmax(0,1.05fr) minmax(0,1fr);gap:40px;align-items:center;text-align:left;padding-top:64px}
++.hero.split .ctas{justify-content:flex-start}.hero.split p.lead{margin:0}
++.viz{background:var(--bg-card);border:1px solid var(--border);border-radius:20px;padding:14px;box-shadow:0 30px 80px rgba(0,0,0,.45),0 0 0 1px rgba(var(--site-rgb),.08);animation:rise .7s .25s cubic-bezier(.2,.8,.2,1) both;text-align:left}
++.viz figcaption{margin-top:10px;font-size:11.5px;color:var(--text-muted);text-align:center}
++.viz-top{display:flex;align-items:center;gap:8px;font-size:13px;padding:2px 4px 12px}
++.viz-top b{font-weight:700}.viz-top .muted{color:var(--text-muted)}
++.viz-top .lat{margin-left:auto;font-size:12px;color:var(--site);background:rgba(var(--site-rgb),.1);border:1px solid rgba(var(--site-rgb),.3);padding:3px 9px;border-radius:999px}
++.viz-top .dot{width:8px;height:8px;border-radius:50%;background:#22c55e;box-shadow:0 0 0 4px rgba(34,197,94,.18)}
++.viz-top .av{width:26px;height:26px;border-radius:8px;display:grid;place-items:center;background:rgba(var(--site-rgb),.15);color:var(--site);font-size:13px}
++.viz-video{position:relative;aspect-ratio:16/9;border-radius:14px;overflow:hidden;background:radial-gradient(120% 90% at 30% 20%,rgba(var(--site-rgb),.28),transparent 60%),linear-gradient(160deg,#1a2338,#0b1020 70%);border:1px solid var(--border)}
++.viz-video::after{content:'';position:absolute;left:10%;right:10%;bottom:0;height:42%;background:linear-gradient(transparent,rgba(0,0,0,.35)),repeating-linear-gradient(90deg,rgba(255,255,255,.05) 0 1px,transparent 1px 38px);transform:perspective(220px) rotateX(58deg);transform-origin:bottom}
++.viz-video .scan{position:absolute;inset:0;background:linear-gradient(transparent 0,rgba(255,255,255,.04) 50%,transparent 100%);background-size:100% 6px;opacity:.5}
++.viz-video .onair{position:absolute;top:10px;left:10px;font-size:11px;font-weight:700;padding:3px 8px;border-radius:6px;background:rgba(239,68,68,.9);color:#fff}.viz-video .onair i{font-size:7px;vertical-align:2px;margin-right:3px}
++.viz-video .cam{position:absolute;bottom:10px;right:10px;font-size:11px;color:#dbe4f5;background:rgba(0,0,0,.45);padding:3px 8px;border-radius:6px}
++.viz-ctrl{display:flex;gap:14px;align-items:center;margin-top:12px}
++.dpad{display:grid;grid-template-columns:repeat(3,34px);grid-template-rows:repeat(3,34px);gap:4px;flex:none}
++.dpad span{display:grid;place-items:center;border-radius:9px;background:var(--bg-hover);color:var(--text-primary);font-size:15px;border:1px solid var(--border)}
++.dpad .u{grid-area:1/2}.dpad .l{grid-area:2/1}.dpad .c{grid-area:2/2;background:rgba(var(--site-rgb),.15);border-color:rgba(var(--site-rgb),.35)}.dpad .r{grid-area:2/3}.dpad .d{grid-area:3/2}
++.dpad .u{background:rgba(var(--site-rgb),.22);border-color:rgba(var(--site-rgb),.5)}
++.viz-side{flex:1;min-width:0;display:grid;gap:8px}
++.viz-side .keys{display:flex;flex-wrap:wrap;gap:6px}
++.viz-side .keys span{font-size:11.5px;padding:5px 9px;border-radius:8px;background:var(--bg-secondary);border:1px solid var(--border);color:var(--text-secondary)}
++.viz-side .meter{display:flex;align-items:center;gap:8px;font-size:11.5px;color:var(--text-muted)}
++.viz-side .meter i{flex:1;height:6px;border-radius:9px;background:linear-gradient(90deg,#22c55e var(--v),var(--bg-hover) var(--v))}
++.viz-side .meter b{color:var(--text-secondary);font-weight:600}
++.viz-side .estop{justify-self:end;font-size:12px;font-weight:800;letter-spacing:.08em;color:#fff;background:#dc2626;border-radius:10px;padding:7px 16px;box-shadow:0 0 0 3px rgba(220,38,38,.25)}
++.feed{list-style:none;display:grid;gap:8px;padding:2px}
++.feed li{display:flex;align-items:flex-start;gap:10px;font-size:13.5px;line-height:1.45;padding:10px 12px;border-radius:12px;background:var(--bg-secondary);border:1px solid var(--border);color:var(--text-secondary)}
++.feed li i{color:#22c55e;margin-top:3px}
++.feed li.ask{flex-wrap:wrap;border-color:rgba(var(--site-rgb),.45);background:rgba(var(--site-rgb),.08);color:var(--text-primary)}.feed li.ask i{color:var(--site)}.feed li.ask>span:first-of-type{flex:1;min-width:160px}
++.feed .pills{display:flex;gap:6px;margin-left:auto}.feed .pills span{font-size:12px;font-weight:600;padding:4px 11px;border-radius:999px;border:1px solid var(--border);color:var(--text-secondary)}.feed .pills .ok{background:var(--site);border-color:var(--site);color:#0b0d10}
++.steps{list-style:none;display:grid;grid-template-columns:repeat(auto-fit,minmax(230px,1fr));gap:14px;counter-reset:s}
++.steps li{position:relative;background:var(--bg-card);border:1px solid var(--border);border-radius:16px;padding:20px 20px 20px;display:flex;flex-direction:column;gap:8px}
++.steps .n{width:30px;height:30px;border-radius:50%;display:grid;place-items:center;font-weight:800;font-size:14px;color:#0b0d10;background:var(--site)}
++.steps b{font-size:15px}.steps span:last-child{font-size:13px;color:var(--text-secondary);line-height:1.55}
++.grid.three{grid-template-columns:repeat(auto-fit,minmax(280px,1fr))}
++.choice{display:grid;grid-template-columns:repeat(auto-fit,minmax(280px,1fr));gap:14px}
++.card.big{padding:24px}.card.big b{font-size:17px}
++.chips{display:flex;flex-wrap:wrap;gap:7px;margin-top:6px}
++.chips span{font-size:12.5px;padding:6px 11px;border-radius:999px;border:1px solid var(--border);background:var(--bg-secondary);color:var(--text-secondary)}
++.chips.big span{font-size:13.5px;padding:9px 14px;color:var(--text-primary)}.chips.big span i{color:var(--site);margin-right:8px}
++.build .card{border-style:dashed;background:rgba(0,0,0,.15)}.build .card b i{color:var(--site);margin-right:6px}.build .card span a{color:var(--text-secondary)}.build .card code{font-size:12px}
++@media (max-width:860px){.hero.split{grid-template-columns:1fr;text-align:center;gap:28px}.hero.split .ctas{justify-content:center}.hero.split p.lead{margin:0 auto}}
++@media (max-width:600px){.hero{padding-top:56px}.ctas .btn{width:100%;justify-content:center}.viz-ctrl{flex-direction:column;align-items:stretch}.dpad{align-self:center}}
@media (prefers-reduced-motion:reduce){*{animation:none!important;transition:none!important}}
</style>
</head>
ddiff --git a/dist/themes.openvibe.network/release.json b/dist/themes.openvibe.network/release.json
iindex ecbe2f2..b70039c 100644
---- a/dist/themes.openvibe.network/release.json
++++ b/dist/themes.openvibe.network/release.json
@@@ -1,6 +1,6 @@
{
"service": "themes",
-- "release": "aebba28c917f",
++ "release": "9bc65bb6a1b1",
"released_at": "2026-09-29T00:00:00.000Z",
"booted_at": null,
"contracts_version": null,
ddiff --git a/sites.json b/sites.json
iindex ac47949..6a1f71f 100644
---- a/sites.json
++++ b/sites.json
@@@ -1240,8 +1240,8 @@
"icon": "fa-robot",
"accent": "#f472b6",
"noRepo": true,
-- "tagline": "Robots, cameras and devices you can share safely.",
-- "description": "OpenVibe.Bot will let you register robots, Raspberry Pis, cameras, motors, sensors and other devices, pair them securely, and control them yourself or hand control to friends, stream viewers, apps or your AI agents with timed turns, queues and permissions. Safety runs on the device too: heartbeats, command time limits, speed and range limits and an emergency stop that works without the cloud. OpenVibe.Live already runs stream-controlled robots; Bot makes the device its own thing.",
++ "tagline": "Get your robot online in minutes.",
++ "description": "OpenVibe.Bot is an open control panel for robots. Add a robot, pair it with one command or a QR code, and drive it from any browser with live video, real controls and a stop button that always works. Buy a ready-made bot or bring your own Raspberry Pi, ESP32, ROS 2 robot or phone. Share control, automate it, hand it to your AI agent, and stream it to OpenVibe.Live or openre.stream when you want to.",
"pillars": [
[
"Pair devices",
@@@ -1272,8 +1272,174 @@
"Device-side agents and hardware scripts."
]
],
-- "keywords": "remote control robot, stream controlled robot, raspberry pi robot control, telepresence robot, iot device control api",
-- "launch": "device pairing and control leases split out of OpenVibe.Live"
++ "keywords": "robot control panel, control a robot from the browser, remote control robot online, raspberry pi robot web control, esp32 robot control, ros 2 web control, telepresence robot, stream a robot live, open source robot controller",
++ "launch": "the Bot service, its device agent and the first robots paired",
++ "vision": {
++ "badge": "being built",
++ "cta": [
++ "Robots on Live today",
++ "https://openvibe.live",
++ "fa-tower-broadcast"
++ ],
++ "viz": {
++ "kind": "panel",
++ "name": "Rover-1",
++ "latency": "84 ms",
++ "onair": "Streaming to openvibe.live",
++ "battery": 82,
++ "keys": [
++ [
++ "fa-lightbulb",
++ "Lights"
++ ],
++ [
++ "fa-bullhorn",
++ "Horn"
++ ],
++ [
++ "fa-comment",
++ "Speak"
++ ],
++ [
++ "fa-camera-rotate",
++ "Camera"
++ ]
++ ],
++ "caption": "Design preview of the robot panel",
++ "label": "Design preview: a robot control panel with live video, a drive pad, buttons, battery level and a stop button"
++ },
++ "stepsTitle": "Online in three steps",
++ "stepsLead": "No port forwarding, no stream keys, no config files.",
++ "steps": [
++ [
++ "Add a robot",
++ "Name it and pick what it is: a rover, an arm, a camera, a phone on wheels or your own design."
++ ],
++ [
++ "Pair it",
++ "Paste one command on the robot, flash a ready-made card, or scan a QR code. It gets its own key, which you can revoke any time."
++ ],
++ [
++ "Drive it",
++ "Live video and controls in any browser, phone included, with a stop button that always works."
++ ]
++ ],
++ "choices": {
++ "title": "Buy one or bring your own",
++ "lead": "Start with hardware that is known to work, or use what you already have.",
++ "items": [
++ {
++ "icon": "fa-box-open",
++ "title": "Get a robot",
++ "text": "Curated kits with parts lists, tested settings and build guides, and ready-made bots that arrive paired to your account.",
++ "chips": [
++ "Rover kits",
++ "Telepresence bots",
++ "Pan-tilt cameras",
++ "Robot arms"
++ ]
++ },
++ {
++ "icon": "fa-screwdriver-wrench",
++ "title": "Bring your own",
++ "text": "Anything with motors, a camera or sensors. Install the OpenVibe device agent or add the library, and your robot shows up in the panel.",
++ "chips": [
++ "Raspberry Pi and Linux boards",
++ "ESP32",
++ "ROS 2",
++ "Android phones",
++ "ONVIF and RTSP cameras",
++ "Serial motor boards"
++ ]
++ }
++ ]
++ },
++ "featuresTitle": "More than a stream",
++ "featuresLead": "A control panel for anything you build, whether or not anyone is watching.",
++ "features": [
++ [
++ "fa-gamepad",
++ "Real controls",
++ "Drive pad, keyboard, touch joystick and gamepad; buttons, sliders, servos and camera pan-tilt, laid out from your robot's profile."
++ ],
++ [
++ "fa-bolt",
++ "Low latency",
++ "Video and commands over WebRTC, so driving feels direct. Works behind ordinary home and mobile networks."
++ ],
++ [
++ "fa-user-group",
++ "Share control",
++ "Invite friends as operators, or open a public queue with timed turns, cooldowns and per-role limits."
++ ],
++ [
++ "fa-shield-halved",
++ "Safe by default",
++ "The robot stops itself when commands stop. An emergency stop, speed and range limits and time windows, all logged."
++ ],
++ [
++ "fa-diagram-project",
++ "Automate it",
++ "Schedules, triggers and webhooks, plus an API and SDKs for your own apps."
++ ],
++ [
++ "fa-user-astronaut",
++ "Hand it to your agent",
++ "Let your OpenVibe.Actor agent patrol, check on or perform with your robot, with your approval."
++ ]
++ ],
++ "connectTitle": "Stream it, record it, connect it",
++ "connectLead": "Optional, one toggle each. Your robot does not need an audience to be useful.",
++ "connect": [
++ [
++ "fa-tower-broadcast",
++ "Stream to OpenVibe.Live",
++ "Put the robot's camera on your channel; viewers can drive it from chat or the panel.",
++ "https://openvibe.live"
++ ],
++ [
++ "fa-satellite-dish",
++ "Stream through openre.stream",
++ "Low-latency ingest and restreaming to other platforms from the same camera.",
++ "https://openre.stream"
++ ],
++ [
++ "fa-photo-film",
++ "Record to OpenVibe.Media",
++ "Keep every run as a video and cut clips from it.",
++ "https://openvibe.media"
++ ],
++ [
++ "fa-code",
++ "Build on it",
++ "The API, SDKs and examples.",
++ "https://openvibe.codes"
++ ]
++ ],
++ "building": "OpenVibe.Bot is being built now, starting with our own robots; stream-controlled robots already run on OpenVibe.Live."
++ },
++ "faq": [
++ [
++ "Do I need to open ports on my router?",
++ "No. The robot connects out to OpenVibe, and video and controls travel over WebRTC, so it works behind ordinary home and mobile networks."
++ ],
++ [
++ "Is it only for streaming?",
++ "No. Streaming is optional. Bot is a control panel for your robot first: drive it, check on it, share it and automate it."
++ ],
++ [
++ "What hardware works?",
++ "A Raspberry Pi or another Linux board, an ESP32, a ROS 2 robot, an Android phone, or an ONVIF or RTSP camera. The curated kits list exactly what to buy."
++ ],
++ [
++ "How does it keep the robot safe?",
++ "The device stops its motors by itself when commands or the connection stop. There is an emergency stop in the panel, limits on speed, range and time, and every command is logged."
++ ],
++ [
++ "What will it cost?",
++ "Controlling your own robot will not cost anything. Limits and any paid extras will be published before launch."
++ ]
++ ]
},
{
"domain": "openvibe.watch",
@@@ -1323,8 +1489,8 @@
"name": "OpenVibe.Actor",
"icon": "fa-user-astronaut",
"accent": "#a78bfa",
-- "tagline": "AI agents that act for you, with your permission.",
-- "description": "OpenVibe.Actor will give you persistent AI agents that work across OpenVibe and, when you allow it, other sites and apps: they use OpenVibe's own APIs first and a sandboxed browser when they must. You decide what each agent may do, for once, a session, a while or always, and anything with real consequences (buying, sending, publishing, applying, moving a robot) waits for your approval, wherever you are on the network.",
++ "tagline": "Your agent in the cloud, connected to everything OpenVibe.",
++ "description": "OpenVibe.Actor gives you an AI agent that lives in OpenVibe's cloud and works for you around the clock. It remembers, runs on schedules and triggers, uses every OpenVibe product as a tool, browses and codes in a sandbox, and asks before it does anything that matters. Talk to it from any OpenVibe site, in chat, or from your own apps.",
"pillars": [
[
"Your agents",
@@@ -1355,9 +1521,162 @@
"The API and SDK agents are built on."
]
],
-- "keywords": "ai agent platform, open source ai agent, personal ai assistant, browser automation agent, ai agent permissions",
-- "launch": "agent principals and delegated grants on OpenVibe.Network and the agent service",
-- "noRepo": true
++ "keywords": "cloud ai agent, hosted ai agent, personal ai agent, ai agent with memory, autonomous ai assistant, ai agent platform, open source ai agent, mcp server, ai agent approvals",
++ "launch": "agent accounts with delegated permissions on OpenVibe.Network and the Actor service",
++ "noRepo": true,
++ "vision": {
++ "badge": "being built",
++ "cta": [
++ "See the network",
++ "https://openvibe.network/#network",
++ "fa-circle-nodes"
++ ],
++ "viz": {
++ "kind": "agent",
++ "name": "Nova",
++ "role": "stream co-host",
++ "state": "always on",
++ "icon": "fa-user-astronaut",
++ "steps": [
++ "Watched tonight's stream and marked 3 highlights",
++ "Clipped the best one on OpenVibe.Media",
++ "Drafted a post for your blog with the clip"
++ ],
++ "ask": "Publish the post on openvibe.blog?",
++ "caption": "Design preview of an agent at work",
++ "label": "Design preview: an agent's activity feed ending in a request for approval"
++ },
++ "stepsTitle": "Start in a minute",
++ "stepsLead": "Describe what you want or start from a template. Change anything later.",
++ "steps": [
++ [
++ "Create an agent",
++ "Pick a template or describe the job in your own words. Choose its model and its personality."
++ ],
++ [
++ "Decide what it may do",
++ "Grant it tools one by one. Anything with consequences, like publishing, spending or moving a robot, waits for your approval."
++ ],
++ [
++ "Let it work",
++ "It runs in the cloud on schedules and triggers, and you can reach it from any OpenVibe site."
++ ]
++ ],
++ "featuresTitle": "What your agent can do",
++ "featuresLead": "An agent is only as useful as what it can reach. Yours can reach the whole network.",
++ "features": [
++ [
++ "fa-cloud",
++ "Always on",
++ "Runs in OpenVibe's cloud around the clock. Close your laptop; it keeps going."
++ ],
++ [
++ "fa-circle-nodes",
++ "Uses the whole network",
++ "Live, Chat, Blog, Wiki, Community, Tools, Media, Host, Bot and more, each through its own API."
++ ],
++ [
++ "fa-window-maximize",
++ "Browses and codes",
++ "A sandboxed browser and code runner for work outside the network."
++ ],
++ [
++ "fa-brain",
++ "Remembers",
++ "Long-term memory you can read, edit and wipe."
++ ],
++ [
++ "fa-hand",
++ "Asks first",
++ "An approval inbox, a full activity log, spending limits and a kill switch."
++ ],
++ [
++ "fa-shuffle",
++ "Any model",
++ "Routed through OpenVibe.AI: hosted, open or local models, or your own key."
++ ]
++ ],
++ "templates": {
++ "title": "Start from a template",
++ "lead": "Each one is a starting point you can change.",
++ "items": [
++ [
++ "fa-tower-broadcast",
++ "Stream co-host"
++ ],
++ [
++ "fa-shield",
++ "Chat moderator"
++ ],
++ [
++ "fa-magnifying-glass",
++ "Research assistant"
++ ],
++ [
++ "fa-globe",
++ "Site builder"
++ ],
++ [
++ "fa-robot",
++ "Robot pilot"
++ ],
++ [
++ "fa-calendar-check",
++ "Personal assistant"
++ ]
++ ]
++ },
++ "connectTitle": "Reachable everywhere",
++ "connectLead": "Your agent is part of the network, not a separate app.",
++ "connect": [
++ [
++ "fa-bars",
++ "On every OpenVibe site",
++ "An agent button in the navbar, with the page you are on as context."
++ ],
++ [
++ "fa-comments",
++ "In chat",
++ "Direct messages on OpenVibe.Chat and @mentions in Live chat and Community threads.",
++ "https://openvibe.chat"
++ ],
++ [
++ "fa-robot",
++ "With your robots",
++ "Give it a robot on OpenVibe.Bot to patrol, check on or perform with, with your approval.",
++ "https://openvibe.bot"
++ ],
++ [
++ "fa-plug",
++ "From your own apps",
++ "An API, webhooks and an MCP server, so other assistants can use OpenVibe tools and talk to your agent.",
++ "https://openvibe.codes"
++ ]
++ ],
++ "building": "OpenVibe.Actor is being built now, on the network's accounts, AI router and event system that already run."
++ },
++ "faq": [
++ [
++ "How is this different from a chat assistant?",
++ "It keeps working when you leave: it has memory, schedules and triggers, and it can act across OpenVibe with the permissions you give it."
++ ],
++ [
++ "Can it do things without asking?",
++ "Only what you allow. You grant each tool, and anything with consequences waits for your approval. Every action is logged, and you can stop an agent at any time."
++ ],
++ [
++ "Which AI models does it use?",
++ "Any model OpenVibe.AI routes to, including open and local models, or your own API key."
++ ],
++ [
++ "Can other apps use my agent?",
++ "Yes: an API, webhooks and an MCP server connect it to other tools and assistants."
++ ],
++ [
++ "What will it cost?",
++ "You will be able to start without paying, within limits published before launch; heavier use and bigger models will be paid."
++ ]
++ ]
},
{
"domain": "openvibe.events",