Compare commits

..

7 Commits

Author SHA1 Message Date
Tim Lingo c38a552266 copy(pricing+hero): disclose the two-bill reality before money moves — price riders, What-you'll-need box, hero claim fix
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-22 17:30:03 -05:00
will.anderson b87b0bed24 Merge pull request 'fix(web): soften two unbacked claims for closed-beta honesty' (#157) from fix/honest-claims-closed-beta into main
Deploy marketing to Cloud Run / deploy (push) Failing after 3m33s
2026-06-18 16:40:41 +00:00
Tim Lingo ef352d2b8a fix(web): soften two false claims for closed-beta honesty
Audit found two website claims with no backing implementation:
- '3 marketplace plugins included' (free tier) -> 'Plugin marketplace access
  (coming soon)'. The marketplace is not built; there are no free plugins.
- 'Connectors - day one' -> 'Connectors (rolling out)'. Only a few connectors
  are available; Slack is coming-soon, Gmail/Drive not yet shipped.

String-content only; elc syntax-checks clean. Three other audit flags (no-card
wording, crisis-line copy, post-quantum 'everything encrypted') intentionally
NOT touched - left for human review (sensitive / conflicting evidence).

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-18 00:42:51 -05:00
will.anderson bb690c4690 Merge pull request 'Deploy: clean prod build — strip CGI content' (#112) from stage into main
Deploy marketing to Cloud Run / deploy (push) Failing after 41s
2026-05-11 21:49:47 +00:00
will.anderson 5885826316 Merge pull request 'Deploy: CI fixes (migrations, source guard, asset-only detection)' (#109) from stage into main
Deploy marketing to Cloud Run / deploy (push) Successful in 1m47s
2026-05-11 20:59:04 +00:00
will.anderson cac986c5e1 Merge pull request 'promote: stage → main' (#5) from stage into main
Deploy marketing to Cloud Run / deploy (push) Failing after 30s
2026-05-11 20:31:39 +00:00
will.anderson cd93af38fb Merge pull request 'promote: stage → main' (#5) from stage into main 2026-05-05 11:07:25 +00:00
5 changed files with 39 additions and 26 deletions
+20 -21
View File
@@ -1,4 +1,3 @@
// elhtml_impl.c — El HTML element stubs.
#include <stdint.h> #include <stdint.h>
#include <stdlib.h> #include <stdlib.h>
#include "el_runtime.h" #include "el_runtime.h"
@@ -20,11 +19,11 @@ 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_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_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_form(el_val_t attrs, el_val_t children);
el_val_t el_h1(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 children); 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 children); 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 children); 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 children); 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_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_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_textarea(el_val_t attrs, el_val_t value);
@@ -177,43 +176,43 @@ el_val_t el_form(el_val_t attrs, el_val_t children) {
return 0; return 0;
} }
el_val_t el_h1(el_val_t attrs, el_val_t children) { el_val_t el_h1(el_val_t attrs, el_val_t text) {
if (str_eq(attrs, EL_STR(""))) { if (str_eq(attrs, EL_STR(""))) {
return el_str_concat(el_str_concat(EL_STR("<h1>"), children), EL_STR("</h1>")); 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(">")), children), 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; return 0;
} }
el_val_t el_h2(el_val_t attrs, el_val_t children) { el_val_t el_h2(el_val_t attrs, el_val_t text) {
if (str_eq(attrs, EL_STR(""))) { if (str_eq(attrs, EL_STR(""))) {
return el_str_concat(el_str_concat(EL_STR("<h2>"), children), EL_STR("</h2>")); 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(">")), children), 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; return 0;
} }
el_val_t el_h3(el_val_t attrs, el_val_t children) { el_val_t el_h3(el_val_t attrs, el_val_t text) {
if (str_eq(attrs, EL_STR(""))) { if (str_eq(attrs, EL_STR(""))) {
return el_str_concat(el_str_concat(EL_STR("<h3>"), children), EL_STR("</h3>")); 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(">")), children), 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; return 0;
} }
el_val_t el_h4(el_val_t attrs, el_val_t children) { el_val_t el_h4(el_val_t attrs, el_val_t text) {
if (str_eq(attrs, EL_STR(""))) { if (str_eq(attrs, EL_STR(""))) {
return el_str_concat(el_str_concat(EL_STR("<h4>"), children), EL_STR("</h4>")); 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(">")), children), 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; return 0;
} }
el_val_t el_button(el_val_t attrs, el_val_t children) { el_val_t el_button(el_val_t attrs, el_val_t label) {
if (str_eq(attrs, EL_STR(""))) { if (str_eq(attrs, EL_STR(""))) {
return el_str_concat(el_str_concat(EL_STR("<button type=\"button\">"), children), EL_STR("</button>")); 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(">")), children), 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; return 0;
} }
+1 -1
View File
@@ -98,7 +98,7 @@ fn checkout_page(plan: String, pub_key: String) -> String {
el_li("", "Persistent memory - never resets") el_li("", "Persistent memory - never resets")
+ el_li("", "Local inference via Ollama (coming)") + el_li("", "Local inference via Ollama (coming)")
+ el_li("", "Bring your own API keys") + el_li("", "Bring your own API keys")
+ el_li("", "3 marketplace plugins included") + el_li("", "Plugin marketplace access (coming soon)")
+ el_li("", "Core built-in capabilities") + el_li("", "Core built-in capabilities")
+ el_li("", "2 devices included") + el_li("", "2 devices included")
} else { } else {
+1 -1
View File
@@ -32,7 +32,7 @@ fn hero() -> String {
let sub: String = el_p( let sub: String = el_p(
"class=\"hero-sub animate-up-3\"", "class=\"hero-sub animate-up-3\"",
"Runs on your machine. Remembers everything. Priced below ChatGPT on day one." "Runs on your machine. Remembers everything. The memory is yours &#8212; forever."
) )
let cta_primary: String = el_a( let cta_primary: String = el_a(
+1 -1
View File
@@ -77,7 +77,7 @@ fn marketplace_categories() -> String {
el_div( el_div(
"class=\"marketplace-categories reveal\" style=\"transition-delay:320ms\"", "class=\"marketplace-categories reveal\" style=\"transition-delay:320ms\"",
marketplace_tags_block("Connectors - day one", connectors) + marketplace_tags_block("Connectors (rolling out)", connectors) +
marketplace_tags_block("Following launch", following) + marketplace_tags_block("Following launch", following) +
el_div( el_div(
"", "",
+16 -2
View File
@@ -36,7 +36,7 @@ fn pricing_free_features() -> String {
el_li("", el_span("class=\"dash\"", "-") + el_span("", "Local inference via Ollama (coming)")) + el_li("", el_span("class=\"dash\"", "-") + el_span("", "Local inference via Ollama (coming)")) +
el_li("", el_span("class=\"dash\"", "-") + el_span("", "Neuron Inference included when it launches - Q3 2026")) + el_li("", el_span("class=\"dash\"", "-") + el_span("", "Neuron Inference included when it launches - Q3 2026")) +
el_li("", el_span("class=\"dash\"", "-") + el_span("", "Unlimited projects")) + el_li("", el_span("class=\"dash\"", "-") + el_span("", "Unlimited projects")) +
el_li("", el_span("class=\"dash\"", "-") + el_span("", "3 marketplace plugins included")) + el_li("", el_span("class=\"dash\"", "-") + el_span("", "Plugin marketplace access (coming soon)")) +
el_li("", el_span("class=\"dash\"", "-") + el_span("", "Core built-in capabilities")) el_li("", el_span("class=\"dash\"", "-") + el_span("", "Core built-in capabilities"))
} }
@@ -91,6 +91,7 @@ fn pricing(sold: Int, total: Int) -> String {
el_span("class=\"pricing-price\"", "$0") + el_span("class=\"pricing-price\"", "$0") +
el_span("class=\"pricing-cadence\"", "forever") el_span("class=\"pricing-cadence\"", "forever")
) + ) +
el_p("class=\"pricing-tagline\" style=\"margin-bottom:.5rem\"", "$0 + your AI provider&#39;s usage &#8212; free provider option available") +
el_p("class=\"pricing-tagline\"", "Start building your memory. No card required.") + el_p("class=\"pricing-tagline\"", "Start building your memory. No card required.") +
el_ul("class=\"pricing-features\"", pricing_free_features()) + el_ul("class=\"pricing-features\"", pricing_free_features()) +
el_div("style=\"flex:1\"", "") + el_div("style=\"flex:1\"", "") +
@@ -108,6 +109,7 @@ fn pricing(sold: Int, total: Int) -> String {
el_span("class=\"pricing-price\"", "$19") + el_span("class=\"pricing-price\"", "$19") +
el_span("class=\"pricing-cadence\"", "/ month") el_span("class=\"pricing-cadence\"", "/ month")
) + ) +
el_p("class=\"pricing-tagline\" style=\"margin-bottom:.5rem\"", "+ your AI provider&#39;s usage (typically $2&#8211;8/mo for everyday chat) &middot; one bill once Neuron Inference launches") +
el_p("class=\"pricing-tagline\"", "Full access. Use your own API keys now. Neuron Inference when it launches.") + el_p("class=\"pricing-tagline\"", "Full access. Use your own API keys now. Neuron Inference when it launches.") +
el_ul("class=\"pricing-features\"", pricing_pro_features()) + el_ul("class=\"pricing-features\"", pricing_pro_features()) +
el_div("style=\"flex:1\"", "") + el_div("style=\"flex:1\"", "") +
@@ -125,6 +127,7 @@ fn pricing(sold: Int, total: Int) -> String {
el_span("class=\"pricing-price\"", "$199") + el_span("class=\"pricing-price\"", "$199") +
el_span("class=\"pricing-cadence\"", "lifetime") el_span("class=\"pricing-cadence\"", "lifetime")
) + ) +
el_p("class=\"pricing-tagline\" style=\"margin-bottom:.5rem\"", "+ your AI provider&#39;s usage until Neuron Inference launches &#8212; then it&#39;s included, forever") +
el_p("class=\"pricing-tagline\"", "Pay once. Everything, forever. Including Neuron Inference when it launches.") + el_p("class=\"pricing-tagline\"", "Pay once. Everything, forever. Including Neuron Inference when it launches.") +
spots_html + spots_html +
el_ul("class=\"pricing-features\"", pricing_founding_features()) + el_ul("class=\"pricing-features\"", pricing_founding_features()) +
@@ -135,6 +138,17 @@ fn pricing(sold: Int, total: Int) -> String {
) )
) )
let need_box: String = el_div(
"class=\"founding-banner reveal\" style=\"margin:0 auto 2.5rem\"",
el_div(
"",
el_p("class=\"founding-banner-label\"", "What you&#39;ll need") +
el_p("class=\"pricing-tagline\" style=\"margin-bottom:0\"",
"Neuron is the mind &#8212; the AI model it thinks with comes from a provider you connect in about two minutes. Google Gemini has a free tier to start (note: Google uses free-tier chats to improve its products &#8212; their paid tier doesn&#39;t). Anthropic, OpenAI, and xAI bill you directly for what you use: everyday chat typically runs $2&#8211;8 a month, and budget models cost under $1. Neuron adds no markup and never touches the bill. When Neuron Inference launches, Neuron includes the AI &#8212; one bill, zero setup. Heavy agentic use costs more than everyday chat &#8212; you&#39;re always billed at your provider&#39;s own rates."
)
)
)
let grid: String = el_div("class=\"pricing-grid\"", card_free + card_pro + card_founding) let grid: String = el_div("class=\"pricing-grid\"", card_free + card_pro + card_founding)
let banner_fill: String = el_div( let banner_fill: String = el_div(
@@ -165,6 +179,6 @@ fn pricing(sold: Int, total: Int) -> String {
el_section( el_section(
"id=\"pricing\" aria-label=\"Pricing\"", "id=\"pricing\" aria-label=\"Pricing\"",
el_div("class=\"container\"", header + grid + banner + fine1 + fine2) el_div("class=\"container\"", header + need_box + grid + banner + fine1 + fine2)
) )
} }