Insurance — Coverage Detail
A single-plan coverage detail page with a hero showing plan name and monthly price, paired whats-covered and not-covered lists, a coverage limits table, optional add-on riders with toggles that recalculate the live total, and a confident get-this-plan call to action.
MCP
Code
:root {
--blue: #2563eb;
--blue-d: #1d4ed8;
--green: #15a06b;
--blue-50: #eef4ff;
--ink: #0f1a2b;
--muted: #5a6b82;
--bg: #f3f7fc;
--white: #ffffff;
--line: #e2eaf4;
--shadow: 0 1px 2px rgba(15, 26, 43, 0.04), 0 8px 24px rgba(15, 26, 43, 0.06);
--radius: 18px;
--radius-sm: 12px;
}
* {
box-sizing: border-box;
margin: 0;
padding: 0;
}
body {
font-family: "Inter", system-ui, -apple-system, sans-serif;
background: var(--bg);
color: var(--ink);
line-height: 1.55;
-webkit-font-smoothing: antialiased;
padding: 32px 18px 120px;
}
.page {
max-width: 960px;
margin: 0 auto;
display: flex;
flex-direction: column;
gap: 36px;
}
/* ---- Hero ---- */
.hero {
background: linear-gradient(140deg, var(--blue) 0%, var(--blue-d) 100%);
color: var(--white);
border-radius: 24px;
padding: 36px;
display: grid;
grid-template-columns: 1.4fr 1fr;
gap: 28px;
box-shadow: var(--shadow);
}
.badge {
display: inline-block;
font-size: 12px;
font-weight: 700;
letter-spacing: 0.04em;
text-transform: uppercase;
padding: 5px 11px;
border-radius: 999px;
}
.badge--feature {
background: rgba(255, 255, 255, 0.18);
color: var(--white);
}
.hero__name {
font-size: 32px;
font-weight: 800;
letter-spacing: -0.02em;
margin: 14px 0 8px;
}
.hero__tag {
color: rgba(255, 255, 255, 0.82);
max-width: 42ch;
}
.hero__points {
list-style: none;
margin-top: 20px;
display: flex;
flex-direction: column;
gap: 9px;
font-size: 14px;
font-weight: 500;
color: rgba(255, 255, 255, 0.92);
}
.hero__points li {
display: flex;
align-items: center;
gap: 10px;
}
.dot {
width: 8px;
height: 8px;
border-radius: 50%;
background: #8be8c0;
flex: none;
box-shadow: 0 0 0 4px rgba(139, 232, 192, 0.25);
}
.pricecard {
background: var(--white);
color: var(--ink);
border-radius: var(--radius);
padding: 24px;
display: flex;
flex-direction: column;
justify-content: center;
gap: 6px;
box-shadow: 0 12px 30px rgba(15, 26, 43, 0.18);
}
.pricecard__label {
font-size: 13px;
font-weight: 600;
color: var(--muted);
}
.pricecard__price {
display: flex;
align-items: baseline;
gap: 2px;
font-weight: 800;
letter-spacing: -0.03em;
line-height: 1;
font-size: 52px;
}
.pricecard__currency {
font-size: 26px;
font-weight: 700;
align-self: flex-start;
margin-top: 6px;
}
.pricecard__per {
font-size: 17px;
font-weight: 600;
color: var(--muted);
}
.pricecard__note {
font-size: 13px;
color: var(--green);
font-weight: 600;
min-height: 19px;
}
.btn {
display: inline-flex;
align-items: center;
justify-content: center;
font-family: inherit;
font-size: 15px;
font-weight: 700;
text-decoration: none;
border: none;
border-radius: 12px;
padding: 13px 22px;
cursor: pointer;
transition: transform 0.12s ease, background 0.15s ease, box-shadow 0.15s ease;
}
.btn:focus-visible {
outline: 3px solid rgba(37, 99, 235, 0.45);
outline-offset: 2px;
}
.btn--ghost {
margin-top: 8px;
background: var(--blue-50);
color: var(--blue-d);
}
.btn--ghost:hover {
background: #e0ebff;
}
.btn--primary {
background: var(--green);
color: var(--white);
box-shadow: 0 8px 18px rgba(21, 160, 107, 0.32);
}
.btn--primary:hover {
background: #128a5c;
transform: translateY(-1px);
}
/* ---- Sections ---- */
.section__title {
font-size: 22px;
font-weight: 800;
letter-spacing: -0.02em;
margin-bottom: 4px;
}
.section__sub {
color: var(--muted);
font-size: 14px;
margin-bottom: 16px;
}
.section__title + .grid2,
.section__title + .table-card {
margin-top: 16px;
}
.card {
background: var(--white);
border: 1px solid var(--line);
border-radius: var(--radius);
box-shadow: var(--shadow);
}
.grid2 {
display: grid;
grid-template-columns: 1fr 1fr;
gap: 18px;
}
.list-card {
padding: 22px 24px;
}
.list-card__title {
display: flex;
align-items: center;
gap: 10px;
font-size: 16px;
font-weight: 700;
margin-bottom: 14px;
}
.ic {
width: 26px;
height: 26px;
border-radius: 50%;
display: inline-flex;
align-items: center;
justify-content: center;
font-size: 14px;
font-weight: 700;
flex: none;
}
.ic--check {
background: #e3f6ed;
color: var(--green);
}
.ic--cross {
background: #fdecec;
color: #c0413c;
}
.checklist {
list-style: none;
display: flex;
flex-direction: column;
gap: 11px;
}
.checklist li {
position: relative;
padding-left: 26px;
font-size: 14.5px;
font-weight: 500;
}
.checklist li::before {
content: "✓";
position: absolute;
left: 0;
top: -1px;
color: var(--green);
font-weight: 800;
}
.checklist--muted li {
color: var(--muted);
}
.checklist--muted li::before {
content: "✕";
color: #c0413c;
}
/* ---- Limits table ---- */
.table-card {
overflow: hidden;
}
.limits {
width: 100%;
border-collapse: collapse;
font-size: 14.5px;
}
.limits caption.sr-only,
.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;
}
.limits thead th {
text-align: left;
background: var(--blue-50);
color: var(--blue-d);
font-size: 12px;
font-weight: 700;
letter-spacing: 0.04em;
text-transform: uppercase;
padding: 14px 18px;
}
.limits tbody th,
.limits tbody td {
padding: 14px 18px;
border-top: 1px solid var(--line);
text-align: left;
}
.limits tbody th {
font-weight: 600;
color: var(--ink);
}
.limits tbody td {
color: var(--muted);
font-weight: 600;
}
.limits tbody td:nth-child(2) {
color: var(--ink);
}
.limits tbody tr:hover {
background: #f8fbff;
}
/* ---- Riders ---- */
.rider-card {
padding: 8px 24px;
}
.riders {
list-style: none;
}
.rider {
display: flex;
align-items: center;
justify-content: space-between;
gap: 18px;
padding: 18px 0;
border-top: 1px solid var(--line);
transition: opacity 0.15s ease;
}
.rider:first-child {
border-top: none;
}
.rider.is-on .rider__name {
color: var(--blue-d);
}
.rider__name {
font-size: 15.5px;
font-weight: 700;
margin-bottom: 3px;
}
.rider__desc {
font-size: 13.5px;
color: var(--muted);
max-width: 48ch;
}
.rider__right {
display: flex;
align-items: center;
gap: 18px;
flex: none;
}
.rider__price {
font-size: 16px;
font-weight: 800;
color: var(--ink);
white-space: nowrap;
}
.rider__per {
font-size: 12px;
font-weight: 600;
color: var(--muted);
}
/* Toggle */
.toggle {
position: relative;
display: inline-flex;
cursor: pointer;
}
.toggle input {
position: absolute;
opacity: 0;
width: 100%;
height: 100%;
margin: 0;
cursor: pointer;
}
.toggle__track {
width: 46px;
height: 27px;
border-radius: 999px;
background: #cdd9e8;
display: inline-flex;
align-items: center;
padding: 3px;
transition: background 0.18s ease;
}
.toggle__thumb {
width: 21px;
height: 21px;
border-radius: 50%;
background: var(--white);
box-shadow: 0 1px 3px rgba(15, 26, 43, 0.3);
transition: transform 0.18s ease;
}
.toggle input:checked + .toggle__track {
background: var(--green);
}
.toggle input:checked + .toggle__track .toggle__thumb {
transform: translateX(19px);
}
.toggle input:focus-visible + .toggle__track {
box-shadow: 0 0 0 3px rgba(37, 99, 235, 0.4);
}
/* ---- Sticky CTA ---- */
.cta {
position: sticky;
bottom: 18px;
margin-top: 4px;
background: var(--white);
border: 1px solid var(--line);
border-radius: var(--radius);
box-shadow: 0 12px 32px rgba(15, 26, 43, 0.14);
padding: 16px 22px;
display: flex;
align-items: center;
justify-content: space-between;
gap: 18px;
}
.cta__line {
font-size: 14px;
font-weight: 700;
color: var(--ink);
}
.cta__riders {
display: inline-block;
margin-left: 8px;
font-size: 12px;
font-weight: 600;
color: var(--blue-d);
background: var(--blue-50);
padding: 3px 10px;
border-radius: 999px;
}
.cta__total {
display: flex;
align-items: baseline;
gap: 5px;
margin-top: 2px;
}
.cta__totalprice {
font-size: 26px;
font-weight: 800;
letter-spacing: -0.02em;
}
.cta__per {
font-size: 13px;
color: var(--muted);
font-weight: 600;
}
.flash {
animation: flash 0.45s ease;
}
@keyframes flash {
0% {
transform: scale(1);
}
40% {
transform: scale(1.12);
color: var(--green);
}
100% {
transform: scale(1);
}
}
/* ---- Responsive ---- */
@media (max-width: 520px) {
body {
padding: 18px 12px 130px;
}
.hero {
grid-template-columns: 1fr;
padding: 26px 22px;
}
.hero__name {
font-size: 26px;
}
.grid2 {
grid-template-columns: 1fr;
}
.pricecard__price {
font-size: 44px;
}
.limits {
font-size: 13px;
}
.limits thead th,
.limits tbody th,
.limits tbody td {
padding: 11px 12px;
}
.rider {
flex-direction: column;
align-items: flex-start;
gap: 12px;
}
.rider__right {
width: 100%;
justify-content: space-between;
}
.cta {
flex-direction: column;
align-items: stretch;
text-align: left;
}
.cta .btn--primary {
width: 100%;
}
}// Insurance — Coverage Detail
// Recalculates the live monthly premium as add-on riders are toggled. Vanilla JS, no libraries.
(function () {
"use strict";
var BASE_PRICE = 148;
var riderList = document.getElementById("riderList");
var heroPrice = document.getElementById("heroPrice");
var ctaPrice = document.getElementById("ctaPrice");
var heroNote = document.getElementById("heroNote");
var ctaRiders = document.getElementById("ctaRiders");
var getPlan = document.getElementById("getPlan");
if (!riderList) return;
var riders = Array.prototype.slice.call(
riderList.querySelectorAll("[data-rider]")
);
function recalc() {
var total = BASE_PRICE;
var active = [];
riders.forEach(function (rider) {
var input = rider.querySelector("[data-toggle]");
var amount = parseInt(rider.getAttribute("data-amount"), 10) || 0;
var on = input && input.checked;
rider.classList.toggle("is-on", !!on);
if (on) {
total += amount;
var name = rider.querySelector(".rider__name");
if (name) active.push(name.textContent.trim());
}
});
// Update the two price displays with a small flash micro-interaction.
[heroPrice, ctaPrice].forEach(function (el) {
if (!el) return;
if (el.textContent !== String(total)) {
el.textContent = total;
el.classList.remove("flash");
// force reflow so the animation can replay
void el.offsetWidth;
el.classList.add("flash");
}
});
if (heroNote) {
heroNote.textContent = active.length
? active.length + " add-on" + (active.length > 1 ? "s" : "") + " selected"
: "Base plan only";
}
if (ctaRiders) {
if (active.length === 0) {
ctaRiders.textContent = "no add-ons";
} else if (active.length <= 2) {
ctaRiders.textContent = "+ " + active.join(", ");
} else {
ctaRiders.textContent = "+ " + active.length + " add-ons";
}
}
}
riders.forEach(function (rider) {
var input = rider.querySelector("[data-toggle]");
if (input) input.addEventListener("change", recalc);
});
if (getPlan) {
getPlan.addEventListener("click", function (e) {
e.preventDefault();
var price = ctaPrice ? ctaPrice.textContent : BASE_PRICE;
var label = getPlan.textContent;
getPlan.textContent = "Securing $" + price + "/mo plan…";
getPlan.style.pointerEvents = "none";
setTimeout(function () {
getPlan.textContent = "Plan reserved ✓";
setTimeout(function () {
getPlan.textContent = label;
getPlan.style.pointerEvents = "";
}, 1800);
}, 700);
});
}
recalc();
})();<!doctype html>
<html lang="en">
<head>
<meta charset="utf-8" />
<meta name="viewport" content="width=device-width, initial-scale=1" />
<title>SecureLife — Essential Health Plan</title>
<link rel="preconnect" href="https://fonts.googleapis.com" />
<link
href="https://fonts.googleapis.com/css2?family=Inter:wght@400;500;600;700;800&display=swap"
rel="stylesheet"
/>
<link rel="stylesheet" href="style.css" />
</head>
<body>
<main class="page">
<!-- Hero -->
<header class="hero">
<div class="hero__info">
<span class="badge badge--feature">Most popular</span>
<h1 class="hero__name">Essential Health Plan</h1>
<p class="hero__tag">
Everyday cover for individuals — doctors, prescriptions and emergencies, with no
surprises.
</p>
<ul class="hero__points">
<li><span class="dot" aria-hidden="true"></span> $0 cost for annual check-ups</li>
<li><span class="dot" aria-hidden="true"></span> Nationwide network of 12,400 providers</li>
<li><span class="dot" aria-hidden="true"></span> 24/7 telehealth included</li>
</ul>
</div>
<aside class="pricecard" aria-label="Plan price">
<p class="pricecard__label">Your monthly premium</p>
<p class="pricecard__price">
<span class="pricecard__currency">$</span><span id="heroPrice" data-price>148</span>
<span class="pricecard__per">/mo</span>
</p>
<p class="pricecard__note" id="heroNote">Base plan only</p>
<a class="btn btn--ghost" href="#riders">Customise add-ons</a>
</aside>
</header>
<!-- Covered / Not covered -->
<section class="section" aria-labelledby="coverHead">
<h2 class="section__title" id="coverHead">What's included</h2>
<div class="grid2">
<div class="card list-card list-card--yes">
<h3 class="list-card__title">
<span class="ic ic--check" aria-hidden="true">✓</span> What's covered
</h3>
<ul class="checklist">
<li>Primary & specialist doctor visits</li>
<li>Generic and brand prescriptions</li>
<li>Emergency room & ambulance</li>
<li>Lab tests, X-rays and diagnostics</li>
<li>Annual preventive screenings</li>
<li>Mental health & therapy sessions</li>
</ul>
</div>
<div class="card list-card list-card--no">
<h3 class="list-card__title">
<span class="ic ic--cross" aria-hidden="true">✕</span> Not covered
</h3>
<ul class="checklist checklist--muted">
<li>Cosmetic and elective procedures</li>
<li>Routine dental & orthodontics</li>
<li>Vision & corrective eyewear</li>
<li>Out-of-network non-emergency care</li>
<li>Experimental treatments</li>
<li>Long-term residential care</li>
</ul>
</div>
</div>
</section>
<!-- Coverage limits -->
<section class="section" aria-labelledby="limitsHead">
<h2 class="section__title" id="limitsHead">Coverage limits</h2>
<div class="card table-card">
<table class="limits">
<caption class="sr-only">Annual coverage limits, deductibles and co-pays by benefit</caption>
<thead>
<tr>
<th scope="col">Benefit</th>
<th scope="col">Annual max</th>
<th scope="col">Deductible</th>
<th scope="col">Co-pay</th>
</tr>
</thead>
<tbody>
<tr>
<th scope="row">Doctor visits</th>
<td>Unlimited</td>
<td>$250</td>
<td>$20 / visit</td>
</tr>
<tr>
<th scope="row">Prescriptions</th>
<td>$4,000</td>
<td>$50</td>
<td>$10 / fill</td>
</tr>
<tr>
<th scope="row">Hospital & surgery</th>
<td>$1,000,000</td>
<td>$500</td>
<td>10% coinsurance</td>
</tr>
<tr>
<th scope="row">Emergency care</th>
<td>$250,000</td>
<td>$250</td>
<td>$150 / visit</td>
</tr>
<tr>
<th scope="row">Mental health</th>
<td>30 sessions</td>
<td>$0</td>
<td>$25 / session</td>
</tr>
</tbody>
</table>
</div>
</section>
<!-- Riders -->
<section class="section" id="riders" aria-labelledby="ridersHead">
<h2 class="section__title" id="ridersHead">Add-on riders</h2>
<p class="section__sub">Tailor the plan — your premium updates instantly.</p>
<div class="card rider-card">
<ul class="riders" id="riderList">
<li class="rider" data-rider data-amount="32">
<div class="rider__text">
<h3 class="rider__name">Dental & Vision</h3>
<p class="rider__desc">Cleanings, fillings, eye exams and a $150 frame allowance.</p>
</div>
<div class="rider__right">
<span class="rider__price">+$32<span class="rider__per">/mo</span></span>
<label class="toggle">
<input type="checkbox" data-toggle aria-label="Add Dental and Vision rider" />
<span class="toggle__track" aria-hidden="true"><span class="toggle__thumb"></span></span>
</label>
</div>
</li>
<li class="rider" data-rider data-amount="24">
<div class="rider__text">
<h3 class="rider__name">Accident protection</h3>
<p class="rider__desc">Cash payout for fractures, dislocations and ER stays.</p>
</div>
<div class="rider__right">
<span class="rider__price">+$24<span class="rider__per">/mo</span></span>
<label class="toggle">
<input type="checkbox" data-toggle aria-label="Add Accident protection rider" />
<span class="toggle__track" aria-hidden="true"><span class="toggle__thumb"></span></span>
</label>
</div>
</li>
<li class="rider" data-rider data-amount="18">
<div class="rider__text">
<h3 class="rider__name">Worldwide travel cover</h3>
<p class="rider__desc">Emergency medical care in 190+ countries while you travel.</p>
</div>
<div class="rider__right">
<span class="rider__price">+$18<span class="rider__per">/mo</span></span>
<label class="toggle">
<input type="checkbox" data-toggle aria-label="Add Worldwide travel cover rider" />
<span class="toggle__track" aria-hidden="true"><span class="toggle__thumb"></span></span>
</label>
</div>
</li>
<li class="rider" data-rider data-amount="40">
<div class="rider__text">
<h3 class="rider__name">Family wellness</h3>
<p class="rider__desc">Add up to 3 dependents with pediatric and maternity care.</p>
</div>
<div class="rider__right">
<span class="rider__price">+$40<span class="rider__per">/mo</span></span>
<label class="toggle">
<input type="checkbox" data-toggle aria-label="Add Family wellness rider" />
<span class="toggle__track" aria-hidden="true"><span class="toggle__thumb"></span></span>
</label>
</div>
</li>
</ul>
</div>
</section>
<!-- Sticky CTA -->
<div class="cta" role="region" aria-label="Plan summary and checkout">
<div class="cta__summary">
<p class="cta__line">
Essential Health Plan
<span class="cta__riders" id="ctaRiders">no add-ons</span>
</p>
<p class="cta__total">
<span class="cta__totalprice">$<span id="ctaPrice" data-price>148</span></span>
<span class="cta__per">/month</span>
</p>
</div>
<a class="btn btn--primary" href="#" id="getPlan">Get this plan</a>
</div>
</main>
<script src="script.js"></script>
</body>
</html>Coverage Detail
A reassuring, single-plan coverage page for an insurance product. The hero leads with the plan name, a short trust line and a big confident monthly price. Below it, two clear columns lay out what’s covered with green checks and what’s not covered with muted crosses, so prospects know exactly where they stand.
A coverage limits table summarises annual maximums, deductibles and co-pay for the main benefit categories. Optional add-on riders sit in their own card, each with a toggle and its own price; flipping any toggle instantly recalculates the running monthly total shown in the hero and in the sticky CTA.
Everything is plain HTML, CSS custom properties and vanilla JavaScript — no libraries, no build
step. Drop it in and restyle the :root palette to match any brand.
Illustrative UI only — not a real insurance product, quote or contract.