SaaS — Fintech SaaS Landing
A trustworthy fintech SaaS landing page in navy, mint, and white with a precise Inter type system. It pairs a finance dashboard mockup built in pure SVG with fictional SOC 2, PCI, ISO, and GDPR compliance badges, payments and reporting feature tiles, and a navy stats band. Vanilla JS drives intersection-triggered animated counters, a live cross-border savings and fee calculator, and an email-validated book-a-demo form.
MCP
Code
:root {
--bg: #f4f7fa;
--surface: #ffffff;
--navy: #0a1f44;
--navy-2: #102a5c;
--ink: #0a1730;
--muted: #5a6781;
--mint: #2dd4a8;
--mint-d: #15b58c;
--mint-l: #5ce8c4;
--line: rgba(10, 31, 68, .1);
--line-2: rgba(10, 31, 68, .07);
--ok: #15a36a;
--danger: #dc2626;
--shadow: 0 18px 50px -20px rgba(10, 31, 68, .28);
--shadow-sm: 0 4px 14px -6px rgba(10, 31, 68, .2);
--radius: 16px;
--maxw: 1140px;
--font: "Inter", system-ui, -apple-system, "Segoe UI", Roboto, sans-serif;
}
* { box-sizing: border-box; }
html { scroll-behavior: smooth; }
body {
margin: 0;
font-family: var(--font);
background: var(--bg);
color: var(--ink);
line-height: 1.55;
-webkit-font-smoothing: antialiased;
-moz-osx-font-smoothing: grayscale;
}
h1, h2, h3 { line-height: 1.15; letter-spacing: -.02em; margin: 0; }
p { margin: 0; }
a { color: inherit; text-decoration: none; }
img, svg { display: block; max-width: 100%; }
.wrap { width: 100%; max-width: var(--maxw); margin: 0 auto; padding: 0 24px; }
.sr-only {
position: absolute; width: 1px; height: 1px; padding: 0; margin: -1px;
overflow: hidden; clip: rect(0 0 0 0); white-space: nowrap; border: 0;
}
.skip {
position: absolute; left: 12px; top: -60px; z-index: 50;
background: var(--navy); color: #fff; padding: 10px 16px; border-radius: 10px;
transition: top .2s;
}
.skip:focus { top: 12px; }
*:focus-visible {
outline: 2px solid var(--mint-d);
outline-offset: 2px;
border-radius: 6px;
}
/* ---------- buttons ---------- */
.btn {
display: inline-flex; align-items: center; justify-content: center; gap: 8px;
font: inherit; font-weight: 600; font-size: 15px;
padding: 11px 20px; border-radius: 11px; border: 1px solid transparent;
cursor: pointer; transition: transform .12s, box-shadow .2s, background .2s, color .2s;
white-space: nowrap;
}
.btn:active { transform: translateY(1px); }
.btn.lg { padding: 14px 26px; font-size: 16px; }
.btn.full { width: 100%; }
.btn.solid { background: var(--navy); color: #fff; box-shadow: var(--shadow-sm); }
.btn.solid:hover { background: var(--navy-2); box-shadow: 0 10px 24px -10px rgba(10,31,68,.5); }
.btn.mint { background: var(--mint); color: var(--navy); font-weight: 700; }
.btn.mint:hover { background: var(--mint-l); }
.btn.line { background: var(--surface); color: var(--navy); border-color: var(--line); }
.btn.line:hover { border-color: var(--mint-d); color: var(--mint-d); }
.btn.ghost { background: transparent; color: var(--ink); }
.btn.ghost:hover { color: var(--mint-d); }
/* ---------- nav ---------- */
.nav {
position: sticky; top: 0; z-index: 40;
background: rgba(244, 247, 250, .82);
backdrop-filter: saturate(160%) blur(12px);
border-bottom: 1px solid var(--line-2);
}
.nav-in { display: flex; align-items: center; gap: 24px; height: 68px; }
.brand {
display: inline-flex; align-items: center; gap: 10px;
font-weight: 800; font-size: 19px; letter-spacing: -.03em; color: var(--navy);
}
.brand-mark { display: inline-flex; }
.brand-mark.sm {
width: 26px; height: 26px; border-radius: 8px;
background: linear-gradient(135deg, var(--mint-l), var(--mint-d));
color: var(--navy); font-weight: 800; align-items: center; justify-content: center;
}
.nav-links { display: flex; gap: 26px; margin-left: 14px; }
.nav-links a { font-size: 15px; font-weight: 500; color: var(--muted); transition: color .15s; }
.nav-links a:hover { color: var(--navy); }
.nav-cta { display: flex; gap: 8px; margin-left: auto; }
.nav-toggle {
display: none; margin-left: auto; flex-direction: column; gap: 5px;
background: none; border: 0; cursor: pointer; padding: 8px;
}
.nav-toggle span { width: 22px; height: 2px; background: var(--navy); border-radius: 2px; transition: .2s; }
/* ---------- hero ---------- */
.hero {
position: relative; overflow: hidden;
background:
radial-gradient(1100px 460px at 78% -8%, rgba(45,212,168,.16), transparent 60%),
radial-gradient(900px 500px at -5% 20%, rgba(16,42,92,.06), transparent 55%);
padding-top: 56px;
}
.hero-in {
display: grid; grid-template-columns: 1.05fr .95fr; gap: 54px; align-items: center;
padding-bottom: 52px;
}
.pill {
display: inline-flex; align-items: center; gap: 8px;
background: var(--surface); border: 1px solid var(--line);
color: var(--navy); font-size: 13px; font-weight: 600;
padding: 6px 13px; border-radius: 999px; box-shadow: var(--shadow-sm);
}
.pill .dot { width: 8px; height: 8px; border-radius: 50%; background: var(--mint); box-shadow: 0 0 0 4px rgba(45,212,168,.22); }
.hero-copy h1 { font-size: clamp(34px, 5vw, 54px); font-weight: 800; margin: 20px 0 16px; color: var(--navy); }
.grad {
background: linear-gradient(105deg, var(--mint-d), var(--mint-l));
-webkit-background-clip: text; background-clip: text; color: transparent;
}
.lede { font-size: clamp(16px, 2vw, 18.5px); color: var(--muted); max-width: 38ch; }
.hero-actions { display: flex; flex-wrap: wrap; gap: 12px; margin: 28px 0 24px; }
.hero-trust {
list-style: none; margin: 0; padding: 0;
display: flex; flex-wrap: wrap; gap: 18px;
}
.hero-trust li {
display: inline-flex; align-items: center; gap: 7px;
font-size: 13.5px; font-weight: 600; color: var(--navy);
}
.hero-trust svg { color: var(--mint-d); }
/* dashboard art */
.hero-art { position: relative; }
.dash {
background: var(--surface); border: 1px solid var(--line);
border-radius: 20px; box-shadow: var(--shadow); padding: 22px;
animation: rise .7s ease both;
}
@keyframes rise { from { opacity: 0; transform: translateY(18px); } to { opacity: 1; transform: none; } }
.dash-top { display: flex; justify-content: space-between; align-items: flex-start; margin-bottom: 14px; }
.dash-eyebrow { font-size: 12.5px; color: var(--muted); font-weight: 600; text-transform: uppercase; letter-spacing: .05em; }
.dash-balance { display: block; font-size: 30px; font-weight: 800; color: var(--navy); margin: 4px 0 6px; letter-spacing: -.02em; }
.dash-delta { font-size: 13px; font-weight: 600; }
.dash-delta.up { color: var(--ok); }
.dash-badge {
font-size: 11.5px; font-weight: 700; color: var(--mint-d);
background: rgba(45,212,168,.13); padding: 4px 10px; border-radius: 999px;
display: inline-flex; align-items: center; gap: 6px;
}
.dash-badge::before { content: ""; width: 7px; height: 7px; border-radius: 50%; background: var(--mint-d); animation: pulse 1.6s infinite; }
@keyframes pulse { 0%,100% { opacity: 1; } 50% { opacity: .3; } }
.dash-chart { width: 100%; height: 96px; margin: 8px 0 16px; }
.chart-line { stroke-dasharray: 700; stroke-dashoffset: 700; animation: draw 1.6s ease .25s forwards; }
@keyframes draw { to { stroke-dashoffset: 0; } }
.dash-rows { display: grid; gap: 4px; }
.d-row {
display: grid; grid-template-columns: auto 1fr auto; align-items: center; gap: 11px;
padding: 9px 6px; border-top: 1px solid var(--line-2); font-size: 13.5px;
}
.d-ic {
width: 26px; height: 26px; border-radius: 8px; display: inline-flex;
align-items: center; justify-content: center; font-weight: 700; font-size: 14px;
}
.d-ic.in { background: rgba(21,163,106,.12); color: var(--ok); }
.d-ic.out { background: rgba(10,31,68,.07); color: var(--navy); }
.d-name { color: var(--ink); font-weight: 500; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.d-amt { font-weight: 700; font-variant-numeric: tabular-nums; color: var(--navy); }
.d-amt.pos { color: var(--ok); }
.card-float {
position: absolute; z-index: 3; right: -14px; top: -34px;
width: 218px; padding: 16px; border-radius: 14px;
background: linear-gradient(135deg, var(--navy), #1b3e7d);
color: #fff; box-shadow: 0 22px 40px -18px rgba(10,31,68,.6);
animation: float 5s ease-in-out infinite;
}
@keyframes float { 0%,100% { transform: translateY(0); } 50% { transform: translateY(-9px); } }
.cm-label { font-size: 11px; opacity: .75; text-transform: uppercase; letter-spacing: .07em; }
.cm-num { display: block; font-size: 18px; font-weight: 700; letter-spacing: .12em; margin: 22px 0 14px; font-variant-numeric: tabular-nums; }
.cm-foot { display: flex; justify-content: space-between; align-items: center; font-size: 10.5px; opacity: .85; }
.cm-brand { color: var(--mint-l); font-weight: 700; letter-spacing: .04em; }
/* logos */
.logos { text-align: center; padding: 8px 24px 48px; }
.logos > span { font-size: 12.5px; font-weight: 600; color: var(--muted); text-transform: uppercase; letter-spacing: .08em; }
.logo-row { display: flex; flex-wrap: wrap; justify-content: center; gap: 34px; margin-top: 16px; }
.logo { font-size: 19px; font-weight: 800; color: var(--navy); opacity: .42; letter-spacing: -.02em; transition: opacity .2s; }
.logo:hover { opacity: .85; }
/* ---------- sections ---------- */
.section { padding: 78px 0; }
.eyebrow { font-size: 13px; font-weight: 700; color: var(--mint-d); text-transform: uppercase; letter-spacing: .08em; }
.sec-h { font-size: clamp(26px, 3.6vw, 38px); font-weight: 800; color: var(--navy); margin: 10px 0; max-width: 18ch; }
.sec-sub { color: var(--muted); font-size: 17px; max-width: 56ch; margin-top: 6px; }
/* badges */
.badges-sec { background: var(--surface); border-top: 1px solid var(--line-2); border-bottom: 1px solid var(--line-2); }
.badges-sec .sec-h, .badges-sec .sec-sub { margin-left: auto; margin-right: auto; text-align: center; }
.badges-sec .sec-h { max-width: none; }
.badges { display: grid; grid-template-columns: repeat(4, 1fr); gap: 18px; margin-top: 40px; }
.badge {
display: flex; flex-direction: column; align-items: center; text-align: center; gap: 4px;
background: var(--bg); border: 1px solid var(--line); border-radius: var(--radius);
padding: 26px 16px; transition: transform .18s, box-shadow .2s, border-color .2s;
}
.badge:hover { transform: translateY(-4px); box-shadow: var(--shadow-sm); border-color: rgba(45,212,168,.5); }
.b-emblem {
width: 58px; height: 58px; border-radius: 14px; display: inline-flex;
align-items: center; justify-content: center; font-weight: 800; font-size: 16px;
margin-bottom: 8px; color: #fff;
}
.b-emblem.soc { background: linear-gradient(135deg, #0a1f44, #1b3e7d); }
.b-emblem.pci { background: linear-gradient(135deg, #15b58c, #2dd4a8); color: var(--navy); }
.b-emblem.iso { background: linear-gradient(135deg, #2b4a82, #4068a8); }
.b-emblem.gdpr { background: linear-gradient(135deg, #0a1f44, #15b58c); font-size: 13px; }
.badge strong { color: var(--navy); font-size: 15.5px; }
.badge small { color: var(--muted); font-size: 12.5px; }
/* feature tiles */
.tiles { display: grid; grid-template-columns: repeat(3, 1fr); gap: 18px; margin-top: 40px; }
.tile {
background: var(--surface); border: 1px solid var(--line); border-radius: var(--radius);
padding: 26px 24px; transition: transform .18s, box-shadow .2s, border-color .2s;
}
.tile:hover { transform: translateY(-5px); box-shadow: var(--shadow); border-color: rgba(45,212,168,.45); }
.t-ic {
width: 46px; height: 46px; border-radius: 12px; display: inline-flex;
align-items: center; justify-content: center; margin-bottom: 16px;
background: rgba(10,31,68,.06); color: var(--navy);
}
.t-ic.pay, .t-ic.rep, .t-ic.fx { background: rgba(45,212,168,.14); color: var(--mint-d); }
.tile h3 { font-size: 18px; color: var(--navy); margin-bottom: 7px; }
.tile p { color: var(--muted); font-size: 14.5px; }
/* stats band */
.stats-band {
background: linear-gradient(120deg, var(--navy), var(--navy-2));
color: #fff; padding: 56px 0;
background-image:
radial-gradient(700px 300px at 90% 120%, rgba(45,212,168,.22), transparent 60%),
linear-gradient(120deg, var(--navy), var(--navy-2));
}
.stats-grid { display: grid; grid-template-columns: repeat(4, 1fr); gap: 24px; text-align: center; }
.stat strong { display: block; font-size: clamp(30px, 4vw, 44px); font-weight: 800; color: #fff; letter-spacing: -.02em; }
.stat strong span { color: var(--mint-l); }
.stat > span:last-child { font-size: 14px; color: rgba(255,255,255,.7); font-weight: 500; }
/* calculator */
.calc-sec { background: var(--surface); border-top: 1px solid var(--line-2); }
.calc-in { display: grid; grid-template-columns: 1fr 420px; gap: 54px; align-items: center; }
.calc-points { list-style: none; padding: 0; margin: 22px 0 0; display: grid; gap: 11px; }
.calc-points li {
position: relative; padding-left: 30px; color: var(--ink); font-size: 15px;
}
.calc-points li::before {
content: "✓"; position: absolute; left: 0; top: 1px;
width: 20px; height: 20px; border-radius: 6px; font-size: 12px; font-weight: 800;
background: rgba(45,212,168,.16); color: var(--mint-d);
display: inline-flex; align-items: center; justify-content: center;
}
.calc-card {
background: var(--bg); border: 1px solid var(--line); border-radius: 20px;
padding: 28px; box-shadow: var(--shadow);
}
.calc-card h3 { font-size: 19px; color: var(--navy); margin-bottom: 20px; }
.fld { display: block; margin-bottom: 22px; }
.fld-top { display: flex; justify-content: space-between; align-items: baseline; margin-bottom: 9px; font-size: 14px; font-weight: 600; color: var(--ink); }
.fld-val { color: var(--mint-d); font-variant-numeric: tabular-nums; font-size: 15px; }
input[type="range"] {
-webkit-appearance: none; appearance: none; width: 100%; height: 6px;
border-radius: 999px; background: var(--line); outline-offset: 4px; cursor: pointer;
}
input[type="range"]::-webkit-slider-thumb {
-webkit-appearance: none; appearance: none; width: 22px; height: 22px; border-radius: 50%;
background: var(--surface); border: 3px solid var(--mint-d); box-shadow: var(--shadow-sm); cursor: grab;
}
input[type="range"]::-moz-range-thumb {
width: 22px; height: 22px; border-radius: 50%;
background: var(--surface); border: 3px solid var(--mint-d); box-shadow: var(--shadow-sm); cursor: grab;
}
.calc-results { background: var(--surface); border: 1px solid var(--line); border-radius: 14px; padding: 18px; margin: 6px 0 18px; }
.cr-row { display: flex; justify-content: space-between; align-items: center; font-size: 14.5px; color: var(--muted); padding: 6px 0; }
.cr-row.big { padding-top: 12px; margin-top: 6px; border-top: 1px dashed var(--line); font-size: 16px; color: var(--ink); font-weight: 600; }
.cr-old { color: var(--ink); font-weight: 600; text-decoration: line-through; text-decoration-color: rgba(220,38,38,.5); font-variant-numeric: tabular-nums; }
.cr-new { color: var(--navy); font-weight: 700; font-variant-numeric: tabular-nums; }
.cr-save { color: var(--ok); font-weight: 800; font-size: 21px; font-variant-numeric: tabular-nums; }
.cr-bar { height: 8px; border-radius: 999px; background: var(--line); margin: 14px 0 12px; overflow: hidden; }
.cr-bar-fill { display: block; height: 100%; width: 0; border-radius: 999px; background: linear-gradient(90deg, var(--mint-d), var(--mint-l)); transition: width .4s ease; }
.cr-note { font-size: 13px; color: var(--muted); }
.cr-note b { color: var(--mint-d); }
/* cta */
.cta { padding: 30px 0 80px; }
.cta-in {
background: linear-gradient(120deg, var(--navy), var(--navy-2));
border-radius: 24px; padding: 46px clamp(28px, 5vw, 56px);
display: grid; grid-template-columns: 1.3fr 1fr; gap: 36px; align-items: center;
box-shadow: var(--shadow);
background-image:
radial-gradient(600px 280px at 100% 0%, rgba(45,212,168,.26), transparent 60%),
linear-gradient(120deg, var(--navy), var(--navy-2));
}
.cta-text h2 { color: #fff; font-size: clamp(24px, 3.4vw, 34px); font-weight: 800; }
.cta-text p { color: rgba(255,255,255,.72); margin-top: 10px; font-size: 16px; }
.cta-form { display: flex; flex-wrap: wrap; gap: 10px; }
.cta-form input {
flex: 1 1 200px; min-width: 0; font: inherit; font-size: 15px;
padding: 13px 16px; border-radius: 11px; border: 1px solid rgba(255,255,255,.18);
background: rgba(255,255,255,.08); color: #fff;
}
.cta-form input::placeholder { color: rgba(255,255,255,.55); }
.cta-form input:focus-visible { outline-color: var(--mint-l); background: rgba(255,255,255,.14); }
.cta-form input.invalid { border-color: #ff8e8e; }
.cta-err { flex-basis: 100%; color: #ffc4c4; font-size: 13px; font-weight: 600; margin: 0; }
/* footer */
.foot { background: var(--surface); border-top: 1px solid var(--line); padding-top: 48px; }
.foot-in { display: grid; grid-template-columns: 2fr 1fr 1fr; gap: 28px; padding-bottom: 28px; }
.foot-brand p { color: var(--muted); font-size: 13.5px; margin-top: 12px; max-width: 40ch; }
.foot nav { display: flex; flex-direction: column; gap: 9px; }
.foot nav strong { color: var(--navy); font-size: 14px; margin-bottom: 4px; }
.foot nav a { color: var(--muted); font-size: 14px; transition: color .15s; }
.foot nav a:hover { color: var(--mint-d); }
.foot-base {
display: flex; justify-content: space-between; align-items: center; flex-wrap: wrap; gap: 10px;
border-top: 1px solid var(--line-2); padding: 18px 24px; font-size: 12.5px; color: var(--muted);
}
/* toast */
.toast {
position: fixed; left: 50%; bottom: 28px; transform: translate(-50%, 26px);
background: var(--navy); color: #fff; font-weight: 600; font-size: 14px;
padding: 13px 22px; border-radius: 12px; box-shadow: var(--shadow);
opacity: 0; pointer-events: none; transition: .3s; z-index: 60; max-width: 88vw;
}
.toast.show { opacity: 1; transform: translate(-50%, 0); }
/* ---------- responsive ---------- */
@media (max-width: 960px) {
.nav-links { display: none; }
.nav-cta { display: none; }
.nav-toggle { display: flex; }
.nav.open .nav-links {
display: flex; flex-direction: column; gap: 4px;
position: absolute; left: 16px; right: 16px; top: 66px; margin: 0;
background: var(--surface); border: 1px solid var(--line); border-radius: 14px;
padding: 12px; box-shadow: var(--shadow);
}
.nav.open .nav-cta {
display: flex; flex-direction: column; position: absolute; left: 16px; right: 16px; top: 224px;
background: var(--surface); border: 1px solid var(--line); border-radius: 14px; padding: 12px; box-shadow: var(--shadow);
}
.hero-in { grid-template-columns: 1fr; gap: 40px; }
.hero-art { max-width: 460px; }
.calc-in { grid-template-columns: 1fr; gap: 36px; }
.cta-in { grid-template-columns: 1fr; }
.badges { grid-template-columns: repeat(2, 1fr); }
.tiles { grid-template-columns: repeat(2, 1fr); }
.stats-grid { grid-template-columns: repeat(2, 1fr); gap: 32px 20px; }
}
@media (max-width: 560px) {
.wrap { padding: 0 18px; }
.section { padding: 56px 0; }
.tiles { grid-template-columns: 1fr; }
.badges { grid-template-columns: 1fr; }
.card-float { right: 8px; top: -22px; width: 188px; }
.hero-trust { gap: 12px; }
.foot-in { grid-template-columns: 1fr 1fr; }
.foot-brand { grid-column: 1 / -1; }
}
@media (prefers-reduced-motion: reduce) {
*, *::before, *::after { animation: none !important; transition: none !important; }
html { scroll-behavior: auto; }
}(function () {
"use strict";
/* ---------- toast helper ---------- */
var toastEl = document.getElementById("toast");
var toastTimer;
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 nav = document.querySelector(".nav");
var toggle = document.querySelector(".nav-toggle");
if (toggle && nav) {
toggle.addEventListener("click", function () {
var open = nav.classList.toggle("open");
toggle.setAttribute("aria-expanded", open ? "true" : "false");
});
nav.querySelectorAll(".nav-links a, .nav-cta a").forEach(function (a) {
a.addEventListener("click", function () {
nav.classList.remove("open");
toggle.setAttribute("aria-expanded", "false");
});
});
}
/* ---------- animated counters ---------- */
function fmt(n, decimals) {
return n.toLocaleString("en-US", {
minimumFractionDigits: decimals,
maximumFractionDigits: decimals
});
}
function animateCount(el) {
var target = parseFloat(el.getAttribute("data-count")) || 0;
var decimals = parseInt(el.getAttribute("data-decimals") || "0", 10);
var suffix = el.getAttribute("data-suffix") || "";
var dur = 1500;
var start = null;
function step(ts) {
if (start === null) start = ts;
var p = Math.min((ts - start) / dur, 1);
var eased = 1 - Math.pow(1 - p, 3); // easeOutCubic
el.textContent = fmt(target * eased, decimals) + suffix;
if (p < 1) requestAnimationFrame(step);
else el.textContent = fmt(target, decimals) + suffix;
}
requestAnimationFrame(step);
}
var counters = document.querySelectorAll("[data-count]");
if ("IntersectionObserver" in window) {
var io = new IntersectionObserver(function (entries) {
entries.forEach(function (e) {
if (e.isIntersecting) {
animateCount(e.target);
io.unobserve(e.target);
}
});
}, { threshold: 0.4 });
counters.forEach(function (c) { io.observe(c); });
} else {
counters.forEach(animateCount);
}
/* ---------- savings calculator ---------- */
var LEGACY_RATE = 0.024; // 2.4% on cross-border
var LEGACY_DOM = 0.009; // 0.9% on domestic
var LL_RATE = 0.006; // flat 0.6%
var vol = document.getElementById("vol");
var cross = document.getElementById("cross");
var volOut = document.getElementById("volOut");
var crossOut = document.getElementById("crossOut");
var curFee = document.getElementById("curFee");
var newFee = document.getElementById("newFee");
var saved = document.getElementById("saved");
var pct = document.getElementById("pct");
var barFill = document.getElementById("barFill");
var usd0 = function (n) {
return "$" + Math.round(n).toLocaleString("en-US");
};
function recalc() {
if (!vol) return;
var monthly = parseInt(vol.value, 10);
var crossShare = parseInt(cross.value, 10) / 100;
var annual = monthly * 12;
var crossVol = annual * crossShare;
var domVol = annual * (1 - crossShare);
var current = crossVol * LEGACY_RATE + domVol * LEGACY_DOM;
var ledger = annual * LL_RATE;
var diff = Math.max(current - ledger, 0);
var savePct = current > 0 ? (diff / current) * 100 : 0;
volOut.textContent = usd0(monthly);
crossOut.textContent = cross.value + "%";
curFee.textContent = usd0(current);
newFee.textContent = usd0(ledger);
saved.textContent = usd0(diff);
pct.textContent = Math.round(savePct) + "%";
barFill.style.width = Math.min(savePct, 100).toFixed(0) + "%";
}
if (vol && cross) {
vol.addEventListener("input", recalc);
cross.addEventListener("input", recalc);
recalc();
}
var calcCta = document.getElementById("calcCta");
if (calcCta) {
calcCta.addEventListener("click", function () {
toast("Estimate saved — scroll down to book your demo.");
var demo = document.getElementById("demo");
if (demo) demo.scrollIntoView({ behavior: "smooth", block: "start" });
setTimeout(function () {
var email = document.getElementById("email");
if (email) email.focus();
}, 600);
});
}
/* ---------- demo form ---------- */
var demoForm = document.getElementById("demoForm");
var emailInput = document.getElementById("email");
var emailErr = document.getElementById("emailErr");
var EMAIL_RE = /^[^\s@]+@[^\s@]+\.[^\s@]{2,}$/;
if (demoForm && emailInput) {
demoForm.addEventListener("submit", function (ev) {
ev.preventDefault();
var val = emailInput.value.trim();
if (!EMAIL_RE.test(val)) {
emailInput.classList.add("invalid");
emailInput.setAttribute("aria-invalid", "true");
if (emailErr) emailErr.hidden = false;
emailInput.focus();
return;
}
emailInput.classList.remove("invalid");
emailInput.removeAttribute("aria-invalid");
if (emailErr) emailErr.hidden = true;
demoForm.reset();
toast("Thanks! A specialist will reach out within one business day.");
});
emailInput.addEventListener("input", function () {
if (!emailInput.classList.contains("invalid")) return;
if (EMAIL_RE.test(emailInput.value.trim())) {
emailInput.classList.remove("invalid");
emailInput.removeAttribute("aria-invalid");
if (emailErr) emailErr.hidden = true;
}
});
}
})();<!doctype html>
<html lang="en">
<head>
<meta charset="utf-8" />
<meta name="viewport" content="width=device-width, initial-scale=1" />
<title>Ledgerline — Banking infrastructure for modern teams</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&display=swap" rel="stylesheet" />
<link rel="stylesheet" href="style.css" />
</head>
<body>
<a class="skip" href="#main">Skip to content</a>
<header class="nav" role="banner">
<div class="wrap nav-in">
<a class="brand" href="#" aria-label="Ledgerline home">
<span class="brand-mark" aria-hidden="true">
<svg viewBox="0 0 32 32" width="28" height="28">
<rect x="2" y="2" width="28" height="28" rx="8" fill="url(#bg)"/>
<path d="M9 21V11m0 10h14M16 21v-6m7 6v-3" stroke="#0a1f44" stroke-width="2.4" stroke-linecap="round"/>
<defs><linearGradient id="bg" x1="0" y1="0" x2="32" y2="32">
<stop stop-color="#5ce8c4"/><stop offset="1" stop-color="#2dd4a8"/>
</linearGradient></defs>
</svg>
</span>
Ledgerline
</a>
<nav class="nav-links" aria-label="Primary">
<a href="#features">Platform</a>
<a href="#stats">Customers</a>
<a href="#calc">Pricing</a>
<a href="#security">Security</a>
</nav>
<div class="nav-cta">
<a class="btn ghost" href="#">Sign in</a>
<a class="btn solid" href="#demo">Book a demo</a>
</div>
<button class="nav-toggle" aria-label="Toggle menu" aria-expanded="false">
<span></span><span></span><span></span>
</button>
</div>
</header>
<main id="main">
<!-- HERO -->
<section class="hero">
<div class="wrap hero-in">
<div class="hero-copy">
<span class="pill"><span class="dot" aria-hidden="true"></span> SOC 2 Type II · PCI-DSS Level 1</span>
<h1>Banking infrastructure your finance team can <span class="grad">actually trust</span>.</h1>
<p class="lede">Move money, reconcile ledgers, and enforce spend controls from one secure API and dashboard. Built for compliance teams who never want to guess where a dollar went.</p>
<div class="hero-actions">
<a class="btn solid lg" href="#demo">Book a demo</a>
<a class="btn line lg" href="#features">Explore the platform</a>
</div>
<ul class="hero-trust" aria-label="Trust signals">
<li><svg viewBox="0 0 24 24" width="18" height="18" aria-hidden="true"><path d="M12 2 4 5v6c0 5 3.4 8.5 8 11 4.6-2.5 8-6 8-11V5l-8-3Z" fill="none" stroke="currentColor" stroke-width="1.8"/><path d="m8.5 12 2.4 2.4 4.6-4.8" fill="none" stroke="currentColor" stroke-width="1.8" stroke-linecap="round"/></svg> 99.99% uptime</li>
<li><svg viewBox="0 0 24 24" width="18" height="18" aria-hidden="true"><rect x="4" y="10" width="16" height="11" rx="2" fill="none" stroke="currentColor" stroke-width="1.8"/><path d="M8 10V7a4 4 0 0 1 8 0v3" fill="none" stroke="currentColor" stroke-width="1.8"/></svg> AES-256 encrypted</li>
<li><svg viewBox="0 0 24 24" width="18" height="18" aria-hidden="true"><circle cx="12" cy="12" r="9" fill="none" stroke="currentColor" stroke-width="1.8"/><path d="M12 7v5l3 2" fill="none" stroke="currentColor" stroke-width="1.8" stroke-linecap="round"/></svg> Real-time settlement</li>
</ul>
</div>
<!-- DASHBOARD MOCKUP -->
<div class="hero-art" aria-hidden="true">
<div class="card-float card-mini">
<span class="cm-label">Virtual card · Operations</span>
<span class="cm-num">4921 ·· 7740</span>
<div class="cm-foot"><span>VALID 09/29</span><span class="cm-brand">ledgerline</span></div>
</div>
<div class="dash">
<div class="dash-top">
<div>
<span class="dash-eyebrow">Treasury balance</span>
<strong class="dash-balance">$<span data-count="2480915" data-decimals="0">0</span></strong>
<span class="dash-delta up">▲ 4.2% vs last week</span>
</div>
<span class="dash-badge">Live</span>
</div>
<svg class="dash-chart" viewBox="0 0 320 110" preserveAspectRatio="none">
<defs>
<linearGradient id="fill" x1="0" y1="0" x2="0" y2="1">
<stop offset="0" stop-color="#2dd4a8" stop-opacity=".35"/>
<stop offset="1" stop-color="#2dd4a8" stop-opacity="0"/>
</linearGradient>
</defs>
<path class="chart-area" d="M0,80 L40,72 L80,76 L120,55 L160,60 L200,40 L240,46 L280,26 L320,30 L320,110 L0,110 Z" fill="url(#fill)"/>
<path class="chart-line" d="M0,80 L40,72 L80,76 L120,55 L160,60 L200,40 L240,46 L280,26 L320,30" fill="none" stroke="#2dd4a8" stroke-width="2.5" stroke-linecap="round" stroke-linejoin="round"/>
</svg>
<div class="dash-rows">
<div class="d-row">
<span class="d-ic in" aria-hidden="true">↓</span>
<span class="d-name">ACH credit · Stripe payout</span>
<span class="d-amt pos">+$84,210.00</span>
</div>
<div class="d-row">
<span class="d-ic out" aria-hidden="true">↑</span>
<span class="d-name">Wire · Payroll batch #318</span>
<span class="d-amt">−$129,400.00</span>
</div>
<div class="d-row">
<span class="d-ic out" aria-hidden="true">↑</span>
<span class="d-name">Card · Cloud infrastructure</span>
<span class="d-amt">−$6,890.55</span>
</div>
</div>
</div>
</div>
</div>
<!-- logo strip -->
<div class="wrap logos">
<span>Trusted by finance teams at</span>
<div class="logo-row">
<span class="logo">Northpay</span>
<span class="logo">Vellum</span>
<span class="logo">Arclight</span>
<span class="logo">Quanta</span>
<span class="logo">Meridian Co</span>
</div>
</div>
</section>
<!-- COMPLIANCE BADGES -->
<section class="section badges-sec" id="security" aria-labelledby="sec-title">
<div class="wrap">
<h2 id="sec-title" class="sec-h">Security & compliance, by default</h2>
<p class="sec-sub">Every transaction is audited, encrypted, and provable. Our controls are reviewed by independent assessors.</p>
<div class="badges">
<div class="badge"><span class="b-emblem soc">SOC 2</span><strong>Type II Certified</strong><small>Continuous control monitoring</small></div>
<div class="badge"><span class="b-emblem pci">PCI</span><strong>DSS Level 1</strong><small>Highest card-data standard</small></div>
<div class="badge"><span class="b-emblem iso">ISO</span><strong>27001</strong><small>Information security mgmt</small></div>
<div class="badge"><span class="b-emblem gdpr">GDPR</span><strong>Compliant</strong><small>EU data residency option</small></div>
</div>
</div>
</section>
<!-- FEATURES -->
<section class="section" id="features" aria-labelledby="feat-title">
<div class="wrap">
<span class="eyebrow">The platform</span>
<h2 id="feat-title" class="sec-h">One ledger for every money movement</h2>
<div class="tiles">
<article class="tile">
<span class="t-ic pay" aria-hidden="true">
<svg viewBox="0 0 24 24" width="22" height="22"><rect x="3" y="6" width="18" height="12" rx="2" fill="none" stroke="currentColor" stroke-width="1.8"/><path d="M3 10h18" stroke="currentColor" stroke-width="1.8"/></svg>
</span>
<h3>Programmatic payments</h3>
<p>Originate ACH, wires, and card payouts through one idempotent API with instant balance confirmation.</p>
</article>
<article class="tile">
<span class="t-ic rep" aria-hidden="true">
<svg viewBox="0 0 24 24" width="22" height="22"><path d="M5 19V5m0 14h14M9 15l3-4 3 2 3-5" fill="none" stroke="currentColor" stroke-width="1.8" stroke-linecap="round" stroke-linejoin="round"/></svg>
</span>
<h3>Reconciled reporting</h3>
<p>Double-entry ledgers that always balance. Export GAAP-ready statements or stream events to your warehouse.</p>
</article>
<article class="tile">
<span class="t-ic ctl" aria-hidden="true">
<svg viewBox="0 0 24 24" width="22" height="22"><circle cx="12" cy="12" r="3" fill="none" stroke="currentColor" stroke-width="1.8"/><path d="M12 3v3m0 12v3M3 12h3m12 0h3" stroke="currentColor" stroke-width="1.8" stroke-linecap="round"/></svg>
</span>
<h3>Granular controls</h3>
<p>Set per-card limits, approval chains, and merchant rules. Freeze spend the instant a policy is breached.</p>
</article>
<article class="tile">
<span class="t-ic aud" aria-hidden="true">
<svg viewBox="0 0 24 24" width="22" height="22"><path d="M4 5h16v14H4z" fill="none" stroke="currentColor" stroke-width="1.8"/><path d="M8 9h8M8 13h5" stroke="currentColor" stroke-width="1.8" stroke-linecap="round"/></svg>
</span>
<h3>Immutable audit trail</h3>
<p>Every state change is signed and time-stamped. Hand auditors a tamper-evident log in one click.</p>
</article>
<article class="tile">
<span class="t-ic fx" aria-hidden="true">
<svg viewBox="0 0 24 24" width="22" height="22"><path d="M7 7h9l-3-3m3 3-3 3M17 17H8l3 3m-3-3 3-3" fill="none" stroke="currentColor" stroke-width="1.8" stroke-linecap="round" stroke-linejoin="round"/></svg>
</span>
<h3>Multi-currency FX</h3>
<p>Hold and convert 34 currencies at interbank rates with locked-in quotes and transparent fees.</p>
</article>
<article class="tile">
<span class="t-ic api" aria-hidden="true">
<svg viewBox="0 0 24 24" width="22" height="22"><path d="M9 8 5 12l4 4m6-8 4 4-4 4M13 6l-2 12" fill="none" stroke="currentColor" stroke-width="1.8" stroke-linecap="round" stroke-linejoin="round"/></svg>
</span>
<h3>Developer-first API</h3>
<p>Typed SDKs, sandbox keys, and webhook replays. Go from test to production in an afternoon.</p>
</article>
</div>
</div>
</section>
<!-- STATS BAND -->
<section class="stats-band" id="stats" aria-label="Key metrics">
<div class="wrap stats-grid">
<div class="stat"><strong>$<span data-count="14.6" data-decimals="1" data-suffix="B">0</span></strong><span>Processed annually</span></div>
<div class="stat"><strong><span data-count="99.99" data-decimals="2" data-suffix="%">0</span></strong><span>Settlement accuracy</span></div>
<div class="stat"><strong><span data-count="220" data-suffix="ms">0</span></strong><span>Median API latency</span></div>
<div class="stat"><strong><span data-count="3400" data-suffix="+">0</span></strong><span>Finance teams</span></div>
</div>
</section>
<!-- CALCULATOR -->
<section class="section calc-sec" id="calc" aria-labelledby="calc-title">
<div class="wrap calc-in">
<div class="calc-copy">
<span class="eyebrow">Savings calculator</span>
<h2 id="calc-title" class="sec-h">See what you keep at interbank rates</h2>
<p class="sec-sub">Legacy processors hide 2.4% in fees on cross-border volume. Ledgerline charges a flat 0.6%. Drag the slider to estimate your annual savings.</p>
<ul class="calc-points">
<li>Flat, published pricing — no surprise interchange markups</li>
<li>Same-day settlement included on every plan</li>
<li>No minimums, no platform fee for teams under $1M/mo</li>
</ul>
</div>
<form class="calc-card" id="calcForm" aria-labelledby="calc-card-title">
<h3 id="calc-card-title">Estimate your savings</h3>
<label class="fld" for="vol">
<span class="fld-top"><span>Monthly payment volume</span><span class="fld-val" id="volOut">$250,000</span></span>
<input type="range" id="vol" min="25000" max="3000000" step="25000" value="250000" />
</label>
<label class="fld" for="cross">
<span class="fld-top"><span>Cross-border share</span><span class="fld-val" id="crossOut">40%</span></span>
<input type="range" id="cross" min="0" max="100" step="5" value="40" />
</label>
<div class="calc-results" role="status" aria-live="polite">
<div class="cr-row"><span>Current fees / yr</span><span id="curFee" class="cr-old">$0</span></div>
<div class="cr-row"><span>With Ledgerline / yr</span><span id="newFee" class="cr-new">$0</span></div>
<div class="cr-row big"><span>You save</span><span id="saved" class="cr-save">$0</span></div>
<div class="cr-bar"><span class="cr-bar-fill" id="barFill"></span></div>
<p class="cr-note" id="crNote">That's <b id="pct">0%</b> off your current processing cost.</p>
</div>
<button type="button" class="btn solid full" id="calcCta">Book a demo with these numbers</button>
</form>
</div>
</section>
<!-- CTA -->
<section class="cta" id="demo" aria-labelledby="cta-title">
<div class="wrap cta-in">
<div class="cta-text">
<h2 id="cta-title">Ready to put your money on a ledger you can prove?</h2>
<p>Book a 30-minute walkthrough. We'll map your current flows and show live settlement in our sandbox.</p>
</div>
<form class="cta-form" id="demoForm" novalidate>
<label class="sr-only" for="email">Work email</label>
<input type="email" id="email" name="email" placeholder="[email protected]" autocomplete="email" required />
<button class="btn mint" type="submit">Book a demo</button>
<p class="cta-err" id="emailErr" role="alert" hidden>Enter a valid work email.</p>
</form>
</div>
</section>
</main>
<footer class="foot" role="contentinfo">
<div class="wrap foot-in">
<div class="foot-brand">
<span class="brand"><span class="brand-mark sm" aria-hidden="true">L</span> Ledgerline</span>
<p>Fictional banking infrastructure for product demos. Not a real financial institution.</p>
</div>
<nav aria-label="Footer"><strong>Platform</strong><a href="#features">Payments</a><a href="#features">Reporting</a><a href="#calc">Pricing</a></nav>
<nav aria-label="Company"><strong>Company</strong><a href="#security">Security</a><a href="#stats">Customers</a><a href="#demo">Contact</a></nav>
</div>
<div class="wrap foot-base"><span>© 2026 Ledgerline (fictional). Illustrative demo only.</span><span>SOC 2 · PCI-DSS · ISO 27001</span></div>
</footer>
<div class="toast" id="toast" role="status" aria-live="polite"></div>
<script src="script.js"></script>
</body>
</html>Fintech SaaS Landing
A conversion-focused landing page for Ledgerline, a fictional banking-infrastructure product. The hero leads with a compliance pill and a clean finance dashboard rendered entirely as inline SVG — an animated treasury-balance counter, a self-drawing area chart, a live transaction ledger, and a floating virtual-card mockup. The palette is deliberately fintech: deep navy for trust, a mint accent for momentum, white surfaces with 1px lines and soft shadows for depth.
Below the fold, fictional SOC 2 Type II, PCI-DSS Level 1, ISO 27001, and GDPR badges signal security by default, followed by six feature tiles (programmatic payments, reconciled reporting, granular controls, immutable audit trail, multi-currency FX, developer-first API) and a navy stats band whose figures count up when scrolled into view. The interactive savings calculator lets visitors drag monthly volume and cross-border share sliders to see annual fees at legacy rates versus a flat 0.6%, with a live savings bar. A book-a-demo CTA validates the email inline and confirms with a toast.
Everything is self-contained vanilla HTML, CSS, and JavaScript: no frameworks, no external images, no chart libraries. Counters use IntersectionObserver with an easeOutCubic tween, and the layout collapses gracefully to a single column down to 360px with a slide-out mobile menu.
Illustrative SaaS UI only — fictional product, metrics, and billing. No real backend.