Clinic — Insurance Card & Coverage
A digital member insurance card that flips in 3D on click or the Flip button. The front carries the payer logo, member name, Member ID, group and plan, plus a PCP / Specialist / ER / Rx copay grid; the back shows customer service lines, the claims mailing address, website and fine print. Below the card, animated progress bars track deductible met and out-of-pocket max, with status chips and a one-tap copy-member-ID action.
MCP
Codice
:root {
--teal: #129c93;
--teal-d: #0c7a73;
--teal-700: #0a655f;
--teal-50: #e7f5f3;
--coral: #ff7a66;
--coral-soft: #ffe6df;
--ink: #16322f;
--ink-2: #3a534f;
--muted: #6b827e;
--bg: #f1f7f6;
--white: #ffffff;
--line: rgba(16, 50, 47, 0.1);
--line-2: rgba(16, 50, 47, 0.18);
--ok: #2f9e6f;
--warn: #d98a2b;
--danger: #d4503e;
--font: "Inter", system-ui, -apple-system, sans-serif;
--r-sm: 8px;
--r-md: 14px;
--r-lg: 20px;
--shadow-1: 0 1px 2px rgba(16, 50, 47, 0.05), 0 4px 14px rgba(16, 50, 47, 0.06);
--shadow-2: 0 16px 40px rgba(12, 122, 115, 0.16);
--shadow-card: 0 18px 46px rgba(10, 101, 95, 0.26);
}
*,
*::before,
*::after {
box-sizing: border-box;
margin: 0;
padding: 0;
}
body {
font-family: var(--font);
background: var(--bg);
color: var(--ink);
-webkit-font-smoothing: antialiased;
line-height: 1.5;
}
.mono {
font-variant-numeric: tabular-nums;
letter-spacing: 0.01em;
}
/* ── Layout ── */
.wrap {
max-width: 560px;
margin: 0 auto;
padding: 36px 20px 64px;
display: flex;
flex-direction: column;
gap: 26px;
}
.page-head {
display: flex;
flex-direction: column;
gap: 6px;
}
.eyebrow {
font-size: 0.78rem;
font-weight: 700;
letter-spacing: 0.04em;
text-transform: uppercase;
color: var(--teal-d);
}
.page-head h1 {
font-size: 1.7rem;
font-weight: 800;
letter-spacing: -0.02em;
}
.lead {
color: var(--muted);
font-size: 0.92rem;
max-width: 42ch;
}
/* ── Card stage / flip ── */
.card-stage {
display: flex;
flex-direction: column;
gap: 16px;
}
.flip {
perspective: 1600px;
}
.flip-inner {
position: relative;
width: 100%;
aspect-ratio: 1.586 / 1;
border: 0;
padding: 0;
background: transparent;
cursor: pointer;
transform-style: preserve-3d;
transition: transform 0.6s cubic-bezier(0.2, 0.7, 0.2, 1);
border-radius: var(--r-lg);
}
.flip-inner:focus-visible {
outline: 3px solid var(--teal);
outline-offset: 4px;
}
.flip[data-face="back"] .flip-inner {
transform: rotateY(180deg);
}
.face {
position: absolute;
inset: 0;
border-radius: var(--r-lg);
backface-visibility: hidden;
-webkit-backface-visibility: hidden;
overflow: hidden;
box-shadow: var(--shadow-card);
text-align: left;
}
/* ── Front face ── */
.face-front {
background: linear-gradient(150deg, var(--teal) 0%, var(--teal-d) 52%, var(--teal-700) 100%);
color: #fff;
padding: 20px 22px;
display: flex;
flex-direction: column;
gap: 14px;
}
.face-front::after {
content: "";
position: absolute;
right: -60px;
top: -90px;
width: 240px;
height: 240px;
background: radial-gradient(circle, rgba(255, 255, 255, 0.16), transparent 62%);
pointer-events: none;
}
.card-top {
display: flex;
align-items: flex-start;
justify-content: space-between;
gap: 12px;
}
.payer {
display: flex;
align-items: center;
gap: 11px;
}
.payer-logo {
display: grid;
place-items: center;
width: 42px;
height: 42px;
border-radius: 11px;
background: rgba(255, 255, 255, 0.16);
border: 1px solid rgba(255, 255, 255, 0.28);
font-weight: 800;
font-size: 0.95rem;
letter-spacing: 0.02em;
}
.payer-name {
display: flex;
flex-direction: column;
line-height: 1.25;
}
.payer-name strong {
font-size: 1.02rem;
font-weight: 700;
}
.payer-name span {
font-size: 0.76rem;
color: rgba(255, 255, 255, 0.78);
font-weight: 500;
}
.card-tag {
font-size: 0.68rem;
font-weight: 700;
text-transform: uppercase;
letter-spacing: 0.07em;
padding: 4px 10px;
border-radius: 999px;
background: rgba(255, 255, 255, 0.18);
border: 1px solid rgba(255, 255, 255, 0.25);
}
.card-grid {
display: grid;
grid-template-columns: 1fr 1fr;
gap: 10px 18px;
}
.field {
min-width: 0;
}
.field-wide {
grid-column: 1 / -1;
}
.field dt {
font-size: 0.64rem;
font-weight: 700;
text-transform: uppercase;
letter-spacing: 0.08em;
color: rgba(255, 255, 255, 0.66);
}
.field dd {
font-size: 0.95rem;
font-weight: 600;
margin-top: 1px;
}
.field-wide dd {
font-size: 1.12rem;
font-weight: 700;
}
.copay {
margin-top: auto;
}
.copay-label {
font-size: 0.64rem;
font-weight: 700;
text-transform: uppercase;
letter-spacing: 0.08em;
color: rgba(255, 255, 255, 0.66);
}
.copay-grid {
margin-top: 6px;
display: grid;
grid-template-columns: repeat(4, 1fr);
gap: 6px;
background: rgba(255, 255, 255, 0.12);
border: 1px solid rgba(255, 255, 255, 0.18);
border-radius: var(--r-sm);
padding: 8px 6px;
}
.copay-cell {
display: flex;
flex-direction: column;
align-items: center;
gap: 2px;
text-align: center;
}
.copay-cell + .copay-cell {
border-left: 1px solid rgba(255, 255, 255, 0.18);
}
.cp-k {
font-size: 0.64rem;
font-weight: 600;
text-transform: uppercase;
letter-spacing: 0.04em;
color: rgba(255, 255, 255, 0.78);
}
.cp-v {
font-size: 1.02rem;
font-weight: 800;
}
/* ── Back face ── */
.face-back {
transform: rotateY(180deg);
background: var(--white);
color: var(--ink);
display: flex;
flex-direction: column;
border: 1px solid var(--line);
}
.back-strip {
height: 38px;
background: var(--ink);
flex-shrink: 0;
}
.back-body {
padding: 16px 20px 18px;
display: flex;
flex-direction: column;
gap: 10px;
}
.back-row {
display: flex;
flex-direction: column;
gap: 1px;
}
.back-k {
font-size: 0.64rem;
font-weight: 700;
text-transform: uppercase;
letter-spacing: 0.07em;
color: var(--muted);
}
.back-v {
font-size: 0.88rem;
font-weight: 600;
color: var(--ink-2);
}
.fine-print {
margin-top: auto;
font-size: 0.66rem;
line-height: 1.4;
color: var(--muted);
border-top: 1px solid var(--line);
padding-top: 9px;
}
/* ── Card controls ── */
.card-controls {
display: flex;
gap: 10px;
flex-wrap: wrap;
}
.btn {
border: none;
border-radius: 11px;
padding: 10px 16px;
font: inherit;
font-weight: 600;
font-size: 0.86rem;
cursor: pointer;
display: inline-flex;
align-items: center;
gap: 8px;
transition: transform 0.12s, background 0.15s, border-color 0.15s, color 0.15s;
}
.btn:active {
transform: translateY(1px);
}
.btn:focus-visible {
outline: 3px solid var(--teal);
outline-offset: 2px;
}
.btn.ghost {
background: var(--white);
border: 1px solid var(--line-2);
color: var(--ink-2);
box-shadow: var(--shadow-1);
}
.btn.ghost:hover {
background: var(--teal-50);
border-color: var(--teal);
color: var(--teal-d);
}
.btn.is-done {
background: rgba(47, 158, 111, 0.12);
border-color: rgba(47, 158, 111, 0.4);
color: var(--ok);
}
.ico {
font-size: 1rem;
line-height: 1;
}
/* ── Coverage ── */
.coverage {
background: var(--white);
border: 1px solid var(--line);
border-radius: var(--r-md);
padding: 20px;
box-shadow: var(--shadow-1);
display: flex;
flex-direction: column;
gap: 18px;
}
.cov-head {
display: flex;
align-items: baseline;
justify-content: space-between;
gap: 10px;
flex-wrap: wrap;
}
.cov-head h2 {
font-size: 1.08rem;
font-weight: 700;
letter-spacing: -0.01em;
}
.cov-cycle {
font-size: 0.76rem;
color: var(--muted);
font-weight: 500;
}
.cov-row {
display: flex;
flex-direction: column;
gap: 8px;
}
.cov-top {
display: flex;
align-items: baseline;
justify-content: space-between;
gap: 10px;
}
.cov-name {
font-size: 0.9rem;
font-weight: 600;
color: var(--ink-2);
}
.cov-amt {
font-size: 0.86rem;
color: var(--muted);
}
.cov-amt strong {
color: var(--ink);
font-weight: 700;
}
.bar {
height: 10px;
border-radius: 999px;
background: var(--teal-50);
overflow: hidden;
}
.bar-fill {
display: block;
height: 100%;
width: 0;
border-radius: inherit;
background: linear-gradient(90deg, var(--teal), var(--teal-d));
transition: width 0.9s cubic-bezier(0.2, 0.7, 0.2, 1);
}
.cov-sub {
font-size: 0.78rem;
color: var(--muted);
}
.chips {
display: flex;
flex-wrap: wrap;
gap: 8px;
border-top: 1px solid var(--line);
padding-top: 16px;
}
.chip {
display: inline-flex;
align-items: center;
gap: 6px;
font-size: 0.76rem;
font-weight: 600;
padding: 6px 11px;
border-radius: 999px;
background: var(--teal-50);
color: var(--teal-d);
}
.chip-ok {
background: rgba(47, 158, 111, 0.14);
color: var(--ok);
}
.chip-warn {
background: rgba(217, 138, 43, 0.16);
color: var(--warn);
}
.chip .dot {
width: 7px;
height: 7px;
border-radius: 50%;
background: currentColor;
}
/* ── Toast ── */
.toast {
position: fixed;
left: 50%;
bottom: 26px;
transform: translateX(-50%);
background: var(--ink);
color: #fff;
padding: 13px 20px;
border-radius: 12px;
font-size: 0.9rem;
font-weight: 500;
box-shadow: var(--shadow-2);
z-index: 50;
max-width: 90vw;
}
@media (prefers-reduced-motion: reduce) {
.flip-inner,
.bar-fill {
transition: none;
}
}
@media (max-width: 520px) {
.wrap {
padding: 26px 16px 52px;
}
.page-head h1 {
font-size: 1.45rem;
}
.face-front {
padding: 16px 16px;
gap: 11px;
}
.card-grid {
gap: 8px 14px;
}
.field-wide dd {
font-size: 1.02rem;
}
.copay-grid {
padding: 7px 4px;
}
.cp-v {
font-size: 0.92rem;
}
.card-controls .btn {
flex: 1;
justify-content: center;
}
}// ── Toast ──────────────────────────────────────────────────────────────────
const toast = document.getElementById("toast");
function showToast(msg) {
toast.textContent = msg;
toast.hidden = false;
clearTimeout(showToast._t);
showToast._t = setTimeout(() => (toast.hidden = true), 2600);
}
// ── Card flip ────────────────────────────────────────────────────────────────
const flip = document.getElementById("flip");
const flipInner = document.getElementById("flipInner");
const flipBtn = document.getElementById("flipBtn");
function setFace(face) {
flip.dataset.face = face;
const onBack = face === "back";
flipInner.setAttribute("aria-pressed", String(onBack));
flipInner.setAttribute(
"aria-label",
`Insurance card, showing ${onBack ? "back" : "front"}. Activate to flip.`,
);
flipInner.querySelector(".face-front").setAttribute("aria-hidden", String(onBack));
flipInner.querySelector(".face-back").setAttribute("aria-hidden", String(!onBack));
}
function toggleFace() {
setFace(flip.dataset.face === "back" ? "front" : "back");
}
// Flip on card activation (click / Enter / Space all fire click on a <button>)
flipInner.addEventListener("click", toggleFace);
flipBtn.addEventListener("click", (e) => {
e.stopPropagation();
toggleFace();
});
// ── Copy member ID ───────────────────────────────────────────────────────────
const copyBtn = document.getElementById("copyBtn");
const memberIdText = document.getElementById("memberId").textContent.trim();
async function copyMemberId() {
let ok = false;
try {
if (navigator.clipboard && window.isSecureContext) {
await navigator.clipboard.writeText(memberIdText);
ok = true;
} else {
const ta = document.createElement("textarea");
ta.value = memberIdText;
ta.style.position = "fixed";
ta.style.opacity = "0";
document.body.appendChild(ta);
ta.select();
ok = document.execCommand("copy");
ta.remove();
}
} catch (_) {
ok = false;
}
if (ok) {
showToast(`Member ID ${memberIdText} copied to clipboard.`);
copyBtn.classList.add("is-done");
const label = copyBtn.innerHTML;
copyBtn.innerHTML = '<span class="ico" aria-hidden="true">✓</span> Copied';
clearTimeout(copyMemberId._t);
copyMemberId._t = setTimeout(() => {
copyBtn.classList.remove("is-done");
copyBtn.innerHTML = label;
}, 1800);
} else {
showToast(`Couldn't copy automatically — your Member ID is ${memberIdText}.`);
}
}
copyBtn.addEventListener("click", copyMemberId);
// ── Animate coverage bars on load ────────────────────────────────────────────
function animateBars() {
document.querySelectorAll(".bar-fill").forEach((fill) => {
const target = getComputedStyle(fill).getPropertyValue("--pct").trim() || "0%";
fill.style.width = "0%";
requestAnimationFrame(() => {
requestAnimationFrame(() => {
fill.style.width = target;
});
});
});
}
if (document.readyState === "complete") animateBars();
else window.addEventListener("load", animateBars);<!doctype html>
<html lang="en">
<head>
<meta charset="utf-8" />
<meta name="viewport" content="width=device-width, initial-scale=1" />
<title>Insurance Card & Coverage · Northpoint Clinic</title>
<link rel="preconnect" href="https://fonts.googleapis.com" />
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin />
<link
href="https://fonts.googleapis.com/css2?family=Inter:wght@400;500;600;700;800&display=swap"
rel="stylesheet"
/>
<link rel="stylesheet" href="style.css" />
</head>
<body>
<main class="wrap">
<header class="page-head">
<p class="eyebrow">Northpoint Clinic · Member portal</p>
<h1>Insurance & Coverage</h1>
<p class="lead">
Your digital member card. Tap the card or use Flip to see customer service details on the
back.
</p>
</header>
<!-- ── Card ─────────────────────────────────────────────── -->
<section class="card-stage" aria-label="Digital insurance card">
<div class="flip" id="flip" data-face="front">
<button
type="button"
class="flip-inner"
id="flipInner"
aria-pressed="false"
aria-label="Insurance card, showing front. Activate to flip."
>
<!-- FRONT -->
<div class="face face-front" aria-hidden="false">
<div class="card-top">
<div class="payer">
<span class="payer-logo" aria-hidden="true">EH</span>
<div class="payer-name">
<strong>Evergreen Health</strong>
<span>PPO Network</span>
</div>
</div>
<span class="card-tag">Medical</span>
</div>
<dl class="card-grid">
<div class="field field-wide">
<dt>Member</dt>
<dd>Maya R. Sandoval</dd>
</div>
<div class="field">
<dt>Member ID</dt>
<dd class="mono" id="memberId">EHX-4827-119-03</dd>
</div>
<div class="field">
<dt>Group #</dt>
<dd class="mono">GRP-58210</dd>
</div>
<div class="field">
<dt>Plan</dt>
<dd>Evergreen Choice Plus</dd>
</div>
<div class="field">
<dt>Effective</dt>
<dd>01 / 2026</dd>
</div>
</dl>
<div class="copay">
<span class="copay-label">Copay</span>
<div class="copay-grid">
<div class="copay-cell">
<span class="cp-k">PCP</span><span class="cp-v">$25</span>
</div>
<div class="copay-cell">
<span class="cp-k">Specialist</span><span class="cp-v">$45</span>
</div>
<div class="copay-cell">
<span class="cp-k">ER</span><span class="cp-v">$250</span>
</div>
<div class="copay-cell">
<span class="cp-k">Rx</span><span class="cp-v">$10</span>
</div>
</div>
</div>
</div>
<!-- BACK -->
<div class="face face-back" aria-hidden="true">
<div class="back-strip"></div>
<div class="back-body">
<div class="back-row">
<span class="back-k">Customer service</span>
<span class="back-v mono">1-800-555-0148</span>
</div>
<div class="back-row">
<span class="back-k">Nurse line (24/7)</span>
<span class="back-v mono">1-800-555-0192</span>
</div>
<div class="back-row">
<span class="back-k">Submit claims</span>
<span class="back-v"
>Evergreen Health, PO Box 9120,<br />Northpoint, OR 97000</span
>
</div>
<div class="back-row">
<span class="back-k">Online</span>
<span class="back-v">member.evergreenhealth.example</span>
</div>
<p class="fine-print">
This card does not guarantee coverage. Possession is not proof of eligibility.
Verify benefits before service. Present at every visit. Illustrative sample — not a
real insurance card.
</p>
</div>
</div>
</button>
</div>
<div class="card-controls">
<button type="button" class="btn ghost" id="copyBtn" data-action="copy">
<span class="ico" aria-hidden="true">⧉</span> Copy member ID
</button>
<button type="button" class="btn ghost" id="flipBtn" data-action="flip">
<span class="ico" aria-hidden="true">⤺</span> Flip card
</button>
</div>
</section>
<!-- ── Coverage summary ──────────────────────────────────── -->
<section class="coverage" aria-label="Coverage summary">
<div class="cov-head">
<h2>This year so far</h2>
<span class="cov-cycle">Plan year resets Jan 1, 2027</span>
</div>
<div class="cov-row">
<div class="cov-top">
<span class="cov-name">Deductible met</span>
<span class="cov-amt"><strong>$930</strong> of $1,500</span>
</div>
<div
class="bar"
role="progressbar"
aria-valuemin="0"
aria-valuemax="100"
aria-valuenow="62"
aria-label="Deductible met"
>
<span class="bar-fill" style="--pct: 62%"></span>
</div>
<span class="cov-sub">$570 remaining before full coverage kicks in</span>
</div>
<div class="cov-row">
<div class="cov-top">
<span class="cov-name">Out-of-pocket max</span>
<span class="cov-amt"><strong>$2,140</strong> of $6,000</span>
</div>
<div
class="bar"
role="progressbar"
aria-valuemin="0"
aria-valuemax="100"
aria-valuenow="36"
aria-label="Out-of-pocket maximum reached"
>
<span class="bar-fill" style="--pct: 36%"></span>
</div>
<span class="cov-sub">$3,860 remaining this plan year</span>
</div>
<div class="chips">
<span class="chip chip-ok"><span class="dot"></span> Active coverage</span>
<span class="chip">In-network: PCP assigned</span>
<span class="chip">Rx benefit included</span>
<span class="chip chip-warn">Referral needed for specialists</span>
</div>
</section>
</main>
<div id="toast" class="toast" role="status" aria-live="polite" hidden></div>
<script src="script.js"></script>
</body>
</html>Insurance Card & Coverage
A patient-facing digital insurance card for Northpoint Clinic. The card flips with a smooth 3D CSS transform — tap the card itself or press Flip card. The front presents the payer logo placeholder, member name, a tabular Member ID, group number, plan name and effective date, finished with a four-up copay grid for PCP, Specialist, ER and Rx visits. The back mirrors a real card: customer service and 24/7 nurse lines, the claims mailing address, the member website and the usual fine print.
Below the card, a coverage summary turns the numbers into something readable. Animated progress bars show the deductible met (62%) and progress toward the out-of-pocket maximum, each with the remaining balance spelled out, alongside status chips for active coverage, an assigned in-network PCP and the specialist referral requirement.
Copy member ID writes the ID to the clipboard and confirms with a toast, briefly switching to a checked state; it falls back gracefully when the Clipboard API is unavailable. Everything is vanilla JS with no dependencies, keyboard-operable, ARIA-labelled and responsive down to roughly 360px.
Illustrative UI only — not intended for real medical use.