Files
oca-py.org/index.html
T
2026-10-24 07:05:46 -03:00

1067 lines
62 KiB
HTML
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
<!DOCTYPE html>
<html lang="es">
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>OCA Paraguay — Comunidad Odoo de Paraguay</title>
<meta name="description" content="OCA Paraguay: la comunidad hispanohablante de la Odoo Community Association en Paraguay. Noticias, tips, eventos y una red de personas apasionadas por el ERP de código abierto." />
<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=Inter:wght@300;400;500;600;700;800;900&family=Sora:wght@600;700;800&display=swap" rel="stylesheet" />
<style>
:root {
--plum: #714B67;
--plum-dark: #4b2f43;
--violet: #6C4CE0;
--violet-soft: #8f7bf0;
--mint: #16C79A;
--mint-dark: #0e8f6e;
--py-red: #D52B1E;
--py-blue: #0038A8;
--ink: #1b1420;
--muted: #6a6172;
--bg: #fbfaff;
--card: #ffffff;
--line: #ece8f4;
--shadow-sm: 0 2px 8px rgba(45, 30, 60, .06);
--shadow: 0 14px 40px rgba(45, 30, 60, .10);
--shadow-lg: 0 30px 70px rgba(45, 30, 60, .16);
--radius: 20px;
--max: 1160px;
}
* { box-sizing: border-box; margin: 0; padding: 0; }
html { scroll-behavior: smooth; }
body {
font-family: 'Inter', system-ui, -apple-system, sans-serif;
color: var(--ink);
background: var(--bg);
line-height: 1.65;
overflow-x: hidden;
-webkit-font-smoothing: antialiased;
}
h1, h2, h3, .brand { font-family: 'Sora', 'Inter', sans-serif; letter-spacing: -0.02em; line-height: 1.12; }
a { color: inherit; text-decoration: none; }
img { max-width: 100%; display: block; }
.container { width: min(var(--max), 92vw); margin: 0 auto; }
/* ---------- Background decorative ---------- */
.bg-blobs { position: fixed; inset: 0; z-index: -1; overflow: hidden; pointer-events: none; }
.blob {
position: absolute; border-radius: 50%; filter: blur(80px); opacity: .5;
animation: float 18s ease-in-out infinite;
}
.blob.b1 { width: 460px; height: 460px; background: #d9cdfb; top: -120px; left: -100px; }
.blob.b2 { width: 400px; height: 400px; background: #c6f3e6; top: 40%; right: -140px; animation-delay: -6s; }
.blob.b3 { width: 360px; height: 360px; background: #ffd9d4; bottom: -120px; left: 30%; animation-delay: -11s; }
@keyframes float {
0%, 100% { transform: translate3d(0,0,0) scale(1); }
33% { transform: translate3d(30px,-40px,0) scale(1.08); }
66% { transform: translate3d(-25px,25px,0) scale(.95); }
}
/* ---------- Nav ---------- */
header.nav {
position: sticky; top: 0; z-index: 100;
backdrop-filter: blur(14px);
background: rgba(251, 250, 255, .78);
border-bottom: 1px solid transparent;
transition: border-color .3s, box-shadow .3s, background .3s;
}
header.nav.scrolled { border-color: var(--line); box-shadow: var(--shadow-sm); background: rgba(251,250,255,.92); }
.nav-inner { display: flex; align-items: center; justify-content: space-between; height: 72px; }
.brand { display: flex; align-items: center; gap: 12px; font-weight: 800; font-size: 1.12rem; }
.brand .logo {
width: 42px; height: 42px; border-radius: 12px; display: grid; place-items: center;
background: linear-gradient(135deg, var(--violet), var(--plum));
color: #fff; font-weight: 800; font-size: .95rem; letter-spacing: .5px;
box-shadow: 0 8px 20px rgba(108, 76, 224, .35);
position: relative; overflow: hidden;
}
.brand .logo::after {
content: ""; position: absolute; inset: 0;
background: linear-gradient(120deg, transparent 30%, rgba(255,255,255,.5) 50%, transparent 70%);
transform: translateX(-120%);
animation: shine 4.5s ease-in-out infinite;
}
.brand .logo-img { background: none; box-shadow: none; overflow: visible; }
.brand .logo-img::after { display: none; }
.brand .logo-img img { width: 42px; height: 42px; object-fit: contain; }
@media (max-width: 720px) { .brand .logo-img img { width: 36px; height: 36px; } }
@keyframes shine { 0%, 60% { transform: translateX(-120%); } 80%, 100% { transform: translateX(120%); } }
.brand small { display: block; font-family: 'Inter'; font-weight: 500; font-size: .68rem; color: var(--muted); letter-spacing: .02em; }
nav ul { display: flex; gap: 6px; list-style: none; align-items: center; }
nav a.link {
padding: 8px 14px; border-radius: 999px; font-size: .92rem; font-weight: 500; color: var(--muted);
transition: color .2s, background .2s;
}
nav a.link:hover { color: var(--violet); background: rgba(108,76,224,.08); }
.btn {
display: inline-flex; align-items: center; gap: 8px; cursor: pointer; border: none;
padding: 11px 20px; border-radius: 999px; font-weight: 600; font-size: .92rem;
transition: transform .18s ease, box-shadow .25s, background .25s;
font-family: inherit;
}
.btn-primary { background: linear-gradient(135deg, var(--violet), var(--plum)); color: #fff; box-shadow: 0 10px 24px rgba(108,76,224,.32); }
.btn-primary:hover { transform: translateY(-2px); box-shadow: 0 16px 32px rgba(108,76,224,.42); }
.btn-ghost { background: #fff; color: var(--ink); border: 1px solid var(--line); box-shadow: var(--shadow-sm); }
.btn-ghost:hover { transform: translateY(-2px); border-color: var(--violet-soft); color: var(--violet); }
.burger { display: none; background: none; border: none; cursor: pointer; padding: 8px; }
.burger span { display: block; width: 22px; height: 2px; background: var(--ink); margin: 5px 0; border-radius: 2px; transition: .3s; }
/* ---------- Hero ---------- */
.hero { padding: 78px 0 40px; position: relative; }
.hero-grid { display: grid; grid-template-columns: 1.08fr .92fr; gap: 54px; align-items: center; }
.pill {
display: inline-flex; align-items: center; gap: 9px; padding: 7px 15px; border-radius: 999px;
background: #fff; border: 1px solid var(--line); box-shadow: var(--shadow-sm);
font-size: .8rem; font-weight: 600; color: var(--plum); margin-bottom: 22px;
}
.dot { width: 8px; height: 8px; border-radius: 50%; background: var(--mint); position: relative; }
.dot::after { content:""; position:absolute; inset:0; border-radius:50%; background: var(--mint); animation: pulse 1.8s ease-out infinite; }
@keyframes pulse { 0% { transform: scale(1); opacity: .8; } 100% { transform: scale(3); opacity: 0; } }
.hero h1 { font-size: clamp(2.3rem, 5vw, 3.7rem); font-weight: 800; margin-bottom: 20px; }
.grad-text {
background: linear-gradient(120deg, var(--violet) 10%, var(--plum) 50%, var(--mint-dark) 95%);
background-size: 220% 220%;
-webkit-background-clip: text; background-clip: text; color: transparent;
animation: gradShift 7s ease infinite;
}
@keyframes gradShift { 0%,100% { background-position: 0% 50%; } 50% { background-position: 100% 50%; } }
.hero p.lead { font-size: 1.12rem; color: var(--muted); max-width: 540px; margin-bottom: 30px; }
.hero-cta { display: flex; gap: 14px; flex-wrap: wrap; }
.hero-meta { display: flex; gap: 26px; margin-top: 38px; flex-wrap: wrap; }
.hero-meta div strong { display: block; font-family: 'Sora'; font-size: 1.6rem; font-weight: 800; color: var(--plum); }
.hero-meta div span { font-size: .82rem; color: var(--muted); }
/* Hero visual stack */
.hero-visual { position: relative; height: 420px; }
.card-float {
position: absolute; background: #fff; border: 1px solid var(--line); border-radius: 18px;
box-shadow: var(--shadow); padding: 18px; width: 240px;
}
.cf-1 { top: 8%; left: 0; animation: bob 6s ease-in-out infinite; }
.cf-2 { top: 36%; right: 0; animation: bob 6s ease-in-out infinite -2s; width: 220px; }
.cf-3 { bottom: 4%; left: 12%; animation: bob 6s ease-in-out infinite -4s; width: 210px; }
@keyframes bob { 0%,100% { transform: translateY(0); } 50% { transform: translateY(-14px); } }
.card-float h4 { font-size: .95rem; margin-bottom: 5px; }
.card-float p { font-size: .78rem; color: var(--muted); }
.cf-ico { width: 38px; height: 38px; border-radius: 11px; display: grid; place-items: center; margin-bottom: 11px; color: #fff; }
.ico-violet { background: linear-gradient(135deg, var(--violet), var(--violet-soft)); }
.ico-mint { background: linear-gradient(135deg, var(--mint), var(--mint-dark)); }
.ico-plum { background: linear-gradient(135deg, var(--plum), var(--plum-dark)); }
.progress { height: 6px; border-radius: 6px; background: #efeaf7; margin-top: 12px; overflow: hidden; }
.progress i { display: block; height: 100%; width: 40%; border-radius: 6px; background: linear-gradient(90deg, var(--violet), var(--mint)); animation: grow 3s ease-in-out infinite; }
@keyframes grow { 0%,100% { width: 35%; } 50% { width: 82%; } }
/* ---------- Sections ---------- */
section { padding: 74px 0; }
.sec-head { max-width: 660px; margin-bottom: 46px; }
.sec-head .kicker {
font-size: .8rem; font-weight: 700; letter-spacing: .14em; text-transform: uppercase; color: var(--violet);
display: inline-flex; align-items: center; gap: 8px; margin-bottom: 12px;
}
.sec-head .kicker::before { content: ""; width: 26px; height: 2px; background: var(--violet); border-radius: 2px; }
.sec-head h2 { font-size: clamp(1.8rem, 3.6vw, 2.6rem); font-weight: 800; margin-bottom: 14px; }
.sec-head p { color: var(--muted); font-size: 1.02rem; }
.sec-head.center { margin-left: auto; margin-right: auto; text-align: center; }
.sec-head.center .kicker { justify-content: center; }
/* Reveal animation */
.reveal { opacity: 0; transform: translateY(26px); transition: opacity .7s cubic-bezier(.2,.7,.2,1), transform .7s cubic-bezier(.2,.7,.2,1); }
.reveal.in { opacity: 1; transform: none; }
/* ---------- News ---------- */
.news-grid { display: grid; grid-template-columns: repeat(3, 1fr); gap: 26px; }
.news-card {
background: var(--card); border: 1px solid var(--line); border-radius: var(--radius); overflow: hidden;
box-shadow: var(--shadow-sm); display: flex; flex-direction: column;
transition: transform .3s cubic-bezier(.2,.7,.2,1), box-shadow .3s, border-color .3s;
}
.news-card:hover { transform: translateY(-8px); box-shadow: var(--shadow-lg); border-color: transparent; }
.news-top { height: 158px; position: relative; overflow: hidden; display: grid; place-items: center; color: #fff; }
.news-top .tag {
position: absolute; top: 14px; left: 14px; background: rgba(255,255,255,.22); backdrop-filter: blur(6px);
padding: 5px 12px; border-radius: 999px; font-size: .72rem; font-weight: 700; letter-spacing: .04em; text-transform: uppercase;
border: 1px solid rgba(255,255,255,.35);
}
.news-top svg { width: 54px; height: 54px; opacity: .95; transition: transform .5s; }
.news-card:hover .news-top svg { transform: scale(1.14) rotate(-4deg); }
.nt-1 { background: linear-gradient(135deg, var(--violet), var(--plum)); }
.nt-2 { background: linear-gradient(135deg, var(--mint), #0b7d8a); }
.nt-3 { background: linear-gradient(135deg, #ff8a5c, var(--py-red)); }
.nt-4 { background: linear-gradient(135deg, #3d7de0, var(--py-blue)); }
.news-body { padding: 22px 22px 24px; display: flex; flex-direction: column; flex: 1; }
.news-date { font-size: .76rem; color: var(--muted); font-weight: 600; margin-bottom: 9px; }
.news-body h3 { font-size: 1.08rem; margin-bottom: 10px; font-weight: 700; }
.news-body p { font-size: .88rem; color: var(--muted); flex: 1; }
.news-body .more { margin-top: 16px; font-weight: 600; font-size: .86rem; color: var(--violet); display: inline-flex; align-items: center; gap: 6px; }
.news-body .more svg { width: 15px; height: 15px; transition: transform .25s; }
.news-card:hover .more svg { transform: translateX(4px); }
/* ---------- Events ---------- */
.events { background: linear-gradient(180deg, transparent, #f4f0fb 40%, transparent); }
.event-list { display: flex; flex-direction: column; gap: 16px; }
.event {
display: grid; grid-template-columns: 92px 1fr auto; gap: 24px; align-items: center;
background: var(--card); border: 1px solid var(--line); border-radius: 18px; padding: 20px 26px;
box-shadow: var(--shadow-sm); transition: transform .28s, box-shadow .28s, border-color .28s;
}
.event:hover { transform: translateY(-4px); box-shadow: var(--shadow); border-color: var(--violet-soft); }
.event-date {
text-align: center; border-right: 1px solid var(--line); padding-right: 22px;
}
.event-date .d { font-family: 'Sora'; font-size: 1.9rem; font-weight: 800; color: var(--plum); line-height: 1; }
.event-date .m { font-size: .78rem; font-weight: 700; text-transform: uppercase; letter-spacing: .1em; color: var(--violet); }
.event-info h3 { font-size: 1.12rem; margin-bottom: 5px; }
.event-info p { font-size: .88rem; color: var(--muted); }
.event-info .loc { display: inline-flex; align-items: center; gap: 6px; margin-top: 8px; font-size: .78rem; font-weight: 600; color: var(--plum); }
.event-info .loc svg { width: 14px; height: 14px; }
.event-info .event-cta { display: inline-flex; align-items: center; gap: 6px; margin-top: 10px; font-size: .8rem; font-weight: 600; color: var(--violet); }
.event-info .event-cta svg { width: 14px; height: 14px; transition: transform .25s; }
.event:hover .event-cta svg { transform: translate(3px, -3px); }
.badge {
font-size: .72rem; font-weight: 700; padding: 5px 12px; border-radius: 999px; text-transform: uppercase; letter-spacing: .05em;
background: rgba(108,76,224,.1); color: var(--violet);
}
.badge.presencial { background: rgba(213,43,30,.1); color: var(--py-red); }
.badge.taller { background: rgba(22,199,154,.14); color: var(--mint-dark); }
/* ---------- Footer ---------- */
footer { border-top: 1px solid var(--line); padding: 54px 0 30px; margin-top: 40px; background: #fff; }
.foot-grid { display: grid; grid-template-columns: 2fr 1fr 1fr; gap: 34px; margin-bottom: 40px; }
.foot-brand p { color: var(--muted); font-size: .88rem; margin-top: 16px; max-width: 300px; }
footer h5 { font-family: 'Sora'; font-size: .9rem; margin-bottom: 16px; }
footer ul { list-style: none; display: flex; flex-direction: column; gap: 10px; }
footer ul a { font-size: .88rem; color: var(--muted); transition: color .2s, padding-left .2s; }
footer ul a:hover { color: var(--violet); padding-left: 4px; }
.foot-bottom { border-top: 1px solid var(--line); padding-top: 24px; display: flex; justify-content: space-between; gap: 18px; flex-wrap: wrap; font-size: .82rem; color: var(--muted); }
.flag-strip { height: 4px; width: 100%; background: linear-gradient(90deg, var(--py-red) 33.3%, #fff 33.3% 66.6%, var(--py-blue) 66.6%); border-radius: 4px; }
/* ---------- Estado Odoo CE ---------- */
.state-features { display: grid; grid-template-columns: repeat(4, 1fr); gap: 18px; margin-bottom: 42px; }
.fact {
display: flex; flex-direction: column; gap: 12px; background: var(--card);
border: 1px solid var(--line); border-radius: 18px; padding: 24px; box-shadow: var(--shadow-sm);
transition: transform .25s, border-color .25s, box-shadow .25s;
}
.fact:hover { transform: translateY(-5px); border-color: var(--violet-soft); box-shadow: var(--shadow); }
.fact .fi { width: 44px; height: 44px; flex: 0 0 44px; border-radius: 13px; display: grid; place-items: center; color: #fff; }
.fact h4 { font-size: 1rem; margin-bottom: 4px; }
.fact p { font-size: .85rem; color: var(--muted); }
.fact code { background: #f3effa; color: var(--plum); padding: 1px 6px; border-radius: 6px; font-size: .8rem; font-family: ui-monospace, 'SF Mono', Menlo, monospace; }
.mod-panel { background: var(--card); border: 1px solid var(--line); border-radius: 20px; box-shadow: var(--shadow); overflow: hidden; }
.mod-head {
padding: 20px 24px; display: flex; align-items: center; justify-content: space-between; gap: 12px; flex-wrap: wrap;
border-bottom: 1px solid var(--line); background: linear-gradient(135deg, var(--plum-dark), var(--violet)); color: #fff;
}
.mod-head h3 { font-size: 1.08rem; }
.branch-pill {
display: inline-flex; align-items: center; gap: 7px; font-size: .76rem; font-weight: 700;
background: rgba(255,255,255,.18); border: 1px solid rgba(255,255,255,.3); padding: 5px 12px; border-radius: 999px;
}
.branch-pill .dot { background: var(--mint); }
.mod-list { list-style: none; display: grid; grid-template-columns: 1fr 1fr; }
.mod-list li { display: grid; grid-template-columns: 1fr auto; gap: 10px; padding: 14px 22px; border-bottom: 1px solid var(--line); align-items: center; transition: background .2s; }
.mod-list li:nth-child(odd) { border-right: 1px solid var(--line); }
.mod-list li:nth-last-child(-n+2) { border-bottom: none; }
.mod-list li:hover { background: #faf8ff; }
.mod-list .name { font-family: ui-monospace, 'SF Mono', Menlo, monospace; font-size: .86rem; font-weight: 600; color: var(--plum); }
.mod-list .desc { font-size: .8rem; color: var(--muted); }
.ver { font-size: .72rem; font-weight: 700; color: var(--violet); background: rgba(108,76,224,.1); padding: 4px 10px; border-radius: 999px; white-space: nowrap; }
.mod-foot { padding: 16px 24px; font-size: .78rem; color: var(--muted); border-top: 1px solid var(--line); background: #faf8ff; }
.mod-foot a { color: var(--violet); font-weight: 600; }
.mod-foot a:hover { text-decoration: underline; }
/* ---------- Hackathon ---------- */
.hack-box {
position: relative; border-radius: 30px; padding: 56px; color: #fff; overflow: hidden;
background: linear-gradient(135deg, #1b1030 0%, #3a1d63 45%, #6C4CE0 100%);
box-shadow: var(--shadow-lg);
}
.hack-box::before {
content: ""; position: absolute; inset: -40%;
background: conic-gradient(from 0deg, rgba(108,76,224,0), rgba(22,199,154,.4), rgba(213,43,30,.28), rgba(108,76,224,0));
filter: blur(70px); opacity: .75; animation: spin 16s linear infinite;
}
@keyframes spin { to { transform: rotate(360deg); } }
.hack-inner { position: relative; z-index: 1; }
.hack-grid { display: grid; grid-template-columns: 1.05fr .95fr; gap: 44px; align-items: start; }
.hack-badge {
display: inline-flex; align-items: center; gap: 9px; padding: 7px 15px; border-radius: 999px;
background: rgba(255,255,255,.12); border: 1px solid rgba(255,255,255,.28);
font-size: .78rem; font-weight: 700; letter-spacing: .06em; text-transform: uppercase; margin-bottom: 20px;
}
.hack-badge .dot { background: var(--mint); }
.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 svg { width: 18px; height: 18px; color: var(--mint); }
.countdown { display: flex; gap: 12px; margin: 0 0 30px; flex-wrap: wrap; }
.cd-unit {
background: rgba(255,255,255,.1); border: 1px solid rgba(255,255,255,.18); border-radius: 14px;
padding: 12px 16px; text-align: center; min-width: 74px; backdrop-filter: blur(6px);
}
.cd-unit strong { font-family: 'Sora'; font-size: 1.7rem; display: block; line-height: 1; }
.cd-unit span { font-size: .66rem; text-transform: uppercase; letter-spacing: .1em; color: rgba(255,255,255,.75); }
.hack-goals { margin-top: 42px; }
.hack-goals > h3 { font-size: 1.3rem; margin-bottom: 18px; display: flex; align-items: center; gap: 12px; }
.hack-goals > h3::before { content: ""; width: 28px; height: 2px; background: var(--mint); border-radius: 2px; }
.hack-targets { display: grid; grid-template-columns: repeat(3, 1fr); gap: 16px; }
.hack-target {
display: flex; gap: 12px; align-items: flex-start; background: rgba(255,255,255,.08);
border: 1px solid rgba(255,255,255,.14); border-radius: 14px; padding: 18px;
transition: transform .28s cubic-bezier(.2,.7,.2,1), background .28s, box-shadow .28s;
}
.hack-target:hover { transform: translateY(-6px); background: rgba(255,255,255,.15); box-shadow: 0 18px 36px rgba(0,0,0,.25); }
.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-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; }
.hack-form > p { font-size: .86rem; color: var(--muted); margin-bottom: 20px; }
.field { margin-bottom: 16px; }
.field label { display: block; font-size: .8rem; font-weight: 600; margin-bottom: 6px; }
.field input, .field textarea {
width: 100%; padding: 12px 14px; border: 1px solid var(--line); border-radius: 12px;
font-family: inherit; font-size: .9rem; background: #fbfaff; color: var(--ink);
transition: border-color .2s, box-shadow .2s, background .2s;
}
.field input:focus, .field textarea:focus { outline: none; border-color: var(--violet); box-shadow: 0 0 0 4px rgba(108,76,224,.14); background: #fff; }
.field textarea { resize: vertical; min-height: 84px; }
.field .err { color: var(--py-red); font-size: .74rem; margin-top: 5px; display: none; }
.field.invalid input, .field.invalid textarea { border-color: var(--py-red); box-shadow: 0 0 0 4px rgba(213,43,30,.1); }
.field.invalid .err { display: block; }
.hack-form .btn { width: 100%; justify-content: center; margin-top: 6px; }
.hack-form .btn:disabled { opacity: .7; cursor: wait; transform: none; }
.form-error { display: none; color: var(--py-red); font-size: .82rem; margin-top: 12px; text-align: center; font-weight: 600; }
.form-error.show { display: block; }
.form-note { font-size: .72rem; color: var(--muted); margin-top: 12px; text-align: center; }
.form-success { display: none; text-align: center; padding: 24px 6px; }
.form-success.show { display: block; animation: pop .45s cubic-bezier(.2,.7,.2,1); }
@keyframes pop { from { transform: scale(.9); opacity: 0; } to { transform: scale(1); opacity: 1; } }
.form-success .ok { width: 64px; height: 64px; border-radius: 50%; background: linear-gradient(135deg, var(--mint), var(--mint-dark)); display: grid; place-items: center; margin: 0 auto 16px; color: #fff; }
.form-success h3 { margin-bottom: 8px; }
.form-success p { font-size: .88rem; color: var(--muted); }
/* ---------- Responsive ---------- */
@media (max-width: 960px) {
.hero-grid { grid-template-columns: 1fr; gap: 40px; }
.hero-visual { height: 400px; max-width: 460px; margin: 0 auto; width: 100%; }
.news-grid { grid-template-columns: repeat(2, 1fr); }
.state-features { grid-template-columns: repeat(2, 1fr); }
.mod-list { grid-template-columns: 1fr; }
.mod-list li:nth-child(odd) { border-right: none; }
.mod-list li:nth-last-child(-n+2) { border-bottom: 1px solid var(--line); }
.mod-list li:last-child { border-bottom: none; }
.hack-grid { grid-template-columns: 1fr; }
.hack-targets { grid-template-columns: 1fr; }
.foot-grid { grid-template-columns: 1fr 1fr; }
}
@media (max-width: 720px) {
nav ul { position: fixed; top: 72px; right: 0; left: 0; flex-direction: column; align-items: stretch;
background: #fff; padding: 18px; gap: 4px; border-bottom: 1px solid var(--line);
transform: translateY(-140%); transition: transform .35s cubic-bezier(.2,.7,.2,1); box-shadow: var(--shadow); }
nav ul.show { transform: translateY(0); }
nav a.link { display: block; padding: 12px 16px; }
.burger { display: block; }
.burger.open span:nth-child(1) { transform: translateY(7px) rotate(45deg); }
.burger.open span:nth-child(2) { opacity: 0; }
.burger.open span:nth-child(3) { transform: translateY(-7px) rotate(-45deg); }
.nav-cta { display: none; }
.news-grid { grid-template-columns: 1fr; }
.state-features { grid-template-columns: 1fr; }
.event { grid-template-columns: 70px 1fr; gap: 16px; padding: 18px; }
.event-date { padding-right: 14px; }
.event-date .d { font-size: 1.5rem; }
.event .badge { grid-column: 2; justify-self: start; margin-top: 6px; }
.hack-box { padding: 34px 24px; }
.hack-form { padding: 24px 20px; }
.foot-grid { grid-template-columns: 1fr; }
section { padding: 54px 0; }
}
@media (prefers-reduced-motion: reduce) {
*, *::before, *::after { animation: none !important; transition: none !important; }
.reveal { opacity: 1; transform: none; }
}
</style>
</head>
<body>
<div class="bg-blobs" aria-hidden="true">
<div class="blob b1"></div>
<div class="blob b2"></div>
<div class="blob b3"></div>
</div>
<!-- ============ NAV ============ -->
<header class="nav" id="nav">
<div class="container nav-inner">
<a href="#top" class="brand">
<span class="logo logo-img"><img src="https://www.odoo-community.org/web/image/3657236-414fdacd/Community%20Badge%20Medium.png" alt="Logo de la Odoo Community Association" /></span>
<span>OCA Paraguay
<small>Comunidad Odoo · Paraguay</small>
</span>
</a>
<nav>
<ul id="menu">
<li><a class="link" href="#estado">Estado Odoo</a></li>
<li><a class="link" href="#hackathon">Hackathon</a></li>
<li><a class="link" href="#noticias">Noticias</a></li>
<li><a class="link" href="#eventos">Eventos</a></li>
</ul>
</nav>
<div class="nav-cta">
<a href="https://www.odoo-community.org/get-involved/become-a-member" class="btn btn-primary" target="_blank" rel="noopener">Hacete miembro de la OCA</a>
</div>
<button class="burger" id="burger" aria-label="Abrir menú" aria-expanded="false">
<span></span><span></span><span></span>
</button>
</div>
</header>
<main id="top">
<!-- ============ HERO ============ -->
<section class="hero">
<div class="container hero-grid">
<div class="hero-copy">
<span class="pill"><span class="dot"></span> Comunidad hispanohablante en crecimiento</span>
<h1>El código abierto se <span class="grad-text">construye en comunidad</span>.</h1>
<p class="lead">
Somos la comunidad paraguaya de la <strong>Odoo Community Association</strong>.
Compartimos módulos, conocimiento y experiencia para que el ERP libre crezca en
Paraguay y en toda Latinoamérica.
</p>
<div class="hero-cta">
<a href="https://www.odoo-community.org/get-involved/become-a-member" class="btn btn-primary" target="_blank" rel="noopener">
Hacete miembro
<svg viewBox="0 0 24 24" width="16" height="16" fill="none" stroke="currentColor" stroke-width="2.2" stroke-linecap="round" stroke-linejoin="round"><path d="M5 12h14M13 6l6 6-6 6"/></svg>
</a>
</div>
<div class="hero-meta">
<div><strong data-count="20000" data-suffix="+">0</strong><span>Módulos OCA</span></div>
<div><strong data-count="62" data-suffix="">0</strong><span>Países</span></div>
<div><strong data-count="1600" data-suffix="+">0</strong><span>Colaboradores</span></div>
</div>
</div>
<div class="hero-visual" aria-hidden="true">
<div class="card-float cf-1">
<div class="cf-ico ico-violet">
<svg viewBox="0 0 24 24" width="19" height="19" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round"><path d="M20 7 12 3 4 7l8 4 8-4Z"/><path d="m4 12 8 4 8-4M4 17l8 4 8-4"/></svg>
</div>
<h4>+20.000 módulos</h4>
<p>Probados y mantenidos por la comunidad, listos para Paraguay.</p>
</div>
<div class="card-float cf-2">
<div class="cf-ico ico-mint">
<svg viewBox="0 0 24 24" width="19" height="19" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path d="M16 3.13a4 4 0 0 1 0 7.75"/><path d="M21 21v-2a4 4 0 0 0-3-3.87"/><circle cx="9" cy="7" r="4"/><path d="M3 21v-2a4 4 0 0 1 4-4h4a4 4 0 0 1 2 .54"/></svg>
</div>
<h4>Peer review real</h4>
<p>No reinventés la rueda: extendé y colaborá.</p>
<div class="progress"><i></i></div>
</div>
<div class="card-float cf-3">
<div class="cf-ico ico-plum">
<svg viewBox="0 0 24 24" width="19" height="19" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path d="M12 2 4 6v6c0 5 3.4 8.5 8 10 4.6-1.5 8-5 8-10V6l-8-4Z"/><path d="m9 12 2 2 4-4"/></svg>
</div>
<h4>100% open source</h4>
<p>Independiente del editor. Licencia AGPL garantizada.</p>
</div>
</div>
</div>
</section>
<!-- ============ ESTADO ODOO CE PY ============ -->
<section id="estado">
<div class="container">
<div class="sec-head reveal">
<span class="kicker">Estado actual</span>
<h2>Odoo Community en Paraguay, hoy</h2>
<p>Un panorama del repositorio oficial <strong>OCA/l10n-paraguay</strong>, la localización de Odoo Community mantenida por la comunidad para el país.</p>
</div>
<div class="state-features reveal">
<div class="fact">
<span class="fi ico-violet"><svg viewBox="0 0 24 24" width="19" height="19" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path d="M9 19c-5 1.5-5-2.5-7-3m14 6v-3.9a3.4 3.4 0 0 0-.9-2.6c3-.3 6.2-1.5 6.2-6.7A5.2 5.2 0 0 0 20 5.8a4.9 4.9 0 0 0-.1-3.5s-1.1-.3-3.6 1.4a12.3 12.3 0 0 0-6.6 0C7.2 2 6.1 2.3 6.1 2.3A4.9 4.9 0 0 0 6 5.8a5.2 5.2 0 0 0-1.4 3.6c0 5.2 3.2 6.4 6.2 6.7A3.4 3.4 0 0 0 10 18.7V22"/></svg></span>
<div>
<h4>Localización oficial bajo el ala de la OCA</h4>
<p>El repo <code>OCA/l10n-paraguay</code> agrupa la localización paraguaya y se distribuye bajo licencia <strong>AGPL-3.0</strong>.</p>
</div>
</div>
<div class="fact">
<span class="fi ico-plum"><svg viewBox="0 0 24 24" width="19" height="19" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path d="M6 3v12"/><circle cx="18" cy="6" r="3"/><circle cx="6" cy="18" r="3"/><path d="M18 9a9 9 0 0 1-9 9"/></svg></span>
<div>
<h4>Rama activa: <code>19.0</code></h4>
<p>La localización ya cubre <strong>Odoo 19</strong>. Avanzar hacia <code>20.0</code> es el próximo gran desafío de la comunidad.</p>
</div>
</div>
<div class="fact">
<span class="fi ico-mint"><svg viewBox="0 0 24 24" width="19" height="19" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path d="M4 4h16v16H4z"/><path d="M8 9h8M8 13h8M8 17h5"/></svg></span>
<div>
<h4>Base contable local</h4>
<p>Plan contable, impuestos y datos base del Paraguay viven en <code>l10n_py</code> y <code>l10n_py_base</code>, con extensiones en <code>l10n_py_account</code>.</p>
</div>
</div>
<div class="fact">
<span class="fi ico-violet"><svg viewBox="0 0 24 24" width="19" height="19" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path d="M14 2H6a2 2 0 0 0-2 2v16a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2V8l-6-6Z"/><path d="M14 2v6h6M9 15l2 2 4-4"/></svg></span>
<div>
<h4>Facturación electrónica SIFEN</h4>
<p>Los módulos <code>l10n_py_edi_base</code> y <code>l10n_py_edi_sifen</code> permiten la <strong>transmisión directa al SIFEN</strong> usando la librería <code>pysifen</code>.</p>
</div>
</div>
</div>
<div class="mod-panel reveal" style="transition-delay:.1s">
<div class="mod-head">
<h3>Módulos disponibles</h3>
<span class="branch-pill"><span class="dot"></span> Rama activa: 19.0</span>
</div>
<ul class="mod-list">
<li>
<div><span class="name">l10n_py</span><div class="desc">Localización contable para Paraguay</div></div>
<span class="ver">19.0.1.0.1</span>
</li>
<li>
<div><span class="name">l10n_py_account</span><div class="desc">Extensiones contables para la localización de Paraguay</div></div>
<span class="ver">19.0.1.1.0</span>
</li>
<li>
<div><span class="name">l10n_py_base</span><div class="desc">Datos base de localización para Paraguay</div></div>
<span class="ver">19.0.1.0.0</span>
</li>
<li>
<div><span class="name">l10n_py_edi_base</span><div class="desc">Módulo base para facturación electrónica en Paraguay</div></div>
<span class="ver">19.0.1.0.0</span>
</li>
<li>
<div><span class="name">l10n_py_edi_sifen</span><div class="desc">Transmisión directa al SIFEN vía librería pysifen</div></div>
<span class="ver">19.0.1.0.0</span>
</li>
<li>
<div><span class="name">l10n_py_libros</span><div class="desc">Registro de comprobantes Ventas/Compras/Ingresos/Egresos (DNIT)</div></div>
<span class="ver">19.0.1.0.0</span>
</li>
<li>
<div><span class="name">l10n_py_maquila_base</span><div class="desc">Módulo base para el régimen de maquila (Ley 7547/2025)</div></div>
<span class="ver">19.0.1.0.0</span>
</li>
<li>
<div><span class="name">l10n_py_maquila_mrp</span><div class="desc">Coeficientes de lista de materiales (BOM), cálculo de VAN y gestión de desperdicios</div></div>
<span class="ver">19.0.1.0.0</span>
</li>
<li>
<div><span class="name">l10n_py_maquila_ops</span><div class="desc">Admisión temporaria, exportación, garantías y operaciones fiscales para maquila</div></div>
<span class="ver">19.0.1.0.0</span>
</li>
<li>
<div><span class="name">l10n_py_maquila_report</span><div class="desc">Reportes CNIME, dashboard, extensión SIFEN y SIMEX para maquila</div></div>
<span class="ver">19.0.1.0.0</span>
</li>
</ul>
<div class="mod-foot"><strong>Help wanted:</strong> la rama <code>19.0</code> ya está activa — sumate a mantener los módulos y a preparar la migración a <code>20.0</code>. <a href="https://github.com/OCA/l10n-paraguay" target="_blank" rel="noopener">Colaborá en GitHub →</a><br /><br />Un agradecimiento especial a <a href="https://kmee.com.br/" target="_blank" rel="noopener">KMEE</a> y su equipo por mantener la localización paraguaya.</div>
</div>
</div>
</section>
<!-- ============ HACKATHON ============ -->
<section id="hackathon">
<div class="container">
<div class="hack-box reveal">
<div class="hack-inner">
<div class="hack-grid">
<div class="hack-copy">
<span class="hack-badge"><span class="dot"></span> Online · Internacional · Gratis</span>
<h2>Hackathon de <span class="grad-text">Internacionalización</span> para Paraguay</h2>
<p>
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.
</p>
<div class="hack-dates">
<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><rect x="3" y="4" width="18" height="18" rx="2"/><path d="M16 2v4M8 2v4M3 10h18"/></svg>
12 y 14 de noviembre de 2026
</div>
<div class="countdown" id="countdown" aria-label="Cuenta regresiva al hackathon">
<div class="cd-unit"><strong id="cd-days">--</strong><span>Días</span></div>
<div class="cd-unit"><strong id="cd-hours">--</strong><span>Horas</span></div>
<div class="cd-unit"><strong id="cd-mins">--</strong><span>Min</span></div>
<div class="cd-unit"><strong id="cd-secs">--</strong><span>Seg</span></div>
</div>
</div>
<div class="hack-form">
<form id="hack-form" novalidate>
<h3>Inscribite al hackathon</h3>
<p>Dejanos tus datos y te avisamos antes del evento. Cupos abiertos para todos los niveles.</p>
<div class="field" id="f-name">
<label for="name">Nombre completo</label>
<input type="text" id="name" name="name" placeholder="Tu nombre" autocomplete="name" required />
<span class="err">Ingresá tu nombre.</span>
</div>
<div class="field" id="f-github">
<label for="github">Usuario de GitHub</label>
<input type="text" id="github" name="github" placeholder="@tu-usuario" autocomplete="off" required />
<span class="err">Ingresá tu usuario de GitHub.</span>
</div>
<div class="field" id="f-email">
<label for="email">Email</label>
<input type="email" id="email" name="email" placeholder="tu@email.com" autocomplete="email" required />
<span class="err">Ingresá un email válido.</span>
</div>
<div class="field" id="f-desc">
<label for="desc">Contanos brevemente cómo podés aportar</label>
<textarea id="desc" name="desc" placeholder="Ej.: puedo migrar módulos a Odoo 19, escribir tests o traducir cadenas al español de Paraguay." required></textarea>
<span class="err">Contanos brevemente tu aporte.</span>
</div>
<button type="submit" class="btn btn-primary" id="hack-submit">
Quiero inscribirme
<svg viewBox="0 0 24 24" width="16" height="16" fill="none" stroke="currentColor" stroke-width="2.2" stroke-linecap="round" stroke-linejoin="round"><path d="M5 12h14M13 6l6 6-6 6"/></svg>
</button>
<p class="form-error" id="form-error">No pudimos enviar tu inscripción. Revisá tu conexión e intentá de nuevo.</p>
<p class="form-note">Tus datos solo se usan para coordinar el hackathon.</p>
</form>
<div class="form-success" id="form-success" role="status" aria-live="polite">
<div class="ok">
<svg viewBox="0 0 24 24" width="30" height="30" fill="none" stroke="currentColor" stroke-width="2.6" stroke-linecap="round" stroke-linejoin="round"><path d="m5 13 4 4L19 7"/></svg>
</div>
<h3>¡Inscripción recibida!</h3>
<p>Gracias, <strong id="success-name">colega</strong>. Te vamos a contactar por email con los detalles del hackathon del 12 y 14 de noviembre de 2026.</p>
</div>
</div>
</div>
<div class="hack-goals">
<h3>Nuestros Objetivos</h3>
<div class="hack-targets">
<div class="hack-target">
<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2.2" stroke-linecap="round" stroke-linejoin="round"><path d="M21 2v6h-6"/><path d="M3 12a9 9 0 0 1 15-6.7L21 8"/><path d="M3 22v-6h6"/><path d="M21 12a9 9 0 0 1-15 6.7L3 16"/></svg>
<div>
<h4>Actualización de módulos a Odoo 19 y 20</h4>
<p>Consolidar la rama 19.0 y avanzar hacia las versiones más recientes del ERP.</p>
</div>
</div>
<div class="hack-target">
<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2.2" stroke-linecap="round" stroke-linejoin="round"><path d="M12 2v20M2 12h20"/><circle cx="12" cy="12" r="9"/></svg>
<div>
<h4>Nuevas funcionalidades (Feature add)</h4>
<p>Incorporar features que la comunidad paraguaya necesita en su día a día.</p>
</div>
</div>
<div class="hack-target">
<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2.2" stroke-linecap="round" stroke-linejoin="round"><path d="M9 11l3 3L22 4"/><path d="M21 12v7a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2V5a2 2 0 0 1 2-2h11"/></svg>
<div>
<h4>Testing y documentación</h4>
<p>Pruebas, cobertura y guías claras para que más gente adopte Odoo en Paraguay.</p>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
</section>
<!-- ============ NEWS ============ -->
<section id="noticias">
<div class="container">
<div class="sec-head reveal">
<span class="kicker">Noticias</span>
<h2>Lo último de la OCA y de la escena local</h2>
<p>Novedades de la comunidad internacional y de nuestro capítulo paraguayo.</p>
</div>
<div class="news-grid">
<a class="news-card reveal" href="https://odoo-community.org/blog/news-updates-1/oca-days-2026-240" target="_blank" rel="noopener">
<div class="news-top nt-1">
<span class="tag">Evento global</span>
<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.7" stroke-linecap="round" stroke-linejoin="round"><rect x="3" y="4" width="18" height="18" rx="2"/><path d="M16 2v4M8 2v4M3 10h18"/></svg>
</div>
<div class="news-body">
<div class="news-date">21 – 23 de septiembre, 2026</div>
<h3>OCA Days 2026 vuelve a Liège</h3>
<p>El encuentro anual de la OCA reúne a miembros de todo el mundo para colaborar, intercambiar conocimiento y ampliar la red. Ya está abierta la inscripción.</p>
<span class="more">Leer en la OCA <svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2.4" stroke-linecap="round" stroke-linejoin="round"><path d="M7 17 17 7M9 7h8v8"/></svg></span>
</div>
</a>
<a class="news-card reveal" style="transition-delay:.08s" href="https://odoo-community.org/blog/news-updates-1/the-new-oca-apps-store-is-online-247" target="_blank" rel="noopener">
<div class="news-top nt-2">
<span class="tag">Apps Store</span>
<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.7" stroke-linecap="round" stroke-linejoin="round"><path d="M3 3h7v7H3zM14 3h7v7h-7zM14 14h7v7h-7zM3 14h7v7H3z"/></svg>
</div>
<div class="news-body">
<div class="news-date">Julio 2026</div>
<h3>Nueva Apps Store de la OCA ya está online</h3>
<p>La nueva plataforma de módulos es más que una tienda: integra búsqueda mejorada, perfiles y mucha más información para elegir el módulo correcto.</p>
<span class="more">Leer en la OCA <svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2.4" stroke-linecap="round" stroke-linejoin="round"><path d="M7 17 17 7M9 7h8v8"/></svg></span>
</div>
</a>
<a class="news-card reveal" style="transition-delay:.16s" href="https://odoo-community.org/blog/news-updates-1/new-ai-policy-248" target="_blank" rel="noopener">
<div class="news-top nt-3">
<span class="tag">Gobernanza</span>
<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.7" stroke-linecap="round" stroke-linejoin="round"><rect x="4" y="4" width="16" height="16" rx="3"/><path d="M9 9h6v6H9zM9 2v2M15 2v2M9 20v2M15 20v2M2 9h2M2 15h2M20 9h2M20 15h2"/></svg>
</div>
<div class="news-body">
<div class="news-date">Agosto 2026</div>
<h3>Nueva Política de IA de la OCA</h3>
<p>El grupo de gobernanza publicó una política para ordenar las contribuciones asistidas por IA y mantener la sostenibilidad de las revisiones de código.</p>
<span class="more">Leer en la OCA <svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2.4" stroke-linecap="round" stroke-linejoin="round"><path d="M7 17 17 7M9 7h8v8"/></svg></span>
</div>
</a>
<a class="news-card reveal" href="#eventos">
<div class="news-top nt-4">
<span class="tag">Paraguay</span>
<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.7" stroke-linecap="round" stroke-linejoin="round"><path d="M12 2 2 7l10 5 10-5-10-5ZM2 17l10 5 10-5M2 12l10 5 10-5"/></svg>
</div>
<div class="news-body">
<div class="news-date">Comunidad local</div>
<h3>Primer sprint OCA Paraguay en Asunción</h3>
<p>Arrancamos con un encuentro presencial para localizar módulos clave y sumar colaboradores paraguayos al ecosistema internacional.</p>
<span class="more">Anotate <svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2.4" stroke-linecap="round" stroke-linejoin="round"><path d="M5 12h14M13 6l6 6-6 6"/></svg></span>
</div>
</a>
<a class="news-card reveal" style="transition-delay:.08s" href="https://odoo-community.org/blog/news-updates-1/list-of-must-have-stock-oca-modules-249" target="_blank" rel="noopener">
<div class="news-top nt-2">
<span class="tag">Recursos</span>
<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.7" stroke-linecap="round" stroke-linejoin="round"><path d="M4 19.5A2.5 2.5 0 0 1 6.5 17H20"/><path d="M6.5 2H20v20H6.5A2.5 2.5 0 0 1 4 19.5v-15A2.5 2.5 0 0 1 6.5 2Z"/></svg>
</div>
<div class="news-body">
<div class="news-date">Julio 2026</div>
<h3>Lista de módulos "Must Have" de Stock</h3>
<p>La OCA publicó su selección de módulos imprescindibles para inventario y productos, una base ideal para cualquier implementación.</p>
<span class="more">Leer en la OCA <svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2.4" stroke-linecap="round" stroke-linejoin="round"><path d="M7 17 17 7M9 7h8v8"/></svg></span>
</div>
</a>
<a class="news-card reveal" style="transition-delay:.16s" href="https://github.com/OCA" target="_blank" rel="noopener">
<div class="news-top nt-1">
<span class="tag">Contribución</span>
<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.7" stroke-linecap="round" stroke-linejoin="round"><circle cx="12" cy="12" r="10"/><path d="M12 8v8M8 12h8"/></svg>
</div>
<div class="news-body">
<div class="news-date">Siempre abierto</div>
<h3>Cómo contribuir tu primer módulo</h3>
<p>Forkeá, creá tu rama por versión, seguí las guías de estilo y abrí un Pull Request. La comunidad te acompaña en cada revisión.</p>
<span class="more">Empezar ahora <svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2.4" stroke-linecap="round" stroke-linejoin="round"><path d="M7 17 17 7M9 7h8v8"/></svg></span>
</div>
</a>
</div>
</div>
</section>
<!-- ============ EVENTS ============ -->
<section id="eventos" class="events">
<div class="container">
<div class="sec-head reveal">
<span class="kicker">Eventos</span>
<h2>Próximos encuentros</h2>
<p>Webinars globales, sesiones de soporte y encuentros presenciales de la comunidad OCA.</p>
</div>
<div class="event-list">
<a class="event reveal" href="https://odoo-community.org/event/oca-ai-psc-oca-ai-modules-alignment-meeting-273" target="_blank" rel="noopener">
<div class="event-date"><div class="d">26</div><div class="m">OCT</div></div>
<div class="event-info">
<h3>OCA AI PSC — Reunión de alineación de módulos de IA</h3>
<p>Encuentro del grupo de trabajo de IA de la OCA para alinear el desarrollo de los módulos de inteligencia artificial.</p>
<span class="loc"><svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><circle cx="12" cy="12" r="10"/><path d="M2 12h20M12 2a15 15 0 0 1 0 20"/></svg> Online · Evento OCA</span>
<span class="event-cta">Ver evento en la OCA <svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2.2" stroke-linecap="round" stroke-linejoin="round"><path d="M7 17 17 7M9 7h8v8"/></svg></span>
</div>
<span class="badge">OCA</span>
</a>
<a class="event reveal" style="transition-delay:.06s" href="https://odoo-community.org/event/webinar-how-to-search-for-an-oca-module-271" target="_blank" rel="noopener">
<div class="event-date"><div class="d">05</div><div class="m">NOV</div></div>
<div class="event-info">
<h3>Webinar | Cómo buscar un módulo de la OCA</h3>
<p>Aprendé a encontrar el módulo adecuado entre los miles disponibles en la nueva Apps Store de la OCA.</p>
<span class="loc"><svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><circle cx="12" cy="12" r="10"/><path d="M2 12h20M12 2a15 15 0 0 1 0 20"/></svg> Online · Sesión en vivo</span>
<span class="event-cta">Ver evento en la OCA <svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2.2" stroke-linecap="round" stroke-linejoin="round"><path d="M7 17 17 7M9 7h8v8"/></svg></span>
</div>
<span class="badge">Webinar</span>
</a>
<a class="event reveal" style="transition-delay:.12s" href="https://odoo-community.org/event/oca-support-group-session-consultants-265" target="_blank" rel="noopener">
<div class="event-date"><div class="d">12</div><div class="m">NOV</div></div>
<div class="event-info">
<h3>Sesión de Soporte OCA | Consultores</h3>
<p>Espacio abierto para llevar tus dudas técnicas y funcionales ante la comunidad internacional.</p>
<span class="loc"><svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><circle cx="12" cy="12" r="10"/><path d="M2 12h20M12 2a15 15 0 0 1 0 20"/></svg> Online · Grupo de consultores</span>
<span class="event-cta">Ver evento en la OCA <svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2.2" stroke-linecap="round" stroke-linejoin="round"><path d="M7 17 17 7M9 7h8v8"/></svg></span>
</div>
<span class="badge">Soporte</span>
</a>
<a class="event reveal" style="transition-delay:.18s" href="https://odoo-community.org/event/oca-netherlands-code-sprint-local-meetup-274" target="_blank" rel="noopener">
<div class="event-date"><div class="d">13</div><div class="m">NOV</div></div>
<div class="event-info">
<h3>OCA Netherlands | Code Sprint &amp; Meetup local</h3>
<p>Jornada de sprint de código y encuentro presencial de la comunidad neerlandesa de la OCA.</p>
<span class="loc"><svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path d="M20 10c0 6-8 12-8 12S4 16 4 10a8 8 0 0 1 16 0Z"/><circle cx="12" cy="10" r="3"/></svg> Tilburg, Países Bajos</span>
<span class="event-cta">Ver evento en la OCA <svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2.2" stroke-linecap="round" stroke-linejoin="round"><path d="M7 17 17 7M9 7h8v8"/></svg></span>
</div>
<span class="badge presencial">Presencial</span>
</a>
<a class="event reveal" style="transition-delay:.24s" href="https://odoo-community.org/event/webinar-oca-modules-field-service-part-1-269" target="_blank" rel="noopener">
<div class="event-date"><div class="d">19</div><div class="m">NOV</div></div>
<div class="event-info">
<h3>Webinar | Módulos OCA — Field Service (Parte 1)</h3>
<p>Primera parte del recorrido por los módulos de servicio en terreno (Field Service) de la OCA.</p>
<span class="loc"><svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><circle cx="12" cy="12" r="10"/><path d="M2 12h20M12 2a15 15 0 0 1 0 20"/></svg> Online · Sesión en vivo</span>
<span class="event-cta">Ver evento en la OCA <svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2.2" stroke-linecap="round" stroke-linejoin="round"><path d="M7 17 17 7M9 7h8v8"/></svg></span>
</div>
<span class="badge">Webinar</span>
</a>
<a class="event reveal" style="transition-delay:.3s" href="https://odoo-community.org/event/oca-day-finland-2026-267" target="_blank" rel="noopener">
<div class="event-date"><div class="d">27</div><div class="m">NOV</div></div>
<div class="event-info">
<h3>OCA Day Finland 2026</h3>
<p>Encuentro anual de la comunidad OCA de Finlandia, con charlas y networking entre miembros.</p>
<span class="loc"><svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path d="M20 10c0 6-8 12-8 12S4 16 4 10a8 8 0 0 1 16 0Z"/><circle cx="12" cy="10" r="3"/></svg> Tampere, Finlandia</span>
<span class="event-cta">Ver evento en la OCA <svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2.2" stroke-linecap="round" stroke-linejoin="round"><path d="M7 17 17 7M9 7h8v8"/></svg></span>
</div>
<span class="badge presencial">Presencial</span>
</a>
<a class="event reveal" style="transition-delay:.36s" href="https://odoo-community.org/event/webinar-oca-modules-field-service-part-2-270" target="_blank" rel="noopener">
<div class="event-date"><div class="d">03</div><div class="m">DIC</div></div>
<div class="event-info">
<h3>Webinar | Módulos OCA — Field Service (Parte 2)</h3>
<p>Continuación del recorrido por los módulos de servicio en terreno (Field Service) de la OCA.</p>
<span class="loc"><svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><circle cx="12" cy="12" r="10"/><path d="M2 12h20M12 2a15 15 0 0 1 0 20"/></svg> Online · Sesión en vivo</span>
<span class="event-cta">Ver evento en la OCA <svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2.2" stroke-linecap="round" stroke-linejoin="round"><path d="M7 17 17 7M9 7h8v8"/></svg></span>
</div>
<span class="badge">Webinar</span>
</a>
<a class="event reveal" style="transition-delay:.42s" href="https://odoo-community.org/event/webinar-oca-modules-must-have-for-stock-products-263" target="_blank" rel="noopener">
<div class="event-date"><div class="d">17</div><div class="m">DIC</div></div>
<div class="event-info">
<h3>Webinar | Módulos OCA "Must Have" para Stock/Productos</h3>
<p>Recorrido práctico por los módulos de Stock y Productos que toda implementación debería conocer.</p>
<span class="loc"><svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><circle cx="12" cy="12" r="10"/><path d="M2 12h20M12 2a15 15 0 0 1 0 20"/></svg> Online · Sesión en vivo</span>
<span class="event-cta">Ver evento en la OCA <svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2.2" stroke-linecap="round" stroke-linejoin="round"><path d="M7 17 17 7M9 7h8v8"/></svg></span>
</div>
<span class="badge">Webinar</span>
</a>
</div>
</div>
</section>
</main>
<!-- ============ FOOTER ============ -->
<footer>
<div class="container">
<div class="foot-grid">
<div class="foot-brand">
<a href="#top" class="brand">
<span class="logo logo-img"><img src="https://www.odoo-community.org/web/image/3657236-414fdacd/Community%20Badge%20Medium.png" alt="Logo de la Odoo Community Association" /></span>
<span>OCA Paraguay<small>Comunidad Odoo · Paraguay</small></span>
</a>
<p>Comunidad paraguaya de la Odoo Community Association. Construimos, traducimos y compartimos software libre para ERP en toda Latinoamérica.</p>
</div>
<div>
<h5>OCA global</h5>
<ul>
<li><a href="https://odoo-community.org" target="_blank" rel="noopener">ODOO Community Association</a></li>
<li><a href="https://github.com/OCA/l10n-paraguay" target="_blank" rel="noopener">Github OCA PY</a></li>
<li><a href="https://oc-guy.com" target="_blank" rel="noopener">The OC Guy</a></li>
</ul>
</div>
<div>
<h5>Sponsor</h5>
<ul>
<li><a href="https://ODOO4projects.com" target="_blank" rel="noopener">ODOO CE Hosting in LATAM</a></li>
</ul>
</div>
</div>
<div class="flag-strip" aria-hidden="true"></div>
<div class="foot-bottom" style="margin-top:24px;">
<span>© <span id="year">2026</span> ODOO4projects LLC</span>
<span>Hecho con ♥ y software libre · Odoo y OCA son marcas de sus respectivos titulares.</span>
</div>
</div>
</footer>
<script>
// Sticky nav shadow
const nav = document.getElementById('nav');
const onScroll = () => nav.classList.toggle('scrolled', window.scrollY > 12);
window.addEventListener('scroll', onScroll, { passive: true });
onScroll();
// Mobile menu
const burger = document.getElementById('burger');
const menu = document.getElementById('menu');
burger.addEventListener('click', () => {
const open = menu.classList.toggle('show');
burger.classList.toggle('open', open);
burger.setAttribute('aria-expanded', String(open));
});
menu.querySelectorAll('a').forEach(a => a.addEventListener('click', () => {
menu.classList.remove('show');
burger.classList.remove('open');
burger.setAttribute('aria-expanded', 'false');
}));
// Reveal on scroll
const io = new IntersectionObserver((entries) => {
entries.forEach(e => { if (e.isIntersecting) { e.target.classList.add('in'); io.unobserve(e.target); } });
}, { threshold: 0.12, rootMargin: '0px 0px -60px 0px' });
document.querySelectorAll('.reveal').forEach(el => io.observe(el));
// Animated counters
const counters = document.querySelectorAll('[data-count]');
const cio = new IntersectionObserver((entries) => {
entries.forEach(e => {
if (!e.isIntersecting) return;
const el = e.target;
const target = parseInt(el.dataset.count, 10);
const suffix = el.dataset.suffix || '';
const duration = 1400;
const start = performance.now();
const tick = (now) => {
const p = Math.min((now - start) / duration, 1);
const eased = 1 - Math.pow(1 - p, 3);
const val = Math.round(target * eased);
el.textContent = val.toLocaleString('es-PY') + suffix;
if (p < 1) requestAnimationFrame(tick);
};
requestAnimationFrame(tick);
cio.unobserve(el);
});
}, { threshold: 0.4 });
counters.forEach(c => cio.observe(c));
// Year
document.getElementById('year').textContent = new Date().getFullYear();
// Subtle parallax on hero cards
const visual = document.querySelector('.hero-visual');
if (visual && !window.matchMedia('(prefers-reduced-motion: reduce)').matches) {
const cards = visual.querySelectorAll('.card-float');
visual.addEventListener('mousemove', (e) => {
const r = visual.getBoundingClientRect();
const x = (e.clientX - r.left) / r.width - 0.5;
const y = (e.clientY - r.top) / r.height - 0.5;
cards.forEach((c, i) => {
const depth = (i + 1) * 8;
c.style.transform = `translate3d(${x * depth}px, ${y * depth}px, 0)`;
});
});
visual.addEventListener('mouseleave', () => {
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'));
});
}
</script>
</body>
</html>