Derive a full UI palette from one or two brand colours — state variants, brand-tinted greys, semantic colours. Use when building or expanding a colour system.
日本語の概要は準備中です。原文の説明を表示しています。
Spinners, skeletons and staggered reveals that manage wait times. Use when designing loading states, async data or the feel of a slow interface.
インストールする前に、エージェントに与えられる指示の中身を確認できます。
Users don't mind waiting as much if they understand what they are waiting for and how much progress is being made. Perceived performance is the design work of making a system feel faster than it actually is.
| Wait Duration | Best Pattern | Use for |
|---|---|---|
| Short (< 1s) | Inline Spinner / Loader | Button actions, small updates, quick data fetches |
| Medium (1s – 3s) | Skeleton Screen | Cards, lists, dashboards, profile pages |
| Long (> 3s) | Determinate Progress Bar | File uploads, complex exports, heavy processing |
| Full Page | Staggered Entry / Animated Sections | Initial app load, hero sections, immersive transitions |
Use spinners for small, contained actions where the layout doesn't change significantly.
disabled state to prevent double-submissions.@keyframes spin {
0% { transform: rotate(0deg); }
100% { transform: rotate(360deg); }
}
.spinner {
animation: spin 800ms cubic-bezier(0.4, 0, 0.2, 1) infinite;
}
Skeleton screens provide a visual placeholder that mimics the layout of the final content. This reduces "layout shift" (CLS) and signals to the user exactly where the content will appear.
A subtle, moving gradient that travels across the skeleton elements.
.skeleton {
background: var(--color-grey-100);
background-image: linear-gradient(
90deg,
rgba(255, 255, 255, 0) 0%,
rgba(255, 255, 255, 0.5) 50%,
rgba(255, 255, 255, 0) 100%
);
background-size: 200% 100%;
animation: shimmer 1.5s infinite;
}
@keyframes shimmer {
0% { background-position: -200% 0; }
100% { background-position: 200% 0; }
}
--color-grey-100 or grey-50). They should not draw focus.For major page transitions or initial loads, use a coordinated animation strategy.
Instead of the whole page appearing at once, animate sections in a sequence. This guides the user's eye from the most important content (hero) down to secondary areas.
.section {
opacity: 0;
transform: translateY(10px);
animation: slide-up 400ms ease-out forwards;
}
/* Stagger by index */
.section:nth-child(1) { animation-delay: 100ms; }
.section:nth-child(2) { animation-delay: 200ms; }
.section:nth-child(3) { animation-delay: 300ms; }
@keyframes slide-up {
to { opacity: 1; transform: translateY(0); }
}
For hero sections, you might use a more complex animation:
Don't wait for everything before showing anything. Load in the order of value to the user, so the thing they came for appears first and the rest fills in around it. This is both a perceived-performance win and a code-efficiency one: you fetch and render less up front.
Prefetch the predictable next step — next page, a hovered row's detail, the next wizard step — in the background so it's instant. Don't speculatively load everything; only where there's an obvious next move.
The fastest UI is one that doesn't wait for the server at all.
Loading doesn't have to be a neutral experience. For waits longer than 2 seconds, consider adding brand personality and "delight" to keep the user engaged.
Replace generic "Loading..." text with wording that reflects the brand's voice.
For significant loading moments (initial app boot, complex data processing), replace the standard spinner with a small, brand-specific animation.
If a wait is consistently long (3s+), use the loading area to tell a small story or provide value:
When transitioning from a loading state to content, use a crisp fade-in (150ms) to make the arrival feel like a reward. Avoid scaling the incoming content, as it can cause layout instability.
The cursor signals affordance: the arrow for ordinary content, pointer for something that can be acted on. It never signals progress. A cursor: wait or cursor: progress puts the status where the user is not looking, says nothing about what is loading or how far along it is, and disappears the moment the pointer moves. Show progress in the element or region that is actually waiting, which [[button-states]] covers for a control and the skeleton and progress patterns above cover for a region.
A loading state buys patience. It does not buy time, and it cannot rescue a request that is going to fail. The thresholds below are the long-established response-time limits, not a new finding; what follows from them is the part usually skipped.
When a request routinely crosses those thresholds, the fix is the request. If it is heading for a backend timeout, a richer indicator only delays the error the user was always going to get, while hiding from the team that the product is broken. The spinner moves the failure later, so nobody fixes the cause, and people abandon the task anyway.
When the wait is genuinely irreducible, the fix is not the request either. A large export, a model call, a video transcode: some work takes the time it takes, and no indicator shortens it. There the answer is to take the work out of the view. Accept the job, tell the user it is running, release them to do something else, and notify them when it lands, with the result waiting somewhere they can find it. Holding a person in front of a progress bar for two minutes is a choice, and it is rarely the one they would make. The failure to avoid is treating an irreducible wait as a performance bug and an optimisable one as a fact of life; they need opposite responses, so decide which you have before you design the wait.
prefers-reduced-motion respected for all loading animations?| Anti-pattern | Problem | Fix |
|---|---|---|
| A global spinner that blocks the whole app | High frustration, user cannot browse other areas | Use contextual loaders or skeletons |
| Skeletons that don't match the final layout | Massive layout shift (CLS) when data arrives | Match shapes and sizes exactly |
| Too many spinners on one page | Visual noise, feels like the whole app is broken | Group loading states into a single container skeleton |
| Faster-than-light skeletons | Shimmer animation that is too fast or high-contrast | Keep shimmer slow (1.5s+) and very subtle |
まだレビューはありません。使ってみた感想をお寄せください。
概要と使いどころ
Derive a full UI palette from one or two brand colours — state variants, brand-tinted greys, semantic colours. Use when building or expanding a colour system.
日本語の概要は準備中です。原文の説明を表示しています。
Top bar, app launcher, tenant and environment cue, status bar. Use when designing the persistent shell or navigation between apps behind one login.
日本語の概要は準備中です。原文の説明を表示しています。
Product visuals must show the real product with real data. Use when building landing pages, hero sections, screenshots or demo panels.
日本語の概要は準備中です。原文の説明を表示しています。
Shape language across type, radius and icons carries brand personality. Use when starting a design system, picking icons or radius tokens, or reviewing visual consistency.
日本語の概要は準備中です。原文の説明を表示しています。
Rest, hover, active, focus, disabled and loading states, derived from the base colour. Use when designing buttons, links, inputs or any clickable component.
日本語の概要は準備中です。原文の説明を表示しています。
Rebuild a live web page 1:1 from measurement into Figma, Penpot or code, then verify it. Use when reproducing a page or checking a rebuild against the original.
日本語の概要は準備中です。原文の説明を表示しています。