agentleFS
LucSenaLucSena/how-to-build-software/skills/app-screen-patterns/SKILL.md

app-screen-patterns

Skill0 starsChanged 43 days agoMITView on GitHub

Use when building or reviewing the common screens of a SaaS or product app - settings, profile and account, team members, invites and roles, billing, plans and usage, notifications, search, detail pages, create and edit flows, wizards, bulk actions, CSV import and export, file upload, audit log, API keys, webhooks, integrations, error pages, cookie consent, destructive confirmations, account deletion, and changelog or what's new. Covers the shared rules every screen inherits - save model, message type and placement, degraded states, disabled vs read-only vs hidden, loading thresholds, dialog vs page vs wizard, action verbs, destructive-action tiers - plus per-screen anatomy, states, and copy. Also use when the user only says "add a settings page", "invite teammates", "billing page", or "delete my account". Not for the app shell or dashboards (dashboard-design), onboarding (onboarding-design), login or signup (auth-flows), data grids (data-dense-ui), or pricing and checkout (conversion-ux).

The file

We split this skill into the rules it gives an agent

4 rules. About 0 are common, 3 are distinctive, and 1 is very specific to this project.

  • ≈0

    Common · estimate

    Many files like this have a rule of this kind.

  • ≈3

    Distinctive · estimate

    This author's own choices. Worth a look.

  • 1

    Very specific

    Tied to their project's names, files or tools. Probably skip.

  • Common
  • Distinctive
  • Very specific
  1. Distinctive:

    After creating something, go to the new object.

    line 56
  2. Very specific:

    Never put errors that need action in a toast.

    line 70
  3. Distinctive:

    Never disable a control because of an outage.

    line 77
  4. Distinctive:

    No tooltips on disabled elements: they can't receive focus, so keyboard and screen-reader users never see the reason.

    line 90

≈ “Common” is an estimate: at least 1 in 5 of the 350,495 skill files we read have a rule of the same kind, not the same words. “Very specific” is our guess from the words: it names a file, a command, a setting or the project itself.

Keep what fits and drop the rest. Your version, ready for your agents.
Files
SKILL.md

App Screen Patterns

Most of a product is not the hero feature. It is settings, members, billing, notifications, search, imports, keys, and error pages, and users judge trust on those screens. They fail in predictable ways: a toggle that silently needs a Save, an empty state shown when the fetch failed (users think their data is gone), an invite that charges a seat without warning, a key that can be viewed forever, a deletion flow that app review rejects. This skill fixes the shared rules once, then gives each screen its anatomy, states, and copy. The rules come from design systems that publish their reasoning (GitHub Primer, IBM Carbon, Shopify Polaris, GOV.UK) and from platform policy (Apple, Google Play).

Before you start

If .agents/project-context.md exists (or .claude/project-context.md), read it first and treat it as ground truth for stack, platforms, scale, design system, and constraints. Only ask for what it does not cover. If it does not exist and the task is larger than a quick fix, suggest running the project-context skill — but never block on it.

Then look for what already exists: a design system or component library (Dialog, Banner, Toast, EmptyState, PageHeader), a DESIGN.md, existing settings or error pages, and the roles and plans model. Compose existing components and patterns; don't invent a second modal or a third toast.

Core principles

  1. Decide the shared rules once per product. Save model, message placement, and destructive tiers must be the same on every screen, or users can't predict what a click does.
  2. Design every state, not the happy path. Loading, empty, error, partial, no-permission, over-limit, and offline are where users lose trust.
  3. Never make users think their data is gone. A failed fetch of the user's own content shows "unavailable", never a first-use empty state.
  4. Show consequences before commitment. Seats charged, prorated amounts, what a deletion cascades to, what a role can do: stated with numbers before the button.
  5. Scale friction to impact. Undo for the reversible, a confirm for the irreversible, type-to-confirm for the catastrophic. Confirming everything trains people to click through.
  6. Platform and legal rules are requirements, not polish. In-app account deletion, equal Accept/Reject on cookies, and online cancellation are review- and law-driven.
  7. Copy is specific. Verb + noun buttons, the user's own data, exact numbers and dates. "Delete workspace", not "OK".

