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
57 changes: 57 additions & 0 deletions apps/marketing/src/components/Background.astro
Original file line number Diff line number Diff line change
@@ -0,0 +1,57 @@
---
const starCount = 160;
let seed = 42;
const rand = () => {
seed = (seed * 16807) % 2147483647;
return (seed - 1) / 2147483646;
};

const stars = Array.from({ length: starCount }, (_, i) => {
const twinkle = rand() < 0.3;
return {
id: i,
x: (rand() * 100).toFixed(3),
y: (rand() * 100).toFixed(3),
r: rand() < 0.85 ? (0.4 + rand() * 0.5).toFixed(3) : (0.8 + rand() * 0.6).toFixed(3),
opacity: (0.15 + rand() * 0.45).toFixed(3),
delay: (rand() * 8).toFixed(3),
twinkle,
};
});
---

<div class="kn-threads" aria-hidden="true">
<svg viewBox="0 0 1440 900" preserveAspectRatio="xMidYMid slice" fill="none" xmlns="http://www.w3.org/2000/svg" class="kn-threads-svg">
<path d="M -80 520 C 180 440, 380 620, 620 460 S 980 340, 1520 480" class="kn-thread kn-thread-a" />
<path d="M 1260 -40 C 1060 160, 860 300, 680 400" class="kn-thread kn-thread-b" />
<path d="M 600 490 C 460 590, 280 720, 60 940" class="kn-thread kn-thread-b" />
<path d="M -40 180 C 200 160, 440 260, 560 340" class="kn-thread kn-thread-c" />
<path d="M -60 780 C 300 740, 600 800, 900 720 S 1300 680, 1520 760" class="kn-thread kn-thread-d" />
<path d="M -40 320 C 200 300, 420 380, 640 340 S 960 260, 1480 380" class="kn-thread kn-thread-claw" />
<path d="M 1100 -20 C 940 140, 780 300, 660 420" class="kn-thread kn-thread-claw-hi" />
<path d="M 620 500 C 520 580, 380 700, 160 920" class="kn-thread kn-thread-claw-hi" />
<path d="M 1520 200 C 1200 260, 900 180, 640 280 S 300 360, -40 240" class="kn-thread kn-thread-ocean" />
<path d="M -40 660 C 200 620, 500 700, 780 640 S 1200 560, 1520 640" class="kn-thread kn-thread-ocean-hi" />
<circle cx="640" cy="462" r="3" class="kn-dot" />
<circle cx="640" cy="462" r="14" class="kn-glow" />
<circle cx="640" cy="462" r="30" fill="var(--kn-landing-accent-dim)" opacity="0.1" />
<circle cx="800" cy="300" r="2" fill="var(--kn-landing-accent)" opacity="0.3" />
<circle cx="800" cy="300" r="10" fill="var(--kn-landing-accent)" opacity="0.04" />
</svg>
</div>

<div class="kn-stars" aria-hidden="true">
<svg width="100%" height="100%" preserveAspectRatio="none" xmlns="http://www.w3.org/2000/svg">
{stars.map((star) => (
<circle
cx={`${star.x}%`}
cy={`${star.y}%`}
r={star.r}
fill="var(--kn-landing-star-color)"
opacity={star.opacity}
class:list={{ "kn-star-twinkle": star.twinkle }}
style={star.twinkle ? `animation-delay:${star.delay}s` : undefined}
/>
))}
</svg>
</div>
9 changes: 2 additions & 7 deletions apps/marketing/src/components/CoreSurfaces.astro
Original file line number Diff line number Diff line change
@@ -1,9 +1,4 @@
---
/**
* Core Surfaces — tabbed spotlight section showing Threads, Diffs, Preview, PR Review, Actions.
* Uses CSS crossfade transitions and keyboard navigation.
*/

