├── .gitignore
├── README.md
├── app
├── blog
│ ├── [slug]
│ │ ├── page-client.tsx
│ │ └── page.tsx
│ └── page.tsx
├── card
│ ├── [slug]
│ │ ├── page-client.tsx
│ │ └── page.tsx
│ ├── overview
│ │ └── page.tsx
│ ├── page.tsx
│ └── styles.module.css
├── globals.css
├── icon.svg
├── layout.tsx
├── page.tsx
└── utils
│ ├── constants.ts
│ └── cx.ts
├── components.json
├── components
├── transition
│ └── slide-transition.tsx
└── ui
│ ├── avatar.tsx
│ ├── button.tsx
│ ├── card.tsx
│ └── dynamic-background.tsx
├── lib
└── utils.ts
├── next.config.ts
├── package.json
├── pnpm-lock.yaml
├── postcss.config.mjs
├── public
├── avatars
│ ├── feedthejim.jpg
│ ├── huozhi.jpg
│ ├── leerob.jpg
│ ├── sebmarkbage.jpg
│ └── ztanner.jpg
├── cards
│ ├── barcelona.png
│ ├── florence.png
│ ├── santamonica.png
│ └── xian.png
└── post
│ └── composable-caching-with-nextjs.png
├── tailwind.config.ts
└── tsconfig.json
/.gitignore:
--------------------------------------------------------------------------------
1 | # See https://help.github.com/articles/ignoring-files/ for more about ignoring files.
2 |
3 | # dependencies
4 | /node_modules
5 | /.pnp
6 | .pnp.*
7 | .yarn/*
8 | !.yarn/patches
9 | !.yarn/plugins
10 | !.yarn/releases
11 | !.yarn/versions
12 |
13 | # testing
14 | /coverage
15 |
16 | # next.js
17 | /.next/
18 | /out/
19 |
20 | # production
21 | /build
22 |
23 | # misc
24 | .DS_Store
25 | *.pem
26 |
27 | # debug
28 | npm-debug.log*
29 | yarn-debug.log*
30 | yarn-error.log*
31 | .pnpm-debug.log*
32 |
33 | # env files (can opt-in for committing if needed)
34 | .env*
35 |
36 | # vercel
37 | .vercel
38 |
39 | # typescript
40 | *.tsbuildinfo
41 | next-env.d.ts
42 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | This is a [Next.js](https://nextjs.org) project that demonstrates the React experimental ViewTransition component.
2 |
3 | ## Getting Started
4 |
5 | First, run the development server:
6 |
7 | ```bash
8 | pnpm dev
9 | ```
10 |
11 | Open [http://localhost:3000](http://localhost:3000) with your browser to see the result.
12 |
13 |
14 | ## Deploy on Vercel
15 |
16 | The easiest way to deploy your Next.js app is to use the [Vercel Platform](https://vercel.com/new?utm_medium=default-template&filter=next.js&utm_source=create-next-app&utm_campaign=create-next-app-readme) from the creators of Next.js.
17 |
18 | Check out our [Next.js deployment documentation](https://nextjs.org/docs/app/building-your-application/deploying) for more details.
19 |
--------------------------------------------------------------------------------
/app/blog/[slug]/page-client.tsx:
--------------------------------------------------------------------------------
1 | 'use client'
2 |
3 | import { unstable_ViewTransition as ViewTransition } from 'react'
4 | import Link from 'next/link'
5 | import { Avatar } from '@/components/ui/avatar'
6 | import { type Post } from '@/app/utils/constants'
7 |
8 | export default function BlogPost({ post }: { post: Post }) {
9 | const { slug } = post
10 | return (
11 |
12 |
13 |
14 |
15 | ← Back to blog
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 | {/* Add a div to hack the transition from Link to h1 on safari, where it needs to be a inline-block */}
24 |
25 |
26 | {post.title}
27 |
28 |
29 |
30 |
31 |
32 |
Posted by
33 |
34 |
35 | {post?.authors.map((author, i) => {
36 | return (
37 |
38 |
39 |
40 |
41 |
42 |
43 |
44 | {author.name}
45 | {author.handle}
46 |
47 |
48 | )
49 | })}
50 |
51 |
52 |
53 |
54 |
55 |
56 | {post.features &&
57 | post.features.map((feature) => (
58 | -
59 |
60 | {feature.title}
61 |
62 | : {feature.description}
63 |
64 | ))}
65 |
66 |
67 | {post.content}
68 |
69 | <>
70 | {'image' in post && post.image ? (
71 |
72 | {/* @ts-ignore */}
73 |

74 |
75 | ) : null}
76 | >
77 |
78 |
79 |
80 |
81 | )
82 | }
83 |
--------------------------------------------------------------------------------
/app/blog/[slug]/page.tsx:
--------------------------------------------------------------------------------
1 | import { POSTS } from '@/app/utils/constants'
2 | import { default as PageClient } from './page-client'
3 |
4 | export default async function Page(
5 | props: { params: Promise<{ slug: string }> }
6 | ) {
7 | const { slug } = await props.params
8 | const post = POSTS.find((item) => item.slug === slug)!
9 |
10 | return
11 | }
12 |
13 |
14 |
15 | export async function generateStaticParams() {
16 | return POSTS.map((post) => ({
17 | params: { slug: post.slug },
18 | }))
19 | }
20 |
21 | export const dynamic = 'force-static'
22 |
--------------------------------------------------------------------------------
/app/blog/page.tsx:
--------------------------------------------------------------------------------
1 | import { unstable_ViewTransition as ViewTransition } from 'react'
2 | import Link from 'next/link'
3 | import { Avatar } from '@/components/ui/avatar'
4 | import { Card, CardContent, CardFooter } from '@/components/ui/card'
5 | import { Button } from '@/components/ui/button'
6 | import { cx } from '@/app/utils/cx'
7 | import { POSTS } from '../utils/constants'
8 |
9 | export default function Page() {
10 | return (
11 |
12 |
13 |
14 | {``}
15 |
16 | {/* Go to home page */}
17 |
18 |
19 | ← Back
20 |
21 |
22 |
23 |
The latest Next.js news
24 |
25 |
26 | {POSTS.map((item, index) => (
27 |
28 |
29 |
30 | {item.authors.map((author, i) => (
31 |
32 |
33 |
34 |
35 |
36 | ))}
37 |
38 |
39 |
40 |
41 | {item.date}
42 |
43 |
44 | {/* NOTE: inline-block is required for safari */}
45 |
46 | {item.title}
47 |
48 |
49 |
{null}
50 |
51 |
{item.description}
52 |
53 | {/* actually displayed features */}
54 |
55 | {item.features?.map((feature) => (
56 |
57 |
58 | {feature.title}
59 |
60 |
61 | ))}
62 |
63 |
64 |
65 |
66 |
67 |
68 |
69 |
70 |
71 |
72 | ))}
73 |
74 |
75 |
76 | )
77 | }
78 |
--------------------------------------------------------------------------------
/app/card/[slug]/page-client.tsx:
--------------------------------------------------------------------------------
1 | 'use client'
2 |
3 | import Image from 'next/image'
4 | import Link from 'next/link'
5 | import { unstable_ViewTransition as ViewTransition } from 'react'
6 | import { type Place } from '@/app/utils/constants'
7 |
8 | export default function Place({ place, places }: { place: Place; places: Place[] }) {
9 | return (
10 |
11 |
12 |
13 |
14 |
18 |
27 |
28 |
29 |
30 |
31 |
32 |
40 |
41 |
42 |
43 |
44 |
45 |
46 | {place.name}
47 |
48 |
49 |
50 |
51 |
52 |
53 |
54 |
Spots
55 |
56 | {places.map((place) => (
57 |
62 |
63 |
64 |
72 | {/* name label */}
73 |
74 |
75 |
{place.name}
76 |
77 | ))}
78 |
79 |
80 |
81 |
82 |
83 | )
84 | }
85 |
--------------------------------------------------------------------------------
/app/card/[slug]/page.tsx:
--------------------------------------------------------------------------------
1 | import { PLACES } from '@/app/utils/constants'
2 |
3 | import { default as PageClient } from './page-client'
4 |
5 | export default async function Page(
6 | props: { params: Promise<{ slug: string }> }
7 | ) {
8 | const params = await props.params
9 | const place = PLACES.find((p) => p.slug === params.slug)!
10 |
11 | return
12 | }
13 |
14 | export async function generateStaticParams() {
15 | return PLACES.map((place) => ({
16 | params: { slug: place.slug },
17 | }))
18 | }
19 |
20 | export const dynamic = 'force-static'
21 |
--------------------------------------------------------------------------------
/app/card/overview/page.tsx:
--------------------------------------------------------------------------------
1 | 'use client'
2 |
3 | import Image from 'next/image'
4 | import Link from 'next/link'
5 | import { unstable_ViewTransition as ViewTransition } from 'react'
6 | import { PLACES } from '@/app/utils/constants'
7 | import { DynamicBackground } from '@/components/ui/dynamic-background'
8 |
9 | function LeftSideBar() {
10 | return (
11 |
12 |
13 |
14 |
15 |
16 | {/* sticker icon */}
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
26 | )
27 | }
28 |
29 | export default function Page() {
30 | return (
31 |
32 | {/* Left Section */}
33 |
34 |
35 |
36 |
37 | {/* Right Section */}
38 |
39 |
40 |
Spots
41 |
42 | {PLACES.map((place) => (
43 |
48 |
49 |
50 |
58 |
59 |
60 |
61 |
{place.name}
62 | {place.description}
63 |
64 |
65 | ))}
66 |
67 |
68 |
69 |
70 | )
71 | }
72 |
--------------------------------------------------------------------------------
/app/card/page.tsx:
--------------------------------------------------------------------------------
1 | 'use client'
2 |
3 | import Image from 'next/image'
4 | import Link from 'next/link'
5 | import { unstable_ViewTransition as ViewTransition } from 'react'
6 | import { PLACES } from '../utils/constants'
7 | import { DynamicBackground } from '@/components/ui/dynamic-background'
8 |
9 | function LeftSideMenu() {
10 | return (
11 |
12 |
13 |
14 |
15 |
16 |
17 | {``}
18 |
19 |
20 |
21 | ← Back
22 |
23 |
24 |
25 |
26 |
27 | {/* sticker icon */}
28 |
29 |
30 |
31 |
32 |
33 |
34 | Las Ciudades
35 |
36 |
37 |
38 |
39 |
40 | Explore The cities.
41 |
42 |
43 |
44 |
45 |
46 | )
47 | }
48 |
49 | export default function Page() {
50 | return (
51 | // make this locate on top of the page when it's on mobile
52 |
53 | {/* Left Section */}
54 |
55 |
56 |
57 |
58 | {/* Right Section */}
59 |
60 |
61 |
Spots
62 |
63 | {PLACES.map((place) => (
64 |
69 |
70 |
71 |
79 |
80 | {/* name label */}
81 |
82 |
83 | {place.name}
84 |
85 |
86 |
87 |
88 | ))}
89 |
90 |
91 |
92 |
93 | )
94 | }
95 |
--------------------------------------------------------------------------------
/app/card/styles.module.css:
--------------------------------------------------------------------------------
1 | @keyframes enter-slide-left {
2 | 0% {
3 | /* opacity: 0; */
4 | transform: translate(60px, 0);
5 | }
6 | 100% {
7 | /* opacity: 1; */
8 | transform: translate(0, 0);
9 | }
10 | }
11 |
12 | @keyframes exit-slide-right {
13 | 0% {
14 | /* opacity: 1; */
15 | transform: translate(0, 0);
16 | }
17 | 100% {
18 | /* opacity: 0; */
19 | transform: translate(-60px, 0);
20 |
21 | }
22 | }
23 |
24 | ::view-transition-new(.enter-slide-left) {
25 | animation: enter-slide-left ease-in 300ms;
26 | animation-delay: 300ms;
27 | }
28 | ::view-transition-old(.exit-slide-right) {
29 | animation: exit-slide-right ease-out 300ms;
30 | animation-delay: 300ms;
31 | }
32 |
33 |
34 | @keyframes spin-90-forward {
35 | 0% {
36 | transform: rotate(0deg);
37 | }
38 | 100% {
39 | transform: rotate(90deg);
40 | }
41 | }
42 |
43 | @keyframes spin-90-backward {
44 | 0% {
45 | transform: rotate(0deg);
46 | }
47 | 100% {
48 | transform: rotate(-90deg);
49 | }
50 | }
51 |
52 | ::view-transition-new(.spin-90-forward) {
53 | animation: spin-90-forward ease-in 300ms;
54 | }
55 | ::view-transition-old(.spin-90-backward) {
56 | animation: spin-90-backward ease-out 300ms;
57 | }
58 |
--------------------------------------------------------------------------------
/app/globals.css:
--------------------------------------------------------------------------------
1 | @import "tailwindcss";
2 |
3 | @theme {
4 | --font-sans: var(--font-geist-sans);
5 | --font-mono: var(--font-geist-mono);
6 | }
7 |
8 | @layer utilities {
9 | .text-balance {
10 | text-wrap: balance;
11 | }
12 | }
13 |
14 |
15 |
16 | @layer base {
17 | :root {
18 | --background: 0 0% 100%;
19 | --foreground: 0 0% 3.9%;
20 | --card: 0 0% 100%;
21 | --card-foreground: 0 0% 3.9%;
22 | --popover: 0 0% 100%;
23 | --popover-foreground: 0 0% 3.9%;
24 | --primary: 0 0% 9%;
25 | --primary-foreground: 0 0% 98%;
26 | --secondary: 0 0% 96.1%;
27 | --secondary-foreground: 0 0% 9%;
28 | --muted: 0 0% 96.1%;
29 | --muted-foreground: 0 0% 45.1%;
30 | --accent: 0 0% 96.1%;
31 | --accent-foreground: 0 0% 9%;
32 | --destructive: 0 84.2% 60.2%;
33 | --destructive-foreground: 0 0% 98%;
34 | --border: 0 0% 89.8%;
35 | --input: 0 0% 89.8%;
36 | --ring: 0 0% 3.9%;
37 | --chart-1: 12 76% 61%;
38 | --chart-2: 173 58% 39%;
39 | --chart-3: 197 37% 24%;
40 | --chart-4: 43 74% 66%;
41 | --chart-5: 27 87% 67%;
42 | --radius: 0.5rem;
43 | }
44 | .dark {
45 | --background: 0 0% 3.9%;
46 | --foreground: 0 0% 98%;
47 | --card: 0 0% 3.9%;
48 | --card-foreground: 0 0% 98%;
49 | --popover: 0 0% 3.9%;
50 | --popover-foreground: 0 0% 98%;
51 | --primary: 0 0% 98%;
52 | --primary-foreground: 0 0% 9%;
53 | --secondary: 0 0% 14.9%;
54 | --secondary-foreground: 0 0% 98%;
55 | --muted: 0 0% 14.9%;
56 | --muted-foreground: 0 0% 63.9%;
57 | --accent: 0 0% 14.9%;
58 | --accent-foreground: 0 0% 98%;
59 | --destructive: 0 62.8% 30.6%;
60 | --destructive-foreground: 0 0% 98%;
61 | --border: 0 0% 14.9%;
62 | --input: 0 0% 14.9%;
63 | --ring: 0 0% 83.1%;
64 | --chart-1: 220 70% 50%;
65 | --chart-2: 160 60% 45%;
66 | --chart-3: 30 80% 55%;
67 | --chart-4: 280 65% 60%;
68 | --chart-5: 340 75% 55%;
69 | }
70 | }
71 |
72 | [data-support-yes],
73 | [data-support-no] {
74 | display: none;
75 | }
76 |
77 |
78 | @supports (view-transition-name: test) {
79 | [data-support] [data-support-yes] {
80 | display: inline;
81 | }
82 | [data-support] [data-support-no] {
83 | display: none;
84 | }
85 | }
86 |
87 | @supports not (view-transition-name: test) {
88 | [data-support] [data-support-yes] {
89 | display: none;
90 | }
91 | [data-support] [data-support-no] {
92 | display: inline;
93 | }
94 | }
95 |
96 | /* Safari */
97 | @supports (-webkit-hyphens: none) and (not (-moz-appearance: none)) {
98 | [data-support] [data-support-yes] {
99 | display: none;
100 | }
101 | [data-support] [data-support-no] {
102 | display: inline;
103 | }
104 | }
105 |
--------------------------------------------------------------------------------
/app/icon.svg:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/app/layout.tsx:
--------------------------------------------------------------------------------
1 | import type { Metadata } from 'next'
2 | import './globals.css'
3 |
4 | export const metadata: Metadata = {
5 | title: 'Next.js View Transition',
6 | description: 'Next.js View Transition Examples',
7 | }
8 |
9 | export default function RootLayout({
10 | children,
11 | }: Readonly<{
12 | children: React.ReactNode
13 | }>) {
14 | return (
15 |
16 | {children}
17 |
18 | )
19 | }
20 |
--------------------------------------------------------------------------------
/app/page.tsx:
--------------------------------------------------------------------------------
1 | import Link from 'next/link'
2 | import { unstable_ViewTransition as ViewTransition } from 'react'
3 |
4 | export default function Page() {
5 | return (
6 |
7 |
{'View Transition Next.js Examples'}
8 |
9 |
10 |
11 | {`Use React `}
12 | {`Experimental `}
13 |
14 |
15 | {``}
16 |
17 |
18 | {` API in Next.js.`}
19 |
20 |
21 |
22 | {/* supports info */}
23 |
24 |
25 | {'🔴 might not work well on your browser'}
26 |
27 |
28 | 🟢 Your browser supports View Transitions.
29 |
30 |
31 |
32 |
33 | -
34 |
35 | {`Floating Elements Transition`}
36 |
37 |
38 |
39 | -
40 |
41 | {`Transform Card Transition`}
42 |
43 |
44 |
45 |
46 |
47 | Source code ↗
48 |
49 |
50 | )
51 | }
52 |
--------------------------------------------------------------------------------
/app/utils/constants.ts:
--------------------------------------------------------------------------------
1 | interface Author {
2 | name: string
3 | handle: string
4 | avatar: string
5 | }
6 |
7 | const AUTHORS: Record = {
8 | 'sebmarkbage': { name: 'Sebastian Silbermann', handle: 'sebmarkbage', avatar: '/avatars/sebmarkbage.jpg' },
9 | 'huozhi': { name: 'Jiachi Liu', handle: 'huozhi', avatar: '/avatars/huozhi.jpg' },
10 | 'ztanner': { name: 'Zack Tanner', handle: 'ztanner', avatar: '/avatars/ztanner.jpg' },
11 | 'leerob': { name: 'Lee Robinson', handle: 'leerob', avatar: '/avatars/leerob.jpg' },
12 | 'feedthejim': { name: 'Jimmy Lai', handle: 'feedthejim', avatar: '/avatars/feedthejim.jpg' },
13 | }
14 |
15 | export const POSTS = [
16 | {
17 | date: 'February 26th, 2025',
18 | title: 'Next.js 15.2',
19 | slug: 'nextjs-15-2',
20 | description: 'Next.js 15.2 includes updates for debugging errors, metadata, Turbopack, and more:',
21 | features: [
22 | {
23 | title: 'Redesigned error UI and improved stack traces',
24 | description: 'A redesigned debugging experience',
25 | },
26 | {
27 | title: 'Streaming metadata',
28 | description: 'Async metadata will no longer block page rendering or client-side page transitions',
29 | },
30 | {
31 | title: 'Turbopack performance improvements',
32 | description: 'Faster compile times and reduced memory usage',
33 | },
34 | {
35 | title: 'React View Transitions (experimental)',
36 | description: "Experimental support for React's new View Transitions API",
37 | },
38 | {
39 | title: 'Node.js Middleware (experimental)',
40 | description: 'Experimental support for using the Node.js runtime in Middleware',
41 | },
42 | ],
43 | authors: ['sebmarkbage', 'huozhi', 'ztanner'].map((author) => AUTHORS[author]),
44 | content: `We've added a feature flag to enable the new experimental View Transitions API in React. This new API allows you to animate between different views and components in your application.
45 |
46 | We've overhauled the UI and presentation of error messages in Next.js, making them easier to understand. The new design highlights the core details of the error—such as the message, the relevant code frame, and the call stack—while reducing noise from code in libraries or dependencies. This means you can quickly get to the root of what went wrong and start fixing it faster.
47 |
48 | Leveraging the newly introduced owner stacks feature in React, we're now able to provide higher fidelity into where your errors are coming from. Next.js will now be able to surface the subcomponent responsible for throwing the error, skipping over intermediary elements that weren't responsible for creating the element that caused the error.
49 |
50 | We're also making it easier to customize your indicator preferences without needing to add additional configuration.
51 | `,
52 | image: null,
53 | },
54 | {
55 | date: 'January 3rd, 2025',
56 | title: 'Composable Caching with Next.js',
57 | slug: 'composable-caching-with-nextjs',
58 | description:
59 | "We're working on a simple and powerful caching model for Next.js. In a previous post, we talked about our journey with caching and how we've arrived at the 'use cache'",
60 |
61 | authors: ['leerob'].map((author) => AUTHORS[author]),
62 | content: `We’re working on a simple and powerful caching model for Next.js. In a previous post, we talked about our journey with caching and how we’ve arrived at the 'use cache' directive.
63 |
64 | This post will discuss the API design and benefits of 'use cache'.
65 |
66 | Behind the scenes, Next.js transforms this code into a server function due to the 'use cache' directive. During compilation, the “dependencies” of this cache entry are found and used as part of the cache key.
67 |
68 | For example, id becomes part of the cache key. If we call getUser(1) multiple times, we return the memoized output from the cached server function. Changing this value will create a new entry in the cache.
69 | `,
70 | image: '/post/composable-caching-with-nextjs.png',
71 | },
72 | {
73 | date: 'December 10th, 2024',
74 | title: 'Next.js 14.1',
75 | slug: 'next-14-1',
76 | description:
77 | 'Next.js 14.1 includes developer experience improvements including:',
78 | authors: ['huozhi', 'feedthejim'].map((author) => AUTHORS[author]),
79 | features: [
80 | {
81 | title: 'Improved Self-Hosting',
82 | description: 'New documentation and custom cache handler',
83 | },
84 | {
85 | title: 'Turbopack Improvements',
86 | description: '5,600 tests passing for next dev --turbo',
87 | },
88 | {
89 | title: 'DX Improvements',
90 | description: 'Improved error messages, pushState and replaceState support',
91 | },
92 | {
93 | title: 'Parallel & Intercepted Routes',
94 | description: '20 bug fixes based on your feedback',
95 | },
96 | {
97 | title: 'next/image Improvements',
98 | description: ', art direction, and dark mode support',
99 | },
100 | ],
101 | content: `Improved Self-Hosting
102 |
103 | We've heard your feedback for improved clarity on how to self-host Next.js with a Node.js server, Docker container, or static export. We've overhauled our self-hosting documentation on:
104 |
105 | - Runtime environment variables
106 | - Custom cache configuration for ISR
107 | - Custom image optimization
108 | - Middleware
109 |
110 | `,
111 | image: null,
112 | },
113 | ]
114 |
115 | export const PLACES = [
116 | {
117 | id: 1,
118 | name: 'Florence',
119 | image: '/cards/florence.png',
120 | slug: 'florence',
121 | // generate human description of the place
122 | description: `A city in central Italy and the capital city of the Tuscany region. It is the most populous city in Tuscany, with 383,084 inhabitants in 2013, and over 1,520,000 in its metropolitan area.`,
123 | },
124 | {
125 | id: 2,
126 | name: `Xi'an`,
127 | image: '/cards/xian.png',
128 | slug: 'xian',
129 | description: 'An ancient city in China with 2000 years history, amazing food, located in the central part of the Shaanxi Province.',
130 | },
131 | {
132 | id: 3,
133 | name: 'Barcelona',
134 | image: '/cards/barcelona.png',
135 | slug: 'barcelona',
136 | description: 'A city on the coast of northeastern Spain. It is the capital and largest city of the autonomous community of Catalonia, as well as the second most populous municipality of Spain.',
137 | },
138 | {
139 | id: 4,
140 | name: 'Santa Monica',
141 | image: '/cards/santamonica.png',
142 | slug: 'santamonica',
143 | description: 'A beachfront city in western Los Angeles County, California, United States. Situated on Santa Monica Bay, it is bordered on five sides by different neighborhoods of the city of Los Angeles.',
144 | },
145 | ]
146 |
147 | export type Post = typeof POSTS[number]
148 | export type Place = typeof PLACES[number]
149 |
--------------------------------------------------------------------------------
/app/utils/cx.ts:
--------------------------------------------------------------------------------
1 | export const cx = (...classes: (string | undefined | null | false)[]): string => {
2 | return classes.filter(Boolean).join(' ')
3 | }
4 |
--------------------------------------------------------------------------------
/components.json:
--------------------------------------------------------------------------------
1 | {
2 | "$schema": "https://ui.shadcn.com/schema.json",
3 | "style": "default",
4 | "rsc": true,
5 | "tsx": true,
6 | "tailwind": {
7 | "config": "tailwind.config.ts",
8 | "css": "app/globals.css",
9 | "baseColor": "neutral",
10 | "cssVariables": true,
11 | "prefix": ""
12 | },
13 | "aliases": {
14 | "components": "@/components",
15 | "utils": "@/lib/utils",
16 | "ui": "@/components/ui",
17 | "lib": "@/lib",
18 | "hooks": "@/hooks"
19 | },
20 | "iconLibrary": "lucide"
21 | }
--------------------------------------------------------------------------------
/components/transition/slide-transition.tsx:
--------------------------------------------------------------------------------
1 | 'use client'
2 |
3 | import { unstable_ViewTransition as ViewTransition } from 'react'
4 | import { cx } from '@/app/utils/cx'
5 |
6 | export function SlideTransition({
7 | name,
8 | children,
9 | direction = 'horizontal',
10 | distance = 100,
11 | duration = 200,
12 | }: {
13 | name: string
14 | children: React.ReactNode
15 | direction?: 'horizontal' | 'vertical'
16 | distance?: number
17 | duration?: number
18 | }) {
19 | const isHorizontal = direction === 'horizontal'
20 | const startName = isHorizontal ? 'left' : 'up'
21 | const endName = isHorizontal ? 'right' : 'down'
22 | const startPosition = isHorizontal ? `-${distance}px 0` : `0 ${distance}px`
23 | const endPosition = isHorizontal ? `${distance}px 0` : `0 100%`
24 |
25 | return (
26 | <>
27 |
59 |
60 | {children}
61 |
62 | >
63 | )
64 | }
65 |
--------------------------------------------------------------------------------
/components/ui/avatar.tsx:
--------------------------------------------------------------------------------
1 | "use client"
2 |
3 | import * as React from "react"
4 | import * as AvatarPrimitive from "@radix-ui/react-avatar"
5 |
6 | import { cn } from "@/lib/utils"
7 |
8 | const Avatar = React.forwardRef<
9 | React.ElementRef,
10 | React.ComponentPropsWithoutRef
11 | >(({ className, ...props }, ref) => (
12 |
20 | ))
21 | Avatar.displayName = AvatarPrimitive.Root.displayName
22 |
23 | const AvatarImage = React.forwardRef<
24 | React.ElementRef,
25 | React.ComponentPropsWithoutRef
26 | >(({ className, ...props }, ref) => (
27 |
32 | ))
33 | AvatarImage.displayName = AvatarPrimitive.Image.displayName
34 |
35 | const AvatarFallback = React.forwardRef<
36 | React.ElementRef,
37 | React.ComponentPropsWithoutRef
38 | >(({ className, ...props }, ref) => (
39 |
47 | ))
48 | AvatarFallback.displayName = AvatarPrimitive.Fallback.displayName
49 |
50 | export { Avatar, AvatarImage, AvatarFallback }
51 |
--------------------------------------------------------------------------------
/components/ui/button.tsx:
--------------------------------------------------------------------------------
1 | import * as React from "react"
2 | import { Slot } from "@radix-ui/react-slot"
3 | import { cva, type VariantProps } from "class-variance-authority"
4 |
5 | import { cn } from "@/lib/utils"
6 |
7 | const buttonVariants = cva(
8 | "inline-flex items-center justify-center gap-2 whitespace-nowrap rounded-md text-sm font-medium ring-offset-background transition-colors focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2 disabled:pointer-events-none disabled:opacity-50 [&_svg]:pointer-events-none [&_svg]:size-4 [&_svg]:shrink-0",
9 | {
10 | variants: {
11 | variant: {
12 | default: "bg-primary text-primary-foreground hover:bg-primary/90",
13 | destructive:
14 | "bg-destructive text-destructive-foreground hover:bg-destructive/90",
15 | outline:
16 | "border border-input bg-background hover:bg-accent hover:text-accent-foreground",
17 | secondary:
18 | "bg-secondary text-secondary-foreground hover:bg-secondary/80",
19 | ghost: "hover:bg-accent hover:text-accent-foreground",
20 | link: "text-primary underline-offset-4 hover:underline",
21 | },
22 | size: {
23 | default: "h-10 px-4 py-2",
24 | sm: "h-9 rounded-md px-3",
25 | lg: "h-11 rounded-md px-8",
26 | icon: "h-10 w-10",
27 | },
28 | },
29 | defaultVariants: {
30 | variant: "default",
31 | size: "default",
32 | },
33 | }
34 | )
35 |
36 | export interface ButtonProps
37 | extends React.ButtonHTMLAttributes,
38 | VariantProps {
39 | asChild?: boolean
40 | }
41 |
42 | const Button = React.forwardRef(
43 | ({ className, variant, size, asChild = false, ...props }, ref) => {
44 | const Comp = asChild ? Slot : "button"
45 | return (
46 |
51 | )
52 | }
53 | )
54 | Button.displayName = "Button"
55 |
56 | export { Button, buttonVariants }
57 |
--------------------------------------------------------------------------------
/components/ui/card.tsx:
--------------------------------------------------------------------------------
1 | import * as React from "react"
2 |
3 | import { cn } from "@/lib/utils"
4 |
5 | const Card = React.forwardRef<
6 | HTMLDivElement,
7 | React.HTMLAttributes
8 | >(({ className, ...props }, ref) => (
9 |
17 | ))
18 | Card.displayName = "Card"
19 |
20 | const CardHeader = React.forwardRef<
21 | HTMLDivElement,
22 | React.HTMLAttributes
23 | >(({ className, ...props }, ref) => (
24 |
29 | ))
30 | CardHeader.displayName = "CardHeader"
31 |
32 | const CardTitle = React.forwardRef<
33 | HTMLDivElement,
34 | React.HTMLAttributes
35 | >(({ className, ...props }, ref) => (
36 |
44 | ))
45 | CardTitle.displayName = "CardTitle"
46 |
47 | const CardDescription = React.forwardRef<
48 | HTMLDivElement,
49 | React.HTMLAttributes
50 | >(({ className, ...props }, ref) => (
51 |
56 | ))
57 | CardDescription.displayName = "CardDescription"
58 |
59 | const CardContent = React.forwardRef<
60 | HTMLDivElement,
61 | React.HTMLAttributes
62 | >(({ className, ...props }, ref) => (
63 |
64 | ))
65 | CardContent.displayName = "CardContent"
66 |
67 | const CardFooter = React.forwardRef<
68 | HTMLDivElement,
69 | React.HTMLAttributes
70 | >(({ className, ...props }, ref) => (
71 |
76 | ))
77 | CardFooter.displayName = "CardFooter"
78 |
79 | export { Card, CardHeader, CardFooter, CardTitle, CardDescription, CardContent }
80 |
--------------------------------------------------------------------------------
/components/ui/dynamic-background.tsx:
--------------------------------------------------------------------------------
1 | import { cx } from '@/app/utils/cx'
2 |
3 | export function DynamicBackground({ className }: { className?: string }) {
4 | return (
5 |
11 | )
12 | }
13 |
--------------------------------------------------------------------------------
/lib/utils.ts:
--------------------------------------------------------------------------------
1 | import { clsx, type ClassValue } from "clsx"
2 | import { twMerge } from "tailwind-merge"
3 |
4 | export function cn(...inputs: ClassValue[]) {
5 | return twMerge(clsx(inputs))
6 | }
7 |
--------------------------------------------------------------------------------
/next.config.ts:
--------------------------------------------------------------------------------
1 | import type { NextConfig } from 'next'
2 |
3 | const nextConfig: NextConfig = {
4 | experimental: {
5 | viewTransition: true,
6 | },
7 | }
8 |
9 | export default nextConfig
10 |
--------------------------------------------------------------------------------
/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "next-view-transition-example",
3 | "private": true,
4 | "scripts": {
5 | "dev": "next dev",
6 | "build": "next build",
7 | "start": "next start",
8 | "lint": "next lint"
9 | },
10 | "dependencies": {
11 | "@radix-ui/react-avatar": "^1.1.3",
12 | "@radix-ui/react-slot": "^1.1.2",
13 | "class-variance-authority": "^0.7.1",
14 | "clsx": "^2.1.1",
15 | "lucide-react": "^0.477.0",
16 | "next": "15.3.1-canary.15",
17 | "react": "^19.0.0",
18 | "react-dom": "^19.0.0",
19 | "tailwind-merge": "^3.0.2",
20 | "tailwindcss-animate": "^1.0.7"
21 | },
22 | "devDependencies": {
23 | "@tailwindcss/postcss": "^4.0.9",
24 | "@types/node": "^22",
25 | "@types/react": "^19",
26 | "@types/react-dom": "^19",
27 | "tailwindcss": "^4.0.9",
28 | "typescript": "^5"
29 | },
30 | "packageManager": "pnpm@9.15.4"
31 | }
32 |
--------------------------------------------------------------------------------
/pnpm-lock.yaml:
--------------------------------------------------------------------------------
1 | lockfileVersion: '9.0'
2 |
3 | settings:
4 | autoInstallPeers: true
5 | excludeLinksFromLockfile: false
6 |
7 | importers:
8 |
9 | .:
10 | dependencies:
11 | '@radix-ui/react-avatar':
12 | specifier: ^1.1.3
13 | version: 1.1.3(@types/react-dom@19.0.4(@types/react@19.0.10))(@types/react@19.0.10)(react-dom@19.0.0(react@19.0.0))(react@19.0.0)
14 | '@radix-ui/react-slot':
15 | specifier: ^1.1.2
16 | version: 1.1.2(@types/react@19.0.10)(react@19.0.0)
17 | class-variance-authority:
18 | specifier: ^0.7.1
19 | version: 0.7.1
20 | clsx:
21 | specifier: ^2.1.1
22 | version: 2.1.1
23 | lucide-react:
24 | specifier: ^0.477.0
25 | version: 0.477.0(react@19.0.0)
26 | next:
27 | specifier: 15.3.1-canary.15
28 | version: 15.3.1-canary.15(react-dom@19.0.0(react@19.0.0))(react@19.0.0)
29 | react:
30 | specifier: ^19.0.0
31 | version: 19.0.0
32 | react-dom:
33 | specifier: ^19.0.0
34 | version: 19.0.0(react@19.0.0)
35 | tailwind-merge:
36 | specifier: ^3.0.2
37 | version: 3.0.2
38 | tailwindcss-animate:
39 | specifier: ^1.0.7
40 | version: 1.0.7(tailwindcss@4.0.9)
41 | devDependencies:
42 | '@tailwindcss/postcss':
43 | specifier: ^4.0.9
44 | version: 4.0.9
45 | '@types/node':
46 | specifier: ^22
47 | version: 22.13.8
48 | '@types/react':
49 | specifier: ^19
50 | version: 19.0.10
51 | '@types/react-dom':
52 | specifier: ^19
53 | version: 19.0.4(@types/react@19.0.10)
54 | tailwindcss:
55 | specifier: ^4.0.9
56 | version: 4.0.9
57 | typescript:
58 | specifier: ^5
59 | version: 5.8.2
60 |
61 | packages:
62 |
63 | '@alloc/quick-lru@5.2.0':
64 | resolution: {integrity: sha512-UrcABB+4bUrFABwbluTIBErXwvbsU/V7TZWfmbgJfbkwiBuziS9gxdODUyuiecfdGQ85jglMW6juS3+z5TsKLw==}
65 | engines: {node: '>=10'}
66 |
67 | '@emnapi/runtime@1.4.3':
68 | resolution: {integrity: sha512-pBPWdu6MLKROBX05wSNKcNb++m5Er+KQ9QkB+WVM+pW2Kx9hoSrVTnu3BdkI5eBLZoKu/J6mW/B6i6bJB2ytXQ==}
69 |
70 | '@img/sharp-darwin-arm64@0.34.1':
71 | resolution: {integrity: sha512-pn44xgBtgpEbZsu+lWf2KNb6OAf70X68k+yk69Ic2Xz11zHR/w24/U49XT7AeRwJ0Px+mhALhU5LPci1Aymk7A==}
72 | engines: {node: ^18.17.0 || ^20.3.0 || >=21.0.0}
73 | cpu: [arm64]
74 | os: [darwin]
75 |
76 | '@img/sharp-darwin-x64@0.34.1':
77 | resolution: {integrity: sha512-VfuYgG2r8BpYiOUN+BfYeFo69nP/MIwAtSJ7/Zpxc5QF3KS22z8Pvg3FkrSFJBPNQ7mmcUcYQFBmEQp7eu1F8Q==}
78 | engines: {node: ^18.17.0 || ^20.3.0 || >=21.0.0}
79 | cpu: [x64]
80 | os: [darwin]
81 |
82 | '@img/sharp-libvips-darwin-arm64@1.1.0':
83 | resolution: {integrity: sha512-HZ/JUmPwrJSoM4DIQPv/BfNh9yrOA8tlBbqbLz4JZ5uew2+o22Ik+tHQJcih7QJuSa0zo5coHTfD5J8inqj9DA==}
84 | cpu: [arm64]
85 | os: [darwin]
86 |
87 | '@img/sharp-libvips-darwin-x64@1.1.0':
88 | resolution: {integrity: sha512-Xzc2ToEmHN+hfvsl9wja0RlnXEgpKNmftriQp6XzY/RaSfwD9th+MSh0WQKzUreLKKINb3afirxW7A0fz2YWuQ==}
89 | cpu: [x64]
90 | os: [darwin]
91 |
92 | '@img/sharp-libvips-linux-arm64@1.1.0':
93 | resolution: {integrity: sha512-IVfGJa7gjChDET1dK9SekxFFdflarnUB8PwW8aGwEoF3oAsSDuNUTYS+SKDOyOJxQyDC1aPFMuRYLoDInyV9Ew==}
94 | cpu: [arm64]
95 | os: [linux]
96 |
97 | '@img/sharp-libvips-linux-arm@1.1.0':
98 | resolution: {integrity: sha512-s8BAd0lwUIvYCJyRdFqvsj+BJIpDBSxs6ivrOPm/R7piTs5UIwY5OjXrP2bqXC9/moGsyRa37eYWYCOGVXxVrA==}
99 | cpu: [arm]
100 | os: [linux]
101 |
102 | '@img/sharp-libvips-linux-ppc64@1.1.0':
103 | resolution: {integrity: sha512-tiXxFZFbhnkWE2LA8oQj7KYR+bWBkiV2nilRldT7bqoEZ4HiDOcePr9wVDAZPi/Id5fT1oY9iGnDq20cwUz8lQ==}
104 | cpu: [ppc64]
105 | os: [linux]
106 |
107 | '@img/sharp-libvips-linux-s390x@1.1.0':
108 | resolution: {integrity: sha512-xukSwvhguw7COyzvmjydRb3x/09+21HykyapcZchiCUkTThEQEOMtBj9UhkaBRLuBrgLFzQ2wbxdeCCJW/jgJA==}
109 | cpu: [s390x]
110 | os: [linux]
111 |
112 | '@img/sharp-libvips-linux-x64@1.1.0':
113 | resolution: {integrity: sha512-yRj2+reB8iMg9W5sULM3S74jVS7zqSzHG3Ol/twnAAkAhnGQnpjj6e4ayUz7V+FpKypwgs82xbRdYtchTTUB+Q==}
114 | cpu: [x64]
115 | os: [linux]
116 |
117 | '@img/sharp-libvips-linuxmusl-arm64@1.1.0':
118 | resolution: {integrity: sha512-jYZdG+whg0MDK+q2COKbYidaqW/WTz0cc1E+tMAusiDygrM4ypmSCjOJPmFTvHHJ8j/6cAGyeDWZOsK06tP33w==}
119 | cpu: [arm64]
120 | os: [linux]
121 |
122 | '@img/sharp-libvips-linuxmusl-x64@1.1.0':
123 | resolution: {integrity: sha512-wK7SBdwrAiycjXdkPnGCPLjYb9lD4l6Ze2gSdAGVZrEL05AOUJESWU2lhlC+Ffn5/G+VKuSm6zzbQSzFX/P65A==}
124 | cpu: [x64]
125 | os: [linux]
126 |
127 | '@img/sharp-linux-arm64@0.34.1':
128 | resolution: {integrity: sha512-kX2c+vbvaXC6vly1RDf/IWNXxrlxLNpBVWkdpRq5Ka7OOKj6nr66etKy2IENf6FtOgklkg9ZdGpEu9kwdlcwOQ==}
129 | engines: {node: ^18.17.0 || ^20.3.0 || >=21.0.0}
130 | cpu: [arm64]
131 | os: [linux]
132 |
133 | '@img/sharp-linux-arm@0.34.1':
134 | resolution: {integrity: sha512-anKiszvACti2sGy9CirTlNyk7BjjZPiML1jt2ZkTdcvpLU1YH6CXwRAZCA2UmRXnhiIftXQ7+Oh62Ji25W72jA==}
135 | engines: {node: ^18.17.0 || ^20.3.0 || >=21.0.0}
136 | cpu: [arm]
137 | os: [linux]
138 |
139 | '@img/sharp-linux-s390x@0.34.1':
140 | resolution: {integrity: sha512-7s0KX2tI9mZI2buRipKIw2X1ufdTeaRgwmRabt5bi9chYfhur+/C1OXg3TKg/eag1W+6CCWLVmSauV1owmRPxA==}
141 | engines: {node: ^18.17.0 || ^20.3.0 || >=21.0.0}
142 | cpu: [s390x]
143 | os: [linux]
144 |
145 | '@img/sharp-linux-x64@0.34.1':
146 | resolution: {integrity: sha512-wExv7SH9nmoBW3Wr2gvQopX1k8q2g5V5Iag8Zk6AVENsjwd+3adjwxtp3Dcu2QhOXr8W9NusBU6XcQUohBZ5MA==}
147 | engines: {node: ^18.17.0 || ^20.3.0 || >=21.0.0}
148 | cpu: [x64]
149 | os: [linux]
150 |
151 | '@img/sharp-linuxmusl-arm64@0.34.1':
152 | resolution: {integrity: sha512-DfvyxzHxw4WGdPiTF0SOHnm11Xv4aQexvqhRDAoD00MzHekAj9a/jADXeXYCDFH/DzYruwHbXU7uz+H+nWmSOQ==}
153 | engines: {node: ^18.17.0 || ^20.3.0 || >=21.0.0}
154 | cpu: [arm64]
155 | os: [linux]
156 |
157 | '@img/sharp-linuxmusl-x64@0.34.1':
158 | resolution: {integrity: sha512-pax/kTR407vNb9qaSIiWVnQplPcGU8LRIJpDT5o8PdAx5aAA7AS3X9PS8Isw1/WfqgQorPotjrZL3Pqh6C5EBg==}
159 | engines: {node: ^18.17.0 || ^20.3.0 || >=21.0.0}
160 | cpu: [x64]
161 | os: [linux]
162 |
163 | '@img/sharp-wasm32@0.34.1':
164 | resolution: {integrity: sha512-YDybQnYrLQfEpzGOQe7OKcyLUCML4YOXl428gOOzBgN6Gw0rv8dpsJ7PqTHxBnXnwXr8S1mYFSLSa727tpz0xg==}
165 | engines: {node: ^18.17.0 || ^20.3.0 || >=21.0.0}
166 | cpu: [wasm32]
167 |
168 | '@img/sharp-win32-ia32@0.34.1':
169 | resolution: {integrity: sha512-WKf/NAZITnonBf3U1LfdjoMgNO5JYRSlhovhRhMxXVdvWYveM4kM3L8m35onYIdh75cOMCo1BexgVQcCDzyoWw==}
170 | engines: {node: ^18.17.0 || ^20.3.0 || >=21.0.0}
171 | cpu: [ia32]
172 | os: [win32]
173 |
174 | '@img/sharp-win32-x64@0.34.1':
175 | resolution: {integrity: sha512-hw1iIAHpNE8q3uMIRCgGOeDoz9KtFNarFLQclLxr/LK1VBkj8nby18RjFvr6aP7USRYAjTZW6yisnBWMX571Tw==}
176 | engines: {node: ^18.17.0 || ^20.3.0 || >=21.0.0}
177 | cpu: [x64]
178 | os: [win32]
179 |
180 | '@next/env@15.3.1-canary.15':
181 | resolution: {integrity: sha512-68oU7HJBCSeEp9ESMvrCSTKJN45s9ck7ZC/32x/HW9RfT8zr2osBiuOp4z2GYA+h+nUPu2oElfMpq7AamYR4Dw==}
182 |
183 | '@next/swc-darwin-arm64@15.3.1-canary.15':
184 | resolution: {integrity: sha512-OQCjX6Vte2k5OAPrWhPRtox2XnY1PwTvdr+bFVVrru6MSRbAqJW09u4GYK65at7hhILiAAMyhCk6yTq46beUaw==}
185 | engines: {node: '>= 10'}
186 | cpu: [arm64]
187 | os: [darwin]
188 |
189 | '@next/swc-darwin-x64@15.3.1-canary.15':
190 | resolution: {integrity: sha512-KXP4QtAQKMJJ9yD9ALgvfdhZlOvSrHjh86dBaCn4pdnBQspyuv8bdvVFVQ72VBIKI/hi1I7Oy1tgNNz3YX1vxA==}
191 | engines: {node: '>= 10'}
192 | cpu: [x64]
193 | os: [darwin]
194 |
195 | '@next/swc-linux-arm64-gnu@15.3.1-canary.15':
196 | resolution: {integrity: sha512-BuM+AzhU7ujlZguFArh55L3lseAyu6IpS6aZNAcM0mx+ug9hl3/K5DYEofr5hl36j6g4S04N6JMC2u9ThHlTbg==}
197 | engines: {node: '>= 10'}
198 | cpu: [arm64]
199 | os: [linux]
200 |
201 | '@next/swc-linux-arm64-musl@15.3.1-canary.15':
202 | resolution: {integrity: sha512-PqVdd1NhheFnVheEfAFdZGx2glpsoKG4Vjd2pl2MkCf/MEqUYFdzBtAaOcBlir1HN7eI2y7FixUbpjFQu2m7gg==}
203 | engines: {node: '>= 10'}
204 | cpu: [arm64]
205 | os: [linux]
206 |
207 | '@next/swc-linux-x64-gnu@15.3.1-canary.15':
208 | resolution: {integrity: sha512-JbtEqPbZoeWtpsDNwJxps+P24RKPQpE7eK8hRK7kGf9x2tAVVQZdOVVGjnzYC8WIibGi0FgXT7Q3UqtI5gR7JA==}
209 | engines: {node: '>= 10'}
210 | cpu: [x64]
211 | os: [linux]
212 |
213 | '@next/swc-linux-x64-musl@15.3.1-canary.15':
214 | resolution: {integrity: sha512-b8k1IIKSUYCsZFQFEr3iLskRDBATCc5lcpDRje2Z7PYV1Oe7vOzmf5gmtknn6YZdyFV1qNRhf9hHl6l4NPgyaw==}
215 | engines: {node: '>= 10'}
216 | cpu: [x64]
217 | os: [linux]
218 |
219 | '@next/swc-win32-arm64-msvc@15.3.1-canary.15':
220 | resolution: {integrity: sha512-I5SL0FCHiEfcewsTpxMGZoIu1sE5BLgUWiJbtqdkByfnAaP9XVIzaeBvW1IRBmNFjAcJmqwDTZtcKlsOTVHh+Q==}
221 | engines: {node: '>= 10'}
222 | cpu: [arm64]
223 | os: [win32]
224 |
225 | '@next/swc-win32-x64-msvc@15.3.1-canary.15':
226 | resolution: {integrity: sha512-2HkLFhKDJI3Y6LYMUHUgNmsKDpssVlfWQTxXEBoYOmaoX1A5R3OjZKnnKjjiRnppKC0rrP97dTgMnzN+e1tQew==}
227 | engines: {node: '>= 10'}
228 | cpu: [x64]
229 | os: [win32]
230 |
231 | '@radix-ui/react-avatar@1.1.3':
232 | resolution: {integrity: sha512-Paen00T4P8L8gd9bNsRMw7Cbaz85oxiv+hzomsRZgFm2byltPFDtfcoqlWJ8GyZlIBWgLssJlzLCnKU0G0302g==}
233 | peerDependencies:
234 | '@types/react': '*'
235 | '@types/react-dom': '*'
236 | react: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc
237 | react-dom: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc
238 | peerDependenciesMeta:
239 | '@types/react':
240 | optional: true
241 | '@types/react-dom':
242 | optional: true
243 |
244 | '@radix-ui/react-compose-refs@1.1.1':
245 | resolution: {integrity: sha512-Y9VzoRDSJtgFMUCoiZBDVo084VQ5hfpXxVE+NgkdNsjiDBByiImMZKKhxMwCbdHvhlENG6a833CbFkOQvTricw==}
246 | peerDependencies:
247 | '@types/react': '*'
248 | react: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc
249 | peerDependenciesMeta:
250 | '@types/react':
251 | optional: true
252 |
253 | '@radix-ui/react-context@1.1.1':
254 | resolution: {integrity: sha512-UASk9zi+crv9WteK/NU4PLvOoL3OuE6BWVKNF6hPRBtYBDXQ2u5iu3O59zUlJiTVvkyuycnqrztsHVJwcK9K+Q==}
255 | peerDependencies:
256 | '@types/react': '*'
257 | react: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc
258 | peerDependenciesMeta:
259 | '@types/react':
260 | optional: true
261 |
262 | '@radix-ui/react-primitive@2.0.2':
263 | resolution: {integrity: sha512-Ec/0d38EIuvDF+GZjcMU/Ze6MxntVJYO/fRlCPhCaVUyPY9WTalHJw54tp9sXeJo3tlShWpy41vQRgLRGOuz+w==}
264 | peerDependencies:
265 | '@types/react': '*'
266 | '@types/react-dom': '*'
267 | react: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc
268 | react-dom: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc
269 | peerDependenciesMeta:
270 | '@types/react':
271 | optional: true
272 | '@types/react-dom':
273 | optional: true
274 |
275 | '@radix-ui/react-slot@1.1.2':
276 | resolution: {integrity: sha512-YAKxaiGsSQJ38VzKH86/BPRC4rh+b1Jpa+JneA5LRE7skmLPNAyeG8kPJj/oo4STLvlrs8vkf/iYyc3A5stYCQ==}
277 | peerDependencies:
278 | '@types/react': '*'
279 | react: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc
280 | peerDependenciesMeta:
281 | '@types/react':
282 | optional: true
283 |
284 | '@radix-ui/react-use-callback-ref@1.1.0':
285 | resolution: {integrity: sha512-CasTfvsy+frcFkbXtSJ2Zu9JHpN8TYKxkgJGWbjiZhFivxaeW7rMeZt7QELGVLaYVfFMsKHjb7Ak0nMEe+2Vfw==}
286 | peerDependencies:
287 | '@types/react': '*'
288 | react: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc
289 | peerDependenciesMeta:
290 | '@types/react':
291 | optional: true
292 |
293 | '@radix-ui/react-use-layout-effect@1.1.0':
294 | resolution: {integrity: sha512-+FPE0rOdziWSrH9athwI1R0HDVbWlEhd+FR+aSDk4uWGmSJ9Z54sdZVDQPZAinJhJXwfT+qnj969mCsT2gfm5w==}
295 | peerDependencies:
296 | '@types/react': '*'
297 | react: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc
298 | peerDependenciesMeta:
299 | '@types/react':
300 | optional: true
301 |
302 | '@swc/counter@0.1.3':
303 | resolution: {integrity: sha512-e2BR4lsJkkRlKZ/qCHPw9ZaSxc0MVUd7gtbtaB7aMvHeJVYe8sOB8DBZkP2DtISHGSku9sCK6T6cnY0CtXrOCQ==}
304 |
305 | '@swc/helpers@0.5.15':
306 | resolution: {integrity: sha512-JQ5TuMi45Owi4/BIMAJBoSQoOJu12oOk/gADqlcUL9JEdHB8vyjUSsxqeNXnmXHjYKMi2WcYtezGEEhqUI/E2g==}
307 |
308 | '@tailwindcss/node@4.0.9':
309 | resolution: {integrity: sha512-tOJvdI7XfJbARYhxX+0RArAhmuDcczTC46DGCEziqxzzbIaPnfYaIyRT31n4u8lROrsO7Q6u/K9bmQHL2uL1bQ==}
310 |
311 | '@tailwindcss/oxide-android-arm64@4.0.9':
312 | resolution: {integrity: sha512-YBgy6+2flE/8dbtrdotVInhMVIxnHJPbAwa7U1gX4l2ThUIaPUp18LjB9wEH8wAGMBZUb//SzLtdXXNBHPUl6Q==}
313 | engines: {node: '>= 10'}
314 | cpu: [arm64]
315 | os: [android]
316 |
317 | '@tailwindcss/oxide-darwin-arm64@4.0.9':
318 | resolution: {integrity: sha512-pWdl4J2dIHXALgy2jVkwKBmtEb73kqIfMpYmcgESr7oPQ+lbcQ4+tlPeVXaSAmang+vglAfFpXQCOvs/aGSqlw==}
319 | engines: {node: '>= 10'}
320 | cpu: [arm64]
321 | os: [darwin]
322 |
323 | '@tailwindcss/oxide-darwin-x64@4.0.9':
324 | resolution: {integrity: sha512-4Dq3lKp0/C7vrRSkNPtBGVebEyWt9QPPlQctxJ0H3MDyiQYvzVYf8jKow7h5QkWNe8hbatEqljMj/Y0M+ERYJg==}
325 | engines: {node: '>= 10'}
326 | cpu: [x64]
327 | os: [darwin]
328 |
329 | '@tailwindcss/oxide-freebsd-x64@4.0.9':
330 | resolution: {integrity: sha512-k7U1RwRODta8x0uealtVt3RoWAWqA+D5FAOsvVGpYoI6ObgmnzqWW6pnVwz70tL8UZ/QXjeMyiICXyjzB6OGtQ==}
331 | engines: {node: '>= 10'}
332 | cpu: [x64]
333 | os: [freebsd]
334 |
335 | '@tailwindcss/oxide-linux-arm-gnueabihf@4.0.9':
336 | resolution: {integrity: sha512-NDDjVweHz2zo4j+oS8y3KwKL5wGCZoXGA9ruJM982uVJLdsF8/1AeKvUwKRlMBpxHt1EdWJSAh8a0Mfhl28GlQ==}
337 | engines: {node: '>= 10'}
338 | cpu: [arm]
339 | os: [linux]
340 |
341 | '@tailwindcss/oxide-linux-arm64-gnu@4.0.9':
342 | resolution: {integrity: sha512-jk90UZ0jzJl3Dy1BhuFfRZ2KP9wVKMXPjmCtY4U6fF2LvrjP5gWFJj5VHzfzHonJexjrGe1lMzgtjriuZkxagg==}
343 | engines: {node: '>= 10'}
344 | cpu: [arm64]
345 | os: [linux]
346 |
347 | '@tailwindcss/oxide-linux-arm64-musl@4.0.9':
348 | resolution: {integrity: sha512-3eMjyTC6HBxh9nRgOHzrc96PYh1/jWOwHZ3Kk0JN0Kl25BJ80Lj9HEvvwVDNTgPg154LdICwuFLuhfgH9DULmg==}
349 | engines: {node: '>= 10'}
350 | cpu: [arm64]
351 | os: [linux]
352 |
353 | '@tailwindcss/oxide-linux-x64-gnu@4.0.9':
354 | resolution: {integrity: sha512-v0D8WqI/c3WpWH1kq/HP0J899ATLdGZmENa2/emmNjubT0sWtEke9W9+wXeEoACuGAhF9i3PO5MeyditpDCiWQ==}
355 | engines: {node: '>= 10'}
356 | cpu: [x64]
357 | os: [linux]
358 |
359 | '@tailwindcss/oxide-linux-x64-musl@4.0.9':
360 | resolution: {integrity: sha512-Kvp0TCkfeXyeehqLJr7otsc4hd/BUPfcIGrQiwsTVCfaMfjQZCG7DjI+9/QqPZha8YapLA9UoIcUILRYO7NE1Q==}
361 | engines: {node: '>= 10'}
362 | cpu: [x64]
363 | os: [linux]
364 |
365 | '@tailwindcss/oxide-win32-arm64-msvc@4.0.9':
366 | resolution: {integrity: sha512-m3+60T/7YvWekajNq/eexjhV8z10rswcz4BC9bioJ7YaN+7K8W2AmLmG0B79H14m6UHE571qB0XsPus4n0QVgQ==}
367 | engines: {node: '>= 10'}
368 | cpu: [arm64]
369 | os: [win32]
370 |
371 | '@tailwindcss/oxide-win32-x64-msvc@4.0.9':
372 | resolution: {integrity: sha512-dpc05mSlqkwVNOUjGu/ZXd5U1XNch1kHFJ4/cHkZFvaW1RzbHmRt24gvM8/HC6IirMxNarzVw4IXVtvrOoZtxA==}
373 | engines: {node: '>= 10'}
374 | cpu: [x64]
375 | os: [win32]
376 |
377 | '@tailwindcss/oxide@4.0.9':
378 | resolution: {integrity: sha512-eLizHmXFqHswJONwfqi/WZjtmWZpIalpvMlNhTM99/bkHtUs6IqgI1XQ0/W5eO2HiRQcIlXUogI2ycvKhVLNcA==}
379 | engines: {node: '>= 10'}
380 |
381 | '@tailwindcss/postcss@4.0.9':
382 | resolution: {integrity: sha512-BT/E+pdMqulavEAVM5NCpxmGEwHiLDPpkmg/c/X25ZBW+izTe+aZ+v1gf/HXTrihRoCxrUp5U4YyHsBTzspQKQ==}
383 |
384 | '@types/node@22.13.8':
385 | resolution: {integrity: sha512-G3EfaZS+iOGYWLLRCEAXdWK9my08oHNZ+FHluRiggIYJPOXzhOiDgpVCUHaUvyIC5/fj7C/p637jdzC666AOKQ==}
386 |
387 | '@types/react-dom@19.0.4':
388 | resolution: {integrity: sha512-4fSQ8vWFkg+TGhePfUzVmat3eC14TXYSsiiDSLI0dVLsrm9gZFABjPy/Qu6TKgl1tq1Bu1yDsuQgY3A3DOjCcg==}
389 | peerDependencies:
390 | '@types/react': ^19.0.0
391 |
392 | '@types/react@19.0.10':
393 | resolution: {integrity: sha512-JuRQ9KXLEjaUNjTWpzuR231Z2WpIwczOkBEIvbHNCzQefFIT0L8IqE6NV6ULLyC1SI/i234JnDoMkfg+RjQj2g==}
394 |
395 | busboy@1.6.0:
396 | resolution: {integrity: sha512-8SFQbg/0hQ9xy3UNTB0YEnsNBbWfhf7RtnzpL7TkBiTBRfrQ9Fxcnz7VJsleJpyp6rVLvXiuORqjlHi5q+PYuA==}
397 | engines: {node: '>=10.16.0'}
398 |
399 | caniuse-lite@1.0.30001701:
400 | resolution: {integrity: sha512-faRs/AW3jA9nTwmJBSO1PQ6L/EOgsB5HMQQq4iCu5zhPgVVgO/pZRHlmatwijZKetFw8/Pr4q6dEN8sJuq8qTw==}
401 |
402 | class-variance-authority@0.7.1:
403 | resolution: {integrity: sha512-Ka+9Trutv7G8M6WT6SeiRWz792K5qEqIGEGzXKhAE6xOWAY6pPH8U+9IY3oCMv6kqTmLsv7Xh/2w2RigkePMsg==}
404 |
405 | client-only@0.0.1:
406 | resolution: {integrity: sha512-IV3Ou0jSMzZrd3pZ48nLkT9DA7Ag1pnPzaiQhpW7c3RbcqqzvzzVu+L8gfqMp/8IM2MQtSiqaCxrrcfu8I8rMA==}
407 |
408 | clsx@2.1.1:
409 | resolution: {integrity: sha512-eYm0QWBtUrBWZWG0d386OGAw16Z995PiOVo2B7bjWSbHedGl5e0ZWaq65kOGgUSNesEIDkB9ISbTg/JK9dhCZA==}
410 | engines: {node: '>=6'}
411 |
412 | color-convert@2.0.1:
413 | resolution: {integrity: sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==}
414 | engines: {node: '>=7.0.0'}
415 |
416 | color-name@1.1.4:
417 | resolution: {integrity: sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==}
418 |
419 | color-string@1.9.1:
420 | resolution: {integrity: sha512-shrVawQFojnZv6xM40anx4CkoDP+fZsw/ZerEMsW/pyzsRbElpsL/DBVW7q3ExxwusdNXI3lXpuhEZkzs8p5Eg==}
421 |
422 | color@4.2.3:
423 | resolution: {integrity: sha512-1rXeuUUiGGrykh+CeBdu5Ie7OJwinCgQY0bc7GCRxy5xVHy+moaqkpL/jqQq0MtQOeYcrqEz4abc5f0KtU7W4A==}
424 | engines: {node: '>=12.5.0'}
425 |
426 | csstype@3.1.3:
427 | resolution: {integrity: sha512-M1uQkMl8rQK/szD0LNhtqxIPLpimGm8sOBwU7lLnCpSbTyY3yeU1Vc7l4KT5zT4s/yOxHH5O7tIuuLOCnLADRw==}
428 |
429 | detect-libc@1.0.3:
430 | resolution: {integrity: sha512-pGjwhsmsp4kL2RTz08wcOlGN83otlqHeD/Z5T8GXZB+/YcpQ/dgo+lbU8ZsGxV0HIvqqxo9l7mqYwyYMD9bKDg==}
431 | engines: {node: '>=0.10'}
432 | hasBin: true
433 |
434 | detect-libc@2.0.3:
435 | resolution: {integrity: sha512-bwy0MGW55bG41VqxxypOsdSdGqLwXPI/focwgTYCFMbdUiBAxLg9CFzG08sz2aqzknwiX7Hkl0bQENjg8iLByw==}
436 | engines: {node: '>=8'}
437 |
438 | enhanced-resolve@5.18.1:
439 | resolution: {integrity: sha512-ZSW3ma5GkcQBIpwZTSRAI8N71Uuwgs93IezB7mf7R60tC8ZbJideoDNKjHn2O9KIlx6rkGTTEk1xUCK2E1Y2Yg==}
440 | engines: {node: '>=10.13.0'}
441 |
442 | graceful-fs@4.2.11:
443 | resolution: {integrity: sha512-RbJ5/jmFcNNCcDV5o9eTnBLJ/HszWV0P73bc+Ff4nS/rJj+YaS6IGyiOL0VoBYX+l1Wrl3k63h/KrH+nhJ0XvQ==}
444 |
445 | is-arrayish@0.3.2:
446 | resolution: {integrity: sha512-eVRqCvVlZbuw3GrM63ovNSNAeA1K16kaR/LRY/92w0zxQ5/1YzwblUX652i4Xs9RwAGjW9d9y6X88t8OaAJfWQ==}
447 |
448 | jiti@2.4.2:
449 | resolution: {integrity: sha512-rg9zJN+G4n2nfJl5MW3BMygZX56zKPNVEYYqq7adpmMh4Jn2QNEwhvQlFy6jPVdcod7txZtKHWnyZiA3a0zP7A==}
450 | hasBin: true
451 |
452 | lightningcss-darwin-arm64@1.29.1:
453 | resolution: {integrity: sha512-HtR5XJ5A0lvCqYAoSv2QdZZyoHNttBpa5EP9aNuzBQeKGfbyH5+UipLWvVzpP4Uml5ej4BYs5I9Lco9u1fECqw==}
454 | engines: {node: '>= 12.0.0'}
455 | cpu: [arm64]
456 | os: [darwin]
457 |
458 | lightningcss-darwin-x64@1.29.1:
459 | resolution: {integrity: sha512-k33G9IzKUpHy/J/3+9MCO4e+PzaFblsgBjSGlpAaFikeBFm8B/CkO3cKU9oI4g+fjS2KlkLM/Bza9K/aw8wsNA==}
460 | engines: {node: '>= 12.0.0'}
461 | cpu: [x64]
462 | os: [darwin]
463 |
464 | lightningcss-freebsd-x64@1.29.1:
465 | resolution: {integrity: sha512-0SUW22fv/8kln2LnIdOCmSuXnxgxVC276W5KLTwoehiO0hxkacBxjHOL5EtHD8BAXg2BvuhsJPmVMasvby3LiQ==}
466 | engines: {node: '>= 12.0.0'}
467 | cpu: [x64]
468 | os: [freebsd]
469 |
470 | lightningcss-linux-arm-gnueabihf@1.29.1:
471 | resolution: {integrity: sha512-sD32pFvlR0kDlqsOZmYqH/68SqUMPNj+0pucGxToXZi4XZgZmqeX/NkxNKCPsswAXU3UeYgDSpGhu05eAufjDg==}
472 | engines: {node: '>= 12.0.0'}
473 | cpu: [arm]
474 | os: [linux]
475 |
476 | lightningcss-linux-arm64-gnu@1.29.1:
477 | resolution: {integrity: sha512-0+vClRIZ6mmJl/dxGuRsE197o1HDEeeRk6nzycSy2GofC2JsY4ifCRnvUWf/CUBQmlrvMzt6SMQNMSEu22csWQ==}
478 | engines: {node: '>= 12.0.0'}
479 | cpu: [arm64]
480 | os: [linux]
481 |
482 | lightningcss-linux-arm64-musl@1.29.1:
483 | resolution: {integrity: sha512-UKMFrG4rL/uHNgelBsDwJcBqVpzNJbzsKkbI3Ja5fg00sgQnHw/VrzUTEc4jhZ+AN2BvQYz/tkHu4vt1kLuJyw==}
484 | engines: {node: '>= 12.0.0'}
485 | cpu: [arm64]
486 | os: [linux]
487 |
488 | lightningcss-linux-x64-gnu@1.29.1:
489 | resolution: {integrity: sha512-u1S+xdODy/eEtjADqirA774y3jLcm8RPtYztwReEXoZKdzgsHYPl0s5V52Tst+GKzqjebkULT86XMSxejzfISw==}
490 | engines: {node: '>= 12.0.0'}
491 | cpu: [x64]
492 | os: [linux]
493 |
494 | lightningcss-linux-x64-musl@1.29.1:
495 | resolution: {integrity: sha512-L0Tx0DtaNUTzXv0lbGCLB/c/qEADanHbu4QdcNOXLIe1i8i22rZRpbT3gpWYsCh9aSL9zFujY/WmEXIatWvXbw==}
496 | engines: {node: '>= 12.0.0'}
497 | cpu: [x64]
498 | os: [linux]
499 |
500 | lightningcss-win32-arm64-msvc@1.29.1:
501 | resolution: {integrity: sha512-QoOVnkIEFfbW4xPi+dpdft/zAKmgLgsRHfJalEPYuJDOWf7cLQzYg0DEh8/sn737FaeMJxHZRc1oBreiwZCjog==}
502 | engines: {node: '>= 12.0.0'}
503 | cpu: [arm64]
504 | os: [win32]
505 |
506 | lightningcss-win32-x64-msvc@1.29.1:
507 | resolution: {integrity: sha512-NygcbThNBe4JElP+olyTI/doBNGJvLs3bFCRPdvuCcxZCcCZ71B858IHpdm7L1btZex0FvCmM17FK98Y9MRy1Q==}
508 | engines: {node: '>= 12.0.0'}
509 | cpu: [x64]
510 | os: [win32]
511 |
512 | lightningcss@1.29.1:
513 | resolution: {integrity: sha512-FmGoeD4S05ewj+AkhTY+D+myDvXI6eL27FjHIjoyUkO/uw7WZD1fBVs0QxeYWa7E17CUHJaYX/RUGISCtcrG4Q==}
514 | engines: {node: '>= 12.0.0'}
515 |
516 | lucide-react@0.477.0:
517 | resolution: {integrity: sha512-yCf7aYxerFZAbd8jHJxjwe1j7jEMPptjnaOqdYeirFnEy85cNR3/L+o0I875CYFYya+eEVzZSbNuRk8BZPDpVw==}
518 | peerDependencies:
519 | react: ^16.5.1 || ^17.0.0 || ^18.0.0 || ^19.0.0
520 |
521 | nanoid@3.3.8:
522 | resolution: {integrity: sha512-WNLf5Sd8oZxOm+TzppcYk8gVOgP+l58xNy58D0nbUnOxOWRWvlcCV4kUF7ltmI6PsrLl/BgKEyS4mqsGChFN0w==}
523 | engines: {node: ^10 || ^12 || ^13.7 || ^14 || >=15.0.1}
524 | hasBin: true
525 |
526 | next@15.3.1-canary.15:
527 | resolution: {integrity: sha512-K04SKrZ+HKrx1+rma4y9nfxilL5HnQ5KiL0biKwyQyhiG5xFLUqaHGzpiYflbWW+ufJWejk3cJJkhK/DUuB37Q==}
528 | engines: {node: ^18.18.0 || ^19.8.0 || >= 20.0.0}
529 | hasBin: true
530 | peerDependencies:
531 | '@opentelemetry/api': ^1.1.0
532 | '@playwright/test': ^1.41.2
533 | babel-plugin-react-compiler: '*'
534 | react: ^18.2.0 || 19.0.0-rc-de68d2f4-20241204 || ^19.0.0
535 | react-dom: ^18.2.0 || 19.0.0-rc-de68d2f4-20241204 || ^19.0.0
536 | sass: ^1.3.0
537 | peerDependenciesMeta:
538 | '@opentelemetry/api':
539 | optional: true
540 | '@playwright/test':
541 | optional: true
542 | babel-plugin-react-compiler:
543 | optional: true
544 | sass:
545 | optional: true
546 |
547 | picocolors@1.1.1:
548 | resolution: {integrity: sha512-xceH2snhtb5M9liqDsmEw56le376mTZkEX/jEb/RxNFyegNul7eNslCXP9FDj/Lcu0X8KEyMceP2ntpaHrDEVA==}
549 |
550 | postcss@8.4.31:
551 | resolution: {integrity: sha512-PS08Iboia9mts/2ygV3eLpY5ghnUcfLV/EXTOW1E2qYxJKGGBUtNjN76FYHnMs36RmARn41bC0AZmn+rR0OVpQ==}
552 | engines: {node: ^10 || ^12 || >=14}
553 |
554 | postcss@8.5.3:
555 | resolution: {integrity: sha512-dle9A3yYxlBSrt8Fu+IpjGT8SY8hN0mlaA6GY8t0P5PjIOZemULz/E2Bnm/2dcUOena75OTNkHI76uZBNUUq3A==}
556 | engines: {node: ^10 || ^12 || >=14}
557 |
558 | react-dom@19.0.0:
559 | resolution: {integrity: sha512-4GV5sHFG0e/0AD4X+ySy6UJd3jVl1iNsNHdpad0qhABJ11twS3TTBnseqsKurKcsNqCEFeGL3uLpVChpIO3QfQ==}
560 | peerDependencies:
561 | react: ^19.0.0
562 |
563 | react@19.0.0:
564 | resolution: {integrity: sha512-V8AVnmPIICiWpGfm6GLzCR/W5FXLchHop40W4nXBmdlEceh16rCN8O8LNWm5bh5XUX91fh7KpA+W0TgMKmgTpQ==}
565 | engines: {node: '>=0.10.0'}
566 |
567 | scheduler@0.25.0:
568 | resolution: {integrity: sha512-xFVuu11jh+xcO7JOAGJNOXld8/TcEHK/4CituBUeUb5hqxJLj9YuemAEuvm9gQ/+pgXYfbQuqAkiYu+u7YEsNA==}
569 |
570 | semver@7.7.1:
571 | resolution: {integrity: sha512-hlq8tAfn0m/61p4BVRcPzIGr6LKiMwo4VM6dGi6pt4qcRkmNzTcWq6eCEjEh+qXjkMDvPlOFFSGwQjoEa6gyMA==}
572 | engines: {node: '>=10'}
573 | hasBin: true
574 |
575 | sharp@0.34.1:
576 | resolution: {integrity: sha512-1j0w61+eVxu7DawFJtnfYcvSv6qPFvfTaqzTQ2BLknVhHTwGS8sc63ZBF4rzkWMBVKybo4S5OBtDdZahh2A1xg==}
577 | engines: {node: ^18.17.0 || ^20.3.0 || >=21.0.0}
578 |
579 | simple-swizzle@0.2.2:
580 | resolution: {integrity: sha512-JA//kQgZtbuY83m+xT+tXJkmJncGMTFT+C+g2h2R9uxkYIrE2yy9sgmcLhCnw57/WSD+Eh3J97FPEDFnbXnDUg==}
581 |
582 | source-map-js@1.2.1:
583 | resolution: {integrity: sha512-UXWMKhLOwVKb728IUtQPXxfYU+usdybtUrK/8uGE8CQMvrhOpwvzDBwj0QhSL7MQc7vIsISBG8VQ8+IDQxpfQA==}
584 | engines: {node: '>=0.10.0'}
585 |
586 | streamsearch@1.1.0:
587 | resolution: {integrity: sha512-Mcc5wHehp9aXz1ax6bZUyY5afg9u2rv5cqQI3mRrYkGC8rW2hM02jWuwjtL++LS5qinSyhj2QfLyNsuc+VsExg==}
588 | engines: {node: '>=10.0.0'}
589 |
590 | styled-jsx@5.1.6:
591 | resolution: {integrity: sha512-qSVyDTeMotdvQYoHWLNGwRFJHC+i+ZvdBRYosOFgC+Wg1vx4frN2/RG/NA7SYqqvKNLf39P2LSRA2pu6n0XYZA==}
592 | engines: {node: '>= 12.0.0'}
593 | peerDependencies:
594 | '@babel/core': '*'
595 | babel-plugin-macros: '*'
596 | react: '>= 16.8.0 || 17.x.x || ^18.0.0-0 || ^19.0.0-0'
597 | peerDependenciesMeta:
598 | '@babel/core':
599 | optional: true
600 | babel-plugin-macros:
601 | optional: true
602 |
603 | tailwind-merge@3.0.2:
604 | resolution: {integrity: sha512-l7z+OYZ7mu3DTqrL88RiKrKIqO3NcpEO8V/Od04bNpvk0kiIFndGEoqfuzvj4yuhRkHKjRkII2z+KS2HfPcSxw==}
605 |
606 | tailwindcss-animate@1.0.7:
607 | resolution: {integrity: sha512-bl6mpH3T7I3UFxuvDEXLxy/VuFxBk5bbzplh7tXI68mwMokNYd1t9qPBHlnyTwfa4JGC4zP516I1hYYtQ/vspA==}
608 | peerDependencies:
609 | tailwindcss: '>=3.0.0 || insiders'
610 |
611 | tailwindcss@4.0.9:
612 | resolution: {integrity: sha512-12laZu+fv1ONDRoNR9ipTOpUD7RN9essRVkX36sjxuRUInpN7hIiHN4lBd/SIFjbISvnXzp8h/hXzmU8SQQYhw==}
613 |
614 | tapable@2.2.1:
615 | resolution: {integrity: sha512-GNzQvQTOIP6RyTfE2Qxb8ZVlNmw0n88vp1szwWRimP02mnTsx3Wtn5qRdqY9w2XduFNUgvOwhNnQsjwCp+kqaQ==}
616 | engines: {node: '>=6'}
617 |
618 | tslib@2.8.1:
619 | resolution: {integrity: sha512-oJFu94HQb+KVduSUQL7wnpmqnfmLsOA/nAh6b6EH0wCEoK0/mPeXU6c3wKDV83MkOuHPRHtSXKKU99IBazS/2w==}
620 |
621 | typescript@5.8.2:
622 | resolution: {integrity: sha512-aJn6wq13/afZp/jT9QZmwEjDqqvSGp1VT5GVg+f/t6/oVyrgXM6BY1h9BRh/O5p3PlUPAe+WuiEZOmb/49RqoQ==}
623 | engines: {node: '>=14.17'}
624 | hasBin: true
625 |
626 | undici-types@6.20.0:
627 | resolution: {integrity: sha512-Ny6QZ2Nju20vw1SRHe3d9jVu6gJ+4e3+MMpqu7pqE5HT6WsTSlce++GQmK5UXS8mzV8DSYHrQH+Xrf2jVcuKNg==}
628 |
629 | snapshots:
630 |
631 | '@alloc/quick-lru@5.2.0': {}
632 |
633 | '@emnapi/runtime@1.4.3':
634 | dependencies:
635 | tslib: 2.8.1
636 | optional: true
637 |
638 | '@img/sharp-darwin-arm64@0.34.1':
639 | optionalDependencies:
640 | '@img/sharp-libvips-darwin-arm64': 1.1.0
641 | optional: true
642 |
643 | '@img/sharp-darwin-x64@0.34.1':
644 | optionalDependencies:
645 | '@img/sharp-libvips-darwin-x64': 1.1.0
646 | optional: true
647 |
648 | '@img/sharp-libvips-darwin-arm64@1.1.0':
649 | optional: true
650 |
651 | '@img/sharp-libvips-darwin-x64@1.1.0':
652 | optional: true
653 |
654 | '@img/sharp-libvips-linux-arm64@1.1.0':
655 | optional: true
656 |
657 | '@img/sharp-libvips-linux-arm@1.1.0':
658 | optional: true
659 |
660 | '@img/sharp-libvips-linux-ppc64@1.1.0':
661 | optional: true
662 |
663 | '@img/sharp-libvips-linux-s390x@1.1.0':
664 | optional: true
665 |
666 | '@img/sharp-libvips-linux-x64@1.1.0':
667 | optional: true
668 |
669 | '@img/sharp-libvips-linuxmusl-arm64@1.1.0':
670 | optional: true
671 |
672 | '@img/sharp-libvips-linuxmusl-x64@1.1.0':
673 | optional: true
674 |
675 | '@img/sharp-linux-arm64@0.34.1':
676 | optionalDependencies:
677 | '@img/sharp-libvips-linux-arm64': 1.1.0
678 | optional: true
679 |
680 | '@img/sharp-linux-arm@0.34.1':
681 | optionalDependencies:
682 | '@img/sharp-libvips-linux-arm': 1.1.0
683 | optional: true
684 |
685 | '@img/sharp-linux-s390x@0.34.1':
686 | optionalDependencies:
687 | '@img/sharp-libvips-linux-s390x': 1.1.0
688 | optional: true
689 |
690 | '@img/sharp-linux-x64@0.34.1':
691 | optionalDependencies:
692 | '@img/sharp-libvips-linux-x64': 1.1.0
693 | optional: true
694 |
695 | '@img/sharp-linuxmusl-arm64@0.34.1':
696 | optionalDependencies:
697 | '@img/sharp-libvips-linuxmusl-arm64': 1.1.0
698 | optional: true
699 |
700 | '@img/sharp-linuxmusl-x64@0.34.1':
701 | optionalDependencies:
702 | '@img/sharp-libvips-linuxmusl-x64': 1.1.0
703 | optional: true
704 |
705 | '@img/sharp-wasm32@0.34.1':
706 | dependencies:
707 | '@emnapi/runtime': 1.4.3
708 | optional: true
709 |
710 | '@img/sharp-win32-ia32@0.34.1':
711 | optional: true
712 |
713 | '@img/sharp-win32-x64@0.34.1':
714 | optional: true
715 |
716 | '@next/env@15.3.1-canary.15': {}
717 |
718 | '@next/swc-darwin-arm64@15.3.1-canary.15':
719 | optional: true
720 |
721 | '@next/swc-darwin-x64@15.3.1-canary.15':
722 | optional: true
723 |
724 | '@next/swc-linux-arm64-gnu@15.3.1-canary.15':
725 | optional: true
726 |
727 | '@next/swc-linux-arm64-musl@15.3.1-canary.15':
728 | optional: true
729 |
730 | '@next/swc-linux-x64-gnu@15.3.1-canary.15':
731 | optional: true
732 |
733 | '@next/swc-linux-x64-musl@15.3.1-canary.15':
734 | optional: true
735 |
736 | '@next/swc-win32-arm64-msvc@15.3.1-canary.15':
737 | optional: true
738 |
739 | '@next/swc-win32-x64-msvc@15.3.1-canary.15':
740 | optional: true
741 |
742 | '@radix-ui/react-avatar@1.1.3(@types/react-dom@19.0.4(@types/react@19.0.10))(@types/react@19.0.10)(react-dom@19.0.0(react@19.0.0))(react@19.0.0)':
743 | dependencies:
744 | '@radix-ui/react-context': 1.1.1(@types/react@19.0.10)(react@19.0.0)
745 | '@radix-ui/react-primitive': 2.0.2(@types/react-dom@19.0.4(@types/react@19.0.10))(@types/react@19.0.10)(react-dom@19.0.0(react@19.0.0))(react@19.0.0)
746 | '@radix-ui/react-use-callback-ref': 1.1.0(@types/react@19.0.10)(react@19.0.0)
747 | '@radix-ui/react-use-layout-effect': 1.1.0(@types/react@19.0.10)(react@19.0.0)
748 | react: 19.0.0
749 | react-dom: 19.0.0(react@19.0.0)
750 | optionalDependencies:
751 | '@types/react': 19.0.10
752 | '@types/react-dom': 19.0.4(@types/react@19.0.10)
753 |
754 | '@radix-ui/react-compose-refs@1.1.1(@types/react@19.0.10)(react@19.0.0)':
755 | dependencies:
756 | react: 19.0.0
757 | optionalDependencies:
758 | '@types/react': 19.0.10
759 |
760 | '@radix-ui/react-context@1.1.1(@types/react@19.0.10)(react@19.0.0)':
761 | dependencies:
762 | react: 19.0.0
763 | optionalDependencies:
764 | '@types/react': 19.0.10
765 |
766 | '@radix-ui/react-primitive@2.0.2(@types/react-dom@19.0.4(@types/react@19.0.10))(@types/react@19.0.10)(react-dom@19.0.0(react@19.0.0))(react@19.0.0)':
767 | dependencies:
768 | '@radix-ui/react-slot': 1.1.2(@types/react@19.0.10)(react@19.0.0)
769 | react: 19.0.0
770 | react-dom: 19.0.0(react@19.0.0)
771 | optionalDependencies:
772 | '@types/react': 19.0.10
773 | '@types/react-dom': 19.0.4(@types/react@19.0.10)
774 |
775 | '@radix-ui/react-slot@1.1.2(@types/react@19.0.10)(react@19.0.0)':
776 | dependencies:
777 | '@radix-ui/react-compose-refs': 1.1.1(@types/react@19.0.10)(react@19.0.0)
778 | react: 19.0.0
779 | optionalDependencies:
780 | '@types/react': 19.0.10
781 |
782 | '@radix-ui/react-use-callback-ref@1.1.0(@types/react@19.0.10)(react@19.0.0)':
783 | dependencies:
784 | react: 19.0.0
785 | optionalDependencies:
786 | '@types/react': 19.0.10
787 |
788 | '@radix-ui/react-use-layout-effect@1.1.0(@types/react@19.0.10)(react@19.0.0)':
789 | dependencies:
790 | react: 19.0.0
791 | optionalDependencies:
792 | '@types/react': 19.0.10
793 |
794 | '@swc/counter@0.1.3': {}
795 |
796 | '@swc/helpers@0.5.15':
797 | dependencies:
798 | tslib: 2.8.1
799 |
800 | '@tailwindcss/node@4.0.9':
801 | dependencies:
802 | enhanced-resolve: 5.18.1
803 | jiti: 2.4.2
804 | tailwindcss: 4.0.9
805 |
806 | '@tailwindcss/oxide-android-arm64@4.0.9':
807 | optional: true
808 |
809 | '@tailwindcss/oxide-darwin-arm64@4.0.9':
810 | optional: true
811 |
812 | '@tailwindcss/oxide-darwin-x64@4.0.9':
813 | optional: true
814 |
815 | '@tailwindcss/oxide-freebsd-x64@4.0.9':
816 | optional: true
817 |
818 | '@tailwindcss/oxide-linux-arm-gnueabihf@4.0.9':
819 | optional: true
820 |
821 | '@tailwindcss/oxide-linux-arm64-gnu@4.0.9':
822 | optional: true
823 |
824 | '@tailwindcss/oxide-linux-arm64-musl@4.0.9':
825 | optional: true
826 |
827 | '@tailwindcss/oxide-linux-x64-gnu@4.0.9':
828 | optional: true
829 |
830 | '@tailwindcss/oxide-linux-x64-musl@4.0.9':
831 | optional: true
832 |
833 | '@tailwindcss/oxide-win32-arm64-msvc@4.0.9':
834 | optional: true
835 |
836 | '@tailwindcss/oxide-win32-x64-msvc@4.0.9':
837 | optional: true
838 |
839 | '@tailwindcss/oxide@4.0.9':
840 | optionalDependencies:
841 | '@tailwindcss/oxide-android-arm64': 4.0.9
842 | '@tailwindcss/oxide-darwin-arm64': 4.0.9
843 | '@tailwindcss/oxide-darwin-x64': 4.0.9
844 | '@tailwindcss/oxide-freebsd-x64': 4.0.9
845 | '@tailwindcss/oxide-linux-arm-gnueabihf': 4.0.9
846 | '@tailwindcss/oxide-linux-arm64-gnu': 4.0.9
847 | '@tailwindcss/oxide-linux-arm64-musl': 4.0.9
848 | '@tailwindcss/oxide-linux-x64-gnu': 4.0.9
849 | '@tailwindcss/oxide-linux-x64-musl': 4.0.9
850 | '@tailwindcss/oxide-win32-arm64-msvc': 4.0.9
851 | '@tailwindcss/oxide-win32-x64-msvc': 4.0.9
852 |
853 | '@tailwindcss/postcss@4.0.9':
854 | dependencies:
855 | '@alloc/quick-lru': 5.2.0
856 | '@tailwindcss/node': 4.0.9
857 | '@tailwindcss/oxide': 4.0.9
858 | lightningcss: 1.29.1
859 | postcss: 8.5.3
860 | tailwindcss: 4.0.9
861 |
862 | '@types/node@22.13.8':
863 | dependencies:
864 | undici-types: 6.20.0
865 |
866 | '@types/react-dom@19.0.4(@types/react@19.0.10)':
867 | dependencies:
868 | '@types/react': 19.0.10
869 |
870 | '@types/react@19.0.10':
871 | dependencies:
872 | csstype: 3.1.3
873 |
874 | busboy@1.6.0:
875 | dependencies:
876 | streamsearch: 1.1.0
877 |
878 | caniuse-lite@1.0.30001701: {}
879 |
880 | class-variance-authority@0.7.1:
881 | dependencies:
882 | clsx: 2.1.1
883 |
884 | client-only@0.0.1: {}
885 |
886 | clsx@2.1.1: {}
887 |
888 | color-convert@2.0.1:
889 | dependencies:
890 | color-name: 1.1.4
891 | optional: true
892 |
893 | color-name@1.1.4:
894 | optional: true
895 |
896 | color-string@1.9.1:
897 | dependencies:
898 | color-name: 1.1.4
899 | simple-swizzle: 0.2.2
900 | optional: true
901 |
902 | color@4.2.3:
903 | dependencies:
904 | color-convert: 2.0.1
905 | color-string: 1.9.1
906 | optional: true
907 |
908 | csstype@3.1.3: {}
909 |
910 | detect-libc@1.0.3: {}
911 |
912 | detect-libc@2.0.3:
913 | optional: true
914 |
915 | enhanced-resolve@5.18.1:
916 | dependencies:
917 | graceful-fs: 4.2.11
918 | tapable: 2.2.1
919 |
920 | graceful-fs@4.2.11: {}
921 |
922 | is-arrayish@0.3.2:
923 | optional: true
924 |
925 | jiti@2.4.2: {}
926 |
927 | lightningcss-darwin-arm64@1.29.1:
928 | optional: true
929 |
930 | lightningcss-darwin-x64@1.29.1:
931 | optional: true
932 |
933 | lightningcss-freebsd-x64@1.29.1:
934 | optional: true
935 |
936 | lightningcss-linux-arm-gnueabihf@1.29.1:
937 | optional: true
938 |
939 | lightningcss-linux-arm64-gnu@1.29.1:
940 | optional: true
941 |
942 | lightningcss-linux-arm64-musl@1.29.1:
943 | optional: true
944 |
945 | lightningcss-linux-x64-gnu@1.29.1:
946 | optional: true
947 |
948 | lightningcss-linux-x64-musl@1.29.1:
949 | optional: true
950 |
951 | lightningcss-win32-arm64-msvc@1.29.1:
952 | optional: true
953 |
954 | lightningcss-win32-x64-msvc@1.29.1:
955 | optional: true
956 |
957 | lightningcss@1.29.1:
958 | dependencies:
959 | detect-libc: 1.0.3
960 | optionalDependencies:
961 | lightningcss-darwin-arm64: 1.29.1
962 | lightningcss-darwin-x64: 1.29.1
963 | lightningcss-freebsd-x64: 1.29.1
964 | lightningcss-linux-arm-gnueabihf: 1.29.1
965 | lightningcss-linux-arm64-gnu: 1.29.1
966 | lightningcss-linux-arm64-musl: 1.29.1
967 | lightningcss-linux-x64-gnu: 1.29.1
968 | lightningcss-linux-x64-musl: 1.29.1
969 | lightningcss-win32-arm64-msvc: 1.29.1
970 | lightningcss-win32-x64-msvc: 1.29.1
971 |
972 | lucide-react@0.477.0(react@19.0.0):
973 | dependencies:
974 | react: 19.0.0
975 |
976 | nanoid@3.3.8: {}
977 |
978 | next@15.3.1-canary.15(react-dom@19.0.0(react@19.0.0))(react@19.0.0):
979 | dependencies:
980 | '@next/env': 15.3.1-canary.15
981 | '@swc/counter': 0.1.3
982 | '@swc/helpers': 0.5.15
983 | busboy: 1.6.0
984 | caniuse-lite: 1.0.30001701
985 | postcss: 8.4.31
986 | react: 19.0.0
987 | react-dom: 19.0.0(react@19.0.0)
988 | styled-jsx: 5.1.6(react@19.0.0)
989 | optionalDependencies:
990 | '@next/swc-darwin-arm64': 15.3.1-canary.15
991 | '@next/swc-darwin-x64': 15.3.1-canary.15
992 | '@next/swc-linux-arm64-gnu': 15.3.1-canary.15
993 | '@next/swc-linux-arm64-musl': 15.3.1-canary.15
994 | '@next/swc-linux-x64-gnu': 15.3.1-canary.15
995 | '@next/swc-linux-x64-musl': 15.3.1-canary.15
996 | '@next/swc-win32-arm64-msvc': 15.3.1-canary.15
997 | '@next/swc-win32-x64-msvc': 15.3.1-canary.15
998 | sharp: 0.34.1
999 | transitivePeerDependencies:
1000 | - '@babel/core'
1001 | - babel-plugin-macros
1002 |
1003 | picocolors@1.1.1: {}
1004 |
1005 | postcss@8.4.31:
1006 | dependencies:
1007 | nanoid: 3.3.8
1008 | picocolors: 1.1.1
1009 | source-map-js: 1.2.1
1010 |
1011 | postcss@8.5.3:
1012 | dependencies:
1013 | nanoid: 3.3.8
1014 | picocolors: 1.1.1
1015 | source-map-js: 1.2.1
1016 |
1017 | react-dom@19.0.0(react@19.0.0):
1018 | dependencies:
1019 | react: 19.0.0
1020 | scheduler: 0.25.0
1021 |
1022 | react@19.0.0: {}
1023 |
1024 | scheduler@0.25.0: {}
1025 |
1026 | semver@7.7.1:
1027 | optional: true
1028 |
1029 | sharp@0.34.1:
1030 | dependencies:
1031 | color: 4.2.3
1032 | detect-libc: 2.0.3
1033 | semver: 7.7.1
1034 | optionalDependencies:
1035 | '@img/sharp-darwin-arm64': 0.34.1
1036 | '@img/sharp-darwin-x64': 0.34.1
1037 | '@img/sharp-libvips-darwin-arm64': 1.1.0
1038 | '@img/sharp-libvips-darwin-x64': 1.1.0
1039 | '@img/sharp-libvips-linux-arm': 1.1.0
1040 | '@img/sharp-libvips-linux-arm64': 1.1.0
1041 | '@img/sharp-libvips-linux-ppc64': 1.1.0
1042 | '@img/sharp-libvips-linux-s390x': 1.1.0
1043 | '@img/sharp-libvips-linux-x64': 1.1.0
1044 | '@img/sharp-libvips-linuxmusl-arm64': 1.1.0
1045 | '@img/sharp-libvips-linuxmusl-x64': 1.1.0
1046 | '@img/sharp-linux-arm': 0.34.1
1047 | '@img/sharp-linux-arm64': 0.34.1
1048 | '@img/sharp-linux-s390x': 0.34.1
1049 | '@img/sharp-linux-x64': 0.34.1
1050 | '@img/sharp-linuxmusl-arm64': 0.34.1
1051 | '@img/sharp-linuxmusl-x64': 0.34.1
1052 | '@img/sharp-wasm32': 0.34.1
1053 | '@img/sharp-win32-ia32': 0.34.1
1054 | '@img/sharp-win32-x64': 0.34.1
1055 | optional: true
1056 |
1057 | simple-swizzle@0.2.2:
1058 | dependencies:
1059 | is-arrayish: 0.3.2
1060 | optional: true
1061 |
1062 | source-map-js@1.2.1: {}
1063 |
1064 | streamsearch@1.1.0: {}
1065 |
1066 | styled-jsx@5.1.6(react@19.0.0):
1067 | dependencies:
1068 | client-only: 0.0.1
1069 | react: 19.0.0
1070 |
1071 | tailwind-merge@3.0.2: {}
1072 |
1073 | tailwindcss-animate@1.0.7(tailwindcss@4.0.9):
1074 | dependencies:
1075 | tailwindcss: 4.0.9
1076 |
1077 | tailwindcss@4.0.9: {}
1078 |
1079 | tapable@2.2.1: {}
1080 |
1081 | tslib@2.8.1: {}
1082 |
1083 | typescript@5.8.2: {}
1084 |
1085 | undici-types@6.20.0: {}
1086 |
--------------------------------------------------------------------------------
/postcss.config.mjs:
--------------------------------------------------------------------------------
1 | const config = {
2 | plugins: ["@tailwindcss/postcss"],
3 | };
4 |
5 | export default config;
6 |
--------------------------------------------------------------------------------
/public/avatars/feedthejim.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/vercel/next-view-transition-example/9d21a7b8ace73bb67aa1b301570f3a0cae405d70/public/avatars/feedthejim.jpg
--------------------------------------------------------------------------------
/public/avatars/huozhi.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/vercel/next-view-transition-example/9d21a7b8ace73bb67aa1b301570f3a0cae405d70/public/avatars/huozhi.jpg
--------------------------------------------------------------------------------
/public/avatars/leerob.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/vercel/next-view-transition-example/9d21a7b8ace73bb67aa1b301570f3a0cae405d70/public/avatars/leerob.jpg
--------------------------------------------------------------------------------
/public/avatars/sebmarkbage.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/vercel/next-view-transition-example/9d21a7b8ace73bb67aa1b301570f3a0cae405d70/public/avatars/sebmarkbage.jpg
--------------------------------------------------------------------------------
/public/avatars/ztanner.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/vercel/next-view-transition-example/9d21a7b8ace73bb67aa1b301570f3a0cae405d70/public/avatars/ztanner.jpg
--------------------------------------------------------------------------------
/public/cards/barcelona.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/vercel/next-view-transition-example/9d21a7b8ace73bb67aa1b301570f3a0cae405d70/public/cards/barcelona.png
--------------------------------------------------------------------------------
/public/cards/florence.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/vercel/next-view-transition-example/9d21a7b8ace73bb67aa1b301570f3a0cae405d70/public/cards/florence.png
--------------------------------------------------------------------------------
/public/cards/santamonica.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/vercel/next-view-transition-example/9d21a7b8ace73bb67aa1b301570f3a0cae405d70/public/cards/santamonica.png
--------------------------------------------------------------------------------
/public/cards/xian.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/vercel/next-view-transition-example/9d21a7b8ace73bb67aa1b301570f3a0cae405d70/public/cards/xian.png
--------------------------------------------------------------------------------
/public/post/composable-caching-with-nextjs.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/vercel/next-view-transition-example/9d21a7b8ace73bb67aa1b301570f3a0cae405d70/public/post/composable-caching-with-nextjs.png
--------------------------------------------------------------------------------
/tailwind.config.ts:
--------------------------------------------------------------------------------
1 | import type { Config } from "tailwindcss";
2 |
3 | const config: Config = {
4 | content: [
5 | "./pages/**/*.{js,ts,jsx,tsx,mdx}",
6 | "./components/**/*.{js,ts,jsx,tsx,mdx}",
7 | "./app/**/*.{js,ts,jsx,tsx,mdx}",
8 | ],
9 | theme: {
10 | extend: {
11 | colors: {
12 | background: 'hsl(var(--background))',
13 | foreground: 'hsl(var(--foreground))',
14 | card: {
15 | DEFAULT: 'hsl(var(--card))',
16 | foreground: 'hsl(var(--card-foreground))'
17 | },
18 | popover: {
19 | DEFAULT: 'hsl(var(--popover))',
20 | foreground: 'hsl(var(--popover-foreground))'
21 | },
22 | primary: {
23 | DEFAULT: 'hsl(var(--primary))',
24 | foreground: 'hsl(var(--primary-foreground))'
25 | },
26 | secondary: {
27 | DEFAULT: 'hsl(var(--secondary))',
28 | foreground: 'hsl(var(--secondary-foreground))'
29 | },
30 | muted: {
31 | DEFAULT: 'hsl(var(--muted))',
32 | foreground: 'hsl(var(--muted-foreground))'
33 | },
34 | accent: {
35 | DEFAULT: 'hsl(var(--accent))',
36 | foreground: 'hsl(var(--accent-foreground))'
37 | },
38 | destructive: {
39 | DEFAULT: 'hsl(var(--destructive))',
40 | foreground: 'hsl(var(--destructive-foreground))'
41 | },
42 | border: 'hsl(var(--border))',
43 | input: 'hsl(var(--input))',
44 | ring: 'hsl(var(--ring))',
45 | chart: {
46 | '1': 'hsl(var(--chart-1))',
47 | '2': 'hsl(var(--chart-2))',
48 | '3': 'hsl(var(--chart-3))',
49 | '4': 'hsl(var(--chart-4))',
50 | '5': 'hsl(var(--chart-5))'
51 | }
52 | },
53 | borderRadius: {
54 | lg: 'var(--radius)',
55 | md: 'calc(var(--radius) - 2px)',
56 | sm: 'calc(var(--radius) - 4px)'
57 | }
58 | }
59 | },
60 | plugins: [require("tailwindcss-animate")],
61 | };
62 | export default config;
63 |
--------------------------------------------------------------------------------
/tsconfig.json:
--------------------------------------------------------------------------------
1 | {
2 | "compilerOptions": {
3 | "target": "ES2017",
4 | "lib": ["dom", "dom.iterable", "esnext"],
5 | "allowJs": true,
6 | "skipLibCheck": true,
7 | "strict": true,
8 | "noEmit": true,
9 | "esModuleInterop": true,
10 | "module": "esnext",
11 | "moduleResolution": "bundler",
12 | "resolveJsonModule": true,
13 | "isolatedModules": true,
14 | "jsx": "preserve",
15 | "incremental": true,
16 | "plugins": [
17 | {
18 | "name": "next"
19 | }
20 | ],
21 | "paths": {
22 | "@/*": ["./*"]
23 | }
24 | },
25 | "include": ["next-env.d.ts", "**/*.ts", "**/*.tsx", ".next/types/**/*.ts"],
26 | "exclude": ["node_modules"]
27 | }
28 |
--------------------------------------------------------------------------------