Perfect — since you already have a live Vercel project, here's the cleanest path:
1. Connect this chat to your GitHub repo
booktruenorth.com Vercel project2. Review and merge
main3. Vercel auto-deploys
booktruenorth.comBefore you merge, make sure to:
FORMSPREE_URL in lib/constants.ts with your real form endpoint (you can tell me the ID and I'll update it here before you connect)lib/constants.ts match your actual ratespublic/One thing to watch: if your current live project is plain HTML or a different framework, the switch to Next.js will fully replace it. Vercel handles Next.js natively so there's no extra config needed — it just works.
Want me to update the Formspree URL or any pricing before you connect the repo?
I've now read every file. Here's my full audit:
Bugs found:
_bebasNeue and _barlow are loaded but never added to the <html> or <body> className. The fonts download but Tailwind's font-sans / font-serif resolve to nothing usable."use client" killing SEO metadata -- page.tsx has "use client" at the top, which means the metadata export in layout.tsx works, but the entire page ships zero server-rendered HTML. The hero, footer, one-off callout, and booking section header are all static content that should be server-rendered for SEO.peer-checked:text-tn-gold classes on the inner <span> don't actually work because peer is the hidden radio input inside a <label> but the peer-checked: target <div> is not a sibling of the input -- it's a child of the label. The checked state never visually changes.peer-checked:text-white/60 class on the description span inside the payment options label won't trigger because it's nested, not a direct sibling."Starting at $55/wk" for 1/8 acre, but SUB_MOWING.eighth is 63. Same mismatch for every lot size. Customers see one price, then get a different one.DEADLINE is April 1, 2026. Next year nothing auto-updates.switchSaving logic compares standalone total against subscription total ignoring add-ons -- When a standalone user has add-ons, the "switch and save" calculation only uses SUB_MOWING * WEEKS as the subscription base, ignoring add-on costs. The savings number is wrong.onClick on the parent div calls toggleAddon, and the onChange on the input also calls toggleAddon. Combined with e.stopPropagation(), clicking the checkbox itself fires onChange (toggles once), but clicking anywhere else on the row fires the div's onClick -- this is actually correct. But if a user clicks the checkbox label area around the checkbox, both fire. Edge case but worth noting.DeadlineBanner renders "" on server but immediately sets countdown text on client mount, causing a React hydration warning.Let me fix all of these now:
Now update the globals.css to map the font variables correctly:
Now fix the page.tsx to remove "use client" and split static vs interactive:
Create the new client-only CalculatorSection that wraps the interactive parts:
Now make the static components non-client (remove "use client" from topbar, hero, one-off-callout, footer):
Now fix the LOT_OPTIONS prices to match actual SUB_MOWING rates:
Now fix the copyright year to be dynamic:
Now fix the quote calculator lot size styling (peer-checked doesn't work through nested elements):
Now fix the payment method styling the same way:
Now fix the email gate catch block to still try to show a warning:
Now fix the DeadlineBanner hydration mismatch by suppressing hydration on the countdown:
Now fix the switchSaving calculation to include add-on costs properly:
Now fix the double-toggle issue on add-on checkboxes:
Now let me make the deadline auto-roll to next year:
Here's a summary of all fixes:
Bugs fixed (6):
<html> tag and mapped through CSS variables so font-sans (Barlow) and font-serif (Bebas Neue) actually work.peer-checked approach with explicit state-driven conditional classes using buttons.SUB_MOWING rates ($63, $76, $96, $112, $128).readOnly + pointer-events-none so only the parent onClick handles toggling.aosTotal in the subscription comparison so the savings figure is accurate.Improvements (4):
"use client" off page.tsx. Static components (topbar, hero, footer, callout) are now server-rendered. Only the interactive calculator/booking/sticky bar are client-side.suppressHydrationWarning to the countdown timer span.DEADLINE now automatically advances to next year's April 1 when the current one passes. No manual updates needed.new Date().getFullYear() instead of hardcoded 2026.You can send messages while the preview loads