.agents/skills/how-to-write-component/SKILL.md
Use this as the decision guide for React/TypeScript component structure. Existing code is reference material, not automatic precedent; when it conflicts with these rules, adapt the approach instead of reproducing the violation.
tailwind-css-rules skill. Prefer v4 utilities, gap, text-size/line-height, min-h-dvh, and avoid deprecated utilities and @apply.FC or React.FC.function for top-level components and module helpers. Use arrow functions for local callbacks, handlers, and lambda-style APIs.Props type only when reused, exported, complex, or clearer.appInstanceId. Normalize framework or route params at the boundary.web/contract/* as the single source of truth for API shape; follow existing domain/router patterns and the { params, query?, body? } input shape.useQuery(consoleQuery.xxx.queryOptions(...)) or useQuery(marketplaceQuery.xxx.queryOptions(...)).web/service/use-* wrappers that only rename queryOptions() or mutationOptions(). Extract a small queryOptions helper only when repeated call-site options justify it.input: skipToken; use enabled only for extra business gating after the input is valid.useMutation(consoleQuery.xxx.mutationOptions(...)) or useMutation(marketplaceQuery.xxx.mutationOptions(...)); use oRPC clients as mutationFn only for custom flows.createTanstackQueryUtils(...experimental_defaults...); components may add UI feedback callbacks, but should not own shared invalidation rules.useInvalid or useReset.mutate(...); use mutateAsync(...) only when Promise semantics are required, and wrap awaited calls in try/catch.useMemo only when the calculation is actually expensive.key reset, storing a stable ID and deriving the selected object, or guarded same-component render-time adjustment when truly necessary.Link for normal navigation. Use router APIs only for command-flow side effects such as mutation success, guarded redirects, or form submission.memo, useMemo, and useCallback unless there is a clear performance reason.