openvibers/openvibe.network Commits

openvibe-shared v1.29.1 (from its earlier pin): changing the theme repaints the page background, bright accents get dark button text (WCAG), the navbar brand is more compact. Account page: primary buttons use the theme's on-accent colour, the theme switcher applies through the shared loader (canvas and browser UI follow), and every text field follows the theme (input colour, hover tint, accent focus ring, placeholder, invalid state); the theme submission form uses the page's field style with a hint. npm test: deploy wrapper: all checks passed

OP OpenVibers committed 29 Sept 2026 · 60f5ab2b90 · 4 files, +32 −15


Changes

ddiff --git a/package-lock.json b/package-lock.json
iindex dc697db0..34b5f81e 100644
---- a/package-lock.json
++++ b/package-lock.json
@@@ -22,7 +22,7 @@
"multer": "^1.4.5-lts.1",
"openvibe-contracts": "https://codeload.github.com/OpenVibers/OpenVibe.Contracts/tar.gz/refs/tags/v0.76.0",
"openvibe-sdk": "https://codeload.github.com/OpenVibers/OpenVibe.SDK/tar.gz/refs/tags/v0.12.0",
-- "openvibe-shared": "https://codeload.github.com/OpenVibers/OpenVibe.Shared/tar.gz/refs/tags/v1.28.1",
++ "openvibe-shared": "https://codeload.github.com/OpenVibers/OpenVibe.Shared/tar.gz/refs/tags/v1.29.1",
"uuid": "^11.1.0",
"web-push": "^3.6.7"
}
@@@ -1490,9 +1490,9 @@
}
},
"node_modules/openvibe-shared": {
-- "version": "1.28.1",
-- "resolved": "https://codeload.github.com/OpenVibers/OpenVibe.Shared/tar.gz/refs/tags/v1.28.1",
-- "integrity": "sha512-AV39sRi9hm8QETRLM1c6q7nrU8XWPUZzCxZP+h7Cho+LsJ47szHtMk3YdCQHT8+aSC5Hpu68EU8sCvbagR+a0g==",
++ "version": "1.29.1",
++ "resolved": "https://codeload.github.com/OpenVibers/OpenVibe.Shared/tar.gz/refs/tags/v1.29.1",
++ "integrity": "sha512-HI1aySq1Lipd/GRGI0exL98LVQ2UXWeIlYk3TaTgMsjV/S1L5tTyaI+tNKJ8q8zKpMNdXj0hSflENBE97i/CxQ==",
"license": "MIT",
"dependencies": {
"jsonwebtoken": "^9.0.0"
ddiff --git a/package.json b/package.json
iindex 496d2449..fd0e9d72 100644
---- a/package.json
++++ b/package.json
@@@ -25,7 +25,7 @@
"multer": "^1.4.5-lts.1",
"openvibe-contracts": "https://codeload.github.com/OpenVibers/OpenVibe.Contracts/tar.gz/refs/tags/v0.76.0",
"openvibe-sdk": "https://codeload.github.com/OpenVibers/OpenVibe.SDK/tar.gz/refs/tags/v0.12.0",
-- "openvibe-shared": "https://codeload.github.com/OpenVibers/OpenVibe.Shared/tar.gz/refs/tags/v1.28.1",
++ "openvibe-shared": "https://codeload.github.com/OpenVibers/OpenVibe.Shared/tar.gz/refs/tags/v1.29.1",
"uuid": "^11.1.0",
"web-push": "^3.6.7"
}
ddiff --git a/public/admin.html b/public/admin.html
iindex 696b986c..cfcbb0d1 100644
---- a/public/admin.html
++++ b/public/admin.html
@@@ -84,7 +84,7 @@ body{min-height:100%;color:var(--text);font-family:'Inter',-apple-system,BlinkMa
/* Buttons */
.btn{padding:8px 16px;border:none;border-radius:8px;font-size:12px;font-weight:600;cursor:pointer;transition:all .15s;display:inline-flex;align-items:center;gap:6px}
--.btn-primary{background:var(--accent);color:#fff}
++.btn-primary{background:var(--accent);color:var(--on-accent,#fff)}
.btn-primary:hover{background:var(--accent-dark)}
.btn-outline{background:transparent;border:1px solid var(--border);color:var(--text)}
.btn-outline:hover{border-color:var(--accent-dark);color:var(--accent-light)}
ddiff --git a/public/my.html b/public/my.html
iindex 51e3631f..77e82aa4 100644
---- a/public/my.html
++++ b/public/my.html
@@@ -82,18 +82,31 @@ body{min-height:100%;color:var(--text);font-family:'Inter',-apple-system,BlinkMa
/* Form fields */
.form-field{margin-bottom:14px}
.form-field label{display:block;font-size:11px;font-weight:600;color:var(--text-muted);text-transform:uppercase;letter-spacing:.5px;margin-bottom:5px}
--.form-field input,.form-field select,.form-field textarea{
-- width:100%;padding:10px 12px;background:var(--bg-input);border:1px solid var(--border);
-- border-radius:8px;color:var(--text);font-size:13px;outline:none;transition:border-color .2s;
--}
--.form-field input:focus,.form-field select:focus,.form-field textarea:focus{border-color:var(--accent)}
++/* Every text field on the page follows the active theme: its input colour, a hover tint and an accent focus ring. */
++:where(input:not([type]),input[type=text],input[type=url],input[type=email],input[type=search],input[type=password],input[type=number],select,textarea){
++ padding:10px 12px;background:var(--bg-input);border:1px solid var(--border);border-radius:10px;
++ color:var(--text);font:inherit;font-size:13px;outline:none;min-height:40px;
++ transition:border-color .18s ease,box-shadow .18s ease,background-color .18s ease;
++}
++:where(input:not([type]),input[type=text],input[type=url],input[type=email],input[type=search],input[type=password],input[type=number],select,textarea):hover{border-color:color-mix(in srgb,var(--accent) 40%,var(--border))}
++:where(input:not([type]),input[type=text],input[type=url],input[type=email],input[type=search],input[type=password],input[type=number],select,textarea):focus{
++ border-color:var(--accent);box-shadow:0 0 0 3px color-mix(in srgb,var(--accent) 24%,transparent);
++ background:color-mix(in srgb,var(--accent) 5%,var(--bg-input));
++}
++:where(input,textarea)::placeholder{color:var(--text-muted);opacity:1}
++:where(input,select,textarea):user-invalid{border-color:var(--danger,#ef4444)}
++.form-field input,.form-field select,.form-field textarea{width:100%}
.form-field textarea{resize:vertical;min-height:60px}
.form-field .hint{font-size:10px;color:var(--text-muted);margin-top:3px}
++.theme-submit{display:grid;grid-template-columns:repeat(2,minmax(0,1fr)) auto;gap:12px;align-items:start;margin-top:16px}
++.theme-submit .form-field{margin:0}
++.theme-submit .btn{margin-top:21px;min-height:40px}
++@media (max-width:640px){.theme-submit{grid-template-columns:1fr}.theme-submit .btn{margin-top:0}}
.btn{
padding:8px 20px;border:none;border-radius:8px;font-size:12px;font-weight:600;cursor:pointer;transition:all .15s;
}
--.btn-primary{background:var(--accent);color:#fff}
++.btn-primary{background:var(--accent);color:var(--on-accent,#fff)}
.btn-primary:hover{background:var(--accent-dark)}
.btn-outline{background:transparent;border:1px solid var(--border);color:var(--text)}
.btn-outline:hover{border-color:var(--accent-dark);color:var(--accent-light)}
@@@ -384,9 +397,9 @@ a.linked-item:hover{background:var(--bg-hover,var(--bg-card));transform:translat
<button class="btn btn-outline" onclick="exportActiveTheme(this)"><i class="fa-solid fa-file-export"></i> Export active theme</button>
<label class="btn btn-outline" style="cursor:pointer"><i class="fa-solid fa-file-import"></i> Import a theme file<input type="file" accept=".json,application/json" onchange="importThemeFile(this)" style="display:none"></label>
</div>
-- <form onsubmit="submitMyTheme(event)" style="display:flex;gap:10px;flex-wrap:wrap;align-items:flex-end;margin-top:14px">
-- <label style="display:grid;gap:4px;font-size:0.85rem">Name<input id="theme-submit-name" required minlength="2" maxlength="60" style="min-width:180px"></label>
-- <label style="display:grid;gap:4px;font-size:0.85rem">Address (lowercase, hyphens)<input id="theme-submit-slug" required pattern="[a-z0-9-]{2,48}" style="min-width:180px"></label>
++ <form class="theme-submit" onsubmit="submitMyTheme(event)">
++ <div class="form-field"><label for="theme-submit-name">Name</label><input id="theme-submit-name" required minlength="2" maxlength="60" placeholder="Midnight Arcade" autocomplete="off"></div>
++ <div class="form-field"><label for="theme-submit-slug">Address</label><input id="theme-submit-slug" required pattern="[a-z0-9-]{2,48}" placeholder="midnight-arcade" autocomplete="off" spellcheck="false"><div class="hint">Lowercase letters, numbers and hyphens</div></div>
<button class="btn btn-primary" type="submit"><i class="fa-solid fa-paper-plane"></i> Submit my colours</button>
</form>
<div id="theme-submissions" style="margin-top:14px"></div>
@@@ -587,6 +600,7 @@ const LOCAL_THEME_MAP = {
'--text': '--text-primary',
'--text-secondary': '--text-secondary',
'--text-muted': '--text-muted',
++ '--on-accent': '--on-accent',
};
function getStoredAccounts() {
@@@ -908,6 +922,9 @@ function themePreviewColors(theme) {
function applyThemeToPage(theme) {
const vars = theme?.variables || {};
++ // The shared loader applies every token (the canvas behind the page, --on-accent, the browser UI);
++ // this page's own short names follow below.
++ if (typeof OpenVibeThemeLoader !== 'undefined' && OpenVibeThemeLoader.applyVars) OpenVibeThemeLoader.applyVars(vars);
Object.entries(LOCAL_THEME_MAP).forEach(([localVar, themeVar]) => {
const value = vars[themeVar];
if (value) document.documentElement.style.setProperty(localVar, value);