1 2<!DOCTYPE html> 3<html lang="pt-BR"> 4 5<head> 6 <meta charset="UTF-8"> 7 <base href="https://embalaki.com.br/"> 8 <meta http-equiv="X-UA-Compatible" content="IE=edge"> 9 <meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no"> 10 11 <title>Embalaki - Caixas e embalagens em geral</title> 12 13 <style> 14 :root { 15 --cor_padrao: #387a04; 16 --cor_secundaria: #053d5a; 17 } 18</style> 19 20 <meta name="title" content="Caixas, Sacolas e Embalagens em Papelão | Enviamos para Todo o Brasil" /> 21 <meta name="description" content="Especialistas em embalagens: fabricamos papelão ondulado e fornecemos caixas, sacolas, bobinas e embalagens personalizadas para logÃstica, comércio e indústria. Atendimento em todo o Brasil"> 22 <meta name="keywords" content="fábrica de papelão, embalagens personalizadas, caixas de papelão, embalagens para e-commerce, sacolas personalizadas, bobinas de papel, envelopes, embalagens industriais, papelão ondulado, fornecedor de embalagens, caixas para envio, embalagens sob medida"> 23 <meta name="author" content="Fábrica de Embalagens Embalaki"> 24 <meta name="google-site-verification" content="BItng278RUCvUuWTJRvj-wcmOE4cERosp3Nt6ibht9g"> 25 26 <!-- Favicon --> 27 <link rel="shortcut icon" href="https://embalaki.com.br/storage/imagens/configuracoes/d18a91a215deb80da60e621378c290eb.png"> 28 29 <!-- Google tag (gtag.js) -->
vendor: 69 bytes, lines 29-30
29 30 <script async src="https://www.googletagmanager.com/gtag/js?id=
30G-7H15RKCT86
vendor: 17 bytes, lines 30-31
30"></script> 31
31<script> 32
vendor: 148 bytes, lines 32-35
32window.dataLayer = window.dataLayer || []; 33 function gtag(){dataLayer.push(arguments);} 34 gtag('js', new Date()); 35 gtag('config', '
35G-7H15RKCT86
vendor: 9 bytes, lines 35-36
35'); 36
36</script>
36 37 38 39
39<script> 40 WebFontConfig = { 41 google: { families: [ 'Open+Sans:300,400,600,700,800', 'Poppins:300,400,500,600,700', 'Shadows+Into+Light:400' ] } 42 }; 43 ( function ( d ) { 44 var wf = d.createElement( 'script' ), s = d.scripts[ 0 ]; 45 wf.src = 'https://embalaki.com.br/templates/porto-min/assets/js/webfont.js'; 46 wf.async = true; 47 s.parentNode.insertBefore( wf, s ); 48 } )( document ); 49 </script>
49 50 51 <!-- Plugins CSS File --> 52 <link rel="stylesheet" type="text/css" href="https://embalaki.com.br/templates/porto-min/assets/css/bootstrap.min.css" > 53 54 <!-- Main CSS File --> 55 <link rel="stylesheet" type="text/css" href="https://embalaki.com.br/templates/porto-min/assets/css/style-loja1.css"> 56 <link rel="stylesheet" type="text/css" href="https://embalaki.com.br/assets/css/porto-adicionais.css?v=1787706172"> 57 <link rel="stylesheet" type="text/css" href="https://embalaki.com.br/templates/porto-min/assets/vendor/fontawesome-free/css/all.min.css"> 58 <link rel="stylesheet" type="text/css" href="https://embalaki.com.br/templates/porto-min/assets/vendor/simple-line-icons/css/simple-line-icons.min.css"> 59 60 <!-- Plugins toastify js --> 61 <link rel="stylesheet" type="text/css" href="https://embalaki.com.br/assets/plugins/toastr/toastr.min.css"> 62 63 <link rel="stylesheet" type="text/css" href="https://embalaki.com.br/assets/plugins/image-uploader/image-uploader.css"> 64 65 <link rel="stylesheet" type="text/css" href="https://embalaki.com.br/assets/css/style-update.css?v=1789039900"> 66 67 </head> 68 69 70<body> 71 72 <div class="page-wrapper"> 73 74 75<header class="header"> 76 77 <div class="header-top"> 78 <div class="container"> 79 <div class="header-left d-none d-sm-block"> 80 <p class="top-message text-uppercase">Bem-vindo à Embalaki</p> 81 </div> 82 83 <div class="header-right header-dropdowns ml-0 ml-sm-auto w-sm-100"> 84 <div class="header-dropdown dropdown-expanded d-none d-lg-block"> 85 <a href="#">Links</a> 86 <div class="header-menu"> 87 <ul> 88 <li><a href="home"><i class="icon-home"></i> Home</a></li><li><a href="sobre"><i class="fas fa-building"></i> Sobre</a></li><li><a href="portfolio"><i class="fas fa-images"></i> Portfólio</a></li><li><a href="faq"><i class="sicon-question"></i> FAQ</a></li><li><a href="contato"><i class="sicon-envelope"></i> Contato</a></li><li><a href="carrinho"><i class="icon-cart"></i> Carrinho</a></li> </ul> 89 </div> 90 </div> 91 92 <span class="separator"></span> 93 94 <div class="header-dropdown mr-auto mr-sm-3 mr-md-0 dropdown-expanded"> 95 <a href="#">Minha Conta</a> 96 97 <div class="header-menu"> 98 <ul class="ul-header-menu"> 99 100 101 <li><a href="cadastro"><i class="sicon-note"></i> Cadastre-se</a></li> 102 <li><a href="login"><i class="sicon-login"></i> Login (Entrar)</a></li> 103 104 105 106 </ul> 107 </div> 108 </div> 109 110 <span class="separator"></span> 111 112 <!-- 113 <div class="header-dropdown"> 114 <a href="#"><i class="flag-br flag"></i>BRA</a> 115 <div class="header-menu"> 116 <ul> 117 <li><a href="#"><i class="flag-br flag mr-2"></i>BRA</a></li> 118 <li><a href="#"><i class="flag-us flag mr-2"></i>ENG</a></li> 119 <li><a href="#"><i class="flag-es flag mr-2"></i>ESP</a></li> 120 </ul> 121 </div> 122 </div> 123 --> 124 125 <!-- 126 <div class="header-dropdown mr-auto mr-sm-3 mr-md-0"> 127 <a href="#">BRL</a> 128 <div class="header-menu"> 129 <ul> 130 <li><a href="#">BRL</a></li> 131 <li><a href="#">USD</a></li> 132 <li><a href="#">EUR</a></li> 133 </ul> 134 </div> 135 </div> 136 --> 137 138 <span class="separator"></span> 139 140 <div class="social-icons"> 141 <a href="https://www.facebook.com/profile.php?id=100088960533452" class="social-icon social-facebook icon-facebook" target="_blank"></a> 142 <a href="https://x.com/embalaki" class="social-icon social-twitter icon-twitter" target="_blank"></a> 143 144 <a href="https://instagram.com/embalaki_" class="social-icon social-instagram icon-instagram" target="_blank"></a> 145 <a href="https://www.youtube.com/channel/UC4_tNXsgJJuqhKgvUKOto0Q" class="social-icon social-youtube sicon-social-youtube" target="_blank"></a> 146 147 </div> 148 </div> 149 </div> 150 </div> 151 152 <div class="header-middle sticky-header" data-sticky-options="{'mobile': false}"> 153 <div class="container"> 154 <div class="header-left col-lg-2 w-auto pl-0"> 155 <button class="mobile-menu-toggler text-primary mr-2" type="button"> 156 <i class="fas fa-bars"></i> 157 </button> 158 <a href="home" class="logo"> 159 <img src="https://embalaki.com.br/storage/imagens/configuracoes/8ef25bd9b58f9c36c7e17f852a15a5ac.png" alt="Embalaki - Caixas e embalagens em geral"> 160 </a> 161 </div> 162 163 <div class="header-right w-lg-max"> 164 <div class="header-icon header-search header-search-inline header-search-category w-lg-max text-right mt-0"> 165 <a href="#" class="search-toggle" role="button"><i class="icon-search-3"></i></a> 166 <form action="produtos" method="get"> 167 <div class="header-search-wrapper"> 168 <input type="search" class="form-control" name="busca" value="" aria-label="Pesquisar" placeholder="Pesquisar..."> 169 <div class="select-custom"> 170 <select id="dep" name="c"> 171 <option value="">Categorias</option> 172 <option value="1" >Caixas de Papelão</option> 173 <option value="68" >Chapas de Papelão</option> 174 <option value="10" >Descartáveis</option> 175 <option value="9" >Envelopes de Segurança</option> 176 <option value="67" >Fitas Adesivas</option> 177 <option value="13" >Outros</option> 178 <option value="12" >Sacolas e Sacos</option> 179 <option value="64" >Saquinho Tipo Zip Lock</option> 180 181 </select> 182 </div> 183 184 <button class="btn icon-magnifier" type="submit"></button> 185 </div> 186 187 </form> 188 </div> 189 190 <div class="header-contact d-none d-lg-flex pl-4 pr-4"> 191 <img alt="phone" src="assets/img/whatsapp.png" width="30" height="30" class="pb-1"> 192 <h6><span>SAC</span>
192<a href="https://web.whatsapp.com/send?phone=(19) 99678-1322" class="text-dark font1">(19) 99678-1322</a></h6> 193 </div> 194 195 <a href="login" class="header-icon" title="Login"><i class="icon-user-2"></i></a> 196 197 <a href="favoritos" class="header-icon" title="Favoritos"><i class="icon-wishlist-2"></i></a> 198 199 <div class="dropdown cart-dropdown"> 200 <a href="#" title="Carrinho de compras" class="dropdown-toggle dropdown-arrow cart-toggle" role="button" 201 data-toggle="dropdown" aria-haspopup="true" aria-expanded="false" data-display="static"> 202 <i class="icon-cart"></i> 203 <span class="cart-count badge-circle"></span> 204 </a> 205 206 <div class="cart-overlay"></div> 207 208 <div class="dropdown-menu mobile-cart"> 209 <a href="#" title="Fechar (Esc)" class="btn-close">Ã</a> 210 211 <div class="dropdownmenu-wrapper custom-scrollbar"> 212 <div class="dropdown-cart-header">Carrinho de compras</div> 213 214 <div class="drop"></div> 215 216 </div> 217 </div> 218 </div> 219 220 221 </div> 222 </div> 223 </div> 224 225 <div class="header-bottom sticky-header d-none d-lg-block" data-sticky-options="{'mobile': false}"> 226 <div class="container"> 227 <nav class="main-nav w-100"> 228 <ul class="menu"> 229 230 <li><a href="produtos">Categorias</a> 231 <ul class="submenu"><li><a href="produtos/caixas-de-papelao">Caixas de Papelão</a><ul class="submenu"><li><a href="produtos/caixas-de-papelao/alimentacaobebidas">Alimentação/Bebidas</a></li><li><a href="produtos/caixas-de-papelao/maleta">Maleta</a><ul class="submenu"><li><a href="produtos/caixas-de-papelao/maleta/16x11x8">16x11x8</a></li><li><a href="produtos/caixas-de-papelao/maleta/16x16x16">16x16x16</a></li><li><a href="produtos/caixas-de-papelao/maleta/18x12x8">18x12x8</a></li><li><a href="produtos/caixas-de-papelao/maleta/20x13x6">20x13x6</a></li><li><a href="produtos/caixas-de-papelao/maleta/20x14x8">20x14x8</a></li><li><a href="produtos/caixas-de-papelao/maleta/21x12x30">21x12x30</a></li><li><a href="produtos/caixas-de-papelao/maleta/22x15x9">22x15x9</a></li><li><a href="produtos/caixas-de-papelao/maleta/23x20x10">23X20X10</a></li><li><a href="produtos/caixas-de-papelao/maleta/24x16x10">24x16x10</a></li><li><a href="produtos/caixas-de-papelao/maleta/26x17x35">26x17x35</a></li><li><a href="produtos/caixas-de-papelao/maleta/26x26x26">26x26x26</a></li><li><a href="produtos/caixas-de-papelao/maleta/28x18x12">28x18x12</a></li><li><a href="produtos/caixas-de-papelao/maleta/29x21x19">29x21x19</a></li><li><a href="produtos/caixas-de-papelao/maleta/31x31x31">31x31x31</a></li><li><a href="produtos/caixas-de-papelao/maleta/34x24x5">34x24x5</a></li><li><a href="produtos/caixas-de-papelao/maleta/36x24x22">36x24x22</a></li><li><a href="produtos/caixas-de-papelao/maleta/39x11x39">39x11x39</a></li><li><a href="produtos/caixas-de-papelao/maleta/39x21x39">39x21x39</a></li><li><a href="produtos/caixas-de-papelao/maleta/42x32x40">42x32x40</a></li><li><a href="produtos/caixas-de-papelao/maleta/45x33x39">45x33x39</a></li><li><a href="produtos/caixas-de-papelao/maleta/9x9x56">9x9x56</a></li><li><a href="produtos/caixas-de-papelao/maleta/21x21x21">21x21x21</a></li></ul></li><li><a href="produtos/caixas-de-papelao/montavel">Montável</a></li><li><a href="produtos/caixas-de-papelao/pac-mini">PAC Mini</a></li></ul></li><li><a href="produtos/chapas-de-papelao">Chapas de Papelão</a></li><li><a href="produtos/descartaveis">Descartáveis</a></li><li><a href="produtos/envelopes-de-seguranca">Envelopes de Segurança</a></li><li><a href="produtos/fitas-adesivas">Fitas Adesivas</a></li><li><a href="produtos/outros">Outros</a></li><li><a href="produtos/sacolas-e-sacos">Sacolas e Sacos</a><ul class="submenu"><li><a href="produtos/sacolas-e-sacos/sacolas-kraft">Sacolas Kraft</a></li><li><a href="produtos/sacolas-e-sacos/sacos-kraft">Sacos Kraft</a></li></ul></li><li><a href="produtos/saquinho-tipo-zip-lock">Saquinho Tipo Zip Lock</a></li></ul> </li> 232 <li><a href="home">Home</a></li><li><a href="sobre">Sobre</a></li><li><a href="portfolio">Portfólio</a></li><li><a href="faq">FAQ</a></li><li><a href="contato">Contato</a></li><li><a href="carrinho">Carrinho</a></li> <li class="float-right"><a href="produtos" class="pl-5">Ofertas!</a></li> 233 <li class="float-right"><a href="produtos?ordem=criado-desc" class="pl-5">Novidades!</a></li> 234 </ul> 235 </nav>
236 </div> 237 </div> 238 239</header> 240 241 <main class="main"> 242 <div id="erro"></div> 243 244 245 246 <div class="page-header mb-4"> 247 <div class="container d-flex flex-column align-items-center"> 248 <nav aria-label="breadcrumb" class="breadcrumb-nav"> 249 <div class="container"> 250 <ol class="breadcrumb"> 251 <li class="breadcrumb-item"><a href="home"><i class="icon-home"></i> Home</a></li> 252 <li class="breadcrumb-item active" aria-current="page"> 253 Sobre a Empresa </li> 254 </ol> 255 </div> 256 </nav> 257 258 <h1>Sobre a Empresa</h1> 259 </div> 260 </div> 261 262 <div class="container mb-4"> 263 <p>A <strong>Embalaki</strong> é especializada na fabricação de caixas de papelão e na comercialização de embalagens para empresas e consumidores de todo o Brasil. Fundada em <strong>15 de outubro de 2012</strong>, a empresa conquistou a confiança de milhares de clientes oferecendo produtos de qualidade, preços competitivos e um atendimento ágil e personalizado.</p> 264<p>Trabalhamos com uma ampla linha de embalagens para atender desde pequenos empreendedores até grandes empresas dos mais diversos segmentos. Além das caixas de papelão, oferecemos diversos produtos para embalagem e expedição, como fitas adesivas, sacos plásticos, envelopes, materiais para proteção e muito mais.</p> 265<p>Nossa missão é fornecer soluções práticas, seguras e econômicas para embalar, proteger e transportar produtos, contribuindo para o crescimento dos negócios de nossos clientes.</p> 266<p>Buscamos constantemente aprimorar nossos processos, investir em novos produtos e oferecer um atendimento diferenciado, auxiliando cada cliente na escolha da embalagem mais adequada para sua necessidade.</p> 267<p>Localizada em <strong>Casa Branca - SP</strong>, a Embalaki atende clientes em todo o território nacional por meio de vendas online e envios rápidos, sempre priorizando qualidade, compromisso e pontualidade.</p> 268<p>Ao longo de mais de uma década de atuação, construÃmos nossa história com base em valores como <strong>transparência, respeito, inovação, compromisso e satisfação do cliente</strong>.</p> 269<p><strong>Embalaki â A embalagem certa para proteger, transportar e valorizar o seu produto.</strong></p> </div> 270 271 </main> 272 <footer class="footer bg-dark position-relative"> 273 <div class="footer-middle"> 274 <div class="container position-static"> 275 276 <div class="footer-ribbon">Entre em contato</div> 277 278 <div class="row"> 279 <div class="col-lg-3 col-sm-6"> 280 <div class="widget"> 281 <ul class="contact-info"> 282 <li><span class="contact-info-label">Whatsapp:</span><a href="tel:">(19) 99678-1322</a></li> 283 <li><span class="contact-info-label">Endereço:</span>Rua Dr. Arnaud Cintra Rodrigues, 642<br>Jardim Boa Esperança<br>Casa Branca - SP<br>CEP 13703020</li> 284 <li><span class="contact-info-label"><a href="horario-de-funcionamento">Horário de Funcionamento:</span></a>Segunda-feira: 7:00 - 17:00<br /> 285Terça-feira: 7:00 - 17:00<br /> 286Quarta-feira: 7:00 - 17:00<br /> 287Quinta-feira: 7:00 - 17:00<br /> 288Sexta-feira: 7:00 - 16:00<br /> 289Sábado: fechado<br /> 290Domingo: fechado</li> 291 </ul> 292 <div class="social-icons"> 293 <a class="social-icon social-facebook icon-facebook" title="Facebook" href="https://www.facebook.com/profile.php?id=100088960533452" target="_blank"></a> <a class="social-icon social-twitter icon-twitter" title="Twitter" href="https://x.com/embalaki" target="_blank"></a> <a class="social-icon social-youtube sicon-social-youtube" title="Youtube" href="https://www.youtube.com/channel/UC4_tNXsgJJuqhKgvUKOto0Q" target="_blank"></a> <a class="social-icon social-instagram icon-instagram" title="Instagran" href="https://instagram.com/embalaki_" target="_blank"></a> </div> 294 </div>
295 </div> 296 297 <div class="col-lg-3 col-sm-6"> 298 <div class="widget"> 299 <h4 class="widget-title pb-1">Atendimento ao Cliente</h4> 300 <ul class="links"> 301 <li><a href="faq">FAQ - Ajuda e Perguntas Frequentes</a></li><li><a href="informacoes-sobre-a-entrega">Informações Sobre a Entrega</a></li><li><a href="formas-de-pagamento">Formas de Pagamento</a></li><li><a href="termos-e-condicoes">Termos e condições</a></li><li><a href="politica-de-privacidade">PolÃtica de Privacidade</a></li> 302 </ul> 303 </div> 304 </div> 305 306 <div class="col-lg-3 col-sm-6"> 307 308 <div class="widget"> 309 <h4 class="widget-title"><a href="tags">Tags Populares</a></h4> 310 <div class="tagcloud"> 311 <a href="produtos?t=Saquinhos Zip Lock">Saquinhos Zip Lock</a> 312 </div> 313 </div> 314 </div> 315 316 <div class="col-lg-3 col-sm-6"> 317 <div class="widget widget-newsletter"> 318 <h4 class="widget-title"><a href="newsletter">Newsletter</a></h4> 319 <p>Receba as últimas novidades, promoções e ofertas exclusivas. Inscreva-se em nosso boletim informativo. 320 </p> 321 <form method="post" class="form-newsletter" novalidate> 322 <input type="email" class="form-control" placeholder="Endereço de e-mail" name="newsletter_email" id="newsletter_email"> 323<input type="submit" class="btn btn-primary shadow-none" value="Inscrever" id="botao-inscrever"> </form> 324 </div> 325 </div> 326 </div> 327 </div> 328 </div> 329 330 <div class="container"> 331 <div class="footer-bottom"> 332 <div class="container d-sm-flex align-items-center"> 333 <div class="footer-left"> 334 <span class="footer-copyright">Embalaki® é uma marca registrada | CNPJ: 12.566.244/0001-15 | Todos os direitos reservados 2025. | by ɹɾ</span> 335 </div> 336 337 <div class="footer-right ml-auto mt-1 mt-sm-0"> 338 <div class="payment-icons"> 339 <span class="payment-icon" style="background-image: url('https://embalaki.com.br/storage/imagens/configuracoes//f9f58cf8b5185d28f17f3ce6a4533e51.png')"></span> 340 <span class="payment-icon" style="background-image: url('https://embalaki.com.br/storage/imagens/configuracoes//b67a6a7af09ffd74c67c0c6b2de86a14.png')"></span> 341 <span class="payment-icon" style="background-image: url('https://embalaki.com.br/storage/imagens/configuracoes//e10751cda6a8de4b2cd5a79a3b0282bd.png')"></span> 342 <span class="payment-icon" style="background-image: url('https://embalaki.com.br/storage/imagens/configuracoes//3924fdd077e1e62386d5d521968681b4.png')"></span> 343 <span class="payment-icon" style="background-image: url('https://embalaki.com.br/storage/imagens/configuracoes//ea2bac5a8da98b2413479bcedab574ff.png')"></span> 344 <span class="payment-icon" style="background-image: url('https://embalaki.com.br/storage/imagens/configuracoes//e52953e9cb5d132c17b9c45dda916874.png')"></span> 345 <span class="payment-icon" style="background-image: url('https://embalaki.com.br/storage/imagens/configuracoes//c2be45a7b713091f45424bb156820db3.png')"></span> 346 <span class="payment-icon" style="background-image: url('https://embalaki.com.br/storage/imagens/configuracoes//06959bbdac43f5ba406331f67d01598e.png')"></span> 347 <span class="payment-icon" style="background-image: url('https://embalaki.com.br/storage/imagens/configuracoes//c0ab983d26977965a080fc09795cd811.png')"></span> 348 349 </div> 350 </div> 351 </div> 352 </div> 353 </div> 354</footer> 355 </div> 356 357 <div class="loading-overlay"> 358 <div class="bounce-loader"> 359 <div class="bounce1"></div> 360 <div class="bounce2"></div> 361 <div class="bounce3"></div> 362 </div> 363 </div> 364 365 <div class="mobile-menu-overlay"></div> 366 367<div class="mobile-menu-container"> 368 <div class="mobile-menu-wrapper"> 369 <span class="mobile-menu-close"><i class="fa fa-times"></i></span> 370 <nav class="mobile-nav"> 371 <ul class="mobile-menu menu-with-icon"> 372 <li> 373 <a href="#" class="sf-with-ul"><i class="sicon-badge"></i> Categorias</a> 374 <ul class="submenu"><li><a href="produtos/caixas-de-papelao">Caixas de Papelão</a><ul class="submenu"><li>
374<a href="produtos/caixas-de-papelao/alimentacaobebidas">Alimentação/Bebidas</a></li><li><a href="produtos/caixas-de-papelao/maleta">Maleta</a><ul class="submenu"><li><a href="produtos/caixas-de-papelao/maleta/16x11x8">16x11x8</a></li><li><a href="produtos/caixas-de-papelao/maleta/16x16x16">16x16x16</a></li><li><a href="produtos/caixas-de-papelao/maleta/18x12x8">18x12x8</a></li><li><a href="produtos/caixas-de-papelao/maleta/20x13x6">20x13x6</a></li><li><a href="produtos/caixas-de-papelao/maleta/20x14x8">20x14x8</a></li><li><a href="produtos/caixas-de-papelao/maleta/21x12x30">21x12x30</a></li><li><a href="produtos/caixas-de-papelao/maleta/22x15x9">22x15x9</a></li><li><a href="produtos/caixas-de-papelao/maleta/23x20x10">23X20X10</a></li><li><a href="produtos/caixas-de-papelao/maleta/24x16x10">24x16x10</a></li><li><a href="produtos/caixas-de-papelao/maleta/26x17x35">26x17x35</a></li><li><a href="produtos/caixas-de-papelao/maleta/26x26x26">26x26x26</a></li><li><a href="produtos/caixas-de-papelao/maleta/28x18x12">28x18x12</a></li><li><a href="produtos/caixas-de-papelao/maleta/29x21x19">29x21x19</a></li><li><a href="produtos/caixas-de-papelao/maleta/31x31x31">31x31x31</a></li><li><a href="produtos/caixas-de-papelao/maleta/34x24x5">34x24x5</a></li><li><a href="produtos/caixas-de-papelao/maleta/36x24x22">36x24x22</a></li><li><a href="produtos/caixas-de-papelao/maleta/39x11x39">39x11x39</a></li><li><a href="produtos/caixas-de-papelao/maleta/39x21x39">39x21x39</a></li><li><a href="produtos/caixas-de-papelao/maleta/42x32x40">42x32x40</a></li><li><a href="produtos/caixas-de-papelao/maleta/45x33x39">45x33x39</a></li><li><a href="produtos/caixas-de-papelao/maleta/9x9x56">9x9x56</a></li><li><a href="produtos/caixas-de-papelao/maleta/21x21x21">21x21x21</a></li></ul></li><li><a href="produtos/caixas-de-papelao/montavel">Montável</a></li><li><a href="produtos/caixas-de-papelao/pac-mini">PAC Mini</a></li></ul></li><li><a href="produtos/chapas-de-papelao">Chapas de Papelão</a></li><li><a href="produtos/descartaveis">Descartáveis</a></li><li><a href="produtos/envelopes-de-seguranca">Envelopes de Segurança</a></li><li><a href="produtos/fitas-adesivas">Fitas Adesivas</a></li><li><a href="produtos/outros">Outros</a></li><li><a href="produtos/sacolas-e-sacos">Sacolas e Sacos</a><ul class="submenu"><li><a href="produtos/sacolas-e-sacos/sacolas-kraft">Sacolas Kraft</a></li><li><a href="produtos/sacolas-e-sacos/sacos-kraft">Sacos Kraft</a></li></ul></li><li><a href="produtos/saquinho-tipo-zip-lock">Saquinho Tipo Zip Lock</a></li></ul> </li> 375 376 <li><a href="home"><i class="icon-home"></i> Home</a></li><li><a href="sobre"><i class="fas fa-building"></i> Sobre</a></li><li><a href="portfolio"><i class="fas fa-images"></i> Portfólio</a></li><li><a href="faq"><i class="sicon-question"></i> FAQ</a></li><li><a href="contato"><i class="sicon-envelope"></i> Contato</a></li><li><a href="carrinho"><i class="icon-cart"></i> Carrinho</a></li> 377 </ul> 378 379 </nav> 380 <!-- End .mobile-nav --> 381 382 <form class="search-wrapper mb-2" action="produtos" method="get"> 383 <input type="text" class="form-control mb-0" name="busca" value="" placeholder="Pesquisar..."> 384 <button class="btn icon-search text-white bg-transparent p-0" type="submit"></button> 385 </form> 386 387 <div class="social-icons"> 388 <a href="https://www.facebook.com/profile.php?id=100088960533452" class="social-icon social-facebook icon-facebook" target="_blank"></a> 389 <a href="https://x.com/embalaki" class="social-icon social-twitter icon-twitter" target="_blank"></a> 390 391 <a href="https://instagram.com/embalaki_" class="social-icon social-instagram icon-instagram" target="_blank"></a> 392 <a href="https://www.youtube.com/channel/UC4_tNXsgJJuqhKgvUKOto0Q" class="social-icon social-youtube sicon-social-youtube" target="_blank"></a> 393 394 395 </div> 396 </div> 397</div> 398 399 <div class="sticky-navbar"> 400 <div class="sticky-info"> 401 <a href="https://embalaki.com.br/home"> 402 <i class="icon-home"></i>Home 403 </a> 404 </div> 405 <div class="sticky-info"> 406 <a href="#menu-mobile" class="sticky-categorias-toggler" aria-label="Abrir categorias"> 407 <i class="icon-bars"></i>Categorias 408 </a> 409 </div> 410 <div class="sticky-info"> 411 <a href="https://embalaki.com.br/favoritos"> 412 <i class="icon-wishlist-2"></i>Favoritos 413 </a> 414 </div> 415 <div class="sticky-info"> 416 <a href="https://embalaki.com.br/login"> 417 <i class="icon-user-2"></i>Minha Conta 418 </a> 419 </div> 420 <div class="sticky-info"> 421 <a href="https://embalaki.com.br/carrinho"> 422 <i class="icon-cart position-relative">
423 <span class="cart-count badge-circle">0</span> 424 </i>Carrinho 425 </a> 426 </div> 427 </div> 428 429 430 <a id="scroll-top" href="#top" title="Top" role="button"><i class="icon-angle-up"></i></a> 431 432 433<!-- âââââââââââââââââââââââââââââââââââââââââââââââââââââââ 434 CHAT WIDGET FLUTUANTE 435 âââââââââââââââââââââââââââââââââââââââââââââââââââââââ --> 436<style> 437/* ââ Cores do sistema ââ */ 438#chat-fab, #chat-widget { 439 --color-primary: #387a04; 440 --color-secondary: #053d5a; 441} 442 443/* ââ Botão flutuante ââ */ 444#chat-fab { 445 position: fixed; 446 bottom: 28px; 447 right: 28px; 448 width: 56px; 449 height: 56px; 450 border-radius: 50%; 451 background: var(--color-primary, #0088cc); 452 color: #fff; 453 border: none; 454 cursor: pointer; 455 box-shadow: 0 4px 16px rgba(0,0,0,.25); 456 display: none; /* controlado via JS conforme admin online */ 457 align-items: center; 458 justify-content: center; 459 font-size: 22px !important; 460 z-index: 9999; 461 transition: transform .2s, box-shadow .2s; 462} 463#chat-fab:hover { transform: scale(1.08); box-shadow: 0 6px 22px rgba(0,0,0,.3); } 464#chat-fab .chat-fab-badge { 465 position: absolute; 466 top: -4px; right: -4px; 467 background: #e53935; 468 color: #fff; 469 border-radius: 50%; 470 font-size: 11px !important; 471 font-weight: 700; 472 min-width: 18px; height: 18px; 473 display: none; 474 align-items: center; 475 justify-content: center; 476 padding: 0 3px; 477 border: 2px solid #fff; 478} 479 480/* ââ Janela do chat ââ */ 481#chat-widget { 482 position: fixed; 483 bottom: 96px; 484 right: 28px; 485 width: 380px; 486 max-height: 580px; 487 background: #fff; 488 border-radius: 16px; 489 box-shadow: 0 8px 40px rgba(0,0,0,.18); 490 display: none; 491 flex-direction: column; 492 overflow: hidden; 493 z-index: 9998; 494 font-family: inherit; 495 font-size: 15px !important; 496 line-height: 1.5 !important; 497} 498#chat-widget * { box-sizing: border-box; } 499#chat-widget.aberto { display: flex; } 500 501/* ââ Header ââ */ 502.cw-header { 503 background: var(--color-primary, #0088cc); 504 color: #fff; 505 padding: 14px 16px; 506 display: flex; 507 align-items: center; 508 gap: 10px; 509} 510.cw-header-avatar { 511 width: 40px; height: 40px; 512 border-radius: 50%; 513 object-fit: cover; 514 border: 2px solid rgba(255,255,255,.5); 515 flex-shrink: 0; 516} 517.cw-header-info { flex: 1; min-width: 0; } 518.cw-header-nome { font-weight: 600; font-size: 16px !important; line-height: 1.2; } 519.cw-header-sub { font-size: 13px !important; opacity: .85; } 520.cw-btn-encerrar { 521 background: rgba(255,255,255,.15); 522 border: 1px solid rgba(255,255,255,.45); 523 color: #fff; 524 border-radius: 20px; 525 font-size: 12px !important; 526 font-weight: 600; 527 cursor: pointer; 528 padding: 4px 10px; 529 white-space: nowrap; 530 display: flex; 531 align-items: center; 532 gap: 5px; 533 transition: background .15s; 534 letter-spacing: .3px; 535} 536.cw-btn-encerrar:hover { background: rgba(255,80,80,.35); border-color: rgba(255,255,255,.6); } 537.cw-btn-encerrar i { font-size: 13px !important; } 538.cw-header-close { 539 background: none; border: none; color: #fff; 540 font-size: 22px !important; cursor: pointer; opacity: .8; line-height: 1; 541 padding: 0 2px; 542} 543.cw-header-close:hover { opacity: 1; } 544 545/* ââ Status aguardando ââ */ 546.cw-aguardando { 547 text-align: center; 548 padding: 28px 20px; 549 color: #555; 550 font-size: 15px !important; 551} 552.cw-aguardando i { font-size: 32px !important; color: var(--color-primary, #0088cc); display: block; margin-bottom: 8px; } 553 554/* ââ Mensagens ââ */ 555.cw-msgs { 556 flex: 1; 557 overflow-y: auto; 558 padding: 12px; 559 display: flex; 560 flex-direction: column; 561 gap: 8px; 562 background: #f8f9fa; 563 position: relative; 564 transition: background .15s, outline .15s; 565} 566.cw-msg { 567 display: flex; 568 gap: 8px; 569 align-items: flex-end; 570 max-width: 92%; 571} 572.cw-msg.minha { margin-left: auto; flex-direction: row-reverse; } 573 574.cw-msg-avatar { 575 width: 30px; height: 30px; 576 border-radius: 50%; object-fit: cover; flex-shrink: 0; 577} 578.cw-msg-body { 579 background: #fff; 580 border-radius: 14px 14px 14px 2px; 581 padding: 10px 14px; 582 font-size: 15px !important; 583 box-shadow: 0 1px 4px rgba(0,0,0,.08); 584 max-width: 270px; 585 word-break: break-word; 586 line-height: 1.5 !important; 587 white-space: pre-line; 588} 589.cw-msg.minha .cw-msg-body { 590 background: var(--color-primary, #0088cc); 591 color: #fff; 592 border-radius: 14px 14px 2px 14px; 593} 594.cw-msg-hora { font-size: 12px !important; color: #aaa; margin-top: 3px; text-align: right; } 595.cw-msg.minha .cw-msg-hora { color: rgba(255,255,255,.7); } 596 597.cw-msg-imagem img { max-width: 210px; border-radius: 10px; display: block; cursor: pointer; } 598.cw-msg-arquivo { 599 display: flex; align-items: center; gap: 8px; 600 background: rgba(0,0,0,.06); border-radius: 8px; padding: 7px 11px; 601} 602.cw-msg.minha .cw-msg-arquivo { background: rgba(255,255,255,.2); } 603.cw-msg-arquivo a { color: inherit; font-size: 14px !important; text-decoration: none; font-weight: 500; } 604 605.cw-msg-sistema { 606 text-align: center; font-size: 13px !important; color: #999; 607 margin: 4px 0; font-style: italic; 608} 609.cw-menu-opcoes { display:flex; flex-direction:column; gap:6px; margin-top:9px; white-space:normal; } 610.cw-menu-opcao { 611 width:100%; border:1px solid var(--color-primary, #0088cc); border-radius:8px; 612 background:#fff; color:var(--color-primary, #0088cc); padding:7px 9px; 613 font-size:13px !important; text-align:left; cursor:pointer; line-height:1.25 !important; 614} 615.cw-menu-opcao:hover { background:var(--color-primary, #0088cc); color:#fff; } 616.cw-menu-opcao:disabled { opacity:.55; cursor:default; } 617 618/* ââ Prévia arquivo ââ */ 619#cw-arquivo-preview { 620 padding: 6px 12px; 621 background: #f0f4ff; 622 border-top: 1px solid #e0e8ff; 623 display: none;
624 align-items: center; 625 gap: 8px; 626 font-size: 14px !important; 627} 628#cw-arquivo-preview i { color: var(--color-primary, #0088cc); font-size: 16px !important; } 629#cw-arquivo-preview .cw-arq-nome { flex: 1; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; } 630.cw-arq-rm { background: none; border: none; cursor: pointer; color: #999; font-size: 16px !important; line-height: 1; } 631.cw-arq-rm:hover { color: #e53935; } 632 633/* ââ Input ââ */ 634.cw-input-area { 635 padding: 10px 12px; 636 border-top: 1px solid #eee; 637 display: flex; 638 gap: 8px; 639 align-items: flex-end; 640 background: #fff; 641} 642.cw-input-area textarea { 643 flex: 1; 644 border: 1px solid #ddd; 645 border-radius: 20px; 646 padding: 10px 14px; 647 font-size: 15px !important; 648 resize: none; 649 max-height: 90px; 650 overflow-y: auto; 651 outline: none; 652 font-family: inherit; 653 line-height: 1.5 !important; 654} 655.cw-input-area textarea:focus { border-color: var(--color-primary, #0088cc); } 656.cw-btn-ico { 657 width: 38px; height: 38px; 658 border-radius: 50%; 659 border: 1px solid #ddd; 660 background: #f5f5f5; 661 color: #555; 662 cursor: pointer; 663 display: flex; align-items: center; justify-content: center; 664 font-size: 16px !important; 665 flex-shrink: 0; 666 transition: background .15s; 667} 668.cw-btn-ico:hover { background: #eaeaea; } 669.cw-btn-enviar { 670 width: 38px; height: 38px; 671 border-radius: 50%; 672 border: none; 673 background: var(--color-primary, #0088cc); 674 color: #fff; 675 cursor: pointer; 676 display: flex; align-items: center; justify-content: center; 677 font-size: 16px !important; 678 flex-shrink: 0; 679 transition: opacity .15s; 680} 681.cw-btn-enviar:disabled { opacity: .5; cursor: default; } 682 683/* ââ Drag-and-drop ââ */ 684#cw-msgs.cw-drag-over { 685 outline: 3px dashed var(--color-primary, #0088cc); 686 outline-offset: -6px; 687 background: #eef6ff; 688} 689.cw-drag-hint { 690 position: absolute; 691 inset: 0; 692 background: rgba(0,136,204,.12); 693 display: flex; 694 flex-direction: column; 695 align-items: center; 696 justify-content: center; 697 gap: 8px; 698 font-size: 15px !important; 699 color: var(--color-primary, #0088cc); 700 font-weight: 600; 701 pointer-events: none; 702 border-radius: 4px; 703 z-index: 10; 704} 705.cw-drag-hint i { font-size: 36px !important; } 706 707/* ââ Conversa fechada ââ */ 708.cw-fechada { 709 text-align: center; 710 padding: 12px; 711 font-size: .92rem !important; 712 color: #888; 713 background: #fff8e1; 714 border-top: 1px solid #ffe082; 715} 716 717/* ââ Digitando ââ */ 718.cw-digitando { 719 display: flex; 720 align-items: center; 721 gap: 6px; 722 padding: 6px 14px; 723 font-size: 13px !important; 724 color: #888; 725 font-style: italic; 726} 727.cw-dots span { 728 display: inline-block; 729 width: 6px; height: 6px; 730 background: #aaa; 731 border-radius: 50%; 732 animation: cw-dot 1.2s infinite; 733} 734.cw-dots span:nth-child(2) { animation-delay: .2s; } 735.cw-dots span:nth-child(3) { animation-delay: .4s; } 736@keyframes cw-dot { 737 0%,80%,100% { transform: scale(.6); opacity:.4; } 738 40% { transform: scale(1); opacity:1; } 739} 740 741/* ââ Posição na fila ââ */ 742.cw-fila { 743 text-align: center; 744 padding: 10px 16px; 745 font-size: 13px !important; 746 color: #555; 747 background: #f0f4ff; 748 border-bottom: 1px solid #dde6ff; 749} 750.cw-fila strong { color: var(--color-primary, #0088cc); } 751 752/* ââ Avaliação ââ */ 753.cw-avaliacao { 754 padding: 16px; 755 background: #fff; 756 border-top: 1px solid #eee; 757 text-align: center; 758} 759.cw-avaliacao p { font-size: 14px !important; color: #444; margin: 0 0 10px; font-weight: 600; } 760.cw-stars { display: flex; justify-content: center; gap: 6px; margin-bottom: 10px; } 761.cw-star { 762 font-size: 28px !important; 763 cursor: pointer; 764 color: #ddd; 765 transition: color .15s, transform .1s; 766 line-height: 1; 767} 768.cw-star.ativo, .cw-star:hover { color: #f5a623; } 769.cw-star:hover { transform: scale(1.15); } 770.cw-avaliacao textarea { 771 width: 100%; border: 1px solid #ddd; border-radius: 8px; 772 padding: 8px 10px; font-size: 13px !important; resize: none; 773 font-family: inherit; outline: none; margin-bottom: 8px; 774} 775.cw-avaliacao textarea:focus { border-color: var(--color-primary, #0088cc); } 776.cw-btn-avaliar { 777 background: var(--color-primary, #0088cc); color: #fff; 778 border: none; border-radius: 8px; padding: 8px 20px; 779 font-size: 13px !important; font-weight: 600; cursor: pointer; 780} 781.cw-btn-avaliar:disabled { opacity: .5; cursor: default; } 782.cw-btn-pular { background: none; border: none; color: #aaa; font-size: 12px !important; cursor: pointer; margin-left: 8px; } 783 784/* ââ Pulso do FAB quando admin quer retomar ââ */ 785@keyframes cw-fab-pulse { 786 0% { box-shadow: 0 4px 16px rgba(0,0,0,.25), 0 0 0 0 #387a0480; } 787 70% { box-shadow: 0 4px 16px rgba(0,0,0,.25), 0 0 0 16px #387a0400; } 788 100% { box-shadow: 0 4px 16px rgba(0,0,0,.25), 0 0 0 0 #387a0400; } 789} 790#chat-fab.cw-pulsando { animation: cw-fab-pulse 1.3s ease-out infinite; } 791 792/* ââ Notificação de retomada ââ */ 793.cw-notif-retomada { 794 position: fixed; 795 bottom: 100px; 796 right: 28px; 797 background: #fff; 798 border-radius: 14px; 799 box-shadow: 0 6px 28px rgba(0,0,0,.18); 800 padding: 14px 16px; 801 font-size: 14px !important; 802 display: flex; 803 flex-direction: column; 804 gap: 10px; 805 z-index: 10001; 806 max-width: 280px; 807 border-left: 4px solid #387a04; 808 animation: cw-notif-in .25s ease; 809} 810@keyframes cw-notif-in { 811 from { opacity: 0; transform: translateY(12px); } 812 to { opacity: 1; transform: translateY(0); } 813} 814.cw-notif-retomada .cw-notif-texto { 815 font-size: 14px !important; 816 color: #333; 817 line-height: 1.4 !important; 818} 819.cw-notif-retomada .cw-notif-acoes { 820 display: flex; 821 gap: 8px; 822} 823.cw-notif-retomada .cw-btn-retomar { 824 background: var(--color-primary, #0088cc); 825 color: #fff; 826 border: none; 827 border-radius: 8px; 828 padding: 6px 14px; 829 font-size: 13px !important; 830 cursor: pointer; 831 flex: 1; 832} 833.cw-notif-retomada .cw-btn-ignorar { 834 background: #f0f0f0; 835 color: #666; 836 border: none; 837 border-radius: 8px; 838 padding: 6px 10px; 839 font-size: 13px !important; 840 cursor: pointer; 841} 842 843/* ââ Tela de identificação visitante ââ */ 844#cw-identificacao { 845 padding: 20px 20px 16px; 846 display: none; 847 flex-direction: column; 848 gap: 10px; 849 background: #f8f9fa; 850 flex: 1; 851} 852.cw-ident-titulo { 853 font-size: 14px !important; 854 color: #555; 855 font-weight: 600; 856 margin: 0; 857} 858.cw-ident-login-link { 859 display: flex; 860 align-items: center; 861 justify-content: center; 862 gap: 7px; 863 background: var(--color-primary, #0088cc); 864 color: #fff !important; 865 border-radius: 10px; 866 padding: 9px 14px; 867 font-size: 14px !important; 868 font-weight: 600; 869 text-decoration: none; 870 transition: opacity .15s; 871} 872.cw-ident-login-link:hover { opacity: .88; color: #fff !important; } 873.cw-ident-sep { 874 display: flex; 875 align-items: center; 876 gap: 8px; 877 font-size: 13px !important; 878 color: #aaa; 879} 880.cw-ident-sep::before, .cw-ident-sep::after { 881 content: ''; 882 flex: 1; 883 height: 1px; 884 background: #ddd; 885} 886#cw-ident-form { display: flex; flex-direction: column; gap: 8px; } 887.cw-ident-input { 888 border: 1px solid #ddd; 889 border-radius: 8px; 890 padding: 9px 12px; 891 font-size: 14px !important; 892 outline: none; 893 font-family: inherit; 894 width: 100%; 895 background: #fff; 896} 897.cw-ident-input:focus { border-color: var(--color-primary, #0088cc); } 898.cw-ident-input[aria-invalid="true"] { border-color: #dc3545; box-shadow: 0 0 0 2px rgba(220,53,69,.12); } 899.cw-ident-btn { 900 background: var(--color-primary, #0088cc); 901 color: #fff; 902 border: none; 903 border-radius: 8px; 904 padding: 10px; 905 font-size: 14px !important; 906 font-weight: 600; 907 cursor: pointer; 908 transition: opacity .15s; 909} 910.cw-ident-btn:hover { opacity: .88; } 911.cw-ident-btn:disabled { opacity: .5; cursor: default; } 912.cw-ident-erro { 913 font-size: 12px !important; 914 color: #e53935; 915 display: none; 916} 917 918/* ââ Responsive ââ */ 919@media (max-width: 575px) { 920 #chat-fab { bottom: 88px; } 921 #chat-widget { bottom: 158px; } 922 .cw-notif-retomada { bottom: 158px; } 923} 924@media (max-width: 420px) { 925 #chat-widget { width: calc(100vw - 24px); right: 12px; } 926 #chat-fab { right: 16px; } 927 .cw-notif-retomada { right: 12px; max-width: calc(100vw - 24px); } 928} 929</style> 930 931<!-- Botão flutuante --> 932<button id="chat-fab" title="Chat com atendimento" aria-label="Abrir chat"> 933 <i class="sicon-bubble" id="chat-fab-icon"></i> 934 <span class="chat-fab-badge" id="chat-fab-badge"></span> 935</button> 936 937<!-- Janela do chat --> 938<div id="chat-widget" role="dialog" aria-label="Chat de atendimento"> 939 940 <!-- Header --> 941 <div class="cw-header"> 942 <img src="https://embalaki.com.br/assets/img/sem-imagem-300.jpg" alt="Atendimento" class="cw-header-avatar" id="cw-header-avatar"> 943 <div class="cw-header-info"> 944 <div class="cw-header-nome">Atendimento Online</div> 945 <div class="cw-header-sub" id="cw-header-sub">Iniciandoâ¦</div> 946 </div> 947 <button class="cw-btn-encerrar" id="cw-btn-encerrar" title="Encerrar atendimento" style="display:none"> 948 <i class="sicon-ban"></i> Encerrar 949 </button> 950 <button class="cw-header-close" id="cw-fechar" title="Fechar">×</button> 951 </div> 952 953 <!-- Identificação visitante --> 954 <div id="cw-identificacao"> 955 <p class="cw-ident-titulo">
955Como deseja continuar?</p> 956 <a href="https://embalaki.com.br/login" class="cw-ident-login-link"> 957 <i class="sicon-login"></i> Entrar com meu cadastro 958 </a> 959 <div class="cw-ident-sep">ou continue como visitante</div> 960 <form id="cw-ident-form" novalidate> 961 <input type="text" id="cw-vis-nome" class="cw-ident-input" 962 placeholder="Seu nome *" maxlength="100" autocomplete="name" required> 963 <input type="email" id="cw-vis-email" class="cw-ident-input" 964 placeholder="E-mail" maxlength="160" autocomplete="email" inputmode="email"> 965 <input type="tel" id="cw-vis-telefone" class="cw-ident-input" 966 placeholder="(00) 00000-0000" maxlength="15" autocomplete="tel" inputmode="numeric"> 967 <small style="font-size:11px;color:#777;line-height:1.3">Informe pelo menos um contato: e-mail ou telefone.</small> 968 <span class="cw-ident-erro" id="cw-ident-erro"></span> 969 <button type="submit" class="cw-ident-btn" id="cw-ident-btn"> 970 Iniciar atendimento 971 </button> 972 </form> 973 </div> 974 975 <!-- Ãrea de mensagens --> 976 <div class="cw-msgs" id="cw-msgs"> 977 <div class="cw-aguardando" id="cw-aguardando"> 978 <i class="sicon-bubble"></i> 979 Aguarde, um atendente irá responder em breve. 980 </div> 981 </div> 982 983 <!-- Posição na fila --> 984 <div id="cw-fila" class="cw-fila" style="display:none"> 985 Você é o <strong id="cw-fila-num">?</strong>º na fila de atendimento 986 </div> 987 988 <!-- Digitando --> 989 <div id="cw-digitando" class="cw-digitando" style="display:none"> 990 <div class="cw-dots"><span></span><span></span><span></span></div> 991 Atendente está digitando⦠992 </div> 993 994 <!-- Prévia do arquivo --> 995 <div id="cw-arquivo-preview"> 996 <i class="sicon-paper-clip"></i> 997 <span class="cw-arq-nome" id="cw-arq-nome"></span> 998 <button class="cw-arq-rm" id="cw-arq-rm" title="Remover">×</button> 999 </div> 1000 1001 <!-- Input --> 1002 <div class="cw-input-area" id="cw-input-area"> 1003 <button class="cw-btn-ico" id="cw-btn-anexo" title="Anexar arquivo" type="button"> 1004 <i class="sicon-paper-clip"></i> 1005 </button> 1006 <input type="file" id="cw-file-input" 1007 accept=".jpg,.jpeg,.png,.gif,.webp,.pdf,.doc,.docx,.xls,.xlsx,.txt" 1008 style="display:none"> 1009 <textarea id="cw-texto" placeholder="Digite sua mensagemâ¦" rows="1"></textarea> 1010 <button class="cw-btn-enviar" id="cw-btn-enviar" title="Enviar" type="button" disabled> 1011 <i class="sicon-arrow-right-circle"></i> 1012 </button> 1013 </div> 1014 1015</div> 1016
1017<script> 1018(function () { 1019 const URL_CHAT = 'https://embalaki.com.br/paginas/controles/chat.php'; 1020 const ASSETS = 'https://embalaki.com.br/assets'; 1021 const CLIENTE_LOGADO = false; 1022 const VIS_CONV_ID_PHP = 0; 1023 const CFG_FILA = true; 1024 const CFG_AVALIACAO = true; 1025 const DENTRO_HORARIO = true; 1026 const BOT_ATIVO = true; 1027 const MSG_FORA_HORA = "Nosso atendimento funciona das 08:00 \u00e0s 16:00."; 1028 1029 let conversa_id = null; 1030 let conversa_id_pendente = null; // conversa diferente reaberta pelo admin 1031 let ultima_id = 0; 1032 let poll_iv = null; 1033 let hb_iv = null; 1034 let disp_iv = null; 1035 let fechada = false; 1036 let audio_ctx = null; 1037 let badge_count = 0; 1038 let enviando_mensagem = false; 1039 let admin_disponivel = true; 1040 let atendente_disponivel = true; 1041 let retomada_silenciada_ate = 0; 1042 let ultimo_verificar_outra = 0; 1043 let digitando_ultimo = 0; 1044 let avaliacao_conversa_id = null; 1045 let fila_mensagens_bot = []; 1046 let bot_exibindo_mensagens = false; 1047 let atendente_digitando_atual = false; 1048 1049 const $widget = document.getElementById('chat-widget'); 1050 const $fab = document.getElementById('chat-fab'); 1051 const $badge = document.getElementById('chat-fab-badge'); 1052 const $msgs = document.getElementById('cw-msgs');
1053 const $sub = document.getElementById('cw-header-sub'); 1054 const $texto = document.getElementById('cw-texto'); 1055 const $enviar = document.getElementById('cw-btn-enviar'); 1056 const $fechar = document.getElementById('cw-fechar'); 1057 const $btnEnc = document.getElementById('cw-btn-encerrar'); 1058 const $anexo = document.getElementById('cw-btn-anexo'); 1059 const $file = document.getElementById('cw-file-input'); 1060 const $prev = document.getElementById('cw-arquivo-preview'); 1061 const $arqNome = document.getElementById('cw-arq-nome'); 1062 const $arqRm = document.getElementById('cw-arq-rm'); 1063 const $aguard = document.getElementById('cw-aguardando'); 1064 const $ident = document.getElementById('cw-identificacao'); 1065 const $identForm = document.getElementById('cw-ident-form'); 1066 const $digitando = document.getElementById('cw-digitando'); 1067 const $fila = document.getElementById('cw-fila'); 1068 const $visEmail = document.getElementById('cw-vis-email'); 1069 const $visTelefone = document.getElementById('cw-vis-telefone'); 1070 1071 function mascarar_telefone(valor) { 1072 const digitos = String(valor || '').replace(/\D/g, '').slice(0, 11); 1073 if (digitos.length <= 2) return digitos ? '(' + digitos : ''; 1074 if (digitos.length <= 6) return '(' + digitos.slice(0, 2) + ') ' + digitos.slice(2); 1075 if (digitos.length <= 10) return '(' + digitos.slice(0, 2) + ') ' + digitos.slice(2, 6) + '-' + digitos.slice(6); 1076 return '(' + digitos.slice(0, 2) + ') ' + digitos.slice(2, 7) + '-' + digitos.slice(7); 1077 } 1078 1079 $visTelefone.addEventListener('input', function () { 1080 this.value = mascarar_telefone(this.value); 1081 this.removeAttribute('aria-invalid'); 1082 }); 1083 $visEmail.addEventListener('input', function () { 1084 this.value = this.value.replace(/\s/g, '').toLowerCase(); 1085 this.removeAttribute('aria-invalid'); 1086 }); 1087 1088 // ââ Disponibilidade de atendentes ââââââââââââââââââââââââââââââââââââââ 1089 function verificar_disponibilidade() { 1090 post({ acao: 'disponivel' }, function (r) { 1091 atendente_disponivel = !!r.atendente_disponivel; 1092 if (r.disponivel) { 1093 admin_disponivel = true; 1094 $fab.style.display = 'flex'; 1095 } else { 1096 admin_disponivel = false; 1097 $fab.style.display = 'none'; 1098 // fecha o widget se estiver aberto e sem conversa ativa 1099 if ($widget.classList.contains('aberto') && !conversa_id) { 1100 $widget.classList.remove('aberto'); 1101 document.getElementById('chat-fab-icon').className = 'sicon-bubble'; 1102 } 1103 } 1104 }); 1105 } 1106 // inicializa visibilidade e verifica conversa pendente 1107 verificar_disponibilidade(); 1108 verificar_conversa_pendente(); 1109 disp_iv = setInterval(verificar_disponibilidade, 30000); 1110 1111 // ââ Abrir/fechar widget ââââââââââââââââââââââââââââââââââââââââââââââââ 1112 $fab.addEventListener('click', () => { 1113 const aberto = $widget.classList.toggle('aberto'); 1114 document.getElementById('chat-fab-icon').className = aberto ? 'sicon-close' : 'sicon-bubble'; 1115 if (aberto) { 1116 if (!DENTRO_HORARIO && !BOT_ATIVO && !conversa_id) { 1117 // fora do horário: mostra mensagem e bloqueia input 1118 mostrar_fora_horario(); 1119 } else if (!conversa_id) { 1120 if (CLIENTE_LOGADO) { 1121 iniciar(); 1122 } else { 1123 mostrar_identificacao(); 1124 } 1125 } 1126 badge_count = 0; atualizar_badge(0); 1127 } 1128 }); 1129 1130 function mostrar_fora_horario() { 1131 $msgs.innerHTML = ''; 1132 $ident.style.display = 'none'; 1133 $msgs.style.display = ''; 1134 document.getElementById('cw-input-area').style.display = 'none'; 1135 $btnEnc.style.display = 'none'; 1136 $sub.textContent = 'Fora do horário'; 1137 const d = document.createElement('div'); 1138 d.className = 'cw-aguardando'; 1139 d.innerHTML = '<i class="sicon-clock"></i>' + esc(MSG_FORA_HORA); 1140 $msgs.appendChild(d); 1141 } 1142 $fechar.addEventListener('click', () => { 1143 $widget.classList.remove('aberto'); 1144 document.getElementById('chat-fab-icon').className = 'sicon-bubble'; 1145 }); 1146 1147 // ââ Tela de identificação (visitante) ââââââââââââââââââââââââââââââââââ 1148 function mostrar_identificacao() { 1149 $ident.style.display = 'flex'; 1150 $msgs.style.display = 'none'; 1151 $prev.style.display = 'none'; 1152 document.getElementById('cw-input-area').style.display = 'none'; 1153 $btnEnc.style.display = 'none'; 1154 $sub.textContent = 'Identificação'; 1155 } 1156 function esconder_identificacao() { 1157 $ident.style.display = 'none'; 1158 $msgs.style.display = ''; 1159 document.getElementById('cw-input-area').style.display = ''; 1160 } 1161 1162 // Formulário visitante 1163 $identForm.addEventListener('submit', function (e) { 1164 e.preventDefault(); 1165 const nome = document.getElementById('cw-vis-nome').value.trim(); 1166 const email = $visEmail.value.trim().toLowerCase(); 1167 const telefone = $visTelefone.value.trim(); 1168 const $erro = document.getElementById('cw-ident-erro'); 1169 const $btn = document.getElementById('cw-ident-btn'); 1170 1171 if (!nome || (!email && !telefone)) { 1172 $erro.textContent = 'Informe seu nome e pelo menos um contato: e-mail ou telefone.'; 1173 $erro.style.display = 'block'; 1174 return; 1175 } 1176 const emailValido = /^[^\s@]+@[^\s@]+\.[^\s@]{2,}$/.test(email); 1177 if (email && !emailValido) { 1178 $visEmail.setAttribute('aria-invalid', 'true'); 1179 $erro.textContent = 'Informe um e-mail válido.'; 1180 $erro.style.display = 'block'; 1181 return; 1182 } 1183 const telefoneDigitos = telefone.replace(/\D/g, ''); 1184 if (telefone && telefoneDigitos.length !== 10 && telefoneDigitos.length !== 11) { 1185 $visTelefone.setAttribute('aria-invalid', 'true'); 1186 $erro.textContent = 'Informe um telefone válido com DDD.'; 1187 $erro.style.display = 'block'; 1188 return; 1189 } 1190 $erro.style.display = 'none'; 1191 $btn.disabled = true; 1192 $btn.textContent = 'Aguardeâ¦'; 1193 1194 post({ acao: 'iniciar_visitante', nome, email, telefone }, function (r) { 1195 $btn.disabled = false;
1196 $btn.textContent = 'Iniciar atendimento'; 1197 if (!r || !r.ok) { 1198 $erro.textContent = (r && r.erro) ? r.erro : 'Erro ao iniciar. Tente novamente.'; 1199 $erro.style.display = 'block'; 1200 return; 1201 } 1202 conversa_id = r.conversa.id; 1203 esconder_identificacao(); 1204 atualizar_status(r.conversa.status, r.conversa.bot_ativo); 1205 carregar_mensagens(); 1206 iniciar_timers(); 1207 }); 1208 }); 1209 1210 // ââ Iniciar conversa (cliente logado) ââââââââââââââââââââââââââââââââââ 1211 function iniciar() { 1212 post({ acao: 'iniciar' }, function (r) { 1213 if (!r.ok) { $sub.textContent = 'Erro ao iniciar atendimento'; return; } 1214 conversa_id = r.conversa.id; 1215 atualizar_status(r.conversa.status, r.conversa.bot_ativo); 1216 carregar_mensagens(); 1217 iniciar_timers(); 1218 }); 1219 } 1220 1221 // ââ Verificar conversa pendente (notifica sem abrir/criar nova) ââââââ 1222 function verificar_conversa_pendente() { 1223 if (conversa_id) return; // poll já cobre se há conversa ativa 1224 // só verifica se logado OU visitante com sessão ativa 1225 if (!CLIENTE_LOGADO && !VIS_CONV_ID_PHP) return; 1226 post({ acao: 'verificar' }, function (r) { 1227 if (!r || !r.ok) return; 1228 // existe conversa aberta para este cliente/visitante 1229 conversa_id = r.conversa.id; 1230 iniciar_timers(); // inicia poll para detectar mudanças de status 1231 if (r.conversa.status === 'atendendo') { 1232 // admin reabriu enquanto cliente não tinha o widget aberto 1233 notificar_retomada(); 1234 } 1235 }); 1236 } 1237 1238 // ââ Timers âââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââ 1239 function iniciar_timers() { 1240 if (!hb_iv) hb_iv = setInterval(heartbeat, 15000); 1241 if (!poll_iv) poll_iv = setInterval(poll_novas, 1000); 1242 heartbeat(); 1243 } 1244 1245 // Verifica a cada 15s se admin iniciou uma conversa proativamente 1246 setInterval(function () { 1247 if (conversa_id) return; // já tem conversa ativa 1248 if (!CLIENTE_LOGADO) return; // visitantes não recebem chamada proativa 1249 if (!admin_disponivel) return; // admin offline, não vale verificar 1250 post({ acao: 'verificar' }, function (r) { 1251 if (!r || !r.ok) return; 1252 conversa_id = r.conversa.id; 1253 iniciar_timers(); 1254 // notifica o cliente com card flutuante 1255 notificar_chamada_admin(); 1256 }); 1257 }, 15000); 1258 1259 function heartbeat() { 1260 if (!CLIENTE_LOGADO) return; // visitantes não são rastreados em tb_online 1261 post({ acao: 'heartbeat' }, () => {}); 1262 } 1263 1264 // ââ Carregar mensagens âââââââââââââââââââââââââââââââââââââââââââââââââ 1265 function carregar_mensagens() { 1266 post({ acao: 'mensagens', conversa_id }, function (rows) { 1267 $msgs.innerHTML = ''; 1268 $aguard.style.display = 'none'; 1269 if (!rows.length) { 1270 append_aguardando(); return; 1271 } 1272 rows.forEach(m => { ultima_id = Math.max(ultima_id, m.id); append_msg(m); }); 1273 scroll_bottom(); 1274 }); 1275 } 1276 1277 function exibir_mensagem_nova(m) { 1278 append_msg(m); 1279 if (m.de_tipo !== 3) { 1280 if (!$widget.classList.contains('aberto')) { 1281 badge_count++; 1282 atualizar_badge(badge_count); 1283 } 1284 tocar_beep(); 1285 notificar_navegador('ð¬ Nova mensagem', m.mensagem || 'Arquivo recebido'); 1286 } 1287 scroll_bottom(); 1288 } 1289 1290 function processar_fila_bot() { 1291 if (bot_exibindo_mensagens || !fila_mensagens_bot.length) return; 1292 bot_exibindo_mensagens = true; 1293 $digitando.innerHTML = '<div class="cw-dots"><span></span><span></span><span></span></div> Assistente virtual está digitandoâ¦'; 1294 $digitando.style.display = 'flex'; 1295 const mensagem = fila_mensagens_bot.shift(); 1296 const tamanho = String(mensagem.mensagem || '').length; 1297 const atraso = Math.min(500, Math.max(180, 140 + tamanho * 1.5)); 1298 setTimeout(function () { 1299 exibir_mensagem_nova(mensagem); 1300 bot_exibindo_mensagens = false;
1301 if (fila_mensagens_bot.length) { 1302 setTimeout(processar_fila_bot, 100); 1303 } else { 1304 $digitando.innerHTML = '<div class="cw-dots"><span></span><span></span><span></span></div> Atendente está digitandoâ¦'; 1305 $digitando.style.display = atendente_digitando_atual ? 'flex' : 'none'; 1306 } 1307 }, atraso); 1308 } 1309 1310 // ââ Poll âââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââ 1311 function poll_novas() { 1312 if (!conversa_id) return; 1313 1314 post({ acao: 'poll', conversa_id, ultima_id }, function (r) { 1315 if (!r || !r.status) return; 1316 1317 if (fechada) { 1318 if (r.status !== 'fechada') { 1319 notificar_retomada(); 1320 } else { 1321 const agora = Date.now(); 1322 if (agora - ultimo_verificar_outra > 10000) { 1323 ultimo_verificar_outra = agora; 1324 verificar_outra_conversa(); 1325 } 1326 } 1327 return; 1328 } 1329 1330 // indicador de digitando 1331 atendente_digitando_atual = !!r.atendente_digitando; 1332 if (!bot_exibindo_mensagens) $digitando.style.display = atendente_digitando_atual ? 'flex' : 'none'; 1333 atendente_disponivel = !!r.atendente_disponivel; 1334 atualizar_bloqueio_aguardando(r.status, r.bot_ativo, r.atendente_id); 1335 1336 // posição na fila 1337 if (CFG_FILA && atendente_disponivel && !r.bot_ativo && r.posicao_fila !== null && r.posicao_fila !== undefined && r.status === 'aguardando') { 1338 document.getElementById('cw-fila-num').textContent = r.posicao_fila; 1339 $fila.style.display = 'block'; 1340 } else { 1341 $fila.style.display = 'none'; 1342 } 1343 1344 // conversa ativa: processa mensagens normalmente 1345 if (r.mensagens && r.mensagens.length) { 1346 r.mensagens.forEach(m => { 1347 ultima_id = Math.max(ultima_id, m.id); 1348 if (r.bot_ativo && m.de_tipo !== 3) fila_mensagens_bot.push(m); 1349 else exibir_mensagem_nova(m); 1350 }); 1351 processar_fila_bot(); 1352 } 1353 if (r.status === 'fechada') { 1354 $digitando.style.display = 'none'; 1355 $fila.style.display = 'none'; 1356 mostrar_fechada(); 1357 } else { 1358 atualizar_status(r.status, r.bot_ativo); 1359 } 1360 }); 1361 } 1362 1363 // ââ Verifica se admin reabriu uma conversa DIFERENTE ââââââââââââââââââ 1364 function verificar_outra_conversa() { 1365 post({ acao: 'verificar' }, function (r) { 1366 if (!r || !r.ok) return; 1367 if (r.conversa.id == conversa_id) return; // mesma que já está fechada 1368 // encontrou outra conversa aberta para este cliente 1369 conversa_id_pendente = r.conversa.id; 1370 notificar_retomada_outra(); 1371 }); 1372 } 1373 1374 // ââ Notificação de chamada proativa do admin ââââââââââââââââââââââââââ 1375 function notificar_chamada_admin() { 1376 $fab.classList.add('cw-pulsando'); 1377 tocar_beep(); 1378 notificar_navegador('ð¬ Atendente disponÃvel', 'Um atendente quer falar com você!'); 1379 1380 if (document.getElementById('cw-notif-retomada')) return; 1381 const card = document.createElement('div'); 1382 card.id = 'cw-notif-retomada'; 1383 card.className = 'cw-notif-retomada'; 1384 card.innerHTML = 1385 '<div class="cw-notif-texto">ð Um atendente quer falar com você!</div>' + 1386 '<div class="cw-notif-acoes">' + 1387 ' <button class="cw-btn-retomar">Responder</button>' + 1388 ' <button class="cw-btn-ignorar">Agora não</button>' + 1389 '</div>'; 1390 document.body.appendChild(card); 1391 1392 card.querySelector('.cw-btn-retomar').addEventListener('click', function () { 1393 card.remove(); 1394 $fab.classList.remove('cw-pulsando'); 1395 $widget.classList.add('aberto'); 1396 document.getElementById('chat-fab-icon').className = 'sicon-close'; 1397 atualizar_status('atendendo'); 1398 carregar_mensagens(); 1399 iniciar_timers(); 1400 }); 1401 card.querySelector('.cw-btn-ignorar').addEventListener('click', function () { 1402 card.remove(); 1403 $fab.classList.remove('cw-pulsando'); 1404 retomada_silenciada_ate = Date.now() + 120000; // silencia 2min 1405 }); 1406 } 1407 1408 function notificar_retomada_outra() { 1409 if (Date.now() < retomada_silenciada_ate) return; 1410 $fab.classList.add('cw-pulsando'); 1411 if (document.getElementById('cw-notif-retomada')) return; 1412 1413 const card = document.createElement('div'); 1414 card.id = 'cw-notif-retomada'; 1415 card.className = 'cw-notif-retomada'; 1416 card.innerHTML = 1417 '<div class="cw-notif-texto">ð¬ Seu atendente quer retomar uma conversa anterior.</div>' + 1418 '<div class="cw-notif-acoes">' + 1419 ' <button class="cw-btn-retomar">
1419Ver conversa</button>' + 1420 ' <button class="cw-btn-ignorar">Agora não</button>' + 1421 '</div>'; 1422 document.body.appendChild(card); 1423 1424 card.querySelector('.cw-btn-retomar').addEventListener('click', function () { 1425 card.remove(); 1426 $fab.classList.remove('cw-pulsando'); 1427 // troca para a conversa reaberta 1428 conversa_id = conversa_id_pendente; 1429 conversa_id_pendente = null; 1430 ultima_id = 0; 1431 retomar_conversa(); 1432 $widget.classList.add('aberto'); 1433 document.getElementById('chat-fab-icon').className = 'sicon-close'; 1434 }); 1435 card.querySelector('.cw-btn-ignorar').addEventListener('click', function () { 1436 card.remove(); 1437 $fab.classList.remove('cw-pulsando'); 1438 retomada_silenciada_ate = Date.now() + 60000; 1439 }); 1440 } 1441 1442 // ââ Notificação de retomada pelo admin ââââââââââââââââââââââââââââââââ 1443 function notificar_retomada() { 1444 // se o widget já está aberto, retoma direto 1445 if ($widget.classList.contains('aberto')) { 1446 retomar_conversa(); 1447 return; 1448 } 1449 1450 // respeita cooldown do "Agora não" 1451 if (Date.now() < retomada_silenciada_ate) return; 1452 1453 // pulsa o FAB 1454 $fab.classList.add('cw-pulsando'); 1455 1456 // mostra card de notificação se ainda não existe 1457 if (document.getElementById('cw-notif-retomada')) return; 1458 const card = document.createElement('div'); 1459 card.id = 'cw-notif-retomada'; 1460 card.className = 'cw-notif-retomada'; 1461 card.innerHTML = 1462 '<div class="cw-notif-texto">ð¬ Seu atendente quer retomar a conversa.</div>' + 1463 '<div class="cw-notif-acoes">' + 1464 ' <button class="cw-btn-retomar">Retomar</button>' + 1465 ' <button class="cw-btn-ignorar">Agora não</button>' + 1466 '</div>'; 1467 document.body.appendChild(card); 1468 1469 card.querySelector('.cw-btn-retomar').addEventListener('click', function () { 1470 card.remove(); 1471 $fab.classList.remove('cw-pulsando'); 1472 retomar_conversa(); 1473 $widget.classList.add('aberto'); 1474 document.getElementById('chat-fab-icon').className = 'sicon-close'; 1475 }); 1476 card.querySelector('.cw-btn-ignorar').addEventListener('click', function () { 1477 card.remove(); 1478 $fab.classList.remove('cw-pulsando'); 1479 retomada_silenciada_ate = Date.now() + 60000; // silencia por 60s 1480 }); 1481 } 1482 1483 function retomar_conversa() { 1484 fechada = false; 1485 retomada_silenciada_ate = 0; 1486 $enviar.disabled = false; 1487 $anexo.disabled = false; 1488 $texto.disabled = false; 1489 const banner = document.getElementById('cw-msg-fechada'); 1490 if (banner) banner.remove(); 1491 atualizar_status('atendendo'); // atualiza subtÃtulo e botão encerrar 1492 carregar_mensagens(); 1493 } 1494 1495 // ââ Status âââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââ 1496 function atualizar_status(status, botAtivo = false) { 1497 const labels = { aguardando: 'Aguardando atendenteâ¦', atendendo: 'Em atendimento', fechada: 'Atendimento encerrado' }; 1498 $sub.textContent = botAtivo ? 'Atendimento automático' : (labels[status] || status);
1499 // mostrar botão encerrar apenas enquanto a conversa está ativa 1500 $btnEnc.style.display = (status === 'aguardando' || status === 'atendendo') ? 'flex' : 'none'; 1501 if (status === 'fechada') mostrar_fechada(); 1502 } 1503 1504 function atualizar_bloqueio_aguardando(status, botAtivo, atendenteId) { 1505 const bloquear = status === 'aguardando' && !botAtivo && !atendenteId && !atendente_disponivel; 1506 $texto.disabled = bloquear; 1507 $anexo.disabled = bloquear; 1508 $enviar.disabled = bloquear || (!$texto.value.trim() && !$file.files.length); 1509 1510 let aviso = document.getElementById('cw-msg-aguardando-offline'); 1511 if (bloquear && !aviso) { 1512 aviso = document.createElement('div'); 1513 aviso.id = 'cw-msg-aguardando-offline'; 1514 aviso.className = 'cw-fechada'; 1515 aviso.textContent = 'Sua conversa está registrada. Aguarde um atendente ficar disponÃvel para continuar.'; 1516 $widget.insertBefore(aviso, document.querySelector('.cw-input-area')); 1517 } else if (!bloquear && aviso) { 1518 aviso.remove(); 1519 } 1520 } 1521 1522 function mostrar_fechada() { 1523 fechada = true; 1524 $btnEnc.style.display = 'none'; 1525 $enviar.disabled = true; 1526 $anexo.disabled = true; 1527 $texto.disabled = true; 1528 if (!document.getElementById('cw-msg-fechada')) { 1529 const d = document.createElement('div'); 1530 d.id = 'cw-msg-fechada'; 1531 d.className = 'cw-fechada'; 1532 d.innerHTML = 'Este atendimento foi encerrado.'; 1533 $widget.insertBefore(d, document.querySelector('.cw-input-area')); 1534 } 1535 } 1536 1537 // ââ Encerrar conversa ââââââââââââââââââââââââââââââââââââââââââââââââââ 1538 $btnEnc.addEventListener('click', () => { 1539 if (!conversa_id || fechada) return; 1540 if (!confirm('Deseja encerrar este atendimento?')) return; 1541 post({ acao: 'encerrar', conversa_id }, function (r) { 1542 if (r && r.ok) { 1543 mostrar_fechada(); 1544 atualizar_status('fechada'); 1545 if (CFG_AVALIACAO && r.pedir_avaliacao) mostrar_avaliacao(conversa_id); 1546 } 1547 }); 1548 }); 1549 1550 // ââ Avaliação ââââââââââââââââââââââââââââââââââââââââââââââââââââââââââ 1551 function mostrar_avaliacao(cid) { 1552 avaliacao_conversa_id = cid; 1553 if (document.getElementById('cw-avaliacao')) return; 1554 const div = document.createElement('div'); 1555 div.id = 'cw-avaliacao'; 1556 div.className = 'cw-avaliacao'; 1557 div.innerHTML = 1558 '<p>Como foi o atendimento?</p>' + 1559 '<div class="cw-stars">' + 1560 [1,2,3,4,5].map(n => `<span class="cw-star" data-nota="${n}">â </span>`).join('') + 1561 '</div>' + 1562 '<textarea id="cw-av-comentario" rows="2" placeholder="Comentário opcionalâ¦"></textarea>' + 1563 '<div>' + 1564 '<button class="cw-btn-avaliar" id="cw-btn-avaliar" disabled>Enviar avaliação</button>' + 1565 '<button class="cw-btn-pular" id="cw-btn-pular">Pular</button>' + 1566 '</div>'; 1567 1568 $widget.insertBefore(div, document.querySelector('.cw-input-area')); 1569 1570 let nota_sel = 0; 1571 div.querySelectorAll('.cw-star').forEach(s => { 1572 s.addEventListener('mouseenter', () => { 1573 div.querySelectorAll('.cw-star').forEach((x, i) => 1574 x.classList.toggle('ativo', i < parseInt(s.dataset.nota))); 1575 }); 1576 s.addEventListener('mouseleave', () => { 1577 div.querySelectorAll('.cw-star').forEach((x, i) => 1578 x.classList.toggle('ativo', i < nota_sel)); 1579 }); 1580 s.addEventListener('click', () => { 1581 nota_sel = parseInt(s.dataset.nota); 1582 div.querySelectorAll('.cw-star').forEach((x, i) => 1583 x.classList.toggle('ativo', i < nota_sel)); 1584 document.getElementById('cw-btn-avaliar').disabled = false;
1585 }); 1586 }); 1587 1588 document.getElementById('cw-btn-avaliar').addEventListener('click', () => { 1589 if (!nota_sel) return; 1590 const comentario = document.getElementById('cw-av-comentario').value.trim(); 1591 post({ acao: 'avaliar', conversa_id: avaliacao_conversa_id, nota: nota_sel, comentario }, () => {}); 1592 div.innerHTML = '<p style="color:#4caf50;font-weight:600">Obrigado pela avaliação! â</p>'; 1593 setTimeout(() => div.remove(), 3000); 1594 }); 1595 document.getElementById('cw-btn-pular').addEventListener('click', () => div.remove()); 1596 } 1597 1598 // ââ Notificação do navegador âââââââââââââââââââââââââââââââââââââââââââ 1599 function solicitar_permissao_notif() { 1600 if (!('Notification' in window)) return; 1601 if (Notification.permission === 'default') Notification.requestPermission(); 1602 } 1603 function notificar_navegador(titulo, corpo) { 1604 if (!('Notification' in window) || Notification.permission !== 'granted') return; 1605 if (document.visibilityState === 'visible') return; // tab ativa, não notifica 1606 try { 1607 new Notification(titulo, { body: corpo.substring(0, 100), icon: ASSETS + '/img/favicon.ico' }); 1608 } catch(e) {} 1609 } 1610 // solicita permissão quando o widget abre pela primeira vez 1611 $fab.addEventListener('click', solicitar_permissao_notif, { once: true }); 1612 1613 function append_aguardando() { 1614 $aguard.style.display = 'block'; 1615 $msgs.appendChild($aguard); 1616 } 1617 1618 // ââ Renderizar mensagem ââââââââââââââââââââââââââââââââââââââââââââââââ 1619 function append_msg(m) { 1620 $aguard.style.display = 'none'; 1621 1622 if (m.tipo === 'sistema') { 1623 const d = document.createElement('div'); 1624 d.className = 'cw-msg-sistema'; 1625 d.textContent = m.mensagem; 1626 $msgs.appendChild(d); 1627 return; 1628 } 1629 1630 const sou_eu = (m.de_tipo == 3); 1631 const wrap = document.createElement('div'); 1632 wrap.className = 'cw-msg' + (sou_eu ? ' minha' : ''); 1633 1634 const hora = m.criado ? m.criado.substring(11, 16) : ''; 1635 1636 let conteudo = ''; 1637 if (m.tipo === 'imagem') { 1638 conteudo = `<div class="cw-msg-imagem"> 1639 <a href="${m.arquivo_url}" target="_blank"> 1640 <img src="${m.arquivo_url}" alt="Foto do produto" loading="lazy" onerror="this.closest('.cw-msg-imagem').style.display='none'"> 1641 </a> 1642 </div>` + (m.mensagem ? `<div style="margin-top:7px">${textoComLinks(m.mensagem)}</div>` : ''); 1643 } else if (m.tipo === 'arquivo') { 1644 const tam = m.arquivo_tamanho ? formatBytes(m.arquivo_tamanho) : ''; 1645 conteudo = `<div class="cw-msg-arquivo"> 1646 <i class="sicon-docs" style="font-size:1.2rem"></i> 1647 <a href="${m.arquivo_url}" download="${esc(m.arquivo_nome)}" target="_blank">${esc(m.arquivo_nome)} <small>(${tam})</small></a> 1648 </div>`; 1649 } else { 1650 conteudo = `<div>${textoComLinks(!sou_eu ? textoSemOpcoesMenu(m.mensagem) : m.mensagem)}</div>`; 1651 if (!sou_eu) conteudo += botoesMenu(m.mensagem); 1652 } 1653 1654 wrap.innerHTML = (!sou_eu 1655 ? `<img src="${m.de_foto || ASSETS+'/img/sem-imagem-300.jpg'}" class="cw-msg-avatar" alt="${esc(m.de_nome)}">` 1656 : '') + 1657 `<div> 1658 <div class="cw-msg-body">${conteudo}</div> 1659 <div class="cw-msg-hora">${hora}</div> 1660 </div>`; 1661 1662 $msgs.appendChild(wrap); 1663 } 1664 1665 $msgs.addEventListener('click', function (e) { 1666 const botao = e.target.closest('.cw-menu-opcao'); 1667 if (!botao || fechada || !conversa_id) return; 1668 $texto.value = botao.dataset.codigo || ''; 1669 enviar(); 1670 }); 1671 1672 // ââ Enviar âââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââ 1673 function enviar() { 1674 if (!conversa_id || fechada || enviando_mensagem) return; 1675 const texto = $texto.value.trim(); 1676 const file = $file.files[0]; 1677 if (!texto && !file) return; 1678 1679 enviando_mensagem = true; 1680 1681 const fd = new FormData(); 1682 fd.append('acao', 'enviar'); 1683 fd.append('conversa_id', conversa_id); 1684 fd.append('mensagem', texto); 1685 if (file) fd.append('arquivo', file); 1686 1687 $enviar.disabled = true; 1688 fetch(URL_CHAT, { method: 'POST', body: fd }) 1689 .then(r => r.json()) 1690 .then(r => { 1691 if (r.ok && r.mensagem) { 1692 ultima_id = Math.max(ultima_id, r.mensagem.id); 1693 $msgs.innerHTML = ''; 1694 append_msg(r.mensagem); // otimista â poll vai preencher resto 1695 // recarrega tudo para garantir ordem 1696 carregar_mensagens(); 1697 $texto.value = ''; 1698 $file.value = ''; 1699 $prev.style.display = 'none'; 1700 $texto.style.height = 'auto'; 1701 } else if (r.aguardando_atendente) { 1702 atendente_disponivel = false;
1703 atualizar_bloqueio_aguardando('aguardando', false, null); 1704 } 1705 }) 1706 .finally(() => { 1707 enviando_mensagem = false; 1708 $enviar.disabled = $texto.disabled || (!$texto.value.trim() && !$file.files.length); 1709 $texto.focus(); 1710 }); 1711 } 1712 1713 $enviar.addEventListener('click', enviar); 1714 1715 $texto.addEventListener('keydown', e => { 1716 if (e.key === 'Enter' && !e.shiftKey) { e.preventDefault(); enviar(); } 1717 }); 1718 $texto.addEventListener('input', function () { 1719 this.style.height = 'auto'; 1720 this.style.height = Math.min(this.scrollHeight, 80) + 'px'; 1721 $enviar.disabled = (!this.value.trim() && !$file.files.length); 1722 // Primeiro sinal imediato; renova de forma limitada enquanto digita. 1723 if (conversa_id && !fechada) { 1724 const agoraDigitando = Date.now(); 1725 if (agoraDigitando - digitando_ultimo >= 1200) { 1726 digitando_ultimo = agoraDigitando; 1727 post({ acao: 'digitando', conversa_id }, () => {}); 1728 } 1729 } 1730 }); 1731 1732 // ââ Arquivo (botão) âââââââââââââââââââââââââââââââââââââââââââââââââââ 1733 $anexo.addEventListener('click', () => $file.click()); 1734 $file.addEventListener('change', function () { 1735 if (!this.files.length) return; 1736 definir_arquivo(this.files[0]); 1737 }); 1738 $arqRm.addEventListener('click', () => { 1739 $file.value = ''; 1740 $prev.style.display = 'none'; 1741 $enviar.disabled = !$texto.value.trim(); 1742 }); 1743 1744 function definir_arquivo(f) { 1745 // injeta no input file via DataTransfer para manter compatibilidade com FormData 1746 try { 1747 const dt = new DataTransfer(); 1748 dt.items.add(f); 1749 $file.files = dt.files; 1750 } catch(e) { /* fallback: arquivo já está no input via change */ } 1751 $arqNome.textContent = f.name; 1752 $prev.style.display = 'flex'; 1753 $enviar.disabled = false; 1754 } 1755 1756 // ââ Drag-and-drop na área de mensagens ââââââââââââââââââââââââââââââââ 1757 let drag_counter = 0; 1758 let $drag_hint = null; 1759 1760 function criar_hint() { 1761 if ($drag_hint) return; 1762 $drag_hint = document.createElement('div'); 1763 $drag_hint.className = 'cw-drag-hint'; 1764 $drag_hint.innerHTML = '<i class="sicon-cloud-upload"></i>Solte o arquivo aqui'; 1765 $msgs.appendChild($drag_hint); 1766 } 1767 1768 function remover_hint() { 1769 if ($drag_hint) { $drag_hint.remove(); $drag_hint = null; } 1770 } 1771 1772 $msgs.addEventListener('dragenter', e => { 1773 if (fechada) return; 1774 e.preventDefault(); 1775 drag_counter++; 1776 $msgs.classList.add('cw-drag-over'); 1777 criar_hint(); 1778 }); 1779 1780 $msgs.addEventListener('dragover', e => { 1781 e.preventDefault(); 1782 e.dataTransfer.dropEffect = 'copy'; 1783 }); 1784 1785 $msgs.addEventListener('dragleave', e => { 1786 drag_counter--; 1787 if (drag_counter <= 0) { 1788 drag_counter = 0; 1789 $msgs.classList.remove('cw-drag-over'); 1790 remover_hint(); 1791 } 1792 }); 1793 1794 $msgs.addEventListener('drop', e => { 1795 e.preventDefault(); 1796 drag_counter = 0; 1797 $msgs.classList.remove('cw-drag-over'); 1798 remover_hint(); 1799 if (fechada) return; 1800 const files = e.dataTransfer.files; 1801 if (!files.length) return; 1802 definir_arquivo(files[0]); 1803 $texto.focus(); 1804 }); 1805 1806 // ââ Badge ââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââ 1807 function atualizar_badge(n) { 1808 if (n > 0) { 1809 $badge.textContent = n > 9 ? '9+' : n; 1810 $badge.style.display = 'flex'; 1811 } else { 1812 $badge.style.display = 'none'; 1813 } 1814 } 1815 1816 // ââ Beep âââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââ 1817 let ultimo_beep = 0; 1818 function tocar_beep() { 1819 const agora = Date.now(); 1820 if (agora - ultimo_beep < 4000) return; 1821 ultimo_beep = agora; 1822 try { 1823 if (!audio_ctx) audio_ctx = new (window.AudioContext || window.webkitAudioContext)(); 1824 const o = audio_ctx.createOscillator(); 1825 const g = audio_ctx.createGain(); 1826 o.connect(g); g.connect(audio_ctx.destination); 1827 o.frequency.value = 660; 1828 g.gain.setValueAtTime(0.2, audio_ctx.currentTime); 1829 g.gain.exponentialRampToValueAtTime(0.001, audio_ctx.currentTime + 0.35); 1830 o.start(); o.stop(audio_ctx.currentTime + 0.35); 1831 } catch(e) {} 1832 } 1833 1834 // ââ Scroll âââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââ 1835 function scroll_bottom() { 1836 $msgs.scrollTop = $msgs.scrollHeight; 1837 } 1838 1839 // ââ Utils ââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââ 1840 function esc(s) { 1841 if (!s) return ''; 1842 return String(s).replace(/&/g,'&').replace(/</g,'<').replace(/>/g,'>').replace(/"/g,'"'); 1843 } 1844 function textoComLinks(s) { 1845 return esc(s).replace(/(https?:\/\/[^\s<]+)/g, '<a href="$1" target="_blank" rel="noopener noreferrer">$1</a>'); 1846 } 1847 function linhasMenu(s) { 1848 return String(s || '').split(/\r?\n/).map((linha, indice) => { 1849 const m = linha.trim().match(/^([0-9]{1,2})\s*[-ââ]\s*(.{2,80})$/);
1850 return m ? { indice, codigo: m[1], titulo: m[2] } : null; 1851 }).filter(Boolean); 1852 } 1853 function textoSemOpcoesMenu(s) { 1854 const texto = String(s || ''); 1855 const opcoes = linhasMenu(texto); 1856 if (opcoes.length < 2) return texto; 1857 const indices = new Set(opcoes.map(o => o.indice)); 1858 return texto.split(/\r?\n/).filter((linha, indice) => !indices.has(indice)).join('\n').trim(); 1859 } 1860 function botoesMenu(s) { 1861 const opcoes = linhasMenu(s); 1862 if (opcoes.length < 2) return ''; 1863 return '<div class="cw-menu-opcoes">' + opcoes.map(o => 1864 `<button type="button" class="cw-menu-opcao" data-codigo="${esc(o.codigo)}"><strong>${esc(o.codigo)}</strong> · ${esc(o.titulo)}</button>` 1865 ).join('') + '</div>'; 1866 } 1867 function formatBytes(b) { 1868 if (b < 1024) return b + ' B'; 1869 if (b < 1048576) return (b/1024).toFixed(1) + ' KB'; 1870 return (b/1048576).toFixed(1) + ' MB'; 1871 } 1872 1873 function post(data, cb) { 1874 const fd = new FormData(); 1875 Object.keys(data).forEach(k => fd.append(k, data[k])); 1876 fetch(URL_CHAT, { method: 'POST', body: fd }) 1877 .then(r => r.json()) 1878 .then(cb) 1879 .catch(() => {}); 1880 } 1881 1882 // Se widget já estava aberto (ex: SPA), inicia ao carregar 1883 if ($widget.classList.contains('aberto')) iniciar(); 1884 1885})(); 1886</script>
1886 1887 1888 <div id="app" 1889 data-base-path="/home2/ant73159/public_html" 1890 data-base-url="https://embalaki.com.br" 1891 data-pasta-arquivos="storage" 1892 data-pagina="sobre" 1893 data-pagina-anterior="sobre"> 1894 </div> 1895 1896 <!-- Plugins JS File --> 1897
1897<script src="https://embalaki.com.br/templates/porto-min/assets/js/jquery.min.js" type="text/javascript"></script>
1897 1898
1898<script src="https://embalaki.com.br/templates/porto-min/assets/js/plugins.min.js" type="text/javascript"></script>
1898 1899
1899<script src="https://embalaki.com.br/templates/porto-min/assets/js/bootstrap.bundle.min.js" type="text/javascript"></script>
1899 1900
1900<script src="https://embalaki.com.br/templates/porto-min/assets/js/jquery.appear.min.js" type="text/javascript"></script>
1900 1901
1901<script src="https://embalaki.com.br/templates/porto-min/assets/js/jquery.plugin.min.js" type="text/javascript"></script>
1901 1902
1902<script src="https://embalaki.com.br/templates/porto-min/assets/js/jquery.countdown.min.js" type="text/javascript"></script>
1902 1903 1904 <!-- nouislider / Preço slider --> 1905
1905<script src="https://embalaki.com.br/templates/porto-min/assets/js/nouislider.min.js" type="text/javascript"></script>
1905 1906 1907 <!-- Main JS File --> 1908
1908<script src="https://embalaki.com.br/templates/porto-min/assets/js/main.js" type="text/javascript"></script>
1908 1909 1910 <!-- Moment --> 1911
1911<script src="https://embalaki.com.br/assets/plugins/moments/moment-with-locales.js" type="text/javascript"></script>
1911 1912 1913 <!-- assets --> 1914
1914<script src="https://embalaki.com.br/assets/js/functions-site.js" type="text/javascript"></script>
1914 1915
1915<script src="https://embalaki.com.br/assets/js/functions.js?v=1790522770" type="text/javascript"></script>
1915 1916
1916<script src="https://embalaki.com.br/assets/js/site.js?v=1788972826" type="text/javascript"></script>
1916 1917 1918 <!-- Plugins toastr --> 1919
1919<script src="https://embalaki.com.br/assets/plugins/toastr/toastr.min.js" type="text/javascript"></script>
1919 1920 1921 <!-- Jquery Validate --> 1922
1922<script src="https://embalaki.com.br/assets/plugins/jquery-validate/jquery.validate.min.js" type="text/javascript"></script>
1922 1923
1923<script src="https://embalaki.com.br/assets/plugins/jquery-validate/additional-methods.min.js" type="text/javascript"></script>
1923 1924
1924<script src="https://embalaki.com.br/assets/plugins/jquery-validate/localization/messages_pt_BR.js" type="text/javascript"></script>
1924 1925 1926 <!-- Jquery Mask --> 1927
1927<script src="https://embalaki.com.br/assets/plugins/jquery.mask.min.js" type="text/javascript"></script>
1927 1928 1929 <!-- upload --> 1930
1930<script src="https://embalaki.com.br/assets/plugins/image-uploader/image-uploader.js" type="text/javascript"></script>
1930 1931 1932
1932<script type="module" src="https://static.cloudflareinsights.com/beacon.min.js/v4bc70e2c01a94c73b74392e4234840661791215815920" integrity="sha512-L0ha0OXavK/8okipN9F8BtP84dg9DUhPERbBXzwI6dgTA55d2+yweo3pn5CSFYs45/r8md2+xvUPtTdvTNRfjA==" data-cf-beacon='{"version":"2024.11.0","token":"398cc59d47934945955d55cecaf1a119","r":1,"spa":2}' crossorigin="anonymous"></script>
1932 1933</body> 1934 1935</html>
Line numbers count LF bytes from the start of the resource, as the search results do. Vendor segments are library code the classifier recognised; they are stored but not indexed. Bytes are shown as Latin1 characters, one per byte.