openvibers/openvibe.coupons Commits

Home: a taste and a door on phones (#140)

OP OpenVibers committed 15 days ago · 14689657f4 · 3 files, +21 −6

Each list of codes is one row that scrolls sideways on a phone (every code is
still there), the figures are one strip, what every code tells you folds under
its heading, the closing call that repeated the hero (submit) and the network
block (Deals) goes, and the hero has two actions; the extension has its own
section. CSS raw budget 67 -> 68 (measured 67.9).

Changes

ddiff --git a/public/css/coupons.css b/public/css/coupons.css
iindex 6eb05db..d5d28f4 100644
---- a/public/css/coupons.css
++++ b/public/css/coupons.css
@@@ -103,6 +103,23 @@ button.primary { background: var(--accent-strong, #2563eb); border-color: var(--
.cp-faq p { margin: 0 0 14px; color: var(--text-secondary, #96a7c2); }
.cp-empty { margin-top: 24px; }
@media (max-width: 600px) { .cp-search { flex-wrap: wrap; } .cp-search button { width: 100%; } .cp-stats b { font-size: 1.3rem; } .cp-stats a { padding: 12px; } .cp-cards > li:nth-child(n+5) { display: none; } }
++/* The home on phones (2026-10-29): a taste and a door. Each list of codes is one sideways row (every code is still
++ there), the figures are one strip, and the explainer folds under its heading. */
++.cp-fold { border: 1px solid var(--border, #1f2d47); border-radius: 14px; background: var(--bg-card, #131c2e); }
++.cp-fold > summary { display: flex; align-items: center; justify-content: space-between; gap: 12px; min-height: 56px; padding: 0 18px; cursor: pointer; list-style: none; }
++.cp-fold > summary::-webkit-details-marker { display: none; }
++.cp-fold > summary h2 { margin: 0; }
++.cp-fold > summary span { color: var(--text-muted, #7386a3); font-weight: 600; font-size: .86rem; text-align: right; }
++.cp-fold > summary:focus-visible { outline: 2px solid var(--accent, #3b82f6); outline-offset: -2px; border-radius: 14px; }
++.cp-fold .sc-sec { max-width: none; margin: 0; padding: 0 18px 18px; }
++@media (max-width: 600px) {
++ .cp-sec .cp-cards, .cp-hero .cp-stats { display: flex; flex-wrap: nowrap; overflow-x: auto; scroll-snap-type: x mandatory; scroll-padding-inline: 16px; scrollbar-width: none; gap: 10px; margin-left: -16px; margin-right: -16px; padding: 0 16px 4px; }
++ .cp-sec .cp-cards::-webkit-scrollbar, .cp-hero .cp-stats::-webkit-scrollbar { display: none; }
++ .cp-sec .cp-cards > li { display: flex; flex: 0 0 84%; min-width: 0; scroll-snap-align: start; }
++ .cp-sec .cp-cards > li:nth-child(n+5) { display: flex; }
++ .cp-hero .cp-stats > li { flex: 0 0 auto; width: 132px; scroll-snap-align: start; }
++ .cp-fold > summary span { display: none; }
++}
@media (prefers-reduced-motion: reduce) { .cp-stats a { transition: none; } }
.home .page .sc-grid { grid-template-columns: repeat(auto-fit, minmax(min(100%, 240px), 1fr)); }
ddiff --git a/server/render/home.js b/server/render/home.js
iindex e9f1449..1ee0cb9 100644
---- a/server/render/home.js
++++ b/server/render/home.js
@@@ -81,7 +81,7 @@ function homePage(d) {
<h1>Coupon codes,<span class="sc-accent"> honestly labelled</span></h1>
<p class="sc-hero-lede">Codes for online shops, each with the deal it is for, its end date when one is stated and what people reported when they tried it. A code is called working only when people said so recently.</p>
<form method="get" action="/" class="search cp-search" role="search"><label class="sr-only" for="q">Find a shop by name or domain</label><input id="q" name="q" type="search" maxlength="60" placeholder="Find a shop, like amazon.com"><button type="submit" class="primary">Search</button></form>
--<div class="sc-actions"><a class="sc-btn sc-primary" href="#cp-new">See the newest codes</a><a class="sc-btn" href="/companion">Get the extension</a><a class="sc-btn" href="/submit">Submit a code</a></div>
++<div class="sc-actions"><a class="sc-btn sc-primary" href="#cp-new">See the newest codes</a><a class="sc-btn" href="/submit">Submit a code</a></div>
</div>
<div class="sc-hero-aside">${stats([
{ n: s.active, label: 'active codes', href: '#cp-new' },
@@@ -107,19 +107,17 @@ ${raw(showcase.features({
{ icon: 'ov:shield', title: 'No referral games', text: 'It never rewrites links or adds referral tags, so whoever sent you keeps the credit.', href: '/companion' },
],
}))}
--${raw(showcase.features({
-- title: 'What every code tells you',
++<section class="cp-sec" aria-labelledby="cp-tells"><details class="cp-fold"><summary><h2 id="cp-tells">What every code tells you</h2><span>the shop, the rules, the end, the reports</span></summary>${raw(showcase.features({
items: [
{ icon: 'ov:coupons', title: 'The right shop', text: 'Each shop lists the domains and paths it covers, so a code is matched to the site you are on.' },
{ icon: 'ov:docs', title: 'Restrictions stated', text: 'Minimum spend, new customers only, the products it applies to: written down, not hidden.' },
{ icon: 'ov:history', title: 'Honest expiry', text: 'An end date when someone stated one, and "No end date stated" when nobody did.', href: '/about#expiry' },
{ icon: 'ov:community', title: 'Reports from people', text: 'Worked or did not work, recently: the status comes from what people said when they tried it.', href: '/about#statuses' },
],
-- }))}
++ }))}</details></section>
<section class="cp-sec" aria-labelledby="cp-faq"><div class="cp-head"><h2 id="cp-faq">Questions and answers</h2></div>
<div class="cp-faq">${d.faq.map((x) => h`<details><summary>${x.q}</summary><p>${x.a}</p></details>`)}</div></section>
${raw(showcase.network({ service: 'coupons' }))}
--${raw(showcase.cta({ title: 'Have a code?', text: 'Share it with a link to where it was published. People report whether it works, and everyone sees what they said.', actions: [{ label: 'Submit a code', href: '/submit', primary: true }, { label: 'Find deals on OpenVibe.Deals', href: 'https://openvibe.deals/' }] }))}
<p class="meta"><a href="/about">How statuses and confidence work</a> · <a href="/feed.xml">RSS</a> · <a href="/atom.xml">Atom</a> · <a href="/feed.json">JSON Feed</a></p>`;
}
ddiff --git a/test/perf-budget.test.js b/test/perf-budget.test.js
iindex ab9aa1f..71da945 100644
---- a/test/perf-budget.test.js
++++ b/test/perf-budget.test.js
@@@ -18,7 +18,7 @@ const BUDGETS = {
jsRawKB: 320, // 319.8 with openvibe-shared 4.43.0 (room.css carries the kit tokens, 4.39.1; the kit's 4.39.0 rules); 312.4 openvibe-shared 4.29.2 (2026-10-28): Notifications 2.0's toast layer (held while a menu is open, grouping, priority, System cards) and the menu's results view; 307.6 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; 300.1 openvibe-shared 4.22.0: the navbar's magnifier search button and More dropdown (search.js and loading.js load only when used); 297.3 Shared 4.20.1: the kit's kit-web.js (copy buttons, menus, confirms; 7 KB) and 4.18-4.19's menu and footer; 287.2 Shared 4.17.0: OpenCoins and Vibes chips (wallet: true) in the navbar; 273.2 openvibe-shared 4.15 footer: the compact footer opens into the whole one, and the pulse line; 263.4 with shared 4.11.0's seasonal navbar; 254.1 with openvibe-shared 4.9.0 (status text twins in every theme, 2026-10-23); 246.2 with openvibe-shared 4.2.x (Ask Actor in the navbar, 2026-10-15); 239.1 (212.2 before the shell's web-runtime.js) // raised 316 -> 325 for the openvibe-shared Kit 2 pin (kit.css grew) // back to the pre-Kit 2 value: Kit 2 has its own files (kit-data.css) since openvibe-shared v4.37.0, so kit.css weighs what it did
jsBrotliKB: 80, // 79.3 with openvibe-shared 4.43.0 (room.css carries the kit tokens, 4.39.1; the kit's 4.39.0 rules); 76.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; 73.5 Shared 4.20.1 (kit-web.js); 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; 59.1 with openvibe-shared 4.4.0 (every site in the launcher, 2026-10-17); 56.3 (49.9 before web-runtime.js) // raised 78 -> 80 for the openvibe-shared Kit 2 pin (kit.css grew) // back to the pre-Kit 2 value: Kit 2 has its own files (kit-data.css) since openvibe-shared v4.37.0, so kit.css weighs what it did
cssFiles: 3, // 3 with the OpenVibe Kit's kit.css on every page (Shared 4.20); 2 (coupons.css + showcase.css, home only)
-- cssRawKB: 67, // 62.7 openvibe-shared 4.26.1 (hero visual); 58.4 with a code's reports over time (2026-10-28: weekly columns, legend, phone labels); 55.6 with the OpenVibe Kit's kit.css (Shared 4.20, 2026-10-28: the shop page's head, tabs, folds and menus); 28.2 with Shared 4.13.0 (2026-10-26: account links); 21.8 with the front page's numbers, tickets and questions (2026-10-22); 18.1 before (4.4 before showcase.css) // raised 67 -> 85 for the openvibe-shared Kit 2 pin (kit.css grew) // back to the pre-Kit 2 value: Kit 2 has its own files (kit-data.css) since openvibe-shared v4.37.0, so kit.css weighs what it did
++ cssRawKB: 68, // 67.9 the home's phone rows and fold (2026-10-29); 62.7 openvibe-shared 4.26.1 (hero visual); 58.4 with a code's reports over time (2026-10-28: weekly columns, legend, phone labels); 55.6 with the OpenVibe Kit's kit.css (Shared 4.20, 2026-10-28: the shop page's head, tabs, folds and menus); 28.2 with Shared 4.13.0 (2026-10-26: account links); 21.8 with the front page's numbers, tickets and questions (2026-10-22); 18.1 before (4.4 before showcase.css) // raised 67 -> 85 for the openvibe-shared Kit 2 pin (kit.css grew) // back to the pre-Kit 2 value: Kit 2 has its own files (kit-data.css) since openvibe-shared v4.37.0, so kit.css weighs what it did
cssBrotliKB: 14, // 12.9 openvibe-shared 4.26.1 (hero visual); 11.5 with kit.css (Shared 4.20); 6.2 with Shared 4.13.0 (2026-10-26: account links); 5.0 with the front page (2026-10-22); 3.6 before (1.2 before showcase.css) // raised 14 -> 17 for the openvibe-shared Kit 2 pin (kit.css grew) // back to the pre-Kit 2 value: Kit 2 has its own files (kit-data.css) since openvibe-shared v4.37.0, so kit.css weighs what it did
externalFiles: 1, // 0
};