// ═══════════════════════════════════════════════════════════════════════════
// PAYBACK INTERNATIONAL — Landing Page
// ═══════════════════════════════════════════════════════════════════════════
//
// HOW TO EDIT (look for these markers in this file):
// [EDIT: HERO] → hero slideshow images, focus labels, headline, tagline
// [EDIT: TICKER] → scrolling client ticker names
// [EDIT: WORK] → work grid items (photos, titles, years, tags)
// [EDIT: SERVICES] → the three service columns
// [EDIT: MANIFESTO] → The Haus copy
// [EDIT: CLIENTS] → the 8 client grid tiles
// [EDIT: CONTACT] → address, email, phone, status pill
// [EDIT: FOOTER] → footer columns and legal line
// [EDIT: STATUS] → bottom status bar text
//
// TO REPLACE A PHOTO:
// 1. Upload your new image into the /media folder (any name, e.g. "new-bike.jpg")
// 2. Find the matching `src:` entry below and point it to your filename
// 3. Save, refresh.
//
// ═══════════════════════════════════════════════════════════════════════════
const { useState, useEffect, useRef, useMemo } = React;
const TWEAK_DEFAULTS = /*EDITMODE-BEGIN*/{
"accent": "holo",
"background": "jet",
"displayFont": "michroma",
"pattern": "hex",
"showCursor": true
}/*EDITMODE-END*/;
// ---------- Theme application ----------
function ThemeBridge({ tweaks }) {
useEffect(() => {
const root = document.documentElement;
const body = document.body;
// Backgrounds
const bgMap = {
jet: { bg: "#070707", bg2: "#0c0c0c", fg: "#e7e5dd", fgDim: "#6e6c66", line: "rgba(231,229,221,0.10)", lineStrong: "rgba(231,229,221,0.24)" },
ink: { bg: "#0f0d09", bg2: "#15130f", fg: "#e7e2d4", fgDim: "#75716a", line: "rgba(231,226,212,0.10)", lineStrong: "rgba(231,226,212,0.24)" },
paper: { bg: "#ece8de", bg2: "#e0dccf", fg: "#0a0a0a", fgDim: "#5a5852", line: "rgba(10,10,10,0.16)", lineStrong: "rgba(10,10,10,0.34)" },
};
const palette = bgMap[tweaks.background] || bgMap.jet;
Object.entries(palette).forEach(([k, v]) => {
root.style.setProperty(`--${k === 'bg2' ? 'bg-2' : k === 'fgDim' ? 'fg-dim' : k === 'lineStrong' ? 'line-strong' : k}`, v);
});
// Accent
const accentColorMap = {
mono: "var(--fg)",
holo: "#f3f1ea", // gradient handled via .holo-text class
red: "#e63946",
blue: "#2e6cff",
};
root.style.setProperty("--accent", accentColorMap[tweaks.accent] || accentColorMap.mono);
body.dataset.accent = tweaks.accent;
// Display font
const fontMap = {
michroma:'"Michroma", "Archivo Black", "Helvetica Neue", Helvetica, Arial, sans-serif',
archivo: '"Archivo Black", "Helvetica Neue", Helvetica, Arial, sans-serif',
anton: '"Anton", "Archivo Black", sans-serif',
helv: '"Helvetica Neue", Helvetica, Arial, sans-serif',
};
root.style.setProperty("--display", fontMap[tweaks.displayFont] || fontMap.michroma);
// Pattern
root.style.setProperty("--hex-opacity", tweaks.background === 'paper' ? "0.08" : "0.06");
}, [tweaks]);
return null;
}
// ---------- Reveal on scroll ----------
function useReveal() {
useEffect(() => {
const els = document.querySelectorAll(".reveal");
const io = new IntersectionObserver((entries) => {
entries.forEach((e) => { if (e.isIntersecting) e.target.classList.add("in"); });
}, { threshold: 0.12 });
els.forEach((el) => io.observe(el));
return () => io.disconnect();
});
}
// ---------- Crop-mark wrapper ----------
function Crop({ children, className = "", style }) {
return (
{children}
);
}
// ---------- Cursor blob ----------
function CursorBlob({ enabled }) {
const ref = React.useRef(null);
const target = React.useRef({ x: 0, y: 0 });
const pos = React.useRef({ x: 0, y: 0 });
React.useEffect(() => {
if (!enabled) return;
const onMove = (e) => { target.current.x = e.clientX; target.current.y = e.clientY; };
const onOver = (e) => {
const el = ref.current;
if (!el) return;
const t = e.target;
const hoverable = t.closest("a,button,.work-card,.client,.btn,input,textarea,select,label");
el.classList.toggle("hover", !!hoverable);
};
window.addEventListener("mousemove", onMove);
window.addEventListener("mouseover", onOver);
let raf;
const loop = () => {
pos.current.x += (target.current.x - pos.current.x) * 0.2;
pos.current.y += (target.current.y - pos.current.y) * 0.2;
if (ref.current) {
ref.current.style.transform = `translate(${pos.current.x - 10}px, ${pos.current.y - 10}px)`;
}
raf = requestAnimationFrame(loop);
};
loop();
return () => {
window.removeEventListener("mousemove", onMove);
window.removeEventListener("mouseover", onOver);
cancelAnimationFrame(raf);
};
}, [enabled]);
if (!enabled) return null;
return
;
}
// ---------- Top nav ----------
function TopNav() {
return (
@payback.intl ↗
);
}
// ---------- Hero ----------
// [EDIT: HERO] — slideshow frames. To swap a photo: change the `src:` to your file in /media.
// To change the headline / tagline, scroll down to the JSX in this same function.
const HERO_FRAMES = [
{ src: "media/hero-03-bike-front.jpeg", focus: "Holo Supermoto · Stealth Profile" },
{ src: "media/work-10-gungo-sm.jpg", focus: "Gurellia Supermoto · Side Profile" },
];
const FRAME_DUR_MS = 6000;
function Hero({ accent }) {
const [idx, setIdx] = useState(0);
useEffect(() => {
const id = setInterval(() => {
setIdx((i) => (i + 1) % HERO_FRAMES.length);
}, FRAME_DUR_MS);
return () => clearInterval(id);
}, []);
const currentFocus = HERO_FRAMES[idx].focus;
return (
FILE/01 · {currentFocus}
2024 — 26 · SLOWMO REEL
{HERO_FRAMES.map((f, i) => (
))}
Custom Vehicle Graphics · Apparel · Identity
A design-led force, shaping visual culture.
{HERO_FRAMES.map((_, i) => (
))}
Vehicle graphics, apparel and identity for OEMs, race teams, influencers, motovloggers and private builds. All Done in-house.
);
}
// ---------- Client marquee ticker ----------
// [EDIT: TICKER] — the scrolling client/keyword strip below the hero.
function ClientTicker() {
const items = [
"Autologue",
"Bombay Custom Works",
"Castrol",
"Classic Legends Pvt Ltd",
"Team RACR",
"3M Car Care",
"YC Design",
"Harjee Motorsports",
];
return (
{[...items, ...items].map((it, i) => (
◆ {it}
))}
);
}
// ---------- Work ----------
// [EDIT: WORK] — the 7-card work grid. Each item has src, title, year, tag.
// To add an item: append to this array and add a matching {col,row} entry in the layout array inside Work().
const WORK = [
{ src: "media/work-10-gungo-sm.jpg", title: "Supermoto / Guerilla 450", year: "2026", tag: "Full Wrap" },
{ src: "media/work-08-honeycomb.webp", title: "Mahindra Thar / Circuit X", year: "2025", tag: "Pre Cuts" },
{ src: "media/work-03-supermoto.webp", title: "Supermoto / Holo Shard", year: "2025", tag: "Full Wrap" },
{ src: "media/work-04-enduro.webp", title: "Enduro / Iridescent Mesh", year: "2026", tag: "Full Wrap" },
{ src: "media/work-06-mx.webp", title: "Honey Comb Pattern", year: "2026", tag: "Material R&D" },
{ src: "media/work-02-detail.webp", title: "Tail / Embossed Mark", year: "2026", tag: "Custom Stamp" },
{ src: "media/work-05-tail.webp", title: "Perf Layer / Detail", year: "2026", tag: "Close-up" },
{ src: "media/work-07-thar.webp", title: "MX 250 / Race Kit 05", year: "2026", tag: "SUV Wrap" },
{ src: "media/work-09-gungo-sm.jpg", title: "Supermoto / Guerilla 450", year: "2026", tag: "Iso View" },
{ src: "media/work-11-gungo-sm.jpg", title: "Supermoto / Guerilla 450", year: "2026", tag: "BCW 07" },
{ src: "media/work-11-SUD-XP.webp", title: "Xpulse / Payback", year: "2025", tag: "Side View" },
{ src: "media/work-12-redbull- adv390.jpeg", title: "RedBull / KTM 390 ADV", year: "2026", tag: "Custom Stamp" },
];
function Lightbox({ idx, onClose, onPrev, onNext }) {
const item = WORK[idx];
React.useEffect(() => {
const handler = (e) => {
if (e.key === "Escape") onClose();
if (e.key === "ArrowLeft") onPrev();
if (e.key === "ArrowRight") onNext();
};
window.addEventListener("keydown", handler);
document.body.style.overflow = "hidden";
return () => {
window.removeEventListener("keydown", handler);
document.body.style.overflow = "";
};
}, [idx]);
return (
e.stopPropagation()}>
✕
←
→
{item.title}
{item.tag} · {item.year}
{String(idx+1).padStart(2,"0")} / {String(WORK.length).padStart(2,"0")}
);
}
function WorkCard({ item, idx, span, onOpen }) {
const ref = React.useRef(null);
React.useEffect(() => {
if (ref.current) {
ref.current.addEventListener('click', () => onOpen(idx));
}
}, []);
return (
{String(idx + 1).padStart(2,"0")}/{String(WORK.length).padStart(2,"0")}
{item.year}
);
}
function Work({ onOpen }) {
const layout = [
{ col: 7, row: 1 },
{ col: 5, row: 1 },
{ col: 4, row: 1 },
{ col: 4, row: 1 },
{ col: 4, row: 1 },
{ col: 6, row: 1 },
{ col: 6, row: 1 },
{ col: 8, row: 1 },
{ col: 4, row: 1 },
{ col: 3, row: 1 },
{ col: 3, row: 1 },
{ col: 6, row: 1 },
];
return (
02 / Selected Work
The Reel · 2024 – 26.
Liveries, full wraps, custom material work and race kits — plotted, prototyped and printed in-house, applied by hand panel by panel.
{WORK.map((item, i) => (
))}
);
}
// ---------- Feature plate ----------
function FeaturePlate() {
return null;
}
// ---------- Services ----------
// [EDIT: SERVICES] — the three service columns. Edit `items` inside the function below.
function Services() {
const items = [
{
n: "S/01", title: "Vehicle Graphics",
desc: "Full wraps, race liveries, accent kits and custom-cut vinyl for two and four wheels. Designed for camera, built for the road.",
rows: [
["Format", "Full / Partial / Kit"],
["Materials", "Cast Vinyl · PPF · Holo"],
["Turnaround", "5 – 14 Days"],
["Coverage", "Pan-India · The Haus + Mobile"],
],
},
{
n: "S/02", title: "Apparel & Merch",
desc: "Drop-cycle apparel, team gear and capsule merch — designed alongside the vehicle so the kit, the rider and the bike all speak the same language.",
rows: [
["Output", "Tees · Hoodies · Caps · Patches"],
["Print", "DTF · Embroidery · Screen"],
["MOQ", "From 25 Units"],
["Lead Time", "10 – 21 Days"],
],
},
{
n: "S/03", title: "Custom Identity",
desc: "For OEMs and brands launching a model, riders launching a name. Logo systems, livery DNA, signage, photography direction — the full grammar.",
rows: [
["Scope", "Identity · Livery · Launch"],
["Deliverable", "Brand Book + Asset Kit"],
["Clients", "OEMs · Teams · Riders"],
["Engagement", "Project / Retainer"],
],
},
];
return (
03 / What We Make
Services & Capabilities.
{items.map((it, i) => (
{it.n}
{it.title}
{it.desc}
{it.rows.map(([k, v], j) => (
{k} {v}
))}
))}
);
}
// ---------- Manifesto ----------
// [EDIT: MANIFESTO] — the the Haus copy. Edit the contents below.
function Manifesto() {
return (
04 / The Haus
We're a design-led force shaping visual culture through motion, innovation and expression.
Built in the real world, not the boardroom. Payback International started in Mumbai. We grew up around riders, mechanics and tuners — and the work still smells like that garage.
We treat a bike like a canvas and a canvas like a product. Every wrap is engineered to survive Indian roads,sun and the camera on every rider's helmet cam.
Design is the loudest part. A livery has six seconds to land at 120 km/h. The shape language, the colour break, the placement of a single number — all of it has to read before the bike has passed.
We work with OEMs, race teams, motovloggers and private builds. Same studio, same standard, every panel.
);
}
// ---------- Clients ----------
// [EDIT: CLIENTS] — the 8-tile client grid. Edit the `cells` array inside.
function Clients() {
const cells = [
{ name: "Autologue", sub: "Studio" },
{ name: "Bombay Custom Works", sub: "Builder" },
{ name: "Castrol", sub: "Lubricants" },
{ name: "Classic Legends", sub: "OEM" },
{ name: "Team RACR", sub: "Race Team" },
{ name: "3M Car Care", sub: "Materials" },
{ name: "YC Design", sub: "Garage / Builder" },
{ name: "Harjee Motorsports", sub: "Race Team" },
];
return (
06 / Worked With
The Index.
Brands, OEMs, race teams and the loudest helmets on Indian roads.
{cells.map((c, i) => (
{c.name}
{c.sub}
))}
);
}
// ---------- Contact ----------
// [EDIT: EMAILJS] — Replace the three placeholder strings below with your
// actual EmailJS credentials from https://dashboard.emailjs.com
//
// EMAILJS_SERVICE_ID — e.g. "service_abc123"
// EMAILJS_TEMPLATE_ID — e.g. "template_xyz789"
// EMAILJS_PUBLIC_KEY — e.g. "user_AbCdEfGhIjKlMnOp"
//
// Your EmailJS template should use these variables:
// {{from_name}} {{from_email}} {{project}} {{vehicle}} {{brief}}
//
// Install the SDK (pick one):
// npm install @emailjs/browser
// OR add to your HTML
:
//
const EMAILJS_SERVICE_ID = "service_56a2mli";
const EMAILJS_TEMPLATE_ID = "template_sneor7x";
const EMAILJS_PUBLIC_KEY = "6HQXk96sV1vgg_uId";
// [EDIT: CONTACT] — address, email, phone, booking status are inside the JSX of this function.
function Contact() {
const [form, setForm] = useState({ name: "", email: "", project: "vehicle", vehicle: "", brief: "" });
const [status, setStatus] = useState("idle");
React.useEffect(() => {
const interval = setInterval(() => {
if (window.grecaptcha && document.getElementById('recaptcha-container') && !document.getElementById('recaptcha-container').hasChildNodes()) {
window.grecaptcha.render('recaptcha-container', {
sitekey: '6LePdPYsAAAAAEFM2Z4UWIPLEY5vByzEe0lC0o5m',
theme: 'dark'
});
clearInterval(interval);
}
}, 500);
return () => clearInterval(interval);
}, []);
const update = (k) => (e) => setForm((f) => ({ ...f, [k]: e.target.value }));
const submit = (e) => {
e.preventDefault();
if (!form.name || !form.email || !form.brief) {
setStatus("missing");
return;
}
setStatus("sending");
emailjs.send(
EMAILJS_SERVICE_ID,
EMAILJS_TEMPLATE_ID,
{
from_name: form.name,
from_email: form.email,
project: form.project,
vehicle: form.vehicle || "—",
brief: form.brief,
to_email: "payback.universe@gmail.com",
},
EMAILJS_PUBLIC_KEY
)
.then(() => setStatus("ok"))
.catch(() => setStatus("error"));
};
return (
);
}
// ---------- Footer ----------
// [EDIT: FOOTER] — link columns and legal line.
function Footer({ accent }) {
return (
);
}
// ---------- Status bar (bottom) ----------
// [EDIT: STATUS] — the live status pill at the bottom of every page.
function StatusBar({ tweaks }) {
const [t, setT] = useState(() => new Date());
useEffect(() => {
const id = setInterval(() => setT(new Date()), 1000);
return () => clearInterval(id);
}, []);
const fmt = t.toUTCString().slice(17, 25);
return (
Studio · Live
MUMBAI 30°C
IST {fmt}
Q3 2026
ACCENT/{tweaks.accent}
@payback.intl
);
}
// ---------- Tweaks ----------
function PaybackTweaks({ tweaks, setTweak }) {
return (
setTweak("accent", v)} options={[
{value:"mono",label:"Mono (logo-true)"},
{value:"holo",label:"Holographic"},
{value:"red",label:"Racing Red"},
{value:"blue",label:"Electric Blue"},
]} />
setTweak("background", v)} options={[
{value:"jet",label:"Jet"},
{value:"ink",label:"Ink"},
{value:"paper",label:"Paper"},
]} />
setTweak("displayFont", v)} options={[
{value:"michroma",label:"Michroma (default)"},
{value:"archivo",label:"Archivo Black"},
{value:"anton",label:"Anton"},
{value:"helv",label:"Helvetica"},
]} />
setTweak("showCursor", v)} />
);
}
window.__lightboxIdx = null;
function App() {
const [tweaks, setTweak] = useTweaks(TWEAK_DEFAULTS);
const [lightboxIdx, setLightboxIdx] = React.useState(null);
React.useEffect(() => {
window.__openLightbox = (idx) => setLightboxIdx(idx);
window.__closeLightbox = () => setLightboxIdx(null);
}, []);
const prev = () => setLightboxIdx((i) => (i - 1 + WORK.length) % WORK.length);
const next = () => setLightboxIdx((i) => (i + 1) % WORK.length);
useReveal();
return (
{lightboxIdx !== null && (
setLightboxIdx(null)}
onPrev={prev}
onNext={next}
/>
)}
);
}
document.addEventListener('click', function(e) {
const card = e.target.closest('.work-card');
if (card && window.__openLightbox) {
const cards = Array.from(document.querySelectorAll('.work-card'));
const idx = cards.indexOf(card);
if (idx !== -1) window.__openLightbox(idx);
}
});
ReactDOM.createRoot(document.getElementById("root")).render( );
// WhatsApp floating button
(function() {
const btn = document.createElement('a');
btn.href = 'https://wa.me/919321093779?text=Hi%2C%20I%27d%20like%20to%20discuss%20a%20project%20with%20Payback%20International.';
btn.target = '_blank';
btn.rel = 'noopener';
btn.style.cssText = 'position:fixed;bottom:48px;right:24px;z-index:200;width:72px;height:72px;background:#1a1a1a;border:1px solid rgba(231,229,221,0.4);border-radius:50%;display:flex;align-items:center;justify-content:center;transition:border-color .2s;text-decoration:none';
btn.innerHTML = ' ';
btn.addEventListener('mouseenter', function() { btn.style.borderColor = '#e7e5dd'; });
btn.addEventListener('mouseleave', function() { btn.style.borderColor = 'rgba(231,229,221,0.24)'; });
document.body.appendChild(btn);
})();
// Vanilla JS lightbox — bypasses React state issues
(function() {
let currentIdx = 0;
function showLightbox(idx) {
currentIdx = idx;
const item = WORK[idx];
document.getElementById('vl-img').src = item.src;
document.getElementById('vl-img').alt = item.title;
document.getElementById('vl-title').textContent = item.title;
document.getElementById('vl-meta').textContent = item.tag + ' · ' + item.year;
document.getElementById('vl-count').textContent = String(idx+1).padStart(2,'0') + ' / ' + String(WORK.length).padStart(2,'0');
document.getElementById('vl-overlay').style.display = 'flex';
document.body.style.overflow = 'hidden';
}
function hideLightbox() {
document.getElementById('vl-overlay').style.display = 'none';
document.body.style.overflow = '';
}
// Create lightbox DOM
const overlay = document.createElement('div');
overlay.id = 'vl-overlay';
overlay.style.cssText = 'display:none;position:fixed;inset:0;background:rgba(0,0,0,.96);z-index:99999;align-items:center;justify-content:center;flex-direction:column';
overlay.innerHTML = `
✕
←
→
`;
document.body.appendChild(overlay);
overlay.addEventListener('click', function(e) {
if (e.target === overlay) hideLightbox();
});
document.getElementById('vl-close').addEventListener('click', hideLightbox);
document.getElementById('vl-prev').addEventListener('click', function() {
showLightbox((currentIdx - 1 + WORK.length) % WORK.length);
});
document.getElementById('vl-next').addEventListener('click', function() {
showLightbox((currentIdx + 1) % WORK.length);
});
document.addEventListener('keydown', function(e) {
if (document.getElementById('vl-overlay').style.display === 'flex') {
if (e.key === 'Escape') hideLightbox();
if (e.key === 'ArrowLeft') showLightbox((currentIdx - 1 + WORK.length) % WORK.length);
if (e.key === 'ArrowRight') showLightbox((currentIdx + 1) % WORK.length);
}
});
document.addEventListener('click', function(e) {
const card = e.target.closest('.work-card');
if (card) {
const cards = Array.from(document.querySelectorAll('.work-card'));
const idx = cards.indexOf(card);
if (idx !== -1) showLightbox(idx);
}
});
})();