Neumorphism Coming Soon html Template with Countdown Timer

·

Coming soon page template

Introduce your upcoming website or product with this neumorphism coming soon page template using HTML5, CSS3, and JavaScript. Soft shadows, rounded countdown cards, and a recessed email field create a distinctive interface, while clear typography keeps the launch message easy to read.

This responsive coming soon page includes a live countdown timer and a newsletter signup layout for inviting visitors to receive launch updates. Separate HTML, CSS, and JavaScript files make it easy to customize the branding, launch date, colors, and content. The email form includes frontend validation and is ready to connect to a newsletter service.

What you will build

You will build a launching soon landing page with a soft neumorphic design and practical launch features. The template includes:

A customizable brand name or text logo.

A prominent launch headline and introductory message.

A live countdown displaying days, hours, minutes, and seconds.

Softly raised countdown cards with rounded corners.

A recessed newsletter email field.

A “Notify Me” button with email validation.

Inline feedback explaining the newsletter demo behavior.

A launch-completion message when the timer reaches zero.

Social media links and a minimal footer.

A responsive layout for mobile, tablet, and desktop.

Subtle animations with 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="A little space for big ideas. Orbit is coming soon. Explore the countdown and get ready for a more thoughtful way to create.">
  <meta name="theme-color" content="#E8EDF2">
  <title>Orbit — Something good is on the way</title>
  
  
</head>
<body>
  <header class="site-header">
    <a class="brand" href="./" aria-label="Orbit home"><span class="brand-mark" aria-hidden="true">o<span></span></span>orbit<span class="brand-period">.</span></a>
    <span class="header-note"><span class="status-dot" aria-hidden="true"></span> A little more time. A lot to look forward to.</span>
  </header>

  <main id="main-content">
    <section class="launch" aria-labelledby="launch-heading">
      <div class="orbit-art" aria-hidden="true"><div class="orbit-center"><svg viewBox="0 0 32 32" fill="none"><path d="m17 5-9 13h7l-1 9 10-14h-8l1-8Z" stroke="currentColor" stroke-width="1.8" stroke-linejoin="round"></path></svg></div><span class="orbit-dot"></span></div>
      <p class="eyebrow">Something new is coming</p>
      <h1 id="launch-heading">We’re Launching <span>Soon</span></h1>
      <p class="intro">Good things take a little time. We’re crafting a thoughtful new<br class="desktop-break"> space for your ideas to take shape. We can’t wait to share it.</p>

      <!-- The timer itself is intentionally not a live region. -->
      <div class="countdown" role="timer" aria-label="Time until Orbit launches" aria-live="off">
        <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="timer-message" id="timer-message" role="status" aria-atomic="true"></p>
      <noscript><p>The countdown needs JavaScript. Our sample launch is January 1, 2027 at 09:00 UTC.</p></noscript>

      <section class="newsletter" aria-labelledby="newsletter-heading">
        <h2 id="newsletter-heading">Be first through the door.</h2>
        <p>A little heads-up when we’re ready. Nothing more.</p>
        <form id="newsletter-form" novalidate="">
          <label for="email">Email address</label>
          <div class="form-row">
            <div class="email-wrap"><svg viewBox="0 0 24 24" fill="none" aria-hidden="true"><rect x="3" y="5" width="18" height="14" rx="3"></rect><path d="m4 7 8 6 8-6"></path></svg><input id="email" name="email" type="email" autocomplete="email" placeholder="you@example.com" required="" aria-describedby="privacy-note form-feedback"></div>
            <button type="submit">Notify Me <span aria-hidden="true">↗</span></button>
          </div>
          <p class="privacy-note" id="privacy-note"><svg viewBox="0 0 16 16" fill="none" aria-hidden="true"><rect x="3.5" y="7" width="9" height="7" rx="2"></rect><path d="M5.5 7V4.5a2.5 2.5 0 0 1 5 0V7"></path></svg> Your inbox is your space. No spam, ever. Demo only; no email is stored.</p>
          <p id="form-feedback" class="form-feedback" role="status" aria-atomic="true"></p>
        </form>
      </section>

      <nav class="social-links" aria-label="Follow Orbit">
        <!-- Replace these sample URLs with your brand's social profiles. -->
        <a href="https://www.instagram.com/example/" aria-label="Orbit on Instagram"><svg viewBox="0 0 24 24" fill="none" aria-hidden="true"><rect x="4" y="4" width="16" height="16" rx="5"></rect><circle cx="12" cy="12" r="3.5"></circle><circle class="solid" cx="17" cy="7" r="1"></circle></svg></a>
        <a href="https://www.linkedin.com/company/example/" aria-label="Orbit on LinkedIn"><svg viewBox="0 0 24 24" fill="none" aria-hidden="true"><path d="M6 10v9M6 6v.1M11 19v-9h4a3 3 0 0 1 3 3v6M11 14a4 4 0 0 1 7 0"></path><circle cx="6" cy="6" r=".7"></circle></svg></a>
        <a href="https://x.com/example" aria-label="Orbit on X"><svg viewBox="0 0 24 24" fill="none" aria-hidden="true"><path d="m5 4 14 16h-4L5 4h4l10 16M19 4l-6 7M5 20l6-7"></path></svg></a>
      </nav>
      <p class="social-caption">Until then, let’s stay connected.</p>
    </section>
  </main>

  <footer class="site-footer"><span>© <span id="copyright-year">2026</span> Orbit. All rights reserved.</span><span>Made with intention. Coming with purpose.</span></footer>


