// soft keys LP v2 — SP対応版
// 「1人に頼らない仕組みを、LINEで。」
(function () {
const R = React;
const C = {
bg: 'oklch(0.99 0.006 150)', sf: '#ffffff',
ink: 'oklch(0.24 0.012 152)', sub: 'oklch(0.50 0.012 152)',
faint: 'oklch(0.70 0.010 152)', ln: 'oklch(0.91 0.010 152)',
gr: 'oklch(0.56 0.11 158)', grd: 'oklch(0.44 0.10 158)',
grs: 'oklch(0.96 0.025 158)',
f: '"Zen Kaku Gothic New", sans-serif',
m: '"Space Mono", monospace',
sh: '0 10px 32px oklch(0.55 0.08 150 / 0.09)',
};
/* ── viewport hook ── */
const useViewport = () => {
const [w, setW] = R.useState(typeof window !== 'undefined' ? window.innerWidth : 1200);
R.useEffect(() => {
const h = () => setW(window.innerWidth);
window.addEventListener('resize', h);
return () => window.removeEventListener('resize', h);
}, []);
return { isMobile: w < 768, isTablet: w < 1024, w };
};
/* ── primitives ── */
function Glyph({ size = 24, color }) {
return (
);
}
function SLabel({ children }) {
return
{children}
;
}
function SHead({ children, sub, center, isMobile }) {
return (
{children}
{sub &&
{sub}
}
);
}
function Card({ children, style }) {
return {children}
;
}
function Slot({ label, h, r = 16 }) {
return (
{label}
);
}
function Field({ label, placeholder, type = 'text', area, opt, name }) {
const b = { width: '100%', boxSizing: 'border-box', font: `15px ${C.f}`, color: C.ink, padding: '13px 15px', borderRadius: 11, border: `1px solid ${C.ln}`, background: C.bg, outline: 'none' };
return (
);
}
/* ── nav ── */
function NavBar() {
const { isMobile } = useViewport();
const [menuOpen, setMenuOpen] = R.useState(false);
const scrollTo = (id) => {
const el = document.getElementById(id);
if (el) { el.scrollIntoView({ behavior: 'smooth', block: 'start' }); setMenuOpen(false); }
};
const navItems = ['できること', '導入事例', 'よくある質問', '事業情報'];
const navIds = ['services', 'cases', 'faq', 'about'];
return (
);
}
/* ── FV ── */
function FVSection() {
const { isMobile } = useViewport();
const icons = [
{ left: '65.4%', top: '32.6%', delay: '0s', icon: 'invoice' },
{ left: '79.2%', top: '14.3%', delay: '.4s', icon: 'dashboard' },
{ left: '93%', top: '32.6%', delay: '.8s', icon: 'doc' },
{ left: '65.4%', top: '61.2%', delay: '1.2s', icon: 'box' },
{ left: '79.2%', top: '80.1%', delay: '1.6s', icon: 'cal' },
{ left: '93%', top: '61.2%', delay: '2.0s', icon: 'chart' },
];
const svgMap = {
invoice: ,
dashboard: ,
doc: ,
box: ,
cal: ,
chart: ,
};
if (isMobile) {
return (
担当者が休んでも、
業務が止まらない
仕組みを。
公式LINE・LINE Worksを活用した業務システムで、属人化・ワンオペを解消します。
{ e.preventDefault(); const el = document.getElementById('cases'); if(el) el.scrollIntoView({behavior:'smooth',block:'start'}); }} style={{ display: 'flex', alignItems: 'center', justifyContent: 'center', gap: 8, font: `600 15px ${C.f}`, color: '#fff', background: 'oklch(0.56 0.11 158)', padding: '16px 24px', borderRadius: 14, textDecoration: 'none', boxShadow: '0 4px 18px rgba(6,199,85,0.45)' }}>
📑 導入事例はこちら
);
}
return (
{icons.map((ic, i) => (
))}
LINE
{[['72%','22%','.2s'],['88%','18%','1.1s'],['96%','52%','.6s'],['70%','70%','1.6s']].map(([l,t,d],i)=>(
))}
担当者が休んでも、
業務が止まらない
仕組みを。
公式LINE・LINE Worksを活用した業務システムで、
属人化・ワンオペを解消します。
{ e.preventDefault(); const el = document.getElementById('cases'); if(el) el.scrollIntoView({behavior:'smooth',block:'start'}); }} style={{ display:'inline-flex', alignItems:'center', gap:'0.6cqw', font:`600 1.45cqw/1 ${C.f}`, color:'#fff', background:'oklch(0.56 0.11 158)', padding:'1cqw 2.8cqw', borderRadius:'3cqw', textDecoration:'none', boxShadow:'0 4px 18px rgba(6,199,85,0.45)', whiteSpace:'nowrap' }}>
📑 導入事例はこちら
);
}
/* ── tagline ── */
function TaglineSection() {
const { isMobile } = useViewport();
const px = isMobile ? 20 : 72;
return (
LINE × システム × HP制作
1人に頼らない
仕組みを、LINEで。
公式LINE・LINE Worksを活用した業務システム運用で、
集客効率化・属人化・ワンオペを解消します。
{[
{ num: '01', n: '受発注', d: '注文から納品書・請求書まで自動化' },
{ num: '02', n: '在庫管理', d: 'リアルタイムで全員が確認できる' },
{ num: '03', n: '電子日報', d: '現場からLINEで即時報告・集計' },
{ num: '04', n: '顧客管理', d: '集客から購買履歴まで一元管理' },
].map((it) => (
))}
);
}
/* ── problems ── */
function ProblemsSection() {
const { isMobile } = useViewport();
const px = isMobile ? 20 : 72;
const items = [
'受注・在庫は担当者にしか分からない',
'担当者が休むと、業務が止まってしまう',
'電話・メモでの受発注でミスが絶えない',
'現場とオフィスで、情報がバラバラ',
'日報や報告書の手入力に時間がかかる',
'新しいシステムを入れたが、現場で使われない',
];
return (
PROBLEM
こんな状況、ありませんか?
{items.map((t, i) => (
?
{t}
))}
その“詰まり”、いつものLINEで解けるかもしれません。
);
}
/* ── services ── */
function ServicesSection() {
const { isMobile, isTablet } = useViewport();
const px = isMobile ? 20 : 72;
const cols = isMobile ? '1fr' : isTablet ? 'repeat(2,1fr)' : 'repeat(3,1fr)';
const services = [
{ tag: '主力サービス', t: 'LINEシステム構築', b: '公式LINE・LINE Worksを業務システムのプラットフォームとして活用。受発注管理・在庫管理・電子日報・予約管理など、御社の業務にあわせてカスタム開発します。', items: ['受発注 / 在庫管理', '電子日報 / 報告システム', '予約 / 問い合わせ対応', '顧客管理 / スタッフ管理'], highlight: true },
{ tag: 'LINE活用', t: 'LINE集客マーケティング', b: '公式LINEアカウントの構築から運用まで。友だち獲得・セグメント配信・クーポン・アンケートを活用し、既存顧客との関係を深めてリピートを増やします。', items: ['公式LINEアカウント開設', 'メッセージ配信 / 自動応答', 'クーポン・ポイント施策', '友だち数・CVR分析'], highlight: false },
{ tag: 'Web制作', t: 'HP制作', b: '集客につながるWebサイトを制作。LINEとの連携導線を設計し、問い合わせから顧客管理まで一貫した仕組みをつくります。', items: ['コーポレートサイト', 'LP / 採用ページ', 'LINE連携フォーム', 'SEO / アクセス解析'], highlight: false },
];
return (
WHAT WE DO
soft keys でできること
{services.map((sv, si) => (
{sv.highlight && }
{sv.tag}
{String(si + 1).padStart(2, '0')}
{sv.t}
{sv.b}
{sv.items.map(it => (
))}
))}
);
}
/* ── cases ── */
function CaseCard({ service, company, industry, title, points, link, accentColor, heroImg, anchorId }) {
const ac = accentColor || C.gr;
return (
{heroImg
?

:
}
{service}
{company}
{industry}
{title}
{points.map((p, i) => (
))}
詳しく読む
);
}
function CasesSection() {
const { isMobile, isTablet } = useViewport();
const px = isMobile ? 20 : 72;
const cols = isMobile ? '1fr' : isTablet ? 'repeat(2,1fr)' : 'repeat(3,1fr)';
const cases = [
{ service: 'LINE集客マーケティング', accentColor: 'oklch(0.50 0.13 158)', company: '本丸池田屋', industry: '和菓子・スイーツ小売', title: 'クイズ×ポイントで地元ファンの再来店を仕組み化', points: ['登録率が上がる仕掛けを設計', '商品への愛着・理解が深まる', 'ポイント交換が再来店のきっかけに'], heroImg: 'assets/ikedaya-hero.jpg', link: 'case-ikedaya.html', anchorId: 'case-line-marketing' },
{ service: 'LINE集客×システム構築', accentColor: 'oklch(0.48 0.12 190)', company: 'OneCar', industry: '複合施設(ドッグ・カフェ・カー)', title: 'LINE予約×クロスセルクーポンで客単価114~116%を達成', points: ['6ヶ月でLINE登録者+360人', '平均利用単価114~116%向上', '3サービスをLINE一本で横断利用促進'], heroImg: 'assets/onecar-hero.jpg', link: 'case-onecar.html', anchorId: 'case-onecar' },
{ service: 'LINEシステム構築', accentColor: C.gr, company: '株式会社 中島屋降旗米穀店', industry: '小売店(米穀・食料品)', title: '電話受注・手書き帳票のワンオペを、LINE一本で解消', points: ['ヒューマンエラーがなくなった', '帳票作成の工数が大幅に削減', '担当者不在でもチームで対応可能に'], heroImg: 'assets/nakajimaya-hero.jpg', link: 'case-nakajimaya.html', anchorId: 'case-line-system' },
{ service: '日報システム(LINE Works)', accentColor: C.grd, company: '有限会社 松寿園', industry: 'お庭の清掃・メンテナンス業', title: 'LINE Worksで社内連携を強化。現場からそのまま日報提出へ', points: ['外出先でその場で日報作成が完了', '全員のスケジュールが可視化', '従業員満足度が向上'], heroImg: 'assets/shojuen-hero.jpg', link: 'case-shojuen.html', anchorId: 'case-lineworks' },
];
return (
CASE STUDIES
導入事例
{cases.map((c, i) => )}
);
}
/* ── faq ── */
function FAQItem({ q, a, defaultOpen }) {
const [open, setOpen] = R.useState(!!defaultOpen);
return (
setOpen(o => !o)} style={{ background: C.sf, border: `1px solid ${C.ln}`, borderRadius: 14, padding: '18px 20px', cursor: 'pointer', boxShadow: C.sh }}>
Q
{q}
+
{open && (
)}
);
}
function FAQSection() {
const { isMobile } = useViewport();
const px = isMobile ? 20 : 72;
const faqs = [
{ q: 'LINEだけで本当に業務システムになりますか?', a: 'はい。公式LINEおよびLINE WorksはAPIやLINE BOT機能を活用することで、受発注・在庫管理・電子日報など様々な業務システムとして機能します。社員が新しいアプリを覚える必要はありません。', open: true },
{ q: '業種・業態を問いますか?', a: '問いません。小売業・飲食・建設・自動車販売・造園業など、さまざまな業種での導入実績があります。「属人化している業務を改善したい」という課題があれば、まずご相談ください。' },
{ q: '費用はどのくらいかかりますか?', a: 'ご要件と規模によって異なります。相談・お見積りは無料です。まずはどんな業務を改善したいかをお聞かせいただければ、最適な構成をご提案します。' },
{ q: '既にLINEを使っていますが、追加で必要なものはありますか?', a: '基本的には既存の公式LINEまたはLINE Worksアカウントをベースに開発します。アカウントをお持ちでない場合も、開設からサポートします。' },
{ q: '導入後のサポートはありますか?', a: '運用開始後も継続してサポートします。使いながら改善・機能追加も可能です。長期的なパートナーとして伴走します。' },
];
return (
FAQ
よくある質問
{faqs.map((f, i) => )}
);
}
/* ── message ── */
function MessageSection() {
const { isMobile } = useViewport();
const px = isMobile ? 20 : 72;
return (
MESSAGE
仕事の“面倒”を、
仕組みで減らしたい。
高機能なシステムほど、現場では使われずに眠ってしまう。そんな光景を、私たちは何度も見てきました。
soft keys は、誰もが使い慣れた LINE を入口に、御社の業務にぴったりの仕組みをつくります。特定の人に頼らなくていい、誰でも動ける体制をつくること。それが、私たちの目指すDXです。
難しさは私たちが引き受けます。現場には“かんたん”だけを届けたい。一社一社に寄り添って、これからも。
soft keys 代表
滝澤 雅大
たきざわ まさひろ
{[
['事業名', 'soft keys'],
['所在地', '長野県松本市里山辺3949-1\nグランデュール出井3 202'],
['連絡先', 'cheetoi1150@gmail.com'],
].map(([k,v]) => (
{k}
{v}
))}
);
}
/* ── contact ── */
function ContactSection() {
const { isMobile } = useViewport();
const px = isMobile ? 20 : 72;
const [status, setStatus] = R.useState(null);
const [errMsg, setErrMsg] = R.useState('');
const formRef = R.useRef(null);
const handleSubmit = async (e) => {
e.preventDefault();
setStatus('sending');
const fd = new FormData(formRef.current);
try {
const res = await fetch('contact.php', { method: 'POST', body: fd });
const json = await res.json();
if (json.success) { setStatus('ok'); formRef.current.reset(); }
else { setStatus('error'); setErrMsg(json.message || '送信に失敗しました。'); }
} catch { setStatus('error'); setErrMsg('通信エラーです。公式LINEよりお問い合わせください。'); }
};
return (
);
}
/* ── footer ── */
function FooterBar() {
const { isMobile } = useViewport();
const px = isMobile ? 20 : 72;
return (
);
}
/* ── main ── */
function LPv2() {
return (
);
}
window.LPv2 = LPv2;
})();