@magicfeedback/popup-sdk 1.4.0 → 1.5.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.js CHANGED
@@ -185,7 +185,7 @@ var init_font = __esm({
185
185
  var style_default;
186
186
  var init_style = __esm({
187
187
  "src/assets/style.css"() {
188
- style_default = '.magicfeedback-container {\n width: 100%;\n}\n\n\n.magicfeedback-success-message,\n.magicfeedback-info-message,\n.magicfeedback-start-message,\n.magicfeedback-container{\n animation-duration: 0.5s;\n animation-name: animate-fade;\n animation-delay: 0.25s;\n animation-fill-mode: backwards;\n\n font-style: normal;\n text-align: justify;\n font-weight: 400;\n font-size: 1.2rem;\n color: #475569;\n line-height: 1.5;\n}\n\n@keyframes animate-fade {\n 0% { opacity: 0; }\n 100% { opacity: 1; }\n}\n\n.magicfeedback-form {\n display: flex;\n flex-direction: column;\n justify-content: flex-start;\n align-items: center;\n width: 100%;\n}\n.magicfeedback-questions {\n display: flex;\n flex-direction: column;\n justify-content: flex-start;\n align-items: flex-start;\n width: 100%;\n}\n\n.magicfeedback-div {\n display: flex;\n flex-direction: column;\n justify-content: flex-start;\n align-items: flex-start;\n margin-bottom: 10px;\n width: 100%;\n}\n\n.magicfeedback-label {\n margin-bottom: 25px;\n margin-top: 20px;\n font-weight: 400;\n font-family: inherit;\n font-size: 1.2rem;\n color: #212529;\n text-align: start;\n word-wrap: break-word;\n white-space: normal;\n\n}\n\n.magicfeedback-checkbox {\n display: flex;\n flex-direction: column;\n flex-wrap: wrap;\n width: 100%;\n}\n\n.magicfeedback-checkbox-container {\n display: flex;\n flex-direction: row;\n justify-content: flex-start;\n align-items: center;\n margin-bottom: 5px;\n margin-top: 5px;\n}\n\n/* Cualificado con `div`: @magicfeedback/native reutiliza la clase "magicfeedback-radio"\n tambi\xE9n en el <input> de cada opci\xF3n (rating), y sin el tag este selector lo capturaba\n tambi\xE9n, rompiendo su tama\xF1o (el input pasaba a display:flex; width:100%). */\ndiv.magicfeedback-radio {\n display: flex;\n flex-direction: column;\n justify-content: flex-start;\n flex-wrap: wrap;\n width: 100%;\n margin-right: 5px;\n padding: 5px;\n box-sizing: border-box;\n}\n\n.magicfeedback-checkbox-container,\n.magicfeedback-radio-container {\n display: flex;\n flex-direction: row;\n justify-content: flex-start;\n align-items: center;\n margin: 5px;\n padding: 5px 0;\n background-color: #fff;\n border-radius: 5px;\n box-shadow: 0 0 3px #ccc;\n}\n\n.deepdots-popup input::-webkit-outer-spin-button,\n.deepdots-popup input::-webkit-inner-spin-button {\n -webkit-appearance: none;\n -moz-appearance: textfield;\n}\n\n.magicfeedback-checkbox input[type="checkbox"] {\n margin-right: 5px;\n margin-left: 5px;\n width: 20px;\n height: 20px;\n cursor: pointer;\n}\n\n\n.magicfeedback-checkbox label,\n.magicfeedback-radio-container label {\n margin-left: 5px;\n font-weight: 400;\n font-family: inherit;\n font-size: 16px;\n color: #212529;\n text-align: start;\n width: 100%;\n}\n\n.deepdots-popup p {\n margin-bottom: 0px;\n font-size: 12px;\n}\n\n.deepdots-popup h2 {\n line-height: 1.66;\n margin: 0;\n padding: 0;\n font-weight: 900;\n color: #222;\n font-family: var(--deepdots-font, \'Montserrat\');\n font-size: 18px;\n text-transform: uppercase;\n text-align: center;\n margin-bottom: 40px;\n}\n\n/* Los controles de formulario no heredan font-family por defecto: cuando hay\n fuente custom (clase deepdots-has-font), los forzamos a usar la del contenedor. */\n.deepdots-popup.deepdots-has-font button,\n.deepdots-popup.deepdots-has-font input,\n.deepdots-popup.deepdots-has-font textarea,\n.deepdots-popup.deepdots-has-font select {\n font-family: var(--deepdots-font, inherit);\n}\n\n.deepdots-popup h6 {\n margin-bottom: 1rem;\n}\n\n.deepdots-popup input[type="date"],\n.deepdots-popup input[type="text"],\n.deepdots-popup input[type="number"],\n.deepdots-popup input[type="email"],\n.deepdots-popup input[type="password"],\n.deepdots-popup textarea,\n.deepdots-popup select {\n box-sizing: border-box;\n padding: 10px;\n margin: 10px 0;\n width: 100%;\n border: 2px solid #ccc; /* Default border color - you can customize this */\n border-radius: 5px;\n font-size: 18px;\n outline: none;\n transition: border-color 0.3s ease;\n min-height: 50px;\n font-family: inherit;\n -webkit-appearance: none;\n}\n\n.deepdots-popup select {\n background-image: linear-gradient(45deg, transparent 50%, gray 50%),\n linear-gradient(135deg, gray 50%, transparent 50%),\n linear-gradient(to right, #ccc, #ccc);\n background-position: calc(100% - 20px) calc(1em + 2px),\n calc(100% - 15px) calc(1em + 2px),\n calc(100% - 2.5em) 0.5em;\n background-size: 5px 5px,\n 5px 5px,\n 1px 1.5em;\n background-repeat: no-repeat;\n}\n\n.magicfeedback-boolean-container {\n display: flex;\n flex-direction: row;\n justify-content: flex-start;\n align-items: center;\n margin: 10px 0;\n width: 100%;\n}\n\n.magicfeedback-boolean-container label {\n margin-left: 10px;\n font-weight: 400;\n font-size: 16px;\n width: 100%;\n padding-top: 5px;\n}\n\n.magicfeedback-boolean-option {\n margin-right: 10px;\n margin-left: 10px;\n width: 100%;\n height: 38px;\n border-radius: 8px;\n font-size: 16px;\n cursor: pointer;\n border: 1px solid #ced4da !important;\n}\n\n.magicfeedback-boolean-option label {\n font-weight: 400;\n font-size: 16px;\n color: #475569;\n cursor: pointer;\n width: 100%;\n height: 100%;\n display: flex;\n justify-content: center;\n align-items: center;\n border-radius: inherit;\n}\n\n.magicfeedback-boolean-option input[type=radio] + label:hover {\n color: #007bff;\n}\n\n.magicfeedback-boolean-option input[type=radio]:checked + label {\n color: #007bff;\n background-color: #cadff8;\n}\n\n.deepdots-popup input[type="radio"] {\n padding: 20px;\n margin: 10px 0 10px 15px;\n width: 40px;\n background-color: #fff;\n box-shadow: none;\n}\n\n/* Style for focused input/select */\n.deepdots-popup input:focus, .deepdots-popup select:focus {\n border-color: #4CAF50; /* Highlight color when focused - you can customize this */\n}\n\n/* Style for invalid input (example: validation error) */\n.deepdots-popup input.error, .deepdots-popup select.error {\n border-color: #ff3333; /* Red color for error state - you can customize this */\n}\n\n.magicfeedback-action-container {\n display: flex;\n flex-direction: row;\n justify-content: space-between;\n align-items: center;\n margin-top: 10px;\n width: 100%;\n}\n\n.magicfeedback-action-container .magicfeedback-submit {\n cursor: pointer;\n padding: 10px;\n margin: 10px 0;\n width: 100px;\n border-radius: 8px;\n font-size: 16px;\n outline: none;\n transition: border-color 0.3s ease;\n background-color: #1E293B;\n color: white;\n}\n\n.magicfeedback-action-container .magicfeedback-back {\n cursor: pointer;\n padding: 10px;\n margin: 10px 0;\n width: 100px;\n border: 0;\n border-radius: 8px;\n font-size: 16px;\n outline: none;\n transition: border-color 0.3s ease;\n background-color: transparent;\n color: #212529;\n}\n\n\n\n/* Rating styles */\n.magicfeedback-rating {\n width: 100%;\n}\n\n.magicfeedback-rating-container {\n display: flex;\n flex-direction: row;\n justify-content: space-around;\n flex-wrap: wrap;\n align-items: center;\n\n margin: 15px 5px;\n padding: 0;\n\n list-style: none;\n font-size: 1.5rem;\n cursor: pointer;\n user-select: none;\n -webkit-user-select: none;\n -moz-user-select: none;\n -ms-user-select: none;\n}\n\n.magicfeedback-rating-placeholder-value,\n.magicfeedback-rating-placeholder{\n text-align: center;\n align-content: center;\n justify-content: center;\n text-wrap: wrap;\n}\n\n.magicfeedback-rating-option {\n margin: 0 0.5rem;\n padding: 0;\n}\n\n@media (max-width: 1024px) {\n .magicfeedback-rating-option {\n margin: 10px 0;\n padding: 0;\n width: 20%;\n display: flex;\n justify-content: center;\n }\n\n .magicfeedback-rating-placeholder-value {\n font-size: 0.75rem;\n margin-bottom: 1px;\n }\n .magicfeedback-rating-placeholder{\n justify-content: center;\n }\n\n .magicfeedback-rating-container {\n flex-wrap: wrap;\n justify-content: flex-start;\n }\n}\n\n\n.magicfeedback-rating-option-label-container {\n display: flex;\n flex-direction: column;\n}\n\n\n.magicfeedback-rating-option-label-container label {\n display: inline-block;\n text-align: center;\n margin-bottom: 0;\n font-weight: 600;\n font-size: 18px;\n color: #475569;\n}\n\n.magicfeedback-rating-option-label-container input[type=radio] {\n position: absolute;\n opacity: 0;\n width: 0;\n height: 0;\n}\n\n/* IMAGE STYLES */\n.magicfeedback-rating-option-label-container input[type=radio] + img {\n cursor: pointer;\n height: 48px;\n width: 48px;\n}\n\n/* LABEL STYLES */\n.magicfeedback-rating-option-label-container input[type=radio] + label {\n cursor: pointer;\n}\n\n/* CHECKED STYLES */\n.magicfeedback-rating-option-label-container input[type=radio]:checked + img {\n box-shadow: #007bff 0px 1px 4px, #007BFFA0 0px 0px 0px 2px;\n border-radius: 50%;\n}\n\n.magicfeedback-rating-number {\n width: 100%;\n}\n.magicfeedback-rating-container,\n.magicfeedback-rating-number-container {\n display: flex;\n flex-direction: row;\n justify-content: space-between;\n align-items: center;\n\n margin: 15px 0;\n padding: 0;\n\n list-style: none;\n font-size: 1.5rem;\n cursor: pointer;\n user-select: none;\n -webkit-user-select: none;\n -moz-user-select: none;\n -ms-user-select: none;\n}\n\n/* Cuando hay placeholders (Very bad / Very good), el placeholder ocupa\n el 100% de la primera l\xEDnea y los boxes bajan a la siguiente */\n.magicfeedback-rating-number-container--with-placeholder {\n flex-wrap: wrap;\n align-items: flex-start;\n}\n\n.magicfeedback-rating-number-container--with-placeholder .magicfeedback-rating-placeholder {\n width: 100%;\n margin-bottom: 8px;\n}\n\n.magicfeedback-rating-number-container--with-placeholder .magicfeedback-rating-number-option {\n width: auto;\n flex: 1;\n}\n\n.magicfeedback-rating-number-option {\n display: flex;\n flex-direction: row;\n justify-content: flex-start;\n align-items: center;\n margin: 5px;\n padding: 0;\n list-style: none;\n font-size: 1.5rem;\n cursor: pointer;\n user-select: none;\n -webkit-user-select: none;\n -moz-user-select: none;\n -ms-user-select: none;\n width: 100%;\n}\n\n.magicfeedback-rating-number-option-row{\n max-width: 100% !important;\n}\n\n.magicfeedback-rating-number-top-placeholder,\n.magicfeedback-rating-number-bottom-placeholder{\n text-align: center !important;\n align-content: center;\n justify-content: center;\n text-wrap: wrap;\n\n font-size: 15px;\n color: #475569;\n\n width: 100%;\n margin: auto;\n}\n\n@media (min-width: 650px) {\n .magicfeedback-rating-number-option-row +.magicfeedback-rating-number-container-ltr:first-child,\n .magicfeedback-rating-number-option-row + +.magicfeedback-rating-number-container-rtl:last-child {\n margin-left: 0;\n width: calc(100% - 10px);\n }\n\n .magicfeedback-rating-number-option-row +.magicfeedback-rating-number-container-rtl:first-child,\n .magicfeedback-rating-number-option-row + +.magicfeedback-rating-number-container-ltr:last-child {\n margin-right: 0;\n width: calc(100% - 10px);\n }\n}\n\n\n.magicfeedback-rating-number-option-label-container {\n display: flex;\n flex-direction: column;\n align-items: center;\n justify-content: center;\n width: 100%;\n height: 100%;\n}\n\n.magicfeedback-rating-number-option-label-container label {\n display: flex;\n align-items: center;\n justify-content: center;\n white-space: nowrap;\n overflow: hidden;\n text-overflow: ellipsis;\n margin: 0 10px;\n font-weight: 600;\n font-size: 14px;\n color: #475569;\n cursor: pointer;\n width: 100%;\n height: 100%;\n min-height: 50px;\n text-align: center;\n padding: 0;\n border-radius: 4px;\n border: 1px solid #ced4da;\n background-color: rgba(246, 246, 246, 0.3);\n transition: background-color 0.15s ease-in-out;\n}\n\n.magicfeedback-rating-number-option-label-container input[type=radio] {\n position: absolute;\n opacity: 0;\n width: 0;\n height: 0;\n}\n\n.magicfeedback-rating-number-option-label-container input[type=radio] + label {\n cursor: pointer;\n}\n\n.magicfeedback-rating-number-option-label-container input[type=radio] + label:hover,\n.magicfeedback-rating-number-option-label-container input[type=radio]:checked + label {\n color: #007bff;\n border: 1px solid #007bff;\n background-color: rgba(86, 168, 253, 0.29);\n}\n\n.magicfeedback-rating-number-container-column{\n align-items: flex-start !important;\n}\n\n@media (max-width: 650px) {\n .magicfeedback-rating-number-container-ltr {\n justify-content: center;\n flex-wrap: wrap;\n }\n\n .magicfeedback-rating-number-container-rtl {\n justify-content: center;\n flex-wrap: wrap-reverse;\n }\n\n .magicfeedback-rating-number-option {\n max-width: 100%;\n height: 55px;\n margin: 5px 0;\n }\n}\n\n.magicfeedback-rating-star {\n width: 100%;\n}\n\n.magicfeedback-rating-star-container {\n display: flex !important;\n flex-direction: row !important;\n justify-content: center !important;\n align-items: center !important;\n flex-wrap: wrap;\n margin: 15px 5px;\n padding: 0;\n list-style: none;\n font-size: 1.5rem;\n cursor: pointer;\n user-select: none;\n -webkit-user-select: none;\n -moz-user-select: none;\n -ms-user-select: none;\n}\n\n.magicfeedback-rating-star-option:not(:checked) > .rating__star {\n float: right;\n width: 1em;\n overflow: hidden;\n white-space: nowrap;\n cursor: pointer;\n font-size: 30px;\n color: #ccc;\n margin: 0 10px;\n}\n\n.magicfeedback-rating-star-option:not(:checked) > .rating__star:hover,\n.magicfeedback-rating-star-option:not(:checked) > .rating__star:hover ~ span {\n color: #deb217 !important;\n}\n\n.magicfeedback-rating-star-selected {\n color: #ffc700 !important;\n}\n\n\n/* Style for multiple choice image */\n.magicfeedback-image-option-label-container:hover {\n cursor: pointer;\n border: 0 !important;\n}\n\n.magicfeedback-image-option-label-container input[type=radio]:checked + img,\n.magicfeedback-image-option-label-container input[type=checkbox]:checked + img {\n border: 1px solid #007bff !important;\n box-shadow: 0 0 3px #007bff !important;\n}\n\n.magicfeedback-image-option-label-container input[type=radio] + img,\n.magicfeedback-image-option-label-container input[type=checkbox] + img {\n border: 1px solid transparent !important;\n}\n\n.magicfeedback-image-option-label-container{\n margin: 10px !important;\n height: calc(100% - 20px) !important;\n width: calc(100% - 20px) !important;\n}\n\n.magicfeedback-multiple-choice-image-option {\n display: flex;\n height: auto !important;\n box-shadow: 0 0 3px #ccc;\n}\n\n.magicfeedback-multiple-choice-image-label {\n font-size: 1rem;\n}\n\n.magicfeedback-consent-container {\n display: flex;\n flex-direction: row;\n justify-content: flex-start;\n align-items: center;\n margin: 10px 0;\n width: 100%;\n}\n\n.magicfeedback-consent-container label {\n margin-left: 10px;\n}\n\n.magicfeedback-start-message-container {\n /* ... add your start message container styles here ... */\n}\n\n.magicfeedback-success-message,\n.magicfeedback-info-message,\n.magicfeedback-start-message {\n margin: 35px 5px;\n}\n\n.magicfeedback-success-message p,\n.magicfeedback-info-message p,\n.magicfeedback-start-message p {\n font-style: normal;\n text-align: start;\n font-weight: 400;\n font-size: 16px;\n color: #475569;\n line-height: 1.5;\n}\n\n.magicfeedback-success-message img,\n.magicfeedback-info-message img,\n.magicfeedback-start-message img {\n width: 400px;\n max-width: 80%;\n height: auto;\n margin: 10px auto;\n}\n\n.magicfeedback-counter,\n.magicfeedback-point-system-total {\n margin: 10px 0 0 0 !important;\n display: flex !important;\n justify-content: right !important;\n align-items: center !important;\n width: 100%;\n}\n\n.magicfeedback-skip-container {\n background-color: transparent !important;\n border: 0 !important;\n color: #999999FF !important;\n padding: 0 !important;\n margin: 0 !important;\n cursor: pointer !important;\n font-size: 0.5em !important;\n font-weight: 400 !important;\n box-shadow: 0 0 0 !important;\n\n &:hover {\n color: #0066ff;\n }\n}\n\n.magicfeedback-skip-container input[type=checkbox] {\n border-color: #999999FF !important;\n border: 0 !important;\n cursor: pointer !important;\n\n}\n\n.magicfeedback-multi-question-matrix,\n.magicfeedback-point-system,\n.magicfeedback-priority-list {\n width: 100% !important;\n}\n\n.magicfeedback-multi-question-matrix-container,\n.magicfeedback-point-system-container,\n.magicfeedback-priority-list-container {\n width: 100% !important;\n overflow-x: auto;\n}\n\n.magicfeedback-point-system-list,\n.magicfeedback-priority-list-list,\n.magicfeedback-multi-question-matrix-table {\n width: 100% !important;\n padding: 0 !important;\n overflow-x: auto;\n}\n\n.magicfeedback-multi-question-matrix {\n position: relative !important;\n}\n\n.magicfeedback-multi-question-matrix-container {\n overflow: auto !important;\n padding-bottom: 10px;\n}\n\n.magicfeedback-multi-question-matrix-label{\n text-align: left !important;\n}\n.magicfeedback-priority-list-item {\n display: flex;\n flex-direction: row;\n justify-content: space-between;\n align-items: center;\n padding: 10px 0 10px 10px;\n\n border: 1px solid #ced4da;\n border-radius: 5px;\n margin: 10px 0 !important;\n}\n\n.magicfeedback-point-system-item {\n height: 45px;\n margin: 5px 0 !important;\n}\n\n.magicfeedback-point-system-item label,\n.magicfeedback-priority-list-item-label {\n font-family: inherit;\n font-size: 18px !important;\n color: #212529;\n text-align: start;\n word-wrap: break-word;\n white-space: normal;\n padding: 0 10px 0 0;\n}\n\n.magicfeedback-point-system-input-container {\n padding: 0 10px 0 0;\n border-radius: 5px;\n font-size: 14px;\n border: 1px solid #ced4da;\n height: 42px;\n margin: auto 0;\n}\n\n.magicfeedback-multi-question-matrix-table thead {\n margin-bottom: 20px;\n}\n\n.magicfeedback-multi-question-matrix-table th{\n text-align: center;\n font-weight: 400 !important;\n font-size: 1rem !important;\n padding: 0 10px !important;\n}\n\n.magicfeedback-multi-question-matrix-table th,\n.magicfeedback-multi-question-matrix-table td label,\n.magicfeedback-priority-list-arrow-up,\n.magicfeedback-priority-list-arrow-down {\n font-style: normal !important;\n font-weight: 400 !important;\n font-size: 1rem !important;\n color: #475569 !important;\n cursor: pointer !important;\n margin: 0 !important;\n line-height: inherit;\n}\n\n.magicfeedback-multi-question-matrix-table tr {\n align-items: center;\n margin: 5px 0;\n}\n\n.magicfeedback-multi-question-matrix-row-tr{\n border-radius: 5px;\n margin: 10px 0 !important;\n}\n\n.magicfeedback-multi-question-matrix-row-tr:nth-child(odd) {\n background-color: #f1f6f6; /* Light gray background for odd rows */\n}\n\n.magicfeedback-multi-question-matrix-row-tr:nth-child(even) {\n background-color: #ffffff; /* White background for even rows */\n}\n\n.magicfeedback-multi-question-matrix-row-label {\n text-align: left !important;\n}\n\n.magicfeedback-point-system-item span {\n color: #475569 !important;\n}\n\n.magicfeedback-point-system-item input {\n padding: 0;\n margin: 0 !important;\n width: auto !important;\n min-width: 100px !important;\n height: auto !important;\n min-height: 42px;\n cursor: pointer;\n font-size: 14px;\n text-align: center !important;\n}\n\n.magicfeedback-multi-question-matrix-table input {\n margin: auto !important;\n padding: 20px !important;\n width: 100% !important;\n height: 15px;\n border: 1px solid #ced4da;\n cursor: pointer;\n}\n\n.magicfeedback-image{\n max-height: 400px !important;\n height: auto !important;\n max-width: 100% !important;\n margin: 10px auto !important;\n}\n\n.magicfeedback-error{\n margin-top: 5px;\n}';
188
+ style_default = '.magicfeedback-container {\n width: 100%;\n}\n\n\n.magicfeedback-success-message,\n.magicfeedback-info-message,\n.magicfeedback-start-message,\n.magicfeedback-container{\n animation-duration: 0.5s;\n animation-name: animate-fade;\n animation-delay: 0.25s;\n animation-fill-mode: backwards;\n\n font-style: normal;\n text-align: justify;\n font-weight: 400;\n font-size: 1.2rem;\n color: #475569;\n line-height: 1.5;\n}\n\n@keyframes animate-fade {\n 0% { opacity: 0; }\n 100% { opacity: 1; }\n}\n\n.magicfeedback-form {\n display: flex;\n flex-direction: column;\n justify-content: flex-start;\n align-items: center;\n width: 100%;\n}\n.magicfeedback-questions {\n display: flex;\n flex-direction: column;\n justify-content: flex-start;\n align-items: flex-start;\n width: 100%;\n}\n\n.magicfeedback-div {\n display: flex;\n flex-direction: column;\n justify-content: flex-start;\n align-items: flex-start;\n margin-bottom: 10px;\n width: 100%;\n}\n\n.magicfeedback-label {\n margin-bottom: 25px;\n margin-top: 20px;\n font-weight: 400;\n font-family: inherit;\n font-size: 1.2rem;\n color: #212529;\n text-align: start;\n word-wrap: break-word;\n white-space: normal;\n\n}\n\n.magicfeedback-checkbox {\n display: flex;\n flex-direction: column;\n flex-wrap: wrap;\n width: 100%;\n}\n\n.magicfeedback-checkbox-container {\n display: flex;\n flex-direction: row;\n justify-content: flex-start;\n align-items: center;\n margin-bottom: 5px;\n margin-top: 5px;\n}\n\n/* Cualificado con `div`: @magicfeedback/native reutiliza la clase "magicfeedback-radio"\n tambi\xE9n en el <input> de cada opci\xF3n (rating), y sin el tag este selector lo capturaba\n tambi\xE9n, rompiendo su tama\xF1o (el input pasaba a display:flex; width:100%). */\ndiv.magicfeedback-radio {\n display: flex;\n flex-direction: column;\n justify-content: flex-start;\n flex-wrap: wrap;\n width: 100%;\n margin-right: 5px;\n padding: 5px;\n box-sizing: border-box;\n}\n\n.magicfeedback-checkbox-container,\n.magicfeedback-radio-container {\n display: flex;\n flex-direction: row;\n justify-content: flex-start;\n align-items: center;\n margin: 5px;\n padding: 5px 0;\n background-color: #fff;\n border-radius: 5px;\n box-shadow: 0 0 3px #ccc;\n}\n\n.deepdots-popup input::-webkit-outer-spin-button,\n.deepdots-popup input::-webkit-inner-spin-button {\n -webkit-appearance: none;\n -moz-appearance: textfield;\n}\n\n.magicfeedback-checkbox input[type="checkbox"] {\n margin-right: 5px;\n margin-left: 5px;\n width: 20px;\n height: 20px;\n cursor: pointer;\n}\n\n\n.magicfeedback-checkbox label,\n.magicfeedback-radio-container label {\n margin-left: 5px;\n font-weight: 400;\n font-family: inherit;\n font-size: 16px;\n color: #212529;\n text-align: start;\n width: 100%;\n}\n\n.deepdots-popup p {\n margin-bottom: 0px;\n font-size: 12px;\n}\n\n.deepdots-popup h2 {\n line-height: 1.66;\n margin: 0;\n padding: 0;\n font-weight: 900;\n color: #222;\n font-family: var(--deepdots-font, \'Montserrat\');\n font-size: 18px;\n text-transform: uppercase;\n text-align: center;\n margin-bottom: 40px;\n}\n\n/* Los controles de formulario no heredan font-family por defecto: cuando hay\n fuente custom (clase deepdots-has-font), los forzamos a usar la del contenedor. */\n.deepdots-popup.deepdots-has-font button,\n.deepdots-popup.deepdots-has-font input,\n.deepdots-popup.deepdots-has-font textarea,\n.deepdots-popup.deepdots-has-font select {\n font-family: var(--deepdots-font, inherit);\n}\n\n.deepdots-popup h6 {\n margin-bottom: 1rem;\n}\n\n.deepdots-popup input[type="date"],\n.deepdots-popup input[type="text"],\n.deepdots-popup input[type="number"],\n.deepdots-popup input[type="email"],\n.deepdots-popup input[type="password"],\n.deepdots-popup textarea,\n.deepdots-popup select {\n box-sizing: border-box;\n padding: 10px;\n margin: 10px 0;\n width: 100%;\n border: 2px solid #ccc; /* Default border color - you can customize this */\n border-radius: 5px;\n font-size: 18px;\n outline: none;\n transition: border-color 0.3s ease;\n min-height: 50px;\n font-family: inherit;\n -webkit-appearance: none;\n}\n\n.deepdots-popup select {\n background-image: linear-gradient(45deg, transparent 50%, gray 50%),\n linear-gradient(135deg, gray 50%, transparent 50%),\n linear-gradient(to right, #ccc, #ccc);\n background-position: calc(100% - 20px) calc(1em + 2px),\n calc(100% - 15px) calc(1em + 2px),\n calc(100% - 2.5em) 0.5em;\n background-size: 5px 5px,\n 5px 5px,\n 1px 1.5em;\n background-repeat: no-repeat;\n}\n\n.magicfeedback-boolean-container {\n display: flex;\n flex-direction: row;\n justify-content: flex-start;\n align-items: center;\n margin: 10px 0;\n width: 100%;\n}\n\n.magicfeedback-boolean-container label {\n margin-left: 10px;\n font-weight: 400;\n font-size: 16px;\n width: 100%;\n padding-top: 5px;\n}\n\n.magicfeedback-boolean-option {\n margin-right: 10px;\n margin-left: 10px;\n width: 100%;\n height: 38px;\n border-radius: 8px;\n font-size: 16px;\n cursor: pointer;\n border: 1px solid #ced4da !important;\n}\n\n.magicfeedback-boolean-option label {\n font-weight: 400;\n font-size: 16px;\n color: #475569;\n cursor: pointer;\n width: 100%;\n height: 100%;\n display: flex;\n justify-content: center;\n align-items: center;\n border-radius: inherit;\n}\n\n.magicfeedback-boolean-option input[type=radio] + label:hover {\n color: #007bff;\n}\n\n.magicfeedback-boolean-option input[type=radio]:checked + label {\n color: #007bff;\n background-color: #cadff8;\n}\n\n/* Tama\xF1o expl\xEDcito y sin padding: un radio nativo con `padding: 20px` y solo `width` (sin\n `height`) se dibujaba enorme en WebKit, que s\xED aplica el padding al control. Se ve\xEDa en\n iOS (WebView de React Native y Safari) y no en Chrome. `flex: 0 0 auto` evita que el\n contenedor flex de la opci\xF3n lo estire. */\n.deepdots-popup input[type="radio"] {\n padding: 0;\n margin: 10px 0 10px 15px;\n width: 20px;\n height: 20px;\n min-width: 20px;\n flex: 0 0 auto;\n background-color: #fff;\n box-shadow: none;\n}\n\n/* Style for focused input/select */\n.deepdots-popup input:focus, .deepdots-popup select:focus {\n border-color: #4CAF50; /* Highlight color when focused - you can customize this */\n}\n\n/* Style for invalid input (example: validation error) */\n.deepdots-popup input.error, .deepdots-popup select.error {\n border-color: #ff3333; /* Red color for error state - you can customize this */\n}\n\n.magicfeedback-action-container {\n display: flex;\n flex-direction: row;\n justify-content: space-between;\n align-items: center;\n margin-top: 10px;\n width: 100%;\n}\n\n.magicfeedback-action-container .magicfeedback-submit {\n cursor: pointer;\n padding: 10px;\n margin: 10px 0;\n width: 100px;\n border-radius: 8px;\n font-size: 16px;\n outline: none;\n transition: border-color 0.3s ease;\n background-color: #1E293B;\n color: white;\n}\n\n.magicfeedback-action-container .magicfeedback-back {\n cursor: pointer;\n padding: 10px;\n margin: 10px 0;\n width: 100px;\n border: 0;\n border-radius: 8px;\n font-size: 16px;\n outline: none;\n transition: border-color 0.3s ease;\n background-color: transparent;\n color: #212529;\n}\n\n\n\n/* Rating styles */\n.magicfeedback-rating {\n width: 100%;\n}\n\n.magicfeedback-rating-container {\n display: flex;\n flex-direction: row;\n justify-content: space-around;\n flex-wrap: wrap;\n align-items: center;\n\n margin: 15px 5px;\n padding: 0;\n\n list-style: none;\n font-size: 1.5rem;\n cursor: pointer;\n user-select: none;\n -webkit-user-select: none;\n -moz-user-select: none;\n -ms-user-select: none;\n}\n\n.magicfeedback-rating-placeholder-value,\n.magicfeedback-rating-placeholder{\n text-align: center;\n align-content: center;\n justify-content: center;\n text-wrap: wrap;\n}\n\n.magicfeedback-rating-option {\n margin: 0 0.5rem;\n padding: 0;\n}\n\n@media (max-width: 1024px) {\n .magicfeedback-rating-option {\n margin: 10px 0;\n padding: 0;\n width: 20%;\n display: flex;\n justify-content: center;\n }\n\n .magicfeedback-rating-placeholder-value {\n font-size: 0.75rem;\n margin-bottom: 1px;\n }\n .magicfeedback-rating-placeholder{\n justify-content: center;\n }\n\n .magicfeedback-rating-container {\n flex-wrap: wrap;\n justify-content: flex-start;\n }\n}\n\n\n.magicfeedback-rating-option-label-container {\n display: flex;\n flex-direction: column;\n}\n\n\n.magicfeedback-rating-option-label-container label {\n display: inline-block;\n text-align: center;\n margin-bottom: 0;\n font-weight: 600;\n font-size: 18px;\n color: #475569;\n}\n\n.magicfeedback-rating-option-label-container input[type=radio] {\n position: absolute;\n opacity: 0;\n width: 0;\n height: 0;\n}\n\n/* IMAGE STYLES */\n.magicfeedback-rating-option-label-container input[type=radio] + img {\n cursor: pointer;\n height: 48px;\n width: 48px;\n}\n\n/* LABEL STYLES */\n.magicfeedback-rating-option-label-container input[type=radio] + label {\n cursor: pointer;\n}\n\n/* CHECKED STYLES */\n.magicfeedback-rating-option-label-container input[type=radio]:checked + img {\n box-shadow: #007bff 0px 1px 4px, #007BFFA0 0px 0px 0px 2px;\n border-radius: 50%;\n}\n\n.magicfeedback-rating-number {\n width: 100%;\n}\n.magicfeedback-rating-container,\n.magicfeedback-rating-number-container {\n display: flex;\n flex-direction: row;\n justify-content: space-between;\n align-items: center;\n\n margin: 15px 0;\n padding: 0;\n\n list-style: none;\n font-size: 1.5rem;\n cursor: pointer;\n user-select: none;\n -webkit-user-select: none;\n -moz-user-select: none;\n -ms-user-select: none;\n}\n\n/* Cuando hay placeholders (Very bad / Very good), el placeholder ocupa\n el 100% de la primera l\xEDnea y los boxes bajan a la siguiente */\n.magicfeedback-rating-number-container--with-placeholder {\n flex-wrap: wrap;\n align-items: flex-start;\n}\n\n.magicfeedback-rating-number-container--with-placeholder .magicfeedback-rating-placeholder {\n width: 100%;\n margin-bottom: 8px;\n}\n\n.magicfeedback-rating-number-container--with-placeholder .magicfeedback-rating-number-option {\n width: auto;\n flex: 1;\n}\n\n.magicfeedback-rating-number-option {\n display: flex;\n flex-direction: row;\n justify-content: flex-start;\n align-items: center;\n margin: 5px;\n padding: 0;\n list-style: none;\n font-size: 1.5rem;\n cursor: pointer;\n user-select: none;\n -webkit-user-select: none;\n -moz-user-select: none;\n -ms-user-select: none;\n width: 100%;\n}\n\n.magicfeedback-rating-number-option-row{\n max-width: 100% !important;\n}\n\n.magicfeedback-rating-number-top-placeholder,\n.magicfeedback-rating-number-bottom-placeholder{\n text-align: center !important;\n align-content: center;\n justify-content: center;\n text-wrap: wrap;\n\n font-size: 15px;\n color: #475569;\n\n width: 100%;\n margin: auto;\n}\n\n@media (min-width: 650px) {\n .magicfeedback-rating-number-option-row +.magicfeedback-rating-number-container-ltr:first-child,\n .magicfeedback-rating-number-option-row + +.magicfeedback-rating-number-container-rtl:last-child {\n margin-left: 0;\n width: calc(100% - 10px);\n }\n\n .magicfeedback-rating-number-option-row +.magicfeedback-rating-number-container-rtl:first-child,\n .magicfeedback-rating-number-option-row + +.magicfeedback-rating-number-container-ltr:last-child {\n margin-right: 0;\n width: calc(100% - 10px);\n }\n}\n\n\n.magicfeedback-rating-number-option-label-container {\n display: flex;\n flex-direction: column;\n align-items: center;\n justify-content: center;\n width: 100%;\n height: 100%;\n}\n\n.magicfeedback-rating-number-option-label-container label {\n display: flex;\n align-items: center;\n justify-content: center;\n white-space: nowrap;\n overflow: hidden;\n text-overflow: ellipsis;\n margin: 0 10px;\n font-weight: 600;\n font-size: 14px;\n color: #475569;\n cursor: pointer;\n width: 100%;\n height: 100%;\n min-height: 50px;\n text-align: center;\n padding: 0;\n border-radius: 4px;\n border: 1px solid #ced4da;\n background-color: rgba(246, 246, 246, 0.3);\n transition: background-color 0.15s ease-in-out;\n}\n\n.magicfeedback-rating-number-option-label-container input[type=radio] {\n position: absolute;\n opacity: 0;\n width: 0;\n height: 0;\n}\n\n.magicfeedback-rating-number-option-label-container input[type=radio] + label {\n cursor: pointer;\n}\n\n.magicfeedback-rating-number-option-label-container input[type=radio] + label:hover,\n.magicfeedback-rating-number-option-label-container input[type=radio]:checked + label {\n color: #007bff;\n border: 1px solid #007bff;\n background-color: rgba(86, 168, 253, 0.29);\n}\n\n.magicfeedback-rating-number-container-column{\n align-items: flex-start !important;\n}\n\n@media (max-width: 650px) {\n .magicfeedback-rating-number-container-ltr {\n justify-content: center;\n flex-wrap: wrap;\n }\n\n .magicfeedback-rating-number-container-rtl {\n justify-content: center;\n flex-wrap: wrap-reverse;\n }\n\n .magicfeedback-rating-number-option {\n max-width: 100%;\n height: 55px;\n margin: 5px 0;\n }\n}\n\n.magicfeedback-rating-star {\n width: 100%;\n}\n\n.magicfeedback-rating-star-container {\n display: flex !important;\n flex-direction: row !important;\n justify-content: center !important;\n align-items: center !important;\n flex-wrap: wrap;\n margin: 15px 5px;\n padding: 0;\n list-style: none;\n font-size: 1.5rem;\n cursor: pointer;\n user-select: none;\n -webkit-user-select: none;\n -moz-user-select: none;\n -ms-user-select: none;\n}\n\n.magicfeedback-rating-star-option:not(:checked) > .rating__star {\n float: right;\n width: 1em;\n overflow: hidden;\n white-space: nowrap;\n cursor: pointer;\n font-size: 30px;\n color: #ccc;\n margin: 0 10px;\n}\n\n.magicfeedback-rating-star-option:not(:checked) > .rating__star:hover,\n.magicfeedback-rating-star-option:not(:checked) > .rating__star:hover ~ span {\n color: #deb217 !important;\n}\n\n.magicfeedback-rating-star-selected {\n color: #ffc700 !important;\n}\n\n\n/* Style for multiple choice image */\n.magicfeedback-image-option-label-container:hover {\n cursor: pointer;\n border: 0 !important;\n}\n\n.magicfeedback-image-option-label-container input[type=radio]:checked + img,\n.magicfeedback-image-option-label-container input[type=checkbox]:checked + img {\n border: 1px solid #007bff !important;\n box-shadow: 0 0 3px #007bff !important;\n}\n\n.magicfeedback-image-option-label-container input[type=radio] + img,\n.magicfeedback-image-option-label-container input[type=checkbox] + img {\n border: 1px solid transparent !important;\n}\n\n.magicfeedback-image-option-label-container{\n margin: 10px !important;\n height: calc(100% - 20px) !important;\n width: calc(100% - 20px) !important;\n}\n\n.magicfeedback-multiple-choice-image-option {\n display: flex;\n height: auto !important;\n box-shadow: 0 0 3px #ccc;\n}\n\n.magicfeedback-multiple-choice-image-label {\n font-size: 1rem;\n}\n\n.magicfeedback-consent-container {\n display: flex;\n flex-direction: row;\n justify-content: flex-start;\n align-items: center;\n margin: 10px 0;\n width: 100%;\n}\n\n.magicfeedback-consent-container label {\n margin-left: 10px;\n}\n\n.magicfeedback-start-message-container {\n /* ... add your start message container styles here ... */\n}\n\n.magicfeedback-success-message,\n.magicfeedback-info-message,\n.magicfeedback-start-message {\n margin: 35px 5px;\n}\n\n.magicfeedback-success-message p,\n.magicfeedback-info-message p,\n.magicfeedback-start-message p {\n font-style: normal;\n text-align: start;\n font-weight: 400;\n font-size: 16px;\n color: #475569;\n line-height: 1.5;\n}\n\n.magicfeedback-success-message img,\n.magicfeedback-info-message img,\n.magicfeedback-start-message img {\n width: 400px;\n max-width: 80%;\n height: auto;\n margin: 10px auto;\n}\n\n.magicfeedback-counter,\n.magicfeedback-point-system-total {\n margin: 10px 0 0 0 !important;\n display: flex !important;\n justify-content: right !important;\n align-items: center !important;\n width: 100%;\n}\n\n.magicfeedback-skip-container {\n background-color: transparent !important;\n border: 0 !important;\n color: #999999FF !important;\n padding: 0 !important;\n margin: 0 !important;\n cursor: pointer !important;\n font-size: 0.5em !important;\n font-weight: 400 !important;\n box-shadow: 0 0 0 !important;\n\n &:hover {\n color: #0066ff;\n }\n}\n\n.magicfeedback-skip-container input[type=checkbox] {\n border-color: #999999FF !important;\n border: 0 !important;\n cursor: pointer !important;\n\n}\n\n.magicfeedback-multi-question-matrix,\n.magicfeedback-point-system,\n.magicfeedback-priority-list {\n width: 100% !important;\n}\n\n.magicfeedback-multi-question-matrix-container,\n.magicfeedback-point-system-container,\n.magicfeedback-priority-list-container {\n width: 100% !important;\n overflow-x: auto;\n}\n\n.magicfeedback-point-system-list,\n.magicfeedback-priority-list-list,\n.magicfeedback-multi-question-matrix-table {\n width: 100% !important;\n padding: 0 !important;\n overflow-x: auto;\n}\n\n.magicfeedback-multi-question-matrix {\n position: relative !important;\n}\n\n.magicfeedback-multi-question-matrix-container {\n overflow: auto !important;\n padding-bottom: 10px;\n}\n\n.magicfeedback-multi-question-matrix-label{\n text-align: left !important;\n}\n.magicfeedback-priority-list-item {\n display: flex;\n flex-direction: row;\n justify-content: space-between;\n align-items: center;\n padding: 10px 0 10px 10px;\n\n border: 1px solid #ced4da;\n border-radius: 5px;\n margin: 10px 0 !important;\n}\n\n.magicfeedback-point-system-item {\n height: 45px;\n margin: 5px 0 !important;\n}\n\n.magicfeedback-point-system-item label,\n.magicfeedback-priority-list-item-label {\n font-family: inherit;\n font-size: 18px !important;\n color: #212529;\n text-align: start;\n word-wrap: break-word;\n white-space: normal;\n padding: 0 10px 0 0;\n}\n\n.magicfeedback-point-system-input-container {\n padding: 0 10px 0 0;\n border-radius: 5px;\n font-size: 14px;\n border: 1px solid #ced4da;\n height: 42px;\n margin: auto 0;\n}\n\n.magicfeedback-multi-question-matrix-table thead {\n margin-bottom: 20px;\n}\n\n.magicfeedback-multi-question-matrix-table th{\n text-align: center;\n font-weight: 400 !important;\n font-size: 1rem !important;\n padding: 0 10px !important;\n}\n\n.magicfeedback-multi-question-matrix-table th,\n.magicfeedback-multi-question-matrix-table td label,\n.magicfeedback-priority-list-arrow-up,\n.magicfeedback-priority-list-arrow-down {\n font-style: normal !important;\n font-weight: 400 !important;\n font-size: 1rem !important;\n color: #475569 !important;\n cursor: pointer !important;\n margin: 0 !important;\n line-height: inherit;\n}\n\n.magicfeedback-multi-question-matrix-table tr {\n align-items: center;\n margin: 5px 0;\n}\n\n.magicfeedback-multi-question-matrix-row-tr{\n border-radius: 5px;\n margin: 10px 0 !important;\n}\n\n.magicfeedback-multi-question-matrix-row-tr:nth-child(odd) {\n background-color: #f1f6f6; /* Light gray background for odd rows */\n}\n\n.magicfeedback-multi-question-matrix-row-tr:nth-child(even) {\n background-color: #ffffff; /* White background for even rows */\n}\n\n.magicfeedback-multi-question-matrix-row-label {\n text-align: left !important;\n}\n\n.magicfeedback-point-system-item span {\n color: #475569 !important;\n}\n\n.magicfeedback-point-system-item input {\n padding: 0;\n margin: 0 !important;\n width: auto !important;\n min-width: 100px !important;\n height: auto !important;\n min-height: 42px;\n cursor: pointer;\n font-size: 14px;\n text-align: center !important;\n}\n\n.magicfeedback-multi-question-matrix-table input {\n margin: auto !important;\n padding: 20px !important;\n width: 100% !important;\n height: 15px;\n border: 1px solid #ced4da;\n cursor: pointer;\n}\n\n.magicfeedback-image{\n max-height: 400px !important;\n height: auto !important;\n max-width: 100% !important;\n margin: 10px auto !important;\n}\n\n.magicfeedback-error{\n margin-top: 5px;\n}';
189
189
  }
190
190
  });
191
191
 
@@ -2153,6 +2153,10 @@ function ensureSpinnerStyles(_popup) {
2153
2153
  const style = document.createElement("style");
2154
2154
  style.id = "deepdots-spinner-styles";
2155
2155
  style.textContent = `
2156
+ /* El enunciado trae margin-top:20px del CSS de surveys, que sumaba al hueco de la barra
2157
+ de progreso y descompensaba la simetr\xEDa. Solo se anula en el primero: entre preguntas
2158
+ de la misma p\xE1gina sigue separando. */
2159
+ .deepdots-popup .magicfeedback-questions .magicfeedback-div:first-child .magicfeedback-label { margin-top: 0; }
2156
2160
  @keyframes ddspin { 0% { transform: rotate(0deg); } 100% { transform: rotate(360deg); } }
2157
2161
  .mf-spinner { display:flex; justify-content:center; align-items:center; padding:8px 0; }
2158
2162
  .mf-spinner-circle { width:28px; height:28px; border:3px solid #e0e6ed; border-top-color:#1E293B; border-radius:50%; animation: ddspin 0.9s linear infinite; }
@@ -2179,7 +2183,9 @@ function ensureResponsiveStyles(_popup) {
2179
2183
  .deepdots-popup button { font-size: 16px !important; }
2180
2184
  .deepdots-popup-header button { width:48px; height:48px; }
2181
2185
  .deepdots-popup-header button svg { width:26px; height:26px; }
2182
- .deepdots-popup-footer { flex-direction: column-reverse !important; gap: 12px !important; }
2186
+ /* Apilados en el orden del DOM: la acci\xF3n principal (Send/Start/Complete) arriba y
2187
+ Back debajo. */
2188
+ .deepdots-popup-footer { flex-direction: column !important; gap: 4px !important; }
2183
2189
  .deepdots-popup-footer button { width: 100%; }
2184
2190
  }
2185
2191
  @media (max-width: 400px) {
@@ -2197,6 +2203,18 @@ function ensureResponsiveStyles(_popup) {
2197
2203
  `;
2198
2204
  document.head.appendChild(style);
2199
2205
  }
2206
+ function ensureCustomCss(css) {
2207
+ const STYLE_ID = "deepdots-custom-css";
2208
+ const existing = document.getElementById(STYLE_ID);
2209
+ if (!css) {
2210
+ existing?.remove();
2211
+ return;
2212
+ }
2213
+ const el = existing ?? document.createElement("style");
2214
+ el.id = STYLE_ID;
2215
+ if (el.textContent !== css) el.textContent = css;
2216
+ document.head.appendChild(el);
2217
+ }
2200
2218
  function ensureFontFace(family, url) {
2201
2219
  const css = buildFontFaceCss(family, url);
2202
2220
  if (!css) return;
@@ -2209,9 +2227,11 @@ function ensureFontFace(family, url) {
2209
2227
  }
2210
2228
  if (el.textContent !== css) el.textContent = css;
2211
2229
  }
2212
- async function renderPopup(container, surveyId, productId, actions, emit, onClose, env = "production", userId, style, sessionId, miniService, analyticsFeedbackSessionId) {
2230
+ async function renderPopup(container, surveyId, productId, actions, emit, onClose, env = "production", userId, style, sessionId, miniService, analyticsFeedbackSessionId, options) {
2213
2231
  let surveyCompletedEmitted = false;
2214
2232
  let stylesInjected = false;
2233
+ let pageDepth = 0;
2234
+ let onStartPage = false;
2215
2235
  const isDark = style?.theme === "dark";
2216
2236
  const theme = {
2217
2237
  popupBg: isDark ? "#1e1e1e" : "#fff",
@@ -2222,7 +2242,9 @@ async function renderPopup(container, surveyId, productId, actions, emit, onClos
2222
2242
  colorScheme: isDark ? "dark" : "light",
2223
2243
  textPrimary: isDark ? "#f0f0f0" : "#111",
2224
2244
  closeBtnHoverBg: isDark ? "rgba(255,255,255,0.10)" : "rgba(0,0,0,0.06)",
2225
- closeBtnHoverColor: isDark ? "#fff" : "#000000"
2245
+ closeBtnHoverColor: isDark ? "#fff" : "#000000",
2246
+ textMuted: isDark ? "#9ca3af" : "#6b7280",
2247
+ progressTrack: isDark ? "#3f3f46" : "#e5e7eb"
2226
2248
  };
2227
2249
  const positionMap = {
2228
2250
  "center": { justifyContent: "center", alignItems: "center", background: "rgba(0,0,0,0.5)" },
@@ -2235,6 +2257,7 @@ async function renderPopup(container, surveyId, productId, actions, emit, onClos
2235
2257
  };
2236
2258
  const pos = positionMap[style?.position ?? "center"] ?? positionMap["center"];
2237
2259
  const popup = document.createElement("div");
2260
+ popup.id = "dd-popup";
2238
2261
  popup.className = "deepdots-popup";
2239
2262
  popup.style.cssText = `
2240
2263
  position: relative;
@@ -2248,6 +2271,7 @@ async function renderPopup(container, surveyId, productId, actions, emit, onClos
2248
2271
  box-shadow: 0 4px 6px rgba(0,0,0,0.1);
2249
2272
  max-width: 600px;
2250
2273
  width: 90%;
2274
+ max-height: 90vh;
2251
2275
  min-height: 200px;
2252
2276
  `;
2253
2277
  const font = style?.font;
@@ -2260,8 +2284,21 @@ async function renderPopup(container, surveyId, productId, actions, emit, onClos
2260
2284
  }
2261
2285
  const header = document.createElement("div");
2262
2286
  header.className = "deepdots-popup-header";
2263
- header.style.cssText = "display:flex; justify-content:flex-end; align-items:center; width:100%;";
2287
+ header.style.cssText = "display:flex; justify-content:space-between; align-items:center; gap:12px; width:100%; flex:0 0 auto;";
2288
+ const titleEl = document.createElement("h2");
2289
+ titleEl.id = "dd-title";
2290
+ titleEl.className = "deepdots-popup-title";
2291
+ titleEl.style.cssText = `margin:0; font-size:17px; font-weight:600; line-height:1.3; color:${theme.textPrimary}; text-transform:none; text-align:left; overflow:hidden; text-overflow:ellipsis; white-space:nowrap;`;
2292
+ titleEl.hidden = true;
2293
+ const setTitle = (value) => {
2294
+ if (!value) return;
2295
+ titleEl.textContent = value;
2296
+ titleEl.hidden = false;
2297
+ };
2298
+ setTitle(options?.title);
2299
+ header.appendChild(titleEl);
2264
2300
  const closeBtn = document.createElement("button");
2301
+ closeBtn.id = "dd-close";
2265
2302
  closeBtn.type = "button";
2266
2303
  closeBtn.setAttribute("aria-label", "Close popup");
2267
2304
  closeBtn.innerHTML = `
@@ -2298,25 +2335,86 @@ async function renderPopup(container, surveyId, productId, actions, emit, onClos
2298
2335
  emit("popup_clicked", surveyId, { action: "close_icon" });
2299
2336
  onClose();
2300
2337
  };
2338
+ closeBtn.style.flex = "0 0 auto";
2339
+ closeBtn.style.marginLeft = "auto";
2301
2340
  header.appendChild(closeBtn);
2341
+ let progressEnabled = options?.showProgressBar === true;
2342
+ let progressShowUnit = true;
2343
+ let progressUnit = "fraction";
2344
+ const progressEl = document.createElement("div");
2345
+ progressEl.id = "dd-progress";
2346
+ progressEl.className = "deepdots-progress";
2347
+ progressEl.style.cssText = "display:none; flex-direction:column; gap:8px; width:100%; flex:0 0 auto; padding:16px 0; box-sizing:border-box;";
2348
+ const progressHead = document.createElement("div");
2349
+ progressHead.className = "deepdots-progress-head";
2350
+ progressHead.style.cssText = "display:flex; flex-direction:row; justify-content:space-between; align-items:center; width:100%; gap:8px;";
2351
+ const progressLabel = document.createElement("span");
2352
+ progressLabel.id = "dd-progress-label";
2353
+ progressLabel.style.cssText = "font-size:13px; line-height:1.2;";
2354
+ const progressCurrent = document.createElement("span");
2355
+ progressCurrent.id = "dd-progress-current";
2356
+ progressCurrent.style.cssText = `font-weight:700; color:${theme.textPrimary};`;
2357
+ const progressTotal = document.createElement("span");
2358
+ progressTotal.id = "dd-progress-total";
2359
+ progressTotal.style.cssText = `font-weight:400; color:${theme.textMuted};`;
2360
+ progressLabel.appendChild(progressCurrent);
2361
+ progressLabel.appendChild(progressTotal);
2362
+ const progressFollowUp = document.createElement("span");
2363
+ progressFollowUp.id = "dd-progress-followup";
2364
+ progressFollowUp.textContent = "Follow-up";
2365
+ progressFollowUp.style.cssText = "display:none; font-size:12px; font-weight:600; color:#fff; background:rgba(59,130,246,0.44); border-radius:999px; padding:2px 10px;";
2366
+ progressHead.appendChild(progressLabel);
2367
+ progressHead.appendChild(progressFollowUp);
2368
+ const progressTrack = document.createElement("div");
2369
+ progressTrack.className = "deepdots-progress-track";
2370
+ progressTrack.style.cssText = `width:100%; height:4px; border-radius:999px; background:${theme.progressTrack}; overflow:hidden;`;
2371
+ const progressBar = document.createElement("div");
2372
+ progressBar.id = "dd-progress-bar";
2373
+ progressBar.style.cssText = "height:100%; width:0%; background:#22C55E; border-radius:999px; transition:width 450ms ease;";
2374
+ progressTrack.appendChild(progressBar);
2375
+ progressEl.appendChild(progressHead);
2376
+ progressEl.appendChild(progressTrack);
2377
+ function updateProgress(p) {
2378
+ const total = typeof p.total === "number" ? p.total : 0;
2379
+ const progress = typeof p.progress === "number" ? p.progress : 0;
2380
+ if (!progressEnabled || onStartPage || p.completed || total <= 1) {
2381
+ progressEl.style.display = "none";
2382
+ containerContent.style.paddingTop = "16px";
2383
+ return;
2384
+ }
2385
+ progressEl.style.display = "flex";
2386
+ containerContent.style.paddingTop = "0";
2387
+ const current = Math.min(total, Math.max(1, progress + 1));
2388
+ const pct = Math.min(100, Math.max(0, current / total * 100));
2389
+ progressBar.style.width = `${pct}%`;
2390
+ const label = Math.min(total, Math.max(1, Math.floor(progress) + 1));
2391
+ progressLabel.style.display = progressShowUnit ? "block" : "none";
2392
+ if (progressUnit === "percentage") {
2393
+ progressCurrent.textContent = `${Math.round(pct)}%`;
2394
+ progressTotal.textContent = "";
2395
+ } else {
2396
+ progressCurrent.textContent = `Question ${label}`;
2397
+ progressTotal.textContent = ` of ${total}`;
2398
+ }
2399
+ progressFollowUp.style.display = p.followup ? "inline-block" : "none";
2400
+ }
2302
2401
  ensureMagicFeedbackStyles(popup);
2303
2402
  ensureSpinnerStyles(popup);
2304
2403
  ensureResponsiveStyles(popup);
2404
+ ensureCustomCss(options?.surveyCss);
2305
2405
  const containerContent = document.createElement("div");
2306
- containerContent.className = "deepdots-popup-container-conetent";
2307
- containerContent.style.cssText = `
2308
- display:flex;
2309
- flex-direction:column;
2310
- padding: 0 20px 12px 20px;
2311
- max-height: 80vh; /* l\xEDmite general del popup */
2312
- overflow: hidden; /* quita scroll del contenedor principal */
2313
- `;
2406
+ containerContent.id = "dd-content";
2407
+ containerContent.className = "deepdots-popup-container-content";
2408
+ containerContent.style.cssText = "display:flex; flex-direction:column; flex:1 1 auto; min-height:0; padding:16px 0 0 0; overflow:hidden;";
2314
2409
  const main = document.createElement("div");
2410
+ main.id = "dd-main";
2315
2411
  main.className = "deepdots-popup-main";
2316
- main.style.cssText = "display:flex; flex-direction:column; width:100%; max-height:80vh; overflow-y:auto;";
2412
+ main.style.cssText = "display:flex; flex-direction:column; width:100%; flex:1 1 auto; min-height:0; overflow-y:auto;";
2317
2413
  const formWrapper = document.createElement("div");
2414
+ formWrapper.id = "dd-form-wrapper";
2318
2415
  formWrapper.style.cssText = "width:100%; flex: 1 1 auto;";
2319
2416
  const errorHint = document.createElement("div");
2417
+ errorHint.id = "dd-error";
2320
2418
  errorHint.className = "deepdots-error-hint";
2321
2419
  errorHint.style.cssText = `
2322
2420
  display: none;
@@ -2345,20 +2443,24 @@ async function renderPopup(container, surveyId, productId, actions, emit, onClos
2345
2443
  main.appendChild(formWrapper);
2346
2444
  main.appendChild(errorHint);
2347
2445
  const footer = document.createElement("div");
2446
+ footer.id = "dd-footer";
2348
2447
  footer.className = "deepdots-popup-footer";
2349
2448
  footer.setAttribute("data-actions-wrapper", "true");
2350
- footer.style.cssText = "display:flex; flex-direction: row-reverse ;justify-content:space-between; align-items:center; gap:8px; margin-top:auto; width:100%; padding-top:16px;";
2449
+ footer.style.cssText = "display:flex; flex-direction: row-reverse ;justify-content:space-between; align-items:center; gap:4px; margin-top:auto; width:100%; padding-top:12px;";
2351
2450
  const backButton = document.createElement("button");
2451
+ backButton.id = "dd-back";
2452
+ backButton.className = "dd-nav-btn";
2352
2453
  backButton.textContent = actions?.back ? actions.back.label : "Back";
2353
2454
  backButton.style.cssText = `
2354
2455
  background: transparent;
2355
- color: #333;
2356
- border: 1px solid #999;
2456
+ color: ${theme.textMuted};
2457
+ border: none;
2458
+ min-height: 44px;
2357
2459
  padding: 12px 24px;
2358
- border-radius: 4px;
2460
+ border-radius: 6px;
2359
2461
  cursor: pointer;
2360
- font-size: 14px;
2361
- box-shadow: 0 2px 4px rgba(0,0,0,0.1);
2462
+ font-size: 15px;
2463
+ font-weight: 600;
2362
2464
  transition: filter .15s ease;
2363
2465
  display: inline-flex;
2364
2466
  align-items: center;
@@ -2376,15 +2478,19 @@ async function renderPopup(container, surveyId, productId, actions, emit, onClos
2376
2478
  formInstance?.back?.();
2377
2479
  };
2378
2480
  const startButton = document.createElement("button");
2481
+ startButton.id = "dd-start";
2482
+ startButton.className = "dd-nav-btn";
2379
2483
  startButton.textContent = actions?.start ? actions.start.label : "Start survey";
2380
2484
  startButton.style.cssText = `
2381
2485
  background: #1E293B;
2382
2486
  color: #fff;
2383
2487
  border: none;
2488
+ min-height: 44px;
2384
2489
  padding: 12px 24px;
2385
- border-radius: 4px;
2490
+ border-radius: 6px;
2386
2491
  cursor: pointer;
2387
- font-size: 14px;
2492
+ font-size: 15px;
2493
+ font-weight: 600;
2388
2494
  box-shadow: 0 2px 4px rgba(0,0,0,0.1);
2389
2495
  transition: filter .15s ease;
2390
2496
  display: inline-flex;
@@ -2395,17 +2501,23 @@ async function renderPopup(container, surveyId, productId, actions, emit, onClos
2395
2501
  startButton.onclick = () => {
2396
2502
  emit("popup_clicked", surveyId, { action: "start_survey" });
2397
2503
  formInstance?.startForm?.();
2504
+ onStartPage = false;
2505
+ updateProgress({ progress: formInstance?.progress, total: formInstance?.total });
2398
2506
  };
2399
2507
  const closeButton = document.createElement("button");
2508
+ closeButton.id = "dd-complete";
2509
+ closeButton.className = "dd-nav-btn";
2400
2510
  closeButton.textContent = actions?.complete ? actions.complete.label : "Complete survey";
2401
2511
  closeButton.style.cssText = `
2402
2512
  background: #1E293B;
2403
2513
  color: #fff;
2404
2514
  border: none;
2515
+ min-height: 44px;
2405
2516
  padding: 12px 24px;
2406
- border-radius: 4px;
2517
+ border-radius: 6px;
2407
2518
  cursor: pointer;
2408
- font-size: 14px;
2519
+ font-size: 15px;
2520
+ font-weight: 600;
2409
2521
  box-shadow: 0 2px 4px rgba(0,0,0,0.1);
2410
2522
  transition: filter .15s ease;
2411
2523
  display: inline-flex;
@@ -2424,15 +2536,19 @@ async function renderPopup(container, surveyId, productId, actions, emit, onClos
2424
2536
  onClose();
2425
2537
  };
2426
2538
  const submitButton = document.createElement("button");
2539
+ submitButton.id = "dd-submit";
2540
+ submitButton.className = "dd-nav-btn";
2427
2541
  submitButton.textContent = actions?.accept ? actions.accept.label : "Send";
2428
2542
  submitButton.style.cssText = `
2429
2543
  background: #1E293B;
2430
2544
  color: #fff;
2431
2545
  border: none;
2546
+ min-height: 44px;
2432
2547
  padding: 12px 24px;
2433
- border-radius: 4px;
2548
+ border-radius: 6px;
2434
2549
  cursor: pointer;
2435
- font-size: 14px;
2550
+ font-size: 15px;
2551
+ font-weight: 600;
2436
2552
  box-shadow: 0 2px 4px rgba(0,0,0,0.1);
2437
2553
  transition: filter .15s ease;
2438
2554
  display: inline-flex;
@@ -2454,8 +2570,9 @@ async function renderPopup(container, surveyId, productId, actions, emit, onClos
2454
2570
  footer.appendChild(backButton);
2455
2571
  footer.appendChild(closeButton);
2456
2572
  footer.appendChild(startButton);
2457
- main.appendChild(footer);
2458
2573
  containerContent.appendChild(main);
2574
+ footer.style.flex = "0 0 auto";
2575
+ containerContent.appendChild(footer);
2459
2576
  function updateButtons(state) {
2460
2577
  backButton.style.display = "none";
2461
2578
  startButton.style.display = "none";
@@ -2492,7 +2609,27 @@ async function renderPopup(container, surveyId, productId, actions, emit, onClos
2492
2609
  break;
2493
2610
  }
2494
2611
  }
2612
+ function updateNavButtons() {
2613
+ updateButtons(pageDepth > 0 ? "in_progress_next" : "in_progress_first");
2614
+ }
2615
+ let successMessageHtml = "";
2616
+ function showSuccessScreen() {
2617
+ progressEl.style.display = "none";
2618
+ formWrapper.style.display = "none";
2619
+ let done = main.querySelector(".deepdots-success");
2620
+ if (!done) {
2621
+ done = document.createElement("div");
2622
+ done.className = "deepdots-success";
2623
+ done.style.cssText = `width:100%; text-align:center; padding:24px 0; color:${theme.textPrimary};`;
2624
+ main.insertBefore(done, errorHint);
2625
+ }
2626
+ done.innerHTML = successMessageHtml || "<p>Thank you for your feedback!</p>";
2627
+ done.querySelectorAll("img").forEach((img) => {
2628
+ img.style.cssText = "max-width:100%; height:auto; margin:0 auto 16px auto; display:block;";
2629
+ });
2630
+ }
2495
2631
  popup.appendChild(header);
2632
+ popup.appendChild(progressEl);
2496
2633
  popup.appendChild(containerContent);
2497
2634
  container.innerHTML = "";
2498
2635
  container.appendChild(popup);
@@ -2538,7 +2675,11 @@ async function renderPopup(container, surveyId, productId, actions, emit, onClos
2538
2675
  formInstance = import_native.default.form(surveyId, productId, profile, metadata);
2539
2676
  const generateOptions = {
2540
2677
  addButton: false,
2541
- getMetaData: true
2678
+ getMetaData: true,
2679
+ // La pantalla final la pinta el popup: `renderSuccess` de @magicfeedback/native usa
2680
+ // textContent, así que el mensaje de la plataforma (HTML con imagen) no se vería, y
2681
+ // su fallback es un literal genérico que ignora `style.successMessage`.
2682
+ addSuccessScreen: false
2542
2683
  };
2543
2684
  generateOptions.onLoadedEvent = ({ formData }) => {
2544
2685
  try {
@@ -2547,6 +2688,14 @@ async function renderPopup(container, surveyId, productId, actions, emit, onClos
2547
2688
  const s = formData?.style;
2548
2689
  if (s && !stylesInjected) {
2549
2690
  stylesInjected = true;
2691
+ if (s.successMessage) successMessageHtml = s.successMessage;
2692
+ if (options?.showProgressBar === void 0) progressEnabled = s.showProgressBar === true;
2693
+ if (s.showProgressUnit !== void 0) progressShowUnit = s.showProgressUnit !== false;
2694
+ if (s.progressUnit) progressUnit = s.progressUnit;
2695
+ if (s.loadingBarColor) {
2696
+ progressBar.style.background = s.loadingBarColor;
2697
+ progressFollowUp.style.background = s.loadingBarColor;
2698
+ }
2550
2699
  if (s.boxBackgroundColor) {
2551
2700
  popup.style.background = s.boxBackgroundColor;
2552
2701
  }
@@ -2565,9 +2714,9 @@ async function renderPopup(container, surveyId, productId, actions, emit, onClos
2565
2714
  closeButton.style.color = "#fff";
2566
2715
  }
2567
2716
  if (s.buttonSecondaryColor) {
2568
- backButton.style.background = "#fff";
2717
+ backButton.style.background = "transparent";
2569
2718
  backButton.style.color = s.buttonSecondaryColor;
2570
- backButton.style.border = `1px solid ${s.buttonSecondaryColor}`;
2719
+ backButton.style.border = "none";
2571
2720
  }
2572
2721
  if (s.logo) {
2573
2722
  if (!document.getElementById("deepdots-popup-logo")) {
@@ -2612,6 +2761,7 @@ async function renderPopup(container, surveyId, productId, actions, emit, onClos
2612
2761
  }
2613
2762
  if (s.startMessage && s.startMessage !== "") {
2614
2763
  sdkLog(s.startMessage);
2764
+ onStartPage = true;
2615
2765
  updateButtons("start");
2616
2766
  } else {
2617
2767
  updateButtons("in_progress_first");
@@ -2619,6 +2769,7 @@ async function renderPopup(container, surveyId, productId, actions, emit, onClos
2619
2769
  } else {
2620
2770
  updateButtons("in_progress_first");
2621
2771
  }
2772
+ updateProgress({ progress: formInstance.progress, total: formInstance.total });
2622
2773
  emit("popup_clicked", surveyId, { action: "loaded" });
2623
2774
  setLoading(false);
2624
2775
  };
@@ -2626,7 +2777,7 @@ async function renderPopup(container, surveyId, productId, actions, emit, onClos
2626
2777
  setLoading(true);
2627
2778
  emit("popup_clicked", surveyId, { action: "before_submit" });
2628
2779
  };
2629
- generateOptions.afterSubmitEvent = ({ error, completed, total, progress }) => {
2780
+ generateOptions.afterSubmitEvent = ({ error, completed, total, progress, followup }) => {
2630
2781
  const errText = error ? typeof error === "string" ? error : error.message ?? String(error) : "";
2631
2782
  if (errText) {
2632
2783
  setLoading(false);
@@ -2634,7 +2785,7 @@ async function renderPopup(container, surveyId, productId, actions, emit, onClos
2634
2785
  errorHint.textContent = "Please answer the required question to continue.";
2635
2786
  errorHint.style.display = "block";
2636
2787
  emit("popup_clicked", surveyId, { action: "validation_error_required" });
2637
- updateButtons("in_progress_next");
2788
+ updateNavButtons();
2638
2789
  return;
2639
2790
  }
2640
2791
  errorHint.textContent = "An error occurred while submitting. Please try again or close the popup.";
@@ -2647,23 +2798,21 @@ async function renderPopup(container, surveyId, productId, actions, emit, onClos
2647
2798
  if (completed) {
2648
2799
  emit("survey_completed", surveyId, { action: "completed" });
2649
2800
  surveyCompletedEmitted = true;
2801
+ showSuccessScreen();
2650
2802
  updateButtons("completed");
2803
+ updateProgress({ progress, total, completed: true });
2651
2804
  return;
2652
2805
  }
2653
2806
  emit("popup_clicked", surveyId, { action: "partial" });
2654
- if (total > 1 && progress > 0 && progress < total) {
2655
- updateButtons("in_progress_next");
2656
- } else {
2657
- updateButtons("in_progress_first");
2658
- }
2807
+ pageDepth++;
2808
+ updateNavButtons();
2809
+ updateProgress({ progress, total, followup });
2659
2810
  };
2660
- generateOptions.onBackEvent = ({ progress }) => {
2811
+ generateOptions.onBackEvent = ({ progress, error, followup }) => {
2661
2812
  emit("popup_clicked", surveyId, { action: "back" });
2662
- if (progress === 0) {
2663
- updateButtons("in_progress_first");
2664
- } else {
2665
- updateButtons("in_progress_next");
2666
- }
2813
+ if (!error) pageDepth = Math.max(0, pageDepth - 1);
2814
+ updateNavButtons();
2815
+ updateProgress({ progress, total: formInstance.total, followup });
2667
2816
  };
2668
2817
  formInstance.generate(formDivId, generateOptions).catch((err) => {
2669
2818
  sdkError("[MagicFeedback] Error generating form:", err);
@@ -2915,14 +3064,17 @@ var POSITION_MAP = {
2915
3064
  "top-right": { justifyContent: "flex-end", alignItems: "flex-start", padding: "16px", background: "transparent" },
2916
3065
  "top-left": { justifyContent: "flex-start", alignItems: "flex-start", padding: "16px", background: "transparent" }
2917
3066
  };
3067
+ function jsonForScript(value) {
3068
+ return JSON.stringify(value ?? null).replace(/</g, "\\u003C").replace(/\u2028/g, "\\u2028").replace(/\u2029/g, "\\u2029");
3069
+ }
2918
3070
  function buildSurveyHtml(opts) {
2919
3071
  const env = opts.env === "development" ? "dev" : "prod";
2920
3072
  const version = opts.version ?? "2.2.4";
2921
3073
  const cdn = `https://cdn.jsdelivr.net/npm/@magicfeedback/native@${version}/dist/magicfeedback-sdk.browser.js`;
2922
- const sid = JSON.stringify(opts.surveyId);
2923
- const pid = JSON.stringify(opts.productId);
2924
- const profileJson = JSON.stringify(opts.profile ?? []);
2925
- const metaJson = JSON.stringify(opts.metadata ?? []);
3074
+ const sid = jsonForScript(opts.surveyId);
3075
+ const pid = jsonForScript(opts.productId);
3076
+ const profileJson = jsonForScript(opts.profile ?? []);
3077
+ const metaJson = jsonForScript(opts.metadata ?? []);
2926
3078
  const fontFaceCss = opts.font ? buildFontFaceCss(opts.font.family, opts.font.url) : "";
2927
3079
  const fontFamilyValue = opts.font ? buildFontFamilyValue(opts.font.family) : "-apple-system,system-ui,sans-serif";
2928
3080
  const popupClass = opts.font?.family ? "deepdots-popup deepdots-has-font" : "deepdots-popup";
@@ -2930,6 +3082,8 @@ function buildSurveyHtml(opts) {
2930
3082
  const popupBg = isDark ? "#1e1e1e" : "#fff";
2931
3083
  const colorScheme = isDark ? "dark" : "light";
2932
3084
  const textPrimary = isDark ? "#f0f0f0" : "#111";
3085
+ const textMuted = isDark ? "#9ca3af" : "#6b7280";
3086
+ const trackBg = isDark ? "#3f3f46" : "#e5e7eb";
2933
3087
  const pos = POSITION_MAP[opts.position ?? "center"] ?? POSITION_MAP.center;
2934
3088
  const chrome = opts.chrome !== false;
2935
3089
  const bodyBg = chrome ? pos.background : "transparent";
@@ -2941,10 +3095,16 @@ function buildSurveyHtml(opts) {
2941
3095
  const cardMaxWidth = chrome ? "600px" : "none";
2942
3096
  const cardWidth = chrome ? "90%" : "100%";
2943
3097
  const cardMinHeight = chrome ? "200px" : "0";
2944
- const backLabel = JSON.stringify(opts.actions?.back?.label ?? "Back");
2945
- const startLabel = JSON.stringify(opts.actions?.start?.label ?? "Start survey");
2946
- const completeLabel = JSON.stringify(opts.actions?.complete?.label ?? "Complete survey");
2947
- const submitLabel = JSON.stringify(opts.actions?.accept?.label ?? "Send");
3098
+ const cardHeight = chrome ? "auto" : "100%";
3099
+ const cardMaxHeight = chrome ? "90vh" : "100%";
3100
+ const mobileCard = chrome ? `.deepdots-popup{width:calc(100% - 24px);max-width:calc(100% - 24px);border-radius:12px;padding:calc(16px + env(safe-area-inset-top)) 16px calc(16px + env(safe-area-inset-bottom)) 16px}` : `.deepdots-popup{width:100%;max-width:100%;border-radius:0;padding:16px}`;
3101
+ const titleJson = jsonForScript(opts.title ?? "");
3102
+ const customCss = (opts.surveyCss ?? "").replace(/<\/\s*style/gi, "<\\/style");
3103
+ const progressPref = opts.showProgressBar === void 0 ? "null" : String(opts.showProgressBar);
3104
+ const backLabel = jsonForScript(opts.actions?.back?.label ?? "Back");
3105
+ const startLabel = jsonForScript(opts.actions?.start?.label ?? "Start survey");
3106
+ const completeLabel = jsonForScript(opts.actions?.complete?.label ?? "Complete survey");
3107
+ const submitLabel = jsonForScript(opts.actions?.accept?.label ?? "Send");
2948
3108
  return `<!DOCTYPE html><html><head>
2949
3109
  <meta name="viewport" content="width=device-width, initial-scale=1.0"/>
2950
3110
  <meta name="color-scheme" content="${colorScheme}"/>
@@ -2953,56 +3113,97 @@ ${style_default}
2953
3113
  ${fontFaceCss}
2954
3114
  html,body{margin:0;padding:0;height:100%;font-family:${fontFamilyValue}}
2955
3115
  body{display:${bodyDisplay};justify-content:${pos.justifyContent};align-items:${pos.alignItems};background:${bodyBg};padding:${bodyPadding};box-sizing:border-box}
2956
- .deepdots-popup{position:relative;display:flex;flex-direction:column;justify-content:flex-start;background:${cardBg};color-scheme:${colorScheme};border-radius:${cardRadius};padding:24px;box-shadow:${cardShadow};max-width:${cardMaxWidth};width:${cardWidth};min-height:${cardMinHeight};box-sizing:border-box}
2957
- .deepdots-popup-header{display:flex;justify-content:flex-end;align-items:center;width:100%}
2958
- #dd-close{background:transparent;border:none;width:32px;height:32px;display:flex;align-items:center;justify-content:center;border-radius:8px;cursor:pointer;color:${textPrimary};padding:4px}
2959
- .deepdots-popup-container-content{display:flex;flex-direction:column;padding:0 20px 12px 20px;max-height:80vh;overflow:hidden;box-sizing:border-box}
2960
- .deepdots-popup-main{display:flex;flex-direction:column;width:100%;max-height:80vh;overflow-y:auto;overflow-x:hidden;position:relative}
3116
+ .deepdots-popup{position:relative;display:flex;flex-direction:column;justify-content:flex-start;background:${cardBg};color-scheme:${colorScheme};border-radius:${cardRadius};padding:24px;box-shadow:${cardShadow};max-width:${cardMaxWidth};width:${cardWidth};min-height:${cardMinHeight};height:${cardHeight};max-height:${cardMaxHeight};box-sizing:border-box}
3117
+ .deepdots-popup-header{display:flex;justify-content:space-between;align-items:center;gap:12px;width:100%;flex:0 0 auto}
3118
+ /* Neutraliza la regla \`.deepdots-popup h2\` del CSS del survey (uppercase, centrado y
3119
+ margin-bottom 40px), pensada para los enunciados y no para el t\xEDtulo de la cabecera. */
3120
+ #dd-title{margin:0;font-family:var(--deepdots-font,'Montserrat',inherit);font-size:17px;font-weight:600;line-height:1.3;color:${textPrimary};text-transform:none;text-align:left;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
3121
+ #dd-close{background:transparent;border:none;width:32px;height:32px;display:flex;align-items:center;justify-content:center;border-radius:8px;cursor:pointer;color:${textPrimary};padding:4px;flex:0 0 auto;margin-left:auto}
3122
+ /* Progreso alineado con la cabecera: sin padding horizontal propio, lo marca la tarjeta.
3123
+ El vertical es el mismo arriba y abajo, y del mismo valor que el padding de la tarjeta. */
3124
+ .deepdots-progress{display:none;flex-direction:column;gap:8px;width:100%;flex:0 0 auto;padding:16px 0;box-sizing:border-box}
3125
+ .deepdots-progress-head{display:flex;flex-direction:row;justify-content:space-between;align-items:center;width:100%;gap:8px}
3126
+ #dd-progress-label{font-size:13px;line-height:1.2}
3127
+ /* "Question 1" en negrita y "of 3" en regular gris, como el mockup. */
3128
+ #dd-progress-current{font-weight:700;color:${textPrimary}}
3129
+ #dd-progress-total{font-weight:400;color:${textMuted}}
3130
+ #dd-progress-followup{display:none;font-size:12px;font-weight:600;color:#fff;background:rgba(59,130,246,0.44);border-radius:999px;padding:2px 10px}
3131
+ .deepdots-progress-track{width:100%;height:4px;border-radius:999px;background:${trackBg};overflow:hidden}
3132
+ #dd-progress-bar{height:100%;width:0%;background:#22C55E;border-radius:999px;transition:width 450ms ease}
3133
+ /* El popup es una columna: solo el bloque de preguntas hace scroll, para que el footer
3134
+ con las acciones quede siempre visible en el borde inferior (antes viv\xEDa dentro del
3135
+ \xE1rea scrollable y hab\xEDa que bajar hasta el final para ver "Send"). */
3136
+ /* Sin sangrado extra: el contenido se alinea con el t\xEDtulo y con la barra de progreso (antes
3137
+ sumaba 20px a los lados sobre el padding de la tarjeta y quedaba m\xE1s adentro que la cabecera). */
3138
+ /* Sin barra de progreso, este padding-top es el que separa la cabecera de la pregunta. Con
3139
+ barra, el JS lo pone a 0 y el hueco lo aporta el padding inferior del bloque de progreso,
3140
+ de modo que el espacio por arriba y por abajo de la barra es id\xE9ntico. */
3141
+ .deepdots-popup-container-content{display:flex;flex-direction:column;flex:1 1 auto;min-height:0;padding:16px 0 0 0;overflow:hidden;box-sizing:border-box}
3142
+ /* El enunciado trae margin-top:20px del CSS de surveys, que sumaba al hueco de la barra y
3143
+ descompensaba la simetr\xEDa. Solo se anula en el primero: entre preguntas sigue separando. */
3144
+ .deepdots-popup .magicfeedback-questions .magicfeedback-div:first-child .magicfeedback-label{margin-top:0}
3145
+ .deepdots-popup-main{display:flex;flex-direction:column;width:100%;flex:1 1 auto;min-height:0;overflow-y:auto;overflow-x:hidden;position:relative}
2961
3146
  #dd-form-wrapper{width:100%;flex:1 1 auto}
2962
3147
  #mf{width:100%;box-sizing:border-box;visibility:hidden}
2963
3148
  .deepdots-popup-main *{max-width:100%;box-sizing:border-box}
2964
3149
  #dd-logo{max-height:40px;max-width:100%;object-fit:contain}
2965
3150
  .deepdots-error-hint{display:none;margin:12px 0 0 0;padding:10px 12px;border-radius:6px;background:#FEF3C7;color:#92400E;border:1px solid #FCD34D;font-size:13px}
2966
- .deepdots-popup-footer{display:flex;flex-direction:row-reverse;justify-content:space-between;align-items:center;gap:8px;margin-top:auto;width:100%;padding-top:16px}
2967
- .dd-nav-btn{display:none;border:none;padding:12px 24px;border-radius:4px;cursor:pointer;font-size:14px;box-shadow:0 2px 4px rgba(0,0,0,0.1);align-items:center;justify-content:center;text-align:center}
2968
- #dd-back{background:transparent;color:#333;border:1px solid #999}
3151
+ /* Pantalla final: el HTML del editor de la plataforma (imagen + texto), centrado. */
3152
+ .deepdots-success{display:none;width:100%;text-align:center;padding:24px 0;color:${textPrimary}}
3153
+ .deepdots-success img{max-width:100%;height:auto;margin:0 auto 16px auto;display:block}
3154
+ .deepdots-success p{margin:0;font-size:16px;font-weight:600;line-height:1.4}
3155
+ .deepdots-popup-footer{display:flex;flex-direction:row-reverse;justify-content:space-between;align-items:center;gap:4px;margin-top:auto;width:100%;padding-top:12px}
3156
+ .dd-nav-btn{display:none;border:none;min-height:44px;padding:12px 24px;border-radius:6px;cursor:pointer;font-size:15px;font-weight:600;align-items:center;justify-content:center;text-align:center}
3157
+ /* Secundario como bot\xF3n de texto: sin borde ni fondo, para que el primario sea la \xFAnica CTA. */
3158
+ #dd-back{background:transparent;color:${textMuted};border:none}
2969
3159
  #dd-start,#dd-complete,#dd-submit{background:#1E293B;color:#fff;border:none}
2970
3160
  #dd-submit:disabled,#dd-start:disabled,#dd-back:disabled,#dd-complete:disabled{opacity:0.6;cursor:not-allowed}
2971
3161
  .mf-spinner{display:none;position:absolute;top:50%;left:50%;transform:translate(-50%,-50%)}
2972
3162
  .mf-spinner-circle{width:28px;height:28px;border:3px solid #e0e6ed;border-top-color:#1E293B;border-radius:50%;animation:ddspin 0.9s linear infinite}
2973
3163
  @keyframes ddspin{0%{transform:rotate(0deg)}100%{transform:rotate(360deg)}}
2974
3164
  @media (max-width:640px){
2975
- .deepdots-popup{width:calc(100% - 24px);max-width:calc(100% - 24px);border-radius:12px}
2976
- .deepdots-popup-footer{flex-direction:column-reverse;gap:12px}
3165
+ ${mobileCard}
3166
+ /* Apilados: la acci\xF3n principal (Send/Start/Complete) arriba y Back debajo. El orden del
3167
+ DOM ya es ese, as\xED que \`column\` (no \`column-reverse\`) es lo que lo respeta. */
3168
+ .deepdots-popup-footer{flex-direction:column;gap:4px}
2977
3169
  .dd-nav-btn{width:100%}
2978
3170
  .magicfeedback-checkbox-container,.magicfeedback-radio-container{margin:4px 0;padding:4px 8px}
2979
3171
  .magicfeedback-checkbox label,.magicfeedback-radio-container label{font-size:15px}
2980
3172
  .deepdots-popup input[type="radio"]{margin:6px 0 6px 8px}
2981
3173
  .deepdots-popup input[type="checkbox"]{width:16px;height:16px}
2982
3174
  }
3175
+ ${customCss}
2983
3176
  </style>
2984
3177
  </head><body>
2985
3178
  <div class="${popupClass}" id="dd-popup">
2986
3179
  <div class="deepdots-popup-header">
3180
+ <h2 id="dd-title" class="deepdots-popup-title" hidden></h2>
2987
3181
  <button type="button" id="dd-close" aria-label="Close popup">
2988
3182
  <svg width="28" height="28" viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg">
2989
3183
  <path d="M6 6L18 18M6 18L18 6" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"/>
2990
3184
  </svg>
2991
3185
  </button>
2992
3186
  </div>
2993
- <div class="deepdots-popup-container-content">
3187
+ <div class="deepdots-progress" id="dd-progress">
3188
+ <div class="deepdots-progress-head">
3189
+ <span id="dd-progress-label"><span id="dd-progress-current"></span><span id="dd-progress-total"></span></span>
3190
+ <span id="dd-progress-followup">Follow-up</span>
3191
+ </div>
3192
+ <div class="deepdots-progress-track"><div id="dd-progress-bar"></div></div>
3193
+ </div>
3194
+ <div class="deepdots-popup-container-content" id="dd-content">
2994
3195
  <div class="deepdots-popup-main" id="dd-main">
2995
3196
  <div id="dd-form-wrapper">
2996
3197
  <div class="mf-spinner" id="dd-spinner" role="status" aria-label="Loading survey"><div class="mf-spinner-circle"></div></div>
2997
3198
  <div id="mf"></div>
2998
3199
  </div>
2999
3200
  <div class="deepdots-error-hint" id="dd-error" role="alert" aria-live="polite"></div>
3000
- <div class="deepdots-popup-footer" id="dd-footer">
3001
- <button type="button" class="dd-nav-btn" id="dd-submit">Send</button>
3002
- <button type="button" class="dd-nav-btn" id="dd-back">Back</button>
3003
- <button type="button" class="dd-nav-btn" id="dd-complete">Complete survey</button>
3004
- <button type="button" class="dd-nav-btn" id="dd-start">Start survey</button>
3005
- </div>
3201
+ </div>
3202
+ <div class="deepdots-popup-footer" id="dd-footer">
3203
+ <button type="button" class="dd-nav-btn" id="dd-submit">Send</button>
3204
+ <button type="button" class="dd-nav-btn" id="dd-back">Back</button>
3205
+ <button type="button" class="dd-nav-btn" id="dd-complete">Complete survey</button>
3206
+ <button type="button" class="dd-nav-btn" id="dd-start">Start survey</button>
3006
3207
  </div>
3007
3208
  </div>
3008
3209
  </div>
@@ -3015,6 +3216,7 @@ body{display:${bodyDisplay};justify-content:${pos.justifyContent};align-items:${
3015
3216
 
3016
3217
  var popup=document.getElementById('dd-popup');
3017
3218
  var main=document.getElementById('dd-main');
3219
+ var content=document.getElementById('dd-content');
3018
3220
  var footer=document.getElementById('dd-footer');
3019
3221
  var spinner=document.getElementById('dd-spinner');
3020
3222
  var formHost=document.getElementById('mf');
@@ -3023,6 +3225,58 @@ body{display:${bodyDisplay};justify-content:${pos.justifyContent};align-items:${
3023
3225
  var startBtn=document.getElementById('dd-start');
3024
3226
  var completeBtn=document.getElementById('dd-complete');
3025
3227
  var submitBtn=document.getElementById('dd-submit');
3228
+ var titleEl=document.getElementById('dd-title');
3229
+ var progressEl=document.getElementById('dd-progress');
3230
+ var progressLabel=document.getElementById('dd-progress-label');
3231
+ var progressCurrent=document.getElementById('dd-progress-current');
3232
+ var progressTotal=document.getElementById('dd-progress-total');
3233
+ var progressFollowUp=document.getElementById('dd-progress-followup');
3234
+ var progressBar=document.getElementById('dd-progress-bar');
3235
+
3236
+ function setTitle(t){
3237
+ if(!t) return;
3238
+ titleEl.textContent=t;
3239
+ titleEl.hidden=false;
3240
+ }
3241
+ setTitle(${titleJson});
3242
+
3243
+ // Estado de la barra de progreso. \`progressPref\` null = manda la plataforma (style).
3244
+ var progressPref=${progressPref};
3245
+ var progressEnabled=progressPref===true;
3246
+ var progressShowUnit=true;
3247
+ var progressUnit='fraction';
3248
+ var onStartPage=false;
3249
+
3250
+ function updateProgress(p){
3251
+ var total=p&&typeof p.total==='number'?p.total:0;
3252
+ var progress=p&&typeof p.progress==='number'?p.progress:0;
3253
+ // Solo tiene sentido con m\xE1s de una p\xE1gina, fuera de la pantalla de inicio y sin completar.
3254
+ if(!progressEnabled||onStartPage||p&&p.completed||total<=1){
3255
+ progressEl.style.display='none';
3256
+ // Sin barra, el hueco cabecera\u2192pregunta lo pone el contenido.
3257
+ content.style.paddingTop='16px';
3258
+ return;
3259
+ }
3260
+ progressEl.style.display='flex';
3261
+ // Con barra, el hueco inferior ya lo pone el bloque de progreso: no duplicarlo.
3262
+ content.style.paddingTop='0';
3263
+ // Espejo de LineProgressQuestion (MagicSurvey): la barra usa el valor real (las follow-up
3264
+ // suman +0.5 y avanzan media casilla) y la etiqueta redondea hacia abajo, porque una
3265
+ // follow-up es un paso DENTRO de la misma pregunta, no la siguiente.
3266
+ var current=Math.min(total,Math.max(1,progress+1));
3267
+ var pct=Math.min(100,Math.max(0,(current/total)*100));
3268
+ progressBar.style.width=pct+'%';
3269
+ var label=Math.min(total,Math.max(1,Math.floor(progress)+1));
3270
+ progressLabel.style.display=progressShowUnit?'block':'none';
3271
+ if(progressUnit==='percentage'){
3272
+ progressCurrent.textContent=Math.round(pct)+'%';
3273
+ progressTotal.textContent='';
3274
+ } else {
3275
+ progressCurrent.textContent='Question '+label;
3276
+ progressTotal.textContent=' of '+total;
3277
+ }
3278
+ progressFollowUp.style.display=p&&p.followup?'inline-block':'none';
3279
+ }
3026
3280
 
3027
3281
  backBtn.textContent=${backLabel};
3028
3282
  startBtn.textContent=${startLabel};
@@ -3031,7 +3285,13 @@ body{display:${bodyDisplay};justify-content:${pos.justifyContent};align-items:${
3031
3285
 
3032
3286
  document.getElementById('dd-close').onclick=function(){ emitJSON('popup_close'); };
3033
3287
  backBtn.onclick=function(){ if(window.DeepdotsForm && window.DeepdotsForm.back){ window.DeepdotsForm.back(); } };
3034
- startBtn.onclick=function(){ if(window.DeepdotsForm && window.DeepdotsForm.startForm){ window.DeepdotsForm.startForm(); } };
3288
+ startBtn.onclick=function(){
3289
+ if(window.DeepdotsForm && window.DeepdotsForm.startForm){
3290
+ window.DeepdotsForm.startForm();
3291
+ onStartPage=false;
3292
+ updateProgress({ progress:window.DeepdotsForm.progress, total:window.DeepdotsForm.total, completed:false, followup:false });
3293
+ }
3294
+ };
3035
3295
  completeBtn.onclick=function(){ emitJSON('popup_close'); };
3036
3296
  var surveyCompletedEmitted=false;
3037
3297
  submitBtn.onclick=function(){
@@ -3039,6 +3299,36 @@ body{display:${bodyDisplay};justify-content:${pos.justifyContent};align-items:${
3039
3299
  if(window.DeepdotsForm && window.DeepdotsForm.send){ window.DeepdotsForm.send(); }
3040
3300
  };
3041
3301
 
3302
+ // Mensaje final configurado en la plataforma (\`style.successMessage\`). Se guarda al cargar
3303
+ // y se pinta al completar. Va por innerHTML porque es HTML del editor de la plataforma
3304
+ // (imagen + texto), igual que ya hace \`renderStartMessage\` con el mensaje de inicio.
3305
+ var successMessageHtml='';
3306
+ function showSuccessScreen(){
3307
+ progressEl.style.display='none';
3308
+ var wrapper=document.getElementById('dd-form-wrapper');
3309
+ if(wrapper){ wrapper.style.display='none'; }
3310
+ var done=document.getElementById('dd-success');
3311
+ if(!done){
3312
+ done=document.createElement('div');
3313
+ done.id='dd-success';
3314
+ done.className='deepdots-success';
3315
+ main.insertBefore(done, errorHint);
3316
+ }
3317
+ done.innerHTML=successMessageHtml || '<p>Thank you for your feedback!</p>';
3318
+ done.style.display='block';
3319
+ }
3320
+
3321
+ // Profundidad de navegaci\xF3n DENTRO del survey: +1 por p\xE1gina avanzada, -1 al volver.
3322
+ // Sustituye a la condici\xF3n \`total>1 && progress>0 && progress<total\`, que escond\xEDa el
3323
+ // Back siempre que la siguiente pantalla era una follow-up din\xE1mica: las follow-up no
3324
+ // entran en el grafo (suman +0.5 al progress y no tocan el total), as\xED que un survey de
3325
+ // una pregunta con follow-up tiene total=1 y nunca cumpl\xEDa \`total>1\`.
3326
+ var pageDepth=0;
3327
+
3328
+ function updateNavButtons(){
3329
+ updateButtons(pageDepth>0?'in_progress_next':'in_progress_first');
3330
+ }
3331
+
3042
3332
  function updateButtons(state){
3043
3333
  backBtn.style.display='none';
3044
3334
  startBtn.style.display='none';
@@ -3083,10 +3373,20 @@ body{display:${bodyDisplay};justify-content:${pos.justifyContent};align-items:${
3083
3373
  form.generate('mf', {
3084
3374
  addButton:false,
3085
3375
  getMetaData:true,
3376
+ // La pantalla final la pinta el popup: renderSuccess de @magicfeedback/native usa
3377
+ // textContent, as\xED que el mensaje de la plataforma (HTML con imagen) no se ver\xEDa, y su
3378
+ // fallback es un literal gen\xE9rico que ignora style.successMessage.
3379
+ addSuccessScreen:false,
3086
3380
  onLoadedEvent:function(args){
3087
3381
  var s=args && args.formData ? args.formData.style : null;
3088
3382
  if(s && !stylesInjected){
3089
3383
  stylesInjected=true;
3384
+ if(s.successMessage){ successMessageHtml=s.successMessage; }
3385
+ // La barra de progreso la decide el host (init) y, si no se pronuncia, la plataforma.
3386
+ if(progressPref===null){ progressEnabled=s.showProgressBar===true; }
3387
+ if(s.showProgressUnit!==undefined){ progressShowUnit=s.showProgressUnit!==false; }
3388
+ if(s.progressUnit){ progressUnit=s.progressUnit; }
3389
+ if(s.loadingBarColor){ progressBar.style.background=s.loadingBarColor; progressFollowUp.style.background=s.loadingBarColor; }
3090
3390
  if(chromeOn && s.boxBackgroundColor){ popup.style.background=s.boxBackgroundColor; }
3091
3391
  if(s.contentAlign){ main.style.justifyContent = s.contentAlign==='center' ? 'center' : 'flex-start'; }
3092
3392
  if(s.buttonPrimaryColor){
@@ -3095,7 +3395,8 @@ body{display:${bodyDisplay};justify-content:${pos.justifyContent};align-items:${
3095
3395
  completeBtn.style.background=s.buttonPrimaryColor; completeBtn.style.border='none'; completeBtn.style.color='#fff';
3096
3396
  }
3097
3397
  if(s.buttonSecondaryColor){
3098
- backBtn.style.background='#fff'; backBtn.style.color=s.buttonSecondaryColor; backBtn.style.border='1px solid '+s.buttonSecondaryColor;
3398
+ // Bot\xF3n de texto: solo ti\xF1e la etiqueta, sin recuperar fondo ni borde.
3399
+ backBtn.style.background='transparent'; backBtn.style.color=s.buttonSecondaryColor; backBtn.style.border='none';
3099
3400
  }
3100
3401
  if(s.logo && !document.getElementById('dd-logo')){
3101
3402
  var logoImg=document.createElement('img');
@@ -3108,11 +3409,13 @@ body{display:${bodyDisplay};justify-content:${pos.justifyContent};align-items:${
3108
3409
  else if(s.logoPosition==='center'){ logoImg.style.margin='0 auto 20px auto'; logoImg.style.display='block'; }
3109
3410
  main.insertBefore(logoImg, document.getElementById('dd-form-wrapper'));
3110
3411
  }
3111
- if(s.startMessage && s.startMessage!==''){ updateButtons('start'); }
3412
+ if(s.startMessage && s.startMessage!==''){ onStartPage=true; updateButtons('start'); }
3112
3413
  else { updateButtons('in_progress_first'); }
3113
3414
  } else {
3114
3415
  updateButtons('in_progress_first');
3115
3416
  }
3417
+ // El total solo se conoce una vez montado el form; sin \xE9l no hay barra que pintar.
3418
+ updateProgress({ progress:form.progress, total:form.total, completed:false, followup:false });
3116
3419
  emitJSON('loaded');
3117
3420
  setLoading(false);
3118
3421
  },
@@ -3125,9 +3428,10 @@ body{display:${bodyDisplay};justify-content:${pos.justifyContent};align-items:${
3125
3428
  if(error){
3126
3429
  setLoading(false);
3127
3430
  if(error.toLowerCase().indexOf('no response')!==-1){
3431
+ // La p\xE1gina no ha cambiado: el estado de navegaci\xF3n se queda como estaba.
3128
3432
  errorHint.textContent='Please answer the required question to continue.';
3129
3433
  errorHint.style.display='block';
3130
- updateButtons('in_progress_next');
3434
+ updateNavButtons();
3131
3435
  return;
3132
3436
  }
3133
3437
  errorHint.textContent='An error occurred while submitting. Please try again or close the popup.';
@@ -3138,17 +3442,23 @@ body{display:${bodyDisplay};justify-content:${pos.justifyContent};align-items:${
3138
3442
  setLoading(false);
3139
3443
  if(p && p.completed){
3140
3444
  surveyCompletedEmitted=true;
3445
+ showSuccessScreen();
3141
3446
  updateButtons('completed');
3447
+ updateProgress(p);
3142
3448
  emitJSON('survey_completed', p);
3143
3449
  return;
3144
3450
  }
3145
- if(p && p.total>1 && p.progress>0 && p.progress<p.total){ updateButtons('in_progress_next'); }
3146
- else { updateButtons('in_progress_first'); }
3451
+ pageDepth++;
3452
+ updateNavButtons();
3453
+ updateProgress(p);
3147
3454
  emitJSON('after_submit', p);
3148
3455
  },
3149
3456
  onBackEvent:function(p){
3150
- if(p && p.progress===0){ updateButtons('in_progress_first'); }
3151
- else { updateButtons('in_progress_next'); }
3457
+ // Con error ("No page found") no hubo navegaci\xF3n: la profundidad no se toca.
3458
+ if(!(p&&p.error)){ pageDepth=Math.max(0,pageDepth-1); }
3459
+ updateNavButtons();
3460
+ // onBackEvent no trae \`total\`: se lee del form, que es su due\xF1o.
3461
+ updateProgress({ progress:p&&p.progress, total:form.total, completed:false, followup:p&&p.followup });
3152
3462
  emitJSON('back', p);
3153
3463
  }
3154
3464
  }).catch(function(e){ setLoading(false); emit('error:init'); });
@@ -3177,7 +3487,7 @@ var ReactNativePopupRenderer = class {
3177
3487
  }
3178
3488
  init() {
3179
3489
  }
3180
- show(surveyId, productId, actions, emit, onClose, env = "production", userId, style, sessionId, miniService, analyticsFeedbackSessionId, renderChrome) {
3490
+ show(surveyId, productId, actions, emit, onClose, env = "production", userId, style, sessionId, miniService, analyticsFeedbackSessionId, renderChrome, options) {
3181
3491
  this.emitFn = emit;
3182
3492
  this.onCloseFn = onClose;
3183
3493
  this.currentSurveyId = surveyId;
@@ -3194,7 +3504,10 @@ var ReactNativePopupRenderer = class {
3194
3504
  position: style?.position,
3195
3505
  actions,
3196
3506
  // renderChrome:false (init) → HTML sin tarjeta/overlay: el host lo envuelve en su Modal.
3197
- chrome: renderChrome
3507
+ chrome: renderChrome,
3508
+ title: options?.title,
3509
+ showProgressBar: options?.showProgressBar,
3510
+ surveyCss: options?.surveyCss
3198
3511
  });
3199
3512
  if (this.options.onShow) {
3200
3513
  this.options.onShow({ surveyId, productId, html });
@@ -3234,7 +3547,6 @@ var ReactNativePopupRenderer = class {
3234
3547
  break;
3235
3548
  case "survey_completed":
3236
3549
  this.emitFn("survey_completed", surveyId);
3237
- this.onCloseFn?.();
3238
3550
  break;
3239
3551
  case "popup_close":
3240
3552
  this.onCloseFn?.();
@@ -3285,14 +3597,14 @@ var BrowserPopupRenderer = class {
3285
3597
  document.body.appendChild(this.container);
3286
3598
  }
3287
3599
  }
3288
- show(surveyId, productId, actions, emit, onClose, env = "production", userId, style, sessionId, miniService, analyticsFeedbackSessionId, _renderChrome) {
3600
+ show(surveyId, productId, actions, emit, onClose, env = "production", userId, style, sessionId, miniService, analyticsFeedbackSessionId, _renderChrome, options) {
3289
3601
  if (this.visible) return;
3290
3602
  if (!this.container || !document.body.contains(this.container)) this.init();
3291
3603
  if (!this.container) return;
3292
3604
  this.visible = true;
3293
3605
  const container = this.container;
3294
3606
  void Promise.resolve().then(() => (init_renderPopup(), renderPopup_exports)).then(({ renderPopup: renderPopup2 }) => {
3295
- renderPopup2(container, surveyId, productId, actions, emit, onClose, env, userId, style, sessionId, miniService, analyticsFeedbackSessionId);
3607
+ renderPopup2(container, surveyId, productId, actions, emit, onClose, env, userId, style, sessionId, miniService, analyticsFeedbackSessionId, options);
3296
3608
  });
3297
3609
  }
3298
3610
  hide() {
@@ -4148,6 +4460,10 @@ var DeepdotsPopups = class {
4148
4460
  this.env = "production";
4149
4461
  /** Si el SDK pinta el "modal" del popup (RN). Default true; false = el host lo envuelve. */
4150
4462
  this.renderChrome = true;
4463
+ /** Barra de progreso. undefined = la decide la plataforma (style.showProgressBar). */
4464
+ this.showProgressBar = void 0;
4465
+ /** CSS del host inyectado al final de los estilos del popup. */
4466
+ this.surveyCss = void 0;
4151
4467
  /** Identidad + sesión (Fase 1 tracking). Null hasta init(). */
4152
4468
  this.tracking = null;
4153
4469
  /** Capa de analytics (canal separado del feedback). Null hasta init(). */
@@ -4199,6 +4515,8 @@ var DeepdotsPopups = class {
4199
4515
  this.baseUrl = env.apiBaseUrl;
4200
4516
  this.env = config.nodeEnv || "production";
4201
4517
  this.renderChrome = config.renderChrome ?? true;
4518
+ this.showProgressBar = config.showProgressBar;
4519
+ this.surveyCss = config.surveyCss;
4202
4520
  this.config = {
4203
4521
  apiKey: config.apiKey || void 0,
4204
4522
  debug: config.debug || false,
@@ -4644,7 +4962,7 @@ var DeepdotsPopups = class {
4644
4962
  this.log("Showing popup (definition)", def);
4645
4963
  this.surveyToPopupId.set(def.surveyId, def.id);
4646
4964
  this.lastShown.set(def.id, Date.now());
4647
- this.renderPopup(def.surveyId, def.productId, def.actions, def.style);
4965
+ this.renderPopup(def.surveyId, def.productId, def.actions, def.style, def.title);
4648
4966
  this.emitEvent("popup_shown", def.surveyId, { popupId: def.id });
4649
4967
  }
4650
4968
  shouldShow(def, pathUrl, skipPathCheck = false) {
@@ -4982,7 +5300,7 @@ var DeepdotsPopups = class {
4982
5300
  document.body.appendChild(this.popupContainer);
4983
5301
  }
4984
5302
  /** Render the popup UI */
4985
- renderPopup(surveyId, productId, actions, style) {
5303
+ renderPopup(surveyId, productId, actions, style, title) {
4986
5304
  const userId = this.tracking?.getUserId() ?? this.config?.userId;
4987
5305
  const sessionId = this.tracking?.getSessionId() ?? void 0;
4988
5306
  const miniService = this.analytics?.getMiniService() ?? void 0;
@@ -5001,7 +5319,8 @@ var DeepdotsPopups = class {
5001
5319
  sessionId,
5002
5320
  miniService,
5003
5321
  analyticsFeedbackSessionId,
5004
- this.renderChrome
5322
+ this.renderChrome,
5323
+ { title, showProgressBar: this.showProgressBar, surveyCss: this.surveyCss }
5005
5324
  );
5006
5325
  return;
5007
5326
  }
@@ -5020,7 +5339,8 @@ var DeepdotsPopups = class {
5020
5339
  style,
5021
5340
  sessionId,
5022
5341
  miniService,
5023
- analyticsFeedbackSessionId
5342
+ analyticsFeedbackSessionId,
5343
+ { title, showProgressBar: this.showProgressBar, surveyCss: this.surveyCss }
5024
5344
  );
5025
5345
  });
5026
5346
  }