</body></html>

CSS source

/* Theme tokens: surfaces remain readable even without box-shadow support. */
:root {
  color-scheme: light;
  --background: #e8edf2;
  --text: #303b4e;
  --muted: #616c7e;
  --accent: #5a58b6;
  --border: #d2dbe5;
  --light: #ffffff;
  --dark: #c8d1dc;
  --raised: 8px 8px 20px var(--dark), -8px -8px 20px var(--light);
  --inset: inset 4px 4px 9px #cdd6e0, inset -4px -4px 9px #ffffff;
  --radius: 20px;
  --space: clamp(1rem, 3vw, 1.8rem);
}
* { box-sizing: border-box; }
body { margin: 0; min-height: 100vh; min-height: 100svh; display: flex; flex-direction: column; background: var(--background); color: var(--text); font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", sans-serif; -webkit-font-smoothing: antialiased; }
a { color: inherit; text-decoration: none; }
button, input { font: inherit; }
a, button, input { -webkit-tap-highlight-color: transparent; }
:focus-visible { outline: 3px solid var(--accent); outline-offset: 5px; }
.site-header, .site-footer { width: min(100% - 3rem, 1320px); margin-inline: auto; display: flex; align-items: center; justify-content: space-between; gap: var(--space); }
.site-header { padding-block: 28px; }
.brand { display: inline-flex; align-items: center; font-size: 27px; font-weight: 750; letter-spacing: -1.4px; min-height: 44px; }
.brand-period { color: var(--accent); }
.brand-mark { position: relative; display: grid; place-items: center; width: 37px; height: 37px; margin-right: 10px; border: 1px solid #eef2f7; border-radius: 50%; box-shadow: 4px 4px 9px var(--dark), -4px -4px 9px var(--light); font-size: 28px; font-weight: 400; line-height: 1; color: var(--accent); }
.brand-mark span { position: absolute; right: 5px; top: 7px; width: 5px; height: 5px; border-radius: 50%; background: var(--accent); }
.header-note { display: none; color: var(--muted); font-size: 11px; letter-spacing: .2px; }
.status-dot { display: inline-block; width: 6px; height: 6px; margin-right: 8px; border-radius: 50%; background: var(--accent); }
main { flex: 1; padding: 24px 24px 45px; display: grid; place-items: center; }
.launch { width: min(100%, 760px); text-align: center; animation: arrive .8s ease-out both; }
.orbit-art { position: relative; width: 108px; height: 108px; border: 1px solid #d5dde7; border-radius: 50%; display: grid; place-items: center; margin: 0 auto 31px; }
.orbit-art::before { content: ""; position: absolute; inset: 8px; border: 1px solid #f5f7fa; border-radius: 50%; }
.orbit-center { width: 68px; height: 68px; border-radius: 50%; box-shadow: var(--raised); display: grid; place-items: center; }
.orbit-center svg { width: 30px; color: var(--accent); }
.orbit-dot { position: absolute; width: 11px; height: 11px; right: 6px; top: 18px; background: var(--accent); border: 3px solid var(--background); border-radius: 50%; box-sizing: content-box; }
.eyebrow { font-size: 10px; font-weight: 700; text-transform: uppercase; letter-spacing: 3px; color: var(--accent); margin: 0 0 18px; }
h1 { margin: 0; font-size: clamp(2.7rem, 7vw, 4.05rem); line-height: 1.12; letter-spacing: -.055em; font-weight: 750; }
h1 span { color: var(--accent); }
.intro { margin: 21px auto 0; max-width: 510px; font-size: 14px; line-height: 1.85; color: var(--muted); }
.desktop-break { display: none; }
.countdown { display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); gap: 20px; max-width: 580px; margin: 38px auto 0; }
.time-card { padding: 23px 8px 20px; border-radius: var(--radius); border: 1px solid #eef2f6; box-shadow: var(--raised); }
.time-value { display: block; font-size: clamp(2.4rem, 6vw, 3.15rem); line-height: 1.12; font-weight: 600; letter-spacing: -2px; font-variant-numeric: tabular-nums; }
.time-label { display: block; margin-top: 11px; color: var(--muted); font-size: 9px; letter-spacing: 2px; text-transform: uppercase; font-weight: 650; }
.timer-message { margin: 15px 0 0; font-size: 13px; color: var(--accent); }
.timer-message:empty { display: none; }
.newsletter { max-width: 490px; margin: 43px auto 0; }
h2 { margin: 0; font-size: 17px; font-weight: 650; letter-spacing: -.3px; }
.newsletter > p { color: var(--muted); font-size: 12px; margin: 9px 0 22px; }
form { text-align: left; }
label { display: block; margin: 0 0 9px 3px; font-size: 11px; font-weight: 600; color: var(--muted); }
.form-row { display: flex; flex-direction: column; gap: 14px; }
.email-wrap { display: flex; align-items: center; flex: 1; min-width: 0; border: 1px solid var(--border); border-radius: 13px; box-shadow: var(--inset); }
.email-wrap > svg { width: 18px; height: 18px; margin-left: 17px; stroke: var(--muted); stroke-width: 1.5; flex-shrink: 0; }
input { color: var(--text); background: transparent; border: 0; border-radius: 12px; width: 100%; min-width: 0; min-height: 52px; padding: 15px 13px; font-size: 14px; }
input::placeholder { color: var(--muted); opacity: 1; }
input[aria-invalid="true"] { outline: 2px solid #a13c4d; outline-offset: 2px; }
button { min-height: 52px; display: flex; align-items: center; justify-content: center; gap: 22px; padding: 15px 22px; border: 1px solid #6562b9; border-radius: 13px; background: var(--accent); color: white; font-size: 12px; font-weight: 600; box-shadow: 5px 5px 12px #c2cbd9, -5px -5px 12px #fff; cursor: pointer; transition: transform .2s ease, background .2s ease; }
button span { font-size: 18px; line-height: 1; }
button:hover { background: #4d4b9f; transform: translateY(-2px); }
button:active { transform: translateY(0); }
.privacy-note { display: flex; justify-content: center; align-items: flex-start; gap: 5px; color: var(--muted); font-size: 10px; line-height: 1.7; margin: 14px 0 0; text-align: center; }
.privacy-note svg { flex-shrink: 0; margin-top: 2px; width: 12px; height: 12px; stroke: currentColor; stroke-width: 1.3; }
.form-feedback { font-size: 12px; line-height: 1.6; color: var(--accent); text-align: center; margin: 12px 0 0; }
.form-feedback:empty { display: none; }
.form-feedback.is-error { color: #a13c4d; }
.social-links { display: flex; justify-content: center; gap: 17px; margin-top: 33px; }
.social-links a { display: grid; place-items: center; width: 44px; height: 44px; border-radius: 50%; border: 1px solid #eef2f6; box-shadow: 4px 4px 10px var(--dark), -4px -4px 10px var(--light); transition: transform .2s ease, color .2s ease; }
.social-links a:hover { color: var(--accent); transform: translateY(-3px); }
.social-links svg { width: 18px; height: 18px; stroke: currentColor; stroke-width: 1.5; stroke-linecap: round; stroke-linejoin: round; }
.social-links .solid { fill: currentColor; stroke: none; }
.social-caption { font-size: 10px; color: var(--muted); margin: 16px 0 0; }
.site-footer { border-top: 1px solid var(--border); padding-block: 22px; color: var(--muted); font-size: 10px; line-height: 1.6; flex-wrap: wrap; }
@keyframes arrive { from { opacity: 0; transform: translateY(12px); } to { opacity: 1; transform: translateY(0); } }
@media (min-width: 540px) {
  .countdown { grid-template-columns: repeat(4, minmax(0, 1fr)); gap: 22px; }
  .form-row { flex-direction: row; }
  .desktop-break { display: initial; }
  .site-header, .site-footer { width: min(100% - 6rem, 1320px); }
}
@media (min-width: 800px) { .header-note { display: inline; } main { padding-top: 12px; } }
@media (prefers-reduced-motion: reduce) { *, *::before, *::after { animation: none !important; transition: none !important; scroll-behavior: auto !important; } }

JavaScript source

"use strict";

// REPLACE this future sample with your launch date. Keep the ISO 8601 format
// and an explicit timezone offset: e.g. 2027-01-01T14:30:00+05:30 for India.
const LAUNCH_DATE = "2027-01-01T09:00:00+00:00";

const launchTimestamp = new Date(LAUNCH_DATE).getTime();
const timerMessage = document.getElementById("timer-message");
const timeElements = ["days", "hours", "minutes", "seconds"].map(
  (unit) => document.getElementById(unit)
);
let countdownInterval;

function displayTime(values) {
  values.forEach((value, index) => {
    timeElements[index].textContent = String(value).padStart(2, "0");
  });
}

function updateCountdown() {
  // Recalculate from the clock each time to avoid accumulating interval drift.
  const remaining = Math.max(0, launchTimestamp - Date.now());
  const totalSeconds = Math.floor(remaining / 1000);
  displayTime([
    Math.floor(totalSeconds / 86400),
    Math.floor((totalSeconds % 86400) / 3600),
    Math.floor((totalSeconds % 3600) / 60),
    totalSeconds % 60
  ]);

  if (remaining === 0) {
    clearInterval(countdownInterval);
    // Only this completion message is announced, never the second-by-second ticks.
    timerMessage.textContent = "We’re live! Stay tuned for our launch update.";
  }
}

if (Number.isFinite(launchTimestamp)) {
  updateCountdown();
  if (launchTimestamp > Date.now()) {
    countdownInterval = setInterval(updateCountdown, 1000);
  }
} else {
  displayTime([0, 0, 0, 0]);
  timerMessage.textContent = "Our launch date is being finalized. Check back soon.";
}

document.getElementById("copyright-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("is-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("is-error");
  // INTEGRATION POINT: connect your newsletter service or backend endpoint here.
  // Await its response before showing a real success message. This demo sends
  // no network request and does not persist email addresses.
  feedback.textContent = "This signup is a demo. Connect an email service to receive subscriptions. Your email has not been sent or saved.";
});

email.addEventListener("input", () => {
  if (email.hasAttribute("aria-invalid")) {
    email.removeAttribute("aria-invalid");
    feedback.textContent = "";
    feedback.classList.remove("is-error");
  }
});

How it works

The project uses index.html for the page structure, style.css for the neumorphic design and responsive layout, and script.js for the countdown timer and form validation. Collecting newsletter subscriptions requires 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.

Discussion (0)

Leave a comment