ギャラリー/

カラムギャラリー

Preview

左右2カラムにスタガード配置されたポートフォリオギャラリー。カラム間のオフセットでリズム感を演出

Source Code
tsx
191 lines
1export function GalleryColumns001() {
2 const projects = [
3 {
4 title: "ブランド戦略デザイン",
5 category: "ブランディング",
6 number: "01",
7 },
8 {
9 title: "ウェブプラットフォーム",
10 category: "プロダクトデザイン",
11 number: "02",
12 },
13 {
14 title: "ビジュアルシステム",
15 category: "アイデンティティ",
16 number: "03",
17 },
18 {
19 title: "デジタルエクスペリエンス",
20 category: "ウェブデザイン",
21 number: "04",
22 },
23 {
24 title: "コマースプラットフォーム",
25 category: "アプリデザイン",
26 number: "05",
27 },
28 {
29 title: "クリエイティブキャンペーン",
30 category: "ブランディング",
31 number: "06",
32 },
33 {
34 title: "モバイルインターフェース",
35 category: "プロダクトデザイン",
36 number: "07",
37 },
38 {
39 title: "エディトリアルデザイン",
40 category: "ウェブデザイン",
41 number: "08",
42 },
43 ];
44
45 const leftColumn = projects.filter((_, i) => i % 2 === 0);
46 const rightColumn = projects.filter((_, i) => i % 2 === 1);
47
48 return (
49 <section className="bg-background py-28">
50 <div className="mx-auto max-w-6xl px-4 sm:px-6 lg:px-8">
51 {/* ヘッダー */}
52 <div className="mb-6 flex flex-col gap-6 sm:flex-row sm:items-end sm:justify-between">
53 <div>
54 <p className="text-[10px] uppercase tracking-[0.3em] text-muted-foreground">
55 Selected Work
56 </p>
57 <h2 className="mt-3 text-2xl font-medium tracking-wide text-foreground sm:text-3xl">
58 プロジェクト
59 </h2>
60 </div>
61 <p className="max-w-xs text-sm font-light leading-relaxed text-muted-foreground">
62 厳選したプロジェクトを、2カラムのレイアウトでご紹介します。
63 </p>
64 </div>
65
66 <div className="h-px bg-border/40" />
67
68 {/* 2カラムギャラリー */}
69 <div className="mt-14 grid grid-cols-1 gap-x-8 gap-y-10 sm:grid-cols-2">
70 {/* 左カラム */}
71 <div className="flex flex-col gap-10">
72 {leftColumn.map((project, i) => (
73 <div key={i} className="group">
74 <div className="relative aspect-[4/5] overflow-hidden border border-border bg-muted">
75 <div className="absolute inset-0 bg-gradient-to-br from-foreground/[0.02] to-foreground/[0.07] transition-all duration-500 group-hover:from-foreground/[0.05] group-hover:to-foreground/[0.11]" />
76 <div className="absolute left-4 top-4 h-1.5 w-1.5 rounded-full bg-foreground/20" />
77 <div className="absolute right-4 top-4 h-1.5 w-1.5 rounded-full bg-foreground/20" />
78 <div className="absolute bottom-4 left-4">
79 <span className="text-[10px] tracking-[0.2em] text-foreground/25">
80 {project.number}
81 </span>
82 </div>
83 <div className="absolute bottom-4 right-4 translate-y-2 opacity-0 transition-all duration-300 group-hover:translate-y-0 group-hover:opacity-100">
84 <svg
85 className="h-4 w-4 text-foreground/40"
86 fill="none"
87 stroke="currentColor"
88 viewBox="0 0 24 24"
89 >
90 <path
91 strokeLinecap="round"
92 strokeLinejoin="round"
93 strokeWidth={1.5}
94 d="M7 17L17 7M17 7H7M17 7v10"
95 />
96 </svg>
97 </div>
98 </div>
99 <div className="mt-4 flex items-baseline justify-between">
100 <div>
101 <h3 className="text-sm font-medium tracking-wide text-foreground">
102 {project.title}
103 </h3>
104 <p className="mt-1 text-xs font-light tracking-wide text-muted-foreground/60">
105 {project.category}
106 </p>
107 </div>
108 <span className="text-[10px] tracking-[0.2em] text-muted-foreground/40">
109 {project.number}
110 </span>
111 </div>
112 </div>
113 ))}
114 </div>
115
116 {/* 右カラム(上にオフセット) */}
117 <div className="flex flex-col gap-10 sm:mt-20">
118 {rightColumn.map((project, i) => (
119 <div key={i} className="group">
120 <div className="relative aspect-[3/4] overflow-hidden border border-border bg-muted">
121 <div className="absolute inset-0 bg-gradient-to-br from-foreground/[0.03] to-foreground/[0.08] transition-all duration-500 group-hover:from-foreground/[0.06] group-hover:to-foreground/[0.12]" />
122 <div className="absolute left-4 top-4 h-1.5 w-1.5 rounded-full bg-foreground/20" />
123 <div className="absolute right-4 top-4 h-1.5 w-1.5 rounded-full bg-foreground/20" />
124 <div className="absolute bottom-4 left-4">
125 <span className="text-[10px] tracking-[0.2em] text-foreground/25">
126 {project.number}
127 </span>
128 </div>
129 <div className="absolute bottom-4 right-4 translate-y-2 opacity-0 transition-all duration-300 group-hover:translate-y-0 group-hover:opacity-100">
130 <svg
131 className="h-4 w-4 text-foreground/40"
132 fill="none"
133 stroke="currentColor"
134 viewBox="0 0 24 24"
135 >
136 <path
137 strokeLinecap="round"
138 strokeLinejoin="round"
139 strokeWidth={1.5}
140 d="M7 17L17 7M17 7H7M17 7v10"
141 />
142 </svg>
143 </div>
144 </div>
145 <div className="mt-4 flex items-baseline justify-between">
146 <div>
147 <h3 className="text-sm font-medium tracking-wide text-foreground">
148 {project.title}
149 </h3>
150 <p className="mt-1 text-xs font-light tracking-wide text-muted-foreground/60">
151 {project.category}
152 </p>
153 </div>
154 <span className="text-[10px] tracking-[0.2em] text-muted-foreground/40">
155 {project.number}
156 </span>
157 </div>
158 </div>
159 ))}
160 </div>
161 </div>
162
163 {/* フッター */}
164 <div className="mt-16 flex items-center justify-between border-t border-border pt-6">
165 <p className="text-xs font-light tracking-wide text-muted-foreground/60">
166{projects.length} プロジェクト
167 </p>
168 <a
169 href="#"
170 className="group/link flex items-center gap-2 text-xs tracking-[0.15em] text-muted-foreground transition-colors hover:text-foreground"
171 >
172 すべてのプロジェクト
173 <svg
174 className="h-3 w-3 transition-transform duration-200 group-hover/link:translate-x-0.5"
175 fill="none"
176 stroke="currentColor"
177 viewBox="0 0 24 24"
178 >
179 <path
180 strokeLinecap="round"
181 strokeLinejoin="round"
182 strokeWidth={1.5}
183 d="M17 8l4 4m0 0l-4 4m4-4H3"
184 />
185 </svg>
186 </a>
187 </div>
188 </div>
189 </section>
190 );
191}