Skip to content
Merged
Show file tree
Hide file tree
Changes from 1 commit
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
128 changes: 127 additions & 1 deletion src/routes/+layout.svelte
Original file line number Diff line number Diff line change
@@ -1,25 +1,151 @@
<script lang="ts">
import '../app.scss';
import { Megaphone } from 'lucide-svelte';
import { page } from '$app/stores';

let { children } = $props();

// Hide banner on contact page only when coming from demo request
let hideBanner = $derived(
$page.route.id === '/contact' && $page.url.searchParams.get('type') === 'demo'
);
</script>

<div class="bg-gradient"></div>
<div class="bg-overlay"></div>

{#if !hideBanner}
<div class="launch-banner">
<div class="banner-content">
<div class="banner-text">
<span class="banner-icon">
<Megaphone size={18} />
</span>
<span class="banner-message">Context Engine is launching soon!</span>
<a href="/contact?type=demo" class="banner-cta">Request Demo</a>
Comment thread
chris-stinemetz marked this conversation as resolved.
Outdated
</div>
</div>
</div>
{/if}

<div class="app">
<main>
{@render children()}
</main>
</div>

<style lang="scss">
.launch-banner {
position: sticky;
top: 0;
z-index: 1000;
background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
color: white;
padding: 0.75rem 1rem;
box-shadow: 0 2px 4px rgba(0, 0, 0, 0.1);
animation: slideDown 0.3s ease-out;
}

.banner-content {
display: flex;
justify-content: space-between;
align-items: center;
max-width: 1200px;
margin: 0 auto;
}

.banner-text {
display: flex;
align-items: center;
gap: 0.5rem;
flex: 1;
}

.banner-icon {
color: rgba(255, 255, 255, 0.9);
display: inline-flex;
align-items: center;
justify-content: center;
animation: pulse 2s cubic-bezier(0.4, 0, 0.6, 1) infinite;
Comment thread
chris-stinemetz marked this conversation as resolved.
}

@keyframes iconPulse {
0%,
100% {
opacity: 0.9;
transform: scale(1);
}
50% {
opacity: 1;
transform: scale(1.1);
}
}

.banner-message {
font-weight: 500;
font-size: 0.95rem;
}

.banner-cta {
background: rgba(255, 255, 255, 0.9);
color: #667eea;
text-decoration: none;
padding: 0.4rem 1rem;
border-radius: 1.25rem;
font-weight: 600;
font-size: 0.875rem;
margin-left: 1rem;
white-space: nowrap;
transition: all 0.2s ease;

&:hover {
background: white;
transform: translateY(-1px);
box-shadow: 0 2px 8px rgba(0, 0, 0, 0.15);
}

&:active {
transform: translateY(0);
}
}

@keyframes slideDown {
from {
transform: translateY(-100%);
opacity: 0;
}
to {
transform: translateY(0);
opacity: 1;
}
}

@media (max-width: 768px) {
.banner-message {
font-size: 0.875rem;
}

.banner-cta {
font-size: 0.8rem;
padding: 0.35rem 0.75rem;
margin-left: 0.75rem;
}

.banner-content {
padding: 0 0.5rem;
}

.banner-text {
gap: 0.25rem;
}
}

.app {
position: relative;
z-index: 1;
min-height: 100vh;
}

main {
min-height: 100vh;
width: 100%;
Expand Down
24 changes: 22 additions & 2 deletions src/routes/contact/+page.svelte
Original file line number Diff line number Diff line change
Expand Up @@ -11,15 +11,25 @@
} from 'lucide-svelte';
// Import Discord icon from a custom SVG since it's not in lucide
import { base } from '$app/paths';
import { page } from '$app/stores';
import { onMount } from 'svelte';

let formState: 'idle' | 'submitting' | 'success' | 'error' = $state('idle');
let isDemo = $state(false);
let formData = $state({
name: '',
email: '',
subject: '',
message: ''
});

onMount(() => {

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

isDemo is only set in onMount, so the initial SSR/first paint will always start in non-demo mode and it won’t react if the user navigates between /contact and /contact?type=demo via client-side navigation (query param changes).

Fix This in Augment

🤖 Was this useful? React with 👍 or 👎, or 🚀 if it prevented an incident/outage.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

fixed

isDemo = $page.url.searchParams.get('type') === 'demo';
if (isDemo) {
formData.subject = 'Request Demo';
}
});

async function handleSubmit(event: SubmitEvent) {
event.preventDefault();
formState = 'submitting';
Expand Down Expand Up @@ -56,7 +66,7 @@
<div class="contact-container" in:fade={{ duration: 300 }}>
<div class="container">
<header class="contact-header">
<h1 class="hero-title">Get In Touch</h1>
<h1 class="hero-title">{isDemo ? 'Request Demo' : 'Get In Touch'}</h1>
<p class="hero-subtitle">
Let's discuss your MCP integration <span class="divider">//</span> Questions about Context Engine?
</p>
Expand Down Expand Up @@ -132,7 +142,10 @@

<form class="contact-form glass" onsubmit={handleSubmit}>
<div class="form-header">
<h2>Send a Message</h2>
<h2>{isDemo ? 'Request Demo' : 'Send a Message'}</h2>
{#if isDemo}
<p class="demo-subtitle">Let's schedule a personalized demo of Context Engine</p>
{/if}
</div>

<div class="form-group">
Expand Down Expand Up @@ -440,6 +453,13 @@
/* Form styling without sticky positioning */
}

.demo-subtitle {
color: var(--text-secondary);
font-size: 1rem;
margin: var(--spacing-xs) 0 0;
font-weight: 400;
}

.discord-icon {
color: #5865f2; /* Discord brand color */
}
Expand Down