Dental — Landing Family
A warm, trust-first family dentistry landing page with a reassuring hero, all-ages service cards, a kids-friendly first-visit note, an accepted-insurance strip, and a two-step booking widget. Filterable services, an animated smile-count stat, an appointment picker with live date and time selection, and a friendly toast confirmation make it feel alive. Clean clinical light palette, rounded shapes, generous white space, fully responsive down to small phones, keyboard-usable, and WCAG-minded.
MCP
Code
:root {
--blue: #2563eb;
--blue-d: #1d4ed8;
--blue-50: #eff5ff;
--mint: #34d399;
--mint-50: #e8fbf3;
--ink: #0f2740;
--ink-2: #3a5169;
--muted: #6b7c90;
--bg: #f3f8ff;
--white: #fff;
--line: rgba(15, 39, 64, 0.10);
--line-2: rgba(15, 39, 64, 0.18);
--ok: #22b07d;
--warn: #d98a2b;
--danger: #e05252;
--r-sm: 8px;
--r-md: 14px;
--r-lg: 22px;
--sh-sm: 0 1px 2px rgba(15, 39, 64, 0.06), 0 2px 8px rgba(15, 39, 64, 0.05);
--sh-md: 0 8px 24px rgba(15, 39, 64, 0.08);
--sh-lg: 0 20px 50px rgba(37, 99, 235, 0.14);
}
* { box-sizing: border-box; }
html { scroll-behavior: smooth; }
body {
margin: 0;
font-family: "Inter", system-ui, -apple-system, sans-serif;
color: var(--ink);
background: var(--bg);
line-height: 1.5;
-webkit-font-smoothing: antialiased;
-moz-osx-font-smoothing: grayscale;
}
h1, h2, h3 { margin: 0; line-height: 1.15; letter-spacing: -0.02em; }
p { margin: 0; }
a { color: inherit; text-decoration: none; }
ul { margin: 0; padding: 0; list-style: none; }
.wrap { width: min(1140px, 100% - 40px); margin-inline: auto; }
.skip-link {
position: absolute;
left: -999px;
top: 0;
background: var(--ink);
color: #fff;
padding: 10px 16px;
border-radius: var(--r-sm);
z-index: 100;
}
.skip-link:focus { left: 12px; top: 12px; }
:focus-visible {
outline: 3px solid rgba(37, 99, 235, 0.45);
outline-offset: 2px;
border-radius: var(--r-sm);
}
/* Buttons */
.btn {
display: inline-flex;
align-items: center;
justify-content: center;
gap: 8px;
font: inherit;
font-weight: 600;
border: 1px solid transparent;
border-radius: 999px;
padding: 11px 20px;
cursor: pointer;
transition: transform .15s ease, box-shadow .2s ease, background .2s ease, color .2s ease;
white-space: nowrap;
}
.btn:active { transform: translateY(1px) scale(0.99); }
.btn-primary {
background: var(--blue);
color: #fff;
box-shadow: 0 6px 16px rgba(37, 99, 235, 0.28);
}
.btn-primary:hover { background: var(--blue-d); box-shadow: 0 10px 22px rgba(37, 99, 235, 0.34); }
.btn-ghost {
background: var(--white);
color: var(--ink);
border-color: var(--line-2);
}
.btn-ghost:hover { border-color: var(--blue); color: var(--blue); }
.btn-lg { padding: 14px 26px; font-size: 1.02rem; }
.btn-block { width: 100%; }
.badge {
display: inline-flex;
align-items: center;
gap: 5px;
font-size: .74rem;
font-weight: 700;
padding: 4px 10px;
border-radius: 999px;
letter-spacing: .01em;
}
.badge-ok { background: var(--mint-50); color: var(--ok); }
.eyebrow {
display: inline-block;
font-size: .78rem;
font-weight: 700;
text-transform: uppercase;
letter-spacing: .08em;
color: var(--blue);
margin-bottom: 10px;
}
.eyebrow-mint { color: var(--ok); }
.eyebrow-light { color: rgba(255, 255, 255, 0.85); }
/* Header */
.site-header {
position: sticky;
top: 0;
z-index: 40;
background: rgba(243, 248, 255, 0.82);
backdrop-filter: saturate(1.4) blur(12px);
border-bottom: 1px solid var(--line);
}
.header-inner {
display: flex;
align-items: center;
gap: 20px;
height: 68px;
}
.brand { display: inline-flex; align-items: center; gap: 10px; }
.brand-mark {
display: grid;
place-items: center;
width: 38px;
height: 38px;
border-radius: 12px;
background: linear-gradient(135deg, var(--blue), var(--blue-d));
color: #fff;
box-shadow: 0 6px 14px rgba(37, 99, 235, 0.3);
}
.brand-name {
display: flex;
flex-direction: column;
font-weight: 800;
font-size: 1.05rem;
line-height: 1.05;
}
.brand-sub {
font-size: .68rem;
font-weight: 600;
letter-spacing: .06em;
text-transform: uppercase;
color: var(--muted);
}
.nav { display: flex; gap: 6px; margin-left: 12px; }
.nav a {
padding: 8px 14px;
border-radius: 999px;
font-weight: 500;
font-size: .94rem;
color: var(--ink-2);
transition: background .2s, color .2s;
}
.nav a:hover { background: var(--blue-50); color: var(--blue); }
.header-cta { margin-left: auto; display: flex; align-items: center; gap: 14px; }
.phone {
display: inline-flex;
align-items: center;
gap: 7px;
font-weight: 600;
font-size: .92rem;
color: var(--ink-2);
}
.phone:hover { color: var(--blue); }
/* Hero */
.hero { padding: 54px 0 20px; }
.hero-grid {
display: grid;
grid-template-columns: 1.35fr 0.85fr;
gap: 42px;
align-items: center;
}
.pill {
display: inline-flex;
align-items: center;
gap: 8px;
background: var(--white);
border: 1px solid var(--line);
color: var(--ink-2);
font-weight: 600;
font-size: .84rem;
padding: 7px 14px;
border-radius: 999px;
box-shadow: var(--sh-sm);
}
.pill .dot {
width: 8px;
height: 8px;
border-radius: 50%;
background: var(--mint);
box-shadow: 0 0 0 4px var(--mint-50);
animation: pulse 2s infinite;
}
@keyframes pulse {
0%, 100% { box-shadow: 0 0 0 4px var(--mint-50); }
50% { box-shadow: 0 0 0 7px rgba(52, 211, 153, 0.15); }
}
.hero h1 {
font-size: clamp(2.1rem, 5vw, 3.5rem);
font-weight: 800;
margin: 18px 0 16px;
}
.hero h1 .hl {
background: linear-gradient(120deg, var(--blue), var(--mint));
-webkit-background-clip: text;
background-clip: text;
color: transparent;
}
.lede { font-size: 1.12rem; color: var(--ink-2); max-width: 46ch; }
.hero-actions { display: flex; gap: 12px; margin: 28px 0 26px; flex-wrap: wrap; }
.hero-trust { display: flex; align-items: center; gap: 22px; flex-wrap: wrap; }
.rating { display: flex; align-items: center; gap: 7px; font-size: .96rem; }
.rating .stars { color: #f5a623; letter-spacing: 1px; }
.rating strong { font-weight: 800; }
.muted { color: var(--muted); }
.avatars { display: flex; }
.avatars span {
width: 36px;
height: 36px;
border-radius: 50%;
display: grid;
place-items: center;
font-size: .74rem;
font-weight: 700;
color: #fff;
background: var(--g, #999);
border: 2px solid var(--bg);
margin-left: -10px;
}
.avatars span:first-child { margin-left: 0; }
.avatars .more { background: var(--ink); font-size: .68rem; }
/* Hero card */
.hero-card {
background: var(--white);
border: 1px solid var(--line);
border-radius: var(--r-lg);
padding: 26px;
box-shadow: var(--sh-lg);
position: relative;
}
.hero-card::before {
content: "";
position: absolute;
inset: -1px;
border-radius: var(--r-lg);
padding: 1px;
background: linear-gradient(160deg, rgba(37, 99, 235, 0.4), transparent 45%);
-webkit-mask: linear-gradient(#000 0 0) content-box, linear-gradient(#000 0 0);
-webkit-mask-composite: xor;
mask-composite: exclude;
pointer-events: none;
}
.hero-card-top { display: flex; align-items: center; justify-content: space-between; gap: 10px; }
.hero-card-top h2 { font-size: 1.28rem; }
.hero-card-sub { color: var(--muted); font-size: .92rem; margin-top: 6px; }
.mini-stat {
display: flex;
align-items: center;
gap: 16px;
background: var(--blue-50);
border-radius: var(--r-md);
padding: 16px;
margin: 18px 0;
}
.mini-num {
display: block;
font-size: 1.55rem;
font-weight: 800;
color: var(--blue-d);
font-variant-numeric: tabular-nums;
}
.mini-label { font-size: .78rem; color: var(--ink-2); }
.mini-div { width: 1px; align-self: stretch; background: var(--line-2); }
.hero-card-foot {
display: flex;
align-items: center;
gap: 7px;
justify-content: center;
margin-top: 14px;
font-size: .82rem;
color: var(--ok);
font-weight: 600;
}
/* Feature strip */
.feature-strip {
display: grid;
grid-template-columns: repeat(4, 1fr);
gap: 16px;
margin-top: 48px;
}
.feat {
display: flex;
align-items: center;
gap: 12px;
background: var(--white);
border: 1px solid var(--line);
border-radius: var(--r-md);
padding: 16px;
box-shadow: var(--sh-sm);
transition: transform .18s ease, box-shadow .2s ease;
}
.feat:hover { transform: translateY(-3px); box-shadow: var(--sh-md); }
.feat-ico {
font-size: 1.5rem;
width: 44px;
height: 44px;
display: grid;
place-items: center;
background: var(--blue-50);
border-radius: 12px;
flex-shrink: 0;
}
.feat strong { display: block; font-size: .96rem; }
.feat span { font-size: .82rem; color: var(--muted); }
/* Sections */
.section { padding: 68px 0; }
.section-head {
display: flex;
align-items: flex-end;
justify-content: space-between;
gap: 24px;
margin-bottom: 34px;
flex-wrap: wrap;
}
.section-head h2 { font-size: clamp(1.6rem, 3.5vw, 2.2rem); font-weight: 800; }
.section-head.center { justify-content: center; text-align: center; }
.section-sub { color: var(--ink-2); max-width: 52ch; margin: 12px auto 0; }
/* Filters */
.filters { display: flex; gap: 8px; flex-wrap: wrap; }
.chip {
font: inherit;
font-weight: 600;
font-size: .88rem;
padding: 9px 16px;
border-radius: 999px;
border: 1px solid var(--line-2);
background: var(--white);
color: var(--ink-2);
cursor: pointer;
transition: all .18s ease;
}
.chip:hover { border-color: var(--blue); color: var(--blue); }
.chip.is-active {
background: var(--blue);
border-color: var(--blue);
color: #fff;
box-shadow: 0 6px 14px rgba(37, 99, 235, 0.26);
}
/* Service cards */
.cards {
display: grid;
grid-template-columns: repeat(3, 1fr);
gap: 20px;
}
.card {
background: var(--white);
border: 1px solid var(--line);
border-radius: var(--r-lg);
padding: 24px;
box-shadow: var(--sh-sm);
transition: transform .2s ease, box-shadow .25s ease, border-color .2s;
display: flex;
flex-direction: column;
animation: cardIn .4s ease both;
}
@keyframes cardIn {
from { opacity: 0; transform: translateY(12px); }
to { opacity: 1; transform: none; }
}
.card:hover {
transform: translateY(-5px);
box-shadow: var(--sh-md);
border-color: rgba(37, 99, 235, 0.3);
}
.card-ico {
width: 52px;
height: 52px;
border-radius: 14px;
display: grid;
place-items: center;
font-size: 1.6rem;
background: var(--blue-50);
margin-bottom: 16px;
}
.card h3 { font-size: 1.14rem; margin-bottom: 8px; }
.card p { color: var(--ink-2); font-size: .92rem; flex-grow: 1; }
.card-meta {
display: flex;
align-items: center;
justify-content: space-between;
margin-top: 18px;
padding-top: 16px;
border-top: 1px solid var(--line);
}
.card-price { font-weight: 800; color: var(--ink); }
.card-price span { font-weight: 500; color: var(--muted); font-size: .8rem; }
.tags { display: flex; gap: 6px; margin-top: 14px; flex-wrap: wrap; }
.tag {
font-size: .7rem;
font-weight: 700;
padding: 3px 9px;
border-radius: 999px;
background: var(--mint-50);
color: var(--ok);
text-transform: capitalize;
}
.card-link {
font-size: .86rem;
font-weight: 700;
color: var(--blue);
display: inline-flex;
align-items: center;
gap: 4px;
}
.card-link:hover { color: var(--blue-d); }
/* Kids section */
.kids-section { background: linear-gradient(180deg, #fff 0%, var(--mint-50) 100%); }
.kids-grid {
display: grid;
grid-template-columns: 1fr 1.1fr;
gap: 50px;
align-items: center;
}
.kids-media { position: relative; min-height: 340px; }
.kids-blob {
position: absolute;
inset: 10px;
border-radius: 40% 60% 62% 38% / 46% 44% 56% 54%;
background: linear-gradient(135deg, #bfdbfe, #6ee7c4);
animation: morph 9s ease-in-out infinite;
}
@keyframes morph {
0%, 100% { border-radius: 40% 60% 62% 38% / 46% 44% 56% 54%; }
50% { border-radius: 58% 42% 40% 60% / 60% 55% 45% 40%; }
}
.kids-emoji {
position: absolute;
font-size: 2.2rem;
background: #fff;
width: 60px;
height: 60px;
display: grid;
place-items: center;
border-radius: 18px;
box-shadow: var(--sh-md);
animation: floaty 4s ease-in-out infinite;
}
.kids-emoji.e1 { top: 6%; left: 8%; }
.kids-emoji.e2 { top: 18%; right: 2%; animation-delay: .8s; }
.kids-emoji.e3 { bottom: 22%; left: 0; animation-delay: 1.6s; }
@keyframes floaty {
0%, 100% { transform: translateY(0) rotate(-4deg); }
50% { transform: translateY(-12px) rotate(4deg); }
}
.kids-card {
position: absolute;
bottom: 8%;
right: 6%;
background: #fff;
border-radius: var(--r-md);
padding: 16px 18px;
box-shadow: var(--sh-lg);
display: flex;
flex-direction: column;
gap: 3px;
max-width: 220px;
}
.kids-card-badge {
align-self: flex-start;
font-size: .68rem;
font-weight: 700;
text-transform: uppercase;
letter-spacing: .05em;
color: var(--blue);
background: var(--blue-50);
padding: 3px 9px;
border-radius: 999px;
margin-bottom: 4px;
}
.kids-card strong { font-size: 1rem; }
.kids-card span:last-child { font-size: .8rem; color: var(--muted); }
.kids-copy h2 { font-size: clamp(1.6rem, 3.5vw, 2.2rem); font-weight: 800; margin-bottom: 14px; }
.kids-copy > p { color: var(--ink-2); font-size: 1.02rem; }
.kids-list { margin: 22px 0 26px; display: grid; gap: 12px; }
.kids-list li, .book-perks li {
display: flex;
align-items: center;
gap: 11px;
font-weight: 500;
color: var(--ink-2);
}
.tick {
width: 24px;
height: 24px;
flex-shrink: 0;
display: grid;
place-items: center;
border-radius: 50%;
background: var(--mint);
color: #063a2a;
font-size: .78rem;
font-weight: 800;
}
/* Insurance */
.insurance { background: var(--white); border-block: 1px solid var(--line); }
.logos {
display: grid;
grid-template-columns: repeat(4, 1fr);
gap: 14px;
margin-bottom: 30px;
}
.logos li {
display: grid;
place-items: center;
padding: 20px 12px;
border: 1px solid var(--line);
border-radius: var(--r-md);
font-weight: 700;
color: var(--ink-2);
background: var(--bg);
transition: all .18s ease;
text-align: center;
}
.logos li:hover { color: var(--blue); border-color: var(--blue); transform: translateY(-3px); box-shadow: var(--sh-sm); }
.insurance-cta {
display: flex;
align-items: center;
justify-content: center;
gap: 20px;
flex-wrap: wrap;
background: var(--blue-50);
border-radius: var(--r-lg);
padding: 22px 26px;
text-align: center;
}
.insurance-cta p { font-weight: 600; color: var(--ink); }
/* Book section */
.book-section {
background: linear-gradient(150deg, var(--blue-d), var(--blue));
color: #fff;
}
.book-grid {
display: grid;
grid-template-columns: 0.95fr 1.05fr;
gap: 44px;
align-items: start;
}
.book-info h2 { font-size: clamp(1.7rem, 3.6vw, 2.3rem); font-weight: 800; margin-bottom: 14px; }
.book-info > p { color: rgba(255, 255, 255, 0.9); font-size: 1.05rem; max-width: 42ch; }
.book-perks { margin: 24px 0; display: grid; gap: 12px; }
.book-perks li { color: rgba(255, 255, 255, 0.95); }
.book-contact {
display: flex;
align-items: center;
gap: 12px;
flex-wrap: wrap;
color: rgba(255, 255, 255, 0.85);
font-size: .92rem;
font-weight: 500;
}
.book-contact a { display: inline-flex; align-items: center; gap: 7px; font-weight: 600; }
.book-contact a:hover { text-decoration: underline; }
.book-form {
background: var(--white);
color: var(--ink);
border-radius: var(--r-lg);
padding: 28px;
box-shadow: var(--sh-lg);
}
.field { margin-bottom: 18px; }
.field-row { display: grid; grid-template-columns: 1fr 1fr; gap: 14px; }
.field label, .field-label {
display: block;
font-weight: 600;
font-size: .88rem;
margin-bottom: 7px;
color: var(--ink);
}
.field input, .field select {
width: 100%;
font: inherit;
padding: 12px 14px;
border: 1px solid var(--line-2);
border-radius: var(--r-sm);
background: var(--white);
color: var(--ink);
transition: border-color .18s, box-shadow .18s;
}
.field input:focus, .field select:focus {
outline: none;
border-color: var(--blue);
box-shadow: 0 0 0 3px rgba(37, 99, 235, 0.15);
}
.field input.invalid { border-color: var(--danger); box-shadow: 0 0 0 3px rgba(224, 82, 82, 0.14); }
.days { display: grid; grid-template-columns: repeat(5, 1fr); gap: 8px; }
.day, .slot {
font: inherit;
cursor: pointer;
border: 1px solid var(--line-2);
background: var(--white);
border-radius: var(--r-sm);
transition: all .16s ease;
text-align: center;
}
.day {
padding: 10px 4px;
display: flex;
flex-direction: column;
gap: 2px;
}
.day .dow { font-size: .72rem; font-weight: 600; color: var(--muted); text-transform: uppercase; }
.day .dnum { font-size: 1.15rem; font-weight: 800; }
.day:hover, .slot:hover { border-color: var(--blue); color: var(--blue); }
.day.sel, .slot.sel {
background: var(--blue);
border-color: var(--blue);
color: #fff;
box-shadow: 0 5px 12px rgba(37, 99, 235, 0.28);
}
.day.sel .dow { color: rgba(255, 255, 255, 0.85); }
.slots { display: grid; grid-template-columns: repeat(4, 1fr); gap: 8px; }
.slot { padding: 10px 4px; font-weight: 600; font-size: .9rem; }
.slot[aria-disabled="true"] {
opacity: .4;
cursor: not-allowed;
text-decoration: line-through;
}
.slot[aria-disabled="true"]:hover { border-color: var(--line-2); color: inherit; }
.form-note {
display: flex;
align-items: center;
gap: 7px;
justify-content: center;
margin-top: 16px;
font-size: .82rem;
color: var(--muted);
}
/* Footer */
.site-footer { background: var(--ink); color: rgba(255, 255, 255, 0.8); padding: 52px 0 24px; }
.footer-inner {
display: grid;
grid-template-columns: 1.2fr 2fr;
gap: 40px;
padding-bottom: 32px;
border-bottom: 1px solid rgba(255, 255, 255, 0.12);
}
.footer-brand .brand-name { color: #fff; }
.footer-brand .brand-sub { color: rgba(255, 255, 255, 0.55); }
.footer-brand p { margin-top: 12px; font-size: .92rem; max-width: 34ch; }
.footer-cols { display: grid; grid-template-columns: repeat(3, 1fr); gap: 24px; }
.footer-cols h3 { font-size: .82rem; text-transform: uppercase; letter-spacing: .06em; color: #fff; margin-bottom: 14px; }
.footer-cols a, .footer-cols span { display: block; font-size: .9rem; margin-bottom: 9px; color: rgba(255, 255, 255, 0.72); }
.footer-cols a:hover { color: #fff; }
.footer-bottom {
display: flex;
align-items: center;
justify-content: space-between;
padding-top: 22px;
font-size: .84rem;
color: rgba(255, 255, 255, 0.55);
flex-wrap: wrap;
gap: 10px;
}
/* Toast */
.toast {
position: fixed;
left: 50%;
bottom: 28px;
transform: translate(-50%, 140%);
background: var(--ink);
color: #fff;
padding: 14px 22px;
border-radius: 999px;
box-shadow: var(--sh-lg);
font-weight: 600;
font-size: .94rem;
display: flex;
align-items: center;
gap: 10px;
z-index: 90;
transition: transform .4s cubic-bezier(.2, 1, .3, 1);
max-width: calc(100% - 32px);
}
.toast.show { transform: translate(-50%, 0); }
.toast .toast-ico {
width: 24px;
height: 24px;
border-radius: 50%;
background: var(--mint);
color: #063a2a;
display: grid;
place-items: center;
font-weight: 800;
flex-shrink: 0;
}
/* Responsive */
@media (max-width: 900px) {
.hero-grid { grid-template-columns: 1fr; gap: 32px; }
.feature-strip { grid-template-columns: repeat(2, 1fr); }
.cards { grid-template-columns: repeat(2, 1fr); }
.kids-grid { grid-template-columns: 1fr; gap: 34px; }
.kids-media { min-height: 300px; order: 2; }
.book-grid { grid-template-columns: 1fr; gap: 30px; }
.logos { grid-template-columns: repeat(3, 1fr); }
.footer-inner { grid-template-columns: 1fr; }
}
@media (max-width: 640px) {
.nav { display: none; }
.cards { grid-template-columns: 1fr; }
}
@media (max-width: 520px) {
.wrap { width: min(1140px, 100% - 28px); }
.header-inner { height: 60px; gap: 10px; }
.phone span { display: none; }
.header-cta { gap: 8px; }
.hero { padding: 34px 0 10px; }
.hero h1 { font-size: 2rem; }
.lede { font-size: 1rem; }
.hero-actions { flex-direction: column; align-items: stretch; }
.hero-actions .btn { width: 100%; }
.feature-strip { grid-template-columns: 1fr; margin-top: 34px; }
.section { padding: 48px 0; }
.section-head { margin-bottom: 24px; }
.filters { width: 100%; overflow-x: auto; flex-wrap: nowrap; padding-bottom: 4px; -webkit-overflow-scrolling: touch; }
.logos { grid-template-columns: repeat(2, 1fr); }
.insurance-cta { flex-direction: column; gap: 14px; }
.field-row { grid-template-columns: 1fr; }
.days { grid-template-columns: repeat(5, 1fr); gap: 6px; }
.day .dnum { font-size: 1rem; }
.slots { grid-template-columns: repeat(3, 1fr); }
.book-form { padding: 20px; }
.footer-cols { grid-template-columns: 1fr; }
.kids-card { right: 2%; max-width: 190px; }
.toast { bottom: 16px; }
}
@media (prefers-reduced-motion: reduce) {
* { animation-duration: .001ms !important; animation-iteration-count: 1 !important; scroll-behavior: auto; }
.card, .feat { transition: none; }
}/* Brightwood Family Dental — landing interactions */
(function () {
"use strict";
/* ---------- Toast helper ---------- */
var toastEl = document.getElementById("toast");
var toastTimer;
function toast(msg) {
if (!toastEl) return;
toastEl.innerHTML = '<span class="toast-ico" aria-hidden="true">✓</span>' + msg;
toastEl.classList.add("show");
clearTimeout(toastTimer);
toastTimer = setTimeout(function () {
toastEl.classList.remove("show");
}, 3600);
}
/* ---------- Services data + render ---------- */
var services = [
{ icon: "🦷", title: "Checkups & Cleanings", desc: "Gentle exams, plaque removal, and a fresh polish to keep every smile bright.", price: "89", tags: ["adults", "seniors", "teens"], groups: ["adults", "teens", "seniors"] },
{ icon: "👶", title: "Kids' First Visit", desc: "A calm, playful introduction to the dentist with counting games and a prize.", price: "Free", tags: ["kids"], groups: ["kids"] },
{ icon: "✨", title: "Teeth Whitening", desc: "Professional brightening that lifts years of stains in a single relaxed visit.", price: "249", tags: ["adults", "teens"], groups: ["adults", "teens"] },
{ icon: "🛡️", title: "Sealants & Fluoride", desc: "Protective barriers that keep growing teeth cavity-free through the school years.", price: "45", tags: ["kids", "teens"], groups: ["kids", "teens"] },
{ icon: "🦷", title: "Braces & Aligners", desc: "Clear or classic — straighten smiles with check-ins that fit busy schedules.", price: "from 1,900", tags: ["teens", "adults"], groups: ["teens", "adults"] },
{ icon: "🩺", title: "Fillings & Crowns", desc: "Tooth-colored repairs and same-day crowns that blend right in, no drama.", price: "from 160", tags: ["adults", "seniors"], groups: ["adults", "seniors"] },
{ icon: "🦴", title: "Dentures & Implants", desc: "Comfortable, natural-looking solutions to restore confident chewing and smiles.", price: "from 990", tags: ["seniors"], groups: ["seniors"] },
{ icon: "😌", title: "Sedation Comfort", desc: "Nervous patient? Gentle sedation options make longer treatments feel like a nap.", price: "120", tags: ["adults", "seniors", "teens"], groups: ["adults", "teens", "seniors"] },
{ icon: "🩷", title: "Emergency Care", desc: "Chipped tooth or sudden ache? Same-day urgent slots for the whole family.", price: "95", tags: ["kids", "adults", "seniors"], groups: ["kids", "teens", "adults", "seniors"] }
];
var grid = document.getElementById("serviceGrid");
function priceMarkup(p) {
if (p === "Free") return '<span class="card-price" style="color:var(--ok)">Free</span>';
if (p.indexOf("from") === 0) return '<span class="card-price"><span>from </span>$' + p.replace("from ", "") + "</span>";
return '<span class="card-price">$' + p + " <span>/ visit</span></span>";
}
function renderServices(filter) {
if (!grid) return;
var list = filter === "all" ? services : services.filter(function (s) { return s.groups.indexOf(filter) !== -1; });
grid.innerHTML = list.map(function (s, i) {
var tags = s.tags.map(function (t) { return '<span class="tag">' + t + "</span>"; }).join("");
return (
'<article class="card" style="animation-delay:' + (i * 40) + 'ms">' +
'<div class="card-ico" aria-hidden="true">' + s.icon + "</div>" +
"<h3>" + s.title + "</h3>" +
"<p>" + s.desc + "</p>" +
'<div class="tags">' + tags + "</div>" +
'<div class="card-meta">' + priceMarkup(s.price) +
'<a class="card-link" href="#book">Book →</a>' +
"</div></article>"
);
}).join("");
}
renderServices("all");
/* ---------- Filter chips ---------- */
var chips = Array.prototype.slice.call(document.querySelectorAll(".chip"));
chips.forEach(function (chip) {
chip.addEventListener("click", function () {
chips.forEach(function (c) {
c.classList.remove("is-active");
c.setAttribute("aria-selected", "false");
});
chip.classList.add("is-active");
chip.setAttribute("aria-selected", "true");
renderServices(chip.getAttribute("data-filter"));
});
});
/* ---------- Animated smile counter ---------- */
var counter = document.getElementById("smileCount");
function animateCount(el) {
var target = parseInt(el.getAttribute("data-target"), 10) || 0;
var start = null;
var dur = 1600;
function step(ts) {
if (!start) start = ts;
var t = Math.min((ts - start) / dur, 1);
var eased = 1 - Math.pow(1 - t, 3);
el.textContent = Math.floor(eased * target).toLocaleString() + "+";
if (t < 1) requestAnimationFrame(step);
}
requestAnimationFrame(step);
}
if (counter) {
if ("IntersectionObserver" in window) {
var io = new IntersectionObserver(function (entries) {
entries.forEach(function (e) {
if (e.isIntersecting) { animateCount(counter); io.disconnect(); }
});
}, { threshold: 0.4 });
io.observe(counter);
} else {
animateCount(counter);
}
}
/* ---------- Day picker ---------- */
var daysEl = document.getElementById("days");
var dowNames = ["Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat"];
var selectedDay = null;
function buildDays() {
if (!daysEl) return;
var frag = "";
var count = 0;
var d = new Date();
d.setDate(d.getDate() + 1); // start tomorrow
while (count < 5) {
var dow = d.getDay();
if (dow !== 0) { // skip Sundays (clinic closed)
var label = dowNames[dow];
var num = d.getDate();
frag += '<button type="button" class="day" role="radio" aria-checked="false" ' +
'data-day="' + label + " " + num + '">' +
'<span class="dow">' + label + "</span>" +
'<span class="dnum">' + num + "</span></button>";
count++;
}
d.setDate(d.getDate() + 1);
}
daysEl.innerHTML = frag;
var dayBtns = daysEl.querySelectorAll(".day");
dayBtns[0].classList.add("sel");
dayBtns[0].setAttribute("aria-checked", "true");
selectedDay = dayBtns[0].getAttribute("data-day");
Array.prototype.forEach.call(dayBtns, function (btn) {
btn.addEventListener("click", function () {
Array.prototype.forEach.call(dayBtns, function (b) {
b.classList.remove("sel");
b.setAttribute("aria-checked", "false");
});
btn.classList.add("sel");
btn.setAttribute("aria-checked", "true");
selectedDay = btn.getAttribute("data-day");
});
});
}
buildDays();
/* ---------- Time slots ---------- */
var slotsEl = document.getElementById("slots");
var slotTimes = ["9:00", "10:30", "12:00", "1:30", "3:00", "4:30", "5:45", "6:30"];
var soldOut = ["12:00", "4:30"]; // pretend unavailable
var selectedSlot = null;
function buildSlots() {
if (!slotsEl) return;
slotsEl.innerHTML = slotTimes.map(function (t) {
var off = soldOut.indexOf(t) !== -1;
return '<button type="button" class="slot" role="radio" ' +
'aria-checked="false" aria-disabled="' + (off ? "true" : "false") + '" ' +
'data-slot="' + t + '">' + t + "</button>";
}).join("");
var slotBtns = slotsEl.querySelectorAll(".slot");
Array.prototype.forEach.call(slotBtns, function (btn) {
btn.addEventListener("click", function () {
if (btn.getAttribute("aria-disabled") === "true") {
toast("Sorry, that slot just filled — try another time.");
return;
}
Array.prototype.forEach.call(slotBtns, function (b) {
b.classList.remove("sel");
b.setAttribute("aria-checked", "false");
});
btn.classList.add("sel");
btn.setAttribute("aria-checked", "true");
selectedSlot = btn.getAttribute("data-slot");
});
});
}
buildSlots();
/* ---------- Form submit ---------- */
var form = document.getElementById("bookForm");
if (form) {
form.addEventListener("submit", function (e) {
e.preventDefault();
var nameInput = document.getElementById("fullName");
var name = nameInput.value.trim();
if (!name) {
nameInput.classList.add("invalid");
nameInput.focus();
toast("Please add your name so we can confirm.");
return;
}
nameInput.classList.remove("invalid");
if (!selectedSlot) {
toast("Pick a time slot to finish booking.");
return;
}
var first = name.split(" ")[0];
toast("Thanks, " + first + "! " + selectedDay + " at " + selectedSlot + " is reserved.");
form.reset();
// restore default selections
buildSlots();
selectedSlot = null;
});
document.getElementById("fullName").addEventListener("input", function () {
this.classList.remove("invalid");
});
}
})();<!doctype html>
<html lang="en">
<head>
<meta charset="utf-8" />
<meta name="viewport" content="width=device-width, initial-scale=1" />
<title>Brightwood Family Dental — Gentle care for every age</title>
<link rel="preconnect" href="https://fonts.googleapis.com" />
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin />
<link href="https://fonts.googleapis.com/css2?family=Inter:wght@400;500;600;700;800&display=swap" rel="stylesheet" />
<link rel="stylesheet" href="style.css" />
</head>
<body>
<a class="skip-link" href="#main">Skip to content</a>
<!-- Header -->
<header class="site-header">
<div class="wrap header-inner">
<a class="brand" href="#top" aria-label="Brightwood Family Dental home">
<span class="brand-mark" aria-hidden="true">
<svg viewBox="0 0 24 24" width="22" height="22" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round">
<path d="M12 5.5C10 3 6.5 3 5 5.5 3.2 8.5 4.5 14 6 18c.6 1.5 2 1.2 2.4-.2.4-1.5.7-3 1.6-3s1.2 1.5 1.6 3c.4 1.4 1.8 1.7 2.4.2 1.5-4 2.8-9.5 1-12.5C13.5 3 12 4 12 5.5Z"/>
</svg>
</span>
<span class="brand-name">Brightwood<span class="brand-sub">Family Dental</span></span>
</a>
<nav class="nav" aria-label="Primary">
<a href="#services">Services</a>
<a href="#kids">For Kids</a>
<a href="#insurance">Insurance</a>
<a href="#book">Book</a>
</nav>
<div class="header-cta">
<a class="phone" href="tel:+15550142200" aria-label="Call the clinic">
<svg viewBox="0 0 24 24" width="16" height="16" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"><path d="M22 16.9v3a2 2 0 0 1-2.2 2 19.8 19.8 0 0 1-8.6-3 19.5 19.5 0 0 1-6-6 19.8 19.8 0 0 1-3-8.6A2 2 0 0 1 4.1 2h3a2 2 0 0 1 2 1.7c.1.9.3 1.8.6 2.6a2 2 0 0 1-.5 2.1L8 9.6a16 16 0 0 0 6 6l1.2-1.2a2 2 0 0 1 2.1-.5c.8.3 1.7.5 2.6.6a2 2 0 0 1 1.7 2Z"/></svg>
<span>(555) 014-2200</span>
</a>
<a class="btn btn-primary" href="#book">Book a visit</a>
</div>
</div>
</header>
<main id="main">
<!-- Hero -->
<section class="hero" id="top">
<div class="wrap hero-grid">
<div class="hero-copy">
<span class="pill">
<span class="dot" aria-hidden="true"></span>
Now welcoming new families
</span>
<h1>Gentle dental care for <span class="hl">every age</span> under one roof.</h1>
<p class="lede">
From first baby teeth to lifelong smiles, our family-friendly team makes every
visit calm, quick, and reassuring. Same-week appointments and evenings available.
</p>
<div class="hero-actions">
<a class="btn btn-primary btn-lg" href="#book">Book an appointment</a>
<a class="btn btn-ghost btn-lg" href="#services">See our services</a>
</div>
<div class="hero-trust">
<div class="rating" aria-label="Rated 4.9 out of 5 from 1,280 reviews">
<span class="stars" aria-hidden="true">★★★★★</span>
<strong>4.9</strong>
<span class="muted">/ 5 · 1,280 reviews</span>
</div>
<div class="avatars" aria-hidden="true">
<span style="--g:linear-gradient(135deg,#60a5fa,#2563eb)">JR</span>
<span style="--g:linear-gradient(135deg,#34d399,#22b07d)">ML</span>
<span style="--g:linear-gradient(135deg,#a78bfa,#7c3aed)">DP</span>
<span style="--g:linear-gradient(135deg,#fbbf24,#d98a2b)">SK</span>
<span class="more">+9k</span>
</div>
</div>
</div>
<!-- Booking card -->
<aside class="hero-card" aria-label="Quick appointment request">
<div class="hero-card-top">
<h2>Request a visit</h2>
<span class="badge badge-ok">Same-week slots</span>
</div>
<p class="hero-card-sub">Pick a day and time — we'll confirm within the hour.</p>
<div class="mini-stat">
<div>
<span class="mini-num" id="smileCount" data-target="18400">0</span>
<span class="mini-label">smiles cared for</span>
</div>
<div class="mini-div" aria-hidden="true"></div>
<div>
<span class="mini-num">14</span>
<span class="mini-label">years serving families</span>
</div>
</div>
<a class="btn btn-primary btn-block" href="#book">Choose a time</a>
<p class="hero-card-foot">
<svg viewBox="0 0 24 24" width="14" height="14" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"><path d="M20 6 9 17l-5-5"/></svg>
No wait-list · Free first consultation
</p>
</aside>
</div>
<!-- Feature strip -->
<div class="wrap feature-strip">
<div class="feat">
<span class="feat-ico" aria-hidden="true">🦷</span>
<div><strong>All ages welcome</strong><span>Toddlers to grandparents</span></div>
</div>
<div class="feat">
<span class="feat-ico" aria-hidden="true">🕐</span>
<div><strong>Evenings & Saturdays</strong><span>Around your schedule</span></div>
</div>
<div class="feat">
<span class="feat-ico" aria-hidden="true">💳</span>
<div><strong>Most insurance</strong><span>Direct billing accepted</span></div>
</div>
<div class="feat">
<span class="feat-ico" aria-hidden="true">🚸</span>
<div><strong>Kid-friendly</strong><span>Play corner & prizes</span></div>
</div>
</div>
</section>
<!-- Services -->
<section class="section" id="services">
<div class="wrap">
<div class="section-head">
<div>
<span class="eyebrow">Our services</span>
<h2>Complete care for the whole family</h2>
</div>
<div class="filters" role="tablist" aria-label="Filter services by age group">
<button class="chip is-active" role="tab" aria-selected="true" data-filter="all">All ages</button>
<button class="chip" role="tab" aria-selected="false" data-filter="kids">Kids</button>
<button class="chip" role="tab" aria-selected="false" data-filter="teens">Teens</button>
<button class="chip" role="tab" aria-selected="false" data-filter="adults">Adults</button>
<button class="chip" role="tab" aria-selected="false" data-filter="seniors">Seniors</button>
</div>
</div>
<div class="cards" id="serviceGrid" aria-live="polite"><!-- injected by JS --></div>
</div>
</section>
<!-- Kids-friendly -->
<section class="section kids-section" id="kids">
<div class="wrap kids-grid">
<div class="kids-media" aria-hidden="true">
<div class="kids-blob"></div>
<div class="kids-emoji e1">😄</div>
<div class="kids-emoji e2">⭐</div>
<div class="kids-emoji e3">🎈</div>
<div class="kids-card">
<span class="kids-card-badge">First visit</span>
<strong>Little Explorers Program</strong>
<span>Ages 1–8 · gentle, playful, no rush</span>
</div>
</div>
<div class="kids-copy">
<span class="eyebrow eyebrow-mint">Kids feel at home</span>
<h2>A first dental visit they'll actually look forward to</h2>
<p>
We keep little ones smiling with a play corner, "count the teeth" games, a treasure
chest of prizes, and a gentle team who explains everything in kid words. Parents stay
right beside the chair the whole time.
</p>
<ul class="kids-list">
<li><span class="tick" aria-hidden="true">✓</span> Cavity-free club with rewards</li>
<li><span class="tick" aria-hidden="true">✓</span> Tell-show-do approach, zero pressure</li>
<li><span class="tick" aria-hidden="true">✓</span> Fluoride & sealants to prevent decay</li>
<li><span class="tick" aria-hidden="true">✓</span> Sibling appointments booked together</li>
</ul>
<a class="btn btn-primary" href="#book">Book your child's visit</a>
</div>
</div>
</section>
<!-- Insurance -->
<section class="section insurance" id="insurance">
<div class="wrap">
<div class="section-head center">
<div>
<span class="eyebrow">Insurance & payment</span>
<h2>We accept most major plans</h2>
<p class="section-sub">Direct billing on the spot, flexible monthly plans, and transparent pricing before any treatment starts.</p>
</div>
</div>
<ul class="logos" aria-label="Accepted insurance providers">
<li>Delta Dental</li>
<li>Cigna</li>
<li>Aetna</li>
<li>MetLife</li>
<li>Guardian</li>
<li>Humana</li>
<li>United Health</li>
<li>Blue Shield</li>
</ul>
<div class="insurance-cta">
<p>Not sure if you're covered? Send us your plan and we'll check for free.</p>
<a class="btn btn-ghost" href="#book">Verify my coverage</a>
</div>
</div>
</section>
<!-- Booking -->
<section class="section book-section" id="book">
<div class="wrap book-grid">
<div class="book-info">
<span class="eyebrow eyebrow-light">Book in 30 seconds</span>
<h2>Reserve your family's appointment</h2>
<p>Choose a day and a time that works — no phone tag required. We'll send a confirmation and a friendly reminder.</p>
<ul class="book-perks">
<li><span class="tick" aria-hidden="true">✓</span> Free first consultation</li>
<li><span class="tick" aria-hidden="true">✓</span> Same-week availability</li>
<li><span class="tick" aria-hidden="true">✓</span> Cancel or reschedule anytime</li>
</ul>
<div class="book-contact">
<a href="tel:+15550142200">
<svg viewBox="0 0 24 24" width="16" height="16" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"><path d="M22 16.9v3a2 2 0 0 1-2.2 2 19.8 19.8 0 0 1-8.6-3 19.5 19.5 0 0 1-6-6 19.8 19.8 0 0 1-3-8.6A2 2 0 0 1 4.1 2h3a2 2 0 0 1 2 1.7c.1.9.3 1.8.6 2.6a2 2 0 0 1-.5 2.1L8 9.6a16 16 0 0 0 6 6l1.2-1.2a2 2 0 0 1 2.1-.5c.8.3 1.7.5 2.6.6a2 2 0 0 1 1.7 2Z"/></svg>
(555) 014-2200
</a>
<span>·</span>
<span>128 Maple Grove Ave, Brightwood</span>
</div>
</div>
<form class="book-form" id="bookForm" novalidate>
<div class="field">
<label for="fullName">Full name</label>
<input id="fullName" name="fullName" type="text" autocomplete="name" placeholder="e.g. Jordan Rivera" required />
</div>
<div class="field-row">
<div class="field">
<label for="patients">Who's visiting?</label>
<select id="patients" name="patients">
<option value="adult">Just me</option>
<option value="child">My child</option>
<option value="family" selected>Whole family</option>
<option value="senior">A senior parent</option>
</select>
</div>
<div class="field">
<label for="reason">Visit type</label>
<select id="reason" name="reason">
<option>Checkup & cleaning</option>
<option>New patient exam</option>
<option>Kids' first visit</option>
<option>Whitening</option>
<option>Tooth pain / urgent</option>
</select>
</div>
</div>
<div class="field">
<span class="field-label">Pick a day</span>
<div class="days" id="days" role="radiogroup" aria-label="Choose an appointment day"><!-- JS --></div>
</div>
<div class="field">
<span class="field-label">Pick a time</span>
<div class="slots" id="slots" role="radiogroup" aria-label="Choose an appointment time"><!-- JS --></div>
</div>
<button class="btn btn-primary btn-block btn-lg" type="submit">Confirm appointment</button>
<p class="form-note">
<svg viewBox="0 0 24 24" width="14" height="14" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"><rect x="3" y="11" width="18" height="11" rx="2"/><path d="M7 11V7a5 5 0 0 1 10 0v4"/></svg>
Your details are private and never shared.
</p>
</form>
</div>
</section>
</main>
<footer class="site-footer">
<div class="wrap footer-inner">
<div class="footer-brand">
<span class="brand-name">Brightwood<span class="brand-sub">Family Dental</span></span>
<p>Gentle, modern dentistry for every generation of your family.</p>
</div>
<div class="footer-cols">
<div>
<h3>Visit</h3>
<a href="#services">Services</a>
<a href="#kids">For kids</a>
<a href="#insurance">Insurance</a>
</div>
<div>
<h3>Hours</h3>
<span>Mon–Fri · 8am–7pm</span>
<span>Saturday · 9am–3pm</span>
<span>Sunday · Closed</span>
</div>
<div>
<h3>Contact</h3>
<a href="tel:+15550142200">(555) 014-2200</a>
<a href="mailto:[email protected]">[email protected]</a>
<span>128 Maple Grove Ave</span>
</div>
</div>
</div>
<div class="wrap footer-bottom">
<span>© 2026 Brightwood Family Dental · Illustrative demo</span>
<span>Made with care 🦷</span>
</div>
</footer>
<div class="toast" id="toast" role="status" aria-live="polite"></div>
<script src="script.js"></script>
</body>
</html>Dental — Landing Family
A single-screen family dentistry landing built around trust and warmth. The hero pairs a reassuring headline and rating badge with a compact “book a visit” card, while an animated counter ticks up to the number of smiles cared for. A filterable services grid covers every age — kids, teens, adults, and seniors — and a soft kids-friendly panel reassures parents about the first visit.
The page is genuinely interactive: service filter chips re-render the grid with a smooth fade, the booking widget lets you pick a day and a time slot with clear selected states, and submitting the form pops a friendly toast confirmation. An accepted-insurance strip and an FAQ-style reassurance row round out the experience. Everything is keyboard operable with visible focus rings, uses accessible contrast, and collapses gracefully to a single column on phones down to ~360px.
Styling follows a clean clinical light theme — calm blues, a mint accent, deep ink text, and lots of white with soft shadows and rounded corners for a reassuring, approachable feel.
Illustrative UI only — not intended for real medical use.