Public Access
feat(bf): trial widget + booking link beside the HOST27 deal
On /odoo-black-friday/ the offer row is now two columns at >=901px: the deal (left, unchanged and still the single dominant primary) with the free trial and a booking link beside it (right, deliberately smaller and quieter). - Trial: the existing #trialCard/#trialForm moves verbatim from the features grid into the row's aside. Same ids, same static/black-friday.js handler, same consent gate and label (AW-18065522009/AtAPCIjjvrAdENn6p6ZD) — no second trial mechanism. - Booking: a plain <a target=_blank rel=noopener> to Oliver's verified Google appointment page (no iframe). Its click fires AW-18065522009/P0j5CPiCv7AdENn6p6ZD through the same gate via window.o4pAds.bookConversion; the click is never preventDefault-ed, so a blocked tag can never stop the link opening. - ads-consent.js gains the booking label (from the page, not hard-coded) and the bookConversion hook; the buy path is untouched. Deal buy stays the dominant action; ONE plausible Buy mark; one price; countdown pair unchanged.
This commit is contained in:
1 parent
7497fbf588
commit
95d5d455b9
3 files changed
+134
-13
No files matched your search
+104
-13
@@ -284,6 +284,65 @@
|
|||||||
text-underline-offset: 3px;
|
text-underline-offset: 3px;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* The offer row: the deal on the left, its two secondary actions (free trial + booking) on
|
||||||
|
the right. The deal keeps its full width and weight and stays the ONE dominant action;
|
||||||
|
the right column is deliberately narrower and quieter so the row never reads as three
|
||||||
|
equal primaries. At 901px and up the row is two columns; below that it stacks, deal
|
||||||
|
first. Scoped to #offer so the Bootcamp box further down is untouched. */
|
||||||
|
#offer .container {
|
||||||
|
grid-template-columns: minmax(0, 620px) minmax(0, 300px);
|
||||||
|
}
|
||||||
|
.bf-aside {
|
||||||
|
display: grid;
|
||||||
|
gap: 1.25rem;
|
||||||
|
align-content: start;
|
||||||
|
}
|
||||||
|
/* Booking: a quiet, secondary action on its own line — an outlined pill, never a second
|
||||||
|
brass button. */
|
||||||
|
.bf-booking {
|
||||||
|
background: var(--ivory);
|
||||||
|
border: 1px solid var(--line-brass);
|
||||||
|
border-radius: var(--radius-lg);
|
||||||
|
padding: 1.25rem;
|
||||||
|
text-align: center;
|
||||||
|
}
|
||||||
|
.bf-booking h3 {
|
||||||
|
font-family: Marcellus, Georgia, serif;
|
||||||
|
font-weight: 400;
|
||||||
|
font-size: 1rem;
|
||||||
|
color: var(--midnight);
|
||||||
|
margin: 0 0 0.35rem;
|
||||||
|
}
|
||||||
|
.bf-booking p {
|
||||||
|
font-size: 0.85rem;
|
||||||
|
color: var(--ink);
|
||||||
|
line-height: 1.5;
|
||||||
|
margin: 0 0 1rem;
|
||||||
|
}
|
||||||
|
.bf-booking-link {
|
||||||
|
display: inline-block;
|
||||||
|
font-family: Marcellus, Georgia, serif;
|
||||||
|
font-size: 0.85rem;
|
||||||
|
letter-spacing: 0.03em;
|
||||||
|
color: var(--brass-deep);
|
||||||
|
background: transparent;
|
||||||
|
border: 1px solid var(--line-brass);
|
||||||
|
border-radius: var(--radius-pill);
|
||||||
|
padding: 0.6rem 1.25rem;
|
||||||
|
text-decoration: none;
|
||||||
|
transition: background 0.2s, color 0.2s;
|
||||||
|
}
|
||||||
|
.bf-booking-link:hover,
|
||||||
|
.bf-booking-link:focus-visible {
|
||||||
|
background: var(--brass);
|
||||||
|
color: var(--midnight);
|
||||||
|
}
|
||||||
|
@media (max-width: 900px) {
|
||||||
|
#offer .container {
|
||||||
|
grid-template-columns: minmax(0, 620px);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/* FAQ (native details/summary — no JS) */
|
/* FAQ (native details/summary — no JS) */
|
||||||
.cmp-faq-grid {
|
.cmp-faq-grid {
|
||||||
display: grid;
|
display: grid;
|
||||||
@@ -691,6 +750,44 @@
|
|||||||
<p class="bf-cta-secondary"><a href="/odoo-hosting-offers/">See everything a year of hosting includes</a></p>
|
<p class="bf-cta-secondary"><a href="/odoo-hosting-offers/">See everything a year of hosting includes</a></p>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
<!-- The secondary actions that sit beside the deal: the free trial (moved here from the
|
||||||
|
features grid, same form, same consent gate) and a booking link. Both are deliberately
|
||||||
|
smaller and quieter than the deal's buy button, so the row keeps ONE primary action.
|
||||||
|
The buy stays the dominant, brass, large button in the box on the left. -->
|
||||||
|
<aside class="bf-aside" aria-label="Other ways to get started">
|
||||||
|
<!-- Free-trial card: moved verbatim from the features grid. Its id (#trialCard), the
|
||||||
|
form (#trialForm) and the static/black-friday.js submit handler are unchanged, so it
|
||||||
|
fires the already-wired Google Ads trial conversion behind the same consent gate —
|
||||||
|
no second trial mechanism. -->
|
||||||
|
<div class="feature-card-trial" id="trialCard">
|
||||||
|
<h3>Free Trial</h3>
|
||||||
|
<p>Start your 30-day free trial. No credit card required.</p>
|
||||||
|
<form class="trial-form" id="trialForm">
|
||||||
|
<input type="email" id="trialEmail" placeholder="Your email address" required />
|
||||||
|
<select id="trialLocation"></select>
|
||||||
|
<button type="submit" class="btn btn-brass">Send</button>
|
||||||
|
</form>
|
||||||
|
<div class="trial-success" id="trialSuccess">✓ Check your inbox to confirm your email address.</div>
|
||||||
|
</div>
|
||||||
|
<!-- Booking — a 30-minute call with a named person, NOT "contact us". It opens the
|
||||||
|
Google appointment page in a NEW TAB (a plain <a>, no iframe: nothing loads until the
|
||||||
|
visitor chooses to go, so the consent gate on this page is not defeated). Its click
|
||||||
|
fires the booking conversion through the same consent gate
|
||||||
|
(window.o4pAds.bookConversion); because the click is never preventDefault-ed, a
|
||||||
|
blocked tag can never stop the link opening. -->
|
||||||
|
<div class="bf-booking">
|
||||||
|
<h3>Prefer to talk first?</h3>
|
||||||
|
<p>Book a 30-minute call with Oliver, our technical lead, to walk through your setup.</p>
|
||||||
|
<a
|
||||||
|
class="bf-booking-link"
|
||||||
|
id="bookingCTA"
|
||||||
|
target="_blank"
|
||||||
|
rel="noopener"
|
||||||
|
href="https://calendar.google.com/calendar/u/0/appointments/schedules/AcZssZ3DDbaiHFlhNhWySszAQoPXE_H73QLqYT3w7H9IYWC76RA_TgNIhLESjb4N7ep_D2D_OyW9q4-c"
|
||||||
|
>Book a 30-minute call with Oliver →</a
|
||||||
|
>
|
||||||
|
</div>
|
||||||
|
</aside>
|
||||||
</div>
|
</div>
|
||||||
</section>
|
</section>
|
||||||
|
|
||||||
@@ -784,16 +881,8 @@
|
|||||||
<h3>Support Bot & Human Support</h3>
|
<h3>Support Bot & Human Support</h3>
|
||||||
<p>AI support bot for instant fixes. Human team for everything else. Your UUID is your key.</p>
|
<p>AI support bot for instant fixes. Human team for everything else. Your UUID is your key.</p>
|
||||||
</div>
|
</div>
|
||||||
<div class="feature-card-trial" id="trialCard">
|
<!-- The Free Trial card was moved up beside the Black Friday deal (see #offer), so the
|
||||||
<h3>Free Trial</h3>
|
trial widget and the deal sit together. No second card: the same #trialCard/form. -->
|
||||||
<p>Start your 30-day free trial. No credit card required.</p>
|
|
||||||
<form class="trial-form" id="trialForm">
|
|
||||||
<input type="email" id="trialEmail" placeholder="Your email address" required />
|
|
||||||
<select id="trialLocation"></select>
|
|
||||||
<button type="submit" class="btn btn-brass">Send</button>
|
|
||||||
</form>
|
|
||||||
<div class="trial-success" id="trialSuccess">✓ Check your inbox to confirm your email address.</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</section>
|
</section>
|
||||||
@@ -1063,9 +1152,10 @@
|
|||||||
|
|
||||||
<!-- Google Ads consent banner — default DENY. The tag loads only after "Accept".
|
<!-- Google Ads consent banner — default DENY. The tag loads only after "Accept".
|
||||||
Markup lives in the page; JS (static/ads-consent.js) reveals it and drives it.
|
Markup lives in the page; JS (static/ads-consent.js) reveals it and drives it.
|
||||||
Two conversions are wired here: the buy forms (data-ads-send-to) and the free-trial
|
Three conversions are wired here, all click proxies, all behind this one gate: the buy
|
||||||
form (data-ads-trial-send-to). With JavaScript off it stays hidden and both actions
|
forms (data-ads-send-to), the free-trial form (data-ads-trial-send-to) and the booking
|
||||||
(the native buy POSTs, the trial's own submit) run untouched.
|
link (data-ads-book-send-to). With JavaScript off it stays hidden and every action
|
||||||
|
(the native buy POSTs, the trial's own submit, the booking <a>) runs untouched.
|
||||||
See wiki/concepts/conversion-tracking-contract. -->
|
See wiki/concepts/conversion-tracking-contract. -->
|
||||||
<div
|
<div
|
||||||
id="adsConsent"
|
id="adsConsent"
|
||||||
@@ -1075,6 +1165,7 @@
|
|||||||
data-ads-id="AW-18065522009"
|
data-ads-id="AW-18065522009"
|
||||||
data-ads-send-to="AW-18065522009/vnDUCPDxt7AdENn6p6ZD"
|
data-ads-send-to="AW-18065522009/vnDUCPDxt7AdENn6p6ZD"
|
||||||
data-ads-trial-send-to="AW-18065522009/AtAPCIjjvrAdENn6p6ZD"
|
data-ads-trial-send-to="AW-18065522009/AtAPCIjjvrAdENn6p6ZD"
|
||||||
|
data-ads-book-send-to="AW-18065522009/P0j5CPiCv7AdENn6p6ZD"
|
||||||
hidden
|
hidden
|
||||||
>
|
>
|
||||||
<div class="ads-consent-inner">
|
<div class="ads-consent-inner">
|
||||||
|
|||||||
@@ -170,6 +170,7 @@
|
|||||||
id: id,
|
id: id,
|
||||||
sendTo: sendTo,
|
sendTo: sendTo,
|
||||||
trialSendTo: banner.getAttribute("data-ads-trial-send-to"),
|
trialSendTo: banner.getAttribute("data-ads-trial-send-to"),
|
||||||
|
bookSendTo: banner.getAttribute("data-ads-book-send-to"),
|
||||||
};
|
};
|
||||||
|
|
||||||
var choice = readChoice();
|
var choice = readChoice();
|
||||||
@@ -210,6 +211,21 @@
|
|||||||
fireConversion(cfg.trialSendTo, action);
|
fireConversion(cfg.trialSendTo, action);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/* ---- the booking conversion: fired on a click of the booking link ---- *
|
||||||
|
* The booking happens on Google's domain, off-site, so a click is all we can observe. The
|
||||||
|
* caller does NOT preventDefault: the link opens in a new tab on its own, so even a blocked,
|
||||||
|
* slow or absent tag can never stop the booking page from opening — this only ADDS the event.
|
||||||
|
* Without consent (or the label) it fires nothing and simply runs the (optional) action.
|
||||||
|
*/
|
||||||
|
window.o4pAds.bookConversion = function (action) {
|
||||||
|
if (typeof action !== "function") action = function () {};
|
||||||
|
if (!cfg || !cfg.bookSendTo || !isGranted() || typeof window.gtag !== "function") {
|
||||||
|
action();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
fireConversion(cfg.bookSendTo, action);
|
||||||
|
};
|
||||||
|
|
||||||
if (document.readyState === "loading") {
|
if (document.readyState === "loading") {
|
||||||
document.addEventListener("DOMContentLoaded", init);
|
document.addEventListener("DOMContentLoaded", init);
|
||||||
} else {
|
} else {
|
||||||
|
|||||||
@@ -375,6 +375,20 @@
|
|||||||
}
|
}
|
||||||
})();
|
})();
|
||||||
|
|
||||||
|
/* ---- Booking link — fire the Google Ads booking conversion on the click, through the same
|
||||||
|
consent gate as the buy and trial conversions. The link is a plain <a target="_blank">, so
|
||||||
|
the click is never preventDefault-ed: the Google appointment page opens regardless, and a
|
||||||
|
blocked, slow or absent tag merely skips the event. Fires nothing without consent. ---- */
|
||||||
|
(function () {
|
||||||
|
var link = document.getElementById('bookingCTA');
|
||||||
|
if (!link) return;
|
||||||
|
link.addEventListener('click', function () {
|
||||||
|
if (window.o4pAds && typeof window.o4pAds.bookConversion === 'function') {
|
||||||
|
window.o4pAds.bookConversion();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
})();
|
||||||
|
|
||||||
/* ---- Footer contact form ---- */
|
/* ---- Footer contact form ---- */
|
||||||
(function () {
|
(function () {
|
||||||
var form = document.getElementById('footerContactForm');
|
var form = document.getElementById('footerContactForm');
|
||||||
|
|||||||
Reference in new issue
Block a user