Skip to content
Merged
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
147 changes: 147 additions & 0 deletions src/pages/index.astro
Original file line number Diff line number Diff line change
Expand Up @@ -819,6 +819,85 @@ const jsonLd = {
}
.final-links a { color: var(--accent); }

/* ── Section: Newsletter ─────────────────────────────────────────── */
.newsletter-section {
padding: 72px 24px;
border-top: 1px solid var(--border);
}
.newsletter-panel {
max-width: 480px;
margin: 0 auto;
text-align: center;
}
.newsletter-panel h2 {
font-size: clamp(22px,2.6vw,30px);
line-height: 1.2;
letter-spacing: -0.01em;
margin-bottom: 10px;
}
.newsletter-panel p {
color: var(--muted);
font-size: 15px;
line-height: 1.6;
margin-bottom: 24px;
}
.newsletter-form {
display: flex;
gap: 8px;
flex-wrap: wrap;
justify-content: center;
}
.newsletter-input {
flex: 1 1 220px;
min-width: 0;
max-width: 300px;
height: 46px;
padding: 0 14px;
background: var(--surface-raised);
border: 1px solid var(--border-strong);
border-radius: 7px;
color: var(--text);
font-size: 14px;
font-family: inherit;
outline: none;
transition: border-color 0.15s;
}
.newsletter-input::placeholder { color: var(--subtle); }
.newsletter-input:focus { border-color: var(--accent); }
[data-theme="light"] .newsletter-input {
background: var(--surface);
border-color: var(--border);
}
.newsletter-btn {
height: 46px;
padding: 0 22px;
background: var(--accent);
color: #02100a;
border: none;
border-radius: 7px;
font-size: 14px;
font-weight: 700;
font-family: inherit;
cursor: pointer;
transition: opacity 0.15s, transform 0.1s;
white-space: nowrap;
}
.newsletter-btn:hover { opacity: 0.88; }
.newsletter-btn:active { transform: scale(0.97); }
.newsletter-btn:disabled { opacity: 0.5; cursor: not-allowed; transform: none; }
.newsletter-msg {
margin-top: 14px;
font-size: 13px;
min-height: 20px;
}
.newsletter-msg.success { color: var(--accent); }
.newsletter-msg.error { color: var(--danger); }
.newsletter-fine {
margin-top: 12px;
font-size: 12px;
color: var(--subtle);
}

/* ── Footer ──────────────────────────────────────────────────────── */
footer {
border-top: 1px solid var(--border);
Expand Down Expand Up @@ -1228,6 +1307,31 @@ const enabled = await <span class="arch-hi-green">client.getBooleanValue</span>(
</div>
</section>

<!-- ════════════════════════════════════════════════════════════════
SECTION 6 — NEWSLETTER
═════════════════════════════════════════════════════════════════ -->
<section class="newsletter-section">
<div class="newsletter-panel">
<div class="section-kicker">Stay in the loop</div>
<h2>Get notified about new releases.</h2>
<p>Changelog, migration guides, and what's next — no noise.</p>
<form class="newsletter-form" id="newsletter-form" novalidate>
<input
class="newsletter-input"
type="email"
name="email"
placeholder="you@company.com"
required
autocomplete="email"
aria-label="Email address"
/>
<button class="newsletter-btn" type="submit">Subscribe</button>
</form>
<p class="newsletter-msg" id="newsletter-msg" aria-live="polite"></p>
<p class="newsletter-fine">No spam. Unsubscribe anytime.</p>
</div>
</section>

</main>

<!-- ── Footer ────────────────────────────────────────────────────── -->
Expand Down Expand Up @@ -1293,6 +1397,49 @@ const enabled = await <span class="arch-hi-green">client.getBooleanValue</span>(
window.location.href = '/docs/';
}
});

// Newsletter signup → Loops
var newsletterForm = document.getElementById('newsletter-form');
var newsletterMsg = document.getElementById('newsletter-msg');
if (newsletterForm) {
newsletterForm.addEventListener('submit', function(e) {
e.preventDefault();
var input = newsletterForm.querySelector('input[type="email"]');
var btn = newsletterForm.querySelector('button[type="submit"]');
var email = input ? input.value.trim() : '';
if (!email) return;
btn.disabled = true;
btn.textContent = 'Subscribing…';
newsletterMsg.textContent = '';
newsletterMsg.className = 'newsletter-msg';
var body = new URLSearchParams();
body.append('email', email);
fetch('https://app.loops.so/api/newsletter-form/cmpeyyijd02t40jud6lemhuu0', {
method: 'POST',
headers: { 'Content-Type': 'application/x-www-form-urlencoded' },
body: body.toString()
})
.then(function(res) { return res.json(); })
.then(function(data) {
if (data && data.success) {
newsletterMsg.textContent = "You're in. Talk soon.";
newsletterMsg.className = 'newsletter-msg success';
newsletterForm.reset();
} else {
newsletterMsg.textContent = data && data.message ? data.message : 'Something went wrong. Try again.';
newsletterMsg.className = 'newsletter-msg error';
}
})
.catch(function() {
newsletterMsg.textContent = 'Network error. Please try again.';
newsletterMsg.className = 'newsletter-msg error';
})
.finally(function() {
btn.disabled = false;
btn.textContent = 'Subscribe';
});
});
}
});
})();
</script>
Expand Down
Loading