/* global React, ReactDOM */
const { useState, useEffect, useMemo } = React;
// Resource resolver: in the standalone-bundled file, window.__resources[id]
// holds an inlined blob URL; otherwise we fall back to the on-disk path.
const __RES = (typeof window !== "undefined" && window.__resources) || {};
const asset = (id, path) => __RES[id] || path;
// ──────────────────────────────────────────────────────────
// Tweak defaults
// ──────────────────────────────────────────────────────────
const TWEAK_DEFAULTS = /*EDITMODE-BEGIN*/{
"palette": "japonesa",
"displayFont": "provicali",
"cardStyle": "editorial",
"featureLastCard": true,
"showCoupon": true,
"showFaq": true,
"headline": "Sabores que reúnem pessoas."
}/*EDITMODE-END*/;
// ──────────────────────────────────────────────────────────
// Icons
// ──────────────────────────────────────────────────────────
const I = {
whatsapp: (
),
menu: (
),
delivery: (
),
instagram: (
),
arrow: (
),
copy: (
),
check: (
),
plus: (
),
insta: (
),
wa: (
),
waMark: (
),
mail: (
),
};
// ──────────────────────────────────────────────────────────
// Brand data
// ──────────────────────────────────────────────────────────
const BRANDS = [
{
id: "ela",
klass: "b-ela",
num: "01",
cat: "Pizzaria pop / Forno alto",
name: "Ela Pizza",
pitch: "Pizza pop, massa fininha e sabor que grita. A pizzaria que virou cultura de bairro — e ninguém pediu silêncio.",
placeholderTag: "Food shot · ela pizza",
logoImg: asset("logoEla", "assets/logo-ela.jpg"),
foodImg: asset("foodEla", "assets/food-ela.jpg"),
links: {
whatsapp: "https://wa.me/5566999022274?text=Ol%C3%A1%20vim%20pelo%20Instagram%20e%20gostaria%20de%20mais%20informa%C3%A7%C3%B5es!%F0%9F%8D%95",
menu: "https://elapizzadelivery.pedir.online/#/",
instagram: "https://www.instagram.com/elapizzadelivery?igsh=bzllYXdxd3dsNjE0",
},
},
{
id: "maki",
klass: "b-maki",
num: "02",
cat: "Sushi & Temakeria · NOVO",
name: "Maki Maki",
pitch: "Sushi e temaki para dividir (ou não). Combinados generosos, molhos da casa e aquele wasabi que respeita quem pede.",
placeholderTag: "Food shot · temaki + combinado",
logoImg: asset("logoMaki", "assets/logo-maki.jpg"),
foodImg: asset("foodMaki", "assets/food-maki.jpg"),
links: {
whatsapp: "https://wa.me/5566996651183?text=Ol%C3%A1%20vim%20pelo%20Instagram%20e%20gostaria%20de%20mais%20informa%C3%A7%C3%B5es!%F0%9F%8D%A3",
menu: "https://makimaki.pedir.online/#/",
instagram: "https://www.instagram.com/makimaki_sushietemaki?igsh=MW03ZmU4OGQ2NTdncQ==",
},
},
{
id: "riso",
klass: "b-riso",
num: "03",
cat: "Pizzaria clássica / Forno a lenha",
name: "Riso Pizza",
pitch: "A pizzaria que abraça. Receitas da nonna, ingredientes simples e aquele cheirinho que faz a casa parar.",
placeholderTag: "Food shot · pizza margherita",
logoImg: asset("logoRiso", "assets/logo-riso.jpg"),
foodImg: asset("foodRiso", "assets/food-riso.jpg"),
links: {
whatsapp: "https://wa.me/5566996105078?text=Ol%C3%A1%20vim%20pelo%20Instagram%20e%20gostaria%20de%20mais%20informa%C3%A7%C3%B5es!%F0%9F%8D%95",
menu: "https://risopizza.pedir.online/#/",
instagram: "https://www.instagram.com/riso.pizza.delivery?igsh=NnN6cml2cmNnc3Jp",
},
},
{
id: "baita",
klass: "b-baita",
num: "04",
cat: "Espetos / Fogo alto",
name: "Baita Espeto",
pitch: "Espeto de boteco com gente grande na brasa. Tempero forte, ponto exato, embalagem que aguenta o trajeto.",
placeholderTag: "Food shot · espeto na brasa",
logoImg: asset("logoBaita", "assets/logo-baita.jpg"),
foodImg: asset("foodBaita", "assets/food-baita.jpg"),
links: {
whatsapp: "https://wa.me/5566996709916?text=Ol%C3%A1%20vim%20pelo%20Instagram%20e%20gostaria%20de%20saber%20mais%20informa%C3%A7%C3%B5es!%20%F0%9F%8D%96",
menu: "https://baitaespeto.pedir.online/#/",
instagram: "https://www.instagram.com/baita.espeto?igsh=OGdoY2F3N3c1MWYx",
},
},
{
id: "kare",
klass: "b-kare",
num: "05",
cat: "Sushi premium / Omakasê",
name: "Kare Sushi",
pitch: "Sushi premium para ocasiões que merecem. Peixe selecionado, corte limpo e tempero feito com a calma de quem leva o ofício a sério.",
placeholderTag: "Food shot · nigiri premium",
logoImg: asset("logoKare", "assets/logo-kare.jpg"),
foodImg: asset("foodKare", "assets/food-kare.jpg"),
links: {
whatsapp: "https://wa.me/5566997191255?text=Ol%C3%A1%20vim%20pelo%20Instagram%20e%20gostaria%20de%20mais%20informa%C3%A7%C3%B5es!%F0%9F%8D%A3",
menu: "https://karesushi.pedir.online/#/off",
instagram: "https://www.instagram.com/kare.sushi.sorriso?igsh=MW0yeTk3dmp6ZHF4NA==",
},
},
];
const FAQS = [
{ q: "Preciso baixar algum aplicativo?",
a: "Não. Tudo funciona direto no navegador do celular. É rápido, leve, e não ocupa memória." },
{ q: "Funciona bem pelo link da bio do Instagram?",
a: "Sim. O site foi otimizado exatamente para quem chega pelo link da bio. Toques largos, carregamento rápido e atalhos para cada marca." },
{ q: "Cada marca tem WhatsApp próprio?",
a: "Sim. Ao escolher a marca, você fala direto com o atendimento especializado dela — sem central, sem intermediário." },
{ q: "Como uso o cupom CHEF?",
a: "Copie o cupom no topo da página, escolha a marca e cole no momento do pedido. Vale para a primeira compra em qualquer operação do grupo." },
{ q: "Vocês entregam em toda a cidade?",
a: "Atendemos as principais regiões. Cada marca tem sua área de cobertura — confira antes de fechar o pedido." },
];
// ──────────────────────────────────────────────────────────
// Subcomponents
// ──────────────────────────────────────────────────────────
function Topbar() {
return (
);
}
function VerticalVideoGallery() {
// In the standalone bundle, only the videos that were actually inlined are
// available; drop any slot whose video wasn't bundled. In the normal project
// file (__RES empty) all 8 slots play from disk.
const allSlots = [1, 2, 3, 4, 5, 6, 7, 8];
const isBundled = Object.keys(__RES).length > 0;
const slots = isBundled ? allSlots.filter((n) => __RES["vid" + n]) : allSlots;
// duplicate once for seamless loop
const items = [...slots, ...slots];
const frameRef = React.useRef(null);
const trackRef = React.useRef(null);
const [activeDot, setActiveDot] = React.useState(0);
React.useEffect(() => {
const frame = frameRef.current;
if (!frame) return;
const cards = Array.from(frame.querySelectorAll(".vgallery-card"));
// Lazy-load videos only as their card enters (or nears) the visible area.
// This is what keeps the initial mobile payload small — the poster JPG
// (~50-100KB) shows immediately, the MP4 (~1-15MB) only downloads on demand.
const io = new IntersectionObserver((entries) => {
entries.forEach((e) => {
const card = e.target;
const v = card.querySelector("video");
if (!v) return;
if (e.isIntersecting) {
// Lazy-attach src on first reveal
if (!v.src && v.dataset.src) {
v.src = v.dataset.src;
v.load();
}
const p = v.play();
if (p && p.catch) p.catch(() => {});
// Fade out poster once frame data is ready
v.addEventListener("loadeddata", () => card.classList.add("is-loaded"), { once: true });
} else if (!v.paused) {
v.pause();
}
});
}, { root: frame, rootMargin: "30% 30% 30% 30%", threshold: 0.01 });
cards.forEach((c) => io.observe(c));
// Track scroll position for dot pagination (mobile only — when horizontal)
let raf = 0;
const onScroll = () => {
cancelAnimationFrame(raf);
raf = requestAnimationFrame(() => {
const isHorizontal = frame.scrollWidth > frame.clientWidth + 10;
if (!isHorizontal) return;
const card = frame.querySelector(".vgallery-card");
if (!card) return;
const cardW = card.getBoundingClientRect().width + 12; // gap
const idx = Math.round(frame.scrollLeft / cardW) % slots.length;
setActiveDot(Math.max(0, idx));
});
};
frame.addEventListener("scroll", onScroll, { passive: true });
onScroll();
return () => { io.disconnect(); frame.removeEventListener("scroll", onScroll); };
}, [slots.length]);
const jumpTo = (i) => {
const frame = frameRef.current;
if (!frame) return;
const card = frame.querySelector(".vgallery-card");
if (!card) return;
const cardW = card.getBoundingClientRect().width + 12;
frame.scrollTo({ left: cardW * i, behavior: "smooth" });
};
// Mobile marquee: JS-driven horizontal auto-scroll (bulletproof across
// devices — does not rely on CSS animation timelines).
React.useEffect(() => {
const frame = frameRef.current;
const track = trackRef.current;
if (!frame || !track) return;
const mq = window.matchMedia("(max-width: 720px)");
let raf = 0;
let offset = 0;
let last = 0;
const SPEED = 36; // px per second
const isMobile = () => mq.matches;
const step = (ts) => {
if (!last) last = ts;
const dt = (ts - last) / 1000;
last = ts;
// half = width of one full (non-duplicated) set of cards
const half = track.scrollWidth / 2;
if (half > 0) {
offset += SPEED * dt;
if (offset >= half) offset -= half;
track.style.transform = "translateX(" + (-offset) + "px)";
}
raf = requestAnimationFrame(step);
};
const start = () => {
if (raf) return;
// Disable the CSS keyframe animation; JS owns the transform now.
track.style.animation = "none";
last = 0;
raf = requestAnimationFrame(step);
};
const stop = () => {
cancelAnimationFrame(raf);
raf = 0;
track.style.transform = "";
track.style.animation = "";
};
const sync = () => { if (isMobile()) start(); else stop(); };
sync();
const onVis = () => {
if (document.hidden) { cancelAnimationFrame(raf); raf = 0; }
else if (isMobile()) { last = 0; if (!raf) raf = requestAnimationFrame(step); }
};
document.addEventListener("visibilitychange", onVis);
mq.addEventListener ? mq.addEventListener("change", sync) : mq.addListener(sync);
return () => {
stop();
document.removeEventListener("visibilitychange", onVis);
mq.removeEventListener ? mq.removeEventListener("change", sync) : mq.removeListener(sync);
};
}, [slots.length]);
return (
{items.map((n, i) => (
))}
arraste
{slots.map((n, i) => (
);
}
function Hero({ headline }) {
// Pre-split headline at first period if any
const [main, ...rest] = headline.split(/(?<=\.)\s+/);
return (
● Panela Company · Desde 2022
Sabores que reúnem
pessoas.
Cinco marcas, uma cozinha-mãe. Reunimos pizzarias, espetaria e sushi sob a mesma obsessão por sabor, consistência e atendimento de gente que cozinha de verdade.
);
}
function BrandsSection({ featureLastCard }) {
return (
● Nossas marcas
Escolha sua marca, fale direto com a cozinha.
Cada operação tem seu próprio WhatsApp, cardápio e identidade — porque cada marca cozinha o que sabe fazer melhor.
05 marcas ativas
Pedido direto · sem app
Resposta em minutos
{BRANDS.map((b, i) => (
))}
);
}
function About() {
return (
Pedro & Gaby · Fundadores
● Quem somos
Somos Pedro e Gaby — um casal movido pelo mesmo propósito:
cozinha, marca e gente.
Nossa história no empreendedorismo começou em 2022, quando decidimos transformar uma paixão em algo maior. Desde então, não construímos apenas restaurantes — desenvolvemos marcas com identidade, padrão e visão de crescimento.
Atuamos no universo do delivery com diferentes operações: pizzas, espetos e sushis. Cada marca nasce com um conceito claro, foco extremo em qualidade e um compromisso inegociável com a experiência do cliente — do pedido à última mordida.
Nosso sonho é grande — e é só o começo. Queremos levar nossas marcas para todo o Brasil e nos tornar referência nacional em comida delivery, provando que é possível crescer sem perder identidade, qualidade e propósito.
05
Marcas
4+
Anos de estrada
50K+
Pedidos entregues
98%
Aprovação dos clientes
);
}
function OwnerStrip() {
return (
● Fale direto com o dono
Dúvidas, sugestões, críticas ou parcerias?
Estamos sempre ouvindo. A resposta vem do Pedro ou da Gaby — sem central, sem robô.