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.
日本語の概要は準備中です。原文の説明を表示しています。
Cards, rows, tiles and cells are fixed slot models that stay aligned when content length varies. Use when building or reviewing any repeated component.
インストールする前に、エージェントに与えられる指示の中身を確認できます。
When a component is rendered many times — a card grid, a list, a table, a nav menu, a row of KPI tiles, a feed — it stops being a single box and becomes a pattern. The value of a pattern is rhythm: the eye learns the layout once and scans the same slot across every instance (the title row, the price row, the action row). Variable content length breaks that rhythm unless the component is built to absorb it.
The principle is general. A card is the most common case, but the same rule governs list rows, table cells, nav items, tiles, comment entries, dashboard widgets, search results — anything repeated. Treat each as a fixed slot model, not a free-form container.
The goal: content of any length, instances that look identical. This is partly content production (write to a target length) and partly layout engineering (build slots that tolerate the variance). This skill covers the layout half and where the two meet.
Name the slots once and treat them as a contract every instance honours. A product card, as a worked example:
┌──────────────────────┐
│ [media] │ ← fixed aspect ratio
│ │
├──────────────────────┤
│ ● Badge │ ← optional slot, space reserved
│ Title │ ← clamp to N lines
│ Subtitle / meta │
│ │
│ Description text… │ ← flexible slot, grows
│ │
├──────────────────────┤
│ €19.99 Read more│ ← anchor, pinned to bottom
└──────────────────────┘
The same three rules apply to a list row (avatar · name · meta · status pinned right), a KPI tile (label · big number · trend pinned bottom), or a search result (title · url · snippet clamped):
A cell that shows a different control per state — a button, then an input, then a value or link — is still one slot. Give each position a fixed width and stretch whatever control it holds to fill it. The same position carries the same role in every row and every state. Content-sized controls change width with their label, so the row reflows, neighbouring controls move under the cursor, and the column stops reading as one list.
The single most common defect: text of different lengths makes the anchor element (a "Read more" link, a price, a status chip) float to a different position in each instance. Fix it by letting the flexible slot grow and pushing the anchor to a fixed edge.
Vertical layout (cards, tiles) — pin the footer to the bottom:
.item {
display: flex;
flex-direction: column;
height: 100%; /* fill the grid/flex track */
}
.item__media {
aspect-ratio: 4 / 3; /* never let media height vary */
object-fit: cover;
}
.item__description {
flex: 1; /* the flexible slot absorbs the slack */
}
.item__footer {
margin-top: auto; /* pin the anchor (price + CTA) to the bottom */
}
For instances to be equal height as siblings, the container track must stretch them — CSS Grid and Flex do this by default (align-items: stretch). Then height: 100% makes each instance fill its track, and margin-top: auto aligns every footer.
.grid {
display: grid;
grid-template-columns: repeat(auto-fill, minmax(260px, 1fr));
gap: var(--space-4);
/* align-items: stretch is the default — do not override it */
}
Horizontal layout (list rows, table cells) — pin the anchor to the right:
.row {
display: flex;
align-items: center;
gap: var(--space-3);
}
.row__title {
flex: 1; /* title absorbs the width variance */
min-width: 0; /* REQUIRED for the title to be allowed to shrink/ellipsis */
}
.row__status {
margin-left: auto; /* status pinned to the right edge */
}
Do not force equal size with a hard-coded height — the tallest natural instance sets the size, and content beyond it clips or overflows. Let the track stretch and pin the anchor.
A slot that appears in some instances and not others — a badge, a discount label, a "verified" tick — shifts everything after it on the instances that have it, breaking alignment. Two fixes:
.item__badge-row {
min-height: 24px; /* always occupies the row */
}
.item__badge {
position: absolute;
top: var(--space-2);
left: var(--space-2);
}
Reserve when the element is inline metadata; overlay when it is a marker on media (Sale, New). Either way, the slot after it must start at the same position in every instance.
When a slot must be fixed-size but its content varies, clamp it to a line count and signal the cut with an ellipsis. This keeps the geometry stable. But truncation hides information — always make the full value recoverable.
Multi-line text — clamp to N lines:
.clamp-2 {
display: -webkit-box;
-webkit-line-clamp: 2;
-webkit-box-orient: vertical;
overflow: hidden;
}
Single-line values (names, SKUs, paths) — ellipsis:
.truncate {
white-space: nowrap;
overflow: hidden;
text-overflow: ellipsis;
min-width: 0; /* needed inside a flex row to allow shrinking */
}
Recover the full value. A clamped or ellipsised string is a usability trap if the full text is unreachable. Provide it:
<span title="Full value here">…</span>. Zero cost, works everywhere, but hover-only (not touch) and unstyled.Only attach a tooltip when text is actually truncated — a
titleon a string that fits adds a redundant hover. Detect overflow (scrollWidth > clientWidth) and settitleconditionally.
The hierarchy of handling variable length:
Constrain one dimension of an image, never both. Width and height: auto, or a fixed aspect-ratio with object-fit. Two constraints distort.
Grid stretches a bare image to the column and a flex column stretches it across the cross axis. Wrap the image or declare align-self/justify-self. A logo that looks squashed in one card and fine in the next is almost always this.
Before blaming CSS for a misaligned mark, measure the asset. Padding baked into the file moves the ink off the box centre, and no layout rule fixes that.
A repeated label/value list gets a fixed-width label column: a grid with a fixed first track, or a table. Every value then starts on the same line. A flex row with a gap and a separator glyph (an arrow, a dash, a pipe) does not align anything, and the glyph is one more mark to read past on every row.
Text expands when translated — German and Finnish commonly run 30–40% longer than English. A component that aligns perfectly in English can break in another locale. Design slots for the long case: clamp text, reserve optional slots, give flex rows min-width: 0, and never assume a label fits on one line because it does in the source language.
When a canvas competes with controls for vertical space, show only the controls that work in the current state and let the others take the same slots in other states. Showing and hiding rows instead resizes the canvas on every state change, which reads as a glitch and moves the thing the user is looking at. Controls disabled in a state are the first to give up their slot.
margin-top: auto for columns, margin-left: auto for rows — so it aligns across instances?aspect-ratio so its size never varies?min-width: 0 so the text is allowed to shrink?まだレビューはありません。使ってみた感想をお寄せください。
概要と使いどころ
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.
日本語の概要は準備中です。原文の説明を表示しています。