{"id":"2cd4d6a9-fb90-45a4-bd45-17a55e5ebda0","shortId":"V7yCMP","kind":"skill","title":"frontend-ui-engineering","tagline":"Builds production-quality UIs. Use when building or modifying user-facing interfaces. Use when creating components, implementing layouts, managing state, or when the output needs to look and feel production-quality rather than AI-generated.","description":"# Frontend UI Engineering\n\n## Overview\n\nBuild production-quality user interfaces that are accessible, performant, and visually polished. The goal is UI that looks like it was built by a design-aware engineer at a top company — not like it was generated by an AI. This means real design system adherence, proper accessibility, thoughtful interaction patterns, and no generic \"AI aesthetic.\"\n\n## When to Use\n\n- Building new UI components or pages\n- Modifying existing user-facing interfaces\n- Implementing responsive layouts\n- Adding interactivity or state management\n- Fixing visual or UX issues\n\n## Component Architecture\n\n### File Structure\n\nColocate everything related to a component:\n\n```\nsrc/components/\n  TaskList/\n    TaskList.tsx          # Component implementation\n    TaskList.test.tsx     # Tests\n    TaskList.stories.tsx  # Storybook stories (if using)\n    use-task-list.ts      # Custom hook (if complex state)\n    types.ts              # Component-specific types (if needed)\n```\n\n### Component Patterns\n\n**Prefer composition over configuration:**\n\n```tsx\n// Good: Composable\n<Card>\n  <CardHeader>\n    <CardTitle>Tasks</CardTitle>\n  </CardHeader>\n  <CardBody>\n    <TaskList tasks={tasks} />\n  </CardBody>\n</Card>\n\n// Avoid: Over-configured\n<Card\n  title=\"Tasks\"\n  headerVariant=\"large\"\n  bodyPadding=\"md\"\n  content={<TaskList tasks={tasks} />}\n/>\n```\n\n**Keep components focused:**\n\n```tsx\n// Good: Does one thing\nexport function TaskItem({ task, onToggle, onDelete }: TaskItemProps) {\n  return (\n    <li className=\"flex items-center gap-3 p-3\">\n      <Checkbox checked={task.done} onChange={() => onToggle(task.id)} />\n      <span className={task.done ? 'line-through text-muted' : ''}>{task.title}</span>\n      <Button variant=\"ghost\" size=\"sm\" onClick={() => onDelete(task.id)}>\n        <TrashIcon />\n      </Button>\n    </li>\n  );\n}\n```\n\n**Separate data fetching from presentation:**\n\n```tsx\n// Container: handles data\nexport function TaskListContainer() {\n  const { tasks, isLoading, error } = useTasks();\n\n  if (isLoading) return <TaskListSkeleton />;\n  if (error) return <ErrorState message=\"Failed to load tasks\" retry={refetch} />;\n  if (tasks.length === 0) return <EmptyState message=\"No tasks yet\" />;\n\n  return <TaskList tasks={tasks} />;\n}\n\n// Presentation: handles rendering\nexport function TaskList({ tasks }: { tasks: Task[] }) {\n  return (\n    <ul role=\"list\" className=\"divide-y\">\n      {tasks.map(task => <TaskItem key={task.id} task={task} />)}\n    </ul>\n  );\n}\n```\n\n## State Management\n\n**Choose the simplest approach that works:**\n\n```\nLocal state (useState)           → Component-specific UI state\nLifted state                     → Shared between 2-3 sibling components\nContext                          → Theme, auth, locale (read-heavy, write-rare)\nURL state (searchParams)         → Filters, pagination, shareable UI state\nServer state (React Query, SWR)  → Remote data with caching\nGlobal store (Zustand, Redux)    → Complex client state shared app-wide\n```\n\n**Avoid prop drilling deeper than 3 levels.** If you're passing props through components that don't use them, introduce context or restructure the component tree.\n\n## Design System Adherence\n\n### Avoid the AI Aesthetic\n\nAI-generated UI has recognizable patterns. Avoid all of them:\n\n| AI Default | Why It Is a Problem | Production Quality |\n|---|---|---|\n| Purple/indigo everything | Models default to visually \"safe\" palettes, making every app look identical | Use the project's actual color palette |\n| Excessive gradients | Gradients add visual noise and clash with most design systems | Flat or subtle gradients matching the design system |\n| Rounded everything (rounded-2xl) | Maximum rounding signals \"friendly\" but ignores the hierarchy of corner radii in real designs | Consistent border-radius from the design system |\n| Generic hero sections | Template-driven layout with no connection to the actual content or user need | Content-first layouts |\n| Lorem ipsum-style copy | Placeholder text hides layout problems that real content reveals (length, wrapping, overflow) | Realistic placeholder content |\n| Oversized padding everywhere | Equal generous padding destroys visual hierarchy and wastes screen space | Consistent spacing scale |\n| Stock card grids | Uniform grids are a layout shortcut that ignores information priority and scanning patterns | Purpose-driven layouts |\n| Shadow-heavy design | Layered shadows add depth that competes with content and slows rendering on low-end devices | Subtle or no shadows unless the design system specifies |\n\n### Spacing and Layout\n\nUse a consistent spacing scale. Don't invent values:\n\n```css\n/* Use the scale: 0.25rem increments (or whatever the project uses) */\n/* Good */  padding: 1rem;      /* 16px */\n/* Good */  gap: 0.75rem;       /* 12px */\n/* Bad */   padding: 13px;      /* Not on any scale */\n/* Bad */   margin-top: 2.3rem; /* Not on any scale */\n```\n\n### Typography\n\nRespect the type hierarchy:\n\n```\nh1 → Page title (one per page)\nh2 → Section title\nh3 → Subsection title\nbody → Default text\nsmall → Secondary/helper text\n```\n\nDon't skip heading levels. Don't use heading styles for non-heading content.\n\n### Color\n\n- Use semantic color tokens: `text-primary`, `bg-surface`, `border-default` — not raw hex values\n- Ensure sufficient contrast (4.5:1 for normal text, 3:1 for large text)\n- Don't rely solely on color to convey information (use icons, text, or patterns too)\n\n## Accessibility (WCAG 2.1 AA)\n\nEvery component must meet these standards:\n\n### Keyboard Navigation\n\n```tsx\n// Every interactive element must be keyboard accessible\n<button onClick={handleClick}>Click me</button>        // ✓ Focusable by default\n<div onClick={handleClick}>Click me</div>               // ✗ Not focusable\n<div role=\"button\" tabIndex={0} onClick={handleClick}    // ✓ But prefer <button>\n     onKeyDown={e => {\n       if (e.key === 'Enter') handleClick();\n       if (e.key === ' ') e.preventDefault();\n     }}\n     onKeyUp={e => {\n       if (e.key === ' ') handleClick();\n     }}>\n  Click me\n</div>\n```\n\n### ARIA Labels\n\n```tsx\n// Label interactive elements that lack visible text\n<button aria-label=\"Close dialog\"><XIcon /></button>\n\n// Label form inputs\n<label htmlFor=\"email\">Email</label>\n<input id=\"email\" type=\"email\" />\n\n// Or use aria-label when no visible label exists\n<input aria-label=\"Search tasks\" type=\"search\" />\n```\n\n### Focus Management\n\n```tsx\n// Move focus when content changes\nfunction Dialog({ isOpen, onClose }: DialogProps) {\n  const closeRef = useRef<HTMLButtonElement>(null);\n\n  useEffect(() => {\n    if (isOpen) closeRef.current?.focus();\n  }, [isOpen]);\n\n  // Trap focus inside dialog when open\n  return (\n    <dialog open={isOpen}>\n      <button ref={closeRef} onClick={onClose}>Close</button>\n      {/* dialog content */}\n    </dialog>\n  );\n}\n```\n\n### Meaningful Empty and Error States\n\n```tsx\n// Don't show blank screens\nfunction TaskList({ tasks }: { tasks: Task[] }) {\n  if (tasks.length === 0) {\n    return (\n      <div role=\"status\" className=\"text-center py-12\">\n        <TasksEmptyIcon className=\"mx-auto h-12 w-12 text-muted\" />\n        <h3 className=\"mt-2 text-sm font-medium\">No tasks</h3>\n        <p className=\"mt-1 text-sm text-muted\">Get started by creating a new task.</p>\n        <Button className=\"mt-4\" onClick={onCreateTask}>Create Task</Button>\n      </div>\n    );\n  }\n\n  return <ul role=\"list\">...</ul>;\n}\n```\n\n## Responsive Design\n\nDesign for mobile first, then expand:\n\n```tsx\n// Tailwind: mobile-first responsive\n<div className=\"\n  grid grid-cols-1      /* Mobile: single column */\n  sm:grid-cols-2        /* Small: 2 columns */\n  lg:grid-cols-3        /* Large: 3 columns */\n  gap-4\n\">\n```\n\nTest at these breakpoints: 320px, 768px, 1024px, 1440px.\n\n## Loading and Transitions\n\n```tsx\n// Skeleton loading (not spinners for content)\nfunction TaskListSkeleton() {\n  return (\n    <div className=\"space-y-3\" aria-busy=\"true\" aria-label=\"Loading tasks\">\n      {Array.from({ length: 3 }).map((_, i) => (\n        <div key={i} className=\"h-12 bg-muted animate-pulse rounded\" />\n      ))}\n    </div>\n  );\n}\n\n// Optimistic updates for perceived speed\nfunction useToggleTask() {\n  const queryClient = useQueryClient();\n\n  return useMutation({\n    mutationFn: toggleTask,\n    onMutate: async (taskId) => {\n      await queryClient.cancelQueries({ queryKey: ['tasks'] });\n      const previous = queryClient.getQueryData(['tasks']);\n\n      queryClient.setQueryData(['tasks'], (old: Task[]) =>\n        old.map(t => t.id === taskId ? { ...t, done: !t.done } : t)\n      );\n\n      return { previous };\n    },\n    onError: (_err, _taskId, context) => {\n      queryClient.setQueryData(['tasks'], context?.previous);\n    },\n  });\n}\n```\n\n## See Also\n\nFor detailed accessibility requirements and testing tools, see `references/accessibility-checklist.md`.\n\n## Common Rationalizations\n\n| Rationalization | Reality |\n|---|---|\n| \"Accessibility is a nice-to-have\" | It's a legal requirement in many jurisdictions and an engineering quality standard. |\n| \"We'll make it responsive later\" | Retrofitting responsive design is 3x harder than building it from the start. |\n| \"The design isn't final, so I'll skip styling\" | Use the design system defaults. Unstyled UI creates a broken first impression for reviewers. |\n| \"This is just a prototype\" | Prototypes become production code. Build the foundation right. |\n| \"The AI aesthetic is fine for now\" | It signals low quality. Use the project's actual design system from the start. |\n\n## Red Flags\n\n- Components with more than 200 lines (split them)\n- Inline styles or arbitrary pixel values\n- Missing error states, loading states, or empty states\n- No keyboard navigation testing\n- Color as the sole indicator of state (red/green without text or icons)\n- Generic \"AI look\" (purple gradients, oversized cards, stock layouts)\n\n## Verification\n\nAfter building UI:\n\n- [ ] Component renders without console errors\n- [ ] All interactive elements are keyboard accessible (Tab through the page)\n- [ ] Screen reader can convey the page's content and structure\n- [ ] Responsive: works at 320px, 768px, 1024px, 1440px\n- [ ] Loading, error, and empty states all handled\n- [ ] Follows the project's design system (spacing, colors, typography)\n- [ ] No accessibility warnings in dev tools or axe-core","tags":["frontend","engineering","agent","skills","addyosmani","agent-skills","antigravity","antigravity-ide","claude-code","cursor"],"capabilities":["skill","source-addyosmani","skill-frontend-ui-engineering","topic-agent-skills","topic-antigravity","topic-antigravity-ide","topic-claude-code","topic-cursor","topic-skills"],"categories":["agent-skills"],"synonyms":[],"warnings":[],"endpointUrl":"https://skills.sh/addyosmani/agent-skills/frontend-ui-engineering","protocol":"skill","transport":"skills-sh","auth":{"type":"none","details":{"cli":"npx skills add addyosmani/agent-skills","source_repo":"https://github.com/addyosmani/agent-skills","install_from":"skills.sh"}},"qualityScore":"0.700","qualityRationale":"deterministic score 0.70 from registry signals: · indexed on github topic:agent-skills · 43270 github stars · SKILL.md body (10,313 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-18T18:50:21.606Z","embedding":null,"createdAt":"2026-04-18T20:31:07.111Z","updatedAt":"2026-05-18T18:50:21.606Z","lastSeenAt":"2026-05-18T18:50:21.606Z","tsv":"'-12':922 '-3':313 '-4':871 '0':269,753,857 '0.25':596 '0.75':610 '1':690,695 '1024px':897,1171 '12px':612 '13px':615 '1440px':898,1172 '16px':607 '1rem':606 '2':312 '2.1':716 '2.3':624 '200':1094 '2xl':451 '3':359,694,914 '320px':895,1169 '3x':1022 '4.5':689 '768px':896,1170 'aa':717 'access':56,96,714,733,981,992,1151,1190 'actual':424,486,1082 'ad':123 'add':430,557 'adher':94,382 'aesthet':104,386,1069 'ai':42,88,103,385,388,398,1068,1129 'ai-gener':41,387 'also':978 'anim':927 'animate-puls':926 'app':352,417 'app-wid':351 'approach':297 'arbitrari':1101 'architectur':134 'aria':774,791 'aria-label':790 'array.from':912 'async':945 'auth':318 'avoid':181,354,383,394 'await':947 'awar':75 'axe':1197 'axe-cor':1196 'bad':613,620 'becom':1060 'bg':677,924 'bg-mute':923 'bg-surfac':676 'blank':848 'bodi':647 'bodypad':190 'border':468,680 'border-default':679 'border-radius':467 'breakpoint':894 'broken':1049 'build':5,12,48,108,1025,1063,1139 'built':70 'button':228,734,751,831,868 'cach':342 'card':185,532,1134 'chang':805 'check':213 'checkbox':212 'choos':294 'clash':434 'classnam':219,869,920 'click':737,745,772 'client':348 'close':836 'closeref':812,833 'closeref.current':818 'code':1062 'coloc':137 'color':425,668,671,704,1116,1187 'common':988 'compani':80 'compet':560 'complex':159,347 'compon':22,111,133,142,146,163,168,197,304,315,367,378,719,1090,1141 'component-specif':162,303 'compos':176 'composit':171 'configur':173,184 'connect':483 'consist':466,528,585 'consol':1144 'const':248,811,937,951 'contain':242 'content':192,487,492,507,514,562,667,804,838,908,1163 'content-first':491 'context':316,374,972,975 'contrast':688 'convey':706,1159 'copi':499 'core':1198 'corner':461 'creat':21,864,874,1047 'css':592 'custom':156 'data':237,244,340 'deeper':357 'default':399,410,648,681,741,1044 'depth':558 'design':74,92,380,437,445,465,472,554,577,878,879,1020,1031,1042,1083,1184 'design-awar':73 'destroy':521 'detail':980 'dev':1193 'devic':570 'dialog':807,824,828,837 'dialogprop':810 'div':742,749,917 'done':964 'drill':356 'driven':479,549 'e':759,768 'e.key':761,765,770 'e.preventdefault':766 'element':729,779,1148 'email':787 'empti':840,1110,1176 'end':569 'engin':4,46,76,1009 'ensur':686 'enter':762 'equal':518 'err':970 'error':251,257,842,1105,1145,1174 'errorst':259 'everi':416,718,727 'everyth':138,408,448 'everywher':517 'excess':427 'exist':115,797 'expand':884 'export':204,245,278 'face':17,118 'fail':261 'feel':35 'fetch':238 'file':135 'filter':329 'final':1034 'fine':1071 'first':493,882,889,1050 'fix':128 'flag':1089 'flat':439 'focus':198,739,748,798,802,819,822 'follow':1180 'form':785 'foundat':1065 'friend':455 'frontend':2,44 'frontend-ui-engin':1 'function':205,246,279,806,850,909,935 'gap':609 'generat':43,85,389 'generic':102,474,1128 'generous':519 'get':861 'ghost':230 'global':343 'goal':62 'good':175,200,604,608 'gradient':428,429,442,1132 'grid':533,535 'h':921 'h1':635 'h2':641 'h3':644 'handl':243,276,1179 'handleclick':736,744,755,763,771 'harder':1023 'head':656,661,666 'headervari':188 'heavi':322,553 'hero':475 'hex':684 'hide':502 'hierarchi':459,523,634 'hook':157 'icon':709,1127 'ident':419 'ignor':457,541 'implement':23,120,147 'impress':1051 'increment':598 'indic':1120 'inform':542,707 'inlin':1098 'input':786 'insid':823 'interact':98,124,728,778,1147 'interfac':18,53,119 'introduc':373 'invent':590 'ipsum':497 'ipsum-styl':496 'isload':250,254 'isn':1032 'isopen':808,817,820,830 'issu':132 'jurisdict':1006 'keep':196 'key':288,918 'keyboard':724,732,1113,1150 'label':775,777,784,792,796 'lack':781 'larg':189,697 'later':1017 'layer':555 'layout':24,122,480,494,503,538,550,582,1136 'legal':1002 'length':509,913 'level':360,657 'lift':308 'like':67,82 'line':222,1095 'line-through':221 'll':1013,1037 'load':263,899,904,1107,1173 'local':300,319 'look':33,66,418,1130 'lorem':495 'low':568,1076 'low-end':567 'make':415,1014 'manag':25,127,293,799 'mani':1005 'map':915 'margin':622 'margin-top':621 'match':443 'maximum':452 'md':191 'mean':90 'meaning':839 'meet':721 'messag':260 'miss':1104 'mobil':881,888 'mobile-first':887 'model':409 'modifi':14,114 'move':801 'mt':870 'must':720,730 'mutationfn':942 'mute':226,925 'navig':725,1114 'need':31,167,490 'new':109,866 'nice':996 'nice-to-hav':995 'nois':432 'non':665 'non-head':664 'normal':692 'null':814 'old':957 'old.map':959 'onchang':215 'onclick':233,735,743,754,834,872 'onclos':809,835 'oncreatetask':873 'ondelet':209,234 'one':202,638 'onerror':969 'onkeydown':758 'onkeyup':767 'onmut':944 'ontoggl':208,216 'open':826,829 'optimist':930 'output':30 'over-configur':182 'overflow':511 'overs':515,1133 'overview':47 'pad':516,520,605,614 'page':113,636,640,1155,1161 'pagin':330 'palett':414,426 'pass':364 'pattern':99,169,393,546,712 'per':639 'perceiv':933 'perform':57 'pixel':1102 'placehold':500,513 'polish':60 'prefer':170,757 'present':240,275 'previous':952,968,976 'primari':675 'prioriti':543 'problem':404,504 'product':7,37,50,405,1061 'production-qu':6,36,49 'project':422,602,1080,1182 'prop':355,365 'proper':95 'prototyp':1058,1059 'puls':928 'purpl':1131 'purple/indigo':407 'purpos':548 'purpose-driven':547 'qualiti':8,38,51,406,1010,1077 'queri':337 'querycli':938 'queryclient.cancelqueries':948 'queryclient.getquerydata':953 'queryclient.setquerydata':955,973 'querykey':949 'radii':462 'radius':469 'rare':325 'rather':39 'ration':989,990 'raw':683 're':363 'react':336 'read':321 'read-heavi':320 'reader':1157 'real':91,464,506 'realist':512 'realiti':991 'recogniz':392 'red':1088 'red/green':1123 'redux':346 'ref':832 'references/accessibility-checklist.md':987 'refetch':266 'relat':139 'reli':701 'rem':597,611,625 'remot':339 'render':277,565,1142 'requir':982,1003 'respect':631 'respons':121,877,890,1016,1019,1166 'restructur':376 'retri':265 'retrofit':1018 'return':211,255,258,270,271,284,827,858,876,911,940,967 'reveal':508 'review':1053 'right':1066 'role':750 'round':447,450,453,929 'rounded-2xl':449 'safe':413 'scale':530,587,595,619,629 'scan':545 'screen':526,849,1156 'searchparam':328 'secondary/helper':651 'section':476,642 'see':977,986 'semant':670 'separ':236 'server':334 'shadow':552,556,574 'shadow-heavi':551 'share':310,350 'shareabl':331 'shortcut':539 'show':847 'sibl':314 'signal':454,1075 'simplest':296 'size':231 'skeleton':903 'skill' 'skill-frontend-ui-engineering' 'skip':655,1038 'slow':564 'sm':232 'small':650 'sole':702,1119 'source-addyosmani' 'space':527,529,580,586,1186 'span':218 'specif':164,305 'specifi':579 'speed':934 'spinner':906 'split':1096 'src/components':143 'standard':723,1011 'start':862,1029,1087 'state':26,126,160,292,301,307,309,327,333,335,349,843,1106,1108,1111,1122,1177 'stock':531,1135 'store':344 'stori':152 'storybook':151 'structur':136,1165 'style':498,662,1039,1099 'subsect':645 'subtl':441,571 'suffici':687 'surfac':678 'swr':338 'system':93,381,438,446,473,578,1043,1084,1185 't.done':965 't.id':961 'tab':1152 'tabindex':752 'tailwind':886 'task':177,179,180,187,194,195,207,249,264,273,274,281,282,283,286,290,291,852,853,854,860,867,875,950,954,956,958,974 'task.done':214,220 'task.id':217,235,289 'task.title':227 'taskid':946,962,971 'taskitem':206,287 'taskitemprop':210 'tasklist':144,178,193,272,280,851 'tasklist.stories.tsx':150 'tasklist.test.tsx':148 'tasklist.tsx':145 'tasklistcontain':247 'tasklistskeleton':910 'tasks.length':268,856 'tasks.map':285 'templat':478 'template-driven':477 'test':149,891,984,1115 'text':225,501,649,652,674,693,698,710,783,1125 'text-mut':224 'text-primari':673 'theme':317 'thing':203 'thought':97 'titl':186,637,643,646 'toggletask':943 'token':672 'tool':985,1194 'top':79,623 'topic-agent-skills' 'topic-antigravity' 'topic-antigravity-ide' 'topic-claude-code' 'topic-cursor' 'topic-skills' 'transit':901 'trap':821 'tree':379 'tsx':174,199,241,726,776,800,844,885,902 'type':165,633 'types.ts':161 'typographi':630,1188 'ui':3,9,45,64,110,306,332,390,1046,1140 'uniform':534 'unless':575 'unstyl':1045 'updat':931 'url':326 'use':10,19,107,154,371,420,583,593,603,660,669,708,789,1040,1078 'use-task-list.ts':155 'useeffect':815 'usemut':941 'usequerycli':939 'user':16,52,117,489 'user-fac':15,116 'useref':813 'usest':302 'usetask':252 'usetoggletask':936 'ux':131 'valu':591,685,1103 'variant':229 'verif':1137 'visibl':782,795 'visual':59,129,412,431,522 'warn':1191 'wast':525 'wcag':715 'whatev':600 'wide':353 'without':1124,1143 'work':299,1167 'wrap':510 'write':324 'write-rar':323 'zustand':345","prices":[{"id":"f449cffb-e1df-4870-9b4d-2bd605fbc792","listingId":"2cd4d6a9-fb90-45a4-bd45-17a55e5ebda0","amountUsd":"0","unit":"free","nativeCurrency":null,"nativeAmount":null,"chain":null,"payTo":null,"paymentMethod":"skill-free","isPrimary":true,"details":{"org":"addyosmani","category":"agent-skills","install_from":"skills.sh"},"createdAt":"2026-04-18T20:31:07.111Z"}],"sources":[{"listingId":"2cd4d6a9-fb90-45a4-bd45-17a55e5ebda0","source":"github","sourceId":"addyosmani/agent-skills/frontend-ui-engineering","sourceUrl":"https://github.com/addyosmani/agent-skills/tree/main/skills/frontend-ui-engineering","isPrimary":false,"firstSeenAt":"2026-04-18T21:52:59.765Z","lastSeenAt":"2026-05-18T18:50:21.606Z"},{"listingId":"2cd4d6a9-fb90-45a4-bd45-17a55e5ebda0","source":"skills_sh","sourceId":"addyosmani/agent-skills/frontend-ui-engineering","sourceUrl":"https://skills.sh/addyosmani/agent-skills/frontend-ui-engineering","isPrimary":true,"firstSeenAt":"2026-04-18T20:31:07.111Z","lastSeenAt":"2026-05-07T22:40:25.253Z"}],"details":{"listingId":"2cd4d6a9-fb90-45a4-bd45-17a55e5ebda0","quickStartSnippet":null,"exampleRequest":null,"exampleResponse":null,"schema":null,"openapiUrl":null,"agentsTxtUrl":null,"citations":[],"useCases":[],"bestFor":[],"notFor":[],"kindDetails":{"org":"addyosmani","slug":"frontend-ui-engineering","github":{"repo":"addyosmani/agent-skills","stars":43270,"topics":["agent-skills","antigravity","antigravity-ide","claude-code","cursor","skills"],"license":"mit","html_url":"https://github.com/addyosmani/agent-skills","pushed_at":"2026-05-16T22:00:25Z","description":"Production-grade engineering skills for AI coding agents.","skill_md_sha":"d4973d4a9e84ad882cf5e52deeed41ebbe8f81ee","skill_md_path":"skills/frontend-ui-engineering/SKILL.md","default_branch":"main","skill_tree_url":"https://github.com/addyosmani/agent-skills/tree/main/skills/frontend-ui-engineering"},"layout":"multi","source":"github","category":"agent-skills","frontmatter":{"name":"frontend-ui-engineering","description":"Builds production-quality UIs. Use when building or modifying user-facing interfaces. Use when creating components, implementing layouts, managing state, or when the output needs to look and feel production-quality rather than AI-generated."},"skills_sh_url":"https://skills.sh/addyosmani/agent-skills/frontend-ui-engineering"},"updatedAt":"2026-05-18T18:50:21.606Z"}}