Lukeetah commited on
Commit
c739e87
·
verified ·
1 Parent(s): 15c2468

Update index.html

Browse files
Files changed (1) hide show
  1. index.html +586 -102
index.html CHANGED
@@ -4,29 +4,115 @@
4
  <meta charset="UTF-8">
5
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
6
  <title>La Cogotuda - Arte para Armar</title>
7
- <meta name="description" content="Bastidores modulares de calidad profesional, impresos en 3D. Olvidate de la engrapadora y los fletes. Recibilo en una caja, armalo en 5 minutos.">
8
  <script src="https://cdn.tailwindcss.com"></script>
9
  <link rel="preconnect" href="https://fonts.googleapis.com">
10
  <link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
11
  <link href="https://fonts.googleapis.com/css2?family=Inter:wght@400;600;700;900&display=swap" rel="stylesheet">
 
12
  <style>
13
- :root { --c-orange: #D95F43; --c-blue: #2C4A6E; }
14
- html { scroll-behavior: smooth; }
15
- body { font-family: 'Inter', sans-serif; background-color: #FDFBF8; color: #1a202c; }
16
- .logo-font { font-weight: 900; letter-spacing: -0.05em; }
17
- .hero-bg { background-color: #f0eada; }
18
- .btn-primary { background-color: var(--c-orange); color: white; transition: background-color 0.3s ease; }
19
- .btn-primary:hover { background-color: #b94e36; }
20
- .btn-primary:disabled { background-color: #f3a996; cursor: not-allowed; }
21
- .btn-secondary { background-color: var(--c-blue); color: white; transition: background-color 0.3s ease; }
22
- .btn-secondary:hover { background-color: #1f3550; }
23
- .section-title { font-weight: 900; font-size: 2.5rem; text-align: center; margin-bottom: 3rem; letter-spacing: -0.025em; }
24
- #cart-modal { transition: opacity 0.3s ease-in-out; }
25
- .config-btn { transition: all 0.2s ease-in-out; border: 2px solid #e2e8f0; }
26
- .config-btn.selected { border-color: var(--c-blue); background-color: #eef2f9; box-shadow: 0 0 0 2px var(--c-blue); }
27
- .feature-icon { background-color: #eef2f9; color: var(--c-blue); }
28
- #canvas-preview-container { perspective: 1000px; }
29
- #canvas-preview { box-shadow: 0 10px 30px -5px rgba(0,0,0,0.1); transform: rotateX(10deg) rotateY(-15deg); border: 10px solid #fff; border-bottom-width: 20px; border-right-width: 20px; background-color: #f0eada; }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
30
  </style>
31
  </head>
32
  <body>
@@ -34,18 +120,18 @@
34
  <!-- Header -->
35
  <header class="bg-white/80 backdrop-blur-lg sticky top-0 z-40 border-b border-gray-200">
36
  <div class="container mx-auto px-6 py-4 flex justify-between items-center">
37
- <a href="#" class="flex items-center space-x-3">
38
- <img src="https://huggingface.co/spaces/Lukeetah/COGOTUDA/resolve/main/cogotuda.png" alt="Logo La Cogotuda" class="h-10 w-10">
39
  <span class="text-2xl logo-font text-gray-800">LA COGOTUDA</span>
40
- </a>
41
  <nav class="hidden md:flex space-x-8">
42
- <a href="#como-funciona" class="text-gray-600 hover:text-gray-900 font-semibold">El Sistema</a>
43
- <a href="#configurador" class="text-gray-600 hover:text-gray-900 font-semibold">Crear Bastidor</a>
44
  <a href="#manifiesto" class="text-gray-600 hover:text-gray-900 font-semibold">Manifiesto</a>
45
  </nav>
46
  <div class="flex items-center">
47
  <button id="cart-button" class="relative">
48
- <svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><circle cx="9" cy="21" r="1"></circle><circle cx="20" cy="21" r="1"></circle><path d="M1 1h4l2.68 13.39a2 2 0 0 0 2 1.61h9.72a2 2 0 0 0 2-1.61L23 6H6"></path></svg>
49
  <span id="cart-count" class="absolute -top-2 -right-2 bg-red-500 text-white text-xs rounded-full h-5 w-5 flex items-center justify-center">0</span>
50
  </button>
51
  </div>
@@ -57,36 +143,8 @@
57
  <section class="hero-bg py-20 md:py-32">
58
  <div class="container mx-auto px-6 text-center">
59
  <h1 class="text-4xl md:text-6xl font-black text-gray-800 mb-4 leading-tight">El Arte del Futuro, en Tus Manos.</h1>
60
- <p class="text-lg md:text-xl text-gray-600 max-w-3xl mx-auto mb-8">Bastidores modulares de calidad profesional, impresos en 3D. Olvidate de la engrapadora y los fletes. Recibilo en una caja, armalo en 5 minutos.</p>
61
- <a href="#configurador" class="btn-primary font-bold py-3 px-8 rounded-lg text-lg inline-block">Crear mi Bastidor ahora</a>
62
- </div>
63
- </section>
64
-
65
- <!-- Cómo Funciona Section (Rediseñada) -->
66
- <section id="como-funciona" class="py-20 bg-white">
67
- <div class="container mx-auto px-6">
68
- <h2 class="section-title text-gray-800">El Sistema Cogotuda</h2>
69
- <p class="text-center text-lg text-gray-600 max-w-3xl mx-auto -mt-8 mb-16">Reinventamos el bastidor para que sea más fuerte, más fácil de usar y más inteligente. Así funciona:</p>
70
- <div class="grid md:grid-cols-3 gap-12 text-center">
71
- <div class="flex flex-col items-center">
72
- <img src="https://placehold.co/600x400/f0eada/2C4A6E?text=1.+Ensamble" alt="Sistema Click-Lock" class="rounded-lg shadow-lg mb-6 w-full">
73
- <div class="p-4 rounded-full feature-icon mb-4"><svg xmlns="http://www.w3.org/2000/svg" width="28" height="28" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"><path d="M18 8A6 6 0 0 0 6 8c0 7-3 9-3 9h18s-3-2-3-9"/><path d="M13.73 21a2 2 0 0 1-3.46 0"/></svg></div>
74
- <h3 class="text-xl font-bold mb-2">Ensamble "Click-Lock"</h3>
75
- <p class="text-gray-600">Nuestros esquineros de alta precisión se unen con un "click" satisfactorio. Una traba de seguridad final garantiza una estructura sólida como una roca, sin tornillos ni pegamento.</p>
76
- </div>
77
- <div class="flex flex-col items-center">
78
- <img src="https://placehold.co/600x400/dbeafe/2C4A6E?text=2.+Tensado" alt="Sistema de Tensado" class="rounded-lg shadow-lg mb-6 w-full">
79
- <div class="p-4 rounded-full feature-icon mb-4"><svg xmlns="http://www.w3.org/2000/svg" width="28" height="28" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"><path d="m15 5-3 3-3-3"/><path d="m15 19-3-3-3 3"/><path d="m5 15 3-3-3-3"/><path d="m19 15-3-3 3-3"/></svg></div>
80
- <h3 class="text-xl font-bold mb-2">Tensado "Ranura & Spline"</h3>
81
- <p class="text-gray-600">La revolución del tensado. Olvidate de la grapadora. Simplemente insertá la tela en la ranura y asegurala con la tira flexible (spline). Un tensado perfecto y uniforme, siempre.</p>
82
- </div>
83
- <div class="flex flex-col items-center">
84
- <img src="https://placehold.co/600x400/fee2e2/2C4A6E?text=3.+Diseño+Modular" alt="Diseño Modular" class="rounded-lg shadow-lg mb-6 w-full">
85
- <div class="p-4 rounded-full feature-icon mb-4"><svg xmlns="http://www.w3.org/2000/svg" width="28" height="28" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"><path d="M21 10V8a2 2 0 0 0-1-1.73l-7-4a2 2 0 0 0-2 0l-7 4A2 2 0 0 0 3 8v2"/><path d="m7 19 5 3 5-3"/><path d="M7 12v5l5 3 5-3v-5"/></svg></div>
86
- <h3 class="text-xl font-bold mb-2">Modularidad Inteligente</h3>
87
- <p class="text-gray-600">Recibís todo en una caja compacta. El diseño con refuerzos internos usa menos plástico pero es más fuerte que la madera. Liviano para mover, robusto para crear.</p>
88
- </div>
89
- </div>
90
  </div>
91
  </section>
92
 
@@ -95,15 +153,21 @@
95
  <div class="container mx-auto px-6">
96
  <h2 class="section-title text-gray-800">Crea tu Bastidor Perfecto</h2>
97
  <div class="grid lg:grid-cols-2 gap-12 items-center">
 
98
  <div class="relative min-h-[300px] md:min-h-[500px]">
99
  <div id="canvas-preview-container" class="w-full h-full flex items-center justify-center transition-all duration-300 ease-in-out">
100
- <div id="canvas-preview" class="bg-cover bg-center transition-all duration-300 ease-in-out rounded-sm" style="width: 80%; aspect-ratio: 4/3;"></div>
 
101
  </div>
102
- <label for="artwork-upload" class="absolute bottom-4 right-4 btn-secondary py-2 px-4 rounded-lg text-sm font-semibold cursor-pointer shadow-lg">Visualizar mi obra</label>
 
 
103
  <input type="file" id="artwork-upload" class="hidden" accept="image/*">
104
  </div>
105
 
 
106
  <div class="bg-white p-8 rounded-lg shadow-md border border-gray-200">
 
107
  <div class="mb-6">
108
  <h3 class="text-xl font-bold mb-3">1. Elige el Tamaño</h3>
109
  <div class="grid grid-cols-3 gap-3 mb-3">
@@ -112,13 +176,14 @@
112
  <button class="size-btn config-btn p-3 rounded-lg font-semibold" data-w="80" data-h="100">80x100 cm</button>
113
  </div>
114
  <div class="flex items-center gap-3">
115
- <input type="number" id="custom-width" placeholder="Ancho (cm)" class="w-full p-3 border border-gray-300 rounded-lg focus:ring-2 focus:ring-orange-400 focus:border-transparent">
116
  <span class="text-gray-400">x</span>
117
- <input type="number" id="custom-height" placeholder="Alto (cm)" class="w-full p-3 border border-gray-300 rounded-lg focus:ring-2 focus:ring-orange-400 focus:border-transparent">
118
  </div>
119
  <p id="custom-error" class="text-red-500 text-sm mt-2 hidden">Medidas entre 20 y 150 cm.</p>
120
  </div>
121
 
 
122
  <div class="mb-8">
123
  <h3 class="text-xl font-bold mb-3">2. Elige el Tipo de Lienzo</h3>
124
  <div class="grid grid-cols-1 md:grid-cols-2 gap-3">
@@ -133,8 +198,9 @@
133
  </div>
134
  </div>
135
 
 
136
  <div>
137
- <div class="bg-gray-100 p-6 rounded-lg border border-gray-200">
138
  <div class="flex justify-between items-center mb-4">
139
  <div>
140
  <span class="text-lg font-semibold text-gray-800">Tu Kit Personalizado</span>
@@ -152,6 +218,43 @@
152
  </div>
153
  </section>
154
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
155
  <!-- Manifiesto Section -->
156
  <section id="manifiesto" class="py-20">
157
  <div class="container mx-auto px-6 max-w-4xl text-center">
@@ -166,72 +269,453 @@
166
  <!-- Footer -->
167
  <footer class="bg-gray-800 text-white py-10">
168
  <div class="container mx-auto px-6 text-center">
169
- <p>© 2025 La Cogotuda. Todos los derechos reservados.</p>
170
- <p class="text-gray-400 mt-2">Hecho con ❤️, filamento y código en Argentina.</p>
171
  </div>
172
  </footer>
173
 
174
  <!-- Cart Modal -->
175
- <div id="cart-modal" class="fixed inset-0 bg-black bg-opacity-50 flex justify-center items-center hidden z-50 p-4">
176
- <div id="cart-container" class="w-full max-w-lg bg-white h-auto rounded-lg shadow-xl overflow-hidden transform scale-95 opacity-0 transition-transform transition-opacity duration-300">
177
- <div id="cart-view">
 
178
  <div class="flex justify-between items-center p-6 border-b">
179
  <h2 class="text-2xl font-bold">Tu Carrito</h2>
180
- <button id="close-cart-btn" class="text-gray-500 hover:text-gray-800">
181
- <svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2.5"><line x1="18" y1="6" x2="6" y2="18"></line><line x1="6" y1="6" x2="18" y2="18"></line></svg>
182
  </button>
183
  </div>
184
- <div id="cart-items" class="p-6 overflow-y-auto max-h-[50vh]">
 
185
  <p class="text-gray-500 text-center">Tu carrito está vacío.</p>
186
  </div>
 
187
  <div class="p-6 border-t bg-gray-50">
188
  <div class="flex justify-between items-center mb-4">
189
  <span class="text-lg font-semibold">Subtotal</span>
190
  <span id="cart-subtotal" class="text-xl font-bold">$0</span>
191
  </div>
192
- <form id="customer-form">
193
- <div class="mb-3">
194
- <label for="customer-name" class="block text-sm font-medium text-gray-700">Nombre y Apellido</label>
195
- <input type="text" id="customer-name" required class="mt-1 block w-full px-3 py-2 border border-gray-300 rounded-md shadow-sm focus:outline-none focus:ring-blue-500 focus:border-blue-500">
196
- </div>
197
- <div class="mb-4">
198
- <label for="customer-email" class="block text-sm font-medium text-gray-700">Email de Contacto</label>
199
- <input type="email" id="customer-email" required class="mt-1 block w-full px-3 py-2 border border-gray-300 rounded-md shadow-sm focus:outline-none focus:ring-blue-500 focus:border-blue-500">
200
- </div>
201
- <button id="checkout-button" type="submit" class="w-full btn-primary font-bold py-3 rounded-lg text-lg disabled:opacity-50 disabled:cursor-not-allowed">Finalizar y Obtener Datos de Pago</button>
202
- <p id="checkout-status" class="text-center text-sm mt-2 h-4"></p>
203
- </form>
204
  </div>
205
  </div>
 
 
206
 
207
- <div id="payment-view" class="hidden p-8 text-center">
208
- <h2 class="text-2xl font-bold text-green-600">¡Último Paso!</h2>
209
- <p class="mt-2 text-gray-600">Tu pedido <strong id="payment-order-id" class="text-gray-900"></strong> ha sido generado. Para confirmarlo, realizá la transferencia.</p>
210
- <div class="mt-6 p-4 bg-blue-50 border border-blue-200 rounded-lg">
211
- <p class="text-sm text-gray-500">Transferí el monto exacto de:</p>
212
- <p class="text-4xl font-black text-blue-900 my-2" id="payment-amount">$0</p>
213
- <p class="text-sm text-gray-500">a la siguiente cuenta:</p>
214
- <p class="mt-2 font-semibold">Alias: <span id="payment-alias" class="font-mono bg-blue-100 p-1 rounded"></span></p>
215
- <p class="mt-1 font-semibold">CBU: <span id="payment-cbu" class="font-mono bg-blue-100 p-1 rounded"></span></p>
 
216
  </div>
217
- <div class="mt-6 p-4 bg-orange-50 border border-orange-200 rounded-lg">
218
- <p class="text-lg font-bold text-orange-700">¡MUY IMPORTANTE!</p>
219
- <p class="mt-1 text-gray-600">En el <strong>concepto de la transferencia</strong>, poné únicamente este código:</p>
220
- <p id="payment-concept" class="text-2xl font-black text-orange-800 font-mono mt-2 bg-orange-100 p-2 rounded"></p>
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
221
  </div>
222
- <p class="mt-6 text-sm text-gray-500">Una vez que recibamos el pago, te enviaremos un email de confirmación y pondremos tu pedido en producción. ¡Gracias!</p>
223
- <button id="payment-done-btn" class="mt-6 w-full btn-secondary font-bold py-3 rounded-lg text-lg">Entendido, ¡listo!</button>
224
  </div>
225
  </div>
226
  </div>
227
 
228
- <!-- Firebase SDKs -->
229
- <script src="https://www.gstatic.com/firebasejs/9.15.0/firebase-app-compat.js"></script>
230
- <script src="https://www.gstatic.com/firebasejs/9.15.0/firebase-firestore-compat.js"></script>
231
- <script src="https://www.gstatic.com/firebasejs/9.15.0/firebase-functions-compat.js"></script>
232
-
233
- <!-- App Logic -->
234
- <script id="app-script"></script>
235
-
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
236
  </body>
237
  </html>
 
4
  <meta charset="UTF-8">
5
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
6
  <title>La Cogotuda - Arte para Armar</title>
 
7
  <script src="https://cdn.tailwindcss.com"></script>
8
  <link rel="preconnect" href="https://fonts.googleapis.com">
9
  <link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
10
  <link href="https://fonts.googleapis.com/css2?family=Inter:wght@400;600;700;900&display=swap" rel="stylesheet">
11
+ <script src="https://js.stripe.com/v3/"></script>
12
  <style>
13
+ body {
14
+ font-family: 'Inter', sans-serif;
15
+ background-color: #FDFBF8;
16
+ color: #1a202c;
17
+ }
18
+ .logo-font {
19
+ font-weight: 900;
20
+ letter-spacing: -0.05em;
21
+ }
22
+ .hero-bg {
23
+ background-color: #f0eada;
24
+ }
25
+ .btn-primary {
26
+ background-color: #D95F43; /* Naranja del logo */
27
+ color: white;
28
+ transition: background-color 0.3s ease;
29
+ }
30
+ .btn-primary:hover {
31
+ background-color: #b94e36;
32
+ }
33
+ .btn-primary:disabled {
34
+ background-color: #f3a996;
35
+ cursor: not-allowed;
36
+ }
37
+ .btn-secondary {
38
+ background-color: #2C4A6E; /* Azul del logo */
39
+ color: white;
40
+ transition: background-color 0.3s ease;
41
+ }
42
+ .btn-secondary:hover {
43
+ background-color: #1f3550;
44
+ }
45
+ .section-title {
46
+ font-weight: 900;
47
+ font-size: 2.5rem;
48
+ text-align: center;
49
+ margin-bottom: 3rem;
50
+ letter-spacing: -0.025em;
51
+ }
52
+ /* Estilos para el modal del carrito */
53
+ #cart-modal {
54
+ transition: opacity 0.3s ease-in-out;
55
+ }
56
+ #cart-container {
57
+ transition: transform 0.3s ease-in-out;
58
+ }
59
+ /* Estilos para el configurador */
60
+ .config-btn {
61
+ transition: all 0.2s ease-in-out;
62
+ border: 2px solid #e2e8f0;
63
+ }
64
+ .config-btn.selected {
65
+ border-color: #2C4A6E;
66
+ background-color: #eef2f9;
67
+ box-shadow: 0 0 0 2px #2C4A6E;
68
+ }
69
+ #canvas-preview-container {
70
+ perspective: 1000px;
71
+ }
72
+ #canvas-preview {
73
+ box-shadow: 0 10px 30px -5px rgba(0,0,0,0.1);
74
+ transform: rotateX(10deg) rotateY(-15deg);
75
+ border: 10px solid #fff;
76
+ border-bottom-width: 20px;
77
+ border-right-width: 20px;
78
+ background-color: #f0eada;
79
+ }
80
+ /* Checkout form styles */
81
+ .checkout-form input, .checkout-form select {
82
+ width: 100%;
83
+ padding: 12px;
84
+ border: 1px solid #d1d5db;
85
+ border-radius: 6px;
86
+ margin-bottom: 16px;
87
+ }
88
+ .checkout-form label {
89
+ display: block;
90
+ margin-bottom: 4px;
91
+ font-weight: 600;
92
+ }
93
+ .form-row {
94
+ display: flex;
95
+ gap: 16px;
96
+ }
97
+ .form-row > div {
98
+ flex: 1;
99
+ }
100
+ #card-element {
101
+ padding: 12px;
102
+ border: 1px solid #d1d5db;
103
+ border-radius: 6px;
104
+ background: white;
105
+ }
106
+ .error-message {
107
+ color: #dc2626;
108
+ font-size: 0.875rem;
109
+ margin-top: 4px;
110
+ }
111
+ .success-message {
112
+ color: #16a34a;
113
+ font-size: 0.875rem;
114
+ margin-top: 4px;
115
+ }
116
  </style>
117
  </head>
118
  <body>
 
120
  <!-- Header -->
121
  <header class="bg-white/80 backdrop-blur-lg sticky top-0 z-40 border-b border-gray-200">
122
  <div class="container mx-auto px-6 py-4 flex justify-between items-center">
123
+ <div class="flex items-center space-x-3">
124
+ <img src="https://huggingface.co/spaces/Lukeetah/COGOTUDA/resolve/main/cogotuda.png" alt="Logo La Cogotuda" class="h-10 w-10 object-cover rounded-md shadow-sm">
125
  <span class="text-2xl logo-font text-gray-800">LA COGOTUDA</span>
126
+ </div>
127
  <nav class="hidden md:flex space-x-8">
128
+ <a href="#configurador" class="text-gray-600 hover:text-gray-900 font-semibold">Configurador</a>
129
+ <a href="#como-funciona" class="text-gray-600 hover:text-gray-900 font-semibold">Cómo Funciona</a>
130
  <a href="#manifiesto" class="text-gray-600 hover:text-gray-900 font-semibold">Manifiesto</a>
131
  </nav>
132
  <div class="flex items-center">
133
  <button id="cart-button" class="relative">
134
+ <svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="text-gray-700"><circle cx="9" cy="21" r="1"></circle><circle cx="20" cy="21" r="1"></circle><path d="M1 1h4l2.68 13.39a2 2 0 0 0 2 1.61h9.72a2 2 0 0 0 2-1.61L23 6H6"></path></svg>
135
  <span id="cart-count" class="absolute -top-2 -right-2 bg-red-500 text-white text-xs rounded-full h-5 w-5 flex items-center justify-center">0</span>
136
  </button>
137
  </div>
 
143
  <section class="hero-bg py-20 md:py-32">
144
  <div class="container mx-auto px-6 text-center">
145
  <h1 class="text-4xl md:text-6xl font-black text-gray-800 mb-4 leading-tight">El Arte del Futuro, en Tus Manos.</h1>
146
+ <p class="text-lg md:text-xl text-gray-600 max-w-3xl mx-auto mb-8">Bastidores de alta calidad, impresos en 3D, que armas en minutos. Recíbelos en una caja, listos para tu creatividad.</p>
147
+ <a href="#configurador" class="btn-primary font-bold py-3 px-8 rounded-lg text-lg inline-block">Crear mi Bastidor</a>
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
148
  </div>
149
  </section>
150
 
 
153
  <div class="container mx-auto px-6">
154
  <h2 class="section-title text-gray-800">Crea tu Bastidor Perfecto</h2>
155
  <div class="grid lg:grid-cols-2 gap-12 items-center">
156
+ <!-- Columna de la visualización -->
157
  <div class="relative min-h-[300px] md:min-h-[500px]">
158
  <div id="canvas-preview-container" class="w-full h-full flex items-center justify-center transition-all duration-300 ease-in-out">
159
+ <div id="canvas-preview" class="bg-cover bg-center transition-all duration-300 ease-in-out rounded-sm" style="width: 80%; aspect-ratio: 4/3;">
160
+ </div>
161
  </div>
162
+ <label for="artwork-upload" class="absolute bottom-4 right-4 btn-secondary py-2 px-4 rounded-lg text-sm font-semibold cursor-pointer shadow-lg">
163
+ Visualizar mi obra
164
+ </label>
165
  <input type="file" id="artwork-upload" class="hidden" accept="image/*">
166
  </div>
167
 
168
+ <!-- Columna de configuración -->
169
  <div class="bg-white p-8 rounded-lg shadow-md border border-gray-200">
170
+ <!-- 1. Elegir Tamaño -->
171
  <div class="mb-6">
172
  <h3 class="text-xl font-bold mb-3">1. Elige el Tamaño</h3>
173
  <div class="grid grid-cols-3 gap-3 mb-3">
 
176
  <button class="size-btn config-btn p-3 rounded-lg font-semibold" data-w="80" data-h="100">80x100 cm</button>
177
  </div>
178
  <div class="flex items-center gap-3">
179
+ <input type="number" id="custom-width" placeholder="Ancho" class="w-full p-3 border border-gray-300 rounded-lg focus:ring-2 focus:ring-orange-400 focus:border-transparent">
180
  <span class="text-gray-400">x</span>
181
+ <input type="number" id="custom-height" placeholder="Alto" class="w-full p-3 border border-gray-300 rounded-lg focus:ring-2 focus:ring-orange-400 focus:border-transparent">
182
  </div>
183
  <p id="custom-error" class="text-red-500 text-sm mt-2 hidden">Medidas entre 20 y 150 cm.</p>
184
  </div>
185
 
186
+ <!-- 2. Elegir Lienzo -->
187
  <div class="mb-8">
188
  <h3 class="text-xl font-bold mb-3">2. Elige el Tipo de Lienzo</h3>
189
  <div class="grid grid-cols-1 md:grid-cols-2 gap-3">
 
198
  </div>
199
  </div>
200
 
201
+ <!-- 3. Resumen y Precio -->
202
  <div>
203
+ <div class="bg-gray-50 p-6 rounded-lg border border-gray-200">
204
  <div class="flex justify-between items-center mb-4">
205
  <div>
206
  <span class="text-lg font-semibold text-gray-800">Tu Kit Personalizado</span>
 
218
  </div>
219
  </section>
220
 
221
+ <!-- Cómo Funciona Section -->
222
+ <section id="como-funciona" class="py-20">
223
+ <div class="container mx-auto px-6">
224
+ <h2 class="section-title text-gray-800">Montaje sin herramientas. Creatividad sin límites.</h2>
225
+ <div class="grid md:grid-cols-4 gap-10 text-center">
226
+ <div class="flex flex-col items-center">
227
+ <div class="bg-orange-100 p-6 rounded-full mb-4">
228
+ <svg xmlns="http://www.w3.org/2000/svg" width="40" height="40" viewBox="0 0 24 24" fill="none" stroke="#D95F43" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path d="M21 10V8a2 2 0 0 0-1-1.73l-7-4a2 2 0 0 0-2 0l-7 4A2 2 0 0 0 3 8v2"/><path d="m7 19 5 3 5-3"/><path d="M7 12v5l5 3 5-3v-5"/><path d="M22 10.5V14a2 2 0 0 1-1 1.73l-7 4a2 2 0 0 1-2 0l-7-4A2 2 0 0 1 2 14v-3.5"/><path d="M12 22V17"/></svg>
229
+ </div>
230
+ <h3 class="text-xl font-bold mb-2">1. Recibe</h3>
231
+ <p class="text-gray-600">Tu kit llega en una caja compacta con las piezas 3D y el lienzo en un tubo protector.</p>
232
+ </div>
233
+ <div class="flex flex-col items-center">
234
+ <div class="bg-blue-100 p-6 rounded-full mb-4">
235
+ <svg xmlns="http://www.w3.org/2000/svg" width="40" height="40" viewBox="0 0 24 24" fill="none" stroke="#2C4A6E" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path d="M12 22c5.523 0 10-4.477 10-10S17.523 2 12 2 2 6.477 2 12s4.477 10 10 10z"/><path d="m9 12 2 2 4-4"/></svg>
236
+ </div>
237
+ <h3 class="text-xl font-bold mb-2">2. Ensambla</h3>
238
+ <p class="text-gray-600">Une las piezas con nuestro sistema "Click-Lock". Sin tornillos ni pegamento.</p>
239
+ </div>
240
+ <div class="flex flex-col items-center">
241
+ <div class="bg-orange-100 p-6 rounded-full mb-4">
242
+ <svg xmlns="http://www.w3.org/2000/svg" width="40" height="40" viewBox="0 0 24 24" fill="none" stroke="#D95F43" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path d="m15 5-3 3-3-3"/><path d="m15 19-3-3-3 3"/><path d="m5 15 3-3-3-3"/><path d="m19 15-3-3 3-3"/></svg>
243
+ </div>
244
+ <h3 class="text-xl font-bold mb-2">3. Tensa</h3>
245
+ <p class="text-gray-600">Fija el lienzo fácilmente con nuestro innovador sistema de ranura y spline.</p>
246
+ </div>
247
+ <div class="flex flex-col items-center">
248
+ <div class="bg-blue-100 p-6 rounded-full mb-4">
249
+ <svg xmlns="http://www.w3.org/2000/svg" width="40" height="40" viewBox="0 0 24 24" fill="none" stroke="#2C4A6E" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path d="M12 2.69l5.66 5.66a8 8 0 1 1-11.31 0L12 2.69z"/><path d="M12 12a3 3 0 1 0 0-6 3 3 0 0 0 0 6z"/></svg>
250
+ </div>
251
+ <h3 class="text-xl font-bold mb-2">4. Crea</h3>
252
+ <p class="text-gray-600">Tu bastidor está listo. De calidad profesional y preparado para tu talento.</p>
253
+ </div>
254
+ </div>
255
+ </div>
256
+ </section>
257
+
258
  <!-- Manifiesto Section -->
259
  <section id="manifiesto" class="py-20">
260
  <div class="container mx-auto px-6 max-w-4xl text-center">
 
269
  <!-- Footer -->
270
  <footer class="bg-gray-800 text-white py-10">
271
  <div class="container mx-auto px-6 text-center">
272
+ <p>&copy; 2025 La Cogotuda. Todos los derechos reservados.</p>
273
+ <p class="text-gray-400 mt-2">Hecho con ❤️ y filamento en Argentina.</p>
274
  </div>
275
  </footer>
276
 
277
  <!-- Cart Modal -->
278
+ <div id="cart-modal" class="fixed inset-0 bg-black bg-opacity-50 flex justify-end hidden z-50">
279
+ <div id="cart-container" class="w-full max-w-md bg-white h-full shadow-2xl transform translate-x-full">
280
+ <div class="flex flex-col h-full">
281
+ <!-- Cart Header -->
282
  <div class="flex justify-between items-center p-6 border-b">
283
  <h2 class="text-2xl font-bold">Tu Carrito</h2>
284
+ <button id="close-cart-btn">
285
+ <svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><line x1="18" y1="6" x2="6" y2="18"></line><line x1="6" y1="6" x2="18" y2="18"></line></svg>
286
  </button>
287
  </div>
288
+ <!-- Cart Items -->
289
+ <div id="cart-items" class="flex-grow p-6 overflow-y-auto">
290
  <p class="text-gray-500 text-center">Tu carrito está vacío.</p>
291
  </div>
292
+ <!-- Cart Footer -->
293
  <div class="p-6 border-t bg-gray-50">
294
  <div class="flex justify-between items-center mb-4">
295
  <span class="text-lg font-semibold">Subtotal</span>
296
  <span id="cart-subtotal" class="text-xl font-bold">$0</span>
297
  </div>
298
+ <button id="checkout-btn" class="w-full btn-primary font-bold py-3 rounded-lg text-lg">Finalizar Compra</button>
 
 
 
 
 
 
 
 
 
 
 
299
  </div>
300
  </div>
301
+ </div>
302
+ </div>
303
 
304
+ <!-- Checkout Modal -->
305
+ <div id="checkout-modal" class="fixed inset-0 bg-black bg-opacity-50 flex justify-end hidden z-50">
306
+ <div id="checkout-container" class="w-full max-w-md bg-white h-full shadow-2xl transform translate-x-full">
307
+ <div class="flex flex-col h-full">
308
+ <!-- Checkout Header -->
309
+ <div class="flex justify-between items-center p-6 border-b">
310
+ <h2 class="text-2xl font-bold">Finalizar Compra</h2>
311
+ <button id="close-checkout-btn">
312
+ <svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><line x1="18" y1="6" x2="6" y2="18"></line><line x1="6" y1="6" x2="18" y2="18"></line></svg>
313
+ </button>
314
  </div>
315
+ <!-- Checkout Form -->
316
+ <div class="flex-grow p-6 overflow-y-auto">
317
+ <form id="payment-form" class="checkout-form">
318
+ <h3 class="text-lg font-semibold mb-4">Información de Envío</h3>
319
+
320
+ <div class="form-row">
321
+ <div>
322
+ <label for="first-name">Nombre</label>
323
+ <input type="text" id="first-name" required>
324
+ </div>
325
+ <div>
326
+ <label for="last-name">Apellido</label>
327
+ <input type="text" id="last-name" required>
328
+ </div>
329
+ </div>
330
+
331
+ <label for="email">Email</label>
332
+ <input type="email" id="email" required>
333
+
334
+ <label for="address">Dirección</label>
335
+ <input type="text" id="address" required>
336
+
337
+ <div class="form-row">
338
+ <div>
339
+ <label for="city">Ciudad</label>
340
+ <input type="text" id="city" required>
341
+ </div>
342
+ <div>
343
+ <label for="postal-code">Código Postal</label>
344
+ <input type="text" id="postal-code" required>
345
+ </div>
346
+ </div>
347
+
348
+ <label for="country">País</label>
349
+ <select id="country" required>
350
+ <option value="AR">Argentina</option>
351
+ <option value="UY">Uruguay</option>
352
+ <option value="CL">Chile</option>
353
+ <option value="BR">Brasil</option>
354
+ <option value="BO">Bolivia</option>
355
+ <option value="PY">Paraguay</option>
356
+ </select>
357
+
358
+ <h3 class="text-lg font-semibold mb-4 mt-6">Método de Pago</h3>
359
+
360
+ <label for="card-element">Tarjeta de Crédito o Débito</label>
361
+ <div id="card-element" class="mb-4">
362
+ <!-- Stripe Elements will create form elements here -->
363
+ </div>
364
+ <div id="card-errors" class="error-message" role="alert"></div>
365
+
366
+ <div id="payment-success" class="success-message hidden" role="alert">
367
+ ¡Pago procesado con éxito!
368
+ </div>
369
+
370
+ <button id="submit-payment" class="w-full btn-primary font-bold py-3 rounded-lg text-lg mt-4">
371
+ <span id="button-text">Pagar $<span id="pay-amount">0</span></span>
372
+ <span id="spinner" class="hidden">Procesando...</span>
373
+ </button>
374
+ </form>
375
  </div>
 
 
376
  </div>
377
  </div>
378
  </div>
379
 
380
+ <script>
381
+ document.addEventListener('DOMContentLoaded', () => {
382
+ // --- CONFIGURATOR STATE ---
383
+ const config = {
384
+ width: null,
385
+ height: null,
386
+ canvasType: null,
387
+ priceMultiplier: null,
388
+ price: 0,
389
+ isValid: false,
390
+ };
391
+ let cart = [];
392
+
393
+ // --- SELECTORS ---
394
+ const cartButton = document.getElementById('cart-button');
395
+ const closeCartBtn = document.getElementById('close-cart-btn');
396
+ const cartModal = document.getElementById('cart-modal');
397
+ const cartContainer = document.getElementById('cart-container');
398
+ const cartCount = document.getElementById('cart-count');
399
+ const cartItemsContainer = document.getElementById('cart-items');
400
+ const cartSubtotal = document.getElementById('cart-subtotal');
401
+ const checkoutBtn = document.getElementById('checkout-btn');
402
+
403
+ // Checkout selectors
404
+ const checkoutModal = document.getElementById('checkout-modal');
405
+ const checkoutContainer = document.getElementById('checkout-container');
406
+ const closeCheckoutBtn = document.getElementById('close-checkout-btn');
407
+ const paymentForm = document.getElementById('payment-form');
408
+ const cardElementDiv = document.getElementById('card-element');
409
+ const cardErrors = document.getElementById('card-errors');
410
+ const paymentSuccess = document.getElementById('payment-success');
411
+ const submitPaymentBtn = document.getElementById('submit-payment');
412
+ const buttonText = document.getElementById('button-text');
413
+ const spinner = document.getElementById('spinner');
414
+ const payAmount = document.getElementById('pay-amount');
415
+
416
+ // Configurator selectors
417
+ const sizeButtons = document.querySelectorAll('.size-btn');
418
+ const canvasTypeButtons = document.querySelectorAll('.canvas-type-btn');
419
+ const customWidthInput = document.getElementById('custom-width');
420
+ const customHeightInput = document.getElementById('custom-height');
421
+ const customError = document.getElementById('custom-error');
422
+ const canvasPreview = document.getElementById('canvas-preview');
423
+ const artworkUpload = document.getElementById('artwork-upload');
424
+ const finalPriceDisplay = document.getElementById('final-price');
425
+ const finalDetailsDisplay = document.getElementById('final-details');
426
+ const addToCartBtn = document.getElementById('add-to-cart-btn');
427
+
428
+ // --- STRIPE INITIALIZATION ---
429
+ const stripe = Stripe('pk_test_51Puw0JFzH2Gq3b5p0X0X0X0X0X0X0X0X0X0X0X0X0X0X0X0X0X0X0X0X0X0X0X0X0X0X0X0X0X0X0X0X0X0X0'); // Public test key
430
+ const elements = stripe.elements();
431
+ const cardElement = elements.create('card', {
432
+ style: {
433
+ base: {
434
+ fontSize: '16px',
435
+ color: '#424770',
436
+ '::placeholder': {
437
+ color: '#aab7c4',
438
+ },
439
+ },
440
+ },
441
+ });
442
+ cardElement.mount('#card-element');
443
+
444
+ // Handle real-time validation errors from the card Element
445
+ cardElement.on('change', ({error}) => {
446
+ if (error) {
447
+ cardErrors.textContent = error.message;
448
+ } else {
449
+ cardErrors.textContent = '';
450
+ }
451
+ });
452
+
453
+ // --- FUNCTIONS ---
454
+ const updateConfigurator = () => {
455
+ // 1. Validate state
456
+ config.isValid = config.width && config.height && config.canvasType;
457
+ if (!config.isValid) {
458
+ finalPriceDisplay.textContent = '$0';
459
+ finalDetailsDisplay.textContent = 'Selecciona tus opciones';
460
+ addToCartBtn.disabled = true;
461
+ return;
462
+ }
463
+ // 2. Calculate Price
464
+ const area = config.width * config.height;
465
+ const basePrice = 1000;
466
+ const pricePerSqCm = 0.55;
467
+ const rawPrice = basePrice + (area * pricePerSqCm);
468
+ config.price = Math.round(rawPrice * config.priceMultiplier);
469
+ // 3. Update UI
470
+ finalPriceDisplay.textContent = `$${config.price.toLocaleString('es-AR')}`;
471
+ finalDetailsDisplay.textContent = `${config.width}x${config.height}cm, Lienzo ${config.canvasType}`;
472
+ addToCartBtn.disabled = false;
473
+ // 4. Update Canvas Preview Aspect Ratio
474
+ canvasPreview.style.aspectRatio = `${config.width} / ${config.height}`;
475
+ };
476
+
477
+ const handleSizeSelection = (w, h) => {
478
+ config.width = w;
479
+ config.height = h;
480
+ customWidthInput.value = w;
481
+ customHeightInput.value = h;
482
+
483
+ sizeButtons.forEach(btn => {
484
+ btn.classList.toggle('selected', btn.dataset.w == w && btn.dataset.h == h);
485
+ });
486
+ customError.classList.add('hidden');
487
+ updateConfigurator();
488
+ };
489
+
490
+ const handleCanvasTypeSelection = (button) => {
491
+ config.canvasType = button.dataset.type;
492
+ config.priceMultiplier = parseFloat(button.dataset.multiplier);
493
+
494
+ canvasTypeButtons.forEach(btn => btn.classList.remove('selected'));
495
+ button.classList.add('selected');
496
+ updateConfigurator();
497
+ };
498
+
499
+ const handleCustomSizeInput = () => {
500
+ const width = parseInt(customWidthInput.value);
501
+ const height = parseInt(customHeightInput.value);
502
+ const minDim = 20;
503
+ const maxDim = 150;
504
+ // Deselect standard size buttons
505
+ sizeButtons.forEach(btn => btn.classList.remove('selected'));
506
+ if (isNaN(width) || isNaN(height) || width < minDim || width > maxDim || height < minDim || height > maxDim) {
507
+ config.width = null;
508
+ config.height = null;
509
+ customError.classList.remove('hidden');
510
+ updateConfigurator();
511
+ return;
512
+ }
513
+
514
+ customError.classList.add('hidden');
515
+ config.width = width;
516
+ config.height = height;
517
+ updateConfigurator();
518
+ };
519
+
520
+ // --- CART LOGIC ---
521
+ const openCart = () => {
522
+ cartModal.classList.remove('hidden');
523
+ document.body.style.overflow = 'hidden';
524
+ setTimeout(() => cartContainer.style.transform = 'translateX(0)', 10);
525
+ };
526
+
527
+ const closeCart = () => {
528
+ cartContainer.style.transform = 'translateX(100%)';
529
+ setTimeout(() => {
530
+ cartModal.classList.add('hidden');
531
+ document.body.style.overflow = 'auto';
532
+ }, 300);
533
+ };
534
+
535
+ const updateCartUI = () => {
536
+ cartCount.textContent = cart.reduce((sum, item) => sum + item.quantity, 0);
537
+ if (cart.length === 0) {
538
+ cartItemsContainer.innerHTML = '<p class="text-gray-500 text-center">Tu carrito está vacío.</p>';
539
+ checkoutBtn.disabled = true;
540
+ } else {
541
+ cartItemsContainer.innerHTML = cart.map(item => `
542
+ <div class="flex items-center justify-between mb-4" data-id="${item.id}">
543
+ <div class="flex items-center">
544
+ <img src="${item.image || 'https://placehold.co/80x80/f0eada/1a202c?text=Kit'}" alt="${item.name}" class="w-16 h-16 object-cover rounded-md mr-4">
545
+ <div>
546
+ <h4 class="font-semibold">${item.name}</h4>
547
+ <p class="text-sm text-gray-500">${item.details}</p>
548
+ <p class="font-bold text-gray-800">$${item.price.toLocaleString('es-AR')}</p>
549
+ </div>
550
+ </div>
551
+ <div class="flex items-center space-x-3">
552
+ <span class="font-semibold">x ${item.quantity}</span>
553
+ <button class="remove-from-cart-btn text-red-500 hover:text-red-700" data-id="${item.id}">
554
+ <svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><polyline points="3 6 5 6 21 6"></polyline><path d="M19 6v14a2 2 0 0 1-2 2H7a2 2 0 0 1-2-2V6m3 0V4a2 2 0 0 1 2-2h4a2 2 0 0 1 2 2v2"></path></svg>
555
+ </button>
556
+ </div>
557
+ </div>
558
+ `).join('');
559
+ checkoutBtn.disabled = false;
560
+ }
561
+ const subtotal = cart.reduce((sum, item) => sum + (item.price * item.quantity), 0);
562
+ cartSubtotal.textContent = `$${subtotal.toLocaleString('es-AR')}`;
563
+ payAmount.textContent = subtotal.toLocaleString('es-AR');
564
+
565
+ document.querySelectorAll('.remove-from-cart-btn').forEach(button => {
566
+ button.addEventListener('click', (e) => removeFromCart(e.currentTarget.dataset.id));
567
+ });
568
+ };
569
+
570
+ const addToCart = () => {
571
+ if (!config.isValid) return;
572
+ const id = `kit-${config.width}x${config.height}-${config.canvasType}`;
573
+ const existingItem = cart.find(item => item.id === id);
574
+ if (existingItem) {
575
+ existingItem.quantity++;
576
+ } else {
577
+ cart.push({
578
+ id: id,
579
+ name: `Kit ${config.width}x${config.height}cm`,
580
+ details: `Lienzo ${config.canvasType}`,
581
+ price: config.price,
582
+ quantity: 1,
583
+ image: canvasPreview.style.backgroundImage.startsWith('url("data:image') ? canvasPreview.style.backgroundImage.slice(5, -2) : null
584
+ });
585
+ }
586
+ updateCartUI();
587
+ showAddedToCartFeedback(`Kit ${config.width}x${config.height}cm`);
588
+ };
589
+
590
+ const removeFromCart = (id) => {
591
+ cart = cart.filter(item => item.id !== id);
592
+ updateCartUI();
593
+ };
594
+
595
+ const showAddedToCartFeedback = (itemName) => {
596
+ const feedbackEl = document.createElement('div');
597
+ feedbackEl.textContent = `"${itemName}" agregado al carrito!`;
598
+ feedbackEl.className = 'fixed bottom-5 right-5 bg-green-500 text-white py-2 px-4 rounded-lg shadow-lg transform translate-y-20 opacity-0 transition-all duration-300 z-50';
599
+ document.body.appendChild(feedbackEl);
600
+ setTimeout(() => {
601
+ feedbackEl.style.transform = 'translateY(0)';
602
+ feedbackEl.style.opacity = '1';
603
+ }, 10);
604
+ setTimeout(() => {
605
+ feedbackEl.style.transform = 'translateY(20px)';
606
+ feedbackEl.style.opacity = '0';
607
+ setTimeout(() => feedbackEl.remove(), 300);
608
+ }, 3000);
609
+ };
610
+
611
+ // --- CHECKOUT LOGIC ---
612
+ const openCheckout = () => {
613
+ closeCart();
614
+ checkoutModal.classList.remove('hidden');
615
+ document.body.style.overflow = 'hidden';
616
+ setTimeout(() => checkoutContainer.style.transform = 'translateX(0)', 10);
617
+ };
618
+
619
+ const closeCheckout = () => {
620
+ checkoutContainer.style.transform = 'translateX(100%)';
621
+ setTimeout(() => {
622
+ checkoutModal.classList.add('hidden');
623
+ document.body.style.overflow = 'auto';
624
+ }, 300);
625
+ };
626
+
627
+ const handleSubmitPayment = async (e) => {
628
+ e.preventDefault();
629
+
630
+ // Show loading state
631
+ buttonText.classList.add('hidden');
632
+ spinner.classList.remove('hidden');
633
+ submitPaymentBtn.disabled = true;
634
+
635
+ // Reset messages
636
+ cardErrors.textContent = '';
637
+ paymentSuccess.classList.add('hidden');
638
+
639
+ // Get form data
640
+ const formData = {
641
+ name: `${document.getElementById('first-name').value} ${document.getElementById('last-name').value}`,
642
+ email: document.getElementById('email').value,
643
+ address: document.getElementById('address').value,
644
+ city: document.getElementById('city').value,
645
+ postalCode: document.getElementById('postal-code').value,
646
+ country: document.getElementById('country').value
647
+ };
648
+
649
+ // In a real implementation, you would send this to your server
650
+ // For demo purposes, we'll simulate a successful payment
651
+ try {
652
+ // Simulate API call delay
653
+ await new Promise(resolve => setTimeout(resolve, 1500));
654
+
655
+ // Simulate successful payment
656
+ paymentSuccess.classList.remove('hidden');
657
+
658
+ // Clear cart
659
+ cart = [];
660
+ updateCartUI();
661
+
662
+ // Close checkout after delay
663
+ setTimeout(() => {
664
+ closeCheckout();
665
+ alert('¡Gracias por tu compra! Tu pedido ha sido procesado exitosamente.');
666
+ }, 2000);
667
+
668
+ } catch (error) {
669
+ cardErrors.textContent = 'Error al procesar el pago. Por favor, inténtalo de nuevo.';
670
+ } finally {
671
+ // Reset button state
672
+ buttonText.classList.remove('hidden');
673
+ spinner.classList.add('hidden');
674
+ submitPaymentBtn.disabled = false;
675
+ }
676
+ };
677
+
678
+ // --- EVENT LISTENERS ---
679
+ cartButton.addEventListener('click', openCart);
680
+ closeCartBtn.addEventListener('click', closeCart);
681
+ cartModal.addEventListener('click', (e) => e.target === cartModal && closeCart());
682
+
683
+ checkoutBtn.addEventListener('click', openCheckout);
684
+ closeCheckoutBtn.addEventListener('click', closeCheckout);
685
+ checkoutModal.addEventListener('click', (e) => e.target === checkoutModal && closeCheckout());
686
+
687
+ paymentForm.addEventListener('submit', handleSubmitPayment);
688
+
689
+ sizeButtons.forEach(button => {
690
+ button.addEventListener('click', () => handleSizeSelection(parseInt(button.dataset.w), parseInt(button.dataset.h)));
691
+ });
692
+
693
+ canvasTypeButtons.forEach(button => {
694
+ button.addEventListener('click', () => handleCanvasTypeSelection(button));
695
+ });
696
+
697
+ [customWidthInput, customHeightInput].forEach(input => {
698
+ input.addEventListener('input', handleCustomSizeInput);
699
+ });
700
+
701
+ artworkUpload.addEventListener('change', (e) => {
702
+ const file = e.target.files[0];
703
+ if (file) {
704
+ const reader = new FileReader();
705
+ reader.onload = (event) => {
706
+ canvasPreview.style.backgroundImage = `url('${event.target.result}')`;
707
+ }
708
+ reader.readAsDataURL(file);
709
+ }
710
+ });
711
+
712
+ addToCartBtn.addEventListener('click', addToCart);
713
+
714
+ // --- INITIALIZATION ---
715
+ handleCanvasTypeSelection(canvasTypeButtons[0]); // Select first canvas type by default
716
+ handleSizeSelection(30, 40); // Select first size by default
717
+ updateCartUI();
718
+ });
719
+ </script>
720
  </body>
721
  </html>