// Carrossel de depoimentos com efeito coverflow. function TestimonialCarousel() { const TOTAL = 15; const [active, setActive] = React.useState(0); // Armazena { w, h } natural de cada imagem após carregamento const [sizes, setSizes] = React.useState({}); const images = Array.from({ length: TOTAL }, (_, i) => `../../assets/depoimentos/${i + 1}.jpg`); const go = (dir) => setActive(a => (a + dir + TOTAL) % TOTAL); const offsetOf = (i) => { let off = ((i - active) % TOTAL + TOTAL) % TOTAL; if (off > TOTAL / 2) off -= TOTAL; return off; }; // Largura base por posição const baseW = (abs) => abs === 0 ? 500 : abs === 1 ? 310 : 240; // Dimensões reais usando o aspect ratio natural da imagem const dimsOf = (i, abs) => { const w = baseW(abs); const s = sizes[i]; if (!s) return { width: w, height: Math.round(w * 0.9) }; // fallback até carregar return { width: w, height: Math.round(w * s.h / s.w) }; }; const styleOf = (offset, i) => { const abs = Math.abs(offset); const sign = offset < 0 ? -1 : 1; const { width, height } = dimsOf(i, Math.min(abs, 2)); if (abs === 0) return { opacity: 1, width, height, tx: 0, z: 10, shadow: true }; if (abs === 1) return { opacity: 0.8, width, height, tx: sign * 455, z: 7, shadow: false }; return { opacity: 0, width, height, tx: sign * 680, z: 1, shadow: false }; }; // Altura do container acompanha a imagem central carregada const cs = sizes[active]; const containerH = cs ? Math.round(500 * cs.h / cs.w) + 40 : 480; return (
{/* Track */}
{images.map((src, i) => { const off = offsetOf(i); const s = styleOf(off, i); return (
{ if (off === 1) go(1); else if (off === -1) go(-1); }} style={{ position: 'absolute', top: '50%', left: '50%', width: s.width, height: s.height, transform: `translateX(calc(-50% + ${s.tx}px)) translateY(-50%)`, opacity: s.opacity, zIndex: s.z, transition: 'opacity 0.48s cubic-bezier(0.4,0,0.2,1), transform 0.48s cubic-bezier(0.4,0,0.2,1), width 0.48s cubic-bezier(0.4,0,0.2,1), height 0.48s cubic-bezier(0.4,0,0.2,1), box-shadow 0.48s ease', borderRadius: 16, overflow: 'hidden', cursor: Math.abs(off) === 1 ? 'pointer' : 'default', boxShadow: s.shadow ? '0 24px 64px rgba(74,46,31,0.28)' : 'none', background: 'var(--cream-50)', }} > { const { naturalWidth: w, naturalHeight: h } = e.target; setSizes(prev => ({ ...prev, [i]: { w, h } })); }} style={{ width: '100%', height: '100%', objectFit: 'contain', display: 'block', pointerEvents: 'none' }} />
); })} {/* Setas */} {[-1, 1].map((dir) => ( ))}
{/* Dots */}
{images.map((_, i) => (
); } // HowItWorksScreen — Explica o modelo de locação por temporada da SBL. function HowItWorksScreen({ onAnnounce }) { const { Button, Badge, Stat } = window.SBLImVeisDesignSystem_08a506; const { isMobile, isTablet } = window.useResponsive(); const { t } = window.useLang(); const platforms = [ { icon: 'layout-grid', badge: 'Uma plataforma', badgeColor: 'info', title: 'Ex.: somente Airbnb', pros: [ 'Processo mais simples e centralizado', 'Menor risco de conflito de reservas', 'Suporte e garantias da plataforma', 'Ideal para quem está começando', ], cons: 'Exposição limitada a uma única audiência — menor volume de reservas e rentabilidade mais baixa.', security: 3, rentability: 1, }, { icon: 'layers', badge: 'Múltiplas plataformas', badgeColor: 'warning', title: 'Ex.: Airbnb + Booking + outros', pros: [ 'Maior alcance e visibilidade', 'Taxa de ocupação mais alta', 'Rentabilidade significativamente maior', 'Diversificação de canais de venda', ], cons: 'Gestão mais complexa de calendários. Risco de double-booking se não houver sincronização profissional.', security: 1, rentability: 3, }, { icon: 'handshake', badge: 'Direto com a SBL', badgeColor: 'success', title: 'Reserva pela própria corretora', pros: [ 'Atendimento personalizado ao hóspede', 'Sem dependência de plataformas externas', 'Acesso à base própria de clientes da SBL', 'Condições flexíveis de negociação', ], cons: 'Menor alcance orgânico comparado às grandes plataformas — indicado como canal complementar.', security: 2, rentability: 2, }, ]; const Dots = ({ filled, total }) => (
{Array.from({ length: total }).map((_, i) => ( ))}
); return (
{/* HERO */}
{t('Locação por Temporada')}

{t('Entenda como funciona a gestão do seu imóvel de temporada')}

{t('A SBL administra todo o processo — da divulgação ao repasse — para que você só precise acompanhar os resultados.')}

{/* PLATAFORMAS */}
{t('Canais de divulgação')}

{t('Como você quer divulgar seu imóvel?')}

{t('Existem três formas de anunciar. Cada uma tem um perfil diferente de segurança e rentabilidade — a escolha certa depende do seu objetivo.')}

{platforms.map((p) => (
{t(p.badge)}

{t(p.title)}

    {p.pros.map((pro) => (
  • {t(pro)}
  • ))}
{t(p.cons)}
{t('Segurança')}
{t('Rentabilidade')}
))}
{/* DEPOIMENTOS */}
{t('Depoimentos reais')}

{t('O que dizem nossos hóspedes')}

{t('Experiências reais de quem já se hospedou em imóveis gerenciados pela SBL em João Pessoa.')}

{/* COMISSÕES */}
{t('Transparência total')}

{t('Comissões e taxas sem surpresa')}

{t('A SBL cobra apenas sobre o que você recebe — sem mensalidades fixas, sem taxas de adesão.')}

{[ { icon: 'percent', title: '20% sobre o valor das diárias', desc: 'É a comissão cobrada pela SBL para administrar o imóvel de temporada — cobre divulgação, gestão de reservas, atendimento aos hóspedes e repasse.', }, { icon: 'sparkles', title: 'Taxa de limpeza — paga pelo hóspede', desc: 'O custo da limpeza é cobrado do hóspede separadamente nas plataformas (não está embutido na diária), portanto não impacta a rentabilidade do proprietário.', }, { icon: 'handshake', title: 'Comissão negociável', desc: 'Proprietários com dois ou mais imóveis sob gestão da SBL podem negociar condições especiais de comissão. Entre em contato para discutir.', }, ].map((item) => (
{t(item.title)}
{t(item.desc)}
))}
); } window.HowItWorksScreen = HowItWorksScreen;