{"id":11,"date":"2026-04-10T08:46:35","date_gmt":"2026-04-10T13:46:35","guid":{"rendered":"https:\/\/constructoracolpatria.com\/sites\/linea-etica\/?page_id=11"},"modified":"2026-04-17T13:34:30","modified_gmt":"2026-04-17T18:34:30","slug":"home","status":"publish","type":"page","link":"https:\/\/constructoracolpatria.com\/sites\/linea-etica\/","title":{"rendered":"Home"},"content":{"rendered":"\t\t<div data-elementor-type=\"wp-page\" data-elementor-id=\"11\" class=\"elementor elementor-11\" data-elementor-post-type=\"page\">\n\t\t\t\t<div class=\"elementor-element elementor-element-c62766a e-con-full e-flex e-con e-parent\" data-id=\"c62766a\" data-element_type=\"container\" data-e-type=\"container\">\n\t\t\t\t<div class=\"elementor-element elementor-element-b357d43 elementor-widget elementor-widget-html\" data-id=\"b357d43\" data-element_type=\"widget\" data-e-type=\"widget\" data-widget_type=\"html.default\">\n\t\t\t\t\t<!DOCTYPE html>\r\n<html lang=\"es\">\r\n<head>\r\n<meta charset=\"UTF-8\"\/>\r\n<meta name=\"viewport\" content=\"width=device-width, initial-scale=1.0\"\/>\r\n<link href=\"https:\/\/fonts.googleapis.com\/css2?family=Playfair+Display:wght@600;700&family=DM+Sans:wght@300;400;500;600&display=swap\" rel=\"stylesheet\"\/>\r\n<script src=\"https:\/\/cdnjs.cloudflare.com\/ajax\/libs\/react\/18.2.0\/umd\/react.production.min.js\"><\/script>\r\n<script src=\"https:\/\/cdnjs.cloudflare.com\/ajax\/libs\/react-dom\/18.2.0\/umd\/react-dom.production.min.js\"><\/script>\r\n<script src=\"https:\/\/cdnjs.cloudflare.com\/ajax\/libs\/babel-standalone\/7.23.2\/babel.min.js\"><\/script>\r\n<style>\r\n:root {\r\n  --rojo: #DA291C;\r\n  --rojo-oscuro: #B01F14;\r\n  --rojo-suave: #FDF2F1;\r\n  --azul: #323444;\r\n  --azul-medio: #4A4D62;\r\n  --azul-suave: #F0F1F5;\r\n  --blanco: #FFFFFF;\r\n  --gris-claro: #F7F8FA;\r\n  --gris-borde: #E2E5EC;\r\n  --gris-texto: #6B7280;\r\n  --gris-oscuro: #374151;\r\n  --negro: #1A1D2E;\r\n  --sombra: 0 1px 3px rgba(50,52,68,.08), 0 4px 16px rgba(50,52,68,.06);\r\n  --sombra-hover: 0 4px 12px rgba(218,41,28,.15), 0 8px 32px rgba(50,52,68,.10);\r\n}\r\n\r\n* { box-sizing: border-box; margin: 0; padding: 0; }\r\n\r\nbody {\r\n  font-family: 'DM Sans', sans-serif;\r\n  background: var(--gris-claro);\r\n  color: var(--negro);\r\n  min-height: 100vh;\r\n}\r\n\r\n\/* \u2500\u2500 Hero \u2500\u2500 *\/\r\n.hero {\r\n  background: var(--azul);\r\n  padding: 56px 24px 64px;\r\n  text-align: center;\r\n  position: relative;\r\n  overflow: hidden;\r\n}\r\n.hero::before {\r\n  content: '';\r\n  position: absolute;\r\n  top: -60px; right: -60px;\r\n  width: 300px; height: 300px;\r\n  border-radius: 50%;\r\n  background: rgba(218,41,28,.12);\r\n  pointer-events: none;\r\n}\r\n.hero::after {\r\n  content: '';\r\n  position: absolute;\r\n  bottom: -40px; left: -40px;\r\n  width: 200px; height: 200px;\r\n  border-radius: 50%;\r\n  background: rgba(255,255,255,.04);\r\n  pointer-events: none;\r\n}\r\n.hero-chip {\r\n  display: inline-flex;\r\n  align-items: center;\r\n  gap: 8px;\r\n  background: rgba(218,41,28,.2);\r\n  border: 1px solid rgba(218,41,28,.4);\r\n  color: #FF8A80;\r\n  font-size: 11px;\r\n  font-weight: 600;\r\n  letter-spacing: .12em;\r\n  text-transform: uppercase;\r\n  padding: 6px 14px;\r\n  border-radius: 20px;\r\n  margin-bottom: 20px;\r\n}\r\n.hero-chip-dot {\r\n  width: 6px; height: 6px;\r\n  border-radius: 50%;\r\n  background: #FF8A80;\r\n  animation: pulse 2s infinite;\r\n}\r\n@keyframes pulse {\r\n  0%,100% { opacity:1; transform:scale(1); }\r\n  50% { opacity:.5; transform:scale(1.3); }\r\n}\r\n.hero h1 {\r\n  font-family: 'Playfair Display', serif;\r\n  font-size: clamp(28px, 5vw, 42px);\r\n  font-weight: 700;\r\n  color: var(--blanco);\r\n  line-height: 1.2;\r\n  margin-bottom: 16px;\r\n  position: relative;\r\n}\r\n.hero h1 span { color: var(--rojo); }\r\n.hero p {\r\n  font-size: 15px;\r\n  color: rgba(255,255,255,.65);\r\n  max-width: 520px;\r\n  margin: 0 auto;\r\n  line-height: 1.7;\r\n  font-weight: 300;\r\n}\r\n\r\n\/* \u2500\u2500 Tabs \u2500\u2500 *\/\r\n.tabs-wrap {\r\n  background: var(--blanco);\r\n  border-bottom: 1px solid var(--gris-borde);\r\n  position: sticky;\r\n  top: 0;\r\n  z-index: 100;\r\n  box-shadow: 0 2px 8px rgba(50,52,68,.06);\r\n}\r\n.tabs {\r\n  display: flex;\r\n  max-width: 1080px;\r\n  margin: 0 auto;\r\n  padding: 0 24px;\r\n}\r\n.tab-btn {\r\n  flex: 1;\r\n  padding: 18px 16px;\r\n  border: none;\r\n  background: transparent;\r\n  font-family: 'DM Sans', sans-serif;\r\n  font-size: 14px;\r\n  font-weight: 500;\r\n  color: var(--gris-texto);\r\n  cursor: pointer;\r\n  border-bottom: 3px solid transparent;\r\n  margin-bottom: -1px;\r\n  transition: all .2s;\r\n  display: flex;\r\n  align-items: center;\r\n  justify-content: center;\r\n  gap: 8px;\r\n}\r\n.tab-btn.active {\r\n  color: var(--rojo);\r\n  border-bottom-color: var(--rojo);\r\n  font-weight: 600;\r\n}\r\n.tab-icon {\r\n  width: 18px; height: 18px;\r\n  opacity: .6;\r\n  transition: opacity .2s;\r\n}\r\n.tab-btn.active .tab-icon { opacity: 1; }\r\n\r\n\/* \u2500\u2500 Content \u2500\u2500 *\/\r\n.content {\r\n  max-width: 1080px;\r\n  margin: 0 auto;\r\n  padding: 36px 24px 60px;\r\n}\r\n\r\n\/* \u2500\u2500 Card \u2500\u2500 *\/\r\n.card {\r\n  background: var(--blanco);\r\n  border-radius: 16px;\r\n  border: 1px solid var(--gris-borde);\r\n  box-shadow: var(--sombra);\r\n  overflow: hidden;\r\n}\r\n.card-section {\r\n  padding: 28px 32px;\r\n  border-bottom: 1px solid var(--gris-borde);\r\n}\r\n.card-section:last-child { border-bottom: none; }\r\n\r\n.section-label {\r\n  display: flex;\r\n  align-items: center;\r\n  gap: 10px;\r\n  font-size: 11px;\r\n  font-weight: 700;\r\n  letter-spacing: .1em;\r\n  text-transform: uppercase;\r\n  color: var(--rojo);\r\n  margin-bottom: 20px;\r\n}\r\n.section-label::after {\r\n  content: '';\r\n  flex: 1;\r\n  height: 1px;\r\n  background: var(--gris-borde);\r\n}\r\n\r\n\/* \u2500\u2500 Fields \u2500\u2500 *\/\r\n.field { margin-bottom: 20px; }\r\n.field:last-child { margin-bottom: 0; }\r\n.label {\r\n  display: block;\r\n  font-size: 13px;\r\n  font-weight: 600;\r\n  color: var(--azul);\r\n  margin-bottom: 8px;\r\n  letter-spacing: .01em;\r\n}\r\n.label .req { color: var(--rojo); margin-left: 2px; }\r\n.label .opt { font-size: 11px; color: var(--gris-texto); font-weight: 400; margin-left: 6px; }\r\n\r\ninput, select, textarea {\r\n  width: 100%;\r\n  padding: 12px 16px;\r\n  border: 1.5px solid var(--gris-borde);\r\n  border-radius: 10px;\r\n  font-size: 14px;\r\n  font-family: 'DM Sans', sans-serif;\r\n  color: var(--negro);\r\n  background: var(--blanco);\r\n  transition: all .2s;\r\n  -webkit-appearance: none;\r\n}\r\ninput::placeholder, textarea::placeholder { color: #B0B7C3; }\r\ninput:focus, select:focus, textarea:focus {\r\n  outline: none;\r\n  border-color: var(--rojo);\r\n  box-shadow: 0 0 0 3px rgba(218,41,28,.08);\r\n}\r\ninput:hover:not(:focus), select:hover:not(:focus), textarea:hover:not(:focus) {\r\n  border-color: #C5CAD8;\r\n}\r\nselect {\r\n  background-image: url(\"data:image\/svg+xml,%3Csvg xmlns='http:\/\/www.w3.org\/2000\/svg' width='16' height='16' viewBox='0 0 24 24' fill='none' stroke='%236B7280' stroke-width='2'%3E%3Cpath d='m6 9 6 6 6-6'\/%3E%3C\/svg%3E\");\r\n  background-repeat: no-repeat;\r\n  background-position: right 14px center;\r\n  padding-right: 44px;\r\n  cursor: pointer;\r\n}\r\ntextarea { min-height: 130px; resize: vertical; line-height: 1.6; }\r\n\r\n.row2 { display: grid; grid-template-columns: 1fr 1fr; gap: 16px; }\r\n\r\n\/* \u2500\u2500 Privacy note \u2500\u2500 *\/\r\n.privacy-note {\r\n  display: flex;\r\n  gap: 14px;\r\n  align-items: flex-start;\r\n  background: var(--rojo-suave);\r\n  border: 1px solid rgba(218,41,28,.15);\r\n  border-radius: 12px;\r\n  padding: 16px 20px;\r\n  margin: 24px 0 0;\r\n}\r\n.privacy-icon {\r\n  width: 36px; height: 36px;\r\n  background: var(--rojo);\r\n  border-radius: 8px;\r\n  display: flex; align-items: center; justify-content: center;\r\n  flex-shrink: 0;\r\n}\r\n.privacy-icon svg { width: 18px; height: 18px; fill: white; }\r\n.privacy-note p { font-size: 13px; color: var(--gris-oscuro); line-height: 1.6; }\r\n.privacy-note strong { color: var(--azul); }\r\n\r\n\/* \u2500\u2500 Submit button \u2500\u2500 *\/\r\n.submit-wrap { padding: 24px 32px; background: var(--gris-claro); }\r\n.btn-primary {\r\n  width: 100%;\r\n  padding: 16px;\r\n  background: var(--rojo);\r\n  color: white;\r\n  border: none;\r\n  border-radius: 12px;\r\n  font-family: 'DM Sans', sans-serif;\r\n  font-size: 15px;\r\n  font-weight: 600;\r\n  cursor: pointer;\r\n  transition: all .2s;\r\n  display: flex;\r\n  align-items: center;\r\n  justify-content: center;\r\n  gap: 8px;\r\n  letter-spacing: .01em;\r\n}\r\n.btn-primary:hover { background: var(--rojo-oscuro); transform: translateY(-1px); box-shadow: var(--sombra-hover); }\r\n.btn-primary:active { transform: translateY(0); }\r\n.btn-primary:disabled { background: #C5CAD8; cursor: not-allowed; transform: none; box-shadow: none; }\r\n.btn-primary svg { width: 18px; height: 18px; fill: white; }\r\n\r\n\/* \u2500\u2500 Error msg \u2500\u2500 *\/\r\n.error-msg {\r\n  background: #FFF0EE;\r\n  border: 1px solid rgba(218,41,28,.25);\r\n  color: #8B1A12;\r\n  padding: 14px 18px;\r\n  border-radius: 10px;\r\n  font-size: 13px;\r\n  margin-bottom: 20px;\r\n  display: flex;\r\n  align-items: center;\r\n  gap: 10px;\r\n}\r\n\r\n\/* \u2500\u2500 Success \u2500\u2500 *\/\r\n.success-wrap {\r\n  padding: 60px 32px;\r\n  text-align: center;\r\n}\r\n.success-ring {\r\n  width: 88px; height: 88px;\r\n  border-radius: 50%;\r\n  background: linear-gradient(135deg, var(--rojo), #F06055);\r\n  display: flex; align-items: center; justify-content: center;\r\n  margin: 0 auto 28px;\r\n  box-shadow: 0 8px 32px rgba(218,41,28,.3);\r\n}\r\n.success-ring svg { width: 40px; height: 40px; fill: white; }\r\n.success-wrap h2 {\r\n  font-family: 'Playfair Display', serif;\r\n  font-size: 26px;\r\n  font-weight: 700;\r\n  color: var(--azul);\r\n  margin-bottom: 8px;\r\n}\r\n.success-wrap > p { font-size: 14px; color: var(--gris-texto); margin-bottom: 24px; }\r\n.case-number-box {\r\n  background: var(--azul);\r\n  border-radius: 14px;\r\n  padding: 24px 32px;\r\n  margin: 0 auto 24px;\r\n  max-width: 320px;\r\n}\r\n.case-number-box .label-small { font-size: 11px; font-weight: 600; letter-spacing: .1em; text-transform: uppercase; color: rgba(255,255,255,.5); margin-bottom: 8px; }\r\n.case-number-box .number { font-family: 'Playfair Display', serif; font-size: 32px; font-weight: 700; color: white; letter-spacing: .05em; }\r\n.case-number-box .sub { font-size: 12px; color: rgba(255,255,255,.4); margin-top: 6px; }\r\n.info-box {\r\n  background: var(--azul-suave);\r\n  border-radius: 12px;\r\n  padding: 16px 20px;\r\n  font-size: 13px;\r\n  color: var(--azul-medio);\r\n  line-height: 1.6;\r\n  margin-bottom: 24px;\r\n  text-align: left;\r\n}\r\n.btn-secondary {\r\n  padding: 13px 28px;\r\n  background: transparent;\r\n  color: var(--rojo);\r\n  border: 2px solid var(--rojo);\r\n  border-radius: 10px;\r\n  font-family: 'DM Sans', sans-serif;\r\n  font-size: 14px;\r\n  font-weight: 600;\r\n  cursor: pointer;\r\n  transition: all .2s;\r\n}\r\n.btn-secondary:hover { background: var(--rojo-suave); }\r\n\r\n\/* \u2500\u2500 Track tab \u2500\u2500 *\/\r\n.track-intro {\r\n  font-size: 14px;\r\n  color: var(--gris-texto);\r\n  line-height: 1.7;\r\n  margin-bottom: 24px;\r\n}\r\n.search-row { display: flex; gap: 10px; margin-bottom: 8px; }\r\n.search-row input { flex: 1; }\r\n.btn-search {\r\n  padding: 12px 24px;\r\n  background: var(--azul);\r\n  color: white;\r\n  border: none;\r\n  border-radius: 10px;\r\n  font-family: 'DM Sans', sans-serif;\r\n  font-size: 14px;\r\n  font-weight: 600;\r\n  cursor: pointer;\r\n  white-space: nowrap;\r\n  transition: background .2s;\r\n}\r\n.btn-search:hover { background: var(--azul-medio); }\r\n.btn-search:disabled { background: #C5CAD8; cursor: not-allowed; }\r\n.hint { font-size: 12px; color: #B0B7C3; margin-bottom: 28px; }\r\n\r\n\/* \u2500\u2500 Case result \u2500\u2500 *\/\r\n.case-result {\r\n  background: var(--blanco);\r\n  border: 1px solid var(--gris-borde);\r\n  border-radius: 16px;\r\n  overflow: hidden;\r\n  box-shadow: var(--sombra);\r\n  animation: fadeUp .3s ease;\r\n}\r\n@keyframes fadeUp {\r\n  from { opacity:0; transform:translateY(12px); }\r\n  to { opacity:1; transform:translateY(0); }\r\n}\r\n.case-result-header {\r\n  background: var(--azul);\r\n  padding: 24px 28px;\r\n}\r\n.case-result-num {\r\n  display: inline-block;\r\n  background: var(--rojo);\r\n  color: white;\r\n  font-size: 12px;\r\n  font-weight: 700;\r\n  padding: 5px 14px;\r\n  border-radius: 20px;\r\n  margin-bottom: 10px;\r\n  letter-spacing: .05em;\r\n}\r\n.case-result-title {\r\n  font-family: 'Playfair Display', serif;\r\n  font-size: 18px;\r\n  font-weight: 600;\r\n  color: white;\r\n  margin-bottom: 12px;\r\n}\r\n.case-result-meta {\r\n  display: flex;\r\n  gap: 16px;\r\n  flex-wrap: wrap;\r\n  align-items: center;\r\n}\r\n.status-pill {\r\n  display: inline-flex;\r\n  align-items: center;\r\n  gap: 6px;\r\n  font-size: 12px;\r\n  font-weight: 600;\r\n  padding: 5px 12px;\r\n  border-radius: 20px;\r\n  background: rgba(255,255,255,.15);\r\n  color: white;\r\n}\r\n.status-dot { width: 7px; height: 7px; border-radius: 50%; }\r\n.case-meta-text { font-size: 12px; color: rgba(255,255,255,.5); }\r\n\r\n.messages { padding: 0; }\r\n.msg { padding: 22px 28px; border-bottom: 1px solid var(--gris-borde); }\r\n.msg:last-child { border-bottom: none; }\r\n.msg-header { display: flex; align-items: center; gap: 10px; margin-bottom: 12px; }\r\n.msg-avatar {\r\n  width: 32px; height: 32px; border-radius: 50%;\r\n  display: flex; align-items: center; justify-content: center;\r\n  font-size: 12px; font-weight: 700; flex-shrink: 0;\r\n}\r\n.msg-avatar.d { background: #FEF3C7; color: #92400E; }\r\n.msg-avatar.e { background: var(--azul-suave); color: var(--azul); }\r\n.msg-sender { font-size: 13px; font-weight: 600; color: var(--azul); }\r\n.msg-time { font-size: 11px; color: #B0B7C3; margin-left: auto; }\r\n.msg-body { font-size: 14px; color: var(--gris-oscuro); line-height: 1.7; margin-left: 42px; }\r\n\r\n\/* \u2500\u2500 File upload \u2500\u2500 *\/\r\n.file-upload-area {\r\n  border: 2px dashed var(--gris-borde);\r\n  border-radius: 12px;\r\n  padding: 28px 20px;\r\n  text-align: center;\r\n  background: var(--gris-claro);\r\n  transition: all .2s;\r\n  cursor: pointer;\r\n  position: relative;\r\n}\r\n.file-upload-area:hover, .file-upload-area.drag-over {\r\n  border-color: var(--rojo);\r\n  background: var(--rojo-suave);\r\n}\r\n.file-upload-area input[type=\"file\"] {\r\n  position: absolute; inset: 0; opacity: 0; cursor: pointer;\r\n  width: 100%; height: 100%;\r\n  padding: 0 !important; border: none !important; background: none !important;\r\n  box-shadow: none !important;\r\n}\r\n.file-upload-icon {\r\n  width: 44px; height: 44px;\r\n  background: var(--azul-suave);\r\n  border-radius: 10px;\r\n  display: flex; align-items: center; justify-content: center;\r\n  margin: 0 auto 12px;\r\n}\r\n.file-upload-icon svg { width: 22px; height: 22px; fill: var(--azul-medio); }\r\n.file-upload-text { font-size: 14px; font-weight: 600; color: var(--azul); margin-bottom: 4px; }\r\n.file-upload-sub { font-size: 12px; color: var(--gris-texto); }\r\n.file-upload-sub span { color: var(--rojo); font-weight: 600; }\r\n.file-list { margin-top: 14px; display: flex; flex-direction: column; gap: 8px; }\r\n.file-item {\r\n  display: flex; align-items: center; gap: 10px;\r\n  background: var(--blanco);\r\n  border: 1px solid var(--gris-borde);\r\n  border-radius: 10px;\r\n  padding: 10px 14px;\r\n}\r\n.file-item-icon { width: 32px; height: 32px; background: var(--azul-suave); border-radius: 8px; display: flex; align-items: center; justify-content: center; flex-shrink: 0; }\r\n.file-item-icon svg { width: 16px; height: 16px; fill: var(--azul-medio); }\r\n.file-item-info { flex: 1; min-width: 0; }\r\n.file-item-name { font-size: 13px; font-weight: 600; color: var(--azul); white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }\r\n.file-item-size { font-size: 11px; color: var(--gris-texto); margin-top: 1px; }\r\n.file-item-remove { width: 28px; height: 28px; border: none; background: #FFF0EE; border-radius: 6px; cursor: pointer; display: flex; align-items: center; justify-content: center; flex-shrink: 0; transition: background .15s; }\r\n.file-item-remove:hover { background: rgba(218,41,28,.2); }\r\n.file-item-remove svg { width: 14px; height: 14px; fill: var(--rojo); }\r\n\r\n\/* \u2500\u2500 Acceptance checkbox \u2500\u2500 *\/\r\n.acceptance-wrap {\r\n  padding: 20px 32px;\r\n  border-top: 1px solid var(--gris-borde);\r\n  background: var(--gris-claro);\r\n}\r\n.acceptance-label {\r\n  display: flex;\r\n  align-items: flex-start;\r\n  gap: 12px;\r\n  cursor: pointer;\r\n  user-select: none;\r\n}\r\n.acceptance-check {\r\n  width: 20px; height: 20px; min-width: 20px;\r\n  border: 2px solid var(--gris-borde);\r\n  border-radius: 5px;\r\n  margin-top: 1px;\r\n  display: flex; align-items: center; justify-content: center;\r\n  background: var(--blanco);\r\n  transition: all .15s;\r\n  flex-shrink: 0;\r\n}\r\n.acceptance-check.checked {\r\n  background: var(--rojo);\r\n  border-color: var(--rojo);\r\n}\r\n.acceptance-check svg { width: 12px; height: 12px; fill: white; }\r\n.acceptance-text { font-size: 13px; color: var(--gris-oscuro); line-height: 1.6; }\r\n.acceptance-text a { color: var(--rojo); text-decoration: underline; }\r\n\r\n@media(max-width:580px) {\r\n  .row2 { grid-template-columns: 1fr; }\r\n  .card-section { padding: 22px 20px; }\r\n  .submit-wrap { padding: 20px; }\r\n  .acceptance-wrap { padding: 16px 20px; }\r\n  .content { padding: 24px 16px 48px; }\r\n  .hero { padding: 40px 20px 48px; }\r\n}\r\n<\/style>\r\n<\/head>\r\n<body>\r\n<div id=\"root\"><\/div>\r\n<script type=\"text\/babel\">\r\nconst { useState } = React;\r\nconst API = 'https:\/\/constructoracolpatria.com\/sites\/linea-etica\/wp-json\/linea-etica\/v1';\r\n\r\nconst TIPOS_USUARIO = ['Contratista','Proveedor','Asociados','Socios','Colaboradores (Colombia)','Colaboradores (Urbana M\u00e9xico y Per\u00fa)','Contrapartes (Urbana M\u00e9xico y Per\u00fa)','Clientes','Otro'];\r\nconst TIPOS_DENUNCIA = ['1. Soborno y corrupci\u00f3n','2. Corrupci\u00f3n privada (pago de comisiones inapropiadas)','3. Conflicto de intereses','4. Fraude corporativo (estafa, hurto, robo o desviaci\u00f3n de activos)','5. Lavado de activos y financiaci\u00f3n del terrorismo (LA\/FT)','6. Irregularidades en contrataci\u00f3n (tr\u00e1fico de influencias y colusi\u00f3n)','7. Regalos y hospitalidades indebidas','8. Uso indebido de recursos o informaci\u00f3n','9. Incumplimiento del C\u00f3digo de \u00c9tica o Pol\u00edticas Internas','10. Incumplimiento legal o regulatorio','11. Otros (especifique en la descripci\u00f3n)'];\r\nconst TIPOS_DOC = ['C\u00e9dula de ciudadan\u00eda','C\u00e9dula de extranjer\u00eda','Pasaporte','NIT','Otro'];\r\n\r\nfunction SubmitForm() {\r\n  const [step, setStep] = useState('form');\r\n  const [loading, setLoading] = useState(false);\r\n  const [error, setError] = useState('');\r\n  const [caseNum, setCaseNum] = useState('');\r\n  const [form, setForm] = useState({ tipo_usuario:'', nombre:'', apellidos:'', tipo_documento:'', numero_documento:'', ciudad:'', email:'', tipo_denuncia:'', descripcion:'' });\r\n  const [archivos, setArchivos] = useState([]);\r\n  const [aceptado, setAceptado] = useState(false);\r\n  const [dragOver, setDragOver] = useState(false);\r\n  const set = (k,v) => setForm(f=>({...f,[k]:v}));\r\n\r\n  const fmtSize = b => b < 1024*1024 ? `${(b\/1024).toFixed(1)} KB` : `${(b\/(1024*1024)).toFixed(1)} MB`;\r\n\r\n  const agregarArchivos = (nuevos) => {\r\n    const arr = Array.from(nuevos);\r\n    const validos = arr.filter(f => f.size <= 10*1024*1024);\r\n    if (validos.length < arr.length) setError('Algunos archivos superan 10 MB y no fueron agregados.');\r\n    setArchivos(prev => {\r\n      const set = new Set(prev.map(f => f.name+f.size));\r\n      return [...prev, ...validos.filter(f => !set.has(f.name+f.size))].slice(0,5);\r\n    });\r\n  };\r\n\r\n  const quitarArchivo = (i) => setArchivos(prev => prev.filter((_,j)=>j!==i));\r\n\r\n  const resetForm = () => {\r\n    setStep('form');\r\n    setForm({tipo_usuario:'',nombre:'',apellidos:'',tipo_documento:'',numero_documento:'',ciudad:'',email:'',tipo_denuncia:'',descripcion:''});\r\n    setArchivos([]); setAceptado(false); setError('');\r\n  };\r\n\r\n  const handleSubmit = async (e) => {\r\n    e.preventDefault(); setError('');\r\n    if (!form.tipo_usuario||!form.ciudad||!form.tipo_denuncia||!form.descripcion) { setError('Complete los campos obligatorios marcados con *.'); return; }\r\n    if (!aceptado) { setError('Debe aceptar el tratamiento de datos personales para continuar.'); return; }\r\n    setLoading(true);\r\n    try {\r\n      const body = new FormData();\r\n      Object.entries(form).forEach(([k,v]) => body.append(k, v));\r\n      archivos.forEach(f => body.append('archivos[]', f));\r\n      const res = await fetch(`${API}\/crear-caso`, { method:'POST', body });\r\n      const data = await res.json();\r\n      if (data.success) { setCaseNum(data.numero_caso); setStep('success'); }\r\n      else setError(data.message||'Error al enviar. Intente de nuevo.');\r\n    } catch { setError('Error de conexi\u00f3n. Por favor intente de nuevo.'); }\r\n    setLoading(false);\r\n  };\r\n\r\n  if (step==='success') return (\r\n  <div className=\"card\"><div className=\"success-wrap\">\r\n    <div className=\"success-ring\"><svg viewBox=\"0 0 24 24\"><path d=\"M9 16.17L4.83 12l-1.42 1.41L9 19 21 7l-1.41-1.41z\"\/><\/svg><\/div>\r\n    <h2>Denuncia registrada<\/h2>\r\n    <p>Su caso ha sido recibido y ser\u00e1 atendido con absoluta confidencialidad.<\/p>\r\n    <div className=\"case-number-box\">\r\n      <div className=\"label-small\">N\u00famero de caso<\/div>\r\n      <div className=\"number\">{caseNum}<\/div>\r\n    <\/div>\r\n    <button className=\"btn-secondary\" onClick={resetForm}>Registrar otra denuncia<\/button>\r\n  <\/div><\/div>\r\n);\r\n\r\n  return (\r\n    <form onSubmit={handleSubmit}>\r\n      {error && <div className=\"error-msg\"><svg style={{width:16,height:16,fill:'#DA291C',flexShrink:0}} viewBox=\"0 0 24 24\"><path d=\"M12 2C6.48 2 2 6.48 2 12s4.48 10 10 10 10-4.48 10-10S17.52 2 12 2zm1 15h-2v-2h2v2zm0-4h-2V7h2v6z\"\/><\/svg>{error}<\/div>}\r\n      <div className=\"card\">\r\n        <div className=\"card-section\">\r\n          <div className=\"section-label\">Informaci\u00f3n del denunciante<\/div>\r\n          <div className=\"field\">\r\n            <label className=\"label\">Tipo de usuario <span className=\"req\">*<\/span><\/label>\r\n            <select value={form.tipo_usuario} onChange={e=>set('tipo_usuario',e.target.value)} required>\r\n              <option value=\"\">Seleccione una opci\u00f3n<\/option>\r\n              {TIPOS_USUARIO.map(t=><option key={t} value={t}>{t}<\/option>)}\r\n            <\/select>\r\n          <\/div>\r\n          <div className=\"row2\">\r\n            <div className=\"field\"><label className=\"label\">Nombre <span className=\"opt\">(opcional)<\/span><\/label><input type=\"text\" placeholder=\"Su nombre\" value={form.nombre} onChange={e=>set('nombre',e.target.value)}\/><\/div>\r\n            <div className=\"field\"><label className=\"label\">Apellidos <span className=\"opt\">(opcional)<\/span><\/label><input type=\"text\" placeholder=\"Sus apellidos\" value={form.apellidos} onChange={e=>set('apellidos',e.target.value)}\/><\/div>\r\n          <\/div>\r\n          <div className=\"row2\">\r\n            <div className=\"field\"><label className=\"label\">Tipo de documento <span className=\"opt\">(opcional)<\/span><\/label><select value={form.tipo_documento} onChange={e=>set('tipo_documento',e.target.value)}><option value=\"\">Seleccione<\/option>{TIPOS_DOC.map(t=><option key={t} value={t}>{t}<\/option>)}<\/select><\/div>\r\n            <div className=\"field\"><label className=\"label\">N\u00famero de documento <span className=\"opt\">(opcional)<\/span><\/label><input type=\"text\" placeholder=\"N\u00famero\" value={form.numero_documento} onChange={e=>set('numero_documento',e.target.value)}\/><\/div>\r\n          <\/div>\r\n          <div className=\"field\"><label className=\"label\">Ciudad o municipio <span className=\"req\">*<\/span><\/label><input type=\"text\" placeholder=\"Ej. Bogot\u00e1\" value={form.ciudad} onChange={e=>set('ciudad',e.target.value)} required\/><\/div>\r\n          <div className=\"field\"><label className=\"label\">Correo electr\u00f3nico <span className=\"opt\">(opcional)<\/span><\/label><input type=\"email\" placeholder=\"su@correo.com\" value={form.email} onChange={e=>set('email',e.target.value)}\/><\/div>\r\n        <\/div>\r\n        <div className=\"card-section\">\r\n          <div className=\"section-label\">Detalle de la denuncia<\/div>\r\n          <div className=\"field\"><label className=\"label\">Tipo de denuncia <span className=\"req\">*<\/span><\/label><select value={form.tipo_denuncia} onChange={e=>set('tipo_denuncia',e.target.value)} required><option value=\"\">Seleccione una categor\u00eda<\/option>{TIPOS_DENUNCIA.map(t=><option key={t} value={t}>{t}<\/option>)}<\/select><\/div>\r\n          <div className=\"field\"><label className=\"label\">Descripci\u00f3n detallada <span className=\"req\">*<\/span><\/label><textarea placeholder=\"Describa los hechos con precisi\u00f3n: fechas, personas involucradas, lugar y cualquier evidencia disponible...\" value={form.descripcion} onChange={e=>set('descripcion',e.target.value)} required\/><\/div>\r\n          <div className=\"field\">\r\n            <label className=\"label\">Archivos adjuntos <span className=\"opt\">(opcional \u2014 m\u00e1x. 5 archivos, 10 MB c\/u)<\/span><\/label>\r\n            <div\r\n              className={`file-upload-area${dragOver?' drag-over':''}`}\r\n              onDragOver={e=>{e.preventDefault();setDragOver(true);}}\r\n              onDragLeave={()=>setDragOver(false)}\r\n              onDrop={e=>{e.preventDefault();setDragOver(false);agregarArchivos(e.dataTransfer.files);}}\r\n            >\r\n              <input type=\"file\" multiple accept=\".pdf,.doc,.docx,.xls,.xlsx,.png,.jpg,.jpeg,.gif,.mp4,.mov,.zip,.rar\" onChange={e=>{agregarArchivos(e.target.files);e.target.value='';}} disabled={archivos.length>=5}\/>\r\n              <div className=\"file-upload-icon\"><svg viewBox=\"0 0 24 24\"><path d=\"M14 2H6a2 2 0 0 0-2 2v16a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2V8l-6-6zm0 9h-2v3H9v-3H7l4-4 4 4h-2zm1-6V3.5L18.5 9H14z\"\/><\/svg><\/div>\r\n              <div className=\"file-upload-text\">{archivos.length>=5?'L\u00edmite de 5 archivos alcanzado':'Haga clic o arrastre archivos aqu\u00ed'}<\/div>\r\n              <div className=\"file-upload-sub\">PDF, Word, Excel, im\u00e1genes, videos \u00b7 <span>M\u00e1x. 10 MB por archivo<\/span><\/div>\r\n            <\/div>\r\n            {archivos.length>0&&<div className=\"file-list\">{archivos.map((f,i)=>(\r\n              <div className=\"file-item\" key={i}>\r\n                <div className=\"file-item-icon\"><svg viewBox=\"0 0 24 24\"><path d=\"M14 2H6a2 2 0 0 0-2 2v16a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2V8l-6-6zM13 9V3.5L18.5 9H13zM8 13h8v1.5H8V13zm0 3h5v1.5H8V16zm0-6h2v1.5H8V10z\"\/><\/svg><\/div>\r\n                <div className=\"file-item-info\">\r\n                  <div className=\"file-item-name\">{f.name}<\/div>\r\n                  <div className=\"file-item-size\">{fmtSize(f.size)}<\/div>\r\n                <\/div>\r\n                <button type=\"button\" className=\"file-item-remove\" onClick={()=>quitarArchivo(i)}>\r\n                  <svg viewBox=\"0 0 24 24\"><path d=\"M19 6.41L17.59 5 12 10.59 6.41 5 5 6.41 10.59 12 5 17.59 6.41 19 12 13.41 17.59 19 19 17.59 13.41 12z\"\/><\/svg>\r\n                <\/button>\r\n              <\/div>\r\n            ))}<\/div>}\r\n          <\/div>\r\n          <div className=\"privacy-note\">\r\n            <div className=\"privacy-icon\"><svg viewBox=\"0 0 24 24\"><path d=\"M12 1L3 5v6c0 5.55 3.84 10.74 9 12 5.16-1.26 9-6.45 9-12V5l-9-4zm-1 14l-3-3 1.41-1.41L11 12.17l4.59-4.58L17 9l-6 6z\"\/><\/svg><\/div>\r\n            <p>Su denuncia ser\u00e1 tratada con <strong>estricta confidencialidad<\/strong>. Los datos personales son opcionales. La Constructora garantiza no represalias y protecci\u00f3n al denunciante.<\/p>\r\n          <\/div>\r\n        <\/div>\r\n        <div className=\"acceptance-wrap\">\r\n          <div className=\"acceptance-label\" onClick={()=>setAceptado(v=>!v)}>\r\n            <div className={`acceptance-check${aceptado?' checked':''}`}>\r\n              {aceptado&&<svg viewBox=\"0 0 24 24\"><path d=\"M9 16.17L4.83 12l-1.42 1.41L9 19 21 7l-1.41-1.41z\"\/><\/svg>}\r\n            <\/div>\r\n            <span className=\"acceptance-text\">\r\n              He le\u00eddo y acepto el tratamiento de mis datos personales conforme a la pol\u00edtica de privacidad de la Constructora Colpatria. Entiendo que la informaci\u00f3n suministrada ser\u00e1 tratada con estricta confidencialidad. <span style={{color:'var(--rojo)',fontWeight:600}}>*<\/span>\r\n            <\/span>\r\n          <\/div>\r\n        <\/div>\r\n        <div className=\"submit-wrap\">\r\n          <button type=\"submit\" className=\"btn-primary\" disabled={loading}>\r\n            {loading ? 'Enviando denuncia...' : (<><svg viewBox=\"0 0 24 24\"><path d=\"M2.01 21L23 12 2.01 3 2 10l15 2-15 2z\"\/><\/svg>Enviar denuncia<\/>)}\r\n          <\/button>\r\n        <\/div>\r\n      <\/div>\r\n    <\/form>\r\n  );\r\n}\r\n\r\nfunction TrackCase() {\r\n  const [numero, setNumero] = useState('');\r\n  const [loading, setLoading] = useState(false);\r\n  const [error, setError] = useState('');\r\n  const [caso, setCaso] = useState(null);\r\n\r\n  const buscar = async () => {\r\n    if(!numero.trim()) return;\r\n    setError(''); setCaso(null); setLoading(true);\r\n    try {\r\n      const res = await fetch(`${API}\/consultar-caso`,{method:'POST',headers:{'Content-Type':'application\/json'},body:JSON.stringify({numero_caso:numero.trim()})});\r\n      const data = await res.json();\r\n      if(data.success) setCaso(data.caso);\r\n      else setError(data.message||'No se encontr\u00f3 ning\u00fan caso con ese n\u00famero.');\r\n    } catch { setError('Error de conexi\u00f3n. Intente de nuevo.'); }\r\n    setLoading(false);\r\n  };\r\n\r\n  const fmt = dt => !dt ? '' : new Date(dt).toLocaleDateString('es-CO',{year:'numeric',month:'long',day:'numeric',hour:'2-digit',minute:'2-digit'});\r\n  const fmtShort = dt => !dt ? '' : new Date(dt).toLocaleDateString('es-CO',{day:'numeric',month:'short',year:'numeric'});\r\n\r\n  return (\r\n    <div>\r\n      <p className=\"track-intro\">Ingrese el n\u00famero de caso que recibi\u00f3 al radicar su denuncia. Podr\u00e1 ver el estado actual y las respuestas del equipo.<\/p>\r\n      <div className=\"search-row\">\r\n        <input type=\"text\" placeholder=\"Ej. CASE-00001\" value={numero} onChange={e=>setNumero(e.target.value)} onKeyDown={e=>e.key==='Enter'&&buscar()}\/>\r\n        <button className=\"btn-search\" onClick={buscar} disabled={loading||!numero.trim()}>{loading?'Buscando...':'Consultar'}<\/button>\r\n      <\/div>\r\n      <p className=\"hint\">El n\u00famero de caso fue enviado a su correo y mostrado al finalizar el formulario.<\/p>\r\n      {error && <div className=\"error-msg\"><svg style={{width:16,height:16,fill:'#DA291C',flexShrink:0}} viewBox=\"0 0 24 24\"><path d=\"M12 2C6.48 2 2 6.48 2 12s4.48 10 10 10 10-4.48 10-10S17.52 2 12 2zm1 15h-2v-2h2v2zm0-4h-2V7h2v6z\"\/><\/svg>{error}<\/div>}\r\n      {caso && (\r\n        <div className=\"case-result\">\r\n          <div className=\"case-result-header\">\r\n            <div className=\"case-result-num\">{caso.numero}<\/div>\r\n            <div className=\"case-result-title\">{caso.asunto}<\/div>\r\n            <div className=\"case-result-meta\">\r\n              <span className=\"status-pill\"><span className=\"status-dot\" style={{background:caso.color_estado}}\/>{caso.estado}<\/span>\r\n              <span className=\"case-meta-text\">Radicado: {fmtShort(caso.creado)}<\/span>\r\n              <span className=\"case-meta-text\">Actualizado: {fmtShort(caso.actualizado)}<\/span>\r\n            <\/div>\r\n          <\/div>\r\n          <div className=\"messages\">\r\n            {caso.mensajes&&caso.mensajes.length>0 ? caso.mensajes.map((m,i)=>(\r\n              <div className=\"msg\" key={i}>\r\n                <div className=\"msg-header\">\r\n                  <div className={`msg-avatar ${m.remitente==='denunciante'?'d':'e'}`}>{m.remitente==='denunciante'?'D':'LE'}<\/div>\r\n                  <span className=\"msg-sender\">{m.remitente==='denunciante'?'Su denuncia':'L\u00ednea \u00c9tica'}<\/span>\r\n                  <span className=\"msg-time\">{fmt(m.created_at)}<\/span>\r\n                <\/div>\r\n                <div className=\"msg-body\" dangerouslySetInnerHTML={{__html:m.content}}\/>\r\n              <\/div>\r\n            )) : <div style={{padding:'24px 28px',fontSize:13,color:'#B0B7C3'}}>No hay mensajes a\u00fan.<\/div>}\r\n          <\/div>\r\n        <\/div>\r\n      )}\r\n    <\/div>\r\n  );\r\n}\r\n\r\nfunction App() {\r\n  const [tab, setTab] = useState('form');\r\n  return (\r\n    <div>\r\n      <div className=\"hero\">\r\n        <div className=\"hero-chip\"><span className=\"hero-chip-dot\"\/>Canal de Denuncia<\/div>\r\n        <h1>L\u00ednea <span>\u00c9tica<\/span><\/h1>\r\n        <p>Mecanismo confidencial para reportar situaciones irregulares. Su informaci\u00f3n es tratada con absoluta reserva y discreci\u00f3n.<\/p>\r\n      <\/div>\r\n      <div className=\"tabs-wrap\">\r\n        <div className=\"tabs\">\r\n          <button className={`tab-btn${tab==='form'?' active':''}`} onClick={()=>setTab('form')}>\r\n            <svg className=\"tab-icon\" viewBox=\"0 0 24 24\" fill=\"currentColor\"><path d=\"M14 2H6a2 2 0 0 0-2 2v16a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2V8l-6-6zm-1 7V3.5L18.5 9H13zM8 13h8v1.5H8V13zm0 3h8v1.5H8V16zm0-6h3v1.5H8V10z\"\/><\/svg>\r\n            Radicar denuncia\r\n          <\/button>\r\n          {\/* Pesta\u00f1a Consultar mi caso temporalmente oculta *\/}\r\n        <\/div>\r\n      <\/div>\r\n      <div className=\"content\">{tab==='form'?<SubmitForm\/>:<TrackCase\/>}<\/div>\r\n    <\/div>\r\n  );\r\n}\r\n\r\nReactDOM.createRoot(document.getElementById('root')).render(<App\/>);\r\n<\/script>\r\n<\/body>\r\n<\/html>\t\t\t\t<\/div>\n\t\t\t\t<\/div>\n\t\t\t\t<\/div>\n\t\t","protected":false},"excerpt":{"rendered":"","protected":false},"author":1,"featured_media":0,"parent":0,"menu_order":0,"comment_status":"closed","ping_status":"closed","template":"","meta":{"footnotes":""},"class_list":["post-11","page","type-page","status-publish","hentry"],"_links":{"self":[{"href":"https:\/\/constructoracolpatria.com\/sites\/linea-etica\/wp-json\/wp\/v2\/pages\/11","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/constructoracolpatria.com\/sites\/linea-etica\/wp-json\/wp\/v2\/pages"}],"about":[{"href":"https:\/\/constructoracolpatria.com\/sites\/linea-etica\/wp-json\/wp\/v2\/types\/page"}],"author":[{"embeddable":true,"href":"https:\/\/constructoracolpatria.com\/sites\/linea-etica\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/constructoracolpatria.com\/sites\/linea-etica\/wp-json\/wp\/v2\/comments?post=11"}],"version-history":[{"count":30,"href":"https:\/\/constructoracolpatria.com\/sites\/linea-etica\/wp-json\/wp\/v2\/pages\/11\/revisions"}],"predecessor-version":[{"id":136,"href":"https:\/\/constructoracolpatria.com\/sites\/linea-etica\/wp-json\/wp\/v2\/pages\/11\/revisions\/136"}],"wp:attachment":[{"href":"https:\/\/constructoracolpatria.com\/sites\/linea-etica\/wp-json\/wp\/v2\/media?parent=11"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}