Skip to content

Commit a3e5b4e

Browse files
Merge pull request #237 from Context-Engine-AI/feature/hero-video-lightbox
feat: add demo video lightbox to hero section
2 parents 5b27296 + 4aee349 commit a3e5b4e

File tree

4 files changed

+235
-1
lines changed

4 files changed

+235
-1
lines changed

src/app.scss

Lines changed: 147 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -515,6 +515,153 @@ body::before {
515515
flex-wrap: wrap;
516516
}
517517

518+
/* Watch Demo Button */
519+
.btn-demo {
520+
display: inline-flex;
521+
align-items: center;
522+
gap: 10px;
523+
padding: 12px 24px;
524+
background: linear-gradient(135deg, rgba(0, 184, 148, 0.15), rgba(45, 103, 255, 0.15));
525+
border: 1px solid rgba(0, 184, 148, 0.4);
526+
border-radius: var(--radius);
527+
color: var(--accent);
528+
font-size: 14px;
529+
font-weight: 600;
530+
cursor: pointer;
531+
transition: all 0.3s ease;
532+
position: relative;
533+
overflow: hidden;
534+
}
535+
536+
.btn-demo::before {
537+
content: '';
538+
position: absolute;
539+
inset: 0;
540+
background: linear-gradient(135deg, rgba(0, 184, 148, 0.08), rgba(45, 103, 255, 0.08));
541+
opacity: 0;
542+
transition: opacity 0.3s ease;
543+
}
544+
545+
.btn-demo:hover {
546+
border-color: rgba(0, 184, 148, 0.7);
547+
box-shadow: 0 0 24px rgba(0, 184, 148, 0.2), 0 0 48px rgba(0, 184, 148, 0.08);
548+
transform: translateY(-1px);
549+
}
550+
551+
.btn-demo:hover::before {
552+
opacity: 1;
553+
}
554+
555+
.btn-demo-icon {
556+
display: flex;
557+
align-items: center;
558+
justify-content: center;
559+
width: 32px;
560+
height: 32px;
561+
background: rgba(0, 184, 148, 0.2);
562+
border-radius: 50%;
563+
transition: all 0.3s ease;
564+
}
565+
566+
.btn-demo:hover .btn-demo-icon {
567+
background: rgba(0, 184, 148, 0.35);
568+
box-shadow: 0 0 12px rgba(0, 184, 148, 0.3);
569+
}
570+
571+
/* Video Lightbox */
572+
.video-lightbox {
573+
position: fixed;
574+
inset: 0;
575+
z-index: 10000;
576+
display: flex;
577+
align-items: center;
578+
justify-content: center;
579+
background: rgba(0, 0, 0, 0.88);
580+
backdrop-filter: blur(12px);
581+
animation: lightboxFadeIn 0.3s ease;
582+
}
583+
584+
@keyframes lightboxFadeIn {
585+
from { opacity: 0; }
586+
to { opacity: 1; }
587+
}
588+
589+
.video-lightbox-inner {
590+
position: relative;
591+
width: 90vw;
592+
max-width: 1200px;
593+
border-radius: var(--radius-lg);
594+
overflow: hidden;
595+
box-shadow: 0 32px 64px rgba(0, 0, 0, 0.5), 0 0 0 1px rgba(255, 255, 255, 0.06);
596+
animation: lightboxSlideUp 0.4s cubic-bezier(0.16, 1, 0.3, 1);
597+
}
598+
599+
@keyframes lightboxSlideUp {
600+
from {
601+
opacity: 0;
602+
transform: translateY(24px) scale(0.97);
603+
}
604+
to {
605+
opacity: 1;
606+
transform: translateY(0) scale(1);
607+
}
608+
}
609+
610+
.video-lightbox-controls {
611+
position: absolute;
612+
top: 16px;
613+
right: 16px;
614+
display: flex;
615+
gap: 8px;
616+
z-index: 10;
617+
}
618+
619+
.video-control-btn {
620+
display: flex;
621+
align-items: center;
622+
justify-content: center;
623+
width: 40px;
624+
height: 40px;
625+
background: rgba(0, 0, 0, 0.6);
626+
backdrop-filter: blur(8px);
627+
border: 1px solid rgba(255, 255, 255, 0.12);
628+
border-radius: 50%;
629+
color: #fff;
630+
cursor: pointer;
631+
transition: all 0.2s ease;
632+
}
633+
634+
.video-control-btn:hover {
635+
background: rgba(0, 0, 0, 0.8);
636+
border-color: rgba(255, 255, 255, 0.25);
637+
transform: scale(1.08);
638+
}
639+
640+
.video-lightbox-player {
641+
display: block;
642+
width: 100%;
643+
height: auto;
644+
background: #000;
645+
}
646+
647+
/* Responsive lightbox */
648+
@media (max-width: 768px) {
649+
.video-lightbox-inner {
650+
width: 96vw;
651+
border-radius: var(--radius);
652+
}
653+
654+
.video-control-btn {
655+
width: 36px;
656+
height: 36px;
657+
}
658+
659+
.video-lightbox-controls {
660+
top: 10px;
661+
right: 10px;
662+
}
663+
}
664+
518665
.hero-stats {
519666
display: flex;
520667
gap: 40px;

src/routes/+page.svelte

Lines changed: 88 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,11 @@
1616
Bug,
1717
Github,
1818
Brain,
19-
Leaf
19+
Leaf,
20+
Play,
21+
X,
22+
Volume2,
23+
VolumeX
2024
} from 'lucide-svelte';
2125
2226
// Form state
@@ -25,6 +29,40 @@
2529
let heroError = $state('');
2630
let heroLoading = $state(false);
2731
32+
// Video lightbox state
33+
let videoOpen = $state(false);
34+
let videoMuted = $state(true);
35+
let videoEl: HTMLVideoElement = $state(null!);
36+
37+
function openVideo() {
38+
videoOpen = true;
39+
document.body.style.overflow = 'hidden';
40+
}
41+
42+
function closeVideo() {
43+
videoOpen = false;
44+
document.body.style.overflow = '';
45+
if (videoEl) {
46+
videoEl.pause();
47+
videoEl.currentTime = 0;
48+
}
49+
}
50+
51+
function toggleMute() {
52+
videoMuted = !videoMuted;
53+
if (videoEl) videoEl.muted = videoMuted;
54+
}
55+
56+
function handleLightboxKeydown(e: KeyboardEvent) {
57+
if (e.key === 'Escape') closeVideo();
58+
}
59+
60+
function handleOverlayClick(e: MouseEvent) {
61+
if ((e.target as HTMLElement).classList.contains('video-lightbox')) {
62+
closeVideo();
63+
}
64+
}
65+
2866
const BETA_SIGNUP_URL = 'https://dev.context-engine.ai/auth/beta-signup';
2967
3068
// Features data
@@ -254,6 +292,10 @@
254292
{/if}
255293

