Vásquez Pérez Abogados
Academia Legal
Bienvenido de vuelta
Accede a tu perfil de Academia Legal.
¿Sin cuenta? Regístrate gratis
Academia Legal
0% leído
Consorcios y uniones temporales Colombia
Academia Legal
Derecho de la Infraestructura

Claves jurídicas para estructurar consorcios y uniones temporales

12 de febrero de 2025
11
Puntos
7 min
Lectura
2025
Publicado
Juan Simón Vásquez Pérez
Juan Simón Vásquez Pérez
Socio · Vásquez Pérez Abogados
Análisis · 7 min
¿No eres abogado?
Tenemos una versión más clara para ti.
Escuchar
Voz femenina · Accesibilidad

Los consorcios y uniones temporales son figuras frecuentes en la contratación pública y en proyectos de infraestructura en Colombia. Su aparente simplicidad esconde una complejidad jurídica que, cuando no se gestiona bien, genera conflictos costosos. Aquí están las claves esenciales para comprender y estructurar correctamente estas figuras.

1

No son personas jurídicas

Ni el consorcio ni la unión temporal tienen personalidad jurídica propia en Colombia. No pueden demandar ni ser demandados en nombre propio, no tienen patrimonio autónomo ni RUT. Son acuerdos de colaboración entre personas jurídicas o naturales que actúan coordinadamente para un propósito específico.

2

El régimen interno no está regulado por ley

El Estatuto de Contratación solo regula los efectos externos del consorcio o la unión temporal. Todo lo interno —distribución de utilidades, toma de decisiones, responsabilidad entre miembros, solución de conflictos— queda en manos del acuerdo de constitución. Sin un acuerdo bien redactado, los conflictos internos son casi irresolubles eficientemente.

Característica Consorcio Unión Temporal
Responsabilidad Solidaria total Proporcional a la participación
Personalidad jurídica No tiene No tiene
Sanciones y multas Solidaria Según participación pactada
Uso recomendado Obras simples o conjuntas Proyectos con roles diferenciados
Riesgo para el integrante Alto — responde por todos Medio — responde por su parte
3

El representante es mandatario, no director

El representante designado actúa como mandatario de los miembros frente a la entidad contratante. Sus facultades deben estar expresamente definidas. Un acto del representante que exceda sus facultades puede comprometer a todos los miembros sin su consentimiento, con consecuencias patrimoniales serias.

4

Capacidad contractual limitada

El consorcio o la unión temporal tiene capacidad para ejecutar el contrato estatal para el que fue constituido. Para cualquier otra actuación jurídica, los miembros deben actuar individualmente. Esta limitación tiene implicaciones prácticas en la gestión de cuentas bancarias, adquisición de equipos y subcontratación.

5

Capacidad procesal debatida

El Consejo de Estado ha debatido si los consorcios pueden comparecer directamente ante los tribunales administrativos. La postura mayoritaria admite esta capacidad para controversias derivadas del contrato, pero la cuestión no está absolutamente zanjada. El acuerdo de constitución debe prever la representación en litigios.

6

Relación externa e interna son planos distintos

La relación externa —con la entidad contratante— se rige por el derecho público. La relación interna —entre los miembros— se rige por el derecho civil y comercial. Confundir estos planos es el error más frecuente en la práctica de estos negocios. Lo que se acuerde con la entidad no necesariamente vincula internamente a los socios, y viceversa.

7

La cláusula de solución de conflictos es indispensable

Sin una cláusula expresa de resolución de disputas, los conflictos internos van a la justicia ordinaria civil: lenta, costosa y poco adecuada para un proyecto de infraestructura en ejecución. El arbitraje es la alternativa recomendada y debe pactarse desde el inicio en el acuerdo de constitución.

8

Consorcio vs. unión temporal: la diferencia es la responsabilidad

En el consorcio, todos los miembros son solidariamente responsables por las obligaciones del grupo. En la unión temporal, cada miembro responde solo por las obligaciones correspondientes a su participación. Esta diferencia tiene implicaciones financieras y de riesgo muy concretas y debe orientar la elección de figura desde el inicio.

9

Las modificaciones del porcentaje requieren autorización

Cambiar la participación de un miembro durante la ejecución del contrato requiere autorización expresa de la entidad contratante. Una modificación no autorizada puede constituir infracción al régimen de inhabilidades e incompatibilidades y dar lugar a sanciones o declaratoria de incumplimiento.

10

El acuerdo de constitución es un documento estratégico

No es una formalidad. Es el documento que define los derechos y obligaciones entre los miembros durante toda la ejecución del contrato. Incluye: distribución de responsabilidades y recursos, mecanismos de toma de decisiones, reglas para aportes adicionales, condiciones de salida y, crucialmente, la cláusula de arbitraje.

11

Las obligaciones tributarias son de los miembros, no del grupo

El consorcio o la unión temporal no tributa como persona jurídica. Son sus miembros quienes declaran individualmente sus ingresos y costos en proporción a su participación. Sin embargo, el grupo tiene obligaciones de retención en la fuente y de información tributaria que no pueden ignorarse bajo pena de sanciones fiscales.

Conclusión

Estructurar bien un consorcio o una unión temporal no es una formalidad pre-contrato: es una inversión estratégica con consecuencias financieras, operativas y legales que se extienden durante toda la ejecución. El mejor momento para acordar las reglas internas es antes de que surja cualquier conflicto. Cuando ya hay litigio, el margen de maniobra se reduce drásticamente.

Comparte si te fue útil
Descarga el PDF completo — disponible para miembros registrados
Comentarios

Regístrate para dejar un comentario y unirte a la conversación.

¿Tiene una pregunta legal?

