openvibers/openvibe.host Commits
Host's front page on a phone: four rows of each list, the numbers in a strip, two hero actions (#196)
Changes
@@@ -33,3 +33,12 @@ ul.log .level { display: inline-block; width: 3.5em; color: var(--hs-muted); } .ul.domains { padding-left: 1.2rem; } ul.domains li { margin-bottom: 1rem; }.intro { max-width: 44rem; }@media (max-width: 40rem) { table { display: block; overflow-x: auto; } .account-bar { text-align: left; } }++++/* Phones (2026-10-29): a taste and a door. The front page's plan and domain lists show four rows each (every plan++ and every ending are a link away), and the numbers are one strip that scrolls sideways. */++@media (max-width: 599px) {++ .hh-short .hc-table tbody tr:nth-child(n+5) { display: none; }++ .hh-stats { display: flex; overflow-x: auto; scrollbar-width: none; gap: 8px; margin-left: -16px; margin-right: -16px; padding: 0 16px 2px; }++ .hh-stats::-webkit-scrollbar { display: none; }++ .hh-stats li { flex: 0 0 auto; min-width: 128px; }++}@@@ -352,10 +352,11 @@ function front({ plans, providers, promos: live, stats, offers: recent = [], domtitle: 'Hosting, compared honestly.',accent: 'Every price dated and sourced.',lede: 'Cloud, VPS and dedicated plans from providers\' official APIs, side by side: price per month, per vCPU and per GB, the day each price was checked and a link to where it came from. Sorted by what you ask for, never by who pays.',-- actions: [{ label: 'Compare plans', href: '/catalog', primary: true }, { label: 'Domain prices', href: '/catalog/domains' }, { label: 'Latest offers', href: '/catalog/offers' }],++ // Two, so they sit side by side on a phone; the latest offers have their own section and link below.++ actions: [{ label: 'Compare plans', href: '/catalog', primary: true }, { label: 'Domain prices', href: '/catalog/domains' }],note: stats.plans ? `${stats.plans} plans from ${stats.providers} provider${stats.providers === 1 ? '' : 's'} so far. More providers join as their sources are checked.` : 'The catalog is filling up: providers join as their official sources are checked and enabled.',aside: aside ? { html: aside } : undefined,-- }) + extra.stats + `<section class="sc-sec" aria-labelledby="hh-cheapest"><h2 id="hh-cheapest">The lowest monthly prices</h2>${planTable(plans.slice(0, 8), { caption: 'Lowest price first' })}++ }) + extra.stats + `<section class="sc-sec hh-short" aria-labelledby="hh-cheapest"><h2 id="hh-cheapest">The lowest monthly prices</h2>${planTable(plans.slice(0, 8), { caption: 'Lowest price first' })}<p class="hc-more">${link('/catalog', 'Filter and sort every plan →', 'button')}</p></section>`+ extra.sizes + extra.value + extra.providers+ domainSection@@@ -160,8 +160,8 @@ function frontSection({ popular = [], cheap = [], stats }) {return `<section class="sc-sec hd-front" aria-labelledby="hd-front-h"><h2 id="hd-front-h">Domain names, compared too</h2><p class="hc-dim">${stats.tlds ? `${stats.tlds.toLocaleString('en')} endings${registrars > 1 ? ` from ${registrars} registrars (${stats.registrars.map(esc).join(', ')})` : ''}, with the first year, the renewal and five years side by side. ` : ''}Check a name at its registry, then register it where it costs least.</p>${checkForm({})}--${tldTable(popular.slice(0, 6), { caption: 'Popular endings: the cheapest price at any registrar' })}--${cheap.length ? tldTable(cheap.slice(0, 6), { caption: 'The cheapest first year right now: check what it renews at' }) : ''}++<div class="hh-short">${tldTable(popular.slice(0, 6), { caption: 'Popular endings: the cheapest price at any registrar' })}</div>++${cheap.length ? '<div class="hh-short">' + tldTable(cheap.slice(0, 6), { caption: 'The cheapest first year right now: check what it renews at' }) + '</div>' : ''}${stats.tlds ? `<p class="hc-more">${link('/catalog/domains', 'Every ending, by price →', 'button')}</p>` : ''}</section>`;}@@@ -19,7 +19,7 @@ const BUDGETS = {jsBrotliKB: 76, // 74.2 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; 70.5 Shared 4.17.0: OpenCoins and Vibes chips (wallet: true) in the navbar; 67.9 openvibe-shared 4.15 footer: the compact footer opens into the whole one, and the pulse line; 65.3 Shared 4.12.0: the light/dark switch, the seasonal mark and the theme pairs; 61.7 with shared 4.11.0's seasonal navbar; 56.3 (was 49.9)cssFiles: 3, // 3 (host.css, openvibe-shared showcase.css, catalog.css: the front page is the hosting catalog since Host#69)cssRawKB: 51, // 46.2 openvibe-shared 4.26.1 (hero visual); 40.7 with Shared 4.13.0 (2026-10-26: account links); 34.8 on 2026-10-22 (the front page's cards and questions); 31.9 (2026-10-16 the domain comparison's and benchmarks' styles; 27.2 with showcase.css 4.1.5, 14.8 before catalog.css)-- cssBrotliKB: 10, // 8.3 with Shared 4.13.0 (2026-10-26: account links); 6.9 (5.7 before the domain and benchmark styles, 3.6 before catalog.css)++ cssBrotliKB: 10.5, // 10.1 with the phone rules that show four rows of each front-page list (2026-10-29); 8.3 with Shared 4.13.0 (2026-10-26: account links); 6.9 (5.7 before the domain and benchmark styles, 3.6 before catalog.css)externalFiles: 1, // 0};
@@ -33,3 +33,12 @@ ul.log .level { display: inline-block; width: 3.5em; color: var(--hs-muted); } .
@@ -33,3 +33,12 @@ ul.log .level { display: inline-block; width: 3.5em; color: var(--hs-muted); } .
ul.domains { padding-left: 1.2rem; } ul.domains li { margin-bottom: 1rem; }
ul.domains { padding-left: 1.2rem; } ul.domains li { margin-bottom: 1rem; }
.intro { max-width: 44rem; }
.intro { max-width: 44rem; }
@media (max-width: 40rem) { table { display: block; overflow-x: auto; } .account-bar { text-align: left; } }
@media (max-width: 40rem) { table { display: block; overflow-x: auto; } .account-bar { text-align: left; } }
+
+/* Phones (2026-10-29): a taste and a door. The front page's plan and domain lists show four rows each (every plan
+ and every ending are a link away), and the numbers are one strip that scrolls sideways. */
+@media (max-width: 599px) {
+ .hh-short .hc-table tbody tr:nth-child(n+5) { display: none; }
+ .hh-stats { display: flex; overflow-x: auto; scrollbar-width: none; gap: 8px; margin-left: -16px; margin-right: -16px; padding: 0 16px 2px; }
+ .hh-stats::-webkit-scrollbar { display: none; }
+ .hh-stats li { flex: 0 0 auto; min-width: 128px; }
+}
@@ -352,10 +352,11 @@ function front({ plans, providers, promos: live, stats, offers: recent = [], dom
@@ -352,10 +352,11 @@ function front({ plans, providers, promos: live, stats, offers: recent = [], dom
title: 'Hosting, compared honestly.',
title: 'Hosting, compared honestly.',
accent: 'Every price dated and sourced.',
accent: 'Every price dated and sourced.',
lede: 'Cloud, VPS and dedicated plans from providers\' official APIs, side by side: price per month, per vCPU and per GB, the day each price was checked and a link to where it came from. Sorted by what you ask for, never by who pays.',
lede: 'Cloud, VPS and dedicated plans from providers\' official APIs, side by side: price per month, per vCPU and per GB, the day each price was checked and a link to where it came from. Sorted by what you ask for, never by who pays.',
- actions: [{ label: 'Compare plans', href: '/catalog', primary: true }, { label: 'Domain prices', href: '/catalog/domains' }, { label: 'Latest offers', href: '/catalog/offers' }],
+ // Two, so they sit side by side on a phone; the latest offers have their own section and link below.
+ actions: [{ label: 'Compare plans', href: '/catalog', primary: true }, { label: 'Domain prices', href: '/catalog/domains' }],
note: stats.plans ? `${stats.plans} plans from ${stats.providers} provider${stats.providers === 1 ? '' : 's'} so far. More providers join as their sources are checked.` : 'The catalog is filling up: providers join as their official sources are checked and enabled.',
note: stats.plans ? `${stats.plans} plans from ${stats.providers} provider${stats.providers === 1 ? '' : 's'} so far. More providers join as their sources are checked.` : 'The catalog is filling up: providers join as their official sources are checked and enabled.',
aside: aside ? { html: aside } : undefined,
aside: aside ? { html: aside } : undefined,
- }) + extra.stats + `<section class="sc-sec" aria-labelledby="hh-cheapest"><h2 id="hh-cheapest">The lowest monthly prices</h2>${planTable(plans.slice(0, 8), { caption: 'Lowest price first' })}
+ }) + extra.stats + `<section class="sc-sec hh-short" aria-labelledby="hh-cheapest"><h2 id="hh-cheapest">The lowest monthly prices</h2>${planTable(plans.slice(0, 8), { caption: 'Lowest price first' })}
<p class="hc-more">${link('/catalog', 'Filter and sort every plan →', 'button')}</p></section>`
<p class="hc-more">${link('/catalog', 'Filter and sort every plan →', 'button')}</p></section>`
+ extra.sizes + extra.value + extra.providers
+ extra.sizes + extra.value + extra.providers
+ domainSection
+ domainSection
@@ -160,8 +160,8 @@ function frontSection({ popular = [], cheap = [], stats }) {
@@ -160,8 +160,8 @@ function frontSection({ popular = [], cheap = [], stats }) {
return `<section class="sc-sec hd-front" aria-labelledby="hd-front-h"><h2 id="hd-front-h">Domain names, compared too</h2>
return `<section class="sc-sec hd-front" aria-labelledby="hd-front-h"><h2 id="hd-front-h">Domain names, compared too</h2>
<p class="hc-dim">${stats.tlds ? `${stats.tlds.toLocaleString('en')} endings${registrars > 1 ? ` from ${registrars} registrars (${stats.registrars.map(esc).join(', ')})` : ''}, with the first year, the renewal and five years side by side. ` : ''}Check a name at its registry, then register it where it costs least.</p>
<p class="hc-dim">${stats.tlds ? `${stats.tlds.toLocaleString('en')} endings${registrars > 1 ? ` from ${registrars} registrars (${stats.registrars.map(esc).join(', ')})` : ''}, with the first year, the renewal and five years side by side. ` : ''}Check a name at its registry, then register it where it costs least.</p>
${checkForm({})}
${checkForm({})}
-${tldTable(popular.slice(0, 6), { caption: 'Popular endings: the cheapest price at any registrar' })}
-${cheap.length ? tldTable(cheap.slice(0, 6), { caption: 'The cheapest first year right now: check what it renews at' }) : ''}
+<div class="hh-short">${tldTable(popular.slice(0, 6), { caption: 'Popular endings: the cheapest price at any registrar' })}</div>
+${cheap.length ? '<div class="hh-short">' + tldTable(cheap.slice(0, 6), { caption: 'The cheapest first year right now: check what it renews at' }) + '</div>' : ''}
${stats.tlds ? `<p class="hc-more">${link('/catalog/domains', 'Every ending, by price →', 'button')}</p>` : ''}</section>`;
${stats.tlds ? `<p class="hc-more">${link('/catalog/domains', 'Every ending, by price →', 'button')}</p>` : ''}</section>`;
}
}
@@ -19,7 +19,7 @@ const BUDGETS = {
@@ -19,7 +19,7 @@ const BUDGETS = {
jsBrotliKB: 76, // 74.2 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; 70.5 Shared 4.17.0: OpenCoins and Vibes chips (wallet: true) in the navbar; 67.9 openvibe-shared 4.15 footer: the compact footer opens into the whole one, and the pulse line; 65.3 Shared 4.12.0: the light/dark switch, the seasonal mark and the theme pairs; 61.7 with shared 4.11.0's seasonal navbar; 56.3 (was 49.9)
jsBrotliKB: 76, // 74.2 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; 70.5 Shared 4.17.0: OpenCoins and Vibes chips (wallet: true) in the navbar; 67.9 openvibe-shared 4.15 footer: the compact footer opens into the whole one, and the pulse line; 65.3 Shared 4.12.0: the light/dark switch, the seasonal mark and the theme pairs; 61.7 with shared 4.11.0's seasonal navbar; 56.3 (was 49.9)
cssFiles: 3, // 3 (host.css, openvibe-shared showcase.css, catalog.css: the front page is the hosting catalog since Host#69)
cssFiles: 3, // 3 (host.css, openvibe-shared showcase.css, catalog.css: the front page is the hosting catalog since Host#69)
cssRawKB: 51, // 46.2 openvibe-shared 4.26.1 (hero visual); 40.7 with Shared 4.13.0 (2026-10-26: account links); 34.8 on 2026-10-22 (the front page's cards and questions); 31.9 (2026-10-16 the domain comparison's and benchmarks' styles; 27.2 with showcase.css 4.1.5, 14.8 before catalog.css)
cssRawKB: 51, // 46.2 openvibe-shared 4.26.1 (hero visual); 40.7 with Shared 4.13.0 (2026-10-26: account links); 34.8 on 2026-10-22 (the front page's cards and questions); 31.9 (2026-10-16 the domain comparison's and benchmarks' styles; 27.2 with showcase.css 4.1.5, 14.8 before catalog.css)
- cssBrotliKB: 10, // 8.3 with Shared 4.13.0 (2026-10-26: account links); 6.9 (5.7 before the domain and benchmark styles, 3.6 before catalog.css)
+ cssBrotliKB: 10.5, // 10.1 with the phone rules that show four rows of each front-page list (2026-10-29); 8.3 with Shared 4.13.0 (2026-10-26: account links); 6.9 (5.7 before the domain and benchmark styles, 3.6 before catalog.css)
externalFiles: 1, // 0
externalFiles: 1, // 0
};
};