nxtgauge-gitops/coming-soon/index.html
sync-test e752326411
All checks were successful
sync-to-github / sync (push) Successful in 6s
feat: wire the coming-soon waitlist form to POST /api/waitlist
Backend endpoint already deployed (nxtgauge-backend-rust
apps/users/src/handlers/waitlist.rs, routed through the gateway).

- ingress.yaml: route /api on nxtgauge.com and www.nxtgauge.com to
  nxtgauge-rust-gateway:9100, same 'more specific paths first' pattern
  nxtgauge-frontend-solid's ingress already uses - the coming-soon
  page is a static nginx site with no backend of its own.
- index.html: handleSubmit now actually awaits the fetch instead of
  unconditionally showing success after a commented-out example call.
  Disables the submit button while in flight, added a form-error state
  for a failed request (was previously just documented, not wired).

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
2026-08-14 03:58:31 +05:30

294 lines
10 KiB
HTML

<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>Nxtgauge — Coming Soon</title>
<meta name="description" content="Nxtgauge is launching soon — India's marketplace for jobs and professional services, powered by AI." />
<meta property="og:title" content="Nxtgauge — Coming Soon" />
<meta property="og:description" content="India's marketplace for jobs and professional services. Launching soon." />
<link rel="icon" href="/assets/nxtgauge-logo.png" type="image/png" />
<link rel="preconnect" href="https://fonts.googleapis.com" />
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin />
<link href="https://fonts.googleapis.com/css2?family=Exo+2:wght@400;600;700;800;900&display=swap" rel="stylesheet" />
<style>
/* ── Brand tokens (from nxtgauge app.css) ─────────────────── */
:root {
--orange: #fd6116;
--orange-dark: #e45a14;
--navy: #050026;
--font: "Exo 2", "Segoe UI", system-ui, -apple-system, sans-serif;
}
*, *::before, *::after { box-sizing: border-box; margin: 0; padding: 0; }
html, body { height: 100%; }
body {
font-family: var(--font);
background: var(--navy);
color: #fff;
-webkit-font-smoothing: antialiased;
display: flex;
flex-direction: column;
align-items: center;
justify-content: center;
min-height: 100dvh;
overflow: hidden;
padding: 32px 24px 100px;
position: relative;
}
/* ── Background layers ───────────────────────────────────────── */
.bg {
position: fixed; inset: 0; pointer-events: none; z-index: 0;
}
.bg-base {
position: absolute; inset: 0;
background: radial-gradient(ellipse 80% 60% at 50% 0%, #17003e 0%, var(--navy) 70%);
}
.bg-mesh {
position: absolute; inset: 0;
background:
radial-gradient(ellipse 65% 55% at 50% 30%, rgba(253,97,22,0.22) 0%, transparent 65%),
radial-gradient(ellipse 45% 40% at 10% 80%, rgba(50,30,120,0.18) 0%, transparent 60%),
radial-gradient(ellipse 45% 40% at 90% 75%, rgba(253,97,22,0.09) 0%, transparent 60%);
}
.bg-grid {
position: absolute; inset: 0;
background-image:
linear-gradient(rgba(255,255,255,0.025) 1px, transparent 1px),
linear-gradient(90deg, rgba(255,255,255,0.025) 1px, transparent 1px);
background-size: 48px 48px;
}
.orb {
position: absolute; border-radius: 50%;
background: radial-gradient(circle, rgba(253,97,22,0.14) 0%, transparent 70%);
animation: orbFloat linear infinite;
}
.orb-1 { width: 600px; height: 600px; top: -220px; left: -180px; animation-duration: 20s; }
.orb-2 { width: 380px; height: 380px; bottom: -100px; right: -60px; animation-duration: 15s; animation-delay: -7s; }
@keyframes orbFloat {
0% { transform: translateY(0) scale(1); }
50% { transform: translateY(-28px) scale(1.04); }
100% { transform: translateY(0) scale(1); }
}
/* ── Content ─────────────────────────────────────────────────── */
.content {
position: relative; z-index: 1;
display: flex; flex-direction: column;
align-items: center; text-align: center;
max-width: 580px; width: 100%;
}
.brand-logo {
height: 50px; width: auto;
margin-bottom: 52px;
filter: brightness(0) invert(1);
}
/* Badge */
.badge {
display: inline-flex; align-items: center; gap: 9px;
font-size: 11px; font-weight: 700; letter-spacing: 0.12em; text-transform: uppercase;
color: var(--orange);
border: 1px solid rgba(253,97,22,0.38);
padding: 7px 18px; border-radius: 999px;
background: rgba(253,97,22,0.08);
margin-bottom: 32px;
}
.badge-dot {
width: 6px; height: 6px; border-radius: 50%;
background: var(--orange);
box-shadow: 0 0 7px var(--orange);
animation: blink 2.2s ease-in-out infinite;
}
@keyframes blink { 0%,100%{opacity:1} 50%{opacity:0.28} }
/* Headline */
h1 {
font-size: clamp(44px, 10vw, 86px);
font-weight: 900;
letter-spacing: -0.04em;
line-height: 0.95;
color: #fff;
margin-bottom: 26px;
}
h1 .accent {
display: block;
background: linear-gradient(105deg, var(--orange) 0%, #ff9c65 55%, #ffcba0 100%);
-webkit-background-clip: text;
-webkit-text-fill-color: transparent;
background-clip: text;
}
/* Tagline */
.tagline {
font-size: clamp(14px, 2vw, 17px);
color: rgba(255,255,255,0.48);
line-height: 1.68;
max-width: 420px;
margin-bottom: 52px;
}
/* Email form */
.form {
display: flex;
width: 100%; max-width: 420px;
margin-bottom: 12px;
}
.form input {
flex: 1; height: 50px; padding: 0 18px;
border: 1.5px solid rgba(255,255,255,0.12); border-right: none;
border-radius: 10px 0 0 10px;
background: rgba(255,255,255,0.05);
color: #fff; font-family: var(--font); font-size: 14px;
outline: none; transition: border-color 0.2s;
}
.form input::placeholder { color: rgba(255,255,255,0.24); }
.form input:focus { border-color: rgba(253,97,22,0.5); }
.form button {
height: 50px; padding: 0 22px;
border: none; border-radius: 0 10px 10px 0;
background: var(--orange); color: var(--navy);
font-family: var(--font); font-size: 14px; font-weight: 700;
cursor: pointer; white-space: nowrap;
transition: background 0.15s;
}
.form button:hover { background: var(--orange-dark); }
.form button:active { transform: scale(0.98); }
.form-note {
font-size: 11px;
color: rgba(255,255,255,0.22);
margin-bottom: 0;
}
.form-success {
display: none;
font-size: 14px; font-weight: 600; color: #4ade80;
animation: fadeIn 0.4s ease;
}
.form-error {
display: none;
font-size: 13px; font-weight: 500; color: #f87171;
margin-top: 8px;
}
@keyframes fadeIn { from{opacity:0;transform:translateY(6px)} to{opacity:1;transform:translateY(0)} }
/* ── Footer ──────────────────────────────────────────────────── */
.footer {
position: fixed; bottom: 0; left: 0; right: 0;
z-index: 1;
display: flex; flex-direction: column; align-items: center;
gap: 6px; padding: 14px 0 18px;
background: linear-gradient(to top, rgba(5,0,38,0.9) 0%, transparent 100%);
}
.footer-copy {
font-size: 11px; color: rgba(255,255,255,0.2); letter-spacing: 0.04em;
}
.footer-powered {
display: flex; align-items: center; gap: 10px;
}
.footer-powered-label {
font-size: 11px; font-weight: 700; letter-spacing: 0.08em;
text-transform: uppercase; color: rgba(255,255,255,0.55);
}
.footer-powered-logo {
height: 26px; width: auto;
filter: brightness(0) invert(1);
opacity: 0.85;
transition: opacity 0.15s;
}
.footer-powered-logo:hover { opacity: 1; }
@media (max-width: 480px) {
.form { flex-direction: column; }
.form input {
border-right: 1.5px solid rgba(255,255,255,0.12);
border-bottom: none;
border-radius: 10px 10px 0 0;
}
.form button { border-radius: 0 0 10px 10px; }
}
</style>
</head>
<body>
<!-- Background -->
<div class="bg" aria-hidden="true">
<div class="bg-base"></div>
<div class="bg-mesh"></div>
<div class="bg-grid"></div>
<div class="orb orb-1"></div>
<div class="orb orb-2"></div>
</div>
<!-- Content -->
<main class="content">
<img class="brand-logo" src="/assets/nxtgauge-logo.png" alt="Nxtgauge" />
<div class="badge">
<div class="badge-dot"></div>
Coming Soon
</div>
<h1>
Something Big<br>
<span class="accent">Is Coming.</span>
</h1>
<p class="tagline">
India's marketplace for jobs and professional services —
verified professionals, AI-powered tools, fair for everyone.
</p>
<form class="form" id="notifyForm" onsubmit="handleSubmit(event)">
<input type="email" id="emailInput" placeholder="Enter your email" required autocomplete="email" />
<button type="submit">Notify Me</button>
</form>
<p class="form-note" id="formNote">No spam. We'll only email when we launch.</p>
<p class="form-success" id="successMsg">✓ You're on the list! We'll reach out when we go live.</p>
<p class="form-error" id="errorMsg">Something went wrong. Please try again.</p>
</main>
<!-- Footer -->
<footer class="footer">
<div class="footer-copy">© 2026 Nxtgauge. All rights reserved.</div>
<div class="footer-powered">
<span class="footer-powered-label">Powered by</span>
<img class="footer-powered-logo" src="/assets/traceworks-trademark-white.svg" alt="Traceworks" />
</div>
</footer>
<script>
async function handleSubmit(e) {
e.preventDefault();
const email = document.getElementById('emailInput').value.trim();
if (!email) return;
const submitBtn = document.querySelector('#notifyForm button[type="submit"]');
const errorMsg = document.getElementById('errorMsg');
errorMsg.style.display = 'none';
submitBtn.disabled = true;
try {
const res = await fetch('/api/waitlist', {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({ email }),
});
if (!res.ok) throw new Error('Request failed');
document.getElementById('notifyForm').style.display = 'none';
document.getElementById('formNote').style.display = 'none';
document.getElementById('successMsg').style.display = 'block';
} catch (err) {
errorMsg.style.display = 'block';
submitBtn.disabled = false;
}
}
</script>
</body>
</html>