FAQ
FAQ with expand-all control
Counter and a single switch for every answer
Counter and a single switch for every answer
Build an FAQ block with Tailwind CSS that gives readers bulk control. The header row has a heading on the left and, on the right, a muted count reading how many of the questions are open plus a small bordered button that toggles between "Expand all" and "Collapse all". Below, seven details elements as bordered cards with the question in medium weight, a muted one-line preview of the answer that is hidden once the item opens, and a chevron that rotates. Answers are relaxed grey prose. Add a footer row with a bordered box offering a link to the full documentation and a support email. Then add JavaScript that keeps the counter in sync with any toggle, switches the button label and behaviour depending on whether every item is already open, and updates the preview visibility when an item opens or closes. <section class="mx-auto max-w-3xl px-6 py-16">
<div class="flex flex-wrap items-end justify-between gap-4">
<div>
<h2 class="text-3xl font-semibold tracking-tight text-neutral-900">Frequently asked</h2>
<p class="mt-2 text-sm text-neutral-500">Seven answers, no marketing copy.</p>
</div>
<div class="flex items-center gap-3">
<span id="faqCounter" class="text-xs text-neutral-400">0 of 7 open</span>
<button id="faqToggleAll" class="rounded-xl border border-neutral-200 px-3.5 py-2 text-xs font-medium text-neutral-600 transition hover:bg-neutral-50">Expand all</button>
</div>
</div>
<div id="faqBulk" class="mt-8 space-y-2.5">
<details class="bulk-item group rounded-xl border border-neutral-200 bg-white px-5 py-4">
<summary class="flex cursor-pointer list-none items-start justify-between gap-4">
<span class="flex-1">
<span class="block text-sm font-medium text-neutral-900">Do you have a free tier?</span>
<span class="preview mt-1 block text-xs text-neutral-400">Yes, and it is not a two-week trial in disguise.</span>
</span>
<span class="mt-0.5 text-neutral-400 transition-transform group-open:rotate-180"><svg aria-hidden="true" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.8" stroke-linecap="round" stroke-linejoin="round" class="inline-block h-[1em] w-[1em] shrink-0 align-[-0.125em] transition-transform"><path d="m7 10 5 5 5-5"/></svg></span>
</summary>
<p class="mt-3 text-sm leading-relaxed text-neutral-500">The free plan is permanent and covers one workspace, three seats and 10,000 events a month. No card, and no countdown in the corner.</p>
</details>
<details class="bulk-item group rounded-xl border border-neutral-200 bg-white px-5 py-4">
<summary class="flex cursor-pointer list-none items-start justify-between gap-4">
<span class="flex-1">
<span class="block text-sm font-medium text-neutral-900">Which warehouses do you support?</span>
<span class="preview mt-1 block text-xs text-neutral-400">Snowflake, BigQuery, Redshift, Databricks and Postgres.</span>
</span>
<span class="mt-0.5 text-neutral-400 transition-transform group-open:rotate-180"><svg aria-hidden="true" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.8" stroke-linecap="round" stroke-linejoin="round" class="inline-block h-[1em] w-[1em] shrink-0 align-[-0.125em] transition-transform"><path d="m7 10 5 5 5-5"/></svg></span>
</summary>
<p class="mt-3 text-sm leading-relaxed text-neutral-500">Snowflake, BigQuery, Redshift, Databricks and plain Postgres, plus anything that speaks the Postgres wire protocol. ClickHouse is in beta.</p>
</details>
<details class="bulk-item group rounded-xl border border-neutral-200 bg-white px-5 py-4">
<summary class="flex cursor-pointer list-none items-start justify-between gap-4">
<span class="flex-1">
<span class="block text-sm font-medium text-neutral-900">How fresh is the data?</span>
<span class="preview mt-1 block text-xs text-neutral-400">Five minutes by default, down to thirty seconds.</span>
</span>
<span class="mt-0.5 text-neutral-400 transition-transform group-open:rotate-180"><svg aria-hidden="true" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.8" stroke-linecap="round" stroke-linejoin="round" class="inline-block h-[1em] w-[1em] shrink-0 align-[-0.125em] transition-transform"><path d="m7 10 5 5 5-5"/></svg></span>
</summary>
<p class="mt-3 text-sm leading-relaxed text-neutral-500">Scheduled syncs run every five minutes on all paid plans. Streaming sources land in under thirty seconds, and every chart shows the age of the data it is drawn from.</p>
</details>
<details class="bulk-item group rounded-xl border border-neutral-200 bg-white px-5 py-4">
<summary class="flex cursor-pointer list-none items-start justify-between gap-4">
<span class="flex-1">
<span class="block text-sm font-medium text-neutral-900">Can I self-host?</span>
<span class="preview mt-1 block text-xs text-neutral-400">On Enterprise, in your own Kubernetes cluster.</span>
</span>
<span class="mt-0.5 text-neutral-400 transition-transform group-open:rotate-180"><svg aria-hidden="true" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.8" stroke-linecap="round" stroke-linejoin="round" class="inline-block h-[1em] w-[1em] shrink-0 align-[-0.125em] transition-transform"><path d="m7 10 5 5 5-5"/></svg></span>
</summary>
<p class="mt-3 text-sm leading-relaxed text-neutral-500">Enterprise customers can run the whole stack in their own cluster with a Helm chart we maintain. Updates are your call, though we ask that you stay within two minor versions.</p>
</details>
<details class="bulk-item group rounded-xl border border-neutral-200 bg-white px-5 py-4">
<summary class="flex cursor-pointer list-none items-start justify-between gap-4">
<span class="flex-1">
<span class="block text-sm font-medium text-neutral-900">What counts as an event?</span>
<span class="preview mt-1 block text-xs text-neutral-400">One row written or one API call — never both.</span>
</span>
<span class="mt-0.5 text-neutral-400 transition-transform group-open:rotate-180"><svg aria-hidden="true" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.8" stroke-linecap="round" stroke-linejoin="round" class="inline-block h-[1em] w-[1em] shrink-0 align-[-0.125em] transition-transform"><path d="m7 10 5 5 5-5"/></svg></span>
</summary>
<p class="mt-3 text-sm leading-relaxed text-neutral-500">A single row ingested, or a single API request, whichever produced it. We do not double-count a row that arrives through the API, and retries are free.</p>
</details>
<details class="bulk-item group rounded-xl border border-neutral-200 bg-white px-5 py-4">
<summary class="flex cursor-pointer list-none items-start justify-between gap-4">
<span class="flex-1">
<span class="block text-sm font-medium text-neutral-900">Do you train models on our data?</span>
<span class="preview mt-1 block text-xs text-neutral-400">No, and it is written into the contract.</span>
</span>
<span class="mt-0.5 text-neutral-400 transition-transform group-open:rotate-180"><svg aria-hidden="true" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.8" stroke-linecap="round" stroke-linejoin="round" class="inline-block h-[1em] w-[1em] shrink-0 align-[-0.125em] transition-transform"><path d="m7 10 5 5 5-5"/></svg></span>
</summary>
<p class="mt-3 text-sm leading-relaxed text-neutral-500">No. Customer data is never used to train shared models, and the DPA says so in a sentence your legal team can point at.</p>
</details>
<details class="bulk-item group rounded-xl border border-neutral-200 bg-white px-5 py-4">
<summary class="flex cursor-pointer list-none items-start justify-between gap-4">
<span class="flex-1">
<span class="block text-sm font-medium text-neutral-900">What is the uptime commitment?</span>
<span class="preview mt-1 block text-xs text-neutral-400">99.9% on Scale, 99.95% with service credits on Enterprise.</span>
</span>
<span class="mt-0.5 text-neutral-400 transition-transform group-open:rotate-180"><svg aria-hidden="true" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.8" stroke-linecap="round" stroke-linejoin="round" class="inline-block h-[1em] w-[1em] shrink-0 align-[-0.125em] transition-transform"><path d="m7 10 5 5 5-5"/></svg></span>
</summary>
<p class="mt-3 text-sm leading-relaxed text-neutral-500">99.9% on Scale and 99.95% on Enterprise, both measured monthly with credits applied automatically rather than on request.</p>
</details>
</div>
<div class="mt-8 flex flex-wrap items-center justify-between gap-3 rounded-xl border border-neutral-200 bg-neutral-50 px-5 py-4">
<p class="text-sm text-neutral-600">Still unanswered? The docs go considerably deeper.</p>
<div class="flex gap-4 text-sm font-medium">
<a href="#" class="text-neutral-900 underline-offset-4 hover:underline">Read the docs <svg aria-hidden="true" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.8" stroke-linecap="round" stroke-linejoin="round" class="inline-block h-[1em] w-[1em] shrink-0 align-[-0.125em] transition-transform"><path d="M14 4h6v6M20 4l-9 9"/><path d="M18 13v6a1 1 0 0 1-1 1H5a1 1 0 0 1-1-1V7a1 1 0 0 1 1-1h6"/></svg></a>
<a href="#" class="text-neutral-500 underline-offset-4 hover:text-neutral-900 hover:underline">[email protected]</a>
</div>
</div>
</section> var items = Array.prototype.slice.call(document.querySelectorAll(".bulk-item"));
var counter = document.getElementById("faqCounter");
var toggleAll = document.getElementById("faqToggleAll");
function openCount() {
return items.filter(function (i) {
return i.open;
}).length;
}
function sync() {
var open = openCount();
counter.textContent = open + " of " + items.length + " open";
// The button always offers the action that changes the most state.
toggleAll.textContent = open === items.length ? "Collapse all" : "Expand all";
items.forEach(function (item) {
var preview = item.querySelector(".preview");
if (preview) preview.classList.toggle("hidden", item.open);
});
}
items.forEach(function (item) {
item.addEventListener("toggle", sync);
});
toggleAll.addEventListener("click", function () {
var expand = openCount() !== items.length;
items.forEach(function (item) {
item.open = expand;
});
sync();
});
sync();