Public Access
fix(bf): page-scoped CRO fixes on /odoo-black-friday/ (deal price, one deal buy, live countdown)
Fix 1: the On the Rise pricing card quoted $395 while the deal block said $295 first year — a price contradiction within one scroll. On this page only the card now reads $295.00 / 'for your first year, then $395 a year'. Other pages keep $395. JSON-LD Offer price was already 295.00 and still matches the visible price. Fix 2: the three list-price Buy Now buttons (data-id 6/4/5) competed with the deal. Side Hustle and Powerhouse buy buttons removed on this page. The On the Rise card's buy is now the deal purchase — the same one-click checkout as the offer block (product 4, /coupon/HOST27?r=/shop/checkout), native POST so it works with JS off. Tracking: the offer-block form is the single element carrying the Plausible Buy class; the Bootcamp CTA and the two list-price buttons no longer carry it. Fix 10: a time-remaining element near the offer and near the buy, computed client-side from one documented constant (2026-11-30T23:59:59-05:00, US/Eastern). The static sentence 'Ends Monday 30 November 2026.' still reads with JS off; past the instant the text switches to the past tense. No visibility animation.
This commit is contained in:
1 parent
46b943bffe
commit
ec6e496900
2 files changed
+92
-8
No files matched your search
@@ -204,6 +204,27 @@
|
|||||||
color: var(--ink-soft);
|
color: var(--ink-soft);
|
||||||
margin: 0 0 1.25rem;
|
margin: 0 0 1.25rem;
|
||||||
}
|
}
|
||||||
|
/* Time remaining (Fix 10). The day count is written into the span by /static/black-friday.js
|
||||||
|
from one documented end instant. The span is empty until then, so with JavaScript off the
|
||||||
|
static sentence "Ends Monday 30 November 2026." still carries the deadline on its own.
|
||||||
|
No visibility/opacity animation touches this element. */
|
||||||
|
.bf-days {
|
||||||
|
font-weight: 600;
|
||||||
|
color: var(--ink);
|
||||||
|
}
|
||||||
|
.bf-days-line {
|
||||||
|
margin: 0 0 0.75rem;
|
||||||
|
font-size: 0.85rem;
|
||||||
|
color: var(--ink-soft);
|
||||||
|
}
|
||||||
|
.pcard-buy {
|
||||||
|
margin: 0;
|
||||||
|
}
|
||||||
|
/* Fix 1: the deal card's year-one framing is a sentence, not a "/ year" tag — give it its own
|
||||||
|
line instead of wrapping mid-phrase beside the number. */
|
||||||
|
.pcard.featured .price small {
|
||||||
|
display: block;
|
||||||
|
}
|
||||||
.bf-cta {
|
.bf-cta {
|
||||||
margin: 0;
|
margin: 0;
|
||||||
}
|
}
|
||||||
@@ -550,7 +571,9 @@
|
|||||||
<!-- mechanism string, used verbatim — see §3. The code is the offer surface: it stays out
|
<!-- mechanism string, used verbatim — see §3. The code is the offer surface: it stays out
|
||||||
of meta, alt text, structured data and build comments. -->
|
of meta, alt text, structured data and build comments. -->
|
||||||
<p class="bf-mechanism bf-code-wrap"><span class="bf-code-label">Your code</span><span class="bf-code">HOST27</span><span class="bf-code-note">takes $100 off your first year at checkout. One redemption per customer.</span></p>
|
<p class="bf-mechanism bf-code-wrap"><span class="bf-code-label">Your code</span><span class="bf-code">HOST27</span><span class="bf-code-note">takes $100 off your first year at checkout. One redemption per customer.</span></p>
|
||||||
<p class="bf-deadline">Ends Monday 30 November 2026.</p>
|
<!-- Fix 10: the static deadline sentence stands alone with JavaScript off; the day count
|
||||||
|
is appended by /static/black-friday.js. -->
|
||||||
|
<p class="bf-deadline">Ends Monday 30 November 2026. <span class="bf-days" data-bf-days></span></p>
|
||||||
<!-- Buy = CLICK PROXY (offer-CTA click), NOT a sale.
|
<!-- Buy = CLICK PROXY (offer-CTA click), NOT a sale.
|
||||||
See wiki/concepts/conversion-tracking-contract. The form posts the On the Rise
|
See wiki/concepts/conversion-tracking-contract. The form posts the On the Rise
|
||||||
product (id 4) straight to the shop basket, so one click lands the visitor in
|
product (id 4) straight to the shop basket, so one click lands the visitor in
|
||||||
@@ -733,7 +756,9 @@
|
|||||||
<small class="price-period">/ year</small>
|
<small class="price-period">/ year</small>
|
||||||
</div>
|
</div>
|
||||||
<p class="desc">"ODOO Standard .. that is all my business needs"</p>
|
<p class="desc">"ODOO Standard .. that is all my business needs"</p>
|
||||||
<a href="javascript:void(0)" class="btn btn-brass btn-buy plausible-event-name=Buy" data-id="6">Buy Now</a>
|
<!-- Fix 2 (this page only): the list-price buy buttons are removed here. They are
|
||||||
|
not what paid traffic came for, and a list-price purchase must not sit one
|
||||||
|
click away beside the deal. The plan stays as a price anchor. -->
|
||||||
<ul>
|
<ul>
|
||||||
<li><i class="fas fa-check" style="color: var(--success)"></i> Launch Odoo CE in 5 minutes</li>
|
<li><i class="fas fa-check" style="color: var(--success)"></i> Launch Odoo CE in 5 minutes</li>
|
||||||
<li><i class="fas fa-check" style="color: var(--success)"></i> Automatic backups — no remembering</li>
|
<li><i class="fas fa-check" style="color: var(--success)"></i> Automatic backups — no remembering</li>
|
||||||
@@ -746,12 +771,29 @@
|
|||||||
<div class="pcard featured">
|
<div class="pcard featured">
|
||||||
<div class="pcard-body">
|
<div class="pcard-body">
|
||||||
<h3>On the Rise</h3>
|
<h3>On the Rise</h3>
|
||||||
|
<!-- Fix 1 (this page only): the card must agree with the offer block above. On this
|
||||||
|
page the On the Rise card shows the Black Friday price — $295 for the first year,
|
||||||
|
then the $395 list price. $395 remains correct on every other page. -->
|
||||||
<div class="price">
|
<div class="price">
|
||||||
<strong>$ 395.00</strong>
|
<strong>$ 295.00</strong>
|
||||||
<small class="price-period">/ year</small>
|
<small class="price-period">for your first year, then $395 a year</small>
|
||||||
</div>
|
</div>
|
||||||
<p class="desc">"I need some modules and professional reports"</p>
|
<p class="desc">"I need some modules and professional reports"</p>
|
||||||
<a href="javascript:void(0)" class="btn btn-brass btn-buy plausible-event-name=Buy" data-id="4">Buy Now</a>
|
<!-- Fix 2: the On the Rise buy is the Black Friday deal purchase — the same one-click
|
||||||
|
checkout as the offer block above (product 4, coupon HOST27 auto-applied,
|
||||||
|
redirect to /shop/checkout). Native POST form, so it works with JavaScript off.
|
||||||
|
Deliberately NOT marked with the Plausible Buy goal class: the offer-block form
|
||||||
|
above is the single Buy-marked element on this page, so the click proxy counts
|
||||||
|
one deal intent, not two. -->
|
||||||
|
<form method="post" action="https://20.odoo4projects.com/shop/post_basket" target="_blank" class="pcard-buy">
|
||||||
|
<input type="hidden" name="basket" value='[{"product_id":4,"qty":1}]' />
|
||||||
|
<input type="hidden" name="clear" value="1" />
|
||||||
|
<input type="hidden" name="redirect" value="/coupon/HOST27?r=/shop/checkout" />
|
||||||
|
<button type="submit" class="btn btn-brass">Buy On the Rise — $295 first year</button>
|
||||||
|
</form>
|
||||||
|
<!-- Fix 10: time remaining, filled in by /static/black-friday.js from one documented
|
||||||
|
end instant. Empty with JavaScript off. -->
|
||||||
|
<p class="bf-days-line"><span class="bf-days" data-bf-days></span></p>
|
||||||
<ul>
|
<ul>
|
||||||
<li><i class="fas fa-check" style="color: var(--success)"></i> Launch Odoo CE in 5 minutes</li>
|
<li><i class="fas fa-check" style="color: var(--success)"></i> Launch Odoo CE in 5 minutes</li>
|
||||||
<li><i class="fas fa-check" style="color: var(--success)"></i> Automatic backups — no remembering</li>
|
<li><i class="fas fa-check" style="color: var(--success)"></i> Automatic backups — no remembering</li>
|
||||||
@@ -770,7 +812,7 @@
|
|||||||
<small class="price-period">/ year</small>
|
<small class="price-period">/ year</small>
|
||||||
</div>
|
</div>
|
||||||
<p class="desc">"ODOO Enterprise is a must have!"</p>
|
<p class="desc">"ODOO Enterprise is a must have!"</p>
|
||||||
<a href="javascript:void(0)" class="btn btn-brass btn-buy plausible-event-name=Buy" data-id="5">Buy Now</a>
|
<!-- Fix 2 (this page only): list-price buy button removed — see the Side Hustle card. -->
|
||||||
<ul>
|
<ul>
|
||||||
<li><i class="fas fa-check" style="color: var(--success)"></i> Launch Odoo CE in 5 minutes</li>
|
<li><i class="fas fa-check" style="color: var(--success)"></i> Launch Odoo CE in 5 minutes</li>
|
||||||
<li><i class="fas fa-check" style="color: var(--success)"></i> Automatic backups — no remembering</li>
|
<li><i class="fas fa-check" style="color: var(--success)"></i> Automatic backups — no remembering</li>
|
||||||
@@ -856,8 +898,11 @@
|
|||||||
<p class="bf-mechanism">Black Friday: <strong>a second year of hosted Odoo Community Edition</strong>. One redemption per customer.<!-- OPEN-SLOT: bootcamp Black Friday price line --></p>
|
<p class="bf-mechanism">Black Friday: <strong>a second year of hosted Odoo Community Edition</strong>. One redemption per customer.<!-- OPEN-SLOT: bootcamp Black Friday price line --></p>
|
||||||
<p class="bf-deadline">Ends Monday 30 November 2026.</p>
|
<p class="bf-deadline">Ends Monday 30 November 2026.</p>
|
||||||
<!-- Buy = CLICK PROXY (offer-CTA click), NOT a sale. The real purchase event is fired on the
|
<!-- Buy = CLICK PROXY (offer-CTA click), NOT a sale. The real purchase event is fired on the
|
||||||
checkout host (20.odoo4projects.com) by odoo-dev. See wiki/concepts/conversion-tracking-contract. -->
|
checkout host (20.odoo4projects.com) by odoo-dev. See wiki/concepts/conversion-tracking-contract.
|
||||||
<p class="bf-cta"><a class="plausible-event-name=Buy" href="/odoo-erp-automation-bootcamp/">See the Bootcamp and what you build</a></p>
|
Fix 2: the existing Plausible Buy goal class was removed here — this is a
|
||||||
|
navigation link to the Bootcamp page, not a deal purchase, and the deal purchase
|
||||||
|
(the Hosting form above) is the single element that may carry the class. -->
|
||||||
|
<p class="bf-cta"><a href="/odoo-erp-automation-bootcamp/">See the Bootcamp and what you build</a></p>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
@@ -423,4 +423,43 @@
|
|||||||
observer.observe(g);
|
observer.observe(g);
|
||||||
});
|
});
|
||||||
})();
|
})();
|
||||||
|
|
||||||
|
/* ---- Black Friday time remaining (Fix 10) ----
|
||||||
|
ONE documented constant: the instant the offer ends — 30 November 2026, end of day, in the
|
||||||
|
account's US/Eastern context (EST, UTC-5, after the 1 Nov DST change). The day count is
|
||||||
|
computed client-side from this instant on every page load; it is NEVER hard-coded, so it
|
||||||
|
stays correct as the date changes.
|
||||||
|
|
||||||
|
Fail-safe: the HTML carries the static sentence "Ends Monday 30 November 2026." with an empty
|
||||||
|
span beside it, so with JavaScript off the deadline still reads correctly on its own. Once the
|
||||||
|
end instant has passed the text switches to the past tense — it never keeps claiming time
|
||||||
|
remains. Nothing here animates visibility. */
|
||||||
|
(function () {
|
||||||
|
var BF_END = new Date('2026-11-30T23:59:59-05:00');
|
||||||
|
var DAY = 86400000;
|
||||||
|
var nodes = document.querySelectorAll('[data-bf-days]');
|
||||||
|
if (!nodes.length) return;
|
||||||
|
|
||||||
|
/* Whole calendar days in US/Eastern, so "days left" is a date difference and not a 24-hour
|
||||||
|
window (the offer ends at the end of a day, not 28 x 24h from now). */
|
||||||
|
function easternDayNumber(d) {
|
||||||
|
var parts = new Intl.DateTimeFormat('en-CA', {
|
||||||
|
timeZone: 'America/New_York', year: 'numeric', month: '2-digit', day: '2-digit'
|
||||||
|
}).format(d).split('-');
|
||||||
|
return Date.UTC(parseInt(parts[0], 10), parseInt(parts[1], 10) - 1, parseInt(parts[2], 10)) / DAY;
|
||||||
|
}
|
||||||
|
|
||||||
|
var daysLeft = easternDayNumber(BF_END) - easternDayNumber(new Date());
|
||||||
|
var text;
|
||||||
|
if (daysLeft > 1) {
|
||||||
|
text = daysLeft + ' days left';
|
||||||
|
} else if (daysLeft === 1) {
|
||||||
|
text = '1 day left';
|
||||||
|
} else if (daysLeft === 0) {
|
||||||
|
text = 'last day today';
|
||||||
|
} else {
|
||||||
|
text = 'this offer has ended';
|
||||||
|
}
|
||||||
|
nodes.forEach(function (n) { n.textContent = text; });
|
||||||
|
})();
|
||||||
})();
|
})();
|
||||||
Reference in new issue
Block a user