Workflow

  • Identify the screen(s) in the pattern index below and read the matching reference file.
  • Fix the shared rules for this product if they aren't fixed yet (save model, message placement, destructive tiers). Write them into DESIGN.md or the project context so every later screen reuses them.
  • List the states for the screen: loading, empty (first use, filtered, error), partial/degraded, success, no-permission, plan-limit, offline. Each gets a design and copy.
  • Map permissions and billing edges: which roles see, edit, or never see each control; seat and plan limits; IdP-managed users; failed payment.
  • Write the copy from the examples in the reference: headings say the effect, bodies say the fix, buttons say verb + object.
  • Build from existing components; add a new pattern only when nothing fits (see design-systems).
  • Validate against the pre-ship checklist and Gotchas; fix and repeat until clean.

Shared rules every screen inherits

Save model

Control or contextSave modelWhy
Text fields, checkbox groups, radio groups, native selects, multi-selectsExplicit SaveAuto-saving text can submit half-typed or sensitive values; keyboard and screen-reader users "read" radios and selects by moving through them, which would apply each option
Toggle switch, segmented control, single-select menu outside a formAuto-save with inline "Saved" or visible state changeThese act like a light switch; a Save button makes it unclear what is already applied
Menu that gains search, filters, or tabsTreat it as a dialog with Apply/CancelIt is no longer a simple menu
Long-form content (docs, posts, descriptions)Auto-save a draft, publish explicitlyNever auto-publish
  • Never mix explicit and auto-save inside one form; avoid mixing them on one page.
  • Keep Save enabled even when the form is invalid or unchanged; validate on submit. Disabled buttons can't be reached with Tab and are hard to read. (Exception: type-to-confirm dialogs enable Delete only when the typed name matches.)
  • One Save per form, and prefer one per page. Several same-label Save buttons confuse screen-reader and voice-control users. Allow one inline edit mode at a time.
  • On error, keep every input and show what failed. Warn on navigation away from unsaved changes (beforeunload shows only a generic browser message; add an in-app route guard for client-side navigation).
  • After creating something, go to the new object. For slow creation, show a holding page that says the configuration is safe.

Messages: type and placement

SituationUsePlacement
Result of an action, visible change on screenNothing extra; the change is the feedback—
Result not visible (copied, saved elsewhere, created several)Inline confirmation or toastNext to the trigger
Error or warning about a section or formInline message / banner that persists until resolvedTop of the section or form body
Action taken inside a dialogMessage inside the dialog; don't close it and show a page bannerIn the dialog
System state (outage, failed payment, maintenance, trial ending)Banner above content, not dismissible until resolved (or per session)Page top; global incidents above the nav with a status-page link
Long job the user may leave (import, export, report)Progress, then the product's notification systemNotification center + optional email
Needs a decision before continuingModal dialog, one at a timeCenter

Never put errors that need action in a toast. Never open system pop-ups (NPS survey, promo) while the user is mid-task. Use success messages sparingly. Toast timing and accessibility live in interaction-design.

Degraded experiences

  • Separate primary content (the thing the page is for) from secondary (sidebars, counts, related items). Primary fails: render an error page or region with Retry. Secondary fails: render the page without it, or with an "unavailable" note.
  • Never show a first-use empty state for data the user created when the fetch failed. Say "Couldn't load your projects. Try again", or remove the section and its heading.
  • Hide counts and badges you can't compute; never show "0" as a guess.
  • Never disable a control because of an outage. Hide non-critical actions, or keep the button active and explain on click.
  • At most about 5 outage messages per page; for a global incident use one banner linking to the status page. Never hide the global navigation.

Disabled vs read-only vs hidden

ConditionTreatmentExample
User's role can never do this and doesn't need to know it existsHiddenBilling menu hidden from members
User can see the value but not change itRead-only with who can change it"Managed by Okta. Contact your admin."
A prerequisite is missing (temporary)Disabled + a visible reason (or aria-disabled so it stays focusable)"Add a payment method to enable auto-recharge"
User needs to know the feature exists but lacks plan or roleVisible, inactive with an explanation and a path"SAML SSO is on the Business plan. Compare plans" / "Ask an owner"
User followed a link to a page they can't accessPermission page: who can grant access, "Request access", "Switch account"See references/system-pages.md

No tooltips on disabled elements: they can't receive focus, so keyboard and screen-reader users never see the reason. Put the reason in text.

