[{"data":1,"prerenderedAt":-1},["ShallowReactive",2],{"skill:01M71AEX5JB0T4MSKEXP4X7ZGN":3,"skill-same:01M71AEX5JB0T4MSKEXP4X7ZGN":75},{"skillNo":4,"name":5,"nameZh":6,"description":7,"descriptionZh":6,"repositoryFullName":8,"ownerLogin":9,"ownerAvatarUrl":10,"ownerAccountNo":11,"ownerDisplayName":12,"repositoryNo":13,"starsCount":14,"licenseSpdxId":15,"licenseFileUrl":6,"sourceHtmlUrl":16,"categories":17,"keywords":23,"publishedAt":44,"linkOnly":45,"markdownContent":46,"markdownBody":47,"frontMatter":48,"refName":51,"commitSha":52,"skillDirectory":53,"forksCount":54,"repositoryHtmlUrl":55,"repositoryHomepageUrl":56,"ownerHtmlUrl":57,"ownerBlogUrl":58,"ownerDescription":59,"updatedAt":60,"install":61,"resources":74},"01M71AEX5JB0T4MSKEXP4X7ZGN","vercel-react-view-transitions",null,"Guide for implementing smooth, native-feeling animations using React's View Transition API (`\u003CViewTransition>` component, `addTransitionType`, and CSS view transition pseudo-elements). Use this skill whenever the user wants to add page transitions, animate route changes, create shared element animations, animate enter\u002Fexit of components, animate list reorder, implement directional (forward\u002Fback) navigation animations, or integrate view transitions in Next.js. Also use when the user mentions view transitions, `startViewTransition`, `ViewTransition`, transition types, or asks about animating between UI states in React without third-party animation libraries.","ariadoss\u002Fsuperskills","ariadoss","https:\u002F\u002Favatars.githubusercontent.com\u002Fu\u002F414341?v=4","01M71AC7383PT6JCRZSQJ4AVTM","Danilo Stern-Sapad","01M71AC73Y7NTBTJ9KQYNENRRE",12,"MIT","https:\u002F\u002Fgithub.com\u002Fariadoss\u002Fsuperskills\u002Fblob\u002Fmain\u002Fdesign-skills\u002Fvercel-react-view-transitions\u002FSKILL.md",[18],{"categoryNo":19,"categoryName":20,"taxonomyType":21,"taxonomyTypeDesc":22},"01JBSEEDCAT000000000000009","前端开发","SCENARIO","使用场景",[24,25,26,27,28,29,30,31,32,33,34,35,36,37,38,39,40,41,42,43],"vercel react view transitions","view","react view transitions","vercel","transitions","react","libraries","create","route","api","components","when","implementing","element","states","types","css","Animation","back","shared","2026-11-10 10:12:30",false,"---\nname: vercel-react-view-transitions\ndescription: Guide for implementing smooth, native-feeling animations using React's View Transition API (`\u003CViewTransition>` component, `addTransitionType`, and CSS view transition pseudo-elements). Use this skill whenever the user wants to add page transitions, animate route changes, create shared element animations, animate enter\u002Fexit of components, animate list reorder, implement directional (forward\u002Fback) navigation animations, or integrate view transitions in Next.js. Also use when the user mentions view transitions, `startViewTransition`, `ViewTransition`, transition types, or asks about animating between UI states in React without third-party animation libraries.\nlicense: MIT\nmetadata:\n  author: vercel\n  version: \"1.0.0\"\n---\n\n# React View Transitions\n\nAnimate between UI states using the browser's native `document.startViewTransition`. Declare *what* with `\u003CViewTransition>`, trigger *when* with `startTransition` \u002F `useDeferredValue` \u002F `Suspense`, control *how* with CSS classes. Unsupported browsers skip animations gracefully.\n\n## When to Animate\n\nEvery `\u003CViewTransition>` should communicate a spatial relationship or continuity. If you can't articulate what it communicates, don't add it.\n\nImplement **all** applicable patterns from this list, in this order:\n\n| Priority | Pattern | What it communicates |\n|----------|---------|---------------------|\n| 1 | **Shared element** (`name`) | \"Same thing — going deeper\" |\n| 2 | **Suspense reveal** | \"Data loaded\" |\n| 3 | **List identity** (per-item `key`) | \"Same items, new arrangement\" |\n| 4 | **State change** (`enter`\u002F`exit`) | \"Something appeared\u002Fdisappeared\" |\n| 5 | **Route change** (layout-level) | \"Going to a new place\" |\n\nThis is an implementation order, not a \"pick one\" list. Implement every pattern that fits the app. Only skip a pattern if the app has no use case for it.\n\n### Choosing Animation Style\n\n| Context | Animation | Why |\n|---------|-----------|-----|\n| Hierarchical navigation (list → detail) | Type-keyed `nav-forward` \u002F `nav-back` | Communicates spatial depth |\n| Lateral navigation (tab-to-tab) | Bare `\u003CViewTransition>` (fade) or `default=\"none\"` | No depth to communicate |\n| Suspense reveal | `enter`\u002F`exit` string props | Content arriving |\n| Revalidation \u002F background refresh | `default=\"none\"` | Silent — no animation needed |\n\nReserve directional slides for hierarchical navigation (list → detail) and ordered sequences (prev\u002Fnext photo, carousel, paginated results). For ordered sequences, the direction communicates position: \"next\" slides from right, \"previous\" from left. Lateral\u002Funordered navigation (tab-to-tab) should not use directional slides — it falsely implies spatial depth.\n\n---\n\n## Availability\n\n- **Next.js:** Do **not** install `react@canary` — the App Router already bundles React canary internally. `ViewTransition` works out of the box. `npm ls react` may show a stable-looking version; this is expected.\n- **Without Next.js:** Install `react@canary react-dom@canary` (`ViewTransition` is not in stable React).\n- Browser support: Chromium 111+, Firefox 144+, Safari 18.2+. Graceful degradation on unsupported browsers.\n\n---\n\n## Core Concepts\n\n### The `\u003CViewTransition>` Component\n\n```jsx\nimport { ViewTransition } from 'react';\n\n\u003CViewTransition>\n  \u003CComponent \u002F>\n\u003C\u002FViewTransition>\n```\n\nReact auto-assigns a unique `view-transition-name` and calls `document.startViewTransition` behind the scenes. Never call `startViewTransition` yourself.\n\n### Animation Triggers\n\n| Trigger | When it fires |\n|---------|--------------|\n| **enter** | `\u003CViewTransition>` first inserted during a Transition |\n| **exit** | `\u003CViewTransition>` first removed during a Transition |\n| **update** | DOM mutations inside a `\u003CViewTransition>`. With nested VTs, mutation applies to the innermost one |\n| **share** | Named VT unmounts and another with same `name` mounts in the same Transition |\n\nOnly `startTransition`, `useDeferredValue`, or `Suspense` activate VTs. Regular `setState` does not animate.\n\n### Critical Placement Rule\n\n`\u003CViewTransition>` only activates enter\u002Fexit if it appears **before any DOM nodes**:\n\n```jsx\n\u002F\u002F Works\n\u003CViewTransition enter=\"auto\" exit=\"auto\">\n  \u003Cdiv>Content\u003C\u002Fdiv>\n\u003C\u002FViewTransition>\n\n\u002F\u002F Broken — div wraps the VT, suppressing enter\u002Fexit\n\u003Cdiv>\n  \u003CViewTransition enter=\"auto\" exit=\"auto\">\n    \u003Cdiv>Content\u003C\u002Fdiv>\n  \u003C\u002FViewTransition>\n\u003C\u002Fdiv>\n```\n\n---\n\n## Styling with View Transition Classes\n\n### Props\n\nValues: `\"auto\"` (browser cross-fade), `\"none\"` (disabled), `\"class-name\"` (custom CSS), or `{ [type]: value }` for type-specific animations.\n\n```jsx\n\u003CViewTransition default=\"none\" enter=\"slide-in\" exit=\"slide-out\" share=\"morph\" \u002F>\n```\n\nIf `default` is `\"none\"`, all triggers are off unless explicitly listed.\n\n### CSS Pseudo-Elements\n\n- `::view-transition-old(.class)` — outgoing snapshot\n- `::view-transition-new(.class)` — incoming snapshot\n- `::view-transition-group(.class)` — container\n- `::view-transition-image-pair(.class)` — old + new pair\n\n---\n\n## Transition Types\n\nTag transitions with `addTransitionType` so VTs can pick different animations based on context. Call it multiple times to stack types — different VTs in the tree react to different types:\n\n```jsx\nstartTransition(() => {\n  addTransitionType('nav-forward');\n  addTransitionType('select-item');\n  router.push('\u002Fdetail\u002F1');\n});\n```\n\nPass an object to map types to CSS classes. Works on `enter`, `exit`, **and** `share`:\n\n```jsx\n\u003CViewTransition\n  enter={{ 'nav-forward': 'slide-from-right', 'nav-back': 'slide-from-left', default: 'none' }}\n  exit={{ 'nav-forward': 'slide-to-left', 'nav-back': 'slide-to-right', default: 'none' }}\n  share={{ 'nav-forward': 'morph-forward', 'nav-back': 'morph-back', default: 'morph' }}\n  default=\"none\"\n>\n  \u003CPage \u002F>\n\u003C\u002FViewTransition>\n```\n\n**TypeScript:** `ViewTransitionClassPerType` requires a `default` key in the object.\n\nFor apps with multiple pages, extract the type-keyed VT into a reusable wrapper:\n\n```jsx\nexport function DirectionalTransition({ children }: { children: React.ReactNode }) {\n  return (\n    \u003CViewTransition\n      enter={{ 'nav-forward': 'nav-forward', 'nav-back': 'nav-back', default: 'none' }}\n      exit={{ 'nav-forward': 'nav-forward', 'nav-back': 'nav-back', default: 'none' }}\n      default=\"none\"\n    >\n      {children}\n    \u003C\u002FViewTransition>\n  );\n}\n```\n\n### `router.back()` and Browser Back Button\n\n`router.back()` and the browser's back\u002Fforward buttons do **not** trigger view transitions (`popstate` is synchronous, incompatible with `startViewTransition`). Use `router.push()` with an explicit URL instead.\n\n---\n\n## Shared Element Transitions\n\nSame `name` on two VTs — one unmounting, one mounting — creates a shared element morph:\n\n```jsx\n\u003CViewTransition name=\"hero-image\">\n  \u003Cimg src=\"\u002Fthumb.jpg\" onClick={() => startTransition(() => onSelect())} \u002F>\n\u003C\u002FViewTransition>\n\n\u002F\u002F On the other view — same name\n\u003CViewTransition name=\"hero-image\">\n  \u003Cimg src=\"\u002Ffull.jpg\" \u002F>\n\u003C\u002FViewTransition>\n```\n\n- Only one VT with a given `name` can be mounted at a time — use unique names (`photo-${id}`).\n- `share` takes precedence over `enter`\u002F`exit`. When no matching pair forms, `enter`\u002F`exit` fires instead.\n- Never use a fade-out exit on pages with shared morphs — use a directional slide instead.\n\n---\n\n## Common Patterns\n\n### Enter\u002FExit\n\n```jsx\n{show && (\n  \u003CViewTransition enter=\"fade-in\" exit=\"fade-out\">\u003CPanel \u002F>\u003C\u002FViewTransition>\n)}\n```\n\n### List Reorder\n\n```jsx\n{items.map(item => (\n  \u003CViewTransition key={item.id}>\u003CItemCard item={item} \u002F>\u003C\u002FViewTransition>\n))}\n```\n\nTrigger inside `startTransition`. Avoid wrapper `\u003Cdiv>`s between list and VT.\n\n### Composing Shared Elements with List Identity\n\n```jsx\n{items.map(item => (\n  \u003CViewTransition key={item.id}>                                      {\u002F* list identity *\u002F}\n    \u003CLink href={`\u002Fitems\u002F${item.id}`}>\n      \u003CViewTransition name={`item-image-${item.id}`} share=\"morph\">   {\u002F* shared element *\u002F}\n        \u003CImage src={item.image} \u002F>\n      \u003C\u002FViewTransition>\n      \u003Cp>{item.name}\u003C\u002Fp>\n    \u003C\u002FLink>\n  \u003C\u002FViewTransition>\n))}\n```\n\n### Force Re-Enter with `key`\n\n```jsx\n\u003CViewTransition key={searchParams.toString()} enter=\"slide-up\" default=\"none\">\n  \u003CResultsGrid \u002F>\n\u003C\u002FViewTransition>\n```\n\n**Caution:** If wrapping `\u003CSuspense>`, changing `key` remounts the boundary and refetches.\n\n### Suspense Fallback to Content\n\nSimple cross-fade:\n```jsx\n\u003CViewTransition>\n  \u003CSuspense fallback={\u003CSkeleton \u002F>}>\u003CContent \u002F>\u003C\u002FSuspense>\n\u003C\u002FViewTransition>\n```\n\nDirectional reveal:\n```jsx\n\u003CSuspense fallback={\u003CViewTransition exit=\"slide-down\">\u003CSkeleton \u002F>\u003C\u002FViewTransition>}>\n  \u003CViewTransition enter=\"slide-up\" default=\"none\">\u003CContent \u002F>\u003C\u002FViewTransition>\n\u003C\u002FSuspense>\n```\n\n---\n\n## How Multiple VTs Interact\n\nEvery VT matching the trigger fires simultaneously in a single `document.startViewTransition`. VTs in **different** transitions (navigation vs later Suspense resolve) don't compete.\n\n### Use `default=\"none\"` Liberally\n\nWithout it, every VT fires the browser cross-fade on **every** transition — Suspense resolves, `useDeferredValue` updates, background revalidations. Always use `default=\"none\"` and explicitly enable only desired triggers.\n\n### Two Patterns Coexist\n\n**Pattern A — Directional slides:** Type-keyed VT on each page, fires during navigation.\n**Pattern B — Suspense reveals:** Simple string props, fires when data loads (no type).\n\nThey coexist because they fire at different moments. `default=\"none\"` on both prevents cross-interference. Always pair `enter` with `exit`. Place directional VTs in page components, not layouts.\n\n### Nested VT Limitation\n\nWhen a parent VT exits, nested VTs inside it do **not** fire their own enter\u002Fexit — only the outermost VT animates. Per-item staggered animations during page navigation are not possible today.\n\n---\n\n## Accessibility\n\nAlways add the reduced motion CSS to your global stylesheet:\n\n```css\n@media (prefers-reduced-motion: reduce) {\n  ::view-transition-group(*),\n  ::view-transition-old(*),\n  ::view-transition-new(*) {\n    animation: none !important;\n  }\n}\n```\n","# React View Transitions\n\nAnimate between UI states using the browser's native `document.startViewTransition`. Declare *what* with `\u003CViewTransition>`, trigger *when* with `startTransition` \u002F `useDeferredValue` \u002F `Suspense`, control *how* with CSS classes. Unsupported browsers skip animations gracefully.\n\n## When to Animate\n\nEvery `\u003CViewTransition>` should communicate a spatial relationship or continuity. If you can't articulate what it communicates, don't add it.\n\nImplement **all** applicable patterns from this list, in this order:\n\n| Priority | Pattern | What it communicates |\n|----------|---------|---------------------|\n| 1 | **Shared element** (`name`) | \"Same thing — going deeper\" |\n| 2 | **Suspense reveal** | \"Data loaded\" |\n| 3 | **List identity** (per-item `key`) | \"Same items, new arrangement\" |\n| 4 | **State change** (`enter`\u002F`exit`) | \"Something appeared\u002Fdisappeared\" |\n| 5 | **Route change** (layout-level) | \"Going to a new place\" |\n\nThis is an implementation order, not a \"pick one\" list. Implement every pattern that fits the app. Only skip a pattern if the app has no use case for it.\n\n### Choosing Animation Style\n\n| Context | Animation | Why |\n|---------|-----------|-----|\n| Hierarchical navigation (list → detail) | Type-keyed `nav-forward` \u002F `nav-back` | Communicates spatial depth |\n| Lateral navigation (tab-to-tab) | Bare `\u003CViewTransition>` (fade) or `default=\"none\"` | No depth to communicate |\n| Suspense reveal | `enter`\u002F`exit` string props | Content arriving |\n| Revalidation \u002F background refresh | `default=\"none\"` | Silent — no animation needed |\n\nReserve directional slides for hierarchical navigation (list → detail) and ordered sequences (prev\u002Fnext photo, carousel, paginated results). For ordered sequences, the direction communicates position: \"next\" slides from right, \"previous\" from left. Lateral\u002Funordered navigation (tab-to-tab) should not use directional slides — it falsely implies spatial depth.\n\n---\n\n## Availability\n\n- **Next.js:** Do **not** install `react@canary` — the App Router already bundles React canary internally. `ViewTransition` works out of the box. `npm ls react` may show a stable-looking version; this is expected.\n- **Without Next.js:** Install `react@canary react-dom@canary` (`ViewTransition` is not in stable React).\n- Browser support: Chromium 111+, Firefox 144+, Safari 18.2+. Graceful degradation on unsupported browsers.\n\n---\n\n## Core Concepts\n\n### The `\u003CViewTransition>` Component\n\n```jsx\nimport { ViewTransition } from 'react';\n\n\u003CViewTransition>\n  \u003CComponent \u002F>\n\u003C\u002FViewTransition>\n```\n\nReact auto-assigns a unique `view-transition-name` and calls `document.startViewTransition` behind the scenes. Never call `startViewTransition` yourself.\n\n### Animation Triggers\n\n| Trigger | When it fires |\n|---------|--------------|\n| **enter** | `\u003CViewTransition>` first inserted during a Transition |\n| **exit** | `\u003CViewTransition>` first removed during a Transition |\n| **update** | DOM mutations inside a `\u003CViewTransition>`. With nested VTs, mutation applies to the innermost one |\n| **share** | Named VT unmounts and another with same `name` mounts in the same Transition |\n\nOnly `startTransition`, `useDeferredValue`, or `Suspense` activate VTs. Regular `setState` does not animate.\n\n### Critical Placement Rule\n\n`\u003CViewTransition>` only activates enter\u002Fexit if it appears **before any DOM nodes**:\n\n```jsx\n\u002F\u002F Works\n\u003CViewTransition enter=\"auto\" exit=\"auto\">\n  \u003Cdiv>Content\u003C\u002Fdiv>\n\u003C\u002FViewTransition>\n\n\u002F\u002F Broken — div wraps the VT, suppressing enter\u002Fexit\n\u003Cdiv>\n  \u003CViewTransition enter=\"auto\" exit=\"auto\">\n    \u003Cdiv>Content\u003C\u002Fdiv>\n  \u003C\u002FViewTransition>\n\u003C\u002Fdiv>\n```\n\n---\n\n## Styling with View Transition Classes\n\n### Props\n\nValues: `\"auto\"` (browser cross-fade), `\"none\"` (disabled), `\"class-name\"` (custom CSS), or `{ [type]: value }` for type-specific animations.\n\n```jsx\n\u003CViewTransition default=\"none\" enter=\"slide-in\" exit=\"slide-out\" share=\"morph\" \u002F>\n```\n\nIf `default` is `\"none\"`, all triggers are off unless explicitly listed.\n\n### CSS Pseudo-Elements\n\n- `::view-transition-old(.class)` — outgoing snapshot\n- `::view-transition-new(.class)` — incoming snapshot\n- `::view-transition-group(.class)` — container\n- `::view-transition-image-pair(.class)` — old + new pair\n\n---\n\n## Transition Types\n\nTag transitions with `addTransitionType` so VTs can pick different animations based on context. Call it multiple times to stack types — different VTs in the tree react to different types:\n\n```jsx\nstartTransition(() => {\n  addTransitionType('nav-forward');\n  addTransitionType('select-item');\n  router.push('\u002Fdetail\u002F1');\n});\n```\n\nPass an object to map types to CSS classes. Works on `enter`, `exit`, **and** `share`:\n\n```jsx\n\u003CViewTransition\n  enter={{ 'nav-forward': 'slide-from-right', 'nav-back': 'slide-from-left', default: 'none' }}\n  exit={{ 'nav-forward': 'slide-to-left', 'nav-back': 'slide-to-right', default: 'none' }}\n  share={{ 'nav-forward': 'morph-forward', 'nav-back': 'morph-back', default: 'morph' }}\n  default=\"none\"\n>\n  \u003CPage \u002F>\n\u003C\u002FViewTransition>\n```\n\n**TypeScript:** `ViewTransitionClassPerType` requires a `default` key in the object.\n\nFor apps with multiple pages, extract the type-keyed VT into a reusable wrapper:\n\n```jsx\nexport function DirectionalTransition({ children }: { children: React.ReactNode }) {\n  return (\n    \u003CViewTransition\n      enter={{ 'nav-forward': 'nav-forward', 'nav-back': 'nav-back', default: 'none' }}\n      exit={{ 'nav-forward': 'nav-forward', 'nav-back': 'nav-back', default: 'none' }}\n      default=\"none\"\n    >\n      {children}\n    \u003C\u002FViewTransition>\n  );\n}\n```\n\n### `router.back()` and Browser Back Button\n\n`router.back()` and the browser's back\u002Fforward buttons do **not** trigger view transitions (`popstate` is synchronous, incompatible with `startViewTransition`). Use `router.push()` with an explicit URL instead.\n\n---\n\n## Shared Element Transitions\n\nSame `name` on two VTs — one unmounting, one mounting — creates a shared element morph:\n\n```jsx\n\u003CViewTransition name=\"hero-image\">\n  \u003Cimg src=\"\u002Fthumb.jpg\" onClick={() => startTransition(() => onSelect())} \u002F>\n\u003C\u002FViewTransition>\n\n\u002F\u002F On the other view — same name\n\u003CViewTransition name=\"hero-image\">\n  \u003Cimg src=\"\u002Ffull.jpg\" \u002F>\n\u003C\u002FViewTransition>\n```\n\n- Only one VT with a given `name` can be mounted at a time — use unique names (`photo-${id}`).\n- `share` takes precedence over `enter`\u002F`exit`. When no matching pair forms, `enter`\u002F`exit` fires instead.\n- Never use a fade-out exit on pages with shared morphs — use a directional slide instead.\n\n---\n\n## Common Patterns\n\n### Enter\u002FExit\n\n```jsx\n{show && (\n  \u003CViewTransition enter=\"fade-in\" exit=\"fade-out\">\u003CPanel \u002F>\u003C\u002FViewTransition>\n)}\n```\n\n### List Reorder\n\n```jsx\n{items.map(item => (\n  \u003CViewTransition key={item.id}>\u003CItemCard item={item} \u002F>\u003C\u002FViewTransition>\n))}\n```\n\nTrigger inside `startTransition`. Avoid wrapper `\u003Cdiv>`s between list and VT.\n\n### Composing Shared Elements with List Identity\n\n```jsx\n{items.map(item => (\n  \u003CViewTransition key={item.id}>                                      {\u002F* list identity *\u002F}\n    \u003CLink href={`\u002Fitems\u002F${item.id}`}>\n      \u003CViewTransition name={`item-image-${item.id}`} share=\"morph\">   {\u002F* shared element *\u002F}\n        \u003CImage src={item.image} \u002F>\n      \u003C\u002FViewTransition>\n      \u003Cp>{item.name}\u003C\u002Fp>\n    \u003C\u002FLink>\n  \u003C\u002FViewTransition>\n))}\n```\n\n### Force Re-Enter with `key`\n\n```jsx\n\u003CViewTransition key={searchParams.toString()} enter=\"slide-up\" default=\"none\">\n  \u003CResultsGrid \u002F>\n\u003C\u002FViewTransition>\n```\n\n**Caution:** If wrapping `\u003CSuspense>`, changing `key` remounts the boundary and refetches.\n\n### Suspense Fallback to Content\n\nSimple cross-fade:\n```jsx\n\u003CViewTransition>\n  \u003CSuspense fallback={\u003CSkeleton \u002F>}>\u003CContent \u002F>\u003C\u002FSuspense>\n\u003C\u002FViewTransition>\n```\n\nDirectional reveal:\n```jsx\n\u003CSuspense fallback={\u003CViewTransition exit=\"slide-down\">\u003CSkeleton \u002F>\u003C\u002FViewTransition>}>\n  \u003CViewTransition enter=\"slide-up\" default=\"none\">\u003CContent \u002F>\u003C\u002FViewTransition>\n\u003C\u002FSuspense>\n```\n\n---\n\n## How Multiple VTs Interact\n\nEvery VT matching the trigger fires simultaneously in a single `document.startViewTransition`. VTs in **different** transitions (navigation vs later Suspense resolve) don't compete.\n\n### Use `default=\"none\"` Liberally\n\nWithout it, every VT fires the browser cross-fade on **every** transition — Suspense resolves, `useDeferredValue` updates, background revalidations. Always use `default=\"none\"` and explicitly enable only desired triggers.\n\n### Two Patterns Coexist\n\n**Pattern A — Directional slides:** Type-keyed VT on each page, fires during navigation.\n**Pattern B — Suspense reveals:** Simple string props, fires when data loads (no type).\n\nThey coexist because they fire at different moments. `default=\"none\"` on both prevents cross-interference. Always pair `enter` with `exit`. Place directional VTs in page components, not layouts.\n\n### Nested VT Limitation\n\nWhen a parent VT exits, nested VTs inside it do **not** fire their own enter\u002Fexit — only the outermost VT animates. Per-item staggered animations during page navigation are not possible today.\n\n---\n\n## Accessibility\n\nAlways add the reduced motion CSS to your global stylesheet:\n\n```css\n@media (prefers-reduced-motion: reduce) {\n  ::view-transition-group(*),\n  ::view-transition-old(*),\n  ::view-transition-new(*) {\n    animation: none !important;\n  }\n}\n```\n",{"name":5,"license":15,"metadata":49,"description":7},{"author":27,"version":50},"1.0.0","main","c7ec8d78e5dc37484c2cfe90ab04de163d97dd41","design-skills\u002Fvercel-react-view-transitions",0,"https:\u002F\u002Fgithub.com\u002Fariadoss\u002Fsuperskills","https:\u002F\u002Fhyperion360.com\u002Fblog\u002Fparallel-ai-agents-engineering-workflow\u002F","https:\u002F\u002Fgithub.com\u002Fariadoss","https:\u002F\u002Fdanilosapad.com\u002F","CEO & Founder of @Hyperion360","2026-11-01 12:36:50",{"source":8,"skillName":5,"commands":62,"prompt":72,"zipAvailable":73},[63,66,69],{"tool":64,"command":65},"npx","npx skills add ariadoss\u002Fsuperskills --skill vercel-react-view-transitions",{"tool":67,"command":68},"bunx","bunx skills add ariadoss\u002Fsuperskills --skill vercel-react-view-transitions",{"tool":70,"command":71},"pnpm","pnpm dlx skills add ariadoss\u002Fsuperskills --skill vercel-react-view-transitions","安装技能，技能地址：https:\u002F\u002Fgithub.com\u002Fariadoss\u002Fsuperskills\u002Fblob\u002Fmain\u002Fdesign-skills\u002Fvercel-react-view-transitions\u002FSKILL.md",true,[],[76,102,127,146,175,191],{"skillNo":77,"name":78,"nameZh":6,"description":79,"descriptionZh":6,"repositoryFullName":8,"ownerLogin":9,"ownerAvatarUrl":10,"ownerAccountNo":11,"ownerDisplayName":12,"repositoryNo":13,"starsCount":14,"licenseSpdxId":15,"licenseFileUrl":6,"sourceHtmlUrl":80,"categories":81,"keywords":85,"publishedAt":44},"01M71AZE3MPF891RM354EMRYA1","youtube","Download YouTube video transcripts when user provides a YouTube URL or asks to download\u002Fget\u002Ffetch a transcript from YouTube. Also use when user wants to transcribe or get captions\u002Fsubtitles from a YouTube video.","https:\u002F\u002Fgithub.com\u002Fariadoss\u002Fsuperskills\u002Fblob\u002Fmain\u002Fskills\u002Fyoutube\u002FSKILL.md",[82],{"categoryNo":83,"categoryName":84,"taxonomyType":21,"taxonomyTypeDesc":22},"01JBSEEDCAT000000000000016","图像与多媒体",[78,86,87,88,89,90,91,92,93,35,94,95,96,97,98,99,100,101],"user","download","transcribe","write","transcript","video transcripts","Bash","URL","Captions","get","fetch","Video","read","use","subtitles","transcripts",{"skillNo":103,"name":104,"nameZh":6,"description":105,"descriptionZh":6,"repositoryFullName":8,"ownerLogin":9,"ownerAvatarUrl":10,"ownerAccountNo":11,"ownerDisplayName":12,"repositoryNo":13,"starsCount":14,"licenseSpdxId":15,"licenseFileUrl":6,"sourceHtmlUrl":106,"categories":107,"keywords":108,"publishedAt":44},"01M71AZAYR85PW6BJGSQXS4BN2","write-plan","Use when you have a spec or requirements for a multi-step task, before touching code. Produces an engineering plan complete with TDD tasks, DRY\u002FSOLID\u002FYAGNI principles, a required Test Plan & Verification section, and a coverage target — then auto-runs \u002Fplan-eng-review as an independent double-check before execution.","https:\u002F\u002Fgithub.com\u002Fariadoss\u002Fsuperskills\u002Fblob\u002Fmain\u002Fskills\u002Fwrite-plan\u002FSKILL.md",[],[109,110,89,111,112,113,114,115,116,35,117,118,119,120,121,122,123,124,125,126],"write plan","plan","dry","verification","review","tasks","code","you","auto","eng","coverage","complete","section","for","test plan","target","as","yagni",{"skillNo":128,"name":129,"nameZh":6,"description":130,"descriptionZh":6,"repositoryFullName":8,"ownerLogin":9,"ownerAvatarUrl":10,"ownerAccountNo":11,"ownerDisplayName":12,"repositoryNo":13,"starsCount":14,"licenseSpdxId":15,"licenseFileUrl":6,"sourceHtmlUrl":131,"categories":132,"keywords":133,"publishedAt":44},"01M71AZ8NDDP5ZMGEE6FSC4FKR","worktrees","Use when starting feature work that needs isolation from current workspace or before executing implementation plans - creates isolated git worktrees with smart directory selection and safety verification","https:\u002F\u002Fgithub.com\u002Fariadoss\u002Fsuperskills\u002Fblob\u002Fmain\u002Fskills\u002Fworktrees\u002FSKILL.md",[],[129,134,135,136,99,137,138,139,140,141,142,112,143,35,144,145],"implementation","workspace","with","plans","feature","isolation","git","directory","work","git worktrees","selection","Safety",{"skillNo":147,"name":148,"nameZh":6,"description":149,"descriptionZh":6,"repositoryFullName":8,"ownerLogin":9,"ownerAvatarUrl":10,"ownerAccountNo":11,"ownerDisplayName":12,"repositoryNo":13,"starsCount":14,"licenseSpdxId":15,"licenseFileUrl":6,"sourceHtmlUrl":150,"categories":151,"keywords":155,"publishedAt":44},"01M71AZ4ZQHTNWFRZVYHKQFP08","web-perf","Analyzes web performance using Chrome DevTools MCP. Measures Core Web Vitals (LCP, INP, CLS) and supplementary metrics (FCP, TBT, Speed Index), identifies render-blocking resources, network dependency chains, layout shifts, caching issues, and accessibility gaps. Use when asked to audit, profile, debug, or optimize page load performance, Lighthouse scores, or site speed. Biases towards retrieval from current documentation over pre-trained knowledge.","https:\u002F\u002Fgithub.com\u002Fariadoss\u002Fsuperskills\u002Fblob\u002Fmain\u002Fskills\u002Fweb-perf\u002FSKILL.md",[152],{"categoryNo":153,"categoryName":154,"taxonomyType":21,"taxonomyTypeDesc":22},"01JBSEEDCAT000000000000023","Skill与智能体开发",[156,157,158,159,160,161,162,163,164,35,165,166,167,168,169,170,171,172,173,174],"web","perf","web perf","resources","MCP","layout","optimize","documentation","caching","qa","knowledge","devtools","issues","render","re","performance","chrome devtools","vitals","never",{"skillNo":176,"name":177,"nameZh":6,"description":178,"descriptionZh":6,"repositoryFullName":8,"ownerLogin":9,"ownerAvatarUrl":10,"ownerAccountNo":11,"ownerDisplayName":12,"repositoryNo":13,"starsCount":14,"licenseSpdxId":15,"licenseFileUrl":6,"sourceHtmlUrl":179,"categories":180,"keywords":181,"publishedAt":44},"01M71AZ2KZNWYEGKKRMJH8PYG2","verify","Use when about to claim work is complete, fixed, or passing, before committing or creating PRs - requires running verification commands and confirming output before making any success claims; evidence before assertions always","https:\u002F\u002Fgithub.com\u002Fariadoss\u002Fsuperskills\u002Fblob\u002Fmain\u002Fskills\u002Fverify\u002FSKILL.md",[],[177,120,182,183,142,112,184,185,35,186,99,187,188,189,190],"commands","about","claims","output","assertions","claim","prs","evidence","running",{"skillNo":192,"name":193,"nameZh":6,"description":194,"descriptionZh":6,"repositoryFullName":8,"ownerLogin":9,"ownerAvatarUrl":10,"ownerAccountNo":11,"ownerDisplayName":12,"repositoryNo":13,"starsCount":14,"licenseSpdxId":15,"licenseFileUrl":6,"sourceHtmlUrl":195,"categories":196,"keywords":197,"publishedAt":44},"01M71AZ0ACCK7N1QMWQK1FV2HJ","validate-idea","Validate a business idea using the minimalist entrepreneur framework. Use when someone has a business idea and wants to test if it's worth pursuing before building anything.","https:\u002F\u002Fgithub.com\u002Fariadoss\u002Fsuperskills\u002Fblob\u002Fmain\u002Fskills\u002Fvalidate-idea\u002FSKILL.md",[],[198,199,200,201,202,203,204,35,205,99,206],"validate","idea","validate idea","framework","it","minimalist","test","business","before building"]