Nuestro equipo responde con claridad y estrategia real.

Consultar ahora
'; w.document.write(html); w.document.close(); } // ── Visit counter (localStorage simulation) ──────────────── // For production: replace with a real endpoint like POST /api/track-visit function trackVisit(slug) { // CountAPI: real global counter, no signup required // Increments once per session to avoid refresh inflation var sessKey = 'vp_hit_' + slug; var endpoint = sessionStorage.getItem(sessKey) ? 'https://api.countapi.xyz/get/vasquezperez-academia/' + slug : 'https://api.countapi.xyz/hit/vasquezperez-academia/' + slug; if(!sessionStorage.getItem(sessKey)){ try { sessionStorage.setItem(sessKey,'1'); } catch(e){} } fetch(endpoint) .then(function(r){ return r.json(); }) .then(function(d){ if(d && typeof d.value === 'number'){ var vc = document.getElementById('visitCounter'); var vn = document.getElementById('visitCount'); if(vc && vn){ vn.textContent = d.value >= 1000 ? (d.value/1000).toFixed(1).replace('.0','')+'k' : d.value.toString(); vc.style.display = 'inline-flex'; } } }) .catch(function(){ // CountAPI unavailable — hide counter rather than show fake number var vc = document.getElementById('visitCounter'); if(vc) vc.style.display = 'none'; }); } // ══════════════════════════════════════════════════════════════════════ // SHARED ARTICLE ENHANCEMENTS // ══════════════════════════════════════════════════════════════════════ // ── SESSION / USER STATE ─────────────────────────────────────────────── var vpSession = (function() { try { return JSON.parse(localStorage.getItem('vp_user') || 'null'); } catch(e) { return null; } })(); function saveSession(user) { vpSession = user; try { localStorage.setItem('vp_user', JSON.stringify(user)); } catch(e) {} } function clearSession() { vpSession = null; try { localStorage.removeItem('vp_user'); } catch(e) {} } function isLoggedIn() { return !!vpSession; } function isAdmin() { return vpSession && vpSession.role === 'admin'; } // ── ACCORDION POINTS ─────────────────────────────────────────────────── // ── FEMALE VOICE AUDIO ───────────────────────────────────────────────── var _isPlaying = false; var _utterance = null; function _getFemalVoice(lang) { var voices = (window.speechSynthesis && window.speechSynthesis.getVoices()) || []; var lc = (lang === 'en') ? 'en' : 'es'; var scored = voices.map(function(v) { var s = 0, n = v.name.toLowerCase(), vl = (v.lang || '').toLowerCase(); if (vl.indexOf(lc) === 0) s += 20; var fem = ['lucia','paulina','monica','clara','paloma','sofia','elena','maria','laura','sara','karen','victoria','female','mujer','google español']; if (fem.some(function(f){ return n.indexOf(f) >= 0; })) s += 30; var mal = ['jorge','carlos','diego','antonio','juan','francisco','male','hombre']; if (mal.some(function(m){ return n.indexOf(m) >= 0; })) s -= 15; if (!v.localService) s += 5; return { v: v, s: s }; }); scored.sort(function(a,b){ return b.s - a.s; }); return scored.length ? scored[0].v : null; } function _updateAudioUI(playing) { var btn = document.getElementById('audioPlayBtn') || document.getElementById('audioCtrlBtn'); var note = document.getElementById('audioNoteEl'); var wave = document.getElementById('waveformEl'); var icon = document.getElementById('audioIconSvg') || document.getElementById('audioPlayIcon'); if (btn) btn.classList.toggle('playing', playing); if (wave) wave.style.display = playing ? 'flex' : 'none'; if (icon) icon.style.display = playing ? 'none' : ''; if (note && !playing) note.textContent = 'Voz femenina · Accesibilidad'; } function toggleAudio() { if (!('speechSynthesis' in window)) { artToast('Tu navegador no soporta lectura en voz.', 'blue'); return; } if (_isPlaying) { window.speechSynthesis.cancel(); _isPlaying = false; _updateAudioUI(false); return; } // Get only the active content div text var activeBlock = null; ['content-es-tech','content-es-simple','content-en-tech','content-en-simple'].forEach(function(id) { var el = document.getElementById(id); if (el && el.style.display !== 'none') activeBlock = el; }); // Fallback to art-body if (!activeBlock) activeBlock = document.getElementById('art-reading-body'); if (!activeBlock) return; // Get plain text — strip HTML, limit to 4500 chars var raw = (activeBlock.innerText || activeBlock.textContent || '').substring(0, 4800).trim(); if (!raw || raw.length < 30) return; var lang = (typeof currentLang !== 'undefined') ? currentLang : 'es'; _utterance = new SpeechSynthesisUtterance(raw); _utterance.lang = (lang === 'en') ? 'en-US' : 'es-CO'; _utterance.rate = 0.87; _utterance.pitch = 1.07; function doSpeak() { var voice = _getFemalVoice(lang); if (voice) { _utterance.voice = voice; var n = document.getElementById('audioNoteEl'); if (n) n.textContent = '🎙 ' + voice.name; } _utterance.onend = _utterance.onerror = function() { _isPlaying = false; _updateAudioUI(false); }; window.speechSynthesis.speak(_utterance); _isPlaying = true; _updateAudioUI(true); } var vl = window.speechSynthesis.getVoices(); if (vl && vl.length > 0) { doSpeak(); } else { window.speechSynthesis.onvoiceschanged = function() { window.speechSynthesis.onvoiceschanged = null; doSpeak(); }; setTimeout(doSpeak, 300); } } // ── PDF DOWNLOAD (gated) ─────────────────────────────────────────────── function dlPDF() { if (!isLoggedIn()) { openUserModal('login'); artToast('Inicia sesión para descargar el PDF.', 'blue'); return; } var titleEl = document.getElementById('hero-title-es') || document.querySelector('.art-hero-title'); var title = titleEl ? titleEl.textContent.trim() : document.title; var activeBlock = null; ['content-es-tech','content-es-simple','content-en-tech','content-en-simple'].forEach(function(id) { var el = document.getElementById(id); if (el && el.style.display !== 'none') activeBlock = el; }); var body = activeBlock ? activeBlock.innerHTML : ''; var w = window.open('','_blank','width=820,height=960'); if (!w) { artToast('Permite las ventanas emergentes para descargar.', 'blue'); return; } w.document.write('' + title + '' + '' + '' + '' + '
Vásquez Pérez Abogados · Academia Legal
' + '