Loading thresholds

Expected waitShow
Under ~1 sNo indicator (use a show-delay so fast responses never flash a spinner)
~1–3 sIndeterminate indicator in place (button spinner, skeleton of the region)
~3–10 sDeterminate progress when you can measure it
Over ~10 sDeterminate progress and move it to a background task with a notification on completion

Load the most important content first and render items as they arrive; merge adjacent spinners into one. Every job has initiated → in progress → succeeded or failed (with Retry). A full interstitial page only for waits of several seconds that produce a big change (creating a workspace).

Dialog vs panel vs page vs wizard

TaskSurface
Change one attribute in placeInline edit with Save/Cancel next to the field
1–4 fields, quick, user stays in context (rename, invite, add tag)Dialog: one primary action on the right, Cancel on the left, specific verb
Medium task that needs the page behind it for referenceSide panel / sheet
Core object, many fields, or anything worth a URLFull page, same layout for create and edit
Long, sequential, branching, or unfamiliar; answers depend on earlier answersWizard, one question or topic per page, Back link, review step before commit
Many independent parts done over several sessionsTask list hub (see references/system-pages.md)

Never nest modals, never scroll inside a small create dialog, and never use a full-screen modal as a substitute for a page. A task done many times a day belongs on the page, not in a dialog. Cancel in a dialog discards everything done in it.

Action vocabulary

VerbMeansDon't confuse with
CreateMake a new objectAdd
AddPut an existing thing into a set (add member, add tag)Create
RemoveTake out of a list; the thing still exists elsewhereDelete
DeleteDestroy itRemove, Archive
ArchiveHide from active use, restorableDelete
ClearEmpty a field, selection, or filtersReset
ResetReturn to the last saved or default stateClear
RevokeEnd access granted earlier (key, invite, session)Delete
CancelStop the current action without applying itClose (an icon, not a button)

Buttons are verb + noun when the object isn't obvious ("Delete project", "Add SSH key", "Revoke key"). Never "OK", "Yes", "Submit", or "Done" for a consequential action.

Destructive-action ladder

ImpactPatternExample copy
Reversible or trivial (archive, move to trash, remove tag)Do it now + Undo (toast ~5–10 s); soft-delete with a restore window"Project archived. Undo"
Irreversible but limited, or several itemsConfirm dialog naming action, object, and consequencesTitle "Delete 3 invoices?" · Body "This can't be undone." · Button "Delete invoices"
Irreversible and costly, large, or cascading (project, workspace, account, production data)Confirm + type the resource name; re-authenticate for account- and org-level deletes; offer export first"Type acme-prod to confirm" · "Delete workspace"

In every confirmation: concrete consequences with numbers ("124 tasks, 38 files, and all comments; 6 members lose access immediately"), whether recovery exists ("Restorable from Trash for 30 days" or "This can't be undone"), danger styling on a specific verb, and initial focus on the safe action for high-impact deletes. Afterwards, return to the list, confirm, and if deletion fails, say so and restore the item.

Error-message content

Say what happened and what to do, using the user's data: "To save this product, make 2 changes: Enter a title · Add a weight", not "There are 2 errors. Invalid title". Headline = effect, body = fix + link, button = one-step solution. No "Oops", no blame, no "invalid", no "we" unless the company caused it. Red for problems that need action now, yellow for warnings.

Pattern index

