diff --git a/img/py_first_day.png b/img/py_first_day.png
new file mode 100644
index 0000000..75794cf
Binary files /dev/null and b/img/py_first_day.png differ
diff --git a/index.html b/index.html
index a65e072..dfc0e31 100644
--- a/index.html
+++ b/index.html
@@ -300,7 +300,7 @@
.hack-copy h2 { font-size: clamp(1.8rem, 3.6vw, 2.7rem); margin-bottom: 14px; }
.hack-copy h2 .grad-text { background: linear-gradient(120deg, #fff 10%, #c6f3e6 50%, #d9cdfb 95%); background-size: 220% 220%; -webkit-background-clip: text; background-clip: text; color: transparent; animation: gradShift 7s ease infinite; }
.hack-copy > p { color: rgba(255,255,255,.85); font-size: 1.02rem; max-width: 520px; }
- .hack-dates { display: inline-flex; align-items: center; gap: 10px; margin: 90px 0; font-weight: 700; font-size: 1.235rem; }
+ .hack-dates { display: inline-flex; align-items: center; gap: 10px; margin: 18px 0 26px; font-weight: 700; font-size: 1.235rem; }
.hack-dates svg { width: 18px; height: 18px; color: var(--mint); }
.countdown { display: flex; gap: 12px; margin: 0 0 30px; flex-wrap: wrap; }
.cd-unit {
@@ -322,6 +322,15 @@
.hack-target svg { width: 22px; height: 22px; flex: 0 0 22px; color: var(--mint); margin-top: 2px; }
.hack-target h4 { font-size: 1rem; margin-bottom: 5px; }
.hack-target p { font-size: .84rem; color: rgba(255,255,255,.78); }
+ .hack-stats { display: flex; gap: 14px; flex-wrap: wrap; margin: 0 0 6px; }
+ .hack-stat {
+ background: rgba(255,255,255,.1); border: 1px solid rgba(255,255,255,.18); border-radius: 14px;
+ padding: 14px 20px; min-width: 112px; text-align: center; backdrop-filter: blur(6px);
+ }
+ .hack-stat strong { font-family: 'Sora'; font-size: 1.7rem; display: block; line-height: 1; }
+ .hack-stat span { font-size: .66rem; text-transform: uppercase; letter-spacing: .1em; color: rgba(255,255,255,.75); }
+ .hack-figure { border-radius: 20px; overflow: hidden; border: 1px solid rgba(255,255,255,.18); box-shadow: 0 26px 50px rgba(0,0,0,.32); }
+ .hack-figure img { display: block; width: 100%; height: auto; }
.hack-form { background: #fff; color: var(--ink); border-radius: 22px; padding: 30px; box-shadow: 0 30px 60px rgba(0,0,0,.32); }
.hack-form h3 { font-size: 1.25rem; margin-bottom: 6px; }
@@ -582,94 +591,52 @@
-
Online · Internacional · Gratis
-
Hackathon de Internacionalización para Paraguay
+
Hackathon · Día 1
+
Primer día del Hackathon de Internacionalización
- Dos jornadas online para llevar la localización paraguaya de Odoo al siguiente nivel.
- Sumate a desarrollar, testear, documentar o traducir junto a la comunidad.
+ Arrancamos el hackathon de la localización paraguaya. Un día de trabajo en equipo:
+ revisamos los módulos, abrimos las primeras propuestas y dejamos la base para lo
+ que viene. Gracias a todos los que se sumaron.
- 12 y 14 de noviembre de 2026
+ 12 de noviembre de 2026
-
-
-- Días
-
-- Horas
-
-- Min
-
-- Seg
+
+
4 Tickets
+
2 Pull requests
+
1 Comunidad
-
-
Nuestros Objetivos
+
Lo que nos llevamos del día 1
+
+
+
+
4 tickets abiertos
+
Problemas y mejoras de la localización identificados y documentados para trabajarlos.
+
+
-
Actualización de módulos a Odoo 19 y 20
-
Consolidar la rama 19.0 y avanzar hacia las versiones más recientes del ERP.
+
2 pull requests
+
Primeras propuestas de código enviadas para revisión de la comunidad.
-
Nuevas funcionalidades (Feature add)
-
Incorporar features que la comunidad paraguaya necesita en su día a día.
-
-
-
-
-
-
Testing y documentación
-
Pruebas, cobertura y guías claras para que más gente adopte Odoo en Paraguay.
+
Aprendimos mucho
+
Un día de aprendizaje compartido: entre todos entendimos mejor cómo llevar Odoo adelante en Paraguay.
@@ -977,91 +944,6 @@
cards.forEach(c => { c.style.transform = ''; });
});
}
-
- // Hackathon countdown (12 Nov 2026)
- const target = new Date('2026-11-12T00:00:00').getTime();
- const cd = {
- days: document.getElementById('cd-days'),
- hours: document.getElementById('cd-hours'),
- mins: document.getElementById('cd-mins'),
- secs: document.getElementById('cd-secs')
- };
- const pad = (n) => String(n).padStart(2, '0');
- const tickCountdown = () => {
- const diff = target - Date.now();
- if (diff <= 0) {
- cd.days.textContent = cd.hours.textContent = cd.mins.textContent = cd.secs.textContent = '00';
- return;
- }
- cd.days.textContent = Math.floor(diff / 86400000);
- cd.hours.textContent = pad(Math.floor(diff / 3600000) % 24);
- cd.mins.textContent = pad(Math.floor(diff / 60000) % 60);
- cd.secs.textContent = pad(Math.floor(diff / 1000) % 60);
- };
- if (cd.days) { tickCountdown(); setInterval(tickCountdown, 1000); }
-
- // Hackathon signup form
- const form = document.getElementById('hack-form');
- if (form) {
- const WEBHOOK_URL = 'https://n8n.odoo4projects.com/webhook/OCA/hackathon';
- const btn = document.getElementById('hack-submit');
- const errorEl = document.getElementById('form-error');
- const setInvalid = (id, bad) => document.getElementById(id).classList.toggle('invalid', bad);
-
- form.addEventListener('submit', async (ev) => {
- ev.preventDefault();
- errorEl.classList.remove('show');
- const name = form.querySelector('#name').value.trim();
- const github = form.querySelector('#github').value.trim();
- const email = form.querySelector('#email').value.trim();
- const desc = form.querySelector('#desc').value.trim();
- const emailOk = /^[^\s@]+@[^\s@]+\.[^\s@]+$/.test(email);
-
- setInvalid('f-name', !name);
- setInvalid('f-github', !github);
- setInvalid('f-email', !emailOk);
- setInvalid('f-desc', !desc);
-
- if (!name || !github || !emailOk || !desc) {
- const firstBad = form.querySelector('.field.invalid input, .field.invalid textarea');
- if (firstBad) firstBad.focus();
- return;
- }
-
- const original = btn.innerHTML;
- btn.disabled = true;
- btn.textContent = 'Enviando…';
-
- try {
- const res = await fetch(WEBHOOK_URL, {
- method: 'POST',
- headers: { 'Content-Type': 'application/json' },
- body: JSON.stringify({
- name: name,
- github: github,
- email: email,
- description: desc,
- event: 'hackathon-oca-py-2026',
- source: window.location.href
- })
- });
- if (!res.ok) throw new Error('HTTP ' + res.status);
-
- document.getElementById('success-name').textContent = name.split(' ')[0];
- form.style.display = 'none';
- document.getElementById('form-success').classList.add('show');
- } catch (err) {
- console.error('Error al enviar la inscripción:', err);
- btn.disabled = false;
- btn.innerHTML = original;
- errorEl.classList.add('show');
- }
- });
-
- form.querySelectorAll('input, textarea').forEach(el => {
- el.addEventListener('input', () => el.closest('.field')?.classList.remove('invalid'));
- });
- }