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
1,009 changes: 1,009 additions & 0 deletions apps/marketing/MARKETING_IMPROVEMENTS.md

Large diffs are not rendered by default.

63 changes: 60 additions & 3 deletions apps/marketing/src/components/Background.astro
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
---
const starCount = 160;
const starCount = 220;
let seed = 42;
const rand = () => {
seed = (seed * 16807) % 2147483647;
Expand All @@ -8,18 +8,31 @@ const rand = () => {

const stars = Array.from({ length: starCount }, (_, i) => {
const twinkle = rand() < 0.3;
const bright = rand() < 0.05;
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),
r: bright
? (1.2 + rand() * 0.6).toFixed(3)
: rand() < 0.85
? (0.4 + rand() * 0.5).toFixed(3)
: (0.8 + rand() * 0.6).toFixed(3),
opacity: bright
? (0.6 + rand() * 0.3).toFixed(3)
: (0.15 + rand() * 0.45).toFixed(3),
delay: (rand() * 8).toFixed(3),
twinkle,
};
});
---

<div class="kn-gradient-mesh" aria-hidden="true">
<div class="kn-mesh-orb kn-mesh-orb--1"></div>
<div class="kn-mesh-orb kn-mesh-orb--2"></div>
<div class="kn-mesh-orb kn-mesh-orb--3"></div>
</div>

<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" />
Expand All @@ -32,6 +45,9 @@ const stars = Array.from({ length: starCount }, (_, i) => {
<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" />
<path d="M -60 420 C 200 380, 500 500, 800 420 S 1200 360, 1520 440" class="kn-thread kn-thread-d" />
<path d="M 1520 520 C 1200 480, 800 580, 500 500 S 100 440, -60 520" class="kn-thread kn-thread-ocean" />
<path d="M 200 -40 C 300 200, 500 350, 700 280 S 1000 200, 1200 340" class="kn-thread kn-thread-c" />
<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" />
Expand All @@ -55,3 +71,44 @@ const stars = Array.from({ length: starCount }, (_, i) => {
))}
</svg>
</div>

<style>
.kn-gradient-mesh {
position: fixed;
inset: 0;
z-index: 0;
pointer-events: none;
}
.kn-mesh-orb {
position: absolute;
border-radius: 50%;
filter: blur(100px);
animation: float var(--duration, 20s) ease-in-out infinite;
}
.kn-mesh-orb--1 {
width: 50vw;
height: 50vw;
top: -10%;
left: -10%;
background: radial-gradient(circle, rgba(202, 58, 41, 0.06), transparent 70%);
--duration: 25s;
}
.kn-mesh-orb--2 {
width: 40vw;
height: 40vw;
top: 40%;
right: -15%;
background: radial-gradient(circle, rgba(167, 139, 250, 0.05), transparent 70%);
--duration: 30s;
animation-delay: -8s;
}
.kn-mesh-orb--3 {
width: 45vw;
height: 45vw;
bottom: -20%;
left: 20%;
background: radial-gradient(circle, rgba(103, 232, 249, 0.04), transparent 70%);
--duration: 28s;
animation-delay: -15s;
}
</style>
41 changes: 39 additions & 2 deletions apps/marketing/src/components/FaqSection.astro
Original file line number Diff line number Diff line change
Expand Up @@ -24,8 +24,13 @@ const { faqs } = Astro.props;
aria-controls={`${id}-panel`}
data-faq-trigger
>
<span>{item.question}</span>
<span class="faq-chevron" aria-hidden="true">⌄</span>
<span class="faq-question">
<span class="faq-number">{String(index + 1).padStart(2, '0')}</span>
{item.question}
</span>
<svg class="faq-chevron" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true">
<path d="M6 9l6 6 6-6" />
</svg>
</button>
<div
id={`${id}-panel`}
Expand All @@ -41,3 +46,35 @@ const { faqs } = Astro.props;
})}
</div>
</section>

<style>
.faq-trigger {
transition: background 0.2s ease;
}

.faq-trigger:hover {
background: rgba(255, 255, 255, 0.02);
}

.faq-question {
display: flex;
align-items: center;
gap: 0.75rem;
}

