Skip to content

Commit abe5e2d

Browse files
committed
Nits
1 parent 08b9e1b commit abe5e2d

File tree

4 files changed

+62
-81
lines changed

4 files changed

+62
-81
lines changed

src/landing/CallToAction.jsx

Lines changed: 25 additions & 75 deletions
Original file line numberDiff line numberDiff line change
@@ -1,82 +1,32 @@
11
import React from 'react';
2-
import { useColorMode } from '@docusaurus/theme-common';
3-
4-
export default function CallToAction({ color }) {
5-
const { colorMode } = useColorMode();
6-
7-
const colorMap = {
8-
blue: {
9-
light: '#bfdbfe',
10-
dark: '#3b82f6'
11-
},
12-
orange: {
13-
light: '#fb923c',
14-
dark: '#7c2d12'
15-
},
16-
green: {
17-
light: '#bbf7d0',
18-
dark: '#10b981'
19-
}
20-
};
21-
22-
const c = colorMap[color ?? 'blue'][colorMode];
2+
import { ArrowRight } from 'lucide-react';
233

4+
export default function CallToAction() {
245
return (
25-
<div className="w-full py-16">
26-
<div className="">
27-
<div className="relative isolate overflow-hidden bg-gray-900 dark:bg-white px-6 py-24 text-center rounded-3xl sm:px-16">
28-
<h2 className="mx-auto max-w-4xl text-4xl font-bold tracking-tight text-white dark:text-gray-900">
29-
Build endpoints, workflows & ETLs, UIs with code only where it matters
30-
</h2>
31-
<p className="mx-auto mt-6 max-w-4xl text-lg leading-8 text-gray-300 dark:text-gray-600">
32-
Get started building your internal tool in under 10 minutes
33-
</p>
34-
<div className="mt-10 flex items-center justify-center gap-x-6">
35-
<a
36-
href="https://app.windmill.dev/user/login"
37-
onClick={() => window.plausible('try-cloud')}
38-
data-analytics='"try-cloud"'
39-
className="rounded-md bg-white px-3.5 py-1.5 text-base hover:text-blue-500 font-semibold leading-7 text-gray-900 shadow-sm focus-visible:outline focus-visible:outline-2 focus-visible:outline-offset-2 focus-visible:outline-white !no-underline"
40-
rel="nofollow"
41-
>
42-
Get started for free
43-
</a>
44-
<a
45-
href="https://www.windmill.dev/book-demo"
46-
data-analytics='"schedule-demo"'
47-
onClick={() => window.plausible('schedule-demo')}
48-
className="text-base font-semibold leading-7 text-white !no-underline dark:text-gray-900"
49-
>
50-
Schedule a demo <span aria-hidden="true"></span>
51-
</a>
52-
</div>
53-
<svg
54-
xmlns="http://www.w3.org/2000/svg"
55-
viewBox="0 0 1024 1024"
56-
className="absolute top-1/2 left-1/2 -z-10 h-[64rem] w-[64rem] -translate-x-1/2"
57-
aria-hidden="true"
6+
<div className="w-full">
7+
<div className="dark:bg-gray-900 bg-gray-50 px-8 sm:px-12 py-10 text-center rounded-xl">
8+
<h2 className="mx-auto max-w-4xl text-3xl font-bold tracking-tight text-transparent bg-clip-text bg-gradient-to-br from-blue-500 to-blue-700 dark:from-blue-400 dark:to-blue-600 sm:text-4xl">
9+
Start building with Windmill
10+
</h2>
11+
<div className="mt-6 flex flex-col sm:flex-row items-center justify-center gap-4">
12+
<a
13+
href="https://app.windmill.dev/user/login"
14+
onClick={() => window.plausible('try-cloud')}
15+
data-analytics='"try-cloud"'
16+
className="rounded-lg bg-blue-600 hover:bg-blue-700 px-6 py-3 text-base font-semibold text-white shadow-sm transition-colors !no-underline"
17+
rel="nofollow"
18+
>
19+
Get started for free
20+
</a>
21+
<a
22+
href="https://www.windmill.dev/book-demo"
23+
data-analytics='"schedule-demo"'
24+
onClick={() => window.plausible('schedule-demo')}
25+
className="group flex items-center gap-2 text-base font-semibold text-gray-900 dark:text-white !no-underline hover:text-blue-600 dark:hover:text-blue-400 transition-colors"
5826
>
59-
<circle
60-
cx={512}
61-
cy={512}
62-
r={512}
63-
fill="url(#827591b1-ce8c-4110-b064-7cb85a0b12171)"
64-
fillOpacity="0.7"
65-
/>
66-
<defs>
67-
<radialGradient
68-
id="827591b1-ce8c-4110-b064-7cb85a0b12171"
69-
cx={0}
70-
cy={0}
71-
r={1}
72-
gradientUnits="userSpaceOnUse"
73-
gradientTransform="translate(512 512) rotate(90) scale(512)"
74-
>
75-
<stop stopColor={c} />
76-
<stop offset={1} stopColor={c} stopOpacity={0} />
77-
</radialGradient>
78-
</defs>
79-
</svg>
27+
Schedule a demo
28+
<ArrowRight size={20} className="group-hover:translate-x-1 transition-transform" />
29+
</a>
8030
</div>
8131
</div>
8232
</div>

src/landing/MobileTutorialSection.tsx

Lines changed: 35 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,8 @@ export default function TutorialSection() {
1616
const [duration, setDuration] = useState(0);
1717
const videoRef = useRef<HTMLVideoElement>(null);
1818
const progressBarRef = useRef<HTMLDivElement>(null);
19+
const containerRef = useRef<HTMLDivElement>(null);
20+
const [hasBeenVisible, setHasBeenVisible] = useState(false);
1921

2022
const tabs = [
2123
{ id: 'scripts', label: 'Scripts', icon: Server, description: 'Write scripts in 20+ languages (Python, TS, Go...) with full LSP support, auto-generated UI, managed dependencies and turn them into instant endpoints or hooks for pubsub events.', video: '/videos/scriptsvideo.mp4' },
@@ -26,6 +28,38 @@ export default function TutorialSection() {
2628

2729
const currentTab = tabs.find(tab => tab.id === selectedTab) || tabs[0];
2830

31+
// Detect when component is visible in viewport (80% threshold)
32+
useEffect(() => {
33+
const container = containerRef.current;
34+
if (!container) return;
35+
36+
const observer = new IntersectionObserver(
37+
(entries) => {
38+
if (entries[0].isIntersecting && !hasBeenVisible) {
39+
setHasBeenVisible(true);
40+
}
41+
},
42+
{ threshold: 0.8 }
43+
);
44+
45+
observer.observe(container);
46+
return () => observer.disconnect();
47+
}, [hasBeenVisible]);
48+
49+
// Play video: Scripts tab plays when visible, others play when tab is clicked
50+
useEffect(() => {
51+
const video = videoRef.current;
52+
if (!video) return;
53+
54+
if (selectedTab === 'scripts') {
55+
if (hasBeenVisible) {
56+
video.play();
57+
}
58+
} else {
59+
video.play();
60+
}
61+
}, [selectedTab, hasBeenVisible]);
62+
2963
// Track video progress
3064
useEffect(() => {
3165
const video = videoRef.current;
@@ -47,9 +81,6 @@ export default function TutorialSection() {
4781
video.addEventListener('pause', handlePause);
4882
video.addEventListener('loadedmetadata', handleLoadedMetadata);
4983

50-
// Autoplay on mount
51-
video.play();
52-
5384
return () => {
5485
video.removeEventListener('timeupdate', handleTimeUpdate);
5586
video.removeEventListener('play', handlePlay);
@@ -93,7 +124,7 @@ export default function TutorialSection() {
93124
const currentTime = duration > 0 ? (progress / 100) * duration : 0;
94125

95126
return (
96-
<div className="w-full">
127+
<div className="w-full" ref={containerRef}>
97128
{/* Tab buttons */}
98129
<div className="flex w-full mb-4 border-b border-gray-200 dark:border-gray-700">
99130
{tabs.map((tab) => (

src/landing/TestimonialsSection.tsx

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -129,7 +129,7 @@ export default function Example() {
129129
const { colorMode } = useColorMode();
130130

131131
return (
132-
<LandingSection bgClass="">
132+
<LandingSection bgClass="pb-8">
133133
<div>
134134
<div className="mx-auto text-left">
135135
<h1 className="tracking-tight leading-tight text-left font-bold text-transparent bg-clip-text bg-gradient-to-br from-blue-400 to-blue-600">
@@ -141,7 +141,7 @@ export default function Example() {
141141
</span>
142142
</div>
143143
<div className="mx-auto mt-8 lg:mx-0 lg:max-w-none">
144-
<div className="grid grid-cols-1 md:grid-cols-2 lg:grid-cols-3 gap-8 mb-8">
144+
<div className="grid grid-cols-1 md:grid-cols-2 lg:grid-cols-3 gap-8">
145145
{clientTestimonials.map((testimonial, index) => (
146146
<div
147147
key={testimonial.author.name + index}

static/videos/frontendvideo.mp4

-10.9 MB
Binary file not shown.

0 commit comments

Comments
 (0)