My front page

Headline that grabs people’s attention

A powerful headline about your product’s features to give focus
to your chosen product collection

Brand identity

Lorem ipsum dolor sit amet, consectetur adipiscing elit. Ut elit tellus, luctus nec.

UI/UX

Lorem ipsum dolor sit amet, consectetur adipiscing elit. Ut elit tellus, luctus nec.

Development

Lorem ipsum dolor sit amet, consectetur adipiscing elit. Ut elit tellus, luctus nec.

Your Identity

Amet minim mollit non deserunt

Lorem ipsum dolor sit amet, consectetur adipiscing
elit. Ut elit tellus, luctus nec ullamcorper mattis, pulvinar
dapibus leo.

Your Identity

Amet minim mollit non deserunt

Lorem ipsum dolor sit amet, consectetur adipiscing
elit. Ut elit tellus, luctus nec ullamcorper mattis, pulvinar
dapibus leo.

Our portfolio

Have a project in mind? Let’s get to work.

/** * イノマネVillage LP — Elementor カスタムJS * 配置場所: WordPress 管理画面 > Elementor > サイト設定 > カスタムコード * または プラグイン「Code Snippets」などで 閉じタグ前に追加 * * ─── EmailJS 設定手順 ─────────────────────────────────────── * 1. https://www.emailjs.com/ で無料アカウント作成 * 2. Email Services → Custom SMTP → info@signup.team0-1.com を追加 * Service ID をメモ(例: service_xxxxxxx) * 3. Email Templates を2つ作成(下記 EMAILJS CONFIG 参照) * 4. Account > Public Key をコピー * 5. 下記 EMAILJS CONFIG の値を実際のものに書き換える * ──────────────────────────────────────────────────────────── */ (function () { 'use strict'; /* ============================================================ EMAILJS CONFIG — ★ここを実際の値に書き換えてください★ ============================================================ */ const EMAILJS_PUBLIC_KEY = 'YOUR_EMAILJS_PUBLIC_KEY'; // Public Key const EMAILJS_SERVICE_ID = 'YOUR_SERVICE_ID'; // Email Service ID const EMAILJS_TEMPLATE_USER = 'YOUR_TEMPLATE_USER_ID'; // ユーザー御礼テンプレートID const EMAILJS_TEMPLATE_ADMIN = 'YOUR_TEMPLATE_ADMIN_ID'; // 管理者通知テンプレートID /* ============================================================ */ /* ── EmailJS 初期化 ─────────────────────────────────────── */ if (typeof emailjs !== 'undefined') { emailjs.init({ publicKey: EMAILJS_PUBLIC_KEY }); } /* ── DOM refs ──────────────────────────────────────────────── */ const header = document.getElementById('js-header'); const burger = document.getElementById('js-burger'); const drawer = document.getElementById('js-drawer'); const overlay = document.getElementById('js-overlay'); const closeBtn = document.getElementById('js-drawer-close'); const floatCta = document.getElementById('js-float-cta'); const priceEl = document.getElementById('js-price-num'); /* ── Header scroll shadow ───────────────────────────────────── */ function onScroll() { const y = window.scrollY; if (header) header.classList.toggle('is-scrolled', y > 40); const heroEl = document.getElementById('sec-hero'); const threshold = heroEl ? heroEl.offsetTop + heroEl.offsetHeight * 0.5 : 500; if (floatCta) floatCta.classList.toggle('is-visible', y > threshold); } window.addEventListener('scroll', onScroll, { passive: true }); onScroll(); /* ── Drawer ─────────────────────────────────────────────────── */ function openDrawer() { if (!drawer || !overlay) return; drawer.classList.add('is-open'); overlay.classList.add('is-open'); document.body.style.overflow = 'hidden'; const spans = burger ? burger.querySelectorAll('span') : []; if (spans[0]) spans[0].style.transform = 'rotate(45deg) translateY(7px)'; if (spans[1]) spans[1].style.opacity = '0'; if (spans[2]) spans[2].style.transform = 'rotate(-45deg) translateY(-7px)'; } function closeDrawer() { if (!drawer || !overlay) return; drawer.classList.remove('is-open'); overlay.classList.remove('is-open'); document.body.style.overflow = ''; if (burger) { burger.querySelectorAll('span').forEach(s => { s.style.transform = ''; s.style.opacity = '' }); } } if (burger) burger.addEventListener('click', openDrawer); if (closeBtn) closeBtn.addEventListener('click', closeDrawer); if (overlay) overlay.addEventListener('click', closeDrawer); if (drawer) drawer.querySelectorAll('a').forEach(a => a.addEventListener('click', closeDrawer)); /* ── Scroll Reveal ──────────────────────────────────────────── */ if ('IntersectionObserver' in window) { const ro = new IntersectionObserver(entries => { entries.forEach(e => { if (e.isIntersecting) { e.target.classList.add('is-visible'); ro.unobserve(e.target); } }); }, { threshold: 0.08, rootMargin: '0px 0px -40px 0px' }); document.querySelectorAll('.js-reveal').forEach(el => ro.observe(el)); } else { document.querySelectorAll('.js-reveal').forEach(el => el.classList.add('is-visible')); } /* ── Price counter 0 → 200 ──────────────────────────────────── */ function runCounter(el, end, ms) { let start = null; const step = ts => { if (!start) start = ts; const p = Math.min((ts - start) / ms, 1); el.textContent = Math.round((1 - Math.pow(1 - p, 4)) * end); if (p < 1) requestAnimationFrame(step); else el.textContent = end; }; requestAnimationFrame(step); } if (priceEl) { if ('IntersectionObserver' in window) { let fired = false; const co = new IntersectionObserver(entries => { if (entries[0].isIntersecting && !fired) { fired = true; runCounter(priceEl, 200, 1600); co.disconnect(); } }, { threshold: 0.5 }); co.observe(priceEl); } else { priceEl.textContent = '200'; } } /* ── Smooth scroll (ヘッダー高さ 76px 分オフセット) ──────── */ document.querySelectorAll('a[href^="#"]').forEach(a => { a.addEventListener('click', function (e) { const id = this.getAttribute('href'); if (!id || id === '#') return; const target = document.querySelector(id); if (!target) return; e.preventDefault(); window.scrollTo({ top: target.getBoundingClientRect().top + window.scrollY - 76, behavior: 'smooth' }); }); }); /* ── Hero v2: overlay parallax ──────────────────────────────── */ const heroBg = document.querySelector('.p-hero-v2__bg'); if (heroBg && window.matchMedia('(min-width:768px)').matches) { window.addEventListener('scroll', () => { heroBg.style.transform = `translateY(${window.scrollY * 0.28}px)`; }, { passive: true }); } /* ── Solution: dim siblings on hover ───────────────────────── */ const solItems = document.querySelectorAll('.p-solution__item'); solItems.forEach(item => { item.addEventListener('mouseenter', () => { solItems.forEach(o => { if (o !== item) { o.style.opacity = '0.72'; o.style.transform = 'scale(0.997)'; o.style.transition = 'opacity .3s, transform .3s'; } }); }); item.addEventListener('mouseleave', () => { solItems.forEach(o => { o.style.opacity = ''; o.style.transform = ''; }); }); }); /* ── Empathy card 3D tilt ───────────────────────────────────── */ document.querySelectorAll('.p-empathy__card').forEach(card => { card.addEventListener('mousemove', e => { const r = card.getBoundingClientRect(); const x = (e.clientX - r.left) / r.width - 0.5; const y = (e.clientY - r.top) / r.height - 0.5; card.style.transform = `perspective(700px) rotateY(${x * 6}deg) rotateX(${-y * 6}deg) scale(1.018)`; card.style.transition = 'transform .08s ease'; }); card.addEventListener('mouseleave', () => { card.style.transform = ''; card.style.transition = 'transform .45s ease, border-color .3s, background .3s'; }); }); /* ── Value2 card ripple ─────────────────────────────────────── */ document.querySelectorAll('.p-value2__card').forEach(card => { card.addEventListener('click', e => { const r = card.getBoundingClientRect(); const rp = document.createElement('span'); Object.assign(rp.style, { position:'absolute', borderRadius:'50%', background:'rgba(79,70,229,.12)', width:'0', height:'0', left:(e.clientX - r.left)+'px', top:(e.clientY - r.top)+'px', transform:'translate(-50%,-50%)', animation:'lxRipple .6s ease-out forwards', pointerEvents:'none' }); card.style.position = 'relative'; card.style.overflow = 'hidden'; card.appendChild(rp); setTimeout(() => rp.remove(), 700); }); }); const ks = document.createElement('style'); ks.textContent = '@keyframes lxRipple{to{width:300px;height:300px;opacity:0}}'; document.head.appendChild(ks); /* ── Steps hover ────────────────────────────────────────────── */ document.querySelectorAll('.p-steps__item').forEach(item => { item.addEventListener('mouseenter', () => { item.style.background = '#f0f4ff'; }); item.addEventListener('mouseleave', () => { item.style.background = ''; }); }); /* ── Comparison table row hover ─────────────────────────────── */ document.querySelectorAll('.p-comparison__table tbody tr').forEach(row => { row.style.transition = 'background .2s'; row.addEventListener('mouseenter', () => row.style.background = 'rgba(255,255,255,.04)'); row.addEventListener('mouseleave', () => row.style.background = ''); }); /* ── Active nav on scroll ───────────────────────────────────── */ const sections = document.querySelectorAll('section[id]'); const navLinks = document.querySelectorAll('.l-header__nav a[href^="#"]'); if ('IntersectionObserver' in window && navLinks.length) { const ao = new IntersectionObserver(entries => { entries.forEach(entry => { if (entry.isIntersecting) { const id = entry.target.id; navLinks.forEach(a => { const active = a.getAttribute('href') === `#${id}`; a.style.color = active ? '#4f46e5' : ''; a.style.borderBottomColor = active ? '#4f46e5' : ''; }); } }); }, { threshold: 0.35, rootMargin: '-76px 0px 0px 0px' }); sections.forEach(s => ao.observe(s)); } /* ── Voice cards lift on hover ──────────────────────────────── */ document.querySelectorAll('.p-voices__card').forEach(card => { card.addEventListener('mouseenter', () => { card.style.transform = 'translateY(-4px)'; card.style.transition = 'transform .3s ease, box-shadow .3s, border-color .3s'; }); card.addEventListener('mouseleave', () => { card.style.transform = ''; }); }); /* ============================================================ CTA インラインフォーム — 送信処理 ============================================================ */ const ctaForm = document.getElementById('js-cta-form'); const ctaThanks = document.getElementById('js-cta-thanks'); const FIELDS = [ { id: 'cta-name', errId: 'err-name', required: true, label: '氏名' }, { id: 'cta-company', errId: 'err-company', required: true, label: '企業名' }, { id: 'cta-department', errId: 'err-department', required: true, label: '部署名' }, { id: 'cta-position', errId: 'err-position', required: true, label: '役職' }, { id: 'cta-email', errId: 'err-email', required: true, label: 'メールアドレス', type: 'email' }, { id: 'cta-message', errId: 'err-message', required: false, label: '問題意識など' }, ]; FIELDS.forEach(f => { const el = document.getElementById(f.id); const err = document.getElementById(f.errId); if (!el || !err) return; el.addEventListener('input', () => { if (el.value.trim()) { err.textContent = ''; el.classList.remove('is-error'); } }); }); function validateForm() { let valid = true; FIELDS.forEach(f => { if (!f.required) return; const el = document.getElementById(f.id); const err = document.getElementById(f.errId); if (!el || !err) return; const val = el.value.trim(); if (!val) { err.textContent = `${f.label}を入力してください`; el.classList.add('is-error'); valid = false; } else if (f.type === 'email' && !/^[^\s@]+@[^\s@]+\.[^\s@]+$/.test(val)) { err.textContent = '正しいメールアドレスを入力してください'; el.classList.add('is-error'); valid = false; } else { err.textContent = ''; el.classList.remove('is-error'); } }); const privacyChk = document.getElementById('cta-privacy'); const privacyErr = document.getElementById('err-privacy'); if (privacyChk && !privacyChk.checked) { if (privacyErr) privacyErr.textContent = 'プライバシーポリシーへの同意が必要です'; valid = false; } else if (privacyErr) { privacyErr.textContent = ''; } return valid; } function getFormValues() { return FIELDS.reduce((acc, f) => { const el = document.getElementById(f.id); acc[f.id.replace('cta-', '')] = el ? el.value.trim() : ''; return acc; }, {}); } if (ctaForm) { ctaForm.addEventListener('submit', async function (e) { e.preventDefault(); if (!validateForm()) { const firstErr = ctaForm.querySelector('.is-error'); if (firstErr) firstErr.focus(); return; } const submitBtn = ctaForm.querySelector('.p-cta__form-submit'); const origHTML = submitBtn ? submitBtn.innerHTML : ''; if (submitBtn) { submitBtn.disabled = true; submitBtn.innerHTML = ' 送信中…'; } /* 既存エラーメッセージを削除 */ const prevErr = ctaForm.querySelector('.p-cta__send-error'); if (prevErr) prevErr.remove(); const vals = getFormValues(); const now = new Date().toLocaleString('ja-JP', { timeZone: 'Asia/Tokyo' }); /* ── 1. DB 保存 ─────────────────────────────────────── */ let dbOk = false; try { const res = await fetch('tables/inomane_inquiries', { method: 'POST', headers: { 'Content-Type': 'application/json' }, body: JSON.stringify({ name: vals.name, company: vals.company, department: vals.department, position: vals.position, email: vals.email, message: vals.message || '', submitted_at: now, status: 'new' }) }); if (res.ok) dbOk = true; } catch (err) { console.warn('[DB] 保存エラー:', err); } /* ── 2. EmailJS 送信 ────────────────────────────────── */ let mailOk = false; if (typeof emailjs !== 'undefined' && EMAILJS_SERVICE_ID !== 'YOUR_SERVICE_ID' && EMAILJS_TEMPLATE_USER !== 'YOUR_TEMPLATE_USER_ID') { try { /* ユーザー御礼メール */ await emailjs.send(EMAILJS_SERVICE_ID, EMAILJS_TEMPLATE_USER, { to_email: vals.email, to_name: vals.name, company: vals.company, department: vals.department, position: vals.position, email: vals.email, message: vals.message || '(記載なし)', submitted_at: now }); /* 管理者通知メール */ await emailjs.send(EMAILJS_SERVICE_ID, EMAILJS_TEMPLATE_ADMIN, { name: vals.name, company: vals.company, department: vals.department, position: vals.position, email: vals.email, message: vals.message || '(記載なし)', submitted_at: now }); mailOk = true; } catch (err) { console.warn('[EmailJS] 送信エラー:', err); } } else { console.warn('[EmailJS] 未設定のためメール送信をスキップ'); mailOk = true; /* 未設定時はフォーム完了扱い */ } /* ── 3. 完了 or エラー処理 ──────────────────────────── */ if (dbOk || mailOk) { ctaForm.style.display = 'none'; if (ctaThanks) { ctaThanks.style.display = 'flex'; ctaThanks.scrollIntoView({ behavior: 'smooth', block: 'center' }); } } else { /* 送信失敗 */ if (submitBtn) { submitBtn.disabled = false; submitBtn.innerHTML = origHTML; } const errDiv = document.createElement('div'); errDiv.className = 'p-cta__send-error'; errDiv.textContent = '送信に失敗しました。時間をおいて再度お試しください。'; ctaForm.insertBefore(errDiv, ctaForm.querySelector('.p-cta__form-submit')); } }); } })();