diff --git a/astro.config.mjs b/astro.config.mjs
index 7941b488..1fdb152a 100644
--- a/astro.config.mjs
+++ b/astro.config.mjs
@@ -13,6 +13,7 @@ const redirects = {
'/page': '/',
'/wtd': '/',
'/hn': '/',
+ '/meet': '/demo',
'/site': '/demo',
'/site/demo': '/demo',
'/video-demo': '/demo',
diff --git a/public/assets/helm.svg b/public/assets/helm.svg
new file mode 100644
index 00000000..1e2db8a2
--- /dev/null
+++ b/public/assets/helm.svg
@@ -0,0 +1,28 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/public/assets/vitess-stacked.png b/public/assets/vitess-stacked.png
new file mode 100644
index 00000000..b207bdf4
Binary files /dev/null and b/public/assets/vitess-stacked.png differ
diff --git a/src/components/shared/TopHeader.astro b/src/components/shared/TopHeader.astro
index 1a48f2b7..1daf496a 100644
--- a/src/components/shared/TopHeader.astro
+++ b/src/components/shared/TopHeader.astro
@@ -20,7 +20,7 @@ const { activeSection = getActiveSection(Astro.url.pathname), showNavTools = fal
{showNavTools ?
: null}
diff --git a/src/components/site/BlogRequestDemo.astro b/src/components/site/BlogRequestDemo.astro
index 330763ed..cf355daa 100644
--- a/src/components/site/BlogRequestDemo.astro
+++ b/src/components/site/BlogRequestDemo.astro
@@ -63,12 +63,14 @@
if (!res.ok) throw new Error('Submission failed');
+ try { sessionStorage.setItem('pl_demo_email', email); } catch {}
+
window.posthog?.capture('blog_demo_requested', {
location: 'blog',
$set: { email },
});
- window.location.assign('https://promptless.ai/meet');
+ window.location.assign('https://promptless.ai/demo');
} catch {
setStatus('Something went wrong. Please try again.', 'error');
submitBtn.disabled = false;
diff --git a/src/components/site/DemoBooking.astro b/src/components/site/DemoBooking.astro
new file mode 100644
index 00000000..9d7dd739
--- /dev/null
+++ b/src/components/site/DemoBooking.astro
@@ -0,0 +1,175 @@
+---
+---
+
+
+
+
+
+
diff --git a/src/components/site/Hero.astro b/src/components/site/Hero.astro
index 977b8245..d0b2ea8c 100644
--- a/src/components/site/Hero.astro
+++ b/src/components/site/Hero.astro
@@ -28,11 +28,11 @@ const {
class="pl-site-form-row"
action="https://submit-form.com/roBOd2Oxb"
method="post"
- data-redirect="/meet"
+ data-redirect="/demo"
>
Work email
-
+
Book demo
@@ -54,7 +54,7 @@ const {
const redirectInput = form.querySelector('input[name="_redirect"]');
if (redirectInput instanceof HTMLInputElement) {
- redirectInput.value = `${window.location.origin}/meet`;
+ redirectInput.value = `${window.location.origin}/demo`;
}
form.addEventListener('submit', async (event) => {
@@ -72,6 +72,9 @@ const {
}
const email = (form.querySelector('input[name="email"]') as HTMLInputElement)?.value?.trim();
+ if (email) {
+ try { sessionStorage.setItem('pl_demo_email', email); } catch {}
+ }
(window as any).posthog?.capture('demo_requested', {
location: 'hero',
...(email ? { $set: { email } } : {}),
@@ -102,7 +105,7 @@ const {
throw new Error(`Formspark submission failed with status ${response.status}`);
}
- const redirectTo = form.dataset.redirect || '/meet';
+ const redirectTo = form.dataset.redirect || '/demo';
window.location.assign(redirectTo);
} catch (_error) {
// Fallback to native form post if fetch fails (e.g. CORS/network).
diff --git a/src/components/site/SocialProofLinks.astro b/src/components/site/SocialProofLinks.astro
new file mode 100644
index 00000000..bebfe59f
--- /dev/null
+++ b/src/components/site/SocialProofLinks.astro
@@ -0,0 +1,104 @@
+---
+const links = [
+ {
+ href: 'https://github.com/vitessio/website/commits/',
+ logo: '/assets/vitess-stacked.png',
+ name: 'vitessio/website',
+ desc: 'View commits on GitHub',
+ },
+ {
+ href: 'https://github.com/helm/helm-www/commits/main/',
+ logo: '/assets/helm.svg',
+ name: 'helm/helm-www',
+ desc: 'View commits on GitHub',
+ },
+];
+---
+
+
+
+
diff --git a/src/components/site/VideoEmbed.astro b/src/components/site/VideoEmbed.astro
index ab7c0b9f..4082b25b 100644
--- a/src/components/site/VideoEmbed.astro
+++ b/src/components/site/VideoEmbed.astro
@@ -10,7 +10,7 @@ const {
} = Astro.props;
---
-
+
diff --git a/src/content/docs/docs/getting-started/welcome.mdx b/src/content/docs/docs/getting-started/welcome.mdx
index 4776cc30..867e16c6 100644
--- a/src/content/docs/docs/getting-started/welcome.mdx
+++ b/src/content/docs/docs/getting-started/welcome.mdx
@@ -91,5 +91,5 @@ Promptless operates through three interconnected components that work together t
diff --git a/src/content/website/demo.mdx b/src/content/website/demo.mdx
index f6bc7c81..8a208565 100644
--- a/src/content/website/demo.mdx
+++ b/src/content/website/demo.mdx
@@ -1,19 +1,31 @@
---
-title: Demo
-description: Introducing Promptless 1.0 and automated documentation workflows.
+title: Book a 15-minute demo
+description: Book a demo and see Promptless in action.
routePath: /demo
order: 2
hidden: false
---
+import DemoBooking from '@components/site/DemoBooking.astro';
import VideoEmbed from '@components/site/VideoEmbed.astro';
-import BlogRequestDemo from '@components/site/BlogRequestDemo.astro';
+import SocialProofLinks from '@components/site/SocialProofLinks.astro';
-Introducing Promptless 1.0: the first AI agent that automatically updates your customer-facing docs.
+Talk to one of our engineers to see how Promptless can automate your docs workflow. 30-day free trial included!
-
+
+
+
+
+#### What to expect
+
+- **We learn how you run docs** — We'll ask about your stack, your team, and where docs maintenance hurts the most
+- **See how Promptless fits** — Based on your answers, we'll show you exactly how Promptless would slot into your workflow
-### Ready to see it in action?
+
-Book a 15-min demo with one of our engineers to see how Promptless can automate your docs workflow. 30-day free trial included!
+### See why Vitess and Helm chose Promptless
-
+Promptless drafts PRs and suggests changes — then the docs maintainers at these CNCF projects review, revise, and ship them. Check the commit history yourself.
+
+
+
+
diff --git a/src/content/website/jobs.mdx b/src/content/website/jobs.mdx
index da6472b4..642fe705 100644
--- a/src/content/website/jobs.mdx
+++ b/src/content/website/jobs.mdx
@@ -29,7 +29,7 @@ For all roles, reach out at **founders@promptless.ai**!
natural break point to give them a nudge. */}
## Founding Docs Practice Lead
@@ -65,7 +65,7 @@ This is a one-of-one role. You'll own the documentation practice at Promptless
natural break point to give them a nudge. */}
## Founding Engineer
@@ -101,5 +101,5 @@ You'll build the core product—the AI agents, the integrations, the infrastruct
natural break point to give them a nudge. */}
diff --git a/src/content/website/meet.mdx b/src/content/website/meet.mdx
deleted file mode 100644
index dcf08e84..00000000
--- a/src/content/website/meet.mdx
+++ /dev/null
@@ -1,14 +0,0 @@
----
-title: Meet
-description: Book a 15-minute discovery call with the Promptless team.
-routePath: /meet
-order: 4
-hidden: false
----
-import MeetCalendarInline from '@components/site/MeetCalendarInline.astro';
-
-Book a 15-minute discovery call with the Promptless team.
-
-
-
-
diff --git a/src/lib/website-navigation.ts b/src/lib/website-navigation.ts
index c918a82b..fb0bb406 100644
--- a/src/lib/website-navigation.ts
+++ b/src/lib/website-navigation.ts
@@ -1,10 +1,10 @@
-export type WebsitePageId = 'home' | 'demo' | 'pricing' | 'meet' | 'jobs' | 'wtd-portland-2026';
+export type WebsitePageId = 'home' | 'demo' | 'pricing' | 'jobs' | 'wtd-portland-2026';
export interface WebsiteNavItem {
id: WebsitePageId;
href: string;
label: string;
- icon: 'overview' | 'video' | 'pricing' | 'meet' | 'jobs' | 'calendar';
+ icon: 'overview' | 'video' | 'pricing' | 'jobs' | 'calendar';
}
interface WebsiteSidebarLink {
@@ -15,9 +15,8 @@ interface WebsiteSidebarLink {
export const WEBSITE_NAV_ITEMS: WebsiteNavItem[] = [
{ id: 'home', href: '/', label: 'Overview', icon: 'overview' },
- { id: 'demo', href: '/demo', label: 'Demo', icon: 'video' },
+ { id: 'demo', href: '/demo', label: 'Book a demo', icon: 'video' },
{ id: 'pricing', href: '/pricing', label: 'Pricing', icon: 'pricing' },
- { id: 'meet', href: '/meet', label: 'Meet', icon: 'meet' },
{ id: 'jobs', href: '/jobs', label: 'Work at Promptless!', icon: 'jobs' },
{ id: 'wtd-portland-2026', href: '/wtd-portland-2026', label: 'WTD 2026', icon: 'calendar' },
];
diff --git a/src/pages/meet.astro b/src/pages/meet.astro
deleted file mode 100644
index 08380f2d..00000000
--- a/src/pages/meet.astro
+++ /dev/null
@@ -1,29 +0,0 @@
----
-import { getEntry } from 'astro:content';
-import StarlightPage from '@astrojs/starlight/components/StarlightPage.astro';
-import { getWebsiteSidebarLinks } from '@lib/website-navigation';
-
-const entry = await getEntry('website', 'meet');
-
-if (!entry) {
- throw new Error('Missing website content entry: meet');
-}
-
-const { Content, headings } = await entry.render();
----
-
-
-
-
-
-
diff --git a/src/styles/site.css b/src/styles/site.css
index 1ffdccf2..ccc0eb65 100644
--- a/src/styles/site.css
+++ b/src/styles/site.css
@@ -553,8 +553,16 @@
font-size: 0.92rem;
}
+.pl-what-to-expect {
+ margin-bottom: -0.5rem;
+}
+
+.pl-what-to-expect ul {
+ margin-bottom: 0;
+}
+
.pl-site-video-embed {
- margin-top: 0.2rem;
+ margin-top: 2.5rem;
position: relative;
overflow: hidden;
border-radius: 0.75rem;
diff --git a/tests/smoke/smoke.spec.ts b/tests/smoke/smoke.spec.ts
index 5a57e9e8..dc8029ea 100644
--- a/tests/smoke/smoke.spec.ts
+++ b/tests/smoke/smoke.spec.ts
@@ -129,7 +129,7 @@ test('primary nav keeps canonical routes with free tools tab', async () => {
test('website/docs/blog/changelog/free tools active state is correct', async () => {
const websiteHtml = await (await fetch(`${preview.baseUrl}/`)).text();
const websiteDemoHtml = await (await fetch(`${preview.baseUrl}/demo`)).text();
- const websiteMeetHtml = await (await fetch(`${preview.baseUrl}/meet`)).text();
+ // /meet now redirects to /demo — no separate page to test
const websitePricingHtml = await (await fetch(`${preview.baseUrl}/pricing`)).text();
const docsHtml = await (await fetch(`${preview.baseUrl}/docs/getting-started/welcome`)).text();
const blogHtml = await (await fetch(`${preview.baseUrl}/blog`)).text();
@@ -147,9 +147,6 @@ test('website/docs/blog/changelog/free tools active state is correct', async ()
const demoNav = getPrimaryNav(websiteDemoHtml);
assertActiveLink(demoNav, '/', 'Home');
- const meetNav = getPrimaryNav(websiteMeetHtml);
- assertActiveLink(meetNav, '/', 'Home');
-
const pricingNav = getPrimaryNav(websitePricingHtml);
assertActiveLink(pricingNav, '/', 'Home');
@@ -209,7 +206,7 @@ test('/blog/all and /changelog/all remain compatibility redirects', async () =>
}
});
-test('website routes are canonicalized to /, /demo, /meet, and /pricing', async () => {
+test('website routes are canonicalized to /, /demo, and /pricing', async () => {
const homepage = await fetch(`${preview.baseUrl}/`);
assert.equal(homepage.status, 200);
const homepageHtml = await homepage.text();
@@ -226,21 +223,17 @@ test('website routes are canonicalized to /, /demo, /meet, and /pricing', async
const demo = await fetch(`${preview.baseUrl}/demo`);
assert.equal(demo.status, 200);
- assert.match(await demo.text(), /Demo/);
-
- const meet = await fetch(`${preview.baseUrl}/meet`);
- assert.equal(meet.status, 200);
- assert.match(await meet.text(), /Meet/);
+ assert.match(await demo.text(), /Book a 15-minute demo/);
const pricing = await fetch(`${preview.baseUrl}/pricing`);
assert.equal(pricing.status, 200);
assert.match(await pricing.text(), /Pricing/);
- const aliases = ['/site', '/site/demo', '/video-demo', '/use-cases', '/faq', '/api-reference'];
+ const aliases = ['/site', '/site/demo', '/video-demo', '/meet', '/use-cases', '/faq', '/api-reference'];
for (const alias of aliases) {
const aliasResponse = await fetch(`${preview.baseUrl}${alias}`, { redirect: 'manual' });
if (aliasResponse.status >= 300 && aliasResponse.status < 400) {
- if (alias === '/site' || alias === '/site/demo' || alias === '/video-demo') {
+ if (alias === '/site' || alias === '/site/demo' || alias === '/video-demo' || alias === '/meet') {
assert.equal(aliasResponse.headers.get('location'), '/demo');
} else {
assert.equal(aliasResponse.headers.get('location'), '/');
@@ -249,7 +242,7 @@ test('website routes are canonicalized to /, /demo, /meet, and /pricing', async
}
assert.equal(aliasResponse.status, 200);
const body = await aliasResponse.text();
- if (alias === '/site' || alias === '/site/demo' || alias === '/video-demo') {
+ if (alias === '/site' || alias === '/site/demo' || alias === '/video-demo' || alias === '/meet') {
assert.match(body, /Redirecting to: \/demo/);
} else {
assert.match(body, /Redirecting to: \//);
@@ -257,34 +250,27 @@ test('website routes are canonicalized to /, /demo, /meet, and /pricing', async
}
});
-test('homepage, demo, meet, and pricing render website content', async () => {
+test('homepage, demo, and pricing render website content', async () => {
const homeResponse = await fetch(`${preview.baseUrl}/`);
assert.equal(homeResponse.status, 200);
const homeHtml = await homeResponse.text();
assert.match(homeHtml, /pl-site-page/);
assert.match(homeHtml, /Automatically update your/);
assert.match(homeHtml, /How Promptless works/);
- assert.match(homeHtml, /Demo/);
+ assert.match(homeHtml, /Book a demo/);
assert.match(homeHtml, /Pricing/);
assert.doesNotMatch(homeHtml, /Getting Started/i);
assert.match(homeHtml, /data-site-icon="overview"/);
assert.match(homeHtml, /data-site-icon="video"/);
assert.match(homeHtml, /data-site-icon="pricing"/);
- assert.match(homeHtml, /data-site-icon="meet"/);
-
const demoResponse = await fetch(`${preview.baseUrl}/demo`);
assert.equal(demoResponse.status, 200);
const demoHtml = await demoResponse.text();
- assert.match(demoHtml, /Demo/);
- assert.match(demoHtml, /Introducing Promptless 1\.0/);
+ assert.match(demoHtml, /Book a 15-minute demo/);
+ assert.match(demoHtml, /cal-inline-demo-booking/);
+ assert.match(demoHtml, /cal-inline-demo-booking/);
assert.match(demoHtml, /tella\.tv/);
- const meetResponse = await fetch(`${preview.baseUrl}/meet`);
- assert.equal(meetResponse.status, 200);
- const meetHtml = await meetResponse.text();
- assert.match(meetHtml, /Meet/);
- assert.match(meetHtml, /15-minute discovery call/i);
-
const pricingResponse = await fetch(`${preview.baseUrl}/pricing`);
assert.equal(pricingResponse.status, 200);
const pricingHtml = await pricingResponse.text();
@@ -313,7 +299,7 @@ test('website header renders expected CTAs and search control', async () => {
assert.equal(response.status, 200);
const html = await response.text();
assert.match(html, /href="https:\/\/app\.gopromptless\.ai"[^>]*>\s*Sign in/i);
- assert.match(html, /href="\/meet"[^>]*>\s*Book demo/i);
+ assert.match(html, /href="\/demo"[^>]*>\s*Book demo/i);
assert.match(html, /aria-label="Search"/i);
});
@@ -371,7 +357,7 @@ test('website compatibility routes redirect to canonical destinations', async ()
assert.match(body, /Redirecting to: \//);
}
- const siteAliases = ['/site', '/site/demo', '/video-demo'];
+ const siteAliases = ['/site', '/site/demo', '/video-demo', '/meet'];
for (const alias of siteAliases) {
const response = await fetch(`${preview.baseUrl}${alias}`, { redirect: 'manual' });
if (response.status >= 300 && response.status < 400) {