Commit Graph
16 Commits
Author SHA1 Message Date
oliver 0cd0fa1af1 feat(analytics): Plausible snippet on every page, FAQ marked on the bootcamp
The snippet was on 10 of 40 pages, so the Trial / FAQ / Buy / Custom Quote /
search posts / Project Plan goals were inert everywhere else. It now sits
verbatim, in the same <head> position as index.html, on all 39 visitor-facing
pages. email/trial-confirmation.html is deliberately left out (email template).

FAQ: the five <details class="bc-faq"> <summary> elements on the bootcamp page
and its DE/ES twins now carry plausible-event-name=FAQ, and the 15
.faq-question buttons on de/es/support.html get the marking they were believed
to already have. No goal renamed: one FAQ goal across all languages.

No markup, copy or behaviour change, and no third-party request beyond the
snippet itself. verify-html.py PROBLEMS 0; check-links.py OK; event checker
59 PASS / 0 FAIL; impeccable detector +0/-0 findings on the changed files.
2026-10-28 21:50:53 +00:00
webmaster 73b3f34696 feat(analytics): add Plausible custom-event markings for six goals
Mark the six conversion goals on the self-hosted Plausible instance so the
events match the goals to be registered in Plausible. Event names verbatim:
Trial, FAQ, Buy, Custom Quote, search posts, Project Plan.

CSS-class markings (work without JS logic, on the clickable element):
- FAQ  -> index/de/es index .faq-card; odoo-hosting-2027 + odoo-community-upgrade
          (de/es twins) and australia <summary>; support.html .faq-question
- Buy  -> index/de/es index .btn-buy anchors; australia + bootcamp native
          post_basket submit buttons (forms stay native POST)

JS call markings in script.js (loaded by index, de/index, es/index):
- Trial        on the successful trial-form POST (.then branch)
- Custom Quote on the successful custom-quote POST (.then branch)
- Project Plan on the successful business-wizard submit
- search posts on the FIRST input of #blogSearch only (guard flag, one per
  pageview, not on every keystroke, not on #ocaSearch)

Nothing fires on page load; the 'Start the free trial' anchors that only
scroll to #trialCard are deliberately not tagged. One goal per topic across
all languages, no language suffix. No visual, behavioural or request change.
2026-10-28 21:07:19 +00:00
oliver 31c02b1a06 Footer "Useful Links": Bootcamp + ODOO Hosting in 2027, drop the four
The list becomes the same four items in all three English pages:
ODOO Bootcamp -> /odoo-erp-automation-bootcamp/ (new, first),
ODOO Hosting in 2027 -> the existing comparison page (renamed from
"Odoo hosting 2027", added to the homepage which lacked it),
Support, Legal. Home / Privacy / Terms / Contact us removed.

Content-only edit inside the existing <ul>; each page keeps its own
href style. No CSS, no markup pattern change, no other footer column
touched. de/ and es/ untouched (translator owns those in parallel).

Checks: verify-html.py PROBLEMS 0; work/verify-footer-useful-links.py
PROBLEMS 0; impeccable detect finding set identical to HEAD (87
anti-patterns / 100 advisories, all pre-existing); browser check at
1280px and 375px on all three pages: 4 items, no overlap, no
horizontal overflow.
2026-10-26 15:47:14 +00:00
oliver 0bc4dc05d7 Bootcamp hero: two-zone scrim so the photo actually reads (EN/DE/ES)
The uniform .72 -> .55 scrim composited the whole hero band to luma ~37 and the
right zone to ~35, against a flat midnight of 25.4: a dark photo made darker.
The scrim is now two zones on the same photo:

  .78  0%-88%   (copy zone: kicker, H1, value line, the four facts, the CTA)
  ramp 88%-94%
  .25  94%-100% (the lit skyline, no copy over it)

.78 is the smallest flat alpha that holds every text block over its floor
(body 4.5:1, large 3.0:1) at 1920/1440/1024/390 in EN, DE and ES - measured on
the rendered page, not modelled. 88% is where the ramp has to start: the longest
translated fact line (DE, 1024px) reaches 89.3% of the hero.