interface Surface {
id: string;
label: string;
Expand All @@ -21,7 +16,7 @@ const { surfaces } = Astro.props;
const defaultId = surfaces[0]?.id ?? "";
---

<section class="spotlight" data-tab-group data-tab-default={defaultId} data-reveal>
<section id="surfaces" class="spotlight" data-tab-group data-tab-default={defaultId} data-reveal>
<div class="spotlight-copy">
<p class="section-kicker">Core surfaces</p>
<h2 class="section-title">Built for the way real AI coding sessions actually unfold.</h2>
Expand Down Expand Up @@ -51,7 +46,7 @@ const defaultId = surfaces[0]?.id ?? "";
<div class="spotlight-panels">
{surfaces.map((item) => (
<article
class="spotlight-panel"
class="spotlight-panel kn-card"
id={`panel-${item.id}`}
data-tab-panel={item.id}
role="tabpanel"
Expand Down
40 changes: 28 additions & 12 deletions apps/marketing/src/components/FaqSection.astro
Original file line number Diff line number Diff line change
@@ -1,27 +1,43 @@
---
/**
* FAQ section — two-column grid of Q&A cards.
*/

interface Props {
faqs: ReadonlyArray<{ question: string; answer: string }>;
}

const { faqs } = Astro.props;
---

<section class="faq-section" aria-label="Frequently asked questions" data-reveal>
<section id="faq" class="faq-section" aria-label="Frequently asked questions" data-reveal>
<div class="section-heading">
<p class="section-kicker">FAQ</p>
<h2 class="section-title">What people need to know before they click.</h2>
</div>

<div class="faq-grid">
{faqs.map((item) => (
<article class="faq-card">
<h3>{item.question}</h3>
<p>{item.answer}</p>
</article>
))}
<div class="faq-shell kn-card" data-faq-root>
{faqs.map((item, index) => {
const id = `faq-${index}`;
return (
<article class="faq-item" data-faq-item>
<button
type="button"
class="faq-trigger"
aria-expanded={index === 0 ? "true" : "false"}
aria-controls={`${id}-panel`}
data-faq-trigger
>
<span>{item.question}</span>
<span class="faq-chevron" aria-hidden="true">⌄</span>
</button>
<div
id={`${id}-panel`}
class="faq-panel"
data-faq-panel
aria-hidden={index === 0 ? "false" : "true"}
style={index === 0 ? "max-height: 220px; opacity: 1;" : "max-height: 0px; opacity: 0;"}
>
<p>{item.answer}</p>
</div>
</article>
);
})}
</div>
</section>
24 changes: 15 additions & 9 deletions apps/marketing/src/components/FeatureGrid.astro
Original file line number Diff line number Diff line change
@@ -1,20 +1,26 @@
---
/**
* Feature grid — three core product pillars.
*/

interface Props {
pillars: ReadonlyArray<{ eyebrow: string; title: string; body: string }>;
}

const { pillars } = Astro.props;
const icons = [
`<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round"><path d="M12 2v20"/><path d="M17 5H9.5a3.5 3.5 0 0 0 0 7H14.5a3.5 3.5 0 0 1 0 7H6"/></svg>`,
`<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round"><path d="M3 7h18"/><path d="M3 12h12"/><path d="M3 17h8"/><path d="M17 11l4 4-4 4"/></svg>`,
`<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round"><path d="M4 14a1 1 0 0 1-.78-1.63l9.9-10.2a.5.5 0 0 1 .86.46l-1.92 6.02A1 1 0 0 0 13 10h7a1 1 0 0 1 .78 1.63l-9.9 10.2a.5.5 0 0 1-.86-.46l1.92-6.02A1 1 0 0 0 11 14z"/></svg>`
] as const;
---

<section class="feature-grid" aria-label="Core product pillars" data-reveal>
{pillars.map((pillar) => (
<article class="feature-card">
<div class="feature-eyebrow">{pillar.eyebrow}</div>
<h2>{pillar.title}</h2>
<section id="features" class="feature-grid feature-grid--bento" aria-label="Core product pillars" data-reveal>
{pillars.map((pillar, index) => (
<article class={`feature-card feature-card--bento feature-card--${index + 1}`}>
<div class="feature-card-head">
<span class="kn-ico-wrap feature-icon" set:html={icons[index] ?? icons[0]} />
<div class="feature-card-copy">
<div class="feature-eyebrow">{pillar.eyebrow}</div>
<h2>{pillar.title}</h2>
</div>
</div>
<p>{pillar.body}</p>
</article>
))}
Expand Down
2 changes: 1 addition & 1 deletion apps/marketing/src/components/FinalCta.astro
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
*/
---

<section class="final-cta" data-reveal>
<section class="final-cta kn-card" data-reveal>
<p class="section-kicker">Ready</p>
<h2>Stop building through tab chaos.</h2>
<p>
Expand Down
100 changes: 16 additions & 84 deletions apps/marketing/src/components/Hero.astro
Original file line number Diff line number Diff line change
@@ -1,14 +1,23 @@
---
/**
* Hero section — headline, CTA, and glassmorphic workspace mockup.
* Hero section — ClawDash-style centered hero with OK Code content.
*/
---

<section class="hero" data-reveal>
<div class="hero-copy">
<div class="eyebrow">
<span class="eyebrow-dot" aria-hidden="true"></span>
AI-native code workspace
<div class="hero-copy hero-copy--centered">
<a href="https://github.com/OpenKnots/okcode/releases" class="kn-pill">
<span class="kn-pill-badge">New</span>
<span class="kn-pill-text">Premium AI coding workspace for desktop + web</span>
<span class="kn-pill-arrow" aria-hidden="true">&rarr;</span>
</a>

<div class="hero-mark" aria-hidden="true">
<div class="hero-mark-glow hero-mark-glow--violet"></div>
<div class="hero-mark-glow hero-mark-glow--cyan"></div>
<div class="hero-mark-core">
<img src="/icon.png" alt="" width="88" height="88" />
</div>
</div>

<h1 class="tagline">The beautiful workspace for shipping with AI.</h1>
Expand All @@ -19,7 +28,7 @@
prompts.
</p>

<div class="hero-actions">
<div class="hero-actions hero-actions--centered">
<a id="download-btn" href="https://github.com/OpenKnots/okcode/releases" class="hero-button">
<span class="hero-button-shine" aria-hidden="true"></span>
<span id="download-label">Download OK Code</span>
Expand All @@ -35,7 +44,7 @@
</a>
</div>

<div class="hero-meta">
<div class="hero-meta hero-meta--centered">
<a href="/download" class="other-platforms">Other platforms</a>
<div class="hero-pills" aria-label="Product highlights">
<span>Desktop + web</span>
Expand All @@ -46,81 +55,4 @@
</div>
</div>
</div>

<div class="hero-visual" aria-hidden="true">
<div class="hero-glow hero-glow--violet"></div>
<div class="hero-glow hero-glow--cyan"></div>

<div class="orb orb--one"></div>
<div class="orb orb--two"></div>

<div class="glass-stage">
<div class="glass-toolbar">
<div class="traffic-lights"><span></span><span></span><span></span></div>
<div class="glass-label">OK Code</div>
<div class="glass-badge">Live workspace</div>
</div>

<div class="glass-body">
<aside class="rail rail--sidebar">
<div class="rail-title"></div>
<div class="rail-chip rail-chip--active"></div>
<div class="rail-chip"></div>
<div class="rail-chip"></div>
<div class="rail-chip rail-chip--short"></div>
</aside>

<section class="center-stack">
<div class="panel panel--thread">
<div class="panel-head">
<span class="panel-kicker">Thread</span>
<span class="panel-status">Agent warm</span>
</div>
<div class="message message--large"></div>
<div class="message"></div>
<div class="message message--short"></div>
</div>

<div class="panel-row">
<div class="panel panel--diff">
<div class="panel-head">
<span class="panel-kicker">Latest diff</span>
</div>
<div class="code-line code-line--add"></div>
<div class="code-line"></div>
<div class="code-line code-line--remove"></div>
<div class="code-line code-line--short"></div>
</div>

<div class="panel panel--preview">
<div class="panel-head">
<span class="panel-kicker">Preview</span>
</div>
<div class="preview-window">
<div class="preview-nav"></div>
<div class="preview-card"></div>
<div class="preview-line"></div>
<div class="preview-line preview-line--short"></div>
</div>
</div>
</div>
</section>

<aside class="rail rail--meta">
<div class="meta-card">
<span class="meta-label">Review ready</span>
<strong>3 files changed</strong>
</div>
<div class="meta-card">
<span class="meta-label">Project action</span>
<strong>Release flow saved</strong>
</div>
<div class="meta-card">
<span class="meta-label">Mode</span>
<strong>Calm dark glass</strong>
</div>
</aside>
</div>
</div>
</div>
</section>
8 changes: 2 additions & 6 deletions apps/marketing/src/components/ThemeShowcase.astro
Original file line number Diff line number Diff line change
@@ -1,8 +1,4 @@
---
/**
* Theme Showcase — tabbed visual identity section with CSS-driven crossfade between themes.
*/

interface Theme {
id: string;
label: string;
Expand Down Expand Up @@ -58,7 +54,7 @@ const defaultId = themes[0]?.id ?? "";
data-active={theme.id === defaultId ? "true" : "false"}
>
<div
class="theme-preview-card"
class="theme-preview-card kn-card"
style={`--theme-gradient:${theme.gradient}; --theme-border:${theme.border}; --theme-accent:${theme.accent};`}
>
<div class="theme-preview-bar">
Expand All @@ -74,7 +70,7 @@ const defaultId = themes[0]?.id ?? "";
</div>
</div>
</div>
<div class="theme-note">
<div class="theme-note kn-card">
<h3>{theme.label}</h3>
<p class="theme-vibe">{theme.vibe}</p>
<p>{theme.body}</p>
Expand Down
6 changes: 3 additions & 3 deletions apps/marketing/src/components/TrustStrip.astro
Original file line number Diff line number Diff line change
Expand Up @@ -5,15 +5,15 @@
---

<section class="trust-strip" aria-label="Why teams use OK Code" data-reveal>
<div class="trust-item">
<div class="trust-item kn-card">
<span class="trust-label">Made for builders</span>
<strong>Designed around real AI coding workflows</strong>
</div>
<div class="trust-item">
<div class="trust-item kn-card">
<span class="trust-label">Calm by default</span>
<strong>Less context switching, more legible work</strong>
</div>
<div class="trust-item">
<div class="trust-item kn-card">
<span class="trust-label">Close to the metal</span>
<strong>Open source, desktop-aware, release-friendly</strong>
</div>
Expand Down
8 changes: 2 additions & 6 deletions apps/marketing/src/components/WorkflowSection.astro
Original file line number Diff line number Diff line change
@@ -1,8 +1,4 @@
---
/**
* Workflow section — four-step numbered cards.
*/

interface Props {
steps: ReadonlyArray<{ step: string; title: string; body: string }>;
}
Expand All @@ -20,9 +16,9 @@ const { steps } = Astro.props;
</p>
</div>

<div class="workflow-grid">
<div class="workflow-grid workflow-grid--cards">
{steps.map((item) => (
<article class="workflow-card">
<article class="workflow-card kn-card">
<span class="workflow-step">{item.step}</span>
<h3>{item.title}</h3>
<p>{item.body}</p>
Expand Down
Loading
Loading