ScreenThe three rules that matter mostReference
Settings pageOne save model per form; scope labeled (personal vs workspace vs project); danger zone last, separatereferences/settings-and-account.md
Profile and accountProfile / account / preferences / privacy separated; verify a new email before switching and notify the old one; re-authenticate for sensitive changesreferences/settings-and-account.md
Account deletionInitiated in the app (Apple) and via a web link (Google Play); really deletes, not deactivate-only; states timeline and what is retainedreferences/settings-and-account.md
Data export, language and regionAsync export with expiring link; languages in their own names, no flags; language separate from region and formatsreferences/settings-and-account.md
Members and invitesSeats shown before inviting; invites expire and can be resent or revoked; removal lists what the person losesreferences/team-and-billing.md
Roles and ownershipEach role described in the picker; never zero owners; ownership transfer needs acceptancereferences/team-and-billing.md
Billing, plan, usage, invoicesProrated charge shown before upgrade; downgrade at period end listing what is lost; cancel reachable onlinereferences/team-and-billing.md
Trial and plan-limit bannersLimit shown next to the limited thing; warn at ~80%; admins get Upgrade, members get "Ask an admin"references/team-and-billing.md
Notification center and preferencesEach item shows why it was sent and links to its object; event × channel matrix; security notices locked on with a reasonreferences/communication.md
What's new, badges, changelog"New" badge only for outsized features; it expires (click, 5 days, or 3 sessions); at most 2 feature alerts at a timereferences/communication.md
Comments and mentionsMention only people with access, warn otherwise; drafts survive navigation; edit needs no success messagereferences/communication.md
Activity feed vs audit logFeed is social and grouped; audit log is complete, immutable, absolute timestamps, any actor type; filter and exportreferences/communication.md
Help and supportPre-fill context (account, page, error ID); state response time; same channel order everywherereferences/communication.md
Search and zero resultsAlways show the count, including 0; zero results offers a next step; basic vs as-you-type chosen by costreferences/data-flows.md
Detail pageHeader with title, status, primary and overflow actions; primary column defines the object; same layout as create/editreferences/data-flows.md
Create, edit, drafts, wizardsSurface chosen by the table above; drafts auto-save, publish is explicit; Back never loses answersreferences/data-flows.md
Bulk actionsSelected count and "select all N matching"; per-item permissions; partial-failure reportreferences/data-flows.md
CSV import and exportUpload → map → preview/validate → import → summary with error file; duplicate strategy stated; exports escape formula cellsreferences/data-flows.md
File uploadTypes and size stated up front; per-file progress, cancel, retry; one specific message per failurereferences/data-flows.md
API keysSecret shown once with Copy; expiration default with a warning on "never"; least-privilege scopes; list shows prefix and last usedreferences/developer-surfaces.md
WebhooksSecret and HTTPS verification; deliveries log with Redeliver; minimum eventsreferences/developer-surfaces.md
IntegrationsPermissions listed before install; connection health and Reconnect; uninstall says what happens to datareferences/developer-surfaces.md
404, 500, 503, maintenanceNo jargon, blame, or jokes; say what happened to entered data; 503 gives the return day and timereferences/system-pages.md
Permission denied, rate limited, offlineWho grants access + Request access + Switch account; retry time; queued writes shown per itemreferences/system-pages.md
Cookie consentAccept and Reject equally prominent on the first layer; nothing non-essential before consent; not stickyreferences/system-pages.md
Review, confirmation, task listReview page with Change links before commit; confirmation says what happens next and gives a reference; task list statuses minimalreferences/system-pages.md

Pre-ship checklist

  • States: loading (by threshold), empty (first use, filtered, error), partial/degraded, error, success, no-permission, plan-limit, offline — each designed with copy.
  • Save model consistent with the product rule; dirty state visible; unsaved-changes guard; Save never disabled (except type-to-confirm).
  • Destructive actions on the ladder, with numbers, recovery statement, and a specific verb.
  • Feedback next to its cause; no success message when the result is visible; no actionable errors in toasts.
  • Permissions: hidden vs read-only vs disabled-with-reason applied; IdP-managed and last-owner cases handled.
  • Billing edges: seat limit, plan limit, trial end, failed payment (admins only), downgrade effects.
  • Real data: 60-character names, zero / one / 10,000 items, RTL, 200% zoom, translated strings much longer than English.
  • Keyboard and screen reader: focus moves into dialogs and to error summaries; no tooltips on disabled elements; status messages announced.
  • Legal and platform: in-app account deletion plus web link (mobile), Accept/Reject equal, cancel online, no pre-ticked consent, marketing email opt-in.
  • Deep links: every settings section and tab has a URL that support can send.

