Dental — Faq Accordion
A trust-first dental FAQ accordion with category chips, a live search filter, and buttery smooth expand-collapse panels. Patients type a keyword to instantly narrow questions about visits, insurance, treatments, and emergencies, then tap a card to reveal a clear answer. Rounded clinical styling, soft shadows, badges, keyboard-friendly controls, an expand-all toggle, and a live result counter make it feel reassuring and effortless to browse.
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;
--shadow-sm: 0 1px 2px rgba(15, 39, 64, 0.06), 0 2px 8px rgba(15, 39, 64, 0.05);
--shadow-md: 0 8px 28px rgba(15, 39, 64, 0.08), 0 2px 6px rgba(15, 39, 64, 0.05);
}
* { box-sizing: border-box; }
html { -webkit-text-size-adjust: 100%; }
body {
margin: 0;
font-family: "Inter", system-ui, -apple-system, sans-serif;
line-height: 1.5;
color: var(--ink);
background:
radial-gradient(1100px 500px at 15% -10%, #e2eeff 0%, rgba(226, 238, 255, 0) 60%),
radial-gradient(900px 480px at 110% 0%, var(--mint-50) 0%, rgba(232, 251, 243, 0) 55%),
var(--bg);
-webkit-font-smoothing: antialiased;
-moz-osx-font-smoothing: grayscale;
min-height: 100vh;
}
.page {
max-width: 760px;
margin: 0 auto;
padding: 48px 20px 80px;
}
/* Header */
.faq__head { text-align: center; }
.pill {
display: inline-flex;
align-items: center;
gap: 7px;
padding: 6px 14px 6px 11px;
background: var(--white);
border: 1px solid var(--line);
border-radius: 999px;
font-size: 13px;
font-weight: 600;
color: var(--blue-d);
box-shadow: var(--shadow-sm);
}
.pill svg { color: var(--blue); }
.faq__title {
margin: 18px 0 8px;
font-size: clamp(26px, 5vw, 38px);
font-weight: 800;
letter-spacing: -0.02em;
color: var(--ink);
}
.faq__sub {
margin: 0 auto;
max-width: 460px;
color: var(--ink-2);
font-size: 15.5px;
}
/* Search */
.search {
position: relative;
margin: 26px auto 0;
max-width: 520px;
}
.search__icon {
position: absolute;
left: 16px;
top: 50%;
transform: translateY(-50%);
color: var(--muted);
pointer-events: none;
}
.search__input {
width: 100%;
padding: 15px 44px 15px 46px;
font: inherit;
font-size: 15.5px;
color: var(--ink);
background: var(--white);
border: 1.5px solid var(--line-2);
border-radius: var(--r-lg);
box-shadow: var(--shadow-sm);
transition: border-color .18s ease, box-shadow .18s ease;
}
.search__input::placeholder { color: var(--muted); }
.search__input:focus {
outline: none;
border-color: var(--blue);
box-shadow: 0 0 0 4px rgba(37, 99, 235, 0.14);
}
.search__clear {
position: absolute;
right: 12px;
top: 50%;
transform: translateY(-50%);
width: 26px;
height: 26px;
display: grid;
place-items: center;
border: none;
border-radius: 999px;
background: var(--blue-50);
color: var(--blue-d);
font-size: 19px;
line-height: 1;
cursor: pointer;
transition: background .15s ease;
}
.search__clear:hover { background: #dce9ff; }
/* Chips */
.chips {
display: flex;
flex-wrap: wrap;
justify-content: center;
gap: 8px;
margin-top: 18px;
}
.chip {
padding: 8px 16px;
font: inherit;
font-size: 13.5px;
font-weight: 600;
color: var(--ink-2);
background: var(--white);
border: 1px solid var(--line);
border-radius: 999px;
cursor: pointer;
box-shadow: var(--shadow-sm);
transition: transform .12s ease, background .15s ease, color .15s ease, border-color .15s ease;
}
.chip:hover { transform: translateY(-1px); border-color: var(--line-2); }
.chip:focus-visible {
outline: none;
box-shadow: 0 0 0 3px rgba(37, 99, 235, 0.28);
}
.chip.is-active {
background: var(--blue);
border-color: var(--blue);
color: var(--white);
box-shadow: 0 4px 14px rgba(37, 99, 235, 0.28);
}
/* Toolbar */
.toolbar {
display: flex;
align-items: center;
justify-content: space-between;
gap: 12px;
margin: 24px 4px 12px;
}
.count {
margin: 0;
font-size: 13px;
font-weight: 500;
color: var(--muted);
}
.count strong { color: var(--ink); font-weight: 700; }
.linkbtn {
border: none;
background: none;
padding: 4px 6px;
font: inherit;
font-size: 13.5px;
font-weight: 600;
color: var(--blue-d);
cursor: pointer;
border-radius: var(--r-sm);
}
.linkbtn:hover { text-decoration: underline; }
.linkbtn:focus-visible {
outline: none;
box-shadow: 0 0 0 3px rgba(37, 99, 235, 0.28);
}
/* List */
.list {
list-style: none;
margin: 0;
padding: 0;
display: grid;
gap: 10px;
}
.item {
background: var(--white);
border: 1px solid var(--line);
border-radius: var(--r-md);
box-shadow: var(--shadow-sm);
overflow: hidden;
transition: box-shadow .2s ease, border-color .2s ease;
}
.item.is-open {
border-color: rgba(37, 99, 235, 0.35);
box-shadow: var(--shadow-md);
}
.item.is-hidden { display: none; }
.item__h { margin: 0; }
.acc {
width: 100%;
display: flex;
align-items: center;
gap: 14px;
padding: 17px 18px;
border: none;
background: none;
text-align: left;
cursor: pointer;
font: inherit;
color: var(--ink);
transition: background .15s ease;
}
.acc:hover { background: var(--blue-50); }
.acc:focus-visible {
outline: none;
box-shadow: inset 0 0 0 2px var(--blue);
}
.acc__q {
flex: 1;
display: flex;
flex-wrap: wrap;
align-items: center;
gap: 8px 10px;
}
.qtext { font-size: 15.5px; font-weight: 600; letter-spacing: -0.01em; }
.qtext mark {
background: #fde68a;
color: inherit;
border-radius: 3px;
padding: 0 2px;
}
.tag {
flex: none;
padding: 3px 9px;
font-size: 11px;
font-weight: 700;
letter-spacing: .02em;
text-transform: uppercase;
border-radius: 999px;
}
.tag--visits { background: var(--blue-50); color: var(--blue-d); }
.tag--insurance { background: var(--mint-50); color: var(--ok); }
.tag--treatments { background: #f3ecff; color: #7c5cd6; }
.tag--emergencies { background: #fdeceb; color: var(--danger); }
.acc__ico {
flex: none;
width: 26px;
height: 26px;
position: relative;
border-radius: 999px;
background: var(--blue-50);
transition: background .2s ease, transform .3s cubic-bezier(.2, .8, .3, 1);
}
.acc__ico::before,
.acc__ico::after {
content: "";
position: absolute;
top: 50%;
left: 50%;
width: 11px;
height: 2px;
border-radius: 2px;
background: var(--blue-d);
transform: translate(-50%, -50%);
transition: transform .28s cubic-bezier(.2, .8, .3, 1), opacity .2s ease;
}
.acc__ico::after { transform: translate(-50%, -50%) rotate(90deg); }
.item.is-open .acc__ico {
background: var(--blue);
transform: rotate(180deg);
}
.item.is-open .acc__ico::before,
.item.is-open .acc__ico::after { background: var(--white); }
.item.is-open .acc__ico::after {
transform: translate(-50%, -50%) rotate(0deg);
opacity: 0;
}
/* Panel */
.panel {
height: 0;
overflow: hidden;
transition: height .3s cubic-bezier(.2, .8, .3, 1);
}
.panel__in {
padding: 0 18px 18px 18px;
color: var(--ink-2);
font-size: 14.5px;
}
.panel__in p { margin: 0; }
.panel__in strong { color: var(--ink); }
/* Empty state */
.empty {
margin-top: 8px;
text-align: center;
padding: 46px 20px;
background: var(--white);
border: 1px dashed var(--line-2);
border-radius: var(--r-md);
}
.empty__ico {
width: 48px;
height: 48px;
margin: 0 auto 12px;
display: grid;
place-items: center;
border-radius: 999px;
background: var(--blue-50);
color: var(--blue);
font-size: 24px;
font-weight: 800;
}
.empty__t { margin: 0 0 4px; font-weight: 700; font-size: 16px; color: var(--ink); }
.empty__s { margin: 0; color: var(--muted); font-size: 14px; }
/* Toast */
.toast {
position: fixed;
left: 50%;
bottom: 24px;
transform: translate(-50%, 20px);
background: var(--ink);
color: var(--white);
padding: 11px 18px;
border-radius: 999px;
font-size: 13.5px;
font-weight: 600;
box-shadow: var(--shadow-md);
opacity: 0;
pointer-events: none;
transition: opacity .22s ease, transform .22s ease;
z-index: 50;
}
.toast.is-show {
opacity: 1;
transform: translate(-50%, 0);
}
@media (max-width: 520px) {
.page { padding: 34px 14px 64px; }
.faq__title { font-size: 25px; }
.acc { padding: 15px 14px; gap: 10px; }
.qtext { font-size: 14.5px; }
.panel__in { padding: 0 14px 16px; }
.toolbar { margin: 20px 2px 10px; }
.chip { padding: 7px 13px; }
}
@media (prefers-reduced-motion: reduce) {
* { transition: none !important; }
}(function () {
"use strict";
var list = document.getElementById("list");
var items = Array.prototype.slice.call(list.querySelectorAll(".item"));
var input = document.getElementById("q");
var clearBtn = document.getElementById("clear");
var chips = Array.prototype.slice.call(document.querySelectorAll(".chip"));
var countEl = document.getElementById("count");
var toggleAllBtn = document.getElementById("toggleAll");
var emptyEl = document.getElementById("empty");
var resetBtn = document.getElementById("reset");
var toastEl = document.getElementById("toast");
var activeCat = "all";
var toastTimer = null;
/* ---- toast helper ---- */
function toast(msg) {
toastEl.textContent = msg;
toastEl.classList.add("is-show");
clearTimeout(toastTimer);
toastTimer = setTimeout(function () {
toastEl.classList.remove("is-show");
}, 1900);
}
/* ---- accordion open/close (height measured for smooth motion) ---- */
function setOpen(item, open) {
var btn = item.querySelector(".acc");
var panel = item.querySelector(".panel");
var inner = item.querySelector(".panel__in");
if (open) {
item.classList.add("is-open");
btn.setAttribute("aria-expanded", "true");
panel.style.height = inner.offsetHeight + "px";
// release to auto after the transition so reflow/resize stays fluid
var onEnd = function (e) {
if (e.propertyName !== "height") return;
if (item.classList.contains("is-open")) panel.style.height = "auto";
panel.removeEventListener("transitionend", onEnd);
};
panel.addEventListener("transitionend", onEnd);
} else {
item.classList.remove("is-open");
btn.setAttribute("aria-expanded", "false");
// from auto -> fixed -> 0 so the collapse animates
panel.style.height = panel.scrollHeight + "px";
// force reflow
void panel.offsetHeight;
panel.style.height = "0px";
}
}
function isOpen(item) {
return item.classList.contains("is-open");
}
items.forEach(function (item) {
var btn = item.querySelector(".acc");
btn.addEventListener("click", function () {
setOpen(item, !isOpen(item));
syncToggleAll();
});
});
/* ---- expand / collapse all (visible items only) ---- */
function visibleItems() {
return items.filter(function (it) {
return !it.classList.contains("is-hidden");
});
}
function syncToggleAll() {
var vis = visibleItems();
var openCount = vis.filter(isOpen).length;
var allOpen = vis.length > 0 && openCount === vis.length;
toggleAllBtn.textContent = allOpen ? "Collapse all" : "Expand all";
toggleAllBtn.setAttribute("aria-expanded", allOpen ? "true" : "false");
}
toggleAllBtn.addEventListener("click", function () {
var vis = visibleItems();
var shouldOpen = vis.some(function (it) { return !isOpen(it); });
vis.forEach(function (it) { setOpen(it, shouldOpen); });
syncToggleAll();
toast(shouldOpen ? "Expanded all answers" : "Collapsed all answers");
});
/* ---- highlight matched query text ---- */
function escapeRe(s) {
return s.replace(/[.*+?^${}()|[\]\\]/g, "\\$&");
}
function highlight(item, query) {
var span = item.querySelector(".qtext");
if (!span.dataset.raw) span.dataset.raw = span.textContent;
var raw = span.dataset.raw;
if (!query) {
span.textContent = raw;
return;
}
var re = new RegExp("(" + escapeRe(query) + ")", "ig");
span.innerHTML = raw.replace(re, "<mark>$1</mark>");
}
/* ---- filtering ---- */
function textOf(item) {
return (
item.querySelector(".qtext").textContent + " " +
item.querySelector(".panel__in").textContent
).toLowerCase();
}
function applyFilter() {
var query = input.value.trim().toLowerCase();
clearBtn.hidden = query.length === 0;
var shown = 0;
items.forEach(function (item) {
var catOk = activeCat === "all" || item.dataset.cat === activeCat;
var textOk = query === "" || textOf(item).indexOf(query) !== -1;
var visible = catOk && textOk;
item.classList.toggle("is-hidden", !visible);
if (visible) {
shown++;
highlight(item, query);
} else if (isOpen(item)) {
setOpen(item, false); // tidy up hidden-but-open panels
}
});
emptyEl.hidden = shown !== 0;
list.hidden = shown === 0;
updateCount(shown, query);
syncToggleAll();
}
function updateCount(shown, query) {
var total = items.length;
if (query === "" && activeCat === "all") {
countEl.innerHTML = "Showing all <strong>" + total + "</strong> questions";
return;
}
var noun = shown === 1 ? "question" : "questions";
countEl.innerHTML = "Showing <strong>" + shown + "</strong> of " + total + " " + noun;
}
/* ---- events ---- */
var debounce = null;
input.addEventListener("input", function () {
clearTimeout(debounce);
debounce = setTimeout(applyFilter, 90);
});
input.addEventListener("keydown", function (e) {
if (e.key === "Escape" && input.value) {
e.preventDefault();
input.value = "";
applyFilter();
}
});
clearBtn.addEventListener("click", function () {
input.value = "";
applyFilter();
input.focus();
});
chips.forEach(function (chip) {
chip.addEventListener("click", function () {
if (chip.dataset.cat === activeCat) return;
chips.forEach(function (c) {
var on = c === chip;
c.classList.toggle("is-active", on);
c.setAttribute("aria-selected", on ? "true" : "false");
});
activeCat = chip.dataset.cat;
applyFilter();
});
});
resetBtn.addEventListener("click", function () {
input.value = "";
activeCat = "all";
chips.forEach(function (c) {
var on = c.dataset.cat === "all";
c.classList.toggle("is-active", on);
c.setAttribute("aria-selected", on ? "true" : "false");
});
applyFilter();
toast("Filters reset");
});
/* ---- init ---- */
applyFilter();
})();<!doctype html>
<html lang="en">
<head>
<meta charset="utf-8" />
<meta name="viewport" content="width=device-width, initial-scale=1" />
<title>Brightsmile Dental — Frequently Asked Questions</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="page">
<section class="faq" aria-labelledby="faq-title">
<header class="faq__head">
<span class="pill">
<svg viewBox="0 0 24 24" aria-hidden="true" width="15" height="15"><path fill="currentColor" d="M12 2c-2 0-3.2.9-4.4 1.7C6.6 4.3 5.9 4.7 5 4.7c-1.7 0-3 1.4-3 3.4 0 2.2.7 4.5 1.6 7 .6 1.6 1 3.4 1.3 4.5.3 1.1 1 1.7 1.8 1.7.9 0 1.4-.7 1.7-1.9.3-1.1.6-2.4 1.6-2.4s1.3 1.3 1.6 2.4c.3 1.2.8 1.9 1.7 1.9.8 0 1.5-.6 1.8-1.7.3-1.1.7-2.9 1.3-4.5.9-2.5 1.6-4.8 1.6-7 0-2-1.3-3.4-3-3.4-.9 0-1.6-.4-2.6-1C15.2 2.9 14 2 12 2Z"/></svg>
Brightsmile Dental
</span>
<h1 id="faq-title" class="faq__title">How can we help you smile?</h1>
<p class="faq__sub">Answers to the questions our patients ask most — about visits, insurance, treatments and after-hours care.</p>
<div class="search" role="search">
<svg class="search__icon" viewBox="0 0 24 24" aria-hidden="true" width="18" height="18"><path fill="currentColor" d="M10 2a8 8 0 1 0 4.9 14.3l4.4 4.4 1.4-1.4-4.4-4.4A8 8 0 0 0 10 2Zm0 2a6 6 0 1 1 0 12 6 6 0 0 1 0-12Z"/></svg>
<input id="q" type="search" class="search__input" placeholder="Search questions… e.g. whitening, insurance, pain" autocomplete="off" aria-label="Search frequently asked questions" />
<button id="clear" class="search__clear" type="button" aria-label="Clear search" hidden>×</button>
</div>
<div class="chips" role="tablist" aria-label="Filter by category">
<button class="chip is-active" role="tab" aria-selected="true" data-cat="all" type="button">All</button>
<button class="chip" role="tab" aria-selected="false" data-cat="visits" type="button">Visits</button>
<button class="chip" role="tab" aria-selected="false" data-cat="insurance" type="button">Insurance</button>
<button class="chip" role="tab" aria-selected="false" data-cat="treatments" type="button">Treatments</button>
<button class="chip" role="tab" aria-selected="false" data-cat="emergencies" type="button">Emergencies</button>
</div>
<div class="toolbar">
<p class="count" id="count" aria-live="polite">Showing all questions</p>
<button id="toggleAll" class="linkbtn" type="button" aria-expanded="false">Expand all</button>
</div>
</header>
<ul class="list" id="list">
<!-- Visits -->
<li class="item" data-cat="visits">
<h2 class="item__h">
<button class="acc" type="button" aria-expanded="false">
<span class="acc__q"><span class="tag tag--visits">Visits</span><span class="qtext">How often should I schedule a check-up and cleaning?</span></span>
<span class="acc__ico" aria-hidden="true"></span>
</button>
</h2>
<div class="panel"><div class="panel__in">
<p>For most patients we recommend a professional cleaning and exam every <strong>six months</strong>. If you are managing gum disease, wear braces, or have a higher risk of cavities, Dr. Amara Vance may suggest visits every three to four months to stay ahead of any changes.</p>
</div></div>
</li>
<li class="item" data-cat="visits">
<h2 class="item__h">
<button class="acc" type="button" aria-expanded="false">
<span class="acc__q"><span class="tag tag--visits">Visits</span><span class="qtext">What should I bring to my first appointment?</span></span>
<span class="acc__ico" aria-hidden="true"></span>
</button>
</h2>
<div class="panel"><div class="panel__in">
<p>Please bring a photo ID, your insurance card, a list of any medications you take, and recent dental X-rays if you have them. Arriving ten minutes early gives you time to complete your new-patient forms comfortably.</p>
</div></div>
</li>
<li class="item" data-cat="visits">
<h2 class="item__h">
<button class="acc" type="button" aria-expanded="false">
<span class="acc__q"><span class="tag tag--visits">Visits</span><span class="qtext">Do you see children and families?</span></span>
<span class="acc__ico" aria-hidden="true"></span>
</button>
</h2>
<div class="panel"><div class="panel__in">
<p>Yes. We welcome patients of every age, and we love making a child’s first visit a friendly one. Family appointments can often be booked back-to-back so everyone is seen in a single trip.</p>
</div></div>
</li>
<!-- Insurance -->
<li class="item" data-cat="insurance">
<h2 class="item__h">
<button class="acc" type="button" aria-expanded="false">
<span class="acc__q"><span class="tag tag--insurance">Insurance</span><span class="qtext">Which dental insurance plans do you accept?</span></span>
<span class="acc__ico" aria-hidden="true"></span>
</button>
</h2>
<div class="panel"><div class="panel__in">
<p>We work with most major PPO plans and are happy to file claims on your behalf. Because coverage varies, call our front desk with your member details and we will verify your benefits before treatment so there are no surprises.</p>
</div></div>
</li>
<li class="item" data-cat="insurance">
<h2 class="item__h">
<button class="acc" type="button" aria-expanded="false">
<span class="acc__q"><span class="tag tag--insurance">Insurance</span><span class="qtext">Do you offer payment plans if I am uninsured?</span></span>
<span class="acc__ico" aria-hidden="true"></span>
</button>
</h2>
<div class="panel"><div class="panel__in">
<p>Absolutely. We offer an in-house membership plan with flat annual pricing, plus interest-free financing through trusted third-party partners for larger treatments. Ask about options that fit your budget when you book.</p>
</div></div>
</li>
<!-- Treatments -->
<li class="item" data-cat="treatments">
<h2 class="item__h">
<button class="acc" type="button" aria-expanded="false">
<span class="acc__q"><span class="tag tag--treatments">Treatments</span><span class="qtext">Is professional teeth whitening safe?</span></span>
<span class="acc__ico" aria-hidden="true"></span>
</button>
</h2>
<div class="panel"><div class="panel__in">
<p>When performed by a trained clinician, whitening is safe for most healthy teeth and gums. We protect your soft tissues, use controlled gel concentrations, and can dial back sensitivity with a gentler formula. Results typically last from several months up to a year.</p>
</div></div>
</li>
<li class="item" data-cat="treatments">
<h2 class="item__h">
<button class="acc" type="button" aria-expanded="false">
<span class="acc__q"><span class="tag tag--treatments">Treatments</span><span class="qtext">How long does a dental implant take?</span></span>
<span class="acc__ico" aria-hidden="true"></span>
</button>
</h2>
<div class="panel"><div class="panel__in">
<p>An implant is placed in a short procedure, then the bone heals around the post over roughly three to four months before the final crown is attached. Every timeline is personalised after imaging, so we will map yours out clearly at your consultation.</p>
</div></div>
</li>
<li class="item" data-cat="treatments">
<h2 class="item__h">
<button class="acc" type="button" aria-expanded="false">
<span class="acc__q"><span class="tag tag--treatments">Treatments</span><span class="qtext">Do fillings hurt, and what are they made of?</span></span>
<span class="acc__ico" aria-hidden="true"></span>
</button>
</h2>
<div class="panel"><div class="panel__in">
<p>We use a gentle local anaesthetic so the procedure itself is comfortable. Our tooth-coloured composite fillings bond directly to the tooth, look natural, and are mercury-free. Mild sensitivity for a day or two afterward is normal and fades quickly.</p>
</div></div>
</li>
<!-- Emergencies -->
<li class="item" data-cat="emergencies">
<h2 class="item__h">
<button class="acc" type="button" aria-expanded="false">
<span class="acc__q"><span class="tag tag--emergencies">Emergencies</span><span class="qtext">What should I do if I knock out a tooth?</span></span>
<span class="acc__ico" aria-hidden="true"></span>
</button>
</h2>
<div class="panel"><div class="panel__in">
<p>Handle the tooth by the crown, not the root, and gently rinse it. If you can, place it back in the socket or keep it in a cup of milk, then call our emergency line right away. Acting within the first hour gives the best chance of saving it.</p>
</div></div>
</li>
<li class="item" data-cat="emergencies">
<h2 class="item__h">
<button class="acc" type="button" aria-expanded="false">
<span class="acc__q"><span class="tag tag--emergencies">Emergencies</span><span class="qtext">I have severe tooth pain after hours — can I be seen?</span></span>
<span class="acc__ico" aria-hidden="true"></span>
</button>
</h2>
<div class="panel"><div class="panel__in">
<p>Yes. Our on-call clinician responds to urgent pain, swelling, and trauma outside regular hours. Call the main number and follow the emergency prompt; we will triage your situation and arrange same-day care whenever it is needed.</p>
</div></div>
</li>
</ul>
<div class="empty" id="empty" hidden>
<div class="empty__ico" aria-hidden="true">?</div>
<p class="empty__t">No questions match your search</p>
<p class="empty__s">Try a different keyword, or <button class="linkbtn" id="reset" type="button">reset filters</button>.</p>
</div>
</section>
</main>
<div class="toast" id="toast" role="status" aria-live="polite"></div>
<script src="script.js"></script>
</body>
</html>A calm, patient-facing FAQ panel for a dental clinic. A prominent search box filters questions in real time as you type, and a row of category chips (Visits, Insurance, Treatments, Emergencies) lets you scope the list with a single tap. A live counter tells you how many answers match, and an empty-state message appears gracefully when nothing does.
Each question is a full-width accordion header with an animated chevron and a smoothly measured height transition, so answers slide open without jank. Only relevant panels stay in view while filtering, matched text is highlighted, and an Expand all / Collapse all toggle handles the whole list at once. Every control is a real button — Tab through them, activate with Enter or Space, and follow the visible focus ring.
The design leans into the dental palette: clinical blues, mint accents, generous white space, and rounded cards with soft shadows to keep the experience trustworthy and low-stress. It is fully responsive down to small phones, where chips wrap and padding tightens for comfortable one-handed reading.
Illustrative UI only — not intended for real medical use.