Update for production backup
@@ -1,8 +1,22 @@
|
||||
-FRAMER MOTION :
|
||||
npm install framer-motion
|
||||
-npm run dev
|
||||
|
||||
|
||||
|
||||
# React + Vite
|
||||
|
||||
This template provides a minimal setup to get React working in Vite with HMR and some ESLint rules.
|
||||
|
||||
Currently, two official plugins are available:
|
||||
|
||||
- [@vitejs/plugin-react](https://github.com/vitejs/vite-plugin-react/blob/main/packages/plugin-react/README.md) uses [Babel](https://babeljs.io/) for Fast Refresh
|
||||
- [@vitejs/plugin-react-swc](https://github.com/vitejs/vite-plugin-react-swc) uses [SWC](https://swc.rs/) for Fast Refresh
|
||||
- [@vitejs/plugin-react](https://github.com/vitejs/vite-plugin-react/blob/main/packages/plugin-react) uses [Babel](https://babeljs.io/) (or [oxc](https://oxc.rs) when used in [rolldown-vite](https://vite.dev/guide/rolldown)) for Fast Refresh
|
||||
- [@vitejs/plugin-react-swc](https://github.com/vitejs/vite-plugin-react/blob/main/packages/plugin-react-swc) uses [SWC](https://swc.rs/) for Fast Refresh
|
||||
|
||||
## React Compiler
|
||||
|
||||
The React Compiler is not enabled on this template because of its impact on dev & build performances. To add it, see [this documentation](https://react.dev/learn/react-compiler/installation).
|
||||
|
||||
## Expanding the ESLint configuration
|
||||
|
||||
If you are developing a production application, we recommend using TypeScript with type-aware lint rules enabled. Check out the [TS template](https://github.com/vitejs/vite/tree/main/packages/create-vite/template-react-ts) for information on how to integrate TypeScript and [`typescript-eslint`](https://typescript-eslint.io) in your project.
|
||||
|
||||
|
Before Width: | Height: | Size: 52 KiB After Width: | Height: | Size: 52 KiB |
|
Before Width: | Height: | Size: 17 KiB After Width: | Height: | Size: 17 KiB |
|
Before Width: | Height: | Size: 31 KiB After Width: | Height: | Size: 31 KiB |
|
Before Width: | Height: | Size: 8.3 KiB After Width: | Height: | Size: 8.3 KiB |
|
After Width: | Height: | Size: 32 KiB |
|
Before Width: | Height: | Size: 130 KiB After Width: | Height: | Size: 130 KiB |
|
Before Width: | Height: | Size: 140 KiB After Width: | Height: | Size: 140 KiB |
|
Before Width: | Height: | Size: 143 KiB After Width: | Height: | Size: 143 KiB |
|
Before Width: | Height: | Size: 155 KiB After Width: | Height: | Size: 155 KiB |
|
After Width: | Height: | Size: 28 KiB |
@@ -1,13 +1,18 @@
|
||||
import js from '@eslint/js'
|
||||
import globals from 'globals'
|
||||
import react from 'eslint-plugin-react'
|
||||
import reactHooks from 'eslint-plugin-react-hooks'
|
||||
import reactRefresh from 'eslint-plugin-react-refresh'
|
||||
import { defineConfig, globalIgnores } from 'eslint/config'
|
||||
|
||||
export default [
|
||||
export default defineConfig([
|
||||
globalIgnores(['dist']),
|
||||
{
|
||||
files: ['**/*.{js,jsx}'],
|
||||
ignores: ['dist'],
|
||||
extends: [
|
||||
js.configs.recommended,
|
||||
reactHooks.configs.flat.recommended,
|
||||
reactRefresh.configs.vite,
|
||||
],
|
||||
languageOptions: {
|
||||
ecmaVersion: 2020,
|
||||
globals: globals.browser,
|
||||
@@ -17,22 +22,8 @@ export default [
|
||||
sourceType: 'module',
|
||||
},
|
||||
},
|
||||
settings: { react: { version: '18.3' } },
|
||||
plugins: {
|
||||
react,
|
||||
'react-hooks': reactHooks,
|
||||
'react-refresh': reactRefresh,
|
||||
},
|
||||
rules: {
|
||||
...js.configs.recommended.rules,
|
||||
...react.configs.recommended.rules,
|
||||
...react.configs['jsx-runtime'].rules,
|
||||
...reactHooks.configs.recommended.rules,
|
||||
'react/jsx-no-target-blank': 'off',
|
||||
'react-refresh/only-export-components': [
|
||||
'warn',
|
||||
{ allowConstantExport: true },
|
||||
],
|
||||
'no-unused-vars': ['error', { varsIgnorePattern: '^[A-Z_]|motion' }],
|
||||
},
|
||||
},
|
||||
]
|
||||
])
|
||||
|
||||
@@ -1,12 +1,39 @@
|
||||
<!doctype html>
|
||||
<html lang="en">
|
||||
<html lang="es">
|
||||
<head>
|
||||
<meta charset="UTF-8" />
|
||||
<link rel="icon" type="image/svg+xml" href="/vite.svg" />
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
|
||||
<title>Vite + React</title>
|
||||
<meta name="theme-color" content="#020617" />
|
||||
|
||||
<!-- SEO Básico -->
|
||||
<meta name="description" content="TESS - Consultoría de Software y Servicios de TI. Creamos aplicaciones web, móviles y soluciones robustas alineadas a los objetivos de tu negocio." />
|
||||
<meta name="keywords" content="desarrollo de software, consultoria ti, aplicaciones web, outsourcing, mexico, tess, tecnologia" />
|
||||
<title>TESS | Consultoría en Desarrollo de Software</title>
|
||||
|
||||
<!-- Open Graph (Facebook, LinkedIn, WhatsApp) -->
|
||||
<meta property="og:type" content="website" />
|
||||
<meta property="og:title" content="TESS | Consultoría en Desarrollo de Software" />
|
||||
<meta property="og:description" content="Impulsamos el crecimiento de tu empresa mediante soluciones tecnológicas a medida." />
|
||||
<meta property="og:image" content="https://tesscorp.com.mx/assets/TESS.png" />
|
||||
<meta property="og:url" content="https://tesscorp.com.mx/" />
|
||||
<meta property="og:site_name" content="TESS Corporation" />
|
||||
|
||||
<!-- Twitter Card -->
|
||||
<meta name="twitter:card" content="summary_large_image" />
|
||||
<meta name="twitter:title" content="TESS | Consultoría de Software" />
|
||||
<meta name="twitter:description" content="Soluciones tecnológicas a medida para transformar tu negocio." />
|
||||
|
||||
<!-- Preloads de Recursos Críticos -->
|
||||
<link rel="preload" as="image" href="/assets/TESS.png" />
|
||||
<link rel="icon" type="image/jpeg" href="/assets/normal-logo-tess.jpeg" />
|
||||
|
||||
<!-- Fuentes (Google Fonts y Material Symbols) -->
|
||||
<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=Material+Symbols+Outlined:wght,FILL@100..700,0..1&display=swap" rel="stylesheet" />
|
||||
<link href="https://fonts.googleapis.com/css2?family=Raleway:wght@300;400;700&display=swap" rel="stylesheet">
|
||||
</head>
|
||||
<body>
|
||||
<body class="bg-brand-dark text-white font-raleway antialiased">
|
||||
<div id="root"></div>
|
||||
<script type="module" src="/src/main.jsx"></script>
|
||||
</body>
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
{
|
||||
"name": "tess-web",
|
||||
"name": "mi-portafolio-tess",
|
||||
"private": true,
|
||||
"version": "0.0.0",
|
||||
"type": "module",
|
||||
@@ -10,24 +10,24 @@
|
||||
"preview": "vite preview"
|
||||
},
|
||||
"dependencies": {
|
||||
"@headlessui/react": "^2.2.0",
|
||||
"@heroicons/react": "^2.1.5",
|
||||
"react": "^18.3.1",
|
||||
"react-dom": "^18.3.1"
|
||||
"framer-motion": "^12.26.2",
|
||||
"react": "^19.2.0",
|
||||
"react-dom": "^19.2.0",
|
||||
"react-fast-marquee": "^1.6.5"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@eslint/js": "^9.8.0",
|
||||
"@types/react": "^18.3.3",
|
||||
"@types/react-dom": "^18.3.0",
|
||||
"@vitejs/plugin-react": "^4.3.1",
|
||||
"autoprefixer": "^10.4.20",
|
||||
"eslint": "^9.8.0",
|
||||
"eslint-plugin-react": "^7.35.0",
|
||||
"eslint-plugin-react-hooks": "^5.1.0-rc.0",
|
||||
"eslint-plugin-react-refresh": "^0.4.9",
|
||||
"globals": "^15.9.0",
|
||||
"postcss": "^8.4.49",
|
||||
"tailwindcss": "^3.4.15",
|
||||
"vite": "^5.4.0"
|
||||
"@eslint/js": "^9.39.1",
|
||||
"@tailwindcss/postcss": "^4.1.18",
|
||||
"@types/react": "^19.2.5",
|
||||
"@types/react-dom": "^19.2.3",
|
||||
"@vitejs/plugin-react": "^5.1.1",
|
||||
"autoprefixer": "^10.4.23",
|
||||
"eslint": "^9.39.1",
|
||||
"eslint-plugin-react-hooks": "^7.0.1",
|
||||
"eslint-plugin-react-refresh": "^0.4.24",
|
||||
"globals": "^16.5.0",
|
||||
"postcss": "^8.5.6",
|
||||
"tailwindcss": "^4.1.18",
|
||||
"vite": "^7.2.4"
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
export default {
|
||||
plugins: {
|
||||
tailwindcss: {},
|
||||
'@tailwindcss/postcss': {},
|
||||
autoprefixer: {},
|
||||
},
|
||||
}
|
||||
|
Before Width: | Height: | Size: 30 KiB |
|
Before Width: | Height: | Size: 14 KiB |
@@ -1,22 +1,44 @@
|
||||
@tailwind base;
|
||||
@tailwind components;
|
||||
@tailwind utilities;
|
||||
#root {
|
||||
max-width: 1280px;
|
||||
margin: 0 auto;
|
||||
padding: 2rem;
|
||||
text-align: center;
|
||||
}
|
||||
html {
|
||||
scroll-behavior: smooth;
|
||||
}
|
||||
.logo {
|
||||
height: 6em;
|
||||
padding: 1.5em;
|
||||
will-change: filter;
|
||||
transition: filter 300ms;
|
||||
}
|
||||
.logo:hover {
|
||||
filter: drop-shadow(0 0 2em #646cffaa);
|
||||
}
|
||||
.logo.react:hover {
|
||||
filter: drop-shadow(0 0 2em #61dafbaa);
|
||||
}
|
||||
|
||||
.custom-background {
|
||||
min-height: 100vh; /* Equivale a min-h-screen en Tailwind */
|
||||
background-size: cover; /* bg-cover */
|
||||
background-position: center; /* bg-center */
|
||||
background-image: url('../public/colage-tess.jpeg'); /* Imagen de fondo */
|
||||
@keyframes logo-spin {
|
||||
from {
|
||||
transform: rotate(0deg);
|
||||
}
|
||||
to {
|
||||
transform: rotate(360deg);
|
||||
}
|
||||
}
|
||||
|
||||
@media (prefers-reduced-motion: no-preference) {
|
||||
a:nth-of-type(2) .logo {
|
||||
animation: logo-spin infinite 20s linear;
|
||||
}
|
||||
}
|
||||
|
||||
.card {
|
||||
padding: 2em;
|
||||
}
|
||||
|
||||
.styleCard {
|
||||
z-index: 10;
|
||||
background: rgba(255, 255, 255, 0.3); /* Fondo blanco con transparencia */
|
||||
backdrop-filter: blur(10px); /* Efecto de desenfoque */
|
||||
-webkit-backdrop-filter: blur(10px); /* Soporte para Safari */
|
||||
border-radius: 2rem; /* Bordes redondeados */
|
||||
border: 1px solid rgba(255, 255, 255, 0.2); /* Borde translúcido */
|
||||
box-shadow: 0 8px 32px rgba(0, 0, 0, 0.25); /* Sombra para profundidad */
|
||||
.read-the-docs {
|
||||
color: #888;
|
||||
}
|
||||
|
||||
@@ -1,157 +1,37 @@
|
||||
import { useState } from 'react'
|
||||
import { Dialog, DialogPanel } from '@headlessui/react'
|
||||
import { Bars3Icon, XMarkIcon } from '@heroicons/react/24/outline'
|
||||
import './App.css'
|
||||
|
||||
const navigation = [
|
||||
{ name: 'Product', href: '1' },
|
||||
{ name: 'Features', href: '2' },
|
||||
{ name: 'Marketplace', href: '3' },
|
||||
{ name: 'Company', href: '4' },
|
||||
]
|
||||
|
||||
import Navbar from "./components/Navbar";
|
||||
import Hero from "./components/Hero";
|
||||
import About from "./components/About";
|
||||
import Work from "./components/Work";
|
||||
import Services from "./components/Services";
|
||||
import Solutions from "./components/Solutions";
|
||||
import Clients from "./components/Clients";
|
||||
import Contact from "./components/Contact";
|
||||
import Footer from "./components/Footer";
|
||||
import React, { useState } from "react";
|
||||
import { AnimatePresence } from "framer-motion";
|
||||
function App() {
|
||||
const [isContactOpen, setIsContactOpen] = useState(false);
|
||||
|
||||
const toggleContact = () => setIsContactOpen(!isContactOpen);
|
||||
|
||||
const [mobileMenuOpen, setMobileMenuOpen] = useState(false)
|
||||
return (
|
||||
<>
|
||||
<div className="custom-background backdrop-blur-sm h-screen w-screen overflow-auto">
|
||||
<header className="absolute inset-x-0 top-0 z-50">
|
||||
<nav aria-label="Global" className="flex items-center justify-between p-6 lg:px-8">
|
||||
<div className="flex lg:flex-1">
|
||||
<a href="1" className="-m-1.5 p-1.5">
|
||||
<span className="sr-only">Your Company</span>
|
||||
<img
|
||||
alt=""
|
||||
src="../public/logotess.png"
|
||||
className="h-8 w-auto"
|
||||
/>
|
||||
</a>
|
||||
<span className="ml-4 text-3xl leading-8 font-semibold text-blue hover:text-blue/50 transition">
|
||||
TESS
|
||||
</span>
|
||||
</div>
|
||||
<div className="flex lg:hidden">
|
||||
<button
|
||||
type="button"
|
||||
onClick={() => setMobileMenuOpen(true)}
|
||||
className="-m-2.5 inline-flex items-center justify-center rounded-md p-2.5 text-gray-700"
|
||||
>
|
||||
<span className="sr-only">Open main menu</span>
|
||||
<Bars3Icon aria-hidden="true" className="size-6" />
|
||||
</button>
|
||||
</div>
|
||||
<div className="hidden lg:flex lg:gap-x-12">
|
||||
{navigation.map((item) => (
|
||||
<a key={item.name} href={item.href} className="text-sm/6 font-semibold text-gray-900">
|
||||
{item.name}
|
||||
</a>
|
||||
))}
|
||||
</div>
|
||||
<div className="hidden lg:flex lg:flex-1 lg:justify-end">
|
||||
<a href="#" className="text-sm/6 font-semibold text-gray-900">
|
||||
Log in <span aria-hidden="true">→</span>
|
||||
</a>
|
||||
</div>
|
||||
</nav>
|
||||
<Dialog open={mobileMenuOpen} onClose={setMobileMenuOpen} className="lg:hidden">
|
||||
<div className="fixed inset-0 z-50" />
|
||||
<DialogPanel className="fixed inset-y-0 right-0 z-50 w-full overflow-y-auto bg-white px-6 py-6 sm:max-w-sm sm:ring-1 sm:ring-gray-900/10">
|
||||
<div className="flex items-center justify-between">
|
||||
<a href="2" className="-m-1.5 p-1.5">
|
||||
<span className="sr-only">Your Company</span>
|
||||
<img
|
||||
alt=""
|
||||
src="../public/logotess.png"
|
||||
className="h-8 w-auto"
|
||||
/>
|
||||
</a>
|
||||
<button
|
||||
type="button"
|
||||
onClick={() => setMobileMenuOpen(false)}
|
||||
className="-m-2.5 rounded-md p-2.5 text-gray-700"
|
||||
>
|
||||
<span className="sr-only">Close menu</span>
|
||||
<XMarkIcon aria-hidden="true" className="size-6" />
|
||||
</button>
|
||||
</div>
|
||||
<div className="mt-6 flow-root">
|
||||
<div className="-my-6 divide-y divide-gray-500/10">
|
||||
<div className="space-y-2 py-6">
|
||||
{navigation.map((item) => (
|
||||
<a
|
||||
key={item.name}
|
||||
href={item.href}
|
||||
className="-mx-3 block rounded-lg px-3 py-2 text-base/7 font-semibold text-gray-900 hover:bg-gray-50"
|
||||
>
|
||||
{item.name}
|
||||
</a>
|
||||
))}
|
||||
</div>
|
||||
<div className="py-6">
|
||||
<a
|
||||
href="3"
|
||||
className="-mx-3 block rounded-lg px-3 py-2.5 text-base/7 font-semibold text-gray-900 hover:bg-gray-50"
|
||||
>
|
||||
Log in
|
||||
</a>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</DialogPanel>
|
||||
</Dialog>
|
||||
</header>
|
||||
|
||||
<div className="relative isolate px-6 pt-14 lg:px-8">
|
||||
<div
|
||||
aria-hidden="true"
|
||||
className="absolute inset-x-0 -top-40 -z-10 transform-gpu overflow-hidden blur-3xl sm:-top-80"
|
||||
>
|
||||
|
||||
</div>
|
||||
<div className="margin- mx-auto max-w-2xl py-32 sm:py-48 lg:py-56 z-10 bg-white/50 backdrop-blur-lg rounded-2xl border border-white/20 shadow-2xl p-6">
|
||||
<div className="hidden sm:mb-8 sm:flex sm:justify-center">
|
||||
<div className="relative rounded-full px-3 py-1 text-sm/6 text-gray-600 ring-1 ring-gray-900/10 hover:ring-gray-900/20">
|
||||
Announcing our next round of funding.{' '}
|
||||
<a href="1" className="font-semibold text-blue-600">
|
||||
<span aria-hidden="true" className="absolute inset-0" />
|
||||
Read more <span aria-hidden="true">→</span>
|
||||
</a>
|
||||
</div>
|
||||
</div>
|
||||
<div className="text-center">
|
||||
<h1 className="text-center text-5xl font-semibold tracking-tight sm:text-7xl text-blue hover:text-blue/50 transition duration-300">
|
||||
Technology Enterprise Support System
|
||||
</h1>
|
||||
<div>
|
||||
<p className="mt-8 text-pretty text-lg font-medium text-gray-500 sm:text-xl/8 justify-center">
|
||||
Potenciamos su empresa con soluciones tecnológicas a medida. Ofrecemos consultoría especializada en optimización de procesos, implementación de TI y desarrollo de software para impulsar la eficiencia y el crecimiento de su negocio.
|
||||
</p>
|
||||
</div>
|
||||
<div className="mt-10 flex items-center justify-center gap-x-6">
|
||||
<a
|
||||
href="2"
|
||||
className="rounded-md bg-blue px-3.5 py-2.5 text-sm font-semibold text-white shadow-sm hover:bg-blue/75 focus-visible:outline focus-visible:outline-2 focus-visible:outline-offset-2 focus-visible:outline-indigo"
|
||||
>
|
||||
Get started
|
||||
</a>
|
||||
<a href="3" className="rounded-full bg-white/5 outline px-3.5 py-2.5 text-sm font-semibold text-black shadow-sm hover:bg-white/25 transition duration-150 focus-visible:outline focus-visible:outline-2 focus-visible:outline-offset-2 focus-visible:outline-indigo">
|
||||
Learn more <span aria-hidden="true">→</span>
|
||||
</a>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div
|
||||
aria-hidden="true"
|
||||
className="absolute inset-x-0 top-[calc(100%-13rem)] -z-10 transform-gpu overflow-hidden blur-3xl sm:top-[calc(100%-30rem)]"
|
||||
>
|
||||
|
||||
</div>
|
||||
</div>
|
||||
<div className="min-h-screen bg-black text-white">
|
||||
<Navbar onContactClick={toggleContact} />
|
||||
<AnimatePresence>
|
||||
{isContactOpen && <Contact onClose={toggleContact} />}
|
||||
</AnimatePresence>
|
||||
<main>
|
||||
<Hero />
|
||||
<About />
|
||||
<Work onOpenContact={toggleContact} />
|
||||
<Services />
|
||||
<Solutions />
|
||||
<Clients />
|
||||
</main>
|
||||
{isContactOpen && <Contact onClose={toggleContact} />}
|
||||
<Footer />
|
||||
</div>
|
||||
</>
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
export default App
|
||||
|
||||
export default App;
|
||||
|
||||
|
After Width: | Height: | Size: 1.6 MiB |
|
After Width: | Height: | Size: 28 KiB |
|
After Width: | Height: | Size: 12 KiB |
|
After Width: | Height: | Size: 521 KiB |
|
After Width: | Height: | Size: 25 KiB |
|
After Width: | Height: | Size: 26 KiB |
|
After Width: | Height: | Size: 10 KiB |
|
After Width: | Height: | Size: 48 KiB |
|
After Width: | Height: | Size: 5.6 MiB |
|
After Width: | Height: | Size: 5.8 MiB |
|
After Width: | Height: | Size: 8.3 KiB |
|
After Width: | Height: | Size: 11 KiB |
|
After Width: | Height: | Size: 3.6 MiB |
|
Before Width: | Height: | Size: 31 KiB |
|
Before Width: | Height: | Size: 14 KiB After Width: | Height: | Size: 32 KiB |
@@ -0,0 +1 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" aria-hidden="true" role="img" class="iconify iconify--logos" width="35.93" height="32" preserveAspectRatio="xMidYMid meet" viewBox="0 0 256 228"><path fill="#00D8FF" d="M210.483 73.824a171.49 171.49 0 0 0-8.24-2.597c.465-1.9.893-3.777 1.273-5.621c6.238-30.281 2.16-54.676-11.769-62.708c-13.355-7.7-35.196.329-57.254 19.526a171.23 171.23 0 0 0-6.375 5.848a155.866 155.866 0 0 0-4.241-3.917C100.759 3.829 77.587-4.822 63.673 3.233C50.33 10.957 46.379 33.89 51.995 62.588a170.974 170.974 0 0 0 1.892 8.48c-3.28.932-6.445 1.924-9.474 2.98C17.309 83.498 0 98.307 0 113.668c0 15.865 18.582 31.778 46.812 41.427a145.52 145.52 0 0 0 6.921 2.165a167.467 167.467 0 0 0-2.01 9.138c-5.354 28.2-1.173 50.591 12.134 58.266c13.744 7.926 36.812-.22 59.273-19.855a145.567 145.567 0 0 0 5.342-4.923a168.064 168.064 0 0 0 6.92 6.314c21.758 18.722 43.246 26.282 56.54 18.586c13.731-7.949 18.194-32.003 12.4-61.268a145.016 145.016 0 0 0-1.535-6.842c1.62-.48 3.21-.974 4.76-1.488c29.348-9.723 48.443-25.443 48.443-41.52c0-15.417-17.868-30.326-45.517-39.844Zm-6.365 70.984c-1.4.463-2.836.91-4.3 1.345c-3.24-10.257-7.612-21.163-12.963-32.432c5.106-11 9.31-21.767 12.459-31.957c2.619.758 5.16 1.557 7.61 2.4c23.69 8.156 38.14 20.213 38.14 29.504c0 9.896-15.606 22.743-40.946 31.14Zm-10.514 20.834c2.562 12.94 2.927 24.64 1.23 33.787c-1.524 8.219-4.59 13.698-8.382 15.893c-8.067 4.67-25.32-1.4-43.927-17.412a156.726 156.726 0 0 1-6.437-5.87c7.214-7.889 14.423-17.06 21.459-27.246c12.376-1.098 24.068-2.894 34.671-5.345a134.17 134.17 0 0 1 1.386 6.193ZM87.276 214.515c-7.882 2.783-14.16 2.863-17.955.675c-8.075-4.657-11.432-22.636-6.853-46.752a156.923 156.923 0 0 1 1.869-8.499c10.486 2.32 22.093 3.988 34.498 4.994c7.084 9.967 14.501 19.128 21.976 27.15a134.668 134.668 0 0 1-4.877 4.492c-9.933 8.682-19.886 14.842-28.658 17.94ZM50.35 144.747c-12.483-4.267-22.792-9.812-29.858-15.863c-6.35-5.437-9.555-10.836-9.555-15.216c0-9.322 13.897-21.212 37.076-29.293c2.813-.98 5.757-1.905 8.812-2.773c3.204 10.42 7.406 21.315 12.477 32.332c-5.137 11.18-9.399 22.249-12.634 32.792a134.718 134.718 0 0 1-6.318-1.979Zm12.378-84.26c-4.811-24.587-1.616-43.134 6.425-47.789c8.564-4.958 27.502 2.111 47.463 19.835a144.318 144.318 0 0 1 3.841 3.545c-7.438 7.987-14.787 17.08-21.808 26.988c-12.04 1.116-23.565 2.908-34.161 5.309a160.342 160.342 0 0 1-1.76-7.887Zm110.427 27.268a347.8 347.8 0 0 0-7.785-12.803c8.168 1.033 15.994 2.404 23.343 4.08c-2.206 7.072-4.956 14.465-8.193 22.045a381.151 381.151 0 0 0-7.365-13.322Zm-45.032-43.861c5.044 5.465 10.096 11.566 15.065 18.186a322.04 322.04 0 0 0-30.257-.006c4.974-6.559 10.069-12.652 15.192-18.18ZM82.802 87.83a323.167 323.167 0 0 0-7.227 13.238c-3.184-7.553-5.909-14.98-8.134-22.152c7.304-1.634 15.093-2.97 23.209-3.984a321.524 321.524 0 0 0-7.848 12.897Zm8.081 65.352c-8.385-.936-16.291-2.203-23.593-3.793c2.26-7.3 5.045-14.885 8.298-22.6a321.187 321.187 0 0 0 7.257 13.246c2.594 4.48 5.28 8.868 8.038 13.147Zm37.542 31.03c-5.184-5.592-10.354-11.779-15.403-18.433c4.902.192 9.899.29 14.978.29c5.218 0 10.376-.117 15.453-.343c-4.985 6.774-10.018 12.97-15.028 18.486Zm52.198-57.817c3.422 7.8 6.306 15.345 8.596 22.52c-7.422 1.694-15.436 3.058-23.88 4.071a382.417 382.417 0 0 0 7.859-13.026a347.403 347.403 0 0 0 7.425-13.565Zm-16.898 8.101a358.557 358.557 0 0 1-12.281 19.815a329.4 329.4 0 0 1-23.444.823c-7.967 0-15.716-.248-23.178-.732a310.202 310.202 0 0 1-12.513-19.846h.001a307.41 307.41 0 0 1-10.923-20.627a310.278 310.278 0 0 1 10.89-20.637l-.001.001a307.318 307.318 0 0 1 12.413-19.761c7.613-.576 15.42-.876 23.31-.876H128c7.926 0 15.743.303 23.354.883a329.357 329.357 0 0 1 12.335 19.695a358.489 358.489 0 0 1 11.036 20.54a329.472 329.472 0 0 1-11 20.722Zm22.56-122.124c8.572 4.944 11.906 24.881 6.52 51.026c-.344 1.668-.73 3.367-1.15 5.09c-10.622-2.452-22.155-4.275-34.23-5.408c-7.034-10.017-14.323-19.124-21.64-27.008a160.789 160.789 0 0 1 5.888-5.4c18.9-16.447 36.564-22.941 44.612-18.3ZM128 90.808c12.625 0 22.86 10.235 22.86 22.86s-10.235 22.86-22.86 22.86s-22.86-10.235-22.86-22.86s10.235-22.86 22.86-22.86Z"></path></svg>
|
||||
|
Before Width: | Height: | Size: 0 B After Width: | Height: | Size: 4.0 KiB |
|
Before Width: | Height: | Size: 130 KiB |
|
Before Width: | Height: | Size: 140 KiB |
|
Before Width: | Height: | Size: 143 KiB |
|
Before Width: | Height: | Size: 155 KiB |
|
After Width: | Height: | Size: 19 KiB |
|
After Width: | Height: | Size: 1.2 MiB |
|
After Width: | Height: | Size: 1.1 MiB |
|
After Width: | Height: | Size: 22 KiB |
@@ -0,0 +1,95 @@
|
||||
import React from "react";
|
||||
import collageTess from "../assets/colage-tess.jpeg";
|
||||
|
||||
const About = () => {
|
||||
return (
|
||||
<section
|
||||
className="py-20 md:py-24 bg-gradient-to-b from-[#003172] to-[#001430]"
|
||||
id="quienes-somos"
|
||||
>
|
||||
<div className="max-w-7xl mx-auto px-6 lg:px-8">
|
||||
{/* Encabezado */}
|
||||
<div className="text-center mb-10 md:mb-12">
|
||||
<h2 className="text-white font-bold text-sm tracking-[0.3em] uppercase mb-3">
|
||||
SOBRE NOSOTROS
|
||||
</h2>
|
||||
|
||||
<h3 className="text-secondaccent text-3xl sm:text-4xl md:text-5xl font-extrabold tracking-tight">
|
||||
Expertos en evolución digital
|
||||
</h3>
|
||||
</div>
|
||||
|
||||
{/* Imagen + Texto */}
|
||||
<div className="grid lg:grid-cols-2 gap-8 lg:gap-12 items-center mb-12 md:mb-14">
|
||||
<div className="relative drop-shadow-2xl max-w-sm md:max-w-md mx-auto lg:max-w-full">
|
||||
<div className="absolute -inset-3 bg-primary/20 blur-3xl rounded-full"></div>
|
||||
|
||||
<img
|
||||
alt="Tech Consultant workspace"
|
||||
className="relative rounded-3xl shadow-2xl w-full border border-white/10 object-cover"
|
||||
src={collageTess}
|
||||
/>
|
||||
</div>
|
||||
|
||||
<div className="space-y-5">
|
||||
<p className="text-blue-50/90 leading-relaxed text-base sm:text-lg lg:text-xl font-light">
|
||||
En TESS somos una consultora de software y servicios de TI que
|
||||
ayuda a las empresas a diseñar, construir y evolucionar sus
|
||||
soluciones digitales.
|
||||
</p>
|
||||
|
||||
<p className="text-blue-50/90 leading-relaxed text-base sm:text-lg lg:text-xl font-light">
|
||||
Combinamos experiencia en desarrollo de software, arquitectura de
|
||||
sistemas y automatización de procesos para que la tecnología sea
|
||||
el motor de tu negocio.
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{/* Tarjetas */}
|
||||
<div className="grid md:grid-cols-2 gap-6 lg:gap-8">
|
||||
{/* Misión */}
|
||||
<article className="glass-card p-6 lg:p-8 rounded-3xl border border-white/10 hover:border-secondary/30 transition-colors group text-center flex flex-col items-center">
|
||||
<div className="w-12 h-12 bg-secondary/10 rounded-2xl flex items-center justify-center mb-4 group-hover:scale-110 transition-transform">
|
||||
<span className="material-symbols-outlined text-accent text-4xl">
|
||||
target
|
||||
</span>
|
||||
</div>
|
||||
|
||||
<h4 className="text-xl lg:text-2xl font-bold mb-3 text-accent">
|
||||
Nuestra Misión
|
||||
</h4>
|
||||
|
||||
<p className="text-blue-100/70 leading-relaxed font-light text-justify text-sm lg:text-base">
|
||||
Impulsamos el crecimiento de empresas mediante soluciones
|
||||
tecnológicas a medida que resuelven sus desafíos reales. Nos
|
||||
especializamos en desarrollo de software personalizado y servicios
|
||||
de TI adaptados a cada cliente.
|
||||
</p>
|
||||
</article>
|
||||
|
||||
{/* Visión */}
|
||||
<article className="glass-card p-6 lg:p-8 rounded-3xl border border-white/10 hover:border-primary/30 transition-colors group text-center flex flex-col items-center">
|
||||
<div className="w-12 h-12 bg-primary/10 rounded-2xl flex items-center justify-center mb-4 group-hover:scale-110 transition-transform">
|
||||
<span className="material-symbols-outlined text-accent text-4xl">
|
||||
lightbulb
|
||||
</span>
|
||||
</div>
|
||||
|
||||
<h4 className="text-xl lg:text-2xl font-bold mb-3 text-accent">
|
||||
Nuestra Visión
|
||||
</h4>
|
||||
|
||||
<p className="text-blue-100/70 leading-relaxed font-light text-justify text-sm lg:text-base">
|
||||
Ser reconocidos como un referente en soluciones tecnológicas
|
||||
personalizadas en Latinoamérica, destacando por innovación,
|
||||
calidad humana y resultados tangibles para nuestros clientes.
|
||||
</p>
|
||||
</article>
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
);
|
||||
};
|
||||
|
||||
export default About;
|
||||
@@ -0,0 +1,262 @@
|
||||
import React, { useState } from "react";
|
||||
import Marquee from "react-fast-marquee";
|
||||
import { motion, AnimatePresence } from "framer-motion";
|
||||
|
||||
import logo1 from "../assets/cl-1.png";
|
||||
import logo2 from "../assets/cl-2.png";
|
||||
import logo3 from "../assets/cl-3.jpeg";
|
||||
import logo5 from "../assets/cl-5.png";
|
||||
|
||||
const successCases = [
|
||||
{
|
||||
id: 1,
|
||||
name: "Hazard",
|
||||
logo: logo1,
|
||||
challenge:
|
||||
"Necesidad de gestión delegada para infraestructura TI, hosting y correos empresariales.",
|
||||
solution:
|
||||
"Soporte TI integral y administración completa de servidores y correos TESS.",
|
||||
result:
|
||||
"Operación continua sin interrupciones técnicas y comunicación empresarial estable.",
|
||||
},
|
||||
{
|
||||
id: 2,
|
||||
name: "Vital Care",
|
||||
logo: logo2,
|
||||
challenge:
|
||||
"Requerimiento de una aplicación médica especializada y soporte técnico concurrente para equipos.",
|
||||
solution:
|
||||
"Desarrollo de App a la medida para doctores + Soporte TI y Hosting TESS.",
|
||||
result:
|
||||
"Optimización de consultas médicas y resolución inmediata de incidencias en equipos de cómputo.",
|
||||
},
|
||||
{
|
||||
id: 3,
|
||||
name: "Clínicas de la Frontera",
|
||||
logo: logo3,
|
||||
challenge:
|
||||
"Gestión ineficiente de infraestructura tecnológica y comunicación.",
|
||||
solution: "Póliza de soporte TI y migración a Hosting y Correo TESS.",
|
||||
result:
|
||||
"Modernización tecnológica y alta disponibilidad en todos sus canales de comunicación.",
|
||||
},
|
||||
{
|
||||
id: 5,
|
||||
name: "TRIMAPE",
|
||||
logo: logo5,
|
||||
challenge:
|
||||
"Control descentralizado en el mantenimiento de equipos industriales.",
|
||||
solution:
|
||||
"Desarrollo e implementación de TESS-ERP adaptado a sus procesos industriales.",
|
||||
result:
|
||||
"Trazabilidad total en mantenimientos y mejora sustancial en la logística operativa.",
|
||||
},
|
||||
];
|
||||
|
||||
const Clients = () => {
|
||||
const logos = [
|
||||
{ name: "Hazard", src: logo1 },
|
||||
{ name: "Vital Care", src: logo2 },
|
||||
{ name: "Clínicas de la Frontera", src: logo3 },
|
||||
{ name: "TRIMAPE", src: logo5 },
|
||||
];
|
||||
|
||||
const [activeCase, setActiveCase] = useState(successCases[0].id);
|
||||
|
||||
return (
|
||||
<section
|
||||
className="py-20 md:py-24 bg-brand-dark bg-gradient-to-b from-[#020617] to-[#000000] overflow-hidden"
|
||||
id="clientes"
|
||||
>
|
||||
<div className="max-w-7xl mx-auto px-6 lg:px-8 text-center mb-10 md:mb-12">
|
||||
<h2
|
||||
className="text-secondary tracking-tight text-white mb-3 text-3xl font-bold md:text-4xl"
|
||||
id="services-subtitle"
|
||||
>
|
||||
Nuestros Casos de Éxito
|
||||
</h2>
|
||||
<p className="max-w-2xl mx-auto text-brand-light text-base md:text-lg leading-relaxed font-light text-justify md:text-center mt-4">
|
||||
Empresas de distintos sectores confían en TESS para resolver sus retos
|
||||
tecnológicos y acelerar su crecimiento.
|
||||
</p>
|
||||
</div>
|
||||
|
||||
{/* Carrusel usando React Fast Marquee */}
|
||||
<div className="max-w-7xl mx-auto px-6 lg:px-8 mb-24 relative">
|
||||
{/* Usamos gradientColors usando formato rgb para overlayar en el fondo oscuro (#020617) */}
|
||||
<Marquee
|
||||
gradient={true}
|
||||
gradientColor={[2, 6, 23]}
|
||||
gradientWidth={100}
|
||||
speed={40}
|
||||
pauseOnHover={true}
|
||||
autoFill={true}
|
||||
className="flex items-center"
|
||||
>
|
||||
{logos.map((client, index) => (
|
||||
<div
|
||||
key={index}
|
||||
className="flex-none mx-14"
|
||||
>
|
||||
<img
|
||||
src={client.src}
|
||||
alt={client.name}
|
||||
className="h-11 md:h-12 w-auto object-contain"
|
||||
/>
|
||||
</div>
|
||||
))}
|
||||
</Marquee>
|
||||
</div>
|
||||
|
||||
{/* Sección Interactiva de Casos de Éxito */}
|
||||
<div className="max-w-7xl mx-auto px-6 lg:px-8 relative z-10">
|
||||
<div className="grid grid-cols-1 lg:grid-cols-12 gap-8 lg:gap-12">
|
||||
{/* Lista de Selección */}
|
||||
<div className="col-span-1 lg:col-span-4 flex flex-col gap-3">
|
||||
{successCases.map((story) => (
|
||||
<button
|
||||
key={story.id}
|
||||
onClick={() => setActiveCase(story.id)}
|
||||
className={`text-left p-5 rounded-xl transition-all duration-300 border ${
|
||||
activeCase === story.id
|
||||
? "bg-primary/20 border-secondaccent/50 shadow-[0_0_20px_rgba(12,192,223,0.15)]"
|
||||
: "bg-brand-dark border-white/10 hover:bg-white/5 hover:border-white/20"
|
||||
}`}
|
||||
>
|
||||
<div className="flex items-center gap-4">
|
||||
<div
|
||||
className={`w-12 h-12 rounded-lg flex items-center justify-center p-2 bg-white ${activeCase === story.id ? "opacity-100 shadow-[0_0_10px_rgba(100,255,218,0.5)]" : "opacity-70 grayscale"}`}
|
||||
>
|
||||
<img
|
||||
src={story.logo}
|
||||
alt={story.name}
|
||||
className="max-h-full max-w-full object-contain"
|
||||
/>
|
||||
</div>
|
||||
<div>
|
||||
<h4
|
||||
className={`font-semibold ${activeCase === story.id ? "text-accent" : "text-brand-light"}`}
|
||||
>
|
||||
{story.name}
|
||||
</h4>
|
||||
<p className="text-sm text-brand-light/60">
|
||||
Ver caso completo →
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
</button>
|
||||
))}
|
||||
</div>
|
||||
|
||||
{/* Panel de Detalles (Contenido Cambiante) */}
|
||||
<div className="col-span-1 lg:col-span-8 bg-primary/20 border border-white/10 rounded-2xl p-6 md:p-10 relative overflow-hidden flex flex-col justify-center min-h-[400px]">
|
||||
{/* Background glow para el caso activo */}
|
||||
<div className="absolute top-0 right-0 w-[300px] h-[300px] bg-accent/10 blur-[100px] rounded-full"></div>
|
||||
|
||||
<AnimatePresence mode="wait">
|
||||
{successCases.map(
|
||||
(story) =>
|
||||
story.id === activeCase && (
|
||||
<motion.div
|
||||
key={story.id}
|
||||
initial={{ opacity: 0, y: 15 }}
|
||||
animate={{ opacity: 1, y: 0 }}
|
||||
exit={{ opacity: 0, y: -15 }}
|
||||
transition={{ duration: 0.4 }}
|
||||
className="relative z-10 h-full flex flex-col justify-center"
|
||||
>
|
||||
<div className="grid grid-cols-1 md:grid-cols-2 gap-8 md:gap-12">
|
||||
{/* Columna Izquierda (Reto y Solución) */}
|
||||
<div className="space-y-8">
|
||||
<div>
|
||||
<div className="flex items-center gap-3 mb-3">
|
||||
<div className="w-8 h-8 rounded-full bg-red-400/20 text-red-400 flex items-center justify-center">
|
||||
<svg
|
||||
className="w-4 h-4"
|
||||
fill="none"
|
||||
viewBox="0 0 24 24"
|
||||
stroke="currentColor"
|
||||
>
|
||||
<path
|
||||
strokeLinecap="round"
|
||||
strokeLinejoin="round"
|
||||
strokeWidth="2"
|
||||
d="M12 9v2m0 4h.01m-6.938 4h13.856c1.54 0 2.502-1.667 1.732-3L13.732 4c-.77-1.333-2.694-1.333-3.464 0L3.34 16c-.77 1.333.192 3 1.732 3z"
|
||||
/>
|
||||
</svg>
|
||||
</div>
|
||||
<h4 className="text-brand-light/70 font-medium uppercase tracking-wider text-sm">
|
||||
El Reto
|
||||
</h4>
|
||||
</div>
|
||||
<p className="text-brand-light text-lg leading-relaxed">
|
||||
{story.challenge}
|
||||
</p>
|
||||
</div>
|
||||
|
||||
<div>
|
||||
<div className="flex items-center gap-3 mb-3">
|
||||
<div className="w-8 h-8 rounded-full bg-accent/20 text-accent flex items-center justify-center">
|
||||
<svg
|
||||
className="w-4 h-4"
|
||||
fill="none"
|
||||
viewBox="0 0 24 24"
|
||||
stroke="currentColor"
|
||||
>
|
||||
<path
|
||||
strokeLinecap="round"
|
||||
strokeLinejoin="round"
|
||||
strokeWidth="2"
|
||||
d="M13 10V3L4 14h7v7l9-11h-7z"
|
||||
/>
|
||||
</svg>
|
||||
</div>
|
||||
<h4 className="text-brand-light/70 font-medium uppercase tracking-wider text-sm">
|
||||
Nuestra Solución
|
||||
</h4>
|
||||
</div>
|
||||
<p className="text-brand-light text-lg leading-relaxed">
|
||||
{story.solution}
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{/* Columna Derecha (Resultado) */}
|
||||
<div className="bg-gradient-to-br from-primary/60 to-brand-dark/80 border border-primary/40 rounded-xl p-6 md:p-8 flex flex-col justify-center border-t-4 border-t-secondaccent">
|
||||
<div className="flex items-center gap-3 mb-4">
|
||||
<div className="w-8 h-8 rounded-full bg-secondaccent/20 text-secondaccent flex items-center justify-center">
|
||||
<svg
|
||||
className="w-4 h-4"
|
||||
fill="none"
|
||||
viewBox="0 0 24 24"
|
||||
stroke="currentColor"
|
||||
>
|
||||
<path
|
||||
strokeLinecap="round"
|
||||
strokeLinejoin="round"
|
||||
strokeWidth="2"
|
||||
d="M9 12l2 2 4-4m6 2a9 9 0 11-18 0 9 9 0 0118 0z"
|
||||
/>
|
||||
</svg>
|
||||
</div>
|
||||
<h4 className="text-secondaccent font-semibold uppercase tracking-wider text-sm">
|
||||
Impacto / Resultado
|
||||
</h4>
|
||||
</div>
|
||||
<p className="text-white text-xl md:text-2xl font-light leading-relaxed">
|
||||
"{story.result}"
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
</motion.div>
|
||||
),
|
||||
)}
|
||||
</AnimatePresence>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
);
|
||||
};
|
||||
|
||||
export default Clients;
|
||||
@@ -0,0 +1,189 @@
|
||||
import { useState } from "react";
|
||||
import { motion } from "framer-motion";
|
||||
{
|
||||
/**modal de contacto */
|
||||
}
|
||||
const Contact = ({ onClose }) => {
|
||||
const [formData, setFormData] = useState({
|
||||
nombre: "",
|
||||
email: "",
|
||||
mensaje: "",
|
||||
});
|
||||
const [isSubmitting, setIsSubmitting] = useState(false);
|
||||
const [status, setStatus] = useState(""); // 'success' | 'error' | ''
|
||||
|
||||
const handleChange = (e) => {
|
||||
setFormData({ ...formData, [e.target.name]: e.target.value });
|
||||
};
|
||||
|
||||
const handleSubmit = async (e) => {
|
||||
e.preventDefault();
|
||||
setIsSubmitting(true);
|
||||
setStatus("");
|
||||
|
||||
try {
|
||||
const response = await fetch("https://api.tesscorp.com.mx/api/contact", {
|
||||
method: "POST",
|
||||
headers: {
|
||||
"Content-Type": "application/json",
|
||||
},
|
||||
body: JSON.stringify(formData),
|
||||
});
|
||||
|
||||
if (response.ok) {
|
||||
setStatus("success");
|
||||
setFormData({ nombre: "", email: "", mensaje: "" });
|
||||
} else {
|
||||
setStatus("error");
|
||||
}
|
||||
} catch (error) {
|
||||
console.error("Error enviando el formulario:", error);
|
||||
setStatus("error");
|
||||
} finally {
|
||||
setIsSubmitting(false);
|
||||
}
|
||||
};
|
||||
return (
|
||||
<div className="fixed inset-0 z-[100] flex items-center justify-center p-4">
|
||||
<motion.div
|
||||
initial={{ opacity: 0 }}
|
||||
animate={{ opacity: 1 }}
|
||||
exit={{ opacity: 0 }}
|
||||
onClick={onClose}
|
||||
className="absolute inset-0 bg-black/10 backdrop-blur-sm"
|
||||
/>
|
||||
|
||||
{/* El Contenedor del Formulario (Modal) */}
|
||||
<motion.div
|
||||
initial={{ opacity: 0, scale: 0.9, y: 20 }}
|
||||
animate={{ opacity: 1, scale: 1, y: 0 }}
|
||||
exit={{ opacity: 0, scale: 0.9, y: 20 }}
|
||||
className="relative w-full max-w-2xl bg-white/5 backdrop-blur-2xl p-8 md:p-12 rounded-[2rem] border border-white/20 shadow-2xl z-10 overflow-y-auto max-h-[90vh]"
|
||||
>
|
||||
{/* Botón para cerrar (X) */}
|
||||
<button
|
||||
onClick={onClose}
|
||||
className="absolute top-6 right-6 text-white/50 hover:text-[#0cc0df] transition-colors"
|
||||
>
|
||||
<span className="material-symbols-outlined text-3xl">close</span>
|
||||
</button>
|
||||
|
||||
<div className="text-center mb-10">
|
||||
<h2 className="text-white text-2xl md:text-3xl font-bold mb-2">
|
||||
Ponte en contacto
|
||||
</h2>
|
||||
<p className="text-white/80 text-sm md:text-base font-light">
|
||||
¿Tienes un proyecto en mente? Hagámoslo realidad juntos.
|
||||
</p>
|
||||
</div>
|
||||
|
||||
<form onSubmit={handleSubmit} className="space-y-6">
|
||||
{/* Campo Nombre */}
|
||||
<div>
|
||||
<label
|
||||
htmlFor="nombre"
|
||||
className="block text-sm font-medium text-white mb-2"
|
||||
>
|
||||
Nombre Completo
|
||||
</label>
|
||||
<input
|
||||
type="text"
|
||||
id="nombre"
|
||||
name="nombre"
|
||||
required
|
||||
value={formData.nombre}
|
||||
onChange={handleChange}
|
||||
className="w-full bg-white/10 backdrop-blur-md border border-white/20 rounded-xl px-4 py-3 text-white placeholder-white/50 focus:outline-none focus:ring-2 focus:ring-emerald-400/50 focus:border-emerald-400 transition-all duration-300"
|
||||
placeholder="Tu nombre..."
|
||||
/>
|
||||
</div>
|
||||
|
||||
{/* Campo Email */}
|
||||
<div>
|
||||
<label
|
||||
htmlFor="email"
|
||||
className="flex items-center gap-2 text-sm font-medium text-white mb-2"
|
||||
>
|
||||
<span className="material-symbols-outlined text-base">mail</span>
|
||||
Correo Electrónico
|
||||
</label>
|
||||
<input
|
||||
type="email"
|
||||
id="email"
|
||||
name="email"
|
||||
required
|
||||
value={formData.email}
|
||||
onChange={handleChange}
|
||||
className="w-full bg-white/10 backdrop-blur-md border border-white/20 rounded-xl px-4 py-3 text-white placeholder-white/50 focus:outline-none focus:ring-2 focus:ring-emerald-400/50 focus:border-emerald-400 transition-all duration-300"
|
||||
placeholder="tu@email.com"
|
||||
/>
|
||||
</div>
|
||||
|
||||
{/* Campo Mensaje */}
|
||||
<div>
|
||||
<label
|
||||
htmlFor="mensaje"
|
||||
className="flex items-center gap-2 text-sm font-medium text-white mb-2"
|
||||
>
|
||||
<span className="material-symbols-outlined text-base">chat</span>
|
||||
Mensaje
|
||||
</label>
|
||||
<textarea
|
||||
id="mensaje"
|
||||
name="mensaje"
|
||||
rows="4"
|
||||
required
|
||||
value={formData.mensaje}
|
||||
onChange={handleChange}
|
||||
className="w-full bg-white/10 backdrop-blur-md border border-white/20 rounded-xl px-4 py-3 text-white placeholder-white/50 focus:outline-none focus:ring-2 focus:ring-emerald-400/50 focus:border-emerald-400 transition-all duration-300 resize-none"
|
||||
placeholder="¿En qué podemos ayudarte?"
|
||||
></textarea>
|
||||
</div>
|
||||
{/* Mensajes de estado */}
|
||||
<div aria-live="polite" className="contents">
|
||||
{status === "success" && (
|
||||
<div className="p-4 bg-green-500/20 border border-green-500/50 rounded-xl text-green-200 text-center">
|
||||
¡Mensaje enviado con éxito! Nos pondremos en contacto contigo
|
||||
pronto.
|
||||
</div>
|
||||
)}
|
||||
{status === "error" && (
|
||||
<div className="p-4 bg-red-500/20 border border-red-500/50 rounded-xl text-red-200 text-center">
|
||||
Hubo un error al enviar el mensaje. Por favor, inténtalo de
|
||||
nuevo más tarde o contáctanos por WhatsApp.
|
||||
</div>
|
||||
)}
|
||||
</div>
|
||||
|
||||
<button
|
||||
type="submit"
|
||||
disabled={isSubmitting}
|
||||
className={`w-full text-white font-bold py-4 rounded-xl transition-all transform hover:scale-[1.01] active:scale-[0.98] shadow-lg shadow-cyan-500/25 ${
|
||||
isSubmitting
|
||||
? "opacity-70 cursor-not-allowed bg-gradient-to-r from-emerald-400 to-cyan-500"
|
||||
: "bg-gradient-to-r from-emerald-400 to-cyan-500 hover:from-emerald-500 hover:to-cyan-600"
|
||||
}`}
|
||||
>
|
||||
{isSubmitting ? "Enviando..." : "Enviar Mensaje"}
|
||||
</button>
|
||||
|
||||
{/* Opción de WhatsApp */}
|
||||
<div className="flex flex-col sm:flex-row items-center justify-center gap-3 pt-6 border-t border-white/10">
|
||||
<span className="text-white/80 text-sm">O comunícate de forma directa vía</span>
|
||||
<a
|
||||
href="https://wa.me/522292565108"
|
||||
target="_blank"
|
||||
rel="noopener noreferrer"
|
||||
className="flex items-center gap-2 text-white bg-[#25D366] hover:bg-[#1da851] px-6 py-2.5 rounded-xl transition-all transform hover:scale-105 shadow-lg shadow-[#25D366]/30 font-bold text-sm"
|
||||
>
|
||||
<i className="fa-brands fa-whatsapp text-xl"></i>
|
||||
WhatsApp
|
||||
</a>
|
||||
</div>
|
||||
</form>
|
||||
</motion.div>
|
||||
</div>
|
||||
);
|
||||
};
|
||||
|
||||
export default Contact;
|
||||
@@ -0,0 +1,137 @@
|
||||
import logoTess from "../assets/logotesspng.png";
|
||||
|
||||
const Footer = () => {
|
||||
const currentYear = new Date().getFullYear();
|
||||
|
||||
return (
|
||||
<footer className="bg-black border-t border-white/5 pt-16 pb-8">
|
||||
<div className="max-w-7xl mx-auto px-6 lg:px-8">
|
||||
<div className="grid grid-cols-1 md:grid-cols-3 gap-12 mb-16">
|
||||
{/* Identidad */}
|
||||
<div className="space-y-6">
|
||||
<div className="flex items-center">
|
||||
<div className="w-48 sm:w-56">
|
||||
<img
|
||||
src={logoTess}
|
||||
alt="TESS Logo"
|
||||
className="w-full h-auto object-contain object-left"
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
<p className="text-white text-sm leading-relaxed max-w-xs">
|
||||
Impulsando la transformación digital con soluciones tecnológicas a
|
||||
medida y estrategias de alto impacto.
|
||||
</p>
|
||||
</div>
|
||||
|
||||
{/* Navegación con Iconos */}
|
||||
<div className="flex flex-col gap-6">
|
||||
<h3 className="text-white font-bold text-lg uppercase tracking-widest text-sm">
|
||||
Navegación
|
||||
</h3>
|
||||
<ul className="space-y-4">
|
||||
{[
|
||||
{ name: "Quienes somos", href: "#quienes-somos", icon: "info" },
|
||||
{
|
||||
name: "Nuestro Trabajo",
|
||||
href: "#nuestro-trabajo",
|
||||
icon: "terminal",
|
||||
},
|
||||
{ name: "Servicios", href: "#servicios", icon: "settings" },
|
||||
{ name: "Clientes", href: "#clientes", icon: "group" },
|
||||
].map((link) => (
|
||||
<li key={link.name}>
|
||||
<a
|
||||
href={link.href}
|
||||
className="group flex items-center gap-3 text-white hover:text-accent transition-colors text-sm"
|
||||
>
|
||||
<span className="material-symbols-outlined text-lg group-hover:scale-110 transition-transform">
|
||||
{link.icon}
|
||||
</span>
|
||||
{link.name}
|
||||
</a>
|
||||
</li>
|
||||
))}
|
||||
</ul>
|
||||
</div>
|
||||
|
||||
{/* Contacto & Social */}
|
||||
<div className="flex flex-col gap-6">
|
||||
<h3 className="text-white font-bold text-lg uppercase tracking-widest text-sm">
|
||||
Hablemos
|
||||
</h3>
|
||||
<div className="flex flex-col gap-4">
|
||||
<a
|
||||
href="mailto:contacto@tesscorp.com.mx"
|
||||
className="group flex items-center gap-2 text-white hover:text-[#0cc0df] transition-colors text-sm font-medium"
|
||||
>
|
||||
<span className="material-symbols-outlined text-lg">mail</span>
|
||||
contacto@tesscorp.com.mx
|
||||
</a>
|
||||
<a
|
||||
href="https://wa.me/522292565108"
|
||||
target="_blank"
|
||||
rel="noopener noreferrer"
|
||||
className="group flex items-center gap-2 text-white hover:text-[#25D366] transition-colors text-sm font-medium"
|
||||
>
|
||||
<i className="fa-brands fa-whatsapp text-lg"></i>
|
||||
229 256 5108
|
||||
</a>
|
||||
<div className="group flex items-start gap-2 text-white text-sm font-medium">
|
||||
<span className="material-symbols-outlined text-lg mt-0.5">location_on</span>
|
||||
<p className="leading-relaxed">
|
||||
Calle Leona Vicario #1640 C.p. 91897<br />
|
||||
Col. Formando Hogar. Veracruz, Ver
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div className="flex gap-6 pt-2">
|
||||
<a
|
||||
href="#"
|
||||
className="text-white/80 hover:text-white transition-all transform hover:-translate-y-1"
|
||||
>
|
||||
<i className="fa-brands fa-linkedin-in text-xl"></i>
|
||||
</a>
|
||||
<a
|
||||
href="#"
|
||||
className="text-white/80 hover:text-white transition-all transform hover:-translate-y-1"
|
||||
>
|
||||
<i className="fa-brands fa-instagram text-xl"></i>
|
||||
</a>
|
||||
<a
|
||||
href="#"
|
||||
className="text-white/80 hover:text-white transition-all transform hover:-translate-y-1"
|
||||
>
|
||||
<i className="fa-brands fa-x-twitter text-xl"></i>
|
||||
</a>
|
||||
</div>
|
||||
|
||||
<div className="w-full mt-4 rounded-lg overflow-hidden border border-white/10">
|
||||
<iframe
|
||||
title="Ubicación de TESS"
|
||||
src="https://maps.google.com/maps?q=Calle%20Leona%20Vicario%201640%2C%20Formando%20Hogar%2C%2091897%20Veracruz%2C%20Ver&t=&z=15&ie=UTF8&iwloc=&output=embed"
|
||||
width="100%"
|
||||
height="200"
|
||||
style={{ border: 0 }}
|
||||
allowFullScreen=""
|
||||
loading="lazy"
|
||||
referrerPolicy="no-referrer-when-downgrade"
|
||||
></iframe>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{/* Copyright */}
|
||||
<div className="border-t border-white/5 pt-8 text-center">
|
||||
<p className="text-white/70 text-xs tracking-widest uppercase">
|
||||
© {currentYear} Technology Enterprise Support System. Todos los
|
||||
derechos reservados.
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
</footer>
|
||||
);
|
||||
};
|
||||
|
||||
export default Footer;
|
||||
@@ -0,0 +1,40 @@
|
||||
import React from "react";
|
||||
import logoPrincipal from "../assets/TESS.png";
|
||||
|
||||
const Hero = () => {
|
||||
return (
|
||||
<header className="relative min-h-[92vh] flex items-center justify-center overflow-hidden bg-gradient-to-b from-[#020617] to-[#003172]">
|
||||
<div className="max-w-7xl mx-auto px-6 lg:px-8 text-center relative z-10 w-full pt-32 pb-16 md:pt-40 md:pb-20 lg:pt-48">
|
||||
<div className="main" />
|
||||
|
||||
<h1 className="text-4xl sm:text-5xl md:text-6xl lg:text-7xl font-extrabold mb-5 md:mb-6 tracking-tight leading-tight drop-shadow-lg drop-shadow-cyan-500/50">
|
||||
Tecnologías que impulsan
|
||||
<br />
|
||||
<span className="text-transparent bg-clip-text bg-[#0cc0df]">
|
||||
tu Éxito.
|
||||
</span>
|
||||
</h1>
|
||||
|
||||
<div className="my-7 md:my-8 flex justify-center">
|
||||
<div className="w-full max-w-[240px] sm:max-w-[280px] md:max-w-[320px]">
|
||||
<img
|
||||
src={logoPrincipal}
|
||||
alt="TESS Logo"
|
||||
className="w-full h-auto object-contain animate-fade-in drop-shadow-[0_0_10px_rgba(255,255,255,0.8)]"
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<p
|
||||
className="max-w-3xl mx-auto text-lg sm:text-xl md:text-2xl font-normal leading-relaxed text-blue-50/90"
|
||||
id="hero-text"
|
||||
>
|
||||
Desarrollo de software, aplicaciones web eficientes y soporte TI que
|
||||
hacen crecer tu negocio con tecnología segura y escalable.
|
||||
</p>
|
||||
</div>
|
||||
</header>
|
||||
);
|
||||
};
|
||||
|
||||
export default Hero;
|
||||
@@ -0,0 +1,203 @@
|
||||
import React, { useState, useEffect } from "react";
|
||||
import { motion, AnimatePresence } from "framer-motion";
|
||||
import logoTess from "../assets/logotesspng.png";
|
||||
|
||||
{
|
||||
/** BARRA DE NAVEGACIÓN (ง •_•)ง*/
|
||||
}
|
||||
const Navbar = ({ onContactClick }) => {
|
||||
const [isScrolled, setIsScrolled] = useState(false);
|
||||
const [isMobileMenuOpen, setIsMobileMenuOpen] = useState(false);
|
||||
|
||||
useEffect(() => {
|
||||
const handleScroll = () => {
|
||||
setIsScrolled(window.scrollY > 50);
|
||||
};
|
||||
|
||||
window.addEventListener("scroll", handleScroll);
|
||||
return () => window.removeEventListener("scroll", handleScroll);
|
||||
}, []);
|
||||
|
||||
return (
|
||||
<nav
|
||||
className={`fixed top-0 left-0 right-0 z-50 px-6 lg:px-8 transition-all duration-500 ${
|
||||
isScrolled
|
||||
? "bg-brand-dark/70 backdrop-blur-2xl border-b border-white/10 py-2"
|
||||
: "bg-transparent py-6"
|
||||
}`}
|
||||
>
|
||||
<div className="max-w-7xl mx-auto">
|
||||
<div
|
||||
className={`relative flex items-center justify-between transition-all duration-500`}
|
||||
>
|
||||
{/* Espaciador en móvil para mantener el balance visual */}
|
||||
<div className="md:hidden w-10"></div>
|
||||
|
||||
{/* Logo */}
|
||||
<div className="absolute left-1/2 -translate-x-1/2 md:static md:translate-x-0 flex items-center gap-3">
|
||||
<a
|
||||
href="#"
|
||||
className="flex items-center gap-2 group transition-all duration-300"
|
||||
onClick={(e) => {
|
||||
e.preventDefault();
|
||||
// Desplazamiento suave al inicio
|
||||
window.scrollTo({ top: 0, behavior: "smooth" });
|
||||
}}
|
||||
>
|
||||
{/* Contenedor de la imagen sin restricción de altura para permitir que crezca */}
|
||||
<div
|
||||
className={`transition-all duration-500 flex items-center justify-center ${
|
||||
isScrolled
|
||||
? "w-36 sm:w-44 md:w-52"
|
||||
: "w-48 sm:w-60 md:w-72 lg:w-80"
|
||||
}`}
|
||||
>
|
||||
<img
|
||||
src={logoTess}
|
||||
alt="Logo TESS"
|
||||
className="w-full h-auto object-contain"
|
||||
/>
|
||||
</div>
|
||||
</a>
|
||||
</div>
|
||||
|
||||
{/* Botón Menú Móvil (Hamburguesa) */}
|
||||
<div className="md:hidden flex items-center ml-auto">
|
||||
<button
|
||||
onClick={() => setIsMobileMenuOpen(!isMobileMenuOpen)}
|
||||
className="text-white hover:text-[#0cc0df] transition-colors p-2"
|
||||
aria-label={
|
||||
isMobileMenuOpen
|
||||
? "Cerrar menú principal"
|
||||
: "Abrir menú principal"
|
||||
}
|
||||
aria-expanded={isMobileMenuOpen}
|
||||
>
|
||||
<span className="material-symbols-outlined text-3xl">
|
||||
{isMobileMenuOpen ? "close" : "menu"}
|
||||
</span>
|
||||
</button>
|
||||
</div>
|
||||
|
||||
{/* Menú Escritorio */}
|
||||
<div className="hidden md:block">
|
||||
<div className="ml-10 flex items-center space-x-8">
|
||||
<a
|
||||
className="text-white/80 hover:text-white px-2 py-1 text-sm font-semibold transition-colors"
|
||||
href="#quienes-somos"
|
||||
>
|
||||
Quienes somos
|
||||
</a>
|
||||
<a
|
||||
className="text-white/80 hover:text-white px-2 py-1 text-sm font-semibold transition-colors"
|
||||
href="#nuestro-trabajo"
|
||||
>
|
||||
Nuestro Trabajo
|
||||
</a>
|
||||
<a
|
||||
className="text-white/80 hover:text-white px-2 py-1 text-sm font-semibold transition-colors"
|
||||
href="#servicios"
|
||||
>
|
||||
Servicios
|
||||
</a>
|
||||
<a
|
||||
className="text-white/80 hover:text-white px-2 py-1 text-sm font-semibold transition-colors"
|
||||
href="#clientes"
|
||||
>
|
||||
Clientes
|
||||
</a>
|
||||
<button
|
||||
onClick={onContactClick}
|
||||
className="px-7 py-2.5 rounded-full text-sm font-bold shadow-lg shadow-cyan-500/25 transition-transform hover:scale-105 bg-gradient-to-r from-emerald-400 to-cyan-500 hover:from-emerald-500 hover:to-cyan-600 text-white"
|
||||
>
|
||||
Contáctanos
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
{/* Menú Móvil */}
|
||||
<AnimatePresence>
|
||||
{isMobileMenuOpen && (
|
||||
<>
|
||||
{/* Overlay */}
|
||||
<motion.div
|
||||
initial={{ opacity: 0 }}
|
||||
animate={{ opacity: 1 }}
|
||||
exit={{ opacity: 0 }}
|
||||
onClick={() => setIsMobileMenuOpen(false)}
|
||||
className="md:hidden fixed inset-0 bg-black/40 backdrop-blur-sm z-40"
|
||||
/>
|
||||
{/* Sidebar */}
|
||||
<motion.div
|
||||
initial={{ x: "100%" }}
|
||||
animate={{ x: 0 }}
|
||||
exit={{ x: "100%" }}
|
||||
transition={{ type: "spring", damping: 25, stiffness: 200 }}
|
||||
className="md:hidden fixed top-0 right-0 h-screen w-[80vw] max-w-sm bg-brand-dark/70 backdrop-blur-3xl border-l border-white/20 shadow-[0_0_40px_rgba(0,0,0,0.5)] rounded-l-[2rem] z-50 flex flex-col"
|
||||
role="dialog"
|
||||
aria-modal="true"
|
||||
aria-label="Menú principal móvil"
|
||||
>
|
||||
<div className="flex justify-end p-6">
|
||||
<button
|
||||
onClick={() => setIsMobileMenuOpen(false)}
|
||||
className="text-white hover:text-[#0cc0df] transition-colors p-2 flex items-center justify-center rounded-xl border border-white/10 bg-white/5 hover:bg-white/10"
|
||||
aria-label="Cerrar menú principal"
|
||||
>
|
||||
<span className="material-symbols-outlined text-2xl">
|
||||
close
|
||||
</span>
|
||||
</button>
|
||||
</div>
|
||||
|
||||
<div className="flex flex-col px-8 py-4 space-y-8 text-left mt-4 h-full overflow-y-auto">
|
||||
<a
|
||||
className="text-white/90 hover:text-white text-xl font-medium transition-colors border-b border-white/10 pb-4"
|
||||
href="#quienes-somos"
|
||||
onClick={() => setIsMobileMenuOpen(false)}
|
||||
>
|
||||
Quienes somos
|
||||
</a>
|
||||
<a
|
||||
className="text-white/90 hover:text-white text-xl font-medium transition-colors border-b border-white/10 pb-4"
|
||||
href="#nuestro-trabajo"
|
||||
onClick={() => setIsMobileMenuOpen(false)}
|
||||
>
|
||||
Nuestro Trabajo
|
||||
</a>
|
||||
<a
|
||||
className="text-white/90 hover:text-white text-xl font-medium transition-colors border-b border-white/10 pb-4"
|
||||
href="#servicios"
|
||||
onClick={() => setIsMobileMenuOpen(false)}
|
||||
>
|
||||
Servicios
|
||||
</a>
|
||||
<a
|
||||
className="text-white/90 hover:text-white text-xl font-medium transition-colors border-b border-white/10 pb-4"
|
||||
href="#clientes"
|
||||
onClick={() => setIsMobileMenuOpen(false)}
|
||||
>
|
||||
Clientes
|
||||
</a>
|
||||
<div className="pt-4">
|
||||
<button
|
||||
onClick={() => {
|
||||
setIsMobileMenuOpen(false);
|
||||
onContactClick();
|
||||
}}
|
||||
className="px-7 py-3 rounded-full text-lg font-bold shadow-lg shadow-cyan-500/25 transition-transform w-full bg-gradient-to-r from-emerald-400 to-cyan-500 hover:from-emerald-500 hover:to-cyan-600 text-white"
|
||||
>
|
||||
Contáctanos
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
</motion.div>
|
||||
</>
|
||||
)}
|
||||
</AnimatePresence>
|
||||
</nav>
|
||||
);
|
||||
};
|
||||
|
||||
export default Navbar;
|
||||
@@ -0,0 +1,94 @@
|
||||
import React from "react";
|
||||
|
||||
const servicesData = [
|
||||
{
|
||||
title: "Desarrollo a Medida",
|
||||
icon: "code",
|
||||
description:
|
||||
"Creamos aplicaciones web, móviles y soluciones back-end robustas, diseñadas específicamente para adaptarse a los procesos únicos de tu negocio.",
|
||||
color: "secondary",
|
||||
},
|
||||
{
|
||||
title: "Consultoría y Arquitectura",
|
||||
icon: "web",
|
||||
description:
|
||||
"Definimos arquitecturas escalables y seguras, garantizando que cada línea de código contribuya a una solución mantenible a largo plazo.",
|
||||
color: "primary",
|
||||
},
|
||||
{
|
||||
title: "Integración de Sistema",
|
||||
icon: "lightbulb",
|
||||
description:
|
||||
"Conectamos tus herramientas y plataformas mediante APIs personalizadas para unificar el flujo de información y eliminar silos de datos.",
|
||||
color: "secondary",
|
||||
},
|
||||
{
|
||||
title: "Soporte Técnico Continuo",
|
||||
icon: "support_agent",
|
||||
description:
|
||||
"No te dejamos solo tras el lanzamiento. Ofrecemos acompañamiento técnico, evolución de producto y soporte constante para tus soluciones en producción.",
|
||||
color: "primary",
|
||||
},
|
||||
];
|
||||
|
||||
const Services = () => {
|
||||
return (
|
||||
<section
|
||||
className="py-20 md:py-24 bg-gradient-to-b from-[#020617] to-[#020617]"
|
||||
id="servicios"
|
||||
>
|
||||
<div className="max-w-7xl mx-auto px-6 lg:px-8">
|
||||
{/* Encabezado */}
|
||||
<div className="text-center mb-12 md:mb-14">
|
||||
<h2 className="text-white font-bold text-sm tracking-[0.3em] uppercase mb-3">
|
||||
NUESTROS SERVICIOS
|
||||
</h2>
|
||||
|
||||
<h3
|
||||
className="text-3xl sm:text-4xl md:text-5xl font-extrabold text-white"
|
||||
id="services-subtitle"
|
||||
>
|
||||
Soluciones integrales
|
||||
</h3>
|
||||
</div>
|
||||
|
||||
{/* Grid de servicios */}
|
||||
<div className="grid md:grid-cols-2 gap-6 lg:gap-8">
|
||||
{servicesData.map((service, index) => (
|
||||
<div
|
||||
key={index}
|
||||
className="glass-card p-6 lg:p-8 rounded-3xl border border-white/10 flex flex-col items-center text-center gap-4 transition-all hover:bg-white/5"
|
||||
>
|
||||
{/* Icono */}
|
||||
<div
|
||||
className={`w-14 h-14 shrink-0 rounded-2xl flex items-center justify-center
|
||||
${
|
||||
service.color === "primary"
|
||||
? "bg-accent/20 text-accent"
|
||||
: "bg-brand-light/20 text-brand-light"
|
||||
}`}
|
||||
>
|
||||
<span className="material-symbols-outlined text-3xl">
|
||||
{service.icon}
|
||||
</span>
|
||||
</div>
|
||||
|
||||
{/* Texto */}
|
||||
<div>
|
||||
<h4 className="text-sm font-bold tracking-[0.2em] uppercase mb-2 text-accent">
|
||||
{service.title}
|
||||
</h4>
|
||||
|
||||
<p className="text-blue-100/60 leading-relaxed text-sm md:text-base">
|
||||
{service.description}
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
))}
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
);
|
||||
};
|
||||
|
||||
export default Services;
|
||||
@@ -0,0 +1,328 @@
|
||||
import React, { useState } from "react";
|
||||
import { motion, AnimatePresence } from "framer-motion";
|
||||
import erpImg from "../assets/erp.png";
|
||||
import crmImg from "../assets/crm.png";
|
||||
|
||||
const Solutions = () => {
|
||||
const [selectedImage, setSelectedImage] = useState(null);
|
||||
|
||||
const containerVariants = {
|
||||
hidden: { opacity: 0 },
|
||||
visible: {
|
||||
opacity: 1,
|
||||
transition: {
|
||||
staggerChildren: 0.3,
|
||||
},
|
||||
},
|
||||
};
|
||||
|
||||
const itemVariants = {
|
||||
hidden: { opacity: 0, y: 30 },
|
||||
visible: {
|
||||
opacity: 1,
|
||||
y: 0,
|
||||
transition: { duration: 0.8, ease: "easeOut" },
|
||||
},
|
||||
};
|
||||
|
||||
return (
|
||||
<section
|
||||
className="py-24 bg-brand-dark relative overflow-hidden"
|
||||
id="soluciones"
|
||||
>
|
||||
<div className="max-w-7xl mx-auto px-6 lg:px-8 relative z-10">
|
||||
<div className="text-center max-w-3xl mx-auto mb-20">
|
||||
<motion.div
|
||||
initial={{ opacity: 0, scale: 0.9 }}
|
||||
whileInView={{ opacity: 1, scale: 1 }}
|
||||
viewport={{ once: true }}
|
||||
transition={{ duration: 0.5 }}
|
||||
className="inline-block mb-4 px-4 py-1.5 rounded-full border border-accent/30 bg-accent/10 text-accent text-sm font-medium tracking-wide"
|
||||
>
|
||||
PRODUCTOS PROPIOS
|
||||
</motion.div>
|
||||
<motion.h2
|
||||
initial={{ opacity: 0, y: 20 }}
|
||||
whileInView={{ opacity: 1, y: 0 }}
|
||||
viewport={{ once: true }}
|
||||
transition={{ duration: 0.5, delay: 0.1 }}
|
||||
className="text-4xl md:text-5xl font-bold mb-6 text-white tracking-tight"
|
||||
>
|
||||
Soluciones TESS
|
||||
</motion.h2>
|
||||
<motion.p
|
||||
initial={{ opacity: 0, y: 20 }}
|
||||
whileInView={{ opacity: 1, y: 0 }}
|
||||
viewport={{ once: true }}
|
||||
transition={{ duration: 0.5, delay: 0.2 }}
|
||||
className="text-lg text-brand-light/80 font-light leading-relaxed"
|
||||
>
|
||||
Desarrollamos herramientas potentes para digitalizar, centralizar y
|
||||
potenciar la gestión completa de tu negocio.
|
||||
</motion.p>
|
||||
</div>
|
||||
|
||||
<motion.div
|
||||
variants={containerVariants}
|
||||
initial="hidden"
|
||||
whileInView="visible"
|
||||
viewport={{ once: true, margin: "-100px" }}
|
||||
className="space-y-32"
|
||||
>
|
||||
{/* TESS-ERP Section */}
|
||||
<motion.div
|
||||
variants={itemVariants}
|
||||
className="flex flex-col lg:flex-row items-center gap-12 lg:gap-20"
|
||||
>
|
||||
<div className="w-full lg:w-1/2 space-y-8">
|
||||
<div className="flex items-center gap-4 mb-2">
|
||||
<div className="w-12 h-12 rounded-xl bg-gradient-to-br from-primary to-secondaccent flex items-center justify-center shadow-lg shadow-secondaccent/30 text-white font-bold text-xl">
|
||||
E
|
||||
</div>
|
||||
<h3 className="text-3xl md:text-4xl font-bold text-white tracking-tight">
|
||||
TESS-
|
||||
<span className="text-transparent bg-clip-text bg-gradient-to-r from-accent to-secondaccent">
|
||||
ERP
|
||||
</span>
|
||||
</h3>
|
||||
</div>
|
||||
|
||||
<p className="text-brand-light text-lg leading-relaxed font-light">
|
||||
Un sistema de planificación de recursos empresariales diseñado
|
||||
para conectar todas las áreas de tu organización. Controla
|
||||
inventarios, finanzas, recursos humanos y operaciones
|
||||
comerciales desde una única plataforma inteligente.
|
||||
</p>
|
||||
|
||||
<ul className="space-y-4">
|
||||
{[
|
||||
"Control centralizado de almacenes e inventario multisucursal.",
|
||||
"Automatización de facturación y contabilidad en tiempo real.",
|
||||
"Módulos escalables según el crecimiento de tu empresa.",
|
||||
"Reportes avanzados e inteligencia de negocios (BI).",
|
||||
].map((feature, idx) => (
|
||||
<li key={idx} className="flex items-start gap-3">
|
||||
<svg
|
||||
className="w-6 h-6 text-accent mt-0.5 flex-shrink-0"
|
||||
fill="none"
|
||||
viewBox="0 0 24 24"
|
||||
stroke="currentColor"
|
||||
>
|
||||
<path
|
||||
strokeLinecap="round"
|
||||
strokeLinejoin="round"
|
||||
strokeWidth="2"
|
||||
d="M9 12l2 2 4-4m6 2a9 9 0 11-18 0 9 9 0 0118 0z"
|
||||
/>
|
||||
</svg>
|
||||
<span className="text-brand-light/80">{feature}</span>
|
||||
</li>
|
||||
))}
|
||||
</ul>
|
||||
|
||||
<div className="pt-4">
|
||||
<button
|
||||
onClick={() =>
|
||||
document
|
||||
.getElementById("contacto")
|
||||
.scrollIntoView({ behavior: "smooth" })
|
||||
}
|
||||
className="px-8 py-3.5 rounded-full bg-secondaccent hover:bg-secondaccent/80 text-white font-medium transition-all duration-300 shadow-[0_0_20px_rgba(12,192,223,0.3)] hover:shadow-[0_0_30px_rgba(12,192,223,0.5)] transform hover:-translate-y-1 inline-flex items-center gap-2"
|
||||
>
|
||||
Solicitar Demo
|
||||
<svg
|
||||
className="w-5 h-5"
|
||||
fill="none"
|
||||
viewBox="0 0 24 24"
|
||||
stroke="currentColor"
|
||||
>
|
||||
<path
|
||||
strokeLinecap="round"
|
||||
strokeLinejoin="round"
|
||||
strokeWidth="2"
|
||||
d="M14 5l7 7m0 0l-7 7m7-7H3"
|
||||
/>
|
||||
</svg>
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div className="w-full lg:w-1/2 relative group perspective-1000">
|
||||
<div className="absolute inset-0 bg-gradient-to-r from-secondaccent/20 to-accent/20 rounded-2xl transform rotate-3 scale-105 opacity-50 transition-transform duration-500 group-hover:rotate-6"></div>
|
||||
<div className="relative rounded-2xl overflow-hidden border border-slate-700/50 bg-slate-800 shadow-2xl transition-transform duration-500 group-hover:scale-[1.02]">
|
||||
{/* Mockup Window UI */}
|
||||
<div className="h-8 bg-slate-900 border-b border-slate-700 flex items-center px-4 gap-2">
|
||||
<div className="w-3 h-3 rounded-full bg-red-400"></div>
|
||||
<div className="w-3 h-3 rounded-full bg-amber-400"></div>
|
||||
<div className="w-3 h-3 rounded-full bg-green-400"></div>
|
||||
</div>
|
||||
{/* Imagen del ERP */}
|
||||
<div
|
||||
className="aspect-[4/3] relative overflow-hidden bg-slate-900 cursor-pointer group"
|
||||
onClick={() => setSelectedImage(erpImg)}
|
||||
>
|
||||
<img src={erpImg} alt="Dashboard de TESS-ERP" className="w-full h-full object-cover object-top transition-transform duration-500 group-hover:scale-105" />
|
||||
<div className="absolute inset-0 bg-black/40 opacity-0 group-hover:opacity-100 transition-opacity duration-300 flex items-center justify-center">
|
||||
<span className="text-white bg-black/50 px-4 py-2 rounded-full backdrop-blur-sm flex items-center gap-2">
|
||||
<svg className="w-5 h-5" fill="none" viewBox="0 0 24 24" stroke="currentColor"><path strokeLinecap="round" strokeLinejoin="round" strokeWidth={2} d="M21 21l-6-6m2-5a7 7 0 11-14 0 7 7 0 0114 0zM10 7v3m0 0v3m0-3h3m-3 0H7" /></svg>
|
||||
Ver detalle
|
||||
</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</motion.div>
|
||||
|
||||
{/* TESS-CRM Section */}
|
||||
<motion.div
|
||||
variants={itemVariants}
|
||||
className="flex flex-col lg:flex-row-reverse items-center gap-12 lg:gap-20"
|
||||
>
|
||||
<div className="w-full lg:w-1/2 space-y-8">
|
||||
<div className="flex items-center gap-4 mb-2">
|
||||
<div className="w-12 h-12 rounded-xl bg-accent/20 flex items-center justify-center shadow-lg shadow-accent/20 text-accent font-bold text-xl border border-accent/30">
|
||||
C
|
||||
</div>
|
||||
<h3 className="text-3xl md:text-4xl font-bold text-white tracking-tight">
|
||||
TESS-
|
||||
<span className="text-accent">CRM</span>
|
||||
</h3>
|
||||
</div>
|
||||
|
||||
<p className="text-slate-300 text-lg leading-relaxed font-light">
|
||||
Maximiza tus conversiones y fideliza a tus clientes. Nuestro
|
||||
gestor de relaciones te permite organizar embudos de ventas,
|
||||
automatizar seguimientos y medir el rendimiento de tu equipo
|
||||
comercial.
|
||||
</p>
|
||||
|
||||
<ul className="space-y-4">
|
||||
{[
|
||||
"Gestión visual de embudos de venta (Pipelines).",
|
||||
"Historial unificado de comunicaciones por cliente.",
|
||||
"Seguimiento de tareas, reuniones y alertas automatizadas.",
|
||||
"Integración con correo electrónico y campañas de marketing.",
|
||||
].map((feature, idx) => (
|
||||
<li key={idx} className="flex items-start gap-3">
|
||||
<svg
|
||||
className="w-6 h-6 text-secondaccent mt-0.5 flex-shrink-0"
|
||||
fill="none"
|
||||
viewBox="0 0 24 24"
|
||||
stroke="currentColor"
|
||||
>
|
||||
<path
|
||||
strokeLinecap="round"
|
||||
strokeLinejoin="round"
|
||||
strokeWidth="2"
|
||||
d="M5 13l4 4L19 7"
|
||||
/>
|
||||
</svg>
|
||||
<span className="text-brand-light/80">{feature}</span>
|
||||
</li>
|
||||
))}
|
||||
</ul>
|
||||
|
||||
<div className="pt-4">
|
||||
<button
|
||||
onClick={() =>
|
||||
document
|
||||
.getElementById("contacto")
|
||||
.scrollIntoView({ behavior: "smooth" })
|
||||
}
|
||||
className="px-8 py-3.5 rounded-full bg-accent hover:bg-accent/80 text-primary font-bold transition-all duration-300 shadow-[0_0_20px_rgba(100,255,218,0.3)] hover:shadow-[0_0_30px_rgba(100,255,218,0.5)] transform hover:-translate-y-1 inline-flex items-center gap-2"
|
||||
>
|
||||
Descubrir CRM
|
||||
<svg
|
||||
className="w-5 h-5"
|
||||
fill="none"
|
||||
viewBox="0 0 24 24"
|
||||
stroke="currentColor"
|
||||
>
|
||||
<path
|
||||
strokeLinecap="round"
|
||||
strokeLinejoin="round"
|
||||
strokeWidth="2"
|
||||
d="M14 5l7 7m0 0l-7 7m7-7H3"
|
||||
/>
|
||||
</svg>
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div className="w-full lg:w-1/2 relative group perspective-1000">
|
||||
<div className="absolute inset-0 bg-accent/10 rounded-2xl transform -rotate-3 scale-105 opacity-50 transition-transform duration-500 group-hover:-rotate-6"></div>
|
||||
<div className="relative rounded-2xl overflow-hidden border border-slate-700/50 bg-slate-800 shadow-2xl transition-transform duration-500 group-hover:scale-[1.02]">
|
||||
{/* Mockup Window UI */}
|
||||
<div className="h-8 bg-slate-900 border-b border-slate-700 flex items-center px-4 gap-2">
|
||||
<div className="w-3 h-3 rounded-full bg-red-400"></div>
|
||||
<div className="w-3 h-3 rounded-full bg-amber-400"></div>
|
||||
<div className="w-3 h-3 rounded-full bg-green-400"></div>
|
||||
</div>
|
||||
{/* Imagen del CRM */}
|
||||
<div
|
||||
className="aspect-[4/3] relative overflow-hidden bg-slate-900 cursor-pointer group"
|
||||
onClick={() => setSelectedImage(crmImg)}
|
||||
>
|
||||
<img src={crmImg} alt="Pipeline de Ventas en TESS-CRM" className="w-full h-full object-cover object-top transition-transform duration-500 group-hover:scale-105" />
|
||||
<div className="absolute inset-0 bg-black/40 opacity-0 group-hover:opacity-100 transition-opacity duration-300 flex items-center justify-center">
|
||||
<span className="text-white bg-black/50 px-4 py-2 rounded-full backdrop-blur-sm flex items-center gap-2">
|
||||
<svg className="w-5 h-5" fill="none" viewBox="0 0 24 24" stroke="currentColor"><path strokeLinecap="round" strokeLinejoin="round" strokeWidth={2} d="M21 21l-6-6m2-5a7 7 0 11-14 0 7 7 0 0114 0zM10 7v3m0 0v3m0-3h3m-3 0H7" /></svg>
|
||||
Ver detalle
|
||||
</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</motion.div>
|
||||
</motion.div>
|
||||
</div>
|
||||
|
||||
{/* Modal Visor de Imágenes */}
|
||||
<AnimatePresence>
|
||||
{selectedImage && (
|
||||
<motion.div
|
||||
initial={{ opacity: 0 }}
|
||||
animate={{ opacity: 1 }}
|
||||
exit={{ opacity: 0 }}
|
||||
onClick={() => setSelectedImage(null)}
|
||||
className="fixed inset-0 z-[100] flex items-center justify-center bg-black/80 backdrop-blur-sm p-4 md:p-8"
|
||||
>
|
||||
<motion.div
|
||||
initial={{ scale: 0.95, opacity: 0 }}
|
||||
animate={{ scale: 1, opacity: 1 }}
|
||||
exit={{ scale: 0.95, opacity: 0 }}
|
||||
onClick={(e) => e.stopPropagation()}
|
||||
className="relative w-full max-w-6xl max-h-[90vh] bg-slate-900 rounded-2xl overflow-hidden shadow-2xl border border-white/10 flex flex-col"
|
||||
>
|
||||
<div className="flex items-center justify-between p-4 border-b border-white/10 bg-black/20">
|
||||
<div className="flex items-center gap-2">
|
||||
<div className="w-3 h-3 rounded-full bg-red-500"></div>
|
||||
<div className="w-3 h-3 rounded-full bg-amber-500"></div>
|
||||
<div className="w-3 h-3 rounded-full bg-green-500"></div>
|
||||
</div>
|
||||
<button
|
||||
onClick={() => setSelectedImage(null)}
|
||||
className="text-white/70 hover:text-white transition-colors"
|
||||
aria-label="Cerrar"
|
||||
>
|
||||
<svg className="w-6 h-6" fill="none" viewBox="0 0 24 24" stroke="currentColor">
|
||||
<path strokeLinecap="round" strokeLinejoin="round" strokeWidth={2} d="M6 18L18 6M6 6l12 12" />
|
||||
</svg>
|
||||
</button>
|
||||
</div>
|
||||
<div className="flex-1 overflow-auto bg-slate-900 flex items-center justify-center p-4">
|
||||
<img
|
||||
src={selectedImage}
|
||||
alt="Vista detallada"
|
||||
className="w-full h-auto max-h-full object-contain rounded"
|
||||
/>
|
||||
</div>
|
||||
</motion.div>
|
||||
</motion.div>
|
||||
)}
|
||||
</AnimatePresence>
|
||||
</section>
|
||||
);
|
||||
};
|
||||
|
||||
export default Solutions;
|
||||
@@ -0,0 +1,67 @@
|
||||
import React from "react";
|
||||
import imagen from "../assets/tesscorpIA.png";
|
||||
|
||||
const Work = ({ onOpenContact }) => {
|
||||
return (
|
||||
<section
|
||||
className="py-20 md:py-24 bg-gradient-to-b from-[#001430] to-[#020617]"
|
||||
id="nuestro-trabajo"
|
||||
>
|
||||
<div className="max-w-7xl mx-auto px-6 lg:px-8">
|
||||
{/* Título */}
|
||||
<h2
|
||||
className="text-2xl md:text-3xl font-bold mb-10 md:mb-12 text-center lg:text-left tracking-tight text-secondaccent"
|
||||
id="work-title"
|
||||
>
|
||||
Nuestro Trabajo
|
||||
</h2>
|
||||
|
||||
<div className="grid grid-cols-1 lg:grid-cols-2 gap-10 lg:gap-14 items-center">
|
||||
{/* Izquierda: Texto y Botón */}
|
||||
<div className="space-y-6 text-blue-100/80">
|
||||
<p className="text-base sm:text-lg md:text-xl leading-relaxed text-justify font-light">
|
||||
Entendemos a fondo tu negocio para alinear la tecnología con tus
|
||||
objetivos. Utilizamos metodologías ágiles y ciclos de entrega
|
||||
cortos para asegurar transparencia total.
|
||||
</p>
|
||||
|
||||
<p className="text-base sm:text-lg md:text-xl leading-relaxed text-justify font-light">
|
||||
Colaboramos con tu equipo para priorizar funcionalidades y validar
|
||||
soluciones rápidamente. Así construimos productos que no solo
|
||||
funcionan hoy, sino que escalan hacia el futuro.
|
||||
</p>
|
||||
|
||||
{/* Botón */}
|
||||
<div className="pt-2">
|
||||
<button
|
||||
id="work-button"
|
||||
onClick={onOpenContact}
|
||||
className="inline-flex items-center justify-center gap-2 px-6 py-3 sm:px-8 sm:py-4 text-white font-bold rounded-2xl transition-all transform hover:scale-105 shadow-lg shadow-cyan-500/25 bg-gradient-to-r from-emerald-400 to-cyan-500 hover:from-emerald-500 hover:to-cyan-600"
|
||||
>
|
||||
Envíanos un correo!
|
||||
<span className="material-symbols-outlined text-[1.2em]">mail</span>
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{/* Derecha: Card Visual */}
|
||||
<div className="relative group">
|
||||
{/* Resplandor */}
|
||||
<div className="absolute -inset-1 bg-gradient-to-r from-[#f9a14d]/20 to-blue-500/20 rounded-[2rem] blur-xl opacity-40 group-hover:opacity-80 transition duration-700"></div>
|
||||
|
||||
<div className="relative glass-card rounded-[2rem] border border-white/10 overflow-hidden shadow-2xl">
|
||||
<img
|
||||
src={imagen}
|
||||
alt="Proyectos TESS"
|
||||
className="w-full h-full object-cover grayscale-[0.25] group-hover:grayscale-0 transition-all duration-700 scale-[1.03] group-hover:scale-100"
|
||||
/>
|
||||
<div className="absolute inset-0 bg-gradient-to-t from-black/60 via-transparent to-transparent"></div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
);
|
||||
};
|
||||
|
||||
export default Work;
|
||||
@@ -1,122 +1,266 @@
|
||||
:root {
|
||||
font-family: Inter, system-ui, Avenir, Helvetica, Arial, sans-serif;
|
||||
line-height: 1.5;
|
||||
font-weight: 400;
|
||||
@import "tailwindcss";
|
||||
|
||||
color-scheme: light dark;
|
||||
color: rgba(255, 255, 255, 0.899);
|
||||
background-color: #0A2647;
|
||||
background-image: url('/public/colage-tess.jpeg');
|
||||
@theme {
|
||||
--color-primary: #031d40;
|
||||
--color-secondary: #020617;
|
||||
--color-accent: #64ffda;
|
||||
--color-secondaccent: #0cc0df;
|
||||
--color-brand-dark: #020617;
|
||||
--color-brand-light: #cfcfcf;
|
||||
|
||||
font-synthesis: none;
|
||||
text-rendering: optimizeLegibility;
|
||||
-webkit-font-smoothing: antialiased;
|
||||
-moz-osx-font-smoothing: grayscale;
|
||||
--font-raleway: "Raleway", sans-serif;
|
||||
}
|
||||
|
||||
a {
|
||||
font-weight: 500;
|
||||
color: #646cff;
|
||||
text-decoration: inherit;
|
||||
}
|
||||
|
||||
a:hover {
|
||||
color: #535bf2;
|
||||
@layer base {
|
||||
body {
|
||||
@apply font-raleway antialiased text-white bg-brand-dark;
|
||||
}
|
||||
}
|
||||
|
||||
/* estrellas del background*/
|
||||
body {
|
||||
margin: 0;
|
||||
display: flex;
|
||||
place-items: center;
|
||||
min-width: 320px;
|
||||
min-height: 100vh;
|
||||
background-image: url('/public/colage-tess.jpeg');
|
||||
background-color: #000;
|
||||
}
|
||||
|
||||
h1 {
|
||||
font-size: 3.2em;
|
||||
line-height: 1.1;
|
||||
}
|
||||
.main {
|
||||
position: fixed;
|
||||
top: 50%;
|
||||
left: 50%;
|
||||
height: 1px;
|
||||
width: 1px;
|
||||
background-color: #fff;
|
||||
border-radius: 50%;
|
||||
box-shadow:
|
||||
-42vw -4vh 0px 0px #fff,
|
||||
25vw -41vh 0px 0px #fff,
|
||||
-20vw 49vh 0px 1px #fff,
|
||||
5vw 40vh 1px 1px #fff,
|
||||
29vw 19vh 1px 0px #fff,
|
||||
-44vw -13vh 0px 0px #fff,
|
||||
46vw 41vh 0px 1px #fff,
|
||||
-3vw -45vh 0px 1px #fff,
|
||||
47vw 35vh 1px 0px #fff,
|
||||
12vw -8vh 1px 0px #fff,
|
||||
-34vw 48vh 1px 1px #fff,
|
||||
32vw 26vh 1px 1px #fff,
|
||||
32vw -41vh 1px 1px #fff,
|
||||
0vw 37vh 1px 1px #fff,
|
||||
34vw -26vh 1px 0px #fff,
|
||||
-14vw -49vh 1px 0px #fff,
|
||||
-12vw 45vh 0px 1px #fff,
|
||||
-44vw -33vh 0px 1px #fff,
|
||||
-13vw 41vh 0px 0px #fff,
|
||||
-36vw -11vh 0px 1px #fff,
|
||||
-23vw -24vh 1px 0px #fff,
|
||||
-38vw -27vh 0px 1px #fff,
|
||||
16vw -19vh 0px 0px #fff,
|
||||
28vw 33vh 1px 0px #fff,
|
||||
-49vw -4vh 0px 0px #fff,
|
||||
16vw 32vh 0px 1px #fff,
|
||||
36vw -18vh 1px 0px #fff,
|
||||
-25vw -30vh 1px 0px #fff,
|
||||
-23vw 24vh 0px 1px #fff,
|
||||
-2vw -35vh 1px 1px #fff,
|
||||
-25vw 9vh 0px 0px #fff,
|
||||
-15vw -34vh 0px 0px #fff,
|
||||
-8vw -19vh 1px 0px #fff,
|
||||
-20vw -20vh 1px 1px #fff,
|
||||
42vw 50vh 0px 1px #fff,
|
||||
-32vw 10vh 1px 0px #fff,
|
||||
-23vw -17vh 0px 0px #fff,
|
||||
44vw 15vh 1px 0px #fff,
|
||||
-40vw 33vh 1px 1px #fff,
|
||||
-43vw 8vh 0px 0px #fff,
|
||||
-48vw -15vh 1px 1px #fff,
|
||||
-24vw 17vh 0px 0px #fff,
|
||||
-31vw 50vh 1px 0px #fff,
|
||||
36vw -38vh 0px 1px #fff,
|
||||
-7vw 48vh 0px 0px #fff,
|
||||
15vw -32vh 0px 0px #fff,
|
||||
29vw -41vh 0px 0px #fff,
|
||||
2vw 37vh 1px 0px #fff,
|
||||
7vw -40vh 1px 1px #fff,
|
||||
15vw 18vh 0px 0px #fff,
|
||||
25vw -13vh 1px 1px #fff,
|
||||
-46vw -12vh 1px 1px #fff,
|
||||
-18vw 22vh 0px 0px #fff,
|
||||
23vw -9vh 1px 0px #fff,
|
||||
50vw 12vh 0px 1px #fff,
|
||||
45vw 2vh 0px 0px #fff,
|
||||
14vw -48vh 1px 0px #fff,
|
||||
23vw 43vh 0px 1px #fff,
|
||||
-40vw 16vh 1px 1px #fff,
|
||||
20vw -31vh 0px 1px #fff,
|
||||
-17vw 44vh 1px 1px #fff,
|
||||
18vw -45vh 0px 0px #fff,
|
||||
33vw -6vh 0px 0px #fff,
|
||||
0vw 7vh 0px 1px #fff,
|
||||
-10vw -18vh 0px 1px #fff,
|
||||
-19vw 5vh 1px 0px #fff,
|
||||
1vw 42vh 0px 0px #fff,
|
||||
22vw 48vh 0px 1px #fff,
|
||||
39vw -8vh 1px 1px #fff,
|
||||
-6vw -42vh 1px 0px #fff,
|
||||
-47vw 34vh 0px 0px #fff,
|
||||
-46vw 19vh 0px 1px #fff,
|
||||
-12vw -32vh 0px 0px #fff,
|
||||
-45vw -38vh 0px 1px #fff,
|
||||
-28vw 18vh 1px 0px #fff,
|
||||
-38vw -46vh 1px 1px #fff,
|
||||
49vw -6vh 1px 1px #fff,
|
||||
-28vw 18vh 1px 1px #fff,
|
||||
10vw -24vh 0px 1px #fff,
|
||||
-5vw -11vh 1px 1px #fff,
|
||||
33vw -8vh 1px 0px #fff,
|
||||
-16vw 17vh 0px 0px #fff,
|
||||
18vw 27vh 0px 1px #fff,
|
||||
-8vw -10vh 1px 1px #fff;
|
||||
|
||||
button {
|
||||
border-radius: 8px;
|
||||
border: 1px solid transparent;
|
||||
padding: 0.6em 1.2em;
|
||||
font-size: 1em;
|
||||
font-weight: 500;
|
||||
font-family: inherit;
|
||||
background-color: #1a1a1a;
|
||||
cursor: pointer;
|
||||
transition: border-color 0.25s;
|
||||
}
|
||||
/* stars were too big with the layers above but left the code in case no one cares -- as in, if noone's just that one other loner who actually cares */
|
||||
|
||||
button:hover {
|
||||
border-color: #646cff;
|
||||
box-shadow:
|
||||
24vw 9vh 1px 0px #fff,
|
||||
12vw -24vh 0px 1px #fff,
|
||||
-45vw -22vh 0px 0px #fff,
|
||||
-37vw -40vh 0px 1px #fff,
|
||||
29vw 19vh 0px 1px #fff,
|
||||
4vw -8vh 0px 1px #fff,
|
||||
-5vw 21vh 1px 1px #fff,
|
||||
-27vw 26vh 1px 1px #fff,
|
||||
-47vw -3vh 1px 1px #fff,
|
||||
-28vw -30vh 0px 1px #fff,
|
||||
-43vw -27vh 0px 1px #fff,
|
||||
4vw 22vh 1px 1px #fff,
|
||||
36vw 23vh 0px 0px #fff,
|
||||
-21vw 24vh 1px 1px #fff,
|
||||
-16vw 2vh 1px 0px #fff,
|
||||
-16vw -6vh 0px 0px #fff,
|
||||
5vw 26vh 0px 0px #fff,
|
||||
-34vw 41vh 0px 0px #fff,
|
||||
1vw 42vh 1px 1px #fff,
|
||||
11vw -13vh 1px 1px #fff,
|
||||
48vw -8vh 1px 0px #fff,
|
||||
22vw -15vh 0px 0px #fff,
|
||||
45vw 49vh 0px 0px #fff,
|
||||
43vw -27vh 1px 1px #fff,
|
||||
20vw -2vh 0px 0px #fff,
|
||||
8vw 22vh 0px 1px #fff,
|
||||
39vw 48vh 1px 1px #fff,
|
||||
-21vw -11vh 0px 1px #fff,
|
||||
-40vw 45vh 0px 1px #fff,
|
||||
11vw -30vh 1px 0px #fff,
|
||||
26vw 30vh 1px 0px #fff,
|
||||
45vw -29vh 0px 1px #fff,
|
||||
-2vw 18vh 0px 0px #fff,
|
||||
-29vw -45vh 1px 0px #fff,
|
||||
-7vw -27vh 1px 1px #fff,
|
||||
42vw 24vh 0px 0px #fff,
|
||||
45vw -48vh 1px 0px #fff,
|
||||
-36vw -18vh 0px 0px #fff,
|
||||
-44vw 13vh 0px 1px #fff,
|
||||
36vw 16vh 0px 1px #fff,
|
||||
40vw 24vh 0px 0px #fff,
|
||||
18vw 11vh 0px 0px #fff,
|
||||
-15vw -23vh 1px 0px #fff,
|
||||
-24vw 48vh 0px 1px #fff,
|
||||
27vw -45vh 1px 0px #fff,
|
||||
-2vw -24vh 0px 1px #fff,
|
||||
-15vw -28vh 0px 0px #fff,
|
||||
-43vw 13vh 1px 0px #fff,
|
||||
7vw 27vh 1px 0px #fff,
|
||||
47vw 5vh 0px 0px #fff,
|
||||
-45vw 15vh 1px 1px #fff,
|
||||
-5vw -28vh 0px 1px #fff,
|
||||
38vw 25vh 1px 1px #fff,
|
||||
-39vw -1vh 1px 0px #fff,
|
||||
5vw 0vh 1px 0px #fff,
|
||||
49vw 13vh 0px 0px #fff,
|
||||
48vw 10vh 0px 1px #fff,
|
||||
19vw -28vh 0px 0px #fff,
|
||||
4vw 7vh 0px 0px #fff,
|
||||
21vw 21vh 1px 1px #fff,
|
||||
-15vw -15vh 0px 1px #fff,
|
||||
-6vw -42vh 1px 0px #fff,
|
||||
-15vw 48vh 1px 1px #fff,
|
||||
-23vw 25vh 1px 1px #fff,
|
||||
-48vw 25vh 0px 1px #fff,
|
||||
-31vw -19vh 0px 1px #fff,
|
||||
4vw 37vh 1px 1px #fff,
|
||||
-43vw 28vh 0px 0px #fff,
|
||||
3vw -25vh 0px 1px #fff,
|
||||
-39vw 14vh 0px 1px #fff,
|
||||
-40vw 31vh 0px 1px #fff,
|
||||
35vw -36vh 1px 1px #fff,
|
||||
16vw 49vh 0px 0px #fff,
|
||||
6vw 39vh 0px 0px #fff,
|
||||
3vw -35vh 0px 1px #fff,
|
||||
-44vw -2vh 1px 0px #fff,
|
||||
-6vw 21vh 1px 0px #fff,
|
||||
48vw 9vh 1px 1px #fff,
|
||||
-43vw 30vh 1px 1px #fff,
|
||||
29vw -12vh 1px 1px #fff,
|
||||
-48vw 13vh 1px 0px #fff,
|
||||
-42vw 32vh 1px 1px #fff,
|
||||
34vw 15vh 1px 1px #fff,
|
||||
29vw -37vh 1px 1px #fff,
|
||||
28vw 2vh 0px 0px #fff;
|
||||
animation: zoom 16s alternate infinite;
|
||||
will-change: transform;
|
||||
}
|
||||
/*aqui acaban las estrellas*/
|
||||
|
||||
button:focus,
|
||||
button:focus-visible {
|
||||
outline: 4px auto -webkit-focus-ring-color;
|
||||
}
|
||||
|
||||
@media (prefers-color-scheme: light) {
|
||||
:root {
|
||||
color: #213547;
|
||||
background-color: #ffffff;
|
||||
@keyframes zoom {
|
||||
0% {
|
||||
transform: scale(1) translateZ(0);
|
||||
}
|
||||
|
||||
a:hover {
|
||||
color: #747bff;
|
||||
}
|
||||
|
||||
button {
|
||||
background-color: #f9f9f9;
|
||||
100% {
|
||||
transform: scale(1.5) translateZ(0);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
body {
|
||||
margin: 0;
|
||||
display: flex;
|
||||
place-items: center;
|
||||
min-width: 320px;
|
||||
min-height: 100vh;
|
||||
background-image:"/public/colage-tess.jpeg";
|
||||
.glass-card {
|
||||
background: rgba(255, 255, 255, 0.03);
|
||||
backdrop-filter: blur(12px);
|
||||
border: 1px solid rgba(255, 255, 255, 0.1);
|
||||
}
|
||||
.mask-gradient {
|
||||
mask-image: linear-gradient(
|
||||
to right,
|
||||
transparent,
|
||||
black 15%,
|
||||
black 85%,
|
||||
transparent
|
||||
);
|
||||
}
|
||||
html {
|
||||
scroll-behavior: smooth;
|
||||
}
|
||||
#hero-text {
|
||||
color: transparent;
|
||||
background: linear-gradient(
|
||||
45deg,
|
||||
#9ae7ff,
|
||||
#78e4ff,
|
||||
#4ddbff,
|
||||
#009ec5,
|
||||
#0099ad
|
||||
);
|
||||
-webkit-background-clip: text;
|
||||
background-clip: text;
|
||||
text-shadow:
|
||||
0 0 5px rgba(0, 117, 212, 0.7),
|
||||
0 0 10px rgba(0, 84, 117, 0.5),
|
||||
0 0 15px rgba(0, 59, 70, 0.3);
|
||||
}
|
||||
|
||||
h1 {
|
||||
font-size: 3.2em;
|
||||
line-height: 1.1;
|
||||
#work-button {
|
||||
background-color: #00bef0;
|
||||
box-shadow: #000000;
|
||||
}
|
||||
#work-button:hover {
|
||||
background-color: #0067ac91;
|
||||
}
|
||||
|
||||
button {
|
||||
border-radius: 8px;
|
||||
border: 1px solid transparent;
|
||||
padding: 0.6em 1.2em;
|
||||
font-size: 1em;
|
||||
font-weight: 500;
|
||||
font-family: inherit;
|
||||
background-color: #1a1a1a;
|
||||
cursor: pointer;
|
||||
transition: border-color 0.25s;
|
||||
}
|
||||
button:hover {
|
||||
border-color: #646cff;
|
||||
}
|
||||
button:focus,
|
||||
button:focus-visible {
|
||||
outline: 4px auto -webkit-focus-ring-color;
|
||||
}
|
||||
|
||||
@media (prefers-color-scheme: light) {
|
||||
:root {
|
||||
color: #213547;
|
||||
background-color: #ffffff;
|
||||
}
|
||||
a:hover {
|
||||
color: #747bff;
|
||||
}
|
||||
button {
|
||||
background-color: #f9f9f9;
|
||||
}
|
||||
#services-subtitle {
|
||||
color: #00bef0;
|
||||
}
|
||||
/*GHH ( •̀ ω •́ )y*/
|
||||
|
||||
@@ -1,7 +1,9 @@
|
||||
import { StrictMode } from 'react'
|
||||
import { createRoot } from 'react-dom/client'
|
||||
|
||||
import App from './App.jsx'
|
||||
import './App.css'
|
||||
import './index.css'
|
||||
import React from 'react'
|
||||
|
||||
createRoot(document.getElementById('root')).render(
|
||||
<StrictMode>
|
||||
|
||||
@@ -1,21 +1,22 @@
|
||||
/** @type {import('tailwindcss').Config} */
|
||||
export default {
|
||||
content: [
|
||||
'./index.html', // Incluye tu archivo HTML principal
|
||||
'./src/**/*.{js,jsx,ts,tsx}', // Analiza todos los archivos de tu carpeta `src`
|
||||
],
|
||||
content: [
|
||||
"./index.html",
|
||||
"./src/**/*.{js,ts,jsx,tsx}", // Esto le dice que busque en toda la carpeta src
|
||||
],
|
||||
theme: {
|
||||
|
||||
|
||||
|
||||
extend: {
|
||||
// Aquí puedes personalizar el tema (colores, fuentes, etc.)
|
||||
colors: {
|
||||
|
||||
'blue': '#4242EE',
|
||||
primary: "#0049ab",
|
||||
secondary: "rgb(59, 59, 59)",
|
||||
accent: "#000000",
|
||||
"brand-dark": "#020617",
|
||||
"black" : "#000000",
|
||||
},
|
||||
fontFamily: {
|
||||
raleway: ["Raleway", "sans-serif"],
|
||||
},
|
||||
},
|
||||
|
||||
},
|
||||
plugins: [],
|
||||
};
|
||||
}
|
||||
@@ -1,10 +1,7 @@
|
||||
import { defineConfig } from 'vite'
|
||||
import react from '@vitejs/plugin-react'
|
||||
|
||||
// https://vitejs.dev/config/
|
||||
// https://vite.dev/config/
|
||||
export default defineConfig({
|
||||
plugins: [react()],
|
||||
css: {
|
||||
postcss: './postcss.config.js', // Asegúrate de tener un archivo PostCSS
|
||||
},
|
||||
})
|
||||
|
||||