// Japanese page: testimonials (3D cards on scroll), FAQ, final CTA, footer. // Same structure and behaviour as ../sections-c.jsx; copy from the copy deck (V-*, F-*, C-*, FT-*). // Voices: quotes are real and anonymous. The avatars are illustrated characters, not photos of the clients. const VOICES = [ { q: '実際に使える最初のバージョンが、数か月ではなく数週間で現場責任者の手元に届きました。', n: '業務責任者', r: '中小企業のお客様', img: '../uploads/voice_avatar_1.webp', badge: '数か月ではなく数週間', bl: '最初のバージョンまで', bg: 'var(--accent)' }, { q: '置き換える前に、まず「なぜこのExcelファイルが必要なのか」を理解してくれました。', n: 'マネージャー', r: '中小企業のお客様', img: '../uploads/voice_avatar_2.webp', badge: 'Excel → 独自システム開発', bl: 'まず業務を理解', bg: '#1d1d1d' }, { q: 'ダッシュボードのおかげで、ようやく経営陣と現場が同じ数字を見られるようになりました。', n: '取締役', r: '中小企業のお客様', img: '../uploads/voice_avatar_3.webp', badge: '数字をひとつのダッシュボードに', bl: '経営と現場', bg: '#e6dfd1' }, ]; function Voices() { const reduced = useReducedMotion(); const sectionRef = React.useRef(null); const stickyRef = React.useRef(null); const cardRefs = React.useRef([]); const n = VOICES.length; useScrollFrame(() => { const section = sectionRef.current; const sticky = stickyRef.current; if (!section || !sticky) return; if (reduced) { cardRefs.current.forEach((c) => c && c.removeAttribute('style')); return; } const p = pinProgress(section); // Title fades out over the first slice, then each card swings in and out. sticky.style.setProperty('--t', clamp01(p * n * 3).toFixed(3)); const span = 1 / n; cardRefs.current.forEach((c, i) => { if (!c) return; const local = (p - i * span) / span; // 0..1 inside this card's window let ry = 90; let o = 0; if (local > 0 && local < 1) { if (local < 0.3) { const k = local / 0.3; ry = 90 * (1 - k); o = k; } else if (local < 0.75 || i === n - 1) { ry = 0; o = 1; } else { const k = (local - 0.75) / 0.25; ry = -90 * k; o = 1 - k; } } else if (local >= 1 && i === n - 1) { ry = 0; o = 1; } c.style.setProperty('--ry', `${ry.toFixed(2)}deg`); c.style.setProperty('--o', o.toFixed(3)); c.style.visibility = o < 0.01 ? 'hidden' : 'visible'; }); }, [reduced]); return (

お客様の声。

{VOICES.map((v, i) => (
(cardRefs.current[i] = el)} className="voice" style={{ margin: 0 }}>
))}
); } const FAQS = [ { q: 'どのような業種に対応していますか?', a: '業種は問いません。スプレッドシートやチャット、紙の書類で業務を回しているなら、その流れを、現場で本当に使われるひとつのシステムにまとめます。' }, { q: '見積もりはどのように依頼できますか?', a: 'まずは30分のオンライン相談で、事業内容と解決したい課題をお聞きします。そのうえで、項目別の見積書(日本円)とプロジェクト提案書をお送りします。ご相談は無料です。' }, { q: 'Excelファイルから少しずつ移行できますか?', a: 'はい。通常は、一番負担の大きいスプレッドシートをひとつ選んで小さな業務システムに置き換え、チームが慣れてから次の業務へとつなげていきます。' }, { q: 'システムを使うのに、ITに詳しい社員は必要ですか?', a: '必要ありません。すべてのシステムにトレーニングと引き継ぎが含まれます。技術者だけでなく、現場のスタッフ、事務担当、経営陣が使いやすいように設計します。' }, { q: '何から自動化すべきか、わからないのですが。', a: '業務の流れを整理し、お使いのファイルやレポートを確認したうえで、事業へのインパクトと導入のしやすさから、最初に取り組むべきシステムに優先順位をつけます。' }, { q: '今使っているツールと連携できますか?', a: 'ほとんどの場合、可能です。会計ソフト、在庫管理、バーコード業務、LINE公式アカウント、既存のERP、主要なSaaSツールと連携できます。' }, { q: '予定より時間がかかりそうな場合は?', a: '見積もりの範囲を超えそうな場合は、作業を進める前に必ずご相談します。' }, { q: '想定外の追加費用はかかりますか?', a: 'かかりません。事前のご承認なしに、追加作業や追加費用が発生することはありません。' }, { q: '拠点はどこですか?実際に作業するのは誰ですか?', a: 'ご相談からお打ち合わせまで、オンラインで対応しています。経験豊富なエンジニアが、要件の整理から本番稼働まで、御社のチームと直接やり取りします。' }, ]; function FAQ() { const [open, setOpen] = React.useState(0); return (

FAQ

よくあるご質問。

知りたいことが見つからない場合は、お気軽にお問い合わせください。

{FAQS.map((f, i) => { const isOpen = open === i; return (

{f.a}

); })}
); } const CTA_WORDS = ['次のアイデアを、', '一緒に', '現実にしましょう。']; const CTA_PILL_AFTER = 1; // Closing call to action: words rise out of their masks, the pill pops in and its sun knob slides across and lights up, and // an accent "horizon" arc rises behind the buttons as the section scrolls into view. function CTA() { const reduced = useReducedMotion(); const ref = React.useRef(null); useScrollFrame(() => { const el = ref.current; if (!el) return; if (reduced) { el.style.removeProperty('--e'); return; } const r = el.getBoundingClientRect(); const vh = window.innerHeight; el.style.setProperty('--e', clamp01((vh - r.top) / (vh * 0.85)).toFixed(4)); }, [reduced]); return (

{CTA_WORDS.join('')}

まずは無料見積 メールで相談する

メールでのお問い合わせ:{SALES_EMAIL}

); } function Footer() { const cols = [ ['メニュー', NAV_ITEMS], ['ご相談・お見積もり', [['まずは無料見積', QUOTE_URL], ['メールで相談する', emailMailto], ['プライバシーポリシー', '/privacy/ja/']]], ['お問い合わせ', [[SALES_EMAIL, `mailto:${SALES_EMAIL}`]]], ]; return ( ); } Object.assign(window, { Voices, FAQ, CTA, Footer });