/* @jsx React.createElement */
// Landing sections for INDIE Labs.
const { useState, useEffect, useRef } = React;
// ============================================================
// HERO — kinetic question that cycles
// ============================================================
const HERO_QUESTIONS = [
"Cafe yang dikelola dari data?",
"Brand UKM level nasional?",
"Founder yang ship, bukan janji?",
"Tim yang main bareng AI?",
"Pengusaha yang tidur tenang?",
];
function HeroQuestion() {
const [i, setI] = useState(0);
const [typed, setTyped] = useState("");
const [phase, setPhase] = useState("typing"); // typing | holding | erasing
useEffect(() => {
let to;
const word = HERO_QUESTIONS[i];
if (phase === "typing") {
if (typed.length < word.length) {
to = setTimeout(() => setTyped(word.slice(0, typed.length + 1)), 28 + Math.random() * 22);
} else {
to = setTimeout(() => setPhase("holding"), 3600);
}
} else if (phase === "holding") {
to = setTimeout(() => setPhase("erasing"), 200);
} else {
if (typed.length > 0) {
to = setTimeout(() => setTyped(word.slice(0, typed.length - 1)), 14);
} else {
to = setTimeout(() => {
setI((i + 1) % HERO_QUESTIONS.length);
setPhase("typing");
}, 360);
}
}
return () => clearTimeout(to);
}, [i, typed, phase]);
return (
{typed}
);
}
function Hero() {
return (
「
INDIE Labs. · R&D for software
」
Mau jadi —Mulai darisatu obrolan.
Kami percaya teknologi itu kendaraan, bukan tujuan.
Tujuannya: kamu jadi versi paling siap dari brand-mu — di
internet, di operasi, di kepercayaan customer.
);
}
// ============================================================
// SERVICES
// ============================================================
const SERVICES = [
{
n: "01",
id: "web",
title: "Web Development",
sub: "Landing · Marketing · Brand",
body: "Punya rumah online sendiri — bukan numpang di marketplace. Brand kamu hadir di Google, di feed, di klien yang Googling kamu jam 11 malam.",
bullets: ["Landing page & micro-site", "Company profile + CMS", "Multi-language ID/EN/JP"],
icon: (
),
},
{
n: "02",
id: "webapp",
title: "Web App",
sub: "POS · Dashboard · Internal tools",
body: "Operasi rapi, kamu tinggal mantau. Bukan kamu yang nge-handle 100 hal harian — tools-mu yang ngerjain, kamu yang mikirin langkah berikutnya.",
bullets: ["POS untuk cafe & restoran", "Dashboard sales & inventory", "Multi-user, role-based"],
icon: (
),
},
{
n: "03",
id: "ai",
title: "AI Integration",
sub: "Chatbot · Automation · LLM",
body: "AI yang kamu pamerin ke klien, bukan disimpen di notebook. Dari prompt yang work jadi produk yang dipake harian — dengan auth, billing, log, semuanya rapi.",
bullets: ["Chatbot WA / web custom", "Workflow automation", "RAG, embeddings, fine-tune"],
icon: (
),
},
{
n: "04",
id: "consult",
title: "IT Consultant",
sub: "Tech stack · Architecture · Audit",
body: "Keputusan teknologi yang gak bikin nyesel enam bulan lagi. Half-day session — jelas, jujur, tanpa upsell tersembunyi.",
bullets: ["Tech stack review", "Architecture & cost audit", "Hiring plan & vendor selection"],
icon: (
),
},
];
function Services() {
return (
Empat jalan jadi versi siap-mu.>}
desc="Bukan tentang fitur atau platform. Tentang siapa kamu setelah enam minggu kerja bareng — brand yang hadir, operasi yang rapi, AI yang dipakai harian."
/>
);
}
// ============================================================
// USE CASES — F&B POS, SMB Accounting, AI-to-Prod
// ============================================================
const USECASES = [
{
k: "F&B",
color: "var(--indie-orange-500)",
title: "Jadi cafe yang dikelola dari data, bukan feeling.",
body: "Tau menu mana yang laku jam berapa, mana yang harus di-pensiunin. Closing tinggal liat dashboard, bukan rekap manual sampe tengah malam.",
points: ["Order ke kitchen display", "Split bill, diskon, voucher", "Laporan harian otomatis ke WA"],
badge: "indiecafe",
},
{
k: "UKM",
color: "var(--indie-cyan-500)",
title: "Jadi UKM yang dipercaya brand nasional.",
body: "Invoice profesional, stok ke-track, supplier puas. Pas calon klien besar nanya ‘sistemnya gimana?’ — kamu udah punya jawabannya.",
points: ["Invoice & quotation generator", "Stok & supplier tracking", "Export ke Excel / e-Faktur"],
badge: "indiepack",
},
{
k: "Founders",
color: "var(--labs-accent)",
title: "Jadi founder yang ship produk, bukan janji.",
body: "Prompt yang work + notebook yang akurat = bukan produk. Kami bantu kemas jadi yang bisa dibayar customer — dengan auth, billing, dan ke-handle 24/7.",
points: ["Frontend chat / form / wizard", "Auth, billing, rate-limit", "Hosting & monitoring beres"],
badge: "indielabs",
},
];
function UseCases() {
return (
Tiga jalan, tiga jadi-an.>}
desc="Customer kami biasanya tidak cerita soal fitur — mereka cerita soal siapa mereka jadi setelah kerja bareng. Tiga pola ini paling sering kami dengar."
/>
{USECASES.map((u) => )}
);
}
function UseCaseCard({ u }) {
return (
{u.k}
{u.title}
{u.body}
{u.points.map((p) => (
→{p}
))}
);
}
// ============================================================
// PROCESS — 4 step
// ============================================================
const PROCESS = [
{ n: "01", t: "Discovery", j: "ディスカバリー", d: "Ngobrol santai 30-60 menit. Kita mapping problem, goal, dan timeline. Free, no strings." },
{ n: "02", t: "Design", j: "デザイン", d: "Wireframe → mockup hi-fi. Kamu review tiap step. Revisi sampai pas, sebelum ngoding sebaris pun." },
{ n: "03", t: "Build", j: "ビルド", d: "Sprint mingguan. Demo tiap Jumat. Kamu lihat progress real, bukan janji-janji." },
{ n: "04", t: "Launch & care", j: "ローンチ", d: "Deploy, monitor, training tim kamu. 30 hari free support pasca-launch." },
];
function Process() {
return (
Empat tahap. Dari ‘punya ide’ jadi ‘punya brand’.>}
desc="Bukan sprint mistis. Empat minggu pertama sudah jelas siapa pegang keputusan apa — supaya gak ada surprise di tengah jalan."
/>