ブログ/

マガジンスタイルブログ

Preview

フィーチャー記事とサイドリストを組み合わせたマガジン風のブログセクション。番号付きの記事一覧と控えめなプレースホルダー画像

Source Code
tsx
180 lines
1import Link from "next/link";
2
3export function BlogMagazine001() {
4 const featuredPost = {
5 title: "デザインシステムが変える開発体験",
6 excerpt:
7 "一貫したUIコンポーネントとデザイントークンの活用により、チーム全体の生産性がどのように向上するかを探ります。実践的なアプローチと導入のポイントを解説。",
8 date: "2026.03.28",
9 category: "デザイン",
10 readTime: "8 min",
11 };
12
13 const posts = [
14 {
15 title: "タイポグラフィの基本原則",
16 excerpt:
17 "可読性と美しさを両立するフォント選びのガイドライン。Webにおけるタイポグラフィの実践的な考え方。",
18 date: "2026.03.21",
19 category: "デザイン",
20 readTime: "5 min",
21 },
22 {
23 title: "パフォーマンス最適化の実践",
24 excerpt:
25 "Core Web Vitals の改善から画像最適化まで、ユーザー体験を向上させる具体的な手法を紹介。",
26 date: "2026.03.14",
27 category: "エンジニアリング",
28 readTime: "6 min",
29 },
30 {
31 title: "アクセシビリティ対応の始め方",
32 excerpt:
33 "すべてのユーザーに優しいWebサイトを作るための基本的な考え方と、今日から実践できるテクニック。",
34 date: "2026.03.07",
35 category: "エンジニアリング",
36 readTime: "7 min",
37 },
38 ];
39
40 return (
41 <section className="border-t border-border bg-background py-28">
42 <div className="mx-auto max-w-6xl px-4 sm:px-6 lg:px-8">
43 {/* ヘッダー */}
44 <div className="flex items-end justify-between">
45 <div>
46 <span className="text-[10px] uppercase tracking-[0.3em] text-muted-foreground">
47 Journal
48 </span>
49 <h2 className="mt-3 text-2xl font-medium tracking-wide text-foreground sm:text-3xl">
50 最新の記事
51 </h2>
52 </div>
53 <Link
54 href="#"
55 className="hidden items-center gap-2 text-xs uppercase tracking-[0.15em] text-muted-foreground transition-colors duration-300 hover:text-foreground sm:flex"
56 >
57 すべての記事
58 <svg
59 className="h-3.5 w-3.5"
60 fill="none"
61 stroke="currentColor"
62 viewBox="0 0 24 24"
63 >
64 <path
65 strokeLinecap="round"
66 strokeLinejoin="round"
67 strokeWidth={1.5}
68 d="M17 8l4 4m0 0l-4 4m4-4H3"
69 />
70 </svg>
71 </Link>
72 </div>
73
74 <div className="mt-4 h-px bg-border/40" />
75
76 {/* メインコンテンツ: フィーチャー + サイドリスト */}
77 <div className="mt-12 grid gap-12 lg:grid-cols-5 lg:gap-16">
78 {/* フィーチャー記事 */}
79 <div className="lg:col-span-3">
80 <Link href="#" className="group block">
81 {/* プレースホルダー画像 */}
82 <div className="aspect-[16/10] overflow-hidden rounded-lg border border-border bg-muted/30">
83 <svg
84 className="h-full w-full text-muted-foreground/10"
85 viewBox="0 0 800 500"
86 fill="none"
87 >
88 <rect width="800" height="500" fill="currentColor" />
89 <circle cx="400" cy="220" r="40" fill="currentColor" className="text-muted-foreground/20" />
90 <path
91 d="M200 350 L350 280 L450 320 L600 250 L700 300 L700 500 L200 500Z"
92 fill="currentColor"
93 className="text-muted-foreground/15"
94 />
95 </svg>
96 </div>
97
98 <div className="mt-6 flex items-center gap-3">
99 <span className="rounded-full border border-border px-3 py-1 text-[10px] uppercase tracking-[0.2em] text-muted-foreground">
100 {featuredPost.category}
101 </span>
102 <span className="text-[10px] tracking-wider text-muted-foreground/60">
103 {featuredPost.readTime}
104 </span>
105 </div>
106
107 <h3 className="mt-4 text-xl font-medium tracking-wide text-foreground transition-colors duration-200 group-hover:text-muted-foreground sm:text-2xl">
108 {featuredPost.title}
109 </h3>
110 <p className="mt-3 font-light leading-relaxed tracking-wide text-muted-foreground">
111 {featuredPost.excerpt}
112 </p>
113 <time className="mt-4 block text-xs tracking-wider text-muted-foreground/50">
114 {featuredPost.date}
115 </time>
116 </Link>
117 </div>
118
119 {/* サイドリスト */}
120 <div className="lg:col-span-2">
121 <div className="flex flex-col divide-y divide-border">
122 {posts.map((post, index) => (
123 <Link key={post.title} href="#" className="group py-6 first:pt-0 last:pb-0">
124 <div className="flex items-start gap-4">
125 <span className="mt-0.5 text-[10px] tabular-nums tracking-wider text-muted-foreground/40">
126 {String(index + 1).padStart(2, "0")}
127 </span>
128 <div className="flex-1">
129 <div className="flex items-center gap-3">
130 <span className="text-[10px] uppercase tracking-[0.2em] text-muted-foreground/60">
131 {post.category}
132 </span>
133 <div className="h-0.5 w-0.5 rounded-full bg-muted-foreground/30" />
134 <span className="text-[10px] tracking-wider text-muted-foreground/50">
135 {post.readTime}
136 </span>
137 </div>
138 <h4 className="mt-2 text-sm font-medium tracking-wide text-foreground transition-colors duration-200 group-hover:text-muted-foreground">
139 {post.title}
140 </h4>
141 <p className="mt-1.5 text-xs font-light leading-relaxed tracking-wide text-muted-foreground/70">
142 {post.excerpt}
143 </p>
144 <time className="mt-2 block text-[10px] tracking-wider text-muted-foreground/40">
145 {post.date}
146 </time>
147 </div>
148 </div>
149 </Link>
150 ))}
151 </div>
152 </div>
153 </div>
154
155 {/* モバイル用リンク */}
156 <div className="mt-12 text-center sm:hidden">
157 <Link
158 href="#"
159 className="inline-flex items-center gap-2 text-xs uppercase tracking-[0.15em] text-muted-foreground transition-colors duration-300 hover:text-foreground"
160 >
161 すべての記事
162 <svg
163 className="h-3.5 w-3.5"
164 fill="none"
165 stroke="currentColor"
166 viewBox="0 0 24 24"
167 >
168 <path
169 strokeLinecap="round"
170 strokeLinejoin="round"
171 strokeWidth={1.5}
172 d="M17 8l4 4m0 0l-4 4m4-4H3"
173 />
174 </svg>
175 </Link>
176 </div>
177 </div>
178 </section>
179 );
180}