openvibers/openvibe.work Commits
The home's picture is the newest listing, leading with its board (#250)
Changes
@@@ -95,3 +95,29 @@.fold-bare { margin-top: 0; }.fold:not(.fold-bare) .fold-body > .sc-sec { margin-top: 0; }}++++/* ── The home's picture (server/http/pages.js sourceScene): the newest listing, leading with its source, on a small++ stack of the next two. The cards behind show only their top edge: enough to read the board and the title. ── */++.wk-scene { width: min(100%, 400px); margin: 0 auto; }++.wk-scene-stack { display: grid; padding-top: 84px; }++.wk-scene-card { grid-area: 1 / 1; display: grid; gap: 4px; min-width: 0; padding: 14px 16px; border-radius: 16px; border: 1px solid var(--border, #1f2d47); color: var(--text-primary, #e6edf7); text-decoration: none; box-shadow: 0 12px 30px rgba(0, 0, 0, .28);++ /* Solid whatever the theme's card colour is (some are see-through): a card must cover the one behind it. */++ background: linear-gradient(var(--bg-card, #131c2e), var(--bg-card, #131c2e)), var(--bg-primary, #0a0f1c); }++.wk-scene-card b { font-size: 1.05rem; line-height: 1.25; overflow: hidden; display: -webkit-box; -webkit-line-clamp: 2; -webkit-box-orient: vertical; }++.wk-scene-card.is-second { transform: translateY(-42px) scale(.95); transform-origin: top center; }++.wk-scene-card.is-second > *, .wk-scene-card.is-third > * { opacity: .7; }++.wk-scene-card.is-third { transform: translateY(-84px) scale(.9); transform-origin: top center; }++.wk-scene-card.is-third > * { opacity: .45; }++.wk-scene-card.is-second b, .wk-scene-card.is-third b { -webkit-line-clamp: 1; }++.wk-scene-card.is-front:hover, .wk-scene-card.is-front:focus-visible { border-color: var(--accent, #3b82f6); outline: none; }++.wk-scene-src { justify-self: start; display: inline-flex; align-items: center; gap: 7px; padding: 3px 10px 3px 8px; border-radius: 999px; font-size: .78rem; font-weight: 750; color: var(--accent-light, #60a5fa); background: color-mix(in srgb, var(--accent, #3b82f6) 16%, transparent); }++.wk-scene-src i { width: 7px; height: 7px; border-radius: 50%; background: currentColor; }++.is-front .wk-scene-src { animation: wkSceneRing 1.4s var(--ov-ease-out, cubic-bezier(.2, .8, .2, 1)) .7s 1 both; }++.wk-scene-meta { color: var(--text-secondary, #96a7c2); font-size: .9rem; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }++.wk-scene-go { margin-top: 6px; color: var(--accent-light, #60a5fa); font-size: .86rem; font-weight: 650; }++.wk-scene figcaption { margin-top: 10px; text-align: center; color: var(--text-muted, #7386a3); font-size: .8rem; }++@keyframes wkSceneRing { 0% { box-shadow: 0 0 0 0 color-mix(in srgb, var(--accent, #3b82f6) 70%, transparent); } 100% { box-shadow: 0 0 0 12px transparent; } }++@media (prefers-reduced-motion: reduce) { .is-front .wk-scene-src { animation: none; } }++html[data-ov-motion=reduced] .is-front .wk-scene-src { animation: none; }++/* A transformed card paints above a plain one whatever the order in the page: the front card says it is in front. */++.wk-scene-card.is-front { position: relative; z-index: 2; }@@@ -133,6 +133,28 @@ ${facets.type.map((t) => link({ type: t.type }, t.label, filters.type === t.typeconst FAQ = ((products.get('openvibe.work') || {}).faq || []);const n = (v) => Number(v || 0).toLocaleString('en-US');const sentence = (t) => (t ? t[0].toUpperCase() + t.slice(1) : t);++ /**++ * The home's picture: the newest listing as a card that leads with its source ("From Remotive"), the way every++ * listing on the site does, with the next two showing behind it. Every word in it is a real row; the caption says++ * when it was read. The source tag is ringed once when the page opens (CSS, public/css/home.css .wk-scene), and++ * is simply there under reduced motion.++ */++ function sourceScene(rows, sourceOf) {++ const tile = (row, cls) => {++ const l = listing.meta(row);++ const src = sourceOf(row) || {};++ return html`<a class="wk-scene-card ${cls}" href="/jobs/${l.id}"${cls === 'is-front' ? '' : raw(' tabindex="-1" aria-hidden="true"')}>++<span class="wk-scene-src"><i aria-hidden="true"></i>From ${src.name || 'a public board'}</span>++<b>${l.title}</b>++<span class="wk-scene-meta">${l.company}${l.location ? html` · ${l.location}` : ''}</span>++${cls === 'is-front' ? html`<span class="wk-scene-go">Read it, with the link to the original</span>` : ''}</a>`;++ };++ const [first, ...rest] = rows.slice(0, 3);++ return html`<figure class="wk-scene" aria-label="The newest remote listing, with the board it came from">++<div class="wk-scene-stack">${rest.reverse().map((row, i, all) => tile(row, all.length - i === 2 ? 'is-third' : 'is-second'))}${tile(first, 'is-front')}</div>++<figcaption>The newest remote listing right now. Every listing names its board.</figcaption></figure>`;++ }++r.get('/', async (req, res) => {const [latest, counts, sum, salaried] = await Promise.all([store.listRecent(s, 6, { remote: true }), store.countsBySource(s), store.homeSummary(s), store.listSalaried(s, 4)]);const fetches = await store.sourceFetches(s);@@@ -142,19 +164,10 @@ ${facets.type.map((t) => link({ type: t.type }, t.label, filters.type === t.type// The title says what this is; the eyebrow is the site's name, not the title again.eyebrow: SITE_NAME,title: 'Find work.',-- // The hero's picture is this site's own (2026-11-01): it drew the generic aura, the same on six homes.-- // What a job seeker has here, around the listings.-- orbit: {-- label: 'What you can do here',-- center: { title: 'Listings', sub: 'from public boards' },-- inner: [-- { icon: 'ov:search', label: 'Search', href: '#search' },-- { icon: 'ov:map', label: 'Remote', href: '/jobs?remote=true' },-- { icon: 'ov:bell', label: 'Alerts', href: '#search' },-- { icon: 'ov:actor', label: 'Your agent', href: 'https://openvibe.actor/' },-- { icon: 'ov:link', label: 'Sources', href: '/sources' },-- ],-- },++ // The hero's picture is the thing itself (2026-11-10; the owner: no more "generic circled" homes): the++ // newest listing, as a card whose first line is the board it came from, on a small stack of the next two.++ // Real rows only: with no listings yet there is no picture.++ ...(latest.length ? { aside: { html: String(sourceScene(latest, sourceOf)) } } : {}),accent: 'Every listing shows where it came from.',// Two lines on a phone: what it is and that it is free. What signing in adds is said where it happens.lede: 'Listings from public job boards, each with its own link. No paywall, and no account needed to look.',nnew file mode 100644@@@ -0,0 +1,46 @@++'use strict';++// The home's picture is the thing itself: the newest remote listing as a card that leads with the board it came from,++// on a small stack of the next two (the owner, 2026-11-09: no more "generic circled" homes). Real rows only: with no++// listings there is no picture, and never an invented one.++const assert = require('assert');++const { boot, check, done } = require('./helpers/boot');++++(async () => {++ const t = await boot();++++ await check('with no listings the hero has no picture (and no orbit)', async () => {++ const r = await t.get('/');++ assert.strictEqual(r.status, 200);++ assert.ok(!r.text.includes('class="wk-scene"'), 'no picture without a listing');++ assert.ok(!/class="sc-orbit|sc-orbit-/.test(r.text), 'the generic orbit is gone');++ });++++ const rows = [++ { title: 'Backend engineer', company: 'Nordlicht Systems', location: 'Berlin, Germany', at: '2026-11-09T10:00:00.000Z' },++ { title: 'Data scientist', company: 'Helles Werk', location: 'Remote, Europe', at: '2026-11-09T11:00:00.000Z' },++ { title: 'Support lead', company: 'Kleine Post', location: '', at: '2026-11-09T12:00:00.000Z' },++ ];++ await Promise.all(rows.map((row, i) => t.ctx.s.db.query(++ `INSERT INTO work_listings (id, source, source_id, url, title, company, location, remote, tags, job_type, salary, excerpt, search_text, posted_at, sort_at, fetched_at, first_seen_at, last_seen_at)++ VALUES ($1,$2,$3,$4,$5,$6,$7,$8,$9,$10,$11,$12,$13,$14,$14,$14,$14,$14)`,++ [`job_pic${'0'.repeat(22)}${i}`, 'arbeitnow', `pic-${i}`, `https://example.org/job/${i}`, row.title, row.company, row.location,++ true, 'nodejs', 'permanent', '', 'A short excerpt of the listing.', `${row.title} ${row.company}`.toLowerCase(), row.at])));++++ await check('with listings the picture is the newest one, leading with its board, over the next two', async () => {++ const r = await t.get('/');++ const scene = (r.text.match(/<figure class="wk-scene"[\s\S]*?<\/figure>/) || [''])[0];++ assert.ok(scene, 'the picture is in the hero');++ const cards = Array.from(scene.matchAll(/<a class="wk-scene-card (is-front|is-second|is-third)" href="(\/jobs\/[^"]+)"([^>]*)>\s*<span class="wk-scene-src"><i aria-hidden="true"><\/i>From ([^<]+)<\/span>\s*<b>([^<]+)<\/b>/g));++ assert.deepStrictEqual(cards.map((m) => m[1]), ['is-third', 'is-second', 'is-front'], 'the front card is last in the markup, so it is on top');++ const front = cards[2];++ assert.strictEqual(front[5], 'Support lead', 'the front card is the newest listing');++ assert.ok(front[4].length > 2 && front[4] !== 'a public board', `it names its board: ${front[4]}`);++ assert.ok(!/aria-hidden/.test(front[3]), 'the front card is a real link');++ cards.slice(0, 2).forEach((m) => assert.ok(/tabindex="-1" aria-hidden="true"/.test(m[3]), 'the cards behind are decoration: out of the tab order'));++ assert.match(scene, /<figcaption>The newest remote listing right now\. Every listing names its board\.<\/figcaption>/);++ assert.ok(!/class="sc-orbit|sc-orbit-/.test(r.text), 'the generic orbit is gone');++ });++++ await t.close();++ done();++})().catch((e) => { console.error(e); process.exit(1); });@@@ -24,7 +24,7 @@ const BUDGETS = {jsBrotliKB: 89.5, // 89.5: measured 87.5 with openvibe-shared 4.163.0, plus room for 4.162.0–4.163.0, 2026-11-09cssFiles: 3, // 3 (app.css, the cached /shared/showcase.css and css/home.css, the curated home's counts, fields, cities, companies and questions, 2026-10-22)cssRawKB: 53.7, // 53.7: measured 48.7 with openvibe-shared 4.161.0, plus room for 4.162.0–4.163.0, 2026-11-09-- cssBrotliKB: 11, // 10.4 with 2026-11-01: phone table cards (+1.3 KB raw) (2026-11-01); raised from 10 on 2026-10-31, with the measured page: 45.6 KB raw / 10.1 KB brotli (the listings' salary line, the gone line and the fetch date under the link out); 10.0 with the home's pick block and folds (the sections below the search are picked one at a time on a phone, 2026-10-30); 9.1 with openvibe-shared 4.48.0 (the site switcher on the mark, the menu's Start tab and quick tools; Kit's touch hit areas and the phone navbar fix, 4.44-4.47.3); 8.6 the home's phone rows, limits and fold (2026-10-29); 6.6–6.7 with Shared 4.13.0; raised from 8 for openvibe-shared v4.39.0 (+1.5 KB raw of kit/room/showcase CSS); measured 8.3++ cssBrotliKB: 11.4, // 11.3 with the home's picture (the newest listing as a stack of cards), 2026-11-10; before: 10.4 with 2026-11-01: phone table cards (+1.3 KB raw) (2026-11-01); raised from 10 on 2026-10-31, with the measured page: 45.6 KB raw / 10.1externalFiles: 0, // 0};
@@ -95,3 +95,29 @@
@@ -95,3 +95,29 @@
.fold-bare { margin-top: 0; }
.fold-bare { margin-top: 0; }
.fold:not(.fold-bare) .fold-body > .sc-sec { margin-top: 0; }
.fold:not(.fold-bare) .fold-body > .sc-sec { margin-top: 0; }
}
}
+
+/* ── The home's picture (server/http/pages.js sourceScene): the newest listing, leading with its source, on a small
+ stack of the next two. The cards behind show only their top edge: enough to read the board and the title. ── */
+.wk-scene { width: min(100%, 400px); margin: 0 auto; }
+.wk-scene-stack { display: grid; padding-top: 84px; }
+.wk-scene-card { grid-area: 1 / 1; display: grid; gap: 4px; min-width: 0; padding: 14px 16px; border-radius: 16px; border: 1px solid var(--border, #1f2d47); color: var(--text-primary, #e6edf7); text-decoration: none; box-shadow: 0 12px 30px rgba(0, 0, 0, .28);
+ /* Solid whatever the theme's card colour is (some are see-through): a card must cover the one behind it. */
+ background: linear-gradient(var(--bg-card, #131c2e), var(--bg-card, #131c2e)), var(--bg-primary, #0a0f1c); }
+.wk-scene-card b { font-size: 1.05rem; line-height: 1.25; overflow: hidden; display: -webkit-box; -webkit-line-clamp: 2; -webkit-box-orient: vertical; }
+.wk-scene-card.is-second { transform: translateY(-42px) scale(.95); transform-origin: top center; }
+.wk-scene-card.is-second > *, .wk-scene-card.is-third > * { opacity: .7; }
+.wk-scene-card.is-third { transform: translateY(-84px) scale(.9); transform-origin: top center; }
+.wk-scene-card.is-third > * { opacity: .45; }
+.wk-scene-card.is-second b, .wk-scene-card.is-third b { -webkit-line-clamp: 1; }
+.wk-scene-card.is-front:hover, .wk-scene-card.is-front:focus-visible { border-color: var(--accent, #3b82f6); outline: none; }
+.wk-scene-src { justify-self: start; display: inline-flex; align-items: center; gap: 7px; padding: 3px 10px 3px 8px; border-radius: 999px; font-size: .78rem; font-weight: 750; color: var(--accent-light, #60a5fa); background: color-mix(in srgb, var(--accent, #3b82f6) 16%, transparent); }
+.wk-scene-src i { width: 7px; height: 7px; border-radius: 50%; background: currentColor; }
+.is-front .wk-scene-src { animation: wkSceneRing 1.4s var(--ov-ease-out, cubic-bezier(.2, .8, .2, 1)) .7s 1 both; }
+.wk-scene-meta { color: var(--text-secondary, #96a7c2); font-size: .9rem; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
+.wk-scene-go { margin-top: 6px; color: var(--accent-light, #60a5fa); font-size: .86rem; font-weight: 650; }
+.wk-scene figcaption { margin-top: 10px; text-align: center; color: var(--text-muted, #7386a3); font-size: .8rem; }
+@keyframes wkSceneRing { 0% { box-shadow: 0 0 0 0 color-mix(in srgb, var(--accent, #3b82f6) 70%, transparent); } 100% { box-shadow: 0 0 0 12px transparent; } }
+@media (prefers-reduced-motion: reduce) { .is-front .wk-scene-src { animation: none; } }
+html[data-ov-motion=reduced] .is-front .wk-scene-src { animation: none; }
+/* A transformed card paints above a plain one whatever the order in the page: the front card says it is in front. */
+.wk-scene-card.is-front { position: relative; z-index: 2; }
@@ -133,6 +133,28 @@ ${facets.type.map((t) => link({ type: t.type }, t.label, filters.type === t.type
@@ -133,6 +133,28 @@ ${facets.type.map((t) => link({ type: t.type }, t.label, filters.type === t.type
const FAQ = ((products.get('openvibe.work') || {}).faq || []);
const FAQ = ((products.get('openvibe.work') || {}).faq || []);
const n = (v) => Number(v || 0).toLocaleString('en-US');
const n = (v) => Number(v || 0).toLocaleString('en-US');
const sentence = (t) => (t ? t[0].toUpperCase() + t.slice(1) : t);
const sentence = (t) => (t ? t[0].toUpperCase() + t.slice(1) : t);
+ /**
+ * The home's picture: the newest listing as a card that leads with its source ("From Remotive"), the way every
+ * listing on the site does, with the next two showing behind it. Every word in it is a real row; the caption says
+ * when it was read. The source tag is ringed once when the page opens (CSS, public/css/home.css .wk-scene), and
+ * is simply there under reduced motion.
+ */
+ function sourceScene(rows, sourceOf) {
+ const tile = (row, cls) => {
+ const l = listing.meta(row);
+ const src = sourceOf(row) || {};
+ return html`<a class="wk-scene-card ${cls}" href="/jobs/${l.id}"${cls === 'is-front' ? '' : raw(' tabindex="-1" aria-hidden="true"')}>
+<span class="wk-scene-src"><i aria-hidden="true"></i>From ${src.name || 'a public board'}</span>
+<b>${l.title}</b>
+<span class="wk-scene-meta">${l.company}${l.location ? html` · ${l.location}` : ''}</span>
+${cls === 'is-front' ? html`<span class="wk-scene-go">Read it, with the link to the original</span>` : ''}</a>`;
+ };
+ const [first, ...rest] = rows.slice(0, 3);
+ return html`<figure class="wk-scene" aria-label="The newest remote listing, with the board it came from">
+<div class="wk-scene-stack">${rest.reverse().map((row, i, all) => tile(row, all.length - i === 2 ? 'is-third' : 'is-second'))}${tile(first, 'is-front')}</div>
+<figcaption>The newest remote listing right now. Every listing names its board.</figcaption></figure>`;
+ }
+
r.get('/', async (req, res) => {
r.get('/', async (req, res) => {
const [latest, counts, sum, salaried] = await Promise.all([store.listRecent(s, 6, { remote: true }), store.countsBySource(s), store.homeSummary(s), store.listSalaried(s, 4)]);
const [latest, counts, sum, salaried] = await Promise.all([store.listRecent(s, 6, { remote: true }), store.countsBySource(s), store.homeSummary(s), store.listSalaried(s, 4)]);
const fetches = await store.sourceFetches(s);
const fetches = await store.sourceFetches(s);
@@ -142,19 +164,10 @@ ${facets.type.map((t) => link({ type: t.type }, t.label, filters.type === t.type
@@ -142,19 +164,10 @@ ${facets.type.map((t) => link({ type: t.type }, t.label, filters.type === t.type
// The title says what this is; the eyebrow is the site's name, not the title again.
// The title says what this is; the eyebrow is the site's name, not the title again.
eyebrow: SITE_NAME,
eyebrow: SITE_NAME,
title: 'Find work.',
title: 'Find work.',
- // The hero's picture is this site's own (2026-11-01): it drew the generic aura, the same on six homes.
- // What a job seeker has here, around the listings.
- orbit: {
- label: 'What you can do here',
- center: { title: 'Listings', sub: 'from public boards' },
- inner: [
- { icon: 'ov:search', label: 'Search', href: '#search' },
- { icon: 'ov:map', label: 'Remote', href: '/jobs?remote=true' },
- { icon: 'ov:bell', label: 'Alerts', href: '#search' },
- { icon: 'ov:actor', label: 'Your agent', href: 'https://openvibe.actor/' },
- { icon: 'ov:link', label: 'Sources', href: '/sources' },
- ],
- },
+ // The hero's picture is the thing itself (2026-11-10; the owner: no more "generic circled" homes): the
+ // newest listing, as a card whose first line is the board it came from, on a small stack of the next two.
+ // Real rows only: with no listings yet there is no picture.
+ ...(latest.length ? { aside: { html: String(sourceScene(latest, sourceOf)) } } : {}),
accent: 'Every listing shows where it came from.',
accent: 'Every listing shows where it came from.',
// Two lines on a phone: what it is and that it is free. What signing in adds is said where it happens.
// Two lines on a phone: what it is and that it is free. What signing in adds is said where it happens.
lede: 'Listings from public job boards, each with its own link. No paywall, and no account needed to look.',
lede: 'Listings from public job boards, each with its own link. No paywall, and no account needed to look.',
new file mode 100644
new file mode 100644
@@ -0,0 +1,46 @@
@@ -0,0 +1,46 @@
+'use strict';
+// The home's picture is the thing itself: the newest remote listing as a card that leads with the board it came from,
+// on a small stack of the next two (the owner, 2026-11-09: no more "generic circled" homes). Real rows only: with no
+// listings there is no picture, and never an invented one.
+const assert = require('assert');
+const { boot, check, done } = require('./helpers/boot');
+
+(async () => {
+ const t = await boot();
+
+ await check('with no listings the hero has no picture (and no orbit)', async () => {
+ const r = await t.get('/');
+ assert.strictEqual(r.status, 200);
+ assert.ok(!r.text.includes('class="wk-scene"'), 'no picture without a listing');
+ assert.ok(!/class="sc-orbit|sc-orbit-/.test(r.text), 'the generic orbit is gone');
+ });
+
+ const rows = [
+ { title: 'Backend engineer', company: 'Nordlicht Systems', location: 'Berlin, Germany', at: '2026-11-09T10:00:00.000Z' },
+ { title: 'Data scientist', company: 'Helles Werk', location: 'Remote, Europe', at: '2026-11-09T11:00:00.000Z' },
+ { title: 'Support lead', company: 'Kleine Post', location: '', at: '2026-11-09T12:00:00.000Z' },
+ ];
+ await Promise.all(rows.map((row, i) => t.ctx.s.db.query(
+ `INSERT INTO work_listings (id, source, source_id, url, title, company, location, remote, tags, job_type, salary, excerpt, search_text, posted_at, sort_at, fetched_at, first_seen_at, last_seen_at)
+ VALUES ($1,$2,$3,$4,$5,$6,$7,$8,$9,$10,$11,$12,$13,$14,$14,$14,$14,$14)`,
+ [`job_pic${'0'.repeat(22)}${i}`, 'arbeitnow', `pic-${i}`, `https://example.org/job/${i}`, row.title, row.company, row.location,
+ true, 'nodejs', 'permanent', '', 'A short excerpt of the listing.', `${row.title} ${row.company}`.toLowerCase(), row.at])));
+
+ await check('with listings the picture is the newest one, leading with its board, over the next two', async () => {
+ const r = await t.get('/');
+ const scene = (r.text.match(/<figure class="wk-scene"[\s\S]*?<\/figure>/) || [''])[0];
+ assert.ok(scene, 'the picture is in the hero');
+ const cards = Array.from(scene.matchAll(/<a class="wk-scene-card (is-front|is-second|is-third)" href="(\/jobs\/[^"]+)"([^>]*)>\s*<span class="wk-scene-src"><i aria-hidden="true"><\/i>From ([^<]+)<\/span>\s*<b>([^<]+)<\/b>/g));
+ assert.deepStrictEqual(cards.map((m) => m[1]), ['is-third', 'is-second', 'is-front'], 'the front card is last in the markup, so it is on top');
+ const front = cards[2];
+ assert.strictEqual(front[5], 'Support lead', 'the front card is the newest listing');
+ assert.ok(front[4].length > 2 && front[4] !== 'a public board', `it names its board: ${front[4]}`);
+ assert.ok(!/aria-hidden/.test(front[3]), 'the front card is a real link');
+ cards.slice(0, 2).forEach((m) => assert.ok(/tabindex="-1" aria-hidden="true"/.test(m[3]), 'the cards behind are decoration: out of the tab order'));
+ assert.match(scene, /<figcaption>The newest remote listing right now\. Every listing names its board\.<\/figcaption>/);
+ assert.ok(!/class="sc-orbit|sc-orbit-/.test(r.text), 'the generic orbit is gone');
+ });
+
+ await t.close();
+ done();
+})().catch((e) => { console.error(e); process.exit(1); });
@@ -24,7 +24,7 @@ const BUDGETS = {
@@ -24,7 +24,7 @@ const BUDGETS = {
jsBrotliKB: 89.5, // 89.5: measured 87.5 with openvibe-shared 4.163.0, plus room for 4.162.0–4.163.0, 2026-11-09
jsBrotliKB: 89.5, // 89.5: measured 87.5 with openvibe-shared 4.163.0, plus room for 4.162.0–4.163.0, 2026-11-09
cssFiles: 3, // 3 (app.css, the cached /shared/showcase.css and css/home.css, the curated home's counts, fields, cities, companies and questions, 2026-10-22)
cssFiles: 3, // 3 (app.css, the cached /shared/showcase.css and css/home.css, the curated home's counts, fields, cities, companies and questions, 2026-10-22)
cssRawKB: 53.7, // 53.7: measured 48.7 with openvibe-shared 4.161.0, plus room for 4.162.0–4.163.0, 2026-11-09
cssRawKB: 53.7, // 53.7: measured 48.7 with openvibe-shared 4.161.0, plus room for 4.162.0–4.163.0, 2026-11-09
- cssBrotliKB: 11, // 10.4 with 2026-11-01: phone table cards (+1.3 KB raw) (2026-11-01); raised from 10 on 2026-10-31, with the measured page: 45.6 KB raw / 10.1 KB brotli (the listings' salary line, the gone line and the fetch date under the link out); 10.0 with the home's pick block and folds (the sections below the search are picked one at a time on a phone, 2026-10-30); 9.1 with openvibe-shared 4.48.0 (the site switcher on the mark, the menu's Start tab and quick tools; Kit's touch hit areas and the phone navbar fix, 4.44-4.47.3); 8.6 the home's phone rows, limits and fold (2026-10-29); 6.6–6.7 with Shared 4.13.0; raised from 8 for openvibe-shared v4.39.0 (+1.5 KB raw of kit/room/showcase CSS); measured 8.3
+ cssBrotliKB: 11.4, // 11.3 with the home's picture (the newest listing as a stack of cards), 2026-11-10; before: 10.4 with 2026-11-01: phone table cards (+1.3 KB raw) (2026-11-01); raised from 10 on 2026-10-31, with the measured page: 45.6 KB raw / 10.1
externalFiles: 0, // 0
externalFiles: 0, // 0
};
};