{"id":24488,"date":"2025-08-20T05:47:00","date_gmt":"2025-08-20T05:47:00","guid":{"rendered":"https:\/\/kansoft.ch\/?page_id=24488"},"modified":"2025-11-27T10:23:20","modified_gmt":"2025-11-27T10:23:20","slug":"swiss-cloud-cost-calculator","status":"publish","type":"page","link":"https:\/\/kansoft.ch\/de\/swiss-cloud-cost-calculator\/","title":{"rendered":"Schweizer Cloud-Kostenrechner"},"content":{"rendered":"\t\t<div data-elementor-type=\"wp-page\" data-elementor-id=\"24488\" class=\"elementor elementor-24488\">\n\t\t\t\t<div class=\"elementor-element elementor-element-035f3e3 e-con-full e-flex e-con e-parent\" data-id=\"035f3e3\" data-element_type=\"container\" data-e-type=\"container\">\n\t\t\t\t<div class=\"elementor-element elementor-element-7008ed3 elementor-widget elementor-widget-html\" data-id=\"7008ed3\" data-element_type=\"widget\" data-e-type=\"widget\" data-widget_type=\"html.default\">\n\t\t\t\t<div class=\"elementor-widget-container\">\n\t\t\t\t\t<link rel=\"preconnect\" href=\"https:\/\/fonts.googleapis.com\">\r\n<link rel=\"preconnect\" href=\"https:\/\/fonts.gstatic.com\" crossorigin>\r\n<link href=\"https:\/\/fonts.googleapis.com\/css2?family=Montserrat:wght@400;500;600;700;800&display=swap\" rel=\"stylesheet\">\r\n<script src=\"https:\/\/cdn.jsdelivr.net\/npm\/chart.js@3.9.1\/dist\/chart.min.js\"><\/script>\r\n<script src=\"https:\/\/cdnjs.cloudflare.com\/ajax\/libs\/jspdf\/2.5.1\/jspdf.umd.min.js\"><\/script>\r\n<script src=\"https:\/\/cdnjs.cloudflare.com\/ajax\/libs\/jspdf-autotable\/3.5.23\/jspdf.plugin.autotable.min.js\"><\/script>\r\n<script charset=\"utf-8\" type=\"text\/javascript\" src=\"\/\/js.hsforms.net\/forms\/embed\/v2.js\"><\/script>\r\n\r\n\r\n<style>\r\n    :root {\r\n        --c-primary: #0A004F;\r\n        --c-primary-dark: #060033;\r\n        --c-primary-gradient: linear-gradient(145deg, var(--c-primary-dark), var(--c-primary));\r\n        --c-accent: #029E84;\r\n        --c-accent-light: #51c9b6;\r\n        --c-accent-hover: #028a73;\r\n        --c-white: #ffffff;\r\n        --c-bg: #f7f9fa;\r\n        --c-bg-light: #ffffff;\r\n        --c-text-dark: #1d2433;\r\n        --c-text-muted: #5a6271;\r\n        --c-border: #e1e4e6;\r\n        --font-family: 'Montserrat', sans-serif;\r\n    }\r\n\r\n    .form-loader-container {\r\n        display: flex;\r\n        justify-content: center;\r\n        align-items: center;\r\n        min-height: 250px;\r\n        \/* Give it some height so it looks good *\/\r\n    }\r\n\r\n    .savings-calculator-container {\r\n        font-family: var(--font-family);\r\n        background-color: var(--c-bg);\r\n        padding: 120px 0;\r\n\r\n         word-break: break-word; \/* Allows long words to break and wrap to the next line *\/\r\n        -webkit-hyphens: auto;   \/* For Safari *\/\r\n        -ms-hyphens: auto;       \/* For IE *\/\r\n        hyphens: auto;           \/* Adds hyphens when breaking words, improving readability *\/\r\n    }\r\n\r\n    .savings-calculator-container *,\r\n    .savings-calculator-container *::before,\r\n    .savings-calculator-container *::after {\r\n        box-sizing: border-box;\r\n    }\r\n\r\n    .hero-header-container {\r\n        text-align: center;\r\n        margin-bottom: 3.5rem;\r\n        padding: 0 20px;\r\n    }\r\n\r\n    .hero-header-container .main-heading {\r\n        font-size: clamp(2rem, 4vw, 2.8rem);\r\n        font-weight: 800;\r\n        color: var(--c-text-dark);\r\n        margin: 0 0 1rem 0;\r\n        letter-spacing: -0.5x;\r\n    }\r\n\r\n    .hero-header-container .main-heading .highlight {\r\n        color: var(--c-accent);\r\n    }\r\n\r\n    .hero-header-container .sub-heading {\r\n        font-size: clamp(1rem, 2.5vw, 1.1rem);\r\n        color: var(--c-text-muted);\r\n        line-height: 1.7;\r\n        max-width: 800px;\r\n        margin: 0 auto;\r\n    }\r\n\r\n    .calculator-layout {\r\n        display: grid;\r\n        grid-template-columns: minmax(0, 1fr) minmax(0, 1.1fr);\r\n        gap: 3rem;\r\n        align-items: flex-start;\r\n        max-width: 1360px;\r\n        margin: 0 auto;\r\n        padding: 0 20px;\r\n    }\r\n\r\n    .calculator-wrapper {\r\n        padding: 2.5rem;\r\n        border-radius: 24px;\r\n        background-color: var(--c-bg-light);\r\n        box-shadow: 0 16px 40px -12px rgba(0, 20, 50, 0.1);\r\n        position: relative;\r\n    }\r\n\r\n    .result-wrapper {\r\n        border-radius: 24px;\r\n        color: var(--c-white);\r\n        position: sticky;\r\n        top: 24px;\r\n        background: var(--c-primary-gradient);\r\n        border: 1px solid rgba(255, 255, 255, 0.1);\r\n        padding: 2.5rem;\r\n        box-shadow: 0 20px 25px -5px rgba(10, 0, 79, 0.2), 0 10px 10px -5px rgba(10, 0, 79, 0.1);\r\n    }\r\n\r\n    #savings-form {\r\n        display: grid;\r\n        grid-template-columns: 1fr 1fr;\r\n        gap: 1rem 1.5rem;\r\n    }\r\n\r\n    .form-title,\r\n    .results-title {\r\n        font-size: 2rem !important;\r\n        font-weight: 700;\r\n        margin-top: 0;\r\n        margin-bottom: 1.5rem;\r\n        color: var(--c-text-dark);\r\n        grid-column: 1 \/ -1;\r\n    }\r\n\r\n    .results-title {\r\n        color: var(--c-white) !important;\r\n    }\r\n\r\n    .calculator-field.full-width {\r\n        grid-column: 1 \/ -1;\r\n    }\r\n\r\n    .calculator-field.hidden {\r\n        display: none;\r\n    }\r\n\r\n    .label-text {\r\n        display: flex;\r\n        justify-content: space-between;\r\n        align-items: center;\r\n        flex-wrap: wrap;\r\n        font-weight: 500;\r\n        margin-bottom: 0.75rem;\r\n        font-size: 0.9rem;\r\n        color: var(--c-text-muted);\r\n    }\r\n\r\n    .label-text strong {\r\n        color: var(--c-primary);\r\n        font-weight: 700;\r\n        font-size: 1rem;\r\n    }\r\n\r\n    .input-field {\r\n        width: 100% !important;\r\n        padding: 14px 18px !important;\r\n        border: 1px solid var(--c-border) !important;\r\n        border-radius: 12px !important;\r\n        font-size: 1rem !important;\r\n        font-family: var(--font-family) !important;\r\n        background-color: #fff !important;\r\n        color: var(--c-text-dark) !important;\r\n        transition: border-color 0.2s, box-shadow 0.2s !important;\r\n    }\r\n\r\n    .input-field:focus {\r\n        outline: none;\r\n        border-color: var(--c-accent) !important;\r\n        background-color: var(--c-white) !important;\r\n    }\r\n\r\n    input[type=\"range\"].range-slider {\r\n        -webkit-appearance: none;\r\n        appearance: none;\r\n        width: 100%;\r\n        height: 8px;\r\n        background: var(--c-border);\r\n        border-radius: 8px;\r\n        outline: none;\r\n        padding: 0;\r\n        margin-top: 8px;\r\n        background-repeat: no-repeat;\r\n        border: none !important;\r\n    }\r\n\r\n    input[type=\"range\"].range-slider::-webkit-slider-thumb {\r\n        -webkit-appearance: none;\r\n        appearance: none;\r\n        width: 22px;\r\n        height: 22px;\r\n        background: var(--c-accent);\r\n        cursor: pointer;\r\n        border-radius: 50%;\r\n        border: 4px solid var(--c-white);\r\n        box-shadow: 0 2px 5px rgba(0, 0, 0, 0.2);\r\n    }\r\n\r\n    input[type=\"range\"].range-slider::-moz-range-thumb {\r\n        width: 22px;\r\n        height: 22px;\r\n        background: var(--c-accent);\r\n        cursor: pointer;\r\n        border-radius: 50%;\r\n        border: 4px solid var(--c-white);\r\n        box-shadow: 0 2px 5px rgba(0, 0, 0, 0.2);\r\n    }\r\n\r\n    .output-summary {\r\n        display: grid;\r\n        grid-template-columns: 1fr 1fr;\r\n        gap: 1.25rem 1.75rem;\r\n        padding-bottom: 2rem;\r\n        margin-bottom: 1.5rem;\r\n        border-bottom: 1px solid rgba(255, 255, 255, 0.15);\r\n    }\r\n\r\n    .summary-item .label {\r\n        font-size: 0.9rem;\r\n        opacity: 0.8;\r\n        margin-bottom: 6px;\r\n    }\r\n\r\n    .summary-item .value {\r\n        font-size: 1.75rem;\r\n        font-weight: 700;\r\n        color: var(--c-accent-light);\r\n    }\r\n\r\n    .detailed-report {\r\n        display: grid;\r\n        grid-template-columns: 180px 1fr;\r\n        gap: 2rem;\r\n        align-items: center;\r\n    }\r\n\r\n    .chart-container {\r\n        position: relative;\r\n        max-width: 180px;\r\n        aspect-ratio: 1 \/ 1;\r\n    }\r\n\r\n    .report-breakdown .report-title {\r\n        font-size: 1.2rem;\r\n        font-weight: 600;\r\n        margin-bottom: 1rem;\r\n        opacity: 0.9;\r\n    }\r\n\r\n    .report-item {\r\n        display: flex;\r\n        align-items: center;\r\n        gap: 1rem;\r\n        padding: 0.75rem 0;\r\n        font-size: 0.95rem;\r\n        border-bottom: 1px solid rgba(255, 255, 255, 0.1);\r\n    }\r\n\r\n    .report-item:last-child {\r\n        border-bottom: none;\r\n    }\r\n\r\n    .report-dot {\r\n        width: 12px;\r\n        height: 12px;\r\n        border-radius: 50%;\r\n        flex-shrink: 0;\r\n    }\r\n\r\n    .report-item .label {\r\n        opacity: 0.8;\r\n        flex-grow: 1;\r\n    }\r\n\r\n    .report-item .value {\r\n        font-weight: 600;\r\n        font-size: 1rem;\r\n    }\r\n\r\n    .download-button {\r\n        width: 100%;\r\n        padding: 16px;\r\n        margin-top: 2rem;\r\n        font-family: var(--font-family);\r\n        font-size: 1rem;\r\n        font-weight: 600;\r\n        color: var(--c-white);\r\n        background-color: var(--c-accent);\r\n        border: none;\r\n        border-radius: 12px;\r\n        cursor: pointer;\r\n        transition: all 0.2s ease-in-out;\r\n    }\r\n\r\n    .download-button:hover {\r\n        background-color: var(--c-accent-hover);\r\n        transform: translateY(-2px);\r\n        box-shadow: 0 4px 15px rgba(2, 158, 132, 0.2);\r\n        color: white;\r\n    }\r\n\r\n    .loading-overlay {\r\n        position: absolute;\r\n        top: 0;\r\n        left: 0;\r\n        width: 100%;\r\n        height: 100%;\r\n        background-color: rgba(255, 255, 255, 0.8);\r\n        backdrop-filter: blur(4px);\r\n        -webkit-backdrop-filter: blur(4px);\r\n        display: flex;\r\n        justify-content: center;\r\n        align-items: center;\r\n        z-index: 10;\r\n        border-radius: 24px;\r\n        opacity: 0;\r\n        visibility: hidden;\r\n        transition: opacity 0.3s ease;\r\n    }\r\n\r\n    .loading-overlay.visible {\r\n        opacity: 1;\r\n        visibility: visible;\r\n    }\r\n\r\n    .spinner {\r\n        width: 56px;\r\n        height: 56px;\r\n        border: 6px solid var(--c-border);\r\n        border-top-color: var(--c-accent);\r\n        border-radius: 50%;\r\n        animation: spin 1s linear infinite;\r\n    }\r\n\r\n    @keyframes spin {\r\n        to {\r\n            transform: rotate(360deg);\r\n        }\r\n    }\r\n\r\n    .modal-overlay {\r\n        position: fixed;\r\n        top: 0;\r\n        left: 0;\r\n        width: 100%;\r\n        height: 100%;\r\n        background-color: rgba(10, 0, 79, 0.6);\r\n        backdrop-filter: blur(8px);\r\n        -webkit-backdrop-filter: blur(8px);\r\n        display: flex;\r\n        justify-content: center;\r\n        align-items: center;\r\n        z-index: 1000;\r\n        opacity: 0;\r\n        visibility: hidden;\r\n        transition: opacity 0.3s ease, visibility 0s 0.3s;\r\n    }\r\n\r\n    .modal-overlay:not(.modal-hidden) {\r\n        opacity: 1;\r\n        visibility: visible;\r\n        transition: opacity 0.3s ease;\r\n    }\r\n\r\n    .modal-content {\r\n        background-color: var(--c-white);\r\n        padding: 2.5rem 3rem;\r\n        border-radius: 24px;\r\n        width: 100%;\r\n        max-width: 500px;\r\n        position: relative;\r\n        box-shadow: 0 20px 25px -5px rgba(0, 0, 0, 0.1), 0 10px 10px -5px rgba(0, 0, 0, 0.04);\r\n        transform: scale(0.95);\r\n        transition: transform 0.3s ease;\r\n    }\r\n\r\n    .modal-overlay:not(.modal-hidden) .modal-content {\r\n        transform: scale(1);\r\n    }\r\n\r\n    .modal-title {\r\n        color: var(--c-primary);\r\n        font-size: 1.8rem;\r\n        font-weight: 700;\r\n        margin: 0 0 0.5rem 0;\r\n        text-align: center;\r\n    }\r\n\r\n    .modal-subtitle {\r\n        color: var(--c-text-muted);\r\n        text-align: center;\r\n        margin-bottom: 2rem;\r\n    }\r\n\r\n    .modal-close {\r\n        position: absolute;\r\n        top: 1rem;\r\n        right: 1.5rem;\r\n        background: none !important;\r\n        border: none !important;\r\n        font-size: 2rem;\r\n        color: var(--c-text-muted) !important;\r\n        cursor: pointer !important;\r\n        line-height: 1;\r\n    }\r\n\r\n    @media (max-width: 1024px) {\r\n        .calculator-layout {\r\n            grid-template-columns: 1fr;\r\n        }\r\n\r\n        \/* ADD THIS RULE *\/\r\n        #savings-form {\r\n            grid-template-columns: 1fr;\r\n        }\r\n        \/* END ADDITION *\/\r\n\r\n        .result-wrapper {\r\n            position: static;\r\n            margin-top: 2rem;\r\n        }\r\n    }\r\n\r\n    @media (max-width: 768px) {\r\n\r\n        \/* #savings-form,\r\n        .output-summary,\r\n        .detailed-report {\r\n            grid-template-columns: 1fr;\r\n        } *\/\r\n\r\n        .output-summary, .detailed-report {\r\n            grid-template-columns: 1fr 1fr;\r\n        }\r\n\r\n        .chart-container {\r\n            margin: 0 auto 1.5rem auto;\r\n        }\r\n\r\n        .modal-content {\r\n            width: 90%;\r\n            padding: 2rem 1.5rem;\r\n        }\r\n    }\r\n<\/style>\r\n\r\n<div class=\"savings-calculator-container\">\r\n    <div class=\"hero-header-container\">\r\n        <h1 class=\"main-heading\">What Are You Really Spending<span class=\"highlight\"> <br>on the Cloud?<\/span><\/h1>\r\n    <\/div>\r\n\r\n    <div class=\"calculator-layout\">\r\n        <div class=\"calculator-wrapper\">\r\n            <div class=\"loading-overlay\" id=\"loadingOverlay\">\r\n                <div class=\"spinner\"><\/div>\r\n            <\/div>\r\n            <form id=\"savings-form\">\r\n                <h2 class=\"form-title\">Your current cloud spend<\/h2>\r\n\r\n                <div class=\"calculator-field\">\r\n                    <label for=\"numInstances\" class=\"label-text\">Number of Instances<\/label>\r\n                    <input class=\"input-field\" type=\"number\" id=\"numInstances\" value=\"0\" min=\"0\">\r\n                <\/div>\r\n\r\n                <div class=\"calculator-field\">\r\n                    <label for=\"cloudProvider\" class=\"label-text\">Cloud Provider<\/label>\r\n                    <select id=\"cloudProvider\" class=\"input-field\">\r\n                        <option value=\"\" selected disabled>Select Provider...<\/option>\r\n                        <option value=\"AWS\">Amazon Web Services (AWS)<\/option>\r\n                        <option value=\"GCP\">Google Cloud (GCP)<\/option>\r\n                        <option value=\"Azure\">Microsoft Azure<\/option>\r\n                    <\/select>\r\n                <\/div>\r\n\r\n                <div class=\"calculator-field full-width\">\r\n                    <label for=\"operatingSystem\" class=\"label-text\">Operating System<\/label>\r\n                    <select id=\"operatingSystem\" class=\"input-field\">\r\n                        <option value=\"\" selected disabled>Select OS...<\/option>\r\n                        <option value=\"linux\">Linux (Default)<\/option>\r\n                        <option value=\"windows\">Windows Server<\/option>\r\n                    <\/select>\r\n                <\/div>\r\n\r\n                <div class=\"calculator-field\" data-provider=\"AWS\">\r\n                    <label for=\"awsRegion\" class=\"label-text\">AWS Region<\/label>\r\n                    <select id=\"awsRegion\" class=\"input-field\">\r\n                        <option value=\"\" selected disabled>Select Region...<\/option>\r\n                        <option value=\"eu-central-1\">Frankfurt (eu-central-1)<\/option>\r\n                        <option value=\"eu-central-2\">Zurich (eu-central-2)<\/option>\r\n                        <option value=\"eu-west-1\">Ireland (eu-west-1)<\/option>\r\n                        <option value=\"eu-west-2\">London (eu-west-2)<\/option>\r\n                        <option value=\"eu-west-3\">Paris (eu-west-3)<\/option>\r\n                        <option value=\"eu-north-1\">Stockholm (eu-north-1)<\/option>\r\n                        <option value=\"eu-south-1\">Milan (eu-south-1)<\/option>\r\n                        <option value=\"eu-south-2\">Spain (eu-south-2)<\/option>\r\n                    <\/select>\r\n                <\/div>\r\n                <div class=\"calculator-field\" data-provider=\"AWS\">\r\n                    <label for=\"awsInstanceType\" class=\"label-text\">AWS Instance Type<\/label>\r\n                    <select id=\"awsInstanceType\" class=\"input-field\">\r\n                        <option value=\"\" selected disabled>Select Instance...<\/option>\r\n                        <optgroup label=\"General Purpose - T3 (Burstable)\">\r\n                            <option value=\"t3.large\">t3.large (2 vCPU, 8GB)<\/option>\r\n                            <option value=\"t3.xlarge\">t3.xlarge (4 vCPU, 16GB)<\/option>\r\n                        <\/optgroup>\r\n                        <optgroup label=\"General Purpose - M6g (Graviton2)\">\r\n                            <option value=\"m6g.large\">m6g.large (2 vCPU, 8GB)<\/option>\r\n                            <option value=\"m6g.xlarge\">m6g.xlarge (4 vCPU, 16GB)<\/option>\r\n                        <\/optgroup>\r\n                        <optgroup label=\"Compute Optimized - C5\">\r\n                            <option value=\"c5.large\">c5.large (2 vCPU, 4GB)<\/option>\r\n                            <option value=\"c5.xlarge\">c5.xlarge (4 vCPU, 8GB)<\/option>\r\n                        <\/optgroup>\r\n                        <optgroup label=\"Memory Optimized - R5\">\r\n                            <option value=\"r5.large\">r5.large (2 vCPU, 16GB)<\/option>\r\n                            <option value=\"r5.xlarge\">r5.xlarge (4 vCPU, 32GB)<\/option>\r\n                        <\/optgroup>\r\n                    <\/select>\r\n                <\/div>\r\n\r\n                <div class=\"calculator-field hidden\" data-provider=\"GCP\">\r\n                    <label for=\"gcpRegion\" class=\"label-text\">GCP Region<\/label>\r\n                    <select id=\"gcpRegion\" class=\"input-field\">\r\n                        <option value=\"\" selected disabled>Select Region...<\/option>\r\n                        <option value=\"europe-west6\">Zurich (europe-west6)<\/option>\r\n                        <option value=\"europe-west3\">Frankfurt (europe-west3)<\/option>\r\n                        <option value=\"europe-west2\">London (europe-west2)<\/option>\r\n                        <option value=\"europe-west9\">Paris (europe-west9)<\/option>\r\n                        <option value=\"europe-south1\">Milan (europe-south1)<\/option>\r\n                        <option value=\"europe-southwest1\">Madrid (europe-southwest1)<\/option>\r\n                        <option value=\"europe-central2\">Warsaw (europe-central2)<\/option>\r\n                    <\/select>\r\n                <\/div>\r\n                <div class=\"calculator-field hidden\" data-provider=\"GCP\">\r\n                    <label for=\"gcpInstanceType\" class=\"label-text\">GCP Instance Type<\/label>\r\n                    <select id=\"gcpInstanceType\" class=\"input-field\">\r\n                        <option value=\"\" selected disabled>Select Instance...<\/option>\r\n                        <optgroup label=\"General Purpose - E2\">\r\n                            <option value=\"e2-standard-2\">E2 Standard 2 (2 vCPU, 8GB)<\/option>\r\n                            <option value=\"e2-standard-4\">E2 Standard 4 (4 vCPU, 16GB)<\/option>\r\n                            <option value=\"e2-standard-8\">E2 Standard 8 (8 vCPU, 32GB)<\/option>\r\n                        <\/optgroup>\r\n                        <optgroup label=\"General Purpose - N2D (AMD)\">\r\n                            <option value=\"n2d-standard-2\">N2D Standard 2 (2 vCPU, 8GB)<\/option>\r\n                            <option value=\"n2d-standard-4\">N2D Standard 4 (4 vCPU, 16GB)<\/option>\r\n                        <\/optgroup>\r\n                        <optgroup label=\"Compute Optimized - C3\">\r\n                            <option value=\"c3-standard-4\">C3 Standard 4 (4 vCPU, 16GB)<\/option>\r\n                            <option value=\"c3-standard-8\">C3 Standard 8 (8 vCPU, 32GB)<\/option>\r\n                        <\/optgroup>\r\n                    <\/select>\r\n                <\/div>\r\n\r\n                <div class=\"calculator-field hidden\" data-provider=\"Azure\">\r\n                    <label for=\"azureRegion\" class=\"label-text\">Azure Region<\/label>\r\n                    <select id=\"azureRegion\" class=\"input-field\">\r\n                        <option value=\"\" selected disabled>Select Region...<\/option>\r\n                        <option value=\"switzerlandnorth\">Switzerland North<\/option>\r\n                        <option value=\"germanywestcentral\">Germany West Central<\/option>\r\n                        <option value=\"uksouth\">UK South (London)<\/option>\r\n                        <option value=\"westeurope\">West Europe (Netherlands)<\/option>\r\n                        <option value=\"northeurope\">North Europe (Ireland)<\/option>\r\n                        <option value=\"francecentral\">France Central<\/option>\r\n                        <option value=\"swedencentral\">Sweden Central<\/option>\r\n                    <\/select>\r\n                <\/div>\r\n                <div class=\"calculator-field hidden\" data-provider=\"Azure\">\r\n                    <label for=\"azureInstanceType\" class=\"label-text\">Azure VM Type<\/label>\r\n                    <select id=\"azureInstanceType\" class=\"input-field\">\r\n                        <option value=\"\" selected disabled>Select VM...<\/option>\r\n                        <optgroup label=\"General Purpose - Dsv5 (Newer)\">\r\n                            <option value=\"Standard_D2s_v5\">D2s v5 (2 vCPU, 8GB)<\/option>\r\n                            <option value=\"Standard_D4s_v5\">D4s v5 (4 vCPU, 16GB)<\/option>\r\n                        <\/optgroup>\r\n                        <optgroup label=\"Memory Optimized - Esv5\">\r\n                            <option value=\"Standard_E2s_v5\">E2s v5 (2 vCPU, 16GB)<\/option>\r\n                            <option value=\"Standard_E4s_v5\">E4s v5 (4 vCPU, 32GB)<\/option>\r\n                        <\/optgroup>\r\n                        <optgroup label=\"Compute Optimized - Fsv2\">\r\n                            <option value=\"Standard_F2s_v2\">F2s v2 (2 vCPU, 4GB)<\/option>\r\n                            <option value=\"Standard_F4s_v2\">F4s v2 (4 vCPU, 8GB)<\/option>\r\n                        <\/optgroup>\r\n                    <\/select>\r\n                <\/div>\r\n\r\n                <div class=\"calculator-field\">\r\n                    <label for=\"numEngineers\" class=\"label-text\">No. of Cloud Users\/Licences<\/label>\r\n                    <input class=\"input-field\" type=\"number\" id=\"numEngineers\" value=\"0\" min=\"0\">\r\n                <\/div>\r\n                <div class=\"calculator-field\">\r\n                    <label for=\"numCustomers\" class=\"label-text\">Number of Customers served<\/label>\r\n                    <input class=\"input-field\" type=\"number\" id=\"numCustomers\" value=\"0\" min=\"0\">\r\n                <\/div>\r\n                <div class=\"calculator-field\">\r\n                    <label for=\"displayCurrency\" class=\"label-text\">Currency<\/label>\r\n                    <select id=\"displayCurrency\" class=\"input-field\">\r\n                        <option value=\"\" selected disabled>Select Currency...<\/option>\r\n                        <option value=\"CHF\">Swiss Franc (CHF)<\/option>\r\n                        <option value=\"EUR\">Euro (EUR)<\/option>\r\n                    <\/select>\r\n                <\/div>\r\n                <div class=\"calculator-field\">\r\n                    <label for=\"typeOfEnvironment\" class=\"label-text\">Type of Environment<\/label>\r\n                    <select id=\"typeOfEnvironment\" class=\"input-field\">\r\n                        <option value=\"\" selected disabled>Select Environment...<\/option>\r\n                        <option value=\"Dev\">Dev \/ Test<\/option>\r\n                        <option value=\"Prod\">Production<\/option>\r\n                    <\/select>\r\n                <\/div>\r\n                <div class=\"calculator-field full-width\">\r\n                    <label for=\"avgUsage\" class=\"label-text\"><span>Average Instance Usage %<\/span><strong\r\n                            id=\"avgUsageLabel\">35%<\/strong><\/label>\r\n                    <input type=\"range\" min=\"10\" max=\"100\" value=\"35\" class=\"input-field range-slider\" id=\"avgUsage\">\r\n                <\/div>\r\n                <div class=\"calculator-field\">\r\n                    <label for=\"autoscalingEnabled\" class=\"label-text\">Autoscaling Enabled?<\/label>\r\n                    <select id=\"autoscalingEnabled\" class=\"input-field\">\r\n                        <option value=\"\" selected disabled>Select Option...<\/option>\r\n                        <option value=\"No\">No<\/option>\r\n                        <option value=\"Yes\">Yes<\/option>\r\n                    <\/select>\r\n                <\/div>\r\n                <div class=\"calculator-field\">\r\n                    <label for=\"reservedInstances\" class=\"label-text\">Committed Use?<\/label>\r\n                    <select id=\"reservedInstances\" class=\"input-field\">\r\n                        <option value=\"\" selected disabled>Select Option...<\/option>\r\n                        <option value=\"No\">No<\/option>\r\n                        <option value=\"Yes\">Yes<\/option>\r\n                    <\/select>\r\n                <\/div>\r\n            <\/form>\r\n        <\/div>\r\n        <div class=\"result-wrapper\">\r\n            <h2 class=\"results-title\">Your Optimization Analysis<\/h2>\r\n            <div id=\"results-content-wrapper\">\r\n                <div class=\"output-summary\">\r\n                    <div class=\"summary-item\">\r\n                        <div class=\"label\">Base Monthly Spend<\/div>\r\n                        <div class=\"value\" id=\"output-base-spend\">CHF 0<\/div>\r\n                    <\/div>\r\n                    <div class=\"summary-item\">\r\n                        <div class=\"label\">Potential Monthly Savings<\/div>\r\n                        <div class=\"value\" id=\"output-monthly-saving\">CHF 0<\/div>\r\n                    <\/div>\r\n                    <div class=\"summary-item\">\r\n                        <div class=\"label\">Potential Annual Savings<\/div>\r\n                        <div class=\"value\" id=\"output-annual-saving\">CHF 0<\/div>\r\n                    <\/div>\r\n                    <div class=\"summary-item\">\r\n                        <div class=\"label\">Optimized Monthly Spend<\/div>\r\n                        <div class=\"value\" id=\"output-optimized-spend\">CHF 0<\/div>\r\n                    <\/div>\r\n                <\/div>\r\n                <div class=\"detailed-report\">\r\n                    <div class=\"chart-container\">\r\n                        <canvas id=\"savingsChart\"><\/canvas>\r\n                    <\/div>\r\n                    <div class=\"report-breakdown\" id=\"report-container\"><\/div>\r\n                <\/div>\r\n                <button id=\"download-report-btn\" class=\"download-button\">Download Full Report<\/button>\r\n            <\/div>\r\n        <\/div>\r\n    <\/div>\r\n\r\n    <div id=\"report-modal\" class=\"modal-overlay modal-hidden\">\r\n        <div class=\"modal-content\">\r\n            <button id=\"modal-close-btn\" class=\"modal-close\">&times;<\/button>\r\n            <h2 class=\"modal-title\">Get Your Detailed Report<\/h2>\r\n            <p class=\"modal-subtitle\">Fill out the form below to download your personalized savings analysis.<\/p>\r\n            <div id=\"form-wrapper\">\r\n                <div class=\"hubspot-no-global-style\">\r\n                    <div id=\"hubspot-report-form-container\"><\/div>\r\n                <\/div>\r\n            <\/div>\r\n        <\/div>\r\n    <\/div>\r\n<\/div>\r\n\r\n<script>\r\n    document.addEventListener('DOMContentLoaded', () => {\r\n        const form = document.getElementById('savings-form');\r\n        if (!form) return;\r\n        const { jsPDF } = window.jspdf;\r\n\r\n        const allInputs = {\r\n            numInstances: document.getElementById('numInstances'),\r\n            cloudProvider: document.getElementById('cloudProvider'),\r\n            awsRegion: document.getElementById('awsRegion'),\r\n            awsInstanceType: document.getElementById('awsInstanceType'),\r\n            gcpRegion: document.getElementById('gcpRegion'),\r\n            gcpInstanceType: document.getElementById('gcpInstanceType'),\r\n            azureRegion: document.getElementById('azureRegion'),\r\n            azureInstanceType: document.getElementById('azureInstanceType'),\r\n            displayCurrency: document.getElementById('displayCurrency'),\r\n            numEngineers: document.getElementById('numEngineers'),\r\n            numCustomers: document.getElementById('numCustomers'),\r\n            avgUsage: document.getElementById('avgUsage'),\r\n            autoscaling: document.getElementById('autoscalingEnabled'),\r\n            ri: document.getElementById('reservedInstances'),\r\n            env: document.getElementById('typeOfEnvironment'),\r\n            operatingSystem: document.getElementById('operatingSystem'),\r\n        };\r\n        const allOutputs = {\r\n            baseSpend: document.getElementById('output-base-spend'),\r\n            monthlySaving: document.getElementById('output-monthly-saving'),\r\n            annualSaving: document.getElementById('output-annual-saving'),\r\n            optimizedSpend: document.getElementById('output-optimized-spend'),\r\n            avgUsageLabel: document.getElementById('avgUsageLabel'),\r\n            reportContainer: document.getElementById('report-container'),\r\n        };\r\n        const loadingOverlay = document.getElementById('loadingOverlay');\r\n        const modalElements = {\r\n            overlay: document.getElementById('report-modal'),\r\n            closeBtn: document.getElementById('modal-close-btn'),\r\n            triggerBtn: document.getElementById('download-report-btn'),\r\n        };\r\n\r\n        let currencyRates = { CHF: 0.91, EUR: 0.92 }; \/\/ Default fallback rates\r\n        let lastCalculatedData = {};\r\n\r\n        const debounce = (func, delay = 1000) => {\r\n            let timeout;\r\n            return (...args) => {\r\n                clearTimeout(timeout);\r\n                timeout = setTimeout(() => {\r\n                    func.apply(this, args);\r\n                }, delay);\r\n            };\r\n        };\r\n\r\n        const formatCurrency = (value, currency) => {\r\n            if (!currency) return 'N\/A'; \/\/ Handle case where currency is not selected\r\n            const options = { style: 'currency', currency: currency, minimumFractionDigits: 0, maximumFractionDigits: 0 };\r\n            const locale = currency === 'CHF' ? 'de-CH' : 'de-DE';\r\n            return new Intl.NumberFormat(locale, options).format(value);\r\n        };\r\n\r\n        const chartCenterText = {\r\n            id: 'chartCenterText',\r\n            afterDraw(chart, args, options) {\r\n                if (!options.text) return;\r\n                const { ctx, chartArea: { top }, width, height } = chart;\r\n                ctx.save();\r\n                ctx.font = `${options.fontWeight || 'bold'} ${options.fontSize || '32px'} ${options.fontFamily || 'sans-serif'}`;\r\n                ctx.textAlign = 'center'; ctx.textBaseline = 'middle';\r\n                ctx.fillStyle = options.fontColor || '#ffffff';\r\n                const textY = (height \/ 2) + top;\r\n                ctx.fillText(options.text, width \/ 2, textY - 8);\r\n                if (options.subText) {\r\n                    ctx.font = `normal 12px ${options.fontFamily || 'sans-serif'}`;\r\n                    ctx.fillStyle = 'rgba(255,255,255,0.7)';\r\n                    ctx.fillText(options.subText, width \/ 2, textY + 18);\r\n                }\r\n                ctx.restore();\r\n            }\r\n        };\r\n        Chart.register(chartCenterText);\r\n        Chart.defaults.color = 'rgba(255, 255, 255, 0.85)';\r\n        Chart.defaults.font.family = \"'Montserrat', sans-serif\";\r\n\r\n        const savingsChart = new Chart(document.getElementById('savingsChart').getContext('2d'), {\r\n            type: 'doughnut',\r\n            data: { labels: [], datasets: [{ data: [], backgroundColor: [], borderWidth: 0 }] },\r\n            options: {\r\n                responsive: true, cutout: '80%',\r\n                plugins: {\r\n                    legend: { display: false },\r\n                    tooltip: { callbacks: { label: (c) => `${c.label}: ${formatCurrency(c.raw, allInputs.displayCurrency.value)}` } },\r\n                    chartCenterText: { text: '', subText: 'Savings Percentage', fontSize: '28px', fontWeight: 'bold', fontColor: '#ffffff' }\r\n                }\r\n            }\r\n        });\r\n\r\n        const updateSliderBackground = (slider) => {\r\n            const percentage = ((slider.value - slider.min) \/ (slider.max - slider.min)) * 100;\r\n            slider.style.backgroundSize = `${percentage}% 100%`;\r\n        };\r\n\r\n        const getCurrencyRates = async () => {\r\n            try {\r\n                const response = await fetch('https:\/\/api.frankfurter.app\/latest?from=USD&to=CHF,EUR');\r\n                if (!response.ok) throw new Error('Failed to fetch currency rates.');\r\n                const data = await response.json();\r\n                currencyRates = data.rates;\r\n            } catch (error) {\r\n                console.error(\"Currency API Error:\", error);\r\n            }\r\n        };\r\n\r\n        const getLivePrice = async (provider, instanceType, region, os) => {\r\n            \/\/ MODIFIED: Prevent API call if essential info is missing\r\n            if (!provider || !instanceType || !region || !os) {\r\n                return null;\r\n            }\r\n            loadingOverlay.classList.add('visible');\r\n            try {\r\n                const baseUrl = 'https:\/\/kansoft.ch';\r\n                let endpoint = '';\r\n\r\n                if (provider === 'GCP') {\r\n                    endpoint = `${baseUrl}\/wp-json\/calculator\/v1\/gcp-price`;\r\n                } else if (provider === 'Azure') {\r\n                    endpoint = `${baseUrl}\/wp-json\/calculator\/v1\/azure-price`;\r\n                } else if (provider === 'AWS') {\r\n                    endpoint = `${baseUrl}\/wp-json\/calculator\/v1\/aws-price`;\r\n                } else {\r\n                    throw new Error('Unsupported cloud provider selected.');\r\n                }\r\n\r\n                const response = await fetch(endpoint, {\r\n                    method: 'POST',\r\n                    headers: { 'Content-Type': 'application\/json' },\r\n                    body: JSON.stringify({ instance_type: instanceType, region: region, os: os })\r\n                });\r\n\r\n                if (!response.ok) {\r\n                    const errorText = await response.text();\r\n                    let errorMessage = 'Failed to fetch pricing data.';\r\n                    try {\r\n                        const errorData = JSON.parse(errorText);\r\n                        errorMessage = errorData.message || errorMessage;\r\n                    } catch (e) {\r\n                        console.error(\"Received non-JSON response from server:\", errorText);\r\n                        errorMessage = \"Server returned an unexpected response. Please ensure the API URL is correct and your WordPress Permalinks are set to 'Post name'.\";\r\n                    }\r\n                    throw new Error(errorMessage);\r\n                }\r\n\r\n                const data = await response.json();\r\n                return data.price;\r\n            } catch (error) {\r\n                console.error(\"Pricing API Error:\", error);\r\n                alert(`Could not retrieve live pricing: ${error.message}`);\r\n                return null;\r\n            } finally {\r\n                loadingOverlay.classList.remove('visible');\r\n            }\r\n        };\r\n\r\n        const toggleProviderFields = () => {\r\n            const selectedProvider = allInputs.cloudProvider.value;\r\n            document.querySelectorAll('[data-provider]').forEach(field => {\r\n                if (field.dataset.provider === selectedProvider) {\r\n                    field.classList.remove('hidden');\r\n                } else {\r\n                    field.classList.add('hidden');\r\n                }\r\n            });\r\n        };\r\n\r\n        const calculateAndRender = async () => {\r\n            const provider = allInputs.cloudProvider.value;\r\n            let region, instanceType;\r\n\r\n            if (provider === 'GCP') {\r\n                region = allInputs.gcpRegion.value;\r\n                instanceType = allInputs.gcpInstanceType.value;\r\n            } else if (provider === 'Azure') {\r\n                region = allInputs.azureRegion.value;\r\n                instanceType = allInputs.azureInstanceType.value;\r\n            } else if (provider === 'AWS') {\r\n                region = allInputs.awsRegion.value;\r\n                instanceType = allInputs.awsInstanceType.value;\r\n            }\r\n\r\n            const values = {\r\n                \/\/ MODIFIED: Changed fallback from 1 to 0 to handle new defaults\r\n                numInstances: parseInt(allInputs.numInstances.value, 10) || 0,\r\n                displayCurrency: allInputs.displayCurrency.value,\r\n                numEngineers: parseFloat(allInputs.numEngineers.value) || 0,\r\n                numCustomers: parseFloat(allInputs.numCustomers.value) || 0,\r\n                avgUsage: parseInt(allInputs.avgUsage.value, 10),\r\n                autoscaling: allInputs.autoscaling.value,\r\n                ri: allInputs.ri.value,\r\n                env: allInputs.env.value,\r\n                provider,\r\n                region,\r\n                instanceType,\r\n                os: allInputs.operatingSystem.value\r\n            };\r\n\r\n            allOutputs.avgUsageLabel.textContent = `${values.avgUsage}%`;\r\n            updateSliderBackground(allInputs.avgUsage);\r\n\r\n            const hourlyPriceUSD = await getLivePrice(provider, instanceType, region, values.os);\r\n            if (hourlyPriceUSD === null) {\r\n                \/\/ Reset outputs if price can't be fetched (e.g., placeholder selected)\r\n                allOutputs.baseSpend.textContent = formatCurrency(0, values.displayCurrency);\r\n                allOutputs.monthlySaving.textContent = formatCurrency(0, values.displayCurrency);\r\n                allOutputs.annualSaving.textContent = formatCurrency(0, values.displayCurrency);\r\n                allOutputs.optimizedSpend.textContent = formatCurrency(0, values.displayCurrency);\r\n                return;\r\n            };\r\n\r\n            const conversionRate = currencyRates[values.displayCurrency] || 1;\r\n            const hoursInMonth = 730;\r\n            const baseMonthlySpend = hourlyPriceUSD * hoursInMonth * values.numInstances * conversionRate;\r\n\r\n            let benchmarkSpend = baseMonthlySpend;\r\n            let savings = { env: 0, autoscaling: 0, ri: 0, usage: 0, ops: 0 };\r\n\r\n            if (values.env === 'Dev') { const optimized = benchmarkSpend * 0.65; savings.env = benchmarkSpend - optimized; benchmarkSpend = optimized; }\r\n            if (values.autoscaling === 'No') { const optimized = benchmarkSpend \/ 1.20; savings.autoscaling = benchmarkSpend - optimized; benchmarkSpend = optimized; }\r\n            if (values.ri === 'No') { const optimized = benchmarkSpend \/ 1.15; savings.ri = benchmarkSpend - optimized; benchmarkSpend = optimized; }\r\n            if (values.avgUsage < 50) { const optimized = benchmarkSpend * (1 - ((50 - values.avgUsage) * 0.007)); savings.usage = benchmarkSpend - optimized; benchmarkSpend = optimized; }\r\n\r\n            \/\/ MODIFIED: Prevent division by zero\r\n            const spendPerEngineer = (baseMonthlySpend > 0 && values.numEngineers > 0) ? baseMonthlySpend \/ values.numEngineers : 0;\r\n            if (spendPerEngineer < 10000 && spendPerEngineer > 0) { const opsSavings = benchmarkSpend * 0.05; savings.ops = opsSavings; benchmarkSpend -= opsSavings; }\r\n\r\n            const totalSavings = Object.values(savings).reduce((sum, val) => sum + val, 0);\r\n            const optimizedSpend = baseMonthlySpend - totalSavings;\r\n            const savingsPercentage = baseMonthlySpend > 0 ? (totalSavings \/ baseMonthlySpend) * 100 : 0;\r\n\r\n            allOutputs.baseSpend.textContent = formatCurrency(baseMonthlySpend, values.displayCurrency);\r\n            allOutputs.monthlySaving.textContent = formatCurrency(totalSavings, values.displayCurrency);\r\n            allOutputs.annualSaving.textContent = formatCurrency(totalSavings * 12, values.displayCurrency);\r\n            allOutputs.optimizedSpend.textContent = formatCurrency(optimizedSpend, values.displayCurrency);\r\n\r\n            const sortedSavings = Object.entries(savings).filter(([_, value]) => value > 1).sort((a, b) => b[1] - a[1]);\r\n            let reportHTML = `<div class=\"report-title\">Savings Breakdown<\/div>`;\r\n            const chartLabels = [], chartData = [], chartColors = [];\r\n            const sourceMap = { env: 'Dev\/Test Waste', autoscaling: 'Autoscaling', ri: 'Committed Use', usage: 'Rightsizing', ops: 'Operational Efficiency' };\r\n            const rankedColorPalette = ['#029E84', '#33A1F2', '#33E0C1', '#79C7F7', '#a29de0'];\r\n\r\n            sortedSavings.forEach(([key, value], index) => {\r\n                const color = rankedColorPalette[index % rankedColorPalette.length];\r\n                reportHTML += `<div class=\"report-item\"><span class=\"report-dot\" style=\"background-color: ${color};\"><\/span><span class=\"label\">${sourceMap[key]}<\/span><span class=\"value\">${formatCurrency(value, values.displayCurrency)}<\/span><\/div>`;\r\n                chartLabels.push(sourceMap[key]); chartData.push(value); chartColors.push(color);\r\n            });\r\n\r\n            if (totalSavings < 1) reportHTML += `<div class=\"report-item\"><span class=\"label\">Your setup is well-optimized!<\/span><\/div>`;\r\n            allOutputs.reportContainer.innerHTML = reportHTML;\r\n\r\n            savingsChart.data.labels = chartLabels;\r\n            savingsChart.data.datasets[0].data = chartData;\r\n            savingsChart.data.datasets[0].backgroundColor = chartColors;\r\n            savingsChart.options.plugins.chartCenterText.text = `${Math.round(savingsPercentage)}%`;\r\n            savingsChart.update();\r\n\r\n            lastCalculatedData = { values, baseMonthlySpend, totalSavings, optimizedSpend, savingsPercentage, sortedSavings };\r\n        };\r\n\r\n        \/\/ --- The generateAndDownloadPDF function and modal logic remain unchanged ---\r\n        \/\/ --- They are included here for completeness ---\r\n        const generateAndDownloadPDF = async () => {\r\n            const { jsPDF } = window.jspdf;\r\n            const doc = new jsPDF('p', 'pt');\r\n            const W = doc.internal.pageSize.getWidth();\r\n            const H = doc.internal.pageSize.getHeight();\r\n            const MARGIN = 40;\r\n            const CONTENT_WIDTH = W - MARGIN * 2;\r\n\r\n            const { values, baseMonthlySpend, totalSavings, optimizedSpend, savingsPercentage, sortedSavings } = lastCalculatedData;\r\n            const currency = values.displayCurrency;\r\n\r\n            \/\/ --- Fetch Comparison Data ---\r\n            loadingOverlay.classList.add('visible');\r\n            let comparisonData = null;\r\n            try {\r\n                const response = await fetch(`https:\/\/kansoft.ch\/wp-json\/calculator\/v1\/compare-prices`, {\r\n                    method: 'POST',\r\n                    headers: { 'Content-Type': 'application\/json' },\r\n                    body: JSON.stringify({\r\n                        provider: values.provider,\r\n                        instance: values.instanceType,\r\n                        region: values.region,\r\n                        os: values.os\r\n                    })\r\n                });\r\n                if (response.ok) {\r\n                    comparisonData = await response.json();\r\n                } else {\r\n                    console.error(\"Comparison API failed:\", await response.text());\r\n                }\r\n            } catch (e) {\r\n                console.error(\"Failed to fetch comparison data:\", e);\r\n            } finally {\r\n                loadingOverlay.classList.remove('visible');\r\n            }\r\n\r\n            \/\/ --- PDF Styling & Helpers ---\r\n            const THEME = { PRIMARY: '#0A004F', ACCENT: '#029E84', TEXT_DARK: '#1d2433', TEXT_LIGHT: '#FFFFFF', TEXT_MUTED: '#5a6271', BORDER: '#e1e4e6', BEST_VALUE_BG: '#E6F6F4', BEST_VALUE_TEXT: '#028a73', BAR_BG: '#F0F2F5', CURRENT_PROVIDER_COLOR: '#F38181' };\r\n            const FONT = 'helvetica';\r\n            const logoUrl = 'https:\/\/kansoft.ch\/wp-content\/uploads\/2024\/11\/Vector-4.png';\r\n            const formatLocalCurrency = (value) => formatCurrency(value, currency);\r\n\r\n            const drawHeader = (docInstance) => {\r\n                docInstance.addImage(logoUrl, 'PNG', MARGIN, 35, 120, 20, 'logo', 'NONE', 0);\r\n                docInstance.link(MARGIN, 35, 120, 20, { url: 'https:\/\/kansoft.ch' });\r\n                docInstance.setFont(FONT, 'normal'); docInstance.setFontSize(10); docInstance.setTextColor(THEME.TEXT_MUTED);\r\n                docInstance.text('Cloud Savings Analysis Report', W - MARGIN, 45, { align: 'right' });\r\n                docInstance.setDrawColor(THEME.BORDER); docInstance.setLineWidth(0.5);\r\n                docInstance.line(MARGIN, 60, W - MARGIN, 60);\r\n            };\r\n            const drawFooter = (docInstance, pageNum, totalPages) => {\r\n                docInstance.setFont(FONT, 'normal'); docInstance.setFontSize(9); docInstance.setTextColor(THEME.TEXT_MUTED);\r\n                docInstance.text(`\\u00A9 ${new Date().getFullYear()} Kansoft Schweiz GmbH`, MARGIN, H - 30);\r\n                docInstance.text(`Page ${pageNum} of ${totalPages}`, W - MARGIN, H - 30, { align: 'right' });\r\n            };\r\n            const drawKPICard = (docInstance, x, y, width, height, title, value) => {\r\n                docInstance.setFillColor('#F8F9FA'); docInstance.setDrawColor(THEME.BORDER);\r\n                docInstance.roundedRect(x, y, width, height, 5, 5, 'FD');\r\n                docInstance.setFontSize(9); docInstance.setTextColor(THEME.PRIMARY); docInstance.setFont(FONT, 'bold');\r\n                docInstance.text(title.toUpperCase(), x + 15, y + 20);\r\n                docInstance.setFontSize(22); docInstance.setFont(FONT, 'bold'); docInstance.setTextColor(THEME.TEXT_DARK);\r\n                docInstance.text(value, x + 15, y + 50);\r\n            };\r\n\r\n            \/\/ --- Page 1: Title Page ---\r\n            let yPos = H \/ 2 - 80;\r\n            doc.setFont(FONT, 'bold'); doc.setFontSize(36); doc.setTextColor(THEME.PRIMARY);\r\n            doc.text(\"Cloud Savings &\", W \/ 2, yPos, { align: 'center' });\r\n            doc.text(\"Comparison Report\", W \/ 2, yPos + 45, { align: 'center' });\r\n            doc.setDrawColor(THEME.ACCENT); doc.setLineWidth(2);\r\n            doc.line(W \/ 2 - 100, yPos + 70, W \/ 2 + 100, yPos + 70);\r\n            doc.setFont(FONT, 'normal'); doc.setFontSize(12); doc.setTextColor(THEME.TEXT_MUTED);\r\n            const reportDate = new Date().toLocaleDateString('en-US', { year: 'numeric', month: 'long', day: 'numeric' });\r\n            doc.text(`Generated on: ${reportDate}`, W \/ 2, yPos + 100, { align: 'center' });\r\n\r\n            const addPageIfNeeded = (currentY, elementHeight) => {\r\n                if (currentY + elementHeight > H - MARGIN * 2) {\r\n                    doc.addPage();\r\n                    return 100; \/\/ Reset yPos for new page\r\n                }\r\n                return currentY;\r\n            };\r\n\r\n            \/\/ --- Page 2: Executive Summary & Analysis ---\r\n            doc.addPage();\r\n            yPos = 100;\r\n            doc.setFont(FONT, 'bold'); doc.setFontSize(18); doc.setTextColor(THEME.PRIMARY);\r\n            doc.text(\"1. Executive Summary\", MARGIN, yPos);\r\n            yPos += 25;\r\n            const introTextString = `This analysis is based on your current configuration of ${values.numInstances} instance(s) on ${values.provider}. Our assessment indicates a significant potential for cost reduction.`;\r\n            doc.setFont(FONT, 'normal'); doc.setFontSize(11); doc.setTextColor(THEME.TEXT_DARK);\r\n            doc.text(introTextString, MARGIN, yPos, { maxWidth: CONTENT_WIDTH, lineHeightFactor: 1.5 });\r\n            yPos += doc.getTextDimensions(introTextString, { maxWidth: CONTENT_WIDTH, lineHeightFactor: 1.5 }).h + 20;\r\n\r\n            const cardWidth = (CONTENT_WIDTH - 20) \/ 2; const cardHeight = 70;\r\n            drawKPICard(doc, MARGIN, yPos, cardWidth, cardHeight, 'Potential Monthly Savings', formatLocalCurrency(totalSavings));\r\n            drawKPICard(doc, MARGIN + cardWidth + 20, yPos, cardWidth, cardHeight, 'Potential Annual Savings', formatLocalCurrency(totalSavings * 12));\r\n            yPos += cardHeight + 15;\r\n            drawKPICard(doc, MARGIN, yPos, cardWidth, cardHeight, 'Optimized Monthly Spend', formatLocalCurrency(optimizedSpend));\r\n            drawKPICard(doc, MARGIN + cardWidth + 20, yPos, cardWidth, cardHeight, 'Overall Savings Percentage', `${Math.round(savingsPercentage)}%`);\r\n            yPos += cardHeight + 30;\r\n\r\n            doc.setFont(FONT, 'bold'); doc.setFontSize(18); doc.setTextColor(THEME.PRIMARY);\r\n            doc.text(\"2. Your Input Parameters\", MARGIN, yPos);\r\n            yPos += 25;\r\n            const autoTableStyles = { headStyles: { fillColor: THEME.PRIMARY, textColor: THEME.TEXT_LIGHT, fontStyle: 'bold' }, styles: { font: FONT, fontSize: 10 }, alternateRowStyles: { fillColor: '#F8F9FA' } };\r\n            doc.setFontSize(14); doc.setTextColor(THEME.PRIMARY);\r\n\r\n            const envName = values.env === 'Dev' ? 'Development' : 'Production';\r\n            const inputData = [\r\n                ['Number of Instances', values.numInstances],\r\n                ['Cloud Provider', values.provider],\r\n                ['Instance Type', values.instanceType],\r\n                ['Region', values.region],\r\n                ['Environment Type', envName],\r\n                ['Average Usage', `${values.avgUsage}%`],\r\n                ['Autoscaling Enabled', values.autoscaling],\r\n                ['Committed Use', values.ri],\r\n            ];\r\n            doc.autoTable({ startY: yPos + 15, head: [['Parameter', 'Your Input']], body: inputData, theme: 'grid', ...autoTableStyles });\r\n            yPos = doc.autoTable.previous.finalY + 30;\r\n\r\n            \/\/ --- Page 3: Cross-Cloud Comparison ---\r\n            if (comparisonData && comparisonData.prices) {\r\n                doc.addPage();\r\n                yPos = 100;\r\n                doc.setFont(FONT, 'bold'); doc.setFontSize(18); doc.setTextColor(THEME.PRIMARY);\r\n                doc.text(\"3. Cross-Cloud Cost Comparison\", MARGIN, yPos);\r\n                yPos += 25;\r\n                const comparisonText = `The following provides an estimated monthly cost for running a comparable virtual machine configuration across the three major cloud providers. Prices are based on On-Demand rates in their respective primary European regions.`;\r\n                doc.setFont(FONT, 'normal'); doc.setFontSize(11); doc.setTextColor(THEME.TEXT_DARK);\r\n                doc.text(comparisonText, MARGIN, yPos, { maxWidth: CONTENT_WIDTH, lineHeightFactor: 1.5 });\r\n                yPos += doc.getTextDimensions(comparisonText, { maxWidth: CONTENT_WIDTH, lineHeightFactor: 1.5 }).h + 30;\r\n\r\n                const hoursInMonth = 730;\r\n                const conversionRate = currencyRates[currency] || 1;\r\n\r\n                let results = [];\r\n                ['aws', 'gcp', 'azure'].forEach(p => {\r\n                    const price = comparisonData.prices[p];\r\n                    if (price) {\r\n                        results.push({\r\n                            provider: p.toUpperCase(),\r\n                            name: comparisonData.equivalents[p].name,\r\n                            cost: price * hoursInMonth * values.numInstances * conversionRate\r\n                        });\r\n                    }\r\n                });\r\n\r\n                const currentProvider = values.provider;\r\n                const userProvider = results.find(r => r.provider === currentProvider);\r\n                const otherProviders = results.filter(r => r.provider !== currentProvider).sort((a, b) => a.cost - b.cost);\r\n                results = [userProvider, ...otherProviders].filter(Boolean);\r\n                const bestValue = [...results].sort((a, b) => a.cost - b.cost)[0];\r\n\r\n                const chartX = MARGIN + 80;\r\n                const chartY = yPos;\r\n                const chartWidth = CONTENT_WIDTH - 80;\r\n                const barHeight = 25;\r\n                const barSpacing = 15;\r\n                const maxCost = results.reduce((max, r) => Math.max(max, r.cost), 0);\r\n                const legendItems = [];\r\n\r\n                if (userProvider && userProvider.provider === bestValue.provider) {\r\n                    legendItems.push({ label: 'Your Current & Best Value Provider', color: THEME.ACCENT });\r\n                    legendItems.push({ label: 'Other Providers', color: THEME.PRIMARY });\r\n                } else {\r\n                    legendItems.push({ label: 'Your Current Provider', color: THEME.CURRENT_PROVIDER_COLOR });\r\n                    legendItems.push({ label: 'Best Value Provider', color: THEME.ACCENT });\r\n                    legendItems.push({ label: 'Other Providers', color: THEME.PRIMARY });\r\n                }\r\n\r\n                doc.setFont(FONT, 'normal');\r\n                doc.setFontSize(10);\r\n                results.forEach((res, index) => {\r\n                    const barY = chartY + index * (barHeight + barSpacing);\r\n                    const barWidth = (res.cost \/ maxCost) * (chartWidth - 80);\r\n                    doc.setTextColor(THEME.TEXT_DARK);\r\n                    doc.text(res.provider, chartX - 5, barY + barHeight \/ 2 + 3, { align: 'right' });\r\n                    doc.setFillColor(THEME.BAR_BG);\r\n                    doc.roundedRect(chartX, barY, chartWidth, barHeight, 3, 3, 'F');\r\n                    const barColor = res.provider === bestValue.provider ? THEME.ACCENT : (res.provider === currentProvider ? THEME.CURRENT_PROVIDER_COLOR : THEME.PRIMARY);\r\n                    doc.setFillColor(barColor);\r\n                    doc.roundedRect(chartX, barY, barWidth, barHeight, 3, 3, 'F');\r\n                    doc.setTextColor(THEME.TEXT_LIGHT);\r\n                    doc.setFont(FONT, 'bold');\r\n                    doc.text(formatLocalCurrency(res.cost), chartX + barWidth - 5, barY + barHeight \/ 2 + 3, { align: 'right' });\r\n                    doc.setFont(FONT, 'normal');\r\n                });\r\n                yPos += results.length * (barHeight + barSpacing) + 30;\r\n\r\n                doc.setFont(FONT, 'bold');\r\n                doc.setFontSize(12);\r\n                doc.setTextColor(THEME.TEXT_DARK);\r\n                yPos += 15;\r\n\r\n                const legendBoxSize = 10;\r\n                let legendX = MARGIN;\r\n                const spacing = 20;\r\n\r\n                legendItems.forEach((item, index) => {\r\n                    doc.setFillColor(item.color);\r\n                    doc.setDrawColor(item.color);\r\n                    doc.roundedRect(legendX, yPos, legendBoxSize, legendBoxSize, 2, 2, 'F');\r\n                    doc.setFont(FONT, 'normal');\r\n                    doc.setFontSize(10);\r\n                    doc.setTextColor(THEME.TEXT_DARK);\r\n                    doc.text(item.label, legendX + legendBoxSize + 10, yPos + legendBoxSize \/ 2 + 3);\r\n                    const itemWidth = doc.getTextDimensions(item.label).w + legendBoxSize + spacing;\r\n                    legendX += itemWidth + 10;\r\n                });\r\n                yPos += 30;\r\n                const comparisonTableBody = [];\r\n                results.forEach((res, index) => {\r\n                    let providerCell = res.provider;\r\n                    if (res.provider === currentProvider && res.provider === bestValue.provider) {\r\n                        providerCell = `${res.provider} (Your Current Provider & Best Value!)`;\r\n                    } else if (res.provider === currentProvider) {\r\n                        providerCell = `${res.provider} (Your Current Provider)`;\r\n                    } else if (res.provider === bestValue.provider) {\r\n                        providerCell = `${res.provider} (Best Value)`;\r\n                    }\r\n                    comparisonTableBody.push([providerCell, res.name, formatLocalCurrency(res.cost)]);\r\n                });\r\n                doc.autoTable({\r\n                    startY: yPos,\r\n                    head: [['Provider', 'Equivalent Instance', `Estimated Monthly Cost (${currency})`]],\r\n                    body: comparisonTableBody,\r\n                    theme: 'grid', ...autoTableStyles,\r\n                    didDrawCell: (data) => {\r\n                        if (data.row.raw[0].includes('Best Value')) {\r\n                            data.cell.styles.fillColor = THEME.BEST_VALUE_BG;\r\n                            data.cell.styles.textColor = THEME.BEST_VALUE_TEXT;\r\n                            data.cell.styles.fontStyle = 'bold';\r\n                        }\r\n                    }\r\n                });\r\n                yPos = doc.autoTable.previous.finalY + 30;\r\n\r\n                doc.setFont(FONT, 'bold'); doc.setFontSize(14); doc.setTextColor(THEME.PRIMARY);\r\n                doc.text(\"3.1 Key Takeaways\", MARGIN, yPos);\r\n                yPos += 20;\r\n                doc.setFont(FONT, 'normal'); doc.setFontSize(11); doc.setTextColor(THEME.TEXT_DARK);\r\n\r\n                if (userProvider && userProvider.provider === bestValue.provider) {\r\n                    const bestValueText = `- Your current provider, ${userProvider.provider}, is already the most cost-effective option for this instance type and region. By focusing on other FinOps strategies like rightsizing and committed use, you can further enhance your savings.`;\r\n                    doc.text(bestValueText, MARGIN + 10, yPos, { maxWidth: CONTENT_WIDTH - 20, lineHeightFactor: 1.5 });\r\n                    yPos += doc.getTextDimensions(bestValueText, { maxWidth: CONTENT_WIDTH - 20, lineHeightFactor: 1.5 }).h + 10;\r\n                } else if (userProvider) {\r\n                    doc.text(`- Based on this specific configuration, ${bestValue.provider} offers the most competitive pricing.`, MARGIN + 10, yPos, { maxWidth: CONTENT_WIDTH - 20, lineHeightFactor: 1.5 });\r\n                    yPos += 30;\r\n                    const nextBestText = `- By choosing ${bestValue.provider} over your current provider (${userProvider.provider}), you could save approximately ${formatLocalCurrency(userProvider.cost - bestValue.cost)} per month.`;\r\n                    doc.text(nextBestText, MARGIN + 10, yPos, { maxWidth: CONTENT_WIDTH - 20, lineHeightFactor: 1.5 });\r\n                    yPos += doc.getTextDimensions(nextBestText, { maxWidth: CONTENT_WIDTH - 20, lineHeightFactor: 1.5 }).h + 10;\r\n                }\r\n\r\n                doc.text(\"- These prices are for On-Demand instances. Significant further savings can be achieved with committed use discounts, which Kansoft can help you optimize.\", MARGIN + 10, yPos, { maxWidth: CONTENT_WIDTH - 20, lineHeightFactor: 1.5 });\r\n            }\r\n\r\n            \/\/ --- Page 4: Methodology ---\r\n            doc.addPage();\r\n            yPos = 100;\r\n            doc.setFont(FONT, 'bold'); doc.setFontSize(18); doc.setTextColor(THEME.PRIMARY);\r\n            doc.text(\"4. Methodology\", MARGIN, yPos);\r\n            yPos += 25;\r\n            doc.setFont(FONT, 'normal'); doc.setFontSize(11); doc.setTextColor(THEME.TEXT_DARK);\r\n            const methodologyContent = [\r\n                { title: \"Pricing Data\", text: \"All instance prices are fetched in real-time from the official public pricing APIs of AWS, Google Cloud, and Microsoft Azure. Prices are for On-Demand, Linux-based virtual machines in the specified regions.\" },\r\n                { title: \"Currency Conversion\", text: \"USD prices are converted to the selected display currency using live exchange rates from the Frankfurter.app API, cached for 12 hours.\" },\r\n                { title: \"Savings Calculations\", text: \"Savings are estimated based on industry-standard FinOps practices. For example, 'Dev\/Test Waste' assumes resources are only needed 65% of the time, while 'Rightsizing' calculates potential savings from reducing underutilization below a 50% threshold.\" }\r\n            ];\r\n            methodologyContent.forEach(point => {\r\n                yPos = addPageIfNeeded(yPos, 50);\r\n                doc.setFont(FONT, 'bold');\r\n                doc.text(`\u2022 ${point.title}`, MARGIN, yPos);\r\n                yPos += 15;\r\n                doc.setFont(FONT, 'normal');\r\n                const textDimensions = doc.getTextDimensions(point.text, { maxWidth: CONTENT_WIDTH - 25, lineHeightFactor: 1.5 });\r\n                doc.text(point.text, MARGIN + 10, yPos, { maxWidth: CONTENT_WIDTH - 25, lineHeightFactor: 1.5 });\r\n                yPos += textDimensions.h + 15;\r\n            });\r\n            yPos = addPageIfNeeded(yPos, 50);\r\n            doc.setFont(FONT, 'normal'); doc.setFontSize(11); doc.setTextColor(THEME.TEXT_DARK);\r\n            const finalSentence = \"This report is intended for directional guidance to highlight key areas for a deeper, personalized FinOps audit.\";\r\n            doc.text(finalSentence, MARGIN, yPos, { maxWidth: CONTENT_WIDTH, lineHeightFactor: 1.5 });\r\n            yPos += doc.getTextDimensions(finalSentence, { maxWidth: CONTENT_WIDTH, lineHeightFactor: 1.5 }).h + 30;\r\n\r\n            yPos = addPageIfNeeded(yPos, 200);\r\n            doc.setFont(FONT, 'bold'); doc.setFontSize(18); doc.setTextColor(THEME.PRIMARY);\r\n            yPos += 40;\r\n            doc.text(\"5. Our Analysis Methodology\", MARGIN, yPos);\r\n            yPos += 25;\r\n            doc.setFont(FONT, 'normal'); doc.setFontSize(11); doc.setTextColor(THEME.TEXT_DARK);\r\n            const methodologyPoints = [\r\n                { title: \"How the Benchmark is Determined\", text: \"Our benchmark is derived from Swiss SaaS-specific industry reports, normalized cloud cost-to-revenue ratios (typically 8-12%), and our internal anonymized data from similar Swiss SaaS firms.\" },\r\n                { title: \"What is Kansoft\u2019s Role?\", text: \"Kansoft provides a comprehensive FinOps audit for transparency, tools to visualize cloud economics, and execution support to implement optimizations. We enable informed decisions, not make inflated promises.\" },\r\n                { title: \"What Factors Are Considered?\", text: \"This calculator considers real variables like cloud provider, environment type, and usage patterns. The tool gives directional insight by highlighting which parts of your spend are likely fixed vs. optimizable.\" },\r\n                { title: \"How We Build Trust\", text: \"We emphasize a privacy-first approach, use neutral language, and offer a no-pressure call to action. Our goal is to empower you with data, showing an indicative gap between your spend and a benchmark for firms with a similar profile.\" }\r\n            ];\r\n            methodologyPoints.forEach(point => {\r\n                doc.setFont(FONT, 'bold');\r\n                doc.text(`\u2022 ${point.title}`, MARGIN + 10, yPos);\r\n                yPos += 15;\r\n                doc.setFont(FONT, 'normal');\r\n                const textDimensions = doc.getTextDimensions(point.text, { maxWidth: CONTENT_WIDTH - 35, lineHeightFactor: 1.5 });\r\n                doc.text(point.text, MARGIN + 25, yPos, { maxWidth: CONTENT_WIDTH - 35, lineHeightFactor: 1.5 });\r\n                yPos += textDimensions.h + 15;\r\n                yPos = addPageIfNeeded(yPos, 50);\r\n            });\r\n\r\n            \/\/ --- Final Pages & Save ---\r\n            doc.addPage();\r\n            let ctaYpos = H \/ 2 - 80;\r\n            doc.setFontSize(22); doc.setFont(FONT, 'bold'); doc.setTextColor(THEME.PRIMARY);\r\n            doc.text(\"Ready to Realize These Savings?\", W \/ 2, ctaYpos, { align: 'center' });\r\n            ctaYpos += 40;\r\n            doc.setFontSize(12); doc.setFont(FONT, 'normal'); doc.setTextColor(THEME.TEXT_DARK);\r\n            const ctaText = \"Let's schedule a call to discuss how Kansoft can help you implement these changes and unlock significant savings for your business.\";\r\n            const ctaTextDim = doc.getTextDimensions(ctaText, { maxWidth: CONTENT_WIDTH - 120, align: 'center', lineHeightFactor: 1.5 });\r\n            doc.text(ctaText, W \/ 2, ctaYpos, { maxWidth: CONTENT_WIDTH - 120, align: 'center', lineHeightFactor: 1.5 });\r\n            ctaYpos += ctaTextDim.h + 50;\r\n            doc.setFillColor(THEME.ACCENT);\r\n            doc.roundedRect(W \/ 2 - 110, ctaYpos, 220, 45, 22.5, 22.5, 'F');\r\n            doc.setFontSize(14); doc.setFont(FONT, 'bold'); doc.setTextColor(THEME.TEXT_LIGHT);\r\n            doc.textWithLink(\"Schedule a Discovery Call\", W \/ 2, ctaYpos + 28, { align: 'center', url: 'https:\/\/meetings-na2.hubspot.com\/amol-dhakne\/30-min-discovery-call?uuid=533e40fc-f883-4251-bde5-e678893b6a18' });\r\n\r\n            const pageCount = doc.internal.getNumberOfPages();\r\n            for (let i = 1; i <= pageCount; i++) {\r\n                doc.setPage(i);\r\n                drawHeader(doc);\r\n                drawFooter(doc, i, pageCount);\r\n                doc.setDrawColor(THEME.ACCENT);\r\n                doc.setLineWidth(12);\r\n                doc.line(0, 0, 0, H);\r\n            }\r\n\r\n            return doc.output('blob');\r\n        };\r\n\r\n        let hubspotData = { email: '', firstname: '' };\r\n        \/\/ Find this part of your script...\r\n        modalElements.triggerBtn.addEventListener('click', () => {\r\n            modalElements.overlay.classList.remove('modal-hidden');\r\n            const formContainer = document.getElementById('hubspot-report-form-container');\r\n\r\n\r\n            if (formContainer && !formContainer.hasChildNodes()) {\r\n                hbspt.forms.create({\r\n                    portalId: \"47003847\",\r\n                    formId: \"5a955ffc-908c-4824-aa94-45e60e235e0c\",\r\n                    region: \"na1\",\r\n                    target: '#hubspot-report-form-container',\r\n\r\n                    \/\/ Add this onFormReady function for translations\r\n                    onFormReady: ($form) => {\r\n                        const isGerman = window.location.pathname.includes('\/de');\r\n                        if (!isGerman) return;\r\n\r\n                        const formElement = $form[0];\r\n\r\n                        \/\/ Define German translations\r\n                        const translations = {\r\n                            firstname: 'Vorname',\r\n                            lastname: 'Nachname',\r\n                            email: 'E-Mail',\r\n                            button: 'Vollst\u00e4ndigen Bericht herunterladen'\r\n                        };\r\n\r\n                        \/\/ Translate button\r\n                        const submitButton = formElement.querySelector('input.hs-button');\r\n                        if (submitButton) {\r\n                            submitButton.value = translations.button;\r\n                        }\r\n\r\n                        \/\/ Translate labels\r\n                        ['firstname', 'lastname', 'email'].forEach(fieldName => {\r\n                            const input = formElement.querySelector(`input[name=\"${fieldName}\"]`);\r\n                            if (input) {\r\n                                const label = formElement.querySelector(`label[for=\"${input.id}\"]`);\r\n                                if (label && label.querySelector('span')) {\r\n                                    label.querySelector('span').textContent = translations[fieldName];\r\n                                }\r\n                            }\r\n                        });\r\n                    },\r\n\r\n                    \/\/ Your existing onFormSubmit and onFormSubmitted functions remain unchanged\r\n                    onFormSubmit: ($form) => {\r\n                        hubspotData.email = $form.find('input[name=\"email\"]').val();\r\n                        hubspotData.firstname = $form.find('input[name=\"firstname\"]').val();\r\n                    },\r\n\r\n                    \/\/ Updated Part 2: Use the captured data for processing\r\n                    onFormSubmitted: async () => { \/\/ Removed $form from here as it's unreliable\r\n                        const formWrapper = document.getElementById('form-wrapper');\r\n\r\n                        \/\/ 1. Immediately show your custom loader\r\n                        formWrapper.innerHTML = `\r\n                <div class=\"form-loader-container\">\r\n                    <div class=\"spinner\"><\/div>\r\n                <\/div>`;\r\n\r\n                        try {\r\n                            \/\/ 2. Use the data from the 'hubspotData' variable\r\n                            if (!hubspotData.email) {\r\n                                throw new Error(\"Could not retrieve email from form.\");\r\n                            }\r\n\r\n                            const pdfBlob = await generateAndDownloadPDF();\r\n\r\n                            const formData = new FormData();\r\n                            formData.append('report_pdf', pdfBlob, 'cloud-report.pdf');\r\n                            formData.append('email', hubspotData.email);\r\n                            formData.append('firstname', hubspotData.firstname);\r\n                            formData.append('calculator_id', 'cloud_spend');\r\n\r\n                            const response = await fetch('\/wp-json\/calculator\/v1\/upload-and-email-report', {\r\n                                method: 'POST',\r\n                                body: formData\r\n                            });\r\n\r\n                            if (!response.ok) {\r\n                                const result = await response.json();\r\n                                throw new Error(result.message || 'An error occurred on the server.');\r\n                            }\r\n\r\n                            \/\/ 3. On success, show your custom success message\r\n                            formWrapper.innerHTML = `<p style=\"text-align:center; color: var(--c-text-muted); min-height: 250px; display: flex; align-items: center; justify-content: center;\"><br>Success! Your personalized report has been sent to your email.<\/p>`;\r\n\r\n                            \/\/ 4. Close the modal after a delay\r\n                            setTimeout(() => {\r\n                                closeModal();\r\n                                \/\/ Reset the form container for the next time the modal is opened\r\n                                setTimeout(() => {\r\n                                    formWrapper.innerHTML = '<div class=\"hubspot-no-global-style\"><div id=\"hubspot-report-form-container\"><\/div><\/div>';\r\n                                }, 500);\r\n                            }, 4000);\r\n\r\n                        } catch (error) {\r\n                            console.error(\"Report Submission Error:\", error);\r\n                            \/\/ 5. On failure, show an error message\r\n                            formWrapper.innerHTML = `<p style=\"text-align:center; color: #d9534f; min-height: 250px; display: flex; align-items: center; justify-content: center;\"><br>Sorry, there was an error processing your report.<br>Please try again or contact us directly.<\/p>`;\r\n                        }\r\n                    }\r\n                });\r\n            }\r\n        });\r\n\r\n        const closeModal = () => modalElements.overlay.classList.add('modal-hidden');\r\n        modalElements.closeBtn.addEventListener('click', closeModal);\r\n        modalElements.overlay.addEventListener('click', (e) => {\r\n            if (e.target === modalElements.overlay) closeModal();\r\n        });\r\n\r\n        allInputs.cloudProvider.addEventListener('change', () => {\r\n            toggleProviderFields();\r\n            calculateAndRender();\r\n        });\r\n\r\n        \/\/form.addEventListener('input', calculateAndRender);\r\n        form.addEventListener('input', debounce(calculateAndRender));\r\n\r\n        const initializeCalculator = async () => {\r\n            await getCurrencyRates();\r\n            toggleProviderFields();\r\n            calculateAndRender();\r\n        };\r\n\r\n        initializeCalculator();\r\n    });\r\n<\/script>\t\t\t\t<\/div>\n\t\t\t\t<\/div>\n\t\t\t\t<\/div>\n\t\t<div class=\"elementor-element elementor-element-4760cba e-flex e-con-boxed e-con e-parent\" data-id=\"4760cba\" data-element_type=\"container\" data-e-type=\"container\" data-settings=\"{&quot;background_background&quot;:&quot;gradient&quot;}\">\n\t\t\t\t\t<div class=\"e-con-inner\">\n\t\t<div class=\"elementor-element elementor-element-e94309b e-con-full e-flex e-con e-child\" data-id=\"e94309b\" data-element_type=\"container\" data-e-type=\"container\">\n\t\t\t\t<div class=\"elementor-element elementor-element-385d642 elementor-widget__width-initial elementor-widget elementor-widget-heading\" data-id=\"385d642\" data-element_type=\"widget\" data-e-type=\"widget\" data-widget_type=\"heading.default\">\n\t\t\t\t<div class=\"elementor-widget-container\">\n\t\t\t\t\t<h4 class=\"elementor-heading-title elementor-size-default\">Plan Your Cloud Strategy with <span style=\"color:#0A004F\"> Local Experts<\/span><\/h4>\t\t\t\t<\/div>\n\t\t\t\t<\/div>\n\t\t\t\t<div class=\"elementor-element elementor-element-da09ebe elementor-widget elementor-widget-text-editor\" data-id=\"da09ebe\" data-element_type=\"widget\" data-e-type=\"widget\" data-widget_type=\"text-editor.default\">\n\t\t\t\t<div class=\"elementor-widget-container\">\n\t\t\t\t\t\t\t\t\t<p><span data-teams=\"true\">Discover cost, compliance, and performance insights tailored for your businesses.<\/span><\/p>\t\t\t\t\t\t\t\t<\/div>\n\t\t\t\t<\/div>\n\t\t\t\t<\/div>\n\t\t<div class=\"elementor-element elementor-element-89eb1e5 e-con-full e-flex e-con e-child\" data-id=\"89eb1e5\" data-element_type=\"container\" data-e-type=\"container\">\n\t\t\t\t<div class=\"elementor-element elementor-element-a7383ff elementor-widget__width-initial openModalBtn3 elementor-align-right elementor-mobile-align-center elementor-widget elementor-widget-button\" data-id=\"a7383ff\" data-element_type=\"widget\" data-e-type=\"widget\" data-widget_type=\"button.default\">\n\t\t\t\t<div class=\"elementor-widget-container\">\n\t\t\t\t\t\t\t\t\t<div class=\"elementor-button-wrapper\">\n\t\t\t\t\t<a class=\"elementor-button elementor-button-link elementor-size-sm\" href=\"#\">\n\t\t\t\t\t\t<span class=\"elementor-button-content-wrapper\">\n\t\t\t\t\t\t\t\t\t<span class=\"elementor-button-text\">Book A Strategy Call<\/span>\n\t\t\t\t\t<\/span>\n\t\t\t\t\t<\/a>\n\t\t\t\t<\/div>\n\t\t\t\t\t\t\t\t<\/div>\n\t\t\t\t<\/div>\n\t\t\t\t<\/div>\n\t\t\t\t\t<\/div>\n\t\t\t\t<\/div>\n\t\t<div class=\"elementor-element elementor-element-2f7a3db e-flex e-con-boxed e-con e-parent\" data-id=\"2f7a3db\" data-element_type=\"container\" data-e-type=\"container\" data-settings=\"{&quot;background_background&quot;:&quot;gradient&quot;}\">\n\t\t\t\t\t<div class=\"e-con-inner\">\n\t\t<div class=\"elementor-element elementor-element-e80b7d2 e-con-full e-flex e-con e-child\" data-id=\"e80b7d2\" data-element_type=\"container\" data-e-type=\"container\">\n\t\t\t\t<div class=\"elementor-element elementor-element-2b92879 elementor-widget elementor-widget-text-editor\" data-id=\"2b92879\" data-element_type=\"widget\" data-e-type=\"widget\" data-widget_type=\"text-editor.default\">\n\t\t\t\t<div class=\"elementor-widget-container\">\n\t\t\t\t\t\t\t\t\t<p>\u00a9 2025 Kansoft Schweiz GmbH. All Rights Reserved<\/p>\t\t\t\t\t\t\t\t<\/div>\n\t\t\t\t<\/div>\n\t\t\t\t<\/div>\n\t\t<div class=\"elementor-element elementor-element-0f4582c e-con-full e-flex e-con e-child\" data-id=\"0f4582c\" data-element_type=\"container\" data-e-type=\"container\">\n\t\t\t\t<div data-ep-wrapper-link=\"{&quot;url&quot;:&quot;https:\\\/\\\/www.linkedin.com\\\/showcase\\\/kansoft-solutions-europe\\\/&quot;,&quot;is_external&quot;:&quot;&quot;,&quot;nofollow&quot;:&quot;&quot;,&quot;custom_attributes&quot;:&quot;&quot;}\" style=\"cursor: pointer\" class=\"bdt-element-link elementor-element elementor-element-27b4569 elementor-widget elementor-widget-image\" data-id=\"27b4569\" data-element_type=\"widget\" data-e-type=\"widget\" data-widget_type=\"image.default\">\n\t\t\t\t<div class=\"elementor-widget-container\">\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t<img decoding=\"async\" width=\"96\" height=\"96\" src=\"https:\/\/i0.wp.com\/kansoft.ch\/wp-content\/uploads\/2025\/09\/in-2-1-1.png?fit=96%2C96&amp;ssl=1\" class=\"attachment-large size-large wp-image-25731\" alt=\"Linkedin Logo\" srcset=\"https:\/\/i0.wp.com\/kansoft.ch\/wp-content\/uploads\/2025\/09\/in-2-1-1.png?w=96&amp;ssl=1 96w, https:\/\/i0.wp.com\/kansoft.ch\/wp-content\/uploads\/2025\/09\/in-2-1-1.png?resize=12%2C12&amp;ssl=1 12w\" sizes=\"(max-width: 96px) 100vw, 96px\" \/>\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t<\/div>\n\t\t\t\t<\/div>\n\t\t\t\t<\/div>\n\t\t\t\t\t<\/div>\n\t\t\t\t<\/div>\n\t\t<div class=\"elementor-element elementor-element-0acce5a e-flex e-con-boxed e-con e-parent\" data-id=\"0acce5a\" data-element_type=\"container\" data-e-type=\"container\">\n\t\t\t\t\t<div class=\"e-con-inner\">\n\t\t\t\t<div class=\"elementor-element elementor-element-edc8ae0 elementor-widget elementor-widget-html\" data-id=\"edc8ae0\" data-element_type=\"widget\" data-e-type=\"widget\" data-widget_type=\"html.default\">\n\t\t\t\t<div class=\"elementor-widget-container\">\n\t\t\t\t\t<style>\r\n    footer#colophon {\r\n    display: none;\r\n}\r\n.ast-primary-header-bar{\r\n        background-color: #f2f5fe00;\r\n}\r\n.bdt-ep-static-carousel-readmore-wrap{\r\n    display: none;\r\n}\r\ndiv#landingherosection {\r\n    background-color: transparent;\r\n    background-image: url(https:\/\/kansoft.ch\/wp-content\/uploads\/2025\/07\/cloud-system-tablet-background-smart-technology-remixed-media.webp);\r\n    background-size: cover;\r\n    background-position: center;\r\n    background-repeat: no-repeat;\r\n    margin-top: 0px;\r\n}\r\nul#ast-hf-menu-1 {\r\n    display: none;\r\n}\r\nbutton#floatingbutton{\r\n    display: none;\r\n}\r\ndiv#landingflag {\r\n    text-align: end;\r\n}\r\n@media only screen and (max-width: 600px) {\r\n    .ast-primary-header-bar {\r\n        background: white!important;\r\n    }\r\nul#ast-hf-menu-1 {\r\n    display: block;\r\n}\r\nli.menu-item.menu-item-type-custom.menu-item-object-custom.menu-item-10974 {\r\n    display: block;\r\n}\r\nli.menu-item.menu-item-type-custom.menu-item-object-custom.menu-item-2084{\r\n    display: block;\r\n}\r\nli.menu-item.menu-item-type-custom.menu-item-object-custom.menu-item-has-children.menu-item-2085{\r\n    display: block;\r\n}\r\nli.menu-item.menu-item-type-custom.menu-item-object-custom.menu-item-2199{\r\n    display: none;\r\n}\r\nli.menu-item.menu-item-type-custom.menu-item-object-custom.menu-item-15505{\r\n    display: block;\r\n}\r\n}\r\n\r\n<\/style>\r\n<script>\r\n    const button = document.querySelector('.scheduleCallBtn3');\r\n    if (button) {\r\n        if (window.location.pathname.includes('\/de')) {\r\n            button.textContent = 'Kostenlose Beratung erhalten';\r\n        } else {\r\n            button.textContent = 'Get A Free Consultation';\r\n        }\r\n    }\r\n<\/script>\r\n\r\n<script>\r\n    document.addEventListener(\"DOMContentLoaded\", function () {\r\n  const logoLink = document.querySelector(\".site-logo-img a.custom-logo-link\");\r\n  if (logoLink) {\r\n    logoLink.setAttribute(\"href\", \"\/\");\r\n  }\r\n});\r\n\r\n<\/script>\r\n<script>\r\ndocument.addEventListener(\"DOMContentLoaded\", function () {\r\n  const headerButtonLink = document.querySelector(\r\n    '.ast-header-html .ast-builder-html-element a[href=\"https:\/\/kansoft.ch\/contact-us\/\"]'\r\n  );\r\n  if (headerButtonLink) {\r\n    headerButtonLink.setAttribute(\"href\", \"\/\");\r\n  }\r\n});\r\n\r\n<\/script>\r\n<script>\r\n    document.addEventListener(\"DOMContentLoaded\", function () {\r\n  const menuLink = document.querySelector('.menu-item-15505 a.menu-link[href=\"#\"]');\r\n  if (menuLink) {\r\n    menuLink.setAttribute(\"href\", \"#landingpageform\");\r\n  }\r\n});\r\n\r\n<\/script>\t\t\t\t<\/div>\n\t\t\t\t<\/div>\n\t\t\t\t\t<\/div>\n\t\t\t\t<\/div>\n\t\t<div class=\"elementor-element elementor-element-7ca09d1 e-flex e-con-boxed e-con e-parent\" data-id=\"7ca09d1\" data-element_type=\"container\" data-e-type=\"container\">\n\t\t\t\t\t<div class=\"e-con-inner\">\n\t\t\t\t<div class=\"elementor-element elementor-element-a68c238 elementor-widget elementor-widget-html\" data-id=\"a68c238\" data-element_type=\"widget\" data-e-type=\"widget\" data-widget_type=\"html.default\">\n\t\t\t\t<div class=\"elementor-widget-container\">\n\t\t\t\t\t<!-- Popup Modal -->\r\n<div id=\"consultationPopup\" class=\"popup-overlay\" style=\"display:none;\">\r\n  <div class=\"popup-content\">\r\n    <span class=\"close-popup\">&times;<\/span>\r\n    <iframe \r\n      src=\"https:\/\/meetings-na2.hubspot.com\/amol-dhakne\/30-min-discovery-call\" \r\n      width=\"100%\" \r\n      height=\"100%\" \r\n      style=\"border: none;\"\r\n      allowtransparency=\"true\">\r\n    <\/iframe>\r\n  <\/div>\r\n<\/div>\r\n\r\n<style>\r\ndiv#consultationPopup {\r\n\r\n    position: fixed;\r\n    z-index: 999999999;\r\n    padding-top: 5px;\r\n    left: 0;\r\n    top: 0;\r\n    width: 100%;\r\n    height: 100%;\r\n    overflow: auto;\r\n    background-color: rgba(0, 0, 0, 0.4);\r\n}\r\n.popup-overlay {\r\n  position: fixed;\r\n  top: 0;\r\n  left: 0;\r\n  width: 100%;\r\n  height: 100%;\r\n  background: rgba(0,0,0,0.7);\r\n  z-index: 9999;\r\n  display: flex;\r\n  justify-content: center;\r\n  align-items: center;\r\n}\r\n\r\n.popup-content {\r\nbackground: white;\r\n    padding: 0;\r\n    border-radius: 8px;\r\n    max-width: 90%;\r\n    width: 80%;\r\n    height: 100%;\r\n    position: relative;\r\n    box-shadow: 0 4px 20px rgba(0, 0, 0, 0.2);\r\n}\r\n\r\n.close-popup {\r\n  position: absolute;\r\n  top: 10px;\r\n  right: 15px;\r\n  font-size: 24px;\r\n  cursor: pointer;\r\n  z-index: 1;\r\n}\r\n<\/style>\r\n\r\n<script>\r\ndocument.querySelector('.scheduleCallBtn3').addEventListener('click', function(e) {\r\n  e.preventDefault();\r\n  document.getElementById('consultationPopup').style.display = 'flex';\r\n});\r\n\r\ndocument.querySelector('.close-popup').addEventListener('click', function() {\r\n  document.getElementById('consultationPopup').style.display = 'none';\r\n});\r\n<\/script>\r\n\t\t\t\t<\/div>\n\t\t\t\t<\/div>\n\t\t\t\t\t<\/div>\n\t\t\t\t<\/div>\n\t\t<div class=\"elementor-element elementor-element-d737d97 e-flex e-con-boxed e-con e-parent\" data-id=\"d737d97\" data-element_type=\"container\" data-e-type=\"container\">\n\t\t\t\t\t<div class=\"e-con-inner\">\n\t\t\t\t<div class=\"elementor-element elementor-element-5a96fcf elementor-widget elementor-widget-html\" data-id=\"5a96fcf\" data-element_type=\"widget\" data-e-type=\"widget\" data-widget_type=\"html.default\">\n\t\t\t\t<div class=\"elementor-widget-container\">\n\t\t\t\t\t<!-- Simple Popup Modal -->\r\n<div id=\"consultationModal\" class=\"consultation-overlay\">\r\n  <div class=\"consultation-box\">\r\n    <span id=\"closeConsultation\" class=\"consultation-close\">&times;<\/span>\r\n    <iframe \r\n      src=\"https:\/\/meetings-na2.hubspot.com\/amol-dhakne\/30-min-discovery-call\" \r\n      width=\"100%\" \r\n      height=\"600px\" \r\n      style=\"border:none; min-height: 580px;\">\r\n    <\/iframe>\r\n  <\/div>\r\n<\/div>\r\n\r\n\r\n\r\n\r\n<style>\r\n    \/* Overlay for the consultation modal *\/\r\n.consultation-overlay {\r\n  display: none;\r\n  position: fixed;\r\n  top: 0; left: 0;\r\n  width: 100%; height: 100%;\r\n  background: rgba(0, 0, 0, 0.6);\r\n  z-index: 9999999999;\r\n  justify-content: center;\r\n  align-items: center;\r\n  \r\n}\r\n\r\n\/* Modal content box *\/\r\n.consultation-box {\r\n  background: #f5f8fa;\r\n  padding: 0;\r\n  border-radius: 8px;\r\n  max-width: 800px;\r\n  width: 90%;\r\n  height: 90%;\r\n  position: relative;\r\n  box-shadow: 0 4px 20px rgba(0, 0, 0, 0.3);\r\n  padding-top: 30px;\r\n}\r\n\r\n\/* Close button *\/\r\n.consultation-close {\r\n     position: absolute;\r\n    top: -3%;\r\n    right: 8px;\r\n    font-size: 51px;\r\n    cursor: pointer;\r\n    z-index: 1;\r\n    color: black;\r\n}\r\n\r\n<\/style>\r\n\r\n      \r\n<script>\r\njQuery(document).ready(function ($) {\r\n  const $menuLink = $('.menu-item-15505 > a');\r\n\r\n  if ($menuLink.length) {\r\n    $menuLink.attr('href', '#');\r\n\r\n    $menuLink.on('click', function (e) {\r\n      e.preventDefault();\r\n      $('#consultationModal').css('display', 'flex');\r\n    });\r\n\r\n    $('#closeConsultation').on('click', function () {\r\n      $('#consultationModal').hide();\r\n    });\r\n\r\n    $('#consultationModal').on('click', function (e) {\r\n      if ($(e.target).is('#consultationModal')) {\r\n        $(this).hide();\r\n      }\r\n    });\r\n  } else {\r\n    console.warn('Consultation menu link not found.');\r\n  }\r\n});\r\n<\/script>\r\n\t\t\t\t<\/div>\n\t\t\t\t<\/div>\n\t\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>What Are You Really Spending on the Cloud? Your current cloud spend Number of Instances Cloud Provider Select Provider&#8230;Amazon Web [&hellip;]<\/p>\n","protected":false},"author":9,"featured_media":25062,"parent":0,"menu_order":0,"comment_status":"closed","ping_status":"closed","template":"","meta":{"content-type":"","site-sidebar-layout":"no-sidebar","site-content-layout":"page-builder","ast-site-content-layout":"full-width-container","site-content-style":"default","site-sidebar-style":"default","ast-global-header-display":"","ast-banner-title-visibility":"","ast-main-header-display":"","ast-hfb-above-header-display":"","ast-hfb-below-header-display":"","ast-hfb-mobile-header-display":"","site-post-title":"disabled","ast-breadcrumbs-content":"","ast-featured-img":"disabled","footer-sml-layout":"","theme-transparent-header-meta":"","adv-header-id-meta":"","stick-header-meta":"","header-above-stick-meta":"","header-main-stick-meta":"","header-below-stick-meta":"","astra-migrate-meta-layouts":"set","ast-page-background-enabled":"default","ast-page-background-meta":{"desktop":{"background-color":"var(--ast-global-color-4)","background-image":"","background-repeat":"repeat","background-position":"center center","background-size":"auto","background-attachment":"scroll","background-type":"","background-media":"","overlay-type":"","overlay-color":"","overlay-gradient":""},"tablet":{"background-color":"","background-image":"","background-repeat":"repeat","background-position":"center center","background-size":"auto","background-attachment":"scroll","background-type":"","background-media":"","overlay-type":"","overlay-color":"","overlay-gradient":""},"mobile":{"background-color":"","background-image":"","background-repeat":"repeat","background-position":"center center","background-size":"auto","background-attachment":"scroll","background-type":"","background-media":"","overlay-type":"","overlay-color":"","overlay-gradient":""}},"ast-content-background-meta":{"desktop":{"background-color":"var(--ast-global-color-5)","background-image":"","background-repeat":"repeat","background-position":"center center","background-size":"auto","background-attachment":"scroll","background-type":"","background-media":"","overlay-type":"","overlay-color":"","overlay-gradient":""},"tablet":{"background-color":"var(--ast-global-color-5)","background-image":"","background-repeat":"repeat","background-position":"center center","background-size":"auto","background-attachment":"scroll","background-type":"","background-media":"","overlay-type":"","overlay-color":"","overlay-gradient":""},"mobile":{"background-color":"var(--ast-global-color-5)","background-image":"","background-repeat":"repeat","background-position":"center center","background-size":"auto","background-attachment":"scroll","background-type":"","background-media":"","overlay-type":"","overlay-color":"","overlay-gradient":""}},"footnotes":""},"class_list":["post-24488","page","type-page","status-publish","has-post-thumbnail","hentry"],"jetpack_shortlink":"https:\/\/wp.me\/PguXna-6mY","_links":{"self":[{"href":"https:\/\/kansoft.ch\/de\/wp-json\/wp\/v2\/pages\/24488","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/kansoft.ch\/de\/wp-json\/wp\/v2\/pages"}],"about":[{"href":"https:\/\/kansoft.ch\/de\/wp-json\/wp\/v2\/types\/page"}],"author":[{"embeddable":true,"href":"https:\/\/kansoft.ch\/de\/wp-json\/wp\/v2\/users\/9"}],"replies":[{"embeddable":true,"href":"https:\/\/kansoft.ch\/de\/wp-json\/wp\/v2\/comments?post=24488"}],"version-history":[{"count":100,"href":"https:\/\/kansoft.ch\/de\/wp-json\/wp\/v2\/pages\/24488\/revisions"}],"predecessor-version":[{"id":27590,"href":"https:\/\/kansoft.ch\/de\/wp-json\/wp\/v2\/pages\/24488\/revisions\/27590"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/kansoft.ch\/de\/wp-json\/wp\/v2\/media\/25062"}],"wp:attachment":[{"href":"https:\/\/kansoft.ch\/de\/wp-json\/wp\/v2\/media?parent=24488"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}