9 İşlemeler 371bae4095 ... b5fccc29c7

Yazar SHA1 Mesaj Tarih
  Roberto Pereyra b5fccc29c7 Merge branch 'roberto' of https://git.contenidosonline.com.ar/pereyra/contenidosonline-web into roberto 2 yıl önce
  Roberto Pereyra 8301b16238 agregardos dockerfile y docker-compose 2 yıl önce
  Paula Pereyra b9640f5cf6 Changed github link for web page 2 yıl önce
  Paula Pereyra ecfd8a4da1 Service email conect. Animation added 2 yıl önce
  Paula Pereyra 352302f22e Footer improvements, UI form contact 2 yıl önce
  Paula Pereyra 1136909243 Add UsTeam Section 2 yıl önce
  Paula Pereyra 92b9a53a99 Finished services section 2 yıl önce
  Paula Pereyra 1e81cb490d Add Logo to header section 2 yıl önce
  Paula Pereyra 626829f39d Files that had been lost 2 yıl önce

+ 12 - 0
Dockerfile

@@ -0,0 +1,12 @@
+# Usamos una imagen base ligera de Nginx para servir contenido estático
+FROM nginx:alpine
+
+# Copiamos el contenido estático generado por Hugo a la carpeta predeterminada de Nginx
+ADD ./public /usr/share/nginx/html
+
+# Exponemos el puerto 80 para servir el sitio
+EXPOSE 80
+
+# El comando predeterminado para iniciar el servidor Nginx
+CMD ["nginx", "-g", "daemon off;"]
+

+ 18 - 1
config.toml

@@ -4,6 +4,7 @@ title = "ContenidosOnline"
 
 [params.navigation]
   logo = "CO"
+  items = [ "servicios", "nosotros", "contacto" ]
 
 [params.header]
   title = "ContenidosOnline"
@@ -12,6 +13,8 @@ title = "ContenidosOnline"
 [params.intro]
   text = "En ContenidosOnline, creemos que un sitio web es una herramienta esencial para cualquier empresa. Por eso, es importante contar con un sitio web profesional, seguro y que cumpla con los estándares actuales. Nosotros te ofrecemos servicio de web hosting, consultoría Linux y programación web para ayudarte a crear el sitio web que tu empresa necesita."
 
+# Icons: https://fontawesome.com/icons
+
 [params.services]
   titleService = "Consultoria Linux"
   titleService2 = "Desarrollo web"
@@ -72,4 +75,18 @@ title = "ContenidosOnline"
     description = [
         "Optimizamos nuestros sitios web para que sean fáciles de encontrar en los resultados de búsqueda. Esto significa que sus clientes potenciales pueden encontrar su sitio web cuando buscan información sobre su negocio.",
       ]
-    icon = "fa-solid fa-magnifying-glass"
+    icon = "fa-solid fa-magnifying-glass"
+
+  [[params.services.item_service_2]]
+    title = "Usabilidad"
+    description = [
+        "Se trata de simplificar la interacción del usuario con su sitio web. Creamos interfaces amigables que permiten a los visitantes navegar y realizar acciones de manera eficiente, mejorando así la retención y la conversión de clientes.",
+      ]
+    icon = "fa-regular fa-hand-pointer"
+
+  [[params.services.item_service_2]]
+    title = "Experiencia de usuario (UX)"
+    description = [
+        "Se enfoca en crear sitios web que sean fáciles de usar y agradables para los visitantes. Nos aseguramos de que los usuarios encuentren lo que necesitan de manera intuitiva, lo que mejora la satisfacción y fidelidad del cliente.",
+      ]
+    icon = "fa-regular fa-face-smile"

+ 8 - 0
docker-compose.yaml

@@ -0,0 +1,8 @@
+version: '3'
+services:
+  contenidosonline-web:
+    image: contenidosonline-web:1.0 
+    ports:
+      - "3050:80"
+    restart: always
+

+ 2 - 0
layouts/index.html

