lsd-pi 1.2.0 → 1.2.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/cli.js +7 -1
- package/dist/onboarding.js +3 -3
- package/dist/resources/agents/scout.md +6 -0
- package/dist/resources/extensions/slash-commands/plan.js +7 -1
- package/dist/resources/extensions/subagent/index.js +10 -2
- package/dist/resources/extensions/usage/index.js +87 -36
- package/package.json +1 -1
- package/packages/pi-agent-core/dist/agent.d.ts.map +1 -1
- package/packages/pi-agent-core/dist/agent.js +8 -2
- package/packages/pi-agent-core/dist/agent.js.map +1 -1
- package/packages/pi-agent-core/src/agent.ts +8 -2
- package/packages/pi-ai/dist/models.generated.d.ts +222 -1
- package/packages/pi-ai/dist/models.generated.d.ts.map +1 -1
- package/packages/pi-ai/dist/models.generated.js +227 -6
- package/packages/pi-ai/dist/models.generated.js.map +1 -1
- package/packages/pi-ai/dist/models.test.js +28 -0
- package/packages/pi-ai/dist/models.test.js.map +1 -1
- package/packages/pi-ai/scripts/generate-models.ts +10 -100
- package/packages/pi-ai/src/models.generated.ts +227 -6
- package/packages/pi-ai/src/models.test.ts +30 -0
- package/packages/pi-coding-agent/dist/core/agent-session.d.ts +2 -0
- package/packages/pi-coding-agent/dist/core/agent-session.d.ts.map +1 -1
- package/packages/pi-coding-agent/dist/core/agent-session.js +28 -0
- package/packages/pi-coding-agent/dist/core/agent-session.js.map +1 -1
- package/packages/pi-coding-agent/dist/core/settings-manager.js +1 -1
- package/packages/pi-coding-agent/dist/core/settings-manager.js.map +1 -1
- package/packages/pi-coding-agent/dist/core/system-prompt.d.ts.map +1 -1
- package/packages/pi-coding-agent/dist/core/system-prompt.js +10 -0
- package/packages/pi-coding-agent/dist/core/system-prompt.js.map +1 -1
- package/packages/pi-coding-agent/dist/index.d.ts +1 -1
- package/packages/pi-coding-agent/dist/index.d.ts.map +1 -1
- package/packages/pi-coding-agent/dist/index.js +1 -1
- package/packages/pi-coding-agent/dist/index.js.map +1 -1
- package/packages/pi-coding-agent/dist/tests/path-display.test.js +13 -0
- package/packages/pi-coding-agent/dist/tests/path-display.test.js.map +1 -1
- package/packages/pi-coding-agent/dist/tests/settings-manager-scout-policy.test.d.ts +2 -0
- package/packages/pi-coding-agent/dist/tests/settings-manager-scout-policy.test.d.ts.map +1 -0
- package/packages/pi-coding-agent/dist/tests/settings-manager-scout-policy.test.js +15 -0
- package/packages/pi-coding-agent/dist/tests/settings-manager-scout-policy.test.js.map +1 -0
- package/packages/pi-coding-agent/package.json +1 -1
- package/packages/pi-coding-agent/src/core/agent-session.ts +35 -0
- package/packages/pi-coding-agent/src/core/settings-manager.ts +1 -1
- package/packages/pi-coding-agent/src/core/system-prompt.ts +26 -0
- package/packages/pi-coding-agent/src/index.ts +1 -0
- package/packages/pi-coding-agent/src/tests/path-display.test.ts +14 -0
- package/pkg/package.json +1 -1
- package/src/resources/agents/scout.md +6 -0
- package/src/resources/extensions/slash-commands/plan.ts +11 -1
- package/src/resources/extensions/subagent/index.ts +10 -2
- package/src/resources/extensions/usage/index.ts +92 -38
- package/dist/resources/agents/javascript-pro.md +0 -280
- package/dist/resources/agents/researcher.md +0 -29
- package/dist/resources/agents/teams-builder.md +0 -74
- package/dist/resources/agents/teams-reviewer.md +0 -113
- package/dist/resources/agents/typescript-pro.md +0 -255
- package/dist/resources/skills/accessibility/SKILL.md +0 -522
- package/dist/resources/skills/accessibility/references/WCAG.md +0 -162
- package/dist/resources/skills/core-web-vitals/SKILL.md +0 -441
- package/dist/resources/skills/core-web-vitals/references/LCP.md +0 -208
- package/dist/resources/skills/frontend-design/SKILL.md +0 -45
- package/dist/resources/skills/make-interfaces-feel-better/SKILL.md +0 -122
- package/dist/resources/skills/make-interfaces-feel-better/animations.md +0 -379
- package/dist/resources/skills/make-interfaces-feel-better/performance.md +0 -88
- package/dist/resources/skills/make-interfaces-feel-better/surfaces.md +0 -247
- package/dist/resources/skills/make-interfaces-feel-better/typography.md +0 -123
- package/dist/resources/skills/react-best-practices/README.md +0 -123
- package/dist/resources/skills/react-best-practices/SKILL.md +0 -136
- package/dist/resources/skills/react-best-practices/metadata.json +0 -15
- package/dist/resources/skills/react-best-practices/rules/_sections.md +0 -46
- package/dist/resources/skills/react-best-practices/rules/_template.md +0 -28
- package/dist/resources/skills/react-best-practices/rules/advanced-event-handler-refs.md +0 -55
- package/dist/resources/skills/react-best-practices/rules/advanced-init-once.md +0 -42
- package/dist/resources/skills/react-best-practices/rules/advanced-use-latest.md +0 -39
- package/dist/resources/skills/react-best-practices/rules/async-api-routes.md +0 -38
- package/dist/resources/skills/react-best-practices/rules/async-defer-await.md +0 -80
- package/dist/resources/skills/react-best-practices/rules/async-dependencies.md +0 -51
- package/dist/resources/skills/react-best-practices/rules/async-parallel.md +0 -28
- package/dist/resources/skills/react-best-practices/rules/async-suspense-boundaries.md +0 -99
- package/dist/resources/skills/react-best-practices/rules/bundle-barrel-imports.md +0 -59
- package/dist/resources/skills/react-best-practices/rules/bundle-conditional.md +0 -31
- package/dist/resources/skills/react-best-practices/rules/bundle-defer-third-party.md +0 -49
- package/dist/resources/skills/react-best-practices/rules/bundle-dynamic-imports.md +0 -35
- package/dist/resources/skills/react-best-practices/rules/bundle-preload.md +0 -50
- package/dist/resources/skills/react-best-practices/rules/client-event-listeners.md +0 -74
- package/dist/resources/skills/react-best-practices/rules/client-localstorage-schema.md +0 -71
- package/dist/resources/skills/react-best-practices/rules/client-passive-event-listeners.md +0 -48
- package/dist/resources/skills/react-best-practices/rules/client-swr-dedup.md +0 -56
- package/dist/resources/skills/react-best-practices/rules/js-batch-dom-css.md +0 -107
- package/dist/resources/skills/react-best-practices/rules/js-cache-function-results.md +0 -80
- package/dist/resources/skills/react-best-practices/rules/js-cache-property-access.md +0 -28
- package/dist/resources/skills/react-best-practices/rules/js-cache-storage.md +0 -70
- package/dist/resources/skills/react-best-practices/rules/js-combine-iterations.md +0 -32
- package/dist/resources/skills/react-best-practices/rules/js-early-exit.md +0 -50
- package/dist/resources/skills/react-best-practices/rules/js-hoist-regexp.md +0 -45
- package/dist/resources/skills/react-best-practices/rules/js-index-maps.md +0 -37
- package/dist/resources/skills/react-best-practices/rules/js-length-check-first.md +0 -49
- package/dist/resources/skills/react-best-practices/rules/js-min-max-loop.md +0 -82
- package/dist/resources/skills/react-best-practices/rules/js-set-map-lookups.md +0 -24
- package/dist/resources/skills/react-best-practices/rules/js-tosorted-immutable.md +0 -57
- package/dist/resources/skills/react-best-practices/rules/rendering-activity.md +0 -26
- package/dist/resources/skills/react-best-practices/rules/rendering-animate-svg-wrapper.md +0 -47
- package/dist/resources/skills/react-best-practices/rules/rendering-conditional-render.md +0 -40
- package/dist/resources/skills/react-best-practices/rules/rendering-content-visibility.md +0 -38
- package/dist/resources/skills/react-best-practices/rules/rendering-hoist-jsx.md +0 -46
- package/dist/resources/skills/react-best-practices/rules/rendering-hydration-no-flicker.md +0 -82
- package/dist/resources/skills/react-best-practices/rules/rendering-hydration-suppress-warning.md +0 -30
- package/dist/resources/skills/react-best-practices/rules/rendering-svg-precision.md +0 -28
- package/dist/resources/skills/react-best-practices/rules/rendering-usetransition-loading.md +0 -75
- package/dist/resources/skills/react-best-practices/rules/rerender-defer-reads.md +0 -39
- package/dist/resources/skills/react-best-practices/rules/rerender-dependencies.md +0 -45
- package/dist/resources/skills/react-best-practices/rules/rerender-derived-state-no-effect.md +0 -40
- package/dist/resources/skills/react-best-practices/rules/rerender-derived-state.md +0 -29
- package/dist/resources/skills/react-best-practices/rules/rerender-functional-setstate.md +0 -74
- package/dist/resources/skills/react-best-practices/rules/rerender-lazy-state-init.md +0 -58
- package/dist/resources/skills/react-best-practices/rules/rerender-memo-with-default-value.md +0 -38
- package/dist/resources/skills/react-best-practices/rules/rerender-memo.md +0 -44
- package/dist/resources/skills/react-best-practices/rules/rerender-move-effect-to-event.md +0 -45
- package/dist/resources/skills/react-best-practices/rules/rerender-simple-expression-in-memo.md +0 -35
- package/dist/resources/skills/react-best-practices/rules/rerender-transitions.md +0 -40
- package/dist/resources/skills/react-best-practices/rules/rerender-use-ref-transient-values.md +0 -73
- package/dist/resources/skills/react-best-practices/rules/server-after-nonblocking.md +0 -73
- package/dist/resources/skills/react-best-practices/rules/server-auth-actions.md +0 -96
- package/dist/resources/skills/react-best-practices/rules/server-cache-lru.md +0 -41
- package/dist/resources/skills/react-best-practices/rules/server-cache-react.md +0 -76
- package/dist/resources/skills/react-best-practices/rules/server-dedup-props.md +0 -65
- package/dist/resources/skills/react-best-practices/rules/server-parallel-fetching.md +0 -83
- package/dist/resources/skills/react-best-practices/rules/server-serialization.md +0 -38
- package/dist/resources/skills/userinterface-wiki/SKILL.md +0 -253
- package/dist/resources/skills/userinterface-wiki/rules/_sections.md +0 -66
- package/dist/resources/skills/userinterface-wiki/rules/_template.md +0 -24
- package/dist/resources/skills/userinterface-wiki/rules/a11y-reduced-motion-check.md +0 -30
- package/dist/resources/skills/userinterface-wiki/rules/a11y-toggle-setting.md +0 -30
- package/dist/resources/skills/userinterface-wiki/rules/a11y-visual-equivalent.md +0 -36
- package/dist/resources/skills/userinterface-wiki/rules/a11y-volume-control.md +0 -28
- package/dist/resources/skills/userinterface-wiki/rules/appropriate-confirmations-only.md +0 -19
- package/dist/resources/skills/userinterface-wiki/rules/appropriate-errors-warnings.md +0 -18
- package/dist/resources/skills/userinterface-wiki/rules/appropriate-no-decorative.md +0 -21
- package/dist/resources/skills/userinterface-wiki/rules/appropriate-no-high-frequency.md +0 -28
- package/dist/resources/skills/userinterface-wiki/rules/appropriate-no-punishing.md +0 -27
- package/dist/resources/skills/userinterface-wiki/rules/container-callback-ref.md +0 -31
- package/dist/resources/skills/userinterface-wiki/rules/container-guard-initial-zero.md +0 -25
- package/dist/resources/skills/userinterface-wiki/rules/container-no-excessive-use.md +0 -13
- package/dist/resources/skills/userinterface-wiki/rules/container-overflow-hidden.md +0 -25
- package/dist/resources/skills/userinterface-wiki/rules/container-transition-delay.md +0 -21
- package/dist/resources/skills/userinterface-wiki/rules/container-two-div-pattern.md +0 -35
- package/dist/resources/skills/userinterface-wiki/rules/container-use-resize-observer.md +0 -48
- package/dist/resources/skills/userinterface-wiki/rules/context-cleanup-nodes.md +0 -25
- package/dist/resources/skills/userinterface-wiki/rules/context-resume-suspended.md +0 -28
- package/dist/resources/skills/userinterface-wiki/rules/context-reuse-single.md +0 -30
- package/dist/resources/skills/userinterface-wiki/rules/design-filter-for-character.md +0 -25
- package/dist/resources/skills/userinterface-wiki/rules/design-noise-for-percussion.md +0 -26
- package/dist/resources/skills/userinterface-wiki/rules/design-oscillator-for-tonal.md +0 -22
- package/dist/resources/skills/userinterface-wiki/rules/duration-max-300ms.md +0 -21
- package/dist/resources/skills/userinterface-wiki/rules/duration-press-hover.md +0 -21
- package/dist/resources/skills/userinterface-wiki/rules/duration-shorten-before-curve.md +0 -21
- package/dist/resources/skills/userinterface-wiki/rules/duration-small-state.md +0 -15
- package/dist/resources/skills/userinterface-wiki/rules/easing-entrance-ease-out.md +0 -21
- package/dist/resources/skills/userinterface-wiki/rules/easing-exit-ease-in.md +0 -21
- package/dist/resources/skills/userinterface-wiki/rules/easing-for-state-change.md +0 -27
- package/dist/resources/skills/userinterface-wiki/rules/easing-linear-only-progress.md +0 -21
- package/dist/resources/skills/userinterface-wiki/rules/easing-natural-decay.md +0 -22
- package/dist/resources/skills/userinterface-wiki/rules/easing-no-linear-motion.md +0 -22
- package/dist/resources/skills/userinterface-wiki/rules/easing-transition-ease-in-out.md +0 -15
- package/dist/resources/skills/userinterface-wiki/rules/envelope-exponential-decay.md +0 -21
- package/dist/resources/skills/userinterface-wiki/rules/envelope-no-zero-target.md +0 -21
- package/dist/resources/skills/userinterface-wiki/rules/envelope-set-initial-value.md +0 -22
- package/dist/resources/skills/userinterface-wiki/rules/exit-key-required.md +0 -29
- package/dist/resources/skills/userinterface-wiki/rules/exit-matches-initial.md +0 -29
- package/dist/resources/skills/userinterface-wiki/rules/exit-prop-required.md +0 -33
- package/dist/resources/skills/userinterface-wiki/rules/exit-requires-wrapper.md +0 -27
- package/dist/resources/skills/userinterface-wiki/rules/impl-default-subtle.md +0 -21
- package/dist/resources/skills/userinterface-wiki/rules/impl-preload-audio.md +0 -34
- package/dist/resources/skills/userinterface-wiki/rules/impl-reset-current-time.md +0 -26
- package/dist/resources/skills/userinterface-wiki/rules/mode-pop-layout-for-lists.md +0 -25
- package/dist/resources/skills/userinterface-wiki/rules/mode-sync-layout-conflict.md +0 -29
- package/dist/resources/skills/userinterface-wiki/rules/mode-wait-doubles-duration.md +0 -25
- package/dist/resources/skills/userinterface-wiki/rules/morphing-aria-hidden.md +0 -21
- package/dist/resources/skills/userinterface-wiki/rules/morphing-consistent-viewbox.md +0 -23
- package/dist/resources/skills/userinterface-wiki/rules/morphing-group-variants.md +0 -33
- package/dist/resources/skills/userinterface-wiki/rules/morphing-jump-non-grouped.md +0 -29
- package/dist/resources/skills/userinterface-wiki/rules/morphing-reduced-motion.md +0 -28
- package/dist/resources/skills/userinterface-wiki/rules/morphing-spring-rotation.md +0 -23
- package/dist/resources/skills/userinterface-wiki/rules/morphing-strokelinecap-round.md +0 -21
- package/dist/resources/skills/userinterface-wiki/rules/morphing-three-lines.md +0 -32
- package/dist/resources/skills/userinterface-wiki/rules/morphing-use-collapsed.md +0 -33
- package/dist/resources/skills/userinterface-wiki/rules/native-backdrop-styling.md +0 -27
- package/dist/resources/skills/userinterface-wiki/rules/native-placeholder-styling.md +0 -27
- package/dist/resources/skills/userinterface-wiki/rules/native-selection-styling.md +0 -18
- package/dist/resources/skills/userinterface-wiki/rules/nested-consistent-timing.md +0 -25
- package/dist/resources/skills/userinterface-wiki/rules/nested-propagate-required.md +0 -41
- package/dist/resources/skills/userinterface-wiki/rules/none-context-menu-entrance.md +0 -25
- package/dist/resources/skills/userinterface-wiki/rules/none-high-frequency.md +0 -29
- package/dist/resources/skills/userinterface-wiki/rules/none-keyboard-navigation.md +0 -32
- package/dist/resources/skills/userinterface-wiki/rules/param-click-duration.md +0 -21
- package/dist/resources/skills/userinterface-wiki/rules/param-filter-frequency-range.md +0 -21
- package/dist/resources/skills/userinterface-wiki/rules/param-q-value-range.md +0 -21
- package/dist/resources/skills/userinterface-wiki/rules/param-reasonable-gain.md +0 -21
- package/dist/resources/skills/userinterface-wiki/rules/physics-active-state.md +0 -23
- package/dist/resources/skills/userinterface-wiki/rules/physics-no-excessive-stagger.md +0 -22
- package/dist/resources/skills/userinterface-wiki/rules/physics-spring-for-overshoot.md +0 -23
- package/dist/resources/skills/userinterface-wiki/rules/physics-subtle-deformation.md +0 -22
- package/dist/resources/skills/userinterface-wiki/rules/prefetch-hit-slop.md +0 -27
- package/dist/resources/skills/userinterface-wiki/rules/prefetch-keyboard-tab.md +0 -19
- package/dist/resources/skills/userinterface-wiki/rules/prefetch-not-everything.md +0 -22
- package/dist/resources/skills/userinterface-wiki/rules/prefetch-touch-fallback.md +0 -34
- package/dist/resources/skills/userinterface-wiki/rules/prefetch-trajectory-over-hover.md +0 -32
- package/dist/resources/skills/userinterface-wiki/rules/prefetch-use-selectively.md +0 -13
- package/dist/resources/skills/userinterface-wiki/rules/presence-disable-interactions.md +0 -31
- package/dist/resources/skills/userinterface-wiki/rules/presence-hook-in-child.md +0 -31
- package/dist/resources/skills/userinterface-wiki/rules/presence-safe-to-remove.md +0 -37
- package/dist/resources/skills/userinterface-wiki/rules/pseudo-content-required.md +0 -28
- package/dist/resources/skills/userinterface-wiki/rules/pseudo-first-line-styling.md +0 -27
- package/dist/resources/skills/userinterface-wiki/rules/pseudo-hit-target-expansion.md +0 -31
- package/dist/resources/skills/userinterface-wiki/rules/pseudo-marker-styling.md +0 -28
- package/dist/resources/skills/userinterface-wiki/rules/pseudo-over-dom-node.md +0 -32
- package/dist/resources/skills/userinterface-wiki/rules/pseudo-position-relative-parent.md +0 -33
- package/dist/resources/skills/userinterface-wiki/rules/pseudo-z-index-layering.md +0 -37
- package/dist/resources/skills/userinterface-wiki/rules/spring-for-gestures.md +0 -27
- package/dist/resources/skills/userinterface-wiki/rules/spring-for-interruptible.md +0 -27
- package/dist/resources/skills/userinterface-wiki/rules/spring-params-balanced.md +0 -29
- package/dist/resources/skills/userinterface-wiki/rules/spring-preserves-velocity.md +0 -28
- package/dist/resources/skills/userinterface-wiki/rules/staging-dim-background.md +0 -22
- package/dist/resources/skills/userinterface-wiki/rules/staging-one-focal-point.md +0 -24
- package/dist/resources/skills/userinterface-wiki/rules/staging-z-index-hierarchy.md +0 -22
- package/dist/resources/skills/userinterface-wiki/rules/timing-consistent.md +0 -24
- package/dist/resources/skills/userinterface-wiki/rules/timing-no-entrance-context-menu.md +0 -22
- package/dist/resources/skills/userinterface-wiki/rules/timing-under-300ms.md +0 -22
- package/dist/resources/skills/userinterface-wiki/rules/transition-name-cleanup.md +0 -28
- package/dist/resources/skills/userinterface-wiki/rules/transition-name-required.md +0 -27
- package/dist/resources/skills/userinterface-wiki/rules/transition-name-unique.md +0 -24
- package/dist/resources/skills/userinterface-wiki/rules/transition-over-js-library.md +0 -32
- package/dist/resources/skills/userinterface-wiki/rules/transition-style-pseudo-elements.md +0 -24
- package/dist/resources/skills/userinterface-wiki/rules/type-antialiased-on-retina.md +0 -18
- package/dist/resources/skills/userinterface-wiki/rules/type-disambiguation-stylistic-set.md +0 -15
- package/dist/resources/skills/userinterface-wiki/rules/type-font-display-swap.md +0 -28
- package/dist/resources/skills/userinterface-wiki/rules/type-justify-with-hyphens.md +0 -24
- package/dist/resources/skills/userinterface-wiki/rules/type-letter-spacing-uppercase.md +0 -28
- package/dist/resources/skills/userinterface-wiki/rules/type-no-font-synthesis.md +0 -18
- package/dist/resources/skills/userinterface-wiki/rules/type-oldstyle-nums-for-prose.md +0 -21
- package/dist/resources/skills/userinterface-wiki/rules/type-opentype-contextual-alternates.md +0 -15
- package/dist/resources/skills/userinterface-wiki/rules/type-optical-sizing-auto.md +0 -25
- package/dist/resources/skills/userinterface-wiki/rules/type-proper-fractions.md +0 -15
- package/dist/resources/skills/userinterface-wiki/rules/type-slashed-zero.md +0 -17
- package/dist/resources/skills/userinterface-wiki/rules/type-tabular-nums-for-data.md +0 -21
- package/dist/resources/skills/userinterface-wiki/rules/type-text-wrap-balance-headings.md +0 -21
- package/dist/resources/skills/userinterface-wiki/rules/type-text-wrap-pretty.md +0 -16
- package/dist/resources/skills/userinterface-wiki/rules/type-underline-offset.md +0 -25
- package/dist/resources/skills/userinterface-wiki/rules/type-variable-weight-continuous.md +0 -23
- package/dist/resources/skills/userinterface-wiki/rules/ux-aesthetic-usability.md +0 -32
- package/dist/resources/skills/userinterface-wiki/rules/ux-cognitive-load-reduce.md +0 -49
- package/dist/resources/skills/userinterface-wiki/rules/ux-common-region-boundaries.md +0 -50
- package/dist/resources/skills/userinterface-wiki/rules/ux-doherty-perceived-speed.md +0 -29
- package/dist/resources/skills/userinterface-wiki/rules/ux-doherty-under-400ms.md +0 -30
- package/dist/resources/skills/userinterface-wiki/rules/ux-fitts-hit-area.md +0 -32
- package/dist/resources/skills/userinterface-wiki/rules/ux-fitts-target-size.md +0 -31
- package/dist/resources/skills/userinterface-wiki/rules/ux-goal-gradient-progress.md +0 -33
- package/dist/resources/skills/userinterface-wiki/rules/ux-hicks-minimize-choices.md +0 -45
- package/dist/resources/skills/userinterface-wiki/rules/ux-jakobs-familiar-patterns.md +0 -37
- package/dist/resources/skills/userinterface-wiki/rules/ux-millers-chunking.md +0 -23
- package/dist/resources/skills/userinterface-wiki/rules/ux-pareto-prioritize-features.md +0 -36
- package/dist/resources/skills/userinterface-wiki/rules/ux-peak-end-finish-strong.md +0 -35
- package/dist/resources/skills/userinterface-wiki/rules/ux-postels-accept-messy-input.md +0 -45
- package/dist/resources/skills/userinterface-wiki/rules/ux-pragnanz-simplify.md +0 -33
- package/dist/resources/skills/userinterface-wiki/rules/ux-progressive-disclosure.md +0 -41
- package/dist/resources/skills/userinterface-wiki/rules/ux-proximity-grouping.md +0 -38
- package/dist/resources/skills/userinterface-wiki/rules/ux-serial-position.md +0 -31
- package/dist/resources/skills/userinterface-wiki/rules/ux-similarity-consistency.md +0 -35
- package/dist/resources/skills/userinterface-wiki/rules/ux-teslers-complexity.md +0 -28
- package/dist/resources/skills/userinterface-wiki/rules/ux-uniform-connectedness.md +0 -43
- package/dist/resources/skills/userinterface-wiki/rules/ux-von-restorff-emphasis.md +0 -29
- package/dist/resources/skills/userinterface-wiki/rules/ux-zeigarnik-show-incomplete.md +0 -36
- package/dist/resources/skills/userinterface-wiki/rules/visual-animate-shadow-pseudo.md +0 -49
- package/dist/resources/skills/userinterface-wiki/rules/visual-border-alpha-colors.md +0 -25
- package/dist/resources/skills/userinterface-wiki/rules/visual-button-shadow-anatomy.md +0 -49
- package/dist/resources/skills/userinterface-wiki/rules/visual-concentric-radius.md +0 -40
- package/dist/resources/skills/userinterface-wiki/rules/visual-consistent-spacing-scale.md +0 -35
- package/dist/resources/skills/userinterface-wiki/rules/visual-layered-shadows.md +0 -30
- package/dist/resources/skills/userinterface-wiki/rules/visual-no-pure-black-shadow.md +0 -25
- package/dist/resources/skills/userinterface-wiki/rules/visual-shadow-direction.md +0 -25
- package/dist/resources/skills/userinterface-wiki/rules/visual-shadow-matches-elevation.md +0 -23
- package/dist/resources/skills/userinterface-wiki/rules/weight-duration-matches-action.md +0 -29
- package/dist/resources/skills/userinterface-wiki/rules/weight-match-action.md +0 -32
- package/dist/resources/skills/web-design-guidelines/SKILL.md +0 -39
- package/dist/resources/skills/web-quality-audit/SKILL.md +0 -168
- package/dist/resources/skills/web-quality-audit/scripts/analyze.sh +0 -91
- package/src/resources/agents/javascript-pro.md +0 -280
- package/src/resources/agents/researcher.md +0 -29
- package/src/resources/agents/teams-builder.md +0 -74
- package/src/resources/agents/teams-reviewer.md +0 -113
- package/src/resources/agents/typescript-pro.md +0 -255
- package/src/resources/skills/accessibility/SKILL.md +0 -522
- package/src/resources/skills/accessibility/references/WCAG.md +0 -162
- package/src/resources/skills/core-web-vitals/SKILL.md +0 -441
- package/src/resources/skills/core-web-vitals/references/LCP.md +0 -208
- package/src/resources/skills/frontend-design/SKILL.md +0 -45
- package/src/resources/skills/make-interfaces-feel-better/SKILL.md +0 -122
- package/src/resources/skills/make-interfaces-feel-better/animations.md +0 -379
- package/src/resources/skills/make-interfaces-feel-better/performance.md +0 -88
- package/src/resources/skills/make-interfaces-feel-better/surfaces.md +0 -247
- package/src/resources/skills/make-interfaces-feel-better/typography.md +0 -123
- package/src/resources/skills/react-best-practices/README.md +0 -123
- package/src/resources/skills/react-best-practices/SKILL.md +0 -136
- package/src/resources/skills/react-best-practices/metadata.json +0 -15
- package/src/resources/skills/react-best-practices/rules/_sections.md +0 -46
- package/src/resources/skills/react-best-practices/rules/_template.md +0 -28
- package/src/resources/skills/react-best-practices/rules/advanced-event-handler-refs.md +0 -55
- package/src/resources/skills/react-best-practices/rules/advanced-init-once.md +0 -42
- package/src/resources/skills/react-best-practices/rules/advanced-use-latest.md +0 -39
- package/src/resources/skills/react-best-practices/rules/async-api-routes.md +0 -38
- package/src/resources/skills/react-best-practices/rules/async-defer-await.md +0 -80
- package/src/resources/skills/react-best-practices/rules/async-dependencies.md +0 -51
- package/src/resources/skills/react-best-practices/rules/async-parallel.md +0 -28
- package/src/resources/skills/react-best-practices/rules/async-suspense-boundaries.md +0 -99
- package/src/resources/skills/react-best-practices/rules/bundle-barrel-imports.md +0 -59
- package/src/resources/skills/react-best-practices/rules/bundle-conditional.md +0 -31
- package/src/resources/skills/react-best-practices/rules/bundle-defer-third-party.md +0 -49
- package/src/resources/skills/react-best-practices/rules/bundle-dynamic-imports.md +0 -35
- package/src/resources/skills/react-best-practices/rules/bundle-preload.md +0 -50
- package/src/resources/skills/react-best-practices/rules/client-event-listeners.md +0 -74
- package/src/resources/skills/react-best-practices/rules/client-localstorage-schema.md +0 -71
- package/src/resources/skills/react-best-practices/rules/client-passive-event-listeners.md +0 -48
- package/src/resources/skills/react-best-practices/rules/client-swr-dedup.md +0 -56
- package/src/resources/skills/react-best-practices/rules/js-batch-dom-css.md +0 -107
- package/src/resources/skills/react-best-practices/rules/js-cache-function-results.md +0 -80
- package/src/resources/skills/react-best-practices/rules/js-cache-property-access.md +0 -28
- package/src/resources/skills/react-best-practices/rules/js-cache-storage.md +0 -70
- package/src/resources/skills/react-best-practices/rules/js-combine-iterations.md +0 -32
- package/src/resources/skills/react-best-practices/rules/js-early-exit.md +0 -50
- package/src/resources/skills/react-best-practices/rules/js-hoist-regexp.md +0 -45
- package/src/resources/skills/react-best-practices/rules/js-index-maps.md +0 -37
- package/src/resources/skills/react-best-practices/rules/js-length-check-first.md +0 -49
- package/src/resources/skills/react-best-practices/rules/js-min-max-loop.md +0 -82
- package/src/resources/skills/react-best-practices/rules/js-set-map-lookups.md +0 -24
- package/src/resources/skills/react-best-practices/rules/js-tosorted-immutable.md +0 -57
- package/src/resources/skills/react-best-practices/rules/rendering-activity.md +0 -26
- package/src/resources/skills/react-best-practices/rules/rendering-animate-svg-wrapper.md +0 -47
- package/src/resources/skills/react-best-practices/rules/rendering-conditional-render.md +0 -40
- package/src/resources/skills/react-best-practices/rules/rendering-content-visibility.md +0 -38
- package/src/resources/skills/react-best-practices/rules/rendering-hoist-jsx.md +0 -46
- package/src/resources/skills/react-best-practices/rules/rendering-hydration-no-flicker.md +0 -82
- package/src/resources/skills/react-best-practices/rules/rendering-hydration-suppress-warning.md +0 -30
- package/src/resources/skills/react-best-practices/rules/rendering-svg-precision.md +0 -28
- package/src/resources/skills/react-best-practices/rules/rendering-usetransition-loading.md +0 -75
- package/src/resources/skills/react-best-practices/rules/rerender-defer-reads.md +0 -39
- package/src/resources/skills/react-best-practices/rules/rerender-dependencies.md +0 -45
- package/src/resources/skills/react-best-practices/rules/rerender-derived-state-no-effect.md +0 -40
- package/src/resources/skills/react-best-practices/rules/rerender-derived-state.md +0 -29
- package/src/resources/skills/react-best-practices/rules/rerender-functional-setstate.md +0 -74
- package/src/resources/skills/react-best-practices/rules/rerender-lazy-state-init.md +0 -58
- package/src/resources/skills/react-best-practices/rules/rerender-memo-with-default-value.md +0 -38
- package/src/resources/skills/react-best-practices/rules/rerender-memo.md +0 -44
- package/src/resources/skills/react-best-practices/rules/rerender-move-effect-to-event.md +0 -45
- package/src/resources/skills/react-best-practices/rules/rerender-simple-expression-in-memo.md +0 -35
- package/src/resources/skills/react-best-practices/rules/rerender-transitions.md +0 -40
- package/src/resources/skills/react-best-practices/rules/rerender-use-ref-transient-values.md +0 -73
- package/src/resources/skills/react-best-practices/rules/server-after-nonblocking.md +0 -73
- package/src/resources/skills/react-best-practices/rules/server-auth-actions.md +0 -96
- package/src/resources/skills/react-best-practices/rules/server-cache-lru.md +0 -41
- package/src/resources/skills/react-best-practices/rules/server-cache-react.md +0 -76
- package/src/resources/skills/react-best-practices/rules/server-dedup-props.md +0 -65
- package/src/resources/skills/react-best-practices/rules/server-parallel-fetching.md +0 -83
- package/src/resources/skills/react-best-practices/rules/server-serialization.md +0 -38
- package/src/resources/skills/userinterface-wiki/SKILL.md +0 -253
- package/src/resources/skills/userinterface-wiki/rules/_sections.md +0 -66
- package/src/resources/skills/userinterface-wiki/rules/_template.md +0 -24
- package/src/resources/skills/userinterface-wiki/rules/a11y-reduced-motion-check.md +0 -30
- package/src/resources/skills/userinterface-wiki/rules/a11y-toggle-setting.md +0 -30
- package/src/resources/skills/userinterface-wiki/rules/a11y-visual-equivalent.md +0 -36
- package/src/resources/skills/userinterface-wiki/rules/a11y-volume-control.md +0 -28
- package/src/resources/skills/userinterface-wiki/rules/appropriate-confirmations-only.md +0 -19
- package/src/resources/skills/userinterface-wiki/rules/appropriate-errors-warnings.md +0 -18
- package/src/resources/skills/userinterface-wiki/rules/appropriate-no-decorative.md +0 -21
- package/src/resources/skills/userinterface-wiki/rules/appropriate-no-high-frequency.md +0 -28
- package/src/resources/skills/userinterface-wiki/rules/appropriate-no-punishing.md +0 -27
- package/src/resources/skills/userinterface-wiki/rules/container-callback-ref.md +0 -31
- package/src/resources/skills/userinterface-wiki/rules/container-guard-initial-zero.md +0 -25
- package/src/resources/skills/userinterface-wiki/rules/container-no-excessive-use.md +0 -13
- package/src/resources/skills/userinterface-wiki/rules/container-overflow-hidden.md +0 -25
- package/src/resources/skills/userinterface-wiki/rules/container-transition-delay.md +0 -21
- package/src/resources/skills/userinterface-wiki/rules/container-two-div-pattern.md +0 -35
- package/src/resources/skills/userinterface-wiki/rules/container-use-resize-observer.md +0 -48
- package/src/resources/skills/userinterface-wiki/rules/context-cleanup-nodes.md +0 -25
- package/src/resources/skills/userinterface-wiki/rules/context-resume-suspended.md +0 -28
- package/src/resources/skills/userinterface-wiki/rules/context-reuse-single.md +0 -30
- package/src/resources/skills/userinterface-wiki/rules/design-filter-for-character.md +0 -25
- package/src/resources/skills/userinterface-wiki/rules/design-noise-for-percussion.md +0 -26
- package/src/resources/skills/userinterface-wiki/rules/design-oscillator-for-tonal.md +0 -22
- package/src/resources/skills/userinterface-wiki/rules/duration-max-300ms.md +0 -21
- package/src/resources/skills/userinterface-wiki/rules/duration-press-hover.md +0 -21
- package/src/resources/skills/userinterface-wiki/rules/duration-shorten-before-curve.md +0 -21
- package/src/resources/skills/userinterface-wiki/rules/duration-small-state.md +0 -15
- package/src/resources/skills/userinterface-wiki/rules/easing-entrance-ease-out.md +0 -21
- package/src/resources/skills/userinterface-wiki/rules/easing-exit-ease-in.md +0 -21
- package/src/resources/skills/userinterface-wiki/rules/easing-for-state-change.md +0 -27
- package/src/resources/skills/userinterface-wiki/rules/easing-linear-only-progress.md +0 -21
- package/src/resources/skills/userinterface-wiki/rules/easing-natural-decay.md +0 -22
- package/src/resources/skills/userinterface-wiki/rules/easing-no-linear-motion.md +0 -22
- package/src/resources/skills/userinterface-wiki/rules/easing-transition-ease-in-out.md +0 -15
- package/src/resources/skills/userinterface-wiki/rules/envelope-exponential-decay.md +0 -21
- package/src/resources/skills/userinterface-wiki/rules/envelope-no-zero-target.md +0 -21
- package/src/resources/skills/userinterface-wiki/rules/envelope-set-initial-value.md +0 -22
- package/src/resources/skills/userinterface-wiki/rules/exit-key-required.md +0 -29
- package/src/resources/skills/userinterface-wiki/rules/exit-matches-initial.md +0 -29
- package/src/resources/skills/userinterface-wiki/rules/exit-prop-required.md +0 -33
- package/src/resources/skills/userinterface-wiki/rules/exit-requires-wrapper.md +0 -27
- package/src/resources/skills/userinterface-wiki/rules/impl-default-subtle.md +0 -21
- package/src/resources/skills/userinterface-wiki/rules/impl-preload-audio.md +0 -34
- package/src/resources/skills/userinterface-wiki/rules/impl-reset-current-time.md +0 -26
- package/src/resources/skills/userinterface-wiki/rules/mode-pop-layout-for-lists.md +0 -25
- package/src/resources/skills/userinterface-wiki/rules/mode-sync-layout-conflict.md +0 -29
- package/src/resources/skills/userinterface-wiki/rules/mode-wait-doubles-duration.md +0 -25
- package/src/resources/skills/userinterface-wiki/rules/morphing-aria-hidden.md +0 -21
- package/src/resources/skills/userinterface-wiki/rules/morphing-consistent-viewbox.md +0 -23
- package/src/resources/skills/userinterface-wiki/rules/morphing-group-variants.md +0 -33
- package/src/resources/skills/userinterface-wiki/rules/morphing-jump-non-grouped.md +0 -29
- package/src/resources/skills/userinterface-wiki/rules/morphing-reduced-motion.md +0 -28
- package/src/resources/skills/userinterface-wiki/rules/morphing-spring-rotation.md +0 -23
- package/src/resources/skills/userinterface-wiki/rules/morphing-strokelinecap-round.md +0 -21
- package/src/resources/skills/userinterface-wiki/rules/morphing-three-lines.md +0 -32
- package/src/resources/skills/userinterface-wiki/rules/morphing-use-collapsed.md +0 -33
- package/src/resources/skills/userinterface-wiki/rules/native-backdrop-styling.md +0 -27
- package/src/resources/skills/userinterface-wiki/rules/native-placeholder-styling.md +0 -27
- package/src/resources/skills/userinterface-wiki/rules/native-selection-styling.md +0 -18
- package/src/resources/skills/userinterface-wiki/rules/nested-consistent-timing.md +0 -25
- package/src/resources/skills/userinterface-wiki/rules/nested-propagate-required.md +0 -41
- package/src/resources/skills/userinterface-wiki/rules/none-context-menu-entrance.md +0 -25
- package/src/resources/skills/userinterface-wiki/rules/none-high-frequency.md +0 -29
- package/src/resources/skills/userinterface-wiki/rules/none-keyboard-navigation.md +0 -32
- package/src/resources/skills/userinterface-wiki/rules/param-click-duration.md +0 -21
- package/src/resources/skills/userinterface-wiki/rules/param-filter-frequency-range.md +0 -21
- package/src/resources/skills/userinterface-wiki/rules/param-q-value-range.md +0 -21
- package/src/resources/skills/userinterface-wiki/rules/param-reasonable-gain.md +0 -21
- package/src/resources/skills/userinterface-wiki/rules/physics-active-state.md +0 -23
- package/src/resources/skills/userinterface-wiki/rules/physics-no-excessive-stagger.md +0 -22
- package/src/resources/skills/userinterface-wiki/rules/physics-spring-for-overshoot.md +0 -23
- package/src/resources/skills/userinterface-wiki/rules/physics-subtle-deformation.md +0 -22
- package/src/resources/skills/userinterface-wiki/rules/prefetch-hit-slop.md +0 -27
- package/src/resources/skills/userinterface-wiki/rules/prefetch-keyboard-tab.md +0 -19
- package/src/resources/skills/userinterface-wiki/rules/prefetch-not-everything.md +0 -22
- package/src/resources/skills/userinterface-wiki/rules/prefetch-touch-fallback.md +0 -34
- package/src/resources/skills/userinterface-wiki/rules/prefetch-trajectory-over-hover.md +0 -32
- package/src/resources/skills/userinterface-wiki/rules/prefetch-use-selectively.md +0 -13
- package/src/resources/skills/userinterface-wiki/rules/presence-disable-interactions.md +0 -31
- package/src/resources/skills/userinterface-wiki/rules/presence-hook-in-child.md +0 -31
- package/src/resources/skills/userinterface-wiki/rules/presence-safe-to-remove.md +0 -37
- package/src/resources/skills/userinterface-wiki/rules/pseudo-content-required.md +0 -28
- package/src/resources/skills/userinterface-wiki/rules/pseudo-first-line-styling.md +0 -27
- package/src/resources/skills/userinterface-wiki/rules/pseudo-hit-target-expansion.md +0 -31
- package/src/resources/skills/userinterface-wiki/rules/pseudo-marker-styling.md +0 -28
- package/src/resources/skills/userinterface-wiki/rules/pseudo-over-dom-node.md +0 -32
- package/src/resources/skills/userinterface-wiki/rules/pseudo-position-relative-parent.md +0 -33
- package/src/resources/skills/userinterface-wiki/rules/pseudo-z-index-layering.md +0 -37
- package/src/resources/skills/userinterface-wiki/rules/spring-for-gestures.md +0 -27
- package/src/resources/skills/userinterface-wiki/rules/spring-for-interruptible.md +0 -27
- package/src/resources/skills/userinterface-wiki/rules/spring-params-balanced.md +0 -29
- package/src/resources/skills/userinterface-wiki/rules/spring-preserves-velocity.md +0 -28
- package/src/resources/skills/userinterface-wiki/rules/staging-dim-background.md +0 -22
- package/src/resources/skills/userinterface-wiki/rules/staging-one-focal-point.md +0 -24
- package/src/resources/skills/userinterface-wiki/rules/staging-z-index-hierarchy.md +0 -22
- package/src/resources/skills/userinterface-wiki/rules/timing-consistent.md +0 -24
- package/src/resources/skills/userinterface-wiki/rules/timing-no-entrance-context-menu.md +0 -22
- package/src/resources/skills/userinterface-wiki/rules/timing-under-300ms.md +0 -22
- package/src/resources/skills/userinterface-wiki/rules/transition-name-cleanup.md +0 -28
- package/src/resources/skills/userinterface-wiki/rules/transition-name-required.md +0 -27
- package/src/resources/skills/userinterface-wiki/rules/transition-name-unique.md +0 -24
- package/src/resources/skills/userinterface-wiki/rules/transition-over-js-library.md +0 -32
- package/src/resources/skills/userinterface-wiki/rules/transition-style-pseudo-elements.md +0 -24
- package/src/resources/skills/userinterface-wiki/rules/type-antialiased-on-retina.md +0 -18
- package/src/resources/skills/userinterface-wiki/rules/type-disambiguation-stylistic-set.md +0 -15
- package/src/resources/skills/userinterface-wiki/rules/type-font-display-swap.md +0 -28
- package/src/resources/skills/userinterface-wiki/rules/type-justify-with-hyphens.md +0 -24
- package/src/resources/skills/userinterface-wiki/rules/type-letter-spacing-uppercase.md +0 -28
- package/src/resources/skills/userinterface-wiki/rules/type-no-font-synthesis.md +0 -18
- package/src/resources/skills/userinterface-wiki/rules/type-oldstyle-nums-for-prose.md +0 -21
- package/src/resources/skills/userinterface-wiki/rules/type-opentype-contextual-alternates.md +0 -15
- package/src/resources/skills/userinterface-wiki/rules/type-optical-sizing-auto.md +0 -25
- package/src/resources/skills/userinterface-wiki/rules/type-proper-fractions.md +0 -15
- package/src/resources/skills/userinterface-wiki/rules/type-slashed-zero.md +0 -17
- package/src/resources/skills/userinterface-wiki/rules/type-tabular-nums-for-data.md +0 -21
- package/src/resources/skills/userinterface-wiki/rules/type-text-wrap-balance-headings.md +0 -21
- package/src/resources/skills/userinterface-wiki/rules/type-text-wrap-pretty.md +0 -16
- package/src/resources/skills/userinterface-wiki/rules/type-underline-offset.md +0 -25
- package/src/resources/skills/userinterface-wiki/rules/type-variable-weight-continuous.md +0 -23
- package/src/resources/skills/userinterface-wiki/rules/ux-aesthetic-usability.md +0 -32
- package/src/resources/skills/userinterface-wiki/rules/ux-cognitive-load-reduce.md +0 -49
- package/src/resources/skills/userinterface-wiki/rules/ux-common-region-boundaries.md +0 -50
- package/src/resources/skills/userinterface-wiki/rules/ux-doherty-perceived-speed.md +0 -29
- package/src/resources/skills/userinterface-wiki/rules/ux-doherty-under-400ms.md +0 -30
- package/src/resources/skills/userinterface-wiki/rules/ux-fitts-hit-area.md +0 -32
- package/src/resources/skills/userinterface-wiki/rules/ux-fitts-target-size.md +0 -31
- package/src/resources/skills/userinterface-wiki/rules/ux-goal-gradient-progress.md +0 -33
- package/src/resources/skills/userinterface-wiki/rules/ux-hicks-minimize-choices.md +0 -45
- package/src/resources/skills/userinterface-wiki/rules/ux-jakobs-familiar-patterns.md +0 -37
- package/src/resources/skills/userinterface-wiki/rules/ux-millers-chunking.md +0 -23
- package/src/resources/skills/userinterface-wiki/rules/ux-pareto-prioritize-features.md +0 -36
- package/src/resources/skills/userinterface-wiki/rules/ux-peak-end-finish-strong.md +0 -35
- package/src/resources/skills/userinterface-wiki/rules/ux-postels-accept-messy-input.md +0 -45
- package/src/resources/skills/userinterface-wiki/rules/ux-pragnanz-simplify.md +0 -33
- package/src/resources/skills/userinterface-wiki/rules/ux-progressive-disclosure.md +0 -41
- package/src/resources/skills/userinterface-wiki/rules/ux-proximity-grouping.md +0 -38
- package/src/resources/skills/userinterface-wiki/rules/ux-serial-position.md +0 -31
- package/src/resources/skills/userinterface-wiki/rules/ux-similarity-consistency.md +0 -35
- package/src/resources/skills/userinterface-wiki/rules/ux-teslers-complexity.md +0 -28
- package/src/resources/skills/userinterface-wiki/rules/ux-uniform-connectedness.md +0 -43
- package/src/resources/skills/userinterface-wiki/rules/ux-von-restorff-emphasis.md +0 -29
- package/src/resources/skills/userinterface-wiki/rules/ux-zeigarnik-show-incomplete.md +0 -36
- package/src/resources/skills/userinterface-wiki/rules/visual-animate-shadow-pseudo.md +0 -49
- package/src/resources/skills/userinterface-wiki/rules/visual-border-alpha-colors.md +0 -25
- package/src/resources/skills/userinterface-wiki/rules/visual-button-shadow-anatomy.md +0 -49
- package/src/resources/skills/userinterface-wiki/rules/visual-concentric-radius.md +0 -40
- package/src/resources/skills/userinterface-wiki/rules/visual-consistent-spacing-scale.md +0 -35
- package/src/resources/skills/userinterface-wiki/rules/visual-layered-shadows.md +0 -30
- package/src/resources/skills/userinterface-wiki/rules/visual-no-pure-black-shadow.md +0 -25
- package/src/resources/skills/userinterface-wiki/rules/visual-shadow-direction.md +0 -25
- package/src/resources/skills/userinterface-wiki/rules/visual-shadow-matches-elevation.md +0 -23
- package/src/resources/skills/userinterface-wiki/rules/weight-duration-matches-action.md +0 -29
- package/src/resources/skills/userinterface-wiki/rules/weight-match-action.md +0 -32
- package/src/resources/skills/web-design-guidelines/SKILL.md +0 -39
- package/src/resources/skills/web-quality-audit/SKILL.md +0 -168
- package/src/resources/skills/web-quality-audit/scripts/analyze.sh +0 -91
|
@@ -1,122 +0,0 @@
|
|
|
1
|
-
---
|
|
2
|
-
name: make-interfaces-feel-better
|
|
3
|
-
description: Design engineering principles for making interfaces feel polished. Use when building UI components, reviewing frontend code, implementing animations, hover states, shadows, borders, typography, micro-interactions, enter/exit animations, or any visual detail work. Triggers on UI polish, design details, "make it feel better", "feels off", stagger animations, border radius, optical alignment, font smoothing, tabular numbers, image outlines, box shadows.
|
|
4
|
-
---
|
|
5
|
-
|
|
6
|
-
# Details that make interfaces feel better
|
|
7
|
-
|
|
8
|
-
Great interfaces rarely come from a single thing. It's usually a collection of small details that compound into a great experience. Apply these principles when building or reviewing UI code.
|
|
9
|
-
|
|
10
|
-
## Quick Reference
|
|
11
|
-
|
|
12
|
-
| Category | When to Use |
|
|
13
|
-
| --- | --- |
|
|
14
|
-
| [Typography](typography.md) | Text wrapping, font smoothing, tabular numbers |
|
|
15
|
-
| [Surfaces](surfaces.md) | Border radius, optical alignment, shadows, image outlines, hit areas |
|
|
16
|
-
| [Animations](animations.md) | Interruptible animations, enter/exit transitions, icon animations, scale on press |
|
|
17
|
-
| [Performance](performance.md) | Transition specificity, `will-change` usage |
|
|
18
|
-
|
|
19
|
-
## Core Principles
|
|
20
|
-
|
|
21
|
-
### 1. Concentric Border Radius
|
|
22
|
-
|
|
23
|
-
Outer radius = inner radius + padding. Mismatched radii on nested elements is the most common thing that makes interfaces feel off.
|
|
24
|
-
|
|
25
|
-
### 2. Optical Over Geometric Alignment
|
|
26
|
-
|
|
27
|
-
When geometric centering looks off, align optically. Buttons with icons, play triangles, and asymmetric icons all need manual adjustment.
|
|
28
|
-
|
|
29
|
-
### 3. Shadows Over Borders
|
|
30
|
-
|
|
31
|
-
Layer multiple transparent `box-shadow` values for natural depth. Shadows adapt to any background; solid borders don't.
|
|
32
|
-
|
|
33
|
-
### 4. Interruptible Animations
|
|
34
|
-
|
|
35
|
-
Use CSS transitions for interactive state changes — they can be interrupted mid-animation. Reserve keyframes for staged sequences that run once.
|
|
36
|
-
|
|
37
|
-
### 5. Split and Stagger Enter Animations
|
|
38
|
-
|
|
39
|
-
Don't animate a single container. Break content into semantic chunks and stagger each with ~100ms delay.
|
|
40
|
-
|
|
41
|
-
### 6. Subtle Exit Animations
|
|
42
|
-
|
|
43
|
-
Use a small fixed `translateY` instead of full height. Exits should be softer than enters.
|
|
44
|
-
|
|
45
|
-
### 7. Contextual Icon Animations
|
|
46
|
-
|
|
47
|
-
Animate icons with `opacity`, `scale`, and `blur` instead of toggling visibility. Use exactly these values: scale from `0.25` to `1`, opacity from `0` to `1`, blur from `4px` to `0px`. If the project has `motion` or `framer-motion` in `package.json`, use `transition: { type: "spring", duration: 0.3, bounce: 0 }` — bounce must always be `0`. If no motion library is installed, keep both icons in the DOM (one absolute-positioned) and cross-fade with CSS transitions using `cubic-bezier(0.2, 0, 0, 1)` — this gives both enter and exit animations without any dependency.
|
|
48
|
-
|
|
49
|
-
### 8. Font Smoothing
|
|
50
|
-
|
|
51
|
-
Apply `-webkit-font-smoothing: antialiased` to the root layout on macOS for crisper text.
|
|
52
|
-
|
|
53
|
-
### 9. Tabular Numbers
|
|
54
|
-
|
|
55
|
-
Use `font-variant-numeric: tabular-nums` for any dynamically updating numbers to prevent layout shift.
|
|
56
|
-
|
|
57
|
-
### 10. Text Wrapping
|
|
58
|
-
|
|
59
|
-
Use `text-wrap: balance` on headings. Use `text-wrap: pretty` for body text to avoid orphans.
|
|
60
|
-
|
|
61
|
-
### 11. Image Outlines
|
|
62
|
-
|
|
63
|
-
Add a subtle `1px` outline with low opacity to images for consistent depth.
|
|
64
|
-
|
|
65
|
-
### 12. Scale on Press
|
|
66
|
-
|
|
67
|
-
A subtle `scale(0.96)` on click gives buttons tactile feedback. Always use `0.96`. Never use a value smaller than `0.95` — anything below feels exaggerated. Add a `static` prop to disable it when motion would be distracting.
|
|
68
|
-
|
|
69
|
-
### 13. Skip Animation on Page Load
|
|
70
|
-
|
|
71
|
-
Use `initial={false}` on `AnimatePresence` to prevent enter animations on first render. Verify it doesn't break intentional entrance animations.
|
|
72
|
-
|
|
73
|
-
### 14. Never Use `transition: all`
|
|
74
|
-
|
|
75
|
-
Always specify exact properties: `transition-property: scale, opacity`. Tailwind's `transition-transform` covers `transform, translate, scale, rotate`.
|
|
76
|
-
|
|
77
|
-
### 15. Use `will-change` Sparingly
|
|
78
|
-
|
|
79
|
-
Only for `transform`, `opacity`, `filter` — properties the GPU can composite. Never use `will-change: all`. Only add when you notice first-frame stutter.
|
|
80
|
-
|
|
81
|
-
### 16. Minimum Hit Area
|
|
82
|
-
|
|
83
|
-
Interactive elements need at least 40×40px hit area. Extend with a pseudo-element if the visible element is smaller. Never let hit areas of two elements overlap.
|
|
84
|
-
|
|
85
|
-
## Common Mistakes
|
|
86
|
-
|
|
87
|
-
| Mistake | Fix |
|
|
88
|
-
| --- | --- |
|
|
89
|
-
| Same border radius on parent and child | Calculate `outerRadius = innerRadius + padding` |
|
|
90
|
-
| Icons look off-center | Adjust optically with padding or fix SVG directly |
|
|
91
|
-
| Hard borders between sections | Use layered `box-shadow` with transparency |
|
|
92
|
-
| Jarring enter/exit animations | Split, stagger, and keep exits subtle |
|
|
93
|
-
| Numbers cause layout shift | Apply `tabular-nums` |
|
|
94
|
-
| Heavy text on macOS | Apply `antialiased` to root |
|
|
95
|
-
| Animation plays on page load | Add `initial={false}` to `AnimatePresence` |
|
|
96
|
-
| `transition: all` on elements | Specify exact properties |
|
|
97
|
-
| First-frame animation stutter | Add `will-change: transform` (sparingly) |
|
|
98
|
-
| Tiny hit areas on small controls | Extend with pseudo-element to 40×40px |
|
|
99
|
-
|
|
100
|
-
## Review Checklist
|
|
101
|
-
|
|
102
|
-
- [ ] Nested rounded elements use concentric border radius
|
|
103
|
-
- [ ] Icons are optically centered, not just geometrically
|
|
104
|
-
- [ ] Shadows used instead of borders where appropriate
|
|
105
|
-
- [ ] Enter animations are split and staggered
|
|
106
|
-
- [ ] Exit animations are subtle
|
|
107
|
-
- [ ] Dynamic numbers use tabular-nums
|
|
108
|
-
- [ ] Font smoothing is applied
|
|
109
|
-
- [ ] Headings use text-wrap: balance
|
|
110
|
-
- [ ] Images have subtle outlines
|
|
111
|
-
- [ ] Buttons use scale on press where appropriate
|
|
112
|
-
- [ ] AnimatePresence uses `initial={false}` for default-state elements
|
|
113
|
-
- [ ] No `transition: all` — only specific properties
|
|
114
|
-
- [ ] `will-change` only on transform/opacity/filter, never `all`
|
|
115
|
-
- [ ] Interactive elements have at least 40×40px hit area
|
|
116
|
-
|
|
117
|
-
## Reference Files
|
|
118
|
-
|
|
119
|
-
- [typography.md](typography.md) — Text wrapping, font smoothing, tabular numbers
|
|
120
|
-
- [surfaces.md](surfaces.md) — Border radius, optical alignment, shadows, image outlines
|
|
121
|
-
- [animations.md](animations.md) — Interruptible animations, enter/exit transitions, icon animations, scale on press
|
|
122
|
-
- [performance.md](performance.md) — Transition specificity, `will-change` usage
|
|
@@ -1,379 +0,0 @@
|
|
|
1
|
-
# Animations
|
|
2
|
-
|
|
3
|
-
Interruptible animations, enter/exit transitions, and contextual icon animations.
|
|
4
|
-
|
|
5
|
-
## Interruptible Animations
|
|
6
|
-
|
|
7
|
-
Users change intent mid-interaction. If animations aren't interruptible, the interface feels broken.
|
|
8
|
-
|
|
9
|
-
### CSS Transitions vs. Keyframes
|
|
10
|
-
|
|
11
|
-
| | CSS Transitions | CSS Keyframe Animations |
|
|
12
|
-
| --- | --- | --- |
|
|
13
|
-
| **Behavior** | Interpolate toward latest state | Run on a fixed timeline |
|
|
14
|
-
| **Interruptible** | Yes — retargets mid-animation | No — restarts from beginning |
|
|
15
|
-
| **Use for** | Interactive state changes (hover, toggle, open/close) | Staged sequences that run once (enter animations, loading) |
|
|
16
|
-
| **Duration** | Adapts to remaining distance | Fixed regardless of state |
|
|
17
|
-
|
|
18
|
-
```css
|
|
19
|
-
/* Good — interruptible transition for a toggle */
|
|
20
|
-
.drawer {
|
|
21
|
-
transform: translateX(-100%);
|
|
22
|
-
transition: transform 200ms ease-out;
|
|
23
|
-
}
|
|
24
|
-
.drawer.open {
|
|
25
|
-
transform: translateX(0);
|
|
26
|
-
}
|
|
27
|
-
|
|
28
|
-
/* Clicking again mid-animation smoothly reverses — no jank */
|
|
29
|
-
```
|
|
30
|
-
|
|
31
|
-
```css
|
|
32
|
-
/* Bad — keyframe animation for interactive element */
|
|
33
|
-
.drawer.open {
|
|
34
|
-
animation: slideIn 200ms ease-out forwards;
|
|
35
|
-
}
|
|
36
|
-
|
|
37
|
-
/* Closing mid-animation snaps or restarts — feels broken */
|
|
38
|
-
```
|
|
39
|
-
|
|
40
|
-
**Rule:** Always prefer CSS transitions for interactive elements. Reserve keyframes for one-shot sequences.
|
|
41
|
-
|
|
42
|
-
## Enter Animations: Split and Stagger
|
|
43
|
-
|
|
44
|
-
Don't animate a single large container. Break content into semantic chunks and animate each individually.
|
|
45
|
-
|
|
46
|
-
### Step by Step
|
|
47
|
-
|
|
48
|
-
1. **Split** into logical groups (title, description, buttons)
|
|
49
|
-
2. **Stagger** with ~100ms delay between groups
|
|
50
|
-
3. **For titles**, consider splitting into individual words with ~80ms stagger
|
|
51
|
-
4. **Combine** `opacity`, `blur`, and `translateY` for the enter effect
|
|
52
|
-
|
|
53
|
-
### Code Example
|
|
54
|
-
|
|
55
|
-
```tsx
|
|
56
|
-
// Motion (Framer Motion) — staggered enter
|
|
57
|
-
function PageHeader() {
|
|
58
|
-
return (
|
|
59
|
-
<motion.div
|
|
60
|
-
initial="hidden"
|
|
61
|
-
animate="visible"
|
|
62
|
-
variants={{
|
|
63
|
-
visible: { transition: { staggerChildren: 0.1 } },
|
|
64
|
-
}}
|
|
65
|
-
>
|
|
66
|
-
<motion.h1
|
|
67
|
-
variants={{
|
|
68
|
-
hidden: { opacity: 0, y: 12, filter: "blur(4px)" },
|
|
69
|
-
visible: { opacity: 1, y: 0, filter: "blur(0px)" },
|
|
70
|
-
}}
|
|
71
|
-
>
|
|
72
|
-
Welcome
|
|
73
|
-
</motion.h1>
|
|
74
|
-
|
|
75
|
-
<motion.p
|
|
76
|
-
variants={{
|
|
77
|
-
hidden: { opacity: 0, y: 12, filter: "blur(4px)" },
|
|
78
|
-
visible: { opacity: 1, y: 0, filter: "blur(0px)" },
|
|
79
|
-
}}
|
|
80
|
-
>
|
|
81
|
-
A description of the page.
|
|
82
|
-
</motion.p>
|
|
83
|
-
|
|
84
|
-
<motion.div
|
|
85
|
-
variants={{
|
|
86
|
-
hidden: { opacity: 0, y: 12, filter: "blur(4px)" },
|
|
87
|
-
visible: { opacity: 1, y: 0, filter: "blur(0px)" },
|
|
88
|
-
}}
|
|
89
|
-
>
|
|
90
|
-
<Button>Get started</Button>
|
|
91
|
-
</motion.div>
|
|
92
|
-
</motion.div>
|
|
93
|
-
);
|
|
94
|
-
}
|
|
95
|
-
```
|
|
96
|
-
|
|
97
|
-
### CSS-Only Stagger
|
|
98
|
-
|
|
99
|
-
```css
|
|
100
|
-
.stagger-item {
|
|
101
|
-
opacity: 0;
|
|
102
|
-
transform: translateY(12px);
|
|
103
|
-
filter: blur(4px);
|
|
104
|
-
animation: fadeInUp 400ms ease-out forwards;
|
|
105
|
-
}
|
|
106
|
-
|
|
107
|
-
.stagger-item:nth-child(1) { animation-delay: 0ms; }
|
|
108
|
-
.stagger-item:nth-child(2) { animation-delay: 100ms; }
|
|
109
|
-
.stagger-item:nth-child(3) { animation-delay: 200ms; }
|
|
110
|
-
|
|
111
|
-
@keyframes fadeInUp {
|
|
112
|
-
to {
|
|
113
|
-
opacity: 1;
|
|
114
|
-
transform: translateY(0);
|
|
115
|
-
filter: blur(0);
|
|
116
|
-
}
|
|
117
|
-
}
|
|
118
|
-
```
|
|
119
|
-
|
|
120
|
-
## Exit Animations
|
|
121
|
-
|
|
122
|
-
Exit animations should be softer and less attention-grabbing than enter animations. The user's focus is moving to the next thing — don't fight for attention.
|
|
123
|
-
|
|
124
|
-
### Subtle Exit (Recommended)
|
|
125
|
-
|
|
126
|
-
```tsx
|
|
127
|
-
// Small fixed translateY — indicates direction without drama
|
|
128
|
-
<motion.div
|
|
129
|
-
exit={{
|
|
130
|
-
opacity: 0,
|
|
131
|
-
y: -12,
|
|
132
|
-
filter: "blur(4px)",
|
|
133
|
-
transition: { duration: 0.15, ease: "easeIn" },
|
|
134
|
-
}}
|
|
135
|
-
>
|
|
136
|
-
{content}
|
|
137
|
-
</motion.div>
|
|
138
|
-
```
|
|
139
|
-
|
|
140
|
-
### Full Exit (When Context Matters)
|
|
141
|
-
|
|
142
|
-
```tsx
|
|
143
|
-
// Slide fully out — use when spatial context is important
|
|
144
|
-
// (e.g., a card returning to a list, a drawer closing)
|
|
145
|
-
<motion.div
|
|
146
|
-
exit={{
|
|
147
|
-
opacity: 0,
|
|
148
|
-
x: "-100%",
|
|
149
|
-
transition: { duration: 0.2, ease: "easeIn" },
|
|
150
|
-
}}
|
|
151
|
-
>
|
|
152
|
-
{content}
|
|
153
|
-
</motion.div>
|
|
154
|
-
```
|
|
155
|
-
|
|
156
|
-
### Good vs. Bad
|
|
157
|
-
|
|
158
|
-
```css
|
|
159
|
-
/* Good — subtle exit */
|
|
160
|
-
.item-exit {
|
|
161
|
-
opacity: 0;
|
|
162
|
-
transform: translateY(-12px);
|
|
163
|
-
transition: opacity 150ms ease-in, transform 150ms ease-in;
|
|
164
|
-
}
|
|
165
|
-
|
|
166
|
-
/* Bad — dramatic exit that steals focus */
|
|
167
|
-
.item-exit {
|
|
168
|
-
opacity: 0;
|
|
169
|
-
transform: translateY(-100%) scale(0.5);
|
|
170
|
-
transition: all 400ms ease-in;
|
|
171
|
-
}
|
|
172
|
-
|
|
173
|
-
/* Bad — no exit animation at all (element just vanishes) */
|
|
174
|
-
.item-exit {
|
|
175
|
-
display: none;
|
|
176
|
-
}
|
|
177
|
-
```
|
|
178
|
-
|
|
179
|
-
**Key points:**
|
|
180
|
-
- Use a small fixed `translateY` (e.g., `-12px`) instead of the full container height
|
|
181
|
-
- Keep some directional movement to indicate where the element went
|
|
182
|
-
- Exit duration should be shorter than enter duration (150ms vs 300ms)
|
|
183
|
-
- Don't remove exit animations entirely — subtle motion preserves context
|
|
184
|
-
|
|
185
|
-
## Contextual Icon Animations
|
|
186
|
-
|
|
187
|
-
When icons appear or disappear contextually (on hover, on state change), animate them with `opacity`, `scale`, and `blur` rather than just toggling visibility.
|
|
188
|
-
|
|
189
|
-
### Motion Example
|
|
190
|
-
|
|
191
|
-
```tsx
|
|
192
|
-
import { AnimatePresence, motion } from "motion/react";
|
|
193
|
-
|
|
194
|
-
function IconButton({ isActive, icon: Icon }) {
|
|
195
|
-
return (
|
|
196
|
-
<button>
|
|
197
|
-
<AnimatePresence mode="popLayout">
|
|
198
|
-
<motion.span
|
|
199
|
-
key={isActive ? "active" : "inactive"}
|
|
200
|
-
initial={{ opacity: 0, scale: 0.25, filter: "blur(4px)" }}
|
|
201
|
-
animate={{ opacity: 1, scale: 1, filter: "blur(0px)" }}
|
|
202
|
-
exit={{ opacity: 0, scale: 0.25, filter: "blur(4px)" }}
|
|
203
|
-
transition={{ type: "spring", duration: 0.3, bounce: 0 }}
|
|
204
|
-
>
|
|
205
|
-
<Icon />
|
|
206
|
-
</motion.span>
|
|
207
|
-
</AnimatePresence>
|
|
208
|
-
</button>
|
|
209
|
-
);
|
|
210
|
-
}
|
|
211
|
-
```
|
|
212
|
-
|
|
213
|
-
### CSS Transition Approach (No Motion)
|
|
214
|
-
|
|
215
|
-
If the project doesn't use Motion (Framer Motion), keep both icons in the DOM and cross-fade them with CSS transitions. Because neither icon unmounts, both enter and exit animate smoothly.
|
|
216
|
-
|
|
217
|
-
The trick: one icon is absolutely positioned on top of the other. Toggling state cross-fades them — the entering icon scales up from `0.25` while the exiting icon scales down to `0.25`, both with opacity and blur.
|
|
218
|
-
|
|
219
|
-
```tsx
|
|
220
|
-
function IconButton({ isActive, ActiveIcon, InactiveIcon }) {
|
|
221
|
-
return (
|
|
222
|
-
<button>
|
|
223
|
-
<div className="relative">
|
|
224
|
-
<div
|
|
225
|
-
className={cn(
|
|
226
|
-
"absolute inset-0 flex items-center justify-center",
|
|
227
|
-
"transition-[opacity,filter,scale] duration-300",
|
|
228
|
-
"cubic-bezier(0.2, 0, 0, 1)",
|
|
229
|
-
isActive
|
|
230
|
-
? "scale-100 opacity-100 blur-0"
|
|
231
|
-
: "scale-[0.25] opacity-0 blur-[4px]"
|
|
232
|
-
)}
|
|
233
|
-
>
|
|
234
|
-
<ActiveIcon />
|
|
235
|
-
</div>
|
|
236
|
-
<div
|
|
237
|
-
className={cn(
|
|
238
|
-
"transition-[opacity,filter,scale] duration-300",
|
|
239
|
-
"cubic-bezier(0.2, 0, 0, 1)",
|
|
240
|
-
isActive
|
|
241
|
-
? "scale-[0.25] opacity-0 blur-[4px]"
|
|
242
|
-
: "scale-100 opacity-100 blur-0"
|
|
243
|
-
)}
|
|
244
|
-
>
|
|
245
|
-
<InactiveIcon />
|
|
246
|
-
</div>
|
|
247
|
-
</div>
|
|
248
|
-
</button>
|
|
249
|
-
);
|
|
250
|
-
}
|
|
251
|
-
```
|
|
252
|
-
|
|
253
|
-
The non-absolute icon (InactiveIcon) defines the layout size. The absolute icon (ActiveIcon) overlays it without affecting flow.
|
|
254
|
-
|
|
255
|
-
### Choosing Between Motion and CSS
|
|
256
|
-
|
|
257
|
-
| | Motion (Framer Motion) | CSS transitions (both icons in DOM) |
|
|
258
|
-
| --- | --- | --- |
|
|
259
|
-
| **Enter animation** | Yes | Yes |
|
|
260
|
-
| **Exit animation** | Yes (via `AnimatePresence`) | Yes (cross-fade — icon never unmounts) |
|
|
261
|
-
| **Spring physics** | Yes | No — use `cubic-bezier(0.2, 0, 0, 1)` as approximation |
|
|
262
|
-
| **When to use** | Project already uses `motion/react` | No motion dependency, or keeping bundle small |
|
|
263
|
-
|
|
264
|
-
**Rule:** Check the project's `package.json` for `motion` or `framer-motion`. If present, use the Motion approach. If not, use the CSS cross-fade pattern — don't add a dependency just for icon transitions.
|
|
265
|
-
|
|
266
|
-
### When to Animate Icons
|
|
267
|
-
|
|
268
|
-
| Animate | Don't animate |
|
|
269
|
-
| --- | --- |
|
|
270
|
-
| Icons that appear on hover (action buttons) | Static navigation icons |
|
|
271
|
-
| State change icons (play → pause, like → liked) | Decorative icons |
|
|
272
|
-
| Icons in contextual toolbars | Icons that are always visible |
|
|
273
|
-
| Loading/success state indicators | Icon labels (text next to icon) |
|
|
274
|
-
|
|
275
|
-
**Important:** Always use exactly these values for contextual icon animations — do not deviate:
|
|
276
|
-
- `scale`: `0.25` → `1` (never use `0.5` or `0.6`)
|
|
277
|
-
- `opacity`: `0` → `1`
|
|
278
|
-
- `filter`: `"blur(4px)"` → `"blur(0px)"`
|
|
279
|
-
- `transition`: `{ type: "spring", duration: 0.3, bounce: 0 }` — **bounce must always be `0`**, never `0.1` or any other value
|
|
280
|
-
|
|
281
|
-
## Scale on Press
|
|
282
|
-
|
|
283
|
-
A subtle scale-down on click gives buttons tactile feedback. Always use `scale(0.96)`. Never use a value smaller than `0.95` — anything below feels exaggerated. Use CSS transitions for interruptibility — if the user releases mid-press, it should smoothly return.
|
|
284
|
-
|
|
285
|
-
Not every button needs this. Add a `static` prop to your button component that disables the scale effect when the motion would be distracting.
|
|
286
|
-
|
|
287
|
-
### CSS Example
|
|
288
|
-
|
|
289
|
-
```css
|
|
290
|
-
.button {
|
|
291
|
-
transition-property: scale;
|
|
292
|
-
transition-duration: 150ms;
|
|
293
|
-
transition-timing-function: ease-out;
|
|
294
|
-
}
|
|
295
|
-
|
|
296
|
-
.button:active {
|
|
297
|
-
scale: 0.96;
|
|
298
|
-
}
|
|
299
|
-
```
|
|
300
|
-
|
|
301
|
-
### Tailwind Example
|
|
302
|
-
|
|
303
|
-
```tsx
|
|
304
|
-
<button className="transition-transform duration-150 ease-out active:scale-[0.96]">
|
|
305
|
-
Click me
|
|
306
|
-
</button>
|
|
307
|
-
```
|
|
308
|
-
|
|
309
|
-
### Motion Example
|
|
310
|
-
|
|
311
|
-
```tsx
|
|
312
|
-
<motion.button whileTap={{ scale: 0.96 }}>
|
|
313
|
-
Click me
|
|
314
|
-
</motion.button>
|
|
315
|
-
```
|
|
316
|
-
|
|
317
|
-
### Static Prop Pattern
|
|
318
|
-
|
|
319
|
-
Extract the scale class into a variable and conditionally apply it based on a `static` prop:
|
|
320
|
-
|
|
321
|
-
```tsx
|
|
322
|
-
const tapScale = "active:not-disabled:scale-[0.96]";
|
|
323
|
-
|
|
324
|
-
function Button({ static: isStatic, className, children, ...props }) {
|
|
325
|
-
return (
|
|
326
|
-
<button
|
|
327
|
-
className={cn(
|
|
328
|
-
"transition-transform duration-150 ease-out",
|
|
329
|
-
!isStatic && tapScale,
|
|
330
|
-
className,
|
|
331
|
-
)}
|
|
332
|
-
{...props}
|
|
333
|
-
>
|
|
334
|
-
{children}
|
|
335
|
-
</button>
|
|
336
|
-
);
|
|
337
|
-
}
|
|
338
|
-
|
|
339
|
-
// Usage
|
|
340
|
-
<Button>Click me</Button> {/* scales on press */}
|
|
341
|
-
<Button static>Submit</Button> {/* no scale */}
|
|
342
|
-
```
|
|
343
|
-
|
|
344
|
-
## Skip Animation on Page Load
|
|
345
|
-
|
|
346
|
-
Use `initial={false}` on `AnimatePresence` to prevent enter animations from firing on first render. Elements that are already in their default state shouldn't animate in on page load — only on subsequent state changes.
|
|
347
|
-
|
|
348
|
-
### When It Works
|
|
349
|
-
|
|
350
|
-
```tsx
|
|
351
|
-
// Good — icon doesn't animate in on mount, only on state change
|
|
352
|
-
<AnimatePresence initial={false} mode="popLayout">
|
|
353
|
-
<motion.span
|
|
354
|
-
key={isActive ? "active" : "inactive"}
|
|
355
|
-
initial={{ opacity: 0, scale: 0.25, filter: "blur(4px)" }}
|
|
356
|
-
animate={{ opacity: 1, scale: 1, filter: "blur(0px)" }}
|
|
357
|
-
exit={{ opacity: 0, scale: 0.25, filter: "blur(4px)" }}
|
|
358
|
-
>
|
|
359
|
-
<Icon />
|
|
360
|
-
</motion.span>
|
|
361
|
-
</AnimatePresence>
|
|
362
|
-
```
|
|
363
|
-
|
|
364
|
-
Works well for: icon swaps, toggles, tabs, segmented controls — anything that has a default state on page load.
|
|
365
|
-
|
|
366
|
-
### When It Breaks
|
|
367
|
-
|
|
368
|
-
Don't use `initial={false}` when the component relies on its `initial` prop to set up a first-time enter animation, like a staggered page hero or a loading state. In those cases, removing the initial animation skips the entire entrance.
|
|
369
|
-
|
|
370
|
-
```tsx
|
|
371
|
-
// Bad — initial={false} would skip the staggered page enter entirely
|
|
372
|
-
<AnimatePresence initial={false}>
|
|
373
|
-
<motion.div initial="hidden" animate="visible" variants={...}>
|
|
374
|
-
...
|
|
375
|
-
</motion.div>
|
|
376
|
-
</AnimatePresence>
|
|
377
|
-
```
|
|
378
|
-
|
|
379
|
-
Verify the component still looks right on a full page refresh before applying this.
|
|
@@ -1,88 +0,0 @@
|
|
|
1
|
-
# Performance
|
|
2
|
-
|
|
3
|
-
Transition specificity and GPU compositing hints.
|
|
4
|
-
|
|
5
|
-
## Transition Only What Changes
|
|
6
|
-
|
|
7
|
-
Never use `transition: all` or Tailwind's `transition` shorthand (which maps to `transition-property: all`). Always specify the exact properties that change.
|
|
8
|
-
|
|
9
|
-
### Why
|
|
10
|
-
|
|
11
|
-
- `transition: all` forces the browser to watch every property for changes
|
|
12
|
-
- Causes unexpected transitions on properties you didn't intend to animate (colors, padding, shadows)
|
|
13
|
-
- Prevents browser optimizations
|
|
14
|
-
|
|
15
|
-
### CSS Example
|
|
16
|
-
|
|
17
|
-
```css
|
|
18
|
-
/* Good — only transition what changes */
|
|
19
|
-
.button {
|
|
20
|
-
transition-property: scale, background-color;
|
|
21
|
-
transition-duration: 150ms;
|
|
22
|
-
transition-timing-function: ease-out;
|
|
23
|
-
}
|
|
24
|
-
|
|
25
|
-
/* Bad — transition everything */
|
|
26
|
-
.button {
|
|
27
|
-
transition: all 150ms ease-out;
|
|
28
|
-
}
|
|
29
|
-
```
|
|
30
|
-
|
|
31
|
-
### Tailwind
|
|
32
|
-
|
|
33
|
-
```tsx
|
|
34
|
-
// Good — explicit properties
|
|
35
|
-
<button className="transition-[scale,background-color] duration-150 ease-out">
|
|
36
|
-
|
|
37
|
-
// Bad — transition all
|
|
38
|
-
<button className="transition duration-150 ease-out">
|
|
39
|
-
```
|
|
40
|
-
|
|
41
|
-
### Tailwind `transition-transform` Note
|
|
42
|
-
|
|
43
|
-
`transition-transform` in Tailwind maps to `transition-property: transform, translate, scale, rotate` — it covers all transform-related properties, not just `transform`. Use this when you're only animating transforms. For multiple non-transform properties, use the bracket syntax: `transition-[scale,opacity,filter]`.
|
|
44
|
-
|
|
45
|
-
## Use `will-change` Sparingly
|
|
46
|
-
|
|
47
|
-
`will-change` hints the browser to pre-promote an element to its own GPU compositing layer. Without it, the browser promotes the element only when the animation starts — that one-time layer promotion can cause a micro-stutter on the first frame.
|
|
48
|
-
|
|
49
|
-
This particularly helps when an element is changing `scale`, `rotation`, or moving around with `transform`. For other properties, it doesn't help much — the browser can't composite them on the GPU anyway.
|
|
50
|
-
|
|
51
|
-
### Rules
|
|
52
|
-
|
|
53
|
-
```css
|
|
54
|
-
/* Good — specific property that benefits from GPU compositing */
|
|
55
|
-
.animated-card {
|
|
56
|
-
will-change: transform;
|
|
57
|
-
}
|
|
58
|
-
|
|
59
|
-
/* Good — multiple compositor-friendly properties */
|
|
60
|
-
.animated-card {
|
|
61
|
-
will-change: transform, opacity;
|
|
62
|
-
}
|
|
63
|
-
|
|
64
|
-
/* Bad — never use will-change: all */
|
|
65
|
-
.animated-card {
|
|
66
|
-
will-change: all;
|
|
67
|
-
}
|
|
68
|
-
|
|
69
|
-
/* Bad — properties that can't be GPU-composited anyway */
|
|
70
|
-
.animated-card {
|
|
71
|
-
will-change: background-color, padding;
|
|
72
|
-
}
|
|
73
|
-
```
|
|
74
|
-
|
|
75
|
-
### Useful Properties
|
|
76
|
-
|
|
77
|
-
| Property | GPU-compositable | Worth using `will-change` |
|
|
78
|
-
| --- | --- | --- |
|
|
79
|
-
| `transform` | Yes | Yes |
|
|
80
|
-
| `opacity` | Yes | Yes |
|
|
81
|
-
| `filter` (blur, brightness) | Yes | Yes |
|
|
82
|
-
| `clip-path` | Yes | Yes |
|
|
83
|
-
| `top`, `left`, `width`, `height` | No | No |
|
|
84
|
-
| `background`, `border`, `color` | No | No |
|
|
85
|
-
|
|
86
|
-
### When to Skip
|
|
87
|
-
|
|
88
|
-
Modern browsers are already good at optimizing on their own. Only add `will-change` when you notice first-frame stutter — Safari in particular benefits from it. Don't add it preemptively to every animated element; each extra compositing layer costs memory.
|