Build anticipation for your next launch with this glassmorphism launching soon page using HTML5, CSS3, and JavaScript. A dark gradient background with purple, indigo, and cyan lighting frames a translucent glass panel, creating a modern setting for your launch announcement.
The template combines a countdown timer, newsletter email form, and social links in a compact layout designed to fit one screen on typical devices. Responsive typography and spacing help keep the page balanced, while scrolling remains available when smaller screens or accessibility settings require more room.
What you will build
You will build a responsive Coming soon page with a glassmorphism interface and a dark illuminated background. The template includes:
A customizable brand name or text logo.
A translucent announcement label and “Launching Soon” headline.
A short introduction for your upcoming website or product.
Purple, indigo, and cyan gradient background lighting.
A central glass panel with blur and subtle borders.
A live countdown showing days, hours, minutes, and seconds.
A newsletter email field and “Notify Me” button.
Email validation with clear demo feedback.
A message displayed when the countdown finishes.
Social media links and a minimal footer.
A compact layout designed for one-screen viewing.
Accessible focus styles and reduced-motion support.
HTML source
<!doctype html>
<html lang="en"><head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<meta name="description" content="Something bright is on the horizon. Discover Aether's upcoming launch and try our launch notification demo.">
<meta name="theme-color" content="#080b18">
<title>Aether — Launching Soon</title>
</head>
<body>
<div class="ambient" aria-hidden="true"><span></span><span></span><span></span></div>
<header class="header">
<a class="brand" href="./" aria-label="Aether home"><span class="brand-mark" aria-hidden="true">✳</span> aether<span class="brand-dot">.</span></a>
<span class="header-note"><span aria-hidden="true"></span> A new perspective is coming</span>
</header>
<main>
<section class="launch-panel" aria-labelledby="launch-title">
<div class="eyebrow"><span aria-hidden="true"></span> SOMETHING EXCITING IS COMING</div>
<h1 id="launch-title">Launching <span>Soon</span></h1>
<p class="intro">A little more possibility. A whole new perspective.<br>We're creating something thoughtful. We can't wait to share it.</p>
<!-- Time values are deliberately not live regions. Only status changes are announced. -->
<div class="countdown" role="group" aria-label="Time until launch">
<div class="time-card"><span class="time-value" id="days">00</span><span class="time-label">Days</span></div>
<div class="time-card"><span class="time-value" id="hours">00</span><span class="time-label">Hours</span></div>
<div class="time-card"><span class="time-value" id="minutes">00</span><span class="time-label">Minutes</span></div>
<div class="time-card"><span class="time-value" id="seconds">00</span><span class="time-label">Seconds</span></div>
</div>
<p class="countdown-status" id="countdown-status" role="status" aria-live="polite" aria-atomic="true"></p>
<div class="signup">
<h2>Be first through the door.</h2>
<p class="signup-copy">A small note when something big is ready.</p>
<form id="newsletter-form" novalidate="">
<label for="email">Email address</label>
<div class="form-row">
<input id="email" name="email" type="email" autocomplete="email" placeholder="you@example.com" required="" aria-describedby="privacy form-feedback">
<button type="submit">Notify Me <span aria-hidden="true">↗</span></button>
</div>
<p id="form-feedback" class="form-feedback" role="status" aria-live="polite" aria-atomic="true"></p>
<p id="privacy" class="privacy"><svg viewBox="0 0 24 24" aria-hidden="true"><rect x="5" y="10" width="14" height="11" rx="3"></rect><path d="M8 10V7a4 4 0 0 1 8 0v3"></path></svg> Demo only. Your email isn't saved or sent. No subscription is created.</p>
</form>
</div>
<!-- Replace these sample profile URLs with your own. -->
<nav class="socials" aria-label="Follow Aether">
<a href="https://www.instagram.com/example/" aria-label="Instagram (sample profile)"><svg viewBox="0 0 24 24" aria-hidden="true"><rect x="3" y="3" width="18" height="18" rx="5"></rect><circle cx="12" cy="12" r="4"></circle><circle class="solid" cx="17.5" cy="6.5" r="1"></circle></svg></a>
<a href="https://www.linkedin.com/company/example/" aria-label="LinkedIn (sample profile)"><svg viewBox="0 0 24 24" aria-hidden="true"><path d="M5 9v11M5 4v.5M10 20V9h4v2c1-3 6-3 6 2v7M14 12v8"></path></svg></a>
<a href="https://x.com/example" aria-label="X (sample profile)"><svg viewBox="0 0 24 24" aria-hidden="true"><path d="m4 4 12 16h4L8 4H4Zm0 16 6.8-7.8M20 4l-6.8 7.8"></path></svg></a>
</nav>
</section>
</main>
<footer>© <span id="year">2026</span> Aether. <span>Good things take a little time.</span></footer>
</body></html>
CSS source
:root {
color-scheme: dark;
--bg: #080b18;
--text: #f7f7ff;
--muted: #b7b9cd;
--violet: #a08aff;
--cyan: #8de6f2;
--glass: rgba(20, 23, 43, .9);
--border: 1px solid rgba(255, 255, 255, .13);
--radius: 28px;
--small-radius: 12px;
--blur: 28px;
--gap: clamp(16px, 2.6svh, 26px);
}
* { box-sizing: border-box; }
body {
margin: 0;
min-height: 100svh;
display: flex;
flex-direction: column;
color: var(--text);
background: radial-gradient(ellipse at 15% 45%, #1c1640 0, transparent 52%), radial-gradient(ellipse at 90% 75%, #092b38 0, transparent 48%), var(--bg);
font-family: ui-sans-serif, system-ui, -apple-system, BlinkMacSystemFont, "Segoe UI", sans-serif;
-webkit-font-smoothing: antialiased;
padding: max(20px, env(safe-area-inset-top)) max(24px, env(safe-area-inset-right)) max(16px, env(safe-area-inset-bottom)) max(24px, env(safe-area-inset-left));
}
.ambient { position: fixed; inset: 0; overflow: hidden; pointer-events: none; z-index: -1; }
.ambient span { position: absolute; width: 42vw; aspect-ratio: 1; border-radius: 50%; filter: blur(85px); opacity: .22; animation: drift 22s ease-in-out infinite alternate; }
.ambient span:nth-child(1) { background: #7345e4; top: 8%; left: -12%; }
.ambient span:nth-child(2) { background: #4c4ee3; top: -28%; right: 5%; animation-delay: -8s; }
.ambient span:nth-child(3) { background: #13b2cf; bottom: -24%; right: -8%; animation-delay: -15s; }
.header { width: 100%; max-width: 1320px; margin-inline: auto; display: flex; align-items: center; justify-content: space-between; gap: 20px; }
.brand { color: var(--text); text-decoration: none; font-size: 25px; font-weight: 650; letter-spacing: -1px; display: flex; align-items: center; }
.brand-mark { font-size: 34px; color: #b9acff; margin-right: 9px; font-weight: 400; }
.brand-dot { color: var(--cyan); }
.header-note { color: var(--muted); font-size: 11px; letter-spacing: .04em; }
.header-note > span, .eyebrow > span { display: inline-block; width: 5px; height: 5px; background: var(--cyan); border-radius: 50%; margin-right: 8px; box-shadow: 0 0 10px #8de6f280; }
main { flex: 1; display: grid; place-items: center; padding-block: var(--gap); min-width: 0; }
.launch-panel { position: relative; width: min(100%, 690px); padding: clamp(24px, 4svh, 42px) clamp(20px, 5vw, 60px) 20px; background: var(--glass); border: var(--border); border-radius: var(--radius); text-align: center; box-shadow: 0 30px 100px #0005, inset 0 1px 0 #ffffff10; animation: enter .8s ease-out both; }
@supports ((backdrop-filter: blur(1px)) or (-webkit-backdrop-filter: blur(1px))) {
.launch-panel { background: linear-gradient(135deg, #ffffff09, #ffffff02), #10132380; backdrop-filter: blur(var(--blur)); -webkit-backdrop-filter: blur(var(--blur)); }
}
.eyebrow { display: inline-flex; align-items: center; padding: 8px 13px; border: var(--border); border-radius: 100px; background: #ffffff04; font-size: clamp(8px, 1.8vw, 9px); letter-spacing: .17em; color: #d6cff4; }
.eyebrow > span { width: 4px; height: 4px; background: var(--violet); flex-shrink: 0; }
h1 { font-size: clamp(42px, 7.5vw, 70px); letter-spacing: -.065em; font-weight: 550; line-height: 1.08; margin: 20px 0 15px; }
h1 span { background: linear-gradient(100deg, #c3b3ff, #a7ddf3); background-clip: text; -webkit-background-clip: text; color: transparent; }
.intro { font-size: clamp(12px, 1.7vw, 14px); line-height: 1.8; color: var(--muted); margin: 0 auto; }
.countdown { display: grid; grid-template-columns: repeat(4, minmax(0, 1fr)); gap: 12px; max-width: 440px; margin: 27px auto 0; }
.time-card { display: flex; flex-direction: column; padding: 15px 6px 12px; border: var(--border); border-radius: var(--small-radius); background: linear-gradient(145deg, #ffffff08, #ffffff02); box-shadow: inset 0 1px 0 #ffffff06; }
.time-value { font-size: clamp(29px, 5vw, 40px); line-height: 1.15; font-weight: 450; letter-spacing: -.04em; font-variant-numeric: tabular-nums; }
.time-label { font-size: 9px; letter-spacing: .15em; text-transform: uppercase; color: var(--muted); margin-top: 7px; }
.countdown-status, .form-feedback { font-size: 12px; line-height: 1.5; margin: 0; }
.countdown-status:not(:empty) { margin-top: 12px; color: var(--cyan); }
.signup { margin-top: 26px; padding-top: 23px; border-top: 1px solid #ffffff0d; }
h2 { font-size: 15px; font-weight: 550; margin: 0 0 5px; letter-spacing: -.02em; }
.signup-copy { color: var(--muted); font-size: 12px; margin: 0 0 17px; }
form { text-align: left; }
label { display: block; font-size: 11px; color: #d0d2e2; margin-bottom: 7px; }
.form-row { display: flex; gap: 9px; }
input, button { font: inherit; border-radius: 9px; min-height: 46px; }
input { min-width: 0; width: 100%; border: var(--border); background: #080b1866; padding: 12px 14px; color: var(--text); font-size: 13px; }
input::placeholder { color: #999bb3; }
input[aria-invalid="true"] { border-color: #ffb4c2; }
button { flex-shrink: 0; padding: 12px 22px; border: 1px solid #ffffff38; background: linear-gradient(110deg, #b6a0fb, #87deed); color: #10152a; font-size: 12px; font-weight: 750; cursor: pointer; box-shadow: 0 3px 20px #a48cff18; transition: filter .2s, transform .2s; }
button span { margin-left: 15px; font-size: 17px; }
button:hover { filter: brightness(1.1); transform: translateY(-1px); }
:focus-visible { outline: 3px solid var(--cyan); outline-offset: 4px; }
.form-feedback:not(:empty) { margin-top: 10px; color: var(--cyan); }
.form-feedback.error { color: #ffb4c2; }
.privacy { display: flex; justify-content: center; align-items: flex-start; gap: 6px; font-size: 10px; color: var(--muted); line-height: 1.6; margin: 12px 0 0; text-align: center; }
.privacy svg { width: 12px; height: 14px; flex-shrink: 0; margin-top: 1px; fill: none; stroke: currentColor; stroke-width: 1.6; }
.socials { display: flex; justify-content: center; gap: 9px; margin-top: 15px; }
.socials a { display: grid; place-items: center; width: 44px; min-height: 44px; color: #bfc2d5; border-radius: 50%; transition: background .2s, color .2s; }
.socials a:hover { color: var(--cyan); background: #ffffff09; }
.socials svg { width: 16px; height: 16px; fill: none; stroke: currentColor; stroke-width: 1.6; stroke-linecap: round; stroke-linejoin: round; }
.socials .solid { fill: currentColor; stroke: none; }
footer { text-align: center; font-size: 10px; line-height: 1.7; color: var(--muted); }
footer > span:last-child { margin-left: 12px; color: #9c9fb6; }
@keyframes drift { to { transform: translate(8%, -7%) scale(1.12); } }
@keyframes enter { from { opacity: 0; transform: translateY(12px); } to { opacity: 1; transform: translateY(0); } }
@media (max-width: 520px) {
body { padding-inline: max(16px, env(safe-area-inset-left)) max(16px, env(safe-area-inset-right)); }
.header-note { display: none; }
.launch-panel { border-radius: 22px; }
.form-row { flex-direction: column; }
button { width: 100%; }
.intro br { display: none; }
footer > span:last-child { display: block; margin-left: 0; }
}
@media (max-width: 360px) {
.countdown { grid-template-columns: repeat(2, minmax(0, 1fr)); gap: 8px; }
.time-card { padding: 9px 6px; }
h1 { font-size: clamp(32px, 11vw, 42px); }
}
@media (max-height: 760px) {
:root { --gap: 14px; }
.launch-panel { padding-top: 22px; padding-bottom: 12px; }
h1 { margin-block: 14px 10px; }
.countdown { margin-top: 18px; }
.signup { margin-top: 18px; padding-top: 16px; }
.socials { margin-top: 8px; }
}
@media (prefers-reduced-motion: reduce) {
*, *::before, *::after { animation: none !important; transition: none !important; }
}
JavaScript source
"use strict";
// Set your launch date here: ISO 8601 with an explicit timezone offset.
const LAUNCH_DATE = "2027-12-01T09:00:00+05:30";
const launchTimestamp = Date.parse(LAUNCH_DATE);
const countdownStatus = document.getElementById("countdown-status");
const timeElements = ["days", "hours", "minutes", "seconds"].map((id) => document.getElementById(id));
let countdownInterval;
function renderTime(values) {
values.forEach((value, index) => {
timeElements[index].textContent = String(value).padStart(2, "0");
});
}
function updateCountdown() {
const remaining = launchTimestamp - Date.now();
if (remaining <= 0) {
renderTime([0, 0, 0, 0]);
clearInterval(countdownInterval);
countdownStatus.textContent = "The countdown is complete. Our launch update is coming shortly.";
return false;
}
const seconds = Math.floor(remaining / 1000);
renderTime([
Math.floor(seconds / 86400),
Math.floor(seconds / 3600) % 24,
Math.floor(seconds / 60) % 60,
seconds % 60,
]);
return true;
}
if (!Number.isFinite(launchTimestamp)) {
renderTime([0, 0, 0, 0]);
countdownStatus.textContent = "Our launch date is being finalized. Please check back soon.";
} else if (updateCountdown()) {
countdownInterval = setInterval(updateCountdown, 1000);
}
document.getElementById("year").textContent = new Date().getFullYear();
const form = document.getElementById("newsletter-form");
const email = document.getElementById("email");
const feedback = document.getElementById("form-feedback");
form.addEventListener("submit", (event) => {
event.preventDefault();
email.value = email.value.trim();
if (!email.validity.valid) {
email.setAttribute("aria-invalid", "true");
feedback.classList.add("error");
feedback.textContent = email.validity.valueMissing
? "Please enter your email address."
: "Please enter a valid email address, such as you@example.com.";
email.focus();
return;
}
email.removeAttribute("aria-invalid");
feedback.classList.remove("error");
// Integration point: send email.value to your backend or newsletter provider.
// Only show a subscription success message after the service confirms signup.
// This frontend demo does not send or store email addresses.
feedback.textContent = "Demo complete. No subscription has been created, and your email has not been saved or sent.";
form.reset();
});
email.addEventListener("input", () => {
if (email.hasAttribute("aria-invalid")) {
email.removeAttribute("aria-invalid");
feedback.classList.remove("error");
feedback.textContent = "";
}
});
How it works
The project uses index.html for the page structure, style.css for the glass effects and responsive design, and script.js for the countdown and form validation. Newsletter subscriptions require connecting the form to an email service or backend.
Try a change
Choose Edit code, make a small change, then press Run to preview it.
Use the source Copy buttons, choose Edit code to open the editor, or Download ZIP to save the project after a six-second countdown.





.webp)

Discussion (0)
Leave a comment