feat(native-el-ui): rewrite checkout/main to use el-html vessel, fix page_close linker error

- checkout.el and main.el: replace raw import of el-html vessel with direct
  extern fn declarations; implementations come from dist/elhtml_impl.c (c_source)
- Add src/elhtml.el as reference file (all el-html extern fn declarations; not imported)
- dist/elhtml_impl.c: pre-compiled el-html vessel C (strips int main + sample global)
- dist/page_close.c: pre-compiled page_close implementation; elc OOMs after emitting
  the ~71KB page_open body and silently drops page_close, so supply it as c_source
- manifest.el: add elhtml_impl.c and page_close.c as c_source entries
- .gitignore: un-ignore dist/elhtml_impl.c and dist/page_close.c
This commit is contained in:
2026-05-08 22:14:38 -05:00
parent 2447310367
commit f2ab12e65b
7 changed files with 909 additions and 328 deletions
+2
View File
@@ -27,5 +27,7 @@ src/assets/js/
!dist/web_stubs.c
!dist/vessel_stubs.c
!dist/soul-demo.c
!dist/page_close.c
!dist/elhtml_impl.c
!dist/entrypoint.sh
!dist/engram-snapshot.json
+341
View File
@@ -0,0 +1,341 @@
#include <stdint.h>
#include <stdlib.h>
#include "el_runtime.h"
el_val_t el_escape(el_val_t s);
el_val_t el_text(el_val_t s);
el_val_t el_attr(el_val_t name, el_val_t value);
el_val_t el_div(el_val_t attrs, el_val_t children);
el_val_t el_section(el_val_t attrs, el_val_t children);
el_val_t el_article(el_val_t attrs, el_val_t children);
el_val_t el_header(el_val_t attrs, el_val_t children);
el_val_t el_footer(el_val_t attrs, el_val_t children);
el_val_t el_main(el_val_t attrs, el_val_t children);
el_val_t el_nav(el_val_t attrs, el_val_t children);
el_val_t el_aside(el_val_t attrs, el_val_t children);
el_val_t el_ul(el_val_t attrs, el_val_t children);
el_val_t el_ol(el_val_t attrs, el_val_t children);
el_val_t el_li(el_val_t attrs, el_val_t children);
el_val_t el_p(el_val_t attrs, el_val_t children);
el_val_t el_span(el_val_t attrs, el_val_t children);
el_val_t el_form(el_val_t attrs, el_val_t children);
el_val_t el_h1(el_val_t attrs, el_val_t text);
el_val_t el_h2(el_val_t attrs, el_val_t text);
el_val_t el_h3(el_val_t attrs, el_val_t text);
el_val_t el_h4(el_val_t attrs, el_val_t text);
el_val_t el_button(el_val_t attrs, el_val_t label);
el_val_t el_a(el_val_t href, el_val_t attrs, el_val_t children);
el_val_t el_input(el_val_t type_attr, el_val_t attrs);
el_val_t el_textarea(el_val_t attrs, el_val_t value);
el_val_t el_label(el_val_t for_id, el_val_t attrs, el_val_t children);
el_val_t el_img(el_val_t src, el_val_t alt, el_val_t attrs);
el_val_t el_video(el_val_t attrs, el_val_t children);
el_val_t el_strong(el_val_t children);
el_val_t el_em(el_val_t children);
el_val_t el_code(el_val_t children);
el_val_t el_pre(el_val_t attrs, el_val_t children);
el_val_t el_hr(void);
el_val_t el_br(void);
el_val_t el_html_doc(el_val_t lang, el_val_t head_html, el_val_t body_html);
el_val_t el_meta(el_val_t name, el_val_t content);
el_val_t el_meta_charset(el_val_t charset);
el_val_t el_link_stylesheet(el_val_t href);
el_val_t el_script_src(el_val_t src, el_val_t defer_load);
el_val_t el_script_inline(el_val_t js);
el_val_t el_title(el_val_t text);
el_val_t el_escape(el_val_t s) {
s = str_replace(s, EL_STR("&"), EL_STR("&amp;"));
s = str_replace(s, EL_STR("<"), EL_STR("&lt;"));
s = str_replace(s, EL_STR(">"), EL_STR("&gt;"));
s = str_replace(s, EL_STR("\""), EL_STR("&quot;"));
return str_replace(s, EL_STR("'"), EL_STR("&#39;"));
return 0;
}
el_val_t el_text(el_val_t s) {
return el_escape(s);
return 0;
}
el_val_t el_attr(el_val_t name, el_val_t value) {
return el_str_concat(el_str_concat(el_str_concat(el_str_concat(EL_STR(" "), name), EL_STR("=\"")), el_escape(value)), EL_STR("\""));
return 0;
}
el_val_t el_div(el_val_t attrs, el_val_t children) {
if (str_eq(attrs, EL_STR(""))) {
return el_str_concat(el_str_concat(EL_STR("<div>"), children), EL_STR("</div>"));
}
return el_str_concat(el_str_concat(el_str_concat(el_str_concat(EL_STR("<div "), attrs), EL_STR(">")), children), EL_STR("</div>"));
return 0;
}
el_val_t el_section(el_val_t attrs, el_val_t children) {
if (str_eq(attrs, EL_STR(""))) {
return el_str_concat(el_str_concat(EL_STR("<section>"), children), EL_STR("</section>"));
}
return el_str_concat(el_str_concat(el_str_concat(el_str_concat(EL_STR("<section "), attrs), EL_STR(">")), children), EL_STR("</section>"));
return 0;
}
el_val_t el_article(el_val_t attrs, el_val_t children) {
if (str_eq(attrs, EL_STR(""))) {
return el_str_concat(el_str_concat(EL_STR("<article>"), children), EL_STR("</article>"));
}
return el_str_concat(el_str_concat(el_str_concat(el_str_concat(EL_STR("<article "), attrs), EL_STR(">")), children), EL_STR("</article>"));
return 0;
}
el_val_t el_header(el_val_t attrs, el_val_t children) {
if (str_eq(attrs, EL_STR(""))) {
return el_str_concat(el_str_concat(EL_STR("<header>"), children), EL_STR("</header>"));
}
return el_str_concat(el_str_concat(el_str_concat(el_str_concat(EL_STR("<header "), attrs), EL_STR(">")), children), EL_STR("</header>"));
return 0;
}
el_val_t el_footer(el_val_t attrs, el_val_t children) {
if (str_eq(attrs, EL_STR(""))) {
return el_str_concat(el_str_concat(EL_STR("<footer>"), children), EL_STR("</footer>"));
}
return el_str_concat(el_str_concat(el_str_concat(el_str_concat(EL_STR("<footer "), attrs), EL_STR(">")), children), EL_STR("</footer>"));
return 0;
}
el_val_t el_main(el_val_t attrs, el_val_t children) {
if (str_eq(attrs, EL_STR(""))) {
return el_str_concat(el_str_concat(EL_STR("<main>"), children), EL_STR("</main>"));
}
return el_str_concat(el_str_concat(el_str_concat(el_str_concat(EL_STR("<main "), attrs), EL_STR(">")), children), EL_STR("</main>"));
return 0;
}
el_val_t el_nav(el_val_t attrs, el_val_t children) {
if (str_eq(attrs, EL_STR(""))) {
return el_str_concat(el_str_concat(EL_STR("<nav>"), children), EL_STR("</nav>"));
}
return el_str_concat(el_str_concat(el_str_concat(el_str_concat(EL_STR("<nav "), attrs), EL_STR(">")), children), EL_STR("</nav>"));
return 0;
}
el_val_t el_aside(el_val_t attrs, el_val_t children) {
if (str_eq(attrs, EL_STR(""))) {
return el_str_concat(el_str_concat(EL_STR("<aside>"), children), EL_STR("</aside>"));
}
return el_str_concat(el_str_concat(el_str_concat(el_str_concat(EL_STR("<aside "), attrs), EL_STR(">")), children), EL_STR("</aside>"));
return 0;
}
el_val_t el_ul(el_val_t attrs, el_val_t children) {
if (str_eq(attrs, EL_STR(""))) {
return el_str_concat(el_str_concat(EL_STR("<ul>"), children), EL_STR("</ul>"));
}
return el_str_concat(el_str_concat(el_str_concat(el_str_concat(EL_STR("<ul "), attrs), EL_STR(">")), children), EL_STR("</ul>"));
return 0;
}
el_val_t el_ol(el_val_t attrs, el_val_t children) {
if (str_eq(attrs, EL_STR(""))) {
return el_str_concat(el_str_concat(EL_STR("<ol>"), children), EL_STR("</ol>"));
}
return el_str_concat(el_str_concat(el_str_concat(el_str_concat(EL_STR("<ol "), attrs), EL_STR(">")), children), EL_STR("</ol>"));
return 0;
}
el_val_t el_li(el_val_t attrs, el_val_t children) {
if (str_eq(attrs, EL_STR(""))) {
return el_str_concat(el_str_concat(EL_STR("<li>"), children), EL_STR("</li>"));
}
return el_str_concat(el_str_concat(el_str_concat(el_str_concat(EL_STR("<li "), attrs), EL_STR(">")), children), EL_STR("</li>"));
return 0;
}
el_val_t el_p(el_val_t attrs, el_val_t children) {
if (str_eq(attrs, EL_STR(""))) {
return el_str_concat(el_str_concat(EL_STR("<p>"), children), EL_STR("</p>"));
}
return el_str_concat(el_str_concat(el_str_concat(el_str_concat(EL_STR("<p "), attrs), EL_STR(">")), children), EL_STR("</p>"));
return 0;
}
el_val_t el_span(el_val_t attrs, el_val_t children) {
if (str_eq(attrs, EL_STR(""))) {
return el_str_concat(el_str_concat(EL_STR("<span>"), children), EL_STR("</span>"));
}
return el_str_concat(el_str_concat(el_str_concat(el_str_concat(EL_STR("<span "), attrs), EL_STR(">")), children), EL_STR("</span>"));
return 0;
}
el_val_t el_form(el_val_t attrs, el_val_t children) {
if (str_eq(attrs, EL_STR(""))) {
return el_str_concat(el_str_concat(EL_STR("<form>"), children), EL_STR("</form>"));
}
return el_str_concat(el_str_concat(el_str_concat(el_str_concat(EL_STR("<form "), attrs), EL_STR(">")), children), EL_STR("</form>"));
return 0;
}
el_val_t el_h1(el_val_t attrs, el_val_t text) {
if (str_eq(attrs, EL_STR(""))) {
return el_str_concat(el_str_concat(EL_STR("<h1>"), el_escape(text)), EL_STR("</h1>"));
}
return el_str_concat(el_str_concat(el_str_concat(el_str_concat(EL_STR("<h1 "), attrs), EL_STR(">")), el_escape(text)), EL_STR("</h1>"));
return 0;
}
el_val_t el_h2(el_val_t attrs, el_val_t text) {
if (str_eq(attrs, EL_STR(""))) {
return el_str_concat(el_str_concat(EL_STR("<h2>"), el_escape(text)), EL_STR("</h2>"));
}
return el_str_concat(el_str_concat(el_str_concat(el_str_concat(EL_STR("<h2 "), attrs), EL_STR(">")), el_escape(text)), EL_STR("</h2>"));
return 0;
}
el_val_t el_h3(el_val_t attrs, el_val_t text) {
if (str_eq(attrs, EL_STR(""))) {
return el_str_concat(el_str_concat(EL_STR("<h3>"), el_escape(text)), EL_STR("</h3>"));
}
return el_str_concat(el_str_concat(el_str_concat(el_str_concat(EL_STR("<h3 "), attrs), EL_STR(">")), el_escape(text)), EL_STR("</h3>"));
return 0;
}
el_val_t el_h4(el_val_t attrs, el_val_t text) {
if (str_eq(attrs, EL_STR(""))) {
return el_str_concat(el_str_concat(EL_STR("<h4>"), el_escape(text)), EL_STR("</h4>"));
}
return el_str_concat(el_str_concat(el_str_concat(el_str_concat(EL_STR("<h4 "), attrs), EL_STR(">")), el_escape(text)), EL_STR("</h4>"));
return 0;
}
el_val_t el_button(el_val_t attrs, el_val_t label) {
if (str_eq(attrs, EL_STR(""))) {
return el_str_concat(el_str_concat(EL_STR("<button type=\"button\">"), el_escape(label)), EL_STR("</button>"));
}
return el_str_concat(el_str_concat(el_str_concat(el_str_concat(EL_STR("<button type=\"button\" "), attrs), EL_STR(">")), el_escape(label)), EL_STR("</button>"));
return 0;
}
el_val_t el_a(el_val_t href, el_val_t attrs, el_val_t children) {
el_val_t h = el_str_concat(el_str_concat(EL_STR("href=\""), el_escape(href)), EL_STR("\""));
if (str_eq(attrs, EL_STR(""))) {
return el_str_concat(el_str_concat(el_str_concat(el_str_concat(EL_STR("<a "), h), EL_STR(">")), children), EL_STR("</a>"));
}
return el_str_concat(el_str_concat(el_str_concat(el_str_concat(el_str_concat(el_str_concat(EL_STR("<a "), h), EL_STR(" ")), attrs), EL_STR(">")), children), EL_STR("</a>"));
return 0;
}
el_val_t el_input(el_val_t type_attr, el_val_t attrs) {
if (str_eq(attrs, EL_STR(""))) {
return el_str_concat(el_str_concat(EL_STR("<input type=\""), type_attr), EL_STR("\" />"));
}
return el_str_concat(el_str_concat(el_str_concat(el_str_concat(EL_STR("<input type=\""), type_attr), EL_STR("\" ")), attrs), EL_STR(" />"));
return 0;
}
el_val_t el_textarea(el_val_t attrs, el_val_t value) {
if (str_eq(attrs, EL_STR(""))) {
return el_str_concat(el_str_concat(EL_STR("<textarea>"), el_escape(value)), EL_STR("</textarea>"));
}
return el_str_concat(el_str_concat(el_str_concat(el_str_concat(EL_STR("<textarea "), attrs), EL_STR(">")), el_escape(value)), EL_STR("</textarea>"));
return 0;
}
el_val_t el_label(el_val_t for_id, el_val_t attrs, el_val_t children) {
el_val_t f = el_str_concat(el_str_concat(EL_STR("for=\""), el_escape(for_id)), EL_STR("\""));
if (str_eq(attrs, EL_STR(""))) {
return el_str_concat(el_str_concat(el_str_concat(el_str_concat(EL_STR("<label "), f), EL_STR(">")), children), EL_STR("</label>"));
}
return el_str_concat(el_str_concat(el_str_concat(el_str_concat(el_str_concat(el_str_concat(EL_STR("<label "), f), EL_STR(" ")), attrs), EL_STR(">")), children), EL_STR("</label>"));
return 0;
}
el_val_t el_img(el_val_t src, el_val_t alt, el_val_t attrs) {
el_val_t base = el_str_concat(el_str_concat(el_str_concat(el_str_concat(EL_STR("src=\""), el_escape(src)), EL_STR("\" alt=\"")), el_escape(alt)), EL_STR("\""));
if (str_eq(attrs, EL_STR(""))) {
return el_str_concat(el_str_concat(EL_STR("<img "), base), EL_STR(" />"));
}
return el_str_concat(el_str_concat(el_str_concat(el_str_concat(EL_STR("<img "), base), EL_STR(" ")), attrs), EL_STR(" />"));
return 0;
}
el_val_t el_video(el_val_t attrs, el_val_t children) {
if (str_eq(attrs, EL_STR(""))) {
return el_str_concat(el_str_concat(EL_STR("<video>"), children), EL_STR("</video>"));
}
return el_str_concat(el_str_concat(el_str_concat(el_str_concat(EL_STR("<video "), attrs), EL_STR(">")), children), EL_STR("</video>"));
return 0;
}
el_val_t el_strong(el_val_t children) {
return el_str_concat(el_str_concat(EL_STR("<strong>"), children), EL_STR("</strong>"));
return 0;
}
el_val_t el_em(el_val_t children) {
return el_str_concat(el_str_concat(EL_STR("<em>"), children), EL_STR("</em>"));
return 0;
}
el_val_t el_code(el_val_t children) {
return el_str_concat(el_str_concat(EL_STR("<code>"), children), EL_STR("</code>"));
return 0;
}
el_val_t el_pre(el_val_t attrs, el_val_t children) {
if (str_eq(attrs, EL_STR(""))) {
return el_str_concat(el_str_concat(EL_STR("<pre>"), children), EL_STR("</pre>"));
}
return el_str_concat(el_str_concat(el_str_concat(el_str_concat(EL_STR("<pre "), attrs), EL_STR(">")), children), EL_STR("</pre>"));
return 0;
}
el_val_t el_hr(void) {
return EL_STR("<hr />");
return 0;
}
el_val_t el_br(void) {
return EL_STR("<br />");
return 0;
}
el_val_t el_html_doc(el_val_t lang, el_val_t head_html, el_val_t body_html) {
return el_str_concat(el_str_concat(el_str_concat(el_str_concat(el_str_concat(el_str_concat(EL_STR("<!doctype html><html lang=\""), el_escape(lang)), EL_STR("\"><head>")), head_html), EL_STR("</head><body>")), body_html), EL_STR("</body></html>"));
return 0;
}
el_val_t el_meta(el_val_t name, el_val_t content) {
return el_str_concat(el_str_concat(el_str_concat(el_str_concat(EL_STR("<meta name=\""), el_escape(name)), EL_STR("\" content=\"")), el_escape(content)), EL_STR("\" />"));
return 0;
}
el_val_t el_meta_charset(el_val_t charset) {
return el_str_concat(el_str_concat(EL_STR("<meta charset=\""), el_escape(charset)), EL_STR("\" />"));
return 0;
}
el_val_t el_link_stylesheet(el_val_t href) {
return el_str_concat(el_str_concat(EL_STR("<link rel=\"stylesheet\" href=\""), el_escape(href)), EL_STR("\" />"));
return 0;
}
el_val_t el_script_src(el_val_t src, el_val_t defer_load) {
if (defer_load) {
return el_str_concat(el_str_concat(EL_STR("<script src=\""), el_escape(src)), EL_STR("\" defer></script>"));
}
return el_str_concat(el_str_concat(EL_STR("<script src=\""), el_escape(src)), EL_STR("\"></script>"));
return 0;
}
el_val_t el_script_inline(el_val_t js) {
return el_str_concat(el_str_concat(EL_STR("<script>"), js), EL_STR("</script>"));
return 0;
}
el_val_t el_title(el_val_t text) {
return el_str_concat(el_str_concat(EL_STR("<title>"), el_escape(text)), EL_STR("</title>"));
return 0;
}
+12
View File
File diff suppressed because one or more lines are too long
+2
View File
@@ -11,4 +11,6 @@ build {
output "dist/"
c_source "dist/web_stubs.c"
c_source "dist/vessel_stubs.c"
c_source "dist/elhtml_impl.c"
c_source "dist/page_close.c"
}
+293 -185
View File
@@ -11,15 +11,63 @@
// 4. User fills name, email, card - submits
// 5. stripe.confirmPayment() redirects to /marketplace/success
// el-html vessel extern declarations (implementations in dist/elhtml_impl.c)
extern fn el_escape(s: String) -> String
extern fn el_text(s: String) -> String
extern fn el_attr(name: String, value: String) -> String
extern fn el_div(attrs: String, children: String) -> String
extern fn el_section(attrs: String, children: String) -> String
extern fn el_article(attrs: String, children: String) -> String
extern fn el_header(attrs: String, children: String) -> String
extern fn el_footer(attrs: String, children: String) -> String
extern fn el_main(attrs: String, children: String) -> String
extern fn el_nav(attrs: String, children: String) -> String
extern fn el_aside(attrs: String, children: String) -> String
extern fn el_ul(attrs: String, children: String) -> String
extern fn el_ol(attrs: String, children: String) -> String
extern fn el_li(attrs: String, children: String) -> String
extern fn el_p(attrs: String, children: String) -> String
extern fn el_span(attrs: String, children: String) -> String
extern fn el_form(attrs: String, children: String) -> String
extern fn el_h1(attrs: String, text: String) -> String
extern fn el_h2(attrs: String, text: String) -> String
extern fn el_h3(attrs: String, text: String) -> String
extern fn el_h4(attrs: String, text: String) -> String
extern fn el_button(attrs: String, label: String) -> String
extern fn el_a(href: String, attrs: String, children: String) -> String
extern fn el_input(type_attr: String, attrs: String) -> String
extern fn el_textarea(attrs: String, value: String) -> String
extern fn el_label(for_id: String, attrs: String, children: String) -> String
extern fn el_img(src: String, alt: String, attrs: String) -> String
extern fn el_strong(children: String) -> String
extern fn el_em(children: String) -> String
extern fn el_code(children: String) -> String
extern fn el_pre(attrs: String, children: String) -> String
extern fn el_hr() -> String
extern fn el_br() -> String
extern fn el_html_doc(lang: String, head_html: String, body_html: String) -> String
extern fn el_meta(name: String, content: String) -> String
extern fn el_meta_charset(charset: String) -> String
extern fn el_link_stylesheet(href: String) -> String
extern fn el_script_src(src: String, defer_load: Bool) -> String
extern fn el_script_inline(js: String) -> String
extern fn el_title(text: String) -> String
fn el_style_block(css: String) -> String {
"<style>" + css + "</style>"
}
fn checkout_nav_html() -> String {
<nav id="nav">
<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>
<div class="nav-links">
<a href="/" class="nav-link">&#8592; Back</a>
</div>
</div>
</nav>
let logo_img: String = el_img(
"/assets/brand/neuron-wordmark-on-light.png",
"Neuron",
"srcset=\"/assets/brand/neuron-wordmark-on-light@2x.png 2x\" height=\"28\""
)
let logo_link: String = el_a("/", "class=\"nav-logo\" aria-label=\"Neuron home\"", logo_img)
let back_link: String = el_a("/", "class=\"nav-link\"", "&#8592; Back")
let nav_links: String = el_div("class=\"nav-links\"", back_link)
let nav_inner: String = el_div("class=\"nav-inner\"", logo_link + nav_links)
el_nav("id=\"nav\"", nav_inner)
}
fn checkout_page(plan: String, pub_key: String) -> String {
@@ -38,216 +86,276 @@ fn checkout_page(plan: String, pub_key: String) -> String {
let plan_cadence: String = if is_founding { "one-time" } else { if is_free { "forever" } else { "billed monthly" } }
let features_html: String = if is_founding {
"<li>Everything in Professional - forever</li>
<li>Neuron Inference when it launches - priced below the major APIs, forever</li>
<li>Never pay again - lifetime updates included</li>
<li>Founding member badge in the app</li>
<li>Private founding member community</li>
<li>Shape the roadmap - your votes carry more weight</li>
<li>Beta features before general release</li>
<li>Name in the credits</li>"
el_li("", "Everything in Professional - forever")
+ el_li("", "Neuron Inference when it launches - priced below the major APIs, forever")
+ el_li("", "Never pay again - lifetime updates included")
+ el_li("", "Founding member badge in the app")
+ el_li("", "Private founding member community")
+ el_li("", "Shape the roadmap - your votes carry more weight")
+ el_li("", "Beta features before general release")
+ el_li("", "Name in the credits")
} else { if is_free {
"<li>Persistent memory - never resets</li>
<li>Local inference via Ollama (coming)</li>
<li>Bring your own API keys</li>
<li>3 marketplace plugins included</li>
<li>Core built-in capabilities</li>
<li>2 devices included</li>"
el_li("", "Persistent memory - never resets")
+ el_li("", "Local inference via Ollama (coming)")
+ el_li("", "Bring your own API keys")
+ el_li("", "3 marketplace plugins included")
+ el_li("", "Core built-in capabilities")
+ el_li("", "2 devices included")
} else {
"<li>Persistent memory - never resets</li>
<li>Bring your own API keys (OpenAI, Anthropic, Grok...)</li>
<li>Neuron Inference when it launches - Q3 2026, priced below the major APIs</li>
<li>Unlimited projects</li>
<li>Full plugin marketplace</li>
<li>IDE, Slack, and more integrations</li>
<li>Early access to new features</li>
<li>2 devices included</li>"
el_li("", "Persistent memory - never resets")
+ el_li("", "Bring your own API keys (OpenAI, Anthropic, Grok...)")
+ el_li("", "Neuron Inference when it launches - Q3 2026, priced below the major APIs")
+ el_li("", "Unlimited projects")
+ el_li("", "Full plugin marketplace")
+ el_li("", "IDE, Slack, and more integrations")
+ el_li("", "Early access to new features")
+ el_li("", "2 devices included")
} }
let nav_html: String = checkout_nav_html()
let main_html: String = <main style="min-height: 100vh; padding: clamp(6rem, 14vh, 9rem) 2rem 4rem;">
<div class="checkout-shell">
// Order summary (left column)
<!-- Left: order summary -->
<div class="checkout-summary">
<p class="label" style="margin-bottom: 1.5rem; color: var(--navy);">Your order</p>
let price_row: String = el_div(
"style=\"display: flex; align-items: baseline; gap: .5rem; margin-top: 1.25rem;\"",
el_span("class=\"checkout-price\"", el_text(plan_price))
+ el_span("class=\"checkout-cadence\"", el_text(plan_cadence))
)
<div style="margin-bottom: 2rem;">
<p class="checkout-plan-name">{plan_name}</p>
<p class="checkout-plan-desc">{plan_desc}</p>
<div style="display: flex; align-items: baseline; gap: .5rem; margin-top: 1.25rem;">
<span class="checkout-price">{plan_price}</span>
<span class="checkout-cadence">{plan_cadence}</span>
</div>
</div>
let plan_block: String = el_div(
"style=\"margin-bottom: 2rem;\"",
el_p("class=\"checkout-plan-name\"", el_text(plan_name))
+ el_p("class=\"checkout-plan-desc\"", el_text(plan_desc))
+ price_row
)
<div class="navy-line-left" style="width: 3rem; margin-bottom: 1.75rem;"></div>
let summary_col: String = el_div(
"class=\"checkout-summary\"",
el_p("class=\"label\" style=\"margin-bottom: 1.5rem; color: var(--navy);\"", "Your order")
+ plan_block
+ el_div("class=\"navy-line-left\" style=\"width: 3rem; margin-bottom: 1.75rem;\"", "")
+ el_ul("class=\"checkout-features\"", features_html)
+ el_p("class=\"checkout-guarantee\"", "Your data stays yours. Runs locally. No telemetry.")
)
<ul class="checkout-features">
{raw(features_html)}
</ul>
// Auth section
<p class="checkout-guarantee">
Your data stays yours. Runs locally. No telemetry.
</p>
</div>
let auth_heading: String = if is_free {
el_p("class=\"label\" style=\"margin-bottom: 1.5rem; color: var(--navy);\"", "Create your account.")
+ el_p("class=\"checkout-auth-hint\" style=\"margin-bottom: 2rem;\"", "No card required. Your account is free, forever.")
} else {
el_p("class=\"label\" style=\"margin-bottom: 1.25rem;\"", "Sign in (optional)")
+ el_p("class=\"checkout-auth-hint\"", "Sign in to link this purchase to an existing account. Or skip and create one later - we'll match it to your email.")
}
<!-- Right: either free thank-you or sign-in + payment form -->
<div class="checkout-form-wrap">
let google_svg: String = "<svg width=\"18\" height=\"18\" viewBox=\"0 0 18 18\" fill=\"none\" aria-hidden=\"true\">"
+ "<path d=\"M17.64 9.2c0-.637-.057-1.251-.164-1.84H9v3.481h4.844c-.209 1.125-.843 2.078-1.796 2.716v2.259h2.908c1.702-1.567 2.684-3.875 2.684-6.615z\" fill=\"#4285F4\"/>"
+ "<path d=\"M9 18c2.43 0 4.467-.806 5.956-2.18l-2.908-2.259c-.806.54-1.837.86-3.048.86-2.344 0-4.328-1.584-5.036-3.711H.957v2.332A8.997 8.997 0 0 0 9 18z\" fill=\"#34A853\"/>"
+ "<path d=\"M3.964 10.71A5.41 5.41 0 0 1 3.682 9c0-.593.102-1.17.282-1.71V4.958H.957A8.996 8.996 0 0 0 0 9c0 1.452.348 2.827.957 4.042l3.007-2.332z\" fill=\"#FBBC05\"/>"
+ "<path d=\"M9 3.58c1.321 0 2.508.454 3.44 1.345l2.582-2.58C13.463.891 11.426 0 9 0A8.997 8.997 0 0 0 .957 4.958L3.964 6.29C4.672 4.163 6.656 3.58 9 3.58z\" fill=\"#EA4335\"/>"
+ "</svg>"
<!-- Auth section: visible immediately for free, collapsed (optional) for paid plans -->
<div id=\"auth-section\" " + (if is_free { "" } else { "style=\"display:none;\"" }) + ">
" + (if is_free { "
<p class=\"label\" style=\"margin-bottom: 1.5rem; color: var(--navy);\">Create your account.</p>
<p class=\"checkout-auth-hint\" style=\"margin-bottom: 2rem;\">No card required. Your account is free, forever.</p>
" } else { "
<p class=\"label\" style=\"margin-bottom: 1.25rem;\">Sign in (optional)</p>
<p class=\"checkout-auth-hint\">Sign in to link this purchase to an existing account. Or skip and create one later - we'll match it to your email.</p>
" }) + "
let github_svg: String = "<svg width=\"18\" height=\"18\" viewBox=\"0 0 24 24\" fill=\"currentColor\" aria-hidden=\"true\">"
+ "<path d=\"M12 0C5.37 0 0 5.37 0 12c0 5.303 3.438 9.8 8.205 11.385.6.113.82-.258.82-.577 0-.285-.01-1.04-.015-2.04-3.338.724-4.042-1.61-4.042-1.61-.546-1.385-1.335-1.755-1.335-1.755-1.087-.744.084-.729.084-.729 1.205.084 1.838 1.236 1.838 1.236 1.07 1.835 2.809 1.305 3.495.998.108-.776.417-1.305.76-1.605-2.665-.3-5.466-1.332-5.466-5.93 0-1.31.465-2.38 1.235-3.22-.135-.303-.54-1.523.105-3.176 0 0 1.005-.322 3.3 1.23.96-.267 1.98-.399 3-.405 1.02.006 2.04.138 3 .405 2.28-1.552 3.285-1.23 3.285-1.23.645 1.653.24 2.873.12 3.176.765.84 1.23 1.91 1.23 3.22 0 4.61-2.805 5.625-5.475 5.92.42.36.81 1.096.81 2.22 0 1.605-.015 2.896-.015 3.286 0 .315.21.69.825.57C20.565 21.795 24 17.298 24 12c0-6.63-5.37-12-12-12z\"/>"
+ "</svg>"
<div class="checkout-social-btns">
<button type="button" class="checkout-social-btn" id="btn-google" onclick="signInWith('google')">
<svg width="18" height="18" viewBox="0 0 18 18" fill="none" aria-hidden="true">
<path d="M17.64 9.2c0-.637-.057-1.251-.164-1.84H9v3.481h4.844c-.209 1.125-.843 2.078-1.796 2.716v2.259h2.908c1.702-1.567 2.684-3.875 2.684-6.615z" fill="#4285F4"/>
<path d="M9 18c2.43 0 4.467-.806 5.956-2.18l-2.908-2.259c-.806.54-1.837.86-3.048.86-2.344 0-4.328-1.584-5.036-3.711H.957v2.332A8.997 8.997 0 0 0 9 18z" fill="#34A853"/>
<path d="M3.964 10.71A5.41 5.41 0 0 1 3.682 9c0-.593.102-1.17.282-1.71V4.958H.957A8.996 8.996 0 0 0 0 9c0 1.452.348 2.827.957 4.042l3.007-2.332z" fill="#FBBC05"/>
<path d="M9 3.58c1.321 0 2.508.454 3.44 1.345l2.582-2.58C13.463.891 11.426 0 9 0A8.997 8.997 0 0 0 .957 4.958L3.964 6.29C4.672 4.163 6.656 3.58 9 3.58z" fill="#EA4335"/>
</svg>
Continue with Google
</button>
<button type="button" class="checkout-social-btn" id="btn-github" onclick="signInWith('github')">
<svg width="18" height="18" viewBox="0 0 24 24" fill="currentColor" aria-hidden="true">
<path d="M12 0C5.37 0 0 5.37 0 12c0 5.303 3.438 9.8 8.205 11.385.6.113.82-.258.82-.577 0-.285-.01-1.04-.015-2.04-3.338.724-4.042-1.61-4.042-1.61-.546-1.385-1.335-1.755-1.335-1.755-1.087-.744.084-.729.084-.729 1.205.084 1.838 1.236 1.838 1.236 1.07 1.835 2.809 1.305 3.495.998.108-.776.417-1.305.76-1.605-2.665-.3-5.466-1.332-5.466-5.93 0-1.31.465-2.38 1.235-3.22-.135-.303-.54-1.523.105-3.176 0 0 1.005-.322 3.3 1.23.96-.267 1.98-.399 3-.405 1.02.006 2.04.138 3 .405 2.28-1.552 3.285-1.23 3.285-1.23.645 1.653.24 2.873.12 3.176.765.84 1.23 1.91 1.23 3.22 0 4.61-2.805 5.625-5.475 5.92.42.36.81 1.096.81 2.22 0 1.605-.015 2.896-.015 3.286 0 .315.21.69.825.57C20.565 21.795 24 17.298 24 12c0-6.63-5.37-12-12-12z"/>
</svg>
Continue with GitHub
</button>
</div>
let social_btns: String = el_div(
"class=\"checkout-social-btns\"",
"<button type=\"button\" class=\"checkout-social-btn\" id=\"btn-google\" onclick=\"signInWith('google')\">"
+ google_svg + "Continue with Google</button>"
+ "<button type=\"button\" class=\"checkout-social-btn\" id=\"btn-github\" onclick=\"signInWith('github')\">"
+ github_svg + "Continue with GitHub</button>"
)
<div id="auth-message" class="checkout-message" style="display:none;"></div>
let auth_message: String = el_div("id=\"auth-message\" class=\"checkout-message\" style=\"display:none;\"", "")
<div class="checkout-auth-divider">
<span id="auth-divider-label">or {#if is_free}create an account with email{#else}create an account{/if}</span>
</div>
let divider_label: String = if is_free {
"or create an account with email"
} else {
"or create an account"
}
<div id="email-auth-form">
<input type="email" id="auth-email" class="checkout-input" placeholder="Email address" autocomplete="email" style="width:100%;display:block;margin-bottom:.75rem">
<input type="password" id="auth-password" class="checkout-input" placeholder="Password - min 8 characters" autocomplete="new-password" style="width:100%;display:block;margin-bottom:.75rem">
<button type="button" class="checkout-email-btn" onclick="signUpWithEmail()">{#if is_free}Create account &#8594;{#else}Create account &rarr;{/if}</button>
<p class="checkout-auth-hint" style="margin-top:.75rem;text-align:center">Already have an account? <a href="#" onclick="showSignIn();return false;" style="color:var(--navy)">Sign in</a></p>
</div>
</div>
let auth_divider: String = el_div(
"class=\"checkout-auth-divider\"",
el_span("id=\"auth-divider-label\"", divider_label)
)
<!-- Free-tier success panel: shown after account creation, no card needed -->
" + (if is_free { "
<div id=\"free-success\" style=\"display:none; text-align:center; padding: 2.5rem 1rem;\">
<div style=\"font-size:2.5rem; margin-bottom:1.25rem;\">&#10003;</div>
<p class=\"label\" style=\"margin-bottom:.75rem; color:var(--navy);\">You&#39;re in.</p>
<p class=\"checkout-auth-hint\" style=\"margin-bottom:2rem;\">Your free account is ready. Download Neuron to get started.</p>
<a href=\"/marketplace\" class=\"checkout-submit\" style=\"display:inline-block; text-decoration:none; padding:.875rem 2rem;\">Go to your account &#8594;</a>
</div>
" } else { "" }) + "
let create_btn_label: String = if is_free { "Create account &#8594;" } else { "Create account &rarr;" }
<!-- Payment form (visible immediately - no auth wall) -->
<div id="payment-section" {#if is_free}style="display:none;"{/if}>
<div id="auth-badge" style="display:none; margin-bottom: 1.5rem;"></div>
{#if is_free}{#else}
<p class="checkout-auth-hint" id="signin-prompt" style="margin-bottom:1.25rem;font-size:.8125rem">Already have an account? <a href="#" onclick="document.getElementById('auth-section').style.display='';this.parentNode.style.display='none';return false;" style="color:var(--navy);text-decoration:underline">Sign in</a> to link your purchase.</p>
{/if}
let email_auth_form: String = el_div(
"id=\"email-auth-form\"",
el_input("email", "id=\"auth-email\" class=\"checkout-input\" placeholder=\"Email address\" autocomplete=\"email\" style=\"width:100%;display:block;margin-bottom:.75rem\"")
+ el_input("password", "id=\"auth-password\" class=\"checkout-input\" placeholder=\"Password - min 8 characters\" autocomplete=\"new-password\" style=\"width:100%;display:block;margin-bottom:.75rem\"")
+ "<button type=\"button\" class=\"checkout-email-btn\" onclick=\"signUpWithEmail()\">" + create_btn_label + "</button>"
+ el_p("class=\"checkout-auth-hint\" style=\"margin-top:.75rem;text-align:center\"",
"Already have an account? "
+ el_a("#", "onclick=\"showSignIn();return false;\" style=\"color:var(--navy)\"", "Sign in")
)
)
<!-- Founding Member attestation (only shown for founding plan) -->
{#if is_founding}
<div id="founding-attestation" style="margin-bottom:2rem;padding:1.5rem;border:1px solid rgba(0,82,160,.2);background:rgba(0,82,160,.03)">
<p style="font-family:var(--body);font-weight:500;font-size:.9rem;color:var(--t1);margin-bottom:.75rem">Before you continue</p>
<p style="font-family:var(--body);font-weight:300;font-size:.8375rem;color:var(--t2);line-height:1.75;margin-bottom:1.25rem">Founding Member is not a ceremonial title. These are the people who will work directly with the team to shape what Neuron becomes. You will have a real voice in what gets built, and we will take it seriously. That requires you to show up in good faith.</p>
<label style="display:flex;gap:.875rem;align-items:flex-start;cursor:pointer">
<input type="checkbox" id="founding-attest-cb" style="margin-top:.2rem;width:16px;height:16px;flex-shrink:0;accent-color:var(--navy)">
<span style="font-family:var(--body);font-weight:300;font-size:.8125rem;color:var(--t2);line-height:1.7">
I am joining as a genuine early user, not to extract proprietary information about Neuron&#39;s technology, architecture, or roadmap. I will engage in good faith. I understand that if this is not my intent, a different plan is a better fit.
</span>
</label>
<p id="attest-warn" style="display:none;font-family:var(--body);font-size:.8rem;color:#c44;margin-top:.75rem">Please confirm the above before continuing.</p>
</div>
{/if}
let auth_section_style: String = if is_free { "" } else { "display:none;" }
let auth_section: String = el_div(
"id=\"auth-section\" style=\"" + auth_section_style + "\"",
auth_heading + social_btns + auth_message + auth_divider + email_auth_form
)
<!-- Payment timing: Professional only (not Founding, not Free) -->
{#if is_founding}{#else}{#if is_free}{#else}
<div style="margin-bottom:1.75rem">
<p class="label" style="margin-bottom:1rem">When would you like to be charged?</p>
<div style="display:flex;flex-direction:column;gap:.625rem">
<label class="checkout-timing-opt" id="timing-now-label">
<input type="radio" name="charge-timing" value="now" id="timing-now" checked style="accent-color:var(--navy)">
<div>
<span style="font-family:var(--body);font-weight:500;font-size:.875rem;color:var(--t1)">Charge me now</span>
<span style="font-family:var(--body);font-weight:300;font-size:.8rem;color:var(--t3);display:block;margin-top:.15rem">Paying now signals you're serious. It gives us real signal about what people actually want to use Neuron for - not just who's curious. That shapes what we build first.</span>
</div>
</label>
<label class="checkout-timing-opt" id="timing-later-label">
<input type="radio" name="charge-timing" value="later" id="timing-later" style="accent-color:var(--navy)">
<div>
<span style="font-family:var(--body);font-weight:500;font-size:.875rem;color:var(--t1)">Hold until product launches (Q3 2026)</span>
<span style="font-family:var(--body);font-weight:300;font-size:.8rem;color:var(--t3);display:block;margin-top:.15rem">We save your payment method securely. Nothing charged until launch. Cancel anytime before then.</span>
</div>
</label>
</div>
</div>
{/if}{/if}
// Free-tier success panel
<p class="label" style="margin-bottom: 1.75rem;">Payment</p>
let free_success: String = if is_free {
el_div(
"id=\"free-success\" style=\"display:none; text-align:center; padding: 2.5rem 1rem;\"",
el_div("style=\"font-size:2.5rem; margin-bottom:1.25rem;\"", "&#10003;")
+ el_p("class=\"label\" style=\"margin-bottom:.75rem; color:var(--navy);\"", "You&#39;re in.")
+ el_p("class=\"checkout-auth-hint\" style=\"margin-bottom:2rem;\"", "Your free account is ready. Download Neuron to get started.")
+ el_a("/marketplace", "class=\"checkout-submit\" style=\"display:inline-block; text-decoration:none; padding:.875rem 2rem;\"", "Go to your account &#8594;")
)
} else { "" }
<form id="payment-form" autocomplete="on">
// Payment section
<div class="checkout-field-group">
<div class="checkout-field">
<label for="buyer-name" class="checkout-label">Full name</label>
<input id="buyer-name" name="name" type="text" autocomplete="name"
class="checkout-input" placeholder="Full name" required>
</div>
<div class="checkout-field">
<label for="buyer-email" class="checkout-label">Email</label>
<input id="buyer-email" name="email" type="email" autocomplete="email"
class="checkout-input" placeholder="you@example.com" required>
</div>
</div>
let payment_section_style: String = if is_free { "display:none;" } else { "" }
<div class="checkout-payment-element-wrap">
<div id="payment-element">
<!-- Stripe Payment Element mounts here -->
<div class="checkout-element-loading">Loading payment form&#8230;</div>
</div>
</div>
let auth_badge: String = el_div("id=\"auth-badge\" style=\"display:none; margin-bottom: 1.5rem;\"", "")
<div id="payment-message" class="checkout-message" style="display:none;"></div>
let signin_prompt: String = if is_free { "" } else {
el_p(
"class=\"checkout-auth-hint\" id=\"signin-prompt\" style=\"margin-bottom:1.25rem;font-size:.8125rem\"",
"Already have an account? "
+ el_a(
"#",
"onclick=\"document.getElementById('auth-section').style.display='';this.parentNode.style.display='none';return false;\" style=\"color:var(--navy);text-decoration:underline\"",
"Sign in"
)
+ " to link your purchase."
)
}
<button id="submit-btn" class="checkout-submit" type="submit" disabled>
<span id="submit-label">{#if is_free}Reserve free tier &#8594;{#else}Complete purchase &#8594;{/if}</span>
<span id="submit-spinner" style="display:none;">Processing&#8230;</span>
</button>
let founding_attestation: String = if is_founding {
el_div(
"id=\"founding-attestation\" style=\"margin-bottom:2rem;padding:1.5rem;border:1px solid rgba(0,82,160,.2);background:rgba(0,82,160,.03)\"",
el_p("style=\"font-family:var(--body);font-weight:500;font-size:.9rem;color:var(--t1);margin-bottom:.75rem\"", "Before you continue")
+ el_p("style=\"font-family:var(--body);font-weight:300;font-size:.8375rem;color:var(--t2);line-height:1.75;margin-bottom:1.25rem\"",
"Founding Member is not a ceremonial title. These are the people who will work directly with the team to shape what Neuron becomes. You will have a real voice in what gets built, and we will take it seriously. That requires you to show up in good faith."
)
+ "<label style=\"display:flex;gap:.875rem;align-items:flex-start;cursor:pointer\">"
+ el_input("checkbox", "id=\"founding-attest-cb\" style=\"margin-top:.2rem;width:16px;height:16px;flex-shrink:0;accent-color:var(--navy)\"")
+ el_span(
"style=\"font-family:var(--body);font-weight:300;font-size:.8125rem;color:var(--t2);line-height:1.7\"",
"I am joining as a genuine early user, not to extract proprietary information about Neuron&#39;s technology, architecture, or roadmap. I will engage in good faith. I understand that if this is not my intent, a different plan is a better fit."
)
+ "</label>"
+ el_p("id=\"attest-warn\" style=\"display:none;font-family:var(--body);font-size:.8rem;color:#c44;margin-top:.75rem\"", "Please confirm the above before continuing.")
)
} else { "" }
<p class="checkout-security">
<svg aria-hidden="true" width="12" height="14" viewBox="0 0 12 14" fill="none">
<path d="M6 0L0 2.5V7c0 3.3 2.5 6.3 6 7 3.5-.7 6-3.7 6-7V2.5L6 0z" fill="currentColor" opacity=".35"/>
<path d="M4 7l1.5 1.5L8.5 5" stroke="currentColor" stroke-width="1.2" stroke-linecap="round" stroke-linejoin="round"/>
</svg>
Secured by Stripe &nbsp;&middot;&nbsp; 256-bit TLS &nbsp;&middot;&nbsp; PCI DSS compliant
</p>
let charge_timing: String = if is_founding || is_free { "" } else {
el_div(
"style=\"margin-bottom:1.75rem\"",
el_p("class=\"label\" style=\"margin-bottom:1rem\"", "When would you like to be charged?")
+ el_div(
"style=\"display:flex;flex-direction:column;gap:.625rem\"",
"<label class=\"checkout-timing-opt\" id=\"timing-now-label\">"
+ el_input("radio", "name=\"charge-timing\" value=\"now\" id=\"timing-now\" checked style=\"accent-color:var(--navy)\"")
+ el_div("",
el_span("style=\"font-family:var(--body);font-weight:500;font-size:.875rem;color:var(--t1)\"", "Charge me now")
+ el_span("style=\"font-family:var(--body);font-weight:300;font-size:.8rem;color:var(--t3);display:block;margin-top:.15rem\"",
"Paying now signals you're serious. It gives us real signal about what people actually want to use Neuron for - not just who's curious. That shapes what we build first."
)
)
+ "</label>"
+ "<label class=\"checkout-timing-opt\" id=\"timing-later-label\">"
+ el_input("radio", "name=\"charge-timing\" value=\"later\" id=\"timing-later\" style=\"accent-color:var(--navy)\"")
+ el_div("",
el_span("style=\"font-family:var(--body);font-weight:500;font-size:.875rem;color:var(--t1)\"", "Hold until product launches (Q3 2026)")
+ el_span("style=\"font-family:var(--body);font-weight:300;font-size:.8rem;color:var(--t3);display:block;margin-top:.15rem\"",
"We save your payment method securely. Nothing charged until launch. Cancel anytime before then."
)
)
+ "</label>"
)
)
}
</form>
</div><!-- /payment-section -->
</div>
let security_svg: String = "<svg aria-hidden=\"true\" width=\"12\" height=\"14\" viewBox=\"0 0 12 14\" fill=\"none\">"
+ "<path d=\"M6 0L0 2.5V7c0 3.3 2.5 6.3 6 7 3.5-.7 6-3.7 6-7V2.5L6 0z\" fill=\"currentColor\" opacity=\".35\"/>"
+ "<path d=\"M4 7l1.5 1.5L8.5 5\" stroke=\"currentColor\" stroke-width=\"1.2\" stroke-linecap=\"round\" stroke-linejoin=\"round\"/>"
+ "</svg>"
</div>
</main>
let submit_label: String = if is_free { "Reserve free tier &#8594;" } else { "Complete purchase &#8594;" }
let payment_form: String = el_form(
"id=\"payment-form\" autocomplete=\"on\"",
el_div(
"class=\"checkout-field-group\"",
el_div("class=\"checkout-field\"",
el_label("buyer-name", "class=\"checkout-label\"", "Full name")
+ el_input("text", "id=\"buyer-name\" name=\"name\" autocomplete=\"name\" class=\"checkout-input\" placeholder=\"Full name\" required")
)
+ el_div("class=\"checkout-field\"",
el_label("buyer-email", "class=\"checkout-label\"", "Email")
+ el_input("email", "id=\"buyer-email\" name=\"email\" autocomplete=\"email\" class=\"checkout-input\" placeholder=\"you@example.com\" required")
)
)
+ el_div(
"class=\"checkout-payment-element-wrap\"",
el_div("id=\"payment-element\"",
el_div("class=\"checkout-element-loading\"", "Loading payment form&#8230;")
)
)
+ el_div("id=\"payment-message\" class=\"checkout-message\" style=\"display:none;\"", "")
+ "<button id=\"submit-btn\" class=\"checkout-submit\" type=\"submit\" disabled>"
+ el_span("id=\"submit-label\"", submit_label)
+ el_span("id=\"submit-spinner\" style=\"display:none;\"", "Processing&#8230;")
+ "</button>"
+ el_p("class=\"checkout-security\"",
security_svg
+ " Secured by Stripe &nbsp;&middot;&nbsp; 256-bit TLS &nbsp;&middot;&nbsp; PCI DSS compliant"
)
)
let payment_section: String = el_div(
"id=\"payment-section\" style=\"" + payment_section_style + "\"",
auth_badge
+ signin_prompt
+ founding_attestation
+ charge_timing
+ el_p("class=\"label\" style=\"margin-bottom: 1.75rem;\"", "Payment")
+ payment_form
)
// Right column
let form_wrap: String = el_div(
"class=\"checkout-form-wrap\"",
auth_section + free_success + payment_section
)
// Full page shell
let checkout_shell: String = el_div("class=\"checkout-shell\"", summary_col + form_wrap)
let main_html: String = el_main(
"style=\"min-height: 100vh; padding: clamp(6rem, 14vh, 9rem) 2rem 4rem;\"",
checkout_shell
)
let style_html: String = checkout_style_html()
let free_init_script: String = if is_free { "<script>document.addEventListener('DOMContentLoaded',function(){window.neuronCheckoutFree&&window.neuronCheckoutFree()});</script>" } else { "" }
return nav_html + main_html + "<!-- Supabase JS --><script src=\"https://cdn.jsdelivr.net/npm/@supabase/supabase-js@2/dist/umd/supabase.js\"></script><!-- Stripe.js --><script src=\"https://js.stripe.com/v3/\" async></script>" + style_html + "<script src=\"/js/checkout-auth.js\" defer></script><script>window.NEURON_CFG=window.NEURON_CFG||{};window.NEURON_CFG.plan=\"{plan}\";window.NEURON_CFG.pub_key=\"{pub_key}\";</script><script src=\"/js/checkout-stripe.js\" defer></script>" + free_init_script
let supabase_script: String = el_script_src("https://cdn.jsdelivr.net/npm/@supabase/supabase-js@2/dist/umd/supabase.js", false)
let stripe_script: String = "<script src=\"https://js.stripe.com/v3/\" async></script>"
let auth_script: String = el_script_src("/js/checkout-auth.js", true)
let cfg_js: String = "window.NEURON_CFG=window.NEURON_CFG||{};window.NEURON_CFG.plan=\"" + plan + "\";window.NEURON_CFG.pub_key=\"" + pub_key + "\";"
let cfg_script: String = el_script_inline(cfg_js)
let stripe_el_script: String = el_script_src("/js/checkout-stripe.js", true)
let free_init_script: String = if is_free {
el_script_inline("document.addEventListener('DOMContentLoaded',function(){window.neuronCheckoutFree&&window.neuronCheckoutFree()});")
} else { "" }
return nav_html + main_html + supabase_script + stripe_script + style_html + auth_script + cfg_script + stripe_el_script + free_init_script
}
fn checkout_style_html() -> String {
<style>
.checkout-plan-name {
let css: String = ".checkout-plan-name {
font-family: var(--head);
font-size: clamp(1.5rem, 3vw, 2rem);
font-weight: 600;
@@ -294,7 +402,7 @@ fn checkout_style_html() -> String {
position: relative;
}
.checkout-features li::before {
content: '';
content: '-';
position: absolute;
left: 0;
color: var(--navy);
@@ -486,6 +594,6 @@ fn checkout_style_html() -> String {
font-size: .8125rem;
color: var(--t2);
}
.checkout-auth-badge strong { color: var(--navy); font-weight: 500; }
</style>
.checkout-auth-badge strong { color: var(--navy); font-weight: 500; }"
el_style_block(css)
}
+45
View File
@@ -0,0 +1,45 @@
// elhtml.el extern declarations for the el-html vessel.
// The implementations live in dist/elhtml.c (pre-compiled).
// Import this file instead of the vessel source directly.
extern fn el_escape(s: String) -> String
extern fn el_text(s: String) -> String
extern fn el_attr(name: String, value: String) -> String
extern fn el_div(attrs: String, children: String) -> String
extern fn el_section(attrs: String, children: String) -> String
extern fn el_article(attrs: String, children: String) -> String
extern fn el_header(attrs: String, children: String) -> String
extern fn el_footer(attrs: String, children: String) -> String
extern fn el_main(attrs: String, children: String) -> String
extern fn el_nav(attrs: String, children: String) -> String
extern fn el_aside(attrs: String, children: String) -> String
extern fn el_ul(attrs: String, children: String) -> String
extern fn el_ol(attrs: String, children: String) -> String
extern fn el_li(attrs: String, children: String) -> String
extern fn el_p(attrs: String, children: String) -> String
extern fn el_span(attrs: String, children: String) -> String
extern fn el_form(attrs: String, children: String) -> String
extern fn el_h1(attrs: String, text: String) -> String
extern fn el_h2(attrs: String, text: String) -> String
extern fn el_h3(attrs: String, text: String) -> String
extern fn el_h4(attrs: String, text: String) -> String
extern fn el_button(attrs: String, label: String) -> String
extern fn el_a(href: String, attrs: String, children: String) -> String
extern fn el_input(type_attr: String, attrs: String) -> String
extern fn el_textarea(attrs: String, value: String) -> String
extern fn el_label(for_id: String, attrs: String, children: String) -> String
extern fn el_img(src: String, alt: String, attrs: String) -> String
extern fn el_video(attrs: String, children: String) -> String
extern fn el_strong(children: String) -> String
extern fn el_em(children: String) -> String
extern fn el_code(children: String) -> String
extern fn el_pre(attrs: String, children: String) -> String
extern fn el_hr() -> String
extern fn el_br() -> String
extern fn el_html_doc(lang: String, head_html: String, body_html: String) -> String
extern fn el_meta(name: String, content: String) -> String
extern fn el_meta_charset(charset: String) -> String
extern fn el_link_stylesheet(href: String) -> String
extern fn el_script_src(src: String, defer_load: Bool) -> String
extern fn el_script_inline(js: String) -> String
extern fn el_title(text: String) -> String
+214 -143
View File
@@ -21,6 +21,48 @@
// GET /brand/* brand assets via handle_request
// GET * 404 JSON (non-/ paths not used by this SPA)
// el-html vessel extern declarations (implementations in dist/elhtml_impl.c)
extern fn el_escape(s: String) -> String
extern fn el_text(s: String) -> String
extern fn el_attr(name: String, value: String) -> String
extern fn el_div(attrs: String, children: String) -> String
extern fn el_section(attrs: String, children: String) -> String
extern fn el_article(attrs: String, children: String) -> String
extern fn el_header(attrs: String, children: String) -> String
extern fn el_footer(attrs: String, children: String) -> String
extern fn el_main(attrs: String, children: String) -> String
extern fn el_nav(attrs: String, children: String) -> String
extern fn el_aside(attrs: String, children: String) -> String
extern fn el_ul(attrs: String, children: String) -> String
extern fn el_ol(attrs: String, children: String) -> String
extern fn el_li(attrs: String, children: String) -> String
extern fn el_p(attrs: String, children: String) -> String
extern fn el_span(attrs: String, children: String) -> String
extern fn el_form(attrs: String, children: String) -> String
extern fn el_h1(attrs: String, text: String) -> String
extern fn el_h2(attrs: String, text: String) -> String
extern fn el_h3(attrs: String, text: String) -> String
extern fn el_h4(attrs: String, text: String) -> String
extern fn el_button(attrs: String, label: String) -> String
extern fn el_a(href: String, attrs: String, children: String) -> String
extern fn el_input(type_attr: String, attrs: String) -> String
extern fn el_textarea(attrs: String, value: String) -> String
extern fn el_label(for_id: String, attrs: String, children: String) -> String
extern fn el_img(src: String, alt: String, attrs: String) -> String
extern fn el_strong(children: String) -> String
extern fn el_em(children: String) -> String
extern fn el_code(children: String) -> String
extern fn el_pre(attrs: String, children: String) -> String
extern fn el_hr() -> String
extern fn el_br() -> String
extern fn el_html_doc(lang: String, head_html: String, body_html: String) -> String
extern fn el_meta(name: String, content: String) -> String
extern fn el_meta_charset(charset: String) -> String
extern fn el_link_stylesheet(href: String) -> String
extern fn el_script_src(src: String, defer_load: Bool) -> String
extern fn el_script_inline(js: String) -> String
extern fn el_title(text: String) -> String
from nav import { nav }
from hero import { hero }
from pillars import { pillars }
@@ -193,140 +235,167 @@ fn share_card_page(question: String, answer_plain: String, answer_html_in: Strin
// TikTok and Snapchat have no web URL share scheme use clipboard copy
let tiktok_copy_text: String = "Copied+%E2%80%94+paste+into+TikTok"
let snap_copy_text: String = "Copied+%E2%80%94+paste+into+Snapchat"
return <!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width,initial-scale=1">
<title>Things Neuron Said</title>
<meta property="og:title" content="Things Neuron Said">
<meta property="og:description" content="{og_desc}">
<meta property="og:image" content="https://neurontechnologies.ai/assets/brand/neuron-wordmark-on-light@2x.png">
<meta property="og:type" content="website">
<meta property="og:url" content="{card_url}">
<meta name="twitter:card" content="summary_large_image">
<meta name="twitter:title" content="Things Neuron Said">
<meta name="twitter:description" content="{og_desc}">
<meta name="twitter:image" content="https://neurontechnologies.ai/assets/brand/neuron-wordmark-on-light@2x.png">
<link rel="preconnect" href="https://fonts.googleapis.com">
<link href="https://fonts.googleapis.com/css2?family=IBM+Plex+Sans:wght@300;400;500;600&display=swap" rel="stylesheet">
<style>
*,*::before,*::after{box-sizing:border-box;margin:0;padding:0}
:root{--navy:#0052A0;--navy-dark:#003d7a;--t1:#0D0D14;--t2:#3A3A4A;--t3:#6B6B7E;--bg:#FAFAF8}
body{font-family:'IBM Plex Sans',system-ui,sans-serif;background:var(--bg);color:var(--t1);min-height:100vh;display:flex;flex-direction:column;align-items:center;justify-content:center;padding:2rem 1rem}
body::before{content:'';position:fixed;inset:0;pointer-events:none;z-index:0;background-image:linear-gradient(rgba(0,0,0,.018) 1px,transparent 1px),linear-gradient(90deg,rgba(0,0,0,.018) 1px,transparent 1px);background-size:48px 48px}
.page{width:100%;max-width:580px;display:flex;flex-direction:column;gap:1.75rem;position:relative;z-index:1}
.page-header{display:flex;align-items:center;justify-content:space-between;gap:1rem}
.wordmark img{height:22px;width:auto;display:block}
.eyebrow{font-size:.65rem;font-weight:400;letter-spacing:.16em;text-transform:uppercase;color:var(--t3)}
.chat-frame{background:#fff;border:1px solid rgba(0,0,0,.09);box-shadow:0 4px 32px rgba(0,0,0,.07),0 1px 4px rgba(0,0,0,.04);padding:1.5rem;display:flex;flex-direction:column;gap:1rem}
.chat-row-user{display:flex;flex-direction:row-reverse}
.chat-row-ai{display:flex;flex-direction:row;align-items:flex-end;gap:.625rem}
.bubble-user{background:#0052A0;color:#fff;border-radius:18px 18px 4px 18px;padding:11px 15px;max-width:78%;font-size:.875rem;line-height:1.55;word-break:break-word}
.bubble-ai{background:var(--bg);color:var(--t1);border:1px solid rgba(0,0,0,.07);border-radius:18px 18px 18px 4px;padding:11px 15px;max-width:88%;font-size:.875rem;font-weight:300;line-height:1.65;word-break:break-word;box-shadow:0 2px 6px rgba(0,0,0,.05)}
.bubble-ai p{margin:0}
.bubble-ai p+p{margin-top:.6rem}
.bubble-ai ul,.bubble-ai ol{margin:.5rem 0 .5rem 1.25rem;padding:0}
.bubble-ai li+li{margin-top:.25rem}
.bubble-ai strong{font-weight:600}
.bubble-ai em{font-style:italic}
.bubble-ai code{font-family:'IBM Plex Mono','Menlo',monospace;font-size:.8rem;background:rgba(0,0,0,.05);padding:1px 4px;border-radius:3px}
.bubble-ai pre{background:rgba(0,0,0,.05);padding:.75rem;border-radius:6px;overflow-x:auto;font-size:.8rem;margin:.5rem 0}
.bubble-ai pre code{background:none;padding:0}
.bubble-ai blockquote{border-left:3px solid rgba(0,82,160,.3);margin:.5rem 0;padding:.25rem 0 .25rem .75rem;color:var(--t2)}
.bubble-ai h1,.bubble-ai h2,.bubble-ai h3,.bubble-ai h4{font-weight:600;margin:.5rem 0 .25rem}
.bubble-ai h1{font-size:1.05rem}.bubble-ai h2{font-size:1rem}.bubble-ai h3{font-size:.95rem}.bubble-ai h4{font-size:.9rem}
.bubble-ai a{color:var(--navy);text-decoration:underline}
.ai-col{display:flex;flex-direction:column;gap:.25rem}
.ai-label{font-size:.6rem;font-weight:600;letter-spacing:.14em;text-transform:uppercase;color:var(--navy)}
.avatar{width:26px;height:26px;border-radius:50%;flex-shrink:0;background:#fff;border:1px solid rgba(0,82,160,.15);display:flex;align-items:center;justify-content:center}
.avatar img{width:14px;height:14px;object-fit:contain}
.vote-row{display:flex;align-items:center;gap:.75rem}
.vote-label{font-size:.65rem;font-weight:400;letter-spacing:.12em;text-transform:uppercase;color:var(--t3)}
.vote-btn{background:none;border:1px solid rgba(0,0,0,.12);cursor:pointer;padding:.3rem .6rem;font-size:.8rem;color:var(--t2);transition:all .15s;line-height:1}
.vote-btn:hover{border-color:var(--navy);color:var(--navy)}
.vote-btn.voted-up{background:var(--navy);color:#fff;border-color:var(--navy)}
.vote-btn.voted-down{background:#f0f0ec;color:var(--t3);border-color:rgba(0,0,0,.12)}
.vote-count{font-size:.8rem;font-weight:500;color:var(--t1);min-width:1.5rem;text-align:center}
.share-section{display:flex;flex-direction:column;gap:.625rem}
.share-label{font-size:.65rem;font-weight:500;letter-spacing:.12em;text-transform:uppercase;color:var(--t3)}
.share-row{display:flex;align-items:center;gap:.5rem;flex-wrap:wrap}
.share-btn{display:inline-flex;align-items:center;justify-content:center;width:36px;height:36px;border-radius:50%;border:none;text-decoration:none;cursor:pointer;transition:opacity .15s,transform .15s;flex-shrink:0}
.share-btn:hover{opacity:.85;transform:scale(1.08)}
.share-btn.copied{outline:2px solid var(--navy)}
.divider{height:1px;background:rgba(0,0,0,.07)}
.footer-row{display:flex;align-items:center;justify-content:space-between;gap:1rem;flex-wrap:wrap}
.footer-note{font-size:.75rem;color:var(--t3)}
.cta-btn{display:inline-flex;align-items:center;gap:.5rem;background:var(--navy);color:#fff;text-decoration:none;font-size:.7rem;font-weight:500;letter-spacing:.14em;text-transform:uppercase;padding:.7rem 1.4rem;white-space:nowrap;transition:background .15s}
.cta-btn:hover{background:var(--navy-dark)}
@media(max-width:480px){.chat-frame{padding:1.25rem}.footer-row{flex-direction:column;align-items:flex-start}}
</style>
</head>
<body>
<div class="page">
<div class="page-header">
<a href="https://neurontechnologies.ai" class="wordmark">
<img src="/assets/brand/neuron-wordmark-on-light.png"
srcset="/assets/brand/neuron-wordmark-on-light@2x.png 2x"
alt="Neuron" height="22">
</a>
<span class="eyebrow">Things Neuron Said</span>
</div>
<div class="chat-frame">
<div class="chat-row-user">
<div class="bubble-user">{raw(q_html)}</div>
</div>
<div class="chat-row-ai">
<div class="avatar"><img src="/assets/neuron-icon.png" alt=""></div>
<div class="ai-col">
<span class="ai-label">Neuron</span>
<div class="bubble-ai">{raw(a_html)}</div>
</div>
</div>
</div>
let cfg_js: String = "window.NEURON_CFG=window.NEURON_CFG||{};window.NEURON_CFG.id=\"" + id + "\";window.NEURON_CFG.card_url=\"" + card_url + "\";"
<div class="vote-row">
<span class="vote-label">Helpful?</span>
<button class="vote-btn" id="vote-up">&#9650;</button>
<span class="vote-count" id="vote-score">0</span>
<button class="vote-btn" id="vote-down">&#9660;</button>
</div>
// Head
<div class="share-section">
<span class="share-label">Share</span>
<div class="share-row">
<a href="{x_href}" target="_blank" rel="noopener" class="share-btn" title="Post on X" style="background:#000">
<img src="/assets/social/x.svg" width="18" height="18" alt="X">
</a>
<a href="{li_href}" target="_blank" rel="noopener" class="share-btn" title="Share on LinkedIn" style="background:transparent">
<img src="/assets/social/linkedin.png" width="18" height="18" alt="LinkedIn">
</a>
<a href="{fb_href}" target="_blank" rel="noopener" class="share-btn" title="Share on Facebook" style="background:#1877F2">
<img src="/assets/social/facebook.svg" width="18" height="18" alt="Facebook">
</a>
<a href="{wa_href}" target="_blank" rel="noopener" class="share-btn" title="Send via WhatsApp" style="background:#25D366">
<img src="/assets/social/whatsapp.svg" width="18" height="18" alt="WhatsApp">
</a>
<button class="share-btn" id="copy-tiktok" onclick="copyForPlatform('tiktok', this)" title="Copy for TikTok" style="background:#010101;border:none">
<img src="/assets/social/tiktok.svg" width="18" height="18" alt="TikTok">
</button>
<button class="share-btn" id="copy-snapchat" onclick="copyForPlatform('snapchat', this)" title="Copy for Snapchat" style="background:#FFFC00;border:none">
<img src="/assets/social/snapchat.svg" width="18" height="18" alt="Snapchat">
</button>
</div>
</div>
let share_css: String = "*,*::before,*::after{box-sizing:border-box;margin:0;padding:0}"
+ ":root{--navy:#0052A0;--navy-dark:#003d7a;--t1:#0D0D14;--t2:#3A3A4A;--t3:#6B6B7E;--bg:#FAFAF8}"
+ "body{font-family:'IBM Plex Sans',system-ui,sans-serif;background:var(--bg);color:var(--t1);min-height:100vh;display:flex;flex-direction:column;align-items:center;justify-content:center;padding:2rem 1rem}"
+ "body::before{content:'';position:fixed;inset:0;pointer-events:none;z-index:0;background-image:linear-gradient(rgba(0,0,0,.018) 1px,transparent 1px),linear-gradient(90deg,rgba(0,0,0,.018) 1px,transparent 1px);background-size:48px 48px}"
+ ".page{width:100%;max-width:580px;display:flex;flex-direction:column;gap:1.75rem;position:relative;z-index:1}"
+ ".page-header{display:flex;align-items:center;justify-content:space-between;gap:1rem}"
+ ".wordmark img{height:22px;width:auto;display:block}"
+ ".eyebrow{font-size:.65rem;font-weight:400;letter-spacing:.16em;text-transform:uppercase;color:var(--t3)}"
+ ".chat-frame{background:#fff;border:1px solid rgba(0,0,0,.09);box-shadow:0 4px 32px rgba(0,0,0,.07),0 1px 4px rgba(0,0,0,.04);padding:1.5rem;display:flex;flex-direction:column;gap:1rem}"
+ ".chat-row-user{display:flex;flex-direction:row-reverse}"
+ ".chat-row-ai{display:flex;flex-direction:row;align-items:flex-end;gap:.625rem}"
+ ".bubble-user{background:#0052A0;color:#fff;border-radius:18px 18px 4px 18px;padding:11px 15px;max-width:78%;font-size:.875rem;line-height:1.55;word-break:break-word}"
+ ".bubble-ai{background:var(--bg);color:var(--t1);border:1px solid rgba(0,0,0,.07);border-radius:18px 18px 18px 4px;padding:11px 15px;max-width:88%;font-size:.875rem;font-weight:300;line-height:1.65;word-break:break-word;box-shadow:0 2px 6px rgba(0,0,0,.05)}"
+ ".bubble-ai p{margin:0}"
+ ".bubble-ai p+p{margin-top:.6rem}"
+ ".bubble-ai ul,.bubble-ai ol{margin:.5rem 0 .5rem 1.25rem;padding:0}"
+ ".bubble-ai li+li{margin-top:.25rem}"
+ ".bubble-ai strong{font-weight:600}"
+ ".bubble-ai em{font-style:italic}"
+ ".bubble-ai code{font-family:'IBM Plex Mono','Menlo',monospace;font-size:.8rem;background:rgba(0,0,0,.05);padding:1px 4px;border-radius:3px}"
+ ".bubble-ai pre{background:rgba(0,0,0,.05);padding:.75rem;border-radius:6px;overflow-x:auto;font-size:.8rem;margin:.5rem 0}"
+ ".bubble-ai pre code{background:none;padding:0}"
+ ".bubble-ai blockquote{border-left:3px solid rgba(0,82,160,.3);margin:.5rem 0;padding:.25rem 0 .25rem .75rem;color:var(--t2)}"
+ ".bubble-ai h1,.bubble-ai h2,.bubble-ai h3,.bubble-ai h4{font-weight:600;margin:.5rem 0 .25rem}"
+ ".bubble-ai h1{font-size:1.05rem}.bubble-ai h2{font-size:1rem}.bubble-ai h3{font-size:.95rem}.bubble-ai h4{font-size:.9rem}"
+ ".bubble-ai a{color:var(--navy);text-decoration:underline}"
+ ".ai-col{display:flex;flex-direction:column;gap:.25rem}"
+ ".ai-label{font-size:.6rem;font-weight:600;letter-spacing:.14em;text-transform:uppercase;color:var(--navy)}"
+ ".avatar{width:26px;height:26px;border-radius:50%;flex-shrink:0;background:#fff;border:1px solid rgba(0,82,160,.15);display:flex;align-items:center;justify-content:center}"
+ ".avatar img{width:14px;height:14px;object-fit:contain}"
+ ".vote-row{display:flex;align-items:center;gap:.75rem}"
+ ".vote-label{font-size:.65rem;font-weight:400;letter-spacing:.12em;text-transform:uppercase;color:var(--t3)}"
+ ".vote-btn{background:none;border:1px solid rgba(0,0,0,.12);cursor:pointer;padding:.3rem .6rem;font-size:.8rem;color:var(--t2);transition:all .15s;line-height:1}"
+ ".vote-btn:hover{border-color:var(--navy);color:var(--navy)}"
+ ".vote-btn.voted-up{background:var(--navy);color:#fff;border-color:var(--navy)}"
+ ".vote-btn.voted-down{background:#f0f0ec;color:var(--t3);border-color:rgba(0,0,0,.12)}"
+ ".vote-count{font-size:.8rem;font-weight:500;color:var(--t1);min-width:1.5rem;text-align:center}"
+ ".share-section{display:flex;flex-direction:column;gap:.625rem}"
+ ".share-label{font-size:.65rem;font-weight:500;letter-spacing:.12em;text-transform:uppercase;color:var(--t3)}"
+ ".share-row{display:flex;align-items:center;gap:.5rem;flex-wrap:wrap}"
+ ".share-btn{display:inline-flex;align-items:center;justify-content:center;width:36px;height:36px;border-radius:50%;border:none;text-decoration:none;cursor:pointer;transition:opacity .15s,transform .15s;flex-shrink:0}"
+ ".share-btn:hover{opacity:.85;transform:scale(1.08)}"
+ ".share-btn.copied{outline:2px solid var(--navy)}"
+ ".divider{height:1px;background:rgba(0,0,0,.07)}"
+ ".footer-row{display:flex;align-items:center;justify-content:space-between;gap:1rem;flex-wrap:wrap}"
+ ".footer-note{font-size:.75rem;color:var(--t3)}"
+ ".cta-btn{display:inline-flex;align-items:center;gap:.5rem;background:var(--navy);color:#fff;text-decoration:none;font-size:.7rem;font-weight:500;letter-spacing:.14em;text-transform:uppercase;padding:.7rem 1.4rem;white-space:nowrap;transition:background .15s}"
+ ".cta-btn:hover{background:var(--navy-dark)}"
+ "@media(max-width:480px){.chat-frame{padding:1.25rem}.footer-row{flex-direction:column;align-items:flex-start}}"
<div class="divider"></div>
let head_html: String = el_meta_charset("UTF-8")
+ "<meta name=\"viewport\" content=\"width=device-width,initial-scale=1\" />"
+ el_title("Things Neuron Said")
+ "<meta property=\"og:title\" content=\"Things Neuron Said\" />"
+ "<meta property=\"og:description\" content=\"" + el_escape(og_desc) + "\" />"
+ "<meta property=\"og:image\" content=\"https://neurontechnologies.ai/assets/brand/neuron-wordmark-on-light@2x.png\" />"
+ "<meta property=\"og:type\" content=\"website\" />"
+ "<meta property=\"og:url\" content=\"" + el_escape(card_url) + "\" />"
+ "<meta name=\"twitter:card\" content=\"summary_large_image\" />"
+ "<meta name=\"twitter:title\" content=\"Things Neuron Said\" />"
+ "<meta name=\"twitter:description\" content=\"" + el_escape(og_desc) + "\" />"
+ "<meta name=\"twitter:image\" content=\"https://neurontechnologies.ai/assets/brand/neuron-wordmark-on-light@2x.png\" />"
+ "<link rel=\"preconnect\" href=\"https://fonts.googleapis.com\" />"
+ "<link href=\"https://fonts.googleapis.com/css2?family=IBM+Plex+Sans:wght@300;400;500;600&display=swap\" rel=\"stylesheet\" />"
+ "<style>" + share_css + "</style>"
<div class="footer-row">
<span class="footer-note">From a live conversation with Neuron.</span>
<a href="https://neurontechnologies.ai" class="cta-btn">Try Neuron &#8599;</a>
</div>
</div>
<script>window.NEURON_CFG=window.NEURON_CFG||{};window.NEURON_CFG.id="{id}";window.NEURON_CFG.card_url="{card_url}";</script><script src="/js/main.js" defer></script>
</body>
</html>
// Body
let wordmark_link: String = el_a(
"https://neurontechnologies.ai",
"class=\"wordmark\"",
el_img(
"/assets/brand/neuron-wordmark-on-light.png",
"Neuron",
"srcset=\"/assets/brand/neuron-wordmark-on-light@2x.png 2x\" height=\"22\""
)
)
let page_header: String = el_div(
"class=\"page-header\"",
wordmark_link + el_span("class=\"eyebrow\"", "Things Neuron Said")
)
let user_bubble: String = el_div("class=\"chat-row-user\"",
el_div("class=\"bubble-user\"", q_html)
)
let avatar: String = el_div("class=\"avatar\"",
el_img("/assets/neuron-icon.png", "", "")
)
let ai_col: String = el_div("class=\"ai-col\"",
el_span("class=\"ai-label\"", "Neuron")
+ el_div("class=\"bubble-ai\"", a_html)
)
let ai_bubble: String = el_div("class=\"chat-row-ai\"", avatar + ai_col)
let chat_frame: String = el_div("class=\"chat-frame\"", user_bubble + ai_bubble)
let vote_row: String = el_div(
"class=\"vote-row\"",
el_span("class=\"vote-label\"", "Helpful?")
+ "<button class=\"vote-btn\" id=\"vote-up\">&#9650;</button>"
+ el_span("class=\"vote-count\" id=\"vote-score\"", "0")
+ "<button class=\"vote-btn\" id=\"vote-down\">&#9660;</button>"
)
let share_row: String = el_div(
"class=\"share-row\"",
el_a(x_href, "target=\"_blank\" rel=\"noopener\" class=\"share-btn\" title=\"Post on X\" style=\"background:#000\"",
el_img("/assets/social/x.svg", "X", "width=\"18\" height=\"18\"")
)
+ el_a(li_href, "target=\"_blank\" rel=\"noopener\" class=\"share-btn\" title=\"Share on LinkedIn\" style=\"background:transparent\"",
el_img("/assets/social/linkedin.png", "LinkedIn", "width=\"18\" height=\"18\"")
)
+ el_a(fb_href, "target=\"_blank\" rel=\"noopener\" class=\"share-btn\" title=\"Share on Facebook\" style=\"background:#1877F2\"",
el_img("/assets/social/facebook.svg", "Facebook", "width=\"18\" height=\"18\"")
)
+ el_a(wa_href, "target=\"_blank\" rel=\"noopener\" class=\"share-btn\" title=\"Send via WhatsApp\" style=\"background:#25D366\"",
el_img("/assets/social/whatsapp.svg", "WhatsApp", "width=\"18\" height=\"18\"")
)
+ "<button class=\"share-btn\" id=\"copy-tiktok\" onclick=\"copyForPlatform('tiktok', this)\" title=\"Copy for TikTok\" style=\"background:#010101;border:none\">"
+ el_img("/assets/social/tiktok.svg", "TikTok", "width=\"18\" height=\"18\"")
+ "</button>"
+ "<button class=\"share-btn\" id=\"copy-snapchat\" onclick=\"copyForPlatform('snapchat', this)\" title=\"Copy for Snapchat\" style=\"background:#FFFC00;border:none\">"
+ el_img("/assets/social/snapchat.svg", "Snapchat", "width=\"18\" height=\"18\"")
+ "</button>"
)
let share_section: String = el_div(
"class=\"share-section\"",
el_span("class=\"share-label\"", "Share") + share_row
)
let footer_row: String = el_div(
"class=\"footer-row\"",
el_span("class=\"footer-note\"", "From a live conversation with Neuron.")
+ el_a("https://neurontechnologies.ai", "class=\"cta-btn\"", "Try Neuron &#8599;")
)
let page_div: String = el_div(
"class=\"page\"",
page_header
+ chat_frame
+ vote_row
+ share_section
+ el_div("class=\"divider\"", "")
+ footer_row
)
let body_html: String = page_div
+ el_script_inline(cfg_js)
+ el_script_src("/js/main.js", true)
el_html_doc("en", head_html, body_html)
}
// Static asset serving
@@ -1643,20 +1712,22 @@ fn handle_request_inner(method: String, path: String, body: String) -> String {
if str_starts_with(path, "/marketplace/success") {
let badge_html: String = founding_badge(get_sold())
let badge_css: String = founding_badge_css()
return page_open() + badge_css + "
<div style=\"min-height:80vh;display:flex;flex-direction:column;align-items:center;justify-content:center;text-align:center;padding:4rem 2rem\">
<p class=\"label\" style=\"margin-bottom:1.5rem\">You&#39;re in.</p>
<h1 class=\"display-lg\" style=\"margin-bottom:1.25rem\">Welcome to Neuron.</h1>
<p style=\"font-family:var(--body);font-weight:300;font-size:1.1rem;color:var(--t2);max-width:28rem;line-height:1.7;margin-bottom:3rem\">
Your license is being provisioned. Check your email - your license key and download instructions will be there in the next few minutes.
</p>
<div style=\"margin-bottom:3rem\">" + badge_html + "</div>
<div style=\"display:flex;gap:1rem;flex-wrap:wrap;justify-content:center\">
<a href=\"/account\" class=\"btn-primary\">View your account &#8594;</a>
<a href=\"/\" class=\"btn-ghost\">Back to home</a>
</div>
</div>
" + page_close()
let success_body: String = el_div(
"style=\"min-height:80vh;display:flex;flex-direction:column;align-items:center;justify-content:center;text-align:center;padding:4rem 2rem\"",
el_p("class=\"label\" style=\"margin-bottom:1.5rem\"", "You&#39;re in.")
+ el_h1("class=\"display-lg\" style=\"margin-bottom:1.25rem\"", "Welcome to Neuron.")
+ el_p(
"style=\"font-family:var(--body);font-weight:300;font-size:1.1rem;color:var(--t2);max-width:28rem;line-height:1.7;margin-bottom:3rem\"",
"Your license is being provisioned. Check your email - your license key and download instructions will be there in the next few minutes."
)
+ el_div("style=\"margin-bottom:3rem\"", badge_html)
+ el_div(
"style=\"display:flex;gap:1rem;flex-wrap:wrap;justify-content:center\"",
el_a("/account", "class=\"btn-primary\"", "View your account &#8594;")
+ el_a("/", "class=\"btn-ghost\"", "Back to home")
)
)
return page_open() + badge_css + success_body + page_close()
}
// Account dashboard