Free
0
3
Fernwise
By Priya Shah
Fernwise is a calm, modern fintech template for wealth, banking and money apps, with a bento hero and live chart, a scroll-lit statement, value cards, a step-by-step section, a services carousel, a comparison table, a searchable FAQ and a multi-step sign-up.
Download Codebase
Commercial License<%# letstemplates: access=free category=fintech %>
<!DOCTYPE html>
<html lang="en">
<head>
<script>
window.FontAwesomeConfig = { autoReplaceSvg: 'nest' };
</script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.4.0/js/all.min.js" crossorigin="anonymous" referrerpolicy="no-referrer"></script>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Fernwise | Tailwind CSS Fintech Template</title>
<meta name="description" content="Fernwise is a calm, modern Tailwind CSS fintech template for wealth, banking and money apps, with a bento hero and live chart, a scroll-lit statement, value cards, a step-by-step section, a services carousel, a comparison table, a searchable FAQ and a multi-step sign-up.">
<meta name="keywords" content="Fernwise, Tailwind CSS template, HTML website template, fintech template, finance website, wealth management template, banking app landing page, investment website, pricing table, sign up form">
<meta name="author" content="Let's templates">
<link rel="canonical" href="">
<meta property="og:type" content="product">
<meta property="og:site_name" content="Let's templates">
<meta property="og:locale" content="en_US">
<meta property="og:url" content="">
<meta property="og:title" content="Fernwise | Tailwind CSS Fintech Template">
<meta property="og:description" content="A calm, modern Tailwind CSS fintech template with a bento hero and live chart, a services carousel, a comparison table and a multi-step sign-up.">
<meta property="og:image" content="">
<meta property="og:image:alt" content="Fernwise template preview">
<meta name="twitter:card" content="summary_large_image">
<meta name="twitter:url" content="">
<meta name="twitter:title" content="Fernwise | Tailwind CSS Fintech Template">
<meta name="twitter:description" content="A calm, modern Tailwind CSS fintech template with a bento hero and live chart, a services carousel, a comparison table and a multi-step sign-up.">
<meta name="twitter:image" content="">
<meta name="twitter:image:alt" content="Fernwise template preview">
<script src="https://cdn.tailwindcss.com/3.4.17"></script>
<link rel="preconnect" href="https://fonts.googleapis.com">
<link href="https://fonts.googleapis.com/css2?family=Archivo:wght@700;800&family=Mulish:wght@400;500;600&display=swap" rel="stylesheet">
<script>
tailwind.config = {
theme: {
extend: {
colors: { pine: { DEFAULT: '#1e3d36', light: '#2f6b5e' }, jade: '#4fa595', paper: '#f5f5f3', stone: '#ecece9', cream: '#ecebdc', mist: '#dde9e7', zest: '#e6e04a' },
fontFamily: { sans: ['Mulish', 'sans-serif'], brand: ['Archivo', 'sans-serif'] }
}
}
}
</script>
<style>
@view-transition { navigation: auto; }
::view-transition-old(root) { animation: 180ms ease-out both page-fade-out; }
::view-transition-new(root) { animation: 220ms ease-in both page-fade-in; }
@keyframes page-fade-out { to { opacity: 0; } }
@keyframes page-fade-in { from { opacity: 0; } }
html { scroll-behavior: smooth; }
[hidden] { display: none !important; }
.arches { background-image: radial-gradient(circle at 70% 120%, transparent 38%, rgba(236,235,220,.55) 38.4%, transparent 39.2%, transparent 46%, rgba(236,235,220,.55) 46.4%, transparent 47.2%); }
.arches-dark { background-image: radial-gradient(circle at 12% 110%, transparent 30%, rgba(255,255,255,.08) 30.4%, transparent 31.4%, transparent 38%, rgba(255,255,255,.08) 38.4%, transparent 39.4%), radial-gradient(circle at 92% 110%, transparent 30%, rgba(255,255,255,.08) 30.4%, transparent 31.4%, transparent 38%, rgba(255,255,255,.08) 38.4%, transparent 39.4%), linear-gradient(110deg, #4fa595 0%, #2f6b5e 45%, #1e3d36 100%); }
.marquee { animation: marquee 30s linear infinite; }
.marquee:hover { animation-play-state: paused; }
@keyframes marquee { to { transform: translateX(-50%); } }
.chart-line { transition: d .6s ease; }
.ring-fill { transition: stroke-dashoffset 1.2s ease; }
.draw { stroke-dasharray: 600; stroke-dashoffset: 0; transition: stroke-dashoffset 1.4s ease; }
.reveal-ready .draw:not(.is-drawn) { stroke-dashoffset: 600; }
[data-word] { transition: color .4s ease; }
.rail-card { transition: background-color .4s ease, color .4s ease, transform .4s ease; }
.rail-card[data-active="true"] { background: #1e3d36; color: #fff; transform: translateY(-.75rem); }
.rail-card[data-active="true"] .rail-muted { color: rgba(255,255,255,.75); }
.reveal-ready [data-reveal] { opacity: 0; transform: translateY(24px); transition: opacity .6s ease, transform .6s ease; transition-delay: var(--reveal-delay, 0ms); }
.reveal-ready [data-reveal].is-visible { opacity: 1; transform: none; }
@media (prefers-reduced-motion: reduce) {
html { scroll-behavior: auto; }
.marquee { animation: none; }
.chart-line, .ring-fill, .draw, [data-word], .rail-card { transition: none; }
::view-transition-old(root), ::view-transition-new(root) { animation: none; }
}
</style>
</head>
<body class="bg-paper font-sans text-pine antialiased">
<% active_page = "index" %>
<% nav = { "index" => "Home", "about" => "About us", "services" => "Services", "pricing" => "Pricing", "faq" => "FAQ" } %>
<!-- block:start navbar -->
<header class="relative z-40">
<nav class="mx-auto flex max-w-7xl items-center justify-between gap-6 px-5 py-6 md:px-10" aria-label="Main">
<a href="index.html" class="leading-none" aria-label="Fernwise Finance home">
<span class="block font-brand text-[1.7rem] font-extrabold tracking-tight">Fernwise</span>
<span class="block font-brand text-[10px] font-bold uppercase tracking-[0.35em]">Finance</span>
</a>
<ul class="hidden items-center gap-10 text-[15px] font-medium lg:flex">
<% nav.each do |slug, label| %>
<% active = active_page == slug %>
<li><a href="<%= slug %>.html" <%= 'aria-current="page"'.html_safe if active %> class="border-b-2 pb-1 transition <%= active ? 'border-pine' : 'border-transparent text-pine/70 hover:text-pine' %>"><%= label %></a></li>
<% end %>
</ul>
<div class="flex items-center gap-2">
<a href="signup.html" <%= 'aria-current="page"'.html_safe if active_page == "signup" %> class="hidden rounded-full bg-pine px-6 py-2.5 text-sm font-medium text-white transition hover:bg-pine-light sm:inline-block">Sign up</a>
<button type="button" data-menu-toggle aria-controls="mobile-menu" aria-expanded="false" aria-label="Open menu" class="grid h-11 w-11 place-items-center rounded-full bg-pine text-white lg:hidden"><i class="fa-solid fa-bars" aria-hidden="true"></i></button>
</div>
</nav>
<div id="mobile-menu" class="hidden px-5 pb-4 lg:hidden">
<ul class="grid gap-1 rounded-3xl bg-white p-3 font-medium shadow-lg">
<% nav.merge("contact" => "Contact", "signup" => "Sign up").each do |slug, label| %>
<% active = active_page == slug %>
<li><a href="<%= slug %>.html" <%= 'aria-current="page"'.html_safe if active %> class="block rounded-2xl px-4 py-3 <%= active ? 'bg-pine text-white' : 'hover:bg-stone' %>"><%= label %></a></li>
<% end %>
</ul>
</div>
</header>
<!-- block:end navbar -->
<% periods = { "1M" => ["$12,480", "M0 70 C 30 66 45 50 70 54 S 110 30 140 40 S 190 22 220 26 S 260 12 280 18", "+4.1%"], "6M" => ["$196,000", "M0 78 C 25 80 30 40 55 44 S 85 28 105 42 S 140 30 160 34 S 200 10 225 18 S 260 30 280 26", "+18.6%"], "1Y" => ["$342,900", "M0 84 C 30 82 50 70 80 62 S 130 50 160 36 S 210 30 240 14 S 270 8 280 6", "+32.4%"] } %>
<!-- block:start hero -->
<section class="mx-auto grid max-w-7xl items-center gap-14 px-5 pb-16 pt-6 md:px-10 lg:grid-cols-[1.05fr_1fr] lg:pb-24">
<div class="grid grid-cols-2 gap-4 sm:gap-5">
<div class="flex flex-col justify-between rounded-[1.75rem] bg-mist p-5 sm:p-6" data-reveal>
<span class="text-2xl" aria-hidden="true">✦✦</span>
<p class="mt-6 text-right text-sm sm:text-base">Active members</p>
<div class="mt-3 flex -space-x-2">
<% [3, 5, 8].each do |n| %><img src="https://storage.googleapis.com/uxpilot-auth.appspot.com/avatars/avatar-<%= n %>.jpg" alt="" class="h-8 w-8 rounded-full border-2 border-mist object-cover"><% end %>
<span class="grid h-8 w-8 place-items-center rounded-full border-2 border-mist bg-pine text-xs text-white" aria-hidden="true"><i class="fa-solid fa-plus"></i></span>
</div>
</div>
<div class="relative min-h-[11rem] rounded-[1.75rem] bg-gradient-to-br from-jade to-pine sm:min-h-[15rem]" data-reveal style="--reveal-delay: 80ms">
<img src="https://images.unsplash.com/photo-1563986768609-322da13575f3?auto=format&fit=crop&crop=focalpoint&fp-x=0.72&fp-y=0.55&fp-z=2.2&w=700&h=800&q=80" alt="Hand holding a phone showing a banking app next to a laptop" class="absolute inset-x-3 -top-8 bottom-3 h-[calc(100%+1.25rem)] w-[calc(100%-1.5rem)] rounded-[1.4rem] object-cover shadow-xl">
</div>
<div class="flex flex-col justify-between rounded-[1.75rem] bg-cream p-5 sm:p-6" data-reveal style="--reveal-delay: 160ms">
<p class="text-3xl font-medium">56+</p>
<div class="mt-6 flex items-end justify-between gap-2"><p class="text-lg">Currencies</p><i class="fa-solid fa-globe text-4xl" aria-hidden="true"></i></div>
</div>
<div class="rounded-[1.75rem] bg-pine p-5 text-white sm:p-6" data-chart data-reveal style="--reveal-delay: 240ms">
<div class="flex flex-wrap items-center justify-between gap-2">
<p class="text-lg font-medium" aria-live="polite"><span data-chart-value><%= periods["6M"][0] %></span> <span data-chart-change class="text-xs text-zest"><%= periods["6M"][2] %></span></p>
<div class="flex rounded-full bg-white/10 p-0.5 text-[11px]" role="group" aria-label="Chart period">
<% periods.each do |label, (value, path, change)| %>
<button type="button" data-period="<%= label %>" data-value="<%= value %>" data-path="<%= path %>" data-change="<%= change %>" aria-pressed="<%= label == '6M' %>" class="rounded-full px-2 py-1 transition aria-pressed:bg-zest aria-pressed:text-pine"><%= label %></button>
<% end %>
</div>
</div>
<svg viewBox="0 0 280 90" class="mt-4 w-full" role="img" aria-label="Portfolio value trend">
<g stroke="rgba(255,255,255,.12)"><line x1="0" y1="20" x2="280" y2="20"/><line x1="0" y1="45" x2="280" y2="45"/><line x1="0" y1="70" x2="280" y2="70"/></g>
<path data-chart-line class="chart-line" d="<%= periods["6M"][1] %>" fill="none" stroke="#e6e04a" stroke-width="3" stroke-linecap="round" style="filter: drop-shadow(0 4px 6px rgba(230,224,74,.35))"/>
</svg>
<div class="mt-1 flex justify-between text-[9px] text-white/50" aria-hidden="true"><% %w[Jan Feb Mar Apr May Jun Jul Aug].each do |m| %><span><%= m %></span><% end %></div>
</div>
</div>
<div>
<h1 class="text-5xl font-medium leading-[1.05] tracking-tight md:text-6xl xl:text-7xl">Building Your Wealth, Protecting Your Tomorrow</h1>
<p class="mt-6 max-w-md leading-relaxed text-pine/80">From the coffee you buy today to the home you'll buy in ten years, Fernwise helps every dollar you earn work a little harder for you.</p>
<a href="signup.html" class="mt-8 inline-block rounded-full bg-pine px-7 py-3 font-medium text-white transition hover:bg-pine-light">Get started now</a>
</div>
</section>
<!-- block:end hero -->
<% partners = [["fa-leaf", "Acrewood"], ["fa-wallet", "Northwind Pay"], ["fa-feather", "Lumio"], ["fa-kiwi-bird", "Kitepoint"], ["fa-book", "Brightledger"], ["fa-cube", "Quanta"], ["fa-anchor", "Harbor & Co"]] %>
<!-- block:start clients -->
<section class="overflow-hidden py-10" aria-label="Partners">
<ul class="marquee flex w-max items-center gap-20 pr-20">
<% (partners + partners).each_with_index do |(icon, name), index| %>
<li class="flex items-center gap-3 whitespace-nowrap font-brand text-3xl font-bold text-pine/35" <%= 'aria-hidden="true"'.html_safe if index >= partners.size %>><i class="fa-solid <%= icon %>" aria-hidden="true"></i><%= name %></li>
<% end %>
</ul>
</section>
<!-- block:end clients -->
<% statement = [["Fernwise", false], ["helps grow and", true], [:chart, nil], ["protect", true], ["wealth", false], ["with strategic finance", true], [:shield, nil], ["and", true], ["investment, providing data-driven", false], ["solutions for lasting security", true]] %>
<!-- block:start about -->
<section class="mx-auto max-w-5xl px-5 py-20 text-center md:px-10" data-word-reveal>
<p class="text-sm text-pine/40">[ About Fernwise ]</p>
<h2 class="mt-5 text-3xl font-medium leading-snug md:text-5xl md:leading-[1.2]">
<% statement.each do |text, strong| %>
<% if text == :chart %>
<span class="inline-grid h-10 w-10 place-items-center rounded-full bg-cream align-middle text-base md:h-12 md:w-12" aria-hidden="true"><i class="fa-solid fa-chart-line"></i></span>
<% elsif text == :shield %>
<span class="inline-grid h-10 w-10 place-items-center rounded-full bg-pine align-middle text-base text-white md:h-12 md:w-12" aria-hidden="true"><i class="fa-solid fa-shield-halved"></i></span>
<% else %>
<% text.split.each do |word| %><span data-word class="<%= strong ? 'text-pine' : 'text-pine/35' %>"><%= word %></span> <% end %>
<% end %>
<% end %>
</h2>
<a href="about.html" class="mt-10 inline-block rounded-full bg-pine px-7 py-3 text-sm font-medium text-white transition hover:bg-pine-light">Learn more</a>
</section>
<!-- block:end about -->
<!-- block:start cta -->
<section class="mx-auto max-w-7xl px-5 pb-20 pt-16 md:px-10">
<div class="arches-dark relative grid rounded-[2rem] text-white md:grid-cols-2">
<div class="relative z-10 p-8 md:p-14">
<h2 class="text-4xl font-medium leading-tight md:text-5xl">Made for Growth, Grounded in Trust</h2>
<p class="mt-5 max-w-md leading-relaxed text-white/85">So we built a platform that makes money simpler: bank-grade security, live insights and plans that adapt as your life does.</p>
<a href="signup.html" class="mt-8 inline-block rounded-full bg-white px-7 py-3 font-medium text-pine transition hover:bg-cream">Get started now</a>
</div>
<div class="relative min-h-[18rem] overflow-hidden rounded-b-[2rem] md:overflow-visible md:rounded-none">
<img src="https://images.unsplash.com/photo-1544005313-94ddf0286df2?auto=format&fit=crop&crop=focalpoint&fp-x=0.5&fp-y=0.35&w=800&h=900&q=80" alt="Young woman in a striped top smiling with confidence" class="absolute bottom-0 right-6 h-[115%] w-[85%] rounded-t-[10rem] object-cover md:h-[128%] md:w-[70%]">
</div>
</div>
</section>
<!-- block:end cta -->
<!-- block:start features -->
<section class="mx-auto max-w-7xl px-5 py-16 md:px-10" data-draw-group>
<div class="mx-auto max-w-xl text-center">
<p class="text-sm text-pine/40">[ Our values ]</p>
<h2 class="mt-3 text-4xl font-medium md:text-5xl">Why choose us?</h2>
<p class="mt-4 text-pine/80">Sound financial guidance whenever and wherever you need it. Your next chapter with Fernwise starts today.</p>
</div>
<div class="mt-12 grid gap-5 md:grid-cols-3">
<article class="arches flex flex-col items-center rounded-[1.75rem] bg-stone p-8 text-center" data-reveal>
<h3 class="text-2xl font-medium">Plans That Fit You</h3>
<p class="mt-3 max-w-[16rem] text-pine/80">Strategies shaped around your goals, not a template.</p>
<div class="relative mt-8 h-40 w-40">
<svg viewBox="0 0 120 120" class="h-full w-full -rotate-90" aria-hidden="true"><circle cx="60" cy="60" r="50" fill="none" stroke="#d9d9d5" stroke-width="10"/><circle data-ring cx="60" cy="60" r="50" fill="none" stroke="#1e3d36" stroke-width="10" stroke-linecap="round" pathLength="100" stroke-dasharray="100" stroke-dashoffset="22" class="ring-fill"/></svg>
<p class="absolute inset-0 grid place-content-center"><span class="text-3xl font-semibold">78%</span><span class="text-[10px]">goals reached early</span></p>
</div>
</article>
<article class="flex flex-col items-center overflow-hidden rounded-[1.75rem] bg-pine pt-8 text-center text-white" data-reveal style="--reveal-delay: 90ms">
<h3 class="text-2xl font-medium">Long-Term Thinking</h3>
<p class="mt-3 max-w-[16rem] px-8 text-white/75">A patient approach that compounds into lasting wealth.</p>
<svg viewBox="0 0 300 140" class="mt-auto w-full pt-6" aria-hidden="true"><path class="draw" d="M10 40 C 50 40 60 120 110 110 S 170 40 200 90 S 260 40 300 20" fill="none" stroke="rgba(255,255,255,.35)" stroke-width="3"/><path class="draw" d="M30 110 C 70 110 80 60 120 70 S 180 110 220 60 S 280 30 300 50" fill="none" stroke="#fff" stroke-width="3"/><circle cx="30" cy="110" r="6" fill="#fff"/><circle cx="10" cy="40" r="6" fill="#fff"/></svg>
</article>
<article class="arches flex flex-col items-center rounded-[1.75rem] bg-stone p-8 text-center" data-reveal style="--reveal-delay: 180ms">
<h3 class="text-2xl font-medium">Integrity Always</h3>
<p class="mt-3 max-w-[16rem] text-pine/80">Advisers with decades in the industry, and no hidden incentives.</p>
<span class="mt-8 grid h-28 w-28 place-items-center rounded-full bg-pine text-5xl text-white" aria-hidden="true"><i class="fa-solid fa-shield-halved"></i></span>
<p class="mt-3 text-xs">Honesty and openness come first.</p>
</article>
</div>
</section>
<!-- block:end features -->
<% callouts = [["2.4", "B", "$", "assets guided", "left-4 top-4 md:left-8 md:top-8"], ["4.9", "", "", "average app rating", "right-4 top-1/3 md:right-8"], ["120", "k+", "", "members in 56 countries", "bottom-4 left-1/3 md:bottom-8"]] %>
<!-- block:start stats -->
<section class="mx-auto max-w-7xl px-5 py-16 md:px-10">
<div class="mx-auto max-w-xl text-center">
<h2 class="text-4xl font-medium leading-tight md:text-5xl">Take Charge of Your Money Story</h2>
<p class="mt-4 text-pine/80">Smarter ways to manage, grow and protect what you earn, all in one place built around you.</p>
</div>
<div class="relative mt-12 overflow-hidden rounded-[2rem]">
<img src="https://images.unsplash.com/photo-1600880292203-757bb62b4baf?auto=format&fit=crop&w=1600&q=80" alt="Financial adviser and client celebrating a plan at a desk" class="aspect-[4/3] w-full object-cover md:aspect-[21/9]" loading="lazy">
<% callouts.each do |value, unit, prefix, label, position| %>
<div class="absolute <%= position %> rounded-2xl bg-white/90 px-4 py-3 shadow-lg backdrop-blur" data-reveal>
<p class="text-xl font-semibold md:text-2xl"><%= prefix %><span data-count-to="<%= value %>"><%= value %></span><%= unit %><% if value == "4.9" %> <i class="fa-solid fa-star text-sm text-zest" aria-hidden="true"></i><% end %></p>
<p class="text-xs text-pine/70"><%= label %></p>
</div>
<% end %>
</div>
</section>
<!-- block:end stats -->
<% steps = [["Start From Anywhere", "Open an account in minutes, from any of 56 countries."], ["Keep Funds Safe", "99.9% uptime and the same encryption banks rely on."], ["Track Every Gain", "AI-powered insights on your spending and savings, around the clock."], ["Feel the Difference", "95% of members say they feel clearer about money within three months."]] %>
<!-- block:start process -->
<section class="mx-auto max-w-7xl px-5 py-16 md:px-10">
<div class="arches rounded-[2rem] bg-stone p-6 md:p-10">
<div class="flex flex-col justify-between gap-6 md:flex-row md:items-start">
<h2 class="text-4xl font-medium leading-tight md:text-5xl"><span class="text-pine/45">Change</span> The Way <span class="text-pine/45">You</span><br><span class="text-pine/45">Use</span> Your Money</h2>
<div class="max-w-xs">
<p class="text-pine/80">Reach financial freedom with Fernwise, the clear and clever way to plan your money.</p>
<a href="signup.html" class="mt-4 inline-block rounded-full bg-pine px-6 py-2.5 text-sm font-medium text-white transition hover:bg-pine-light">Get started now</a>
</div>
</div>
<div class="mt-12 grid items-center gap-10 lg:grid-cols-[1fr_1.25fr]">
<div class="relative mx-auto aspect-square w-full max-w-md">
<div class="absolute right-[8%] top-[4%] h-[64%] w-[58%] rounded-3xl bg-white/70 p-4 shadow-sm">
<p class="text-xs font-semibold">Recent activity</p>
<svg viewBox="0 0 160 90" class="mt-6 w-full" aria-hidden="true"><path d="M0 70 L20 40 L35 60 L50 30 L70 70 L90 45 L110 55 L130 10 L160 60 V90 H0 Z" fill="rgba(79,165,149,.25)"/><path d="M0 70 L20 40 L35 60 L50 30 L70 70 L90 45 L110 55 L130 10 L160 60" fill="none" stroke="#1e3d36" stroke-width="2"/></svg>
</div>
<img src="https://images.unsplash.com/photo-1517841905240-472988babdf9?auto=format&fit=crop&crop=focalpoint&fp-x=0.45&fp-y=0.45&w=600&h=800&q=80" alt="Smiling woman in a denim jacket" class="absolute bottom-[6%] left-[16%] h-[78%] w-[52%] rounded-[2rem] object-cover shadow-lg" loading="lazy">
<div class="absolute left-0 top-[30%] rounded-2xl bg-pine/70 px-4 py-3 text-white backdrop-blur" data-reveal>
<p class="text-[9px] text-white/70">Mar 26, 12:00</p>
<p class="text-xl font-semibold">122,637</p>
<p class="mt-1 w-fit rounded-full bg-white/20 px-2 text-[10px]">▲ 21.4%</p>
</div>
<div class="absolute right-0 top-[64%] w-44 rounded-2xl bg-white px-4 py-3 shadow-lg" data-reveal style="--reveal-delay: 120ms">
<p class="text-[10px] text-pine/70">Active members</p>
<p class="flex items-center justify-between font-semibold">56,990 <span class="text-[10px] font-medium"><i class="fa-solid fa-arrow-up" aria-hidden="true"></i> 8.46%</span></p>
<span class="mt-2 block h-1.5 rounded-full bg-stone"><span class="block h-full w-3/5 rounded-full bg-pine"></span></span>
</div>
<div class="absolute bottom-0 left-[4%] w-36 rounded-2xl bg-white px-3 py-2 shadow-lg" data-reveal style="--reveal-delay: 240ms">
<p class="text-[10px] font-semibold">Total balance</p>
<p class="text-xs">$4,200 <span class="text-pine/60">+14%</span></p>
<div class="mt-2 flex h-8 items-end gap-1" aria-hidden="true"><% [30, 45, 25, 80, 100, 40, 70].each do |h| %><span class="w-3 rounded-sm <%= h > 60 ? 'bg-pine' : 'bg-mist' %>" style="height: <%= h %>%"></span><% end %></div>
</div>
</div>
<ol class="grid gap-4 sm:grid-cols-2">
<% steps.each_with_index do |(title, text), index| %>
<li class="flex flex-col rounded-3xl bg-paper p-7" data-reveal style="--reveal-delay: <%= index * 80 %>ms">
<p class="text-sm text-pine/50">Step <%= index + 1 %></p>
<h3 class="mt-3 flex items-center gap-3 text-lg font-medium"><span class="grid h-9 w-9 shrink-0 place-items-center rounded-full border border-pine/40 text-sm" aria-hidden="true"><i class="fa-solid fa-hand-holding-dollar"></i></span><%= title %></h3>
<p class="mt-5 text-pine/80"><%= text %></p>
<a href="services.html" class="mt-6 w-fit border-b border-pine pb-0.5 text-sm">Read more</a>
</li>
<% end %>
</ol>
</div>
</div>
</section>
<!-- block:end process -->
<% services = [["fa-building-columns", "Retirement & Estate Planning", "Plan for retirement and the legacy you leave, with tax-smart strategies."], ["fa-hand-holding-dollar", "Investment Advisory", "Research-backed recommendations that help your portfolio grow steadily."], ["fa-sack-dollar", "Wealth Management", "End-to-end care for your assets, so they're protected and keep growing."], ["fa-piggy-bank", "Smart Savings", "Automatic round-ups and goal pots that save without you thinking about it."], ["fa-credit-card", "Everyday Banking", "A free account and card with instant alerts and zero foreign fees."], ["fa-umbrella", "Insurance Review", "We check your cover every year so you never pay for what you don't need."]] %>
<!-- block:start products -->
<section class="py-16" data-rail>
<div class="mx-auto flex max-w-7xl flex-col justify-between gap-6 px-5 md:flex-row md:items-end md:px-10">
<div>
<h2 class="text-4xl font-medium">Services That Work for You</h2>
<p class="mt-4 max-w-md text-pine/80">Expert advice, investment strategy and wealth management to help you grow, protect and make the most of your financial future.</p>
</div>
<a href="contact.html" class="w-fit rounded-full bg-pine px-6 py-2.5 text-sm font-medium text-white transition hover:bg-pine-light">Let's talk</a>
</div>
<ul data-rail-track class="mt-10 flex snap-x snap-mandatory gap-5 overflow-x-auto px-5 pb-6 pt-4 [scrollbar-width:none] md:px-[max(2.5rem,calc((100vw-80rem)/2+2.5rem))]" tabindex="0" aria-label="Services">
<% services.each_with_index do |(icon, title, text), index| %>
<li data-rail-item data-active="<%= index == 1 %>" class="rail-card flex w-[82%] shrink-0 snap-center flex-col rounded-[1.75rem] bg-stone p-8 sm:w-[24rem]">
<h3 class="flex items-center gap-4 text-lg font-medium"><i class="fa-solid <%= icon %> text-2xl" aria-hidden="true"></i><%= title %></h3>
<p class="rail-muted mt-5 text-pine/80"><%= text %></p>
<a href="services.html" class="mt-6 w-fit border-b border-current pb-0.5 text-sm">Read more</a>
</li>
<% end %>
</ul>
<div class="mt-4 flex justify-center gap-6">
<button type="button" data-rail-prev aria-label="Previous service" class="grid h-10 w-10 place-items-center rounded-full transition hover:bg-stone"><i class="fa-solid fa-chevron-left" aria-hidden="true"></i></button>
<button type="button" data-rail-next aria-label="Next service" class="grid h-10 w-10 place-items-center rounded-full transition hover:bg-stone"><i class="fa-solid fa-chevron-right" aria-hidden="true"></i></button>
</div>
</section>
<!-- block:end products -->
<!-- block:start newsletter -->
<section class="mx-auto max-w-7xl px-5 py-16 md:px-10">
<div class="arches-dark rounded-[2rem] px-6 py-20 text-center text-white md:py-24">
<h2 class="mx-auto max-w-2xl text-4xl font-medium leading-tight md:text-5xl">Become a Member and Meet the Whole Community</h2>
<p class="mx-auto mt-5 max-w-md text-white/80">Learn to make the right call when it matters most, and how to ride out the hard months.</p>
<form data-contact-form data-error="Please enter a valid email address." data-success="Welcome aboard! Check your inbox to confirm." class="mx-auto mt-10 flex max-w-md items-center gap-2 rounded-full bg-cream p-1.5 pl-6" novalidate>
<label class="sr-only" for="member-email">Email address</label>
<input id="member-email" type="email" name="email" required autocomplete="email" placeholder="Enter your email here" class="min-w-0 flex-1 bg-transparent text-pine placeholder:text-pine/50 focus:outline-none">
<button type="submit" aria-label="Join" class="grid h-11 w-11 shrink-0 place-items-center rounded-full bg-white text-pine transition hover:bg-pine hover:text-white"><i class="fa-solid fa-arrow-right" aria-hidden="true"></i></button>
</form>
<p data-form-status class="mt-4 text-sm text-white/90" role="status" aria-live="polite"></p>
</div>
</section>
<!-- block:end newsletter -->
<!-- block:start footer -->
<% columns = { "Account" => [["Savings", "services"], ["Joint accounts", "services"], ["Investing", "services"], ["Freelancers", "pricing"]], "Help" => [["Help center", "faq"], ["Contact", "contact"], ["Sign up", "signup"]], "Finance" => [["Cards", "services"], ["Plans", "pricing"], ["Payments", "services"]], "Company" => [["About us", "about"], ["Services", "services"], ["Careers", "about"]] } %>
<footer class="arches mt-10 bg-stone">
<div class="mx-auto grid max-w-7xl gap-12 px-5 py-16 md:px-10 lg:grid-cols-[1fr_1.6fr]">
<div>
<a href="index.html" class="inline-block leading-none" aria-label="Fernwise Finance home">
<span class="block font-brand text-6xl font-extrabold tracking-tight">Fernwise</span>
<span class="mt-1 block font-brand text-2xl font-bold uppercase tracking-[0.3em] text-pine/90">Finance</span>
</a>
<ul class="mt-8 flex gap-6 text-2xl">
<li><a href="mailto:hello@fernwise.finance" aria-label="Email"><i class="fa-regular fa-envelope" aria-hidden="true"></i></a></li>
<li><a href="https://www.instagram.com" aria-label="Instagram"><i class="fa-brands fa-instagram" aria-hidden="true"></i></a></li>
<li><a href="https://www.whatsapp.com" aria-label="WhatsApp"><i class="fa-brands fa-whatsapp" aria-hidden="true"></i></a></li>
</ul>
</div>
<div class="grid grid-cols-2 gap-8 sm:grid-cols-4">
<% columns.each do |title, links| %>
<div>
<p class="font-medium"><%= title %></p>
<ul class="mt-4 grid gap-3 text-pine/60">
<% links.each do |label, slug| %><li><a href="<%= slug %>.html" class="transition hover:text-pine"><%= label %></a></li><% end %>
</ul>
</div>
<% end %>
</div>
</div>
<div class="mx-auto flex max-w-7xl flex-wrap justify-between gap-4 border-t border-pine/15 px-5 py-6 text-sm text-pine/60 md:px-10">
<p><span class="text-pine">© Fernwise Finance <span data-current-year>2026</span></span> | All rights reserved.</p>
<ul class="flex gap-8"><li><a href="faq.html" class="hover:text-pine">Privacy</a></li><li><a href="faq.html" class="hover:text-pine">Terms of use</a></li><li><a href="faq.html" class="hover:text-pine">Disclosures</a></li></ul>
</div>
</footer>
<!-- block:end footer -->
<script>
document.querySelectorAll('[data-menu-toggle]').forEach((button) => {
const menu = document.getElementById(button.getAttribute('aria-controls'));
if (!menu) return;
button.addEventListener('click', () => {
const open = button.getAttribute('aria-expanded') === 'true';
button.setAttribute('aria-expanded', String(!open));
menu.classList.toggle('hidden', open);
});
});
const reducedMotion = matchMedia('(prefers-reduced-motion: reduce)').matches;
const watchMotion = !reducedMotion && !navigator.webdriver && 'IntersectionObserver' in window;
document.querySelectorAll('[data-chart]').forEach((chart) => {
const line = chart.querySelector('[data-chart-line]');
chart.querySelectorAll('[data-period]').forEach((button) => {
button.addEventListener('click', () => {
chart.querySelectorAll('[data-period]').forEach((other) => other.setAttribute('aria-pressed', String(other === button)));
line.setAttribute('d', button.dataset.path);
chart.querySelector('[data-chart-value]').textContent = button.dataset.value;
chart.querySelector('[data-chart-change]').textContent = button.dataset.change;
});
});
});
document.querySelectorAll('[data-word-reveal]').forEach((root) => {
const words = [...root.querySelectorAll('[data-word]')];
if (!watchMotion) return;
const muted = words.map((word) => word.classList.contains('text-pine/35'));
const paint = () => {
const rect = root.getBoundingClientRect();
const progress = Math.min(Math.max((innerHeight * 0.85 - rect.top) / (rect.height + innerHeight * 0.3), 0), 1);
const lit = Math.round(progress * words.length);
words.forEach((word, index) => {
if (!muted[index]) return;
word.classList.toggle('text-pine', index < lit);
word.classList.toggle('text-pine/35', index >= lit);
});
};
addEventListener('scroll', paint, { passive: true });
paint();
});
(() => {
if (!watchMotion) return;
const rings = document.querySelectorAll('[data-ring]');
const draws = document.querySelectorAll('.draw');
const observer = new IntersectionObserver((entries) => {
entries.forEach((entry) => {
if (!entry.isIntersecting) return;
entry.target.querySelectorAll('[data-ring]').forEach((ring) => { ring.style.strokeDashoffset = ring.dataset.offset; });
entry.target.querySelectorAll('.draw').forEach((path) => path.classList.add('is-drawn'));
observer.unobserve(entry.target);
});
}, { threshold: 0.3 });
rings.forEach((ring) => { ring.dataset.offset = ring.getAttribute('stroke-dashoffset'); ring.style.strokeDashoffset = 100; });
document.querySelectorAll('[data-draw-group]').forEach((group) => observer.observe(group));
if (draws.length) document.documentElement.classList.add('reveal-ready');
})();
(() => {
const counters = document.querySelectorAll('[data-count-to]');
if (!counters.length || !watchMotion) return;
const observer = new IntersectionObserver((entries) => {
entries.forEach((entry) => {
if (!entry.isIntersecting) return;
const el = entry.target;
const target = Number(el.dataset.countTo);
const decimals = (el.dataset.countTo.split('.')[1] || '').length;
const start = performance.now();
const tick = (now) => {
const progress = Math.min((now - start) / 700, 1);
el.textContent = (target * progress).toFixed(decimals);
if (progress < 1) requestAnimationFrame(tick);
};
requestAnimationFrame(tick);
observer.unobserve(el);
});
}, { threshold: 0.6 });
counters.forEach((el) => observer.observe(el));
})();
document.querySelectorAll('[data-rail]').forEach((rail) => {
const track = rail.querySelector('[data-rail-track]');
const items = [...track.querySelectorAll('[data-rail-item]')];
const step = () => (items[0]?.getBoundingClientRect().width || 300) + 20;
const mark = () => {
const center = track.getBoundingClientRect().left + track.clientWidth / 2;
let best = items[0];
items.forEach((item) => {
const rect = item.getBoundingClientRect();
if (Math.abs(rect.left + rect.width / 2 - center) < Math.abs(best.getBoundingClientRect().left + best.getBoundingClientRect().width / 2 - center)) best = item;
});
items.forEach((item) => { item.dataset.active = String(item === best); });
};
let frame;
track.addEventListener('scroll', () => { cancelAnimationFrame(frame); frame = requestAnimationFrame(mark); }, { passive: true });
rail.querySelector('[data-rail-prev]')?.addEventListener('click', () => track.scrollBy({ left: -step(), behavior: reducedMotion ? 'auto' : 'smooth' }));
rail.querySelector('[data-rail-next]')?.addEventListener('click', () => track.scrollBy({ left: step(), behavior: reducedMotion ? 'auto' : 'smooth' }));
});
document.querySelectorAll('[data-billing]').forEach((root) => {
root.addEventListener('change', (event) => {
if (event.target.name !== 'billing') return;
const yearly = event.target.value === 'yearly';
root.querySelectorAll('[data-monthly]').forEach((price) => { price.textContent = yearly ? price.dataset.yearly : price.dataset.monthly; });
root.querySelectorAll('[data-billing-note]').forEach((note) => { note.textContent = yearly ? 'per month, billed yearly' : 'per month'; });
});
});
document.querySelectorAll('[data-faq-search]').forEach((root) => {
const input = root.querySelector('[data-faq-input]');
const items = [...root.querySelectorAll('[data-faq-item]')];
const empty = root.querySelector('[data-faq-empty]');
const count = root.querySelector('[data-faq-count]');
let topic = 'all';
const apply = () => {
const query = String(input.value || '').trim().toLowerCase();
let shown = 0;
items.forEach((item) => {
const match = (topic === 'all' || item.dataset.topic === topic) && (!query || item.textContent.toLowerCase().includes(query));
item.hidden = !match;
if (match) shown += 1;
});
empty.hidden = shown > 0;
count.textContent = shown;
};
input.addEventListener('input', apply);
root.querySelectorAll('[data-faq-topic]').forEach((chip) => {
chip.addEventListener('click', () => {
topic = chip.dataset.faqTopic;
root.querySelectorAll('[data-faq-topic]').forEach((other) => { other.setAttribute('aria-pressed', String(other === chip)); other.selected = other === chip; });
apply();
});
});
});
document.querySelectorAll('[data-accordion]').forEach((accordion) => {
accordion.addEventListener('click', (event) => {
const trigger = event.target.closest('[data-accordion-trigger]');
if (!trigger) return;
const open = trigger.getAttribute('aria-expanded') !== 'true';
trigger.setAttribute('aria-expanded', String(open));
document.getElementById(trigger.getAttribute('aria-controls')).hidden = !open;
});
});
document.querySelectorAll('[data-service-tabs]').forEach((root) => {
const tabs = [...root.querySelectorAll('[role="tab"]')];
const select = (tab) => tabs.forEach((other) => {
const active = other === tab;
other.setAttribute('aria-selected', String(active));
other.tabIndex = active ? 0 : -1;
document.getElementById(other.getAttribute('aria-controls')).hidden = !active;
});
tabs.forEach((tab, index) => {
tab.addEventListener('click', () => select(tab));
tab.addEventListener('keydown', (event) => {
const move = { ArrowRight: 1, ArrowDown: 1, ArrowLeft: -1, ArrowUp: -1 }[event.key];
if (!move) return;
event.preventDefault();
const next = tabs[(index + move + tabs.length) % tabs.length];
next.focus();
select(next);
});
});
});
document.querySelectorAll('[data-timeline]').forEach((timeline) => {
const fill = timeline.querySelector('[data-timeline-fill]');
if (!fill) return;
const update = () => {
const rect = timeline.getBoundingClientRect();
const progress = Math.min(Math.max((innerHeight * 0.6 - rect.top) / rect.height, 0), 1);
fill.style.transform = `scaleY(${watchMotion ? progress : 1})`;
};
addEventListener('scroll', update, { passive: true });
update();
});
document.querySelectorAll('[data-wizard]').forEach((wizard) => {
const steps = [...wizard.querySelectorAll('[data-wizard-step]')];
const bar = wizard.querySelector('[data-wizard-bar]');
const label = wizard.querySelector('[data-wizard-label]');
const status = wizard.querySelector('[data-form-status]');
let current = 0;
const show = (index) => {
current = index;
steps.forEach((step, i) => { step.hidden = i !== index; });
bar.style.width = `${((index + 1) / steps.length) * 100}%`;
bar.value = (index + 1) / steps.length;
label.textContent = `Step ${index + 1} of ${steps.length}`;
wizard.querySelectorAll('[data-wizard-dot]').forEach((dot, i) => dot.classList.toggle('step-primary', i <= index));
};
const valid = () => {
const fields = [...steps[current].querySelectorAll('[required]')];
const bad = fields.find((field) => !field.checkValidity());
if (bad) { status.textContent = wizard.dataset.error; bad.focus(); return false; }
status.textContent = '';
return true;
};
wizard.addEventListener('click', (event) => {
if (event.target.closest('[data-wizard-next]') && valid()) show(Math.min(current + 1, steps.length - 1));
if (event.target.closest('[data-wizard-back]')) show(Math.max(current - 1, 0));
});
wizard.addEventListener('submit', (event) => {
event.preventDefault();
if (!valid()) return;
const plan = wizard.querySelector('[name="plan"]:checked')?.value || 'Starter';
status.textContent = `Account created on the ${plan} plan. Check your inbox to verify your email.`;
});
show(0);
});
document.querySelectorAll('[data-contact-form]').forEach((form) => {
form.addEventListener('submit', (event) => {
event.preventDefault();
const status = form.parentElement.querySelector('[data-form-status]');
if (!form.checkValidity()) {
status.textContent = form.dataset.error;
form.querySelector(':invalid')?.focus();
return;
}
status.textContent = form.dataset.success;
form.reset();
});
});
document.querySelectorAll('[data-current-year]').forEach((el) => { el.textContent = new Date().getFullYear(); });
(() => {
const items = document.querySelectorAll('[data-reveal]');
if (!items.length || !watchMotion) return;
document.documentElement.classList.add('reveal-ready');
const observer = new IntersectionObserver((entries) => {
entries.forEach((entry) => {
if (!entry.isIntersecting) return;
entry.target.classList.add('is-visible');
observer.unobserve(entry.target);
});
}, { rootMargin: '0px 0px -10% 0px' });
items.forEach((item) => observer.observe(item));
})();
</script>
</body>
</html>
Unlimited access to all templates
Unlock our entire library of premium UI kits, dashboards, and landing pages. Renews automatically, cancel anytime.
$20
/ 3 months
or $60 / year
Get Unlimited Access