openvibers/openvibe.network Commits
Front door: the five things people do now as a ranked list; Try next rows as doors (#834)
Changes
@@@ -332,12 +332,15 @@ p.rc-quiet { margin: 0; color: var(--text-muted); }.td-box { display: grid; align-content: start; gap: 12px; padding: 16px; min-width: 0; }.td-sites { display: grid; grid-template-columns: repeat(4, minmax(0, 1fr)); gap: 8px; }.td-site { display: grid; justify-items: center; gap: 6px; padding: 10px 4px; border-radius: 12px; border: 1px solid transparent; color: var(--text); text-decoration: none; font-size: 12px; font-weight: 650; min-width: 0; }--.td-site span:last-child { max-width: 100%; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }++.td-site span:last-child { max-width: 100%; overflow-wrap: anywhere; text-align: center; line-height: 1.25; }.td-site .td-site-ic { width: 40px; height: 40px; border-radius: 12px; font-size: 16px; }.td-tries { display: grid; gap: 8px; }.td-tries::before { content: "Try next"; font-size: 11.5px; font-weight: 700; letter-spacing: .06em; text-transform: uppercase; color: var(--text-muted); }--.td-try { display: flex; align-items: center; gap: 10px; padding: 10px; border-radius: 12px; border: 1px solid var(--border); color: var(--text); text-decoration: none; }--.td-try-t { display: grid; gap: 1px; min-width: 0; }++.td-try { display: flex; align-items: center; gap: 12px; min-height: 56px; padding: 8px 14px 8px 8px; border-radius: 12px; border: 1px solid var(--border); background: color-mix(in srgb, var(--accent) 4%, transparent); color: var(--text); text-decoration: none; }++/* Try next (Opus, 2026-11-11): a row you can tell is a door, the chevron at its end. */++.td-try::after { content: ""; flex: none; width: 7px; height: 7px; margin-left: auto; border-top: 2px solid var(--text-muted); border-right: 2px solid var(--text-muted); transform: rotate(45deg); }++.td-try:hover::after { border-color: var(--accent); }++.td-try-t { display: grid; gap: 1px; min-width: 0; flex: 1; }.td-try-t b { font-size: 13.5px; }.td-try-t small { font-size: 12px; color: var(--text-muted); }.td-bal { display: flex; align-items: baseline; gap: 8px; }@@@ -208,9 +208,26 @@ function moreParts(parts) {return `<div class="more"><h2 class="more-pick-h">${sectionIcon('grid')}More about OpenVibe</h2><nav class="more-pick" data-ovk-scroll aria-label="More about OpenVibe">${chips}</nav>\n${shown.map(([, , html]) => html.replace(/^<section class="([^"]*)" id="([^"]*)"/, '<section class="$1" id="$2" data-more-part')).join('\n')}</div>`;}--// The five things people do now (plan L43): a plain list, no new styles. The order and the numbers are Report's;--// when Report does not answer the fixed starter list is used and the section says so in data-source. Opus places and--// styles the block; this only renders it.++// The five things people do now (plan L43; designed by Opus 2026-11-11): a ranked list, each row its place, the site's++// mark, the reason Report gives and the number behind it (growth when it is rising, else the week's opens; a number++// Report did not send is left out). The order and the numbers are Report's; when Report does not answer the fixed++// starter list is used and the section says so in data-source. A phone reads it as rows, a computer as five cards.++const POP_ICON = { 'media-hub': 'fa-play', video: 'fa-play', tours: 'fa-route', community: 'fa-users', news: 'fa-newspaper',++ design: 'fa-palette', report: 'fa-chart-column', network: 'fa-circle-nodes', music: 'fa-music', trade: 'fa-chart-line',++ coupons: 'fa-ticket', deals: 'fa-tags', download: 'fa-folder', cam: 'fa-camera', openre: 'fa-share-nodes', host: 'fa-server',++ reviews: 'fa-star', media: 'fa-photo-film', exchange: 'fa-arrow-right-arrow-left', compare: 'fa-scale-balanced' };++const popIcon = (it) => POP_ICON[it.id] || POP_ICON[it.icon] || (INTENTS.find((x) => x[0] === it.id || x[0] === it.icon) || [])[1] || 'fa-circle-nodes';++/** The number behind a row: "+44%" or "35×" this week when it is rising, else the week's opens; '' when Report sent none. */++function popFigure(it) {++ const g = Number(it.growth_7d_pct);++ if (/rising/i.test(it.reason) && Number.isFinite(g) && g > 0) {++ const big = g >= 200 && Number(it.opens_prev_7d) > 0;++ const v = big ? `${Math.round(Number(it.opens_7d) / Number(it.opens_prev_7d))}×` : `+${g}%`;++ return `<span class="pop-n is-up" title="${esc(big ? `${v} last week's opens` : `${v} on last week`)}"><i class="fa-solid fa-arrow-trend-up" aria-hidden="true"></i>${esc(v)}</span>`;++ }++ const n = Number(it.opens_7d);++ return Number.isFinite(n) && n > 0 ? `<span class="pop-n" title="${esc(`${n.toLocaleString('en-US')} opens this week`)}">${esc(fmtVisits(n))}<small>this week</small></span>` : '';++}function popularNow() {const p = homePopular.peek();const items = Array.isArray(p.items) ? p.items.slice(0, 5) : [];@@@ -218,7 +235,10 @@ function popularNow() {const lede = p.source === 'report'? "Ranked from OpenVibe.Report's numbers: what people opened today and this week.": 'A fixed starter list while OpenVibe.Report is away.';-- return `<section class="sc-sec" id="popular" data-source="${esc(p.source)}" aria-labelledby="h-popular"><h2 id="h-popular" class="ovk-titled">${sectionIcon('grid')}Five things people do now</h2><p class="sc-lede">${esc(lede)}</p><ul class="now-list">${items.map((it) => `<li><a href="${esc(it.url)}"><b>${esc(it.name)}</b><small>${esc(it.reason)}</small></a></li>`).join('')}</ul></section>`;++ const row = (it, i) => `<li><a class="pop-row" href="${esc(it.url)}"><span class="pop-rank" aria-hidden="true">${i + 1}</span>`++ + `<span class="pop-ic" aria-hidden="true"><i class="fa-solid ${esc(popIcon(it))}"></i></span>`++ + `<span class="pop-t"><b>${esc(it.name)}</b><small>${esc(it.reason)}</small></span>${popFigure(it)}</a></li>`;++ return `<section class="sc-sec pop" id="popular" data-source="${esc(p.source)}" aria-labelledby="h-popular"><h2 id="h-popular" class="ovk-titled">${sectionIcon('grid')}Five things people do now</h2><p class="sc-lede">${esc(lede)}</p><ol class="pop-list">${items.map(row).join('')}</ol></section>`;}// The hero's numbers: only what Network read itself within the last minute (server/home/activity.js); a number it@@@ -347,6 +367,31 @@ const CSS = `}.now-code{display:inline-block;margin:0 0 3px;padding:1px 7px;border-radius:6px;border:1px dashed var(--accent,#3b82f6);color:var(--accent-light,#60a5fa);font:700 12.5px/1.5 ui-monospace,SFMono-Regular,Menlo,Consolas,monospace;letter-spacing:.3px}.now-list b{overflow-wrap:anywhere}++.pop-list{list-style:none;margin:14px 0 0;padding:0;display:grid;gap:8px;counter-reset:none}++.pop-row{display:grid;grid-template-columns:auto auto minmax(0,1fr) auto;align-items:center;gap:12px;min-height:60px;padding:10px 14px 10px 10px;border-radius:14px;border:1px solid var(--border,rgba(255,255,255,.08));background:color-mix(in srgb,var(--bg-secondary,#101828) 80%,transparent);color:inherit;text-decoration:none;transition:border-color .15s ease,transform .15s ease}++.pop-row:hover,.pop-row:focus-visible{border-color:var(--accent,#3b82f6)}++.pop-row:focus-visible{outline:2px solid var(--accent,#3b82f6);outline-offset:2px}++.pop-rank{display:grid;place-items:center;width:24px;font-size:13px;font-weight:800;color:var(--text-muted,#7d8aa0);font-variant-numeric:tabular-nums}++.pop-list li:first-child .pop-rank{color:var(--accent-light,#60a5fa)}++.pop-ic{display:grid;place-items:center;width:40px;height:40px;border-radius:12px;background:color-mix(in srgb,var(--accent,#3b82f6) 14%,transparent);color:var(--accent-light,#60a5fa);font-size:16px}++.pop-t{display:grid;gap:2px;min-width:0}++.pop-t b{font-size:14.5px;line-height:1.3;overflow-wrap:anywhere}++.pop-t small{font-size:12.5px;line-height:1.35;color:var(--text-secondary,#a8b3c4)}++.pop-n{display:grid;justify-items:end;gap:0;font-size:14px;font-weight:750;font-variant-numeric:tabular-nums;color:var(--text-primary,#e6edf7);white-space:nowrap}++.pop-n small{font-size:11px;font-weight:500;color:var(--text-muted,#7d8aa0)}++.pop-n.is-up{display:inline-flex;align-items:center;gap:5px;color:var(--success,#22c55e)}++.pop-n.is-up i{font-size:12px}++@media (min-width:861px){++.pop-list{grid-template-columns:repeat(5,minmax(0,1fr));gap:12px}++.pop-row{grid-template-columns:auto minmax(0,1fr);grid-template-rows:auto auto 1fr;align-items:start;gap:10px 10px;min-height:0;height:100%;padding:14px;position:relative}++.pop-row:hover{transform:translateY(-2px)}++.pop-rank{position:absolute;top:12px;right:12px;width:auto}++.pop-ic{grid-column:1;grid-row:1}++.pop-t{grid-column:1/-1;grid-row:2}++.pop-n{grid-column:1/-1;grid-row:3;justify-items:start;align-self:end}++.pop-n.is-up{justify-content:flex-start}++}++@media (prefers-reduced-motion:reduce){.pop-row{transition:none}.pop-row:hover{transform:none}}.net-num{margin-top:18px;padding:16px 18px;border-radius:16px;border:1px solid var(--border,rgba(255,255,255,.08));background:color-mix(in srgb,var(--bg-secondary,#101828) 85%,transparent)}.net-num h2{font-size:12px;font-weight:800;letter-spacing:.7px;text-transform:uppercase;color:var(--text-muted,#7d8aa0);margin:0 0 10px}.net-num ul{list-style:none;margin:0;padding:0;display:grid;gap:8px;grid-template-columns:repeat(auto-fill,minmax(min(140px,100%),1fr))}@@@ -92,8 +92,10 @@ for (const [id, , verb, , href] of home.INTENTS) {}assert.ok(/Go live<\/b><small>From a browser tab\. No OBS, no follower minimum\./.test(html), 'browser go-live stays the headline promise');// The five most popular list (plan L43) is a plain list; with no Report wired in this process it says it is the floor.--assert.ok(/<section class="sc-sec" id="popular" data-source="fallback"/.test(html), 'the signed-out popularity list is on the page and names its source');--assert.ok(html.includes('Five things people do now') && /<ul class="now-list">/.test(html), 'the list is plain, with the existing classes');++assert.ok(/<section class="sc-sec pop" id="popular" data-source="fallback"/.test(html), 'the signed-out popularity list is on the page and names its source');++assert.ok(html.includes('Five things people do now') && /<ol class="pop-list">/.test(html), 'the five are a ranked list');++assert.ok(/<a class="pop-row" href="https:\/\/openvibe\.live\/"><span class="pop-rank" aria-hidden="true">1<\/span><span class="pop-ic" aria-hidden="true"><i class="fa-solid fa-tower-broadcast"><\/i><\/span>/.test(html), 'each row: its place, the site\'s mark');++assert.ok(!/class="pop-n/.test(html.slice(html.indexOf('id="popular"'), html.indexOf('</ol>', html.indexOf('id="popular"')))), 'the fallback list has no numbers, so it shows none');assert.ok(/Nobody is live right now/.test(html) && /Go live from your browser/.test(html), 'an honest empty state');const open = sites.filter((s) => s.status === 'open' && s.id !== 'network');// The hero's orbit (2026-10-28): the most used sites around the mark, the count of every site in its middle.@@@ -12,7 +12,7 @@ const { spawn } = require('child_process');const { measure, check, format } = require('openvibe-shared/perf-budget');const BUDGETS = {-- htmlRawKB: 209.5, // 209.5: measured 209 KB with openvibe-shared 4.190.0 (2026-11-10: the site name's dropdown, the footer's online strip, the balances pill); 206: measured 205.8 KB with openvibe-shared 4.185.0 (the navbar's links in the first HTML since 4.184.0), 2026-11-10; 205.4: measured 205.4 KB with the front door's five most popular destinations (plan L43, 2026-11-09: Report's ranked list adds about 1.2 KB of plain list markup); 204.2: measured 204.2 KB with openvibe-contracts 0.373.0 (the Git service in the network list) on openvibe-shared 4.173.0, 2026-11-09; 204: measured 203.5 KB with the shared page head's kit CSS on the home (openvibe-shared 4.163.0 + page head 1369721), 2026-11-09; 198.8 with openvibe-contracts 0.348.0 (2026-11-08: Studio joins the menu; Studio and Locker get menu lines); 197.4 with Email open (contracts 0.330.0, 2026-11-07: the mail site in the network list); 196 with the Node's own item in the navbar (openvibe-shared 4.117.0, 2026-11-06: the Node link and the llms.txt section); 194.9 with the Organization naming every open site in sameAs (SEO-27, 2026-11-03); 192.4 with Tours and Shoes open (contracts 0.265.0, 2026-10-31); 189.9 with Casino open (contracts 0.264.0, 2026-10-31); 189 with the look-boot script inline above the stylesheets on every page (L42, 2026-10-31: +1 KB); 188 with the agent layer's rel=alternate/describedby link tags on every public page (SEO-1/SEO-2, 2026-10-29: +0.2 KB); 187 with Bench open (contracts 0.238.0, 2026-10-28); 186 with Cam open (contracts 0.237.0, 2026-10-28); 184.4 with Fun open (contracts 0.236.0, 2026-10-28); 182.7 with Vision and Exchange open (contracts 0.235.0, 2026-10-28); 179 with Meme open (contracts 0.234.0, 2026-10-28); 174.1 with Domains, Report and Design open (contracts 0.226-0.228, 2026-10-28); 168.1 the hero's orbit and rich cards for live streams, recordings and screenshots (2026-10-28: the owner asked for animated visuals and YouTube-style cards); 152.4 openvibe-shared 4.15 footer: the compact footer opens into the whole one, and the pulse line; 147.9 with the home's FAQ (six questions and their FAQPage JSON-LD), the numbers panel and the service map's group headings (2026-10-22); 141.2 with Tips and VIP open (contracts 0.200.0, 37 sites; the Opening next section is gone); 134 with Play (contracts 0.172.1); 128.3 with Events, AI and Search added (31 sites, contracts 0.135.0); 122.3 (shared 2.21.0: a real glyph for every product card, where ten drew the 'V'); was 110.6 with 33 live sites (contracts 0.119.0). The home page lists every site, so it grows with the network++ htmlRawKB: 210.5, // 210.5: measured 209.9 KB with the popular block designed (2026-11-11: ranks, marks, numbers and its CSS, +0.9 KB); 209.5: measured 209 KB with openvibe-shared 4.190.0 (2026-11-10: the site name's dropdown, the footer's online strip, the balances pill); 206: measured 205.8 KB with openvibe-shared 4.185.0 (the navbar's links in the first HTML since 4.184.0), 2026-11-10; 205.4: measured 205.4 KB with the front door's five most popular destinations (plan L43, 2026-11-09: Report's ranked list adds about 1.2 KB of plain list markup); 204.2: measured 204.2 KB with openvibe-contracts 0.373.0 (the Git service in the network list) on openvibe-shared 4.173.0, 2026-11-09; 204: measured 203.5 KB with the shared page head's kit CSS on the home (openvibe-shared 4.163.0 + page head 1369721), 2026-11-09; 198.8 with openvibe-contracts 0.348.0 (2026-11-08: Studio joins the menu; Studio and Locker get menu lines); 197.4 with Email open (contracts 0.330.0, 2026-11-07: the mail site in the network list); 196 with the Node's own item in the navbar (openvibe-shared 4.117.0, 2026-11-06: the Node link and the llms.txt section); 194.9 with the Organization naming every open site in sameAs (SEO-27, 2026-11-03); 192.4 with Tours and Shoes open (contracts 0.265.0, 2026-10-31); 189.9 with Casino open (contracts 0.264.0, 2026-10-31); 189 with the look-boot script inline above the stylesheets on every page (L42, 2026-10-31: +1 KB); 188 with the agent layer's rel=alternate/describedby link tags on every public page (SEO-1/SEO-2, 2026-10-29: +0.2 KB); 187 with Bench open (contracts 0.238.0, 2026-10-28); 186 with Cam open (contracts 0.237.0, 2026-10-28); 184.4 with Fun open (contracts 0.236.0, 2026-10-28); 182.7 with Vision and Exchange open (contracts 0.235.0, 2026-10-28); 179 with Meme open (contracts 0.234.0, 2026-10-28); 174.1 with Domains, Report and Design open (contracts 0.226-0.228, 2026-10-28); 168.1 the hero's orbit and rich cards for live streams, recordings and screenshots (2026-10-28: the owner asked for animated visuals and YouTube-style cards); 152.4 openvibe-shared 4.15 footer: the compact footer opens into the whole one, and the pulse line; 147.9 with the home's FAQ (six questions and their FAQPage JSON-LD), the numbers panel and the service map's group headings (2026-10-22); 141.2 with Tips and VIP open (contracts 0.200.0, 37 sites; the Opening next section is gone); 134 with Play (contracts 0.172.1); 128.3 with Events, AI and Search added (31 sites, contracts 0.135.0); 122.3 (shared 2.21.0: a real glyph for every product card, where ten drew the 'V'); was 110.6 with 33 live sites (contracts 0.119.0). The home page lists every site, so it grows with the networkhtmlBrotliKB: 39.5, // 39.5: measured 39.3 KB brotli with openvibe-shared 4.190.0 (2026-11-10: the site name's dropdown, the footer's online strip, the balances pill); 39: measured 38.6 KB brotli with the shared page head's kit CSS on the home (openvibe-shared 4.163.0 + page head 1369721), 2026-11-09; 38.1 with openvibe-contracts 0.348.0 (2026-11-08: Studio joins the menu; Studio and Locker get menu lines); 37.9 with openvibe-shared 4.129.0 (2026-11-07: the one menu (the burger opens the OpenVibe menu)); 37.8 with openvibe-shared 4.129.0 (2026-11-07: the one menu (the burger opens the OpenVibe menu)); 36.1 with the Node's own item in the navbar (openvibe-shared 4.117.0, 2026-11-06); 35.5 with Tours and Shoes open (2026-10-31); 35.1 with the look-boot script inline above the stylesheets on every page (L42, 2026-10-31: +0.6 KB); 34.2 with the lower half as one block of chips on phones (2026-10-30); 33.1 with Games granted its Bench match capabilities (BENCH-7, 2026-10-29: the home lists what each service may do); 32.0 with Fun, Vision and Exchange open (contracts 0.236.0, 2026-10-28); 31.2 with Domains, Report and Design open (2026-10-28); 30.1 with the Organization saying who OpenVibe is (description, other names, what it is not, 15 sites; 2026-10-28); 28.5 with the FAQ, numbers and groups (2026-10-22); 26.1 with Play; 25.1 (31 sites, contracts 0.135.0); 24.1 (shared 2.21.0, the same glyphs); 20.5 (contracts 0.116.0)jsFiles: 8, // 7 with boost.js, was 6 (2026-10-13, plan T11 step 3: one more script on every boosted page; it loads route-transition.js on the first move only)jsRawKB: 448.5, // 448.5 openvibe-shared v4.205.0 (2026-11-11: measured 448.4, raised by pin-bump from 445); 445 openvibe-shared v4.202.0 (2026-11-11: measured 444.6, raised by pin-bump from 444); 444 openvibe-shared v4.201.0 (2026-11-11: measured 443.7, raised by pin-bump from 440.5); 440.5 openvibe-shared v4.200.0 (2026-11-10: measured 440.2, raised by pin-bump from 440.0); 440.0: measured 439.6 KB raw / 106.7 KB brotli with openvibe-shared 4.197.0 (2026-11-10: the menu's row of places, the You tab's row, the Sign in mark, the tooltip); 438.5: measured 438 KB raw / 106.5 KB brotli with openvibe-shared 4.190.0 (2026-11-10: the site name's dropdown, the footer's online strip, the balances pill); 421: measured 420.9 KB raw / 102.2 KB brotli with openvibe-shared 4.186.0 (the mark's Working and Thinking states, the Dock and the menu as one sheet, bare controls), 2026-11-10; 420.5: measured 419.9 KB raw / 101.9 KB brotli with openvibe-shared 4.185.0 (Calm reduces, the solids and site marks, the You tab, the Dock out of the orb), 2026-11-10; 417: measured 416.4 KB raw / 100.9 KB brotli with openvibe-shared 4.179.0, 2026-11-09; 410: measured 409.2 KB raw / 99.4 KB brotli with openvibe-shared 4.173.0 (the wallet's cookie mode), 2026-11-09; 409: measured 408.1 KB raw / 99.0 KB brotli after merging main's Frame feed work (openvibe-shared 4.167.0), 2026-11-09; 406: measured 405.7 KB raw / 98.4 KB brotli with the shared page head's kit script on the home (openvibe-shared 4.163.0 + page head 1369721), 2026-11-09; 381.8: measured 375.8 KB raw / 91.1 KB brotli with openvibe-shared 4.159.0, plus room for 4.160.0–4.161.0 (the navbar's slots loader, the keyboard watcher, the pop motion), 2026-11-09; 373 with openvibe-shared 4.153.0 (2026-11-08: signed in to the network, signed in here, on phones too; a page can turn away a carried card); 372.3 with openvibe-shared 4.152.0 (2026-11-08: the menu marks the page you are on and opens without the keyboard on a phone, floating cards follow you across OpenVibe sites (overlay.js), and the navbar preconnects to the next OpenVibe site on intent); 369.6 with openvibe-shared 4.150.0 (2026-11-08: the bell opens the Dock on Activity, the Dock's phone header is in two rows, and the menu's orb is the close button with an open/close animation); 368.6 with openvibe-shared 4.149.0 (2026-11-08: the menu has tabs at the top; the phone's menu button is the orb of 4.148.0); 366.5 with openvibe-shared 4.118.0 (2026-11-06: the Locker re-auth link, the 44 px footer and TLD targets; main's 4.117.0 navbar item and the account-safety helper included); about 363.8 with both (2026-11-06: openvibe-shared 4.117.0's featured navbar item, +1.7 KB, and the account-safety helper, +8.5 KB; merged, to be confirmed by CI's measure); 353.6 with the account-safety helper on every page (2026-11-06: the one re-authentication path and the scheduled-deletion banner, +8.5 KB); 345.1 with openvibe-shared 4.114.0 (2026-11-06: the one Share sheet in the navbar (ov-share.js and ov-qr.js load on the first press); navbar.js gains its click handler); 343.9 with openvibe-shared 4.112.1 (2026-11-06: theme-loader.js (4.111.1) and the footer/appbar phone CSS (4.112.1)); 342.3 with openvibe-shared 4.109.2 (2026-11-03: OpenVibe's own select, the navbar loads ov-forms); 339.6 with openvibe-shared 4.107.0 (2026-11-03: open.<tld> sites are named for their domain; the brand knows its front door); 337.8 with openvibe-shared 4.103.0 (2026-11-02: the puzzle glyph, two-line sidebar rows, boost lets parsed pages go, eight solids) (2026-11-02); 334.1 openvibe-shared 4.70.0 (2026-11-01: the app bar, busy(), skeletons, view transitions); 333.2 with openvibe-shared 4.53.0: the footer's columns fold on phones (2026-10-30); 330.1 with openvibe-shared 4.52.0 (from 4.47.2): the seasonal fall, rich embeds, the Dock and its Chats tab (2026-10-30); 323.2 with openvibe-shared 4.47.2 (the comfort settings in theme-loader 4.45, touch targets 4.46, the grouped updates log 4.47.2); 313.7 with openvibe-shared 4.43.0 (room.css carries the kit tokens, 4.39.1; the kit's 4.39.0 rules); 306.4 openvibe-shared 4.25.0: the menu's orb beside the brand, both balances on phones, messages, the account sheet on phones and the bar stepping away on phones; 298.9 openvibe-shared 4.22.0: the navbar's magnifier search button and More dropdown (search.js and loading.js load only when used); 293.1 Shared 4.17.0: OpenCoins and Vibes chips (wallet: true) in the navbar; 279.1 openvibe-shared 4.15 footer: the compact footer opens into the whole one, and the pulse line; 269.3 with shared 4.11.0's seasonal navbar (Pumpkin Night and the season badge, +2.6); 249.8 with boost.js (13.1); 228.3
@@ -332,12 +332,15 @@ p.rc-quiet { margin: 0; color: var(--text-muted); }
@@ -332,12 +332,15 @@ p.rc-quiet { margin: 0; color: var(--text-muted); }
.td-box { display: grid; align-content: start; gap: 12px; padding: 16px; min-width: 0; }
.td-box { display: grid; align-content: start; gap: 12px; padding: 16px; min-width: 0; }
.td-sites { display: grid; grid-template-columns: repeat(4, minmax(0, 1fr)); gap: 8px; }
.td-sites { display: grid; grid-template-columns: repeat(4, minmax(0, 1fr)); gap: 8px; }
.td-site { display: grid; justify-items: center; gap: 6px; padding: 10px 4px; border-radius: 12px; border: 1px solid transparent; color: var(--text); text-decoration: none; font-size: 12px; font-weight: 650; min-width: 0; }
.td-site { display: grid; justify-items: center; gap: 6px; padding: 10px 4px; border-radius: 12px; border: 1px solid transparent; color: var(--text); text-decoration: none; font-size: 12px; font-weight: 650; min-width: 0; }
-.td-site span:last-child { max-width: 100%; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
+.td-site span:last-child { max-width: 100%; overflow-wrap: anywhere; text-align: center; line-height: 1.25; }
.td-site .td-site-ic { width: 40px; height: 40px; border-radius: 12px; font-size: 16px; }
.td-site .td-site-ic { width: 40px; height: 40px; border-radius: 12px; font-size: 16px; }
.td-tries { display: grid; gap: 8px; }
.td-tries { display: grid; gap: 8px; }
.td-tries::before { content: "Try next"; font-size: 11.5px; font-weight: 700; letter-spacing: .06em; text-transform: uppercase; color: var(--text-muted); }
.td-tries::before { content: "Try next"; font-size: 11.5px; font-weight: 700; letter-spacing: .06em; text-transform: uppercase; color: var(--text-muted); }
-.td-try { display: flex; align-items: center; gap: 10px; padding: 10px; border-radius: 12px; border: 1px solid var(--border); color: var(--text); text-decoration: none; }
-.td-try-t { display: grid; gap: 1px; min-width: 0; }
+.td-try { display: flex; align-items: center; gap: 12px; min-height: 56px; padding: 8px 14px 8px 8px; border-radius: 12px; border: 1px solid var(--border); background: color-mix(in srgb, var(--accent) 4%, transparent); color: var(--text); text-decoration: none; }
+/* Try next (Opus, 2026-11-11): a row you can tell is a door, the chevron at its end. */
+.td-try::after { content: ""; flex: none; width: 7px; height: 7px; margin-left: auto; border-top: 2px solid var(--text-muted); border-right: 2px solid var(--text-muted); transform: rotate(45deg); }
+.td-try:hover::after { border-color: var(--accent); }
+.td-try-t { display: grid; gap: 1px; min-width: 0; flex: 1; }
.td-try-t b { font-size: 13.5px; }
.td-try-t b { font-size: 13.5px; }
.td-try-t small { font-size: 12px; color: var(--text-muted); }
.td-try-t small { font-size: 12px; color: var(--text-muted); }
.td-bal { display: flex; align-items: baseline; gap: 8px; }
.td-bal { display: flex; align-items: baseline; gap: 8px; }
@@ -208,9 +208,26 @@ function moreParts(parts) {
@@ -208,9 +208,26 @@ function moreParts(parts) {
return `<div class="more"><h2 class="more-pick-h">${sectionIcon('grid')}More about OpenVibe</h2><nav class="more-pick" data-ovk-scroll aria-label="More about OpenVibe">${chips}</nav>\n${shown.map(([, , html]) => html.replace(/^<section class="([^"]*)" id="([^"]*)"/, '<section class="$1" id="$2" data-more-part')).join('\n')}</div>`;
return `<div class="more"><h2 class="more-pick-h">${sectionIcon('grid')}More about OpenVibe</h2><nav class="more-pick" data-ovk-scroll aria-label="More about OpenVibe">${chips}</nav>\n${shown.map(([, , html]) => html.replace(/^<section class="([^"]*)" id="([^"]*)"/, '<section class="$1" id="$2" data-more-part')).join('\n')}</div>`;
}
}
-// The five things people do now (plan L43): a plain list, no new styles. The order and the numbers are Report's;
-// when Report does not answer the fixed starter list is used and the section says so in data-source. Opus places and
-// styles the block; this only renders it.
+// The five things people do now (plan L43; designed by Opus 2026-11-11): a ranked list, each row its place, the site's
+// mark, the reason Report gives and the number behind it (growth when it is rising, else the week's opens; a number
+// Report did not send is left out). The order and the numbers are Report's; when Report does not answer the fixed
+// starter list is used and the section says so in data-source. A phone reads it as rows, a computer as five cards.
+const POP_ICON = { 'media-hub': 'fa-play', video: 'fa-play', tours: 'fa-route', community: 'fa-users', news: 'fa-newspaper',
+ design: 'fa-palette', report: 'fa-chart-column', network: 'fa-circle-nodes', music: 'fa-music', trade: 'fa-chart-line',
+ coupons: 'fa-ticket', deals: 'fa-tags', download: 'fa-folder', cam: 'fa-camera', openre: 'fa-share-nodes', host: 'fa-server',
+ reviews: 'fa-star', media: 'fa-photo-film', exchange: 'fa-arrow-right-arrow-left', compare: 'fa-scale-balanced' };
+const popIcon = (it) => POP_ICON[it.id] || POP_ICON[it.icon] || (INTENTS.find((x) => x[0] === it.id || x[0] === it.icon) || [])[1] || 'fa-circle-nodes';
+/** The number behind a row: "+44%" or "35×" this week when it is rising, else the week's opens; '' when Report sent none. */
+function popFigure(it) {
+ const g = Number(it.growth_7d_pct);
+ if (/rising/i.test(it.reason) && Number.isFinite(g) && g > 0) {
+ const big = g >= 200 && Number(it.opens_prev_7d) > 0;
+ const v = big ? `${Math.round(Number(it.opens_7d) / Number(it.opens_prev_7d))}×` : `+${g}%`;
+ return `<span class="pop-n is-up" title="${esc(big ? `${v} last week's opens` : `${v} on last week`)}"><i class="fa-solid fa-arrow-trend-up" aria-hidden="true"></i>${esc(v)}</span>`;
+ }
+ const n = Number(it.opens_7d);
+ return Number.isFinite(n) && n > 0 ? `<span class="pop-n" title="${esc(`${n.toLocaleString('en-US')} opens this week`)}">${esc(fmtVisits(n))}<small>this week</small></span>` : '';
+}
function popularNow() {
function popularNow() {
const p = homePopular.peek();
const p = homePopular.peek();
const items = Array.isArray(p.items) ? p.items.slice(0, 5) : [];
const items = Array.isArray(p.items) ? p.items.slice(0, 5) : [];
@@ -218,7 +235,10 @@ function popularNow() {
@@ -218,7 +235,10 @@ function popularNow() {
const lede = p.source === 'report'
const lede = p.source === 'report'
? "Ranked from OpenVibe.Report's numbers: what people opened today and this week."
? "Ranked from OpenVibe.Report's numbers: what people opened today and this week."
: 'A fixed starter list while OpenVibe.Report is away.';
: 'A fixed starter list while OpenVibe.Report is away.';
- return `<section class="sc-sec" id="popular" data-source="${esc(p.source)}" aria-labelledby="h-popular"><h2 id="h-popular" class="ovk-titled">${sectionIcon('grid')}Five things people do now</h2><p class="sc-lede">${esc(lede)}</p><ul class="now-list">${items.map((it) => `<li><a href="${esc(it.url)}"><b>${esc(it.name)}</b><small>${esc(it.reason)}</small></a></li>`).join('')}</ul></section>`;
+ const row = (it, i) => `<li><a class="pop-row" href="${esc(it.url)}"><span class="pop-rank" aria-hidden="true">${i + 1}</span>`
+ + `<span class="pop-ic" aria-hidden="true"><i class="fa-solid ${esc(popIcon(it))}"></i></span>`
+ + `<span class="pop-t"><b>${esc(it.name)}</b><small>${esc(it.reason)}</small></span>${popFigure(it)}</a></li>`;
+ return `<section class="sc-sec pop" id="popular" data-source="${esc(p.source)}" aria-labelledby="h-popular"><h2 id="h-popular" class="ovk-titled">${sectionIcon('grid')}Five things people do now</h2><p class="sc-lede">${esc(lede)}</p><ol class="pop-list">${items.map(row).join('')}</ol></section>`;
}
}
// The hero's numbers: only what Network read itself within the last minute (server/home/activity.js); a number it
// The hero's numbers: only what Network read itself within the last minute (server/home/activity.js); a number it
@@ -347,6 +367,31 @@ const CSS = `
@@ -347,6 +367,31 @@ const CSS = `
}
}
.now-code{display:inline-block;margin:0 0 3px;padding:1px 7px;border-radius:6px;border:1px dashed var(--accent,#3b82f6);color:var(--accent-light,#60a5fa);font:700 12.5px/1.5 ui-monospace,SFMono-Regular,Menlo,Consolas,monospace;letter-spacing:.3px}
.now-code{display:inline-block;margin:0 0 3px;padding:1px 7px;border-radius:6px;border:1px dashed var(--accent,#3b82f6);color:var(--accent-light,#60a5fa);font:700 12.5px/1.5 ui-monospace,SFMono-Regular,Menlo,Consolas,monospace;letter-spacing:.3px}
.now-list b{overflow-wrap:anywhere}
.now-list b{overflow-wrap:anywhere}
+.pop-list{list-style:none;margin:14px 0 0;padding:0;display:grid;gap:8px;counter-reset:none}
+.pop-row{display:grid;grid-template-columns:auto auto minmax(0,1fr) auto;align-items:center;gap:12px;min-height:60px;padding:10px 14px 10px 10px;border-radius:14px;border:1px solid var(--border,rgba(255,255,255,.08));background:color-mix(in srgb,var(--bg-secondary,#101828) 80%,transparent);color:inherit;text-decoration:none;transition:border-color .15s ease,transform .15s ease}
+.pop-row:hover,.pop-row:focus-visible{border-color:var(--accent,#3b82f6)}
+.pop-row:focus-visible{outline:2px solid var(--accent,#3b82f6);outline-offset:2px}
+.pop-rank{display:grid;place-items:center;width:24px;font-size:13px;font-weight:800;color:var(--text-muted,#7d8aa0);font-variant-numeric:tabular-nums}
+.pop-list li:first-child .pop-rank{color:var(--accent-light,#60a5fa)}
+.pop-ic{display:grid;place-items:center;width:40px;height:40px;border-radius:12px;background:color-mix(in srgb,var(--accent,#3b82f6) 14%,transparent);color:var(--accent-light,#60a5fa);font-size:16px}
+.pop-t{display:grid;gap:2px;min-width:0}
+.pop-t b{font-size:14.5px;line-height:1.3;overflow-wrap:anywhere}
+.pop-t small{font-size:12.5px;line-height:1.35;color:var(--text-secondary,#a8b3c4)}
+.pop-n{display:grid;justify-items:end;gap:0;font-size:14px;font-weight:750;font-variant-numeric:tabular-nums;color:var(--text-primary,#e6edf7);white-space:nowrap}
+.pop-n small{font-size:11px;font-weight:500;color:var(--text-muted,#7d8aa0)}
+.pop-n.is-up{display:inline-flex;align-items:center;gap:5px;color:var(--success,#22c55e)}
+.pop-n.is-up i{font-size:12px}
+@media (min-width:861px){
+.pop-list{grid-template-columns:repeat(5,minmax(0,1fr));gap:12px}
+.pop-row{grid-template-columns:auto minmax(0,1fr);grid-template-rows:auto auto 1fr;align-items:start;gap:10px 10px;min-height:0;height:100%;padding:14px;position:relative}
+.pop-row:hover{transform:translateY(-2px)}
+.pop-rank{position:absolute;top:12px;right:12px;width:auto}
+.pop-ic{grid-column:1;grid-row:1}
+.pop-t{grid-column:1/-1;grid-row:2}
+.pop-n{grid-column:1/-1;grid-row:3;justify-items:start;align-self:end}
+.pop-n.is-up{justify-content:flex-start}
+}
+@media (prefers-reduced-motion:reduce){.pop-row{transition:none}.pop-row:hover{transform:none}}
.net-num{margin-top:18px;padding:16px 18px;border-radius:16px;border:1px solid var(--border,rgba(255,255,255,.08));background:color-mix(in srgb,var(--bg-secondary,#101828) 85%,transparent)}
.net-num{margin-top:18px;padding:16px 18px;border-radius:16px;border:1px solid var(--border,rgba(255,255,255,.08));background:color-mix(in srgb,var(--bg-secondary,#101828) 85%,transparent)}
.net-num h2{font-size:12px;font-weight:800;letter-spacing:.7px;text-transform:uppercase;color:var(--text-muted,#7d8aa0);margin:0 0 10px}
.net-num h2{font-size:12px;font-weight:800;letter-spacing:.7px;text-transform:uppercase;color:var(--text-muted,#7d8aa0);margin:0 0 10px}
.net-num ul{list-style:none;margin:0;padding:0;display:grid;gap:8px;grid-template-columns:repeat(auto-fill,minmax(min(140px,100%),1fr))}
.net-num ul{list-style:none;margin:0;padding:0;display:grid;gap:8px;grid-template-columns:repeat(auto-fill,minmax(min(140px,100%),1fr))}
@@ -92,8 +92,10 @@ for (const [id, , verb, , href] of home.INTENTS) {
@@ -92,8 +92,10 @@ for (const [id, , verb, , href] of home.INTENTS) {
}
}
assert.ok(/Go live<\/b><small>From a browser tab\. No OBS, no follower minimum\./.test(html), 'browser go-live stays the headline promise');
assert.ok(/Go live<\/b><small>From a browser tab\. No OBS, no follower minimum\./.test(html), 'browser go-live stays the headline promise');
// The five most popular list (plan L43) is a plain list; with no Report wired in this process it says it is the floor.
// The five most popular list (plan L43) is a plain list; with no Report wired in this process it says it is the floor.
-assert.ok(/<section class="sc-sec" id="popular" data-source="fallback"/.test(html), 'the signed-out popularity list is on the page and names its source');
-assert.ok(html.includes('Five things people do now') && /<ul class="now-list">/.test(html), 'the list is plain, with the existing classes');
+assert.ok(/<section class="sc-sec pop" id="popular" data-source="fallback"/.test(html), 'the signed-out popularity list is on the page and names its source');
+assert.ok(html.includes('Five things people do now') && /<ol class="pop-list">/.test(html), 'the five are a ranked list');
+assert.ok(/<a class="pop-row" href="https:\/\/openvibe\.live\/"><span class="pop-rank" aria-hidden="true">1<\/span><span class="pop-ic" aria-hidden="true"><i class="fa-solid fa-tower-broadcast"><\/i><\/span>/.test(html), 'each row: its place, the site\'s mark');
+assert.ok(!/class="pop-n/.test(html.slice(html.indexOf('id="popular"'), html.indexOf('</ol>', html.indexOf('id="popular"')))), 'the fallback list has no numbers, so it shows none');
assert.ok(/Nobody is live right now/.test(html) && /Go live from your browser/.test(html), 'an honest empty state');
assert.ok(/Nobody is live right now/.test(html) && /Go live from your browser/.test(html), 'an honest empty state');
const open = sites.filter((s) => s.status === 'open' && s.id !== 'network');
const open = sites.filter((s) => s.status === 'open' && s.id !== 'network');
// The hero's orbit (2026-10-28): the most used sites around the mark, the count of every site in its middle.
// The hero's orbit (2026-10-28): the most used sites around the mark, the count of every site in its middle.
@@ -12,7 +12,7 @@ const { spawn } = require('child_process');
@@ -12,7 +12,7 @@ const { spawn } = require('child_process');
const { measure, check, format } = require('openvibe-shared/perf-budget');
const { measure, check, format } = require('openvibe-shared/perf-budget');
const BUDGETS = {
const BUDGETS = {
- htmlRawKB: 209.5, // 209.5: measured 209 KB with openvibe-shared 4.190.0 (2026-11-10: the site name's dropdown, the footer's online strip, the balances pill); 206: measured 205.8 KB with openvibe-shared 4.185.0 (the navbar's links in the first HTML since 4.184.0), 2026-11-10; 205.4: measured 205.4 KB with the front door's five most popular destinations (plan L43, 2026-11-09: Report's ranked list adds about 1.2 KB of plain list markup); 204.2: measured 204.2 KB with openvibe-contracts 0.373.0 (the Git service in the network list) on openvibe-shared 4.173.0, 2026-11-09; 204: measured 203.5 KB with the shared page head's kit CSS on the home (openvibe-shared 4.163.0 + page head 1369721), 2026-11-09; 198.8 with openvibe-contracts 0.348.0 (2026-11-08: Studio joins the menu; Studio and Locker get menu lines); 197.4 with Email open (contracts 0.330.0, 2026-11-07: the mail site in the network list); 196 with the Node's own item in the navbar (openvibe-shared 4.117.0, 2026-11-06: the Node link and the llms.txt section); 194.9 with the Organization naming every open site in sameAs (SEO-27, 2026-11-03); 192.4 with Tours and Shoes open (contracts 0.265.0, 2026-10-31); 189.9 with Casino open (contracts 0.264.0, 2026-10-31); 189 with the look-boot script inline above the stylesheets on every page (L42, 2026-10-31: +1 KB); 188 with the agent layer's rel=alternate/describedby link tags on every public page (SEO-1/SEO-2, 2026-10-29: +0.2 KB); 187 with Bench open (contracts 0.238.0, 2026-10-28); 186 with Cam open (contracts 0.237.0, 2026-10-28); 184.4 with Fun open (contracts 0.236.0, 2026-10-28); 182.7 with Vision and Exchange open (contracts 0.235.0, 2026-10-28); 179 with Meme open (contracts 0.234.0, 2026-10-28); 174.1 with Domains, Report and Design open (contracts 0.226-0.228, 2026-10-28); 168.1 the hero's orbit and rich cards for live streams, recordings and screenshots (2026-10-28: the owner asked for animated visuals and YouTube-style cards); 152.4 openvibe-shared 4.15 footer: the compact footer opens into the whole one, and the pulse line; 147.9 with the home's FAQ (six questions and their FAQPage JSON-LD), the numbers panel and the service map's group headings (2026-10-22); 141.2 with Tips and VIP open (contracts 0.200.0, 37 sites; the Opening next section is gone); 134 with Play (contracts 0.172.1); 128.3 with Events, AI and Search added (31 sites, contracts 0.135.0); 122.3 (shared 2.21.0: a real glyph for every product card, where ten drew the 'V'); was 110.6 with 33 live sites (contracts 0.119.0). The home page lists every site, so it grows with the network
+ htmlRawKB: 210.5, // 210.5: measured 209.9 KB with the popular block designed (2026-11-11: ranks, marks, numbers and its CSS, +0.9 KB); 209.5: measured 209 KB with openvibe-shared 4.190.0 (2026-11-10: the site name's dropdown, the footer's online strip, the balances pill); 206: measured 205.8 KB with openvibe-shared 4.185.0 (the navbar's links in the first HTML since 4.184.0), 2026-11-10; 205.4: measured 205.4 KB with the front door's five most popular destinations (plan L43, 2026-11-09: Report's ranked list adds about 1.2 KB of plain list markup); 204.2: measured 204.2 KB with openvibe-contracts 0.373.0 (the Git service in the network list) on openvibe-shared 4.173.0, 2026-11-09; 204: measured 203.5 KB with the shared page head's kit CSS on the home (openvibe-shared 4.163.0 + page head 1369721), 2026-11-09; 198.8 with openvibe-contracts 0.348.0 (2026-11-08: Studio joins the menu; Studio and Locker get menu lines); 197.4 with Email open (contracts 0.330.0, 2026-11-07: the mail site in the network list); 196 with the Node's own item in the navbar (openvibe-shared 4.117.0, 2026-11-06: the Node link and the llms.txt section); 194.9 with the Organization naming every open site in sameAs (SEO-27, 2026-11-03); 192.4 with Tours and Shoes open (contracts 0.265.0, 2026-10-31); 189.9 with Casino open (contracts 0.264.0, 2026-10-31); 189 with the look-boot script inline above the stylesheets on every page (L42, 2026-10-31: +1 KB); 188 with the agent layer's rel=alternate/describedby link tags on every public page (SEO-1/SEO-2, 2026-10-29: +0.2 KB); 187 with Bench open (contracts 0.238.0, 2026-10-28); 186 with Cam open (contracts 0.237.0, 2026-10-28); 184.4 with Fun open (contracts 0.236.0, 2026-10-28); 182.7 with Vision and Exchange open (contracts 0.235.0, 2026-10-28); 179 with Meme open (contracts 0.234.0, 2026-10-28); 174.1 with Domains, Report and Design open (contracts 0.226-0.228, 2026-10-28); 168.1 the hero's orbit and rich cards for live streams, recordings and screenshots (2026-10-28: the owner asked for animated visuals and YouTube-style cards); 152.4 openvibe-shared 4.15 footer: the compact footer opens into the whole one, and the pulse line; 147.9 with the home's FAQ (six questions and their FAQPage JSON-LD), the numbers panel and the service map's group headings (2026-10-22); 141.2 with Tips and VIP open (contracts 0.200.0, 37 sites; the Opening next section is gone); 134 with Play (contracts 0.172.1); 128.3 with Events, AI and Search added (31 sites, contracts 0.135.0); 122.3 (shared 2.21.0: a real glyph for every product card, where ten drew the 'V'); was 110.6 with 33 live sites (contracts 0.119.0). The home page lists every site, so it grows with the network
htmlBrotliKB: 39.5, // 39.5: measured 39.3 KB brotli with openvibe-shared 4.190.0 (2026-11-10: the site name's dropdown, the footer's online strip, the balances pill); 39: measured 38.6 KB brotli with the shared page head's kit CSS on the home (openvibe-shared 4.163.0 + page head 1369721), 2026-11-09; 38.1 with openvibe-contracts 0.348.0 (2026-11-08: Studio joins the menu; Studio and Locker get menu lines); 37.9 with openvibe-shared 4.129.0 (2026-11-07: the one menu (the burger opens the OpenVibe menu)); 37.8 with openvibe-shared 4.129.0 (2026-11-07: the one menu (the burger opens the OpenVibe menu)); 36.1 with the Node's own item in the navbar (openvibe-shared 4.117.0, 2026-11-06); 35.5 with Tours and Shoes open (2026-10-31); 35.1 with the look-boot script inline above the stylesheets on every page (L42, 2026-10-31: +0.6 KB); 34.2 with the lower half as one block of chips on phones (2026-10-30); 33.1 with Games granted its Bench match capabilities (BENCH-7, 2026-10-29: the home lists what each service may do); 32.0 with Fun, Vision and Exchange open (contracts 0.236.0, 2026-10-28); 31.2 with Domains, Report and Design open (2026-10-28); 30.1 with the Organization saying who OpenVibe is (description, other names, what it is not, 15 sites; 2026-10-28); 28.5 with the FAQ, numbers and groups (2026-10-22); 26.1 with Play; 25.1 (31 sites, contracts 0.135.0); 24.1 (shared 2.21.0, the same glyphs); 20.5 (contracts 0.116.0)
htmlBrotliKB: 39.5, // 39.5: measured 39.3 KB brotli with openvibe-shared 4.190.0 (2026-11-10: the site name's dropdown, the footer's online strip, the balances pill); 39: measured 38.6 KB brotli with the shared page head's kit CSS on the home (openvibe-shared 4.163.0 + page head 1369721), 2026-11-09; 38.1 with openvibe-contracts 0.348.0 (2026-11-08: Studio joins the menu; Studio and Locker get menu lines); 37.9 with openvibe-shared 4.129.0 (2026-11-07: the one menu (the burger opens the OpenVibe menu)); 37.8 with openvibe-shared 4.129.0 (2026-11-07: the one menu (the burger opens the OpenVibe menu)); 36.1 with the Node's own item in the navbar (openvibe-shared 4.117.0, 2026-11-06); 35.5 with Tours and Shoes open (2026-10-31); 35.1 with the look-boot script inline above the stylesheets on every page (L42, 2026-10-31: +0.6 KB); 34.2 with the lower half as one block of chips on phones (2026-10-30); 33.1 with Games granted its Bench match capabilities (BENCH-7, 2026-10-29: the home lists what each service may do); 32.0 with Fun, Vision and Exchange open (contracts 0.236.0, 2026-10-28); 31.2 with Domains, Report and Design open (2026-10-28); 30.1 with the Organization saying who OpenVibe is (description, other names, what it is not, 15 sites; 2026-10-28); 28.5 with the FAQ, numbers and groups (2026-10-22); 26.1 with Play; 25.1 (31 sites, contracts 0.135.0); 24.1 (shared 2.21.0, the same glyphs); 20.5 (contracts 0.116.0)
jsFiles: 8, // 7 with boost.js, was 6 (2026-10-13, plan T11 step 3: one more script on every boosted page; it loads route-transition.js on the first move only)
jsFiles: 8, // 7 with boost.js, was 6 (2026-10-13, plan T11 step 3: one more script on every boosted page; it loads route-transition.js on the first move only)
jsRawKB: 448.5, // 448.5 openvibe-shared v4.205.0 (2026-11-11: measured 448.4, raised by pin-bump from 445); 445 openvibe-shared v4.202.0 (2026-11-11: measured 444.6, raised by pin-bump from 444); 444 openvibe-shared v4.201.0 (2026-11-11: measured 443.7, raised by pin-bump from 440.5); 440.5 openvibe-shared v4.200.0 (2026-11-10: measured 440.2, raised by pin-bump from 440.0); 440.0: measured 439.6 KB raw / 106.7 KB brotli with openvibe-shared 4.197.0 (2026-11-10: the menu's row of places, the You tab's row, the Sign in mark, the tooltip); 438.5: measured 438 KB raw / 106.5 KB brotli with openvibe-shared 4.190.0 (2026-11-10: the site name's dropdown, the footer's online strip, the balances pill); 421: measured 420.9 KB raw / 102.2 KB brotli with openvibe-shared 4.186.0 (the mark's Working and Thinking states, the Dock and the menu as one sheet, bare controls), 2026-11-10; 420.5: measured 419.9 KB raw / 101.9 KB brotli with openvibe-shared 4.185.0 (Calm reduces, the solids and site marks, the You tab, the Dock out of the orb), 2026-11-10; 417: measured 416.4 KB raw / 100.9 KB brotli with openvibe-shared 4.179.0, 2026-11-09; 410: measured 409.2 KB raw / 99.4 KB brotli with openvibe-shared 4.173.0 (the wallet's cookie mode), 2026-11-09; 409: measured 408.1 KB raw / 99.0 KB brotli after merging main's Frame feed work (openvibe-shared 4.167.0), 2026-11-09; 406: measured 405.7 KB raw / 98.4 KB brotli with the shared page head's kit script on the home (openvibe-shared 4.163.0 + page head 1369721), 2026-11-09; 381.8: measured 375.8 KB raw / 91.1 KB brotli with openvibe-shared 4.159.0, plus room for 4.160.0–4.161.0 (the navbar's slots loader, the keyboard watcher, the pop motion), 2026-11-09; 373 with openvibe-shared 4.153.0 (2026-11-08: signed in to the network, signed in here, on phones too; a page can turn away a carried card); 372.3 with openvibe-shared 4.152.0 (2026-11-08: the menu marks the page you are on and opens without the keyboard on a phone, floating cards follow you across OpenVibe sites (overlay.js), and the navbar preconnects to the next OpenVibe site on intent); 369.6 with openvibe-shared 4.150.0 (2026-11-08: the bell opens the Dock on Activity, the Dock's phone header is in two rows, and the menu's orb is the close button with an open/close animation); 368.6 with openvibe-shared 4.149.0 (2026-11-08: the menu has tabs at the top; the phone's menu button is the orb of 4.148.0); 366.5 with openvibe-shared 4.118.0 (2026-11-06: the Locker re-auth link, the 44 px footer and TLD targets; main's 4.117.0 navbar item and the account-safety helper included); about 363.8 with both (2026-11-06: openvibe-shared 4.117.0's featured navbar item, +1.7 KB, and the account-safety helper, +8.5 KB; merged, to be confirmed by CI's measure); 353.6 with the account-safety helper on every page (2026-11-06: the one re-authentication path and the scheduled-deletion banner, +8.5 KB); 345.1 with openvibe-shared 4.114.0 (2026-11-06: the one Share sheet in the navbar (ov-share.js and ov-qr.js load on the first press); navbar.js gains its click handler); 343.9 with openvibe-shared 4.112.1 (2026-11-06: theme-loader.js (4.111.1) and the footer/appbar phone CSS (4.112.1)); 342.3 with openvibe-shared 4.109.2 (2026-11-03: OpenVibe's own select, the navbar loads ov-forms); 339.6 with openvibe-shared 4.107.0 (2026-11-03: open.<tld> sites are named for their domain; the brand knows its front door); 337.8 with openvibe-shared 4.103.0 (2026-11-02: the puzzle glyph, two-line sidebar rows, boost lets parsed pages go, eight solids) (2026-11-02); 334.1 openvibe-shared 4.70.0 (2026-11-01: the app bar, busy(), skeletons, view transitions); 333.2 with openvibe-shared 4.53.0: the footer's columns fold on phones (2026-10-30); 330.1 with openvibe-shared 4.52.0 (from 4.47.2): the seasonal fall, rich embeds, the Dock and its Chats tab (2026-10-30); 323.2 with openvibe-shared 4.47.2 (the comfort settings in theme-loader 4.45, touch targets 4.46, the grouped updates log 4.47.2); 313.7 with openvibe-shared 4.43.0 (room.css carries the kit tokens, 4.39.1; the kit's 4.39.0 rules); 306.4 openvibe-shared 4.25.0: the menu's orb beside the brand, both balances on phones, messages, the account sheet on phones and the bar stepping away on phones; 298.9 openvibe-shared 4.22.0: the navbar's magnifier search button and More dropdown (search.js and loading.js load only when used); 293.1 Shared 4.17.0: OpenCoins and Vibes chips (wallet: true) in the navbar; 279.1 openvibe-shared 4.15 footer: the compact footer opens into the whole one, and the pulse line; 269.3 with shared 4.11.0's seasonal navbar (Pumpkin Night and the season badge, +2.6); 249.8 with boost.js (13.1); 228.3
jsRawKB: 448.5, // 448.5 openvibe-shared v4.205.0 (2026-11-11: measured 448.4, raised by pin-bump from 445); 445 openvibe-shared v4.202.0 (2026-11-11: measured 444.6, raised by pin-bump from 444); 444 openvibe-shared v4.201.0 (2026-11-11: measured 443.7, raised by pin-bump from 440.5); 440.5 openvibe-shared v4.200.0 (2026-11-10: measured 440.2, raised by pin-bump from 440.0); 440.0: measured 439.6 KB raw / 106.7 KB brotli with openvibe-shared 4.197.0 (2026-11-10: the menu's row of places, the You tab's row, the Sign in mark, the tooltip); 438.5: measured 438 KB raw / 106.5 KB brotli with openvibe-shared 4.190.0 (2026-11-10: the site name's dropdown, the footer's online strip, the balances pill); 421: measured 420.9 KB raw / 102.2 KB brotli with openvibe-shared 4.186.0 (the mark's Working and Thinking states, the Dock and the menu as one sheet, bare controls), 2026-11-10; 420.5: measured 419.9 KB raw / 101.9 KB brotli with openvibe-shared 4.185.0 (Calm reduces, the solids and site marks, the You tab, the Dock out of the orb), 2026-11-10; 417: measured 416.4 KB raw / 100.9 KB brotli with openvibe-shared 4.179.0, 2026-11-09; 410: measured 409.2 KB raw / 99.4 KB brotli with openvibe-shared 4.173.0 (the wallet's cookie mode), 2026-11-09; 409: measured 408.1 KB raw / 99.0 KB brotli after merging main's Frame feed work (openvibe-shared 4.167.0), 2026-11-09; 406: measured 405.7 KB raw / 98.4 KB brotli with the shared page head's kit script on the home (openvibe-shared 4.163.0 + page head 1369721), 2026-11-09; 381.8: measured 375.8 KB raw / 91.1 KB brotli with openvibe-shared 4.159.0, plus room for 4.160.0–4.161.0 (the navbar's slots loader, the keyboard watcher, the pop motion), 2026-11-09; 373 with openvibe-shared 4.153.0 (2026-11-08: signed in to the network, signed in here, on phones too; a page can turn away a carried card); 372.3 with openvibe-shared 4.152.0 (2026-11-08: the menu marks the page you are on and opens without the keyboard on a phone, floating cards follow you across OpenVibe sites (overlay.js), and the navbar preconnects to the next OpenVibe site on intent); 369.6 with openvibe-shared 4.150.0 (2026-11-08: the bell opens the Dock on Activity, the Dock's phone header is in two rows, and the menu's orb is the close button with an open/close animation); 368.6 with openvibe-shared 4.149.0 (2026-11-08: the menu has tabs at the top; the phone's menu button is the orb of 4.148.0); 366.5 with openvibe-shared 4.118.0 (2026-11-06: the Locker re-auth link, the 44 px footer and TLD targets; main's 4.117.0 navbar item and the account-safety helper included); about 363.8 with both (2026-11-06: openvibe-shared 4.117.0's featured navbar item, +1.7 KB, and the account-safety helper, +8.5 KB; merged, to be confirmed by CI's measure); 353.6 with the account-safety helper on every page (2026-11-06: the one re-authentication path and the scheduled-deletion banner, +8.5 KB); 345.1 with openvibe-shared 4.114.0 (2026-11-06: the one Share sheet in the navbar (ov-share.js and ov-qr.js load on the first press); navbar.js gains its click handler); 343.9 with openvibe-shared 4.112.1 (2026-11-06: theme-loader.js (4.111.1) and the footer/appbar phone CSS (4.112.1)); 342.3 with openvibe-shared 4.109.2 (2026-11-03: OpenVibe's own select, the navbar loads ov-forms); 339.6 with openvibe-shared 4.107.0 (2026-11-03: open.<tld> sites are named for their domain; the brand knows its front door); 337.8 with openvibe-shared 4.103.0 (2026-11-02: the puzzle glyph, two-line sidebar rows, boost lets parsed pages go, eight solids) (2026-11-02); 334.1 openvibe-shared 4.70.0 (2026-11-01: the app bar, busy(), skeletons, view transitions); 333.2 with openvibe-shared 4.53.0: the footer's columns fold on phones (2026-10-30); 330.1 with openvibe-shared 4.52.0 (from 4.47.2): the seasonal fall, rich embeds, the Dock and its Chats tab (2026-10-30); 323.2 with openvibe-shared 4.47.2 (the comfort settings in theme-loader 4.45, touch targets 4.46, the grouped updates log 4.47.2); 313.7 with openvibe-shared 4.43.0 (room.css carries the kit tokens, 4.39.1; the kit's 4.39.0 rules); 306.4 openvibe-shared 4.25.0: the menu's orb beside the brand, both balances on phones, messages, the account sheet on phones and the bar stepping away on phones; 298.9 openvibe-shared 4.22.0: the navbar's magnifier search button and More dropdown (search.js and loading.js load only when used); 293.1 Shared 4.17.0: OpenCoins and Vibes chips (wallet: true) in the navbar; 279.1 openvibe-shared 4.15 footer: the compact footer opens into the whole one, and the pulse line; 269.3 with shared 4.11.0's seasonal navbar (Pumpkin Night and the season badge, +2.6); 249.8 with boost.js (13.1); 228.3