Card skeleton
A grid of cards that holds each photo, title, detail and price in place while it loads.
You reviewed all 18 expense reports. New ones land here as soon as someone submits them.
Live preview: try it.
<!-- Icons: Lucide (lucide.dev), ISC licence -->
<style>
.odl-empty-all-done { box-sizing: border-box; inline-size: 100%; max-inline-size: 40rem; margin-inline: auto; container-type: inline-size; font: var(--ds-text-body-md); color: var(--ds-color-text-primary); text-wrap: pretty; }
.odl-empty-all-done *, .odl-empty-all-done *::before, .odl-empty-all-done *::after { box-sizing: border-box; }
.odl-empty-all-done svg { flex: none; inline-size: var(--ds-size-icon-sm); block-size: var(--ds-size-icon-sm); fill: none; stroke: currentColor; stroke-width: var(--ds-icon-stroke-md); }
.odl-empty-all-done h2, .odl-empty-all-done h3, .odl-empty-all-done p, .odl-empty-all-done ul, .odl-empty-all-done ol, .odl-empty-all-done dl, .odl-empty-all-done dd { margin: 0; }
.odl-empty-all-done h2, .odl-empty-all-done h3 { text-wrap: balance; }
.odl-empty-all-done .odl-btn { display: inline-flex; align-items: center; justify-content: center; gap: var(--ds-space-inline-sm); min-block-size: max(var(--ds-size-control-md), var(--ds-size-target-min)); padding: 0 var(--ds-space-inset-md);
border: var(--ds-border-width-default) solid transparent; border-radius: var(--ds-radius-control); background: var(--ds-color-bg-action-primary); color: var(--ds-color-text-on-action);
font: var(--ds-text-label-lg); font-weight: var(--ds-font-weight-label); text-decoration: none; white-space: nowrap; cursor: pointer; transition: background-color var(--ds-motion-duration-short) var(--ds-motion-easing-standard); }
.odl-empty-all-done .odl-btn:hover { background: var(--ds-color-bg-action-primary-hover); }
.odl-empty-all-done .odl-btn:active { background: var(--ds-color-bg-action-primary-pressed); }
.odl-empty-all-done .odl-btn.is-quiet { border-color: var(--ds-color-border-default); background: var(--ds-color-surface-raised); color: var(--ds-color-text-primary); }
.odl-empty-all-done .odl-btn.is-quiet:hover { background: var(--ds-color-bg-neutral-subtle); }
.odl-empty-all-done .odl-btn.is-text { padding-inline: var(--ds-space-inset-sm); background: transparent; color: var(--ds-color-text-link); }
.odl-empty-all-done .odl-btn.is-text:hover { background: var(--ds-color-bg-neutral-subtle); }
.odl-empty-all-done .odl-btn[disabled], .odl-empty-all-done .odl-btn[aria-disabled="true"] { opacity: var(--ds-opacity-disabled-container); cursor: not-allowed; }
.odl-empty-all-done button:focus-visible, .odl-empty-all-done a:focus-visible, .odl-empty-all-done input:focus-visible, .odl-empty-all-done textarea:focus-visible, .odl-empty-all-done [tabindex]:focus-visible { outline: var(--ds-focus-ring-width) solid var(--ds-color-border-focus); outline-offset: var(--ds-focus-ring-offset); }
.odl-empty-all-done .odl-sr { position: absolute; inline-size: 1px; block-size: 1px; overflow: hidden; clip-path: inset(50%); white-space: nowrap; }
.odl-empty-all-done { display: grid; justify-items: center; padding: var(--ds-space-section-sm) var(--ds-space-inset-xl); text-align: center;
border: var(--ds-border-width-default) solid var(--ds-color-border-subtle); border-radius: var(--ds-radius-container); background: var(--ds-color-surface-raised); }
.odl-empty-all-done .odl-art { display: grid; place-items: center; inline-size: calc(var(--ds-size-control-lg) * 1.25); aspect-ratio: 1; margin-block-end: var(--ds-state-empty-gap, var(--ds-space-stack-md));
border-radius: var(--ds-radius-full); background: var(--ds-color-surface-sunken); color: var(--ds-color-icon-default); }
.odl-empty-all-done .odl-art svg { inline-size: var(--ds-state-empty-media, var(--ds-size-icon-lg)); block-size: var(--ds-state-empty-media, var(--ds-size-icon-lg)); stroke-width: var(--ds-icon-stroke-sm); }
.odl-empty-all-done h2 { font: var(--ds-text-title-md); font-weight: var(--ds-font-weight-heading); }
.odl-empty-all-done .odl-lead { max-inline-size: var(--ds-state-empty-measure, var(--ds-layout-measure-lead)); margin-block-start: var(--ds-space-stack-sm); color: var(--ds-color-text-secondary); }
.odl-empty-all-done .odl-acts { display: flex; flex-wrap: wrap; justify-content: center; gap: var(--ds-space-inline-sm); margin-block-start: var(--ds-space-stack-xl); }
@container (max-width: 26rem) {
.odl-empty-all-done { padding: var(--ds-space-section-sm) var(--ds-space-inset-lg); }
.odl-empty-all-done .odl-acts { flex-direction: column; align-self: stretch; }
}
.odl-empty-all-done .odl-art { background: var(--ds-color-bg-success-subtle); color: var(--ds-color-text-success); }
.odl-empty-all-done .odl-meta { margin-block-start: var(--ds-space-stack-md); color: var(--ds-color-text-tertiary); font: var(--ds-text-label-md); font-variant-numeric: tabular-nums; }
@media (prefers-reduced-motion: reduce) { .odl-empty-all-done, .odl-empty-all-done *, .odl-empty-all-done *::before, .odl-empty-all-done *::after { transition: none !important; animation: none !important; } }
</style>
<section class="odl-empty-all-done" aria-label="Review queue">
<span class="odl-art" aria-hidden="true"><svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"><path d="m3 17 2 2 4-4"/><path d="m3 7 2 2 4-4"/><path d="M13 6h8"/><path d="M13 12h8"/><path d="M13 18h8"/></svg></span>
<h2 data-od-slot="title">You're all caught up</h2>
<p class="odl-lead" data-od-slot="message">You reviewed all 18 expense reports. New ones land here as soon as someone submits them.</p>
<p class="odl-meta" data-od-slot="checked">Checked a minute ago</p>
<div class="odl-acts"><a class="odl-btn is-quiet" href="#" data-od-action="history">See what you approved</a></div>
</section>
A grid of cards that holds each photo, title, detail and price in place while it loads.
A planned-downtime page that says what is paused.
A 403 page that says who owns the page and lets the person ask for access with an.