openvibers/openvibe.deals Commits

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

OP OpenVibers committed 15 days ago · d6540732ad · 2 files, +19 −7

Each deal list and the campaigns are one row that scrolls sideways on a phone
(every card is still there), the category and shop clouds show ten each (all a
link away), the figures are one strip, how it works folds, the closing call that
repeated the hero goes, and the hero has two actions.

Changes

ddiff --git a/public/css/deals.css b/public/css/deals.css
iindex 00a0565..905f421 100644
---- a/public/css/deals.css
++++ b/public/css/deals.css
@@@ -174,4 +174,18 @@ code { overflow-wrap: anywhere; }
@media (prefers-reduced-motion: reduce) { .hm-card, .hm-stats a { transition: none; } }
.hm-card .price-none { font-size: .88rem; font-weight: 500; }
/* A phone shows four cards a section (all eight stay in the page for crawlers and the "see all" link has the rest). */
--@media (max-width: 600px) { .hm-cards > li:nth-child(n+5) { display: none; } }
++/* Phones (2026-10-29): a taste and a door. Each deal list and the campaigns are one row that scrolls sideways (every card
++ is still there), the clouds show ten each (all are a link away), the figures are one strip. */
++.hm-fold { margin: 48px 0 0; font-family: var(--ov-font, 'Inter', -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, sans-serif); border: 1px solid var(--border, #1f2d47); border-radius: 14px; background: var(--bg-card, #131c2e); }
++.hm-fold > summary { display: flex; align-items: center; justify-content: space-between; gap: 10px; min-height: 48px; padding: 0 16px; cursor: pointer; font-weight: 700; list-style: none; }
++.hm-fold > summary::-webkit-details-marker { display: none; }
++.hm-fold > summary span { color: var(--text-muted, #7386a3); font-weight: 600; font-size: .86rem; }
++.hm-fold > summary:focus-visible { outline: 2px solid var(--accent, #3b82f6); outline-offset: -2px; border-radius: 14px; }
++.hm-fold .sc-sec { margin: 0; max-width: none; padding: 0 16px 14px; }
++@media (max-width: 600px) {
++ .hm-cards, .hm-cf, .hm-stats { display: flex; 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; }
++ .hm-cards::-webkit-scrollbar, .hm-cf::-webkit-scrollbar, .hm-stats::-webkit-scrollbar { display: none; }
++ .hm-cards > li, .hm-cf > li { flex: 0 0 82%; scroll-snap-align: start; }
++ .hm-stats > li { flex: 0 0 auto; width: 132px; scroll-snap-align: start; }
++ .hm-chips > li:nth-child(n+11) { display: none; }
++}
ddiff --git a/server/render/home.js b/server/render/home.js
iindex c71c1b7..f8f42a6 100644
---- a/server/render/home.js
++++ b/server/render/home.js
@@@ -122,7 +122,7 @@ function homePage(d, urls) {
<h1>Today's deals,<span class="sc-accent"> with the time every price was seen</span></h1>
<p class="sc-hero-lede">Deals from DealNews' editors and from the OpenVibe community, by shop, category and end date. Every price says when it was seen, and an old one says it may be gone.</p>
<form class="hm-search" action="/search" method="get" role="search"><label class="sr" for="hm-q">Search deals</label><input id="hm-q" name="q" type="search" maxlength="100" placeholder="Search deals, like air fryer or lululemon"><button type="submit">Search</button></form>
--<div class="sc-actions"><a class="sc-btn sc-primary" href="/new">See the newest deals</a><a class="sc-btn" href="/watches">Watch a price</a><a class="sc-btn" href="/submit">Post a deal</a></div>
++<div class="sc-actions"><a class="sc-btn sc-primary" href="/new">See the newest deals</a><a class="sc-btn" href="/submit">Post a deal</a></div>
</div>
<div class="sc-hero-aside">${stats([
{ n: d.stats.active, label: 'active deals', href: '/new' },
@@@ -148,8 +148,7 @@ ${under ? section({ id: 'hm-under', title: `Under ${under}`, lede: `Deals with a
${section({ id: 'hm-categories', title: 'Browse by category', lede: 'Categories as each deal\'s source names them, the most deals first.', more: { href: '/c', label: 'All categories' }, body: chips(catLinks, 'deal') })}
${section({ id: 'hm-shops', title: 'Shop by store', lede: 'Where the deals are sold, as their sources name the shop.', more: { href: '/at', label: `All ${count(d.sellers.length)} shops` }, body: chips(shopLinks, 'deal') })}
${section({ id: 'hm-crowdfunding', title: 'Crowdfunding', lede: 'Open-source and community campaigns from Open Collective with what they received, plus one search across Kickstarter, Indiegogo, GoFundMe and more.', more: { href: '/crowdfunding', label: 'Search crowdfunding' }, body: d.campaigns.length ? html`<ol class="cf-grid hm-cf">${d.campaigns.map(campaignCard)}</ol>` : '' })}
--${raw(showcase.features({
-- title: 'How it works',
++<details class="hm-fold"><summary>How it works<span>prices, votes, shops, watches</span></summary>${raw(showcase.features({
lede: 'A deal is a link, a title and every price anyone saw for it, each with its source and time.',
items: [
{ icon: 'ov:history', title: 'Prices with their time', text: 'Each deal keeps every price it was seen at, newest first, each with its source. Nothing is called current without a fresh one.', href: '/new' },
@@@ -157,10 +156,9 @@ ${raw(showcase.features({
{ icon: 'ov:search', title: 'By shop and category', text: 'Every deal is filed under the shop that sells it and the category its source gives it.', href: '/at' },
{ icon: 'ov:bell', title: 'Watches and saved searches', text: 'Watch words, a product or a price limit for new prices that match, or save a search to run again.', href: '/watches' },
],
-- }))}
++ }))}</details>
${faq(d.faq)}
--${raw(showcase.network({ service: 'deals' }))}
--${raw(showcase.cta({ title: 'Know a good deal?', text: 'Post it with the price you see and the time is recorded with it. People vote, and the best rise to the top.', actions: [{ label: 'Post a deal', href: '/submit', primary: true }, { label: 'Find coupon codes on OpenVibe.Coupons', href: 'https://openvibe.coupons/' }] }))}`;
++${raw(showcase.network({ service: 'deals' }))}`;
}
module.exports = { homePage, faqItems, faqJsonLd, card, money };