{"id":"a7d5615f-2395-4297-b38f-9c02f3a6d82b","shortId":"C43x24","kind":"skill","title":"notifications-and-recovery","tagline":"When something goes wrong, the user must be able to recover or try again. Toasts, inline errors, banners, and notification patterns each have a specific role. Use when designing error states, success confirmations, async feedback, in-place editing, or any system that communicates","description":"# Notifications and Recovery\n\nWhen something changes — success, failure, or anything in between — the user must know. And when something goes wrong, they must always have a path forward. A notification without a recovery action is just an apology.\n\n---\n\n## Pattern Selection\n\n| Pattern | When to use | Dismissal |\n|---|---|---|\n| **Toast** | Transient result of a user action (saved, sent, deleted) | Auto-dismiss 4–6s, manual close |\n| **Inline error** | Field-level validation, form errors | Clears on correction |\n| **Alert banner** | Persistent issue affecting the current context | Manual dismiss or resolved state |\n| **Modal / dialog** | Blocking error requiring a decision before continuing | User action required |\n| **Empty state** | No data yet — guide the user to the first action | N/A |\n| **Skeleton / loading** | Async content pending | Replaced by content |\n| **In-place confirmation** | Inline edit saved, row updated, item toggled | Auto-clears after 2–3s |\n\n---\n\n## Toast Notifications\n\nToasts confirm that a background action completed. They appear without interrupting the user's flow.\n\n**Placement:** bottom-center or bottom-right. Never top-center — it competes with page content and navigation.\n\n**Duration:** 4–6 seconds for information. Errors should persist until dismissed — the user needs time to read and act.\n\n**Anatomy:**\n```\n[Icon] Message text                    [Action] [×]\n```\n\n- Icon: colour-coded (green ✓ success, red ✗ error, orange ⚠ warning, blue ℹ info)\n- Message: one sentence, plain language\n- Action (optional): \"Undo\", \"Retry\", \"View\" — one action maximum\n- Close button: always present on errors; optional on success\n\n```\n✓ \"Changes saved.\"\n✓ \"Message sent.  [Undo]\"\n✗ \"Could not save. Check your connection.  [Retry]\"  ← persists until dismissed\n```\n\n**Never:** multiple simultaneous toasts. Queue them; show one at a time.\n\n---\n\n## Inline Errors\n\nInline errors appear adjacent to the element that caused them. They are the most contextual and actionable form of error feedback.\n\n**Form validation:**\n- Validate on blur (leaving a field), not on every keystroke — keystroke validation is noisy\n- Validate on submit for the complete form\n- Show the error message directly below the field, in red, with an icon\n- The field border changes to `--color-error`\n- Error message is associated via `aria-describedby` for screen readers\n\n```html\n<label for=\"email\">Email</label>\n<input id=\"email\" aria-describedby=\"email-error\" aria-invalid=\"true\">\n<p id=\"email-error\" role=\"alert\">Enter a valid email address.</p>\n```\n\n**In-place editing:**\n- When a field is edited inline (table cell, card title), show save/cancel controls adjacent to the field\n- On save: brief success indicator (\"✓ Saved\") that fades after 2s — do not navigate away\n- On error: inline error message below the field with a retry option\n- On cancel: restore the original value immediately\n\n---\n\n## Alert Banners\n\nBanners are persistent — they stay until the condition is resolved or the user dismisses them.\n\n**Use for:**\n- Service degradation (\"Some features are temporarily unavailable\")\n- Account issues requiring action (\"Your subscription expires in 3 days. [Renew]\")\n- Ongoing sync errors (\"Changes are not saving. [Retry]\")\n- Important announcements tied to the current page\n\n**Placement:** top of the affected section, not the entire page unless the issue is truly global.\n\n**Anatomy:**\n```\n[Icon] [Message — describes the issue and its scope] [Action] [×]\n```\n\n- One banner at a time per region — multiple simultaneous banners create alarm fatigue\n- Dismissible unless the condition is blocking\n- Colour follows status colour conventions: red (error), orange (warning), blue (info), green (success/resolved)\n\n---\n\n## Recovery Patterns\n\nEvery error state must have a path forward. Design the recovery action at the same time as the error message.\n\n### Retry\nFor transient failures (network, timeout, rate limit):\n\n```\n\"Could not load results.\"\n[Try again]\n```\n\n- Retry button triggers the same action\n- After 3 failed retries, escalate: \"Still having trouble? [Contact support]\"\n- Show a spinner during retry — do not let the user click multiple times\n\n### Undo\nFor destructive or irreversible actions (delete, archive, send):\n\n```\n\"Message sent.  [Undo]  ×\"\n```\n\n- Undo window: 5–10 seconds. Toast persists for this duration.\n- After the window closes, the action is final\n- Undo is preferable to confirmation dialogs for low-stakes actions — it is faster and less disruptive\n\n### Autosave and Draft Recovery\nFor long-form inputs (forms, documents, editors):\n\n- Autosave every 30–60 seconds silently\n- On save failure: \"Autosave failed — your changes are stored locally. [Retry save]\"\n- On return after crash or close: \"You have unsaved changes from [time]. [Restore] [Discard]\"\n\n### Graceful Degradation\nWhen a feature fails but the rest of the product still works:\n\n- Show an error state for the failed section only — do not blank the entire page\n- Offer a fallback: \"Could not load recommendations. [Browse all products →]\"\n- Log the error silently; surface only what the user needs to know\n\n---\n\n## Loading and Skeleton States\n\nLoading is not an error, but it is a state that needs design.\n\n- **Skeleton screens** for content-heavy pages — show the layout shape while data loads\n- **Spinners** for targeted async actions (button loading, inline refresh)\n- **Progress bars** for long operations with known duration (file upload, multi-step processing)\n- Never show a blank screen while loading — always show something\n\nSkeleton screens reduce perceived wait time compared to spinners. Match the skeleton shape to the actual content layout.\n\n---\n\n## Notification Accessibility\n\n- Errors use `role=\"alert\"` — announced immediately by screen readers\n- Status updates use `role=\"status\"` — announced politely (after current speech)\n- Toasts must be reachable by keyboard — do not use `pointer-events: none` on the close button\n- Auto-dismissing toasts must have sufficient duration (`prefers-reduced-motion` users may need more time to read)\n\n```html\n<!-- Error: immediate announcement -->\n<div role=\"alert\">Could not save. Check your connection.</div>\n\n<!-- Status: polite announcement -->\n<div role=\"status\" aria-live=\"polite\">Changes saved.</div>\n```\n\n---\n\n## Review Checklist\n\n- [ ] Does every error have a recovery action (retry, undo, contact support)?\n- [ ] Do toasts auto-dismiss for success but persist for errors?\n- [ ] Is there never more than one toast visible at a time?\n- [ ] Are inline errors placed adjacent to the field, not at the top of the form?\n- [ ] Are form errors associated to their inputs via `aria-describedby`?\n- [ ] Do alert banners appear at the top of the affected section, not always full-page?\n- [ ] Is autosave or draft recovery available for long-form inputs?\n- [ ] Do loading states use skeletons for content and spinners for targeted actions?\n- [ ] Are errors announced via `role=\"alert\"` and status updates via `role=\"status\"`?","tags":["notifications","and","recovery","dembrandt","skills","accessibility","agent-skills","claude-code-skills","claude-skills","cursor-skills","design-system","design-tokens"],"capabilities":["skill","source-dembrandt","skill-notifications-and-recovery","topic-accessibility","topic-agent-skills","topic-claude-code-skills","topic-claude-skills","topic-cursor-skills","topic-design-system","topic-design-tokens","topic-enterprise-ux","topic-gestalt","topic-skills-sh","topic-typography","topic-ui-design"],"categories":["dembrandt-skills"],"synonyms":[],"warnings":[],"endpointUrl":"https://skills.sh/dembrandt/dembrandt-skills/notifications-and-recovery","protocol":"skill","transport":"skills-sh","auth":{"type":"none","details":{"cli":"npx skills add dembrandt/dembrandt-skills","source_repo":"https://github.com/dembrandt/dembrandt-skills","install_from":"skills.sh"}},"qualityScore":"0.454","qualityRationale":"deterministic score 0.45 from registry signals: · indexed on github topic:agent-skills · 9 github stars · SKILL.md body (6,983 chars)","verified":false,"liveness":"unknown","lastLivenessCheck":null,"agentReviews":{"count":0,"score_avg":null,"cost_usd_avg":null,"success_rate":null,"latency_p50_ms":null,"narrative_summary":null,"summary_updated_at":null},"enrichmentModel":"deterministic:skill-github:v1","enrichmentVersion":1,"enrichedAt":"2026-05-18T19:08:27.924Z","embedding":null,"createdAt":"2026-05-18T13:14:03.007Z","updatedAt":"2026-05-18T19:08:27.924Z","lastSeenAt":"2026-05-18T19:08:27.924Z","tsv":"'10':635 '2':183 '2s':421 '3':479,598 '30':681 '3s':184 '4':107,222 '5':634 '6':223 '60':682 '6s':108 'abl':13 'access':845 'account':471 'act':239 'action':82,100,145,158,192,244,263,269,324,474,522,568,596,625,647,660,797,918,1009 'actual':841 'address':390 'adjac':311,408,949 'affect':126,501,980 'alarm':534 'alert':122,445,849,972,1015 'alway':72,273,823,983 'anatomi':240,513 'announc':491,850,860,1012 'anyth':58 'apolog':86 'appear':195,310,974 'archiv':627 'aria':379,969 'aria-describedbi':378,968 'associ':376,963 'async':38,162,796 'auto':105,180,883,926 'auto-clear':179 'auto-dismiss':104,882,925 'autosav':667,679,688,988 'avail':992 'away':425 'background':191 'banner':22,123,446,447,524,532,973 'bar':803 'blank':736,819 'block':137,541 'blue':255,551 'blur':333 'border':367 'bottom':204,208 'bottom-cent':203 'bottom-right':207 'brief':414 'brows':747 'button':272,592,798,881 'cancel':439 'card':403 'caus':316 'cell':402 'center':205,213 'chang':54,280,368,485,691,706,908 'check':288,905 'checklist':911 'clear':119,181 'click':617 'close':110,271,645,702,880 'code':248 'color':371 'color-error':370 'colour':247,542,545 'colour-cod':246 'communic':48 'compar':832 'compet':215 'complet':193,350 'condit':454,539 'confirm':37,171,188,654 'connect':290,907 'contact':605,921 'content':163,167,218,783,842,1004 'content-heavi':782 'context':129 'contextu':322 'continu':143 'control':407 'convent':546 'correct':121 'could':285,585,743,902 'crash':700 'creat':533 'current':128,495,863 'data':150,791 'day':480 'decis':141 'degrad':465,712 'delet':103,626 'describ':516 'describedbi':380,970 'design':33,565,778 'destruct':622 'dialog':136,655 'direct':356 'discard':710 'dismiss':93,106,131,231,294,460,536,884,927 'disrupt':666 'document':677 'draft':669,990 'durat':221,641,809,889 'edit':43,173,394,399 'editor':678 'element':314 'email':385,389 'empti':147 'enter':386 'entir':505,738 'error':21,34,112,118,138,227,252,276,307,309,327,354,372,373,427,429,484,548,558,575,727,752,770,846,914,933,947,962,1011 'escal':601 'event':876 'everi':339,557,680,913 'expir':477 'fade':419 'fail':599,689,716,731 'failur':56,580,687 'fallback':742 'faster':663 'fatigu':535 'featur':467,715 'feedback':39,328 'field':114,336,359,366,397,411,433,952 'field-level':113 'file':810 'final':649 'first':157 'flow':201 'follow':543 'form':117,325,329,351,674,676,959,961,996 'forward':76,564 'full':985 'full-pag':984 'global':512 'goe':7,68 'grace':711 'green':249,553 'guid':152 'heavi':784 'html':384,901 'icon':241,245,364,514 'immedi':444,851 'import':490 'in-plac':40,168,391 'indic':416 'info':257,552 'inform':226 'inlin':20,111,172,306,308,400,428,800,946 'input':675,966,997 'interrupt':197 'irrevers':624 'issu':125,472,509,518 'item':177 'keyboard':870 'keystrok':340,341 'know':64,761 'known':808 'languag':262 'layout':788,843 'leav':334 'less':665 'let':614 'level':115 'limit':584 'load':161,587,745,762,766,792,799,822,999 'local':694 'log':750 'long':673,805,995 'long-form':672,994 'low':658 'low-stak':657 'manual':109,130 'match':835 'maximum':270 'may':895 'messag':242,258,282,355,374,430,515,576,629 'modal':135 'motion':893 'multi':813 'multi-step':812 'multipl':296,530,618 'must':11,63,71,560,866,886 'n/a':159 'navig':220,424 'need':234,759,777,896 'network':581 'never':210,295,816,936 'noisi':344 'none':877 'notif':2,24,49,78,186,844 'notifications-and-recoveri':1 'offer':740 'one':259,268,302,523,939 'ongo':482 'oper':806 'option':264,277,437 'orang':253,549 'origin':442 'page':217,496,506,739,785,986 'path':75,563 'pattern':25,87,89,556 'pend':164 'per':528 'perceiv':829 'persist':124,229,292,449,638,931 'place':42,170,393,948 'placement':202,497 'plain':261 'pointer':875 'pointer-ev':874 'polit':861 'prefer':652,891 'prefers-reduced-mot':890 'present':274 'process':815 'product':722,749 'progress':802 'queue':299 'rate':583 'reachabl':868 'read':237,900 'reader':383,854 'recommend':746 'recov':15 'recoveri':4,51,81,555,567,670,917,991 'red':251,361,547 'reduc':828,892 'refresh':801 'region':529 'renew':481 'replac':165 'requir':139,146,473 'resolv':133,456 'rest':719 'restor':440,709 'result':96,588 'retri':266,291,436,489,577,591,600,611,695,919 'return':698 'review':910 'right':209 'role':30,848,858,1014,1020 'row':175 'save':101,174,281,287,413,417,488,686,696,904,909 'save/cancel':406 'scope':521 'screen':382,780,820,827,853 'second':224,636,683 'section':502,732,981 'select':88 'send':628 'sent':102,283,630 'sentenc':260 'servic':464 'shape':789,838 'show':301,352,405,607,725,786,817,824 'silent':684,753 'simultan':297,531 'skeleton':160,764,779,826,837,1002 'skill' 'skill-notifications-and-recovery' 'someth':6,53,67,825 'source-dembrandt' 'specif':29 'speech':864 'spinner':609,793,834,1006 'stake':659 'state':35,134,148,559,728,765,775,1000 'status':544,855,859,1017,1021 'stay':451 'step':814 'still':602,723 'store':693 'submit':347 'subscript':476 'success':36,55,250,279,415,929 'success/resolved':554 'suffici':888 'support':606,922 'surfac':754 'sync':483 'system':46 'tabl':401 'target':795,1008 'temporarili':469 'text':243 'tie':492 'time':235,305,527,572,619,708,831,898,944 'timeout':582 'titl':404 'toast':19,94,185,187,298,637,865,885,924,940 'toggl':178 'top':212,498,956,977 'top-cent':211 'topic-accessibility' 'topic-agent-skills' 'topic-claude-code-skills' 'topic-claude-skills' 'topic-cursor-skills' 'topic-design-system' 'topic-design-tokens' 'topic-enterprise-ux' 'topic-gestalt' 'topic-skills-sh' 'topic-typography' 'topic-ui-design' 'transient':95,579 'tri':17,589 'trigger':593 'troubl':604 'truli':511 'unavail':470 'undo':265,284,620,631,632,650,920 'unless':507,537 'unsav':705 'updat':176,856,1018 'upload':811 'use':31,92,462,847,857,873,1001 'user':10,62,99,144,154,199,233,459,616,758,894 'valid':116,330,331,342,345,388 'valu':443 'via':377,967,1013,1019 'view':267 'visibl':941 'wait':830 'warn':254,550 'window':633,644 'without':79,196 'work':724 'wrong':8,69 'yet':151 'ℹ':256","prices":[{"id":"5faabd41-28b9-40c2-8dcb-2198ff703767","listingId":"a7d5615f-2395-4297-b38f-9c02f3a6d82b","amountUsd":"0","unit":"free","nativeCurrency":null,"nativeAmount":null,"chain":null,"payTo":null,"paymentMethod":"skill-free","isPrimary":true,"details":{"org":"dembrandt","category":"dembrandt-skills","install_from":"skills.sh"},"createdAt":"2026-05-18T13:14:03.007Z"}],"sources":[{"listingId":"a7d5615f-2395-4297-b38f-9c02f3a6d82b","source":"github","sourceId":"dembrandt/dembrandt-skills/notifications-and-recovery","sourceUrl":"https://github.com/dembrandt/dembrandt-skills/tree/main/skills/notifications-and-recovery","isPrimary":false,"firstSeenAt":"2026-05-18T13:14:03.007Z","lastSeenAt":"2026-05-18T19:08:27.924Z"}],"details":{"listingId":"a7d5615f-2395-4297-b38f-9c02f3a6d82b","quickStartSnippet":null,"exampleRequest":null,"exampleResponse":null,"schema":null,"openapiUrl":null,"agentsTxtUrl":null,"citations":[],"useCases":[],"bestFor":[],"notFor":[],"kindDetails":{"org":"dembrandt","slug":"notifications-and-recovery","github":{"repo":"dembrandt/dembrandt-skills","stars":9,"topics":["accessibility","agent-skills","claude-code-skills","claude-skills","cursor-skills","design-system","design-tokens","enterprise-ux","gestalt","skills-sh","typography","ui-design","ux","wcag"],"license":"mit","html_url":"https://github.com/dembrandt/dembrandt-skills","pushed_at":"2026-05-14T22:34:06Z","description":"UX and design system skills for AI agents based on 20 years of experience","skill_md_sha":"6784e059940d45ce4cb7a739fea17d7e83a78b2c","skill_md_path":"skills/notifications-and-recovery/SKILL.md","default_branch":"main","skill_tree_url":"https://github.com/dembrandt/dembrandt-skills/tree/main/skills/notifications-and-recovery"},"layout":"multi","source":"github","category":"dembrandt-skills","frontmatter":{"name":"notifications-and-recovery","description":"When something goes wrong, the user must be able to recover or try again. Toasts, inline errors, banners, and notification patterns each have a specific role. Use when designing error states, success confirmations, async feedback, in-place editing, or any system that communicates state changes to the user."},"skills_sh_url":"https://skills.sh/dembrandt/dembrandt-skills/notifications-and-recovery"},"updatedAt":"2026-05-18T19:08:27.924Z"}}