nav order matches page; pricing moved last; setup-intent attach fix

Page section order is now: hero → pillars → how-it-works → inference →
efficiency → comparison → enterprise → mission → local-first → safety →
environmental → marketplace → viral → pricing → footer. Pricing is the
last content block so visitors scroll the whole story before being asked
to commit. Nav (desktop + mobile + dropdown) reordered to mirror the
page: How it works → Enterprise → Mission ▾ → Marketplace → Pricing →
About / Gallery / Account.

Stripe attach bug: /api/link-customer was hitting
POST /v1/payment_intents/{id} for every Intent regardless of type, so
SetupIntents (seti_*) returned 404 from Stripe. Branched on the id
prefix - SetupIntents go to /v1/setup_intents/{id} and skip the
receipt_email param (PaymentIntent-only field). Caught from a live
422 in the dashboard the moment Will tested timing=later.
This commit is contained in:
Will Anderson
2026-05-02 00:52:59 -05:00
parent 1349450b14
commit 40691c05c8
2 changed files with 28 additions and 9 deletions
+21 -5
View File
@@ -146,6 +146,10 @@ fn persist_founding_count(sold: Int) {
// Page assembly
fn page(sold: Int, total: Int) -> String {
// Page order is the source of truth; nav must mirror it section-for-section.
// Pricing is intentionally last so a visitor can scroll the whole story
// (what / how / why / who-it's-for / safety / planet) before being asked
// to commit to a plan.
return page_open()
+ nav()
+ hero()
@@ -159,9 +163,9 @@ fn page(sold: Int, total: Int) -> String {
+ local_first()
+ safety()
+ environmental()
+ pricing(sold, total)
+ marketplace()
+ viral()
+ pricing(sold, total)
+ footer()
+ page_close()
}
@@ -521,11 +525,23 @@ fn handle_request(method: String, path: String, body: String) -> String {
}
}
// 3. Attach customer + receipt_email to the PaymentIntent
// 3. Attach customer to the live Intent. SetupIntents (seti_*) and
// PaymentIntents (pi_*) live at different REST endpoints, so
// branch on the id prefix. SetupIntents do not accept
// receipt_email - that's a PaymentIntent-only field.
if !str_eq(lc_cus_id, "") {
let lc_attach_body: String = "customer=" + lc_cus_id + "&receipt_email=" + lc_email_enc
let lc_attach_url: String = "https://api.stripe.com/v1/payment_intents/" + lc_pi_id
let lc_attach: String = http_post_form_auth(lc_attach_url, lc_attach_body, lc_auth)
let lc_is_setup: Bool = str_starts_with(lc_pi_id, "seti_")
let lc_attach_url: String = if lc_is_setup {
"https://api.stripe.com/v1/setup_intents/" + lc_pi_id
} else {
"https://api.stripe.com/v1/payment_intents/" + lc_pi_id
}
let lc_attach_body: String = if lc_is_setup {
"customer=" + lc_cus_id
} else {
"customer=" + lc_cus_id + "&receipt_email=" + lc_email_enc
}
let _lc_attach: String = http_post_form_auth(lc_attach_url, lc_attach_body, lc_auth)
}
// 4. Upsert the Supabase waitlist row so /account can find this purchase by email
+7 -4
View File
@@ -9,8 +9,11 @@ fn nav() -> String {
<div class=\"nav-inner\">
<a href=\"/\" class=\"nav-logo\" aria-label=\"Neuron home\"><img src=\"/assets/brand/neuron-wordmark-on-light.png\" srcset=\"/assets/brand/neuron-wordmark-on-light@2x.png 2x\" alt=\"Neuron\" height=\"28\"></a>
<!-- Order mirrors page section order: how-it-works → enterprise →
mission/safety/environment → marketplace → pricing. -->
<div class=\"nav-links\">
<a href=\"/#how-it-works\" class=\"nav-link\">How it works</a>
<a href=\"/#how-it-works\" class=\"nav-link\">How it works</a>
<a href=\"/#enterprise\" class=\"nav-link\">Enterprise</a>
<div class=\"nav-dropdown\">
<button class=\"nav-link nav-dropdown-btn\" aria-haspopup=\"true\" aria-expanded=\"false\">Mission &#9662;</button>
<div class=\"nav-dropdown-menu\">
@@ -19,9 +22,8 @@ fn nav() -> String {
<a href=\"/#environmental\" class=\"nav-dropdown-item\">Environment</a>
</div>
</div>
<a href=\"/#marketplace\" class=\"nav-link\">Marketplace</a>
<a href=\"/#pricing\" class=\"nav-link\">Pricing</a>
<a href=\"/#marketplace\" class=\"nav-link\">Marketplace</a>
<a href=\"/#enterprise\" class=\"nav-link\">Enterprise</a>
<a href=\"/about\" class=\"nav-link\">About</a>
<a href=\"/said\" class=\"nav-link\">Gallery</a>
<a href=\"/account\" class=\"nav-link\">Account</a>
@@ -36,11 +38,12 @@ fn nav() -> String {
<div class=\"nav-mobile\" id=\"nav-mobile\" role=\"navigation\" aria-label=\"Mobile navigation\">
<a href=\"/#how-it-works\" class=\"nav-mobile-link\">How it works</a>
<a href=\"/#enterprise\" class=\"nav-mobile-link\">Enterprise</a>
<a href=\"/#mission\" class=\"nav-mobile-link\">Mission</a>
<a href=\"/#safety\" class=\"nav-mobile-link\" style=\"padding-left:1.75rem;font-size:0.8rem;color:var(--t3)\">- Safety</a>
<a href=\"/#environmental\" class=\"nav-mobile-link\" style=\"padding-left:1.75rem;font-size:0.8rem;color:var(--t3)\">- Environment</a>
<a href=\"/#marketplace\" class=\"nav-mobile-link\">Marketplace</a>
<a href=\"/#pricing\" class=\"nav-mobile-link\">Pricing</a>
<a href=\"/#enterprise\" class=\"nav-mobile-link\">Enterprise</a>
<a href=\"/about\" class=\"nav-mobile-link\">About</a>
<a href=\"/said\" class=\"nav-mobile-link\">Gallery</a>
<a href=\"/account\" class=\"nav-mobile-link\">Account</a>