// Japanese page: statement (gray -> accent wipe), Solutions card stack, Work showcase.
// Same structure and behaviour as ../sections-a.jsx; copy from the copy deck (S-*, SO-*, W-*).
function StatementText({ duplicate }) {
const pill = duplicate
? 無料見積
: 無料見積 ;
return (
あなたのアイデアを、{' '}
{' '}
確実に機能する本番システムへ。迅速に立ち上げ、{' '}
{' '}
事業とともに成長し、確かな成果につなげます。{pill}
);
}
function Statement() {
const reduced = useReducedMotion();
const sectionRef = React.useRef(null);
const stickyRef = React.useRef(null);
useScrollFrame(() => {
const section = sectionRef.current;
const sticky = stickyRef.current;
if (!section || !sticky) return;
const p = reduced ? 0 : pinProgress(section);
sticky.style.setProperty('--wipe', clamp01((p - 0.42) / 0.5).toFixed(4));
}, [reduced]);
return (
);
}
const SERVICES = [
{ t: 'ダッシュボード・レポート', d: '営業・現場・経理の数字をリアルタイムで確認。日報・週報・月報も、Excelの更新を待たずに自動で作成されます。' },
{ t: '業務システム', d: '受発注、購買、承認、案件管理をひとつのシステムに。今の業務の進め方に合わせてつくります。' },
{ t: '在庫・受注管理', d: '在庫の動き、受注、配送、バーコード読み取り、発注アラートを一元管理。すべての拠点・倉庫をまとめて把握できます。' },
{ t: '予約・決済', d: 'オンライン予約、決済、リマインド、お客様のセルフサービスで、Lineとスプレッドシート頼みの運用から卒業できます。' },
{ t: '業務フローの自動化', d: '申請書、チェックリスト、承認、引き継ぎを紙やチャットから移行。誰が何をしたのか、記録がきちんと残ります。' },
{ t: 'システム連携', d: '会計ソフト、ECサイト、Line Businessなど、今お使いのツールと連携。同じデータを何度も入力する手間をなくします。' },
{ t: 'AIアシスタント', d: '書類の読み取り、社内からの質問への回答、返信文の下書き、写真のチェックまで。本当に手間が減るところにAIを組み込みます。' },
];
// Original line illustrations, one per service. Drawn on a 400x220 canvas.
function ServiceArt({ i }) {
const a = 'var(--accent)';
const w = 'rgba(255,255,255,0.85)';
const m = 'rgba(255,255,255,0.22)';
const g = 'rgba(255,255,255,0.08)';
const arts = [
// 0 dashboard: bars + trend line
{[0, 1, 2, 3, 4, 5, 6, 7].map((k) => {
const h = [60, 92, 74, 120, 104, 138, 116, 150][k];
return ;
})}
,
// 1 ERP: connected modules
{[[60, 40], [60, 136], [170, 88], [280, 40], [280, 136]].map(([x, y], k) => (
))}
,
// 2 inventory: shelving with boxes
{[56, 118, 180].map((y) => )}
{[
[56, [[70, 40], [118, 30], [156, 46], [212, 36], [258, 28], [296, 38]]],
[118, [[74, 34], [116, 46], [172, 30], [212, 48], [270, 34]]],
[180, [[68, 38], [114, 30], [152, 44], [206, 34], [250, 48], [306, 28]]],
].map(([shelf, boxes], r) => boxes.map(([x, s], k) => {
const hot = r === 1 && k === 3;
return ;
}))}
,
// 3 booking: calendar with booked slots
支払済
{Array.from({ length: 21 }, (_, k) => {
const booked = [2, 5, 9, 10, 15, 19].includes(k);
return ;
})}
,
// 4 workflow: checklist
{[0, 1, 2, 3].map((k) => (
{k !== 2 && }
{k === 2 && }
))}
,
// 5 integrations: hub and spokes
{[[84, 56], [84, 164], [316, 56], [316, 164], [200, 30], [200, 190]].map(([x, y], k) => (
))}
,
// 6 AI assistant: chat exchange
{[146, 128, 84].map((wd, k) => )}
,
];
return (
{arts[i]}
);
}
function Solutions() {
const reduced = useReducedMotion();
const sectionRef = React.useRef(null);
const [active, setActive] = React.useState(0);
const n = SERVICES.length;
useScrollFrame(() => {
const section = sectionRef.current;
if (!section || reduced) return;
const p = pinProgress(section);
const idx = Math.min(n - 1, Math.floor(p * n * 0.999));
setActive((prev) => (prev === idx ? prev : idx));
}, [reduced]);
return (
実績ある手法とムダのないプロセスで、最初のワークショップから本番稼働まで、アイデアを確実にかたちにします。
まずは一番困っている業務から。準備ができたら、次の機能へそのままつなげられます。
{!reduced && (
{String(active + 1).padStart(2, '0')} / {String(n).padStart(2, '0')}
)}
{SERVICES.map((s, i) => {
const d = i - active;
const cls = d < 0 ? ' is-gone' : '';
return (
3 ? 0 : undefined }}
>
{String(i + 1).padStart(2, '0')}.
);
})}
);
}
// Example builds: drawn sample screens, one per kind of system. Not client work; all figures are sample data.
function WsSide({ active }) {
return (
{[0, 1, 2, 3, 4].map((k) => )}
);
}
function WsTop({ title, chip }) {
return (
{title}
{chip}
);
}
function ScreenDashboard() {
const bars = [34, 52, 46, 70, 62, 84, 58, 76, 92, 66, 48, 30];
const branches = [['A店', '順調', 'ok', 92], ['B店', '混雑', 'warn', 71], ['C店', '遅延', 'bad', 48], ['D店', '順調', 'ok', 88], ['オンラインストア', '順調', 'ok', 95]];
return (
<>
受注件数 1,248 前週比 +8%
対応中 36 本日期限 12件
期限超過 4 要フォロー 2件
納期遵守率 94% 目標 90%
時間帯別の受注 リアルタイム
{bars.map((h, k) => )}
8:00 12:00 16:00 19:00
店舗別の状況
{branches.map(([n, s, c, v]) => (
{n} {s}
))}
>
);
}
function ScreenOrders() {
const cols = [
['新規', 12, [['SO-2291', '24点', ''], ['SO-2292', '6点', ''], ['SO-2293', '11点', '']]],
['承認待ち', 5, [['SO-2287', '値引き 12%', 'approve'], ['SO-2288', '与信枠の確認', 'approve']]],
['梱包中', 8, [['SO-2280', 'ピッキング 18/24', 'warn', 75], ['SO-2283', 'ピッキング 9/9', 'ok', 100], ['SO-2284', 'ピッキング 3/12', 'warn', 25]]],
['配送中', 6, [['SO-2276', '到着予定 15:40', 'ok', 100], ['SO-2278', '到着予定 17:10', 'ok', 100], ['SO-2279', '到着予定 18:00', 'ok', 100]]],
];
const stages = [['新規', 12], ['承認', 5], ['梱包', 8], ['配送中', 6], ['配送済み', 41]];
return (
<>
{stages.map(([s, n], k) =>
{n} {s}
)}
{cols.map(([name, total, cards]) => (
{name} {total}
{cards.map(([id, sub, state, pct]) => (
{id}
{sub}
{state === 'approve'
?
上長の承認待ち 承認
: state &&
}
))}
))}
>
);
}
function ScreenBooking() {
const days = Array.from({ length: 35 }, (_, k) => k - 2);
const slots = [['9:00', 'taken'], ['9:30', ''], ['10:00', 'taken'], ['10:30', 'is-on'], ['11:00', ''], ['11:30', ''], ['14:00', 'taken'], ['14:30', ''], ['15:00', '']];
return (
<>
メニュー 日時 予約金 予約完了
10月 ‹ ›
{['月', '火', '水', '木', '金', '土', '日'].map((d, k) => {d} )}
{days.map((d) => 31 ? 'is-off' : ''}>{d < 1 || d > 31 ? '' : d} )}
10月23日(金) 空き 6枠
{slots.map(([t, c]) => {t} )}
リマインドを設定しました 前日にLINEとメールでお知らせ
ご予約内容
メニュー ご相談 · 60分
日時 10月23日(金)10:30
担当 指名なし
予約金 ¥5,000
24時間前まで、日時の変更は無料です。
予約金を支払う
カード コンビニ PayPay
>
);
}
function ScreenInventory() {
const rows = [
['梱包用段ボール(M)', 'PK-104', 1840, 82, 'ok', '在庫あり'],
['感熱ラベル', 'LB-220', 96, 18, 'bad', '要発注'],
['清掃キット', 'CL-031', 240, 46, 'warn', '残りわずか'],
['プリンタートナー', 'TN-512', 6, 9, 'bad', '要発注'],
['梱包テープ', 'TP-077', 610, 74, 'ok', '在庫あり'],
['作業用手袋(箱)', 'GL-210', 58, 14, 'bad', '要発注'],
['緩衝材ロール', 'BW-118', 320, 66, 'ok', '在庫あり'],
['レシート用紙', 'RP-045', 410, 58, 'ok', '在庫あり'],
];
return (
<>
3品目が発注点を下回っています。 発注書の下書きを作成しました。 発注書を確認
取扱品目 842 2拠点の合計
在庫僅少 4 3品目が発注点
入荷予定 5件 本日入荷 2件
品目 品番 在庫数 水準 状態
{rows.map(([n, sku, q, lvl, c, s]) => (
{n} {sku} {q.toLocaleString('en-US')}
{s}
))}
>
);
}
const WORK_ITEMS = [
{ t: '全店舗の稼働状況をリアルタイムで一覧', tag: 'ダッシュボード', bg: '../uploads/process_scale.webp', Screen: ScreenDashboard, label: 'ダッシュボードのサンプル画面:受注件数、納期遵守率、時間帯別の受注、店舗ごとの状況' },
{ t: '承認フロー付きの受注〜配送管理', tag: '業務システム', bg: '../uploads/process_design.webp', Screen: ScreenOrders, label: '業務システムのサンプル画面:新規受注から承認、梱包、配送までの流れ' },
{ t: 'オンライン予約・決済・リマインド', tag: '顧客ポータル', bg: '../uploads/process_discover.webp', Screen: ScreenBooking, label: '顧客ポータルのサンプル画面:日時を選び、予約金を支払い、リマインドを受け取る' },
{ t: '自動発注アラート付きの在庫管理', tag: '在庫管理', bg: '../uploads/process_build.webp', Screen: ScreenInventory, label: '在庫管理のサンプル画面:品目ごとの在庫数と発注アラート、発注書の下書き' },
];
function WorkMedia({ children, className = '' }) {
const ref = React.useRef(null);
const reduced = useReducedMotion();
useScrollFrame(() => {
const el = ref.current;
if (!el) return;
const r = el.getBoundingClientRect();
const vh = window.innerHeight;
if (r.bottom < 0 || r.top > vh) return;
const centre = (r.top + r.height / 2 - vh / 2) / vh; // -1..1 roughly
el.style.setProperty('--par', reduced ? '0px' : `${(centre * -60).toFixed(1)}px`);
el.style.setProperty('--sc', reduced ? '1' : (1 - Math.min(0.06, Math.abs(centre) * 0.08)).toFixed(3));
}, [reduced]);
return {children}
;
}
function Work() {
return (
事例
{QUOTE_HOST}
{WORK_ITEMS.map(({ t, tag, bg, Screen, label }) => (
))}
);
}
Object.assign(window, { Statement, Solutions, Work });