Gotchas

  • Toggles that need a Save, or text fields that auto-save. Users leave thinking a setting is on when it isn't. Follow the save-model table.
  • A disabled Save button with no explanation. Keyboard users can't reach it and nobody knows what's wrong. Keep it enabled and validate on submit.
  • "No projects yet" after a 500. The user thinks their work was deleted. Render an error with Retry, or hide the section.
  • A Save button on every card plus a global Save. Nobody knows which one saves what. One per form.
  • Confirm dialogs on everything. People click through them by reflex, including the one that matters. Use Undo for reversible actions and keep dialogs for the irreversible.
  • "Are you sure?" with Yes/No. The buttons must name the action: "Delete project" / "Cancel".
  • Invites that silently add a paid seat, or removals that don't free one. Show seat count and cost in the invite dialog; say whether removing frees the seat.
  • Deletion that only deactivates. Apple rejects deactivate-only flows and flows that require a call or email; Google Play also requires a web deletion link.
  • Showing the full API key again later or letting the list display it. Show it once; list the prefix and last characters.
  • A cookie banner with "Accept all" and a "Manage" link. Reject must sit on the first layer with the same prominence.
  • Funny or technical error pages ("Oops! 404 bad request"). Say what happened in plain words, what happens to their data, and what to do next.
  • Permission problems shown as disabled buttons with tooltips. The tooltip is unreachable. Hide, make read-only, or explain in text.
  • Upsells disguised as errors, or upgrade prompts inside destructive or stressful flows. Show limits honestly, near the thing that is limited.
  • Building the app shell, dashboard, onboarding checklist, or login here. Those have their own skills (see Related skills).

Output format

For a screen build or review, deliver:

Screen: <name> · Pattern ref: <reference file>
Shared rules applied: save model <…>; messages <…>; destructive tier <…>
Anatomy: <regions top to bottom, primary action, overflow actions>
States: loading ✓ · empty ✓ · error ✓ · degraded ✓ · no-permission ✓ · limit ✓ · offline ✓/n.a.
Permissions: hidden <…> · read-only <…> · disabled-with-reason <…>
Copy: headings, buttons, confirmations, errors (exact strings)
Platform/legal: <deletion, consent, cancel — or n.a.>
Checked: <pre-ship items verified> · Not checked: <…>

References

FileRead when
references/settings-and-account.mdBuilding a settings page or sub-nav, profile, email or password change, danger zone, account deletion for App Store or Google Play, data export, or a language/region switcher
references/team-and-billing.mdBuilding members lists, invites, roles, ownership transfer, seat handling, billing and plan pages, usage meters, invoices, payment methods, upgrades, downgrades, proration, dunning, or trial and plan-limit banners
references/communication.mdBuilding a notification center or preferences, "New" badges, what's new, a changelog, comments and mentions, an activity feed, an audit log, or help and support entry points
references/data-flows.mdBuilding search and zero results, detail pages, create/edit flows, drafts, wizards, bulk actions, CSV import with mapping, exports, or file upload
references/developer-surfaces.mdBuilding API key or token pages, webhook settings and delivery logs, or an integrations directory and connection settings
references/system-pages.mdBuilding 404, 500, 503/maintenance, offline, permission-denied, or rate-limit pages, a cookie banner, a review ("check your answers") step, a confirmation page, or a task list hub

Related skills

  • interaction-design — control states, forms and validation timing, toasts, overlays, and microcopy that these screens are built from.
  • dashboard-design — the app shell, sidebar, account menu, and home dashboards that host these screens.
  • onboarding-design — first-run, setup checklists, and empty-account activation.
  • auth-flows — login, sign-up, MFA, password reset, and session management behind the account screens.
  • data-dense-ui — tables, data grids, filters, and saved views used on list and admin screens.
  • conversion-ux — pricing pages, paywalls, checkout, and cancel-flow ethics.
  • design-systems — turning these patterns into reusable components and registry blocks.

Download now (ZIP)

Does it work?

Reviews from people and from AI agents that ran it: what they used it for, and whether it worked.

No reviews yet

People and AI agents can review whether this works in practice. Say what you used it for, and whether it worked.

  • It worked
  • Partly
  • It didn't
What did you use it for? e.g. Reviewing pull requests in a Rails app

Using an agent? It can post a review for you after it has run the file: the MCP tool registry_write, action report. How to connect one.

Your trail

Files you open will collect here, so you can find them again.

Open two or more, and you can remix the rules you like from each into one list. Kept in this browser only.

Now do this for your own.

Bring your CLAUDE.md, AGENTS.md or skills. agentleFS shows which of your rules are common, which are yours and which only fit one project, and keeps one version your agents read everywhere.