Nex AGI Nex N2.5 Mini – Personal Finance
via Nex AGI · Generated
- AIMAC Debt 0.00
- Cost $0.0027
- Total Violations 0
- HTML Size 54 KB
- Em Dashes 8
Screenshot
View Live Page
Artifacts
View Generated HTML
<!doctype html>
<html lang="en">
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<meta name="description" content="Northlight Money helps you budget, invest, build credit, and plan for retirement with clear, practical guidance.">
<meta name="theme-color" content="#0d5c56">
<title>Northlight Money | Personal Finance, Made Clear</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=DM+Sans:wght@400;500;600;700&family=Manrope:wght@500;600;700;800&display=swap" rel="stylesheet">
<style>
:root {
--brand: #0d5c56;
--brand-deep: #073d3b;
--brand-soft: #e9f5ef;
--lime: #d8f7a4;
--ink: #102a2a;
--ink-soft: #596d69;
--cream: #fbfcfa;
--paper: #ffffff;
--line: #dce8e1;
--warm: #f4f7f1;
--danger: #b54848;
--radius-lg: 30px;
--radius-md: 18px;
--shadow: 0 22px 60px rgba(15, 63, 59, 0.12);
--max: 1180px;
}
* { box-sizing: border-box; }
html { scroll-behavior: smooth; }
body {
margin: 0;
background: var(--cream);
color: var(--ink);
font-family: "DM Sans", ui-sans-serif, system-ui, -apple-system, BlinkMacSystemFont, "Segoe UI", sans-serif;
line-height: 1.65;
-webkit-font-smoothing: antialiased;
}
body.nav-open { overflow: hidden; }
img { display: block; max-width: 100%; }
a { color: inherit; text-decoration: none; }
button, input, textarea, select { font: inherit; }
button { cursor: pointer; }
h1, h2, h3, p { margin-top: 0; }
h1, h2, h3 { font-family: "Manrope", "DM Sans", ui-sans-serif, sans-serif; line-height: 1.12; }
::selection { background: var(--lime); color: var(--ink); }
.container { width: min(calc(100% - 40px), var(--max)); margin-inline: auto; }
.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-link {
position: absolute;
left: 16px;
top: -60px;
z-index: 100;
padding: 10px 16px;
border-radius: 999px;
background: var(--ink);
color: #fff;
transition: top .2s ease;
}
.skip-link:focus { top: 12px; }
.site-header {
position: sticky;
top: 0;
z-index: 20;
border-bottom: 1px solid rgba(16, 42, 42, 0.08);
background: rgba(251, 252, 250, 0.9);
backdrop-filter: blur(16px);
}
.header-inner {
min-height: 84px;
display: flex;
align-items: center;
gap: 26px;
}
.brand { display: flex; align-items: center; gap: 12px; flex-shrink: 0; }
.brand img { width: 58px; height: 58px; border-radius: 17px; object-fit: cover; box-shadow: 0 8px 20px rgba(13, 92, 86, 0.16); }
.brand-copy { display: grid; line-height: 1.1; }
.brand-copy strong { font-family: "Manrope", sans-serif; font-size: 18px; letter-spacing: -0.3px; }
.brand-copy small { margin-top: 4px; color: var(--ink-soft); font-size: 11px; letter-spacing: 0.01em; }
.nav-toggle {
display: none;
width: 44px;
height: 44px;
margin-left: auto;
align-items: center;
justify-content: center;
border: 1px solid var(--line);
border-radius: 13px;
background: #fff;
}
.nav-toggle span,
.nav-toggle span::before,
.nav-toggle span::after {
display: block;
width: 19px;
height: 2px;
background: var(--ink);
border-radius: 4px;
transition: transform .2s ease, opacity .2s ease;
}
.nav-toggle span { position: relative; }
.nav-toggle span::before,
.nav-toggle span::after { content: ""; position: absolute; left: 0; }
.nav-toggle span::before { top: -6px; }
.nav-toggle span::after { top: 6px; }
.nav-toggle.is-active span { background: transparent; }
.nav-toggle.is-active span::before { top: 0; transform: rotate(45deg); }
.nav-toggle.is-active span::after { top: 0; transform: rotate(-45deg); }
.main-nav { display: flex; align-items: center; gap: 25px; margin-left: auto; }
.main-nav a {
position: relative;
padding: 8px 0;
color: var(--ink-soft);
font-size: 14px;
font-weight: 600;
}
.main-nav a::after {
content: "";
position: absolute;
right: 0;
bottom: 1px;
left: 0;
height: 2px;
border-radius: 4px;
background: var(--brand);
transform: scaleX(0);
transform-origin: left;
transition: transform .2s ease;
}
.main-nav a:hover, .main-nav a:focus-visible { color: var(--brand); }
.main-nav a:hover::after, .main-nav a:focus-visible::after { transform: scaleX(1); }
.button {
display: inline-flex;
align-items: center;
justify-content: center;
gap: 9px;
min-height: 50px;
padding: 0 20px;
border: 1px solid transparent;
border-radius: 999px;
font-weight: 700;
line-height: 1;
transition: transform .2s ease, box-shadow .2s ease, background .2s ease, border-color .2s ease;
}
.button:hover { transform: translateY(-2px); }
.button-primary { background: var(--brand); color: #fff; box-shadow: 0 12px 28px rgba(13, 92, 86, 0.22); }
.button-primary:hover { background: #0a4d48; box-shadow: 0 15px 34px rgba(13, 92, 86, 0.28); }
.button-secondary { border-color: var(--line); background: rgba(255, 255, 255, 0.72); color: var(--ink); }
.button-secondary:hover { border-color: #a8c5b8; background: #fff; }
.button-light { background: var(--lime); color: var(--brand-deep); }
.button-light:hover { background: #e4ffc0; }
.button-text { min-height: auto; padding: 7px 0; color: var(--brand); font-size: 14px; }
.button-text::after { display: none; }
.header-cta { min-height: 43px; padding-inline: 17px; font-size: 13px; }
.hero {
position: relative;
overflow: hidden;
padding: 94px 0 78px;
background:
radial-gradient(circle at 82% 18%, rgba(216, 247, 164, 0.58), transparent 31%),
linear-gradient(135deg, #fbfdf9 0%, #eef6f0 100%);
}
.hero::before {
content: "";
position: absolute;
width: 340px;
height: 340px;
right: -130px;
bottom: -180px;
border: 1px solid rgba(13, 92, 86, 0.12);
border-radius: 50%;
}
.hero-grid { display: grid; grid-template-columns: minmax(0, 1.02fr) minmax(420px, 0.98fr); gap: 70px; align-items: center; }
.eyebrow, .section-kicker {
display: inline-flex;
align-items: center;
gap: 9px;
color: var(--brand);
font-size: 12px;
font-weight: 800;
letter-spacing: 0.12em;
text-transform: uppercase;
}
.eyebrow::before, .section-kicker::before { content: ""; width: 23px; height: 2px; border-radius: 5px; background: currentColor; }
.hero h1 { max-width: 730px; margin: 18px 0 22px; font-size: clamp(43px, 5vw, 72px); letter-spacing: -3.1px; }
.lead { max-width: 640px; margin-bottom: 0; color: var(--ink-soft); font-size: clamp(17px, 1.5vw, 20px); }
.hero-actions { display: flex; flex-wrap: wrap; gap: 11px; margin-top: 30px; }
.hero-proof { display: flex; flex-wrap: wrap; gap: 27px; margin-top: 39px; padding-top: 23px; border-top: 1px solid rgba(16, 42, 42, 0.12); }
.proof-point { display: grid; gap: 1px; }
.proof-point strong { font-family: "Manrope", sans-serif; font-size: 22px; letter-spacing: -0.6px; }
.proof-point span { color: var(--ink-soft); font-size: 12px; }
.hero-visual { position: relative; min-height: 540px; }
.hero-visual > img { width: 100%; height: 540px; object-fit: cover; border-radius: 32px; filter: saturate(0.72); box-shadow: var(--shadow); }
.visual-card {
position: absolute;
padding: 17px 19px;
border: 1px solid rgba(255, 255, 255, 0.82);
border-radius: 18px;
background: rgba(255, 255, 255, 0.9);
box-shadow: 0 16px 36px rgba(15, 63, 59, 0.14);
backdrop-filter: blur(12px);
}
.visual-card.one { top: 43px; left: -36px; width: 210px; }
.visual-card.two { right: -23px; bottom: 35px; width: 220px; }
.visual-card small { display: block; color: var(--ink-soft); font-size: 11px; font-weight: 700; letter-spacing: 0.08em; text-transform: uppercase; }
.visual-card strong { display: block; margin-top: 4px; font-family: "Manrope", sans-serif; font-size: 21px; letter-spacing: -0.5px; }
.visual-card.two strong { color: var(--brand); }
.visual-card .mini-line { display: flex; align-items: center; gap: 7px; margin-top: 11px; color: var(--ink-soft); font-size: 11px; }
.status-dot { width: 8px; height: 8px; border-radius: 50%; background: #68c787; box-shadow: 0 0 0 4px rgba(104, 199, 135, 0.16); }
.strip { background: var(--brand-deep); color: #e9f5ef; }
.strip-inner { display: flex; align-items: center; justify-content: space-between; gap: 24px; padding: 17px 0; font-size: 13px; }
.strip-label { color: var(--lime); font-weight: 800; letter-spacing: 0.1em; text-transform: uppercase; }
.strip-item { display: flex; align-items: center; gap: 8px; }
.strip-item::before { content: "✓"; color: var(--lime); font-weight: 800; }
.section { padding: 110px 0; }
.section-tint { background: var(--warm); }
.section-dark {
color: #fff;
background:
radial-gradient(circle at 8% 15%, rgba(216, 247, 164, 0.16), transparent 27%),
linear-gradient(135deg, #073d3b 0%, #0c514c 58%, #082f2e 100%);
}
.section-head { max-width: 730px; margin-bottom: 48px; }
.section-head h2 { margin: 13px 0 19px; font-size: clamp(34px, 4vw, 52px); letter-spacing: -1.8px; }
.section-head p { margin-bottom: 0; color: var(--ink-soft); font-size: 17px; }
.section-dark .section-head p { color: #c9ded9; }
.section-dark .section-kicker { color: var(--lime); }
.split { display: grid; grid-template-columns: 1fr 1fr; gap: 72px; align-items: center; }
.split.reverse .split-media { order: 2; }
.split-copy h2 { margin: 13px 0 20px; font-size: clamp(34px, 4vw, 52px); letter-spacing: -1.8px; }
.split-copy p { color: var(--ink-soft); font-size: 17px; }
.split-copy .body-copy + .body-copy { margin-top: 15px; }
.check-list { display: grid; gap: 12px; margin: 26px 0 30px; padding: 0; list-style: none; }
.check-list li { display: flex; align-items: flex-start; gap: 10px; color: var(--ink); font-weight: 600; }
.check-list svg { flex: 0 0 auto; margin-top: 3px; color: var(--brand); }
.button-row { display: flex; flex-wrap: wrap; align-items: center; gap: 19px; }
.split-media { position: relative; }
.split-media > img { width: 100%; aspect-ratio: 4 / 3; object-fit: cover; border-radius: 28px; box-shadow: var(--shadow); }
.image-caption { position: absolute; right: 22px; bottom: 21px; padding: 10px 13px; border-radius: 999px; background: rgba(255, 255, 255, 0.9); color: var(--brand-deep); font-size: 11px; font-weight: 800; letter-spacing: 0.06em; text-transform: uppercase; backdrop-filter: blur(8px); }
.budget-card { position: absolute; bottom: -27px; left: -31px; width: 255px; padding: 20px; border: 1px solid rgba(255, 255, 255, 0.8); border-radius: 20px; background: #fff; box-shadow: var(--shadow); }
.budget-card small { color: var(--ink-soft); font-weight: 700; letter-spacing: 0.08em; text-transform: uppercase; }
.budget-card strong { display: block; margin: 5px 0 14px; font-family: "Manrope", sans-serif; font-size: 27px; letter-spacing: -0.8px; }
.budget-card .budget-label { display: flex; justify-content: space-between; gap: 10px; margin-top: 9px; color: var(--ink-soft); font-size: 11px; }
.progress-track { height: 8px; overflow: hidden; border-radius: 999px; background: #dfe9e2; }
.progress-fill { display: block; width: 0; height: 100%; border-radius: inherit; background: linear-gradient(90deg, var(--brand), #65b88d); transition: width .45s ease; }
.feature-row { display: grid; grid-template-columns: repeat(3, 1fr); gap: 14px; margin-top: 30px; }
.feature-card { padding: 20px; border: 1px solid var(--line); border-radius: 18px; background: rgba(255, 255, 255, 0.72); }
.feature-icon { display: grid; width: 38px; height: 38px; place-items: center; border-radius: 12px; background: var(--brand-soft); color: var(--brand); }
.feature-card h3 { margin: 15px 0 7px; font-size: 16px; letter-spacing: -0.3px; }
.feature-card p { margin-bottom: 0; color: var(--ink-soft); font-size: 13px; }
.retirement-points { display: grid; gap: 14px; margin: 27px 0 30px; padding: 0; list-style: none; }
.retirement-points li { display: flex; gap: 11px; align-items: flex-start; color: #eaf7f2; font-weight: 600; }
.retirement-points svg { flex: 0 0 auto; margin-top: 3px; color: var(--lime); }
.retirement-card { display: flex; align-items: center; justify-content: space-between; gap: 18px; margin-top: 28px; padding: 20px 22px; border: 1px solid rgba(216, 247, 164, 0.24); border-radius: 18px; background: rgba(255, 255, 255, 0.07); }
.retirement-card strong { display: block; font-family: "Manrope", sans-serif; font-size: 20px; }
.retirement-card span { display: block; color: #c9ded9; font-size: 12px; }
.tools-section { background: #fff; }
.tool-shell { display: grid; grid-template-columns: 0.78fr 1.22fr; gap: 43px; align-items: start; padding: 42px; border: 1px solid var(--line); border-radius: var(--radius-lg); background: #f0f6f1; box-shadow: 0 18px 50px rgba(15, 63, 59, 0.08); }
.tool-intro { position: sticky; top: 120px; }
.tool-intro h3 { margin: 13px 0 13px; font-size: 29px; letter-spacing: -0.8px; }
.tool-intro p { color: var(--ink-soft); }
.tool-intro .tool-note { display: flex; gap: 10px; margin-top: 25px; padding: 14px; border-radius: 14px; background: #fff; color: var(--ink-soft); font-size: 12px; }
.tool-note svg { flex: 0 0 auto; margin-top: 1px; color: var(--brand); }
.calculator-form { display: grid; grid-template-columns: 1fr 1fr; gap: 18px; }
.field { display: grid; gap: 7px; }
.field.full { grid-column: 1 / -1; }
.field label { color: var(--ink); font-size: 12px; font-weight: 800; letter-spacing: 0.04em; text-transform: uppercase; }
.input-wrap { position: relative; }
.input-wrap span { position: absolute; top: 50%; left: 15px; color: var(--ink-soft); font-size: 15px; transform: translateY(-50%); }
.input-wrap input { width: 100%; padding: 14px 15px 14px 38px; border: 1px solid var(--line); border-radius: 12px; outline: none; background: #fff; color: var(--ink); transition: border-color .2s ease, box-shadow .2s ease; }
.input-wrap input:focus { border-color: var(--brand); box-shadow: 0 0 0 4px rgba(13, 92, 86, 0.11); }
.calculator-result { grid-column: 1 / -1; display: grid; grid-template-columns: repeat(3, 1fr); gap: 12px; margin-top: 3px; }
.result-card { min-height: 126px; padding: 18px; border: 1px solid var(--line); border-radius: 16px; background: #fff; }
.result-card span { display: block; color: var(--ink-soft); font-size: 11px; font-weight: 700; letter-spacing: 0.06em; text-transform: uppercase; }
.result-card strong { display: block; margin-top: 8px; font-family: "Manrope", sans-serif; font-size: 25px; letter-spacing: -0.7px; }
.result-card.is-negative strong { color: var(--danger); }
.result-card small { display: block; margin-top: 7px; color: var(--ink-soft); font-size: 11px; }
.result-progress { grid-column: 1 / -1; padding: 17px 18px; border: 1px solid var(--line); border-radius: 16px; background: #fff; }
.result-progress-head { display: flex; justify-content: space-between; gap: 15px; color: var(--ink); font-size: 12px; font-weight: 700; }
.result-progress-head span:last-child { color: var(--ink-soft); font-weight: 500; }
.result-progress .progress-track { margin-top: 12px; }
.result-progress p { margin: 12px 0 0; color: var(--ink-soft); font-size: 12px; }
.quote-grid { display: grid; grid-template-columns: repeat(3, 1fr); gap: 17px; }
.quote-card { display: flex; flex-direction: column; min-height: 260px; padding: 25px; border: 1px solid var(--line); border-radius: 22px; background: #fff; }
.quote-card blockquote { margin: 0; color: var(--ink); font-size: 16px; line-height: 1.6; }
.quote-card blockquote::before { content: "“"; display: block; height: 29px; color: var(--brand); font-family: Georgia, serif; font-size: 42px; line-height: 0.75; }
.quote-person { display: flex; align-items: center; gap: 11px; margin-top: auto; }
.quote-person img { width: 44px; height: 44px; border-radius: 50%; object-fit: cover; }
.quote-person strong { display: block; font-size: 13px; }
.quote-person span { color: var(--ink-soft); font-size: 11px; }
.stars { color: #e4a92b; letter-spacing: 2px; }
.faq-layout { display: grid; grid-template-columns: 0.72fr 1.28fr; gap: 72px; align-items: start; }
.faq-list { border-top: 1px solid var(--line); }
.faq-list details { padding: 0 0 20px; margin-bottom: 20px; border-bottom: 1px solid var(--line); }
.faq-list summary { display: flex; align-items: center; justify-content: space-between; gap: 20px; cursor: pointer; list-style: none; font-family: "Manrope", sans-serif; font-weight: 700; }
.faq-list summary::-webkit-details-marker { display: none; }
.faq-list summary::after { content: "+"; display: grid; width: 29px; height: 29px; flex: 0 0 auto; place-items: center; border-radius: 50%; background: var(--brand-soft); color: var(--brand); font-family: "DM Sans", sans-serif; font-size: 19px; }
.faq-list details[open] summary::after { content: "−"; }
.faq-list details p { margin: 12px 0 0; color: var(--ink-soft); font-size: 14px; }
.contact-section { background: var(--warm); }
.contact-grid { display: grid; grid-template-columns: 1fr 1fr; gap: 72px; align-items: center; }
.contact-copy h2 { margin: 13px 0 19px; font-size: clamp(34px, 4vw, 52px); letter-spacing: -1.8px; }
.contact-copy p { max-width: 530px; color: var(--ink-soft); font-size: 17px; }
.contact-methods { display: grid; gap: 12px; margin-top: 28px; }
.contact-method { display: flex; align-items: center; gap: 11px; color: var(--ink); font-size: 13px; font-weight: 600; }
.contact-method svg { color: var(--brand); }
.contact-form { padding: 30px; border: 1px solid var(--line); border-radius: 25px; background: #fff; box-shadow: 0 18px 48px rgba(15, 63, 59, 0.08); }
.contact-form h3 { margin-bottom: 6px; font-size: 22px; letter-spacing: -0.5px; }
.contact-form > p { margin-bottom: 22px; color: var(--ink-soft); font-size: 13px; }
.form-row { display: grid; grid-template-columns: 1fr 1fr; gap: 14px; }
.form-field { display: grid; gap: 6px; }
.form-field label { color: var(--ink); font-size: 11px; font-weight: 800; letter-spacing: 0.05em; text-transform: uppercase; }
.form-field input, .form-field select, .form-field textarea { width: 100%; padding: 13px 14px; border: 1px solid var(--line); border-radius: 11px; outline: none; background: #fbfcfa; color: var(--ink); }
.form-field input:focus, .form-field select:focus, .form-field textarea:focus { border-color: var(--brand); box-shadow: 0 0 0 4px rgba(13, 92, 86, 0.1); }
.form-field textarea { min-height: 110px; resize: vertical; }
.form-submit { width: 100%; margin-top: 18px; }
.form-success { display: grid; min-height: 270px; place-items: center; padding: 28px; border-radius: 18px; background: var(--brand-soft); text-align: center; }
.form-success svg { margin: 0 auto 12px; color: var(--brand); }
.form-success h3 { margin-bottom: 5px; }
.form-success p { margin-bottom: 0; color: var(--ink-soft); font-size: 13px; }
.site-footer { padding: 72px 0 24px; background: #0b312f; color: #d9e8e4; }
.footer-grid { display: grid; grid-template-columns: 1.35fr 0.7fr 0.7fr 1fr; gap: 42px; }
.footer-brand .brand-copy strong { color: #fff; }
.footer-brand .brand-copy small { color: #a9c7c0; }
.footer-brand p { max-width: 310px; margin: 19px 0 0; color: #a9c7c0; font-size: 13px; }
.social-links { display: flex; gap: 9px; margin-top: 22px; }
.social-links a { display: grid; width: 36px; height: 36px; place-items: center; border: 1px solid rgba(255, 255, 255, 0.17); border-radius: 50%; color: #e9f5ef; transition: background .2s ease, border-color .2s ease; }
.social-links a:hover { background: rgba(255, 255, 255, 0.1); border-color: rgba(255, 255, 255, 0.32); }
.footer-col h3 { margin: 5px 0 15px; color: #fff; font-size: 13px; letter-spacing: 0.04em; text-transform: uppercase; }
.footer-col ul { display: grid; gap: 10px; margin: 0; padding: 0; list-style: none; }
.footer-col a { color: #a9c7c0; font-size: 13px; }
.footer-col a:hover { color: #fff; }
.footer-contact p { margin: 0 0 9px; color: #a9c7c0; font-size: 13px; }
.footer-contact a { color: #e9f5ef; font-weight: 700; }
.footer-bottom { display: flex; justify-content: space-between; gap: 20px; margin-top: 53px; padding-top: 22px; border-top: 1px solid rgba(255, 255, 255, 0.12); color: #8fb2aa; font-size: 11px; }
.footer-bottom-links { display: flex; flex-wrap: wrap; gap: 18px; }
@media (max-width: 1000px) {
.hero-grid, .split, .tool-shell, .faq-layout, .contact-grid { gap: 42px; }
.hero-grid { grid-template-columns: 1fr; }
.hero-visual { width: min(100%, 640px); }
.split.reverse .split-media { order: 0; }
.footer-grid { grid-template-columns: 1.3fr 1fr 1fr; }
.footer-contact { grid-column: 1 / -1; }
}
@media (max-width: 760px) {
.container { width: min(calc(100% - 30px), var(--max)); }
.header-inner { min-height: 74px; }
.brand img { width: 48px; height: 48px; border-radius: 14px; }
.brand-copy strong { font-size: 16px; }
.brand-copy small { font-size: 9px; }
.nav-toggle { display: flex; }
.header-cta { display: none; }
.main-nav {
position: absolute;
top: calc(100% + 1px);
right: 15px;
left: 15px;
display: none;
flex-direction: column;
align-items: stretch;
gap: 0;
padding: 10px;
border: 1px solid var(--line);
border-radius: 0 0 18px 18px;
background: #fff;
box-shadow: var(--shadow);
}
.main-nav.is-open { display: flex; }
.main-nav a { padding: 13px 14px; border-radius: 10px; }
.main-nav a:hover, .main-nav a:focus-visible { background: var(--brand-soft); }
.main-nav a::after { display: none; }
.hero { padding: 65px 0 58px; }
.hero h1 { letter-spacing: -2px; }
.hero-proof { gap: 18px; }
.proof-point strong { font-size: 19px; }
.visual-card.one { left: 0; }
.visual-card.two { right: 0; }
.strip-inner { align-items: flex-start; flex-direction: column; gap: 8px; }
.section { padding: 78px 0; }
.section-head { margin-bottom: 34px; }
.split, .tool-shell, .faq-layout, .contact-grid { grid-template-columns: 1fr; }
.split-copy h2, .contact-copy h2 { font-size: clamp(34px, 10vw, 48px); }
.split-media > img { aspect-ratio: 4 / 3; }
.budget-card { bottom: -20px; left: 0; width: min(245px, 80%); }
.feature-row, .quote-grid { grid-template-columns: 1fr; }
.tool-shell { padding: 26px; }
.tool-intro { position: static; }
.calculator-form, .form-row { grid-template-columns: 1fr; }
.calculator-result { grid-template-columns: 1fr; }
.footer-grid { grid-template-columns: 1fr 1fr; gap: 32px 24px; }
.footer-contact { grid-column: auto; }
.footer-bottom { flex-direction: column; }
}
@media (prefers-reduced-motion: reduce) {
*, *::before, *::after { scroll-behavior: auto !important; transition-duration: 0.01ms !important; animation-duration: 0.01ms !important; }
}
</style>
</head>
<body>
<a class="skip-link" href="#main-content">Skip to main content</a>
<header class="site-header">
<div class="container header-inner">
<a class="brand" href="#home" aria-label="Northlight Money home">
<img src="https://placehold.co/160x52/0d5c56/ffffff?text=Northlight" alt="Northlight Money logo placeholder">
<span class="brand-copy">
<strong>Northlight Money</strong>
<small>Clarity for every dollar. Confidence for every decade.</small>
</span>
</a>
<button class="nav-toggle" type="button" aria-expanded="false" aria-controls="primary-navigation" aria-label="Open navigation"><span></span></button>
<nav class="main-nav" id="primary-navigation" aria-label="Primary navigation">
<a href="#home">Home</a>
<a href="#budget">Budget</a>
<a href="#investing">Investment</a>
<a href="#retirement">Retirement</a>
<a href="#credit">Credit</a>
<a href="#tools">Tools</a>
<a href="#contact">Contact</a>
</nav>
<a class="button button-primary header-cta" href="#tools">Start planning</a>
</div>
</header>
<main id="main-content">
<section class="hero" id="home">
<div class="container hero-grid">
<div class="hero-copy">
<span class="eyebrow">A clearer way to manage money</span>
<h1>Turn financial noise into a plan you can follow.</h1>
<p class="lead">Northlight Money brings budgeting, investing, credit health, and retirement planning into one practical system—so your money has a direction, not just a balance.</p>
<div class="hero-actions">
<a class="button button-primary" href="#budget">Create Budget <span aria-hidden="true">→</span></a>
<a class="button button-secondary" href="#investing">Explore Investing</a>
</div>
<div class="hero-proof" aria-label="Northlight Money highlights">
<div class="proof-point"><strong>12k+</strong><span>members building better habits</span></div>
<div class="proof-point"><strong>92%</strong><span>feel more in control</span></div>
<div class="proof-point"><strong>4.9/5</strong><span>average member rating</span></div>
</div>
</div>
<div class="hero-visual" aria-label="A visual representation of a personal finance plan">
<img src="https://picsum.photos/1200/850?grayscale" alt="Person reviewing financial documents at a bright desk" loading="eager">
<div class="visual-card one">
<small>Monthly surplus</small>
<strong>+$1,370</strong>
<div class="mini-line"><span class="status-dot"></span>On track for June</div>
</div>
<div class="visual-card two">
<small>Emergency fund</small>
<strong>$15,420</strong>
<div class="mini-line"><span class="status-dot"></span>3.4 months covered</div>
</div>
</div>
</div>
</section>
<div class="strip" aria-label="Platform benefits">
<div class="container strip-inner">
<span class="strip-label">Built for real life</span>
<span class="strip-item">Simple budgeting</span>
<span class="strip-item">Smart saving</span>
<span class="strip-item">Investing with purpose</span>
<span class="strip-item">Credit clarity</span>
</div>
</div>
<section class="section section-tint" id="budget">
<div class="container split">
<div class="split-copy">
<span class="section-kicker">Budgeting</span>
<h2>Start with a budget that works with your life.</h2>
<p class="body-copy">Money moves faster than most spreadsheets. Northlight turns your income, bills, and goals into a living plan you can update in minutes. Instead of judging every purchase, you will see where your money goes, where it can go further, and what is possible next.</p>
<p class="body-copy">Our flexible 50/30/20 framework makes room for essentials, meaningful spending, and future-you. Categories adapt to your rhythm, so a busy week does not mean abandoning the plan. Small, consistent adjustments compound into real financial breathing room.</p>
<ul class="check-list">
<li><svg width="18" height="18" viewBox="0 0 20 20" fill="none" aria-hidden="true"><circle cx="10" cy="10" r="9" fill="currentColor" opacity=".12"/><path d="m6 10 2.3 2.3L14 7" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"/></svg>See fixed and flexible spending at a glance</li>
<li><svg width="18" height="18" viewBox="0 0 20 20" fill="none" aria-hidden="true"><circle cx="10" cy="10" r="9" fill="currentColor" opacity=".12"/><path d="m6 10 2.3 2.3L14 7" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"/></svg>Set a savings target without the guilt trip</li>
<li><svg width="18" height="18" viewBox="0 0 20 20" fill="none" aria-hidden="true"><circle cx="10" cy="10" r="9" fill="currentColor" opacity=".12"/><path d="m6 10 2.3 2.3L14 7" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"/></svg>Get gentle alerts before a category runs dry</li>
<li><svg width="18" height="18" viewBox="0 0 20 20" fill="none" aria-hidden="true"><circle cx="10" cy="10" r="9" fill="currentColor" opacity=".12"/><path d="m6 10 2.3 2.3L14 7" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"/></svg>Build habits that survive busy weeks</li>
</ul>
<div class="button-row">
<a class="button button-primary" href="#tools">Create Budget</a>
<a class="button button-text" href="#tools">See the 50/30/20 method <span aria-hidden="true">→</span></a>
</div>
</div>
<div class="split-media">
<img src="https://picsum.photos/900/650?grayscale" alt="A person organizing a home budget and financial notes" loading="lazy">
<span class="image-caption">Your plan, in focus</span>
<div class="budget-card" aria-label="Sample monthly budget summary">
<small>May budget</small>
<strong>$4,820</strong>
<div class="budget-label"><span>Planned</span><span>$6,200</span></div>
<div class="progress-track"><span class="progress-fill" style="width: 78%"></span></div>
<div class="budget-label"><span>Used</span><span>78%</span></div>
</div>
</div>
</div>
</section>
<section class="section" id="investing">
<div class="container split reverse">
<div class="split-media">
<img src="https://picsum.photos/900/650?grayscale" alt="Long-term investment growth represented by a financial chart" loading="lazy">
<span class="image-caption">Think in decades</span>
</div>
<div class="split-copy">
<span class="section-kicker">Investment</span>
<h2>Build a portfolio around your future, not the news cycle.</h2>
<p class="body-copy">Long-term wealth is built through consistency, diversification, and time in the market—not perfect timing. Northlight helps you choose an allocation that matches your goals, risk comfort, and timeline, then keeps your plan on course when markets get noisy.</p>
<p class="body-copy">From tax-advantaged accounts to tax optimization strategies and periodic rebalancing, every recommendation starts with your complete financial picture. You get clear explanations, realistic projections, and the confidence to keep going.</p>
<div class="feature-row">
<article class="feature-card">
<div class="feature-icon" aria-hidden="true"><svg width="19" height="19" viewBox="0 0 20 20" fill="none"><path d="M3 15.5h14M5.5 15.5v-4m4 4V8m4 7.5v-3m4 3V5.5" stroke="currentColor" stroke-width="1.8" stroke-linecap="round"/></svg></div>
<h3>Diversification</h3>
<p>Spread risk across asset classes instead of putting your future in one place.</p>
</article>
<article class="feature-card">
<div class="feature-icon" aria-hidden="true"><svg width="19" height="19" viewBox="0 0 20 20" fill="none"><path d="M10 2.5 4 5.5v4c0 3.8 2.5 6.6 6 8 3.5-1.4 6-4.2 6-8v-4l-6-3Z" stroke="currentColor" stroke-width="1.8" stroke-linejoin="round"/><path d="m7 10 2 2 4-4" stroke="currentColor" stroke-width="1.8" stroke-linecap="round" stroke-linejoin="round"/></svg></div>
<h3>Tax optimization</h3>
<p>Use account types and strategies that may help keep more of what you earn.</p>
</article>
<article class="feature-card">
<div class="feature-icon" aria-hidden="true"><svg width="19" height="19" viewBox="0 0 20 20" fill="none"><path d="M3 16.5 7.5 12l3 3L17 8m0 0h-4m4 0v4" stroke="currentColor" stroke-width="1.8" stroke-linecap="round" stroke-linejoin="round"/></svg></div>
<h3>Rebalancing</h3>
<p>Bring your portfolio back to its intended mix as life and markets change.</p>
</article>
</div>
<div class="button-row" style="margin-top: 28px">
<a class="button button-primary" href="#tools">Calculate a Plan</a>
<a class="button button-text" href="#retirement">Understand your timeline <span aria-hidden="true">→</span></a>
</div>
</div>
</div>
</section>
<section class="section section-dark" id="retirement">
<div class="container split">
<div class="split-copy">
<span class="section-kicker">Retirement</span>
<h2>Retirement planning works best before you need it.</h2>
<p class="body-copy">Your retirement plan should answer three useful questions: how much do I need, when can I go, and how do I keep that plan flexible? Northlight brings those questions together in one view, using your income, savings, expected expenses, and desired lifestyle.</p>
<p class="body-copy">Whether you are starting your first employer plan, increasing contributions, or preparing to leave the workforce, we help you model scenarios without drowning in jargon. You can see how changes today affect tomorrow—and make decisions from a place of clarity.</p>
<ul class="retirement-points">
<li><svg width="18" height="18" viewBox="0 0 20 20" fill="none" aria-hidden="true"><circle cx="10" cy="10" r="9" fill="currentColor" opacity=".15"/><path d="m6 10 2.3 2.3L14 7" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"/></svg>Project future income and withdrawal needs</li>
<li><svg width="18" height="18" viewBox="0 0 20 20" fill="none" aria-hidden="true"><circle cx="10" cy="10" r="9" fill="currentColor" opacity=".15"/><path d="m6 10 2.3 2.3L14 7" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"/></svg>Model tax-efficient withdrawal strategies</li>
<li><svg width="18" height="18" viewBox="0 0 20 20" fill="none" aria-hidden="true"><circle cx="10" cy="10" r="9" fill="currentColor" opacity=".15"/><path d="m6 10 2.3 2.3L14 7" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"/></svg>Keep a plan that adapts as your life changes</li>
</ul>
<div class="button-row">
<a class="button button-light" href="#tools">Estimate Retirement</a>
<a class="button button-text" style="color: var(--lime)" href="#contact">Talk to an expert <span aria-hidden="true">→</span></a>
</div>
</div>
<div class="split-media">
<img src="https://picsum.photos/900/650?grayscale" alt="A mature couple reviewing their long-term financial goals" loading="lazy">
<div class="retirement-card">
<div><strong>Plan with confidence</strong><span>See how small changes compound over time.</span></div>
<span aria-hidden="true">↗</span>
</div>
</div>
</div>
</section>
<section class="section tools-section" id="tools">
<div class="container">
<div class="section-head">
<span class="section-kicker">Interactive money checkup</span>
<h2>Get a clearer picture in 60 seconds.</h2>
<p>Run a quick emergency fund calculation using a few numbers you already know. It is a starting point—not financial advice—but it can help you choose your next practical step.</p>
</div>
<div class="tool-shell">
<div class="tool-intro">
<h3>Build your financial cushion.</h3>
<p>Your emergency fund is the pause button between an unexpected expense and a high-interest debt spiral. Aim for a reserve that covers essential living costs while you get back on track.</p>
<div class="tool-note">
<svg width="17" height="17" viewBox="0 0 20 20" fill="none" aria-hidden="true"><circle cx="10" cy="10" r="9" stroke="currentColor" stroke-width="1.7"/><path d="M10 9v5m0-8.5v.01" stroke="currentColor" stroke-width="1.8" stroke-linecap="round"/></svg>
<span>Use whole dollar estimates. Results update automatically.</span>
</div>
</div>
<form class="calculator-form" id="money-checkup">
<div class="field">
<label for="income">Monthly take-home income</label>
<div class="input-wrap"><span>$</span><input id="income" name="income" type="number" min="0" step="100" value="6200" inputmode="decimal" required></div>
</div>
<div class="field">
<label for="essentials">Monthly essentials</label>
<div class="input-wrap"><span>$</span><input id="essentials" name="essentials" type="number" min="0" step="100" value="3850" inputmode="decimal" required></div>
</div>
<div class="field">
<label for="savings">Monthly savings contribution</label>
<div class="input-wrap"><span>$</span><input id="savings" name="savings" type="number" min="0" step="50" value="750" inputmode="decimal" required></div>
</div>
<div class="field">
<label for="target">Emergency fund target</label>
<div class="input-wrap"><span>$</span><input id="target" name="target" type="number" min="0" step="500" value="15000" inputmode="decimal" required></div>
</div>
<div class="calculator-result" aria-live="polite">
<div class="result-card" id="cushionCard"><span>Monthly cushion</span><strong id="monthlyCushion">$2,600</strong><small>Income after essentials and savings</small></div>
<div class="result-card"><span>Months to target</span><strong id="monthsToGoal">20</strong><small>At your current contribution</small></div>
<div class="result-card"><span>Savings rate</span><strong id="savingsRate">12%</strong><small>Contribution as a share of income</small></div>
<div class="result-progress">
<div class="result-progress-head"><span>Emergency fund momentum</span><span id="momentumLabel">22% of a 3-month reserve</span></div>
<div class="progress-track"><span class="progress-fill" id="momentumFill"></span></div>
<p>Recommended 3-month reserve: <strong id="reserveAmount">$11,550</strong> · Your target is <strong id="targetMultiple">3.9x</strong> one month of essentials.</p>
</div>
</div>
</form>
</div>
</div>
</section>
<section class="section" aria-labelledby="testimonials-heading">
<div class="container">
<div class="section-head">
<span class="section-kicker">Member stories</span>
<h2 id="testimonials-heading">Less guessing. More forward motion.</h2>
<p>Real money changes often start with one clear decision. Here is what members say after building their first complete plan.</p>
</div>
<div class="quote-grid">
<article class="quote-card">
<blockquote>I finally understood why I was always short at the end of the month. Northlight made my budget feel manageable instead of restrictive.</blockquote>
<div><span class="stars" aria-label="5 out of 5 stars">★★★★★</span></div>
<div class="quote-person"><img src="https://i.pravatar.cc/100?img=12" alt="Maya R." loading="lazy"><div><strong>Maya R.</strong><span>Product designer · Denver</span></div></div>
</article>
<article class="quote-card">
<blockquote>The retirement and debt tools helped us decide what to tackle first. We stopped arguing about money and started making plans together.</blockquote>
<div><span class="stars" aria-label="5 out of 5 stars">★★★★★</span></div>
<div class="quote-person"><img src="https://i.pravatar.cc/100?img=32" alt="Daniel and Priya K." loading="lazy"><div><strong>Daniel & Priya K.</strong><span>First-time homeowners · Austin</span></div></div>
</article>
<article class="quote-card">
<blockquote>My budget became a conversation I actually wanted to have. The alerts catch problems early, and the explanations make sense.</blockquote>
<div><span class="stars" aria-label="5 out of 5 stars">★★★★★</span></div>
<div class="quote-person"><img src="https://i.pravatar.cc/100?img=15" alt="Jordan T." loading="lazy"><div><strong>Jordan T.</strong><span>Small business owner · Portland</span></div></div>
</article>
</div>
</div>
</section>
<section class="section section-tint" id="credit" aria-labelledby="faq-heading">
<div class="container faq-layout">
<div class="section-head">
<span class="section-kicker">Questions, answered</span>
<h2 id="faq-heading">Money questions, without the jargon.</h2>
<p>Everything you need to know before taking your next step with Northlight Money.</p>
</div>
<div class="faq-list">
<details open>
<summary>What makes Northlight different from a spreadsheet?</summary>
<p>A spreadsheet records what happened. Northlight helps you act on it. We connect your goals, spending patterns, credit profile, and investment timeline so every number has a purpose—and every plan has a next step.</p>
</details>
<details>
<summary>Do I need an account to use the tools?</summary>
<p>No. You can explore the budgeting, emergency fund, and retirement calculators without creating an account. Connecting accounts is optional and gives you a more complete view of your financial life.</p>
</details>
<details>
<summary>Is Northlight offering financial advice?</summary>
<p>Northlight provides educational resources and planning tools. Content on this page is for general information and is not individualized investment, tax, or legal advice. Always consider your circumstances and consult a qualified professional.</p>
</details>
<details>
<summary>How is my information protected?</summary>
<p>We use encrypted connections, least-privilege access, and secure data handling practices. You control which connections you create, and you can review or remove them at any time from your dashboard.</p>
</details>
<details>
<summary>Can I use Northlight with my existing bank?</summary>
<p>Yes. Northlight is designed to work alongside the accounts and providers you already use. You can begin with manual entries or connect eligible accounts for a more automatic experience.</p>
</details>
</div>
</div>
</section>
<section class="section contact-section" id="contact">
<div class="container contact-grid">
<div class="contact-copy">
<span class="section-kicker">Let's talk</span>
<h2>Ready to make your next money decision with confidence?</h2>
<p>Tell us a little about where you are and where you want to go. A Northlight planning specialist will follow up with a helpful, no-pressure starting point for your financial journey.</p>
<a class="button button-primary" href="#contact-form">Request a Consultation <span aria-hidden="true">→</span></a>
<div class="contact-methods">
<div class="contact-method"><svg width="17" height="17" viewBox="0 0 20 20" fill="none" aria-hidden="true"><path d="M4 3h4l1.5 4-2 1.5a12.2 12.2 0 0 0 5 5L13 12l4 1.5v4c0 .8-.7 1.5-1.5 1.5C8.5 18 2 11.5 2 4.5 2 3.7 2.7 3 3.5 3Z" stroke="currentColor" stroke-width="1.6" stroke-linejoin="round"/></svg>(303) 555-0184</div>
<div class="contact-method"><svg width="17" height="17" viewBox="0 0 20 20" fill="none" aria-hidden="true"><rect x="3" y="4.5" width="14" height="11" rx="2" stroke="currentColor" stroke-width="1.6"/><path d="m4 6 6 4.5L16 6" stroke="currentColor" stroke-width="1.6" stroke-linecap="round" stroke-linejoin="round"/></svg>hello@northlightmoney.com</div>
<div class="contact-method"><svg width="17" height="17" viewBox="0 0 20 20" fill="none" aria-hidden="true"><path d="M10 18s6-5.1 6-9.5A6 6 0 0 0 4 8.5C4 12.9 10 18 10 18Z" stroke="currentColor" stroke-width="1.6"/><circle cx="10" cy="8.5" r="2" stroke="currentColor" stroke-width="1.6"/></svg>1200 Meridian Ave, Suite 210, Denver, CO 80202</div>
</div>
</div>
<div class="contact-form" id="contact-form">
<h3>Start your planning conversation</h3>
<p>We typically respond within one business day.</p>
<form id="contact-form" novalidate>
<div class="form-row">
<div class="form-field"><label for="name">Full name</label><input id="name" name="name" type="text" autocomplete="name" placeholder="Alex Morgan" required></div>
<div class="form-field"><label for="email">Email address</label><input id="email" name="email" type="email" autocomplete="email" placeholder="alex@example.com" required></div>
</div>
<div class="form-row" style="margin-top:14px">
<div class="form-field"><label for="topic">I'm interested in</label><select id="topic" name="topic"><option>Budgeting</option><option>Investing</option><option>Retirement</option><option>Credit health</option><option>Something else</option></select></div>
<div class="form-field"><label for="timeline">My timeline</label><select id="timeline" name="timeline"><option>Just getting started</option><option>Next 3 months</option><option>Next 6–12 months</option><option>1 year or more</option></select></div>
</div>
<div class="form-field" style="margin-top:14px"><label for="message">What would you like help with?</label><textarea id="message" name="message" placeholder="Share a goal, a question, or a number you want to understand better..."></textarea></div>
<button class="button button-primary form-submit" type="submit">Send My Request</button>
</form>
<div class="form-success" id="contact-success" hidden>
<div><svg width="42" height="42" viewBox="0 0 42 42" fill="none" aria-hidden="true"><circle cx="21" cy="21" r="20" stroke="currentColor" stroke-width="2"/><path d="m13 21 5.5 5.5L29 16" stroke="currentColor" stroke-width="2.5" stroke-linecap="round" stroke-linejoin="round"/></svg><h3>Thanks for reaching out.</h3><p>Your request is on its way. We will be in touch soon.</p></div>
</div>
</div>
</div>
</section>
</main>
<footer class="site-footer">
<div class="container">
<div class="footer-grid">
<div class="footer-brand">
<a class="brand" href="#home" aria-label="Northlight Money home">
<img src="https://placehold.co/160x52/0d5c56/ffffff?text=Northlight" alt="Northlight Money logo placeholder">
<span class="brand-copy"><strong>Northlight Money</strong><small>Clarity for every dollar.</small></span>
</a>
<p>Practical tools and clear guidance for budgeting, investing, credit, saving, and retirement—made for the life you are building today.</p>
<div class="social-links" aria-label="Social media links">
<a href="https://www.linkedin.com/" target="_blank" rel="noopener" aria-label="Northlight Money on LinkedIn"><svg width="16" height="16" viewBox="0 0 20 20" fill="none" aria-hidden="true"><path d="M4 4h3v12H4V4Zm1.5 1.5a1.8 1.8 0 1 0 0 3.6 1.8 1.8 0 0 0 0-3.6ZM8.5 8h3v1.7c.6-1 1.7-1.9 3.5-1.9 2.5 0 3.5 1.5 3.5 4.2V16h-3v-5.4c0-1.6-.6-2.5-1.8-2.5-1.4 0-2.2 1-2.2 2.7V16h-3V8Z" fill="currentColor"/></svg></a>
<a href="https://www.instagram.com/" target="_blank" rel="noopener" aria-label="Northlight Money on Instagram"><svg width="16" height="16" viewBox="0 0 20 20" fill="none" aria-hidden="true"><rect x="3" y="3" width="14" height="14" rx="4" stroke="currentColor" stroke-width="1.7"/><circle cx="10" cy="10" r="3.5" stroke="currentColor" stroke-width="1.7"/><circle cx="14.5" cy="5.5" r="1" fill="currentColor"/></svg></a>
<a href="https://www.facebook.com/" target="_blank" rel="noopener" aria-label="Northlight Money on Facebook"><svg width="16" height="16" viewBox="0 0 20 20" fill="none" aria-hidden="true"><path d="M12.5 17v-5h2l.4-2.5h-2.4V7.8c0-.7.3-1.3 1.4-1.3h1.2V4.2c-.5-.1-1.1-.2-1.8-.2-2 0-3.3 1.2-3.3 3.4v2.1H6.5V12h2.1v5h3.9Z" fill="currentColor"/></svg></a>
</div>
</div>
<div class="footer-col">
<h3>Explore</h3>
<ul><li><a href="#budget">Budgeting</a></li><li><a href="#investing">Investment</a></li><li><a href="#retirement">Retirement</a></li><li><a href="#credit">Credit health</a></li><li><a href="#tools">Free tools</a></li></ul>
</div>
<div class="footer-col">
<h3>Resources</h3>
<ul><li><a href="#tools">Emergency fund guide</a></li><li><a href="#investing">Investing basics</a></li><li><a href="#retirement">Retirement checklist</a></li><li><a href="#faq-heading">FAQ</a></li><li><a href="#contact">Contact us</a></li></ul>
</div>
<div class="footer-col footer-contact">
<h3>Visit or call</h3>
<p>1200 Meridian Ave, Suite 210<br>Denver, CO 80202</p>
<p><a href="tel:+13035550184">(303) 555-0184</a></p>
<p><a href="mailto:hello@northlightmoney.com">hello@northlightmoney.com</a></p>
</div>
</div>
<div class="footer-bottom">
<span>© <span id="currentYear">2025</span> Northlight Money. All rights reserved.</span>
<div class="footer-bottom-links"><a href="#privacy">Privacy</a><a href="#terms">Terms</a><a href="#accessibility">Accessibility</a><a href="#disclosures">Disclosures</a></div>
</div>
</div>
</footer>
<script>
(function () {
var navToggle = document.querySelector('.nav-toggle');
var primaryNav = document.getElementById('primary-navigation');
if (navToggle && primaryNav) {
navToggle.addEventListener('click', function () {
var isOpen = primaryNav.classList.toggle('is-open');
navToggle.setAttribute('aria-expanded', String(isOpen));
navToggle.classList.toggle('is-active', isOpen);
navToggle.setAttribute('aria-label', isOpen ? 'Close navigation' : 'Open navigation');
});
primaryNav.querySelectorAll('a').forEach(function (link) {
link.addEventListener('click', function () {
primaryNav.classList.remove('is-open');
navToggle.setAttribute('aria-expanded', 'false');
navToggle.classList.remove('is-active');
navToggle.setAttribute('aria-label', 'Open navigation');
});
});
}
var currency = new Intl.NumberFormat('en-US', { style: 'currency', currency: 'USD', maximumFractionDigits: 0 });
var form = document.getElementById('money-checkup');
var income = document.getElementById('income');
var essentials = document.getElementById('essentials');
var savings = document.getElementById('savings');
var target = document.getElementById('target');
var monthlyCushion = document.getElementById('monthlyCushion');
var monthsToGoal = document.getElementById('monthsToGoal');
var savingsRate = document.getElementById('savingsRate');
var cushionCard = document.getElementById('cushionCard');
var momentumFill = document.getElementById('momentumFill');
var momentumLabel = document.getElementById('momentumLabel');
var reserveAmount = document.getElementById('reserveAmount');
var targetMultiple = document.getElementById('targetMultiple');
function updateCalculator() {
var incomeValue = parseFloat(income.value) || 0;
var essentialsValue = parseFloat(essentials.value) || 0;
var savingsValue = parseFloat(savings.value) || 0;
var targetValue = parseFloat(target.value) || 0;
var cushion = incomeValue - essentialsValue - savingsValue;
var months = savingsValue > 0 ? Math.ceil(targetValue / savingsValue) : null;
var rate = incomeValue > 0 ? Math.min(100, (savingsValue / incomeValue) * 100) : 0;
var reserve = essentialsValue * 3;
var multiple = essentialsValue > 0 ? targetValue / essentialsValue : 0;
var momentum = reserve > 0 ? Math.max(0, Math.min(100, (savingsValue / reserve) * 100)) : 0;
monthlyCushion.textContent = currency.format(cushion);
cushionCard.classList.toggle('is-negative', cushion < 0);
monthsToGoal.textContent = months === null ? '—' : String(months);
savingsRate.textContent = rate.toFixed(0) + '%';
reserveAmount.textContent = currency.format(reserve);
targetMultiple.textContent = multiple.toFixed(1) + 'x';
momentumFill.style.width = momentum.toFixed(1) + '%';
momentumLabel.textContent = Math.round(momentum) + '% of a 3-month reserve';
}
if (form && income && essentials && savings && target) {
[income, essentials, savings, target].forEach(function (input) {
input.addEventListener('input', updateCalculator);
});
updateCalculator();
}
var contactForm = document.getElementById('contact-form');
var contactSuccess = document.getElementById('contact-success');
if (contactForm && contactSuccess) {
contactForm.addEventListener('submit', function (event) {
event.preventDefault();
contactForm.hidden = true;
contactSuccess.hidden = false;
});
}
var currentYear = document.getElementById('currentYear');
if (currentYear) currentYear.textContent = String(new Date().getFullYear());
})();
</script>
</body>
</html>
View Axe Report (JSON)
{
"testEngine": {
"name": "axe-core",
"version": "4.10.2"
},
"testRunner": {
"name": "axe"
},
"testEnvironment": {
"userAgent": "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) HeadlessChrome/156.0.8078.4 Safari/537.36",
"windowWidth": 1280,
"windowHeight": 720,
"orientationAngle": 0,
"orientationType": "landscape-primary"
},
"timestamp": "2026-11-12T09:55:57.838Z",
"url": "https://benchmark.aimac.invalid/c67f2a66ab020d09e990c100c8c2d1e2fe2f222e1d86c5d7268d3b0fe7019b38.html",
"toolOptions": {
"runOnly": {
"type": "tag",
"values": [
"wcag2a",
"wcag2aa",
"wcag21a",
"wcag21aa",
"wcag22a",
"wcag22aa"
]
},
"resultTypes": [
"violations"
],
"reporter": "v1"
},
"inapplicable": [
{
"id": "area-alt",
"impact": null,
"tags": [
"cat.text-alternatives",
"wcag2a",
"wcag244",
"wcag412",
"section508",
"section508.22.a",
"TTv5",
"TT6.a",
"EN-301-549",
"EN-9.2.4.4",
"EN-9.4.1.2",
"ACT"
],
"description": "Ensure <area> elements of image maps have alternative text",
"help": "Active <area> elements must have alternative text",
"helpUrl": "https://dequeuniversity.com/rules/axe/4.10/area-alt?application=axeAPI",
"nodes": []
},
{
"id": "aria-braille-equivalent",
"impact": null,
"tags": [
"cat.aria",
"wcag2a",
"wcag412",
"EN-301-549",
"EN-9.4.1.2"
],
"description": "Ensure aria-braillelabel and aria-brailleroledescription have a non-braille equivalent",
"help": "aria-braille attributes must have a non-braille equivalent",
"helpUrl": "https://dequeuniversity.com/rules/axe/4.10/aria-braille-equivalent?application=axeAPI",
"nodes": []
},
{
"id": "aria-command-name",
"impact": null,
"tags": [
"cat.aria",
"wcag2a",
"wcag412",
"TTv5",
"TT6.a",
"EN-301-549",
"EN-9.4.1.2",
"ACT"
],
"description": "Ensure every ARIA button, link and menuitem has an accessible name",
"help": "ARIA commands must have an accessible name",
"helpUrl": "https://dequeuniversity.com/rules/axe/4.10/aria-command-name?application=axeAPI",
"nodes": []
},
{
"id": "aria-deprecated-role",
"impact": null,
"tags": [
"cat.aria",
"wcag2a",
"wcag412",
"EN-301-549",
"EN-9.4.1.2"
],
"description": "Ensure elements do not use deprecated roles",
"help": "Deprecated ARIA roles must not be used",
"helpUrl": "https://dequeuniversity.com/rules/axe/4.10/aria-deprecated-role?application=axeAPI",
"nodes": []
},
{
"id": "aria-input-field-name",
"impact": null,
"tags": [
"cat.aria",
"wcag2a",
"wcag412",
"TTv5",
"TT5.c",
"EN-301-549",
"EN-9.4.1.2",
"ACT"
],
"description": "Ensure every ARIA input field has an accessible name",
"help": "ARIA input fields must have an accessible name",
"helpUrl": "https://dequeuniversity.com/rules/axe/4.10/aria-input-field-name?application=axeAPI",
"nodes": []
},
{
"id": "aria-meter-name",
"impact": null,
"tags": [
"cat.aria",
"wcag2a",
"wcag111",
"EN-301-549",
"EN-9.1.1.1"
],
"description": "Ensure every ARIA meter node has an accessible name",
"help": "ARIA meter nodes must have an accessible name",
"helpUrl": "https://dequeuniversity.com/rules/axe/4.10/aria-meter-name?application=axeAPI",
"nodes": []
},
{
"id": "aria-progressbar-name",
"impact": null,
"tags": [
"cat.aria",
"wcag2a",
"wcag111",
"EN-301-549",
"EN-9.1.1.1"
],
"description": "Ensure every ARIA progressbar node has an accessible name",
"help": "ARIA progressbar nodes must have an accessible name",
"helpUrl": "https://dequeuniversity.com/rules/axe/4.10/aria-progressbar-name?application=axeAPI",
"nodes": []
},
{
"id": "aria-required-attr",
"impact": null,
"tags": [
"cat.aria",
"wcag2a",
"wcag412",
"EN-301-549",
"EN-9.4.1.2"
],
"description": "Ensure elements with ARIA roles have all required ARIA attributes",
"help": "Required ARIA attributes must be provided",
"helpUrl": "https://dequeuniversity.com/rules/axe/4.10/aria-required-attr?application=axeAPI",
"nodes": []
},
{
"id": "aria-required-children",
"impact": null,
"tags": [
"cat.aria",
"wcag2a",
"wcag131",
"EN-301-549",
"EN-9.1.3.1"
],
"description": "Ensure elements with an ARIA role that require child roles contain them",
"help": "Certain ARIA roles must contain particular children",
"helpUrl": "https://dequeuniversity.com/rules/axe/4.10/aria-required-children?application=axeAPI",
"nodes": []
},
{
"id": "aria-required-parent",
"impact": null,
"tags": [
"cat.aria",
"wcag2a",
"wcag131",
"EN-301-549",
"EN-9.1.3.1"
],
"description": "Ensure elements with an ARIA role that require parent roles are contained by them",
"help": "Certain ARIA roles must be contained by particular parents",
"helpUrl": "https://dequeuniversity.com/rules/axe/4.10/aria-required-parent?application=axeAPI",
"nodes": []
},
{
"id": "aria-roles",
"impact": null,
"tags": [
"cat.aria",
"wcag2a",
"wcag412",
"EN-301-549",
"EN-9.4.1.2"
],
"description": "Ensure all elements with a role attribute use a valid value",
"help": "ARIA roles used must conform to valid values",
"helpUrl": "https://dequeuniversity.com/rules/axe/4.10/aria-roles?application=axeAPI",
"nodes": []
},
{
"id": "aria-toggle-field-name",
"impact": null,
"tags": [
"cat.aria",
"wcag2a",
"wcag412",
"TTv5",
"TT5.c",
"EN-301-549",
"EN-9.4.1.2",
"ACT"
],
"description": "Ensure every ARIA toggle field has an accessible name",
"help": "ARIA toggle fields must have an accessible name",
"helpUrl": "https://dequeuniversity.com/rules/axe/4.10/aria-toggle-field-name?application=axeAPI",
"nodes": []
},
{
"id": "aria-tooltip-name",
"impact": null,
"tags": [
"cat.aria",
"wcag2a",
"wcag412",
"EN-301-549",
"EN-9.4.1.2"
],
"description": "Ensure every ARIA tooltip node has an accessible name",
"help": "ARIA tooltip nodes must have an accessible name",
"helpUrl": "https://dequeuniversity.com/rules/axe/4.10/aria-tooltip-name?application=axeAPI",
"nodes": []
},
{
"id": "blink",
"impact": null,
"tags": [
"cat.time-and-media",
"wcag2a",
"wcag222",
"section508",
"section508.22.j",
"TTv5",
"TT2.b",
"EN-301-549",
"EN-9.2.2.2"
],
"description": "Ensure <blink> elements are not used",
"help": "<blink> elements are deprecated and must not be used",
"helpUrl": "https://dequeuniversity.com/rules/axe/4.10/blink?application=axeAPI",
"nodes": []
},
{
"id": "definition-list",
"impact": null,
"tags": [
"cat.structure",
"wcag2a",
"wcag131",
"EN-301-549",
"EN-9.1.3.1"
],
"description": "Ensure <dl> elements are structured correctly",
"help": "<dl> elements must only directly contain properly-ordered <dt> and <dd> groups, <script>, <template> or <div> elements",
"helpUrl": "https://dequeuniversity.com/rules/axe/4.10/definition-list?application=axeAPI",
"nodes": []
},
{
"id": "dlitem",
"impact": null,
"tags": [
"cat.structure",
"wcag2a",
"wcag131",
"EN-301-549",
"EN-9.1.3.1"
],
"description": "Ensure <dt> and <dd> elements are contained by a <dl>",
"help": "<dt> and <dd> elements must be contained by a <dl>",
"helpUrl": "https://dequeuniversity.com/rules/axe/4.10/dlitem?application=axeAPI",
"nodes": []
},
{
"id": "frame-focusable-content",
"impact": null,
"tags": [
"cat.keyboard",
"wcag2a",
"wcag211",
"TTv5",
"TT4.a",
"EN-301-549",
"EN-9.2.1.1"
],
"description": "Ensure <frame> and <iframe> elements with focusable content do not have tabindex=-1",
"help": "Frames with focusable content must not have tabindex=-1",
"helpUrl": "https://dequeuniversity.com/rules/axe/4.10/frame-focusable-content?application=axeAPI",
"nodes": []
},
{
"id": "frame-title-unique",
"impact": null,
"tags": [
"cat.text-alternatives",
"wcag2a",
"wcag412",
"TTv5",
"TT12.d",
"EN-301-549",
"EN-9.4.1.2"
],
"description": "Ensure <iframe> and <frame> elements contain a unique title attribute",
"help": "Frames must have a unique title attribute",
"helpUrl": "https://dequeuniversity.com/rules/axe/4.10/frame-title-unique?application=axeAPI",
"nodes": []
},
{
"id": "frame-title",
"impact": null,
"tags": [
"cat.text-alternatives",
"wcag2a",
"wcag412",
"section508",
"section508.22.i",
"TTv5",
"TT12.d",
"EN-301-549",
"EN-9.4.1.2"
],
"description": "Ensure <iframe> and <frame> elements have an accessible name",
"help": "Frames must have an accessible name",
"helpUrl": "https://dequeuniversity.com/rules/axe/4.10/frame-title?application=axeAPI",
"nodes": []
},
{
"id": "html-xml-lang-mismatch",
"impact": null,
"tags": [
"cat.language",
"wcag2a",
"wcag311",
"EN-301-549",
"EN-9.3.1.1",
"ACT"
],
"description": "Ensure that HTML elements with both valid lang and xml:lang attributes agree on the base language of the page",
"help": "HTML elements with lang and xml:lang must have the same base language",
"helpUrl": "https://dequeuniversity.com/rules/axe/4.10/html-xml-lang-mismatch?application=axeAPI",
"nodes": []
},
{
"id": "input-button-name",
"impact": null,
"tags": [
"cat.name-role-value",
"wcag2a",
"wcag412",
"section508",
"section508.22.a",
"TTv5",
"TT5.c",
"EN-301-549",
"EN-9.4.1.2",
"ACT"
],
"description": "Ensure input buttons have discernible text",
"help": "Input buttons must have discernible text",
"helpUrl": "https://dequeuniversity.com/rules/axe/4.10/input-button-name?application=axeAPI",
"nodes": []
},
{
"id": "input-image-alt",
"impact": null,
"tags": [
"cat.text-alternatives",
"wcag2a",
"wcag111",
"wcag412",
"section508",
"section508.22.a",
"TTv5",
"TT7.a",
"EN-301-549",
"EN-9.1.1.1",
"EN-9.4.1.2",
"ACT"
],
"description": "Ensure <input type=\"image\"> elements have alternative text",
"help": "Image buttons must have alternative text",
"helpUrl": "https://dequeuniversity.com/rules/axe/4.10/input-image-alt?application=axeAPI",
"nodes": []
},
{
"id": "marquee",
"impact": null,
"tags": [
"cat.parsing",
"wcag2a",
"wcag222",
"TTv5",
"TT2.b",
"EN-301-549",
"EN-9.2.2.2"
],
"description": "Ensure <marquee> elements are not used",
"help": "<marquee> elements are deprecated and must not be used",
"helpUrl": "https://dequeuniversity.com/rules/axe/4.10/marquee?application=axeAPI",
"nodes": []
},
{
"id": "meta-refresh",
"impact": null,
"tags": [
"cat.time-and-media",
"wcag2a",
"wcag221",
"TTv5",
"TT8.a",
"EN-301-549",
"EN-9.2.2.1"
],
"description": "Ensure <meta http-equiv=\"refresh\"> is not used for delayed refresh",
"help": "Delayed refresh under 20 hours must not be used",
"helpUrl": "https://dequeuniversity.com/rules/axe/4.10/meta-refresh?application=axeAPI",
"nodes": []
},
{
"id": "object-alt",
"impact": null,
"tags": [
"cat.text-alternatives",
"wcag2a",
"wcag111",
"section508",
"section508.22.a",
"EN-301-549",
"EN-9.1.1.1"
],
"description": "Ensure <object> elements have alternative text",
"help": "<object> elements must have alternative text",
"helpUrl": "https://dequeuniversity.com/rules/axe/4.10/object-alt?application=axeAPI",
"nodes": []
},
{
"id": "role-img-alt",
"impact": null,
"tags": [
"cat.text-alternatives",
"wcag2a",
"wcag111",
"section508",
"section508.22.a",
"TTv5",
"TT7.a",
"EN-301-549",
"EN-9.1.1.1",
"ACT"
],
"description": "Ensure [role=\"img\"] elements have alternative text",
"help": "[role=\"img\"] elements must have an alternative text",
"helpUrl": "https://dequeuniversity.com/rules/axe/4.10/role-img-alt?application=axeAPI",
"nodes": []
},
{
"id": "scrollable-region-focusable",
"impact": null,
"tags": [
"cat.keyboard",
"wcag2a",
"wcag211",
"wcag213",
"TTv5",
"TT4.a",
"EN-301-549",
"EN-9.2.1.1",
"EN-9.2.1.3"
],
"description": "Ensure elements that have scrollable content are accessible by keyboard",
"help": "Scrollable region must have keyboard access",
"helpUrl": "https://dequeuniversity.com/rules/axe/4.10/scrollable-region-focusable?application=axeAPI",
"nodes": []
},
{
"id": "server-side-image-map",
"impact": null,
"tags": [
"cat.text-alternatives",
"wcag2a",
"wcag211",
"section508",
"section508.22.f",
"TTv5",
"TT4.a",
"EN-301-549",
"EN-9.2.1.1"
],
"description": "Ensure that server-side image maps are not used",
"help": "Server-side image maps must not be used",
"helpUrl": "https://dequeuniversity.com/rules/axe/4.10/server-side-image-map?application=axeAPI",
"nodes": []
},
{
"id": "svg-img-alt",
"impact": null,
"tags": [
"cat.text-alternatives",
"wcag2a",
"wcag111",
"section508",
"section508.22.a",
"TTv5",
"TT7.a",
"EN-301-549",
"EN-9.1.1.1",
"ACT"
],
"description": "Ensure <svg> elements with an img, graphics-document or graphics-symbol role have an accessible text",
"help": "<svg> elements with an img role must have an alternative text",
"helpUrl": "https://dequeuniversity.com/rules/axe/4.10/svg-img-alt?application=axeAPI",
"nodes": []
},
{
"id": "td-headers-attr",
"impact": null,
"tags": [
"cat.tables",
"wcag2a",
"wcag131",
"section508",
"section508.22.g",
"TTv5",
"TT14.b",
"EN-301-549",
"EN-9.1.3.1"
],
"description": "Ensure that each cell in a table that uses the headers attribute refers only to other cells in that table",
"help": "Table cells that use the headers attribute must only refer to cells in the same table",
"helpUrl": "https://dequeuniversity.com/rules/axe/4.10/td-headers-attr?application=axeAPI",
"nodes": []
},
{
"id": "th-has-data-cells",
"impact": null,
"tags": [
"cat.tables",
"wcag2a",
"wcag131",
"section508",
"section508.22.g",
"TTv5",
"TT14.b",
"EN-301-549",
"EN-9.1.3.1"
],
"description": "Ensure that <th> elements and elements with role=columnheader/rowheader have data cells they describe",
"help": "Table headers in a data table must refer to data cells",
"helpUrl": "https://dequeuniversity.com/rules/axe/4.10/th-has-data-cells?application=axeAPI",
"nodes": []
},
{
"id": "valid-lang",
"impact": null,
"tags": [
"cat.language",
"wcag2aa",
"wcag312",
"TTv5",
"TT11.b",
"EN-301-549",
"EN-9.3.1.2",
"ACT"
],
"description": "Ensure lang attributes have valid values",
"help": "lang attribute must have a valid value",
"helpUrl": "https://dequeuniversity.com/rules/axe/4.10/valid-lang?application=axeAPI",
"nodes": []
},
{
"id": "video-caption",
"impact": null,
"tags": [
"cat.text-alternatives",
"wcag2a",
"wcag122",
"section508",
"section508.22.a",
"TTv5",
"TT17.a",
"EN-301-549",
"EN-9.1.2.2"
],
"description": "Ensure <video> elements have captions",
"help": "<video> elements must have captions",
"helpUrl": "https://dequeuniversity.com/rules/axe/4.10/video-caption?application=axeAPI",
"nodes": []
},
{
"id": "no-autoplay-audio",
"impact": null,
"tags": [
"cat.time-and-media",
"wcag2a",
"wcag142",
"TTv5",
"TT2.a",
"EN-301-549",
"EN-9.1.4.2",
"ACT"
],
"description": "Ensure <video> or <audio> elements do not autoplay audio for more than 3 seconds without a control mechanism to stop or mute the audio",
"help": "<video> or <audio> elements must not play automatically",
"helpUrl": "https://dequeuniversity.com/rules/axe/4.10/no-autoplay-audio?application=axeAPI",
"nodes": []
}
],
"passes": [
{
"id": "aria-allowed-attr",
"impact": null,
"tags": [
"cat.aria",
"wcag2a",
"wcag412",
"EN-301-549",
"EN-9.4.1.2"
],
"description": "Ensure an element's role supports its ARIA attributes",
"help": "Elements must only use supported ARIA attributes",
"helpUrl": "https://dequeuniversity.com/rules/axe/4.10/aria-allowed-attr?application=axeAPI",
"nodes": [
{
"any": [],
"all": [
{
"id": "aria-allowed-attr",
"data": null,
"relatedNodes": [],
"impact": "critical",
"message": "ARIA attributes are used correctly for the defined role"
}
],
"none": [
{
"id": "aria-unsupported-attr",
"data": null,
"relatedNodes": [],
"impact": "critical",
"message": "ARIA attribute is supported"
}
],
"impact": null,
"html": "<a class=\"brand\" href=\"#home\" aria-label=\"Northlight Money home\">",
"target": [
".header-inner > .brand[aria-label=\"Northlight Money home\"][href$=\"#home\"]"
]
}
]
},
{
"id": "aria-conditional-attr",
"impact": null,
"tags": [
"cat.aria",
"wcag2a",
"wcag412",
"EN-301-549",
"EN-9.4.1.2"
],
"description": "Ensure ARIA attributes are used as described in the specification of the element's role",
"help": "ARIA attributes must be used as specified for the element's role",
"helpUrl": "https://dequeuniversity.com/rules/axe/4.10/aria-conditional-attr?application=axeAPI",
"nodes": [
{
"any": [],
"all": [
{
"id": "aria-conditional-attr",
"data": null,
"relatedNodes": [],
"impact": "serious",
"message": "ARIA attribute is allowed"
}
],
"none": [],
"impact": null,
"html": "<a class=\"brand\" href=\"#home\" aria-label=\"Northlight Money home\">",
"target": [
".header-inner > .brand[aria-label=\"Northlight Money home\"][href$=\"#home\"]"
]
}
]
},
{
"id": "aria-hidden-body",
"impact": null,
"tags": [
"cat.aria",
"wcag2a",
"wcag131",
"wcag412",
"EN-301-549",
"EN-9.1.3.1",
"EN-9.4.1.2"
],
"description": "Ensure aria-hidden=\"true\" is not present on the document body.",
"help": "aria-hidden=\"true\" must not be present on the document body",
"helpUrl": "https://dequeuniversity.com/rules/axe/4.10/aria-hidden-body?application=axeAPI",
"nodes": [
{
"any": [
{
"id": "aria-hidden-body",
"data": null,
"relatedNodes": [],
"impact": "critical",
"message": "No aria-hidden attribute is present on document body"
}
],
"all": [],
"none": [],
"impact": null,
"html": "<body>",
"target": [
"body"
]
}
]
},
{
"id": "aria-hidden-focus",
"impact": null,
"tags": [
"cat.name-role-value",
"wcag2a",
"wcag412",
"TTv5",
"TT6.a",
"EN-301-549",
"EN-9.4.1.2"
],
"description": "Ensure aria-hidden elements are not focusable nor contain focusable elements",
"help": "ARIA hidden element must not be focusable or contain focusable elements",
"helpUrl": "https://dequeuniversity.com/rules/axe/4.10/aria-hidden-focus?application=axeAPI",
"nodes": [
{
"any": [],
"all": [
{
"id": "focusable-modal-open",
"data": null,
"relatedNodes": [],
"impact": "serious",
"message": "No focusable elements while a modal is open"
},
{
"id": "focusable-disabled",
"data": null,
"relatedNodes": [],
"impact": "serious",
"message": "No focusable elements contained within element"
},
{
"id": "focusable-not-tabbable",
"data": null,
"relatedNodes": [],
"impact": "serious",
"message": "No focusable elements contained within element"
}
],
"none": [],
"impact": null,
"html": "<span aria-hidden=\"true\">\u2192</span>",
"target": [
".button-primary.button[href$=\"#budget\"] > span[aria-hidden=\"true\"]"
]
}
]
},
{
"id": "aria-prohibited-attr",
"impact": "serious",
"tags": [
"cat.aria",
"wcag2a",
"wcag412",
"EN-301-549",
"EN-9.4.1.2"
],
"description": "Ensure ARIA attributes are not prohibited for an element's role",
"help": "Elements must only use permitted ARIA attributes",
"helpUrl": "https://dequeuniversity.com/rules/axe/4.10/aria-prohibited-attr?application=axeAPI",
"nodes": [
{
"any": [],
"all": [],
"none": [
{
"id": "aria-prohibited-attr",
"data": null,
"relatedNodes": [],
"impact": "serious",
"message": "ARIA attribute is allowed"
}
],
"impact": null,
"html": "<a class=\"brand\" href=\"#home\" aria-label=\"Northlight Money home\">",
"target": [
".header-inner > .brand[aria-label=\"Northlight Money home\"][href$=\"#home\"]"
]
}
]
},
{
"id": "aria-valid-attr-value",
"impact": null,
"tags": [
"cat.aria",
"wcag2a",
"wcag412",
"EN-301-549",
"EN-9.4.1.2"
],
"description": "Ensure all ARIA attributes have valid values",
"help": "ARIA attributes must conform to valid values",
"helpUrl": "https://dequeuniversity.com/rules/axe/4.10/aria-valid-attr-value?application=axeAPI",
"nodes": [
{
"any": [],
"all": [
{
"id": "aria-valid-attr-value",
"data": null,
"relatedNodes": [],
"impact": "critical",
"message": "ARIA attribute values are valid"
},
{
"id": "aria-errormessage",
"data": null,
"relatedNodes": [],
"impact": "critical",
"message": "aria-errormessage exists and references elements visible to screen readers that use a supported aria-errormessage technique"
},
{
"id": "aria-level",
"data": null,
"relatedNodes": [],
"impact": "critical",
"message": "aria-level values are valid"
}
],
"none": [],
"impact": null,
"html": "<a class=\"brand\" href=\"#home\" aria-label=\"Northlight Money home\">",
"target": [
".header-inner > .brand[aria-label=\"Northlight Money home\"][href$=\"#home\"]"
]
}
]
},
{
"id": "aria-valid-attr",
"impact": null,
"tags": [
"cat.aria",
"wcag2a",
"wcag412",
"EN-301-549",
"EN-9.4.1.2"
],
"description": "Ensure attributes that begin with aria- are valid ARIA attributes",
"help": "ARIA attributes must conform to valid names",
"helpUrl": "https://dequeuniversity.com/rules/axe/4.10/aria-valid-attr?application=axeAPI",
"nodes": [
{
"any": [
{
"id": "aria-valid-attr",
"data": null,
"relatedNodes": [],
"impact": "critical",
"message": "ARIA attribute name is valid"
}
],
"all": [],
"none": [],
"impact": null,
"html": "<a class=\"brand\" href=\"#home\" aria-label=\"Northlight Money home\">",
"target": [
".header-inner > .brand[aria-label=\"Northlight Money home\"][href$=\"#home\"]"
]
}
]
},
{
"id": "autocomplete-valid",
"impact": null,
"tags": [
"cat.forms",
"wcag21aa",
"wcag135",
"EN-301-549",
"EN-9.1.3.5",
"ACT"
],
"description": "Ensure the autocomplete attribute is correct and suitable for the form field",
"help": "autocomplete attribute must be used correctly",
"helpUrl": "https://dequeuniversity.com/rules/axe/4.10/autocomplete-valid?application=axeAPI",
"nodes": [
{
"any": [],
"all": [
{
"id": "autocomplete-valid",
"data": null,
"relatedNodes": [],
"impact": "serious",
"message": "the autocomplete attribute is correctly formatted"
}
],
"none": [],
"impact": null,
"html": "<input id=\"name\" name=\"name\" type=\"text\" autocomplete=\"name\" placeholder=\"Alex Morgan\" required=\"\">",
"target": [
"#name"
]
}
]
},
{
"id": "avoid-inline-spacing",
"impact": null,
"tags": [
"cat.structure",
"wcag21aa",
"wcag1412",
"EN-301-549",
"EN-9.1.4.12",
"ACT"
],
"description": "Ensure that text spacing set through style attributes can be adjusted with custom stylesheets",
"help": "Inline text spacing must be adjustable with custom stylesheets",
"helpUrl": "https://dequeuniversity.com/rules/axe/4.10/avoid-inline-spacing?application=axeAPI",
"nodes": [
{
"any": [],
"all": [
{
"id": "important-letter-spacing",
"data": null,
"relatedNodes": [],
"impact": "serious",
"message": "Letter-spacing in the style attribute is not set to !important, or meets the minimum"
},
{
"id": "important-word-spacing",
"data": null,
"relatedNodes": [],
"impact": "serious",
"message": "word-spacing in the style attribute is not set to !important, or meets the minimum"
},
{
"id": "important-line-height",
"data": null,
"relatedNodes": [],
"impact": "serious",
"message": "line-height in the style attribute is not set to !important, or meets the minimum"
}
],
"none": [],
"impact": null,
"html": "<span class=\"progress-fill\" style=\"width: 78%\"></span>",
"target": [
".budget-card > .progress-track > .progress-fill"
]
}
]
},
{
"id": "button-name",
"impact": null,
"tags": [
"cat.name-role-value",
"wcag2a",
"wcag412",
"section508",
"section508.22.a",
"TTv5",
"TT6.a",
"EN-301-549",
"EN-9.4.1.2",
"ACT"
],
"description": "Ensure buttons have discernible text",
"help": "Buttons must have discernible text",
"helpUrl": "https://dequeuniversity.com/rules/axe/4.10/button-name?application=axeAPI",
"nodes": [
{
"any": [
{
"id": "button-has-visible-text",
"data": null,
"relatedNodes": [],
"impact": "critical",
"message": "Element has inner text that is visible to screen readers"
}
],
"all": [],
"none": [],
"impact": null,
"html": "<button class=\"button button-primary form-submit\" type=\"submit\">Send My Request</button>",
"target": [
".form-submit"
]
}
]
},
{
"id": "bypass",
"impact": null,
"tags": [
"cat.keyboard",
"wcag2a",
"wcag241",
"section508",
"section508.22.o",
"TTv5",
"TT9.a",
"EN-301-549",
"EN-9.2.4.1"
],
"description": "Ensure each page has at least one mechanism for a user to bypass navigation and jump straight to the content",
"help": "Page must have means to bypass repeated blocks",
"helpUrl": "https://dequeuniversity.com/rules/axe/4.10/bypass?application=axeAPI",
"nodes": [
{
"any": [
{
"id": "internal-link-present",
"data": null,
"relatedNodes": [],
"impact": "serious",
"message": "Valid skip link found"
},
{
"id": "header-present",
"data": null,
"relatedNodes": [
{
"html": "<h1>Turn financial noise into a plan you can follow.</h1>",
"target": [
"h1"
]
},
{
"html": "<h2>Start with a budget that works with your life.</h2>",
"target": [
"#budget > .split.container > .split-copy > h2"
]
},
{
"html": "<h2>Build a portfolio around your future, not the news cycle.</h2>",
"target": [
".reverse > .split-copy > h2"
]
},
{
"html": "<h3>Diversification</h3>",
"target": [
".feature-card:nth-child(1) > h3"
]
},
{
"html": "<h3>Tax optimization</h3>",
"target": [
".feature-card:nth-child(2) > h3"
]
},
{
"html": "<h3>Rebalancing</h3>",
"target": [
".feature-card:nth-child(3) > h3"
]
},
{
"html": "<h2>Retirement planning works best before you need it.</h2>",
"target": [
"#retirement > .split.container > .split-copy > h2"
]
},
{
"html": "<h2>Get a clearer picture in 60 seconds.</h2>",
"target": [
"#tools > .container > .section-head > h2"
]
},
{
"html": "<h3>Build your financial cushion.</h3>",
"target": [
".tool-intro > h3"
]
},
{
"html": "<h2 id=\"testimonials-heading\">Less guessing. More forward motion.</h2>",
"target": [
"#testimonials-heading"
]
},
{
"html": "<h2 id=\"faq-heading\">Money questions, without the jargon.</h2>",
"target": [
"#faq-heading"
]
},
{
"html": "<h2>Ready to make your next money decision with confidence?</h2>",
"target": [
".contact-copy > h2"
]
},
{
"html": "<h3>Start your planning conversation</h3>",
"target": [
".contact-form > h3"
]
},
{
"html": "<h3>Thanks for reaching out.</h3>",
"target": [
"#contact-success > div > h3"
]
},
{
"html": "<h3>Explore</h3>",
"target": [
".footer-col:nth-child(2) > h3"
]
},
{
"html": "<h3>Resources</h3>",
"target": [
".footer-col:nth-child(3) > h3"
]
},
{
"html": "<h3>Visit or call</h3>",
"target": [
".footer-contact > h3"
]
}
],
"impact": "serious",
"message": "Page has a heading"
},
{
"id": "landmark",
"data": null,
"relatedNodes": [
{
"html": "<main id=\"main-content\">",
"target": [
"#main-content"
]
}
],
"impact": "serious",
"message": "Page has a landmark region"
}
],
"all": [],
"none": [],
"impact": null,
"html": "<html lang=\"en\">",
"target": [
"html"
]
}
]
},
{
"id": "color-contrast",
"impact": "serious",
"tags": [
"cat.color",
"wcag2aa",
"wcag143",
"TTv5",
"TT13.c",
"EN-301-549",
"EN-9.1.4.3",
"ACT"
],
"description": "Ensure the contrast between foreground and background colors meets WCAG 2 AA minimum contrast ratio thresholds",
"help": "Elements must meet minimum color contrast ratio thresholds",
"helpUrl": "https://dequeuniversity.com/rules/axe/4.10/color-contrast?application=axeAPI",
"nodes": [
{
"any": [
{
"id": "color-contrast",
"data": {
"fgColor": "#102a2a",
"bgColor": "#fbfcfa",
"contrastRatio": 14.71,
"fontSize": "13.5pt (18px)",
"fontWeight": "bold",
"messageKey": null,
"expectedContrastRatio": "4.5:1",
"shadowColor": null
},
"relatedNodes": [],
"impact": "serious",
"message": "Element has sufficient color contrast of 14.71"
}
],
"all": [],
"none": [],
"impact": null,
"html": "<strong>Northlight Money</strong>",
"target": [
".header-inner > .brand[aria-label=\"Northlight Money home\"][href$=\"#home\"] > .brand-copy > strong"
]
}
]
},
{
"id": "document-title",
"impact": null,
"tags": [
"cat.text-alternatives",
"wcag2a",
"wcag242",
"TTv5",
"TT12.a",
"EN-301-549",
"EN-9.2.4.2",
"ACT"
],
"description": "Ensure each HTML document contains a non-empty <title> element",
"help": "Documents must have <title> element to aid in navigation",
"helpUrl": "https://dequeuniversity.com/rules/axe/4.10/document-title?application=axeAPI",
"nodes": [
{
"any": [
{
"id": "doc-has-title",
"data": null,
"relatedNodes": [],
"impact": "serious",
"message": "Document has a non-empty <title> element"
}
],
"all": [],
"none": [],
"impact": null,
"html": "<html lang=\"en\">",
"target": [
"html"
]
}
]
},
{
"id": "duplicate-id-aria",
"impact": null,
"tags": [
"cat.parsing",
"wcag2a",
"wcag412",
"EN-301-549",
"EN-9.4.1.2"
],
"description": "Ensure every id attribute value used in ARIA and in labels is unique",
"help": "IDs used in ARIA and labels must be unique",
"helpUrl": "https://dequeuniversity.com/rules/axe/4.10/duplicate-id-aria?application=axeAPI",
"nodes": [
{
"any": [
{
"id": "duplicate-id-aria",
"data": "primary-navigation",
"relatedNodes": [],
"impact": "critical",
"message": "Document has no elements referenced with ARIA or labels that share the same id attribute"
}
],
"all": [],
"none": [],
"impact": null,
"html": "<nav class=\"main-nav\" id=\"primary-navigation\" aria-label=\"Primary navigation\">",
"target": [
"#primary-navigation"
]
}
]
},
{
"id": "form-field-multiple-labels",
"impact": null,
"tags": [
"cat.forms",
"wcag2a",
"wcag332",
"TTv5",
"TT5.c",
"EN-301-549",
"EN-9.3.3.2"
],
"description": "Ensure form field does not have multiple label elements",
"help": "Form field must not have multiple label elements",
"helpUrl": "https://dequeuniversity.com/rules/axe/4.10/form-field-multiple-labels?application=axeAPI",
"nodes": [
{
"any": [],
"all": [],
"none": [
{
"id": "multiple-label",
"data": null,
"relatedNodes": [
{
"html": "<label for=\"income\">Monthly take-home income</label>",
"target": [
"label[for=\"income\"]"
]
}
],
"impact": "moderate",
"message": "Form field does not have multiple label elements"
}
],
"impact": null,
"html": "<input id=\"income\" name=\"income\" type=\"number\" min=\"0\" step=\"100\" value=\"6200\" inputmode=\"decimal\" required=\"\">",
"target": [
"#income"
]
}
]
},
{
"id": "html-has-lang",
"impact": null,
"tags": [
"cat.language",
"wcag2a",
"wcag311",
"TTv5",
"TT11.a",
"EN-301-549",
"EN-9.3.1.1",
"ACT"
],
"description": "Ensure every HTML document has a lang attribute",
"help": "<html> element must have a lang attribute",
"helpUrl": "https://dequeuniversity.com/rules/axe/4.10/html-has-lang?application=axeAPI",
"nodes": [
{
"any": [
{
"id": "has-lang",
"data": null,
"relatedNodes": [],
"impact": "serious",
"message": "The <html> element has a lang attribute"
}
],
"all": [],
"none": [],
"impact": null,
"html": "<html lang=\"en\">",
"target": [
"html"
]
}
]
},
{
"id": "html-lang-valid",
"impact": null,
"tags": [
"cat.language",
"wcag2a",
"wcag311",
"TTv5",
"TT11.a",
"EN-301-549",
"EN-9.3.1.1",
"ACT"
],
"description": "Ensure the lang attribute of the <html> element has a valid value",
"help": "<html> element must have a valid value for the lang attribute",
"helpUrl": "https://dequeuniversity.com/rules/axe/4.10/html-lang-valid?application=axeAPI",
"nodes": [
{
"any": [],
"all": [],
"none": [
{
"id": "valid-lang",
"data": null,
"relatedNodes": [],
"impact": "serious",
"message": "Value of lang attribute is included in the list of valid languages"
}
],
"impact": null,
"html": "<html lang=\"en\">",
"target": [
"html"
]
}
]
},
{
"id": "image-alt",
"impact": null,
"tags": [
"cat.text-alternatives",
"wcag2a",
"wcag111",
"section508",
"section508.22.a",
"TTv5",
"TT7.a",
"TT7.b",
"EN-301-549",
"EN-9.1.1.1",
"ACT"
],
"description": "Ensure <img> elements have alternative text or a role of none or presentation",
"help": "Images must have alternative text",
"helpUrl": "https://dequeuniversity.com/rules/axe/4.10/image-alt?application=axeAPI",
"nodes": [
{
"any": [
{
"id": "has-alt",
"data": null,
"relatedNodes": [],
"impact": "critical",
"message": "Element has an alt attribute"
}
],
"all": [],
"none": [
{
"id": "alt-space-value",
"data": null,
"relatedNodes": [],
"impact": "critical",
"message": "Element has a valid alt attribute value"
}
],
"impact": null,
"html": "<img src=\"https://placehold.co/160x52/0d5c56/ffffff?text=Northlight\" alt=\"Northlight Money logo placeholder\">",
"target": [
".header-inner > .brand[aria-label=\"Northlight Money home\"][href$=\"#home\"] > img"
]
}
]
},
{
"id": "label",
"impact": null,
"tags": [
"cat.forms",
"wcag2a",
"wcag412",
"section508",
"section508.22.n",
"TTv5",
"TT5.c",
"EN-301-549",
"EN-9.4.1.2",
"ACT"
],
"description": "Ensure every form element has a label",
"help": "Form elements must have labels",
"helpUrl": "https://dequeuniversity.com/rules/axe/4.10/label?application=axeAPI",
"nodes": [
{
"any": [
{
"id": "explicit-label",
"data": {
"explicitLabel": "Monthly take-home income"
},
"relatedNodes": [
{
"html": "<label for=\"income\">Monthly take-home income</label>",
"target": [
"label[for=\"income\"]"
]
}
],
"impact": "critical",
"message": "Element has an explicit <label>"
}
],
"all": [],
"none": [
{
"id": "hidden-explicit-label",
"data": null,
"relatedNodes": [],
"impact": "critical",
"message": "Form element has a visible explicit <label>"
}
],
"impact": null,
"html": "<input id=\"income\" name=\"income\" type=\"number\" min=\"0\" step=\"100\" value=\"6200\" inputmode=\"decimal\" required=\"\">",
"target": [
"#income"
]
}
]
},
{
"id": "link-in-text-block",
"impact": null,
"tags": [
"cat.color",
"wcag2a",
"wcag141",
"TTv5",
"TT13.a",
"EN-301-549",
"EN-9.1.4.1"
],
"description": "Ensure links are distinguished from surrounding text in a way that does not rely on color",
"help": "Links must be distinguishable without relying on color",
"helpUrl": "https://dequeuniversity.com/rules/axe/4.10/link-in-text-block?application=axeAPI",
"nodes": [
{
"any": [
{
"id": "link-in-text-block-style",
"data": null,
"relatedNodes": [
{
"html": "<div class=\"contact-copy\">",
"target": [
".contact-copy"
]
}
],
"impact": "serious",
"message": "Links can be distinguished from surrounding text by visual styling"
}
],
"all": [],
"none": [],
"impact": null,
"html": "<a class=\"button button-primary\" href=\"#contact-form\">Request a Consultation <span aria-hidden=\"true\">\u2192</span></a>",
"target": [
"a[href$=\"#contact-form\"]"
]
}
]
},
{
"id": "link-name",
"impact": null,
"tags": [
"cat.name-role-value",
"wcag2a",
"wcag244",
"wcag412",
"section508",
"section508.22.a",
"TTv5",
"TT6.a",
"EN-301-549",
"EN-9.2.4.4",
"EN-9.4.1.2",
"ACT"
],
"description": "Ensure links have discernible text",
"help": "Links must have discernible text",
"helpUrl": "https://dequeuniversity.com/rules/axe/4.10/link-name?application=axeAPI",
"nodes": [
{
"any": [
{
"id": "has-visible-text",
"data": null,
"relatedNodes": [],
"impact": "serious",
"message": "Element has text that is visible to screen readers"
}
],
"all": [],
"none": [
{
"id": "focusable-no-name",
"data": null,
"relatedNodes": [],
"impact": "serious",
"message": "Element is not in tab order or has accessible text"
}
],
"impact": null,
"html": "<a class=\"skip-link\" href=\"#main-content\">Skip to main content</a>",
"target": [
".skip-link"
]
}
]
},
{
"id": "list",
"impact": null,
"tags": [
"cat.structure",
"wcag2a",
"wcag131",
"EN-301-549",
"EN-9.1.3.1"
],
"description": "Ensure that lists are structured correctly",
"help": "<ul> and <ol> must only directly contain <li>, <script> or <template> elements",
"helpUrl": "https://dequeuniversity.com/rules/axe/4.10/list?application=axeAPI",
"nodes": [
{
"any": [],
"all": [],
"none": [
{
"id": "only-listitems",
"data": null,
"relatedNodes": [],
"impact": "serious",
"message": "List element only has direct children that are allowed inside <li> elements"
}
],
"impact": null,
"html": "<ul class=\"check-list\">",
"target": [
".check-list"
]
}
]
},
{
"id": "listitem",
"impact": null,
"tags": [
"cat.structure",
"wcag2a",
"wcag131",
"EN-301-549",
"EN-9.1.3.1"
],
"description": "Ensure <li> elements are used semantically",
"help": "<li> elements must be contained in a <ul> or <ol>",
"helpUrl": "https://dequeuniversity.com/rules/axe/4.10/listitem?application=axeAPI",
"nodes": [
{
"any": [
{
"id": "listitem",
"data": null,
"relatedNodes": [],
"impact": "serious",
"message": "List item has a <ul>, <ol> or role=\"list\" parent element"
}
],
"all": [],
"none": [],
"impact": null,
"html": "<li>",
"target": [
".check-list > li:nth-child(1)"
]
}
]
},
{
"id": "meta-viewport",
"impact": null,
"tags": [
"cat.sensory-and-visual-cues",
"wcag2aa",
"wcag144",
"EN-301-549",
"EN-9.1.4.4",
"ACT"
],
"description": "Ensure <meta name=\"viewport\"> does not disable text scaling and zooming",
"help": "Zooming and scaling must not be disabled",
"helpUrl": "https://dequeuniversity.com/rules/axe/4.10/meta-viewport?application=axeAPI",
"nodes": [
{
"any": [
{
"id": "meta-viewport",
"data": null,
"relatedNodes": [],
"impact": "critical",
"message": "<meta> tag does not disable zooming on mobile devices"
}
],
"all": [],
"none": [],
"impact": null,
"html": "<meta name=\"viewport\" content=\"width=device-width, initial-scale=1\">",
"target": [
"meta[name=\"viewport\"]"
]
}
]
},
{
"id": "nested-interactive",
"impact": null,
"tags": [
"cat.keyboard",
"wcag2a",
"wcag412",
"TTv5",
"TT6.a",
"EN-301-549",
"EN-9.4.1.2"
],
"description": "Ensure interactive controls are not nested as they are not always announced by screen readers or can cause focus problems for assistive technologies",
"help": "Interactive controls must not be nested",
"helpUrl": "https://dequeuniversity.com/rules/axe/4.10/nested-interactive?application=axeAPI",
"nodes": [
{
"any": [
{
"id": "no-focusable-content",
"data": null,
"relatedNodes": [],
"impact": "serious",
"message": "Element does not have focusable descendants"
}
],
"all": [],
"none": [],
"impact": null,
"html": "<img src=\"https://placehold.co/160x52/0d5c56/ffffff?text=Northlight\" alt=\"Northlight Money logo placeholder\">",
"target": [
".header-inner > .brand[aria-label=\"Northlight Money home\"][href$=\"#home\"] > img"
]
}
]
},
{
"id": "select-name",
"impact": null,
"tags": [
"cat.forms",
"wcag2a",
"wcag412",
"section508",
"section508.22.n",
"TTv5",
"TT5.c",
"EN-301-549",
"EN-9.4.1.2",
"ACT"
],
"description": "Ensure select element has an accessible name",
"help": "Select element must have an accessible name",
"helpUrl": "https://dequeuniversity.com/rules/axe/4.10/select-name?application=axeAPI",
"nodes": [
{
"any": [
{
"id": "explicit-label",
"data": {
"explicitLabel": "I'm interested in"
},
"relatedNodes": [
{
"html": "<label for=\"topic\">I'm interested in</label>",
"target": [
"label[for=\"topic\"]"
]
}
],
"impact": "critical",
"message": "Element has an explicit <label>"
}
],
"all": [],
"none": [
{
"id": "hidden-explicit-label",
"data": null,
"relatedNodes": [],
"impact": "critical",
"message": "Form element has a visible explicit <label>"
}
],
"impact": null,
"html": "<select id=\"topic\" name=\"topic\"><option>Budgeting</option><option>Investing</option><option>Retirement</option><option>Credit health</option><option>Something else</option></select>",
"target": [
"#topic"
]
}
]
},
{
"id": "summary-name",
"impact": null,
"tags": [
"cat.name-role-value",
"wcag2a",
"wcag412",
"section508",
"section508.22.a",
"TTv5",
"TT6.a",
"EN-301-549",
"EN-9.4.1.2"
],
"description": "Ensure summary elements have discernible text",
"help": "Summary elements must have discernible text",
"helpUrl": "https://dequeuniversity.com/rules/axe/4.10/summary-name?application=axeAPI",
"nodes": [
{
"any": [
{
"id": "has-visible-text",
"data": null,
"relatedNodes": [],
"impact": "serious",
"message": "Element has text that is visible to screen readers"
}
],
"all": [],
"none": [],
"impact": null,
"html": "<summary>What makes Northlight different from a spreadsheet?</summary>",
"target": [
"details[open=\"\"] > summary"
]
}
]
},
{
"id": "target-size",
"impact": null,
"tags": [
"cat.sensory-and-visual-cues",
"wcag22aa",
"wcag258"
],
"description": "Ensure touch targets have sufficient size and space",
"help": "All touch targets must be 24px large, or leave sufficient space",
"helpUrl": "https://dequeuniversity.com/rules/axe/4.10/target-size?application=axeAPI",
"nodes": [
{
"any": [
{
"id": "target-size",
"data": {
"minSize": 24,
"width": 185.9,
"height": 46.4
},
"relatedNodes": [],
"impact": "serious",
"message": "Control has sufficient size (185.9px by 46.4px, should be at least 24px by 24px)"
},
{
"id": "target-offset",
"data": {
"closestOffset": 24,
"minOffset": 24
},
"relatedNodes": [],
"impact": "serious",
"message": "Target has sufficient space from its closest neighbors. Safe clickable space has a diameter of 24px which is at least 24px."
}
],
"all": [],
"none": [],
"impact": null,
"html": "<a class=\"skip-link\" href=\"#main-content\">Skip to main content</a>",
"target": [
".skip-link"
]
}
]
}
],
"incomplete": [
{
"id": "aria-prohibited-attr",
"impact": "serious",
"tags": [
"cat.aria",
"wcag2a",
"wcag412",
"EN-301-549",
"EN-9.4.1.2"
],
"description": "Ensure ARIA attributes are not prohibited for an element's role",
"help": "Elements must only use permitted ARIA attributes",
"helpUrl": "https://dequeuniversity.com/rules/axe/4.10/aria-prohibited-attr?application=axeAPI",
"nodes": [
{
"any": [],
"all": [],
"none": [
{
"id": "aria-prohibited-attr",
"data": {
"role": null,
"nodeName": "div",
"messageKey": "noRoleSingular",
"prohibited": [
"aria-label"
]
},
"relatedNodes": [],
"impact": "serious",
"message": "aria-label attribute is not well supported on a div with no valid role attribute."
}
],
"impact": "serious",
"html": "<div class=\"hero-proof\" aria-label=\"Northlight Money highlights\">",
"target": [
".hero-proof"
],
"failureSummary": "Fix all of the following:\n aria-label attribute is not well supported on a div with no valid role attribute."
}
]
},
{
"id": "color-contrast",
"impact": "serious",
"tags": [
"cat.color",
"wcag2aa",
"wcag143",
"TTv5",
"TT13.c",
"EN-301-549",
"EN-9.1.4.3",
"ACT"
],
"description": "Ensure the contrast between foreground and background colors meets WCAG 2 AA minimum contrast ratio thresholds",
"help": "Elements must meet minimum color contrast ratio thresholds",
"helpUrl": "https://dequeuniversity.com/rules/axe/4.10/color-contrast?application=axeAPI",
"nodes": [
{
"any": [
{
"id": "color-contrast",
"data": {
"fgColor": null,
"bgColor": null,
"contrastRatio": 0,
"fontSize": "9.0pt (12px)",
"fontWeight": "bold",
"messageKey": "bgGradient",
"expectedContrastRatio": "4.5:1",
"shadowColor": null
},
"relatedNodes": [
{
"html": "<section class=\"hero\" id=\"home\">",
"target": [
"#home"
]
}
],
"impact": "serious",
"message": "Element's background color could not be determined due to a background gradient"
}
],
"all": [],
"none": [],
"impact": "serious",
"html": "<span class=\"eyebrow\">A clearer way to manage money</span>",
"target": [
".eyebrow"
],
"failureSummary": "Fix any of the following:\n Element's background color could not be determined due to a background gradient"
}
]
}
],
"violations": [],
"coverage": {
"contract": "main-document-vertical-scroll",
"complete": true,
"positions": [
{
"y": 0,
"height": 7561
},
{
"y": 576,
"height": 7561
},
{
"y": 1152,
"height": 7561
},
{
"y": 1728,
"height": 7561
},
{
"y": 2304,
"height": 7561
},
{
"y": 2880,
"height": 7561
},
{
"y": 3456,
"height": 7561
},
{
"y": 4032,
"height": 7561
},
{
"y": 4608,
"height": 7561
},
{
"y": 5184,
"height": 7561
},
{
"y": 5760,
"height": 7561
},
{
"y": 6336,
"height": 7561
},
{
"y": 6841,
"height": 7561
}
],
"scans": 14,
"max_states": 512,
"settle_ms": 5000,
"page_timeout_seconds": 150,
"layout_stability": "consecutive 100ms size samples within one CSS pixel",
"animation_settling": "finite animations present when scroll resources are ready finish or are cancelled",
"interactive_states": "not exercised",
"horizontal_scroll": "not exercised"
}
}
System Prompt
You are a lead web developer at a top digital agency, tasked with creating a one-page website for a new client based on the given specifications, delivered as an HTML file. First non-whitespace char '<', last non-whitespace char '>'. Use the following services to generate placeholder images where needed:
- placehold.co (text): https://placehold.co/[{w}x{h}|{size}][/{bg-color}/{text-color}]?text={text}&font=[lato|lora|montserrat|noto sans|open sans|oswald|playfair display|poppins|pt sans|raleway|roboto|source sans|source sans pro]
- picsum.photos (photos): https://picsum.photos/[{w}/{h}|{size}]?[grayscale][&blur={1-10}]
- pravatar.cc (avatars): https://i.pravatar.cc/{size}?u={identifier}
Choose sizes appropriate to layout.
User Prompt
Create a **complete, polished, production-quality** primary web page for a new client in the "Personal Finance" sector.
Your goal is to generate the full HTML code for a page that is not just functional but also visually compelling, content-rich, and feels like a finished product ready for launch.
**Client & Category:**
- Industry: "Personal Finance"
- Description: Banking, investing, budgeting, savings, credit, and personal money management resources.
**Your Creative Task:**
1. **Invent:** Create a unique, professional-sounding site name and a strong tagline fitting the "Personal Finance" category.
2. **Define Page:** Determine the most effective primary page type (e.g., homepage, service landing page, category portal) to showcase this fictional entity.
3. **Design:** Develop an opinionated, modern, and professional layout. Make distinct choices about structure and flow.
**Content & Structure Requirements (Deliver a COMPLETE page):**
- **Overall:** The final page must feel substantial and complete, with realistic amounts of text (multiple paragraphs per section where appropriate, avoid single sentences), well-integrated placeholder images, and logical flow. It should look like a real website a business would proudly use.
- **HEADER:** Include the invented site name, tagline, a logo placeholder image, and a primary navigation bar. Ensure the navigation has **at least 5-7 clearly defined, relevant links** including: "Retirement", "Contact", "Investment".
- **MAIN CONTENT:** Structure this area with **at least 3-4 distinct, well-developed sections**.
- Address key topics relevant to the "Personal Finance" category. Consider themes similar to: "Debt Management", "Emergency Fund", "Retirement Planning".
- **Content Depth:** Populate each section with **substantial, realistic text** (multiple sentences/paragraphs). Use authentic industry language and terminology like: "tax optimization", "diversification", "portfolio".
- **Visuals:** Integrate relevant placeholder images logically within the content sections.
- **Calls to Action:** Include clear and contextually relevant CTAs. Use strong verbs similar to: "Create Budget", "Calculate", "Download Guide".
- **ENGAGEMENT (Recommended):** Strongly consider incorporating **one meaningful interactive element** that would genuinely benefit a user in the "Personal Finance" sector. Ideas similar but not limited to: "savings goal tracker".
- **SIDEBAR (Optional):** If your design includes a sidebar, populate it with **useful, relevant content**. Ideas: "trending topics", "expert insights", "calculator tools".
- **FOOTER:** Include a professional footer with invented contact details, copyright (current year), social media links, and standard links (Privacy, Terms).
- **MODERN WEB PATTERNS:** Include modern web patterns like testimonial cards, feature grids, or FAQ accordions where appropriate.