site/examples/landing.html
working modalvalidationlight<!DOCTYPE html>
<html lang="en" data-theme="light">
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<title>VERSEVA Design · Example: landing page</title>
<link rel="preconnect" href="https://fonts.googleapis.com">
<link rel="stylesheet" href="https://fonts.googleapis.com/css2?family=Archivo:wght@500..700&family=Manrope:wght@400..700&family=JetBrains+Mono:wght@400..600&display=swap">
<link rel="stylesheet" href="../../tokens.css?v=1p3">
<link rel="stylesheet" href="../../components.css?v=1p3">
<style>
* { margin: 0; box-sizing: border-box; }
body { background: var(--bg); color: var(--text-1); font-family: var(--font-sans); font-size: 15px; line-height: 1.65; }
.crumb { position: sticky; top: 0; z-index: 10; background: var(--bg); display: flex; align-items: center; gap: var(--s-3); padding: var(--s-3) var(--s-5); border-bottom: 1px solid var(--hairline); font-size: 12.5px; color: var(--text-3); }
.crumb a { color: var(--text-2); text-decoration: none; font-family: var(--font-display); font-weight: var(--display-weight); }
.page { max-width: var(--container-content); margin: 0 auto; padding: 0 var(--s-5) var(--s-8); }
.nav { display: flex; align-items: center; gap: var(--s-5); padding: var(--s-4) 0; }
.nav .mark { font-family: var(--font-display); font-weight: var(--display-weight); font-size: 16px; }
.nav nav { flex: 1; display: flex; gap: var(--s-4); }
.nav nav a { font-size: 13.5px; color: var(--text-2); text-decoration: none; }
@media (max-width: 599.98px) { .nav { flex-wrap: wrap; row-gap: var(--s-2); } .nav .mark { flex: 1; } .nav nav { order: 1; flex-basis: 100%; } }
.hero { padding: var(--s-9) 0 var(--s-7); max-width: 46rem; }
.hero h1 { font-family: var(--font-display); font-weight: var(--display-weight); font-size: clamp(38px, 6vw, 60px); letter-spacing: -0.025em; line-height: 1.05; }
.hero p { color: var(--text-2); font-size: 17px; max-width: 52ch; padding-top: var(--s-4); }
.hero .cta { display: flex; gap: var(--s-3); padding-top: var(--s-5); }
.proof { display: grid; grid-template-columns: repeat(auto-fit, minmax(220px, 1fr)); gap: var(--s-4); padding-top: var(--s-6); }
.proof .card .bd b { color: var(--text-1); font-weight: 600; }
.band { display: flex; gap: var(--s-6); flex-wrap: wrap; align-items: center; padding: var(--s-7) 0; }
.band .stat { flex: 1; min-width: 160px; }
footer { display: flex; justify-content: space-between; flex-wrap: wrap; gap: var(--s-3); padding-top: var(--s-7); color: var(--text-3); font-size: 12.5px; }
.badge-line { font-family: var(--font-display); font-weight: var(--display-weight); font-size: 13px; color: var(--text-2); }
.crumb a { display: inline-flex; align-items: center; gap: 8px; }
.crumb .vmark { width: 16px; height: 16px; flex: none; }
.crumb .codelink { margin-left: auto; }
</style>
</head>
<body>
<div class="crumb"><a href="../index.html"><svg class="vmark" viewBox="0 0 768 775.92" aria-hidden="true"><defs><clipPath id="vmk-a"><path d="M400 277h358v396.4H400z"/></clipPath><clipPath id="vmk-b"><path d="M10 97h550v576.4H10z"/></clipPath><clipPath id="vmk-c"><path d="M10 94.5h358V491H10z"/></clipPath><clipPath id="vmk-d"><path d="M208 94.5h550V671H208z"/></clipPath></defs><g clip-path="url(#vmk-a)"><path fill="currentColor" opacity=".55" d="M 558.605469 278.128906 C 555.410156 277.984375 552.164062 277.90625 548.96875 277.90625 C 466.261719 277.90625 407.433594 327.675781 401.222656 333.144531 L 400.800781 333.59375 C 400.800781 333.59375 587.386719 406.570312 718.046875 673.386719 C 718.046875 673.386719 767.757812 550.011719 756.207031 509.574219 C 740.042969 453 663.917969 362.328125 584.683594 279.359375 L 558.605469 278.128906"/></g><g clip-path="url(#vmk-b)"><path fill="currentColor" d="M 49.953125 673.386719 C 49.953125 673.386719 262.128906 253.59375 559.761719 253.59375 C 497.894531 190.457031 437.765625 134.679688 406.402344 106.136719 C 393.699219 94.574219 374.308594 94.574219 361.601562 106.136719 C 285.859375 175.0625 42.257812 402.917969 11.796875 509.574219 C 0.242188 550.011719 49.953125 673.386719 49.953125 673.386719"/></g><g clip-path="url(#vmk-c)"><path fill="currentColor" opacity=".55" d="M 209.394531 489.785156 C 212.589844 489.929688 215.835938 490.007812 219.03125 490.007812 C 301.738281 490.007812 360.566406 440.238281 366.777344 434.765625 L 367.199219 434.316406 C 367.199219 434.316406 180.613281 361.34375 49.953125 94.523438 C 49.953125 94.523438 0.242188 217.902344 11.792969 258.335938 C 27.957031 314.914062 104.082031 405.585938 183.316406 488.554688 L 209.394531 489.785156"/></g><g clip-path="url(#vmk-d)"><path fill="currentColor" d="M 718.046875 94.523438 C 718.046875 94.523438 505.871094 514.316406 208.238281 514.316406 C 270.105469 577.453125 330.234375 633.230469 361.597656 661.773438 C 374.300781 673.335938 393.691406 673.335938 406.398438 661.773438 C 482.140625 592.847656 725.742188 364.992188 756.203125 258.335938 C 767.757812 217.902344 718.046875 94.523438 718.046875 94.523438"/></g></svg><span>VERSEVA Design</span></a><span>examples</span><span>landing page</span><a class="btn btn-secondary sm codelink" href="../code.html?f=examples/landing.html">Code</a></div>
<div class="page">
<header class="nav">
<span class="mark">Ledgerline</span>
<nav><a href="#how">How it works</a><a href="#proof">Proof</a><a href="#pricing">Pricing</a></nav>
<button class="btn btn-ghost sm" type="button">Sign in</button>
<button class="btn btn-primary sm" type="button" data-open="signup">Start free</button>
</header>
<section class="hero">
<h1>Monthly close in five days</h1>
<p>Ledgerline reconciles every account, flags what a human must see, and files the rest. Built for restaurant groups tired of closing in week three.</p>
<div class="cta">
<button class="btn btn-primary lg" type="button" data-open="signup">Start free</button>
<button class="btn btn-secondary lg" type="button" id="watchbtn">Watch the close</button>
</div>
</section>
<section class="proof" id="proof">
<div class="card"><div class="hd"><h4>11 locations</h4></div><div class="bd"><b>Harbor Group</b> closed March in 4 days, 6 hours of bookkeeper time total.</div></div>
<div class="card"><div class="hd"><h4>98.4% auto-matched</h4></div><div class="bd"><b>Northline</b> reviews forty transactions a month. The rest file themselves.</div></div>
<div class="card"><div class="hd"><h4>Zero restatements</h4></div><div class="bd"><b>Crestpoint</b> has run eleven clean audits on Ledgerline books.</div></div>
</section>
<section class="band">
<div class="stat"><div class="num">5<i>days</i></div><div class="lbl">Median close</div></div>
<div class="stat"><div class="num">312</div><div class="lbl">Locations closing monthly</div></div>
<div class="stat"><div class="num">4.9</div><div class="lbl">Controller rating</div></div>
</section>
<footer>
<span>Ledgerline is a fictional product; this page is a VERSEVA Design example.</span>
<span class="badge-line">Built on VERSEVA Design</span>
</footer>
</div>
<div class="ovl" id="signup-ovl">
<div class="modal">
<div class="bd">
<h4>Start free</h4>
<p>Thirty days, every location, no card. The fictional onboarding takes four minutes.</p>
<div class="field" id="email-field">
<label for="email">Work email</label>
<input id="email" type="email" placeholder="you@restaurantgroup.com">
<div class="help" id="email-help">We only use this to create the workspace.</div>
</div>
</div>
<div class="ft">
<button class="btn btn-ghost" type="button" id="signup-cancel">Cancel</button>
<button class="btn btn-primary" type="button" id="signup-go">Create workspace</button>
</div>
</div>
</div>
<div id="toastwrap"></div>
<style>
.ovl { position: fixed; inset: 0; background: color-mix(in srgb, var(--text-1) 18%, transparent); display: none; align-items: center; justify-content: center; z-index: 9; padding: var(--s-5); }
.ovl.open { display: flex; }
#toastwrap .toast { position: fixed; right: var(--s-5); bottom: var(--s-5); z-index: 10; }
</style>
<script>
const ovl = document.getElementById('signup-ovl');
const emailField = document.getElementById('email-field');
const email = document.getElementById('email');
const help = document.getElementById('email-help');
document.querySelectorAll('[data-open="signup"]').forEach((b) => b.addEventListener('click', () => {
ovl.classList.add('open');
email.focus();
}));
const close = () => {
ovl.classList.remove('open');
emailField.classList.remove('error');
help.textContent = 'We only use this to create the workspace.';
email.value = '';
};
document.getElementById('signup-cancel').addEventListener('click', close);
ovl.addEventListener('click', (e) => { if (e.target === ovl) close(); });
document.getElementById('signup-go').addEventListener('click', () => {
if (!/^[^@\s]+@[^@\s]+\.[^@\s]+$/.test(email.value.trim())) {
emailField.classList.add('error');
help.textContent = 'Enter a work email first.';
email.focus();
return;
}
close();
const wrap = document.getElementById('toastwrap');
wrap.replaceChildren();
const toast = document.createElement('div');
toast.className = 'toast ok';
toast.innerHTML = '<span class="dot"></span>Workspace created. Check your inbox (fictionally).';
wrap.append(toast);
setTimeout(() => toast.remove(), 2600);
});
document.getElementById('watchbtn').addEventListener('click', () => {
document.getElementById('proof').scrollIntoView({ behavior: matchMedia('(prefers-reduced-motion: reduce)').matches ? 'auto' : 'smooth' });
});
</script>
</body>
</html>