Error panel
Category: Feedback · Tags: error, retry, failure, details, recovery
Something went wrong
We couldn’t load your recent payments. Your data is safe; this is usually temporary.
Technical details
Error 503: service unavailable. Reference: PAY-7F3K-2291. Time: 6 Nov 2026, 14:02 UTC.
How to use it
Use in place of content that failed to load -- a widget, a panel, a page section -- so people know what failed and can retry without reloading the page. Replace the simulated retry in the script with your real request, keep the details useful for support (an error code and reference, never stack traces or personal data), and change the ids. For a problem that interrupts the user's own action, use the alert; when there is simply nothing to show, use the empty state.
Accessibility
A <section> named by its heading, with the explanation in plain words, a native "Try again" <button>, and the technical details in a native <details>/<summary> disclosure, so they are keyboard operable and announced as collapsed or expanded without ARIA. A role="status" line reports "Retrying…" and the outcome politely, and focus stays on the button. The heading #991b1b and body #0f172a on #fef2f2 are 7.6:1 and 16.3:1, the button's white text on #991b1b is 8.3:1, and the details text #0f172a on #ffffff is 17.9:1.
Source (copy-ready)
<section class="dcl-errpanel" aria-labelledby="dcl-errpanel-title">
<h3 class="dcl-errpanel__title" id="dcl-errpanel-title">Something went wrong</h3>
<p class="dcl-errpanel__text">We couldn’t load your recent payments. Your data is safe; this is usually temporary.</p>
<div class="dcl-errpanel__actions">
<button type="button" class="dcl-errpanel__retry">Try again</button>
<p class="dcl-errpanel__status" role="status"></p>
</div>
<details class="dcl-errpanel__details">
<summary class="dcl-errpanel__summary">Technical details</summary>
<p class="dcl-errpanel__code">Error 503: service unavailable. Reference: PAY-7F3K-2291. Time: 6 Nov 2026, 14:02 UTC.</p>
</details>
</section>
<style>
.dcl-errpanel { box-sizing: border-box; max-width: 32rem; padding: 1rem 1.25rem; border: 1px solid #fca5a5; border-radius: 0.5rem; font: inherit; color: #0f172a; background-color: #fef2f2; }
.dcl-errpanel__title { margin: 0 0 0.375rem; font-size: 1.125rem; color: #991b1b; background-color: #fef2f2; }
.dcl-errpanel__text { margin: 0 0 1rem; color: #0f172a; background-color: #fef2f2; }
.dcl-errpanel__actions { display: flex; flex-wrap: wrap; align-items: center; gap: 0.5rem 1rem; }
.dcl-errpanel__retry { padding: 0.5rem 1rem; border: none; border-radius: 0.375rem; font: inherit; font-weight: 600; cursor: pointer; color: #ffffff; background-color: #991b1b; }
.dcl-errpanel__retry:hover { color: #ffffff; background-color: #7f1d1d; }
.dcl-errpanel__retry:focus-visible { outline: 2px solid #7f1d1d; outline-offset: 2px; }
.dcl-errpanel__status { margin: 0; font-size: 0.875rem; color: #0f172a; background-color: #fef2f2; }
.dcl-errpanel__details { margin-top: 1rem; border-top: 1px solid #fca5a5; padding-top: 0.75rem; }
.dcl-errpanel__summary { cursor: pointer; font-weight: 600; color: #0f172a; background-color: #fef2f2; }
.dcl-errpanel__summary:focus-visible { outline: 2px solid #7f1d1d; outline-offset: 2px; }
.dcl-errpanel__code { margin: 0.5rem 0 0; padding: 0.5rem 0.75rem; border-radius: 0.25rem; font-family: ui-monospace, SFMono-Regular, Menlo, Consolas, monospace; font-size: 0.8125rem; overflow-wrap: anywhere; color: #0f172a; background-color: #ffffff; }
</style>
<script>
(function () {
document.querySelectorAll(".dcl-errpanel").forEach(function (root) {
if (root.dataset.dclBound) { return; }
root.dataset.dclBound = "true";
var retry = root.querySelector(".dcl-errpanel__retry");
var status = root.querySelector(".dcl-errpanel__status");
if (!retry) { return; }
var busy = false;
retry.addEventListener("click", function () {
if (busy) { return; }
busy = true;
retry.setAttribute("aria-disabled", "true");
if (status) { status.textContent = "Retrying\u2026"; }
/* Replace this timer with your real request. */
window.setTimeout(function () {
busy = false;
retry.removeAttribute("aria-disabled");
if (status) { status.textContent = "Still unavailable. Please try again in a minute."; }
}, 1200);
});
});
})();
</script>
Was this useful? Send feedback.