@@ -8,6 +8,8 @@
     <main>
       {{ partial "intro.html" . }}
       {{ partial "services.html" . }}
+      {{ partial "usTeam.html" . }}
+      {{ partial "contact.html" . }}
     </main>
 
     {{ partial "footer.html" .}}

+ 36 - 0
layouts/partials/contact.html

@@ -0,0 +1,36 @@
+<div class="contact-container" id="contacto"> 
+  <div class="container animation-scroll">
+    <h3 class="title-section">Contacto</h3>
+    <div class="row">
+      <div class="column-left">
+      </div>
+      <div class="column-right">
+        <form id="contactForm">
+          <div class="row-form">
+            <label for="nombre">Nombre y Apellido</label>
+            <input type="text" id="nombre" name="nombre" required>
+            <p class="formulario__input-error none">Requerido. Debe ser mínimo 4 letras</p>
+          </div>
+          <div class="row-form">
+            <label for="email">Email</label>
+            <input type="text" id="email" name="email" required>
+            <p class="formulario__input-error none">Requerido. Revise si el formato es el correcto</p>
+          </div>
+          <div class="row-form">
+            <label for="telefono">Teléfono</label>
+            <input type="number" id="telefono" name="telefono">
+          </div>
+          <div class="row-form">
+            <label for="mensaje">Mensaje</label>
+            <textarea name="mensaje" id="mensaje" cols="30" rows="10" required></textarea>
+            <p class="formulario__input-error none">Requerido</p>
+          </div>
+          <input class="button__form" type="submit" value="Enviar">
+          <div class="contact-form-response none">
+            <p>Los datos han sido enviados</p>
+          </div>
+        </form>
+      </div>
+    </div>
+  </div>
+</div>

+ 11 - 2
layouts/partials/footer.html

@@ -1,3 +1,12 @@
-<footer>
-  
+<footer class="footer">
+  <div class="container">
+    <div class="nav-footer">
+      <ul class="nav-links">
+        {{ range $item := .Site.Params.navigation.items }}
+          <li class="nav-link"><a href="#{{$item}}">{{$item}}</a></li>
+        {{ end }}
+      </ul>
+    </div>
+    <p>Copyright &copy; {{ now.Format "2006" }} ContenidosOnline</p>
+  </div>
 </footer>

+ 1 - 0
layouts/partials/head.html

@@ -1,6 +1,7 @@
 <meta charset="UTF-8" />
 <meta name="viewport" content="width=device-width, initial-scale=1.0" />
 <title>{{ .Title }}</title>
+<link rel="icon" href="img/Logo-2.svg" type="image/svg+xml">
 
 <!-- Style -->
 <link rel="stylesheet" href="css/main.css">

+ 7 - 0
layouts/partials/header.html

@@ -0,0 +1,7 @@
+<header class="header-top">
+  <div class="container__header animation-scroll">
+    <img src="img/Logo-2.svg" alt="Logo" width="260" height="145">
+    <h1 class="no-margins">{{ with .Site.Params.header.title }}{{ . | markdownify }}{{ end }}</h1>
+    <h2 class="no-margins">{{ with .Site.Params.header.subtitle }}{{ . | markdownify }}{{ end }}</h2>
+  </div>
+</header>

+ 5 - 0
layouts/partials/intro.html

@@ -0,0 +1,5 @@
+<div class="container">
+  <div class="intro-container">
+    <span class="animation-scroll">{{ with .Site.Params.intro.text }}{{ . | markdownify }}{{ end }}</span>
+  </div>
+</div>

+ 3 - 3
layouts/partials/nav.html

@@ -9,8 +9,8 @@
     <span class="menu-icon__line"></span>
   </label>
   <ul class="nav-links">
-    <li class="nav-link"><a href="#">Servicios</a></li>
-    <li class="nav-link"><a href="#">Nosotros</a></li>
-    <li class="nav-link"><a href="#">Contacto</a></li>
+    {{ range $item := .Site.Params.navigation.items }}
+      <li class="nav-link"><a href="#{{$item}}">{{$item}}</a></li>
+    {{ end }}
   </ul>
 </nav>