.faq-number {
font-size: 0.72rem;
font-weight: 600;
color: var(--kn-landing-accent, #ca3a29);
opacity: 0.6;
font-variant-numeric: tabular-nums;
}

.faq-chevron {
width: 1.25rem;
height: 1.25rem;
flex-shrink: 0;
color: var(--kn-landing-text-muted, #8a94a4);
transition: transform 0.3s cubic-bezier(0.16, 1, 0.3, 1), color 0.3s ease;
}
</style>
36 changes: 35 additions & 1 deletion apps/marketing/src/components/FeatureGrid.astro
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ const icons = [
] as const;
---

<section id="features" class="feature-grid feature-grid--bento" aria-label="Core product pillars" data-reveal>
<section id="features" class="feature-grid feature-grid--bento" aria-label="Core product pillars" data-reveal data-reveal-children>
{pillars.map((pillar, index) => (
<article class={`feature-card feature-card--bento feature-card--${index + 1}`}>
<div class="feature-card-head">
Expand All @@ -25,3 +25,37 @@ const icons = [
</article>
))}
</section>

<style>
.feature-card {
position: relative;
overflow: hidden;
transition: transform 0.3s cubic-bezier(0.16, 1, 0.3, 1), box-shadow 0.3s ease, border-color 0.3s ease;
}

.feature-card::before {
content: "";
position: absolute;
top: 0;
left: 0;
right: 0;
height: 2px;
background: linear-gradient(90deg, transparent, var(--kn-landing-accent, #ca3a29), transparent);
opacity: 0;
transition: opacity 0.3s ease;
}

.feature-card:hover {
transform: translateY(-4px);
box-shadow: 0 24px 80px rgba(0, 0, 0, 0.4), 0 0 40px rgba(202, 58, 41, 0.06);
border-color: var(--kn-landing-border-hover, rgba(192, 200, 212, 0.16));
}

.feature-card:hover::before {
opacity: 1;
}

.feature-card--1 :global(.kn-ico-wrap) { color: var(--kn-landing-accent-bright, #ff4e41); }
.feature-card--2 :global(.kn-ico-wrap) { color: #67e8f9; }
.feature-card--3 :global(.kn-ico-wrap) { color: #fbbf24; }
</style>
105 changes: 86 additions & 19 deletions apps/marketing/src/components/FinalCta.astro
Original file line number Diff line number Diff line change
Expand Up @@ -5,24 +5,91 @@
---

<section class="final-cta kn-card" data-reveal>
<p class="section-kicker">Ready</p>
<h2>Stop building through tab chaos.</h2>
<p>
Bring chat, code review, preview, and release flow into one calm workspace built for serious
AI-assisted work.
</p>
<div class="final-cta-actions">
<a href="https://github.com/OpenKnots/okcode/releases" class="hero-button">
<span class="hero-button-shine" aria-hidden="true"></span>
<span>Download OK Code</span>
</a>
<a
href="https://github.com/OpenKnots/okcode"
target="_blank"
rel="noopener noreferrer"
class="secondary-button"
>
Explore on GitHub
</a>
<div class="final-cta-mesh" aria-hidden="true">
<div class="final-cta-orb final-cta-orb--1"></div>
<div class="final-cta-orb final-cta-orb--2"></div>
</div>
<div class="final-cta-content">
<p class="section-kicker">Ready</p>
<h2>Stop building through tab chaos.</h2>
<p>
Bring chat, code review, preview, and release flow into one calm workspace built for serious
AI-assisted work.
</p>
<div class="final-cta-actions">
<a href="https://github.com/OpenKnots/okcode/releases" class="hero-button">
<span class="hero-button-shine" aria-hidden="true"></span>
<span>Download OK Code</span>
</a>
<a
href="https://github.com/OpenKnots/okcode"
target="_blank"
rel="noopener noreferrer"
class="secondary-button"
>
Explore on GitHub
</a>
</div>
</div>
</section>

<style>
.final-cta {
position: relative;
overflow: hidden;
}

.final-cta::before {
content: "";
position: absolute;
top: 0;
left: 10%;
right: 10%;
height: 1px;
background: linear-gradient(90deg, transparent, var(--kn-landing-accent, #ca3a29), transparent);
opacity: 0.4;
}

.final-cta-mesh {
position: absolute;
inset: 0;
overflow: hidden;
pointer-events: none;
}

.final-cta-orb {
position: absolute;
border-radius: 50%;
filter: blur(60px);
animation: float var(--duration) ease-in-out infinite;
}

.final-cta-orb--1 {
width: 24rem;
height: 24rem;
top: -40%;
left: -10%;
background: radial-gradient(circle, rgba(202, 58, 41, 0.12), transparent 70%);
--duration: 16s;
}

.final-cta-orb--2 {
width: 20rem;
height: 20rem;
bottom: -30%;
right: -5%;
background: radial-gradient(circle, rgba(167, 139, 250, 0.08), transparent 70%);
--duration: 20s;
animation-delay: -6s;
}

.final-cta-content {
position: relative;
z-index: 1;
}

@keyframes float {
0%, 100% { transform: translateY(0); }
50% { transform: translateY(-12px); }
}
</style>
Loading
Loading