{"id":5880,"date":"2025-10-28T18:37:17","date_gmt":"2025-10-28T23:37:17","guid":{"rendered":"https:\/\/inversionesguru.com\/co\/?post_type=herramientas&#038;p=5880"},"modified":"2026-05-30T12:10:25","modified_gmt":"2026-05-30T17:10:25","slug":"calculadora-bolsillos-davivienda-colombia","status":"publish","type":"herramientas","link":"https:\/\/inversionesguru.com\/co\/herramientas\/calculadora-bolsillos-davivienda-colombia\/","title":{"rendered":"Calculadora Bolsillos Davivienda Colombia | Simula 8% EA"},"content":{"rendered":"\t\t<div data-elementor-type=\"wp-post\" data-elementor-id=\"5880\" class=\"elementor elementor-5880\" data-elementor-post-type=\"herramientas\">\n\t\t\t\t<div class=\"elementor-element elementor-element-29c714b e-con-full e-flex e-con e-parent\" data-id=\"29c714b\" data-element_type=\"container\" data-e-type=\"container\" data-settings=\"{&quot;ekit_has_onepagescroll_dot&quot;:&quot;yes&quot;}\">\n\t\t\t\t<div class=\"elementor-element elementor-element-4e30729 elementor-widget elementor-widget-html\" data-id=\"4e30729\" data-element_type=\"widget\" data-e-type=\"widget\" data-settings=\"{&quot;ekit_we_effect_on&quot;:&quot;none&quot;}\" data-widget_type=\"html.default\">\n\t\t\t\t\t<style>\n  #ig-davi-pocket-tool {\n    --ig-ink: #17332f;\n    --ig-ink-2: #24443e;\n    --ig-muted: #5b6f68;\n    --ig-muted-2: #789088;\n    --ig-bg-a: #effbf6;\n    --ig-bg-b: #fff3ec;\n    --ig-panel: #ffffff;\n    --ig-panel-soft: rgba(255, 255, 255, 0.78);\n    --ig-line: rgba(23, 51, 47, 0.13);\n    --ig-line-strong: rgba(23, 51, 47, 0.24);\n    --ig-accent: #0f9f7a;\n    --ig-accent-dark: #08755d;\n    --ig-coral: #ef6a4a;\n    --ig-coral-dark: #c84f34;\n    --ig-green-soft: #dff8ed;\n    --ig-coral-soft: #ffe2d7;\n    --ig-red: #e30613;\n    --ig-red-soft: #fff0f1;\n    --ig-shadow: 0 24px 54px rgba(23, 51, 47, 0.12);\n    --ig-shadow-soft: 0 14px 34px rgba(23, 51, 47, 0.08);\n    --ig-radius: 8px;\n    display: block;\n    width: 100%;\n    overflow: hidden;\n    color: var(--ig-ink);\n    background:\n      linear-gradient(90deg, rgba(15, 159, 122, 0.07) 1px, transparent 1px),\n      linear-gradient(180deg, rgba(23, 51, 47, 0.05) 1px, transparent 1px),\n      var(--ig-bg-a);\n    background-size: 56px 56px, 56px 56px, auto;\n    font-family: Inter, ui-sans-serif, system-ui, -apple-system, BlinkMacSystemFont, \"Segoe UI\", sans-serif;\n    line-height: 1.5;\n    -webkit-font-smoothing: antialiased;\n    text-rendering: optimizeLegibility;\n  }\n\n  #ig-davi-pocket-tool *,\n  #ig-davi-pocket-tool *::before,\n  #ig-davi-pocket-tool *::after { box-sizing: border-box; }\n\n  #ig-davi-pocket-tool :where(h1,h2,h3,h4,p,ul,li,figure,blockquote) { margin: 0; padding: 0; }\n  #ig-davi-pocket-tool :where(button,input,select,a) { font: inherit; -webkit-tap-highlight-color: transparent; }\n  #ig-davi-pocket-tool button { cursor: pointer; }\n  #ig-davi-pocket-tool a { color: inherit; text-decoration: none; }\n  #ig-davi-pocket-tool :where(h1,h2,h3,p,span,strong,label,td,th,button) { overflow-wrap: break-word; }\n\n  #ig-davi-pocket-tool .ig-wrap {\n    width: min(1120px, calc(100% - 32px));\n    max-width: 100%;\n    margin: 0 auto;\n  }\n\n  #ig-davi-pocket-tool .ig-section { padding: 42px 0; }\n\n  #ig-davi-pocket-tool .ig-hero {\n    display: grid;\n    grid-template-columns: minmax(0, 1.05fr) minmax(320px, 0.95fr);\n    gap: 24px;\n    align-items: stretch;\n  }\n\n  #ig-davi-pocket-tool .ig-card,\n  #ig-davi-pocket-tool .ig-rate-card,\n  #ig-davi-pocket-tool .ig-kpi,\n  #ig-davi-pocket-tool .ig-info-box,\n  #ig-davi-pocket-tool .ig-table-shell,\n  #ig-davi-pocket-tool .ig-pdf-box {\n    min-width: 0;\n    border: 1px solid var(--ig-line);\n    border-radius: var(--ig-radius);\n    background: rgba(255, 255, 255, 0.91);\n    box-shadow: var(--ig-shadow-soft);\n  }\n\n  #ig-davi-pocket-tool .ig-main-card { padding: 26px; }\n\n  #ig-davi-pocket-tool .ig-eyebrow {\n    display: inline-flex;\n    align-items: center;\n    gap: 8px;\n    width: fit-content;\n    min-height: 32px;\n    padding: 6px 10px;\n    border: 1px solid rgba(15, 159, 122, 0.24);\n    border-radius: var(--ig-radius);\n    background: rgba(255, 255, 255, 0.72);\n    color: var(--ig-accent-dark);\n    font-size: 12px;\n    font-weight: 850;\n  }\n\n  #ig-davi-pocket-tool .ig-bank-badge {\n    display: inline-flex;\n    align-items: center;\n    gap: 8px;\n    min-height: 30px;\n    padding: 5px 9px;\n    border: 1px solid rgba(227, 6, 19, 0.18);\n    border-radius: var(--ig-radius);\n    background: var(--ig-red-soft);\n    color: #a90610;\n    font-size: 12px;\n    font-weight: 850;\n  }\n\n  #ig-davi-pocket-tool .ig-hero-top {\n    display: flex;\n    flex-wrap: wrap;\n    gap: 10px;\n    align-items: center;\n    justify-content: space-between;\n    margin-bottom: 14px;\n  }\n\n  #ig-davi-pocket-tool h1 {\n    max-width: 820px;\n    color: var(--ig-ink);\n    font-size: clamp(32px, 4.2vw, 54px);\n    line-height: 1.05;\n    font-weight: 930;\n    letter-spacing: -0.02em;\n  }\n\n  #ig-davi-pocket-tool h1 span { color: var(--ig-coral-dark); }\n\n  #ig-davi-pocket-tool .ig-lead {\n    max-width: 760px;\n    margin-top: 14px;\n    color: var(--ig-muted);\n    font-size: 17px;\n    line-height: 1.72;\n  }\n\n  #ig-davi-pocket-tool .ig-proof-grid {\n    display: grid;\n    grid-template-columns: repeat(3, minmax(0, 1fr));\n    gap: 10px;\n    margin-top: 20px;\n  }\n\n  #ig-davi-pocket-tool .ig-proof {\n    display: flex;\n    gap: 9px;\n    align-items: center;\n    min-height: 54px;\n    padding: 10px 12px;\n    border: 1px solid var(--ig-line);\n    border-radius: var(--ig-radius);\n    background: rgba(255,255,255,0.72);\n    color: var(--ig-ink-2);\n    font-size: 13px;\n    font-weight: 780;\n  }\n\n  #ig-davi-pocket-tool .ig-icon-dot {\n    display: inline-flex;\n    align-items: center;\n    justify-content: center;\n    flex: 0 0 auto;\n    width: 34px;\n    height: 34px;\n    border-radius: var(--ig-radius);\n    color: var(--ig-accent-dark);\n    background: var(--ig-green-soft);\n  }\n\n  #ig-davi-pocket-tool .ig-icon-dot.is-coral { color: var(--ig-coral-dark); background: var(--ig-coral-soft); }\n  #ig-davi-pocket-tool .ig-icon-dot.is-red { color: #a90610; background: var(--ig-red-soft); }\n\n  #ig-davi-pocket-tool .ig-rate-panel {\n    position: relative;\n    display: grid;\n    gap: 14px;\n    padding: 20px;\n    overflow: hidden;\n    background:\n      linear-gradient(135deg, rgba(239, 106, 74, 0.12), transparent 44%),\n      var(--ig-ink);\n    color: #ffffff;\n    box-shadow: var(--ig-shadow);\n  }\n\n  #ig-davi-pocket-tool .ig-rate-panel::after {\n    content: \"\";\n    position: absolute;\n    inset: 12px;\n    border: 1px dashed rgba(255,255,255,0.18);\n    border-radius: var(--ig-radius);\n    pointer-events: none;\n  }\n\n  #ig-davi-pocket-tool .ig-rate-panel > * { position: relative; z-index: 1; }\n  #ig-davi-pocket-tool .ig-rate-panel h2 { color: #ffffff; font-size: 25px; line-height: 1.15; font-weight: 930; }\n  #ig-davi-pocket-tool .ig-rate-panel p { color: rgba(255,255,255,0.76); font-size: 14px; line-height: 1.62; }\n\n  #ig-davi-pocket-tool .ig-rate-grid {\n    display: grid;\n    grid-template-columns: repeat(3, minmax(0, 1fr));\n    gap: 10px;\n  }\n\n  #ig-davi-pocket-tool .ig-rate-card {\n    padding: 14px;\n    border-color: rgba(255,255,255,0.16);\n    background: rgba(255,255,255,0.08);\n    box-shadow: none;\n  }\n\n  #ig-davi-pocket-tool .ig-rate-card span {\n    display: block;\n    color: rgba(255,255,255,0.72);\n    font-size: 11px;\n    font-weight: 800;\n    text-transform: uppercase;\n    line-height: 1.35;\n  }\n\n  #ig-davi-pocket-tool .ig-rate-card strong {\n    display: block;\n    margin-top: 6px;\n    color: #ffffff;\n    font-size: 25px;\n    line-height: 1;\n    font-weight: 930;\n  }\n\n  #ig-davi-pocket-tool .ig-rate-card small {\n    display: block;\n    margin-top: 6px;\n    color: rgba(255,255,255,0.72);\n    font-size: 11px;\n    line-height: 1.4;\n  }\n\n  #ig-davi-pocket-tool .ig-form-grid {\n    display: grid;\n    grid-template-columns: repeat(2, minmax(0, 1fr));\n    gap: 16px;\n    margin-top: 22px;\n  }\n\n  #ig-davi-pocket-tool .ig-field { display: grid; gap: 7px; }\n\n  #ig-davi-pocket-tool .ig-field label {\n    color: var(--ig-ink-2);\n    font-size: 13px;\n    font-weight: 850;\n  }\n\n  #ig-davi-pocket-tool .ig-field input,\n  #ig-davi-pocket-tool .ig-field select {\n    width: 100%;\n    min-height: 50px;\n    padding: 12px 12px;\n    border: 1px solid var(--ig-line);\n    border-radius: var(--ig-radius);\n    outline: 0;\n    background: #ffffff;\n    color: var(--ig-ink);\n    font-size: 15px;\n    transition: border-color 180ms ease, box-shadow 180ms ease, background-color 180ms ease;\n  }\n\n  #ig-davi-pocket-tool .ig-field input:focus,\n  #ig-davi-pocket-tool .ig-field select:focus {\n    border-color: var(--ig-accent);\n    box-shadow: 0 0 0 4px rgba(15, 159, 122, 0.14);\n  }\n\n  #ig-davi-pocket-tool .ig-help { color: var(--ig-muted); font-size: 12px; line-height: 1.45; }\n\n  #ig-davi-pocket-tool .ig-actions {\n    display: flex;\n    flex-wrap: wrap;\n    gap: 10px;\n    align-items: center;\n    margin-top: 22px;\n  }\n\n  #ig-davi-pocket-tool .ig-btn {\n    display: inline-flex;\n    align-items: center;\n    justify-content: center;\n    gap: 9px;\n    min-height: 50px;\n    padding: 12px 16px;\n    border: 1px solid transparent;\n    border-radius: var(--ig-radius);\n    background: var(--ig-ink);\n    color: #ffffff;\n    font-size: 14px;\n    font-weight: 850;\n    transition: transform 180ms ease, background-color 180ms ease, border-color 180ms ease, box-shadow 180ms ease, opacity 180ms ease;\n  }\n\n  #ig-davi-pocket-tool .ig-btn:hover { transform: translateY(-2px); background: var(--ig-accent-dark); box-shadow: 0 12px 22px rgba(23,51,47,0.16); }\n  #ig-davi-pocket-tool .ig-btn.secondary { background: #ffffff; color: var(--ig-ink); border-color: var(--ig-line); }\n  #ig-davi-pocket-tool .ig-btn.secondary:hover { background: var(--ig-bg-a); border-color: var(--ig-line-strong); }\n  #ig-davi-pocket-tool .ig-btn.coral { background: var(--ig-coral); }\n  #ig-davi-pocket-tool .ig-btn.coral:hover { background: var(--ig-coral-dark); }\n  #ig-davi-pocket-tool .ig-btn:disabled { cursor: not-allowed; opacity: 0.54; transform: none; box-shadow: none; }\n\n  #ig-davi-pocket-tool .ig-error {\n    display: none;\n    margin-top: 14px;\n    padding: 12px 14px;\n    border: 1px solid #fecaca;\n    border-radius: var(--ig-radius);\n    background: #fff1f2;\n    color: #b42318;\n    font-size: 13px;\n    font-weight: 750;\n  }\n\n  #ig-davi-pocket-tool .ig-error.is-visible { display: block; }\n\n  #ig-davi-pocket-tool .ig-results {\n    display: none;\n    margin-top: 20px;\n    animation: ig-davi-rise 360ms ease both;\n  }\n\n  #ig-davi-pocket-tool .ig-results.is-visible { display: block; }\n\n  #ig-davi-pocket-tool .ig-section-head {\n    display: grid;\n    grid-template-columns: minmax(0, 1fr) auto;\n    gap: 16px;\n    align-items: end;\n    margin: 22px 0 14px;\n  }\n\n  #ig-davi-pocket-tool .ig-section-head h2 {\n    color: var(--ig-ink);\n    font-size: 28px;\n    line-height: 1.15;\n    font-weight: 930;\n  }\n\n  #ig-davi-pocket-tool .ig-section-head p { margin-top: 7px; color: var(--ig-muted); font-size: 14px; line-height: 1.62; }\n\n  #ig-davi-pocket-tool .ig-kpi-grid {\n    display: grid;\n    grid-template-columns: repeat(4, minmax(0, 1fr));\n    gap: 12px;\n  }\n\n  #ig-davi-pocket-tool .ig-kpi {\n    position: relative;\n    padding: 16px;\n    overflow: hidden;\n  }\n\n  #ig-davi-pocket-tool .ig-kpi::before {\n    content: \"\";\n    position: absolute;\n    inset: 0 auto 0 0;\n    width: 4px;\n    background: var(--ig-accent);\n  }\n\n  #ig-davi-pocket-tool .ig-kpi.is-coral::before { background: var(--ig-coral); }\n  #ig-davi-pocket-tool .ig-kpi.is-final { background: var(--ig-ink); color: #ffffff; }\n  #ig-davi-pocket-tool .ig-kpi.is-final * { color: #ffffff; }\n\n  #ig-davi-pocket-tool .ig-kpi span {\n    display: block;\n    color: var(--ig-muted);\n    font-size: 11px;\n    line-height: 1.35;\n    font-weight: 850;\n    text-transform: uppercase;\n  }\n\n  #ig-davi-pocket-tool .ig-kpi strong {\n    display: block;\n    margin-top: 8px;\n    color: var(--ig-ink);\n    font-size: clamp(19px, 2.1vw, 28px);\n    line-height: 1.05;\n    font-weight: 930;\n    font-variant-numeric: tabular-nums;\n  }\n\n  #ig-davi-pocket-tool .ig-kpi small { display: block; margin-top: 6px; color: var(--ig-muted); font-size: 11px; }\n\n  #ig-davi-pocket-tool .ig-table-shell {\n    width: 100%;\n    overflow: auto;\n    margin-top: 12px;\n  }\n\n  #ig-davi-pocket-tool table {\n    width: 100%;\n    min-width: 920px;\n    border-collapse: collapse;\n    font-variant-numeric: tabular-nums;\n  }\n\n  #ig-davi-pocket-tool th {\n    padding: 12px 11px;\n    background: var(--ig-ink);\n    color: #ffffff;\n    font-size: 11px;\n    line-height: 1.3;\n    font-weight: 850;\n    text-align: left;\n    white-space: nowrap;\n  }\n\n  #ig-davi-pocket-tool td {\n    padding: 11px;\n    border-bottom: 1px solid var(--ig-line);\n    color: var(--ig-ink-2);\n    font-size: 13px;\n    white-space: nowrap;\n  }\n\n  #ig-davi-pocket-tool tbody tr:nth-child(even) { background: rgba(239, 251, 246, 0.74); }\n  #ig-davi-pocket-tool tbody tr:hover { background: var(--ig-bg-b); }\n  #ig-davi-pocket-tool .ig-num { text-align: right; }\n  #ig-davi-pocket-tool .ig-badge { display: inline-flex; align-items: center; justify-content: center; min-height: 25px; padding: 4px 8px; border-radius: var(--ig-radius); background: var(--ig-green-soft); color: var(--ig-accent-dark); font-size: 12px; font-weight: 850; }\n  #ig-davi-pocket-tool .ig-badge.is-coral { background: var(--ig-coral-soft); color: var(--ig-coral-dark); }\n\n  #ig-davi-pocket-tool .ig-info-grid {\n    display: grid;\n    grid-template-columns: repeat(2, minmax(0, 1fr));\n    gap: 14px;\n    margin-top: 14px;\n  }\n\n  #ig-davi-pocket-tool .ig-info-box { padding: 16px; }\n  #ig-davi-pocket-tool .ig-info-box h3 { color: var(--ig-ink); font-size: 17px; line-height: 1.25; font-weight: 900; margin-bottom: 10px; }\n  #ig-davi-pocket-tool .ig-info-box ul { list-style: none; display: grid; gap: 8px; }\n  #ig-davi-pocket-tool .ig-info-box li { position: relative; padding-left: 17px; color: var(--ig-muted); font-size: 13px; line-height: 1.48; }\n  #ig-davi-pocket-tool .ig-info-box li::before { content: \"\"; position: absolute; left: 0; top: 0.58em; width: 7px; height: 7px; border-radius: 999px; background: var(--ig-accent); }\n\n  #ig-davi-pocket-tool .ig-pdf-box {\n    display: none;\n    margin-top: 14px;\n    padding: 15px;\n    border-color: rgba(239, 106, 74, 0.26);\n    background: var(--ig-bg-b);\n  }\n\n  #ig-davi-pocket-tool .ig-pdf-box.is-visible { display: block; animation: ig-davi-rise 360ms ease both; }\n  #ig-davi-pocket-tool .ig-pdf-actions { display: flex; flex-wrap: wrap; gap: 10px; align-items: center; justify-content: space-between; }\n  #ig-davi-pocket-tool .ig-pdf-status { color: var(--ig-muted); font-size: 12px; font-weight: 750; }\n\n  #ig-davi-pocket-tool .ig-toast {\n    display: none;\n    min-height: 34px;\n    padding: 7px 10px;\n    border-radius: var(--ig-radius);\n    background: var(--ig-green-soft);\n    color: var(--ig-accent-dark);\n    font-size: 12px;\n    font-weight: 850;\n  }\n\n  #ig-davi-pocket-tool .ig-toast.is-visible { display: inline-flex; align-items: center; }\n\n  #ig-davi-pocket-tool footer {\n    margin-top: 24px;\n    padding: 18px 0 4px;\n    border-top: 1px solid var(--ig-line);\n    color: var(--ig-muted);\n    font-size: 12px;\n    text-align: center;\n  }\n\n  #ig-davi-pocket-tool .ig-reveal { opacity: 0; transform: translateY(12px); transition: opacity 520ms ease, transform 520ms ease; }\n  #ig-davi-pocket-tool .ig-reveal.is-visible { opacity: 1; transform: translateY(0); }\n\n  @keyframes ig-davi-rise { from { opacity: 0; transform: translateY(10px); } to { opacity: 1; transform: translateY(0); } }\n\n  @media (prefers-reduced-motion: reduce) {\n    #ig-davi-pocket-tool *, #ig-davi-pocket-tool *::before, #ig-davi-pocket-tool *::after { animation-duration: 1ms !important; transition-duration: 1ms !important; scroll-behavior: auto !important; }\n    #ig-davi-pocket-tool .ig-reveal { opacity: 1; transform: none; }\n  }\n\n  @media (max-width: 980px) {\n    #ig-davi-pocket-tool .ig-hero { grid-template-columns: 1fr; }\n    #ig-davi-pocket-tool .ig-kpi-grid { grid-template-columns: repeat(2, minmax(0, 1fr)); }\n  }\n\n  @media (max-width: 760px) {\n    #ig-davi-pocket-tool .ig-section { padding: 24px 0; }\n    #ig-davi-pocket-tool .ig-wrap { width: min(100% - 20px, 1120px); }\n    #ig-davi-pocket-tool .ig-main-card { padding: 18px; }\n    #ig-davi-pocket-tool .ig-proof-grid, #ig-davi-pocket-tool .ig-rate-grid, #ig-davi-pocket-tool .ig-form-grid, #ig-davi-pocket-tool .ig-info-grid, #ig-davi-pocket-tool .ig-kpi-grid { grid-template-columns: 1fr; }\n    #ig-davi-pocket-tool .ig-section-head { grid-template-columns: 1fr; align-items: start; }\n    #ig-davi-pocket-tool .ig-actions, #ig-davi-pocket-tool .ig-pdf-actions { display: grid; grid-template-columns: 1fr; }\n    #ig-davi-pocket-tool .ig-btn { width: 100%; }\n    #ig-davi-pocket-tool .ig-pdf-status { text-align: center; }\n  }\n<\/style>\n\n<div id=\"ig-davi-pocket-tool\">\n  <section class=\"ig-section\">\n    <div class=\"ig-wrap\">\n      <div class=\"ig-hero\">\n        <article class=\"ig-card ig-main-card ig-reveal\">\n          <div class=\"ig-hero-top\">\n            <span class=\"ig-eyebrow\">\u25a3 Herramienta financiera IG<\/span>\n            <span class=\"ig-bank-badge\">\u25cf Bolsillos Davivienda<\/span>\n          <\/div>\n          <h1>Calculadora de <span>Bolsillos Davivienda<\/span><\/h1>\n          <p class=\"ig-lead\">Simula cu\u00e1nto podr\u00edas recibir por guardar tus ahorros en Bolsillos, usando tramos de tasa por saldo promedio, tipo de cuenta y retenci\u00f3n estimada sobre intereses.<\/p>\n\n          <div class=\"ig-proof-grid\" aria-label=\"Beneficios principales de Bolsillos Davivienda\">\n            <span class=\"ig-proof\"><span class=\"ig-icon-dot\">15<\/span> Hasta 15 bolsillos por cuenta<\/span>\n            <span class=\"ig-proof\"><span class=\"ig-icon-dot is-red\">$0<\/span> Sin cuota de manejo adicional<\/span>\n            <span class=\"ig-proof\"><span class=\"ig-icon-dot is-coral\">\u21bb<\/span> Abonos autom\u00e1ticos programables<\/span>\n          <\/div>\n\n          <form id=\"igDaviForm\" autocomplete=\"off\" novalidate>\n            <div class=\"ig-form-grid\">\n              <div class=\"ig-field\">\n                <label for=\"igDaviAmount\">Saldo inicial en Bolsillos<\/label>\n                <input id=\"igDaviAmount\" name=\"monto\" type=\"text\" inputmode=\"decimal\" placeholder=\"Ej: $ 10.000.000\" value=\"10.000.000\">\n                <span class=\"ig-help\">Acepta 10000000, 10.000.000, $ 10.000.000, 10,000,000 y decimales.<\/span>\n              <\/div>\n\n              <div class=\"ig-field\">\n                <label for=\"igDaviMonthly\">Aporte mensual programado<\/label>\n                <input id=\"igDaviMonthly\" name=\"aporte\" type=\"text\" inputmode=\"decimal\" placeholder=\"Ej: $ 500.000\" value=\"500.000\">\n                <span class=\"ig-help\">El aporte recurrente se aplica desde el mes 2 para no duplicar el saldo inicial.<\/span>\n              <\/div>\n\n              <div class=\"ig-field\">\n                <label for=\"igDaviMonths\">Plazo de simulaci\u00f3n<\/label>\n                <input id=\"igDaviMonths\" name=\"meses\" type=\"number\" min=\"1\" max=\"120\" step=\"1\" value=\"12\">\n                <span class=\"ig-help\">Entre 1 y 120 meses.<\/span>\n              <\/div>\n\n              <div class=\"ig-field\">\n                <label for=\"igDaviAccount\">Tipo de cuenta asociada<\/label>\n                <select id=\"igDaviAccount\" name=\"tipoCuenta\">\n                  <option value=\"tradicional\">Cuenta Tradicional, Rural y Ni\u00f1os<\/option>\n                  <option value=\"nomina\" selected>Cuenta de N\u00f3mina y Pensi\u00f3n<\/option>\n                <\/select>\n                <span class=\"ig-help\">La tasa de 8,25% E.A. aplica solo en el tramo igual o superior a $10 millones para N\u00f3mina\/Pensi\u00f3n.<\/span>\n              <\/div>\n\n              <div class=\"ig-field\">\n                <label for=\"igDaviTiming\">Momento estimado del aporte<\/label>\n                <select id=\"igDaviTiming\" name=\"momentoAporte\">\n                  <option value=\"start\" selected>Inicio de cada mes<\/option>\n                  <option value=\"middle\">Mitad de cada mes<\/option>\n                  <option value=\"end\">Final de cada mes<\/option>\n                <\/select>\n                <span class=\"ig-help\">Se usa para aproximar el saldo promedio mensual.<\/span>\n              <\/div>\n\n              <div class=\"ig-field\">\n                <label for=\"igDaviRetention\">Retenci\u00f3n sobre intereses<\/label>\n                <select id=\"igDaviRetention\" name=\"retencion\">\n                  <option value=\"0.07\" selected>7% estimado<\/option>\n                  <option value=\"0\">0% sin retenci\u00f3n en la simulaci\u00f3n<\/option>\n                <\/select>\n                <span class=\"ig-help\">Campo educativo; la aplicaci\u00f3n real depende de condiciones tributarias y del banco.<\/span>\n              <\/div>\n            <\/div>\n\n            <div class=\"ig-actions\">\n              <button class=\"ig-btn\" id=\"igDaviCalculate\" type=\"submit\">Calcular rendimientos<\/button>\n              <button class=\"ig-btn secondary\" id=\"igDaviClear\" type=\"button\">Limpiar<\/button>\n              <button class=\"ig-btn secondary\" id=\"igDaviShare\" type=\"button\">Compartir escenario<\/button>\n              <span class=\"ig-toast\" id=\"igDaviToast\" role=\"status\" aria-live=\"polite\">Enlace copiado<\/span>\n            <\/div>\n            <div class=\"ig-error\" id=\"igDaviError\" role=\"alert\" aria-live=\"assertive\"><\/div>\n          <\/form>\n        <\/article>\n\n        <aside class=\"ig-rate-panel ig-reveal\" aria-label=\"Tasas usadas por la calculadora\">\n          <span class=\"ig-eyebrow\">Tasas parametrizadas<\/span>\n          <h2>La tasa cambia seg\u00fan el saldo promedio y el tipo de cuenta.<\/h2>\n          <p>Los rendimientos se liquidan mensualmente sobre el saldo promedio de los Bolsillos activos por cuenta. Por eso esta versi\u00f3n calcula con saldo promedio estimado, no \u00fanicamente con el saldo final del mes.<\/p>\n          <div class=\"ig-rate-grid\">\n            <div class=\"ig-rate-card\"><span>Menos de $5 millones<\/span><strong>0,10%<\/strong><small>E.A. para ambas categor\u00edas.<\/small><\/div>\n            <div class=\"ig-rate-card\"><span>Desde $5M hasta $9.999.999<\/span><strong>8,00%<\/strong><small>E.A. para ambas categor\u00edas.<\/small><\/div>\n            <div class=\"ig-rate-card\"><span>$10M o m\u00e1s<\/span><strong>8,25%<\/strong><small>E.A. solo N\u00f3mina\/Pensi\u00f3n. Otras cuentas: 8,00% E.A.<\/small><\/div>\n          <\/div>\n          <p><strong>Nota:<\/strong> simulaci\u00f3n educativa. Antes de decidir, valida tasas y tarifas vigentes directamente en Davivienda.<\/p>\n        <\/aside>\n      <\/div>\n\n      <section class=\"ig-results\" id=\"igDaviResults\" aria-live=\"polite\">\n        <div class=\"ig-section-head\">\n          <div>\n            <span class=\"ig-eyebrow\">Resultado de simulaci\u00f3n<\/span>\n            <h2>Resumen claro antes de mover tu dinero<\/h2>\n            <p>Los valores se calculan de forma compuesta mensual, con tasa efectiva mensual derivada de la tasa E.A. usada en cada tramo.<\/p>\n          <\/div>\n        <\/div>\n\n        <div class=\"ig-kpi-grid\">\n          <div class=\"ig-kpi\"><span>Total aportado<\/span><strong id=\"igDaviKpiPrincipal\">$0<\/strong><small>Saldo inicial + aportes recurrentes.<\/small><\/div>\n          <div class=\"ig-kpi\"><span>Intereses brutos<\/span><strong id=\"igDaviKpiGross\">$0<\/strong><small>Antes de retenci\u00f3n estimada.<\/small><\/div>\n          <div class=\"ig-kpi is-coral\"><span>Retenci\u00f3n estimada<\/span><strong id=\"igDaviKpiTax\">$0<\/strong><small>Seg\u00fan selecci\u00f3n del usuario.<\/small><\/div>\n          <div class=\"ig-kpi is-final\"><span>Saldo final estimado<\/span><strong id=\"igDaviKpiFinal\">$0<\/strong><small id=\"igDaviKpiRateNote\">Tasa m\u00e1xima usada: 0,00% E.A.<\/small><\/div>\n        <\/div>\n\n        <div class=\"ig-info-grid\">\n          <div class=\"ig-info-box\">\n            <h3>Lectura r\u00e1pida<\/h3>\n            <ul id=\"igDaviInsights\"><\/ul>\n          <\/div>\n          <div class=\"ig-info-box\">\n            <h3>Condiciones a tener presentes<\/h3>\n            <ul>\n              <li>Hasta 15 Bolsillos por cuenta, administrables desde la App Davivienda.<\/li>\n              <li>Sin cuota de manejo adicional para usar Bolsillos.<\/li>\n              <li>Los rendimientos pueden cambiar si retiras dinero o si el saldo promedio cae de tramo.<\/li>\n              <li>El c\u00e1lculo es referencial y no reemplaza la informaci\u00f3n oficial de Davivienda.<\/li>\n            <\/ul>\n          <\/div>\n        <\/div>\n\n        <div class=\"ig-pdf-box\" id=\"igDaviPdfBox\">\n          <div class=\"ig-pdf-actions\">\n            <div>\n              <strong>Reporte descargable<\/strong>\n              <div class=\"ig-pdf-status\" id=\"igDaviPdfStatus\">Listo para generar PDF con sello IG, URL visible y marca de agua.<\/div>\n            <\/div>\n            <div class=\"ig-actions\" style=\"margin-top:0\">\n              <button class=\"ig-btn coral\" id=\"igDaviPdf\" type=\"button\">Descargar PDF<\/button>\n              <button class=\"ig-btn secondary\" id=\"igDaviPrint\" type=\"button\">Imprimir \/ guardar como PDF<\/button>\n            <\/div>\n          <\/div>\n        <\/div>\n\n        <div class=\"ig-section-head\">\n          <div>\n            <span class=\"ig-eyebrow\">Detalle mensual<\/span>\n            <h2>Proyecci\u00f3n mes a mes<\/h2>\n            <p>Incluye saldo inicial, aporte, saldo promedio estimado, tasa aplicada, inter\u00e9s bruto, retenci\u00f3n, inter\u00e9s neto y saldo final.<\/p>\n          <\/div>\n        <\/div>\n\n        <div class=\"ig-table-shell\">\n          <table aria-label=\"Tabla de proyecci\u00f3n mensual de Bolsillos Davivienda\">\n            <thead>\n              <tr>\n                <th>Mes<\/th>\n                <th class=\"ig-num\">Saldo inicial<\/th>\n                <th class=\"ig-num\">Aporte<\/th>\n                <th class=\"ig-num\">Saldo promedio<\/th>\n                <th>Tasa E.A.<\/th>\n                <th class=\"ig-num\">Inter\u00e9s bruto<\/th>\n                <th class=\"ig-num\">Retenci\u00f3n<\/th>\n                <th class=\"ig-num\">Inter\u00e9s neto<\/th>\n                <th class=\"ig-num\">Saldo final<\/th>\n              <\/tr>\n            <\/thead>\n            <tbody id=\"igDaviTableBody\"><\/tbody>\n          <\/table>\n        <\/div>\n      <\/section>\n\n      <footer>\n        Herramienta educativa de InversionesGuru Colombia. URL de referencia para reportes: https:\/\/inversionesguru.com\/co\/. Verifica condiciones oficiales en Davivienda antes de tomar decisiones financieras.\n      <\/footer>\n    <\/div>\n  <\/section>\n<\/div>\n\n<script>\n(function(){\n  'use strict';\n\n  const root = document.getElementById('ig-davi-pocket-tool');\n  if (!root || root.dataset.ready === 'true') return;\n  root.dataset.ready = 'true';\n\n  const CONFIG = {\n    thresholdLow: 5000000,\n    thresholdHigh: 10000000,\n    rates: {\n      low: 0.001,\n      mid: 0.08,\n      highTraditional: 0.08,\n      highPayroll: 0.0825\n    },\n    minMonths: 1,\n    maxMonths: 120,\n    reportUrl: 'https:\/\/inversionesguru.com\/co\/',\n    pdfName: 'reporte-bolsillos-davivienda-ig.pdf'\n  };\n\n  const $ = selector => root.querySelector(selector);\n  const fmtMoney0 = value => new Intl.NumberFormat('es-CO', { style: 'currency', currency: 'COP', maximumFractionDigits: 0 }).format(Number(value) || 0);\n  const fmtMoney2 = value => new Intl.NumberFormat('es-CO', { style: 'currency', currency: 'COP', minimumFractionDigits: 2, maximumFractionDigits: 2 }).format(Number(value) || 0);\n  const fmtPct = value => new Intl.NumberFormat('es-CO', { style: 'percent', minimumFractionDigits: 2, maximumFractionDigits: 2 }).format(Number(value) || 0);\n  const monthlyRate = annualRate => Math.pow(1 + annualRate, 1 \/ 12) - 1;\n  const clamp = (value, min, max) => Math.max(min, Math.min(max, value));\n\n  const els = {\n    form: $('#igDaviForm'),\n    amount: $('#igDaviAmount'),\n    monthly: $('#igDaviMonthly'),\n    months: $('#igDaviMonths'),\n    account: $('#igDaviAccount'),\n    timing: $('#igDaviTiming'),\n    retention: $('#igDaviRetention'),\n    error: $('#igDaviError'),\n    results: $('#igDaviResults'),\n    pdfBox: $('#igDaviPdfBox'),\n    pdfButton: $('#igDaviPdf'),\n    printButton: $('#igDaviPrint'),\n    pdfStatus: $('#igDaviPdfStatus'),\n    share: $('#igDaviShare'),\n    clear: $('#igDaviClear'),\n    toast: $('#igDaviToast'),\n    principal: $('#igDaviKpiPrincipal'),\n    gross: $('#igDaviKpiGross'),\n    tax: $('#igDaviKpiTax'),\n    final: $('#igDaviKpiFinal'),\n    rateNote: $('#igDaviKpiRateNote'),\n    insights: $('#igDaviInsights'),\n    tbody: $('#igDaviTableBody')\n  };\n\n  let lastReport = null;\n\n  function onlyDigits(value) { return String(value || '').replace(\/\\D\/g, ''); }\n\n  function decimalSeparator(value) {\n    const clean = String(value || '').replace(\/[^\\d.,]\/g, '');\n    const lastComma = clean.lastIndexOf(',');\n    const lastDot = clean.lastIndexOf('.');\n    if (lastComma === -1 && lastDot === -1) return null;\n    if (lastComma !== -1 && lastDot !== -1) return lastComma > lastDot ? ',' : '.';\n    const sep = lastComma !== -1 ? ',' : '.';\n    const last = clean.lastIndexOf(sep);\n    const occurrences = clean.split(sep).length - 1;\n    const after = clean.slice(last + 1).replace(\/\\D\/g, '');\n    if (clean.endsWith(sep)) return sep;\n    if (after.length === 0) return null;\n    if (occurrences > 1) return after.length <= 2 ? sep : null;\n    return after.length <= 2 ? sep : null;\n  }\n\n  function numberParts(value) {\n    const raw = String(value || '').trim().replace(\/\\s\/g, '').replace(\/-\/g, '');\n    const sep = decimalSeparator(raw);\n    if (!sep) return { int: onlyDigits(raw), dec: '', hasDecimal: false };\n    const idx = raw.lastIndexOf(sep);\n    const left = raw.slice(0, idx);\n    const right = raw.slice(idx + 1);\n    return { int: onlyDigits(left), dec: onlyDigits(right).slice(0, 2), hasDecimal: true };\n  }\n\n  function parseMoney(value) {\n    const parts = numberParts(value);\n    if (!parts.int && !parts.dec) return NaN;\n    const normalized = (parts.int || '0') + (parts.hasDecimal && parts.dec ? '.' + parts.dec : '');\n    const num = Number(normalized);\n    return Number.isFinite(num) ? num : NaN;\n  }\n\n  function formatInputValue(value) {\n    const parts = numberParts(value);\n    if (!parts.int && !parts.hasDecimal) return '';\n    const intFormatted = (parts.int || '0').replace(\/^0+(?=\\d)\/, '').replace(\/\\B(?=(\\d{3})+(?!\\d))\/g, '.');\n    if (!parts.hasDecimal) return intFormatted;\n    return intFormatted + ',' + parts.dec;\n  }\n\n  function attachMoneyFormatter(input) {\n    if (!input) return;\n    input.addEventListener('input', () => { input.value = formatInputValue(input.value); });\n    input.addEventListener('blur', () => {\n      const parsed = parseMoney(input.value);\n      if (Number.isFinite(parsed)) input.value = formatInputValue(String(parsed.toLocaleString('en-US', { maximumFractionDigits: 2, useGrouping: false })));\n    });\n  }\n\n  function getRate(accountType, averageBalance) {\n    if (averageBalance < CONFIG.thresholdLow) return CONFIG.rates.low;\n    if (averageBalance < CONFIG.thresholdHigh) return CONFIG.rates.mid;\n    return accountType === 'nomina' ? CONFIG.rates.highPayroll : CONFIG.rates.highTraditional;\n  }\n\n  function timingFactor(value) {\n    if (value === 'middle') return 0.5;\n    if (value === 'end') return 0;\n    return 1;\n  }\n\n  function accountLabel(value) {\n    return value === 'nomina' ? 'Cuenta de N\u00f3mina y Pensi\u00f3n' : 'Cuenta Tradicional, Rural y Ni\u00f1os';\n  }\n\n  function timingLabel(value) {\n    if (value === 'middle') return 'Mitad de cada mes';\n    if (value === 'end') return 'Final de cada mes';\n    return 'Inicio de cada mes';\n  }\n\n  function showError(message) {\n    els.error.textContent = message;\n    els.error.classList.add('is-visible');\n  }\n\n  function hideError() {\n    els.error.textContent = '';\n    els.error.classList.remove('is-visible');\n  }\n\n  function validateInputs() {\n    const amount = parseMoney(els.amount.value);\n    const monthly = parseMoney(els.monthly.value || '0') || 0;\n    const months = Number(els.months.value);\n    const retention = Number(els.retention.value);\n\n    if (!Number.isFinite(amount) || amount <= 0) throw new Error('Ingresa un saldo inicial v\u00e1lido mayor a $0. Ejemplo: 10.000.000');\n    if (!Number.isFinite(monthly) || monthly < 0) throw new Error('El aporte mensual no puede ser negativo.');\n    if (!Number.isInteger(months) || months < CONFIG.minMonths || months > CONFIG.maxMonths) throw new Error('El plazo debe estar entre 1 y 120 meses.');\n    if (!Number.isFinite(retention) || retention < 0 || retention > 1) throw new Error('La retenci\u00f3n seleccionada no es v\u00e1lida.');\n\n    return {\n      amount,\n      monthly,\n      months,\n      account: els.account.value,\n      timing: els.timing.value,\n      retention\n    };\n  }\n\n  function calculateScenario(input) {\n    let balance = input.amount;\n    let totalGross = 0;\n    let totalTax = 0;\n    let maxRate = 0;\n    const factor = timingFactor(input.timing);\n    const rows = [];\n\n    for (let month = 1; month <= input.months; month++) {\n      const opening = balance;\n      const contribution = month === 1 ? 0 : input.monthly;\n      const average = opening + (contribution * factor);\n      const rateEA = getRate(input.account, average);\n      const rateEM = monthlyRate(rateEA);\n      const gross = average * rateEM;\n      const tax = gross * input.retention;\n      const net = gross - tax;\n      const closing = opening + contribution + net;\n\n      totalGross += gross;\n      totalTax += tax;\n      maxRate = Math.max(maxRate, rateEA);\n      balance = closing;\n\n      rows.push({ month, opening, contribution, average, rateEA, rateEM, gross, tax, net, closing });\n    }\n\n    const totalPrincipal = input.amount + (input.monthly * Math.max(0, input.months - 1));\n    return { input, totalPrincipal, totalGross, totalTax, totalNetInterest: totalGross - totalTax, finalBalance: balance, maxRate, rows };\n  }\n\n  function renderInsights(report) {\n    const finalGain = report.finalBalance - report.totalPrincipal;\n    const firstHighMonth = report.rows.find(row => row.rateEA >= CONFIG.rates.mid);\n    const highPayrollUsed = report.rows.some(row => row.rateEA === CONFIG.rates.highPayroll);\n    const items = [\n      'Ganancia neta estimada: ' + fmtMoney2(finalGain) + ' despu\u00e9s de retenci\u00f3n seleccionada.',\n      firstHighMonth ? 'La simulaci\u00f3n entra en tramo de tasa alta desde el mes ' + firstHighMonth.month + '.' : 'El escenario no alcanza saldo promedio de $5 millones; se mantiene en 0,10% E.A.',\n      highPayrollUsed ? 'Se aplic\u00f3 8,25% E.A. en al menos un mes por saldo promedio igual o superior a $10 millones en N\u00f3mina\/Pensi\u00f3n.' : 'No se aplic\u00f3 8,25% E.A.; revisa tipo de cuenta o saldo promedio si esperabas ese tramo.',\n      'Aporte recurrente considerado desde el mes 2: ' + fmtMoney0(report.input.monthly) + '.'\n    ];\n    els.insights.innerHTML = items.map(item => '<li>' + item + '<\/li>').join('');\n  }\n\n  function renderReport(report) {\n    els.principal.textContent = fmtMoney0(report.totalPrincipal);\n    els.gross.textContent = fmtMoney2(report.totalGross);\n    els.tax.textContent = fmtMoney2(report.totalTax);\n    els.final.textContent = fmtMoney2(report.finalBalance);\n    els.rateNote.textContent = 'Tasa m\u00e1xima usada: ' + fmtPct(report.maxRate) + ' E.A.';\n\n    els.tbody.innerHTML = report.rows.map(row => {\n      const badgeClass = row.rateEA >= CONFIG.rates.highPayroll ? 'ig-badge is-coral' : 'ig-badge';\n      return '<tr>' +\n        '<td><strong>Mes ' + row.month + '<\/strong><\/td>' +\n        '<td class=\"ig-num\">' + fmtMoney0(row.opening) + '<\/td>' +\n        '<td class=\"ig-num\">' + (row.contribution > 0 ? fmtMoney0(row.contribution) : '\u2014') + '<\/td>' +\n        '<td class=\"ig-num\">' + fmtMoney0(row.average) + '<\/td>' +\n        '<td><span class=\"' + badgeClass + '\">' + fmtPct(row.rateEA) + '<\/span><\/td>' +\n        '<td class=\"ig-num\">' + fmtMoney2(row.gross) + '<\/td>' +\n        '<td class=\"ig-num\">' + fmtMoney2(row.tax) + '<\/td>' +\n        '<td class=\"ig-num\"><strong>' + fmtMoney2(row.net) + '<\/strong><\/td>' +\n        '<td class=\"ig-num\"><strong>' + fmtMoney0(row.closing) + '<\/strong><\/td>' +\n      '<\/tr>';\n    }).join('');\n\n    renderInsights(report);\n    els.results.classList.add('is-visible');\n    els.pdfBox.classList.add('is-visible');\n    els.results.scrollIntoView({ behavior: 'smooth', block: 'start' });\n  }\n\n  function buildUrl(report) {\n    const params = new URLSearchParams();\n    params.set('monto', String(Math.round(report.input.amount * 100) \/ 100));\n    params.set('aporte', String(Math.round(report.input.monthly * 100) \/ 100));\n    params.set('meses', String(report.input.months));\n    params.set('cuenta', report.input.account);\n    params.set('momento', report.input.timing);\n    params.set('retencion', String(report.input.retention));\n    return location.origin + location.pathname + '?' + params.toString();\n  }\n\n  function setFromUrl() {\n    const params = new URLSearchParams(location.search);\n    if (!params.has('monto')) return;\n    if (params.has('monto')) els.amount.value = formatInputValue(params.get('monto'));\n    if (params.has('aporte')) els.monthly.value = formatInputValue(params.get('aporte'));\n    if (params.has('meses')) els.months.value = String(clamp(parseInt(params.get('meses'), 10) || 12, CONFIG.minMonths, CONFIG.maxMonths));\n    if (params.has('cuenta') && ['tradicional','nomina'].includes(params.get('cuenta'))) els.account.value = params.get('cuenta');\n    if (params.has('momento') && ['start','middle','end'].includes(params.get('momento'))) els.timing.value = params.get('momento');\n    if (params.has('retencion') && ['0','0.07'].includes(params.get('retencion'))) els.retention.value = params.get('retencion');\n    setTimeout(() => els.form.requestSubmit(), 60);\n  }\n\n  function ensureJsPdf() {\n    if (window.jspdf && window.jspdf.jsPDF) return Promise.resolve(window.jspdf.jsPDF);\n    return new Promise((resolve, reject) => {\n      const existing = document.querySelector('script[data-ig-jspdf=\"true\"]');\n      if (existing) {\n        existing.addEventListener('load', () => window.jspdf && window.jspdf.jsPDF ? resolve(window.jspdf.jsPDF) : reject(new Error('jsPDF no disponible')), { once: true });\n        existing.addEventListener('error', reject, { once: true });\n        return;\n      }\n      const script = document.createElement('script');\n      script.src = 'https:\/\/cdn.jsdelivr.net\/npm\/jspdf@2.5.1\/dist\/jspdf.umd.min.js';\n      script.async = true;\n      script.dataset.igJspdf = 'true';\n      script.onload = () => window.jspdf && window.jspdf.jsPDF ? resolve(window.jspdf.jsPDF) : reject(new Error('jsPDF no disponible'));\n      script.onerror = reject;\n      document.head.appendChild(script);\n    });\n  }\n\n  function safeText(value) { return String(value == null ? '' : value).replace(\/\\s+\/g, ' ').trim(); }\n\n  function exportPdf(jsPDF, report) {\n    const doc = new jsPDF({ unit: 'mm', format: 'a4' });\n    const margin = 16;\n    const pageWidth = 210;\n    const pageHeight = 297;\n    const contentWidth = pageWidth - margin * 2;\n    let y = 0;\n\n    function decorate() {\n      doc.setFillColor(15, 159, 122);\n      doc.roundedRect(margin, 11, 12, 12, 2, 2, 'F');\n      doc.setTextColor(255, 255, 255);\n      doc.setFont('helvetica', 'bold');\n      doc.setFontSize(8);\n      doc.text('IG', margin + 3.2, 18.6);\n\n      doc.setTextColor(23, 51, 47);\n      doc.setFont('helvetica', 'bold');\n      doc.setFontSize(11);\n      doc.text('InversionesGuru Colombia', margin + 16, 16);\n      doc.setTextColor(91, 111, 104);\n      doc.setFont('helvetica', 'normal');\n      doc.setFontSize(8);\n      doc.text(CONFIG.reportUrl, margin + 16, 21);\n\n      doc.setTextColor(226, 239, 234);\n      doc.setFont('helvetica', 'bold');\n      doc.setFontSize(20);\n      doc.text('inversionesguru.com\/co\/', 37, 158, { angle: 32 });\n      doc.text('inversionesguru.com\/co\/', 70, 230, { angle: 32 });\n\n      doc.setDrawColor(217, 228, 223);\n      doc.line(margin, 28, pageWidth - margin, 28);\n      y = 36;\n    }\n\n    function nextPage(required) {\n      if (y + required <= pageHeight - 18) return;\n      doc.addPage();\n      decorate();\n    }\n\n    function line(text, x, yy, options) {\n      doc.text(safeText(text), x, yy, options || {});\n    }\n\n    function sectionTitle(title) {\n      nextPage(12);\n      doc.setTextColor(23, 51, 47);\n      doc.setFont('helvetica', 'bold');\n      doc.setFontSize(12);\n      line(title, margin, y);\n      y += 7;\n    }\n\n    function paragraph(text) {\n      const lines = doc.splitTextToSize(safeText(text), contentWidth);\n      nextPage(lines.length * 5 + 2);\n      doc.setTextColor(91, 111, 104);\n      doc.setFont('helvetica', 'normal');\n      doc.setFontSize(9);\n      doc.text(lines, margin, y);\n      y += lines.length * 5 + 2;\n    }\n\n    function twoColRows(rows) {\n      rows.forEach(row => {\n        nextPage(9);\n        doc.setTextColor(91, 111, 104);\n        doc.setFont('helvetica', 'normal');\n        doc.setFontSize(9);\n        line(row[0], margin, y);\n        doc.setTextColor(23, 51, 47);\n        doc.setFont('helvetica', 'bold');\n        line(row[1], pageWidth - margin, y, { align: 'right' });\n        y += 7;\n      });\n      y += 2;\n    }\n\n    function drawTable(rows) {\n      const headers = ['Mes', 'Promedio', 'Tasa', 'Int. neto', 'Saldo final'];\n      const widths = [17, 39, 26, 39, 39];\n      const x0 = margin;\n      nextPage(16);\n      doc.setFillColor(23, 51, 47);\n      doc.rect(x0, y, contentWidth, 8, 'F');\n      doc.setTextColor(255,255,255);\n      doc.setFont('helvetica', 'bold');\n      doc.setFontSize(7);\n      let x = x0;\n      headers.forEach((header, index) => {\n        line(header, x + 2, y + 5.3);\n        x += widths[index];\n      });\n      y += 8;\n\n      doc.setFont('helvetica', 'normal');\n      rows.forEach((row, i) => {\n        nextPage(8);\n        if (i % 2 === 0) {\n          doc.setFillColor(239, 251, 246);\n          doc.rect(x0, y, contentWidth, 7.4, 'F');\n        }\n        doc.setTextColor(36, 68, 62);\n        doc.setFontSize(7);\n        const cells = [String(row.month), fmtMoney0(row.average), fmtPct(row.rateEA), fmtMoney2(row.net), fmtMoney0(row.closing)];\n        x = x0;\n        cells.forEach((cell, index) => {\n          line(cell, x + 2, y + 5);\n          x += widths[index];\n        });\n        y += 7.4;\n      });\n      y += 4;\n    }\n\n    decorate();\n    doc.setTextColor(23, 51, 47);\n    doc.setFont('helvetica', 'bold');\n    doc.setFontSize(18);\n    line('Reporte: Calculadora de Bolsillos Davivienda', margin, y);\n    y += 8;\n    paragraph('Simulaci\u00f3n educativa generada por InversionesGuru. Incluye sello visual IG, URL visible y marca de agua. Verifica siempre las condiciones oficiales vigentes de Davivienda.');\n\n    sectionTitle('Datos de entrada');\n    twoColRows([\n      ['Saldo inicial', fmtMoney2(report.input.amount)],\n      ['Aporte mensual desde mes 2', fmtMoney2(report.input.monthly)],\n      ['Plazo', report.input.months + ' meses'],\n      ['Tipo de cuenta', accountLabel(report.input.account)],\n      ['Momento del aporte', timingLabel(report.input.timing)],\n      ['Retenci\u00f3n seleccionada', fmtPct(report.input.retention)]\n    ]);\n\n    sectionTitle('Resumen');\n    twoColRows([\n      ['Total aportado', fmtMoney0(report.totalPrincipal)],\n      ['Intereses brutos', fmtMoney2(report.totalGross)],\n      ['Retenci\u00f3n estimada', fmtMoney2(report.totalTax)],\n      ['Inter\u00e9s neto estimado', fmtMoney2(report.totalNetInterest)],\n      ['Saldo final estimado', fmtMoney2(report.finalBalance)],\n      ['Tasa m\u00e1xima usada', fmtPct(report.maxRate) + ' E.A.']\n    ]);\n\n    sectionTitle('Detalle mensual');\n    drawTable(report.rows.slice(0, 120));\n\n    paragraph('Metodolog\u00eda: tasa efectiva mensual derivada de la tasa E.A. correspondiente al tramo de saldo promedio estimado. El aporte mensual se considera desde el mes 2 y ponderado seg\u00fan el momento elegido para aproximar saldo promedio.');\n\n    const totalPages = doc.getNumberOfPages();\n    for (let i = 1; i <= totalPages; i++) {\n      doc.setPage(i);\n      doc.setTextColor(91, 111, 104);\n      doc.setFontSize(8);\n      doc.text('P\u00e1gina ' + i + ' de ' + totalPages + ' \u00b7 ' + CONFIG.reportUrl, pageWidth - margin, pageHeight - 9, { align: 'right' });\n    }\n\n    doc.save(CONFIG.pdfName);\n  }\n\n  function printableHtml(report) {\n    const rows = report.rows.map(row => '<tr><td>Mes ' + row.month + '<\/td><td>' + fmtMoney0(row.average) + '<\/td><td>' + fmtPct(row.rateEA) + '<\/td><td>' + fmtMoney2(row.net) + '<\/td><td>' + fmtMoney0(row.closing) + '<\/td><\/tr>').join('');\n    return '<!doctype html><html lang=\"es\"><head><meta charset=\"utf-8\"><title>Reporte Bolsillos Davivienda<\/title><style>' +\n      'body{font-family:Arial,sans-serif;color:#17332f;margin:32px;position:relative}body:before{content:\"inversionesguru.com\/co\/\";position:fixed;left:15%;top:42%;font-size:42px;color:#e2efea;transform:rotate(-30deg);z-index:-1;font-weight:700}.seal{display:inline-flex;align-items:center;justify-content:center;width:42px;height:42px;border-radius:8px;background:#0f9f7a;color:#fff;font-weight:800;margin-right:10px}.top{display:flex;align-items:center;border-bottom:1px solid #d9e4df;padding-bottom:14px;margin-bottom:20px}h1{font-size:24px;margin:0}.url{color:#5b6f68;font-size:12px}table{width:100%;border-collapse:collapse;margin-top:16px;font-size:12px}th{background:#17332f;color:white;text-align:left;padding:8px}td{border-bottom:1px solid #d9e4df;padding:8px}.grid{display:grid;grid-template-columns:1fr 1fr;gap:10px;margin:14px 0}.box{border:1px solid #d9e4df;border-radius:8px;padding:10px}.box span{display:block;color:#5b6f68;font-size:11px}.box strong{font-size:18px}@media print{button{display:none}}' +\n      '<\/style><\/head><body><div class=\"top\"><div class=\"seal\">IG<\/div><div><h1>Reporte: Calculadora de Bolsillos Davivienda<\/h1><div class=\"url\">' + CONFIG.reportUrl + '<\/div><\/div><\/div>' +\n      '<p>Simulaci\u00f3n educativa. Verifica condiciones oficiales en Davivienda antes de tomar decisiones financieras.<\/p>' +\n      '<div class=\"grid\"><div class=\"box\"><span>Saldo inicial<\/span><strong>' + fmtMoney2(report.input.amount) + '<\/strong><\/div><div class=\"box\"><span>Aporte mensual<\/span><strong>' + fmtMoney2(report.input.monthly) + '<\/strong><\/div><div class=\"box\"><span>Intereses netos<\/span><strong>' + fmtMoney2(report.totalNetInterest) + '<\/strong><\/div><div class=\"box\"><span>Saldo final estimado<\/span><strong>' + fmtMoney2(report.finalBalance) + '<\/strong><\/div><\/div>' +\n      '<p><strong>Tipo de cuenta:<\/strong> ' + accountLabel(report.input.account) + ' \u00b7 <strong>Plazo:<\/strong> ' + report.input.months + ' meses \u00b7 <strong>Tasa m\u00e1xima usada:<\/strong> ' + fmtPct(report.maxRate) + ' E.A.<\/p>' +\n      '<table><thead><tr><th>Mes<\/th><th>Saldo promedio<\/th><th>Tasa<\/th><th>Inter\u00e9s neto<\/th><th>Saldo final<\/th><\/tr><\/thead><tbody>' + rows + '<\/tbody><\/table>' +\n      '<script>window.onload=function(){setTimeout(function(){window.print()},250)}<\\\/script><\/body><\/html>';\n  }\n\n  function printFallback(report) {\n    const w = window.open('', '_blank', 'noopener,noreferrer,width=980,height=720');\n    if (!w) throw new Error('Ventana emergente bloqueada');\n    w.document.open();\n    w.document.write(printableHtml(report));\n    w.document.close();\n  }\n\n  function calculateAndRender() {\n    hideError();\n    try {\n      const input = validateInputs();\n      const report = calculateScenario(input);\n      lastReport = report;\n      renderReport(report);\n      history.replaceState(null, '', buildUrl(report));\n      return report;\n    } catch (error) {\n      showError(error.message || 'No fue posible calcular. Revisa los datos ingresados.');\n      return null;\n    }\n  }\n\n  attachMoneyFormatter(els.amount);\n  attachMoneyFormatter(els.monthly);\n\n  els.form.addEventListener('submit', event => {\n    event.preventDefault();\n    calculateAndRender();\n  });\n\n  els.clear.addEventListener('click', () => {\n    hideError();\n    els.amount.value = '';\n    els.monthly.value = '';\n    els.months.value = '12';\n    els.account.value = 'nomina';\n    els.timing.value = 'start';\n    els.retention.value = '0.07';\n    els.results.classList.remove('is-visible');\n    els.pdfBox.classList.remove('is-visible');\n    els.tbody.innerHTML = '';\n    lastReport = null;\n    history.replaceState(null, '', location.pathname);\n    root.scrollIntoView({ behavior: 'smooth', block: 'start' });\n  });\n\n  els.share.addEventListener('click', async () => {\n    const report = lastReport || calculateAndRender();\n    if (!report) return;\n    const url = buildUrl(report);\n    try {\n      await navigator.clipboard.writeText(url);\n      els.toast.textContent = 'Enlace copiado';\n      els.toast.classList.add('is-visible');\n      setTimeout(() => els.toast.classList.remove('is-visible'), 2400);\n    } catch (error) {\n      els.toast.textContent = 'Copia la URL desde la barra del navegador';\n      els.toast.classList.add('is-visible');\n      setTimeout(() => els.toast.classList.remove('is-visible'), 3200);\n    }\n  });\n\n  els.pdfButton.addEventListener('click', async () => {\n    const report = lastReport || calculateAndRender();\n    if (!report) return;\n    const oldText = els.pdfButton.textContent;\n    els.pdfButton.disabled = true;\n    els.pdfButton.textContent = 'Generando PDF...';\n    els.pdfStatus.textContent = 'Preparando reporte descargable.';\n    try {\n      const jsPDF = await ensureJsPdf();\n      exportPdf(jsPDF, report);\n      els.pdfStatus.textContent = 'PDF generado con sello IG, URL visible y marca de agua.';\n    } catch (error) {\n      try {\n        printFallback(report);\n        els.pdfStatus.textContent = 'No carg\u00f3 jsPDF. Se abri\u00f3 impresi\u00f3n; elige \u201cGuardar como PDF\u201d.';\n      } catch (fallbackError) {\n        els.pdfStatus.textContent = 'No fue posible abrir el PDF ni la vista de impresi\u00f3n. Revisa bloqueadores de ventanas emergentes.';\n      }\n    } finally {\n      els.pdfButton.disabled = false;\n      els.pdfButton.textContent = oldText;\n    }\n  });\n\n  els.printButton.addEventListener('click', () => {\n    const report = lastReport || calculateAndRender();\n    if (!report) return;\n    try { printFallback(report); }\n    catch (error) { showError('No se pudo abrir la vista de impresi\u00f3n. Revisa si el navegador bloque\u00f3 ventanas emergentes.'); }\n  });\n\n  function initReveal() {\n    const items = Array.from(root.querySelectorAll('.ig-reveal'));\n    if (!('IntersectionObserver' in window)) {\n      items.forEach(item => item.classList.add('is-visible'));\n      return;\n    }\n    const obs = new IntersectionObserver(entries => {\n      entries.forEach(entry => {\n        if (entry.isIntersecting) {\n          entry.target.classList.add('is-visible');\n          obs.unobserve(entry.target);\n        }\n      });\n    }, { threshold: 0.14 });\n    items.forEach(item => obs.observe(item));\n  }\n\n  initReveal();\n  setFromUrl();\n})();\n<\/script>\n\t\t\t\t<\/div>\n\t\t\t\t<\/div>\n\t\t\t\t<\/div>\n\t\t","protected":false},"excerpt":{"rendered":"<p>\u25a3 Herramienta financiera IG \u25cf Bolsillos Davivienda Calculadora de Bolsillos Davivienda Simula cu\u00e1nto podr\u00edas recibir por guardar tus ahorros en Bolsillos, usando tramos de tasa por saldo promedio, tipo de cuenta y retenci\u00f3n estimada sobre intereses. 15 Hasta 15 bolsillos por cuenta $0 Sin cuota de manejo adicional \u21bb Abonos autom\u00e1ticos programables Saldo inicial en&#8230;<\/p>\n","protected":false},"author":1,"featured_media":5813,"template":"","meta":{"_kadence_starter_templates_imported_post":false,"_kad_post_transparent":"","_kad_post_title":"","_kad_post_layout":"","_kad_post_sidebar_id":"","_kad_post_content_style":"","_kad_post_vertical_padding":"","_kad_post_feature":"","_kad_post_feature_position":"","_kad_post_header":false,"_kad_post_footer":false,"_kad_post_classname":"","footnotes":""},"class_list":["post-5880","herramientas","type-herramientas","status-publish","has-post-thumbnail","hentry"],"_links":{"self":[{"href":"https:\/\/inversionesguru.com\/co\/wp-json\/wp\/v2\/herramientas\/5880","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/inversionesguru.com\/co\/wp-json\/wp\/v2\/herramientas"}],"about":[{"href":"https:\/\/inversionesguru.com\/co\/wp-json\/wp\/v2\/types\/herramientas"}],"author":[{"embeddable":true,"href":"https:\/\/inversionesguru.com\/co\/wp-json\/wp\/v2\/users\/1"}],"version-history":[{"count":14,"href":"https:\/\/inversionesguru.com\/co\/wp-json\/wp\/v2\/herramientas\/5880\/revisions"}],"predecessor-version":[{"id":8631,"href":"https:\/\/inversionesguru.com\/co\/wp-json\/wp\/v2\/herramientas\/5880\/revisions\/8631"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/inversionesguru.com\/co\/wp-json\/wp\/v2\/media\/5813"}],"wp:attachment":[{"href":"https:\/\/inversionesguru.com\/co\/wp-json\/wp\/v2\/media?parent=5880"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}