

New
View Details
コンタクト
エレガントコンタクト
#ミニマル#スプリット+1
抽象的なSVGマップと拠点情報を組み合わせたコンタクトセクション。複数拠点の情報をエレガントに表示
1"use client";23import { useState } from "react";45export function ContactMap001() {6 const [formData, setFormData] = useState({7 name: "",8 email: "",9 message: "",10 });1112 const handleSubmit = (e: React.FormEvent) => {13 e.preventDefault();14 };1516 const handleChange = (17 e: React.ChangeEvent<HTMLInputElement | HTMLTextAreaElement>18 ) => {19 setFormData((prev) => ({20 ...prev,21 [e.target.name]: e.target.value,22 }));23 };2425 const offices = [26 { city: "東京", address: "渋谷区神南1-2-3", hours: "9:00 – 18:00" },27 { city: "大阪", address: "北区梅田4-5-6", hours: "9:00 – 18:00" },28 { city: "福岡", address: "中央区天神7-8-9", hours: "10:00 – 17:00" },29 ];3031 return (32 <section className="bg-background py-28 border-t border-border">33 <div className="mx-auto max-w-6xl px-4 sm:px-6 lg:px-8">34 {/* ヘッダー */}35 <div className="text-center">36 <p className="text-[10px] uppercase tracking-[0.3em] text-muted-foreground">37 Contact38 </p>39 <h2 className="mt-3 text-2xl font-medium tracking-wide text-foreground sm:text-3xl">40 お問い合わせ41 </h2>42 <p className="mx-auto mt-4 max-w-md text-sm font-light leading-relaxed text-muted-foreground">43 ご相談やご質問がございましたら、お気軽にお問い合わせください。44 </p>45 </div>4647 <div className="mt-6 h-px bg-border/40" />4849 <div className="mt-16 grid grid-cols-1 gap-16 lg:grid-cols-2">50 {/* 左: マップ風ビジュアル + 拠点情報 */}51 <div>52 {/* SVGマップ風装飾 */}53 <div className="relative overflow-hidden rounded-lg border border-border bg-muted/20 p-8">54 {/* コーナードット */}55 <div className="absolute left-2.5 top-2.5 h-1.5 w-1.5 rounded-full bg-foreground/15" />56 <div className="absolute right-2.5 top-2.5 h-1.5 w-1.5 rounded-full bg-foreground/15" />57 <div className="absolute bottom-2.5 left-2.5 h-1.5 w-1.5 rounded-full bg-foreground/15" />58 <div className="absolute bottom-2.5 right-2.5 h-1.5 w-1.5 rounded-full bg-foreground/15" />5960 <svg61 viewBox="0 0 400 240"62 fill="none"63 className="w-full text-foreground/[0.06]"64 aria-hidden="true"65 >66 {/* グリッド線 */}67 {Array.from({ length: 9 }, (_, i) => (68 <line69 key={`h-${i}`}70 x1="0"71 y1={i * 30}72 x2="400"73 y2={i * 30}74 stroke="currentColor"75 strokeWidth="0.5"76 />77 ))}78 {Array.from({ length: 14 }, (_, i) => (79 <line80 key={`v-${i}`}81 x1={i * 30}82 y1="0"83 x2={i * 30}84 y2="240"85 stroke="currentColor"86 strokeWidth="0.5"87 />88 ))}89 {/* 抽象的な島の輪郭 */}90 <path91 d="M180 40 C200 35, 240 30, 270 50 C290 65, 310 55, 320 70 C330 85, 340 100, 330 120 C320 140, 300 150, 280 145 C260 140, 250 155, 230 160 C210 165, 190 155, 175 140 C160 125, 150 105, 155 90 C160 75, 165 50, 180 40Z"92 stroke="currentColor"93 strokeWidth="1"94 className="text-foreground/10"95 fill="none"96 />97 {/* ロケーションピン */}98 <circle cx="220" cy="70" r="4" className="fill-foreground/20" />99 <circle cx="220" cy="70" r="1.5" className="fill-foreground/40" />100 <circle cx="270" cy="110" r="4" className="fill-foreground/20" />101 <circle cx="270" cy="110" r="1.5" className="fill-foreground/40" />102 <circle cx="300" cy="135" r="4" className="fill-foreground/20" />103 <circle cx="300" cy="135" r="1.5" className="fill-foreground/40" />104 {/* 接続線 */}105 <line106 x1="220"107 y1="70"108 x2="270"109 y2="110"110 stroke="currentColor"111 strokeWidth="0.5"112 strokeDasharray="4 4"113 className="text-foreground/10"114 />115 <line116 x1="270"117 y1="110"118 x2="300"119 y2="135"120 stroke="currentColor"121 strokeWidth="0.5"122 strokeDasharray="4 4"123 className="text-foreground/10"124 />125 </svg>126 </div>127128 {/* 拠点一覧 */}129 <div className="mt-8 space-y-4">130 {offices.map((office, index) => (131 <div132 key={office.city}133 className="flex items-start gap-4"134 >135 <div className="flex h-8 w-8 shrink-0 items-center justify-center rounded-full border border-border text-[10px] font-medium text-muted-foreground">136 {String(index + 1).padStart(2, "0")}137 </div>138 <div className="flex-1">139 <div className="flex items-center gap-3">140 <p className="text-sm font-medium tracking-wide text-foreground">141 {office.city}142 </p>143 <div className="h-px flex-1 bg-border/30" />144 <p className="text-[10px] tracking-[0.15em] text-muted-foreground/60">145 {office.hours}146 </p>147 </div>148 <p className="mt-1 text-xs font-light tracking-wide text-muted-foreground">149 {office.address}150 </p>151 </div>152 </div>153 ))}154 </div>155156 {/* メールリンク */}157 <div className="mt-8 flex items-center gap-4 border-t border-border/40 pt-6">158 <svg159 className="h-4 w-4 text-muted-foreground/60"160 fill="none"161 stroke="currentColor"162 viewBox="0 0 24 24"163 >164 <path165 strokeLinecap="round"166 strokeLinejoin="round"167 strokeWidth={1.5}168 d="M21.75 6.75v10.5a2.25 2.25 0 01-2.25 2.25h-15a2.25 2.25 0 01-2.25-2.25V6.75m19.5 0A2.25 2.25 0 0019.5 4.5h-15a2.25 2.25 0 00-2.25 2.25m19.5 0v.243a2.25 2.25 0 01-1.07 1.916l-7.5 4.615a2.25 2.25 0 01-2.36 0L3.32 8.91a2.25 2.25 0 01-1.07-1.916V6.75"169 />170 </svg>171 <span className="text-xs font-light tracking-wide text-muted-foreground">172 hello@example.com173 </span>174 </div>175 </div>176177 {/* 右: フォーム */}178 <div>179 <form onSubmit={handleSubmit} className="space-y-8">180 <div>181 <label182 htmlFor="contact-map-name"183 className="block text-[10px] uppercase tracking-[0.2em] text-muted-foreground"184 >185 お名前186 </label>187 <input188 type="text"189 id="contact-map-name"190 name="name"191 value={formData.name}192 onChange={handleChange}193 className="mt-3 block w-full border-b border-border bg-transparent py-3 text-sm tracking-wide text-foreground placeholder-muted-foreground/40 transition-colors duration-200 focus:border-foreground focus:outline-none"194 placeholder="山田 太郎"195 />196 </div>197198 <div>199 <label200 htmlFor="contact-map-email"201 className="block text-[10px] uppercase tracking-[0.2em] text-muted-foreground"202 >203 メールアドレス204 </label>205 <input206 type="email"207 id="contact-map-email"208 name="email"209 value={formData.email}210 onChange={handleChange}211 className="mt-3 block w-full border-b border-border bg-transparent py-3 text-sm tracking-wide text-foreground placeholder-muted-foreground/40 transition-colors duration-200 focus:border-foreground focus:outline-none"212 placeholder="your@email.com"213 />214 </div>215216 <div>217 <label218 htmlFor="contact-map-message"219 className="block text-[10px] uppercase tracking-[0.2em] text-muted-foreground"220 >221 メッセージ222 </label>223 <textarea224 id="contact-map-message"225 name="message"226 rows={5}227 value={formData.message}228 onChange={handleChange}229 className="mt-3 block w-full resize-none border-b border-border bg-transparent py-3 text-sm tracking-wide text-foreground placeholder-muted-foreground/40 transition-colors duration-200 focus:border-foreground focus:outline-none"230 placeholder="プロジェクトの概要やご要望をお聞かせください..."231 />232 </div>233234 <div className="flex items-center justify-between pt-2">235 <p className="text-[10px] tracking-wide text-muted-foreground/50">236 通常2営業日以内にご返信237 </p>238 <button239 type="submit"240 className="group inline-flex items-center gap-2 border-b border-foreground py-2 text-xs font-medium uppercase tracking-[0.15em] text-foreground transition-colors duration-200 hover:border-muted-foreground hover:text-muted-foreground"241 >242 送信する243 <svg244 className="h-3.5 w-3.5 transition-transform duration-200 group-hover:translate-x-0.5"245 fill="none"246 stroke="currentColor"247 viewBox="0 0 24 24"248 >249 <path250 strokeLinecap="round"251 strokeLinejoin="round"252 strokeWidth={1.5}253 d="M17 8l4 4m0 0l-4 4m4-4H3"254 />255 </svg>256 </button>257 </div>258 </form>259 </div>260 </div>261 </div>262 </section>263 );264}