+ 3 - 0
layouts/partials/script.html

@@ -1 +1,4 @@
+<!-- Email -->
+<script type="text/javascript" src="https://cdn.jsdelivr.net/npm/@emailjs/browser@3/dist/email.min.js"></script>
+<script type="text/javascript">emailjs.init('KjgzLqUvLg29kOMXi')</script>
 <script src="js/main.js"></script>

+ 41 - 0
layouts/partials/services.html

@@ -0,0 +1,41 @@
+<div class="services-container" id="servicios"> 
+  <div class="container">
+    <h3 class="title-section">Servicios</h3>
+    <span>{{ .Site.Params.services.titleService }}</span>
+    <div class="container-services__items">
+      {{ range $item := .Site.Params.services.item_service_1 }}
+        <div class="service-item animation-scroll">
+          <div class="icon-item-container">
+            <i class="{{$item.icon }}"></i>
+          </div>
+          <div class="texts-item-container">
+            <h4 class="no-margins">{{ $item.title }}</h4>
+            <ul>
+              {{ range $descriptionElement := $item.description}}
+                <li>{{ $descriptionElement }}</li>
+              {{ end }}
+            </ul>
+          </div>
+        </div>
+      {{ end }}
+    </div>
+    <span>{{ .Site.Params.services.titleService2 }}</span>
+    <div class="container-services__items">
+      {{ range $item := .Site.Params.services.item_service_2 }}
+        <div class="service-item animation-scroll">
+          <div class="icon-item-container">
+            <i class="{{$item.icon }}"></i>
+          </div>
+          <div class="texts-item-container">
+            <h4 class="no-margins">{{ $item.title }}</h4>
+            <ul>
+              {{ range $descriptionElement := $item.description}}
+                <li>{{ $descriptionElement }}</li>
+              {{ end }}
+            </ul>
+          </div>
+        </div>
+      {{ end }}
+    </div>
+  </div>
+</div>

+ 37 - 0
layouts/partials/usTeam.html

@@ -0,0 +1,37 @@
+<div class="usTeam-container" id="nosotros">
+  <div class="container">
+    <h3 class="title-section ligth-bg-text">Nosotros</h3>
+    <div class="container__item-usTeam">
+      <div class="team-item-container animation-scroll">
+        <figure>
+          <svg xmlns="http://www.w3.org/2000/svg" width="50" height="50" viewBox="0 0 22 24"><path fill="currentColor" d="M14.041 16.683a14.884 14.884 0 0 1-.035-.72c2.549-.261 4.338-.872 4.338-1.585c-.007 0-.006-.03-.006-.041C16.432 12.619 19.99.417 13.367.663a3.344 3.344 0 0 0-2.196-.664h.008C2.208.677 6.175 12.202 4.13 14.377h-.004c.008.698 1.736 1.298 4.211 1.566c-.007.17-.022.381-.054.734C7.256 19.447.321 18.671.001 24h22.294c-.319-5.33-7.225-4.554-8.253-7.317z"/></svg>
+        </figure>
+        <div class="container__text">
+          <h4 class="no-margins">Paula Pereyra</h4>
+          <h6 class="no-margins">Desarrolladora Web</h6>
+          <div class="container-links">
+            <a class="social" href="https://www.linkedin.com/in/paula-pereyra-b1031622a/" target="_blank">
+              <i class="fa-brands fa-linkedin">
+              </i>
+            </a>
+            <a class="social" href="https://pereyrapaula.github.io/" target="_blank">
+              <i class="fa-solid fa-globe"></i>
+            </a>
+          </div>
+        </div>
+      </div>
+      <div class="team-item-container animation-scroll">
+        <figure>
+          <svg xmlns="http://www.w3.org/2000/svg" width="50" height="50" viewBox="0 0 22 24"><path fill="currentColor" d="M14.145 16.629a23.876 23.876 0 0 1-.052-2.525l-.001.037a4.847 4.847 0 0 0 1.333-2.868l.002-.021c.339-.028.874-.358 1.03-1.666a1.217 1.217 0 0 0-.455-1.218l-.003-.002c.552-1.66 1.698-6.796-2.121-7.326C13.485.35 12.479 0 11.171 0c-5.233.096-5.864 3.951-4.72 8.366a1.222 1.222 0 0 0-.455 1.229l-.001-.008c.16 1.306.691 1.638 1.03 1.666a4.858 4.858 0 0 0 1.374 2.888a24.648 24.648 0 0 1-.058 2.569l.005-.081C7.308 19.413.32 18.631 0 24h22.458c-.322-5.369-7.278-4.587-8.314-7.371z"/></svg>
+        </figure>
+        <div class="container__text">
+          <h4 class="no-margins">Roberto Pereyra</h4>
+          <h6 class="no-margins">Administrador de servidores <br>Unix - Linux</h6>
+          <div class="container-links">
+            <a href="#contacto" class="social"><i class="fa-solid fa-envelope"></i></a>
+          </div>
+        </div>
+      </div>
+    </div>
+  </div>
+</div>

