Give your upcoming launch a tactile, distinctive presentation with this skeuomorphic coming soon page using HTML5, CSS3, and JavaScript. A stationery-style panel, brushed-metal brand plate, recessed email field, and raised button recreate the familiar appearance of physical objects.
The template includes a live countdown timer and a newsletter signup layout for your launch announcement. Warm ivory tones, restrained brass accents, and realistic shadows create a polished design without overwhelming the content. Separate HTML, CSS, and JavaScript files make the branding, launch date, and visual details easy to customize.
What you will build
You will build a responsive coming soon page with physical design details and interactive launch features. The template includes:
A metal-style brand nameplate.
A paper-inspired panel with layered edges and subtle texture.
A prominent coming soon headline and supporting paragraph.
A mechanical-style countdown showing days, hours, minutes, and seconds.
A recessed newsletter email field.
A raised “Notify Me” button with a pressed state.
Email validation and clear frontend demo feedback.
A message displayed when the countdown finishes.
Social links styled as small physical buttons.
A contact email and minimal copyright footer.
A compact responsive layout for mobile, tablet, and desktop.
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 great is taking shape at North & Co. Count down to our launch and discover what's coming next.">
<meta name="theme-color" content="#eeeade">
<title>Coming Soon — North & Co.</title>
</head>
<body>
<main class="stationery" aria-labelledby="announcement-title">
<header class="header">
<!-- Customize the brand name here and in the footer. -->
<a class="nameplate" href="#" aria-label="North and Company home"><span aria-hidden="true" class="screw"></span> NORTH <span class="ampersand">&</span> CO. <span aria-hidden="true" class="screw"></span></a>
<div class="header-actions"><span class="work-label"><span aria-hidden="true" class="status-dot"></span> WORK IN PROGRESS</span>
<button class="theme-toggle" type="button" aria-label="Dark mode" aria-pressed="false" hidden=""><svg aria-hidden="true" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.6"><path d="M20.5 13A8.5 8.5 0 0 1 11 3.5 8.5 8.5 0 1 0 20.5 13Z"></path></svg></button></div>
</header>
<section class="announcement">
<p class="eyebrow">A LITTLE PATIENCE. SOMETHING SPECIAL.</p>
<h1 id="announcement-title">Something Great<br>Is Coming<span class="brass">.</span></h1>
<p class="intro">Good things take a little craftsmanship. We’re putting the finishing<br class="desktop-break"> touches on a new experience, and we can’t wait to share it with you.</p>
<div class="divider" aria-hidden="true"><span>✦</span></div>
</section>
<section class="countdown-section" aria-labelledby="countdown-heading">
<h2 id="countdown-heading" class="eyebrow">COUNTING DOWN TO SOMETHING NEW</h2>
<!-- The timer is deliberately not a live region. Only its final status is announced. -->
<div class="countdown" role="timer" aria-label="Time remaining until launch" aria-live="off">
<div class="counter"><span class="display" id="days">00</span><span class="unit">DAYS</span></div>
<div class="counter"><span class="display" id="hours">00</span><span class="unit">HOURS</span></div>
<div class="counter"><span class="display" id="minutes">00</span><span class="unit">MINUTES</span></div>
<div class="counter"><span class="display" id="seconds">00</span><span class="unit">SECONDS</span></div>
</div>
<p id="countdown-status" class="timer-status" role="status"></p>
<noscript><p class="fallback">Our launch is on its way. Enable JavaScript to see the live countdown. This demo form requires JavaScript; contact us by email instead.</p></noscript>
</section>
<section class="signup" aria-labelledby="signup-heading">
<h2 id="signup-heading">Be the first to know.</h2>
<p>Leave your email for a little good news on launch day.</p>
<form id="newsletter-form">
<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 class="notify-button" type="submit" disabled="">Notify Me <span aria-hidden="true">→</span></button>
</div>
<p id="form-feedback" class="form-feedback" role="status" aria-atomic="true"></p>
<p id="privacy" class="privacy"><svg aria-hidden="true" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.7"><rect x="5" y="10" width="14" height="11" rx="2"></rect><path d="M8 10V7a4 4 0 0 1 8 0v3"></path></svg> Just the launch announcement. No noise, ever. <span>Frontend demo only.</span></p>
</form>
</section>
<footer class="footer">
<div class="footer-top">
<!-- Replace these URLs with your brand's social profiles. -->
<nav class="socials" aria-label="Social media">
<a class="social-button" href="https://www.instagram.com/" aria-label="Instagram"><svg aria-hidden="true" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.6"><rect x="3" y="3" width="18" height="18" rx="5"></rect><circle cx="12" cy="12" r="4"></circle><circle cx="17.5" cy="6.5" r=".8" fill="currentColor" stroke="none"></circle></svg></a>
<a class="social-button" href="https://www.linkedin.com/" aria-label="LinkedIn"><svg aria-hidden="true" viewBox="0 0 24 24" fill="currentColor"><path d="M5 3a2 2 0 1 0 0 4 2 2 0 0 0 0-4ZM3.5 9h3v12h-3V9Zm5.5 0h3v1.6c.7-1.1 1.8-1.9 3.5-1.9 3 0 4 1.9 4 5V21h-3v-6.5c0-1.7-.5-2.8-2-2.8s-2.5 1.2-2.5 2.8V21H9V9Z"></path></svg></a>
<a class="social-button" href="https://www.pinterest.com/" aria-label="Pinterest"><svg aria-hidden="true" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.8" stroke-linecap="round"><path d="M9 21 12 9m-2 7c1 2 6 2 8-3 3-8-9-12-12-4-1 3 0 5 1 6m5-6c-2 5 0 7 2 6"></path></svg></a>
</nav>
<a class="contact" href="mailto:hello@northandco.example">Say hello <span aria-hidden="true">↗</span><br><span>hello@northandco.example</span></a>
</div>
<div class="footer-bottom"><span>© <span id="year">2026</span> North & Co.</span><span>MADE WITH CARE. WORTH THE WAIT.</span></div>
</footer>
</main>
<p class="desk-note" aria-hidden="true">SOMETHING THOUGHTFUL IS TAKING SHAPE.</p>
</body></html>
CSS source
/* All textures are CSS-only; solid base colors preserve readability. */
:root {
--desk-glow: #f9f6ed; --paper-top: #fffdf5; --paper-bottom: #f4f0e5; --edge: #f5f1e7; --highlight: #fff; --input-bg: #eeece3; --button-top: #fcfaf3; --button-bottom: #e9e5d9; --feedback: #243c4b; --error: #8c3023; --desk: #eeeade; --paper: #faf7ee; --ink: #30332f; --muted: #696b63;
--navy: #243c4b; --brass: #9a7843; --border: #d8d2c4;
--texture: repeating-linear-gradient(0deg, transparent 0 3px, #79644204 3px 4px);
--paper-shadow: 0 2px 3px #493c2420, 0 18px 45px #493c2417, 0 45px 90px #493c240b;
--radius: 5px; --space: clamp(22px, 4vw, 44px);
}
* { box-sizing: border-box; }
body { margin: 0; min-height: 100svh; padding: 38px 20px 18px; display: flex; flex-direction: column; align-items: center; justify-content: center; background: var(--texture), radial-gradient(ellipse at 50% 20%, var(--desk-glow), var(--desk) 75%); color: var(--ink); font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", sans-serif; -webkit-font-smoothing: antialiased; }
a { color: inherit; }
.stationery { position: relative; isolation: isolate; width: min(100%, 700px); padding: 30px 48px 22px; border: 1px solid var(--highlight); border-radius: var(--radius); background: var(--texture), linear-gradient(120deg, var(--paper-top), var(--paper) 60%, var(--paper-bottom)); box-shadow: var(--paper-shadow); animation: arrive .7s ease-out both; }
.stationery::before, .stationery::after { content: ""; position: absolute; z-index: -1; inset: 5px 3px -5px; border: 1px solid var(--border); background: var(--edge); border-radius: var(--radius); box-shadow: 0 2px 3px #493c2410; }
.stationery::after { inset: 8px 7px -9px; z-index: -2; background: var(--desk); }
.header { display: flex; align-items: center; justify-content: space-between; gap: 16px; }
.nameplate { display: inline-flex; align-items: center; gap: 10px; padding: 12px 10px; border: 1px solid #a9aaa0; border-radius: 3px; background: repeating-linear-gradient(0deg, #ffffff10 0 1px, #4c4e4410 1px 2px), linear-gradient(110deg, #d1d2c9, #eeeee5 45%, #bfc1b7); box-shadow: inset 0 1px #fff, 0 2px 3px #33332726; text-shadow: 0 1px var(--highlight); text-decoration: none; font-size: 12px; letter-spacing: 2px; font-weight: 750; white-space: nowrap; }
.ampersand { color: #73776a; font-family: Georgia, serif; font-style: italic; font-size: 17px; }
.screw { width: 5px; height: 5px; border-radius: 50%; background: linear-gradient(135deg,#818579 40%,#e7e8df 45%,#707467 55%,#b9bcb0 60%); box-shadow: 0 1px 1px #fff; }
.work-label, .eyebrow { font-size: 9px; font-weight: 650; letter-spacing: 1.7px; }
.work-label { color: var(--muted); display: flex; align-items: center; gap: 7px; white-space: nowrap; }
.status-dot { width: 5px; height: 5px; border-radius: 50%; background: var(--brass); box-shadow: 0 0 0 3px #9a784310; }
.announcement { text-align: center; padding-top: 37px; }
.eyebrow { color: var(--muted); margin: 0 0 17px; line-height: 1.6; }
h1 { margin: 0; font-size: clamp(34px, 6vw, 49px); font-weight: 650; letter-spacing: -2px; line-height: 1.12; text-shadow: 0 1px var(--highlight); }
.brass { color: var(--brass); }
.intro { font-size: 13px; line-height: 1.8; color: var(--muted); margin: 19px 0 0; }
.divider { display: flex; align-items: center; gap: 13px; width: 108px; margin: 22px auto; color: var(--brass); font-size: 14px; text-shadow: 0 1px var(--highlight); }
.divider::before,.divider::after { content: ""; height: 1px; flex: 1; background: var(--border); box-shadow: 0 1px var(--highlight); }
.countdown-section { text-align: center; }
.countdown-section h2 { font-size: 8px; margin-bottom: 14px; }
.countdown { display: grid; grid-template-columns: repeat(4,minmax(0,1fr)); gap: 15px; max-width: 410px; margin: auto; }
.counter { min-width: 0; }
.display { position: relative; display: block; padding: 14px 3px; border: 4px solid #c9c7bb; border-radius: 6px; background: linear-gradient(#303635,#222827); box-shadow: inset 0 3px 7px #0009, 0 1px 0 #fff, 0 2px 3px #0002; color: #f5f3e9; font-size: clamp(28px,5vw,40px); font-family: ui-monospace, "Cascadia Code", "Courier New", monospace; line-height: 1; font-weight: 600; font-variant-numeric: tabular-nums; text-shadow: 0 2px 2px #0008; }
.display::after { content: ""; position: absolute; left: 0; right: 0; top: 50%; height: 1px; background: #0009; box-shadow: 0 1px #ffffff12; }
.unit { display: block; margin-top: 10px; font-size: 8px; letter-spacing: 1.8px; font-weight: 650; color: var(--muted); }
.timer-status:empty,.form-feedback:empty { display: none; }
.timer-status,.fallback { font-size: 12px; line-height: 1.6; }
.signup { margin-top: 26px; text-align: center; }
.signup h2 { font-size: 19px; font-weight: 600; letter-spacing: -.4px; margin: 0 0 7px; }
.signup > p { font-size: 12px; color: var(--muted); margin: 0 0 18px; line-height: 1.6; }
form { max-width: 452px; margin: auto; text-align: left; }
label { display: block; font-size: 11px; font-weight: 600; margin-bottom: 7px; }
.form-row { display: flex; gap: 9px; }
input { width: 100%; min-width: 0; min-height: 46px; border: 1px solid #c9c4b8; border-radius: var(--radius); padding: 12px 14px; background: var(--input-bg); box-shadow: inset 0 2px 4px #00000020, 0 1px var(--highlight); color: var(--ink); font: inherit; font-size: 13px; }
input::placeholder { color: var(--muted); }
button { font: inherit; cursor: pointer; }
.notify-button { min-height: 46px; flex-shrink: 0; padding: 0 21px; border: 1px solid #182e3c; border-radius: var(--radius); color: #fffdf5; background: linear-gradient(#334d5c,var(--navy)); box-shadow: inset 0 1px #ffffff30, 0 3px 0 #172a35, 0 4px 5px #0002; font-size: 12px; font-weight: 600; transition: transform .15s,box-shadow .15s,filter .15s; }
.notify-button span { margin-left: 17px; color: #d4c6a6; }
.notify-button:hover { filter: brightness(1.12); }
.notify-button:active { transform: translateY(2px); box-shadow: inset 0 2px 3px #0003,0 1px 0 #172a35; }
.privacy { display: flex; justify-content: center; align-items: center; gap: 5px; flex-wrap: wrap; font-size: 9px; line-height: 1.5; color: var(--muted); margin: 13px 0 0; }
.privacy svg { width: 11px; height: 11px; }
.privacy span { font-style: italic; }
.form-feedback { font-size: 12px; line-height: 1.6; color: var(--feedback); margin: 12px 0 0; }
input[aria-invalid="true"] { border-color: #9a3d2c; }
.form-feedback.error { color: var(--error); }
.footer { border-top: 1px solid var(--border); box-shadow: inset 0 1px var(--highlight); margin-top: 27px; padding-top: 18px; }
.footer-top { display: flex; align-items: center; justify-content: space-between; gap: 12px; }
.socials { display: flex; gap: 8px; }
.social-button { display: grid; place-items: center; width: 44px; height: 44px; border: 1px solid #d3cec0; border-radius: 4px; background: linear-gradient(var(--button-top),var(--button-bottom)); box-shadow: inset 0 1px var(--highlight),0 2px 2px #4a42221a; transition: transform .15s; }
.social-button svg { width: 16px; height: 16px; }
.social-button:active { transform: translateY(1px); box-shadow: inset 0 1px 3px #0002; }
.contact { text-decoration: none; text-align: right; font-size: 10px; line-height: 1.9; }
.contact > span:last-child { color: var(--muted); }
.footer-bottom { display: flex; justify-content: space-between; gap: 12px; margin-top: 19px; color: var(--muted); font-size: 9px; }
.footer-bottom > span:last-child { font-size: 7px; letter-spacing: 1.25px; }
.desk-note { margin: 25px 0 0; font-size: 7px; letter-spacing: 2px; color: var(--muted); text-align: center; }
:focus-visible { outline: 3px solid #967238; outline-offset: 4px; }
@keyframes arrive { from { opacity: 0; transform: translateY(10px); } to { opacity: 1; transform: translateY(0); } }
@media (max-width: 560px) { body { padding: 22px 15px; } .stationery { padding: 24px; } .header { flex-direction: column; gap: 18px; } .announcement { padding-top: 26px; } .desktop-break { display: none; } .intro { font-size: 13px; } .form-row { flex-direction: column; gap: 12px; } input { font-size: 16px; } .notify-button { min-height: 48px; } .footer-bottom { flex-direction: column; align-items: center; gap: 9px; } .countdown { gap: 9px; } .display { border-width: 3px; } }
@media (max-width: 360px) { .countdown { grid-template-columns: repeat(2,minmax(0,1fr)); max-width: 230px; gap: 15px; } .display { font-size: 36px; } .footer-top { flex-direction: column; gap: 16px; } .contact { text-align: center; } h1 { font-size: 32px; letter-spacing: -1.3px; } }
@media (prefers-reduced-motion: reduce) { *,*::before,*::after { animation: none !important; transition: none !important; scroll-behavior: auto !important; } }
[hidden] { display: none !important; }
.notify-button:disabled { cursor: not-allowed; opacity: .65; box-shadow: none; }
/* Height-aware spacing keeps the board compact without clipping content or zoom. */
body { padding: clamp(14px, 2.5svh, 28px) 16px; }
.stationery { flex-shrink: 0; padding-top: 22px; padding-bottom: 18px; }
.header-actions { display: flex; align-items: center; gap: 12px; }
.theme-toggle { display: grid; place-items: center; flex-shrink: 0; width: 44px; height: 44px; padding: 11px; border: 1px solid var(--border); border-radius: 50%; color: var(--ink); background: linear-gradient(var(--button-top),var(--button-bottom)); box-shadow: inset 0 1px var(--highlight),0 2px 3px #0002; }
.theme-toggle svg { width: 20px; height: 20px; }
.theme-toggle:active { box-shadow: inset 0 2px 4px #0003; }
.announcement { padding-top: clamp(16px, 3svh, 30px); }
.intro { margin-top: 13px; }
.divider { margin: clamp(12px, 2svh, 20px) auto; }
.signup { margin-top: clamp(16px, 2.5svh, 24px); }
.signup > p { margin-bottom: 12px; }
.footer { margin-top: 18px; padding-top: 12px; }
.footer-bottom { margin-top: 12px; }
.desk-note { margin-top: 18px; }
.nameplate { color: #30332f; }
@media (max-width: 560px) {
.stationery { padding: 20px; }
.header { flex-direction: row; flex-wrap: wrap; justify-content: center; gap: 10px 18px; }
.header-actions { gap: 8px; }
.work-label { font-size: 8px; letter-spacing: 1px; }
.eyebrow { margin-bottom: 12px; }
.footer-bottom { flex-direction: row; flex-wrap: wrap; justify-content: center; }
}
@media (max-height: 740px) and (min-width: 561px) {
.stationery { padding-top: 16px; padding-bottom: 14px; }
h1 { font-size: 42px; }
.announcement { padding-top: 14px; }
.eyebrow { margin-bottom: 10px; }
.intro { margin-top: 10px; line-height: 1.6; }
.divider { margin: 12px auto; }
.display { padding-top: 10px; padding-bottom: 10px; }
.signup { margin-top: 16px; }
.desk-note { display: none; }
}
:root { color-scheme: light; }
:root[data-theme="dark"] {
color-scheme: dark;
--desk: #171c1e; --desk-glow: #303639;
--paper: #2c3233; --paper-top: #343a3b; --paper-bottom: #272d2e;
--edge: #242a2b; --highlight: #ffffff14;
--ink: #f0eee5; --muted: #b9bcb4; --border: #505654;
--brass: #d4b47b; --input-bg: #202627;
--button-top: #3e4748; --button-bottom: #303839;
--feedback: #c8dfec; --error: #ffb4a4;
--paper-shadow: 0 2px 3px #0006, 0 18px 45px #0004, 0 45px 90px #0003;
}
@media (prefers-color-scheme: dark) {
:root:not([data-theme="light"]) {
color-scheme: dark;
--desk: #171c1e; --desk-glow: #303639;
--paper: #2c3233; --paper-top: #343a3b; --paper-bottom: #272d2e;
--edge: #242a2b; --highlight: #ffffff14;
--ink: #f0eee5; --muted: #b9bcb4; --border: #505654;
--brass: #d4b47b; --input-bg: #202627;
--button-top: #3e4748; --button-bottom: #303839;
--feedback: #c8dfec; --error: #ffb4a4;
--paper-shadow: 0 2px 3px #0006, 0 18px 45px #0004, 0 45px 90px #0003;
}
}
JavaScript source
'use strict';
// CUSTOMIZE: launch date in ISO 8601 format with an explicit timezone offset.
const LAUNCH_DATE = '2027-06-01T09:00:00+05:30';
const launchTimestamp = Date.parse(LAUNCH_DATE);
const countdownStatus = document.getElementById('countdown-status');
const timer = document.querySelector('[role="timer"]');
const units = ['days', 'hours', 'minutes', 'seconds'];
let countdownInterval;
function updateCountdown() {
if (!Number.isFinite(launchTimestamp)) {
countdownStatus.textContent = 'Our launch date is being finalized. Please check back soon.';
timer.hidden = true;
return false;
}
const remaining = Math.max(0, Math.ceil((launchTimestamp - Date.now()) / 1000));
const values = [Math.floor(remaining / 86400), Math.floor(remaining / 3600) % 24,
Math.floor(remaining / 60) % 60, remaining % 60];
units.forEach((unit, index) => {
document.getElementById(unit).textContent = String(values[index]).padStart(2, '0');
});
if (remaining === 0) {
countdownStatus.textContent = 'The countdown is complete. Watch for our launch announcement.';
return false;
}
return true;
}
if (updateCountdown()) {
countdownInterval = window.setInterval(() => {
if (!updateCountdown()) window.clearInterval(countdownInterval);
}, 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');
// Keep native validation available without JS; provide inline feedback when JS runs.
form.noValidate = true;
form.querySelector('button').disabled = false;
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 a POST request to your backend/newsletter provider here.
// Only report subscription success after the service confirms it.
// This demo sends no requests and stores no email addresses.
feedback.textContent = 'Thanks for your interest! This is a frontend demonstration. No subscription has been created and your email has not been sent or saved.';
form.reset();
});
email.addEventListener('input', () => {
email.removeAttribute('aria-invalid');
feedback.textContent = '';
feedback.classList.remove('error');
});
// Theme choice lasts for this page visit; no browser storage is needed.
const themeToggle = document.querySelector('.theme-toggle');
const systemTheme = window.matchMedia('(prefers-color-scheme: dark)');
function syncThemeButton() {
const dark = document.documentElement.dataset.theme
? document.documentElement.dataset.theme === 'dark' : systemTheme.matches;
themeToggle.setAttribute('aria-pressed', String(dark));
document.querySelector('meta[name="theme-color"]').content = dark ? '#171c1e' : '#eeeade';
}
themeToggle.hidden = false;
syncThemeButton();
themeToggle.addEventListener('click', () => {
document.documentElement.dataset.theme = themeToggle.getAttribute('aria-pressed') === 'true' ? 'light' : 'dark';
syncThemeButton();
});
systemTheme.addEventListener('change', syncThemeButton);
How it works
The project uses index.html for the page structure, style.css for the skeuomorphic effects and responsive layout, and script.js for the countdown and form validation. Collecting subscriptions requires connecting the form to a newsletter 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