Banking — Wealth / Investing Landing
A refined marketing landing page for a fictional wealth and investing platform, built in vanilla HTML, CSS, and JavaScript. It pairs a calm charcoal-and-emerald palette with serif display type, an animated SVG portfolio chart, an allocation breakdown, a switchable performance band, transparent pricing tiers, verifiable trust credentials, testimonials, and an email capture call to action — all responsive down to small phones with reveal-on-scroll and toast micro-interactions.
MCP
Code
:root {
--charcoal: #14181f;
--charcoal-2: #1c222c;
--charcoal-3: #262e3a;
--emerald: #0fb5a6;
--emerald-d: #0a8f83;
--emerald-50: #e7f7f5;
--gold: #c2a878;
--bone: #fbf9f4;
--bone-2: #f3efe6;
--ink: #14181f;
--ink-2: #3f4856;
--muted: #6b7686;
--surface: #ffffff;
--line: rgba(20, 24, 31, 0.10);
--line-2: rgba(20, 24, 31, 0.18);
--ok: #1f9d62;
--up: #0fb5a6;
--down: #d4493e;
--r-sm: 8px;
--r-md: 14px;
--r-lg: 20px;
--r-xl: 28px;
--shadow-sm: 0 1px 2px rgba(20, 24, 31, 0.06), 0 1px 3px rgba(20, 24, 31, 0.05);
--shadow-md: 0 8px 24px -8px rgba(20, 24, 31, 0.18), 0 2px 8px rgba(20, 24, 31, 0.06);
--shadow-lg: 0 28px 60px -24px rgba(20, 24, 31, 0.32);
--serif: "Fraunces", Georgia, "Times New Roman", serif;
--sans: "Inter", system-ui, -apple-system, sans-serif;
}
* { box-sizing: border-box; }
html { scroll-behavior: smooth; }
body {
margin: 0;
font-family: var(--sans);
color: var(--ink);
background: var(--bone);
line-height: 1.5;
-webkit-font-smoothing: antialiased;
-moz-osx-font-smoothing: grayscale;
font-variant-numeric: tabular-nums;
}
h1, h2, h3, h4 { margin: 0; line-height: 1.12; letter-spacing: -0.01em; }
p { margin: 0; }
a { color: inherit; text-decoration: none; }
img, svg { display: block; }
.wrap { width: min(1160px, 92vw); margin-inline: auto; }
.serif { font-family: var(--serif); font-weight: 500; letter-spacing: -0.015em; }
.light { color: var(--bone); }
.muted { color: var(--muted); }
.sr-only, .skip {
position: absolute; width: 1px; height: 1px; padding: 0; margin: -1px;
overflow: hidden; clip: rect(0 0 0 0); white-space: nowrap; border: 0;
}
.skip:focus {
position: fixed; top: 12px; left: 12px; width: auto; height: auto;
clip: auto; margin: 0; padding: 10px 16px; background: var(--charcoal);
color: var(--bone); border-radius: var(--r-sm); z-index: 100;
}
/* Buttons */
.btn {
display: inline-flex; align-items: center; justify-content: center; gap: 8px;
font-family: var(--sans); font-weight: 600; font-size: 0.95rem;
padding: 11px 20px; border-radius: 999px; border: 1px solid transparent;
cursor: pointer; transition: transform 0.15s ease, background 0.2s ease, box-shadow 0.2s ease, border-color 0.2s ease;
white-space: nowrap;
}
.btn:active { transform: translateY(1px) scale(0.99); }
.btn.lg { padding: 14px 26px; font-size: 1rem; }
.btn.full { width: 100%; }
.btn-solid { background: var(--emerald); color: #042d29; box-shadow: 0 6px 18px -8px rgba(15, 181, 166, 0.7); }
.btn-solid:hover { background: var(--emerald-d); color: var(--bone); box-shadow: 0 10px 24px -8px rgba(15, 181, 166, 0.8); }
.btn-ghost { background: transparent; color: var(--ink); border-color: var(--line-2); }
.btn-ghost:hover { background: var(--bone-2); border-color: var(--ink-2); }
.eyebrow {
display: inline-flex; align-items: center; gap: 8px;
font-size: 0.8rem; font-weight: 600; letter-spacing: 0.02em;
color: var(--emerald-d); background: var(--emerald-50);
padding: 6px 14px; border-radius: 999px; margin-bottom: 22px;
}
.eyebrow .dot { width: 7px; height: 7px; border-radius: 50%; background: var(--emerald); box-shadow: 0 0 0 4px rgba(15,181,166,0.18); }
.kicker { display: block; font-size: 0.78rem; font-weight: 700; letter-spacing: 0.14em; text-transform: uppercase; color: var(--emerald-d); margin-bottom: 14px; }
.kicker.light { color: var(--emerald); }
/* NAV */
.nav {
position: sticky; top: 0; z-index: 40;
background: rgba(251, 249, 244, 0.82);
backdrop-filter: saturate(140%) blur(14px);
border-bottom: 1px solid var(--line);
}
.nav-inner { display: flex; align-items: center; gap: 24px; height: 70px; }
.brand { display: inline-flex; align-items: center; gap: 9px; font-weight: 700; font-size: 1.18rem; letter-spacing: -0.01em; }
.brand-mark { color: var(--emerald); font-size: 1rem; }
.brand-name { font-family: var(--serif); font-weight: 600; }
.nav-links { display: flex; gap: 28px; margin-left: 14px; }
.nav-links a { font-size: 0.94rem; font-weight: 500; color: var(--ink-2); transition: color 0.2s; }
.nav-links a:hover { color: var(--ink); }
.nav-cta { display: flex; gap: 10px; margin-left: auto; }
.nav-toggle { display: none; margin-left: auto; flex-direction: column; gap: 5px; background: none; border: 0; padding: 8px; cursor: pointer; }
.nav-toggle span { width: 22px; height: 2px; background: var(--ink); border-radius: 2px; transition: transform 0.25s, opacity 0.2s; }
.nav-toggle[aria-expanded="true"] span:nth-child(1) { transform: translateY(7px) rotate(45deg); }
.nav-toggle[aria-expanded="true"] span:nth-child(2) { opacity: 0; }
.nav-toggle[aria-expanded="true"] span:nth-child(3) { transform: translateY(-7px) rotate(-45deg); }
.mobile-menu { display: flex; flex-direction: column; gap: 4px; padding: 12px 4vw 22px; border-bottom: 1px solid var(--line); background: var(--bone); }
.mobile-menu a { padding: 12px 6px; font-weight: 500; color: var(--ink-2); border-bottom: 1px solid var(--line); }
.mobile-menu a.btn { margin-top: 12px; border-bottom: 0; color: #042d29; }
/* HERO */
.hero { padding: 64px 0 40px; background:
radial-gradient(900px 420px at 88% -8%, rgba(15,181,166,0.10), transparent 60%),
radial-gradient(700px 380px at 6% 10%, rgba(194,168,120,0.10), transparent 60%);
}
.hero-grid { display: grid; grid-template-columns: 1.04fr 0.96fr; gap: 56px; align-items: center; }
.display { font-family: var(--serif); font-weight: 500; font-size: clamp(2.4rem, 5vw, 3.7rem); letter-spacing: -0.02em; }
.display em { font-style: italic; color: var(--emerald-d); }
.lede { margin-top: 22px; font-size: 1.12rem; color: var(--ink-2); max-width: 30em; }
.hero-actions { display: flex; gap: 12px; margin-top: 30px; flex-wrap: wrap; }
.hero-trust { list-style: none; margin: 30px 0 0; padding: 0; display: grid; gap: 10px; }
.hero-trust li { display: flex; align-items: center; gap: 9px; font-size: 0.9rem; color: var(--ink-2); }
.hero-trust .lock, .hero-trust .check { font-size: 0.85rem; }
/* Portfolio card */
.hero-card { perspective: 1000px; }
.pcard {
background: var(--surface); border: 1px solid var(--line);
border-radius: var(--r-xl); padding: 24px; box-shadow: var(--shadow-lg);
}
.pcard-head { display: flex; justify-content: space-between; align-items: flex-start; margin-bottom: 18px; }
.pcard-label { font-size: 0.82rem; color: var(--muted); font-weight: 500; }
.pcard-value { font-size: 2.1rem; font-weight: 800; letter-spacing: -0.02em; margin-top: 4px; }
.pcard-value .cents { font-size: 1.2rem; color: var(--muted); font-weight: 600; }
.pcard-delta { margin-top: 6px; font-size: 0.9rem; font-weight: 600; }
.pcard-delta.up { color: var(--up); }
.pill { font-size: 0.72rem; font-weight: 700; padding: 5px 11px; border-radius: 999px; letter-spacing: 0.02em; }
.pill-ok { color: var(--emerald-d); background: var(--emerald-50); }
.chart { position: relative; height: 200px; margin: 6px -4px 8px; }
.chart svg { width: 100%; height: 100%; }
#gridLines line { stroke: var(--line); stroke-width: 1; stroke-dasharray: 3 5; }
.chart-tip {
position: absolute; transform: translate(-50%, -130%); pointer-events: none;
background: var(--charcoal); color: var(--bone); font-size: 0.78rem; font-weight: 600;
padding: 6px 10px; border-radius: var(--r-sm); white-space: nowrap; box-shadow: var(--shadow-md);
}
.chart-tip::after { content: ""; position: absolute; left: 50%; bottom: -5px; transform: translateX(-50%); border: 5px solid transparent; border-top-color: var(--charcoal); border-bottom: 0; }
.pcard-foot { border-top: 1px solid var(--line); padding-top: 16px; }
.alloc-label { font-size: 0.78rem; color: var(--muted); font-weight: 600; }
.bars { display: flex; height: 10px; border-radius: 999px; overflow: hidden; margin: 9px 0 12px; background: var(--bone-2); }
.bseg { width: var(--w); background: var(--c); transition: filter 0.2s; }
.bseg:hover { filter: brightness(1.1); }
.legend { display: grid; grid-template-columns: 1fr 1fr; gap: 7px 14px; font-size: 0.8rem; color: var(--ink-2); }
.legend span { display: inline-flex; align-items: center; gap: 7px; }
.legend i { width: 9px; height: 9px; border-radius: 3px; }
/* Logos */
.logos { display: flex; align-items: center; gap: 28px; margin-top: 56px; flex-wrap: wrap; }
.logos > span { font-size: 0.76rem; letter-spacing: 0.1em; text-transform: uppercase; color: var(--muted); font-weight: 600; }
.logo-row { display: flex; gap: 34px; flex-wrap: wrap; }
.logo { font-family: var(--serif); font-weight: 600; font-size: 1.05rem; color: var(--ink-2); opacity: 0.62; letter-spacing: 0.02em; transition: opacity 0.2s; }
.logo:hover { opacity: 1; }
/* Sections */
.section { padding: 90px 0; }
.sec-head { max-width: 40em; margin-bottom: 48px; }
.sec-head h2 { font-size: clamp(1.8rem, 3.4vw, 2.5rem); }
.sec-sub { margin-top: 16px; font-size: 1.08rem; color: var(--ink-2); }
/* Features */
.feature-grid { display: grid; grid-template-columns: repeat(3, 1fr); gap: 24px; }
.feature {
background: var(--surface); border: 1px solid var(--line); border-radius: var(--r-lg);
padding: 30px; box-shadow: var(--shadow-sm); transition: transform 0.25s ease, box-shadow 0.25s ease, border-color 0.25s;
}
.feature:hover { transform: translateY(-4px); box-shadow: var(--shadow-md); border-color: var(--line-2); }
.ficon { width: 50px; height: 50px; display: grid; place-items: center; border-radius: 14px; background: var(--charcoal); color: var(--emerald); font-size: 1.3rem; margin-bottom: 20px; }
.feature h3 { font-family: var(--serif); font-weight: 600; font-size: 1.32rem; margin-bottom: 10px; }
.feature p { color: var(--ink-2); font-size: 0.96rem; }
.flist { list-style: none; padding: 18px 0 0; margin: 0; display: grid; gap: 9px; }
.flist li { position: relative; padding-left: 24px; font-size: 0.9rem; color: var(--ink-2); }
.flist li::before { content: "✓"; position: absolute; left: 0; color: var(--emerald-d); font-weight: 700; }
/* Performance band */
.perf { background: var(--charcoal); color: var(--bone); padding: 84px 0; position: relative; overflow: hidden; }
.perf::before { content: ""; position: absolute; inset: 0; background: radial-gradient(700px 360px at 90% 0%, rgba(15,181,166,0.16), transparent 60%); pointer-events: none; }
.perf-grid { display: grid; grid-template-columns: 1.1fr 1fr; gap: 56px; align-items: center; position: relative; }
.perf-copy h2 { font-size: clamp(1.9rem, 3.6vw, 2.6rem); max-width: 12em; }
.perf-sub { margin-top: 16px; color: rgba(251,249,244,0.72); font-size: 1.02rem; max-width: 32em; }
.range { display: inline-flex; gap: 4px; margin-top: 26px; background: rgba(255,255,255,0.06); padding: 5px; border-radius: 999px; border: 1px solid rgba(255,255,255,0.10); }
.range-btn { background: none; border: 0; color: rgba(251,249,244,0.7); font-family: var(--sans); font-weight: 600; font-size: 0.9rem; padding: 8px 18px; border-radius: 999px; cursor: pointer; transition: background 0.2s, color 0.2s; }
.range-btn.active { background: var(--emerald); color: #042d29; }
.range-btn:hover:not(.active) { color: var(--bone); }
.perf-stats { display: grid; grid-template-columns: 1fr 1fr; gap: 1px; background: rgba(255,255,255,0.10); border-radius: var(--r-lg); overflow: hidden; border: 1px solid rgba(255,255,255,0.10); }
.stat { background: var(--charcoal-2); padding: 26px 24px; }
.stat-label { display: block; font-size: 0.82rem; color: rgba(251,249,244,0.62); margin-bottom: 10px; font-weight: 500; }
.stat-num { font-size: 1.85rem; font-weight: 800; letter-spacing: -0.02em; }
.stat-num.up { color: var(--emerald); }
/* Pricing */
.price-grid { display: grid; grid-template-columns: repeat(3, 1fr); gap: 22px; align-items: stretch; }
.plan {
position: relative; background: var(--surface); border: 1px solid var(--line);
border-radius: var(--r-lg); padding: 32px 28px; display: flex; flex-direction: column;
box-shadow: var(--shadow-sm); transition: transform 0.25s, box-shadow 0.25s;
}
.plan:hover { transform: translateY(-3px); box-shadow: var(--shadow-md); }
.plan.featured { background: var(--charcoal); color: var(--bone); border-color: var(--charcoal); box-shadow: var(--shadow-lg); }
.plan.featured .plan-min, .plan.featured .plan-list li { color: rgba(251,249,244,0.78); }
.plan-badge { position: absolute; top: -13px; left: 50%; transform: translateX(-50%); background: var(--emerald); color: #042d29; font-size: 0.74rem; font-weight: 700; padding: 5px 14px; border-radius: 999px; letter-spacing: 0.02em; }
.plan-name { font-family: var(--serif); font-weight: 600; font-size: 1.35rem; }
.plan-fee { display: flex; align-items: baseline; gap: 8px; margin: 16px 0 4px; }
.pct { font-size: 2.4rem; font-weight: 800; letter-spacing: -0.03em; }
.pct small { font-size: 1.2rem; font-weight: 700; }
.per { font-size: 0.95rem; color: var(--muted); }
.plan.featured .per { color: rgba(251,249,244,0.6); }
.plan-min { font-size: 0.88rem; color: var(--muted); margin-bottom: 22px; }
.plan-list { list-style: none; padding: 0; margin: 0 0 26px; display: grid; gap: 12px; flex: 1; }
.plan-list li { display: flex; gap: 10px; font-size: 0.92rem; color: var(--ink-2); }
.plan-list li span { color: var(--emerald-d); font-weight: 700; }
.plan.featured .plan-list li span { color: var(--emerald); }
.plan-list li.muted span { color: var(--muted); }
/* Trust */
.trust { background: var(--bone-2); }
.trust-grid { display: grid; grid-template-columns: repeat(4, 1fr); gap: 18px; margin-bottom: 36px; }
.tcard { background: var(--surface); border: 1px solid var(--line); border-radius: var(--r-md); padding: 28px 22px; text-align: center; box-shadow: var(--shadow-sm); }
.tnum { display: block; font-family: var(--serif); font-weight: 600; font-size: 1.9rem; color: var(--ink); letter-spacing: -0.01em; }
.tlabel { display: block; margin-top: 8px; font-size: 0.85rem; color: var(--muted); }
.badges { display: flex; gap: 12px; flex-wrap: wrap; }
.badge { display: inline-flex; align-items: center; gap: 8px; background: var(--surface); border: 1px solid var(--line); border-radius: 999px; padding: 9px 16px; font-size: 0.86rem; font-weight: 500; color: var(--ink-2); }
/* Testimonials */
.testi-grid { display: grid; grid-template-columns: repeat(3, 1fr); gap: 22px; }
.quote { margin: 0; background: var(--surface); border: 1px solid var(--line); border-radius: var(--r-lg); padding: 30px; box-shadow: var(--shadow-sm); transition: transform 0.25s, box-shadow 0.25s; }
.quote:hover { transform: translateY(-3px); box-shadow: var(--shadow-md); }
.quote blockquote { margin: 0 0 22px; font-family: var(--serif); font-size: 1.12rem; font-weight: 400; line-height: 1.5; color: var(--ink); }
.quote figcaption { display: flex; align-items: center; gap: 12px; font-size: 0.9rem; }
.avatar { width: 42px; height: 42px; border-radius: 50%; display: grid; place-items: center; background: var(--charcoal); color: var(--emerald); font-weight: 700; font-size: 0.85rem; flex: none; }
/* CTA */
.cta { background: linear-gradient(160deg, var(--charcoal) 0%, var(--charcoal-3) 100%); color: var(--bone); padding: 84px 0; position: relative; overflow: hidden; }
.cta::before { content: ""; position: absolute; inset: 0; background: radial-gradient(600px 320px at 50% -20%, rgba(15,181,166,0.20), transparent 65%); }
.cta-inner { position: relative; text-align: center; max-width: 38em; margin-inline: auto; }
.cta-inner h2 { font-size: clamp(1.9rem, 4vw, 2.7rem); }
.cta-sub { margin-top: 16px; color: rgba(251,249,244,0.74); font-size: 1.08rem; }
.cta-form { display: flex; gap: 10px; margin: 30px auto 0; max-width: 460px; }
.cta-form input { flex: 1; padding: 14px 18px; border-radius: 999px; border: 1px solid rgba(255,255,255,0.18); background: rgba(255,255,255,0.06); color: var(--bone); font-family: var(--sans); font-size: 1rem; }
.cta-form input::placeholder { color: rgba(251,249,244,0.5); }
.cta-form input:focus { outline: 2px solid var(--emerald); outline-offset: 1px; background: rgba(255,255,255,0.10); }
.cta-form input.invalid { border-color: var(--down); outline-color: var(--down); }
.cta-fine { margin-top: 18px; font-size: 0.85rem; color: rgba(251,249,244,0.6); }
/* Footer */
.footer { background: var(--charcoal); color: var(--bone); padding: 64px 0 28px; }
.foot-grid { display: grid; grid-template-columns: 1.6fr 1fr 1fr 1fr; gap: 36px; padding-bottom: 40px; border-bottom: 1px solid rgba(255,255,255,0.10); }
.foot-brand .brand { font-size: 1.2rem; }
.foot-brand p { margin-top: 14px; color: rgba(251,249,244,0.6); font-size: 0.88rem; max-width: 30em; }
.footer h4 { font-size: 0.82rem; letter-spacing: 0.1em; text-transform: uppercase; color: rgba(251,249,244,0.5); margin-bottom: 16px; }
.footer nav a { display: block; padding: 5px 0; color: rgba(251,249,244,0.78); font-size: 0.92rem; transition: color 0.2s; }
.footer nav a:hover { color: var(--emerald); }
.foot-base { display: flex; justify-content: space-between; align-items: center; gap: 16px; padding-top: 24px; font-size: 0.82rem; color: rgba(251,249,244,0.55); flex-wrap: wrap; }
/* Toast */
.toast {
position: fixed; left: 50%; bottom: 28px; transform: translate(-50%, 140%);
background: var(--charcoal); color: var(--bone); padding: 14px 22px; border-radius: var(--r-md);
box-shadow: var(--shadow-lg); font-weight: 600; font-size: 0.92rem; z-index: 80;
border: 1px solid rgba(15,181,166,0.4); transition: transform 0.35s cubic-bezier(.2,.9,.3,1.2); max-width: 90vw;
}
.toast.show { transform: translate(-50%, 0); }
/* Reveal */
.reveal { opacity: 0; transform: translateY(18px); transition: opacity 0.6s ease, transform 0.6s ease; }
.reveal.in { opacity: 1; transform: none; }
/* Responsive */
@media (max-width: 940px) {
.hero-grid, .perf-grid { grid-template-columns: 1fr; gap: 40px; }
.feature-grid, .price-grid, .testi-grid { grid-template-columns: 1fr; }
.trust-grid { grid-template-columns: 1fr 1fr; }
.foot-grid { grid-template-columns: 1fr 1fr; }
.nav-links, .nav-cta { display: none; }
.nav-toggle { display: flex; }
}
@media (max-width: 520px) {
.hero { padding: 40px 0 28px; }
.section { padding: 60px 0; }
.perf, .cta, .footer { padding: 56px 0; }
.pcard { padding: 18px; }
.pcard-value { font-size: 1.7rem; }
.perf-stats { grid-template-columns: 1fr; }
.trust-grid, .foot-grid { grid-template-columns: 1fr; }
.legend { grid-template-columns: 1fr; }
.cta-form { flex-direction: column; }
.cta-form .btn { width: 100%; }
.badges { gap: 8px; }
.badge { font-size: 0.8rem; padding: 8px 13px; }
.foot-base { flex-direction: column; align-items: flex-start; }
}
@media (prefers-reduced-motion: reduce) {
* { animation: none !important; transition: none !important; }
.reveal { opacity: 1; transform: none; }
html { scroll-behavior: auto; }
}(function () {
"use strict";
/* ---------- Toast helper ---------- */
var toastEl = document.getElementById("toast");
var toastTimer = null;
function toast(msg) {
if (!toastEl) return;
toastEl.textContent = msg;
toastEl.classList.add("show");
clearTimeout(toastTimer);
toastTimer = setTimeout(function () {
toastEl.classList.remove("show");
}, 2600);
}
/* ---------- Mobile nav ---------- */
var navToggle = document.getElementById("navToggle");
var mobileMenu = document.getElementById("mobileMenu");
if (navToggle && mobileMenu) {
navToggle.addEventListener("click", function () {
var open = navToggle.getAttribute("aria-expanded") === "true";
navToggle.setAttribute("aria-expanded", String(!open));
navToggle.setAttribute("aria-label", open ? "Open menu" : "Close menu");
mobileMenu.hidden = open;
});
mobileMenu.addEventListener("click", function (e) {
if (e.target.tagName === "A") {
navToggle.setAttribute("aria-expanded", "false");
navToggle.setAttribute("aria-label", "Open menu");
mobileMenu.hidden = true;
}
});
}
/* ---------- Reveal on scroll ---------- */
var reveals = Array.prototype.slice.call(document.querySelectorAll(".reveal"));
if ("IntersectionObserver" in window) {
var io = new IntersectionObserver(
function (entries) {
entries.forEach(function (en) {
if (en.isIntersecting) {
en.target.classList.add("in");
io.unobserve(en.target);
}
});
},
{ threshold: 0.12, rootMargin: "0px 0px -40px 0px" }
);
reveals.forEach(function (el) { io.observe(el); });
} else {
reveals.forEach(function (el) { el.classList.add("in"); });
}
/* ---------- Portfolio chart ---------- */
var W = 560, H = 220, PAD = 14;
var linePath = document.getElementById("linePath");
var areaPath = document.getElementById("areaPath");
var dot = document.getElementById("dot");
var grid = document.getElementById("gridLines");
var tip = document.getElementById("chartTip");
var svg = document.getElementById("heroChart");
// Seeded pseudo-random walk -> deterministic, realistic monthly values
function buildSeries(months, start, drift, vol, seed) {
var v = start, out = [], s = seed;
for (var i = 0; i < months; i++) {
s = (s * 9301 + 49297) % 233280;
var rnd = s / 233280 - 0.5;
v = v * (1 + drift + rnd * vol);
out.push(v);
}
return out;
}
var series = buildSeries(12, 1050000, 0.018, 0.05, 7);
// force the last point to be the displayed value
series[series.length - 1] = 1284930.42;
var labels = ["Jul","Aug","Sep","Oct","Nov","Dec","Jan","Feb","Mar","Apr","May","Jun"];
function buildGrid() {
if (!grid) return;
grid.innerHTML = "";
for (var i = 1; i <= 3; i++) {
var y = (H / 4) * i;
var ln = document.createElementNS("http://www.w3.org/2000/svg", "line");
ln.setAttribute("x1", "0"); ln.setAttribute("x2", String(W));
ln.setAttribute("y1", String(y)); ln.setAttribute("y2", String(y));
grid.appendChild(ln);
}
}
var points = [];
function computePoints(data) {
var min = Math.min.apply(null, data);
var max = Math.max.apply(null, data);
var range = max - min || 1;
points = data.map(function (val, i) {
var x = PAD + (i / (data.length - 1)) * (W - PAD * 2);
var y = PAD + (1 - (val - min) / range) * (H - PAD * 2);
return { x: x, y: y, val: val, label: labels[i] };
});
}
function lineD(pts) {
return pts.map(function (p, i) {
return (i === 0 ? "M" : "L") + p.x.toFixed(1) + " " + p.y.toFixed(1);
}).join(" ");
}
function drawChart(animate) {
buildGrid();
computePoints(series);
var d = lineD(points);
linePath.setAttribute("d", d);
areaPath.setAttribute("d", d + " L" + points[points.length - 1].x.toFixed(1) + " " + H + " L" + points[0].x.toFixed(1) + " " + H + " Z");
var last = points[points.length - 1];
dot.setAttribute("cx", last.x); dot.setAttribute("cy", last.y);
if (animate) {
var len = linePath.getTotalLength();
linePath.style.transition = "none";
linePath.style.strokeDasharray = len;
linePath.style.strokeDashoffset = len;
areaPath.style.opacity = "0";
// force reflow
linePath.getBoundingClientRect();
linePath.style.transition = "stroke-dashoffset 1.5s ease";
areaPath.style.transition = "opacity 1.1s ease 0.4s";
linePath.style.strokeDashoffset = "0";
areaPath.style.opacity = "1";
}
}
// Tooltip / hover on chart
if (svg && tip) {
svg.addEventListener("mousemove", function (e) {
var rect = svg.getBoundingClientRect();
var px = ((e.clientX - rect.left) / rect.width) * W;
var nearest = points[0], best = Infinity;
points.forEach(function (p) {
var dx = Math.abs(p.x - px);
if (dx < best) { best = dx; nearest = p; }
});
dot.setAttribute("cx", nearest.x);
dot.setAttribute("cy", nearest.y);
tip.hidden = false;
tip.style.left = (nearest.x / W) * rect.width + "px";
tip.style.top = (nearest.y / H) * rect.height + "px";
tip.textContent = nearest.label + " · $" + Math.round(nearest.val).toLocaleString("en-US");
});
svg.addEventListener("mouseleave", function () {
tip.hidden = true;
drawChart(false);
});
}
drawChart(true);
/* ---------- Hero value count-up ---------- */
var heroValue = document.getElementById("heroValue");
function animateValue() {
if (!heroValue) return;
var target = 1284930.42;
var start = performance.now();
var dur = 1400;
function frame(now) {
var t = Math.min((now - start) / dur, 1);
var eased = 1 - Math.pow(1 - t, 3);
var cur = target * eased;
var whole = Math.floor(cur);
var cents = Math.round((cur - whole) * 100);
heroValue.innerHTML = "$" + whole.toLocaleString("en-US") +
'<span class="cents">.' + String(cents).padStart(2, "0") + "</span>";
if (t < 1) requestAnimationFrame(frame);
}
requestAnimationFrame(frame);
}
if (window.matchMedia && window.matchMedia("(prefers-reduced-motion: reduce)").matches) {
// leave static markup
} else {
animateValue();
}
/* ---------- Performance range toggle ---------- */
var rangeData = {
"1Y": { ret: "+11.2%", growth: "$111,200" },
"5Y": { ret: "+9.4%", growth: "$156,720" },
"10Y": { ret: "+8.7%", growth: "$230,180" }
};
var statReturn = document.getElementById("statReturn");
var statGrowth = document.getElementById("statGrowth");
var rangeBtns = document.querySelectorAll(".range-btn");
rangeBtns.forEach(function (btn) {
btn.addEventListener("click", function () {
rangeBtns.forEach(function (b) { b.classList.remove("active"); b.removeAttribute("aria-selected"); });
btn.classList.add("active");
btn.setAttribute("aria-selected", "true");
var d = rangeData[btn.dataset.range];
if (d && statReturn && statGrowth) {
statReturn.textContent = d.ret;
statGrowth.textContent = d.growth;
}
});
});
/* ---------- CTA form ---------- */
var form = document.getElementById("ctaForm");
if (form) {
form.addEventListener("submit", function (e) {
e.preventDefault();
var input = document.getElementById("ctaEmail");
var val = (input.value || "").trim();
var valid = /^[^\s@]+@[^\s@]+\.[^\s@]+$/.test(val);
if (!valid) {
input.classList.add("invalid");
input.focus();
toast("Please enter a valid email address.");
return;
}
input.classList.remove("invalid");
input.value = "";
toast("Thanks — your invite to Meridian is on its way.");
});
document.getElementById("ctaEmail").addEventListener("input", function () {
this.classList.remove("invalid");
});
}
/* ---------- CTA on solid/ghost demo buttons ---------- */
document.querySelectorAll('a[href="#cta"]').forEach(function (a) {
if (a.closest(".cta-form") || a.closest(".mobile-menu")) return;
a.addEventListener("click", function () {
var label = a.textContent.trim();
if (/open account|get started|sign in/i.test(label)) {
setTimeout(function () { toast("Demo only — account opening is not available."); }, 350);
}
});
});
document.querySelectorAll(".plan .btn").forEach(function (b) {
b.addEventListener("click", function (e) {
var plan = b.closest(".plan").querySelector(".plan-name").textContent;
toast("Selected the " + plan + " plan (demo).");
});
});
})();<!doctype html>
<html lang="en">
<head>
<meta charset="utf-8" />
<meta name="viewport" content="width=device-width, initial-scale=1" />
<title>Meridian — Private Wealth & Investing</title>
<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=Inter:wght@400;500;600;700;800&family=Fraunces:opsz,wght@9..144,400;9..144,500;9..144,600&display=swap" rel="stylesheet" />
<link rel="stylesheet" href="style.css" />
</head>
<body>
<a class="skip" href="#main">Skip to content</a>
<header class="nav" id="top">
<div class="wrap nav-inner">
<a class="brand" href="#top" aria-label="Meridian home">
<span class="brand-mark" aria-hidden="true">◆</span>
<span class="brand-name">Meridian</span>
</a>
<nav class="nav-links" aria-label="Primary">
<a href="#features">Approach</a>
<a href="#performance">Performance</a>
<a href="#pricing">Fees</a>
<a href="#trust">Why Meridian</a>
</nav>
<div class="nav-cta">
<a href="#cta" class="btn btn-ghost">Sign in</a>
<a href="#cta" class="btn btn-solid">Open account</a>
</div>
<button class="nav-toggle" id="navToggle" aria-expanded="false" aria-controls="mobileMenu" aria-label="Open menu">
<span></span><span></span><span></span>
</button>
</div>
<div class="mobile-menu" id="mobileMenu" hidden>
<a href="#features">Approach</a>
<a href="#performance">Performance</a>
<a href="#pricing">Fees</a>
<a href="#trust">Why Meridian</a>
<a href="#cta" class="btn btn-solid full">Open account</a>
</div>
</header>
<main id="main">
<!-- HERO -->
<section class="hero">
<div class="wrap hero-grid">
<div class="hero-copy reveal">
<span class="eyebrow"><span class="dot" aria-hidden="true"></span> Private wealth, made effortless</span>
<h1 class="display">Grow your wealth with <em>quiet</em> confidence.</h1>
<p class="lede">A fully managed investing platform — human advisory, automated discipline, and tax-aware decisions working in the background, so your portfolio compounds while you live your life.</p>
<div class="hero-actions">
<a href="#cta" class="btn btn-solid lg">Start investing</a>
<a href="#performance" class="btn btn-ghost lg">View performance</a>
</div>
<ul class="hero-trust">
<li><span class="lock" aria-hidden="true">🔒</span> Assets held by Sterling Custody, FDIC & SIPC eligible</li>
<li><span class="check" aria-hidden="true">✓</span> $4.2B managed · 38,000+ households</li>
</ul>
</div>
<div class="hero-card reveal">
<div class="pcard">
<div class="pcard-head">
<div>
<span class="pcard-label">Total portfolio value</span>
<div class="pcard-value" id="heroValue">$1,284,930<span class="cents">.42</span></div>
<div class="pcard-delta up">▲ <span id="heroDelta">$18,420.55</span> · +1.46% today</div>
</div>
<span class="pill pill-ok">All-time high</span>
</div>
<div class="chart" aria-label="Portfolio value over the last 12 months">
<svg id="heroChart" viewBox="0 0 560 220" preserveAspectRatio="none" role="img">
<defs>
<linearGradient id="area" x1="0" y1="0" x2="0" y2="1">
<stop offset="0%" stop-color="#0fb5a6" stop-opacity="0.34" />
<stop offset="100%" stop-color="#0fb5a6" stop-opacity="0" />
</linearGradient>
</defs>
<g id="gridLines"></g>
<path id="areaPath" fill="url(#area)" d="" />
<path id="linePath" fill="none" stroke="#0fb5a6" stroke-width="2.5" stroke-linecap="round" stroke-linejoin="round" d="" />
<circle id="dot" r="5" fill="#0fb5a6" stroke="#fbf9f4" stroke-width="2.5" cx="0" cy="0" />
</svg>
<div class="chart-tip" id="chartTip" hidden></div>
</div>
<div class="pcard-foot">
<div class="alloc">
<span class="alloc-label">Allocation</span>
<div class="bars">
<span class="bseg" style="--w:52%;--c:#0fb5a6" title="Equities 52%"></span>
<span class="bseg" style="--w:26%;--c:#7c8aa5" title="Bonds 26%"></span>
<span class="bseg" style="--w:14%;--c:#c2a878" title="Real assets 14%"></span>
<span class="bseg" style="--w:8%;--c:#3f4856" title="Cash 8%"></span>
</div>
<div class="legend">
<span><i style="background:#0fb5a6"></i>Equities 52%</span>
<span><i style="background:#7c8aa5"></i>Bonds 26%</span>
<span><i style="background:#c2a878"></i>Real assets 14%</span>
<span><i style="background:#3f4856"></i>Cash 8%</span>
</div>
</div>
</div>
</div>
</div>
</div>
<div class="logos wrap reveal" aria-label="As featured in">
<span>As seen in</span>
<div class="logo-row">
<span class="logo">FINSCOPE</span>
<span class="logo">The Ledger</span>
<span class="logo">Capital&Co</span>
<span class="logo">NORTHWIRE</span>
<span class="logo">Mercato</span>
</div>
</div>
</section>
<!-- FEATURES -->
<section class="section" id="features">
<div class="wrap">
<div class="sec-head reveal">
<span class="kicker">The approach</span>
<h2 class="serif">Three disciplines, one calm portfolio.</h2>
<p class="sec-sub">Every dollar is managed by a dedicated advisor and reinforced by automation that never sleeps, never panics, and never chases a headline.</p>
</div>
<div class="feature-grid">
<article class="feature reveal">
<div class="ficon">👤</div>
<h3>Dedicated advisory</h3>
<p>A credentialed CFP® who knows your goals, builds your plan, and rebalances with intention. Reach them by message, call, or video — no call-center queues.</p>
<ul class=" flist">
<li>Personal financial plan</li>
<li>Unlimited advisor messaging</li>
<li>Quarterly review calls</li>
</ul>
</article>
<article class="feature reveal">
<div class="ficon">⟳</div>
<h3>Auto-invest & rebalance</h3>
<p>Schedule deposits and let Meridian buy globally diversified funds at the right weights. Drift is corrected automatically, dividends reinvested same-day.</p>
<ul class="flist">
<li>Smart recurring deposits</li>
<li>Daily drift monitoring</li>
<li>Fractional, zero-commission</li>
</ul>
</article>
<article class="feature reveal">
<div class="ficon">◇</div>
<h3>Tax-loss harvesting</h3>
<p>We capture losses to offset gains and lower your tax bill, while keeping your market exposure intact. Realized savings are reported in plain language.</p>
<ul class="flist">
<li>Automated daily harvesting</li>
<li>Wash-sale protection</li>
<li>Year-end tax pack</li>
</ul>
</article>
</div>
</div>
</section>
<!-- PERFORMANCE BAND -->
<section class="perf" id="performance">
<div class="wrap perf-grid reveal">
<div class="perf-copy">
<span class="kicker light">Performance</span>
<h2 class="serif light">Built for the long arc, not the loud day.</h2>
<p class="perf-sub">Returns for the Meridian Balanced Growth strategy, net of fees. Past performance does not guarantee future results.</p>
<div class="range" role="tablist" aria-label="Performance range">
<button class="range-btn" role="tab" data-range="1Y">1Y</button>
<button class="range-btn active" role="tab" data-range="5Y" aria-selected="true">5Y</button>
<button class="range-btn" role="tab" data-range="10Y">10Y</button>
</div>
</div>
<div class="perf-stats">
<div class="stat">
<span class="stat-label">Annualized return</span>
<span class="stat-num up" id="statReturn">+9.4%</span>
</div>
<div class="stat">
<span class="stat-label">Growth of $100k</span>
<span class="stat-num" id="statGrowth">$156,720</span>
</div>
<div class="stat">
<span class="stat-label">Avg. fee drag saved</span>
<span class="stat-num up">+0.71%</span>
</div>
<div class="stat">
<span class="stat-label">Tax alpha (est.)</span>
<span class="stat-num up">+1.3%</span>
</div>
</div>
</div>
</section>
<!-- PRICING -->
<section class="section" id="pricing">
<div class="wrap">
<div class="sec-head reveal">
<span class="kicker">Fees, in full view</span>
<h2 class="serif">One transparent fee. Nothing hidden.</h2>
<p class="sec-sub">No trading commissions, no exit penalties, no surprise line items. The more you invest, the less you pay.</p>
</div>
<div class="price-grid">
<article class="plan reveal">
<h3 class="plan-name">Core</h3>
<div class="plan-fee"><span class="pct">0.25<small>%</small></span><span class="per">/ year</span></div>
<p class="plan-min">For balances up to $250k</p>
<ul class="plan-list">
<li><span aria-hidden="true">✓</span> Automated investing & rebalance</li>
<li><span aria-hidden="true">✓</span> Tax-loss harvesting</li>
<li><span aria-hidden="true">✓</span> Goal planning tools</li>
<li class="muted"><span aria-hidden="true">—</span> Dedicated advisor</li>
</ul>
<a href="#cta" class="btn btn-ghost full">Choose Core</a>
</article>
<article class="plan featured reveal">
<span class="plan-badge">Most popular</span>
<h3 class="plan-name">Premier</h3>
<div class="plan-fee"><span class="pct">0.40<small>%</small></span><span class="per">/ year</span></div>
<p class="plan-min">For balances $250k+</p>
<ul class="plan-list">
<li><span aria-hidden="true">✓</span> Everything in Core</li>
<li><span aria-hidden="true">✓</span> Dedicated CFP® advisor</li>
<li><span aria-hidden="true">✓</span> Estate & trust planning</li>
<li><span aria-hidden="true">✓</span> Private market access</li>
</ul>
<a href="#cta" class="btn btn-solid full">Choose Premier</a>
</article>
<article class="plan reveal">
<h3 class="plan-name">Family Office</h3>
<div class="plan-fee"><span class="pct">Custom</span></div>
<p class="plan-min">For balances $5M+</p>
<ul class="plan-list">
<li><span aria-hidden="true">✓</span> Everything in Premier</li>
<li><span aria-hidden="true">✓</span> Multi-generational planning</li>
<li><span aria-hidden="true">✓</span> Concierge tax & legal</li>
<li><span aria-hidden="true">✓</span> Bespoke direct indexing</li>
</ul>
<a href="#cta" class="btn btn-ghost full">Talk to us</a>
</article>
</div>
</div>
</section>
<!-- TRUST -->
<section class="section trust" id="trust">
<div class="wrap">
<div class="sec-head reveal">
<span class="kicker">Why Meridian</span>
<h2 class="serif">Credentials you can verify.</h2>
</div>
<div class="trust-grid reveal">
<div class="tcard">
<span class="tnum">$4.2B</span>
<span class="tlabel">Assets under management</span>
</div>
<div class="tcard">
<span class="tnum">SIPC</span>
<span class="tlabel">Protected up to $500k</span>
</div>
<div class="tcard">
<span class="tnum">256-bit</span>
<span class="tlabel">Bank-grade encryption</span>
</div>
<div class="tcard">
<span class="tnum">SOC 2</span>
<span class="tlabel">Type II audited</span>
</div>
</div>
<div class="badges reveal">
<span class="badge"><span aria-hidden="true">🔒</span> 2-factor secured</span>
<span class="badge"><span aria-hidden="true">✓</span> Fiduciary standard</span>
<span class="badge"><span aria-hidden="true">◆</span> Registered Investment Adviser</span>
<span class="badge"><span aria-hidden="true">⚖</span> No-conflict, fee-only</span>
</div>
</div>
</section>
<!-- TESTIMONIALS -->
<section class="section testi">
<div class="wrap">
<div class="sec-head reveal">
<span class="kicker">In their words</span>
<h2 class="serif">Trusted by people who value their time.</h2>
</div>
<div class="testi-grid">
<figure class="quote reveal">
<blockquote>"I moved three scattered accounts to Meridian and finally see one clear picture. The tax harvesting alone paid for the year."</blockquote>
<figcaption>
<span class="avatar" aria-hidden="true">ER</span>
<span><strong>Elena Ramos</strong><br /><span class="muted">Founder, Lumen Studio</span></span>
</figcaption>
</figure>
<figure class="quote reveal">
<blockquote>"My advisor actually knows my name and my goals. It feels like a private bank without the private-bank attitude."</blockquote>
<figcaption>
<span class="avatar" aria-hidden="true">DK</span>
<span><strong>David Koh</strong><br /><span class="muted">Surgeon</span></span>
</figcaption>
</figure>
<figure class="quote reveal">
<blockquote>"Calm, transparent, and quietly excellent. I check it once a month and sleep fine the other 29 days."</blockquote>
<figcaption>
<span class="avatar" aria-hidden="true">MA</span>
<span><strong>Mara Anand</strong><br /><span class="muted">Retired CFO</span></span>
</figcaption>
</figure>
</div>
</div>
</section>
<!-- CTA -->
<section class="cta" id="cta">
<div class="wrap cta-inner reveal">
<h2 class="serif light">Open an account in about 8 minutes.</h2>
<p class="cta-sub">No minimums to begin. Link a bank, set a goal, and your portfolio starts working the same day.</p>
<form class="cta-form" id="ctaForm" novalidate>
<label class="sr-only" for="ctaEmail">Email address</label>
<input id="ctaEmail" name="email" type="email" inputmode="email" autocomplete="email" placeholder="you@email.com" required />
<button type="submit" class="btn btn-solid lg">Get started</button>
</form>
<p class="cta-fine"><span aria-hidden="true">🔒</span> We never sell your data. Cancel anytime, no penalty.</p>
</div>
</section>
</main>
<footer class="footer">
<div class="wrap foot-grid">
<div class="foot-brand">
<span class="brand"><span class="brand-mark" aria-hidden="true">◆</span> <span class="brand-name">Meridian</span></span>
<p>Private wealth management for the long view. Member SIPC. Investing involves risk, including possible loss of principal.</p>
</div>
<nav aria-label="Product">
<h4>Product</h4>
<a href="#features">Advisory</a>
<a href="#features">Auto-invest</a>
<a href="#pricing">Fees</a>
<a href="#performance">Performance</a>
</nav>
<nav aria-label="Company">
<h4>Company</h4>
<a href="#trust">About</a>
<a href="#trust">Disclosures</a>
<a href="#cta">Careers</a>
<a href="#cta">Contact</a>
</nav>
<nav aria-label="Legal">
<h4>Legal</h4>
<a href="#trust">Form ADV</a>
<a href="#trust">Privacy</a>
<a href="#trust">Terms</a>
<a href="#trust">Security</a>
</nav>
</div>
<div class="wrap foot-base">
<span>© 2026 Meridian Wealth, Inc. · A fictional demo. Not real financial advice.</span>
<span class="foot-secure"><span aria-hidden="true">🔒</span> Bank-grade 256-bit encryption</span>
</div>
</footer>
<div class="toast" id="toast" role="status" aria-live="polite"></div>
<script src="script.js"></script>
</body>
</html>Wealth / Investing Landing
A full marketing landing for Meridian, a fictional private wealth and investing platform. The design leans premium and quiet: a charcoal base, emerald accents, bone backgrounds, and a Fraunces serif display paired with Inter for everything else. The hero centers on a glass-clean portfolio card showing total value, today’s change, an animated value count-up, and an SVG line chart with a gradient area fill that draws itself in on load and reveals per-month tooltips on hover. Beneath it sits an allocation bar with a labeled legend.
The page then walks through the product story: three feature cards (dedicated advisory, auto-invest and rebalance, tax-loss harvesting), a dark performance band with a 1Y/5Y/10Y toggle that updates the annualized return and growth figures, three transparent fee tiers with a highlighted “Premier” plan, a verifiable trust grid (AUM, SIPC, encryption, SOC 2) with security badges, customer testimonials, and an email-capture CTA.
Interactions are all vanilla JS: an IntersectionObserver reveal system, a sticky blurred nav with an accessible mobile menu, the self-drawing and hover-traced chart, the performance range tabs, inline email validation, and a small toast() helper for feedback. Money figures use tabular numerals and right-aligned formatting, and the whole layout reflows cleanly to a single column on phones while honoring prefers-reduced-motion.
Illustrative UI only — not real banking software or financial advice.