' + title + '

' + '
vasquezperez.com/academialegal · © 2026 · Documento informativo
' + body + '' + 'window.onload=function(){window.print();}'); w.document.close(); } // ── USER MODAL (Login / Register) ───────────────────────────────────── var _umTab = 'login'; var _umRole = ''; function openUserModal(tab) { _umTab = tab || 'login'; var m = document.getElementById('userModal'); if (!m) return; m.style.display = 'flex'; document.body.style.overflow = 'hidden'; setTimeout(function() { m.classList.add('vis'); }, 10); switchUMTab(_umTab); setTimeout(function() { var e = document.getElementById('umEmail'); if(e) e.focus(); }, 380); } function closeUserModal() { var m = document.getElementById('userModal'); if (!m) return; m.classList.remove('vis'); setTimeout(function() { m.style.display = 'none'; document.body.style.overflow = ''; }, 300); } function switchUMTab(tab) { _umTab = tab; document.querySelectorAll('.um-tab').forEach(function(b) { b.classList.toggle('on', b.dataset.tab === tab); }); var loginFields = document.getElementById('umLoginFields'); var regFields = document.getElementById('umRegFields'); var umTitle = document.getElementById('umTitle'); var umSub = document.getElementById('umSub'); if (loginFields) loginFields.style.display = (tab === 'login') ? '' : 'none'; if (regFields) regFields.style.display = (tab === 'register') ? '' : 'none'; if (umTitle) umTitle.textContent = (tab === 'login') ? 'Acceder' : 'Crear cuenta'; if (umSub) umSub.textContent = (tab === 'login') ? 'Ingresa con tus credenciales.' : 'Regístrate para reaccionar, comentar y descargar.'; } function setRole(role) { _umRole = role; document.querySelectorAll('.um-role-btn').forEach(function(b) { b.classList.toggle('on', b.dataset.role === role); }); } function doUserAction() { var email = (document.getElementById('umEmail') || {value:''}).value.trim().toLowerCase(); var pass = (document.getElementById('umPass') || {value:''}).value; var errEl = document.getElementById('umErr'); var btn = document.getElementById('umBtn'); var spin = document.getElementById('umSpin'); var btnTxt = document.getElementById('umBtnTxt'); if (errEl) errEl.style.display = 'none'; if (!email || !pass) { if (errEl) { errEl.textContent = 'Completa todos los campos.'; errEl.style.display = 'block'; } return; } if (_umTab === 'register') { var name = (document.getElementById('umName') || {value:''}).value.trim(); var consent = document.getElementById('umConsent'); if (!name) { if(errEl){errEl.textContent='Escribe tu nombre completo.';errEl.style.display='block';} return; } if (!_umRole) { if(errEl){errEl.textContent='Indica si eres abogado o no.';errEl.style.display='block';} return; } if (!consent || !consent.checked) { if(errEl){errEl.textContent='Debes autorizar el tratamiento de datos para continuar.';errEl.style.display='block';} return; } } if (btn) btn.disabled = true; if (btnTxt) btnTxt.style.display = 'none'; if (spin) spin.style.display = 'block'; setTimeout(function() { var ADMIN_EMAIL = 'admin@vasquezperez.com'; var ADMIN_PASS = 'vpAdmin2026!'; var user; if (_umTab === 'login') { if (email === ADMIN_EMAIL && pass === ADMIN_PASS) { user = { email: email, name: 'Juan Simón Vásquez Pérez', role: 'admin', readerPref: 'tech' }; } else if (email.includes('@') && pass.length >= 6) { // Simulate existing user - in production: POST /api/auth/login var stored = null; try { stored = JSON.parse(localStorage.getItem('vp_users_' + email)); } catch(e) {} if (stored && stored.pass === pass) { user = stored; } else { if (errEl) { errEl.textContent = 'Credenciales incorrectas.'; errEl.style.display = 'block'; } if (btn) btn.disabled = false; if (btnTxt) btnTxt.style.display = ''; if (spin) spin.style.display = 'none'; return; } } else { if (errEl) { errEl.textContent = 'Credenciales incorrectas.'; errEl.style.display = 'block'; } if (btn) btn.disabled = false; if (btnTxt) btnTxt.style.display = ''; if (spin) spin.style.display = 'none'; return; } } else { // Register var name = (document.getElementById('umName') || {value:''}).value.trim(); user = { email: email, name: name, role: 'user', readerPref: (_umRole === 'lawyer') ? 'tech' : 'simple', profession: _umRole }; try { localStorage.setItem('vp_users_' + email, JSON.stringify(Object.assign({}, user, {pass: pass}))); } catch(e) {} // In production: POST /api/auth/register with tratamiento de datos flag } saveSession(user); closeUserModal(); applySession(user); artToast('Bienvenido, ' + user.name.split(' ')[0] + '!', 'green'); // Apply reader preference based on profile if (user.readerPref && typeof setReader === 'function') { setTimeout(function() { setReader(user.readerPref, document.querySelector('[data-mode="' + user.readerPref + '"]')); }, 300); } }, 700); } function applySession(user) { if (!user) return; // Update nav access button var accessBtn = document.getElementById('navAccessBtn') || document.getElementById('artNavAccess'); if (accessBtn) { var initials = user.name.split(' ').map(function(w){return w[0]||'';}).join('').substring(0,2).toUpperCase(); accessBtn.textContent = initials; accessBtn.style.background = (user.role === 'admin') ? 'var(--blue)' : 'rgba(255,255,255,.15)'; accessBtn.style.borderRadius = '100px'; accessBtn.style.width = '34px'; accessBtn.style.height = '34px'; accessBtn.style.padding = '0'; accessBtn.style.fontWeight = '800'; accessBtn.style.fontSize = '11px'; accessBtn.onclick = function() { if (user.role === 'admin') { openUserModal('admin'); } else { if(confirm('¿Cerrar sesión?')) { clearSession(); location.reload(); } } }; } // Unlock gated content document.querySelectorAll('.gate-badge').forEach(function(g) { var btn = g.querySelector('.gate-btn'); if (btn) { btn.textContent = '✓ Disponible'; btn.style.background = '#059669'; btn.onclick = dlPDF; } }); // Show comments var cg = document.getElementById('commentGated'); var ci = document.getElementById('commentInput'); if (cg) cg.style.display = 'none'; if (ci) ci.style.display = ''; } // ── REACTIONS ────────────────────────────────────────────────────────── function doReaction(type) { if (!isLoggedIn()) { openUserModal('login'); artToast('Inicia sesión para reaccionar.', 'blue'); return; } var slug = (window.location.pathname.split('/').filter(Boolean).pop() || 'articulo'); var key = 'vp_react_' + slug + '_' + type; var btn = document.querySelector('.reaction-btn[data-type="' + type + '"]'); var cnt = btn ? btn.querySelector('.rcount') : null; var already = false; try { already = localStorage.getItem(key) === '1'; } catch(e) {} if (already) { try { localStorage.removeItem(key); } catch(e) {} if (btn) btn.classList.remove('active'); if (cnt) cnt.textContent = Math.max(0, parseInt(cnt.textContent||'0') - 1); } else { try { localStorage.setItem(key, '1'); } catch(e) {} if (btn) btn.classList.add('active'); if (cnt) cnt.textContent = parseInt(cnt.textContent||'0') + 1; artToast(type === 'like' ? '¡Gracias por tu reacción!' : 'Comentario marcado.', 'green'); } } function doComment() { if (!isLoggedIn()) { openUserModal('login'); return; } var input = document.getElementById('commentText'); var text = input ? input.value.trim() : ''; if (!text) return; var list = document.getElementById('commentList'); if (list) { var initials = vpSession.name.split(' ').map(function(w){return w[0]||'';}).join('').substring(0,2).toUpperCase(); var now = new Date().toLocaleDateString('es-CO', {day:'2-digit',month:'short',year:'numeric'}); var el = document.createElement('div'); el.className = 'comment-item'; el.innerHTML = '
' + initials + '
' + vpSession.name.split(' ')[0] + '
' + now + '
' + text.replace(//g,'>') + '
'; list.appendChild(el); } if (input) input.value = ''; artToast('Comentario publicado.', 'green'); } // ── TOAST ────────────────────────────────────────────────────────────── function artToast(msg, type) { var t = document.createElement('div'); t.className = 'art-toast ' + (type || 'blue'); t.textContent = msg; document.body.appendChild(t); setTimeout(function() { t.classList.add('show'); }, 20); setTimeout(function() { t.classList.remove('show'); setTimeout(function(){t.remove();},400); }, 3500); } // ── COUNTAPI VISIT COUNTER ───────────────────────────────────────────── function initVisitCounter(slug) { var vc = document.getElementById('visitCounter'); var vcn = document.getElementById('visitCount'); if (!vc || !vcn) return; var sessKey = 'vp_hit_' + slug; var endpoint = sessionStorage.getItem(sessKey) ? 'https://api.countapi.xyz/get/vasquezperez-academia/' + slug : 'https://api.countapi.xyz/hit/vasquezperez-academia/' + slug; if (!sessionStorage.getItem(sessKey)) { try { sessionStorage.setItem(sessKey, '1'); } catch(e){} } fetch(endpoint) .then(function(r) { return r.json(); }) .then(function(d) { if (d && typeof d.value === 'number') { vcn.textContent = d.value >= 1000 ? (d.value/1000).toFixed(1).replace('.0','')+'k' : String(d.value); vc.style.display = 'inline-flex'; } }) .catch(function() { /* silent */ }); } // ── LOAD COMMENTS FROM LOCAL STORAGE (demo) ──────────────────────────── function loadDemoComments(slug) { // In production: GET /api/comments/{slug} // Demo: show 1 sample comment var list = document.getElementById('commentList'); if (!list) return; var sample = '
MC
María C.
Abr 2026
Excelente análisis. Muy útil para entender los tiempos en la transferencia de acciones.
'; list.innerHTML = sample; } /* ════ VP PREMIUM AUTH SYSTEM ════════════════════════════════════════ */ var _vps = (function(){ try{ return JSON.parse(localStorage.getItem('vp_user')||'null'); }catch(e){ return null; } })(); var _vpTab = 'login'; var _vpRole = ''; function _isLoggedIn(){ return !!_vps; } function _isAdmin(){ return _vps && _vps.role === 'admin'; } /* ── Open / Close ──────────────────────────────────────────────────── */ function openVPModal(tab){ _vpTab = tab||'login'; var m = document.getElementById('vpModal'); if(!m) return; m.style.display = 'flex'; document.body.style.overflow = 'hidden'; requestAnimationFrame(function(){ m.classList.add('vis'); }); _vpSwitchTab(_vpTab); setTimeout(function(){ var e=document.getElementById('vpEmail'); if(e) e.focus(); }, 420); } function closeVPModal(){ var m = document.getElementById('vpModal'); if(!m) return; m.classList.remove('vis'); setTimeout(function(){ m.style.display='none'; document.body.style.overflow=''; }, 340); } /* ── Tabs ──────────────────────────────────────────────────────────── */ function _vpSwitchTab(tab){ _vpTab = tab; document.querySelectorAll('.vp-tab').forEach(function(b){ b.classList.toggle('on', b.dataset.tab===tab); }); var lf=document.getElementById('vpLogin'); var rf=document.getElementById('vpReg'); var hl=document.getElementById('vpHL'); var sl=document.getElementById('vpSL'); var ch=document.getElementById('vpChips'); if(lf) lf.style.display = tab==='login' ? '' : 'none'; if(rf) rf.style.display = tab==='register' ? '' : 'none'; if(hl) hl.textContent = tab==='login' ? 'Bienvenido de vuelta' : 'Crea tu cuenta'; if(sl) sl.textContent = tab==='login' ? 'Accede a tu perfil de Academia Legal.' : 'Regístrate para acceder a todos los beneficios.'; if(ch) ch.style.display = tab==='register' ? '' : 'none'; var ft=document.getElementById('vpFoot'); if(ft) ft.innerHTML = tab==='login' ? '\u00bfSin cuenta? Regístrate gratis' : '\u00bfYa tienes cuenta? Ingresar'; } /* ── Role ──────────────────────────────────────────────────────────── */ function _vpPickRole(r){ _vpRole = r; document.querySelectorAll('.vp-role').forEach(function(b){ b.classList.toggle('on', b.dataset.role===r); }); } /* ── Submit ────────────────────────────────────────────────────────── */ function vpSubmit(){ var email = (document.getElementById('vpEmail')||{value:''}).value.trim().toLowerCase(); var pass = (document.getElementById('vpPass') ||{value:''}).value; var errEl = document.getElementById('vpErr'); var btn = document.getElementById('vpBtn'); var spin = document.getElementById('vpSpin'); var btxt = document.getElementById('vpBtnTxt'); if(errEl){ errEl.style.display='none'; errEl.classList.remove('show'); } function showErr(msg){ if(errEl){ errEl.textContent=msg; errEl.style.display='block'; errEl.classList.add('show'); } } if(!email||!pass){ showErr('Completa todos los campos.'); return; } if(pass.length<6){ showErr('La contraseña debe tener al menos 6 caracteres.'); return; } if(_vpTab==='register'){ var name = (document.getElementById('vpName')||{value:''}).value.trim(); var ck = document.getElementById('vpCk'); if(!name){ showErr('Escribe tu nombre completo.'); return; } if(!_vpRole){ showErr('Selecciona tu perfil para continuar.'); return; } if(!ck||!ck.checked){ showErr('Debes autorizar el tratamiento de datos personales para registrarte.'); return; } } if(btn) btn.disabled=true; if(btxt) btxt.style.display='none'; if(spin) spin.style.display='block'; setTimeout(function(){ var user; if(_vpTab==='login'){ if(email==='admin@vasquezperez.com' && pass==='vpAdmin2026!'){ user={email:email,name:'Juan Simón Vásquez Pérez',role:'admin',pref:'tech',ini:'JS'}; } else { var st=null; try{ st=JSON.parse(localStorage.getItem('vp_u_'+email)); }catch(e){} if(st && st.pw===pass){ user={email:email,name:st.name,role:'user',pref:st.pref,ini:st.ini,prof:st.prof}; } else { showErr('Correo o contraseña incorrectos.'); if(btn) btn.disabled=false; if(btxt) btxt.style.display=''; if(spin) spin.style.display='none'; var pe=document.getElementById('vpPass'); if(pe){ pe.classList.add('shake'); setTimeout(function(){ pe.classList.remove('shake'); },600); } return; } } } else { var name=(document.getElementById('vpName')||{value:''}).value.trim(); var ini=name.split(' ').map(function(w){ return w[0]||''; }).join('').substring(0,2).toUpperCase(); user={email:email,name:name,role:'user',pref:(_vpRole==='lawyer'?'tech':'simple'),ini:ini,prof:_vpRole}; try{ localStorage.setItem('vp_u_'+email, JSON.stringify({name:name,pw:pass,pref:user.pref,ini:ini,prof:_vpRole})); }catch(e){} } _vps=user; try{ localStorage.setItem('vp_user',JSON.stringify(user)); }catch(e){} closeVPModal(); _vpApply(user); vpToast(_vpTab==='register' ? 'Bienvenido, '+user.name.split(' ')[0]+'!' : 'Sesión iniciada.', 'green'); if(user.pref && typeof setReader==='function'){ setTimeout(function(){ setReader(user.pref, document.querySelector('[data-mode="'+user.pref+'"]')); },320); } },700); } /* ── Apply session visually ────────────────────────────────────────── */ function _vpApply(user){ if(!user) return; var acc=document.getElementById('vpAccess'); if(acc){ var color=user.role==='admin'?'#153ABF':'#059669'; var sess=document.createElement('div'); sess.className='vp-session'; sess.id='vpSession'; sess.innerHTML=( '
'+user.ini+'
'+ ''+user.name.split(' ')[0]+''+ ''+ '
'+ '
'+ '
'+user.name+'
'+ '
'+(user.role==='admin'?'Administrador':(user.pref==='tech'?'Abogado':'Usuario'))+'
'+ '
'+ ''+ '
'+ ''+ '
' ); sess.style.display='flex'; sess.addEventListener('click',function(){ sess.classList.toggle('open'); }); document.addEventListener('click',function(e){ if(!sess.contains(e.target)) sess.classList.remove('open'); }); acc.parentNode.replaceChild(sess, acc); } /* Unlock gated content */ document.querySelectorAll('.gate-unlock').forEach(function(b){ b.textContent='↓ Descargar PDF'; b.style.background='#059669'; b.onclick=function(){ downloadPDF(); }; }); var cg=document.getElementById('cmtGated'); if(cg) cg.style.display='none'; var ci=document.getElementById('cmtInput'); if(ci) ci.style.display=''; } /* ── Logout ────────────────────────────────────────────────────────── */ function vpLogout(){ _vps=null; try{ localStorage.removeItem('vp_user'); }catch(e){} vpToast('Sesión cerrada.','blue'); setTimeout(function(){ location.reload(); },700); } /* ── Reactions ─────────────────────────────────────────────────────── */ function vpReact(type){ if(!_isLoggedIn()){ openVPModal('login'); vpToast('Inicia sesión para reaccionar.','blue'); return; } var slug=(window.location.pathname.split('/').filter(Boolean).pop()||'art'); var key='vp_rx_'+slug+'_'+type; var btn=document.querySelector('.rxn-btn[data-type="'+type+'"]'); var cnt=btn?btn.querySelector('.rxn-count'):null; var had=false; try{ had=localStorage.getItem(key)==='1'; }catch(e){} if(had){ try{ localStorage.removeItem(key); }catch(e){} if(btn) btn.classList.remove('on'); if(cnt) cnt.textContent=Math.max(0,parseInt(cnt.textContent||'0')-1); } else { try{ localStorage.setItem(key,'1'); }catch(e){} if(btn) btn.classList.add('on'); if(cnt) cnt.textContent=parseInt(cnt.textContent||'0')+1; vpToast('¡Gracias!','green'); } } /* ── Comment ───────────────────────────────────────────────────────── */ function vpComment(){ if(!_isLoggedIn()){ openVPModal('login'); return; } var inp=document.getElementById('cmtText'); var txt=inp?inp.value.trim():''; if(!txt) return; var list=document.getElementById('cmtList'); if(list){ var ini=_vps.name.split(' ').map(function(w){ return w[0]||''; }).join('').substring(0,2).toUpperCase(); var now=new Date().toLocaleDateString('es-CO',{day:'2-digit',month:'short',year:'numeric'}); var el=document.createElement('div'); el.className='cmt'; el.innerHTML=( '
'+ '
'+ini+'
'+ '
'+_vps.name.split(' ')[0]+'
'+ '
'+now+'
'+ '
'+ '
'+txt.replace(//g,'>')+'
' ); list.appendChild(el); } if(inp) inp.value=''; vpToast('Comentario publicado.','green'); } /* ── PDF Download (gated) ─────────────────────────────────────────── */ function downloadPDF(){ if(!_isLoggedIn()){ openVPModal('login'); vpToast('Inicia sesión para descargar.','blue'); return; } var titleEl=document.getElementById('hero-title-es')||document.querySelector('.art-hero-title'); var title=titleEl?titleEl.textContent.trim():document.title; var activeBlock=['content-es-tech','content-es-simple','content-en-tech','content-en-simple'].reduce(function(a,id){ var el=document.getElementById(id); return (el&&el.style.display!=='none')?el:a; },null)||document.getElementById('art-reading-body'); var body=activeBlock?activeBlock.innerHTML:''; var w=window.open('','_blank','width=820,height=960'); if(!w){ vpToast('Permite ventanas emergentes para descargar.','blue'); return; } w.document.write( ''+title+''+ ''+ ''+ ''+ '
Vásquez Pérez Abogados · Academia Legal
'+ '