256294
<div class="hero-actions">
295+
<button class="btn btn-demo" onclick={openVideo}>
296+
<span class="btn-demo-icon"><Play size={18} /></span>
297+
Watch Demo
298+
</button>
257299
<a
258300
href="https://github.com/Context-Engine-AI/Context-Engine"
259301
class="btn btn-secondary"
@@ -416,6 +458,51 @@ result = <span class="c-fn">repo_search</span>(
416458
</div>
417459
</section>
418460

461+
<!-- Video Lightbox -->
462+
{#if videoOpen}
463+
<!-- svelte-ignore a11y_no_noninteractive_element_interactions -->
464+
<div
465+
class="video-lightbox"
466+
role="dialog"
467+
aria-modal="true"
468+
aria-label="Demo video"
469+
tabindex="-1"
470+
onkeydown={handleLightboxKeydown}
471+
onclick={handleOverlayClick}
472+
>
473+
<div class="video-lightbox-inner">
474+
<div class="video-lightbox-controls">
475+
<button
476+
class="video-control-btn"
477+
onclick={toggleMute}
478+
aria-label={videoMuted ? 'Unmute' : 'Mute'}
479+
>
480+
{#if videoMuted}
481+
<VolumeX size={20} />
482+
{:else}
483+
<Volume2 size={20} />
484+
{/if}
485+
</button>
486+
<button class="video-control-btn" onclick={closeVideo} aria-label="Close video">
487+
<X size={20} />
488+
</button>
489+
</div>
490+
<!-- svelte-ignore a11y_media_has_caption -->
491+
<video
492+
bind:this={videoEl}
493+
autoplay
494+
muted={videoMuted}
495+
loop
496+
playsinline
497+
class="video-lightbox-player"
498+
>
499+
<source src="{base}/context_engine_1.webm" type="video/webm" />
500+
<source src="{base}/context_engine_1.mp4" type="video/mp4" />
501+
</video>
502+
</div>
503+
</div>
504+
{/if}
505+
419506
<!-- Footer -->
420507
<footer class="footer">
421508
<div class="footer-content">

static/context_engine_1.mp4

8.27 MB
Binary file not shown.

static/context_engine_1.webm

6.26 MB
Binary file not shown.

0 commit comments

Comments
 (0)