diff --git a/pai.js b/pai.js
new file mode 100644
index 0000000..098444e
--- /dev/null
+++ b/pai.js
@@ -0,0 +1,66 @@
+const map = document.getElementById('map');
+const img = document.getElementById('mapImage');
+
+// CSV読み込み関数
+async function loadCSV(url) {
+ const response = await fetch(url);
+ const text = await response.text();
+ const rows = text.trim().split("\n").map(r => r.split(","));
+ const headers = rows.shift();
+ return rows.map(r => Object.fromEntries(r.map((v,i) => [headers[i], v])));
+}
+
+// ピンを配置する関数
+function placePins(pins) {
+ document.querySelectorAll('.pin, .tooltip').forEach(e => e.remove());
+
+ const rect = img.getBoundingClientRect();
+ const width = rect.width;
+ const height = rect.height;
+
+ pins.forEach(pos => {
+ const x = parseFloat(pos.x);
+ const y = parseFloat(pos.y);
+
+ // ピン本体
+ const pin = document.createElement('div');
+ pin.className = 'pin';
+ pin.style.left = (x * width) + 'px';
+ pin.style.top = (y * height) + 'px';
+
+ const iconImg = document.createElement('img');
+ iconImg.src = pos.icon;
+ pin.appendChild(iconImg);
+
+ // 吹き出し
+ const tooltip = document.createElement('div');
+ tooltip.className = 'tooltip';
+ tooltip.style.left = (x * width) + 'px';
+ tooltip.style.top = (y * height) + 'px';
+ tooltip.innerHTML = `
+ ${pos.title}
+ ${pos.description}
+
+ 公式サイトへ
+ `;
+
+ // クリックで表示切替
+ pin.addEventListener('click', () => {
+ const isVisible = tooltip.style.display === 'block';
+ document.querySelectorAll('.tooltip').forEach(t => t.style.display = 'none');
+ tooltip.style.display = isVisible ? 'none' : 'block';
+ });
+
+ map.appendChild(pin);
+ map.appendChild(tooltip);
+ });
+}
+
+// 初期化
+async function init() {
+ const pins = await loadCSV('spots.csv');
+ placePins(pins);
+ window.addEventListener('resize', () => placePins(pins));
+}
+
+img.addEventListener('load', init);