Imported from fusengine/kimi-code (
plugins/design-expert/skills/design-webapp/SKILL.md). Install upstream withnpx skills add fusengine/kimi-code --skill design-webapp. Copyright stays with the author.
Requires every data surface to explicitly cover empty, loading, and error states (never a silent blank default), and applies preattentive-processing rules to tables and dataviz (right-aligned numbers, sticky headers, bar/line over pie, consistent category-to-color mapping).
Reuses design-web's general component guides (buttons, cards, grids, icons) rather than duplicating them — this skill only adds what's specific to apps.
Sources craft from the local corpus's two application interfaces (reve, linear) — no sector browsing — and declares the three reproduced elements (Je reproduis) that design-review verdicts.
Design Webapp — Dashboards, Density, States
When
After design-system tokens exist and design-method's Gate 0 has locked register
product (dense, predictable, motion stays discreet). Read design-method's routing
table first — if the surface is a marketing/landing page instead, use design-web.
Input
design-system.md— OKLCH palette, typography, spacing density, the 3 dials.design-method/references/register/product.md— the Domain-Specificity Floor and the Product Furniture table (generic KPI ribbon, marketing triad reused in-app, cookie-cutter empty state, undifferentiated settings list, generic nav vocabulary).- The corpus's two application interfaces, both under
../design-web/references/refs-design/—reve-recode/(tokens-reve.md§3 surface hierarchy, §4 application UI patterns) andlinear-recode/(tokens-linear.md§6 masking/light, §7 button architecture), plus each folder'sdesign-system.md. Loaded once per task (step 11). - The specific page/pattern being built (dashboard, auth, settings, data table, etc.).
Steps
-
Register
product≠ marketing register. No hero, no scroll-reveal, no CTA-tricks — this register optimizes for glance-speed, not first impression. Density is a feature: Enterprise Dense / Standard spacing profile (design-system/references/spacing-density.md),MOTION_INTENSITY ≤ 4by default (design-motion/references/motion-performance.md). The Focal-Block Floor and Signature Dominance fromdesign-webdo not apply here (register/product.md§4) — several equal-weight blocks in one viewport is correct, not a defect. -
Pick the page pattern from
references/layouts/pages/— dashboard, auth-login, auth-register, onboarding, profile, settings, error-pages. Each is a starting structure, not a template to copy verbatim — adapt density fromdesign-system.md, and run the Domain-Specificity Floor test on it: would this page's copy/icons/grouping look native dropped unedited into an unrelated product in the same category? If yes, it's furniture — name the product's real entities instead (register/product.md§2-3).This is where app structure comes from — not from the page-structure banks. Page structure in this plugin now comes from a matched pair of files, and both are marketing instruments: a hero treatment from
../design-method/references/macrostructure-bank.md(eight treatments of the first screen) and a body sequence from../design-method/references/body-sequence-bank.md(ten sequences read off shipped code). Naming one without the other is an incomplete plan — there.Neither applies to an app surface, and this is a real difference, not a shortcut: an app has no first screen to compose and no scroll narrative to order. It has a persistent shell, a task, and the data that task needs; the reader arrives mid-session with an intent, not at a pitch. So the banks are not consulted here, and a webapp plan that names a hero treatment or a body sequence has mis-routed. There is exactly one case where both picks are still required — a marketing-adjacent page inside the app shell — and that page routes to
design-webanyway (step 11).What does transpose from the banks is their underlying rule, which holds in every register: a structure is chosen for the principle it serves on this subject, never adopted because it is the common shape. The
productequivalent of "don't reach the canon by omission" is the Domain-Specificity Floor above — reaching a settings page's shape by omission is the same defect wearing different clothes. -
Pick the interaction pattern(s) from
references/layouts/patterns/— data-table, command-palette, modal-dialog, toast-notifications, empty-state. Apps lean on these far more than marketing sites do. -
Cover every state explicitly — empty, loading, error, populated. Never a blank or silent default:
- Loading — skeleton rows/cards, never spinner-only (
layouts/patterns/data-table.md— NNG: skeletons perceived 9-12% faster than spinners). - Empty — name the actual object type and the actual first action ("No invoices yet
— create one from a quote" beats "No data yet",
register/product.md§3 Cookie-cutter empty state). - Error — actionable message + retry affordance, never a raw stack trace or generic "Something went wrong."
- For data tables specifically, this extends to sorting/filtering/pagination states.
- Loading — skeleton rows/cards, never spinner-only (
-
Tables (hard rules,
layouts/patterns/data-table.md): first column is a readable identifier (not a raw ID/UUID), numeric columns right-aligned, header sticky on scroll, wrap content rather than truncate where legibility matters, density is a first-class mode (standard 48dp row / dense 36dp row — Material 3 baseline), mobile falls back to horizontal scroll with a sticky first column. Corpus procedure for the dense case:linear/tokens-linear.md§5.9 — a row height that cannot grow, withnowrap+text-overflow: ellipsis, is the condition for a dense list to stay readable at a glance (step 11). Where legibility beats density, the wrap rule above wins over it. -
Dataviz: prefer bar/line charts over pie — preattentive processing reads magnitude/trend faster than angle/area. Color encodes data, never decorates; keep category → color mapping consistent across every chart on the same surface (
layouts/pages/dashboard.md— F-pattern placement for the North Star metric still applies). -
Forms: one column, label above the field, inline validation — reuse
../design-web/references/forms-guide.mdrather than duplicating form rules here; this skill only adds the product-register defaults (single column over multi-column, no marketing-style floating labels). -
Command palette (if present): keyboard shortcuts are optional and revealed only after the user has triggered the action manually at least once — never taught upfront as a required interaction (
layouts/patterns/command-palette.md). -
Apply the responsive shell from
references/responsive-dashboard.md— sidebar behavior across breakpoints (full at desktop, icon-rail at tablet, hamburger at mobile). -
Reuse general component guides from
design-web(buttons, cards, grids, icons) rather than duplicating them — this skill only adds what's specific to apps: density, data-heavy states, and persistent navigation. -
No sector browsing — but the corpus is opened, looked at, then read. Apps are function-first: skip the fuse-browser step, don't go look at sector sites, and never pull taste from a template platform (banned plugin-wide,
../design-web/references/design-inspiration.md). But skipping the browse is not skipping the source of taste. The corpus is local and two of its entries are application interfaces.Open
../design-web/references/refs-design/reve-recode/index.htmlin a browser and scroll it before you read a line of the token file below. Double-click,file://, no server. The surface hierarchy described in §3 is a thing you can see in about four seconds and cannot reconstruct from a list of hex values — white panels separating from aneutral-50ground by a 4% border plus a very low shadow is a look, and the numbers only let you reproduce it once you know what it is.../design-web/references/refs-design/linear-recode/index.htmlis the second application surface worth opening; it draws six product windows in markup.Then read. This is the only place depth, surface hierarchy and real UI procedures come from here; without it this skill has no source of taste at all, which is worse than browsing. Paths below are relative to
../design-web/references/.refs-design/reve-recode/tokens-reve.md— an app token system, read whole.- §3 Surface hierarchy — the page ground is
neutral-50, not white; white is reserved for panels laid on top, and that is where separation comes from, not from a shadow. Roles are named and distinct: page / panel / well (field background, image reserve) / canvas / panel border / field border / modal scrim. The resting card is a border at 4% black plus a very low shadow — the border separates white from white, the shadow gives altitude, and neither alone is enough. Elevations are role-based (control / panel / upward / resting / selection), not a t-shirt scale. Selection signals through a surface change, never an accent border. - §4 Application UI patterns — the field carries no border: it signals through a
neutral-100background on the white panel, full radius, 40px tall, and its focus ring is neutral (color-mix24% of the text colour, offset 1px) because the accent stays reserved for general keyboard navigation. One focus token for the whole app, with an explicit exclusion list for components managing their own ring. The list row is two levels, never three (name on one line with an ellipsis, description in reduced secondary). The status label is a fixed frame that never takes the accent — it stays muted so it cannot compete with the name. Keyboard shortcuts usekbd:has(> kbd)— semantic markup, no class. Scrollbars are themed globally at 4px withscrollbar-gutter: stable, which removes the 15px layout jump when a dialog locks scrolling. The<button>reset inherits everything from surrounding text before redeclaring, and the primary inverts text and background so it follows the theme with no second token set.
refs-design/linear-recode/tokens-linear.md— a dense product surface.- §6 Masking and light — edges are never cut, they dissolve:
mask-imagefrom opaque to transparent on anything leaving its frame, driven by a set of named mask tokens rather than literal colours. The hairline that follows the pointer is a solid 1px border masked by a radial gradient centred on the cursor, with JS writing only--x/--y— no layout property is touched. Large halos ship as a pre-blurred SVG data-URI so the blur costs nothing during scroll (with the documented trap: a data-URI colour escapes the token system and must be neutralised per theme). - §7 Button architecture — a single class carries all the geometry; size and
variant only reassign variables, never a metric. Five sizes (24/32/40/40/44px) with
line-heightequal to button height, and the secondary variant built from fourbox-shadows instead of aborder. - Also directly applicable to app surfaces: §5.9 fixed 44px row height with
nowrap+text-overflow: ellipsis— the row cannot grow, which is the condition for a dense list to stay readable at a glance; §5.10 a--min-tap-size: 44pxtoken sizing the target independently of the text; §2.5 depth by stacking five shadows at 1–8% (none visible alone) rather than one shadow at 20%.
Each folder's
design-system.mdholds the same systems as shipped tokens — reve's two ramps, one opaque for surfaces and one alpha ramp for text (so type sits on any surface without needing a matching grey), linear's four parallel four-step ramps (background/text/border/line) where a component picks one level per ramp and never a free value, its five-shadow stack, and its split density profile (dense inside the data surfaces, generous between them).Cite what you took in the
Je reproduisline below — a procedure and the section it was read from, never an impression. Borrow the mechanism, not the hex value. A marketing-adjacent surface inside the app (e.g. an in-app pricing page) routes todesign-webfor that one page. - §3 Surface hierarchy — the page ground is
-
Generate directly as HTML/CSS (default), or optionally via Gemini Design MCP (
../design-web/references/gemini/) — same brief content either way.
Declared Elements — the Je reproduis line
Before handoff, write this line into the deliverable's report and into design-system.md,
verbatim in this format — identical to ../design-web/SKILL.md's, because design-review
parses the same string (../design-review/SKILL.md Input,
../design-review/references/review-procedure.md Input + Part 2 item 4):
Je reproduis: {el1} [corpus: {reference}/{tokens section}], {el2} [corpus: {reference}/{tokens section}], {el3} [sector: {url} — register]
Exactly three elements, each nameable in the rendered screen — the verdict is binary, so
"a clean, dense feel" is not an element while "fields carry no border and signal through a
neutral-100 background on the white panel" is. Register product changes what gets
declared, never the format — the prefix and the three comma-separated slots are parsed,
so they stay byte-identical to design-web's.
-
The two corpus elements are UI procedures, taken from the application references read in step 11 and cited with the
tokens-*.mdsection they were read from. Worked examples:{surfaces separate by ground-vs-panel, resting card = 4% border + very low shadow} [corpus: reve/tokens-reve.md §3]{borderless fields on a neutral-100 well, neutral focus ring, accent reserved for keyboard nav} [corpus: reve/tokens-reve.md §4]{every dense surface dissolves at its edge through mask-image, never a cut} [corpus: linear/tokens-linear.md §6]{one button class, size and variant reassigning variables only, never a metric} [corpus: linear/tokens-linear.md §7]{44px rows that cannot grow, nowrap + ellipsis} [corpus: linear/tokens-linear.md §5.9]
Borrow the mechanism, not the hex value — a colour lifted without the procedure that makes it work is not a reproduced element and will verdict
[absent]. -
The third is a register signal, and for an app that signal is the domain: the product's real entities, actions and vocabulary (
register/product.md§2-3, the Domain-Specificity Floor) — never a craft borrowing, craft is the corpus's job. Because this skill does not browse, the normal value of slot three is[sector: none — register from brief], which is an explicitly valid tag and not an empty slot (../design-review/references/review-procedure.mdInput). Use a real[sector: {url} — register]only when the brief itself named a product to match on register — never go find one to fill the slot.
Output Gate — the Lookalike Test does not apply here
It is a brand-register gate. Its definition stays canonical in
../design-web/references/design-inspiration.md and is not restated, renumbered or
re-parameterised here — and no silhouette count is repeated.
Stated plainly rather than mentioned for form: an app screen is supposed to share a
silhouette with other app screens. A settings page that reads as a settings page is
correct, a data table that reads as a data table is correct, and Jakob's Law makes
silhouette novelty a cost here rather than a win — the opposite of the brand register,
where the page is the product and looking like the competition is the defect. Running a
distinguishability test on a dashboard would push toward exactly the unfamiliarity this
register must avoid.
The structural gate product runs instead is the Domain-Specificity Floor (step 2):
could this screen's copy, icons and grouping drop unedited into an unrelated product in the
same category? That — not silhouette sameness — is the failure this register actually has,
and it is what design-review should be handed in place of a lookalike verdict.
Failure Handling
- Gemini Design MCP (if chosen) unavailable → fall back to direct generation.
- A referenced page pattern doesn't fit the request → adapt the closest one rather than inventing an unstructured layout; note the deviation in the output report.
- A data surface has no obvious empty/error copy yet → block on that, don't ship a silent blank state; ask the owner for the real object name/action if it isn't in the brief.
- A corpus procedure doesn't fit this surface → take a different one from the same sheets,
never fall back to "no corpus element": two corpus slots are mandatory, and a line short
of them is a blocking finding at
design-review, not a soft warning.
Output
- HTML/CSS for the app surface, with every interaction state covered (step 4) and table/ dataviz hard rules applied (steps 5-6).
- The
Je reproduisline written, three elements, two[corpus: …]and one[sector: …]. - Responsive shell verified across the size classes in
responsive-dashboard.md. - Ready for
design-motion.
Next → design-motion, then design-review.
References
| File | Purpose |
|---|---|
references/responsive-dashboard.md |
Sidebar + content responsive pattern |
references/layouts/pages/dashboard.md |
Dashboard page structure, F-pattern KPI placement |
references/layouts/pages/auth-login.md |
Login page structure |
references/layouts/pages/auth-register.md |
Registration page structure |
references/layouts/pages/onboarding.md |
Onboarding flow structure |
references/layouts/pages/profile.md |
Profile page structure |
references/layouts/pages/settings.md |
Settings page structure |
references/layouts/pages/error-pages.md |
404/500/error page structure |
references/layouts/patterns/data-table.md |
Sortable/filterable table pattern, density tokens |
references/layouts/patterns/command-palette.md |
Cmd-K palette pattern |
references/layouts/patterns/modal-dialog.md |
Modal/dialog pattern |
references/layouts/patterns/toast-notifications.md |
Toast/notification pattern |
references/layouts/patterns/empty-state.md |
Empty-state pattern |
../design-method/references/register/product.md |
Domain-Specificity Floor, Product Furniture table |
Shared with design-web (load from there, don't duplicate)
| File | Purpose |
|---|---|
../design-web/references/buttons-guide.md |
Button states, sizing |
../design-web/references/forms-guide.md |
Validation, layout |
../design-web/references/cards-guide.md |
Card patterns |
../design-web/references/grids-layout.md |
Layout/grid system |
../design-web/references/icons-guide.md |
Icon usage |
../design-web/references/gemini/ |
Optional Gemini Design MCP path |
../design-web/references/refs-design/reve-recode/tokens-reve.md |
App surface hierarchy (§3), application UI patterns (§4) — corpus source, step 11 |
../design-web/references/refs-design/linear-recode/tokens-linear.md |
Masking/light techniques (§6), button architecture (§7) — corpus source, step 11 |
../design-web/references/refs-design/README.md |
Corpus index — technique → reference → section |
../design-web/references/design-inspiration.md |
Canonical taste-sourcing order, template-platform ban, canonical Lookalike Test (brand only) |