Measured before -> after (full-range mean luma of the rendered band):
  whole band     37.3 / 36.8 / 37.6 / 37.3  ->  33.8 / 33.6 / 34.1 / 34.0
  right 88-100%  34.8 / 35.9 / 35.5 / 38.4  ->  38.7 / 40.2 / 39.4 / 43.4
  plateau 94-100%                          ->  41.4 / 44.2 / 42.7 / 46.9
  (= 1.63x-1.91x the flat-midnight 25.4, was 1.37x-1.51x)
Worst text block: 4.87:1 (was 3.13:1). No copy, buy form, JSON-LD, selector,
hreflang or price touched: de/ and es/ differ ONLY by this inserted hero block.
2026-10-25 11:39:40 +00:00
oliver 718059c7e1 Bootcamp hero: London night aerial behind the header copy
The user asked for a photo in the header of /odoo-erp-automation-bootcamp/.
Adds our own London night aerial (art-director's chosen cut, measured) as the
page-scoped .bc-hero background, under a midnight gradient scrim
(rgba(13,27,46,.72) -> .55, inside CI §5's band) and over the --midnight base.

- desktop: bootcamp-hero-desktop-1920.webp, cover, background-position 50% 25%
- <=640px: bootcamp-hero-mobile-900.webp, background-position 50% 50%
- the global .hero::after 50% wash is switched off on this page only, so the
  scrim above is the one that was measured

No copy, buy form, JSON-LD, language selector or hreflang change. One CSS block,
two images, nothing else. verify-html.py PROBLEMS: 0; impeccable detect finding
set identical to HEAD; check-links 0. Worst p05 over rendered type 5.64:1.
2026-10-25 10:42:46 +00:00
oliver e5e4f5b016 Bootcamp: instructor reads 'Oliver - The OC Guy - Arnold' (facts list + section lead)
The user's instruction: use 'Oliver - The OC Guy - Arnold' (his alter ego
'The OC Guy'). Rendered with the typed hyphen form in the two places the name
is shown - the facts-list <dd> and the 'Your instructor' <strong>. Bio
paragraphs, <title>, meta description and FAQ text untouched.

JSON-LD: both Course/CourseInstance instructor Person nodes keep
name 'Oliver Arnold' (legal name) and gain alternateName 'The OC Guy'.
2026-10-25 10:16:24 +00:00
oliver 89bb7b7cba i18n: publish the bootcamp page in DE + ES, cluster the EN page, price 465.00
- add de|es/odoo-erp-automation-bootcamp/index.html (build-i18n.py from the
  translator's files; canonical + hreflang cluster + top-bar selector)
- EN bootcamp page gains the four hreflang alternates (was asymmetric)
- price 790 -> 465.00 across all three pages (JSON-LD offers.price, the three
  buy-button labels, the bc-price sentence); the three buy forms stay
  byte-identical apart from the label language
- sitemap.xml: +/de/ and /es/odoo-erp-automation-bootcamp/; llms.txt: Languages
  section names the new pages
2026-10-24 22:38:21 +00:00
oliver ca9a5b47cf Bootcamp page: instructor dd carries the full title (Oliver Arnold, Technical Lead at ODOO4projects) 2026-10-24 22:33:09 +00:00
oliver 7784a46b7d Bootcamp page: instructor dd says 'Oliver Arnold' (drop ', sole instructor') 2026-10-24 22:30:20 +00:00
oliver 24e542f4ab Bootcamp page: CTAs say 'Buy for 790 USD' and post the basket natively
The three CTAs (hero, mid-page, §7) were <a class="btn-buy"> that only worked
through JavaScript. They are now native <form method="post" target="_blank">
elements posting basket=[{"product_id":12,"qty":1}] + clear=1 to
https://20.odoo4projects.com/shop/post_basket, so the buy works with JavaScript
disabled; the button keeps the brass styling and the same size classes.

static/buy.js no longer builds a form on click. It is now pure progressive
enhancement: a capture-phase submit listener appends the utm_source/medium/
campaign hidden inputs from the cookies and lets the native submit proceed.

One page-scoped declaration keeps the button height at 55px: a <button> takes
line-height:normal from the UA font shorthand where the <a>s inherited the body
line-height (measured 49.19px vs 54.78px without it).
2026-10-24 22:26:40 +00:00
oliver 45a3cc5398 Bootcamp page: Reserve your seat now buys the bootcamp (product_id 12)
The three Reserve-your-seat CTAs posted to /support.html#contact. They now
run the same checkout path as the main page's Buy Now: a new page-local
static/buy.js mirrors script.js buyNow() (POST basket to
20.odoo4projects.com/shop/post_basket, clear=1, UTM cookies appended) and
binds .btn-buy via one delegated click handler. CTAs become
.btn-buy[data-id=12]; label unchanged. script.js and the homepage untouched.

The Price-and-booking section keeps a second, smaller link to
/support.html#contact so readers who have questions still have a fallback.
2026-10-24 22:03:38 +00:00
oliver 0721804aab Language selector: move it into the visible top bar on every page that loads lang.js
The EN | DE | ES switcher existed but rendered into the footer slot, so a
visitor had to scroll to the bottom of the page to find it (measured live:
y=5582 on /, y=5498 on /odoo-erp-automation-bootcamp/). The user asked for a
selector a visitor can actually see.

- index.html, de/index.html, es/index.html: the slot is now the first child of
  .hero .container, right-aligned in flow above the kicker. In flow, not a
  fixed pill, so it cannot collide with the absolute .hero-notice.
- odoo-erp-automation-bootcamp/index.html: the slot is now the last child of
  .bc-topbar .container, right of the nav links, behind a hairline brass
  divider; .bc-topbar-links gets margin-left:auto so the brand stays left.
- One [data-lang-switcher] per page; the footer slot is removed everywhere.
- Styling follows the CI: Inter 12px / .06em / uppercase codes (the existing
  .lang-switch rules), active language in --brass on these midnight surfaces,
  the other two in the surrounding text colour. CSS-only, in each page's
  inline <style>; lang.js is untouched, so its redirect behaviour is unchanged.
- The rules are recorded in work/i18n/I18N-BUILD-PLAN.md §3 for the phase-2
  pages (de|es/odoo-hosting-2027.html, de|es/support.html).
2026-10-24 21:51:08 +00:00
oliver 7b2d241330 Bootcamp page: remove the internal 'Note on the count' paragraph
The paragraph explained the 12-to-10 lesson merge — internal reasoning
about the old page, with no place on a sales page. The ten-lesson <ol>
and the section layout are unchanged.
2026-10-24 21:45:37 +00:00
oliver acae3bdbd9 Bootcamp: correct the session schedule (first 22 Jan 2026, last 26 Mar 2026, 18:00-19:00 Central Time) 2026-10-24 21:42:57 +00:00
oliver fa654dc8d7 Bootcamp page: publish the price, USD 790
The user confirmed the price (USD 790) and the term (Q1 2026, already
correct). Replaces the 'Price and booking' placeholder sentence with the
price statement and drops the TODO(olchi) comment that marked it. Adds an
Offer (price 790, USD, Paid) to the Course node so the price is
machine-readable; the FAQPage node is unchanged.
2026-10-24 21:36:52 +00:00
oliver 0f5fb95b12 Publish the Odoo Bootcamp page at /odoo-erp-automation-bootcamp/ (fixes the ranking 404)
New directory page built from the copywriter's reviewed copy (webmaster/out copy:
/root/workspace/copywriter/out/2026-10-24-bootcamp-page-copy.md), with the four
placeholders resolved: Thursdays 16:00-17:00 (UTC-3), first session Thursday
8 January 2026 (ten sessions, last 12 March 2026), no price printed (price is
confirmed on registration, offers omitted from JSON-LD), booking CTA is
/support.html#contact.

- odoo-erp-automation-bootcamp/index.html: standalone landing page in the CI
  (midnight/brass/cream, Marcellus+Inter, page-scoped CSS, non-blocking
  style.css, no third-party JS), 8 H2 sections from the copy, Course + FAQPage
  JSON-LD, footer from index.html with the language-switcher slot.
- sitemap.xml: 16 -> 17 <loc> entries (lastmod 2026-10-24, priority 0.9).
- llms.txt: one line for the bootcamp under Key pages.

Verified: verify-html.py PROBLEMS 0 (FILES extended with the new page),
node --check script.js OK, no console errors at 1280/375, no horizontal
overflow at 375.
2026-10-24 21:33:25 +00:00