Commit graph

7 commits

Author SHA1 Message Date
justin
9a9b0b9130 Add Ontario alongside BC on CRTC page
- New 'Choose your province: BC or Ontario' comparison card (entity name,
  registered office city, fees, annual return, portal, area codes, corp tax)
  inserted above the carriers banner. Previously Ontario was only mentioned
  in a buried FAQ; BC outnumbered ON 53:12.
- Tax-comparison H2 + collapse-menu label now read 'British Columbia / Ontario'
  and the key-takeaway notes ON is ~12.2% (within ~1pt of BC).
- Made hero chip, 'what we deliver' (registered office + file corporation),
  and banking copy province-aware (BC or Ontario) instead of BC-only.
- Verified headless: province card renders, H2 visible (not auto-collapsed),
  13 accordions + proof expander intact, 28 Ontario mentions, no new JS errors.
2026-06-20 06:40:18 -05:00
justin
b1629160d5 crtc collapse: skip card-wrapped headings whose body isn't a sibling (fixes empty US-wholesale + banking expanders; vendor directory left inline) 2026-06-20 01:30:26 -05:00
justin
345c22e561 crtc page: add 'is this real?' proof expander (public RMD/499 stats + named CA operators, defamation-safe); keep standalone expanders out of auto-collapse 2026-06-20 01:12:10 -05:00
justin
0562fd2bd3 crtc page: add 5-min-read TL;DR + collapsible deep-detail sections (non-destructive JS/CSS enhancement) 2026-06-20 01:08:41 -05:00
justin
f481a1d13c analytics: filter email-scanner / headless traffic out of Umami stats
Email security gateways (Microsoft Defender Safe Links / ATP, Proofpoint,
Mimecast, Barracuda, etc.) auto-fetch and often render every link in a
campaign email to scan for malware. The advanced ones drive a real headless
browser, execute JS, and fire Umami pageviews/clicks that masquerade as human
visits -- inflating campaign click-through.

New site/public/js/pw-bot-filter.js queries multiple real-browser signals and
gates Umami via its official data-before-send hook (umamiBeforeSend), dropping
all events when the visitor is a bot. Signals (from empirical chromium probing):
  decisive: navigator.webdriver, HeadlessChrome UA, known scanner UAs, zero/
            collapsed screen|viewport|outer geometry, window LARGER than the
            physical screen (impossible on real HW; uses outerW/H so page zoom
            does not false-positive), software GPU rasterizer (SwiftShader/
            llvmpipe/swrast via WebGL UNMASKED_RENDERER), zero logical CPUs.
  soft (>=2 to trip): tiny screen, inner>screen, low color depth, empty
            navigator.languages, no input device (no fine/coarse pointer + no
            hover + 0 touch), no WebGL on a desktop UA.
Designed to FAIL OPEN: only strong/corroborated evidence suppresses, so real
visitors (incl. zoomed, privacy-tooled, remote-desktop, kiosk) still count.

Wired before the Umami tag in Base.astro (Astro pages) and all 86 static
public/**/*.html pages; both load with defer so order is guaranteed and the
hook is defined before Umami reads it.

Tested end-to-end with chromium (site/tests/bot-filter.test.sh, 4/4):
default headless-new, spoofed-Windows-UA + normal 1366x768 window, and
spoofed-UA + 1x1 window are all caught; hook returns null to drop the event.
2026-06-18 02:02:34 -05:00
justin
7399211271 trust/security: DMARC p=reject; MTA-STS cert+HTTPS policy live; cookie consent banner (CSP-safe); /accessibility page; footer legal links (Security/Accessibility) on all pages; scope TrustedSite to /order payment pages only 2026-06-06 21:01:36 -05:00
justin
bd5193e45f Add Umami custom event tracking across all key pages
- Created /js/pw-analytics.js with conversion funnel events
- Added to Base.astro layout (all Astro pages) + 6 static HTML pages
- Events tracked: compliance-check-start, compliance-check-complete,
  order-cta-click, checkout-page-view, checkout-start, esign-opened,
  esign-submitted, campaign-click (UTM attribution), contact-form-submit
- Server-side payment-complete event from checkout webhook via Umami API
- Auto-tracks any element with data-track="event-name" attribute

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-05-05 05:10:13 -05:00