'+title+'

'+ '
vasquezperez.com/academialegal · 2026 · Documento informativo
'+ body+ ''+ 'window.onload=function(){window.print();}'+ '' ); w.document.close(); } /* ── Female voice audio ───────────────────────────────────────────── */ var _playing=false; function _femVoice(lang){ var voices=(window.speechSynthesis&&window.speechSynthesis.getVoices())||[]; var lc=lang==='en'?'en':'es'; var fem=['lucia','paulina','monica','clara','paloma','sofia','elena','maria','laura','karen','victoria','female','mujer','google esp']; var mal=['jorge','carlos','diego','antonio','juan','francisco','male','hombre']; var sc=voices.map(function(v){ var s=0,n=v.name.toLowerCase(),vl=(v.lang||'').toLowerCase(); if(vl.indexOf(lc)===0) s+=20; if(fem.some(function(f){ return n.indexOf(f)>=0; })) s+=30; if(mal.some(function(m){ return n.indexOf(m)>=0; })) s-=15; if(!v.localService) s+=5; return {v:v,s:s}; }); sc.sort(function(a,b){ return b.s-a.s; }); return sc.length?sc[0].v:null; } function toggleAudio(){ if(!('speechSynthesis' in window)){ vpToast('Tu navegador no soporta lectura en voz.','blue'); return; } if(_playing){ window.speechSynthesis.cancel(); _playing=false; _updAudioUI(false); return; } var blocks=['content-es-tech','content-es-simple','content-en-tech','content-en-simple']; var block=blocks.reduce(function(a,id){ var el=document.getElementById(id); return(el&&el.style.display!=='none')?el:a; },null); if(!block) block=document.getElementById('art-reading-body'); if(!block) return; var txt=(block.innerText||block.textContent||'').substring(0,4800).trim(); if(!txt||txt.length<20) return; var lang=typeof currentLang!=='undefined'?currentLang:'es'; var u=new SpeechSynthesisUtterance(txt); u.lang=lang==='en'?'en-US':'es-CO'; u.rate=0.87; u.pitch=1.06; function go(){ var v=_femVoice(lang); if(v){ u.voice=v; var n=document.getElementById('audioNoteEl'); if(n) n.textContent='Voz: '+v.name; } u.onend=u.onerror=function(){ _playing=false; _updAudioUI(false); }; window.speechSynthesis.speak(u); _playing=true; _updAudioUI(true); } var vl=window.speechSynthesis.getVoices(); if(vl&&vl.length>0){ go(); } else { window.speechSynthesis.onvoiceschanged=function(){ window.speechSynthesis.onvoiceschanged=null; go(); }; setTimeout(go,300); } } function _updAudioUI(p){ var btn=document.getElementById('audioCtrlBtn'); var wave=document.getElementById('waveformEl'); var icon=document.getElementById('audioIconSvg'); var note=document.getElementById('audioNoteEl'); if(btn) btn.style.color=p?'var(--blue)':''; if(wave) wave.style.display=p?'flex':'none'; if(icon) icon.style.display=p?'none':''; if(note&&!p) note.textContent='Voz femenina · Accesibilidad'; } /* ── CountAPI ─────────────────────────────────────────────────────── */ function initVC(slug){ var vc=document.getElementById('visitCounter'); var vcn=document.getElementById('visitCount'); if(!vc||!vcn) return; var key='vp_hit_'+slug; var ep=sessionStorage.getItem(key) ?'https://api.countapi.xyz/get/vasquezperez-academia/'+slug :'https://api.countapi.xyz/hit/vasquezperez-academia/'+slug; if(!sessionStorage.getItem(key)){ try{ sessionStorage.setItem(key,'1'); }catch(e){} } fetch(ep).then(function(r){ return r.json(); }).then(function(d){ if(d&&typeof d.value==='number'){ vcn.textContent=d.value>=1000?(d.value/1000).toFixed(1).replace('.0','')+'k':String(d.value); vc.style.display='inline-flex'; } }).catch(function(){}); } /* ── Toast ────────────────────────────────────────────────────────── */ function vpToast(msg,type){ var t=document.createElement('div'); t.className='vp-toast '+(type||'blue'); t.innerHTML=''+msg+''; document.body.appendChild(t); setTimeout(function(){ t.classList.add('show'); },20); setTimeout(function(){ t.classList.remove('show'); setTimeout(function(){ t.remove(); },420); },3800); } /* ── Dividend calculator ──────────────────────────────────────────── */ function calcDiv(){ var ins=document.getElementById('calcIns'); var div=document.getElementById('calcDiv'); var res=document.getElementById('calcResult'); if(!ins||!div||!res) return; var id=ins.value?new Date(ins.value):null; var dd=div.value?new Date(div.value):null; if(!id||!dd){ res.className='acc-result'; res.textContent='Ingresa ambas fechas para calcular.'; return; } var fmt=function(d){ return d.toLocaleDateString('es-CO',{day:'numeric',month:'long',year:'numeric'}); }; if(id<=dd){ res.className='acc-result ok'; res.innerHTML='Tienes derecho a ese dividendo. Estabas inscrito el '+fmt(id)+', antes de que el dividendo fuera exigible el '+fmt(dd)+'.'; } else { var diff=Math.round((id-dd)/(86400000)); res.className='acc-result warn'; res.innerHTML='No tienes derecho a ese dividendo. Te inscribiste el '+fmt(id)+', pero el dividendo ya era exigible desde el '+fmt(dd)+' — '+diff+' día(s) antes. Solo tienes derecho a dividendos exigibles después del '+fmt(id)+'.'; } } /* ── Accordion ────────────────────────────────────────────────────── */ function initAccordion(){ document.querySelectorAll('.art-point').forEach(function(pt){ if(pt.dataset.ready==='1') return; pt.dataset.ready='1'; var pn=pt.querySelector('.point-num'); var pc=pt.querySelector('.point-content'); if(!pn||!pc) return; var h4=pc.querySelector('h4'); var p=pc.querySelector('p'); var title=h4?h4.textContent.trim():''; var body=p?p.outerHTML:''; pt.innerHTML=( '
'+ '
'+pn.textContent.trim()+'
'+ '
'+title+'
'+ '
'+ '
'+ (body?'
'+body+'
':'') ); if(body){ pt.addEventListener('click',function(){ var open=pt.classList.contains('open'); var par=pt.parentNode; if(par) par.querySelectorAll('.art-point.open').forEach(function(o){ if(o!==pt) o.classList.remove('open'); }); pt.classList.toggle('open',!open); }); } }); var first=document.querySelector('#content-es-tech .art-point')||document.querySelector('.art-point'); if(first&&first.querySelector&&first.querySelector('.ap-body')) first.classList.add('open'); } /* ── Keyboard ─────────────────────────────────────────────────────── */ document.addEventListener('keydown',function(e){ if(e.key==='Escape') closeVPModal(); }); /* ── Init ─────────────────────────────────────────────────────────── */ document.addEventListener('DOMContentLoaded',function(){ initAccordion(); if(_vps) _vpApply(_vps); if(_vps&&_vps.pref&&typeof setReader==='function'){ setReader(_vps.pref, document.querySelector('[data-mode="'+_vps.pref+'"]')); } }); /* ═══ VP ACADEMIA — PREMIUM ARTICLE INTERACTIONS ═══════════════════ */ (function(){ /* ── 1. Reading progress bar ──────────────────────────────────────── */ var _rpBar = document.createElement('div'); _rpBar.className = 'vp-read-bar'; document.body.appendChild(_rpBar); window.addEventListener('scroll', function(){ var h = document.documentElement.scrollHeight - window.innerHeight; if(h > 0) _rpBar.style.width = Math.min(100, (window.scrollY/h)*100) + '%'; }, {passive:true}); /* ── 2. Accordion premium ──────────────────────────────────────────── */ function initAccordion(){ document.querySelectorAll('.art-point').forEach(function(pt){ if(pt.dataset.vpAc) return; pt.dataset.vpAc = '1'; /* reconstruct into ap-header / ap-body */ var pnEl = pt.querySelector('.point-num, .pn'); var pcEl = pt.querySelector('.point-content, .pc'); if(!pnEl || !pcEl) return; var num = pnEl.textContent.trim() || '•'; var h4 = pcEl.querySelector('h4'); var pEl = pcEl.querySelector('p'); var title = h4 ? h4.textContent.trim() : ''; var body = pEl ? pEl.outerHTML : ''; pt.innerHTML = ( '
' + '
' + num + '
' + '
' + title + '
' + '
' + '' + '' + '' + '
' + '
' + (body ? '
' + body + '
' : '') ); pt.addEventListener('click', function(){ var isOpen = pt.classList.contains('open'); /* close siblings */ var par = pt.parentNode; if(par) par.querySelectorAll('.art-point.open').forEach(function(o){ if(o !== pt) o.classList.remove('open'); }); pt.classList.toggle('open', !isOpen); }); }); /* open first by default */ var first = document.querySelector('#content-es-tech .art-point') || document.querySelector('.art-body .art-point'); if(first && !first.classList.contains('open')) first.classList.add('open'); } window.initAccordion = initAccordion; /* ── 3. Reveal on scroll ───────────────────────────────────────────── */ (function(){ var targets = '.art-point, .art-cta-block, .art-related, ' + '.rxn-bar, .cmts, .tl-wrap, .acc-calc, ' + '.art-lead, .vp-callout, .art-conclusion-block'; function addReveal(){ document.querySelectorAll(targets).forEach(function(el){ if(!el.classList.contains('vp-reveal')){ el.classList.add('vp-reveal'); } }); } addReveal(); if(!('IntersectionObserver' in window)){ document.querySelectorAll('.vp-reveal').forEach(function(el){ el.classList.add('vp-vis'); }); return; } var io = new IntersectionObserver(function(entries){ entries.forEach(function(e){ if(e.isIntersecting){ e.target.classList.add('vp-vis'); io.unobserve(e.target); } }); }, {threshold: 0.07, rootMargin: '0px 0px -32px 0px'}); document.querySelectorAll('.vp-reveal').forEach(function(el){ io.observe(el); }); })(); /* ── 4. Hero stat counter animation ───────────────────────────────── */ (function(){ if(!('IntersectionObserver' in window)) return; var io = new IntersectionObserver(function(entries){ entries.forEach(function(e){ if(!e.isIntersecting) return; var el = e.target; var end = parseInt(el.dataset.target || '0', 10); var sfx = el.dataset.suffix || ''; var dur = 1100; var t0 = Date.now(); io.unobserve(el); (function tick(){ var p = Math.min(1, (Date.now()-t0)/dur); var ease = 1 - Math.pow(1-p, 3); el.textContent = Math.round(ease * end) + (p >= 1 ? sfx : ''); if(p < 1) requestAnimationFrame(tick); })(); }); }, {threshold: 0.5}); document.querySelectorAll('.hero-stat-num[data-target]').forEach(function(el){ io.observe(el); }); })(); /* ── 5. artCtrl elevation on scroll ───────────────────────────────── */ (function(){ var ctrl = document.getElementById('artCtrl'); if(!ctrl) return; window.addEventListener('scroll', function(){ ctrl.classList.toggle('elevated', window.scrollY > 80); }, {passive: true}); })(); /* ── 6. Visit counter ──────────────────────────────────────────────── */ function initVC(slug){ var vc = document.getElementById('visitCounter'); var vcn = document.getElementById('visitCount'); if(!vc || !vcn) return; var key = 'vp_hit_' + slug; var ep = sessionStorage.getItem(key) ? 'https://api.countapi.xyz/get/vasquezperez-academia/' + slug : 'https://api.countapi.xyz/hit/vasquezperez-academia/' + slug; try{ sessionStorage.setItem(key,'1'); }catch(e){} fetch(ep) .then(function(r){ return r.json(); }) .then(function(d){ if(d && typeof d.value === 'number'){ vcn.textContent = d.value >= 1000 ? (d.value/1000).toFixed(1).replace('.0','') + 'k' : String(d.value); vc.style.display = 'inline-flex'; } }).catch(function(){}); } window.initVC = initVC; })(); // ── INIT ────────────────────────────────── function openUserModal(t){ if(typeof openVPModal==='function') openVPModal(t); } function artToast(m,t){ if(typeof vpToast==='function') vpToast(m,t); } document.addEventListener('DOMContentLoaded',function(){ if(typeof initAccordion==='function') initAccordion(); if(typeof initVC==='function') initVC('consorcios'); if(typeof _vps!=='undefined'&&_vps){ if(typeof _vpApply==='function') _vpApply(_vps); if(_vps.pref&&typeof setReader==='function'){ setReader(_vps.pref,document.querySelector('[data-mode="'+_vps.pref+'"]')); } } }); function isLoggedIn(){ return typeof _isLoggedIn==='function'&&_isLoggedIn(); }