+ 242 - 3
static/css/main.css

@@ -29,12 +29,35 @@ body {
   padding: 0;
 }
 
+.none {
+  display: none;
+}
+
+.animation-scroll {
+  view-timeline-name: --animated;
+  view-timeline-axis: block;
+
+  animation-timeline: --animated;
+  animation-name: show;
+
+  animation-range: entry 25% cover 50%;
+  animation-fill-mode: both;
+}
+
 .container {
   /* Extra Large: xl */ 
   max-width: 1200px;
   margin: 0 auto;
 }
 
+.ligth-bg-text {
+  color: #329998 !important;
+}
+
+.ligth-bg-text::after {
+  background: #329998 !important;
+}
+
 @media screen and (max-width: 767px) {
   .container {
     width: 100%;
@@ -99,7 +122,7 @@ body {
 }
 .main-header .nav-links .nav-link a:hover {
   background: rgba(255, 255, 255, 0.03);
-  color: #fff;
+  color: #0e3131;
 }
 .main-header .menu-icon {
   position: relative;
@@ -277,7 +300,7 @@ body {
 }
 
 .intro-container > span {
-  font-size: clamp(16px, 1.1vw, 28px);
+  font-size: clamp(16px, 1.1vw, 17px);
 }
 
 /* Services Section */
@@ -326,7 +349,6 @@ body {
   font-size: 80px;
 }
 
-
 .text-item-container > h2 {
   font-size: 18px;
   font-weight: bold;
@@ -367,6 +389,211 @@ body {
   }
 }
 
+/* UsTeam */
+
+.usTeam-container {
+  padding: 4rem 0;
+}   
+
+.container__item-usTeam {
+  display: flex;
+  flex-direction: row;
+  justify-content: center;
+}
+
+.team-item-container {
+  border: 2px solid #f2f2f2;
+  padding: 80px 30px 30px 30px;
+  float: left;
+  width: 100%;
+  position: relative;
+  margin: 4rem 2rem;
+  max-width: 340px;
+}
+
+.team-item-container > figure {
+  position: absolute;
+  margin-top: -30px;
+  top: 0;
+  left: 50%;
+  margin-left: -3rem;
+  display: block;
+  padding: 15px;
+  border: 5px solid #329998;
+  border-radius: 50%;
+}
+
+.team-item-container > figure > svg {
+  color: #267271;
+}
+
+.team-item-container > figure > svg:hover {
+  color: #329998;
+}
+
+.team-item-container > .container__text > h4 {
+  color: #000;
+  font-family: "Source Sans Pro", Arial, sans-serif;
+  font-weight: 400;
+  font-size: 24px;
+  text-align: center;
+  margin-bottom: .4rem;
+}
+
+.team-item-container > .container__text > h6 {
+  color: #b3b3b3;
+  font-weight: 300;
+  font-size: 18px;
+  line-height: 1.5;
+  text-align: center;
+}
+
+.team-item-container > .container__text > .container-links {
+  display: inline-block;
+  width: 100%;
+  text-align: center;
+  margin: 1rem 0;
+}
+
+a.social {
+  text-decoration: none;
+  color: inherit
+}
+
+.team-item-container > .container__text > .container-links > a.social > i {
+  margin-right: 0.5rem;
+  font-size: 1.3rem;
+  background-color: #329998;
+  color: #fff;
+  border-radius: 5px;
+  padding: 10px;
+}
+
+.team-item-container > .container__text > .container-links > i:hover {
+  cursor: pointer;
+  background-color: #1c4645;
+}
+
+@media screen and (max-width: 768px)  {
+  .container__item-usTeam {
+    display: flex;
+    flex-direction: column;
+    align-items: center;
+  }
+
+  .container__item-usTeam > .team-item-container {
+    width: 100%;
+    margin: 2rem 0;
+  }
+}
+
+/* Contact */
+
+.contact-container {
+  padding: 6rem 4rem;
+  background: #329998;
+  min-height: 800px;
+  max-height: 1000px;
+  clip-path: polygon(0px 0px, 100% 0px, 100% 100%, 0px 93.85%);
+}
+
+.contact-container > .container > .row {
+  display: grid;
+  grid-template-columns: repeat(2, 1fr);
+}
+
+form > .row-form {
+  display: flex;
+  flex-direction: column;
+  margin: 1rem 0;
+}
+
+form > .row-form > input {
+  border: none;
+  padding: 1rem;
+  font-family: var(--ff-main);
+  font-size: 16px;
+}
+
+form > .row-form > textarea {
+  resize: vertical;
+  max-height: 250px;
+  padding: 1rem;
+  font-family: var(--ff-main);
+  font-size: 16px;
+}
+
+form > .row-form > label {
+  margin-bottom: .5rem;
+  color: #FFF;
+}
+
+#contactForm > input {
+  width: 100%;
+  padding: 1rem 0;
+  border: none;
+}
+
+.formulario__input-error {
+  color: #fb0000;
+  text-shadow: 1px 1px #143f3e;
+  font-weight: bold;
+}
+
+input[type="submit"] {
+  background-color: rgb(29 119 118);
+  color: rgb(232, 230, 227);
+  border-color: transparent;
+  text-transform: uppercase;
+  border-radius: 3px;
+  font-size: 18px;
+}
+
+input[type="submit"]:disabled {
+  background-color: rgb(48, 52, 54);
+  color: rgb(232, 230, 227);
+  outline-color: currentcolor;
+}
+
+@media screen and (max-width: 768px) {
+  .contact-container > .container > .row {
+    grid-template-columns: 1fr;
+  }
+
+  .contact-container {
+    padding: 4rem 1rem
+  }
+}
+
+/* Footer */
+
+footer {
+  padding: 2rem;
+  color: #329998;
+  text-align: center;
+}
+
+.nav-footer > .nav-links {
+  display: flex;
+  justify-content: center;
+  list-style: none;
+  padding: 0;
+}
+
+.nav-footer > .nav-links > li {
+  text-transform: uppercase;
+  margin: 0 1rem 1rem 0;
+}
+
+.nav-footer > .nav-links > li:last-child {
+  margin: 0;
+}
+
+.nav-footer > .nav-links > li > a {
+  color: inherit;
+  font-weight: bold;
+  text-decoration: none;
+}
 
 /* Animaciones */
 @keyframes pulse {
@@ -397,3 +624,15 @@ body {
   50% { transform: translateY(0px) rotate(0deg); }
   100% { transform: translateY(0px) rotate(90deg); }
 }
+
+@keyframes show {
+	from {
+		opacity: 0;
+		scale: 25%;
+	}
+	
+	to {
+		opacity: 1;
+		scale: 100%;
+	}
+}

BIN
static/fonts/SourceSansPro-Regular.ttf


+ 49 - 0
static/img/Logo-1.svg

@@ -0,0 +1,49 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<svg id="Capa_3" data-name="Capa 3" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" viewBox="0 0 414.28 243.02">
+  <defs>
+    <style>
+      .cls-1, .cls-2 {
+        fill: #fff;
+      }
+
+      .cls-3 {
+        font-family: MicrosoftPhagsPa-Bold, 'Microsoft PhagsPa';
+        font-size: 45px;
+        font-weight: 700;
+      }
+
+      .cls-2 {
+        stroke: #fff;
+        stroke-miterlimit: 10;
+      }
+
+      .cls-4 {
+        mask: url(#mask);
+      }
+
+      .cls-5 {
+        fill: #74bf48;
+      }
+
+      .cls-6 {
+        filter: url(#luminosity-invert-noclip);
+      }
+    </style>
+    <filter id="luminosity-invert-noclip" x="175.6" y=".5" width="238.68" height="174.96" color-interpolation-filters="sRGB" filterUnits="userSpaceOnUse">
+      <feColorMatrix result="cm" values="-1 0 0 0 1 0 -1 0 0 1 0 0 -1 0 1 0 0 0 1 0"/>
+      <feFlood flood-color="#fff" result="bg"/>
+      <feBlend in="cm" in2="bg"/>
+    </filter>
+    <mask id="mask" x="175.6" y=".5" width="238.68" height="174.96" maskUnits="userSpaceOnUse">
+      <g class="cls-6">
+        <polygon class="cls-1" points="233.92 87.98 273.88 35.06 316 35.06 354.88 87.98 318.16 137.66 273.88 137.66 233.92 87.98"/>
+      </g>
+    </mask>
+  </defs>
+  <rect class="cls-5" x="10.36" y=".5" width="395.28" height="174.96" rx="34.02" ry="34.02"/>
+  <polygon class="cls-2" points="61.09 85.82 98.89 35.06 187.45 35.06 213.37 .5 61.09 .5 .61 85.82 63.25 175.46 213.37 175.46 188.53 138.74 98.89 138.74 61.09 85.82"/>
+  <g class="cls-4">
+    <polygon class="cls-1" points="175.6 81.5 238.24 .5 348.4 .5 414.28 87.98 351.64 175.46 241.48 175.46 175.6 81.5"/>
+  </g>
+  <text class="cls-3" transform="translate(18.27 231.23)"><tspan x="0" y="0">ContenidosOnline</tspan></text>
+</svg>

+ 42 - 0
static/img/Logo-2.svg

@@ -0,0 +1,42 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<svg id="Capa_3" data-name="Capa 3" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" viewBox="0 0 414.28 175.96">
+  <defs>
+    <style>
+      .cls-1, .cls-2 {
+        fill: #fff;
+      }
+
+      .cls-2 {
+        stroke: #fff;
+        stroke-miterlimit: 10;
+      }
+
+      .cls-3 {
+        mask: url(#mask);
+      }
+
+      .cls-4 {
+        fill: #74bf48;
+      }
+
+      .cls-5 {
+        filter: url(#luminosity-invert-noclip);
+      }
+    </style>
+    <filter id="luminosity-invert-noclip" x="175.6" y=".5" width="238.68" height="174.96" color-interpolation-filters="sRGB" filterUnits="userSpaceOnUse">
+      <feColorMatrix result="cm" values="-1 0 0 0 1 0 -1 0 0 1 0 0 -1 0 1 0 0 0 1 0"/>
+      <feFlood flood-color="#fff" result="bg"/>
+      <feBlend in="cm" in2="bg"/>
+    </filter>
+    <mask id="mask" x="175.6" y=".5" width="238.68" height="174.96" maskUnits="userSpaceOnUse">
+      <g class="cls-5">
+        <polygon class="cls-1" points="233.92 87.98 273.88 35.06 316 35.06 354.88 87.98 318.16 137.66 273.88 137.66 233.92 87.98"/>
+      </g>
+    </mask>
+  </defs>
+  <rect class="cls-4" x="10.36" y=".5" width="395.28" height="174.96" rx="34.02" ry="34.02"/>
+  <polygon class="cls-2" points="61.09 85.82 98.89 35.06 187.45 35.06 213.37 .5 61.09 .5 .61 85.82 63.25 175.46 213.37 175.46 188.53 138.74 98.89 138.74 61.09 85.82"/>
+  <g class="cls-3">
+    <polygon class="cls-1" points="175.6 81.5 238.24 .5 348.4 .5 414.28 87.98 351.64 175.46 241.48 175.46 175.6 81.5"/>
+  </g>
+</svg>

+ 84 - 0
static/js/main.js

@@ -0,0 +1,84 @@
+// CONFIGURATION NAVBAR
+const header = document.querySelector(".main-header");
+window.addEventListener("scroll", () => {
+  const scrollPos = window.scrollY;
+  if (scrollPos > 10) {
+    header.classList.add("scrolled");
+  } else {
+    header.classList.remove("scrolled");
+  }
+})
+
+// CONFIGURATION FORM
+
+const form = document.getElementById("contactForm");
+const fields = {
+  nombre: false,
+  email: false,
+  mensaje: false
+}
+const expresiones = {
+  nombre: /^.{4,30}$/,
+  email: /^[a-zA-Z0-9_.+-]+@[a-zA-Z0-9-]+\.[a-zA-Z0-9-.]+$/
+}
+const loader = document.querySelector(".contact-form-loader");
+const inputs = document.querySelectorAll("input:not([type='submit']), textarea");
+const inputSubmit = document.querySelector("input[type='submit']")
+
+const validateForm = (e) => {
+  switch (e.target.name) {
+    case "nombre":
+      validateField(expresiones.nombre, e.target, 'nombre');
+      break;
+    case "email":
+      validateField(expresiones.email, e.target, 'email');
+      break;
+    case "mensaje":
+      if (e.target.value.length === 0) {
+        document.querySelector("textarea[name='mensaje'] + .formulario__input-error").classList.remove('none')
+        fields.mensaje = false;
+      } else {
+        document.querySelector("textarea[name='mensaje'] + .formulario__input-error").classList.add('none')
+        fields.mensaje = true;
+      }
+      break;
+  }
+}
+
+const validateField = (expresion, input, field) => {
+  if (expresion.test(input.value)) {
+    document.querySelector(`input[name='${field}']`).classList.remove('input__border-error')
+    document.querySelector(`input[name='${field}'] + .formulario__input-error`).classList.add('none')
+    fields[field] = true;
+  } else {
+    document.querySelector(`input[name='${field}']`).classList.add('input__border-error')
+    document.querySelector(`input[name='${field}'] + .formulario__input-error`).classList.remove('none')
+    fields[field] = false;
+  }
+}
+
+inputs.forEach((input) => {
+  input.addEventListener('keyup', validateForm);
+  input.addEventListener('blur', validateForm);
+});
+
+form.addEventListener('submit', (e) => {
+  e.preventDefault();
+  if (fields.nombre && fields.email && fields.mensaje) {
+    inputSubmit.disabled = true;
+    inputSubmit.value = "Enviando...";
+
+    const serviceID = 'default_service';
+    const templateID = 'template_ab3seev';
+
+    emailjs.sendForm(serviceID, templateID, document.getElementById("contactForm"))
+      .then(() => {
+        inputSubmit.value = 'Enviar';
+        document.querySelector(".contact-form-response").classList.remove('none');
+        form.reset();
+      }, (err) => {
+        inputSubmit.value = 'Enviar';
+        // console.log(JSON.stringify(err));
+      });
+  }
+});