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
129 changes: 128 additions & 1 deletion src/routes/+layout.svelte
Original file line number Diff line number Diff line change
@@ -1,25 +1,152 @@
<script lang="ts">
import '../app.scss';
import { Megaphone } from 'lucide-svelte';
import { page } from '$app/stores';
import { base } from '$app/paths';

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="{base}/contact?type=demo" class="banner-cta">Request Demo</a>
</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;
}

@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
22 changes: 19 additions & 3 deletions src/routes/contact/+page.svelte
Original file line number Diff line number Diff line change
Expand Up @@ -11,12 +11,18 @@
} 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');

// Reactive to URL changes, works with SSR and client-side navigation
let isDemo = $derived($page.url.searchParams.get('type') === 'demo');

let formData = $state({
name: '',
email: '',
subject: '',
subject: isDemo ? 'Request Demo' : '',
message: ''
});

Expand Down Expand Up @@ -56,7 +62,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 +138,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 +449,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