feat(bf): show the code on arrival and buy in one click on /odoo-black-friday/

The code was behind a reveal (click 'Open the Black Friday price'). Both offer
cards are now always open: the price and HOST27 are readable without any
interaction. The scroll animation (opacity/transform only, base state fully
opaque, behind @supports) is presentation, never a gate.

The hosting CTA is now a native form that posts the On the Rise product straight
to the shop basket, so one click from the page lands in checkout with the plan in
the cart — replacing a three-navigation detour (offers hub -> homepage trial ->
pricing).

Bootcamp box content is untouched; only its reveal gate was removed.
This commit is contained in:
webmaster committed 2026-11-01 23:10:54 +00:00
1 parent 4801e09466
commit 3e2a7a71a6
1 file changed
+129 -97
+129 -97
View File
@@ -152,56 +152,16 @@
margin-bottom: 1.25rem; margin-bottom: 1.25rem;
} }
/* Reveal mechanic — native <details>/<summary>: the panel is in the DOM in both states, /* Both offer cards are always open: the Black Friday price and the code are readable on
keyboard-operable, and works with JavaScript disabled. CSS reveals it; JS only mirrors arrival, with no reveal and no click. The scroll animation further down is presentation
the open state to aria-expanded. The panel is never display:none by our stylesheet. */ only — the base state is fully visible, so the offer is complete with JavaScript off,
.bf-reveal { under reduced motion, or if the animation never runs. */
border-top: 1px solid var(--line);
}
.bf-reveal-summary {
cursor: pointer;
list-style: none;
display: block;
padding: 1.25rem 0 1rem;
}
.bf-reveal-summary::-webkit-details-marker {
display: none;
}
.bf-reveal-summary:focus-visible {
outline: 2px solid var(--brass);
outline-offset: 3px;
border-radius: var(--radius);
}
.bf-teaser { .bf-teaser {
font-size: 1.02rem; font-size: 1.02rem;
color: var(--ink); color: var(--ink);
line-height: 1.6; line-height: 1.6;
margin: 0 0 1rem; margin: 0 0 1rem;
} }
.bf-open-label {
display: inline-flex;
align-items: center;
gap: 0.5rem;
font-family: Inter, sans-serif;
font-weight: 600;
font-size: 0.82rem;
letter-spacing: 0.04em;
text-transform: uppercase;
color: var(--midnight);
background: var(--brass);
border-radius: var(--radius-pill);
padding: 0.6rem 1.25rem;
}
.bf-open-label::after {
content: "+";
font-size: 1.05rem;
line-height: 1;
}
/* closed state only: the label is the invitation, so it goes once the panel is open.
`[open]` is set by the browser natively — this needs no JavaScript. */
.bf-reveal[open] .bf-open-label {
display: none;
}
.bf-panel { .bf-panel {
padding: 0.25rem 0 1.25rem; padding: 0.25rem 0 1.25rem;
border-top: 1px solid var(--line); border-top: 1px solid var(--line);
@@ -236,6 +196,62 @@
.bf-mechanism strong { .bf-mechanism strong {
color: var(--midnight); color: var(--midnight);
} }
/* The code lives on the offer surface only. It is readable on arrival; the chip is easy to
select so it can be copied at checkout. */
.bf-code-wrap {
display: flex;
flex-wrap: wrap;
align-items: baseline;
gap: 0.4rem 0.7rem;
}
.bf-code-label {
font-family: Inter, sans-serif;
font-weight: 600;
font-size: 0.72rem;
letter-spacing: 0.08em;
text-transform: uppercase;
color: var(--brass-deep);
}
.bf-code {
font-family: Marcellus, Georgia, serif;
font-size: 1.3rem;
letter-spacing: 0.12em;
color: var(--midnight);
background: var(--brass);
border-radius: var(--radius-pill);
padding: 0.2rem 0.9rem;
user-select: all;
}
.bf-code-note {
font-size: 0.9rem;
color: var(--ink-soft);
}
/* Presentation only: the code fades and rises a little as it scrolls into view. Opacity and
transform only — never visibility. The base state is fully opaque, so a build where the
animation never fires still shows the code. Everything here is behind @supports, so an
unsupported browser renders the static, visible code. */
@media (prefers-reduced-motion: no-preference) {
@supports (animation-timeline: view()) {
.bf-code {
animation-name: bf-code-in;
animation-timing-function: linear;
animation-fill-mode: both;
animation-duration: auto;
animation-timeline: view();
animation-range: entry 0% cover 45%;
}
}
}
@keyframes bf-code-in {
from {
opacity: 0.8;
transform: translateY(8px);
}
to {
opacity: 1;
transform: translateY(0);
}
}
.bf-deadline { .bf-deadline {
font-size: 0.85rem; font-size: 0.85rem;
color: var(--ink-soft); color: var(--ink-soft);
@@ -264,6 +280,41 @@
outline: 3px solid var(--midnight); outline: 3px solid var(--midnight);
outline-offset: 2px; outline-offset: 2px;
} }
/* Hosting CTA: a native form that posts the plan straight to the shop basket, so one click
from this page lands the visitor in checkout with the plan already in the cart. Works with
JavaScript off (it is a plain form POST). */
.bf-cta-form {
margin: 0 0 0.75rem;
}
.bf-cta-form .btn {
display: inline-block;
font-family: Marcellus, Georgia, serif;
font-size: 0.9rem;
letter-spacing: 0.04em;
color: var(--midnight);
background: var(--brass);
border: 0;
border-radius: var(--radius-pill);
padding: 0.8rem 1.75rem;
cursor: pointer;
}
.bf-cta-form .btn:hover {
background: var(--brass-bright);
color: var(--midnight);
}
.bf-cta-form .btn:focus-visible {
outline: 3px solid var(--midnight);
outline-offset: 2px;
}
.bf-cta-secondary {
font-size: 0.85rem;
margin: 0;
}
.bf-cta-secondary a {
color: var(--brass-deep);
text-decoration: underline;
text-underline-offset: 3px;
}
/* FAQ (native details/summary — no JS) */ /* FAQ (native details/summary — no JS) */
.cmp-faq-grid { .cmp-faq-grid {
@@ -523,53 +574,50 @@
</div> </div>
</section> </section>
<!-- The two Black Friday offers — one section, two boxes, Bootcamp first. Each box carries the <!-- The two Black Friday offers — one section, two boxes, Bootcamp first. Both cards are always
same reveal mechanic: a native <details class="bf-reveal"> with a closed teaser <summary>, open: the price and the code are readable on arrival, with no reveal and no click. -->
then the open panel. -->
<section class="section-light bf-box" id="offer"> <section class="section-light bf-box" id="offer">
<div class="container"> <div class="container">
<!-- Box 1 — Bootcamp --> <!-- Box 1 — Bootcamp -->
<div class="bf-box-inner"> <div class="bf-box-inner">
<h2 class="bf-box-title">Bootcamp: ten live sessions to a working system</h2> <h2 class="bf-box-title">Bootcamp: ten live sessions to a working system</h2>
<details class="bf-reveal"> <div class="bf-panel">
<summary class="bf-reveal-summary" aria-expanded="false"> <p class="bf-teaser">A working system for your business in ten live sessions, USD 595 — with a second hosted year added for Black Friday.</p>
<p class="bf-teaser">A working system for your business in ten live sessions, USD 595. Open to see the Black Friday offer.</p> <p class="bf-price"><strong>USD 595.00</strong> for the full programme. Black Friday adds <strong>a second year of hosted Odoo Community Edition</strong>, on top of the one already included.</p>
<span class="bf-open-label">Open the Black Friday offer</span> <p class="bf-included">Ten live Thursday sessions, 18:00–19:00 Central Time, starting Thursday 21 January 2027. Six seats, and no more. Your first hosted year is included as standard; the second year is the Black Friday add-on.</p>
</summary> <!-- Bootcamp mechanism string — ONE reusable line, isolated exactly as the Hosting box's is
<div class="bf-panel"> (copy §3b). Whether the discount code applies to the Bootcamp is UNCONFIRMED
<p class="bf-price"><strong>USD 595.00</strong> for the full programme. Black Friday adds <strong>a second year of hosted Odoo Community Edition</strong>, on top of the one already included.</p> (BOOTCAMP-CONFIRM), so the discounted figure stays a build placeholder and is NOT
<p class="bf-included">Ten live Thursday sessions, 18:00–19:00 Central Time, starting Thursday 21 January 2027. Six seats, and no more. Your first hosted year is included as standard; the second year is the Black Friday add-on.</p> printed. Swap this one line when it is confirmed. -->
<!-- Bootcamp mechanism string — ONE reusable line, isolated exactly as the Hosting box's is <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>
(copy §3b). Whether the discount code applies to the Bootcamp is UNCONFIRMED <p class="bf-deadline">Ends Monday 30 November 2026.</p>
(BOOTCAMP-CONFIRM), so the discounted figure stays a build placeholder and is NOT <!-- Buy = CLICK PROXY (offer-CTA click), NOT a sale. The real purchase event is fired on the
printed. Swap this one line when it is confirmed. --> checkout host (20.odoo4projects.com) by odoo-dev. See wiki/concepts/conversion-tracking-contract. -->
<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-cta"><a class="plausible-event-name=Buy" href="/odoo-erp-automation-bootcamp/">See the Bootcamp and what you build</a></p>
<p class="bf-deadline">Ends Monday 30 November 2026.</p> </div>
<!-- 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. -->
<p class="bf-cta"><a class="plausible-event-name=Buy" href="/odoo-erp-automation-bootcamp/">See the Bootcamp and what you build</a></p>
</div>
</details>
</div> </div>
<!-- Box 2 — Hosting, On the Rise --> <!-- Box 2 — Hosting, On the Rise -->
<div class="bf-box-inner"> <div class="bf-box-inner">
<h2 class="bf-box-title">Hosting: On the Rise</h2> <h2 class="bf-box-title">Hosting: On the Rise</h2>
<details class="bf-reveal"> <div class="bf-panel">
<summary class="bf-reveal-summary" aria-expanded="false"> <p class="bf-teaser">Your whole business in one system. The Black Friday price is right here — no code to hunt for.</p>
<p class="bf-teaser">Your whole business in one system, $395 a year. Open to see the Black Friday price.</p> <p class="bf-price"><strong>$395.00</strong> a year — <strong>$295.00</strong> for your first year.</p>
<span class="bf-open-label">Open the Black Friday price</span> <p class="bf-included">Then it renews at the $395 list price. One yearly price, no per-user licence, no setup fee. We run the server, the backups, your certificate and the version upgrades for you.</p>
</summary> <!-- mechanism string, used verbatim — see §3. The code is the offer surface: it stays out
<div class="bf-panel"> of meta, alt text, structured data and build comments. -->
<p class="bf-price"><strong>$395.00</strong> a year — <strong>$295.00</strong> for your first year.</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-included">Then it renews at the $395 list price. One yearly price, no per-user licence, no setup fee. We run the server, the backups, your certificate and the version upgrades for you.</p> <p class="bf-deadline">Ends Monday 30 November 2026.</p>
<!-- mechanism string, used verbatim — see §3 --> <!-- Buy = CLICK PROXY (offer-CTA click), NOT a sale (see the other box on this page).
<p class="bf-mechanism">Black Friday: <strong>$100 off your first year</strong> with code <strong>HOST27</strong>. One redemption per customer.</p> The form posts the On the Rise product (id 4) straight to the shop basket, so one
<p class="bf-deadline">Ends Monday 30 November 2026.</p> click lands the visitor in checkout with the plan already in the cart. -->
<!-- Buy = CLICK PROXY (offer-CTA click), NOT a sale (see the other box on this page). --> <form method="post" action="https://20.odoo4projects.com/shop/post_basket" target="_blank" class="bf-cta-form plausible-event-name=Buy">
<p class="bf-cta"><a class="plausible-event-name=Buy" href="/odoo-hosting-offers/">See what a year of hosting includes</a></p> <input type="hidden" name="basket" value='[{"product_id":4,"qty":1}]' />
</div> <input type="hidden" name="clear" value="1" />
</details> <button type="submit" class="btn btn-brass btn-lg">Buy On the Rise — $295 first year</button>
</form>
<p class="bf-cta-secondary"><a href="/odoo-hosting-offers/">See everything a year of hosting includes</a></p>
</div>
</div> </div>
</div> </div>
</section> </section>
@@ -661,21 +709,5 @@
<div class="fcopy">Copyright &copy; ODOO4projects LLC</div> <div class="fcopy">Copyright &copy; ODOO4projects LLC</div>
</div> </div>
</footer> </footer>
<script>
/* Enhancement only: mirror each reveal's open state to aria-expanded. Without JS the native
<details> still toggles, keyboard-operable, and exposes its state. */
(function () {
var reveals = document.querySelectorAll(".bf-reveal");
Array.prototype.forEach.call(reveals, function (reveal) {
var summary = reveal.querySelector("summary");
function sync() {
if (summary) summary.setAttribute("aria-expanded", reveal.open ? "true" : "false");
}
sync();
reveal.addEventListener("toggle", sync);
});
})();
</script>
</body> </body>
</html> </html>