Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion src/components/site/BlogRequestDemo.astro
Original file line number Diff line number Diff line change
Expand Up @@ -70,7 +70,7 @@
$set: { email },
});

window.location.assign('https://promptless.ai/demo');
window.location.assign('https://promptless.ai/demo#book');
} catch {
setStatus('Something went wrong. Please try again.', 'error');
submitBtn.disabled = false;
Expand Down
90 changes: 50 additions & 40 deletions src/components/site/DemoBooking.astro
Original file line number Diff line number Diff line change
Expand Up @@ -2,21 +2,32 @@
---

<!--
Email-gated Cal.com booking widget.
Cal.com booking widget + email capture.

The Cal.com embed is always loaded (hidden via display:none) so it's ready
instantly when revealed. If the visitor already provided their email (stored
in sessionStorage by the homepage hero or blog CTA), we show it immediately
with the email prefilled. Otherwise we show a small email form first.
The Cal.com embed is always visible. Below it, a simple email form lets
visitors leave their email if they prefer not to book immediately.

No-JS fallback: the email gate and Cal.com embed both require JavaScript.
We show a plain link to the Cal.com booking page via <noscript>. Users who
submitted their email on the homepage via the native form POST will be asked
for their email again on Cal.com — there is no way to pass it without JS.
If the visitor already provided their email (stored in sessionStorage by
the homepage hero or blog CTA), it's prefilled into the Cal.com embed.

No-JS fallback: a plain link to the Cal.com booking page via <noscript>.
-->

<div id="demo-booking">
<div id="book">
<div id="demo-calendar" class="pl-site-meet-calendar">
<div class="pl-site-meet-calendar-mount" id="cal-inline-demo-booking"></div>
</div>

<noscript>
<p>
<a href="https://app.cal.com/team/promptless/15m-discovery-call">
Book a 15-minute demo &rarr;
</a>
</p>
</noscript>

<div id="demo-email-gate" class="demo-email-gate">
<p class="demo-email-label">Not ready to book? Leave your email and we'll follow up.</p>
<form id="demo-email-form" class="pl-site-form-row">
<label class="sr-only" for="demo-gate-email">Work email</label>
<input
Expand All @@ -26,29 +37,33 @@
placeholder="Work email"
required
/>
<button type="submit">Continue to booking</button>
<button type="submit">Send</button>
</form>
<p id="demo-email-status" class="demo-email-status" aria-live="polite"></p>
</div>
</div>

<div id="demo-calendar" class="pl-site-meet-calendar" style="display:none;">
<div class="pl-site-meet-calendar-mount" id="cal-inline-demo-booking"></div>
</div>
<style>
.demo-email-label {
margin: 0 0 0.5rem;
font-size: 0.92rem;
color: #475569;
}

<noscript>
<p>
<a href="https://app.cal.com/team/promptless/15m-discovery-call">
Book a 15-minute demo &rarr;
</a>
</p>
</noscript>
</div>
.demo-email-status {
margin: 0.35rem 0 0;
font-size: 0.84rem;
line-height: 1.4;
color: #16a34a;
min-height: 1.2em;
}
</style>

<script is:inline>
(() => {
var EMAIL_KEY = 'pl_demo_email';
var gate = document.getElementById('demo-email-gate');
var calendar = document.getElementById('demo-calendar');
var form = document.getElementById('demo-email-form');
var statusEl = document.getElementById('demo-email-status');
var namespace = 'demo-booking';
var elementSelector = '#cal-inline-demo-booking';

Expand All @@ -60,7 +75,6 @@
try { sessionStorage.setItem(EMAIL_KEY, email); } catch {}
}

// Load Cal.com embed immediately (hidden) so it's prewarmed
function bootCal() {
var mountEl = document.querySelector(elementSelector);
if (!mountEl || mountEl.dataset.calMounted === 'true') return;
Expand Down Expand Up @@ -112,27 +126,21 @@
mountEl.dataset.calMounted = 'true';
}

function showCal() {
if (calendar) calendar.style.display = '';
if (gate) gate.style.display = 'none';
}

// Query param overrides:
// ?demo=reset — clear stored email, show the gate
// ?demo=cal — skip the gate, show Cal.com
// Query param override: ?demo=reset — clear stored email
var params = new URLSearchParams(window.location.search);
var demoParam = params.get('demo');
if (demoParam === 'reset') {
try { sessionStorage.removeItem(EMAIL_KEY); } catch {}
}

// Always boot Cal.com embed on page load (stays hidden until revealed)
bootCal();

var storedEmail = demoParam === 'reset' ? null : getStoredEmail();
if (storedEmail || demoParam === 'cal') {
showCal();
return;
// Scroll to #book if the URL hash targets it (e.g. /demo#book)
if (window.location.hash === '#book') {
var bookEl = document.getElementById('book');
if (bookEl) {
setTimeout(function () { bookEl.scrollIntoView({ behavior: 'smooth' }); }, 100);
}
}

if (form) {
Expand Down Expand Up @@ -163,13 +171,15 @@
});
}

showCal();
if (statusEl) {
statusEl.textContent = 'Thanks! We\u2019ll be in touch.';
}
form.style.display = 'none';
});
}

