<!DOCTYPE html>
<html lang="es">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1.0">
<title>TOTI'S® — Víctor Garcés · Systems Developer</title>
<meta name="description" content="Víctor Manuel Garcés Borje — Systems Developer, Full Stack, Troubleshooting Assistance. Especialista en sistemas industriales para Chile.">
<meta name="keywords" content="systems developer Chile, full stack developer, troubleshooting, Víctor Garcés, desarrollo web industrial, PWA Chile, Victor Garces Borje">
<meta name="author" content="Víctor Manuel Garcés Borje">
<meta name="robots" content="index, follow">
<meta http-equiv="content-language" content="es">
<link rel="canonical" href="https://totis.cl/">
<meta property="og:image" content="https://totis.cl/favicon.png">
<meta name="google-site-verification" content="Apib7-x98H0j5cPqHWwSMm6dNU4GmODRoqxLiDzdx9I">
<meta property="og:type" content="website">
<meta property="og:url" content="https://totis.cl/">
<meta property="og:title" content="TOTI'S® — Víctor Garcés · Systems Developer">
<meta property="og:description" content="Víctor Manuel Garcés Borje — Systems Developer, Full Stack, Troubleshooting Assistance. Especialista en sistemas industriales para Chile.">
<meta property="og:locale" content="es_CL">
<meta property="og:site_name" content="Toti's®">
<meta name="twitter:card" content="summary">
<meta name="twitter:title" content="TOTI'S® — Víctor Garcés · Systems Developer">
<meta name="twitter:description" content="Systems Developer, Full Stack y Troubleshooting. Especialista en sistemas industriales. Chile.">
<link rel="preconnect" href="https://fonts.googleapis.com">
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
<link href="https://fonts.googleapis.com/css2?family=Cormorant+Garamond:wght@400;600;700&family=DM+Mono:wght@300;400&family=DM+Sans:wght@300;400;500&display=swap" rel="stylesheet">
<script src="https://challenges.cloudflare.com/turnstile/v0/api.js" async defer></script>
<style>
:root {
  --gold: #d4af37;
  --gold-light: #f0d060;
  --gold-dim: #8a6e1a;
  --pink: #ff1493;
  --pink-dim: rgba(255,20,147,0.15);
  --dark: #080808;
  --dark-2: #111111;
  --dark-3: #1a1a1a;
  --text: #e8e0cc;
  --text-dim: #7a7060;
}
* { margin:0; padding:0; box-sizing:border-box; }
body { font-family: 'DM Sans', sans-serif; background-color: var(--dark); background-image: url('fondo.png'); background-size: cover; background-position: center top; background-attachment: scroll; color: var(--text); min-height: 100vh; overflow-x: hidden; }
.bg-layer { position: fixed; inset: 0; z-index: 0; background: rgba(8,8,8,0.72), radial-gradient(ellipse 80% 60% at 20% 10%, rgba(212,175,55,0.06) 0%, transparent 60%), radial-gradient(ellipse 60% 50% at 85% 80%, rgba(255,20,147,0.06) 0%, transparent 55%); pointer-events: none; }
.bg-grid { position: fixed; inset: 0; z-index: 0; background-image: linear-gradient(rgba(212,175,55,0.03) 1px, transparent 1px), linear-gradient(90deg, rgba(212,175,55,0.03) 1px, transparent 1px); background-size: 60px 60px; pointer-events: none; }
.page { position: relative; z-index: 1; min-height: 100vh; display: grid; grid-template-rows: auto 1fr auto; max-width: 900px; margin: 0 auto; padding: 0 24px; }
header { padding: 48px 0 0; display: flex; flex-direction: column; align-items: center; text-align: center; animation: fadeUp 0.9s ease both; }
.logo-wrap { position: relative; margin-bottom: 8px; }
.logo { font-family: 'Cormorant Garamond', serif; font-size: clamp(64px, 14vw, 110px); font-weight: 700; letter-spacing: 6px; line-height: 1; background: linear-gradient(135deg, var(--gold-dim) 0%, var(--gold) 40%, var(--gold-light) 55%, var(--gold) 70%, var(--gold-dim) 100%); -webkit-background-clip: text; -webkit-text-fill-color: transparent; background-clip: text; filter: drop-shadow(0 0 20px rgba(212,175,55,0.35)) drop-shadow(0 0 40px rgba(255,20,147,0.2)); animation: logoPulse 4s ease-in-out infinite; }
@keyframes logoPulse { 0%,100% { filter: drop-shadow(0 0 20px rgba(212,175,55,0.35)) drop-shadow(0 0 40px rgba(255,20,147,0.2)); } 50% { filter: drop-shadow(0 0 30px rgba(212,175,55,0.55)) drop-shadow(0 0 60px rgba(255,20,147,0.35)); } }
.logo-reg { font-family: 'Cormorant Garamond', serif; font-size: 0.35em; vertical-align: super; -webkit-text-fill-color: var(--gold); }
.tagline { font-family: 'DM Mono', monospace; font-size: clamp(10px, 2.5vw, 13px); font-weight: 300; letter-spacing: 4px; color: var(--gold); text-transform: uppercase; opacity: 0.7; margin-bottom: 32px; }
.sep { width: 100%; max-width: 300px; height: 1px; background: linear-gradient(90deg, transparent, var(--gold-dim), var(--pink-dim), var(--gold-dim), transparent); margin: 0 auto 32px; opacity: 0.6; }
.hero { display: flex; flex-direction: column; align-items: center; gap: 8px; margin-bottom: 40px; animation: fadeUp 1s 0.15s ease both; }
.hero-name { font-family: 'Cormorant Garamond', serif; font-size: clamp(22px, 5vw, 30px); font-weight: 600; color: var(--text); letter-spacing: 1px; }
.hero-roles { display: flex; flex-wrap: wrap; justify-content: center; gap: 8px; }
.role-pill { font-family: 'DM Mono', monospace; font-size: 10px; font-weight: 400; letter-spacing: 2px; text-transform: uppercase; color: var(--gold); border: 1px solid rgba(212,175,55,0.5); border-radius: 2px; padding: 6px 14px; background: rgba(0,0,0,0.65); backdrop-filter: blur(4px); -webkit-backdrop-filter: blur(4px); text-shadow: 0 1px 4px rgba(0,0,0,0.8); transition: all 0.3s ease; }
.role-pill:hover { border-color: var(--pink); color: var(--pink); background: rgba(0,0,0,0.8); box-shadow: 0 0 16px rgba(255,20,147,0.35); text-shadow: 0 0 8px rgba(255,20,147,0.5); }
.section-label { font-family: 'DM Mono', monospace; font-size: 10px; letter-spacing: 4px; text-transform: uppercase; color: var(--text-dim); text-align: center; margin-bottom: 20px; }
.projects-grid { display: grid; grid-template-columns: repeat(auto-fit, minmax(180px, 1fr)); gap: 12px; margin-bottom: 48px; animation: fadeUp 1s 0.3s ease both; }
.project-card { display: block; text-decoration: none; background: var(--dark-2); border: 1px solid rgba(212,175,55,0.12); border-radius: 4px; padding: 20px 16px; position: relative; overflow: hidden; transition: all 0.35s ease; cursor: pointer; }
.project-card::before { content: ''; position: absolute; top: 0; left: 0; width: 100%; height: 2px; background: linear-gradient(90deg, transparent, var(--gold-dim), transparent); transform: translateX(-100%); transition: transform 0.5s ease; }
.project-card:hover::before { transform: translateX(100%); }
.project-card:hover { border-color: rgba(255,20,147,0.3); background: var(--dark-3); transform: translateY(-3px); box-shadow: 0 8px 30px rgba(255,20,147,0.08), 0 0 0 1px rgba(255,20,147,0.1); }
.project-icon { font-size: 28px; display: block; margin-bottom: 12px; filter: grayscale(0.3); }
.project-name { font-family: 'DM Mono', monospace; font-size: 11px; letter-spacing: 2px; text-transform: uppercase; color: var(--gold); margin-bottom: 6px; display: block; }
.project-desc { font-size: 12px; color: var(--text-dim); line-height: 1.5; }
.project-tag { margin-top: 14px; display: inline-block; font-family: 'DM Mono', monospace; font-size: 9px; letter-spacing: 1.5px; text-transform: uppercase; color: rgba(212,175,55,0.5); border: 1px solid rgba(212,175,55,0.15); border-radius: 2px; padding: 3px 8px; }
.social-section { display: flex; flex-direction: column; align-items: center; gap: 20px; margin-bottom: 48px; animation: fadeUp 1s 0.45s ease both; }
.social-row { display: flex; gap: 16px; flex-wrap: wrap; justify-content: center; }
.social-btn { display: flex; align-items: center; gap: 8px; text-decoration: none; color: var(--text-dim); font-family: 'DM Mono', monospace; font-size: 11px; letter-spacing: 2px; text-transform: uppercase; border: 1px solid rgba(212,175,55,0.12); border-radius: 3px; padding: 10px 18px; background: var(--dark-2); transition: all 0.3s ease; }
.social-btn svg { width: 14px; height: 14px; fill: currentColor; flex-shrink: 0; }
.social-btn:hover { color: var(--gold); border-color: rgba(212,175,55,0.5); background: rgba(212,175,55,0.08); box-shadow: 0 0 20px rgba(212,175,55,0.2); transform: translateY(-2px); }
.social-btn.whatsapp:hover { color: #25D366; border-color: rgba(37,211,102,0.5); background: rgba(37,211,102,0.08); box-shadow: 0 0 20px rgba(37,211,102,0.25); transform: translateY(-2px); }
.social-btn.facebook:hover { color: #1877F2; border-color: rgba(24,119,242,0.5); background: rgba(24,119,242,0.08); box-shadow: 0 0 20px rgba(24,119,242,0.25); transform: translateY(-2px); }
.social-btn.instagram:hover { color: #E1306C; border-color: rgba(225,48,108,0.5); background: rgba(225,48,108,0.08); box-shadow: 0 0 20px rgba(225,48,108,0.25); transform: translateY(-2px); }
footer { border-top: 1px solid rgba(212,175,55,0.08); padding: 20px 0 32px; text-align: center; animation: fadeUp 1s 0.6s ease both; }
.footer-text { font-family: 'DM Mono', monospace; font-size: 10px; letter-spacing: 2px; color: var(--gold); text-transform: uppercase; }
.footer-text span { color: rgba(212,175,55,0.4); }
.footer-visits { font-family: 'DM Mono', monospace; font-size: 10px; letter-spacing: 2px; color: var(--gold); text-transform: uppercase; margin-top: 10px; display: flex; align-items: center; justify-content: center; gap: 6px; }
.visits-dot { display: inline-block; width: 5px; height: 5px; border-radius: 50%; background: var(--gold-dim); box-shadow: 0 0 6px var(--gold-dim); animation: blink 3s ease-in-out infinite; }
.status-dot { display: inline-block; width: 5px; height: 5px; border-radius: 50%; background: #25D366; margin-right: 6px; vertical-align: middle; box-shadow: 0 0 6px #25D366; animation: blink 2.5s ease-in-out infinite; }
@keyframes blink { 0%,100% { opacity: 1; } 50% { opacity: 0.3; } }
@keyframes fadeUp { from { opacity: 0; transform: translateY(20px); } to { opacity: 1; transform: translateY(0); } }
.modal-overlay { display: none; position: fixed; inset: 0; z-index: 999; background: rgba(0,0,0,0.85); backdrop-filter: blur(8px); -webkit-backdrop-filter: blur(8px); align-items: center; justify-content: center; padding: 20px; }
.modal-overlay.active { display: flex; animation: fadeIn 0.25s ease; }
@keyframes fadeIn { from { opacity: 0; } to { opacity: 1; } }
.modal { background: var(--dark-2); border: 1px solid rgba(212,175,55,0.25); border-radius: 6px; padding: 32px 28px; width: 100%; max-width: 420px; position: relative; animation: slideUp 0.3s ease; }
@keyframes slideUp { from { transform: translateY(20px); opacity: 0; } to { transform: translateY(0); opacity: 1; } }
.modal-close { position: absolute; top: 14px; right: 16px; background: none; border: none; color: var(--text-dim); font-size: 20px; cursor: pointer; line-height: 1; transition: color 0.2s; }
.modal-close:hover { color: var(--gold); }
.modal-icon { font-size: 32px; text-align: center; margin-bottom: 8px; }
.modal-title { font-family: 'Cormorant Garamond', serif; font-size: 22px; font-weight: 600; color: var(--gold); text-align: center; margin-bottom: 4px; }
.modal-sub { font-family: 'DM Mono', monospace; font-size: 10px; letter-spacing: 2px; text-transform: uppercase; color: var(--text-dim); text-align: center; margin-bottom: 24px; }
.modal-network { display: flex; align-items: center; justify-content: center; gap: 8px; font-family: 'DM Mono', monospace; font-size: 11px; letter-spacing: 2px; text-transform: uppercase; color: var(--gold); background: rgba(212,175,55,0.06); border: 1px solid rgba(212,175,55,0.2); border-radius: 3px; padding: 8px; margin-bottom: 20px; }
.modal label { display: block; font-family: 'DM Mono', monospace; font-size: 10px; letter-spacing: 2px; text-transform: uppercase; color: var(--text-dim); margin-bottom: 6px; margin-top: 14px; }
.modal input { width: 100%; background: rgba(255,255,255,0.04); border: 1px solid rgba(212,175,55,0.2); border-radius: 3px; padding: 10px 14px; color: var(--text); font-family: 'DM Sans', sans-serif; font-size: 14px; outline: none; transition: border-color 0.2s, box-shadow 0.2s; }
.modal input:focus { border-color: rgba(212,175,55,0.6); box-shadow: 0 0 0 3px rgba(212,175,55,0.08); }
.modal input::placeholder { color: var(--text-dim); }
.modal-btn { width: 100%; margin-top: 22px; padding: 13px; background: linear-gradient(135deg, var(--gold-dim), var(--gold)); border: none; border-radius: 3px; color: #000; font-family: 'DM Mono', monospace; font-size: 11px; font-weight: 500; letter-spacing: 3px; text-transform: uppercase; cursor: pointer; transition: all 0.3s ease; }
.modal-btn:hover { background: linear-gradient(135deg, var(--gold), var(--gold-light)); box-shadow: 0 4px 20px rgba(212,175,55,0.3); transform: translateY(-1px); }
.modal-btn:disabled { opacity: 0.5; cursor: not-allowed; transform: none; }
.modal-success { text-align: center; padding: 16px 0; }
.modal-success .success-icon { font-size: 40px; margin-bottom: 12px; }
.modal-success .success-title { font-family: 'Cormorant Garamond', serif; font-size: 20px; color: var(--gold); margin-bottom: 8px; }
.modal-success .success-msg { font-size: 13px; color: var(--text-dim); line-height: 1.6; }
@media (max-width: 480px) { .page { padding: 0 16px; } header { padding-top: 36px; } .projects-grid { grid-template-columns: 1fr 1fr; gap: 8px; } .project-card { padding: 16px 12px; } .social-btn { padding: 9px 14px; font-size: 10px; } }
@media (max-width: 340px) { .projects-grid { grid-template-columns: 1fr; } }
#consultaBtn { position: fixed; right: 24px; bottom: 32px; width: 62px; height: 62px; background: linear-gradient(135deg, #c9a227, #f0c040); border: none; border-radius: 50%; cursor: pointer; box-shadow: 0 4px 20px rgba(201,162,39,0.65); display: flex; align-items: center; justify-content: center; transition: transform .2s, box-shadow .2s; z-index: 9999; }
#consultaBtn:hover { transform: scale(1.1); box-shadow: 0 6px 28px rgba(201,162,39,0.85); }
#consultaBtn svg { width: 30px; height: 30px; fill: #111; }
#consultaPanel { display: none; position: fixed; right: 24px; bottom: 108px; width: 320px; background: #1a1a1a; border: 1px solid #c9a227; border-radius: 16px; box-shadow: 0 8px 40px rgba(0,0,0,0.8); z-index: 9998; overflow: hidden; animation: consultaSlideUp .25s ease; }
@keyframes consultaSlideUp { from { opacity: 0; transform: translateY(20px); } to { opacity: 1; transform: translateY(0); } }
#consultaPanel.open { display: block; }
.cp-header { background: linear-gradient(135deg, #c9a227, #f0c040); padding: 13px 16px; display: flex; align-items: center; justify-content: space-between; }
.cp-header span { font-weight: 700; font-size: 14px; color: #111; letter-spacing: .4px; }
.cp-header button { background: none; border: none; cursor: pointer; font-size: 18px; color: #111; line-height: 1; }
.cp-body { padding: 16px 16px 18px; }
.cp-body label { display: block; font-size: 10px; color: #c9a227; font-weight: 700; margin-bottom: 3px; text-transform: uppercase; letter-spacing: .6px; }
.cp-body input, .cp-body textarea { width: 100%; background: #252525; border: 1px solid #333; border-radius: 7px; color: #eee; font-size: 13px; padding: 9px 11px; margin-bottom: 10px; outline: none; transition: border-color .2s; font-family: inherit; }
.cp-body input:focus, .cp-body textarea:focus { border-color: #c9a227; }
.cp-body textarea { resize: none; height: 72px; }
#cpSendBtn { width: 100%; padding: 11px; background: linear-gradient(135deg, #c9a227, #f0c040); border: none; border-radius: 7px; color: #111; font-size: 14px; font-weight: 700; cursor: pointer; transition: opacity .2s; letter-spacing: .4px; }
#cpSendBtn:hover { opacity: .9; }
#cpSendBtn:disabled { opacity: .6; cursor: not-allowed; }
#cpSuccess { display: none; text-align: center; padding: 28px 18px 24px; }
#cpSuccess .cpCheck { font-size: 46px; margin-bottom: 12px; }
#cpSuccess h3 { color: #c9a227; font-size: 15px; margin-bottom: 8px; }
#cpSuccess p { color: #aaa; font-size: 13px; line-height: 1.6; }
@media (max-width: 400px) { #consultaPanel { right: 10px; width: calc(100vw - 20px); } #consultaBtn { right: 14px; bottom: 20px; } }
</style>
<script type="application/ld+json">
{
  "@context": "https://schema.org",
  "@type": "Person",
  "name": "Víctor Manuel Garcés Borje",
  "alternateName": "Toti's",
  "url": "https://totis.cl",
  "jobTitle": "Systems Developer & Full Stack",
  "description": "Desarrollador Full Stack especializado en sistemas industriales, PWAs y troubleshooting técnico. Especialista en Cloudflare, JavaScript y bases de datos para Chile.",
  "telephone": "+56934072459",
  "email": "vgarcesb@gmail.com",
  "image": "https://totis.cl/favicon.png",
  "address": { "@type": "PostalAddress", "addressLocality": "Santiago", "addressRegion": "Región Metropolitana", "addressCountry": "CL" },
  "knowsAbout": ["Desarrollo Web","PWA","Cloudflare Workers","Cloudflare D1","JavaScript","Sistemas Industriales","Troubleshooting","Full Stack","IndexedDB","Mantenimiento Industrial"],
  "hasOccupation": { "@type": "Occupation", "name": "Systems Developer", "occupationLocation": { "@type": "Country", "name": "Chile" }, "description": "Desarrollo de sistemas industriales, PWAs offline, portales de gestión y troubleshooting técnico." },
  "sameAs": ["https://www.facebook.com/vgarcesb","https://www.instagram.com/totivgb"]
}
</script>
</head>
<body>

<div class="bg-layer"></div>
<div class="bg-grid"></div>

<div class="page">

  <header>
    <div class="logo-wrap">
      <div class="logo" aria-label="TOTI'S">TOTI'S<span class="logo-reg" aria-hidden="true">®</span></div>
    </div>
    <div class="tagline">Diseño en Elegancia</div>
    <div class="sep" role="separator" aria-hidden="true"></div>
    <div class="hero">
      <div class="hero-name">Víctor Manuel Garcés Borje</div>
      <div class="hero-roles" role="list" aria-label="Especialidades">
        <span class="role-pill" role="listitem">Systems Developer</span>
        <span class="role-pill" role="listitem">Full Stack</span>
        <span class="role-pill" role="listitem">Troubleshooting</span>
        <span class="role-pill" role="listitem">Chile</span>
      </div>
    </div>
  </header>

  <main>

    <div class="section-label" aria-hidden="true">— Proyectos —</div>
    <div class="projects-grid" role="list" aria-label="Proyectos industriales">

      <a class="project-card" href="https://generadores.totis.cl" target="_blank" rel="noopener" role="listitem" aria-label="Proyecto Generadores — Bitácora y hoja de vida de grupos electrógenos">
        <span class="project-icon" aria-hidden="true">⚡</span>
        <span class="project-name">Generadores</span>
        <span class="project-desc">Bitácora y hoja de vida de grupos electrógenos</span>
        <span class="project-tag" aria-label="Tecnología: Cloudflare D1">Cloudflare D1</span>
      </a>

      <a class="project-card" href="https://hvac.totis.cl" target="_blank" rel="noopener" role="listitem" aria-label="Proyecto HVAC — Gestión de sistemas de climatización industrial">
        <span class="project-icon" aria-hidden="true">❄️</span>
        <span class="project-name">HVAC</span>
        <span class="project-desc">Gestión de sistemas de climatización industrial</span>
        <span class="project-tag" aria-label="Tecnología: Cloudflare D1">Cloudflare D1</span>
      </a>

      <a class="project-card" href="https://ups.totis.cl" target="_blank" rel="noopener" role="listitem" aria-label="Proyecto UPS — Control y mantención de sistemas de respaldo eléctrico">
        <span class="project-icon" aria-hidden="true">🔋</span>
        <span class="project-name">UPS</span>
        <span class="project-desc">Control y mantención de sistemas de respaldo eléctrico</span>
        <span class="project-tag" aria-label="Tecnología: Cloudflare D1">Cloudflare D1</span>
      </a>

      <a class="project-card" href="https://caldera.totis.cl" target="_blank" rel="noopener" role="listitem" aria-label="Proyecto Calderas — Registro técnico y mantención de calderas industriales">
        <span class="project-icon" aria-hidden="true">🔥</span>
        <span class="project-name">Calderas</span>
        <span class="project-desc">Registro técnico y mantención de calderas industriales</span>
        <span class="project-tag" aria-label="Tecnología: Cloudflare D1">Cloudflare D1</span>
      </a>

    </div>

    <div class="section-label" aria-hidden="true">— Contacto —</div>
    <div class="social-section">
      <div class="social-row" role="list" aria-label="Redes sociales y contacto">

        <a class="social-btn whatsapp"
           href="#"
           role="listitem"
           aria-label="Contactar por WhatsApp"
           data-url="https://wa.me/56934072459"
           data-network="WhatsApp 💬"
           onclick="abrirModal(event, this)"
           title="WhatsApp">
          <svg viewBox="0 0 24 24" xmlns="http://www.w3.org/2000/svg" aria-hidden="true">
            <path d="M17.472 14.382c-.297-.149-1.758-.867-2.03-.967-.273-.099-.471-.148-.67.15-.197.297-.767.966-.94 1.164-.173.199-.347.223-.644.075-.297-.15-1.255-.463-2.39-1.475-.883-.788-1.48-1.761-1.653-2.059-.173-.297-.018-.458.13-.606.134-.133.298-.347.446-.52.149-.174.198-.298.298-.497.099-.198.05-.371-.025-.52-.075-.149-.669-1.612-.916-2.207-.242-.579-.487-.5-.669-.51-.173-.008-.371-.01-.57-.01-.198 0-.52.074-.792.372-.272.297-1.04 1.016-1.04 2.479 0 1.462 1.065 2.875 1.213 3.074.149.198 2.096 3.2 5.077 4.487.709.306 1.262.489 1.694.625.712.227 1.36.195 1.871.118.571-.085 1.758-.719 2.006-1.413.248-.694.248-1.289.173-1.413-.074-.124-.272-.198-.57-.347m-5.421 7.403h-.004a9.87 9.87 0 01-5.031-1.378l-.361-.214-3.741.982.998-3.648-.235-.374a9.86 9.86 0 01-1.51-5.26c.001-5.45 4.436-9.884 9.888-9.884 2.64 0 5.122 1.03 6.988 2.898a9.825 9.825 0 012.893 6.994c-.003 5.45-4.437 9.884-9.885 9.884m8.413-18.297A11.815 11.815 0 0012.05 0C5.495 0 .16 5.335.157 11.892c0 2.096.547 4.142 1.588 5.945L.057 24l6.305-1.654a11.882 11.882 0 005.683 1.448h.005c6.554 0 11.89-5.335 11.893-11.893a11.821 11.821 0 00-3.48-8.413z"/>
          </svg>
          <span aria-hidden="true">WhatsApp</span>
        </a>

        <a class="social-btn facebook"
           href="#"
           role="listitem"
           aria-label="Visitar perfil de Facebook"
           data-url="https://www.facebook.com/vgarcesb"
           data-network="Facebook 👤"
           onclick="abrirModal(event, this)"
           title="Facebook">
          <svg viewBox="0 0 24 24" xmlns="http://www.w3.org/2000/svg" aria-hidden="true">
            <path d="M24 12.073c0-6.627-5.373-12-12-12s-12 5.373-12 12c0 5.99 4.388 10.954 10.125 11.854v-8.385H7.078v-3.47h3.047V9.43c0-3.007 1.792-4.669 4.533-4.669 1.312 0 2.686.235 2.686.235v2.953H15.83c-1.491 0-1.956.925-1.956 1.874v2.25h3.328l-.532 3.47h-2.796v8.385C19.612 23.027 24 18.062 24 12.073z"/>
          </svg>
          <span aria-hidden="true">Facebook</span>
        </a>

        <a class="social-btn instagram"
           href="#"
           role="listitem"
           aria-label="Visitar perfil de Instagram"
           data-url="https://www.instagram.com/totivgb"
           data-network="Instagram 📷"
           onclick="abrirModal(event, this)"
           title="Instagram">
          <svg viewBox="0 0 24 24" xmlns="http://www.w3.org/2000/svg" aria-hidden="true">
            <path d="M12 2.163c3.204 0 3.584.012 4.85.07 3.252.148 4.771 1.691 4.919 4.919.058 1.265.069 1.645.069 4.849 0 3.205-.012 3.584-.069 4.849-.149 3.225-1.664 4.771-4.919 4.919-1.266.058-1.644.07-4.85.07-3.204 0-3.584-.012-4.849-.07-3.26-.149-4.771-1.699-4.919-4.92-.058-1.265-.07-1.644-.07-4.849 0-3.204.013-3.583.07-4.849.149-3.227 1.664-4.771 4.919-4.919 1.266-.057 1.645-.069 4.849-.069zm0-2.163c-3.259 0-3.667.014-4.947.072-4.358.2-6.78 2.618-6.98 6.98-.059 1.281-.073 1.689-.073 4.948 0 3.259.014 3.668.072 4.948.2 4.358 2.618 6.78 6.98 6.98 1.281.058 1.689.072 4.948.072 3.259 0 3.668-.014 4.948-.072 4.354-.2 6.782-2.618 6.979-6.98.059-1.28.073-1.689.073-4.948 0-3.259-.014-3.667-.072-4.947-.196-4.354-2.617-6.78-6.979-6.98-1.281-.059-1.69-.073-4.949-.073zm0 5.838c-3.403 0-6.162 2.759-6.162 6.162s2.759 6.163 6.162 6.163 6.162-2.759 6.162-6.163c0-3.403-2.759-6.162-6.162-6.162zm0 10.162c-2.209 0-4-1.79-4-4 0-2.209 1.791-4 4-4s4 1.791 4 4c0 2.21-1.791 4-4 4zm6.406-11.845c-.796 0-1.441.645-1.441 1.44s.645 1.44 1.441 1.44c.795 0 1.439-.645 1.439-1.44s-.644-1.44-1.439-1.44z"/>
          </svg>
          <span aria-hidden="true">Instagram</span>
        </a>

      </div>

      <div style="font-family:'DM Mono',monospace;font-size:10px;letter-spacing:2px;color:var(--gold);text-align:center;" aria-live="polite">
        <span class="status-dot" aria-hidden="true"></span>Disponible para proyectos · Chile
      </div>
    </div>

  </main>

  <footer>
    <div class="footer-text">
      © 2026 TOTI'S® <span>·</span> Víctor Manuel Garcés Borje <span>·</span> totis.cl
    </div>
    <div class="footer-visits" aria-live="polite" aria-label="Contador de visitas">
      <span class="visits-dot" aria-hidden="true"></span>
      <span id="visitCount" aria-label="Número de visitas">···</span> visitas
    </div>
  </footer>

</div>

<!-- MODAL CONTACTO -->
<div class="modal-overlay"
     id="modalOverlay"
     role="dialog"
     aria-modal="true"
     aria-labelledby="modal-title"
     aria-hidden="true">
  <div class="modal">
    <button class="modal-close"
            aria-label="Cerrar diálogo"
            onclick="cerrarModal()">✕</button>

    <div id="modalForm">
      <div class="modal-icon" aria-hidden="true">🔐</div>
      <div class="modal-title" id="modal-title">Conectemos</div>
      <div class="modal-sub">Déjame tus datos para continuar</div>
      <div class="modal-network" id="modalNetwork" aria-live="polite">WhatsApp 💬</div>
      <label for="inputNombre">Nombre completo</label>
      <input type="text" id="inputNombre" placeholder="Tu nombre" required autocomplete="name" maxlength="80" pattern="[a-zA-ZáéíóúÁÉÍÓÚñÑ\s]+">
      <label for="inputCorreo">Correo electrónico</label>
      <input type="email" id="inputCorreo" placeholder="tu@correo.com" required autocomplete="email" maxlength="100">
      <label for="inputTelefono">Teléfono / WhatsApp</label>
      <input type="tel" id="inputTelefono" placeholder="+56 9 XXXX XXXX" autocomplete="tel" maxlength="20">
      <div class="cf-turnstile" data-sitekey="0x4AAAAAADr_tg7fuvSedgL0" data-callback="onTurnstileModal" style="margin-top:14px;"></div>
      <button class="modal-btn" id="btnEnviar" onclick="enviarYRedirigir()">
        Continuar →
      </button>
    </div>

    <div class="modal-success" id="modalSuccess" style="display:none" role="status" aria-live="polite">
      <div class="success-icon" aria-hidden="true">✅</div>
      <div class="success-title">¡Gracias!</div>
      <div class="success-msg">Tomaré contacto contigo pronto.<br>Ahora te redirigimos...</div>
    </div>
  </div>
</div>

<!-- WIDGET CONSULTA ONLINE FLOTANTE -->
<button id="consultaBtn"
        title="Consulta Online"
        aria-label="Abrir panel de consulta online"
        aria-expanded="false"
        aria-controls="consultaPanel"
        onclick="toggleConsulta()">
  <svg viewBox="0 0 24 24" xmlns="http://www.w3.org/2000/svg" aria-hidden="true">
    <path d="M20 2H4C2.9 2 2 2.9 2 4v18l4-4h14c1.1 0 2-.9 2-2V4c0-1.1-.9-2-2-2zm-2 12H6v-2h12v2zm0-3H6V9h12v2zm0-3H6V6h12v2z"/>
  </svg>
</button>

<div id="consultaPanel"
     role="dialog"
     aria-modal="true"
     aria-labelledby="cp-title"
     aria-hidden="true">
  <div class="cp-header">
    <span id="cp-title">💬 Consulta Online — Totis</span>
    <button onclick="toggleConsulta()" aria-label="Cerrar panel de consulta" title="Cerrar">✕</button>
  </div>
  <div class="cp-body" id="cpFormArea">
    <label for="cpNombre">Nombre</label>
    <input type="text" id="cpNombre" placeholder="Tu nombre completo" maxlength="80" autocomplete="name"/>
    <label for="cpEmail">Email</label>
    <input type="email" id="cpEmail" placeholder="correo@ejemplo.com" maxlength="100" autocomplete="email"/>
    <label for="cpTelefono">Teléfono</label>
    <input type="tel" id="cpTelefono" placeholder="+56 9 XXXX XXXX" maxlength="20" autocomplete="tel"/>
    <label for="cpConsulta">Tu consulta</label>
    <textarea id="cpConsulta" placeholder="Escribe aquí tu consulta o solicitud..."></textarea>
    <div class="cf-turnstile" data-sitekey="0x4AAAAAADr_tg7fuvSedgL0" data-callback="onTurnstileWidget" style="margin-bottom:10px;"></div>
    <button id="cpSendBtn" onclick="enviarConsultaWidget()">Enviar Consulta</button>
  </div>
  <div id="cpSuccess" role="status" aria-live="polite">
    <div class="cpCheck" aria-hidden="true">✅</div>
    <h3>¡Mensaje recibido!</h3>
    <p>Contactaremos a la brevedad.<br>¡Gracias por consultar!</p>
  </div>
</div>

<script>
  var MAIL_API = 'https://totis-web.vgarcesb.workers.dev';
  let urlDestino = '';
  var tsTokenModal = '';
  var tsTokenWidget = '';
  function onTurnstileModal(token) { tsTokenModal = token; }
  function onTurnstileWidget(token) { tsTokenWidget = token; }

  function abrirModal(e, btn) {
    e.preventDefault();
    urlDestino = btn.getAttribute('data-url');
    const red = btn.getAttribute('data-network');
    document.getElementById('modalNetwork').textContent = red;
    document.getElementById('modalForm').style.display = 'block';
    document.getElementById('modalSuccess').style.display = 'none';
    document.getElementById('inputNombre').value = '';
    document.getElementById('inputCorreo').value = '';
    document.getElementById('inputTelefono').value = '';
    document.getElementById('btnEnviar').disabled = false;
    document.getElementById('btnEnviar').textContent = 'Continuar →';
    const overlay = document.getElementById('modalOverlay');
    overlay.classList.add('active');
    overlay.setAttribute('aria-hidden', 'false');
    setTimeout(function(){ document.getElementById('inputNombre').focus(); }, 100);
  }

  function cerrarModal() {
    const overlay = document.getElementById('modalOverlay');
    overlay.classList.remove('active');
    overlay.setAttribute('aria-hidden', 'true');
  }

  document.getElementById('modalOverlay').addEventListener('click', function(e) {
    if (e.target === this) cerrarModal();
  });

  document.addEventListener('keydown', function(e) {
    if (e.key === 'Escape') cerrarModal();
  });

  function htmlEsc(str) {
    return String(str || '').replace(/[<>"'&]/g, function(c) {
      return {'<':'&lt;','>':'&gt;','"':'&quot;',"'":'&#39;','&':'&amp;'}[c];
    });
  }
  function emailValido(e) { return /^[^\s@]+@[^\s@]+\.[^\s@]+$/.test(e); }
  var lastSendModal = 0;

  function enviarYRedirigir() {
    var now = Date.now();
    if (now - lastSendModal < 30000) { alert('Por favor espera 30 segundos.'); return; }
    const nombre   = htmlEsc(document.getElementById('inputNombre').value.trim());
    const correo   = htmlEsc(document.getElementById('inputCorreo').value.trim());
    const telefono = htmlEsc(document.getElementById('inputTelefono').value.trim());
    const red      = document.getElementById('modalNetwork').textContent;
    if (!nombre || !emailValido(correo)) { alert('Por favor completa nombre y un correo válido.'); return; }
    if (!tsTokenModal) { alert('Por favor completa la verificación de seguridad.'); return; }
    const btn = document.getElementById('btnEnviar');
    btn.disabled = true;
    btn.textContent = 'Enviando...';
    fetch(MAIL_API + '/api/send-contact', {
      method: 'POST',
      headers: { 'Content-Type': 'application/json' },
      body: JSON.stringify({ tipo: 'red-social', nombre: nombre, correo: correo, telefono: telefono, red: red, turnstileToken: tsTokenModal })
    }).then(function() {
      lastSendModal = now;
      document.getElementById('modalForm').style.display = 'none';
      document.getElementById('modalSuccess').style.display = 'block';
      setTimeout(function() { cerrarModal(); window.open(urlDestino, '_blank'); }, 2000);
    }).catch(function() { cerrarModal(); window.open(urlDestino, '_blank'); });
  }

  // Contador de visitas
  (function() {
   var WORKER_URL = 'https://totis-api.totis.cl';
    var el = document.getElementById('visitCount');
    fetch(WORKER_URL + '/api/visita', { method: 'POST', headers: { 'Content-Type': 'application/json' } })
    .then(function(r) { return r.json(); })
    .then(function(data) { if (el && data.total !== undefined) el.textContent = data.total.toLocaleString('es-CL'); })
    .catch(function() { if (el) el.textContent = '—'; });
  })();

  // Widget consulta
  function toggleConsulta() {
    var panel = document.getElementById('consultaPanel');
    var btn   = document.getElementById('consultaBtn');
    var isOpen = panel.classList.toggle('open');
    panel.setAttribute('aria-hidden', isOpen ? 'false' : 'true');
    btn.setAttribute('aria-expanded', isOpen ? 'true' : 'false');
    if (isOpen) {
      document.getElementById('cpFormArea').style.display = 'block';
      document.getElementById('cpSuccess').style.display = 'none';
      setTimeout(function(){ document.getElementById('cpNombre').focus(); }, 100);
    }
  }

  function cpSanitize(str) {
    return str.replace(/[<>"'&]/g, function(c) {
      return {'<':'&lt;','>':'&gt;','"':'&quot;',"'":'&#39;','&':'&amp;'}[c];
    });
  }
  function cpValidEmail(e) { return /^[^\s@]+@[^\s@]+\.[^\s@]+$/.test(e); }
  var cpLastSend = 0;

  function enviarConsultaWidget() {
    var now = Date.now();
    if (now - cpLastSend < 30000) { alert('Por favor espera 30 segundos.'); return; }
    var nombre   = cpSanitize(document.getElementById('cpNombre').value.trim());
    var email    = cpSanitize(document.getElementById('cpEmail').value.trim());
    var telefono = cpSanitize(document.getElementById('cpTelefono').value.trim());
    var consulta = cpSanitize(document.getElementById('cpConsulta').value.trim());
    if (!nombre)              { alert('Por favor ingresa tu nombre.');       return; }
    if (!cpValidEmail(email)) { alert('Por favor ingresa un email válido.'); return; }
    if (!consulta)            { alert('Por favor escribe tu consulta.');     return; }
    if (!tsTokenWidget)       { alert('Por favor completa la verificación de seguridad.'); return; }
    var btn = document.getElementById('cpSendBtn');
    btn.textContent = 'Enviando...';
    btn.disabled = true;
    fetch(MAIL_API + '/api/send-contact', {
      method: 'POST',
      headers: { 'Content-Type': 'application/json' },
      body: JSON.stringify({ tipo: 'consulta', nombre: nombre, correo: email, telefono: telefono, mensaje: consulta, turnstileToken: tsTokenWidget })
    }).then(function() { cpMostrarExito(); }).catch(function() { cpMostrarExito(); });
    cpLastSend = now;
  }

  function cpMostrarExito() {
    document.getElementById('cpFormArea').style.display = 'none';
    document.getElementById('cpSuccess').style.display = 'block';
    ['cpNombre','cpEmail','cpTelefono','cpConsulta'].forEach(function(id){ document.getElementById(id).value=''; });
    var btn = document.getElementById('cpSendBtn');
    btn.textContent = 'Enviar Consulta';
    btn.disabled = false;
  }
</script>
</body>
</html>