document.addEventListener('astro:page-load', function () {
bootCal();
if (getStoredEmail()) showCal();
});
})();
</script>
6 changes: 3 additions & 3 deletions src/components/site/Hero.astro
Original file line number Diff line number Diff line change
Expand Up @@ -31,11 +31,11 @@ const {
class="pl-site-form-row"
action="https://submit-form.com/roBOd2Oxb"
method="post"
data-redirect="/demo"
data-redirect="/demo#book"
>
<label class="sr-only" for="work-email">Work email</label>
<input id="work-email" type="email" name="email" placeholder="Work email" required />
<input type="hidden" name="_redirect" value="/demo" />
<input type="hidden" name="_redirect" value="/demo#book" />
<button type="submit" name="submit" data-track-action="book_demo" data-track-funnel="conversion" data-track-location="hero">Book demo</button>
</form>

Expand All @@ -57,7 +57,7 @@ const {
const redirectInput = form.querySelector('input[name="_redirect"]');

if (redirectInput instanceof HTMLInputElement) {
redirectInput.value = `${window.location.origin}/demo`;
redirectInput.value = `${window.location.origin}/demo#book`;
}

form.addEventListener('submit', async (event) => {
Expand Down
19 changes: 6 additions & 13 deletions src/content/website/demo.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -9,23 +9,16 @@ import DemoBooking from '@components/site/DemoBooking.astro';
import VideoEmbed from '@components/site/VideoEmbed.astro';
import SocialProofLinks from '@components/site/SocialProofLinks.astro';

Talk to one of our engineers to see how Promptless can automate your docs workflow. 30-day free trial included!

<DemoBooking />

<div class="pl-what-to-expect">

#### 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

</div>
<VideoEmbed />

### 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.

<SocialProofLinks />

<VideoEmbed />
### Book a 15-minute demo

Talk to one of our engineers to see how Promptless can automate your docs workflow. 30-day free trial included!

<DemoBooking />
2 changes: 1 addition & 1 deletion src/lib/website-navigation.ts
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ interface WebsiteSidebarLink {

export const WEBSITE_NAV_ITEMS: WebsiteNavItem[] = [
{ id: 'home', href: '/', label: 'Overview', icon: 'overview' },
{ id: 'demo', href: '/demo', label: 'Book a demo', icon: 'video' },
{ id: 'demo', href: '/demo', label: 'Watch a demo', icon: 'video' },
{ id: 'pricing', href: '/pricing', label: 'Pricing', icon: 'pricing' },
{ id: 'jobs', href: '/jobs', label: 'Work at Promptless!', icon: 'jobs' },
{ id: 'wtd-portland-2026', href: '/wtd-portland-2026', label: 'WTD 2026', icon: 'calendar' },
Expand Down
2 changes: 1 addition & 1 deletion src/pages/demo.astro
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@ const { Content, headings } = await entry.render();
editUrl: false,
}}
>
<div class="pl-site-page pl-site-page-compact">
<div class="pl-site-page pl-site-page-compact pl-site-page-no-title">
<Content />
</div>
</StarlightPage>
4 changes: 4 additions & 0 deletions src/styles/custom.css
Original file line number Diff line number Diff line change
Expand Up @@ -486,6 +486,10 @@ main:has(.pl-site-page.pl-site-page-compact) .content-panel:first-of-type {
padding-bottom: 0.5rem;
}

main:has(.pl-site-page.pl-site-page-no-title) .content-panel:first-of-type {
display: none;
}

main:has(.pl-site-page.pl-site-page-compact) .content-panel + .content-panel {
padding-top: 0.5rem;
}
Expand Down
Loading